Update FreeBSD network drivers with the 9.3 release

This commit is contained in:
Jérôme Duval
2014-07-12 14:32:52 +02:00
parent 712e51d79a
commit 57f444065f
125 changed files with 248105 additions and 297 deletions
@@ -1659,6 +1659,7 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
(mtod(m, intptr_t) & 3) != 0) {
m = m_defrag(*m_head, M_NOWAIT);
if (m == NULL) {
m_freem(*m_head);
*m_head = NULL;
return (ENOBUFS);
}
@@ -40,7 +40,7 @@
#define ALE_TSO_MAXSEGSIZE 4096
#define ALE_TSO_MAXSIZE (65535 + sizeof(struct ether_vlan_header))
#define ALE_MAXTXSEGS 32
#define ALE_MAXTXSEGS 35
#define ALE_ADDR_LO(x) ((uint64_t) (x) & 0xFFFFFFFF)
#define ALE_ADDR_HI(x) ((uint64_t) (x) >> 32)
@@ -42,7 +42,7 @@
#define ALC_TSO_MAXSEGSIZE 4096
#define ALC_TSO_MAXSIZE (65535 + sizeof(struct ether_vlan_header))
#define ALC_MAXTXSEGS 32
#define ALC_MAXTXSEGS 35
#define ALC_ADDR_LO(x) ((uint64_t) (x) & 0xFFFFFFFF)
#define ALC_ADDR_HI(x) ((uint64_t) (x) >> 32)
@@ -42,7 +42,7 @@
#define AGE_TSO_MAXSEGSIZE 4096
#define AGE_TSO_MAXSIZE (65535 + sizeof(struct ether_vlan_header))
#define AGE_MAXTXSEGS 32
#define AGE_MAXTXSEGS 35
#define AGE_RX_BUF_ALIGN 8
#ifndef __NO_STRICT_ALIGNMENT
#define AGE_RX_BUF_SIZE (MCLBYTES - AGE_RX_BUF_ALIGN)
@@ -132,7 +132,7 @@ static void ae_mac_config(ae_softc_t *sc);
static int ae_intr(void *arg);
static void ae_int_task(void *arg, int pending);
static void ae_tx_intr(ae_softc_t *sc);
static int ae_rxeof(ae_softc_t *sc, ae_rxd_t *rxd);
static void ae_rxeof(ae_softc_t *sc, ae_rxd_t *rxd);
static void ae_rx_intr(ae_softc_t *sc);
static void ae_watchdog(ae_softc_t *sc);
static void ae_tick(void *arg);
@@ -585,7 +585,7 @@ ae_init_locked(ae_softc_t *sc)
val = eaddr[0] << 8 | eaddr[1];
AE_WRITE_4(sc, AE_EADDR1_REG, val);
bzero(sc->rxd_base_dma, AE_RXD_COUNT_DEFAULT * 1536 + 120);
bzero(sc->rxd_base_dma, AE_RXD_COUNT_DEFAULT * 1536 + AE_RXD_PADDING);
bzero(sc->txd_base, AE_TXD_BUFSIZE_DEFAULT);
bzero(sc->txs_base, AE_TXS_COUNT_DEFAULT * 4);
/*
@@ -1149,8 +1149,8 @@ ae_alloc_rings(ae_softc_t *sc)
*/
error = bus_dma_tag_create(sc->dma_parent_tag,
128, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
NULL, NULL, AE_RXD_COUNT_DEFAULT * 1536 + 120, 1,
AE_RXD_COUNT_DEFAULT * 1536 + 120, 0, NULL, NULL,
NULL, NULL, AE_RXD_COUNT_DEFAULT * 1536 + AE_RXD_PADDING, 1,
AE_RXD_COUNT_DEFAULT * 1536 + AE_RXD_PADDING, 0, NULL, NULL,
&sc->dma_rxd_tag);
if (error != 0) {
device_printf(sc->dev, "could not creare TxS DMA tag.\n");
@@ -1209,15 +1209,15 @@ ae_alloc_rings(ae_softc_t *sc)
return (error);
}
error = bus_dmamap_load(sc->dma_rxd_tag, sc->dma_rxd_map,
sc->rxd_base_dma, AE_RXD_COUNT_DEFAULT * 1536 + 120, ae_dmamap_cb,
&busaddr, BUS_DMA_NOWAIT);
sc->rxd_base_dma, AE_RXD_COUNT_DEFAULT * 1536 + AE_RXD_PADDING,
ae_dmamap_cb, &busaddr, BUS_DMA_NOWAIT);
if (error != 0 || busaddr == 0) {
device_printf(sc->dev,
"could not load DMA map for RxD ring.\n");
return (error);
}
sc->dma_rxd_busaddr = busaddr + 120;
sc->rxd_base = (ae_rxd_t *)(sc->rxd_base_dma + 120);
sc->dma_rxd_busaddr = busaddr + AE_RXD_PADDING;
sc->rxd_base = (ae_rxd_t *)(sc->rxd_base_dma + AE_RXD_PADDING);
return (0);
}
@@ -1885,7 +1885,7 @@ ae_tx_intr(ae_softc_t *sc)
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
}
static int
static void
ae_rxeof(ae_softc_t *sc, ae_rxd_t *rxd)
{
struct ifnet *ifp;
@@ -1904,12 +1904,15 @@ ae_rxeof(ae_softc_t *sc, ae_rxd_t *rxd)
size = le16toh(rxd->len) - ETHER_CRC_LEN;
if (size < (ETHER_MIN_LEN - ETHER_CRC_LEN - ETHER_VLAN_ENCAP_LEN)) {
if_printf(ifp, "Runt frame received.");
return (EIO);
ifp->if_ierrors++;
return;
}
m = m_devget(&rxd->data[0], size, ETHER_ALIGN, ifp, NULL);
if (m == NULL)
return (ENOBUFS);
if (m == NULL) {
ifp->if_iqdrops++;
return;
}
if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 &&
(flags & AE_RXD_HAS_VLAN) != 0) {
@@ -1917,14 +1920,13 @@ ae_rxeof(ae_softc_t *sc, ae_rxd_t *rxd)
m->m_flags |= M_VLANTAG;
}
ifp->if_ipackets++;
/*
* Pass it through.
*/
AE_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
AE_LOCK(sc);
return (0);
}
static void
@@ -1933,7 +1935,7 @@ ae_rx_intr(ae_softc_t *sc)
ae_rxd_t *rxd;
struct ifnet *ifp;
uint16_t flags;
int count, error;
int count;
KASSERT(sc != NULL, ("[ae, %d]: sc is NULL!", __LINE__));
@@ -1961,17 +1963,10 @@ ae_rx_intr(ae_softc_t *sc)
*/
sc->rxd_cur = (sc->rxd_cur + 1) % AE_RXD_COUNT_DEFAULT;
if ((flags & AE_RXD_SUCCESS) == 0) {
if ((flags & AE_RXD_SUCCESS) != 0)
ae_rxeof(sc, rxd);
else
ifp->if_ierrors++;
continue;
}
error = ae_rxeof(sc, rxd);
if (error != 0) {
ifp->if_ierrors++;
continue;
} else {
ifp->if_ipackets++;
}
}
if (count > 0) {
@@ -104,6 +104,8 @@
#define AE_RXD_COUNT_MIN 16
#define AE_RXD_COUNT_MAX 512
#define AE_RXD_COUNT_DEFAULT 64
/* Padding to align frames on a 128-byte boundary. */
#define AE_RXD_PADDING 120
#define AE_TXD_BUFSIZE_MIN 4096
#define AE_TXD_BUFSIZE_MAX 65536
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 2006-2010 Broadcom Corporation
* David Christensen <davidch@broadcom.com>. All rights reserved.
* Copyright (c) 2006-2014 QLogic Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,9 +9,6 @@
* 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.
* 3. Neither the name of Broadcom Corporation nor the name of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written consent.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -6355,8 +6351,8 @@ struct fw_info {
#define BCE_TX_TIMEOUT 5
#define BCE_MAX_SEGMENTS 32
#define BCE_TSO_MAX_SIZE 65536
#define BCE_MAX_SEGMENTS 35
#define BCE_TSO_MAX_SIZE (65535 + sizeof(struct ether_vlan_header))
#define BCE_TSO_MAX_SEG_SIZE 4096
#define BCE_DMA_ALIGN 8
@@ -176,6 +176,8 @@ static const struct bge_type {
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5721 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5722 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5723 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5725 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5727 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5750 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5750M },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5751 },
@@ -195,6 +197,7 @@ static const struct bge_type {
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5761E },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5761S },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5761SE },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5762 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5764 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5780 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5780S },
@@ -217,11 +220,16 @@ static const struct bge_type {
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57760 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57761 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57762 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57764 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57765 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57766 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57767 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57780 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57781 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57782 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57785 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57786 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57787 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57788 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57790 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM57791 },
@@ -310,6 +318,7 @@ static const struct bge_revision {
{ BGE_CHIPID_BCM5722_A0, "BCM5722 A0" },
{ BGE_CHIPID_BCM5761_A0, "BCM5761 A0" },
{ BGE_CHIPID_BCM5761_A1, "BCM5761 A1" },
{ BGE_CHIPID_BCM5762_A0, "BCM5762 A0" },
{ BGE_CHIPID_BCM5784_A0, "BCM5784 A0" },
{ BGE_CHIPID_BCM5784_A1, "BCM5784 A1" },
/* 5754 and 5787 share the same ASIC ID */
@@ -354,6 +363,7 @@ static const struct bge_revision bge_majorrevs[] = {
{ BGE_ASICREV_BCM5717, "unknown BCM5717" },
{ BGE_ASICREV_BCM5719, "unknown BCM5719" },
{ BGE_ASICREV_BCM5720, "unknown BCM5720" },
{ BGE_ASICREV_BCM5762, "unknown BCM5762" },
{ 0, NULL }
};
@@ -1802,6 +1812,20 @@ bge_chipinit(struct bge_softc *sc)
pci_write_config(sc->bge_dev, BGE_PCI_MSI_DATA + 2, val, 2);
}
if (sc->bge_asicrev == BGE_ASICREV_BCM57765 ||
sc->bge_asicrev == BGE_ASICREV_BCM57766) {
/*
* For the 57766 and non Ax versions of 57765, bootcode
* needs to setup the PCIE Fast Training Sequence (FTS)
* value to prevent transmit hangs.
*/
if (sc->bge_chiprev != BGE_CHIPREV_57765_AX) {
CSR_WRITE_4(sc, BGE_CPMU_PADRNG_CTL,
CSR_READ_4(sc, BGE_CPMU_PADRNG_CTL) |
BGE_CPMU_PADRNG_CTL_RDIV2);
}
}
/*
* Set up the PCI DMA control register.
*/
@@ -1877,8 +1901,9 @@ bge_chipinit(struct bge_softc *sc)
* a status tag update and leave interrupts permanently
* disabled.
*/
if (sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
sc->bge_asicrev != BGE_ASICREV_BCM57765)
if (!BGE_IS_57765_PLUS(sc) &&
sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
sc->bge_asicrev != BGE_ASICREV_BCM5762)
dma_rw_ctl |= BGE_PCIDMARWCTL_TAGGED_STATUS_WA;
}
pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4);
@@ -1887,7 +1912,8 @@ bge_chipinit(struct bge_softc *sc)
* Set up general mode register.
*/
mode_ctl = bge_dma_swap_options(sc);
if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5720 ||
sc->bge_asicrev == BGE_ASICREV_BCM5762) {
/* Retain Host-2-BMC settings written by APE firmware. */
mode_ctl |= CSR_READ_4(sc, BGE_MODE_CTL) &
(BGE_MODECTL_BYTESWAP_B2HRX_DATA |
@@ -1945,7 +1971,7 @@ bge_blockinit(struct bge_softc *sc)
struct bge_rcb *rcb;
bus_size_t vrcb;
bge_hostaddr taddr;
uint32_t dmactl, val;
uint32_t dmactl, rdmareg, val;
int i, limit;
/*
@@ -2216,6 +2242,11 @@ bge_blockinit(struct bge_softc *sc)
if (!BGE_IS_5705_PLUS(sc))
/* 5700 to 5704 had 16 send rings. */
limit = BGE_TX_RINGS_EXTSSRAM_MAX;
else if (BGE_IS_57765_PLUS(sc) ||
sc->bge_asicrev == BGE_ASICREV_BCM5762)
limit = 2;
else if (BGE_IS_5717_PLUS(sc))
limit = 4;
else
limit = 1;
vrcb = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
@@ -2254,6 +2285,7 @@ bge_blockinit(struct bge_softc *sc)
} else if (!BGE_IS_5705_PLUS(sc))
limit = BGE_RX_RINGS_MAX;
else if (sc->bge_asicrev == BGE_ASICREV_BCM5755 ||
sc->bge_asicrev == BGE_ASICREV_BCM5762 ||
BGE_IS_57765_PLUS(sc))
limit = 4;
else
@@ -2293,7 +2325,8 @@ bge_blockinit(struct bge_softc *sc)
/* Set inter-packet gap */
val = 0x2620;
if (sc->bge_asicrev == BGE_ASICREV_BCM5720)
if (sc->bge_asicrev == BGE_ASICREV_BCM5720 ||
sc->bge_asicrev == BGE_ASICREV_BCM5762)
val |= CSR_READ_4(sc, BGE_TX_LENGTHS) &
(BGE_TXLEN_JMB_FRM_LEN_MSK | BGE_TXLEN_CNT_DN_VAL_MSK);
CSR_WRITE_4(sc, BGE_TX_LENGTHS, val);
@@ -2457,7 +2490,8 @@ bge_blockinit(struct bge_softc *sc)
val |= BGE_RDMAMODE_TSO6_ENABLE;
}
if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5720 ||
sc->bge_asicrev == BGE_ASICREV_BCM5762) {
val |= CSR_READ_4(sc, BGE_RDMA_MODE) &
BGE_RDMAMODE_H2BNC_VLAN_DET;
/*
@@ -2471,14 +2505,18 @@ bge_blockinit(struct bge_softc *sc)
sc->bge_asicrev == BGE_ASICREV_BCM5784 ||
sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
sc->bge_asicrev == BGE_ASICREV_BCM57780 ||
BGE_IS_5717_PLUS(sc)) {
dmactl = CSR_READ_4(sc, BGE_RDMA_RSRVCTRL);
BGE_IS_5717_PLUS(sc) || BGE_IS_57765_PLUS(sc)) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5762)
rdmareg = BGE_RDMA_RSRVCTRL_REG2;
else
rdmareg = BGE_RDMA_RSRVCTRL;
dmactl = CSR_READ_4(sc, rdmareg);
/*
* Adjust tx margin to prevent TX data corruption and
* fix internal FIFO overflow.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
if (sc->bge_chipid == BGE_CHIPID_BCM5719_A0 ||
sc->bge_asicrev == BGE_ASICREV_BCM5762) {
dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK |
BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK |
BGE_RDMA_RSRVCTRL_TXMRGN_MASK);
@@ -2491,7 +2529,7 @@ bge_blockinit(struct bge_softc *sc)
* The fix is to limit the number of RX BDs
* the hardware would fetch at a fime.
*/
CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL, dmactl |
CSR_WRITE_4(sc, rdmareg, dmactl |
BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
}
@@ -2509,11 +2547,34 @@ bge_blockinit(struct bge_softc *sc)
CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
} else if (sc->bge_asicrev == BGE_ASICREV_BCM5762) {
CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL_REG2,
CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL_REG2) |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
}
CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
DELAY(40);
if (sc->bge_flags & BGE_FLAG_RDMA_BUG) {
for (i = 0; i < BGE_NUM_RDMA_CHANNELS / 2; i++) {
val = CSR_READ_4(sc, BGE_RDMA_LENGTH + i * 4);
if ((val & 0xFFFF) > BGE_FRAMELEN)
break;
if (((val >> 16) & 0xFFFF) > BGE_FRAMELEN)
break;
}
if (i != BGE_NUM_RDMA_CHANNELS / 2) {
val = CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL);
if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
val |= BGE_RDMA_TX_LENGTH_WA_5719;
else
val |= BGE_RDMA_TX_LENGTH_WA_5720;
CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL, val);
}
}
/* Turn on RX data completion state machine */
CSR_WRITE_4(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
@@ -2640,6 +2701,12 @@ bge_chipid(device_t dev)
case BCOM_DEVICEID_BCM5718:
case BCOM_DEVICEID_BCM5719:
case BCOM_DEVICEID_BCM5720:
case BCOM_DEVICEID_BCM5725:
case BCOM_DEVICEID_BCM5727:
case BCOM_DEVICEID_BCM5762:
case BCOM_DEVICEID_BCM57764:
case BCOM_DEVICEID_BCM57767:
case BCOM_DEVICEID_BCM57787:
id = pci_read_config(dev,
BGE_PCI_GEN2_PRODID_ASICREV, 4);
break;
@@ -2648,7 +2715,9 @@ bge_chipid(device_t dev)
case BCOM_DEVICEID_BCM57765:
case BCOM_DEVICEID_BCM57766:
case BCOM_DEVICEID_BCM57781:
case BCOM_DEVICEID_BCM57782:
case BCOM_DEVICEID_BCM57785:
case BCOM_DEVICEID_BCM57786:
case BCOM_DEVICEID_BCM57791:
case BCOM_DEVICEID_BCM57795:
id = pci_read_config(dev,
@@ -3271,7 +3340,7 @@ bge_attach(device_t dev)
struct bge_softc *sc;
uint32_t hwcfg = 0, misccfg, pcistate;
u_char eaddr[ETHER_ADDR_LEN];
int capmask, error, msicount, reg, rid, trys;
int capmask, error, reg, rid, trys;
sc = device_get_softc(dev);
sc->bge_dev = dev;
@@ -3280,11 +3349,11 @@ bge_attach(device_t dev)
TASK_INIT(&sc->bge_intr_task, 0, bge_intr_task, sc);
callout_init_mtx(&sc->bge_stat_ch, &sc->bge_mtx, 0);
/*
* Map control/status registers.
*/
pci_enable_busmaster(dev);
/*
* Allocate control/status registers.
*/
rid = PCIR_BAR(0);
sc->bge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
@@ -3348,6 +3417,7 @@ bge_attach(device_t dev)
/* Save chipset family. */
switch (sc->bge_asicrev) {
case BGE_ASICREV_BCM5762:
case BGE_ASICREV_BCM57765:
case BGE_ASICREV_BCM57766:
sc->bge_flags |= BGE_FLAG_57765_PLUS;
@@ -3358,10 +3428,18 @@ bge_attach(device_t dev)
sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS |
BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO |
BGE_FLAG_JUMBO_FRAME;
if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
/* Jumbo frame on BCM5719 A0 does not work. */
sc->bge_flags &= ~BGE_FLAG_JUMBO;
if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
sc->bge_asicrev == BGE_ASICREV_BCM5720) {
/*
* Enable work around for DMA engine miscalculation
* of TXMBUF available space.
*/
sc->bge_flags |= BGE_FLAG_RDMA_BUG;
if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
/* Jumbo frame on BCM5719 A0 does not work. */
sc->bge_flags &= ~BGE_FLAG_JUMBO;
}
}
break;
case BGE_ASICREV_BCM5755:
@@ -3400,6 +3478,7 @@ bge_attach(device_t dev)
case BGE_ASICREV_BCM5719:
case BGE_ASICREV_BCM5720:
case BGE_ASICREV_BCM5761:
case BGE_ASICREV_BCM5762:
sc->bge_flags |= BGE_FLAG_APE;
break;
}
@@ -3584,13 +3663,8 @@ bge_attach(device_t dev)
rid = 0;
if (pci_find_cap(sc->bge_dev, PCIY_MSI, &reg) == 0) {
sc->bge_msicap = reg;
if (bge_can_use_msi(sc)) {
msicount = pci_msi_count(dev);
if (msicount > 1)
msicount = 1;
} else
msicount = 0;
if (msicount == 1 && pci_alloc_msi(dev, &msicount) == 0) {
reg = 1;
if (bge_can_use_msi(sc) && pci_alloc_msi(dev, &reg) == 0) {
rid = 1;
sc->bge_flags |= BGE_FLAG_MSI;
}
@@ -3607,7 +3681,7 @@ bge_attach(device_t dev)
#endif
sc->bge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
RF_ACTIVE | (rid != 0 ? 0 : RF_SHAREABLE));
if (sc->bge_irq == NULL) {
device_printf(sc->bge_dev, "couldn't map interrupt\n");
@@ -3950,20 +4024,19 @@ bge_release_resources(struct bge_softc *sc)
if (sc->bge_intrhand != NULL)
bus_teardown_intr(dev, sc->bge_irq, sc->bge_intrhand);
if (sc->bge_irq != NULL)
if (sc->bge_irq != NULL) {
bus_release_resource(dev, SYS_RES_IRQ,
sc->bge_flags & BGE_FLAG_MSI ? 1 : 0, sc->bge_irq);
if (sc->bge_flags & BGE_FLAG_MSI)
rman_get_rid(sc->bge_irq), sc->bge_irq);
pci_release_msi(dev);
}
if (sc->bge_res != NULL)
bus_release_resource(dev, SYS_RES_MEMORY,
PCIR_BAR(0), sc->bge_res);
rman_get_rid(sc->bge_res), sc->bge_res);
if (sc->bge_res2 != NULL)
bus_release_resource(dev, SYS_RES_MEMORY,
PCIR_BAR(2), sc->bge_res2);
rman_get_rid(sc->bge_res2), sc->bge_res2);
if (sc->bge_ifp != NULL)
if_free(sc->bge_ifp);
@@ -4779,6 +4852,7 @@ bge_stats_update_regs(struct bge_softc *sc)
{
struct ifnet *ifp;
struct bge_mac_stats *stats;
uint32_t val;
ifp = sc->bge_ifp;
stats = &sc->bge_mac_stats;
@@ -4879,6 +4953,24 @@ bge_stats_update_regs(struct bge_softc *sc)
ifp->if_collisions = (u_long)stats->etherStatsCollisions;
ifp->if_ierrors = (u_long)(stats->NoMoreRxBDs + stats->InputDiscards +
stats->InputErrors);
if (sc->bge_flags & BGE_FLAG_RDMA_BUG) {
/*
* If controller transmitted more than BGE_NUM_RDMA_CHANNELS
* frames, it's safe to disable workaround for DMA engine's
* miscalculation of TXMBUF space.
*/
if (stats->ifHCOutUcastPkts + stats->ifHCOutMulticastPkts +
stats->ifHCOutBroadcastPkts > BGE_NUM_RDMA_CHANNELS) {
val = CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL);
if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
val &= ~BGE_RDMA_TX_LENGTH_WA_5719;
else
val &= ~BGE_RDMA_TX_LENGTH_WA_5720;
CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL, val);
sc->bge_flags &= ~BGE_FLAG_RDMA_BUG;
}
}
}
static void
@@ -5208,17 +5300,51 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
csum_flags |= BGE_TXBDFLAG_VLAN_TAG;
vlan_tag = m->m_pkthdr.ether_vtag;
}
for (i = 0; ; i++) {
d = &sc->bge_ldata.bge_tx_ring[idx];
d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr);
d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr);
d->bge_len = segs[i].ds_len;
d->bge_flags = csum_flags;
d->bge_vlan_tag = vlan_tag;
d->bge_mss = mss;
if (i == nsegs - 1)
break;
BGE_INC(idx, BGE_TX_RING_CNT);
if (sc->bge_asicrev == BGE_ASICREV_BCM5762 &&
(m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
/*
* 5725 family of devices corrupts TSO packets when TSO DMA
* buffers cross into regions which are within MSS bytes of
* a 4GB boundary. If we encounter the condition, drop the
* packet.
*/
for (i = 0; ; i++) {
d = &sc->bge_ldata.bge_tx_ring[idx];
d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr);
d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr);
d->bge_len = segs[i].ds_len;
if (d->bge_addr.bge_addr_lo + segs[i].ds_len + mss <
d->bge_addr.bge_addr_lo)
break;
d->bge_flags = csum_flags;
d->bge_vlan_tag = vlan_tag;
d->bge_mss = mss;
if (i == nsegs - 1)
break;
BGE_INC(idx, BGE_TX_RING_CNT);
}
if (i != nsegs - 1) {
bus_dmamap_sync(sc->bge_cdata.bge_tx_mtag, map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, map);
m_freem(*m_head);
*m_head = NULL;
return (EIO);
}
} else {
for (i = 0; ; i++) {
d = &sc->bge_ldata.bge_tx_ring[idx];
d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr);
d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr);
d->bge_len = segs[i].ds_len;
d->bge_flags = csum_flags;
d->bge_vlan_tag = vlan_tag;
d->bge_mss = mss;
if (i == nsegs - 1)
break;
BGE_INC(idx, BGE_TX_RING_CNT);
}
}
/* Mark the last segment as end of packet... */
@@ -5445,7 +5571,8 @@ bge_init_locked(struct bge_softc *sc)
mode = CSR_READ_4(sc, BGE_TX_MODE);
if (BGE_IS_5755_PLUS(sc) || sc->bge_asicrev == BGE_ASICREV_BCM5906)
mode |= BGE_TXMODE_MBUF_LOCKUP_FIX;
if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5720 ||
sc->bge_asicrev == BGE_ASICREV_BCM5762) {
mode &= ~(BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
mode |= CSR_READ_4(sc, BGE_TX_MODE) &
(BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
@@ -331,6 +331,7 @@
#define BGE_CHIPID_BCM5717_B0 0x05717100
#define BGE_CHIPID_BCM5719_A0 0x05719000
#define BGE_CHIPID_BCM5720_A0 0x05720000
#define BGE_CHIPID_BCM5762_A0 0x05762000
#define BGE_CHIPID_BCM57765_A0 0x57785000
#define BGE_CHIPID_BCM57765_B0 0x57785100
@@ -357,6 +358,7 @@
#define BGE_ASICREV_BCM5719 0x5719
#define BGE_ASICREV_BCM5720 0x5720
#define BGE_ASICREV_BCM5761 0x5761
#define BGE_ASICREV_BCM5762 0x5762
#define BGE_ASICREV_BCM5784 0x5784
#define BGE_ASICREV_BCM5785 0x5785
#define BGE_ASICREV_BCM57765 0x57785
@@ -378,6 +380,7 @@
#define BGE_CHIPREV_5717_AX 0x57170
#define BGE_CHIPREV_5717_BX 0x57171
#define BGE_CHIPREV_5761_AX 0x57611
#define BGE_CHIPREV_57765_AX 0x577850
#define BGE_CHIPREV_5784_AX 0x57841
/* PCI DMA Read/Write Control register */
@@ -1289,6 +1292,7 @@
#define BGE_CPMU_MUTEX_REQ 0x365C
#define BGE_CPMU_MUTEX_GNT 0x3660
#define BGE_CPMU_PHY_STRAP 0x3664
#define BGE_CPMU_PADRNG_CTL 0x3668
/* Central Power Management Unit (CPMU) register */
#define BGE_CPMU_CTRL_LINK_IDLE_MODE 0x00000200
@@ -1328,6 +1332,9 @@
/* CPMU GPHY Strap register */
#define BGE_CPMU_PHY_STRAP_IS_SERDES 0x00000020
/* CPMU Padring Control register */
#define BGE_CPMU_PADRNG_CTL_RDIV2 0x00040000
/*
* Mbuf Cluster Free registers (has nothing to do with BSD mbufs)
*/
@@ -1539,6 +1546,8 @@
*/
#define BGE_RDMA_MODE 0x4800
#define BGE_RDMA_STATUS 0x4804
#define BGE_RDMA_RSRVCTRL_REG2 0x4890
#define BGE_RDMA_LSO_CRPTEN_CTRL_REG2 0x48A0
#define BGE_RDMA_RSRVCTRL 0x4900
#define BGE_RDMA_LSO_CRPTEN_CTRL 0x4910
@@ -1586,6 +1595,8 @@
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 0x00020000
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K 0x00030000
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K 0x000C0000
#define BGE_RDMA_TX_LENGTH_WA_5719 0x02000000
#define BGE_RDMA_TX_LENGTH_WA_5720 0x00200000
/* BD Read DMA Mode register */
#define BGE_RDMA_BD_MODE 0x4A00
@@ -1603,6 +1614,9 @@
#define BGE_RDMA_NON_LSO_MODE_RESET 0x00000001
#define BGE_RDMA_NON_LSO_MODE_ENABLE 0x00000002
#define BGE_RDMA_LENGTH 0x4BE0
#define BGE_NUM_RDMA_CHANNELS 4
/*
* Write DMA control registers
*/
@@ -2444,6 +2458,8 @@ struct bge_status_block {
#define BCOM_DEVICEID_BCM5721 0x1659
#define BCOM_DEVICEID_BCM5722 0x165A
#define BCOM_DEVICEID_BCM5723 0x165B
#define BCOM_DEVICEID_BCM5725 0x1643
#define BCOM_DEVICEID_BCM5727 0x16F3
#define BCOM_DEVICEID_BCM5750 0x1676
#define BCOM_DEVICEID_BCM5750M 0x167C
#define BCOM_DEVICEID_BCM5751 0x1677
@@ -2463,6 +2479,7 @@ struct bge_status_block {
#define BCOM_DEVICEID_BCM5761E 0x1680
#define BCOM_DEVICEID_BCM5761S 0x1688
#define BCOM_DEVICEID_BCM5761SE 0x1689
#define BCOM_DEVICEID_BCM5762 0x1687
#define BCOM_DEVICEID_BCM5764 0x1684
#define BCOM_DEVICEID_BCM5780 0x166A
#define BCOM_DEVICEID_BCM5780S 0x166B
@@ -2485,11 +2502,16 @@ struct bge_status_block {
#define BCOM_DEVICEID_BCM57760 0x1690
#define BCOM_DEVICEID_BCM57761 0x16B0
#define BCOM_DEVICEID_BCM57762 0x1682
#define BCOM_DEVICEID_BCM57764 0x1642
#define BCOM_DEVICEID_BCM57765 0x16B4
#define BCOM_DEVICEID_BCM57766 0x1686
#define BCOM_DEVICEID_BCM57767 0x1683
#define BCOM_DEVICEID_BCM57780 0x1692
#define BCOM_DEVICEID_BCM57781 0x16B1
#define BCOM_DEVICEID_BCM57782 0x16B7
#define BCOM_DEVICEID_BCM57785 0x16B5
#define BCOM_DEVICEID_BCM57786 0x16B3
#define BCOM_DEVICEID_BCM57787 0x1641
#define BCOM_DEVICEID_BCM57788 0x1691
#define BCOM_DEVICEID_BCM57790 0x1694
#define BCOM_DEVICEID_BCM57791 0x16B2
@@ -2829,7 +2851,7 @@ struct bge_gib {
*/
#define BGE_NSEG_JUMBO 4
#define BGE_NSEG_NEW 32
#define BGE_NSEG_NEW 35
#define BGE_TSOSEG_SZ 4096
/* Maximum DMA address for controllers that have 40bit DMA address bug. */
@@ -2982,6 +3004,7 @@ struct bge_softc {
#define BGE_FLAG_SHORT_DMA_BUG 0x08000000
#define BGE_FLAG_4K_RDMA_BUG 0x10000000
#define BGE_FLAG_MBOX_REORDER 0x20000000
#define BGE_FLAG_RDMA_BUG 0x40000000
uint32_t bge_mfw_flags; /* Management F/W flags */
#define BGE_MFW_ON_RXCPU 0x00000001
#define BGE_MFW_ON_APE 0x00000002
@@ -147,6 +147,7 @@ static const struct mii_phydesc brgphys[] = {
MII_PHY_DESC(BROADCOM3, BCM5720C),
MII_PHY_DESC(BROADCOM3, BCM57765),
MII_PHY_DESC(BROADCOM3, BCM57780),
MII_PHY_DESC(BROADCOM4, BCM5725C),
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906),
MII_PHY_END
};
@@ -932,6 +933,8 @@ brgphy_reset(struct mii_softc *sc)
return;
}
break;
case MII_OUI_BROADCOM4:
return;
}
ifp = sc->mii_pdata->mii_ifp;
@@ -250,7 +250,7 @@ struct fxp_cb_ucode {
/*
* Number of DMA segments in a TxCB.
*/
#define FXP_NTXSEG 32
#define FXP_NTXSEG 35
struct fxp_tbd {
uint32_t tb_addr;
@@ -129,7 +129,7 @@
#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
#define E1000_RXDEXT_STATERR_TST 0x00000100 /* Time Stamp taken */
#define E1000_RXDEXT_STATERR_TST 0x00010000 /* Time Stamp taken */
#define E1000_RXDEXT_STATERR_LB 0x00040000
#define E1000_RXDEXT_STATERR_CE 0x01000000
#define E1000_RXDEXT_STATERR_SE 0x02000000
@@ -3865,8 +3865,7 @@ em_txeof(struct tx_ring *txr)
EM_TX_LOCK_ASSERT(txr);
#ifdef DEV_NETMAP
if (netmap_tx_irq(ifp, txr->me |
(NETMAP_LOCKED_ENTER | NETMAP_LOCKED_EXIT)))
if (netmap_tx_irq(ifp, txr->me))
return;
#endif /* DEV_NETMAP */
@@ -4399,7 +4398,7 @@ em_initialize_receive_unit(struct adapter *adapter)
* preserve the rx buffers passed to userspace.
*/
if (ifp->if_capenable & IFCAP_NETMAP)
rdt -= NA(adapter->ifp)->rx_rings[i].nr_hwavail;
rdt -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[i]);
#endif /* DEV_NETMAP */
E1000_WRITE_REG(hw, E1000_RDT(i), rdt);
}
@@ -4478,8 +4477,10 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
EM_RX_LOCK(rxr);
#ifdef DEV_NETMAP
if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed))
if (netmap_rx_irq(ifp, rxr->me, &processed)) {
EM_RX_UNLOCK(rxr);
return (FALSE);
}
#endif /* DEV_NETMAP */
for (i = rxr->next_to_check, processed = 0; count != 0;) {
@@ -2883,6 +2883,9 @@ igb_setup_msix(struct adapter *adapter)
if (queues > maxqueues)
queues = maxqueues;
/* reflect correct sysctl value */
igb_num_queues = queues;
/*
** One vector (RX/TX pair) per queue
** plus an additional for Link interrupt
@@ -3907,8 +3910,7 @@ igb_txeof(struct tx_ring *txr)
IGB_TX_LOCK_ASSERT(txr);
#ifdef DEV_NETMAP
if (netmap_tx_irq(ifp, txr->me |
(NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
if (netmap_tx_irq(ifp, txr->me ))
return (FALSE);
#endif /* DEV_NETMAP */
if (txr->tx_avail == adapter->num_tx_desc) {
@@ -4569,13 +4571,13 @@ igb_initialize_receive_units(struct adapter *adapter)
* an init() while a netmap client is active must
* preserve the rx buffers passed to userspace.
* In this driver it means we adjust RDT to
* somthing different from next_to_refresh
* something different from next_to_refresh
* (which is not used in netmap mode).
*/
if (ifp->if_capenable & IFCAP_NETMAP) {
struct netmap_adapter *na = NA(adapter->ifp);
struct netmap_kring *kring = &na->rx_rings[i];
int t = rxr->next_to_refresh - kring->nr_hwavail;
int t = rxr->next_to_refresh - nm_kr_rxspace(kring);
if (t >= adapter->num_rx_desc)
t -= adapter->num_rx_desc;
@@ -4763,8 +4765,10 @@ igb_rxeof(struct igb_queue *que, int count, int *done)
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
#ifdef DEV_NETMAP
if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed))
if (netmap_rx_irq(ifp, rxr->me, &processed)) {
IGB_RX_UNLOCK(rxr);
return (FALSE);
}
#endif /* DEV_NETMAP */
/* Main clean loop */
@@ -2716,7 +2716,7 @@ lem_setup_transmit_structures(struct adapter *adapter)
void *addr;
addr = PNMB(slot + si, &paddr);
adapter->tx_desc_base[si].buffer_addr = htole64(paddr);
adapter->tx_desc_base[i].buffer_addr = htole64(paddr);
/* reload the map for netmap mode */
netmap_load_map(adapter->txtag, tx_buffer->map, addr);
}
@@ -3030,7 +3030,7 @@ lem_txeof(struct adapter *adapter)
EM_TX_LOCK_ASSERT(adapter);
#ifdef DEV_NETMAP
if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
if (netmap_tx_irq(ifp, 0))
return;
#endif /* DEV_NETMAP */
if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
@@ -3413,7 +3413,7 @@ lem_initialize_receive_unit(struct adapter *adapter)
#ifdef DEV_NETMAP
/* preserve buffers already made available to clients */
if (ifp->if_capenable & IFCAP_NETMAP)
rctl -= NA(adapter->ifp)->rx_rings[0].nr_hwavail;
rctl -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[0]);
#endif /* DEV_NETMAP */
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), rctl);
@@ -3499,8 +3499,10 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
BUS_DMASYNC_POSTREAD);
#ifdef DEV_NETMAP
if (netmap_rx_irq(ifp, 0 | NETMAP_LOCKED_ENTER, &rx_sent))
if (netmap_rx_irq(ifp, 0, &rx_sent)) {
EM_RX_UNLOCK(adapter);
return (FALSE);
}
#endif /* DEV_NETMAP */
if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
@@ -49,7 +49,7 @@
#define JME_RX_RING_ALIGN 16
#define JME_TSO_MAXSEGSIZE 4096
#define JME_TSO_MAXSIZE (65535 + sizeof(struct ether_vlan_header))
#define JME_MAXTXSEGS 32
#define JME_MAXTXSEGS 35
#define JME_RX_BUF_ALIGN sizeof(uint64_t)
#define JME_SSB_ALIGN 16
@@ -4078,12 +4078,12 @@ msk_init_locked(struct msk_if_softc *sc_if)
CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask);
CSR_READ_4(sc, B0_IMSK);
sc_if->msk_flags &= ~MSK_FLAG_LINK;
mii_mediachg(mii);
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
sc_if->msk_flags &= ~MSK_FLAG_LINK;
mii_mediachg(mii);
callout_reset(&sc_if->msk_tick_ch, hz, msk_tick, sc_if);
}
@@ -2338,7 +2338,7 @@ struct msk_stat_desc {
#endif
#define MSK_RX_BUF_ALIGN 8
#define MSK_JUMBO_RX_RING_CNT MSK_RX_RING_CNT
#define MSK_MAXTXSEGS 32
#define MSK_MAXTXSEGS 35
#define MSK_TSO_MAXSGSIZE 4096
#define MSK_TSO_MAXSIZE (65535 + sizeof(struct ether_vlan_header))
@@ -78,6 +78,7 @@ static int nfe_suspend(device_t);
static int nfe_resume(device_t);
static int nfe_shutdown(device_t);
static int nfe_can_use_msix(struct nfe_softc *);
static int nfe_detect_msik9(struct nfe_softc *);
static void nfe_power(struct nfe_softc *);
static int nfe_miibus_readreg(device_t, int, int);
static int nfe_miibus_writereg(device_t, int, int, int);
@@ -333,13 +334,38 @@ nfe_alloc_msix(struct nfe_softc *sc, int count)
}
}
static int
nfe_detect_msik9(struct nfe_softc *sc)
{
static const char *maker = "MSI";
static const char *product = "K9N6PGM2-V2 (MS-7309)";
char *m, *p;
int found;
found = 0;
m = getenv("smbios.planar.maker");
p = getenv("smbios.planar.product");
if (m != NULL && p != NULL) {
if (strcmp(m, maker) == 0 && strcmp(p, product) == 0)
found = 1;
}
if (m != NULL)
freeenv(m);
if (p != NULL)
freeenv(p);
return (found);
}
static int
nfe_attach(device_t dev)
{
struct nfe_softc *sc;
struct ifnet *ifp;
bus_addr_t dma_addr_max;
int error = 0, i, msic, reg, rid;
int error = 0, i, msic, phyloc, reg, rid;
sc = device_get_softc(dev);
sc->nfe_dev = dev;
@@ -608,8 +634,16 @@ nfe_attach(device_t dev)
#endif
/* Do MII setup */
phyloc = MII_PHY_ANY;
if (sc->nfe_devid == PCI_PRODUCT_NVIDIA_MCP61_LAN1 ||
sc->nfe_devid == PCI_PRODUCT_NVIDIA_MCP61_LAN2 ||
sc->nfe_devid == PCI_PRODUCT_NVIDIA_MCP61_LAN3 ||
sc->nfe_devid == PCI_PRODUCT_NVIDIA_MCP61_LAN4) {
if (nfe_detect_msik9(sc) != 0)
phyloc = 0;
}
error = mii_attach(dev, &sc->nfe_miibus, ifp, nfe_ifmedia_upd,
nfe_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY,
nfe_ifmedia_sts, BMSR_DEFCAPMASK, phyloc, MII_OFFSET_ANY,
MIIF_DOPAUSE);
if (error != 0) {
device_printf(dev, "attaching PHYs failed\n");
@@ -1342,15 +1376,12 @@ nfe_free_rx_ring(struct nfe_softc *sc, struct nfe_rx_ring *ring)
{
struct nfe_rx_data *data;
void *desc;
int i, descsize;
int i;
if (sc->nfe_flags & NFE_40BIT_ADDR) {
if (sc->nfe_flags & NFE_40BIT_ADDR)
desc = ring->desc64;
descsize = sizeof (struct nfe_desc64);
} else {
else
desc = ring->desc32;
descsize = sizeof (struct nfe_desc32);
}
for (i = 0; i < NFE_RX_RING_COUNT; i++) {
data = &ring->data[i];
@@ -3206,8 +3237,8 @@ nfe_stats_clear(struct nfe_softc *sc)
else
return;
for (i = 0; i < mib_cnt; i += sizeof(uint32_t))
NFE_READ(sc, NFE_TX_OCTET + i);
for (i = 0; i < mib_cnt; i++)
NFE_READ(sc, NFE_TX_OCTET + i * sizeof(uint32_t));
if ((sc->nfe_flags & NFE_MIB_V3) != 0) {
NFE_READ(sc, NFE_TX_UNICAST);
@@ -3261,7 +3292,7 @@ nfe_stats_update(struct nfe_softc *sc)
if ((sc->nfe_flags & NFE_MIB_V3) != 0) {
stats->tx_unicast += NFE_READ(sc, NFE_TX_UNICAST);
stats->tx_multicast += NFE_READ(sc, NFE_TX_MULTICAST);
stats->rx_broadcast += NFE_READ(sc, NFE_TX_BROADCAST);
stats->tx_broadcast += NFE_READ(sc, NFE_TX_BROADCAST);
}
}
@@ -40,7 +40,7 @@
(NFE_JUMBO_FRAMELEN - NFE_RX_HEADERS)
#define NFE_MIN_FRAMELEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
#define NFE_MAX_SCATTER 32
#define NFE_MAX_SCATTER 35
#define NFE_TSO_MAXSGSIZE 4096
#define NFE_TSO_MAXSIZE (65535 + sizeof(struct ether_vlan_header))
@@ -16,13 +16,6 @@
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -15,13 +15,6 @@
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -15,13 +15,6 @@
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -15,13 +15,6 @@
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -16,13 +16,6 @@
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -16,13 +16,6 @@
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -15,13 +15,6 @@
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -138,11 +138,6 @@ MODULE_DEPEND(sk, miibus, 1, 1, 1);
/* "device miibus" required. See GENERIC if you get errors here. */
#include "miibus_if.h"
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif
static const struct sk_type sk_devs[] = {
{
VENDORID_SK,
@@ -2899,13 +2894,11 @@ static void
sk_txeof(sc_if)
struct sk_if_softc *sc_if;
{
struct sk_softc *sc;
struct sk_txdesc *txd;
struct sk_tx_desc *cur_tx;
struct ifnet *ifp;
u_int32_t idx, sk_ctl;
sc = sc_if->sk_softc;
ifp = sc_if->sk_ifp;
txd = STAILQ_FIRST(&sc_if->sk_cdata.sk_txbusyq);
@@ -357,6 +357,7 @@ an_probe(device_t dev)
CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 0xFFFF);
sc->an_dev = dev;
mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF);
AN_LOCK(sc);
@@ -685,6 +686,9 @@ an_attach(struct an_softc *sc, int flags)
device_printf(sc->an_dev, "can not if_alloc()\n");
goto fail;
}
ifp->if_softc = sc;
if_initname(ifp, device_get_name(sc->an_dev),
device_get_unit(sc->an_dev));
sc->an_gone = 0;
sc->an_associated = 0;
@@ -758,9 +762,6 @@ an_attach(struct an_softc *sc, int flags)
#endif
AN_UNLOCK(sc);
ifp->if_softc = sc;
if_initname(ifp, device_get_name(sc->an_dev),
device_get_unit(sc->an_dev));
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = an_ioctl;
@@ -1388,7 +1389,7 @@ an_reset(struct an_softc *sc)
an_cmd(sc, AN_CMD_NOOP2, 0);
if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT)
if_printf(sc->an_ifp, "reset failed\n");
device_printf(sc->an_dev, "reset failed\n");
an_cmd(sc, AN_CMD_DISABLE, 0);
@@ -141,8 +141,6 @@ an_pccard_attach(device_t dev)
an_alloc_irq(dev, sc->irq_rid, 0);
sc->an_dev = dev;
error = an_attach(sc, flags);
if (error)
goto fail;
@@ -0,0 +1,727 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#ifdef AH_SUPPORT_AR9300
#include "ah.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300phy.h"
#if ATH_SUPPORT_AIC
#define ATH_AIC_TEST_PATTERN 1
struct ath_aic_sram_info {
HAL_BOOL valid;
u_int8_t rot_quad_att_db;
HAL_BOOL vga_quad_sign;
u_int8_t rot_dir_att_db;
HAL_BOOL vga_dir_sign;
u_int8_t com_att_6db;
};
struct ath_aic_out_info {
int16_t dir_path_gain_lin;
int16_t quad_path_gain_lin;
struct ath_aic_sram_info sram;
};
#define ATH_AIC_MAX_COM_ATT_DB_TABLE 6
#define ATH_AIC_MAX_AIC_LIN_TABLE 69
#define ATH_AIC_MIN_ROT_DIR_ATT_DB 0
#define ATH_AIC_MIN_ROT_QUAD_ATT_DB 0
#define ATH_AIC_MAX_ROT_DIR_ATT_DB 37
#define ATH_AIC_MAX_ROT_QUAD_ATT_DB 37
#define ATH_AIC_SRAM_AUTO_INCREMENT 0x80000000
#define ATH_AIC_SRAM_GAIN_TABLE_OFFSET 0x280
#define ATH_AIC_SRAM_CAL_OFFSET 0x140
#define ATH_AIC_MAX_CAL_COUNT 5
#define ATH_AIC_MEAS_MAG_THRESH 20
#define ATH_AIC_BT_JUPITER_CTRL 0x66820
#define ATH_AIC_BT_AIC_ENABLE 0x02
static const u_int8_t com_att_db_table[ATH_AIC_MAX_COM_ATT_DB_TABLE] = {
0, 3, 9, 15, 21, 27};
static const u_int16_t aic_lin_table[ATH_AIC_MAX_AIC_LIN_TABLE] = {
8191, 7300, 6506, 5799, 5168, 4606, 4105, 3659,
3261, 2906, 2590, 2309, 2057, 1834, 1634, 1457,
1298, 1157, 1031, 919, 819, 730, 651, 580,
517, 461, 411, 366, 326, 291, 259, 231,
206, 183, 163, 146, 130, 116, 103, 92,
82, 73, 65, 58, 52, 46, 41, 37,
33, 29, 26, 23, 21, 18, 16, 15,
13, 12, 10, 9, 8, 7, 7, 6,
5, 5, 4, 4, 3};
#if ATH_AIC_TEST_PATTERN
static const u_int32_t aic_test_pattern[ATH_AIC_MAX_BT_CHANNEL] = {
0x00000, // 0
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x1918d,
0x1938d, // 10
0x00000,
0x1978d,
0x19e8d,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000, // 20
0x00000,
0x00000,
0x1ce8f,
0x00000,
0x00000,
0x00000,
0x00000,
0x1ca93,
0x1c995,
0x00000, // 30
0x1c897,
0x1c899,
0x00000,
0x00000,
0x1c79f,
0x00000,
0x1c7a5,
0x1c6ab,
0x00000,
0x00000, // 40
0x00000,
0x00000,
0x1c63f,
0x00000,
0x1c52b,
0x1c525,
0x1c523,
0x00000,
0x00000,
0x00000, // 50
0x00000,
0x00000,
0x1c617,
0x00000,
0x1c615,
0x1c613,
0x00000,
0x00000,
0x00000,
0x00000, // 60
0x1c80f,
0x1c90f,
0x1c90f,
0x1ca0f,
0x1ca0d,
0x1cb0d,
0x00000,
0x00000,
0x00000,
0x00000, // 70
0x1d00d,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000
};
#endif
static void
ar9300_aic_gain_table(struct ath_hal *ah)
{
u_int32_t aic_atten_word[19], i;
/* Program gain table */
aic_atten_word[0] = (0x1 & 0xf)<<14 | (0x1f & 0x1f)<<9 | (0x0 & 0xf)<<5 |
(0x1f & 0x1f); // -01 dB: 4'd1, 5'd31, 00 dB: 4'd0, 5'd31;
aic_atten_word[1] = (0x3 & 0xf)<<14 | (0x1f & 0x1f)<<9 | (0x2 & 0xf)<<5 |
(0x1f & 0x1f); // -03 dB: 4'd3, 5'd31, -02 dB: 4'd2, 5'd31;
aic_atten_word[2] = (0x5 & 0xf)<<14 | (0x1f & 0x1f)<<9 | (0x4 & 0xf)<<5 |
(0x1f & 0x1f); // -05 dB: 4'd5, 5'd31, -04 dB: 4'd4, 5'd31;
aic_atten_word[3] = (0x1 & 0xf)<<14 | (0x1e & 0x1f)<<9 | (0x0 & 0xf)<<5 |
(0x1e & 0x1f); // -07 dB: 4'd1, 5'd30, -06 dB: 4'd0, 5'd30;
aic_atten_word[4] = (0x3 & 0xf)<<14 | (0x1e & 0x1f)<<9 | (0x2 & 0xf)<<5 |
(0x1e & 0x1f); // -09 dB: 4'd3, 5'd30, -08 dB: 4'd2, 5'd30;
aic_atten_word[5] = (0x5 & 0xf)<<14 | (0x1e & 0x1f)<<9 | (0x4 & 0xf)<<5 |
(0x1e & 0x1f); // -11 dB: 4'd5, 5'd30, -10 dB: 4'd4, 5'd30;
aic_atten_word[6] = (0x1 & 0xf)<<14 | (0xf & 0x1f)<<9 | (0x0 & 0xf)<<5 |
(0xf & 0x1f); // -13 dB: 4'd1, 5'd15, -12 dB: 4'd0, 5'd15;
aic_atten_word[7] = (0x3 & 0xf)<<14 | (0xf & 0x1f)<<9 | (0x2 & 0xf)<<5 |
(0xf & 0x1f); // -15 dB: 4'd3, 5'd15, -14 dB: 4'd2, 5'd15;
aic_atten_word[8] = (0x5 & 0xf)<<14 | (0xf & 0x1f)<<9 | (0x4 & 0xf)<<5 |
(0xf & 0x1f); // -17 dB: 4'd5, 5'd15, -16 dB: 4'd4, 5'd15;
aic_atten_word[9] = (0x1 & 0xf)<<14 | (0x7 & 0x1f)<<9 | (0x0 & 0xf)<<5 |
(0x7 & 0x1f); // -19 dB: 4'd1, 5'd07, -18 dB: 4'd0, 5'd07;
aic_atten_word[10] =(0x3 & 0xf)<<14 | (0x7 & 0x1f)<<9 | (0x2 & 0xf)<<5 |
(0x7 & 0x1f); // -21 dB: 4'd3, 5'd07, -20 dB: 4'd2, 5'd07;
aic_atten_word[11] =(0x5 & 0xf)<<14 | (0x7 & 0x1f)<<9 | (0x4 & 0xf)<<5 |
(0x7 & 0x1f); // -23 dB: 4'd5, 5'd07, -22 dB: 4'd4, 5'd07;
aic_atten_word[12] =(0x7 & 0xf)<<14 | (0x7 & 0x1f)<<9 | (0x6 & 0xf)<<5 |
(0x7 & 0x1f); // -25 dB: 4'd7, 5'd07, -24 dB: 4'd6, 5'd07;
aic_atten_word[13] =(0x3 & 0xf)<<14 | (0x3 & 0x1f)<<9 | (0x2 & 0xf)<<5 |
(0x3 & 0x1f); // -27 dB: 4'd3, 5'd03, -26 dB: 4'd2, 5'd03;
aic_atten_word[14] =(0x5 & 0xf)<<14 | (0x3 & 0x1f)<<9 | (0x4 & 0xf)<<5 |
(0x3 & 0x1f); // -29 dB: 4'd5, 5'd03, -28 dB: 4'd4, 5'd03;
aic_atten_word[15] =(0x1 & 0xf)<<14 | (0x1 & 0x1f)<<9 | (0x0 & 0xf)<<5 |
(0x1 & 0x1f); // -31 dB: 4'd1, 5'd01, -30 dB: 4'd0, 5'd01;
aic_atten_word[16] =(0x3 & 0xf)<<14 | (0x1 & 0x1f)<<9 | (0x2 & 0xf)<<5 |
(0x1 & 0x1f); // -33 dB: 4'd3, 5'd01, -32 dB: 4'd2, 5'd01;
aic_atten_word[17] =(0x5 & 0xf)<<14 | (0x1 & 0x1f)<<9 | (0x4 & 0xf)<<5 |
(0x1 & 0x1f); // -35 dB: 4'd5, 5'd01, -34 dB: 4'd4, 5'd01;
aic_atten_word[18] =(0x7 & 0xf)<<14 | (0x1 & 0x1f)<<9 | (0x6 & 0xf)<<5 |
(0x1 & 0x1f); // -37 dB: 4'd7, 5'd01, -36 dB: 4'd6, 5'd01;
/* Write to Gain table with auto increment enabled. */
OS_REG_WRITE(ah, (AR_PHY_AIC_SRAM_ADDR_B0 + 0x3000),
(ATH_AIC_SRAM_AUTO_INCREMENT |
ATH_AIC_SRAM_GAIN_TABLE_OFFSET));
for (i = 0; i < 19; i++) {
OS_REG_WRITE(ah, (AR_PHY_AIC_SRAM_DATA_B0 + 0x3000),
aic_atten_word[i]);
}
}
static int16_t
ar9300_aic_find_valid (struct ath_aic_sram_info *cal_sram,
HAL_BOOL dir,
u_int8_t index)
{
int16_t i;
if (dir) {
/* search forward */
for (i = index + 1; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
if (cal_sram[i].valid) {
break;
}
}
}
else {
/* search backword */
for (i = index - 1; i >= 0; i--) {
if (cal_sram[i].valid) {
break;
}
}
}
if ((i >= ATH_AIC_MAX_BT_CHANNEL) || (i < 0)) {
i = -1;
}
return i;
}
static int16_t
ar9300_aic_find_index (u_int8_t type, int16_t value)
{
int16_t i = -1;
/*
* type 0: aic_lin_table, 1: com_att_db_table
*/
if (type == 0) {
/* Find in aic_lin_table */
for (i = ATH_AIC_MAX_AIC_LIN_TABLE - 1; i >= 0; i--) {
if (aic_lin_table[i] >= value) {
break;
}
}
}
else if (type == 1) {
/* find in com_att_db_table */
for (i = 0; i < ATH_AIC_MAX_COM_ATT_DB_TABLE; i++) {
if (com_att_db_table[i] > value) {
i--;
break;
}
}
if (i >= ATH_AIC_MAX_COM_ATT_DB_TABLE) {
i = -1;
}
}
return i;
}
static HAL_BOOL
ar9300_aic_cal_post_process (struct ath_hal *ah)
{
struct ath_hal_9300 *ahp = AH9300(ah);
struct ath_aic_sram_info cal_sram[ATH_AIC_MAX_BT_CHANNEL];
struct ath_aic_out_info aic_sram[ATH_AIC_MAX_BT_CHANNEL];
u_int32_t dir_path_gain_idx, quad_path_gain_idx, value;
u_int32_t fixed_com_att_db;
int8_t dir_path_sign, quad_path_sign;
int16_t i;
HAL_BOOL ret = AH_TRUE;
/* Read CAL_SRAM and get valid values. */
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) CAL_SRAM:\n");
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1,
(ATH_AIC_SRAM_CAL_OFFSET + i*4));
#if ATH_AIC_TEST_PATTERN
value = aic_test_pattern[i];
#else
value = OS_REG_READ(ah, AR_PHY_AIC_SRAM_DATA_B1);
#endif
cal_sram[i].valid = MS(value, AR_PHY_AIC_SRAM_VALID);
cal_sram[i].rot_quad_att_db = MS(value,
AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB);
cal_sram[i].vga_quad_sign = MS(value, AR_PHY_AIC_SRAM_VGA_QUAD_SIGN);
cal_sram[i].rot_dir_att_db = MS(value, AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB);
cal_sram[i].vga_dir_sign = MS(value, AR_PHY_AIC_SRAM_VGA_DIR_SIGN);
cal_sram[i].com_att_6db = MS(value, AR_PHY_AIC_SRAM_COM_ATT_6DB);
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) %2d %2d %2d %2d %2d %2d %2d 0x%05x\n",
i, cal_sram[i].vga_quad_sign,
cal_sram[i].vga_dir_sign,
cal_sram[i].rot_dir_att_db,
cal_sram[i].rot_quad_att_db,
cal_sram[i].com_att_6db,
cal_sram[i].valid,
value);
if (cal_sram[i].valid) {
dir_path_gain_idx = cal_sram[i].rot_dir_att_db +
com_att_db_table[cal_sram[i].com_att_6db];
quad_path_gain_idx = cal_sram[i].rot_quad_att_db +
com_att_db_table[cal_sram[i].com_att_6db];
dir_path_sign = (cal_sram[i].vga_dir_sign) ? 1 : -1;
quad_path_sign = (cal_sram[i].vga_quad_sign) ? 1 : -1;
aic_sram[i].dir_path_gain_lin = dir_path_sign *
aic_lin_table[dir_path_gain_idx];
aic_sram[i].quad_path_gain_lin = quad_path_sign *
aic_lin_table[quad_path_gain_idx];
}
}
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
int16_t start_idx, end_idx;
if (cal_sram[i].valid) {
continue;
}
start_idx = ar9300_aic_find_valid(cal_sram, 0, i);
end_idx = ar9300_aic_find_valid(cal_sram, 1, i);
if (start_idx < 0)
{
/* extrapolation */
start_idx = end_idx;
end_idx = ar9300_aic_find_valid(cal_sram, 1, start_idx);
if (end_idx < 0) {
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) Error (1): i = %d, start_idx = %d \n",
i, start_idx);
ret = AH_FALSE;
break;
}
aic_sram[i].dir_path_gain_lin =
((aic_sram[start_idx].dir_path_gain_lin -
aic_sram[end_idx].dir_path_gain_lin) *
(start_idx - i) + ((end_idx - i) >> 1)) /
(end_idx - i) +
aic_sram[start_idx].dir_path_gain_lin;
aic_sram[i].quad_path_gain_lin =
((aic_sram[start_idx].quad_path_gain_lin -
aic_sram[end_idx].quad_path_gain_lin) *
(start_idx - i) + ((end_idx - i) >> 1)) /
(end_idx - i) +
aic_sram[start_idx].quad_path_gain_lin;
}
if (end_idx < 0)
{
/* extrapolation */
end_idx = ar9300_aic_find_valid(cal_sram, 0, start_idx);
if (end_idx < 0) {
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) Error (2): i = %d, start_idx = %d\n",
i, start_idx);
ret = AH_FALSE;
break;
}
aic_sram[i].dir_path_gain_lin =
((aic_sram[start_idx].dir_path_gain_lin -
aic_sram[end_idx].dir_path_gain_lin) *
(i - start_idx) + ((start_idx - end_idx) >> 1)) /
(start_idx - end_idx) +
aic_sram[start_idx].dir_path_gain_lin;
aic_sram[i].quad_path_gain_lin =
((aic_sram[start_idx].quad_path_gain_lin -
aic_sram[end_idx].quad_path_gain_lin) *
(i - start_idx) + ((start_idx - end_idx) >> 1)) /
(start_idx - end_idx) +
aic_sram[start_idx].quad_path_gain_lin;
}
else {
/* interpolation */
aic_sram[i].dir_path_gain_lin =
(((end_idx - i) * aic_sram[start_idx].dir_path_gain_lin) +
((i - start_idx) * aic_sram[end_idx].dir_path_gain_lin) +
((end_idx - start_idx) >> 1)) /
(end_idx - start_idx);
aic_sram[i].quad_path_gain_lin =
(((end_idx - i) * aic_sram[start_idx].quad_path_gain_lin) +
((i - start_idx) * aic_sram[end_idx].quad_path_gain_lin) +
((end_idx - start_idx) >> 1))/
(end_idx - start_idx);
}
}
/* From dir/quad_path_gain_lin to sram. */
i = ar9300_aic_find_valid(cal_sram, 1, 0);
if (i < 0) {
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) Error (3): can't find valid. Force it to 0.\n");
i = 0;
ret = AH_FALSE;
}
fixed_com_att_db = com_att_db_table[cal_sram[i].com_att_6db];
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
int16_t rot_dir_path_att_db, rot_quad_path_att_db;
aic_sram[i].sram.vga_dir_sign = (aic_sram[i].dir_path_gain_lin >= 0)
? 1 : 0;
aic_sram[i].sram.vga_quad_sign= (aic_sram[i].quad_path_gain_lin >= 0)
? 1 : 0;
rot_dir_path_att_db =
ar9300_aic_find_index(0, abs(aic_sram[i].dir_path_gain_lin)) -
fixed_com_att_db;
rot_quad_path_att_db =
ar9300_aic_find_index(0, abs(aic_sram[i].quad_path_gain_lin)) -
fixed_com_att_db;
aic_sram[i].sram.com_att_6db = ar9300_aic_find_index(1,
fixed_com_att_db);
aic_sram[i].sram.valid = 1;
aic_sram[i].sram.rot_dir_att_db =
MIN(MAX(rot_dir_path_att_db, ATH_AIC_MIN_ROT_DIR_ATT_DB),
ATH_AIC_MAX_ROT_DIR_ATT_DB);
aic_sram[i].sram.rot_quad_att_db =
MIN(MAX(rot_quad_path_att_db, ATH_AIC_MIN_ROT_QUAD_ATT_DB),
ATH_AIC_MAX_ROT_QUAD_ATT_DB);
}
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Post processing results:\n");
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
ahp->ah_aic_sram[i] = (SM(aic_sram[i].sram.vga_dir_sign,
AR_PHY_AIC_SRAM_VGA_DIR_SIGN) |
SM(aic_sram[i].sram.vga_quad_sign,
AR_PHY_AIC_SRAM_VGA_QUAD_SIGN) |
SM(aic_sram[i].sram.com_att_6db,
AR_PHY_AIC_SRAM_COM_ATT_6DB) |
SM(aic_sram[i].sram.valid,
AR_PHY_AIC_SRAM_VALID) |
SM(aic_sram[i].sram.rot_dir_att_db,
AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB) |
SM(aic_sram[i].sram.rot_quad_att_db,
AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB));
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) ch%02d 0x%05x %2d %2d %2d %2d %2d %2d %d %d\n",
i,
ahp->ah_aic_sram[i],
aic_sram[i].sram.vga_quad_sign,
aic_sram[i].sram.vga_dir_sign,
aic_sram[i].sram.rot_dir_att_db,
aic_sram[i].sram.rot_quad_att_db,
aic_sram[i].sram.com_att_6db,
aic_sram[i].sram.valid,
aic_sram[i].dir_path_gain_lin,
aic_sram[i].quad_path_gain_lin);
}
return ret;
}
u_int32_t
ar9300_aic_calibration(struct ath_hal *ah)
{
u_int32_t aic_ctrl_b0[5], aic_ctrl_b1[5];
u_int32_t aic_stat_b0[2], aic_stat_b1[2];
u_int32_t aic_stat, value;
u_int32_t i, cal_count = ATH_AIC_MAX_CAL_COUNT;
struct ath_hal_9300 *ahp = AH9300(ah);
if (AR_SREV_JUPITER_10(ah)) {
aic_ctrl_b0[0] = AR_PHY_AIC_CTRL_0_B0_10;
aic_ctrl_b0[1] = AR_PHY_AIC_CTRL_1_B0_10;
aic_ctrl_b0[2] = AR_PHY_AIC_CTRL_2_B0_10;
aic_ctrl_b0[3] = AR_PHY_AIC_CTRL_3_B0_10;
aic_ctrl_b1[0] = AR_PHY_AIC_CTRL_0_B1_10;
aic_ctrl_b1[1] = AR_PHY_AIC_CTRL_1_B1_10;
aic_stat_b0[0] = AR_PHY_AIC_STAT_0_B0_10;
aic_stat_b0[1] = AR_PHY_AIC_STAT_1_B0_10;
aic_stat_b1[0] = AR_PHY_AIC_STAT_0_B1_10;
aic_stat_b1[1] = AR_PHY_AIC_STAT_1_B1_10;
}
else {
aic_ctrl_b0[0] = AR_PHY_AIC_CTRL_0_B0_20;
aic_ctrl_b0[1] = AR_PHY_AIC_CTRL_1_B0_20;
aic_ctrl_b0[2] = AR_PHY_AIC_CTRL_2_B0_20;
aic_ctrl_b0[3] = AR_PHY_AIC_CTRL_3_B0_20;
aic_ctrl_b0[4] = AR_PHY_AIC_CTRL_4_B0_20;
aic_ctrl_b1[0] = AR_PHY_AIC_CTRL_0_B1_20;
aic_ctrl_b1[1] = AR_PHY_AIC_CTRL_1_B1_20;
aic_ctrl_b1[4] = AR_PHY_AIC_CTRL_4_B1_20;
aic_stat_b0[0] = AR_PHY_AIC_STAT_0_B0_20;
aic_stat_b0[1] = AR_PHY_AIC_STAT_1_B0_20;
aic_stat_b1[0] = AR_PHY_AIC_STAT_0_B1_20;
aic_stat_b1[1] = AR_PHY_AIC_STAT_1_B1_20;
}
/* Config LNA gain difference */
OS_REG_WRITE(ah, AR_PHY_BT_COEX_4, 0x22180600);
OS_REG_WRITE(ah, AR_PHY_BT_COEX_5, 0x52443a2e);
OS_REG_WRITE(ah, aic_ctrl_b0[0],
(SM(0, AR_PHY_AIC_MON_ENABLE) |
SM(40, AR_PHY_AIC_CAL_MAX_HOP_COUNT) |
SM(1, AR_PHY_AIC_CAL_MIN_VALID_COUNT) | //26
SM(37, AR_PHY_AIC_F_WLAN) |
SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) |
SM(0, AR_PHY_AIC_CAL_ENABLE) |
SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
SM(0, AR_PHY_AIC_ENABLE)));
OS_REG_WRITE(ah, aic_ctrl_b1[0],
(SM(0, AR_PHY_AIC_MON_ENABLE) |
SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) |
SM(0, AR_PHY_AIC_CAL_ENABLE) |
SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
SM(0, AR_PHY_AIC_ENABLE)));
OS_REG_WRITE(ah, aic_ctrl_b0[1],
(SM(8, AR_PHY_AIC_CAL_BT_REF_DELAY) |
SM(6, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) |
SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) |
SM(0, AR_PHY_AIC_BT_IDLE_CFG) |
SM(1, AR_PHY_AIC_STDBY_COND) |
SM(37, AR_PHY_AIC_STDBY_ROT_ATT_DB) |
SM(5, AR_PHY_AIC_STDBY_COM_ATT_DB) |
SM(15, AR_PHY_AIC_RSSI_MAX) |
SM(0, AR_PHY_AIC_RSSI_MIN)));
OS_REG_WRITE(ah, aic_ctrl_b1[1],
(SM(6, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) |
SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) |
SM(15, AR_PHY_AIC_RSSI_MAX) |
SM(0, AR_PHY_AIC_RSSI_MIN)));
OS_REG_WRITE(ah, aic_ctrl_b0[2],
(SM(44, AR_PHY_AIC_RADIO_DELAY) |
SM(7, AR_PHY_AIC_CAL_STEP_SIZE_CORR) |
SM(12, AR_PHY_AIC_CAL_ROT_IDX_CORR) |
SM(2, AR_PHY_AIC_CAL_CONV_CHECK_FACTOR) |
SM(5, AR_PHY_AIC_ROT_IDX_COUNT_MAX) |
SM(1, AR_PHY_AIC_CAL_SYNTH_TOGGLE) |
SM(1, AR_PHY_AIC_CAL_SYNTH_AFTER_BTRX) |
SM(200, AR_PHY_AIC_CAL_SYNTH_SETTLING)));
OS_REG_WRITE(ah, aic_ctrl_b0[3],
(SM(20, AR_PHY_AIC_MON_MAX_HOP_COUNT) |
SM(10, AR_PHY_AIC_MON_MIN_STALE_COUNT) |
SM(1, AR_PHY_AIC_MON_PWR_EST_LONG) |
SM(2, AR_PHY_AIC_MON_PD_TALLY_SCALING) |
SM(18, AR_PHY_AIC_MON_PERF_THR) |
SM(1, AR_PHY_AIC_CAL_COM_ATT_DB_FIXED) |
SM(2, AR_PHY_AIC_CAL_TARGET_MAG_SETTING) |
SM(3, AR_PHY_AIC_CAL_PERF_CHECK_FACTOR) |
SM(1, AR_PHY_AIC_CAL_PWR_EST_LONG)));
ar9300_aic_gain_table(ah);
/* Need to enable AIC reference signal in BT modem. */
OS_REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL,
(OS_REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) |
ATH_AIC_BT_AIC_ENABLE));
while (cal_count)
{
/* Start calibration */
OS_REG_CLR_BIT(ah, aic_ctrl_b1[0], AR_PHY_AIC_CAL_ENABLE);
OS_REG_SET_BIT(ah, aic_ctrl_b1[0], AR_PHY_AIC_CAL_CH_VALID_RESET);
OS_REG_SET_BIT(ah, aic_ctrl_b1[0], AR_PHY_AIC_CAL_ENABLE);
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Start calibration #%d\n",
(ATH_AIC_MAX_CAL_COUNT - cal_count));
/* Wait until calibration is completed. */
for (i = 0; i < 10000; i++) {
/*
* Use AR_PHY_AIC_CAL_ENABLE bit instead of AR_PHY_AIC_CAL_DONE.
* Sometimes CAL_DONE bit is not asserted.
*/
if ((OS_REG_READ(ah, aic_ctrl_b1[0]) & AR_PHY_AIC_CAL_ENABLE) == 0)
{
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Cal is done at #%d\n", i);
break;
}
OS_DELAY(1);
}
/* print out status registers */
aic_stat = OS_REG_READ(ah, aic_stat_b1[0]);
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) CAL_DONE = %d, CAL_ACTIVE = %d, MEAS_COUNT = %d\n",
MS(aic_stat, AR_PHY_AIC_CAL_DONE),
MS(aic_stat, AR_PHY_AIC_CAL_ACTIVE),
MS(aic_stat, AR_PHY_AIC_MEAS_COUNT));
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) ANT_ISO = %d, HOP_COUNT = %d, VALID_COUNT = %d\n",
MS(aic_stat, AR_PHY_AIC_CAL_ANT_ISO_EST),
MS(aic_stat, AR_PHY_AIC_CAL_HOP_COUNT),
MS(aic_stat, AR_PHY_AIC_CAL_VALID_COUNT));
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) BT_WEAK = %d, BT_STRONG = %d, , \n",
MS(aic_stat, AR_PHY_AIC_CAL_BT_TOO_WEAK_ERR),
MS(aic_stat, AR_PHY_AIC_CAL_BT_TOO_STRONG_ERR));
aic_stat = OS_REG_READ(ah, aic_stat_b1[1]);
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) MEAS_MAG_MIN = %d, CAL_AIC_SM = %d, AIC_SM = %d\n",
MS(aic_stat, AR_PHY_AIC_MEAS_MAG_MIN),
MS(aic_stat, AR_PHY_AIC_CAL_AIC_SM),
MS(aic_stat, AR_PHY_AIC_SM));
if (i >= 10000) {
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Calibration failed.\n");
break;
}
/* print out calibration result */
if (MS(aic_stat, AR_PHY_AIC_MEAS_MAG_MIN) < ATH_AIC_MEAS_MAG_THRESH) {
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1,
(ATH_AIC_SRAM_CAL_OFFSET + i*4));
value = OS_REG_READ(ah, AR_PHY_AIC_SRAM_DATA_B1);
if (value & 0x01) {
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(AIC) BT chan %02d: 0x%08x\n", i, value);
}
}
break;
}
cal_count--;
}
if (!cal_count) {
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Calibration failed2.\n");
}
/* Disable AIC reference signal in BT modem. */
OS_REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL,
(OS_REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) &
~ATH_AIC_BT_AIC_ENABLE));
ahp->ah_aic_enabled = ar9300_aic_cal_post_process(ah) ? AH_TRUE : AH_FALSE;
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) ah_aic_enable = %d\n",
ahp->ah_aic_enabled);
return 0;
}
u_int32_t
ar9300_aic_start_normal (struct ath_hal *ah)
{
struct ath_hal_9300 *ahp = AH9300(ah);
u_int32_t aic_ctrl0_b1, aic_ctrl1_b0, aic_ctrl1_b1;
int16_t i;
/* Config LNA gain difference */
OS_REG_WRITE(ah, AR_PHY_BT_COEX_4, 0x22180600);
OS_REG_WRITE(ah, AR_PHY_BT_COEX_5, 0x52443a2e);
ar9300_aic_gain_table(ah);
OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1, ATH_AIC_SRAM_AUTO_INCREMENT);
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_DATA_B1, ahp->ah_aic_sram[i]);
}
if (AR_SREV_JUPITER_10(ah)) {
aic_ctrl0_b1 = AR_PHY_AIC_CTRL_0_B1_10;
aic_ctrl1_b0 = AR_PHY_AIC_CTRL_1_B0_10;
aic_ctrl1_b1 = AR_PHY_AIC_CTRL_1_B1_10;
}
else {
aic_ctrl0_b1 = AR_PHY_AIC_CTRL_0_B1_20;
aic_ctrl1_b0 = AR_PHY_AIC_CTRL_1_B0_20;
aic_ctrl1_b1 = AR_PHY_AIC_CTRL_1_B1_20;
}
OS_REG_WRITE(ah, aic_ctrl1_b0,
(SM(0, AR_PHY_AIC_BT_IDLE_CFG) |
SM(1, AR_PHY_AIC_STDBY_COND) |
SM(37, AR_PHY_AIC_STDBY_ROT_ATT_DB) |
SM(5, AR_PHY_AIC_STDBY_COM_ATT_DB) |
SM(15, AR_PHY_AIC_RSSI_MAX) |
SM(0, AR_PHY_AIC_RSSI_MIN)));
OS_REG_WRITE(ah, aic_ctrl1_b1,
(SM(15, AR_PHY_AIC_RSSI_MAX) |
SM(0, AR_PHY_AIC_RSSI_MIN)));
OS_REG_WRITE(ah, aic_ctrl0_b1,
(SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
SM(1, AR_PHY_AIC_ENABLE)));
ahp->ah_aic_enabled = AH_TRUE;
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Start normal operation mode.\n");
return 0;
}
#endif
#endif
@@ -0,0 +1,195 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#define TU_TO_USEC(_tu) ((_tu) << 10)
#define ONE_EIGHTH_TU_TO_USEC(_tu8) ((_tu8) << 7)
extern u_int32_t ar9300_num_tx_pending(struct ath_hal *ah, u_int q);
/*
* Initializes all of the hardware registers used to
* send beacons. Note that for station operation the
* driver calls ar9300_set_sta_beacon_timers instead.
*/
void
ar9300_beacon_init(struct ath_hal *ah,
u_int32_t next_beacon, u_int32_t beacon_period, HAL_OPMODE opmode)
{
u_int32_t beacon_period_usec;
HALASSERT(opmode == HAL_M_IBSS || opmode == HAL_M_HOSTAP);
if (opmode == HAL_M_IBSS) {
OS_REG_SET_BIT(ah, AR_TXCFG, AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
}
OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, ONE_EIGHTH_TU_TO_USEC(next_beacon));
OS_REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
(ONE_EIGHTH_TU_TO_USEC(next_beacon) -
ah->ah_config.ah_dma_beacon_response_time));
OS_REG_WRITE(ah, AR_NEXT_SWBA,
(ONE_EIGHTH_TU_TO_USEC(next_beacon) -
ah->ah_config.ah_sw_beacon_response_time));
beacon_period_usec =
ONE_EIGHTH_TU_TO_USEC(beacon_period & HAL_BEACON_PERIOD_TU8);
OS_REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period_usec);
OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period_usec);
OS_REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period_usec);
/* reset TSF if required */
if (beacon_period & HAL_BEACON_RESET_TSF) {
ar9300_reset_tsf(ah);
}
/* enable timers */
OS_REG_SET_BIT(ah, AR_TIMER_MODE,
AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN);
}
/*
* Set all the beacon related bits on the h/w for stations
* i.e. initializes the corresponding h/w timers;
*/
void
ar9300_set_sta_beacon_timers(struct ath_hal *ah, const HAL_BEACON_STATE *bs)
{
u_int32_t next_tbtt, beaconintval, dtimperiod, beacontimeout;
HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
HALASSERT(bs->bs_intval != 0);
/* no cfp setting since h/w automatically takes care */
OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
/*
* Start the beacon timers by setting the BEACON register
* to the beacon interval; no need to write tim offset since
* h/w parses IEs.
*/
OS_REG_WRITE(ah, AR_BEACON_PERIOD,
TU_TO_USEC(bs->bs_intval & HAL_BEACON_PERIOD));
OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
TU_TO_USEC(bs->bs_intval & HAL_BEACON_PERIOD));
/*
* Configure the BMISS interrupt. Note that we
* assume the caller blocks interrupts while enabling
* the threshold.
*/
HALASSERT(bs->bs_bmissthreshold <=
(AR_RSSI_THR_BM_THR >> AR_RSSI_THR_BM_THR_S));
OS_REG_RMW_FIELD(ah, AR_RSSI_THR,
AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
/*
* Program the sleep registers to correlate with the beacon setup.
*/
/*
* Current implementation assumes sw processing of beacons -
* assuming an interrupt is generated every beacon which
* causes the hardware to become awake until the sw tells
* it to go to sleep again; beacon timeout is to allow for
* beacon jitter; cab timeout is max time to wait for cab
* after seeing the last DTIM or MORE CAB bit
*/
#define CAB_TIMEOUT_VAL 10 /* in TU */
#define BEACON_TIMEOUT_VAL 10 /* in TU */
#define MIN_BEACON_TIMEOUT_VAL 1 /* in 1/8 TU */
#define SLEEP_SLOP 3 /* in TU */
/*
* For max powersave mode we may want to sleep for longer than a
* beacon period and not want to receive all beacons; modify the
* timers accordingly; make sure to align the next TIM to the
* next DTIM if we decide to wake for DTIMs only
*/
beaconintval = bs->bs_intval & HAL_BEACON_PERIOD;
HALASSERT(beaconintval != 0);
if (bs->bs_sleepduration > beaconintval) {
HALASSERT(roundup(bs->bs_sleepduration, beaconintval) ==
bs->bs_sleepduration);
beaconintval = bs->bs_sleepduration;
}
dtimperiod = bs->bs_dtimperiod;
if (bs->bs_sleepduration > dtimperiod) {
HALASSERT(dtimperiod == 0 ||
roundup(bs->bs_sleepduration, dtimperiod) ==
bs->bs_sleepduration);
dtimperiod = bs->bs_sleepduration;
}
HALASSERT(beaconintval <= dtimperiod);
if (beaconintval == dtimperiod) {
next_tbtt = bs->bs_nextdtim;
} else {
next_tbtt = bs->bs_nexttbtt;
}
HALDEBUG(ah, HAL_DEBUG_BEACON,
"%s: next DTIM %d\n", __func__, bs->bs_nextdtim);
HALDEBUG(ah, HAL_DEBUG_BEACON,
"%s: next beacon %d\n", __func__, next_tbtt);
HALDEBUG(ah, HAL_DEBUG_BEACON,
"%s: beacon period %d\n", __func__, beaconintval);
HALDEBUG(ah, HAL_DEBUG_BEACON,
"%s: DTIM period %d\n", __func__, dtimperiod);
OS_REG_WRITE(ah, AR_NEXT_DTIM, TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
OS_REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(next_tbtt - SLEEP_SLOP));
/* cab timeout is now in 1/8 TU */
OS_REG_WRITE(ah, AR_SLEEP1,
SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
| AR_SLEEP1_ASSUME_DTIM);
/* beacon timeout is now in 1/8 TU */
if (p_cap->halAutoSleepSupport) {
beacontimeout = (BEACON_TIMEOUT_VAL << 3);
} else {
/*
* Use a very small value to make sure the timeout occurs before
* the TBTT. In this case the chip will not go back to sleep
* automatically, instead it will wait for the SW to explicitly
* set it to that mode.
*/
beacontimeout = MIN_BEACON_TIMEOUT_VAL;
}
OS_REG_WRITE(ah, AR_SLEEP2,
SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
OS_REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
OS_REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
/* clear HOST AP related timers first */
OS_REG_CLR_BIT(ah, AR_TIMER_MODE, (AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN));
OS_REG_SET_BIT(ah, AR_TIMER_MODE, AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN
| AR_DTIM_TIMER_EN);
/* TSF out of range threshold */
OS_REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
#undef CAB_TIMEOUT_VAL
#undef BEACON_TIMEOUT_VAL
#undef SLEEP_SLOP
}
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2012, Qualcomm Atheros, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the following conditions are met:
* 1. The materials contained herein are unmodified and are used
* unmodified.
* 2. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following NO
* ''WARRANTY'' disclaimer below (''Disclaimer''), without
* modification.
* 3. Redistributions in binary form must reproduce at minimum a
* disclaimer similar to the Disclaimer below and any redistribution
* must be conditioned upon including a substantially similar
* Disclaimer requirement for further binary redistribution.
* 4. Neither the names of the above-listed copyright holders nor the
* names of any contributors may be used to endorse or promote
* product derived from this software without specific prior written
* permission.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
* FOR 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 DAMAGES.
*
* $FreeBSD$
*
*/
#ifndef __AR9300_DEVID_H__
#define __AR9300_DEVID_H__
/*
* AR9380 HAL device IDs.
*/
/*
* MAC Version and Revision
*/
#define AR_SREV_VERSION_AR9380 0x1C0
#define AR_SREV_VERSION_AR9580 0x1C0
#define AR_SREV_VERSION_AR9460 0x280
#define AR_SREV_VERSION_AR9330 0x200
#define AR_SREV_VERSION_AR9340 0x300
#define AR_SREV_VERSION_QCA9550 0x400
#define AR_SREV_VERSION_AR9485 0x240
#define AR_SREV_REVISION_AR9380_10 0 /* AR9380 1.0 */
#define AR_SREV_REVISION_AR9380_20 2 /* AR9380 2.0/2.1 */
#define AR_SREV_REVISION_AR9380_22 3 /* AR9380 2.2 */
#define AR_SREV_REVISION_AR9580_10 4 /* AR9580/Peacock 1.0 */
#define AR_SREV_REVISION_AR9330_10 0 /* AR9330 1.0 */
#define AR_SREV_REVISION_AR9330_11 1 /* AR9330 1.1 */
#define AR_SREV_REVISION_AR9330_12 2 /* AR9330 1.2 */
#define AR_SREV_REVISION_AR9330_11_MASK 0xf /* AR9330 1.1 revision mask */
#define AR_SREV_REVISION_AR9485_10 0 /* AR9485 1.0 */
#define AR_SREV_REVISION_AR9485_11 1 /* AR9485 1.1 */
#define AR_SREV_REVISION_AR9340_10 0 /* AR9340 1.0 */
#define AR_SREV_REVISION_AR9340_11 1 /* AR9340 1.1 */
#define AR_SREV_REVISION_AR9340_12 2 /* AR9340 1.2 */
#define AR_SREV_REVISION_AR9340_MASK 0xf /* AR9340 revision mask */
#define AR_SREV_REVISION_AR9460_10 0 /* AR946x 1.0 */
#endif /* __AR9300_DEVID_H__ */
@@ -0,0 +1,675 @@
/*
* Copyright (c) 2012, 2013 Adrian Chadd <adrian@FreeBSD.org>.
*
* 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ah_devid.h"
#include "ah_desc.h"
#include "ar9300.h"
#include "ar9300reg.h"
#include "ar9300phy.h"
#include "ar9300desc.h"
#include "ar9300_freebsd.h"
#include "ar9300_stub.h"
#include "ar9300_stub_funcs.h"
#define FIX_NOISE_FLOOR 1
#define NEXT_TBTT_NOW 5
static HAL_BOOL ar9300ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix);
static HAL_BOOL ar9300SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix);
static void
ar9300SetChainMasks(struct ath_hal *ah, uint32_t tx_chainmask,
uint32_t rx_chainmask)
{
AH9300(ah)->ah_tx_chainmask =
tx_chainmask & AH_PRIVATE(ah)->ah_caps.halTxChainMask;
AH9300(ah)->ah_rx_chainmask =
rx_chainmask & AH_PRIVATE(ah)->ah_caps.halRxChainMask;
}
static u_int
ar9300GetSlotTime(struct ath_hal *ah)
{
u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff;
return (ath_hal_mac_usec(ah, clks)); /* convert from system clocks */
}
static HAL_BOOL
ar9300_freebsd_set_tx_power_limit(struct ath_hal *ah, uint32_t limit)
{
return (ar9300_set_tx_power_limit(ah, limit, 0, 0));
}
void
ar9300_attach_freebsd_ops(struct ath_hal *ah)
{
/* stub everything first */
ar9300_set_stub_functions(ah);
/* Global functions */
ah->ah_detach = ar9300_detach;
ah->ah_getRateTable = ar9300_get_rate_table;
/* Reset functions */
ah->ah_reset = ar9300_reset_freebsd;
ah->ah_phyDisable = ar9300_phy_disable;
ah->ah_disable = ar9300_disable;
ah->ah_configPCIE = ar9300_config_pcie_freebsd;
// ah->ah_disablePCIE = ar9300_disable_pcie_phy;
ah->ah_setPCUConfig = ar9300_set_pcu_config;
// perCalibration
ah->ah_perCalibrationN = ar9300_per_calibration_freebsd;
ah->ah_resetCalValid = ar9300_reset_cal_valid_freebsd;
ah->ah_setTxPowerLimit = ar9300_freebsd_set_tx_power_limit;
ah->ah_getChanNoise = ath_hal_getChanNoise;
/* Transmit functions */
ah->ah_setupTxQueue = ar9300_setup_tx_queue;
ah->ah_setTxQueueProps = ar9300_set_tx_queue_props;
ah->ah_getTxQueueProps = ar9300_get_tx_queue_props;
ah->ah_releaseTxQueue = ar9300_release_tx_queue;
ah->ah_resetTxQueue = ar9300_reset_tx_queue;
ah->ah_getTxDP = ar9300_get_tx_dp;
ah->ah_setTxDP = ar9300_set_tx_dp;
ah->ah_numTxPending = ar9300_num_tx_pending;
ah->ah_startTxDma = ar9300_start_tx_dma;
ah->ah_stopTxDma = ar9300_stop_tx_dma_freebsd;
ah->ah_setupTxDesc = ar9300_freebsd_setup_tx_desc;
ah->ah_setupXTxDesc = ar9300_freebsd_setup_x_tx_desc;
ah->ah_fillTxDesc = ar9300_freebsd_fill_tx_desc;
ah->ah_procTxDesc = ar9300_freebsd_proc_tx_desc;
ah->ah_getTxIntrQueue = ar9300_get_tx_intr_queue;
// reqTxIntrDesc
ah->ah_getTxCompletionRates = ar9300_freebsd_get_tx_completion_rates;
ah->ah_setTxDescLink = ar9300_set_desc_link;
ah->ah_getTxDescLink = ar9300_freebsd_get_desc_link;
ah->ah_getTxDescLinkPtr = ar9300_get_desc_link_ptr;
ah->ah_setupTxStatusRing = ar9300_setup_tx_status_ring;
ah->ah_getTxRawTxDesc = ar9300_get_raw_tx_desc;
ah->ah_updateTxTrigLevel = ar9300_update_tx_trig_level;
/* RX functions */
ah->ah_getRxDP = ar9300_get_rx_dp;
ah->ah_setRxDP = ar9300_set_rx_dp;
ah->ah_enableReceive = ar9300_enable_receive;
ah->ah_stopDmaReceive = ar9300_stop_dma_receive_freebsd;
ah->ah_startPcuReceive = ar9300_start_pcu_receive_freebsd;
ah->ah_stopPcuReceive = ar9300_stop_pcu_receive;
ah->ah_setMulticastFilter = ar9300_set_multicast_filter;
ah->ah_setMulticastFilterIndex = ar9300SetMulticastFilterIndex;
ah->ah_clrMulticastFilterIndex = ar9300ClrMulticastFilterIndex;
ah->ah_getRxFilter = ar9300_get_rx_filter;
ah->ah_setRxFilter = ar9300_set_rx_filter;
/* setupRxDesc */
ah->ah_procRxDesc = ar9300_proc_rx_desc_freebsd;
ah->ah_rxMonitor = ar9300_ani_rxmonitor_freebsd;
ah->ah_aniPoll = ar9300_ani_poll_freebsd;
ah->ah_procMibEvent = ar9300_process_mib_intr;
/* Misc functions */
ah->ah_getCapability = ar9300_get_capability;
ah->ah_setCapability = ar9300_set_capability;
ah->ah_getDiagState = ar9300_get_diag_state;
ah->ah_getMacAddress = ar9300_get_mac_address;
ah->ah_setMacAddress = ar9300_set_mac_address;
ah->ah_getBssIdMask = ar9300_get_bss_id_mask;
ah->ah_setBssIdMask = ar9300_set_bss_id_mask;
ah->ah_setRegulatoryDomain = ar9300_set_regulatory_domain;
ah->ah_setLedState = ar9300_set_led_state;
ah->ah_writeAssocid = ar9300_write_associd;
ah->ah_gpioCfgInput = ar9300_gpio_cfg_input;
ah->ah_gpioCfgOutput = ar9300_gpio_cfg_output;
ah->ah_gpioGet = ar9300_gpio_get;
ah->ah_gpioSet = ar9300_gpio_set;
ah->ah_gpioSetIntr = ar9300_gpio_set_intr;
/* polarity */
/* mask */
ah->ah_getTsf32 = ar9300_get_tsf32;
ah->ah_getTsf64 = ar9300_get_tsf64;
ah->ah_resetTsf = ar9300_reset_tsf;
ah->ah_detectCardPresent = ar9300_detect_card_present;
// ah->ah_updateMibCounters = ar9300_update_mib_counters;
ah->ah_getRfGain = ar9300_get_rfgain;
ah->ah_getDefAntenna = ar9300_get_def_antenna;
ah->ah_setDefAntenna = ar9300_set_def_antenna;
// ah->ah_getAntennaSwitch = ar9300_get_antenna_switch;
// ah->ah_setAntennaSwitch = ar9300_set_antenna_switch;
// ah->ah_setSifsTime = ar9300_set_sifs_time;
// ah->ah_getSifsTime = ar9300_get_sifs_time;
ah->ah_setSlotTime = ar9300_set_slot_time;
ah->ah_getSlotTime = ar9300GetSlotTime;
ah->ah_getAckTimeout = ar9300_get_ack_timeout;
ah->ah_setAckTimeout = ar9300_set_ack_timeout;
// XXX ack/ctsrate
// XXX CTS timeout
// XXX decompmask
// coverageclass
ah->ah_setQuiet = ar9300_set_quiet;
ah->ah_getMibCycleCounts = ar9300_freebsd_get_mib_cycle_counts;
/* DFS functions */
ah->ah_enableDfs = ar9300_enable_dfs;
ah->ah_getDfsThresh = ar9300_get_dfs_thresh;
ah->ah_getDfsDefaultThresh = ar9300_freebsd_get_dfs_default_thresh;
// procradarevent
ah->ah_isFastClockEnabled = ar9300_is_fast_clock_enabled;
ah->ah_get11nExtBusy = ar9300_get_11n_ext_busy;
/* Key cache functions */
ah->ah_getKeyCacheSize = ar9300_get_key_cache_size;
ah->ah_resetKeyCacheEntry = ar9300_reset_key_cache_entry;
ah->ah_isKeyCacheEntryValid = ar9300_is_key_cache_entry_valid;
ah->ah_setKeyCacheEntry = ar9300_set_key_cache_entry;
ah->ah_setKeyCacheEntryMac = ar9300_set_key_cache_entry_mac;
/* Power management functions */
ah->ah_setPowerMode = ar9300_set_power_mode;
ah->ah_getPowerMode = ar9300_get_power_mode;
/* Beacon functions */
/* ah_setBeaconTimers */
ah->ah_beaconInit = ar9300_freebsd_beacon_init;
/* ah_setBeaconTimers */
ah->ah_setStationBeaconTimers = ar9300_set_sta_beacon_timers;
/* ah_resetStationBeaconTimers */
/* ah_getNextTBTT */
/* Interrupt functions */
ah->ah_isInterruptPending = ar9300_is_interrupt_pending;
ah->ah_getPendingInterrupts = ar9300_get_pending_interrupts_freebsd;
ah->ah_getInterrupts = ar9300_get_interrupts;
ah->ah_setInterrupts = ar9300_set_interrupts_freebsd;
/* Regulatory/internal functions */
// AH_PRIVATE(ah)->ah_getNfAdjust = ar9300_get_nf_adjust;
AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
// AH_PRIVATE(ah)->ah_getChipPowerLimits = ar9300_get_chip_power_limits;
AH_PRIVATE(ah)->ah_getWirelessModes = ar9300_get_wireless_modes;
AH_PRIVATE(ah)->ah_getChannelEdges = ar9300_get_channel_edges;
AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
/* XXX ah_eeprom */
/* XXX ah_eeversion */
/* XXX ah_eepromDetach */
/* XXX ah_eepromGet */
AH_PRIVATE(ah)->ah_eepromGet = ar9300_eeprom_get_freebsd;
/* XXX ah_eepromSet */
/* XXX ah_getSpurChan */
/* XXX ah_eepromDiag */
/* 802.11n functions */
ah->ah_chainTxDesc = ar9300_freebsd_chain_tx_desc;
ah->ah_setupFirstTxDesc= ar9300_freebsd_setup_first_tx_desc;
ah->ah_setupLastTxDesc = ar9300_freebsd_setup_last_tx_desc;
ah->ah_set11nRateScenario = ar9300_freebsd_set_11n_rate_scenario;
ah->ah_set11nTxDesc = ar9300_freebsd_setup_11n_desc;
ah->ah_set11nAggrFirst = ar9300_set_11n_aggr_first;
ah->ah_set11nAggrMiddle = ar9300_set_11n_aggr_middle;
ah->ah_set11nAggrLast = ar9300_set_11n_aggr_last;
ah->ah_clr11nAggr = ar9300_clr_11n_aggr;
ah->ah_set11nBurstDuration = ar9300_set_11n_burst_duration;
/* ah_get11nExtBusy */
ah->ah_set11nMac2040 = ar9300_set_11n_mac2040;
ah->ah_setChainMasks = ar9300SetChainMasks;
/* ah_get11nRxClear */
/* ah_set11nRxClear */
/* bluetooth coexistence functions */
ah->ah_btCoexSetInfo = ar9300_set_bt_coex_info;
ah->ah_btCoexSetConfig = ar9300_bt_coex_config;
ah->ah_btCoexSetQcuThresh = ar9300_bt_coex_set_qcu_thresh;
ah->ah_btCoexSetWeights = ar9300_bt_coex_set_weights;
ah->ah_btCoexSetBmissThresh = ar9300_bt_coex_setup_bmiss_thresh;
ah->ah_btCoexSetParameter = ar9300_bt_coex_set_parameter;
ah->ah_btCoexDisable = ar9300_bt_coex_disable;
ah->ah_btCoexEnable = ar9300_bt_coex_enable;
/* LNA diversity functions */
ah->ah_divLnaConfGet = ar9300_ant_div_comb_get_config;
ah->ah_divLnaConfSet = ar9300_ant_div_comb_set_config;
/* Setup HAL configuration defaults */
ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable = 0x000bbb88;
}
HAL_BOOL
ar9300_reset_freebsd(struct ath_hal *ah, HAL_OPMODE opmode,
struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
HAL_STATUS *status)
{
HAL_BOOL r;
HAL_HT_MACMODE macmode;
struct ath_hal_private *ap = AH_PRIVATE(ah);
macmode =
IEEE80211_IS_CHAN_HT40(chan) ?
HAL_HT_MACMODE_2040 : HAL_HT_MACMODE_20;
r = ar9300_reset(ah, opmode, chan, macmode,
ap->ah_caps.halTxChainMask,
ap->ah_caps.halRxChainMask,
HAL_HT_EXTPROTSPACING_20, /* always 20Mhz channel spacing */
bChannelChange,
status,
AH_FALSE); /* XXX should really extend ath_hal_reset() */
return (r);
}
void
ar9300_config_pcie_freebsd(struct ath_hal *ah, HAL_BOOL restore,
HAL_BOOL powerOff)
{
ar9300_config_pci_power_save(ah, restore ? 1 : 0, powerOff ? 1 : 0);
}
/*
* This is a copy from ar9300_eeprom_get(), purely because the FreeBSD
* API is very silly and inconsistent.
*
* The AR93xx HAL doesn't call the eepromGetFlag() function, so this
* only occurs for FreeBSD code.
*
* When I fix this particular API, I'll undo this.
*/
HAL_STATUS
ar9300_eeprom_get_freebsd(struct ath_hal *ah, int param, void *val)
{
switch (param) {
case AR_EEP_FSTCLK_5G:
return HAL_OK;
default:
ath_hal_printf(ah, "%s: called, param=%d\n",
__func__, param);
return HAL_EIO;
}
}
HAL_BOOL
ar9300_stop_tx_dma_freebsd(struct ath_hal *ah, u_int q)
{
return ar9300_stop_tx_dma(ah, q, 1000);
}
void
ar9300_ani_poll_freebsd(struct ath_hal *ah,
const struct ieee80211_channel *chan)
{
HAL_NODE_STATS stats;
HAL_ANISTATS anistats;
OS_MEMZERO(&stats, sizeof(stats));
OS_MEMZERO(&anistats, sizeof(anistats));
ar9300_ani_ar_poll(ah, &stats, chan, &anistats);
}
/*
* Setup the configuration parameters in the style the AR9300 HAL
* wants.
*/
void
ar9300_config_defaults_freebsd(struct ath_hal *ah)
{
ah->ah_config.ath_hal_enable_ani = AH_TRUE;
}
HAL_BOOL
ar9300_stop_dma_receive_freebsd(struct ath_hal *ah)
{
return ar9300_stop_dma_receive(ah, 1000);
}
HAL_BOOL
ar9300_get_pending_interrupts_freebsd(struct ath_hal *ah, HAL_INT *masked)
{
/* Non-MSI, so no MSI vector; and 'nortc' = 0 */
return ar9300_get_pending_interrupts(ah, masked, HAL_INT_LINE, 0, 0);
}
HAL_INT
ar9300_set_interrupts_freebsd(struct ath_hal *ah, HAL_INT ints)
{
/* nortc = 0 */
return ar9300_set_interrupts(ah, ints, 0);
}
HAL_BOOL
ar9300_per_calibration_freebsd(struct ath_hal *ah,
struct ieee80211_channel *chan, u_int rxchainmask, HAL_BOOL long_cal,
HAL_BOOL *isCalDone)
{
/* XXX fake scheduled calibrations for now */
u_int32_t sched_cals = 0xfffffff;
return ar9300_calibration(ah, chan,
AH_PRIVATE(ah)->ah_caps.halRxChainMask,
long_cal,
isCalDone,
0, /* is_scan */
&sched_cals);
}
HAL_BOOL
ar9300_reset_cal_valid_freebsd(struct ath_hal *ah,
const struct ieee80211_channel *chan)
{
HAL_BOOL is_cal_done = AH_TRUE;
ar9300_reset_cal_valid(ah, chan, &is_cal_done, 0xffffffff);
return (is_cal_done);
}
void
ar9300_start_pcu_receive_freebsd(struct ath_hal *ah)
{
/* is_scanning flag == NULL */
ar9300_start_pcu_receive(ah, AH_FALSE);
}
/*
* FreeBSD will just pass in the descriptor value as 'pa'.
* The Atheros HAL treats 'pa' as the physical address of the RX
* descriptor and 'bufaddr' as the physical address of the RX buffer.
* I'm not sure why they didn't collapse them - the AR9300 RX descriptor
* routine doesn't check 'pa'.
*/
HAL_STATUS
ar9300_proc_rx_desc_freebsd(struct ath_hal *ah, struct ath_desc *ds,
uint32_t pa, struct ath_desc *ds_next, uint64_t tsf,
struct ath_rx_status *rxs)
{
return (ar9300_proc_rx_desc_fast(ah, ds, 0, ds_next, rxs,
(void *) ds));
}
void
ar9300_ani_rxmonitor_freebsd(struct ath_hal *ah, const HAL_NODE_STATS *stats,
const struct ieee80211_channel *chan)
{
}
void
ar9300_freebsd_get_desc_link(struct ath_hal *ah, void *ds, uint32_t *link)
{
struct ar9300_txc *ads = AR9300TXC(ds);
(*link) = ads->ds_link;
}
/*
* TX descriptor field setting wrappers - eek.
*/
HAL_BOOL
ar9300_freebsd_setup_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower,
u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags,
u_int rtsctsRate, u_int rtsCtsDuration, u_int compicvLen,
u_int compivLen, u_int comp)
{
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_KEY_TYPE keyType = 0; /* XXX No padding */
if (keyIx != HAL_TXKEYIX_INVALID)
keyType = ahp->ah_keytype[keyIx];
/* XXX bounds check keyix */
ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx,
keyType, flags);
return AH_TRUE;
}
HAL_BOOL
ar9300_freebsd_setup_x_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
u_int txRate1, u_int txTries1,
u_int txRate2, u_int txTries2,
u_int txRate3, u_int txTries3)
{
ath_hal_printf(ah, "%s: called, 0x%x/%d, 0x%x/%d, 0x%x/%d\n",
__func__,
txRate1, txTries1,
txRate2, txTries2,
txRate3, txTries3);
/* XXX should only be called during probe */
return (AH_TRUE);
}
HAL_BOOL
ar9300_freebsd_fill_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
HAL_DMA_ADDR *bufListPtr, uint32_t *segLenPtr, u_int descId, u_int qid,
HAL_BOOL firstSeg, HAL_BOOL lastSeg,
const struct ath_desc *ds0)
{
HAL_KEY_TYPE keyType = 0;
const struct ar9300_txc *ads = AR9300TXC_CONST(ds0);
/*
* FreeBSD's HAL doesn't pass the keytype to fill_tx_desc();
* it's copied as part of the descriptor chaining.
*
* So, extract it from ds0.
*/
keyType = MS(ads->ds_ctl17, AR_encr_type);
return ar9300_fill_tx_desc(ah, ds, bufListPtr, segLenPtr, descId,
qid, keyType, firstSeg, lastSeg, ds0);
}
HAL_BOOL
ar9300_freebsd_get_tx_completion_rates(struct ath_hal *ah,
const struct ath_desc *ds0, int *rates, int *tries)
{
ath_hal_printf(ah, "%s: called\n", __func__);
return AH_FALSE; /* XXX for now */
}
/*
* 802.11n TX descriptor wrappers
*/
void
ar9300_freebsd_set_11n_rate_scenario(struct ath_hal *ah, struct ath_desc *ds,
u_int durUpdateEn, u_int rtsctsRate, HAL_11N_RATE_SERIES series[],
u_int nseries, u_int flags)
{
/* lastds=NULL, rtscts_duration is 0, smart antenna is 0 */
ar9300_set_11n_rate_scenario(ah, (void *) ds, (void *)ds, durUpdateEn,
rtsctsRate, 0, series, nseries, flags, 0);
}
/* chaintxdesc */
HAL_BOOL
ar9300_freebsd_chain_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
HAL_DMA_ADDR *bufLenList, uint32_t *segLenList,
u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int keyIx,
HAL_CIPHER cipher, uint8_t numDelims,
HAL_BOOL firstSeg, HAL_BOOL lastSeg, HAL_BOOL lastAggr)
{
ath_hal_printf(ah, "%s: called\n", __func__);
return AH_FALSE;
}
/* setupfirsttxdesc */
HAL_BOOL
ar9300_freebsd_setup_first_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
u_int aggrLen, u_int flags, u_int txPower, u_int txRate0,
u_int txTries0, u_int antMode, u_int rtsctsRate, u_int rtsctsDuration)
{
ath_hal_printf(ah, "%s: called\n", __func__);
return AH_FALSE;
}
/* setuplasttxdesc */
/*
* This gets called but for now let's not log anything;
* it's only used to update the rate control information.
*/
HAL_BOOL
ar9300_freebsd_setup_last_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
const struct ath_desc *ds0)
{
// ath_hal_printf(ah, "%s: called\n", __func__);
return AH_FALSE;
}
void
ar9300_freebsd_setup_11n_desc(struct ath_hal *ah, void *ds, u_int pktLen,
HAL_PKT_TYPE type, u_int txPower, u_int keyIx, u_int flags)
{
ath_hal_printf(ah, "%s: called\n", __func__);
#if 0
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_KEY_TYPE keyType = 0; /* XXX No padding */
if (keyIx != HAL_TXKEYIX_INVALID)
keyType = ahp->ah_keytype[keyIx];
/* XXX bounds check keyix */
ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx,
keyType, flags);
#endif
}
HAL_STATUS
ar9300_freebsd_proc_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
struct ath_tx_status *ts)
{
return ar9300_proc_tx_desc(ah, ts);
}
void
ar9300_freebsd_beacon_init(struct ath_hal *ah, uint32_t next_beacon,
uint32_t beacon_period)
{
ar9300_beacon_init(ah, AH_PRIVATE(ah)->ah_opmode,
next_beacon, beacon_period);
}
HAL_BOOL
ar9300_freebsd_get_mib_cycle_counts(struct ath_hal *ah,
HAL_SURVEY_SAMPLE *hs)
{
return (AH_FALSE);
}
HAL_BOOL
ar9300_freebsd_get_dfs_default_thresh(struct ath_hal *ah,
HAL_PHYERR_PARAM *pe)
{
/* XXX not yet */
return (AH_FALSE);
}
/*
* Clear multicast filter by index - from FreeBSD ar5212_recv.c
*/
static HAL_BOOL
ar9300ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
{
uint32_t val;
if (ix >= 64)
return (AH_FALSE);
if (ix >= 32) {
val = OS_REG_READ(ah, AR_MCAST_FIL1);
OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32))));
} else {
val = OS_REG_READ(ah, AR_MCAST_FIL0);
OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<<ix)));
}
return AH_TRUE;
}
/*
* Set multicast filter by index - from FreeBSD ar5212_recv.c
*/
static HAL_BOOL
ar9300SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
{
uint32_t val;
if (ix >= 64)
return (AH_FALSE);
if (ix >= 32) {
val = OS_REG_READ(ah, AR_MCAST_FIL1);
OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32))));
} else {
val = OS_REG_READ(ah, AR_MCAST_FIL0);
OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<<ix)));
}
return (AH_TRUE);
}
/*
* RF attach stubs
*/
static HAL_BOOL
rf9330_attach(struct ath_hal *ah, HAL_STATUS *status)
{
(*status) = HAL_EINVAL;
return (AH_FALSE);
}
static HAL_BOOL
rf9330_probe(struct ath_hal *ah)
{
return (AH_FALSE);
}
AH_RF(RF9330, rf9330_probe, rf9330_attach);
@@ -0,0 +1,82 @@
#ifndef __AR9300_FREEBSD_H__
#define __AR9300_FREEBSD_H__
extern void ar9300_attach_freebsd_ops(struct ath_hal *ah);
extern HAL_BOOL ar9300_reset_freebsd(struct ath_hal *ah, HAL_OPMODE opmode,
struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
HAL_STATUS *status);
extern void ar9300_config_pcie_freebsd(struct ath_hal *, HAL_BOOL, HAL_BOOL);
extern HAL_STATUS ar9300_eeprom_get_freebsd(struct ath_hal *, int param,
void *val);
extern HAL_BOOL ar9300_stop_tx_dma_freebsd(struct ath_hal *ah, u_int q);
extern void ar9300_ani_poll_freebsd(struct ath_hal *ah,
const struct ieee80211_channel *chan);
extern void ar9300_config_defaults_freebsd(struct ath_hal *ah);
extern HAL_BOOL ar9300_stop_dma_receive_freebsd(struct ath_hal *ah);
extern HAL_BOOL ar9300_get_pending_interrupts_freebsd(struct ath_hal *ah,
HAL_INT *masked);
extern HAL_INT ar9300_set_interrupts_freebsd(struct ath_hal *ah,
HAL_INT mask);
extern HAL_BOOL ar9300_per_calibration_freebsd(struct ath_hal *ah,
struct ieee80211_channel *chan, u_int rxchainmask,
HAL_BOOL longCal, HAL_BOOL *isCalDone);
extern HAL_BOOL ar9300_reset_cal_valid_freebsd(struct ath_hal *ah,
const struct ieee80211_channel *chan);
extern void ar9300_start_pcu_receive_freebsd(struct ath_hal *ah);
extern HAL_STATUS ar9300_proc_rx_desc_freebsd(struct ath_hal *ah,
struct ath_desc *ds, uint32_t pa, struct ath_desc *ds_next,
uint64_t tsf, struct ath_rx_status *rxs);
extern void ar9300_ani_rxmonitor_freebsd(struct ath_hal *ah,
const HAL_NODE_STATS *stats, const struct ieee80211_channel *chan);
extern void ar9300_freebsd_get_desc_link(struct ath_hal *, void *ds,
uint32_t *);
extern HAL_BOOL ar9300_freebsd_setup_tx_desc(struct ath_hal *ah,
struct ath_desc *ds, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type,
u_int txPower, u_int txRate0, u_int txTries0, u_int keyIx,
u_int antMode, u_int flags, u_int rtsctsRate, u_int rtsCtsDuration,
u_int compicvLen, u_int compivLen, u_int comp);
extern HAL_BOOL ar9300_freebsd_setup_x_tx_desc(struct ath_hal *ah,
struct ath_desc *ds, u_int txRate1, u_int txTries1,
u_int txRate2, u_int txTries2, u_int txRate3, u_int txTries3);
extern HAL_BOOL ar9300_freebsd_fill_tx_desc(struct ath_hal *ah,
struct ath_desc *ds, HAL_DMA_ADDR *bufAddrList,
uint32_t *segLenList, u_int descId, u_int qId, HAL_BOOL firstSeg,
HAL_BOOL lastSeg, const struct ath_desc *ds0);
extern HAL_BOOL ar9300_freebsd_get_tx_completion_rates(struct ath_hal *ah,
const struct ath_desc *ds0, int *rates, int *tries);
extern void ar9300_freebsd_set_11n_rate_scenario(struct ath_hal *,
struct ath_desc *, u_int, u_int, HAL_11N_RATE_SERIES series[],
u_int, u_int);
extern HAL_BOOL ar9300_freebsd_chain_tx_desc(struct ath_hal *ah,
struct ath_desc *ds,
HAL_DMA_ADDR *bufAddrList,
uint32_t *segLenList,
u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type,
u_int keyIx, HAL_CIPHER cipher, uint8_t numDelims,
HAL_BOOL firstSeg, HAL_BOOL lastSeg, HAL_BOOL lastAggr);
extern HAL_BOOL ar9300_freebsd_setup_first_tx_desc(struct ath_hal *ah,
struct ath_desc *ds, u_int aggrLen, u_int flags, u_int txPower,
u_int txRate0, u_int txTries0, u_int antMode, u_int rtsctsRate,
u_int rtsctsDuration);
extern HAL_BOOL ar9300_freebsd_setup_last_tx_desc(struct ath_hal *ah,
struct ath_desc *ds, const struct ath_desc *ds0);
extern void ar9300_freebsd_setup_11n_desc(struct ath_hal *ah,
void *ds, u_int pktLen, HAL_PKT_TYPE type, u_int txPower,
u_int keyIx, u_int flags);
extern HAL_STATUS ar9300_freebsd_proc_tx_desc(struct ath_hal *ah,
struct ath_desc *ds, struct ath_tx_status *ts);
extern void ar9300_freebsd_beacon_init(struct ath_hal *ah,
uint32_t next_beacon, uint32_t beacon_period);
extern HAL_BOOL ar9300_freebsd_get_mib_cycle_counts(struct ath_hal *ah,
HAL_SURVEY_SAMPLE *);
extern HAL_BOOL ar9300_freebsd_get_dfs_default_thresh(struct ath_hal *ah,
HAL_PHYERR_PARAM *pe);
#endif /* __AR9300_FREEBSD_H__ */
@@ -0,0 +1,611 @@
#ifndef __AR9300_FREEBSD_INC_H__
#define __AR9300_FREEBSD_INC_H__
/*
* Define some configuration entries for the AR9300 HAL, so #if entries
* don't have to be removed.
*/
#define ATH_DRIVER_SIM 0 /* SIM */
#define ATH_WOW 0 /* Wake on Wireless */
#define ATH_SUPPORT_MCI 1 /* MCI btcoex */
#define ATH_SUPPORT_AIC 0 /* XXX to do with btcoex? */
#define AH_NEED_TX_DATA_SWAP 0 /* TX descriptor swap? */
#define AH_NEED_RX_DATA_SWAP 0 /* TX descriptor swap? */
#define ATH_SUPPORT_WIRESHARK 0 /* Radiotap HAL code */
#define AH_SUPPORT_WRITE_EEPROM 0 /* EEPROM write support */
#define ATH_SUPPORT_WAPI 0 /* China WAPI support */
#define ATH_ANT_DIV_COMB 1 /* Antenna combining */
#define ATH_SUPPORT_RAW_ADC_CAPTURE 0 /* Raw ADC capture support */
#define ATH_TRAFFIC_FAST_RECOVER 0 /* XXX not sure yet */
#define ATH_SUPPORT_SPECTRAL 0 /* Spectral scan support */
#define ATH_BT_COEX 1 /* Enable BT Coex code */
#define ATH_PCIE_ERROR_MONITOR 0 /* ??? */
#define ATH_SUPPORT_CRDC 0 /* ??? */
#define ATH_LOW_POWER_ENABLE 0 /* ??? */
#define ATH_SUPPORT_VOW_DCS 0 /* Video over wireless dynamic channel select */
#define REMOVE_PKT_LOG 1
#define ATH_VC_MODE_PROXY_STA 0 /* Azimuth + proxysta? */
#define ATH_GEN_RANDOMNESS 0
#define __PKT_SERIOUS_ERRORS__ 0
#define HAL_INTR_REFCOUNT_DISABLE 1 /* XXX wha? And atomics in the HAL!? */
#define UMAC_SUPPORT_SMARTANTENNA 0 /* sigh.. */
#define ATH_SMARTANTENNA_DISABLE_JTAG 0
#define ATH_SUPPORT_WIRESHARK 0
#define ATH_SUPPORT_WIFIPOS 0
#define ATH_SUPPORT_PAPRD 1
#define ATH_SUPPORT_TxBF 0
#define AH_PRIVATE_DIAG 1
/* XXX need to reverify these; they came in with qcamain */
#define ATH_SUPPORT_FAST_CC 0
#define ATH_SUPPORT_RADIO_RETENTION 0
#define ATH_SUPPORT_CAL_REUSE 0
#define ATH_WOW_OFFLOAD 0
#define HAL_NO_INTERSPERSED_READS
/* Required or things will probe/attach, but not work right */
#define AH_SUPPORT_OSPREY 1
#define AH_SUPPORT_POSEIDON 1
#define AH_SUPPORT_AR9300 1
/* These are the embedded boards; we don't currently support these */
#ifdef AH_SUPPORT_AR9330
#define AH_SUPPORT_HORNET 1
#endif /* AH_SUPPORT_AR9330 */
#ifdef AH_SUPPORT_AR9340
#define AH_SUPPORT_WASP 1
#endif /* AH_SUPPORT_AR9340 */
//#define AH_SUPPORT_SCORPION 1
#define FIX_NOISE_FLOOR 1
/* XXX this needs to be removed! No atomics in the HAL! */
typedef int os_atomic_t; /* XXX shouldn't do atomics here! */
#define OS_ATOMIC_INC(a) (*a)++
#define OS_ATOMIC_DEC(a) (*a)--
/*
* HAL definitions which aren't necessarily for public consumption (yet).
*/
enum {
HAL_TRUE_CHIP = 1,
HAL_MAC_TO_MAC_EMU,
HAL_MAC_BB_EMU,
};
/* HAL_KEY_TYPE */
enum {
HAL_KEY_PROXY_STA_MASK = 0x10,
};
typedef enum {
HAL_SMPS_DEFAULT = 0,
HAL_SMPS_SW_CTRL_LOW_PWR, /* Software control, low power setting */
HAL_SMPS_SW_CTRL_HIGH_PWR, /* Software control, high power setting */
HAL_SMPS_HW_CTRL /* Hardware Control */
} HAL_SMPS_MODE;
/*
* Green Tx, Based on different RSSI of Received Beacon thresholds,
* using different tx power by modified register tx power related values.
* The thresholds are decided by system team.
*/
#define GreenTX_thres1 56 /* in dB */
#define GreenTX_thres2 36 /* in dB */
typedef enum {
HAL_RSSI_TX_POWER_NONE = 0,
HAL_RSSI_TX_POWER_SHORT = 1, /* short range, reduce OB/DB bias current and disable PAL */
HAL_RSSI_TX_POWER_MIDDLE = 2, /* middle range, reduce OB/DB bias current and PAL is enabled */
HAL_RSSI_TX_POWER_LONG = 3, /* long range, orig. OB/DB bias current and PAL is enabled */
} HAL_RSSI_TX_POWER;
struct dfs_pulse {
u_int32_t rp_numpulses ; /* Num of pulses in radar burst */
u_int32_t rp_pulsedur; /* Duration of each pulse in usecs */
u_int32_t rp_pulsefreq; /* Frequency of pulses in burst */
u_int32_t rp_max_pulsefreq; /* Frequency of pulses in burst */
u_int32_t rp_patterntype; /* fixed or variable pattern type*/
u_int32_t rp_pulsevar; /* Time variation of pulse duration for
matched filter (single-sided) in usecs */
u_int32_t rp_threshold; /* Threshold for MF output to indicate
radar match */
u_int32_t rp_mindur; /* Min pulse duration to be considered for
this pulse type */
u_int32_t rp_maxdur; /* Max pusle duration to be considered for
this pulse type */
u_int32_t rp_rssithresh; /* Minimum rssi to be considered a radar pulse */
u_int32_t rp_meanoffset; /* Offset for timing adjustment */
int32_t rp_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dBm */
/* lower than in non TURBO mode.
This will be used to offset that diff.*/
u_int32_t rp_ignore_pri_window;
u_int32_t rp_pulseid; /* Unique ID for identifying filter */
};
struct dfs_staggered_pulse {
u_int32_t rp_numpulses; /* Num of pulses in radar burst */
u_int32_t rp_pulsedur; /* Duration of each pulse in usecs */
u_int32_t rp_min_pulsefreq; /* Frequency of pulses in burst */
u_int32_t rp_max_pulsefreq; /* Frequency of pulses in burst */
u_int32_t rp_patterntype; /* fixed or variable pattern type*/
u_int32_t rp_pulsevar; /* Time variation of pulse duration for
matched filter (single-sided) in usecs */
u_int32_t rp_threshold; /* Thershold for MF output to indicateC
radar match */
u_int32_t rp_mindur; /* Min pulse duration to be considered for
this pulse type */
u_int32_t rp_maxdur; /* Max pusle duration to be considered for
this pulse type */
u_int32_t rp_rssithresh; /* Minimum rssi to be considered a radar pulse */
u_int32_t rp_meanoffset; /* Offset for timing adjustment */
int32_t rp_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dBm */
/* lower than in non TURBO mode. This will be used to offset that diff.*/
u_int32_t rp_pulseid; /* Unique ID for identifying filter */
};
struct dfs_bin5pulse {
u_int32_t b5_threshold; /* Number of bin5 pulses to indicate detection */
u_int32_t b5_mindur; /* Min duration for a bin5 pulse */
u_int32_t b5_maxdur; /* Max duration for a bin5 pulse */
u_int32_t b5_timewindow; /* Window over which to count bin5 pulses */
u_int32_t b5_rssithresh; /* Min rssi to be considered a pulse */
u_int32_t b5_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dB */
};
#if 0
/* SPECTRAL SCAN defines begin */
typedef struct {
u_int16_t ss_fft_period; /* Skip interval for FFT reports */
u_int16_t ss_period; /* Spectral scan period */
u_int16_t ss_count; /* # of reports to return from ss_active */
u_int16_t ss_short_report;/* Set to report ony 1 set of FFT results */
u_int8_t radar_bin_thresh_sel;
u_int16_t ss_spectral_pri; /* are we doing a noise power cal ? */
int8_t ss_nf_cal[AH_MAX_CHAINS*2]; /* nf calibrated values for ctl+ext from eeprom */
int8_t ss_nf_pwr[AH_MAX_CHAINS*2]; /* nf pwr values for ctl+ext from eeprom */
int32_t ss_nf_temp_data; /* temperature data taken during nf scan */
} HAL_SPECTRAL_PARAM;
#define HAL_SPECTRAL_PARAM_NOVAL 0xFFFF
#define HAL_SPECTRAL_PARAM_ENABLE 0x8000 /* Enable/Disable if applicable */
#endif
/*
* Noise power data definitions
* units are: 4 x dBm - NOISE_PWR_DATA_OFFSET (e.g. -25 = (-25/4 - 90) = -96.25 dBm)
* range (for 6 signed bits) is (-32 to 31) + offset => -122dBm to -59dBm
* resolution (2 bits) is 0.25dBm
*/
#define NOISE_PWR_DATA_OFFSET -90 /* dbm - all pwr report data is represented offset by this */
#define INT_2_NOISE_PWR_DBM(_p) (((_p) - NOISE_PWR_DATA_OFFSET) << 2)
#define NOISE_PWR_DBM_2_INT(_p) ((((_p) + 3) >> 2) + NOISE_PWR_DATA_OFFSET)
#define NOISE_PWR_DBM_2_DEC(_p) (((-(_p)) & 3) * 25)
#define N2DBM(_x,_y) ((((_x) - NOISE_PWR_DATA_OFFSET) << 2) - (_y)/25)
/* SPECTRAL SCAN defines end */
typedef struct halvowstats {
u_int32_t tx_frame_count;
u_int32_t rx_frame_count;
u_int32_t rx_clear_count;
u_int32_t cycle_count;
u_int32_t ext_cycle_count;
} HAL_VOWSTATS;
#define HAL_BT_COEX_FLAG_LOW_ACK_PWR 0x00000001
#define HAL_BT_COEX_FLAG_LOWER_TX_PWR 0x00000002
#define HAL_BT_COEX_FLAG_ANT_DIV_ALLOW 0x00000004 /* Check Rx Diversity is allowed */
#define HAL_BT_COEX_FLAG_ANT_DIV_ENABLE 0x00000008 /* Check Diversity is on or off */
#define HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR 0x00000010
#define HAL_BT_COEX_FLAG_MCI_FTP_STOMP_RX 0x00000020
/*
* Weight table configurations.
*/
#define AR9300_BT_WGHT 0xcccc4444
#define AR9300_STOMP_ALL_WLAN_WGHT0 0xfffffff0
#define AR9300_STOMP_ALL_WLAN_WGHT1 0xfffffff0
#define AR9300_STOMP_LOW_WLAN_WGHT0 0x88888880
#define AR9300_STOMP_LOW_WLAN_WGHT1 0x88888880
#define AR9300_STOMP_NONE_WLAN_WGHT0 0x00000000
#define AR9300_STOMP_NONE_WLAN_WGHT1 0x00000000
#define AR9300_STOMP_ALL_FORCE_WLAN_WGHT0 0xffffffff // Stomp BT even when WLAN is idle
#define AR9300_STOMP_ALL_FORCE_WLAN_WGHT1 0xffffffff
#define AR9300_STOMP_LOW_FORCE_WLAN_WGHT0 0x88888888 // Stomp BT even when WLAN is idle
#define AR9300_STOMP_LOW_FORCE_WLAN_WGHT1 0x88888888
#define JUPITER_STOMP_ALL_WLAN_WGHT0 0x01017d01
#define JUPITER_STOMP_ALL_WLAN_WGHT1 0x41414101
#define JUPITER_STOMP_ALL_WLAN_WGHT2 0x41414101
#define JUPITER_STOMP_ALL_WLAN_WGHT3 0x41414141
#define JUPITER_STOMP_LOW_WLAN_WGHT0 0x01017d01
#define JUPITER_STOMP_LOW_WLAN_WGHT1 0x3b3b3b01
#define JUPITER_STOMP_LOW_WLAN_WGHT2 0x3b3b3b01
#define JUPITER_STOMP_LOW_WLAN_WGHT3 0x3b3b3b3b
#define JUPITER_STOMP_LOW_FTP_WLAN_WGHT0 0x01017d01
#define JUPITER_STOMP_LOW_FTP_WLAN_WGHT1 0x013b0101
#define JUPITER_STOMP_LOW_FTP_WLAN_WGHT2 0x3b3b0101
#define JUPITER_STOMP_LOW_FTP_WLAN_WGHT3 0x3b3b013b
#define JUPITER_STOMP_NONE_WLAN_WGHT0 0x01017d01
#define JUPITER_STOMP_NONE_WLAN_WGHT1 0x01010101
#define JUPITER_STOMP_NONE_WLAN_WGHT2 0x01010101
#define JUPITER_STOMP_NONE_WLAN_WGHT3 0x01010101
#define JUPITER_STOMP_ALL_FORCE_WLAN_WGHT0 0x01017d7d
#define JUPITER_STOMP_ALL_FORCE_WLAN_WGHT1 0x7d7d7d01
#define JUPITER_STOMP_ALL_FORCE_WLAN_WGHT2 0x7d7d7d7d
#define JUPITER_STOMP_ALL_FORCE_WLAN_WGHT3 0x7d7d7d7d
#define JUPITER_STOMP_LOW_FORCE_WLAN_WGHT0 0x01013b3b
#define JUPITER_STOMP_LOW_FORCE_WLAN_WGHT1 0x3b3b3b01
#define JUPITER_STOMP_LOW_FORCE_WLAN_WGHT2 0x3b3b3b3b
#define JUPITER_STOMP_LOW_FORCE_WLAN_WGHT3 0x3b3b3b3b
#define MCI_CONCUR_TX_WLAN_WGHT1_MASK 0xff000000
#define MCI_CONCUR_TX_WLAN_WGHT1_MASK_S 24
#define MCI_CONCUR_TX_WLAN_WGHT2_MASK 0x00ff0000
#define MCI_CONCUR_TX_WLAN_WGHT2_MASK_S 16
#define MCI_CONCUR_TX_WLAN_WGHT3_MASK 0x000000ff
#define MCI_CONCUR_TX_WLAN_WGHT3_MASK_S 0
#define MCI_CONCUR_TX_WLAN_WGHT3_MASK2 0x00ff0000
#define MCI_CONCUR_TX_WLAN_WGHT3_MASK2_S 16
#define MCI_QUERY_BT_VERSION_VERBOSE 0
#define MCI_LINKID_INDEX_MGMT_PENDING 1
#define HAL_MCI_FLAG_DISABLE_TIMESTAMP 0x00000001 /* Disable time stamp */
typedef enum mci_message_header {
MCI_LNA_CTRL = 0x10, /* len = 0 */
MCI_CONT_NACK = 0x20, /* len = 0 */
MCI_CONT_INFO = 0x30, /* len = 4 */
MCI_CONT_RST = 0x40, /* len = 0 */
MCI_SCHD_INFO = 0x50, /* len = 16 */
MCI_CPU_INT = 0x60, /* len = 4 */
MCI_SYS_WAKING = 0x70, /* len = 0 */
MCI_GPM = 0x80, /* len = 16 */
MCI_LNA_INFO = 0x90, /* len = 1 */
MCI_LNA_STATE = 0x94,
MCI_LNA_TAKE = 0x98,
MCI_LNA_TRANS = 0x9c,
MCI_SYS_SLEEPING = 0xa0, /* len = 0 */
MCI_REQ_WAKE = 0xc0, /* len = 0 */
MCI_DEBUG_16 = 0xfe, /* len = 2 */
MCI_REMOTE_RESET = 0xff /* len = 16 */
} MCI_MESSAGE_HEADER;
/* Default remote BT device MCI COEX version */
#define MCI_GPM_COEX_MAJOR_VERSION_DEFAULT 3
#define MCI_GPM_COEX_MINOR_VERSION_DEFAULT 0
/* Local WLAN MCI COEX version */
#define MCI_GPM_COEX_MAJOR_VERSION_WLAN 3
#define MCI_GPM_COEX_MINOR_VERSION_WLAN 0
typedef enum mci_gpm_subtype {
MCI_GPM_BT_CAL_REQ = 0,
MCI_GPM_BT_CAL_GRANT = 1,
MCI_GPM_BT_CAL_DONE = 2,
MCI_GPM_WLAN_CAL_REQ = 3,
MCI_GPM_WLAN_CAL_GRANT = 4,
MCI_GPM_WLAN_CAL_DONE = 5,
MCI_GPM_COEX_AGENT = 0x0C,
MCI_GPM_RSVD_PATTERN = 0xFE,
MCI_GPM_RSVD_PATTERN32 = 0xFEFEFEFE,
MCI_GPM_BT_DEBUG = 0xFF
} MCI_GPM_SUBTYPE_T;
typedef enum mci_gpm_coex_opcode {
MCI_GPM_COEX_VERSION_QUERY = 0,
MCI_GPM_COEX_VERSION_RESPONSE = 1,
MCI_GPM_COEX_STATUS_QUERY = 2,
MCI_GPM_COEX_HALT_BT_GPM = 3,
MCI_GPM_COEX_WLAN_CHANNELS = 4,
MCI_GPM_COEX_BT_PROFILE_INFO = 5,
MCI_GPM_COEX_BT_STATUS_UPDATE = 6,
MCI_GPM_COEX_BT_UPDATE_FLAGS = 7
} MCI_GPM_COEX_OPCODE_T;
typedef enum mci_gpm_coex_query_type {
/* WLAN information */
MCI_GPM_COEX_QUERY_WLAN_ALL_INFO = 0x01,
/* BT information */
MCI_GPM_COEX_QUERY_BT_ALL_INFO = 0x01,
MCI_GPM_COEX_QUERY_BT_TOPOLOGY = 0x02,
MCI_GPM_COEX_QUERY_BT_DEBUG = 0x04
} MCI_GPM_COEX_QUERY_TYPE_T;
typedef enum mci_gpm_coex_halt_bt_gpm {
MCI_GPM_COEX_BT_GPM_UNHALT = 0,
MCI_GPM_COEX_BT_GPM_HALT = 1
} MCI_GPM_COEX_HALT_BT_GPM_T;
typedef enum mci_gpm_coex_profile_type {
MCI_GPM_COEX_PROFILE_UNKNOWN = 0,
MCI_GPM_COEX_PROFILE_RFCOMM = 1,
MCI_GPM_COEX_PROFILE_A2DP = 2,
MCI_GPM_COEX_PROFILE_HID = 3,
MCI_GPM_COEX_PROFILE_BNEP = 4,
MCI_GPM_COEX_PROFILE_VOICE = 5,
MCI_GPM_COEX_PROFILE_MAX
} MCI_GPM_COEX_PROFILE_TYPE_T;
typedef enum mci_gpm_coex_profile_state {
MCI_GPM_COEX_PROFILE_STATE_END = 0,
MCI_GPM_COEX_PROFILE_STATE_START = 1
} MCI_GPM_COEX_PROFILE_STATE_T;
typedef enum mci_gpm_coex_profile_role {
MCI_GPM_COEX_PROFILE_SLAVE = 0,
MCI_GPM_COEX_PROFILE_MASTER = 1
} MCI_GPM_COEX_PROFILE_ROLE_T;
typedef enum mci_gpm_coex_bt_status_type {
MCI_GPM_COEX_BT_NONLINK_STATUS = 0,
MCI_GPM_COEX_BT_LINK_STATUS = 1
} MCI_GPM_COEX_BT_STATUS_TYPE_T;
typedef enum mci_gpm_coex_bt_status_state {
MCI_GPM_COEX_BT_NORMAL_STATUS = 0,
MCI_GPM_COEX_BT_CRITICAL_STATUS = 1
} MCI_GPM_COEX_BT_STATUS_STATE_T;
#define MCI_GPM_INVALID_PROFILE_HANDLE 0xff
typedef enum mci_gpm_coex_bt_updata_flags_op {
MCI_GPM_COEX_BT_FLAGS_READ = 0x00,
MCI_GPM_COEX_BT_FLAGS_SET = 0x01,
MCI_GPM_COEX_BT_FLAGS_CLEAR = 0x02
} MCI_GPM_COEX_BT_FLAGS_OP_T;
/* MCI GPM/Coex opcode/type definitions */
enum {
MCI_GPM_COEX_W_GPM_PAYLOAD = 1,
MCI_GPM_COEX_B_GPM_TYPE = 4,
MCI_GPM_COEX_B_GPM_OPCODE = 5,
/* MCI_GPM_WLAN_CAL_REQ, MCI_GPM_WLAN_CAL_DONE */
MCI_GPM_WLAN_CAL_W_SEQUENCE = 2,
/* MCI_GPM_COEX_VERSION_QUERY */
/* MCI_GPM_COEX_VERSION_RESPONSE */
MCI_GPM_COEX_B_MAJOR_VERSION = 6,
MCI_GPM_COEX_B_MINOR_VERSION = 7,
/* MCI_GPM_COEX_STATUS_QUERY */
MCI_GPM_COEX_B_BT_BITMAP = 6,
MCI_GPM_COEX_B_WLAN_BITMAP = 7,
/* MCI_GPM_COEX_HALT_BT_GPM */
MCI_GPM_COEX_B_HALT_STATE = 6,
/* MCI_GPM_COEX_WLAN_CHANNELS */
MCI_GPM_COEX_B_CHANNEL_MAP = 6,
/* MCI_GPM_COEX_BT_PROFILE_INFO */
MCI_GPM_COEX_B_PROFILE_TYPE = 6,
MCI_GPM_COEX_B_PROFILE_LINKID = 7,
MCI_GPM_COEX_B_PROFILE_STATE = 8,
MCI_GPM_COEX_B_PROFILE_ROLE = 9,
MCI_GPM_COEX_B_PROFILE_RATE = 10,
MCI_GPM_COEX_B_PROFILE_VOTYPE = 11,
MCI_GPM_COEX_H_PROFILE_T = 12,
MCI_GPM_COEX_B_PROFILE_W = 14,
MCI_GPM_COEX_B_PROFILE_A = 15,
/* MCI_GPM_COEX_BT_STATUS_UPDATE */
MCI_GPM_COEX_B_STATUS_TYPE = 6,
MCI_GPM_COEX_B_STATUS_LINKID = 7,
MCI_GPM_COEX_B_STATUS_STATE = 8,
/* MCI_GPM_COEX_BT_UPDATE_FLAGS */
MCI_GPM_COEX_B_BT_FLAGS_OP = 10,
MCI_GPM_COEX_W_BT_FLAGS = 6
};
#define MCI_GPM_RECYCLE(_p_gpm) \
{ \
*(((u_int32_t *)(_p_gpm)) + MCI_GPM_COEX_W_GPM_PAYLOAD) = MCI_GPM_RSVD_PATTERN32; \
}
#define MCI_GPM_TYPE(_p_gpm) \
(*(((u_int8_t *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) & 0xff)
#define MCI_GPM_OPCODE(_p_gpm) \
(*(((u_int8_t *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) & 0xff)
#define MCI_GPM_SET_CAL_TYPE(_p_gpm, _cal_type) \
{ \
*(((u_int8_t *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_cal_type) & 0xff; \
}
#define MCI_GPM_SET_TYPE_OPCODE(_p_gpm, _type, _opcode) \
{ \
*(((u_int8_t *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_type) & 0xff; \
*(((u_int8_t *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) = (_opcode) & 0xff; \
}
#define MCI_GPM_IS_CAL_TYPE(_type) ((_type) <= MCI_GPM_WLAN_CAL_DONE)
#define MCI_NUM_BT_CHANNELS 79
#define MCI_GPM_SET_CHANNEL_BIT(_p_gpm, _bt_chan) \
{ \
if (_bt_chan < MCI_NUM_BT_CHANNELS) { \
*(((u_int8_t *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \
(_bt_chan / 8)) |= 1 << (_bt_chan & 7); \
} \
}
#define MCI_GPM_CLR_CHANNEL_BIT(_p_gpm, _bt_chan) \
{ \
if (_bt_chan < MCI_NUM_BT_CHANNELS) { \
*(((u_int8_t *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \
(_bt_chan / 8)) &= ~(1 << (_bt_chan & 7)); \
} \
}
#define HAL_MCI_INTERRUPT_SW_MSG_DONE 0x00000001
#define HAL_MCI_INTERRUPT_CPU_INT_MSG 0x00000002
#define HAL_MCI_INTERRUPT_RX_CHKSUM_FAIL 0x00000004
#define HAL_MCI_INTERRUPT_RX_INVALID_HDR 0x00000008
#define HAL_MCI_INTERRUPT_RX_HW_MSG_FAIL 0x00000010
#define HAL_MCI_INTERRUPT_RX_SW_MSG_FAIL 0x00000020
#define HAL_MCI_INTERRUPT_TX_HW_MSG_FAIL 0x00000080
#define HAL_MCI_INTERRUPT_TX_SW_MSG_FAIL 0x00000100
#define HAL_MCI_INTERRUPT_RX_MSG 0x00000200
#define HAL_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE 0x00000400
#define HAL_MCI_INTERRUPT_CONT_INFO_TIMEOUT 0x80000000
#define HAL_MCI_INTERRUPT_MSG_FAIL_MASK ( HAL_MCI_INTERRUPT_RX_HW_MSG_FAIL | \
HAL_MCI_INTERRUPT_RX_SW_MSG_FAIL | \
HAL_MCI_INTERRUPT_TX_HW_MSG_FAIL | \
HAL_MCI_INTERRUPT_TX_SW_MSG_FAIL )
#define HAL_MCI_INTERRUPT_RX_MSG_REMOTE_RESET 0x00000001
#define HAL_MCI_INTERRUPT_RX_MSG_LNA_CONTROL 0x00000002
#define HAL_MCI_INTERRUPT_RX_MSG_CONT_NACK 0x00000004
#define HAL_MCI_INTERRUPT_RX_MSG_CONT_INFO 0x00000008
#define HAL_MCI_INTERRUPT_RX_MSG_CONT_RST 0x00000010
#define HAL_MCI_INTERRUPT_RX_MSG_SCHD_INFO 0x00000020
#define HAL_MCI_INTERRUPT_RX_MSG_CPU_INT 0x00000040
#define HAL_MCI_INTERRUPT_RX_MSG_GPM 0x00000100
#define HAL_MCI_INTERRUPT_RX_MSG_LNA_INFO 0x00000200
#define HAL_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING 0x00000400
#define HAL_MCI_INTERRUPT_RX_MSG_SYS_WAKING 0x00000800
#define HAL_MCI_INTERRUPT_RX_MSG_REQ_WAKE 0x00001000
#define HAL_MCI_INTERRUPT_RX_MSG_MONITOR (HAL_MCI_INTERRUPT_RX_MSG_LNA_CONTROL | \
HAL_MCI_INTERRUPT_RX_MSG_LNA_INFO | \
HAL_MCI_INTERRUPT_RX_MSG_CONT_NACK | \
HAL_MCI_INTERRUPT_RX_MSG_CONT_INFO | \
HAL_MCI_INTERRUPT_RX_MSG_CONT_RST)
typedef enum mci_bt_state {
MCI_BT_SLEEP,
MCI_BT_AWAKE,
MCI_BT_CAL_START,
MCI_BT_CAL
} MCI_BT_STATE_T;
/* Type of state query */
typedef enum mci_state_type {
HAL_MCI_STATE_ENABLE,
HAL_MCI_STATE_INIT_GPM_OFFSET,
HAL_MCI_STATE_NEXT_GPM_OFFSET,
HAL_MCI_STATE_LAST_GPM_OFFSET,
HAL_MCI_STATE_BT,
HAL_MCI_STATE_SET_BT_SLEEP,
HAL_MCI_STATE_SET_BT_AWAKE,
HAL_MCI_STATE_SET_BT_CAL_START,
HAL_MCI_STATE_SET_BT_CAL,
HAL_MCI_STATE_LAST_SCHD_MSG_OFFSET,
HAL_MCI_STATE_REMOTE_SLEEP,
HAL_MCI_STATE_CONT_RSSI_POWER,
HAL_MCI_STATE_CONT_PRIORITY,
HAL_MCI_STATE_CONT_TXRX,
HAL_MCI_STATE_RESET_REQ_WAKE,
HAL_MCI_STATE_SEND_WLAN_COEX_VERSION,
HAL_MCI_STATE_SET_BT_COEX_VERSION,
HAL_MCI_STATE_SEND_WLAN_CHANNELS,
HAL_MCI_STATE_SEND_VERSION_QUERY,
HAL_MCI_STATE_SEND_STATUS_QUERY,
HAL_MCI_STATE_NEED_FLUSH_BT_INFO,
HAL_MCI_STATE_SET_CONCUR_TX_PRI,
HAL_MCI_STATE_RECOVER_RX,
HAL_MCI_STATE_NEED_FTP_STOMP,
HAL_MCI_STATE_NEED_TUNING,
HAL_MCI_STATE_SHARED_CHAIN_CONCUR_TX,
HAL_MCI_STATE_DEBUG,
HAL_MCI_STATE_MAX
} HAL_MCI_STATE_TYPE;
#define HAL_MCI_STATE_DEBUG_REQ_BT_DEBUG 1
#define HAL_MCI_BT_MCI_FLAGS_UPDATE_CORR 0x00000002
#define HAL_MCI_BT_MCI_FLAGS_UPDATE_HDR 0x00000004
#define HAL_MCI_BT_MCI_FLAGS_UPDATE_PLD 0x00000008
#define HAL_MCI_BT_MCI_FLAGS_LNA_CTRL 0x00000010
#define HAL_MCI_BT_MCI_FLAGS_DEBUG 0x00000020
#define HAL_MCI_BT_MCI_FLAGS_SCHED_MSG 0x00000040
#define HAL_MCI_BT_MCI_FLAGS_CONT_MSG 0x00000080
#define HAL_MCI_BT_MCI_FLAGS_COEX_GPM 0x00000100
#define HAL_MCI_BT_MCI_FLAGS_CPU_INT_MSG 0x00000200
#define HAL_MCI_BT_MCI_FLAGS_MCI_MODE 0x00000400
#define HAL_MCI_BT_MCI_FLAGS_EGRET_MODE 0x00000800
#define HAL_MCI_BT_MCI_FLAGS_JUPITER_MODE 0x00001000
#define HAL_MCI_BT_MCI_FLAGS_OTHER 0x00010000
#define HAL_MCI_DEFAULT_BT_MCI_FLAGS 0x00011dde
/*
HAL_MCI_BT_MCI_FLAGS_UPDATE_CORR = 1
HAL_MCI_BT_MCI_FLAGS_UPDATE_HDR = 1
HAL_MCI_BT_MCI_FLAGS_UPDATE_PLD = 1
HAL_MCI_BT_MCI_FLAGS_LNA_CTRL = 1
HAL_MCI_BT_MCI_FLAGS_DEBUG = 0
HAL_MCI_BT_MCI_FLAGS_SCHED_MSG = 1
HAL_MCI_BT_MCI_FLAGS_CONT_MSG = 1
HAL_MCI_BT_MCI_FLAGS_COEX_GPM = 1
HAL_MCI_BT_MCI_FLAGS_CPU_INT_MSG = 0
HAL_MCI_BT_MCI_FLAGS_MCI_MODE = 1
HAL_MCI_BT_MCI_FLAGS_EGRET_MODE = 1
HAL_MCI_BT_MCI_FLAGS_JUPITER_MODE = 1
HAL_MCI_BT_MCI_FLAGS_OTHER = 1
*/
#define HAL_MCI_TOGGLE_BT_MCI_FLAGS \
( HAL_MCI_BT_MCI_FLAGS_UPDATE_CORR | \
HAL_MCI_BT_MCI_FLAGS_UPDATE_HDR | \
HAL_MCI_BT_MCI_FLAGS_UPDATE_PLD | \
HAL_MCI_BT_MCI_FLAGS_MCI_MODE )
#define HAL_MCI_2G_FLAGS_CLEAR_MASK 0x00000000
#define HAL_MCI_2G_FLAGS_SET_MASK HAL_MCI_TOGGLE_BT_MCI_FLAGS
#define HAL_MCI_2G_FLAGS HAL_MCI_DEFAULT_BT_MCI_FLAGS
#define HAL_MCI_5G_FLAGS_CLEAR_MASK HAL_MCI_TOGGLE_BT_MCI_FLAGS
#define HAL_MCI_5G_FLAGS_SET_MASK 0x00000000
#define HAL_MCI_5G_FLAGS (HAL_MCI_DEFAULT_BT_MCI_FLAGS & \
~HAL_MCI_TOGGLE_BT_MCI_FLAGS)
#define HAL_MCI_GPM_NOMORE 0
#define HAL_MCI_GPM_MORE 1
#define HAL_MCI_GPM_INVALID 0xffffffff
#define ATH_AIC_MAX_BT_CHANNEL 79
/*
* Default value for Jupiter is 0x00002201
* Default value for Aphrodite is 0x00002282
*/
#define ATH_MCI_CONFIG_CONCUR_TX 0x00000003
#define ATH_MCI_CONFIG_MCI_OBS_MCI 0x00000004
#define ATH_MCI_CONFIG_MCI_OBS_TXRX 0x00000008
#define ATH_MCI_CONFIG_MCI_OBS_BT 0x00000010
#define ATH_MCI_CONFIG_DISABLE_MCI_CAL 0x00000020
#define ATH_MCI_CONFIG_DISABLE_OSLA 0x00000040
#define ATH_MCI_CONFIG_DISABLE_FTP_STOMP 0x00000080
#define ATH_MCI_CONFIG_AGGR_THRESH 0x00000700
#define ATH_MCI_CONFIG_AGGR_THRESH_S 8
#define ATH_MCI_CONFIG_DISABLE_AGGR_THRESH 0x00000800
#define ATH_MCI_CONFIG_CLK_DIV 0x00003000
#define ATH_MCI_CONFIG_CLK_DIV_S 12
#define ATH_MCI_CONFIG_DISABLE_TUNING 0x00004000
#define ATH_MCI_CONFIG_MCI_WEIGHT_DBG 0x40000000
#define ATH_MCI_CONFIG_DISABLE_MCI 0x80000000
#define ATH_MCI_CONFIG_MCI_OBS_MASK ( ATH_MCI_CONFIG_MCI_OBS_MCI | \
ATH_MCI_CONFIG_MCI_OBS_TXRX | \
ATH_MCI_CONFIG_MCI_OBS_BT )
#define ATH_MCI_CONFIG_MCI_OBS_GPIO 0x0000002F
#define ATH_MCI_CONCUR_TX_SHARED_CHN 0x01
#define ATH_MCI_CONCUR_TX_UNSHARED_CHN 0x02
#define ATH_MCI_CONCUR_TX_DEBUG 0x03
/*
* The values below come from the system team test result.
* For Jupiter, BT tx power level is from 0(-20dBm) to 6(4dBm).
* Lowest WLAN tx power would be in bit[23:16] of dword 1.
*/
static const u_int32_t mci_concur_tx_max_pwr[4][8] =
{ /* No limit */
{0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f,
0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f},
/* 11G */
{0x16161616, 0x12121516, 0x12121212, 0x12121212,
0x12121212, 0x12121212, 0x12121212, 0x7f121212},
/* HT20 */
{0x15151515, 0x14141515, 0x14141414, 0x14141414,
0x14141414, 0x14141414, 0x14141414, 0x7f141414},
/* HT40 */
{0x10101010, 0x10101010, 0x10101010, 0x10101010,
0x10101010, 0x10101010, 0x10101010, 0x7f101010}};
#define ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK 0x00ff0000
#define ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK_S 16
#endif /* __AR9300_FREEBSD_INC_H__ */
@@ -0,0 +1,647 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ah_devid.h"
#ifdef AH_DEBUG
#include "ah_desc.h" /* NB: for HAL_PHYERR* */
#endif
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300phy.h"
#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
/*
* Configure GPIO Output Mux control
*/
#if UMAC_SUPPORT_SMARTANTENNA
static void ar9340_soc_gpio_cfg_output_mux(
struct ath_hal *ah,
u_int32_t gpio,
u_int32_t ah_signal_type)
{
#define ADDR_READ(addr) (*((volatile u_int32_t *)(addr)))
#define ADDR_WRITE(addr, b) (void)((*(volatile u_int32_t *) (addr)) = (b))
#define AR9340_SOC_GPIO_FUN0 0xB804002c
#define AR9340_SOC_GPIO_OE 0xB8040000
#if ATH_SMARTANTENNA_DISABLE_JTAG
#define AR9340_SOC_GPIO_FUNCTION (volatile u_int32_t*) 0xB804006c
#define WASP_DISABLE_JTAG 0x2
#define MAX_JTAG_GPIO_PIN 1
#endif
u_int8_t out_func, shift;
u_int32_t flags;
volatile u_int32_t* address;
if (!ah_signal_type){
return;
}
#if ATH_SMARTANTENNA_DISABLE_JTAG
/*
* To use GPIO pins 0 and 1 for controling antennas, JTAG needs to disabled.
*/
if (gpio <= MAX_JTAG_GPIO_PIN) {
flags = ADDR_READ(AR9340_SOC_GPIO_FUNCTION);
flags |= WASP_DISABLE_JTAG;
ADDR_WRITE(AR9340_SOC_GPIO_FUNCTION, flags);
}
#endif
out_func = gpio / 4;
shift = (gpio % 4);
address = (volatile u_int32_t *)(AR9340_SOC_GPIO_FUN0 + (out_func*4));
flags = ADDR_READ(address);
flags |= ah_signal_type << (8*shift);
ADDR_WRITE(address, flags);
flags = ADDR_READ(AR9340_SOC_GPIO_OE);
flags &= ~(1 << gpio);
ADDR_WRITE(AR9340_SOC_GPIO_OE, flags);
}
#endif
static void
ar9300_gpio_cfg_output_mux(struct ath_hal *ah, u_int32_t gpio, u_int32_t type)
{
int addr;
u_int32_t gpio_shift;
/* each MUX controls 6 GPIO pins */
if (gpio > 11) {
addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX3);
} else if (gpio > 5) {
addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX2);
} else {
addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1);
}
/*
* 5 bits per GPIO pin.
* Bits 0..4 for 1st pin in that mux,
* bits 5..9 for 2nd pin, etc.
*/
gpio_shift = (gpio % 6) * 5;
OS_REG_RMW(ah, addr, (type << gpio_shift), (0x1f << gpio_shift));
}
/*
* Configure GPIO Output lines
*/
HAL_BOOL
ar9300_gpio_cfg_output(
struct ath_hal *ah,
u_int32_t gpio,
HAL_GPIO_MUX_TYPE hal_signal_type)
{
u_int32_t ah_signal_type;
u_int32_t gpio_shift;
u_int8_t smart_ant = 0;
static const u_int32_t mux_signal_conversion_table[] = {
/* HAL_GPIO_OUTPUT_MUX_AS_OUTPUT */
AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
/* HAL_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED */
AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
/* HAL_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED */
AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
/* HAL_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED */
AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
/* HAL_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED */
AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
/* HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE */
AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL,
/* HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME */
AR_GPIO_OUTPUT_MUX_AS_TX_FRAME,
/* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA */
AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA,
/* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK */
AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK,
/* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA */
AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA,
/* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK */
AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK,
/* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX */
AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX,
/* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX */
AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX,
/* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX */
AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX,
/* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX */
AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX,
/* HAL_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE */
AR_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE,
/* HAL_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA */
AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA,
/* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0 */
AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0,
/* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1 */
AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1,
/* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2 */
AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2,
/* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_SWCOM3 */
AR_GPIO_OUTPUT_MUX_AS_SWCOM3,
};
HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
if ((gpio == AR9382_GPIO_PIN_8_RESERVED) ||
(gpio == AR9382_GPIO_PIN_11_RESERVED) ||
(gpio == AR9382_GPIO_9_INPUT_ONLY))
{
return AH_FALSE;
}
/* Convert HAL signal type definitions to hardware-specific values. */
if ((int) hal_signal_type < ARRAY_LENGTH(mux_signal_conversion_table))
{
ah_signal_type = mux_signal_conversion_table[hal_signal_type];
} else {
return AH_FALSE;
}
if (gpio <= AR9382_MAX_JTAG_GPIO_PIN_NUM) {
OS_REG_SET_BIT(ah,
AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
}
#if UMAC_SUPPORT_SMARTANTENNA
/* Get the pin and func values for smart antenna */
switch (ah_signal_type)
{
case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0:
gpio = ATH_GPIOPIN_ANTCHAIN0;
ah_signal_type = ATH_GPIOFUNC_ANTCHAIN0;
smart_ant = 1;
break;
case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1:
gpio = ATH_GPIOPIN_ANTCHAIN1;
ah_signal_type = ATH_GPIOFUNC_ANTCHAIN1;
smart_ant = 1;
break;
case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2:
gpio = ATH_GPIOPIN_ANTCHAIN2;
ah_signal_type = ATH_GPIOFUNC_ANTCHAIN2;
smart_ant = 1;
break;
#if ATH_SMARTANTENNA_ROUTE_SWCOM_TO_GPIO
case AR_GPIO_OUTPUT_MUX_AS_SWCOM3:
gpio = ATH_GPIOPIN_ROUTE_SWCOM3;
ah_signal_type = ATH_GPIOFUNC_ROUTE_SWCOM3;
smart_ant = 1;
break;
#endif
default:
break;
}
#endif
if (smart_ant && (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)))
{
#if UMAC_SUPPORT_SMARTANTENNA
ar9340_soc_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
#endif
return AH_TRUE;
} else
{
/* Configure the MUX */
ar9300_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
}
/* 2 bits per output mode */
gpio_shift = 2 * gpio;
OS_REG_RMW(ah,
AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
(AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
(AR_GPIO_OE_OUT_DRV << gpio_shift));
return AH_TRUE;
}
/*
* Configure GPIO Output lines -LED off
*/
HAL_BOOL
ar9300_gpio_cfg_output_led_off(
struct ath_hal *ah,
u_int32_t gpio,
HAL_GPIO_MUX_TYPE halSignalType)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
u_int32_t ah_signal_type;
u_int32_t gpio_shift;
u_int8_t smart_ant = 0;
static const u_int32_t mux_signal_conversion_table[] = {
/* HAL_GPIO_OUTPUT_MUX_AS_OUTPUT */
AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
/* HAL_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED */
AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
/* HAL_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED */
AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
/* HAL_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED */
AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
/* HAL_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED */
AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
/* HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE */
AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL,
/* HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME */
AR_GPIO_OUTPUT_MUX_AS_TX_FRAME,
/* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA */
AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA,
/* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK */
AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK,
/* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA */
AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA,
/* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK */
AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK,
/* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX */
AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX,
/* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX */
AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX,
/* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX */
AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX,
/* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX */
AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX,
AR_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE,
AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA,
AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0,
AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1,
AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2
};
HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);
/* Convert HAL signal type definitions to hardware-specific values. */
if ((int) halSignalType < ARRAY_LENGTH(mux_signal_conversion_table))
{
ah_signal_type = mux_signal_conversion_table[halSignalType];
} else {
return AH_FALSE;
}
#if UMAC_SUPPORT_SMARTANTENNA
/* Get the pin and func values for smart antenna */
switch (halSignalType)
{
case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0:
gpio = ATH_GPIOPIN_ANTCHAIN0;
ah_signal_type = ATH_GPIOFUNC_ANTCHAIN0;
smart_ant = 1;
break;
case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1:
gpio = ATH_GPIOPIN_ANTCHAIN1;
ah_signal_type = ATH_GPIOFUNC_ANTCHAIN1;
smart_ant = 1;
break;
case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2:
gpio = ATH_GPIOPIN_ANTCHAIN2;
ah_signal_type = ATH_GPIOFUNC_ANTCHAIN2;
smart_ant = 1;
break;
default:
break;
}
#endif
if (smart_ant && AR_SREV_WASP(ah))
{
return AH_FALSE;
}
// Configure the MUX
ar9300_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
// 2 bits per output mode
gpio_shift = 2*gpio;
OS_REG_RMW(ah,
AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
(AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
(AR_GPIO_OE_OUT_DRV << gpio_shift));
return AH_TRUE;
#undef N
}
/*
* Configure GPIO Input lines
*/
HAL_BOOL
ar9300_gpio_cfg_input(struct ath_hal *ah, u_int32_t gpio)
{
u_int32_t gpio_shift;
HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
if ((gpio == AR9382_GPIO_PIN_8_RESERVED) ||
(gpio == AR9382_GPIO_PIN_11_RESERVED) ||
(gpio > AR9382_MAX_GPIO_INPUT_PIN_NUM))
{
return AH_FALSE;
}
if (gpio <= AR9382_MAX_JTAG_GPIO_PIN_NUM) {
OS_REG_SET_BIT(ah,
AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
}
/* TODO: configure input mux for AR9300 */
/* If configured as input, set output to tristate */
gpio_shift = 2 * gpio;
OS_REG_RMW(ah,
AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
(AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
(AR_GPIO_OE_OUT_DRV << gpio_shift));
return AH_TRUE;
}
/*
* Once configured for I/O - set output lines
* output the level of GPio PIN without care work mode
*/
HAL_BOOL
ar9300_gpio_set(struct ath_hal *ah, u_int32_t gpio, u_int32_t val)
{
HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
if ((gpio == AR9382_GPIO_PIN_8_RESERVED) ||
(gpio == AR9382_GPIO_PIN_11_RESERVED) ||
(gpio == AR9382_GPIO_9_INPUT_ONLY))
{
return AH_FALSE;
}
OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUT),
((val & 1) << gpio), AR_GPIO_BIT(gpio));
return AH_TRUE;
}
/*
* Once configured for I/O - get input lines
*/
u_int32_t
ar9300_gpio_get(struct ath_hal *ah, u_int32_t gpio)
{
u_int32_t gpio_in;
HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
if ((gpio == AR9382_GPIO_PIN_8_RESERVED) ||
(gpio == AR9382_GPIO_PIN_11_RESERVED))
{
return 0xffffffff;
}
gpio_in = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN));
OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN),
(1 << gpio), AR_GPIO_BIT(gpio));
return (MS(gpio_in, AR_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
}
u_int32_t
ar9300_gpio_get_intr(struct ath_hal *ah)
{
unsigned int mask = 0;
struct ath_hal_9300 *ahp = AH9300(ah);
mask = ahp->ah_gpio_cause;
return mask;
}
/*
* Set the GPIO Interrupt
* Sync and Async interrupts are both set/cleared.
* Async GPIO interrupts may not be raised when the chip is put to sleep.
*/
void
ar9300_gpio_set_intr(struct ath_hal *ah, u_int gpio, u_int32_t ilevel)
{
int i, reg_bit;
u_int32_t reg_val;
u_int32_t regs[2], shifts[2];
#ifdef AH_ASSERT
u_int32_t gpio_mask;
u_int32_t old_field_val = 0, field_val = 0;
#endif
#ifdef ATH_GPIO_USE_ASYNC_CAUSE
regs[0] = AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE);
regs[1] = AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK);
shifts[0] = AR_INTR_ASYNC_ENABLE_GPIO_S;
shifts[1] = AR_INTR_ASYNC_MASK_GPIO_S;
#else
regs[0] = AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE);
regs[1] = AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK);
shifts[0] = AR_INTR_SYNC_ENABLE_GPIO_S;
shifts[1] = AR_INTR_SYNC_MASK_GPIO_S;
#endif
HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
if ((gpio == AR9382_GPIO_PIN_8_RESERVED) ||
(gpio == AR9382_GPIO_PIN_11_RESERVED) ||
(gpio > AR9382_MAX_GPIO_INPUT_PIN_NUM))
{
return;
}
#ifdef AH_ASSERT
gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.halNumGpioPins) - 1;
#endif
if (ilevel == HAL_GPIO_INTR_DISABLE) {
/* clear this GPIO's bit in the interrupt registers */
for (i = 0; i < ARRAY_LENGTH(regs); i++) {
reg_val = OS_REG_READ(ah, regs[i]);
reg_bit = shifts[i] + gpio;
reg_val &= ~(1 << reg_bit);
OS_REG_WRITE(ah, regs[i], reg_val);
/* check that each register has same GPIOs enabled */
#ifdef AH_ASSERT
field_val = (reg_val >> shifts[i]) & gpio_mask;
HALASSERT(i == 0 || old_field_val == field_val);
old_field_val = field_val;
#endif
}
} else {
reg_val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL));
reg_bit = gpio;
if (ilevel == HAL_GPIO_INTR_HIGH) {
/* 0 == interrupt on pin high */
reg_val &= ~(1 << reg_bit);
} else if (ilevel == HAL_GPIO_INTR_LOW) {
/* 1 == interrupt on pin low */
reg_val |= (1 << reg_bit);
}
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), reg_val);
/* set this GPIO's bit in the interrupt registers */
for (i = 0; i < ARRAY_LENGTH(regs); i++) {
reg_val = OS_REG_READ(ah, regs[i]);
reg_bit = shifts[i] + gpio;
reg_val |= (1 << reg_bit);
OS_REG_WRITE(ah, regs[i], reg_val);
/* check that each register has same GPIOs enabled */
#ifdef AH_ASSERT
field_val = (reg_val >> shifts[i]) & gpio_mask;
HALASSERT(i == 0 || old_field_val == field_val);
old_field_val = field_val;
#endif
}
}
}
u_int32_t
ar9300_gpio_get_polarity(struct ath_hal *ah)
{
return OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL));
}
void
ar9300_gpio_set_polarity(struct ath_hal *ah, u_int32_t pol_map,
u_int32_t changed_mask)
{
u_int32_t gpio_mask;
gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.halNumGpioPins) - 1;
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), gpio_mask & pol_map);
#ifndef ATH_GPIO_USE_ASYNC_CAUSE
/*
* For SYNC_CAUSE type interrupts, we need to clear the cause register
* explicitly. Otherwise an interrupt with the original polarity setting
* will come up immediately (if there is already an interrupt source),
* which is not what we want usually.
*/
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR),
changed_mask << AR_INTR_SYNC_ENABLE_GPIO_S);
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR));
#endif
}
/*
* get the GPIO input pin mask
* gpio0 - gpio13
* gpio8, gpio11, regard as reserved by the chip ar9382
*/
u_int32_t
ar9300_gpio_get_mask(struct ath_hal *ah)
{
u_int32_t mask = (1 << (AR9382_MAX_GPIO_INPUT_PIN_NUM + 1) ) - 1;
if (AH_PRIVATE(ah)->ah_devid == AR9300_DEVID_AR9380_PCIE) {
mask = (1 << AR9382_MAX_GPIO_PIN_NUM) - 1;
mask &= ~(1 << AR9382_GPIO_PIN_8_RESERVED |
1 << AR9382_GPIO_PIN_11_RESERVED);
}
return mask;
}
int
ar9300_gpio_set_mask(struct ath_hal *ah, u_int32_t mask, u_int32_t pol_map)
{
u_int32_t invalid = ~((1 << (AR9382_MAX_GPIO_INPUT_PIN_NUM + 1)) - 1);
if (AH_PRIVATE(ah)->ah_devid == AR9300_DEVID_AR9380_PCIE) {
invalid = ~((1 << AR9382_MAX_GPIO_PIN_NUM) - 1);
invalid |= 1 << AR9382_GPIO_PIN_8_RESERVED |
1 << AR9382_GPIO_PIN_11_RESERVED;
}
if (mask & invalid) {
ath_hal_printf(ah, "%s: invalid GPIO mask 0x%x\n", __func__, mask);
return -1;
}
AH9300(ah)->ah_gpio_mask = mask;
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), mask & pol_map);
return 0;
}
#ifdef AH_DEBUG
void ar9300_gpio_show(struct ath_hal *ah);
void ar9300_gpio_show(struct ath_hal *ah)
{
ath_hal_printf(ah, "--- 9382 GPIOs ---(ah=%p)\n", ah );
ath_hal_printf(ah,
"AH9300(_ah)->ah_hostifregs:%p\r\n", &(AH9300(ah)->ah_hostifregs));
ath_hal_printf(ah,
"GPIO_OUT: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUT)));
ath_hal_printf(ah,
"GPIO_IN: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN)));
ath_hal_printf(ah,
"GPIO_OE: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT)));
ath_hal_printf(ah,
"GPIO_OE1_OUT: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE1_OUT)));
ath_hal_printf(ah,
"GPIO_INTR_POLAR: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL)));
ath_hal_printf(ah,
"GPIO_INPUT_VALUE: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL)));
ath_hal_printf(ah,
"GPIO_INPUT_MUX1: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_MUX1)));
ath_hal_printf(ah,
"GPIO_INPUT_MUX2: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_MUX2)));
ath_hal_printf(ah,
"GPIO_OUTPUT_MUX1: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1)));
ath_hal_printf(ah,
"GPIO_OUTPUT_MUX2: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX2)));
ath_hal_printf(ah,
"GPIO_OUTPUT_MUX3: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX3)));
ath_hal_printf(ah,
"GPIO_INPUT_STATE: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INPUT_STATE)));
ath_hal_printf(ah,
"GPIO_PDPU: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_PDPU)));
ath_hal_printf(ah,
"GPIO_DS: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_DS)));
ath_hal_printf(ah,
"AR_INTR_ASYNC_ENABLE: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE)));
ath_hal_printf(ah,
"AR_INTR_ASYNC_MASK: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK)));
ath_hal_printf(ah,
"AR_INTR_SYNC_ENABLE: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE)));
ath_hal_printf(ah,
"AR_INTR_SYNC_MASK: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK)));
ath_hal_printf(ah,
"AR_INTR_ASYNC_CAUSE: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE)));
ath_hal_printf(ah,
"AR_INTR_SYNC_CAUSE: 0x%08X\n",
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)));
}
#endif /*AH_DEBUG*/
@@ -0,0 +1,773 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300phy.h"
/*
* Checks to see if an interrupt is pending on our NIC
*
* Returns: TRUE if an interrupt is pending
* FALSE if not
*/
HAL_BOOL
ar9300_is_interrupt_pending(struct ath_hal *ah)
{
u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
u_int32_t host_isr;
/*
* Some platforms trigger our ISR before applying power to
* the card, so make sure.
*/
host_isr = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE));
if ((host_isr & AR_INTR_ASYNC_USED) && (host_isr != AR_INTR_SPURIOUS)) {
return AH_TRUE;
}
host_isr = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE));
if (AR_SREV_POSEIDON(ah)) {
sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
}
else if (AR_SREV_WASP(ah)) {
sync_en_def = AR9340_INTR_SYNC_DEFAULT;
}
if ((host_isr & (sync_en_def | AR_INTR_SYNC_MASK_GPIO)) &&
(host_isr != AR_INTR_SPURIOUS)) {
return AH_TRUE;
}
return AH_FALSE;
}
/*
* Reads the Interrupt Status Register value from the NIC, thus deasserting
* the interrupt line, and returns both the masked and unmasked mapped ISR
* values. The value returned is mapped to abstract the hw-specific bit
* locations in the Interrupt Status Register.
*
* Returns: A hardware-abstracted bitmap of all non-masked-out
* interrupts pending, as well as an unmasked value
*/
#define MAP_ISR_S2_HAL_CST 6 /* Carrier sense timeout */
#define MAP_ISR_S2_HAL_GTT 6 /* Global transmit timeout */
#define MAP_ISR_S2_HAL_TIM 3 /* TIM */
#define MAP_ISR_S2_HAL_CABEND 0 /* CABEND */
#define MAP_ISR_S2_HAL_DTIMSYNC 7 /* DTIMSYNC */
#define MAP_ISR_S2_HAL_DTIM 7 /* DTIM */
#define MAP_ISR_S2_HAL_TSFOOR 4 /* Rx TSF out of range */
#define MAP_ISR_S2_HAL_BBPANIC 6 /* Panic watchdog IRQ from BB */
HAL_BOOL
ar9300_get_pending_interrupts(
struct ath_hal *ah,
HAL_INT *masked,
HAL_INT_TYPE type,
u_int8_t msi,
HAL_BOOL nortc)
{
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_BOOL ret_val = AH_TRUE;
u_int32_t isr = 0;
u_int32_t mask2 = 0;
u_int32_t sync_cause = 0;
u_int32_t async_cause;
u_int32_t msi_pend_addr_mask = 0;
u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
*masked = 0;
if (!nortc) {
if (HAL_INT_MSI == type) {
if (msi == HAL_MSIVEC_RXHP) {
OS_REG_WRITE(ah, AR_ISR, AR_ISR_HP_RXOK);
*masked = HAL_INT_RXHP;
goto end;
} else if (msi == HAL_MSIVEC_RXLP) {
OS_REG_WRITE(ah, AR_ISR,
(AR_ISR_LP_RXOK | AR_ISR_RXMINTR | AR_ISR_RXINTM));
*masked = HAL_INT_RXLP;
goto end;
} else if (msi == HAL_MSIVEC_TX) {
OS_REG_WRITE(ah, AR_ISR, AR_ISR_TXOK);
*masked = HAL_INT_TX;
goto end;
} else if (msi == HAL_MSIVEC_MISC) {
/*
* For the misc MSI event fall through and determine the cause.
*/
}
}
}
/* Make sure mac interrupt is pending in async interrupt cause register */
async_cause = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE));
if (async_cause & AR_INTR_ASYNC_USED) {
/*
* RTC may not be on since it runs on a slow 32khz clock
* so check its status to be sure
*/
if (!nortc &&
(OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
AR_RTC_STATUS_ON)
{
isr = OS_REG_READ(ah, AR_ISR);
}
}
if (AR_SREV_POSEIDON(ah)) {
sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
}
else if (AR_SREV_WASP(ah)) {
sync_en_def = AR9340_INTR_SYNC_DEFAULT;
}
sync_cause =
OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)) &
(sync_en_def | AR_INTR_SYNC_MASK_GPIO);
if (!isr && !sync_cause && !async_cause) {
ret_val = AH_FALSE;
goto end;
}
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: isr=0x%x, sync_cause=0x%x, async_cause=0x%x\n",
__func__,
isr,
sync_cause,
async_cause);
if (isr) {
if (isr & AR_ISR_BCNMISC) {
u_int32_t isr2;
isr2 = OS_REG_READ(ah, AR_ISR_S2);
/* Translate ISR bits to HAL values */
mask2 |= ((isr2 & AR_ISR_S2_TIM) >> MAP_ISR_S2_HAL_TIM);
mask2 |= ((isr2 & AR_ISR_S2_DTIM) >> MAP_ISR_S2_HAL_DTIM);
mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >> MAP_ISR_S2_HAL_DTIMSYNC);
mask2 |= ((isr2 & AR_ISR_S2_CABEND) >> MAP_ISR_S2_HAL_CABEND);
mask2 |= ((isr2 & AR_ISR_S2_GTT) << MAP_ISR_S2_HAL_GTT);
mask2 |= ((isr2 & AR_ISR_S2_CST) << MAP_ISR_S2_HAL_CST);
mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >> MAP_ISR_S2_HAL_TSFOOR);
mask2 |= ((isr2 & AR_ISR_S2_BBPANIC) >> MAP_ISR_S2_HAL_BBPANIC);
if (!p_cap->halIsrRacSupport) {
/*
* EV61133 (missing interrupts due to ISR_RAC):
* If not using ISR_RAC, clear interrupts by writing to ISR_S2.
* This avoids a race condition where a new BCNMISC interrupt
* could come in between reading the ISR and clearing the
* interrupt via the primary ISR. We therefore clear the
* interrupt via the secondary, which avoids this race.
*/
OS_REG_WRITE(ah, AR_ISR_S2, isr2);
isr &= ~AR_ISR_BCNMISC;
}
}
/* Use AR_ISR_RAC only if chip supports it.
* See EV61133 (missing interrupts due to ISR_RAC)
*/
if (p_cap->halIsrRacSupport) {
isr = OS_REG_READ(ah, AR_ISR_RAC);
}
if (isr == 0xffffffff) {
*masked = 0;
ret_val = AH_FALSE;
goto end;
}
*masked = isr & HAL_INT_COMMON;
/*
* When interrupt mitigation is switched on, we fake a normal RX or TX
* interrupt when we received a mitigated interrupt. This way, the upper
* layer do not need to know about feature.
*/
if (ahp->ah_intr_mitigation_rx) {
/* Only Rx interrupt mitigation. No Tx intr. mitigation. */
if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) {
*masked |= HAL_INT_RXLP;
}
}
if (ahp->ah_intr_mitigation_tx) {
if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) {
*masked |= HAL_INT_TX;
}
}
if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) {
*masked |= HAL_INT_RXLP;
}
if (isr & AR_ISR_HP_RXOK) {
*masked |= HAL_INT_RXHP;
}
if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
*masked |= HAL_INT_TX;
if (!p_cap->halIsrRacSupport) {
u_int32_t s0, s1;
/*
* EV61133 (missing interrupts due to ISR_RAC):
* If not using ISR_RAC, clear interrupts by writing to
* ISR_S0/S1.
* This avoids a race condition where a new interrupt
* could come in between reading the ISR and clearing the
* interrupt via the primary ISR. We therefore clear the
* interrupt via the secondary, which avoids this race.
*/
s0 = OS_REG_READ(ah, AR_ISR_S0);
OS_REG_WRITE(ah, AR_ISR_S0, s0);
s1 = OS_REG_READ(ah, AR_ISR_S1);
OS_REG_WRITE(ah, AR_ISR_S1, s1);
isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL);
}
}
/*
* Do not treat receive overflows as fatal for owl.
*/
if (isr & AR_ISR_RXORN) {
#if __PKT_SERIOUS_ERRORS__
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: receive FIFO overrun interrupt\n", __func__);
#endif
}
#if 0
/* XXX Verify if this is fixed for Osprey */
if (!p_cap->halAutoSleepSupport) {
u_int32_t isr5 = OS_REG_READ(ah, AR_ISR_S5_S);
if (isr5 & AR_ISR_S5_TIM_TIMER) {
*masked |= HAL_INT_TIM_TIMER;
}
}
#endif
if (isr & AR_ISR_GENTMR) {
u_int32_t s5;
if (p_cap->halIsrRacSupport) {
/* Use secondary shadow registers if using ISR_RAC */
s5 = OS_REG_READ(ah, AR_ISR_S5_S);
} else {
s5 = OS_REG_READ(ah, AR_ISR_S5);
}
if (isr & AR_ISR_GENTMR) {
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: GENTIMER, ISR_RAC=0x%x ISR_S2_S=0x%x\n", __func__,
isr, s5);
ahp->ah_intr_gen_timer_trigger =
MS(s5, AR_ISR_S5_GENTIMER_TRIG);
ahp->ah_intr_gen_timer_thresh =
MS(s5, AR_ISR_S5_GENTIMER_THRESH);
if (ahp->ah_intr_gen_timer_trigger) {
*masked |= HAL_INT_GENTIMER;
}
}
if (!p_cap->halIsrRacSupport) {
/*
* EV61133 (missing interrupts due to ISR_RAC):
* If not using ISR_RAC, clear interrupts by writing to ISR_S5.
* This avoids a race condition where a new interrupt
* could come in between reading the ISR and clearing the
* interrupt via the primary ISR. We therefore clear the
* interrupt via the secondary, which avoids this race.
*/
OS_REG_WRITE(ah, AR_ISR_S5, s5);
isr &= ~AR_ISR_GENTMR;
}
}
*masked |= mask2;
if (!p_cap->halIsrRacSupport) {
/*
* EV61133 (missing interrupts due to ISR_RAC):
* If not using ISR_RAC, clear the interrupts we've read by
* writing back ones in these locations to the primary ISR
* (except for interrupts that have a secondary isr register -
* see above).
*/
OS_REG_WRITE(ah, AR_ISR, isr);
/* Flush prior write */
(void) OS_REG_READ(ah, AR_ISR);
}
#ifdef AH_SUPPORT_AR9300
if (*masked & HAL_INT_BBPANIC) {
ar9300_handle_bb_panic(ah);
}
#endif
}
if (async_cause) {
if (nortc) {
OS_REG_WRITE(ah,
AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE_CLR), async_cause);
/* Flush prior write */
(void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE_CLR));
} else {
#ifdef ATH_GPIO_USE_ASYNC_CAUSE
if (async_cause & AR_INTR_ASYNC_CAUSE_GPIO) {
ahp->ah_gpio_cause = (async_cause & AR_INTR_ASYNC_CAUSE_GPIO) >>
AR_INTR_ASYNC_ENABLE_GPIO_S;
*masked |= HAL_INT_GPIO;
}
#endif
}
#if ATH_SUPPORT_MCI
if ((async_cause & AR_INTR_ASYNC_CAUSE_MCI) &&
p_cap->halMciSupport)
{
u_int32_t int_raw, int_rx_msg;
int_rx_msg = OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
int_raw = OS_REG_READ(ah, AR_MCI_INTERRUPT_RAW);
if ((int_raw == 0xdeadbeef) || (int_rx_msg == 0xdeadbeef))
{
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
"(MCI) Get 0xdeadbeef during MCI int processing"
"new int_raw=0x%08x, new rx_msg_raw=0x%08x, "
"int_raw=0x%08x, rx_msg_raw=0x%08x\n",
int_raw, int_rx_msg, ahp->ah_mci_int_raw,
ahp->ah_mci_int_rx_msg);
}
else {
if (ahp->ah_mci_int_raw || ahp->ah_mci_int_rx_msg) {
ahp->ah_mci_int_rx_msg |= int_rx_msg;
ahp->ah_mci_int_raw |= int_raw;
}
else {
ahp->ah_mci_int_rx_msg = int_rx_msg;
ahp->ah_mci_int_raw = int_raw;
}
*masked |= HAL_INT_MCI;
ahp->ah_mci_rx_status = OS_REG_READ(ah, AR_MCI_RX_STATUS);
if (int_rx_msg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) {
ahp->ah_mci_cont_status =
OS_REG_READ(ah, AR_MCI_CONT_STATUS);
}
OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
int_rx_msg);
OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, int_raw);
HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s:AR_INTR_SYNC_MCI\n", __func__);
}
}
#endif
}
if (sync_cause) {
int host1_fatal, host1_perr, radm_cpl_timeout, local_timeout;
host1_fatal = AR_SREV_WASP(ah) ?
AR9340_INTR_SYNC_HOST1_FATAL : AR9300_INTR_SYNC_HOST1_FATAL;
host1_perr = AR_SREV_WASP(ah) ?
AR9340_INTR_SYNC_HOST1_PERR : AR9300_INTR_SYNC_HOST1_PERR;
radm_cpl_timeout = AR_SREV_WASP(ah) ?
0x0 : AR9300_INTR_SYNC_RADM_CPL_TIMEOUT;
local_timeout = AR_SREV_WASP(ah) ?
AR9340_INTR_SYNC_LOCAL_TIMEOUT : AR9300_INTR_SYNC_LOCAL_TIMEOUT;
if (sync_cause & host1_fatal) {
#if __PKT_SERIOUS_ERRORS__
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
"%s: received PCI FATAL interrupt\n", __func__);
#endif
*masked |= HAL_INT_FATAL; /* Set FATAL INT flag here;*/
}
if (sync_cause & host1_perr) {
#if __PKT_SERIOUS_ERRORS__
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
"%s: received PCI PERR interrupt\n", __func__);
#endif
}
if (sync_cause & radm_cpl_timeout) {
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
__func__);
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), 0);
*masked |= HAL_INT_FATAL;
}
if (sync_cause & local_timeout) {
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
__func__);
}
#ifndef ATH_GPIO_USE_ASYNC_CAUSE
if (sync_cause & AR_INTR_SYNC_MASK_GPIO) {
ahp->ah_gpio_cause = (sync_cause & AR_INTR_SYNC_MASK_GPIO) >>
AR_INTR_SYNC_ENABLE_GPIO_S;
*masked |= HAL_INT_GPIO;
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: AR_INTR_SYNC_GPIO\n", __func__);
}
#endif
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR), sync_cause);
/* Flush prior write */
(void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR));
}
end:
if (HAL_INT_MSI == type) {
/*
* WAR for Bug EV#75887
* In normal case, SW read HOST_INTF_PCIE_MSI (0x40A4) and write
* into ah_msi_reg. Then use value of ah_msi_reg to set bit#25
* when want to enable HW write the cfg_msi_pending.
* Sometimes, driver get MSI interrupt before read 0x40a4 and
* ah_msi_reg is initialization value (0x0).
* We don't know why "MSI interrupt earlier than driver read" now...
*/
if (!ahp->ah_msi_reg) {
ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI));
}
if (AR_SREV_POSEIDON(ah)) {
msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
} else {
msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR;
}
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI),
((ahp->ah_msi_reg | AR_PCIE_MSI_ENABLE) & msi_pend_addr_mask));
}
return ret_val;
}
HAL_INT
ar9300_get_interrupts(struct ath_hal *ah)
{
return AH9300(ah)->ah_mask_reg;
}
/*
* Atomically enables NIC interrupts. Interrupts are passed in
* via the enumerated bitmask in ints.
*/
HAL_INT
ar9300_set_interrupts(struct ath_hal *ah, HAL_INT ints, HAL_BOOL nortc)
{
struct ath_hal_9300 *ahp = AH9300(ah);
u_int32_t omask = ahp->ah_mask_reg;
u_int32_t mask, mask2, msi_mask = 0;
u_int32_t msi_pend_addr_mask = 0;
u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: 0x%x => 0x%x\n", __func__, omask, ints);
if (omask & HAL_INT_GLOBAL) {
HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: disable IER\n", __func__);
if (ah->ah_config.ath_hal_enable_msi) {
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0);
/* flush write to HW */
(void)OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE));
}
if (!nortc) {
OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
(void) OS_REG_READ(ah, AR_IER); /* flush write to HW */
}
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
/* flush write to HW */
(void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE));
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE), 0);
/* flush write to HW */
(void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE));
}
if (!nortc) {
/* reference count for global IER */
if (ints & HAL_INT_GLOBAL) {
#ifdef AH_DEBUG
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: Request HAL_INT_GLOBAL ENABLED\n", __func__);
#if 0
if (OS_ATOMIC_READ(&ahp->ah_ier_ref_count) == 0) {
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
"%s: WARNING: ah_ier_ref_count is 0 "
"and attempting to enable IER\n",
__func__);
}
#endif
#endif
#if 0
if (OS_ATOMIC_READ(&ahp->ah_ier_ref_count) > 0) {
OS_ATOMIC_DEC(&ahp->ah_ier_ref_count);
}
#endif
} else {
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: Request HAL_INT_GLOBAL DISABLED\n", __func__);
OS_ATOMIC_INC(&ahp->ah_ier_ref_count);
}
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: ah_ier_ref_count = %d\n", __func__, ahp->ah_ier_ref_count);
mask = ints & HAL_INT_COMMON;
mask2 = 0;
msi_mask = 0;
if (ints & HAL_INT_TX) {
if (ahp->ah_intr_mitigation_tx) {
mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
} else if (ahp->ah_tx_ok_interrupt_mask) {
mask |= AR_IMR_TXOK;
}
msi_mask |= AR_INTR_PRIO_TX;
if (ahp->ah_tx_err_interrupt_mask) {
mask |= AR_IMR_TXERR;
}
if (ahp->ah_tx_eol_interrupt_mask) {
mask |= AR_IMR_TXEOL;
}
}
if (ints & HAL_INT_RX) {
mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
if (ahp->ah_intr_mitigation_rx) {
mask &= ~(AR_IMR_RXOK_LP);
mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
} else {
mask |= AR_IMR_RXOK_LP;
}
msi_mask |= AR_INTR_PRIO_RXLP | AR_INTR_PRIO_RXHP;
if (! p_cap->halAutoSleepSupport) {
mask |= AR_IMR_GENTMR;
}
}
if (ints & (HAL_INT_BMISC)) {
mask |= AR_IMR_BCNMISC;
if (ints & HAL_INT_TIM) {
mask2 |= AR_IMR_S2_TIM;
}
if (ints & HAL_INT_DTIM) {
mask2 |= AR_IMR_S2_DTIM;
}
if (ints & HAL_INT_DTIMSYNC) {
mask2 |= AR_IMR_S2_DTIMSYNC;
}
if (ints & HAL_INT_CABEND) {
mask2 |= (AR_IMR_S2_CABEND);
}
if (ints & HAL_INT_TSFOOR) {
mask2 |= AR_IMR_S2_TSFOOR;
}
}
if (ints & (HAL_INT_GTT | HAL_INT_CST)) {
mask |= AR_IMR_BCNMISC;
if (ints & HAL_INT_GTT) {
mask2 |= AR_IMR_S2_GTT;
}
if (ints & HAL_INT_CST) {
mask2 |= AR_IMR_S2_CST;
}
}
if (ints & HAL_INT_BBPANIC) {
/* EV92527 - MAC secondary interrupt must enable AR_IMR_BCNMISC */
mask |= AR_IMR_BCNMISC;
mask2 |= AR_IMR_S2_BBPANIC;
}
if (ints & HAL_INT_GENTIMER) {
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: enabling gen timer\n", __func__);
mask |= AR_IMR_GENTMR;
}
/* Write the new IMR and store off our SW copy. */
HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask);
OS_REG_WRITE(ah, AR_IMR, mask);
ahp->ah_mask2Reg &= ~(AR_IMR_S2_TIM |
AR_IMR_S2_DTIM |
AR_IMR_S2_DTIMSYNC |
AR_IMR_S2_CABEND |
AR_IMR_S2_CABTO |
AR_IMR_S2_TSFOOR |
AR_IMR_S2_GTT |
AR_IMR_S2_CST |
AR_IMR_S2_BBPANIC);
ahp->ah_mask2Reg |= mask2;
OS_REG_WRITE(ah, AR_IMR_S2, ahp->ah_mask2Reg );
ahp->ah_mask_reg = ints;
if (! p_cap->halAutoSleepSupport) {
if (ints & HAL_INT_TIM_TIMER) {
OS_REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
}
else {
OS_REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
}
}
}
/* Re-enable interrupts if they were enabled before. */
#if HAL_INTR_REFCOUNT_DISABLE
if ((ints & HAL_INT_GLOBAL)) {
#else
if ((ints & HAL_INT_GLOBAL) && (OS_ATOMIC_READ(&ahp->ah_ier_ref_count) == 0)) {
#endif
HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: enable IER\n", __func__);
if (!nortc) {
OS_REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
}
mask = AR_INTR_MAC_IRQ;
#ifdef ATH_GPIO_USE_ASYNC_CAUSE
if (ints & HAL_INT_GPIO) {
if (ahp->ah_gpio_mask) {
mask |= SM(ahp->ah_gpio_mask, AR_INTR_ASYNC_MASK_GPIO);
}
}
#endif
#if ATH_SUPPORT_MCI
if (ints & HAL_INT_MCI) {
mask |= AR_INTR_ASYNC_MASK_MCI;
}
#endif
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE), mask);
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK), mask);
if (ah->ah_config.ath_hal_enable_msi) {
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE),
msi_mask);
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK),
msi_mask);
if (AR_SREV_POSEIDON(ah)) {
msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
} else {
msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR;
}
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI),
((ahp->ah_msi_reg | AR_PCIE_MSI_ENABLE) & msi_pend_addr_mask));
}
/*
* debug - enable to see all synchronous interrupts status
* Enable synchronous GPIO interrupts as well, since some async
* GPIO interrupts don't wake the chip up.
*/
mask = 0;
#ifndef ATH_GPIO_USE_ASYNC_CAUSE
if (ints & HAL_INT_GPIO) {
mask |= SM(ahp->ah_gpio_mask, AR_INTR_SYNC_MASK_GPIO);
}
#endif
if (AR_SREV_POSEIDON(ah)) {
sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
}
else if (AR_SREV_WASP(ah)) {
sync_en_def = AR9340_INTR_SYNC_DEFAULT;
}
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE),
(sync_en_def | mask));
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK),
(sync_en_def | mask));
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"AR_IMR 0x%x IER 0x%x\n",
OS_REG_READ(ah, AR_IMR), OS_REG_READ(ah, AR_IER));
}
return omask;
}
void
ar9300_set_intr_mitigation_timer(
struct ath_hal* ah,
HAL_INT_MITIGATION reg,
u_int32_t value)
{
#ifdef AR5416_INT_MITIGATION
switch (reg) {
case HAL_INT_THRESHOLD:
OS_REG_WRITE(ah, AR_MIRT, 0);
break;
case HAL_INT_RX_LASTPKT:
OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, value);
break;
case HAL_INT_RX_FIRSTPKT:
OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, value);
break;
case HAL_INT_TX_LASTPKT:
OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, value);
break;
case HAL_INT_TX_FIRSTPKT:
OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, value);
break;
default:
break;
}
#endif
}
u_int32_t
ar9300_get_intr_mitigation_timer(struct ath_hal* ah, HAL_INT_MITIGATION reg)
{
u_int32_t val = 0;
#ifdef AR5416_INT_MITIGATION
switch (reg) {
case HAL_INT_THRESHOLD:
val = OS_REG_READ(ah, AR_MIRT);
break;
case HAL_INT_RX_LASTPKT:
val = OS_REG_READ(ah, AR_RIMT) & 0xFFFF;
break;
case HAL_INT_RX_FIRSTPKT:
val = OS_REG_READ(ah, AR_RIMT) >> 16;
break;
case HAL_INT_TX_LASTPKT:
val = OS_REG_READ(ah, AR_TIMT) & 0xFFFF;
break;
case HAL_INT_TX_FIRSTPKT:
val = OS_REG_READ(ah, AR_TIMT) >> 16;
break;
default:
break;
}
#endif
return val;
}
@@ -0,0 +1,438 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
/*
* Note: The key cache hardware requires that each double-word
* pair be written in even/odd order (since the destination is
* a 64-bit register). Don't reorder the writes in this code
* w/o considering this!
*/
#define KEY_XOR 0xaa
#define IS_MIC_ENABLED(ah) \
(AH9300(ah)->ah_sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
/*
* This isn't the keytable type; this is actually something separate
* for the TX descriptor.
*/
static const int keyType[] = {
1, /* HAL_CIPHER_WEP */
0, /* HAL_CIPHER_AES_OCB */
2, /* HAL_CIPHER_AES_CCM */
0, /* HAL_CIPHER_CKIP */
3, /* HAL_CIPHER_TKIP */
0 /* HAL_CIPHER_CLR */
};
/*
* Return the size of the hardware key cache.
*/
u_int32_t
ar9300_get_key_cache_size(struct ath_hal *ah)
{
return AH_PRIVATE(ah)->ah_caps.halKeyCacheSize;
}
/*
* Return AH_TRUE if the specific key cache entry is valid.
*/
HAL_BOOL
ar9300_is_key_cache_entry_valid(struct ath_hal *ah, u_int16_t entry)
{
if (entry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) {
u_int32_t val = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry));
if (val & AR_KEYTABLE_VALID) {
return AH_TRUE;
}
}
return AH_FALSE;
}
/*
* Clear the specified key cache entry and any associated MIC entry.
*/
HAL_BOOL
ar9300_reset_key_cache_entry(struct ath_hal *ah, u_int16_t entry)
{
u_int32_t key_type;
struct ath_hal_9300 *ahp = AH9300(ah);
if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) {
HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
"%s: entry %u out of range\n", __func__, entry);
return AH_FALSE;
}
ahp->ah_keytype[entry] = keyType[HAL_CIPHER_CLR];
key_type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry));
/* XXX why not clear key type/valid bit first? */
OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) {
u_int16_t micentry = entry + 64; /* MIC goes at slot+64 */
HALASSERT(micentry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
/* NB: key type and MAC are known to be ok */
}
if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) {
return AH_TRUE;
}
if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL)
== HAL_OK) {
if (key_type == AR_KEYTABLE_TYPE_TKIP ||
key_type == AR_KEYTABLE_TYPE_40 ||
key_type == AR_KEYTABLE_TYPE_104 ||
key_type == AR_KEYTABLE_TYPE_128) {
/* SW WAR for Bug 31602 */
if (--ahp->ah_rifs_sec_cnt == 0) {
HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
"%s: Count = %d, enabling RIFS\n",
__func__, ahp->ah_rifs_sec_cnt);
ar9300_set_rifs_delay(ah, AH_TRUE);
}
}
}
return AH_TRUE;
}
/*
* Sets the mac part of the specified key cache entry (and any
* associated MIC entry) and mark them valid.
*/
HAL_BOOL
ar9300_set_key_cache_entry_mac(
struct ath_hal *ah,
u_int16_t entry,
const u_int8_t *mac)
{
u_int32_t mac_hi, mac_lo;
u_int32_t unicast_addr = AR_KEYTABLE_VALID;
if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) {
HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
"%s: entry %u out of range\n", __func__, entry);
return AH_FALSE;
}
/*
* Set MAC address -- shifted right by 1. mac_lo is
* the 4 MSBs, and mac_hi is the 2 LSBs.
*/
if (mac != AH_NULL) {
/*
* If upper layers have requested mcast MACaddr lookup, then
* signify this to the hw by setting the (poorly named) valid_bit
* to 0. Yes, really 0. The hardware specs, pcu_registers.txt, is
* has incorrectly named valid_bit. It should be called "Unicast".
* When the Key Cache entry is to decrypt Unicast frames, this bit
* should be '1'; for multicast and broadcast frames, this bit is '0'.
*/
if (mac[0] & 0x01) {
unicast_addr = 0; /* Not an unicast address */
}
mac_hi = (mac[5] << 8) | mac[4];
mac_lo = (mac[3] << 24) | (mac[2] << 16)
| (mac[1] << 8) | mac[0];
mac_lo >>= 1; /* Note that the bit 0 is shifted out. This bit is used to
* indicate that this is a multicast key cache. */
mac_lo |= (mac_hi & 1) << 31; /* carry */
mac_hi >>= 1;
} else {
mac_lo = mac_hi = 0;
}
OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), mac_lo);
OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), mac_hi | unicast_addr);
return AH_TRUE;
}
/*
* Sets the contents of the specified key cache entry
* and any associated MIC entry.
*/
HAL_BOOL
ar9300_set_key_cache_entry(struct ath_hal *ah, u_int16_t entry,
const HAL_KEYVAL *k, const u_int8_t *mac,
int xor_key)
{
const HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
u_int32_t key0, key1, key2, key3, key4;
u_int32_t key_type;
u_int32_t xor_mask = xor_key ?
(KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0;
struct ath_hal_9300 *ahp = AH9300(ah);
u_int32_t pwrmgt, pwrmgt_mic, uapsd_cfg, psta = 0;
int is_proxysta_key = k->kv_type & HAL_KEY_PROXY_STA_MASK;
if (entry >= p_cap->halKeyCacheSize) {
HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
"%s: entry %u out of range\n", __func__, entry);
return AH_FALSE;
}
HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s[%d] mac %s proxy %d\n",
__func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null",
is_proxysta_key);
switch (k->kv_type & AH_KEYTYPE_MASK) {
case HAL_CIPHER_AES_OCB:
key_type = AR_KEYTABLE_TYPE_AES;
break;
case HAL_CIPHER_AES_CCM:
if (!p_cap->halCipherAesCcmSupport) {
HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: AES-CCM not supported by "
"mac rev 0x%x\n",
__func__, AH_PRIVATE(ah)->ah_macRev);
return AH_FALSE;
}
key_type = AR_KEYTABLE_TYPE_CCM;
break;
case HAL_CIPHER_TKIP:
key_type = AR_KEYTABLE_TYPE_TKIP;
if (IS_MIC_ENABLED(ah) && entry + 64 >= p_cap->halKeyCacheSize) {
HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
"%s: entry %u inappropriate for TKIP\n",
__func__, entry);
return AH_FALSE;
}
break;
case HAL_CIPHER_WEP:
if (k->kv_len < 40 / NBBY) {
HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: WEP key length %u too small\n",
__func__, k->kv_len);
return AH_FALSE;
}
if (k->kv_len <= 40 / NBBY) {
key_type = AR_KEYTABLE_TYPE_40;
} else if (k->kv_len <= 104 / NBBY) {
key_type = AR_KEYTABLE_TYPE_104;
} else {
key_type = AR_KEYTABLE_TYPE_128;
}
break;
case HAL_CIPHER_CLR:
key_type = AR_KEYTABLE_TYPE_CLR;
break;
default:
HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: cipher %u not supported\n",
__func__, k->kv_type);
return AH_FALSE;
}
key0 = LE_READ_4(k->kv_val + 0) ^ xor_mask;
key1 = (LE_READ_2(k->kv_val + 4) ^ xor_mask) & 0xffff;
key2 = LE_READ_4(k->kv_val + 6) ^ xor_mask;
key3 = (LE_READ_2(k->kv_val + 10) ^ xor_mask) & 0xffff;
key4 = LE_READ_4(k->kv_val + 12) ^ xor_mask;
if (k->kv_len <= 104 / NBBY) {
key4 &= 0xff;
}
/* Extract the UAPSD AC bits and shift it appropriately */
uapsd_cfg = k->kv_apsd;
uapsd_cfg = (u_int32_t) SM(uapsd_cfg, AR_KEYTABLE_UAPSD);
/* Need to preserve the power management bit used by MAC */
pwrmgt = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEYTABLE_PWRMGT;
if (is_proxysta_key) {
u_int8_t bcast_mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
if (!mac || OS_MEMCMP(mac, bcast_mac, 6)) {
psta = AR_KEYTABLE_DIR_ACK_BIT;
}
}
/*
* Note: key cache hardware requires that each double-word
* pair be written in even/odd order (since the destination is
* a 64-bit register). Don't reorder these writes w/o
* considering this!
*/
if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) {
u_int16_t micentry = entry + 64; /* MIC goes at slot+64 */
/* Need to preserve the power management bit used by MAC */
pwrmgt_mic =
OS_REG_READ(ah, AR_KEYTABLE_TYPE(micentry)) & AR_KEYTABLE_PWRMGT;
/*
* Invalidate the encrypt/decrypt key until the MIC
* key is installed so pending rx frames will fail
* with decrypt errors rather than a MIC error.
*/
OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry),
key_type | pwrmgt | uapsd_cfg | psta);
ar9300_set_key_cache_entry_mac(ah, entry, mac);
/*
* since the AR_MISC_MODE register was written with the contents of
* ah_misc_mode (if any) in ar9300_attach, just check ah_misc_mode and
* save a pci read per key set.
*/
if (ahp->ah_misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
u_int32_t mic0, mic1, mic2, mic3, mic4;
/*
* both RX and TX mic values can be combined into
* one cache slot entry.
* 8*N + 800 31:0 RX Michael key 0
* 8*N + 804 15:0 TX Michael key 0 [31:16]
* 8*N + 808 31:0 RX Michael key 1
* 8*N + 80C 15:0 TX Michael key 0 [15:0]
* 8*N + 810 31:0 TX Michael key 1
* 8*N + 814 15:0 reserved
* 8*N + 818 31:0 reserved
* 8*N + 81C 14:0 reserved
* 15 key valid == 0
*/
/* RX mic */
mic0 = LE_READ_4(k->kv_mic + 0);
mic2 = LE_READ_4(k->kv_mic + 4);
/* TX mic */
mic1 = LE_READ_2(k->kv_txmic + 2) & 0xffff;
mic3 = LE_READ_2(k->kv_txmic + 0) & 0xffff;
mic4 = LE_READ_4(k->kv_txmic + 4);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
AR_KEYTABLE_TYPE_CLR | pwrmgt_mic | uapsd_cfg);
} else {
u_int32_t mic0, mic2;
mic0 = LE_READ_4(k->kv_mic + 0);
mic2 = LE_READ_4(k->kv_mic + 4);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
OS_REG_WRITE(ah,
AR_KEYTABLE_TYPE(micentry | pwrmgt_mic | uapsd_cfg),
AR_KEYTABLE_TYPE_CLR);
}
/* NB: MIC key is not marked valid and has no MAC address */
OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
/* correct intentionally corrupted key */
OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
} else {
OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry),
key_type | pwrmgt | uapsd_cfg | psta);
/*
ath_hal_printf(ah, "%s[%d] mac %s proxy %d\n",
__func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null",
is_proxysta_key);
*/
ar9300_set_key_cache_entry_mac(ah, entry, mac);
}
ahp->ah_keytype[entry] = keyType[k->kv_type];
HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: entry=%d, k->kv_type=%d,"
"keyType=%d\n", __func__, entry, k->kv_type, keyType[k->kv_type]);
if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) {
return AH_TRUE;
}
if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL)
== HAL_OK) {
if (key_type == AR_KEYTABLE_TYPE_TKIP ||
key_type == AR_KEYTABLE_TYPE_40 ||
key_type == AR_KEYTABLE_TYPE_104 ||
key_type == AR_KEYTABLE_TYPE_128) {
/* SW WAR for Bug 31602 */
ahp->ah_rifs_sec_cnt++;
HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
"%s: Count = %d, disabling RIFS\n",
__func__, ahp->ah_rifs_sec_cnt);
ar9300_set_rifs_delay(ah, AH_FALSE);
}
}
HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s[%d] mac %s proxy %d\n",
__func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null",
is_proxysta_key);
return AH_TRUE;
}
/*
* Enable the Keysearch for every subframe of an aggregate
*/
void
ar9300_enable_keysearch_always(struct ath_hal *ah, int enable)
{
u_int32_t val;
if (!ah) {
return;
}
val = OS_REG_READ(ah, AR_PCU_MISC);
if (enable) {
val |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
} else {
val &= ~AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
}
OS_REG_WRITE(ah, AR_PCU_MISC, val);
}
void ar9300_dump_keycache(struct ath_hal *ah, int n, u_int32_t *entry)
{
#define AH_KEY_REG_SIZE 8
int i;
for (i = 0; i < AH_KEY_REG_SIZE; i++) {
entry[i] = OS_REG_READ(ah, AR_KEYTABLE_KEY0(n) + i * 4);
}
#undef AH_KEY_REG_SIZE
}
@@ -0,0 +1,601 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_desc.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300phy.h"
#include "ar9300/ar9300reg.h"
/*
* Default 5413/9300 radar phy parameters
* Values adjusted to fix EV76432/EV76320
*/
#define AR9300_DFS_FIRPWR -28
#define AR9300_DFS_RRSSI 0
#define AR9300_DFS_HEIGHT 10
#define AR9300_DFS_PRSSI 6
#define AR9300_DFS_INBAND 8
#define AR9300_DFS_RELPWR 8
#define AR9300_DFS_RELSTEP 12
#define AR9300_DFS_MAXLEN 255
/*
* This PRSSI value should be used during CAC.
*/
#define AR9300_DFS_PRSSI_CAC 10
/*
* make sure that value matches value in ar9300_osprey_2p2_mac_core[][2]
* for register 0x1040 to 0x104c
*/
#define AR9300_DEFAULT_DIFS 0x002ffc0f
#define AR9300_FCC_RADARS_FCC_OFFSET 4
struct dfs_pulse ar9300_etsi_radars[] = {
/* for short pulses, RSSI threshold should be smaller than
* Kquick-drop. The chip has only one chance to drop the gain which
* will be reported as the estimated RSSI */
/* TYPE staggered pulse */
/* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */
{30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, /* Type 5*/
/* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */
{30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, /* Type 6 */
/* constant PRF based */
/* 0.8-5us, 200 300 PRF, 10 pulses */
{10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, /* Type 1 */
{10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, /* Type 1 */
{10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, /* Type 1 */
{10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, /* Type 1 */
// {10, 5, 200, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33},
/* 0.8-15us, 200-1600 PRF, 15 pulses */
{15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 34}, /* Type 2 */
/* 0.8-15us, 2300-4000 PRF, 25 pulses*/
{25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 35}, /* Type 3 */
/* 20-30us, 2000-4000 PRF, 20 pulses*/
{20, 30, 2000, 4000, 0, 24, 8, 19, 33, 24, 0, 0, 0, 36}, /* Type 4 */
};
/* The following are for FCC Bin 1-4 pulses */
struct dfs_pulse ar9300_fcc_radars[] = {
/* following two filters are specific to Japan/MKK4 */
// {18, 1, 720, 720, 1, 6, 6, 0, 1, 18, 0, 3, 0, 17}, // 1389 +/- 6 us
// {18, 4, 250, 250, 1, 10, 5, 1, 6, 18, 0, 3, 0, 18}, // 4000 +/- 6 us
// {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 0, 19}, // 3846 +/- 7 us
{18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, // 1389 +/- 6 us
{18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, // 4000 +/- 6 us
{18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, // 3846 +/- 7 us
// {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 1, 20}, // 3846 +/- 7 us
{18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 1, 20}, // 3846 +/- 7 us
/* following filters are common to both FCC and JAPAN */
// FCC TYPE 1
// {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0, 0}, // 518 to 3066
{18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 8},
{18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0},
// FCC TYPE 6
// {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 0, 1}, // 333 +/- 7 us
//{9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 0, 1},
{9, 1, 3003, 3003, 0, 7, 5, 0, 1, 18, 0, 0, 1, 1},
// FCC TYPE 2
{23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2},
// FCC TYPE 3
{18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5},
// FCC TYPE 4
{16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11},
};
struct dfs_bin5pulse ar9300_bin5pulses[] = {
{2, 28, 105, 12, 22, 5},
};
#if 0
/*
* Find the internal HAL channel corresponding to the
* public HAL channel specified in c
*/
static HAL_CHANNEL_INTERNAL *
getchannel(struct ath_hal *ah, const struct ieee80211_channel *c)
{
#define CHAN_FLAGS (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER)
HAL_CHANNEL_INTERNAL *base, *cc;
int flags = c->channel_flags & CHAN_FLAGS;
int n, lim;
/*
* Check current channel to avoid the lookup.
*/
cc = AH_PRIVATE(ah)->ah_curchan;
if (cc != AH_NULL && cc->channel == c->channel &&
(cc->channel_flags & CHAN_FLAGS) == flags) {
return cc;
}
/* binary search based on known sorting order */
base = AH_TABLES(ah)->ah_channels;
n = AH_PRIVATE(ah)->ah_nchan;
/* binary search based on known sorting order */
for (lim = n; lim != 0; lim >>= 1) {
int d;
cc = &base[lim >> 1];
d = c->channel - cc->channel;
if (d == 0) {
if ((cc->channel_flags & CHAN_FLAGS) == flags) {
return cc;
}
d = flags - (cc->channel_flags & CHAN_FLAGS);
}
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: channel %u/0x%x d %d\n", __func__,
cc->channel, cc->channel_flags, d);
if (d > 0) {
base = cc + 1;
lim--;
}
}
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: no match for %u/0x%x\n",
__func__, c->channel, c->channel_flags);
return AH_NULL;
#undef CHAN_FLAGS
}
/*
* Check the internal channel list to see if the desired channel
* is ok to release from the NOL. If not, then do nothing. If so,
* mark the channel as clear and reset the internal tsf time
*/
void
ar9300_check_dfs(struct ath_hal *ah, struct ieee80211_channel *chan)
{
HAL_CHANNEL_INTERNAL *ichan = AH_NULL;
ichan = getchannel(ah, chan);
if (ichan == AH_NULL) {
return;
}
if (!(ichan->priv_flags & CHANNEL_INTERFERENCE)) {
return;
}
ichan->priv_flags &= ~CHANNEL_INTERFERENCE;
ichan->dfs_tsf = 0;
}
/*
* This function marks the channel as having found a dfs event
* It also marks the end time that the dfs event should be cleared
* If the channel is already marked, then tsf end time can only
* be increased
*/
void
ar9300_dfs_found(struct ath_hal *ah, struct ieee80211_channel *chan, u_int64_t nol_time)
{
HAL_CHANNEL_INTERNAL *ichan;
ichan = getchannel(ah, chan);
if (ichan == AH_NULL) {
return;
}
if (!(ichan->priv_flags & CHANNEL_INTERFERENCE)) {
ichan->dfs_tsf = ar9300_get_tsf64(ah);
}
ichan->dfs_tsf += nol_time;
ichan->priv_flags |= CHANNEL_INTERFERENCE;
chan->priv_flags |= CHANNEL_INTERFERENCE;
}
#endif
/*
* Enable radar detection and set the radar parameters per the
* values in pe
*/
void
ar9300_enable_dfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
{
u_int32_t val;
struct ath_hal_private *ahp = AH_PRIVATE(ah);
const struct ieee80211_channel *chan = ahp->ah_curchan;
struct ath_hal_9300 *ah9300 = AH9300(ah);
int reg_writes = 0;
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
val |= AR_PHY_RADAR_0_FFT_ENA | AR_PHY_RADAR_0_ENA;
if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_FIRPWR;
val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
}
if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_RRSSI;
val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
}
if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_HEIGHT;
val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
}
if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_PRSSI;
if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
#if 0
if (ah->ah_use_cac_prssi) {
val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI);
} else {
#endif
val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
// }
} else {
val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
}
}
if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_INBAND;
val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
}
OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
val = OS_REG_READ(ah, AR_PHY_RADAR_1);
val |= AR_PHY_RADAR_1_MAX_RRSSI | AR_PHY_RADAR_1_BLOCK_CHECK;
if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_1_MAXLEN;
val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN);
}
if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH;
val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH);
}
if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_1_RELPWR_THRESH;
val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH);
}
OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
if (ath_hal_getcapability(ah, HAL_CAP_EXT_CHAN_DFS, 0, 0) == HAL_OK) {
val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
if (IEEE80211_IS_CHAN_HT40(chan)) {
/* Enable extension channel radar detection */
OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val | AR_PHY_RADAR_EXT_ENA);
} else {
/* HT20 mode, disable extension channel radar detect */
OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);
}
}
/*
apply DFS postamble array from INI
column 0 is register ID, column 1 is HT20 value, colum2 is HT40 value
*/
if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_OSPREY_22(ah) || AR_SREV_SCORPION(ah)) {
REG_WRITE_ARRAY(&ah9300->ah_ini_dfs, IEEE80211_IS_CHAN_HT40(chan)? 2:1, reg_writes);
}
#ifdef ATH_HAL_DFS_CHIRPING_FIX_APH128
ath_hal_printf(ah, "DFS change the timing value\n");
if (AR_SREV_AR9580(ah) && IEEE80211_IS_CHAN_HT40(chan)) {
OS_REG_WRITE(ah, AR_PHY_TIMING6, 0x3140c00a);
}
#endif
}
/*
* Get the radar parameter values and return them in the pe
* structure
*/
void
ar9300_get_dfs_thresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
{
u_int32_t val, temp;
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
temp = MS(val, AR_PHY_RADAR_0_FIRPWR);
temp |= ~(AR_PHY_RADAR_0_FIRPWR >> AR_PHY_RADAR_0_FIRPWR_S);
pe->pe_firpwr = temp;
pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI);
pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT);
pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI);
pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND);
val = OS_REG_READ(ah, AR_PHY_RADAR_1);
pe->pe_relpwr = MS(val, AR_PHY_RADAR_1_RELPWR_THRESH);
pe->pe_enrelpwr = !! (val & AR_PHY_RADAR_1_RELPWR_ENA);
pe->pe_relstep = MS(val, AR_PHY_RADAR_1_RELSTEP_THRESH);
pe->pe_en_relstep_check = !! (val & AR_PHY_RADAR_1_RELSTEP_CHECK);
pe->pe_maxlen = MS(val, AR_PHY_RADAR_1_MAXLEN);
}
#if 0
HAL_BOOL
ar9300_radar_wait(struct ath_hal *ah, struct ieee80211_channel *chan)
{
struct ath_hal_private *ahp = AH_PRIVATE(ah);
if (!ahp->ah_curchan) {
return AH_TRUE;
}
/*
* Rely on the upper layers to determine that we have spent
* enough time waiting.
*/
chan->channel = ahp->ah_curchan->channel;
chan->channel_flags = ahp->ah_curchan->channel_flags;
chan->max_reg_tx_power = ahp->ah_curchan->max_reg_tx_power;
ahp->ah_curchan->priv_flags |= CHANNEL_DFS_CLEAR;
chan->priv_flags = ahp->ah_curchan->priv_flags;
return AH_FALSE;
}
#endif
struct dfs_pulse *
ar9300_get_dfs_radars(
struct ath_hal *ah,
u_int32_t dfsdomain,
int *numradars,
struct dfs_bin5pulse **bin5pulses,
int *numb5radars,
HAL_PHYERR_PARAM *pe)
{
struct dfs_pulse *dfs_radars = AH_NULL;
switch (dfsdomain) {
case HAL_DFS_FCC_DOMAIN:
dfs_radars = &ar9300_fcc_radars[AR9300_FCC_RADARS_FCC_OFFSET];
*numradars =
ARRAY_LENGTH(ar9300_fcc_radars) - AR9300_FCC_RADARS_FCC_OFFSET;
*bin5pulses = &ar9300_bin5pulses[0];
*numb5radars = ARRAY_LENGTH(ar9300_bin5pulses);
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: DFS_FCC_DOMAIN_9300\n", __func__);
break;
case HAL_DFS_ETSI_DOMAIN:
dfs_radars = &ar9300_etsi_radars[0];
*numradars = ARRAY_LENGTH(ar9300_etsi_radars);
*bin5pulses = &ar9300_bin5pulses[0];
*numb5radars = ARRAY_LENGTH(ar9300_bin5pulses);
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: DFS_ETSI_DOMAIN_9300\n", __func__);
break;
case HAL_DFS_MKK4_DOMAIN:
dfs_radars = &ar9300_fcc_radars[0];
*numradars = ARRAY_LENGTH(ar9300_fcc_radars);
*bin5pulses = &ar9300_bin5pulses[0];
*numb5radars = ARRAY_LENGTH(ar9300_bin5pulses);
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: DFS_MKK4_DOMAIN_9300\n", __func__);
break;
default:
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: no domain\n", __func__);
return AH_NULL;
}
/* Set the default phy parameters per chip */
pe->pe_firpwr = AR9300_DFS_FIRPWR;
pe->pe_rrssi = AR9300_DFS_RRSSI;
pe->pe_height = AR9300_DFS_HEIGHT;
pe->pe_prssi = AR9300_DFS_PRSSI;
/*
we have an issue with PRSSI.
For normal operation we use AR9300_DFS_PRSSI, which is set to 6.
Please refer to EV91563, 94164.
However, this causes problem during CAC as no radar is detected
during that period with PRSSI=6. Only PRSSI= 10 seems to fix this.
We use this flag to keep track of change in PRSSI.
*/
// ah->ah_use_cac_prssi = 0;
pe->pe_inband = AR9300_DFS_INBAND;
pe->pe_relpwr = AR9300_DFS_RELPWR;
pe->pe_relstep = AR9300_DFS_RELSTEP;
pe->pe_maxlen = AR9300_DFS_MAXLEN;
return dfs_radars;
}
void ar9300_adjust_difs(struct ath_hal *ah, u_int32_t val)
{
if (val == 0) {
/*
* EV 116936:
* Restore the register values with that of the HAL structure.
* Do not assume and overwrite these values to whatever
* is in ar9300_osprey22.ini.
*/
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_TX_QUEUE_INFO *qi;
int q;
AH9300(ah)->ah_fccaifs = 0;
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: restore DIFS \n", __func__);
for (q = 0; q < 4; q++) {
qi = &ahp->ah_txq[q];
OS_REG_WRITE(ah, AR_DLCL_IFS(q),
SM(qi->tqi_cwmin, AR_D_LCL_IFS_CWMIN)
| SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
| SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
}
} else {
/*
* These are values from George Lai and are specific to
* FCC domain. They are yet to be determined for other domains.
*/
AH9300(ah)->ah_fccaifs = 1;
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: set DIFS to default\n", __func__);
/*printk("%s: modify DIFS\n", __func__);*/
OS_REG_WRITE(ah, AR_DLCL_IFS(0), 0x05fffc0f);
OS_REG_WRITE(ah, AR_DLCL_IFS(1), 0x05f0fc0f);
OS_REG_WRITE(ah, AR_DLCL_IFS(2), 0x05f03c07);
OS_REG_WRITE(ah, AR_DLCL_IFS(3), 0x05f01c03);
}
}
u_int32_t ar9300_dfs_config_fft(struct ath_hal *ah, HAL_BOOL is_enable)
{
u_int32_t val;
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
if (is_enable) {
val |= AR_PHY_RADAR_0_FFT_ENA;
} else {
val &= ~AR_PHY_RADAR_0_FFT_ENA;
}
OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
return val;
}
/*
function to adjust PRSSI value for CAC problem
*/
void
ar9300_dfs_cac_war(struct ath_hal *ah, u_int32_t start)
{
u_int32_t val;
if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
if (start) {
val &= ~AR_PHY_RADAR_0_PRSSI;
val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI);
} else {
val &= ~AR_PHY_RADAR_0_PRSSI;
val |= SM(AR9300_DFS_PRSSI, AR_PHY_RADAR_0_PRSSI);
}
OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA);
// ah->ah_use_cac_prssi = start;
}
}
#if 0
struct ieee80211_channel *
ar9300_get_extension_channel(struct ath_hal *ah)
{
struct ath_hal_private *ahp = AH_PRIVATE(ah);
struct ath_hal_private_tables *aht = AH_TABLES(ah);
int i = 0;
HAL_CHANNEL_INTERNAL *ichan = AH_NULL;
CHAN_CENTERS centers;
ichan = ahp->ah_curchan;
ar9300_get_channel_centers(ah, ichan, &centers);
if (centers.ctl_center == centers.ext_center) {
return AH_NULL;
}
for (i = 0; i < ahp->ah_nchan; i++) {
ichan = &aht->ah_channels[i];
if (ichan->channel == centers.ext_center) {
return (struct ieee80211_channel*)ichan;
}
}
return AH_NULL;
}
#endif
HAL_BOOL
ar9300_is_fast_clock_enabled(struct ath_hal *ah)
{
struct ath_hal_private *ahp = AH_PRIVATE(ah);
if (IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan)) {
return AH_TRUE;
}
return AH_FALSE;
}
/*
* This should be enabled and linked into the build once
* radar support is enabled.
*/
#if 0
HAL_BOOL
ar9300_handle_radar_bb_panic(struct ath_hal *ah)
{
u_int32_t status;
u_int32_t val;
#ifdef AH_DEBUG
struct ath_hal_9300 *ahp = AH9300(ah);
#endif
status = AH_PRIVATE(ah)->ah_bb_panic_last_status;
if ( status == 0x04000539 ) {
/* recover from this BB panic without reset*/
/* set AR9300_DFS_FIRPWR to -1 */
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
val &= (~AR_PHY_RADAR_0_FIRPWR);
val |= SM( 0x7f, AR_PHY_RADAR_0_FIRPWR);
OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
OS_DELAY(1);
/* set AR9300_DFS_FIRPWR to its default value */
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
val &= ~AR_PHY_RADAR_0_FIRPWR;
val |= SM( AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR);
OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
return AH_TRUE;
} else if (status == 0x0400000a) {
/* EV 92527 : reset required if we see this signature */
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x0400000a\n", __func__);
return AH_FALSE;
} else if (status == 0x1300000a) {
/* EV92527: we do not need a reset if we see this signature */
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x1300000a\n", __func__);
return AH_TRUE;
} else if (AR_SREV_WASP(ah) && (status == 0x04000409)) {
return AH_TRUE;
} else {
if (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK &&
(status & 0xff00000f) == 0x04000009 &&
status != 0x04000409 &&
status != 0x04000b09 &&
status != 0x04000e09 &&
(status & 0x0000ff00))
{
/* disable RIFS Rx */
#ifdef AH_DEBUG
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: BB status=0x%08x rifs=%d - disable\n",
__func__, status, ahp->ah_rifs_enabled);
ar9300_set_rifs_delay(ah, AH_FALSE);
}
return AH_FALSE;
}
}
#endif
#endif
@@ -0,0 +1,267 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300phy.h"
/* chansel table, used by Hornet and Poseidon */
static const u_int32_t ar9300_chansel_xtal_25M[] = {
0x101479e, /* Freq 2412 - (128 << 17) + 83870 */
0x101d027, /* Freq 2417 - (128 << 17) + 118823 */
0x10258af, /* Freq 2422 - (129 << 17) + 22703 */
0x102e138, /* Freq 2427 - (129 << 17) + 57656 */
0x10369c0, /* Freq 2432 - (129 << 17) + 92608 */
0x103f249, /* Freq 2437 - (129 << 17) + 127561 */
0x1047ad1, /* Freq 2442 - (130 << 17) + 31441 */
0x105035a, /* Freq 2447 - (130 << 17) + 66394 */
0x1058be2, /* Freq 2452 - (130 << 17) + 101346 */
0x106146b, /* Freq 2457 - (131 << 17) + 5227 */
0x1069cf3, /* Freq 2462 - (131 << 17) + 40179 */
0x107257c, /* Freq 2467 - (131 << 17) + 75132 */
0x107ae04, /* Freq 2472 - (131 << 17) + 110084 */
0x108f5b2, /* Freq 2484 - (132 << 17) + 62898 */
};
static const u_int32_t ar9300_chansel_xtal_40M[] = {
0xa0ccbe, /* Freq 2412 - (80 << 17) + 52414 */
0xa12213, /* Freq 2417 - (80 << 17) + 74259 */
0xa17769, /* Freq 2422 - (80 << 17) + 96105 */
0xa1ccbe, /* Freq 2427 - (80 << 17) + 117950 */
0xa22213, /* Freq 2432 - (81 << 17) + 8723 */
0xa27769, /* Freq 2437 - (81 << 17) + 30569 */
0xa2ccbe, /* Freq 2442 - (81 << 17) + 52414 */
0xa32213, /* Freq 2447 - (81 << 17) + 74259 */
0xa37769, /* Freq 2452 - (81 << 17) + 96105 */
0xa3ccbe, /* Freq 2457 - (81 << 17) + 117950 */
0xa42213, /* Freq 2462 - (82 << 17) + 8723 */
0xa47769, /* Freq 2467 - (82 << 17) + 30569 */
0xa4ccbe, /* Freq 2472 - (82 << 17) + 52414 */
0xa5998b, /* Freq 2484 - (82 << 17) + 104843 */
};
/*
* 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>>amode_ref_sel))
*
* 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
ar9300_set_channel(struct ath_hal *ah, struct ieee80211_channel *chan)
{
u_int16_t b_mode, frac_mode = 0, a_mode_ref_sel = 0;
u_int32_t freq, channel_sel, reg32;
u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz;
CHAN_CENTERS centers;
int load_synth_channel;
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
/*
* Put this behind AH_DEBUG_ALQ for now until the Hornet
* channel_sel code below is made to work.
*/
#ifdef AH_DEBUG_ALQ
OS_MARK(ah, AH_MARK_SETCHANNEL, ichan->channel);
#endif
ar9300_get_channel_centers(ah, chan, &centers);
freq = centers.synth_center;
if (freq < 4800) { /* 2 GHz, fractional mode */
b_mode = 1; /* 2 GHz */
if (AR_SREV_HORNET(ah)) {
#if 0
u_int32_t ichan =
ieee80211_mhz2ieee(ah, chan->ic_freq, chan->ic_flags);
HALASSERT(ichan > 0 && ichan <= 14);
if (clk_25mhz) {
channel_sel = ar9300_chansel_xtal_25M[ichan - 1];
} else {
channel_sel = ar9300_chansel_xtal_40M[ichan - 1];
}
#endif
uint32_t i;
i = ath_hal_mhz2ieee_2ghz(ah, ichan);
HALASSERT(i > 0 && i <= 14);
if (clk_25mhz) {
channel_sel = ar9300_chansel_xtal_25M[i - 1];
} else {
channel_sel = ar9300_chansel_xtal_40M[i - 1];
}
} else if (AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
u_int32_t channel_frac;
/*
* freq_ref = (40 / (refdiva >> a_mode_ref_sel));
* (where refdiva = 1 and amoderefsel = 0)
* ndiv = ((chan_mhz * 4) / 3) / freq_ref;
* chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
*/
channel_sel = (freq * 4) / 120;
channel_frac = (((freq * 4) % 120) * 0x20000) / 120;
channel_sel = (channel_sel << 17) | (channel_frac);
} else if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
u_int32_t channel_frac;
if (clk_25mhz) {
/*
* freq_ref = (50 / (refdiva >> a_mode_ref_sel));
* (where refdiva = 1 and amoderefsel = 0)
* ndiv = ((chan_mhz * 4) / 3) / freq_ref;
* chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
*/
if (AR_SREV_SCORPION(ah)) {
/* Doubler is off for Scorpion */
channel_sel = (freq * 4) / 75;
channel_frac = (((freq * 4) % 75) * 0x20000) / 75;
} else {
channel_sel = (freq * 2) / 75;
channel_frac = (((freq * 2) % 75) * 0x20000) / 75;
}
} else {
/*
* freq_ref = (50 / (refdiva >> a_mode_ref_sel));
* (where refdiva = 1 and amoderefsel = 0)
* ndiv = ((chan_mhz * 4) / 3) / freq_ref;
* chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
*/
if (AR_SREV_SCORPION(ah)) {
/* Doubler is off for Scorpion */
channel_sel = (freq * 4) / 120;
channel_frac = (((freq * 4) % 120) * 0x20000) / 120;
} else {
channel_sel = (freq * 2) / 120;
channel_frac = (((freq * 2) % 120) * 0x20000) / 120;
}
}
channel_sel = (channel_sel << 17) | (channel_frac);
} else {
channel_sel = CHANSEL_2G(freq);
}
} else {
b_mode = 0; /* 5 GHz */
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && clk_25mhz){
u_int32_t channel_frac;
/*
* freq_ref = (50 / (refdiva >> amoderefsel));
* (refdiva = 1, amoderefsel = 0)
* ndiv = ((chan_mhz * 2) / 3) / freq_ref;
* chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
*/
channel_sel = freq / 75 ;
channel_frac = ((freq % 75) * 0x20000) / 75;
channel_sel = (channel_sel << 17) | (channel_frac);
} else {
channel_sel = CHANSEL_5G(freq);
/* Doubler is ON, so, divide channel_sel by 2. */
channel_sel >>= 1;
}
}
/* Enable fractional mode for all channels */
frac_mode = 1;
a_mode_ref_sel = 0;
load_synth_channel = 0;
reg32 = (b_mode << 29);
OS_REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
/* Enable Long shift Select for Synthesizer */
OS_REG_RMW_FIELD(ah,
AR_PHY_65NM_CH0_SYNTH4, AR_PHY_SYNTH4_LONG_SHIFT_SELECT, 1);
/* program synth. setting */
reg32 =
(channel_sel << 2) |
(a_mode_ref_sel << 28) |
(frac_mode << 30) |
(load_synth_channel << 31);
if (IEEE80211_IS_CHAN_QUARTER(chan)) {
reg32 += CHANSEL_5G_DOT5MHZ;
}
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
/* Toggle Load Synth channel bit */
load_synth_channel = 1;
reg32 |= load_synth_channel << 31;
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
AH_PRIVATE(ah)->ah_curchan = chan;
return AH_TRUE;
}
#if 0
static HAL_BOOL
ar9300_get_chip_power_limits(struct ath_hal *ah, HAL_CHANNEL *chans,
u_int32_t nchans)
{
int i;
for (i = 0; i < nchans; i++) {
chans[i].max_tx_power = AR9300_MAX_RATE_POWER;
chans[i].min_tx_power = AR9300_MAX_RATE_POWER;
}
return AH_TRUE;
}
#endif
/* XXX FreeBSD */
static HAL_BOOL
ar9300_get_chip_power_limits(struct ath_hal *ah,
struct ieee80211_channel *chan)
{
/* XXX ? */
chan->ic_minpower = 0;
chan->ic_maxpower = AR9300_MAX_RATE_POWER;
return AH_TRUE;
}
HAL_BOOL
ar9300_rf_attach(struct ath_hal *ah, HAL_STATUS *status)
{
struct ath_hal_9300 *ahp = AH9300(ah);
ahp->ah_rf_hal.set_channel = ar9300_set_channel;
ahp->ah_rf_hal.get_chip_power_lim = ar9300_get_chip_power_limits;
*status = HAL_OK;
return AH_TRUE;
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* Copyright (c) 2002-2009 Atheros Communications, Inc.
* All Rights Reserved.
*
* Copyright (c) 2011 Qualcomm Atheros, Inc.
* All Rights Reserved.
* Qualcomm Atheros Confidential and Proprietary.
*
*/
#include "opt_ah.h"
#ifdef AH_SUPPORT_AR9300
#include "ah.h"
#include "ah_desc.h"
#include "ah_internal.h"
#include "ar9300/ar9300phy.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300desc.h"
#else
/*
* Raw capture mode not enabled - insert dummy code to keep the compiler happy
*/
typedef int ar9300_dummy_adc_capture;
#endif /* AH_SUPPORT_AR9300*/
@@ -0,0 +1,337 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_desc.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300desc.h"
/*
* Get the RXDP.
*/
u_int32_t
ar9300_get_rx_dp(struct ath_hal *ath, HAL_RX_QUEUE qtype)
{
if (qtype == HAL_RX_QUEUE_HP) {
return OS_REG_READ(ath, AR_HP_RXDP);
} else {
return OS_REG_READ(ath, AR_LP_RXDP);
}
}
/*
* Set the rx_dp.
*/
void
ar9300_set_rx_dp(struct ath_hal *ah, u_int32_t rxdp, HAL_RX_QUEUE qtype)
{
HALASSERT((qtype == HAL_RX_QUEUE_HP) || (qtype == HAL_RX_QUEUE_LP));
if (qtype == HAL_RX_QUEUE_HP) {
OS_REG_WRITE(ah, AR_HP_RXDP, rxdp);
} else {
OS_REG_WRITE(ah, AR_LP_RXDP, rxdp);
}
}
/*
* Set Receive Enable bits.
*/
void
ar9300_enable_receive(struct ath_hal *ah)
{
OS_REG_WRITE(ah, AR_CR, 0);
}
/*
* Set the RX abort bit.
*/
HAL_BOOL
ar9300_set_rx_abort(struct ath_hal *ah, HAL_BOOL set)
{
if (set) {
/* Set the force_rx_abort bit */
OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
if ( AH9300(ah)->ah_reset_reason == HAL_RESET_BBPANIC ){
/* depending upon the BB panic status, rx state may not return to 0,
* so skipping the wait for BB panic reset */
OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
return AH_FALSE;
} else {
HAL_BOOL okay;
okay = ath_hal_wait(
ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0);
/* Wait for Rx state to return to 0 */
if (!okay) {
/* abort: chip rx failed to go idle in 10 ms */
OS_REG_CLR_BIT(ah, AR_DIAG_SW,
(AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
HALDEBUG(ah, HAL_DEBUG_RX,
"%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
__func__, OS_REG_READ(ah, AR_OBS_BUS_1));
return AH_FALSE; /* failure */
}
}
} else {
OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
}
return AH_TRUE; /* success */
}
/*
* Stop Receive at the DMA engine
*/
HAL_BOOL
ar9300_stop_dma_receive(struct ath_hal *ah, u_int timeout)
{
int wait;
HAL_BOOL status, okay;
u_int32_t org_value;
#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
#define AH_TIME_QUANTUM 100 /* usec */
if (timeout == 0) {
timeout = AH_RX_STOP_DMA_TIMEOUT;
}
org_value = OS_REG_READ(ah, AR_MACMISC);
OS_REG_WRITE(ah, AR_MACMISC,
((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
(AR_MACMISC_MISC_OBS_BUS_1 << AR_MACMISC_MISC_OBS_BUS_MSB_S)));
okay = ath_hal_wait(
ah, AR_DMADBG_7, AR_DMADBG_RX_STATE, 0);
/* wait for Rx DMA state machine to become idle */
if (!okay) {
HALDEBUG(ah, HAL_DEBUG_RX,
"reg AR_DMADBG_7 is not 0, instead 0x%08x\n",
OS_REG_READ(ah, AR_DMADBG_7));
}
/* Set receive disable bit */
OS_REG_WRITE(ah, AR_CR, AR_CR_RXD);
/* Wait for rx enable bit to go low */
for (wait = timeout / AH_TIME_QUANTUM; wait != 0; wait--) {
if ((OS_REG_READ(ah, AR_CR) & AR_CR_RXE) == 0) {
break;
}
OS_DELAY(AH_TIME_QUANTUM);
}
if (wait == 0) {
HALDEBUG(ah, HAL_DEBUG_RX, "%s: dma failed to stop in %d ms\n"
"AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
__func__,
timeout / 1000,
OS_REG_READ(ah, AR_CR),
OS_REG_READ(ah, AR_DIAG_SW));
status = AH_FALSE;
} else {
status = AH_TRUE;
}
OS_REG_WRITE(ah, AR_MACMISC, org_value);
return status;
#undef AH_RX_STOP_DMA_TIMEOUT
#undef AH_TIME_QUANTUM
}
/*
* Start Transmit at the PCU engine (unpause receive)
*/
void
ar9300_start_pcu_receive(struct ath_hal *ah, HAL_BOOL is_scanning)
{
ar9300_enable_mib_counters(ah);
ar9300_ani_reset(ah, is_scanning);
/* Clear RX_DIS and RX_ABORT after enabling phy errors in ani_reset */
OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
}
/*
* Stop Transmit at the PCU engine (pause receive)
*/
void
ar9300_stop_pcu_receive(struct ath_hal *ah)
{
OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
ar9300_disable_mib_counters(ah);
}
/*
* Set multicast filter 0 (lower 32-bits)
* filter 1 (upper 32-bits)
*/
void
ar9300_set_multicast_filter(
struct ath_hal *ah,
u_int32_t filter0,
u_int32_t filter1)
{
OS_REG_WRITE(ah, AR_MCAST_FIL0, filter0);
OS_REG_WRITE(ah, AR_MCAST_FIL1, filter1);
}
/*
* Get the receive filter.
*/
u_int32_t
ar9300_get_rx_filter(struct ath_hal *ah)
{
u_int32_t bits = OS_REG_READ(ah, AR_RX_FILTER);
u_int32_t phybits = OS_REG_READ(ah, AR_PHY_ERR);
if (phybits & AR_PHY_ERR_RADAR) {
bits |= HAL_RX_FILTER_PHYRADAR;
}
if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING)) {
bits |= HAL_RX_FILTER_PHYERR;
}
return bits;
}
/*
* Set the receive filter.
*/
void
ar9300_set_rx_filter(struct ath_hal *ah, u_int32_t bits)
{
u_int32_t phybits;
if (AR_SREV_SCORPION(ah)) {
/* Enable Rx for 4 address frames */
bits |= AR_RX_4ADDRESS;
}
if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
/* HW fix for rx hang and corruption. */
bits |= AR_RX_CONTROL_WRAPPER;
}
OS_REG_WRITE(ah, AR_RX_FILTER,
bits | AR_RX_UNCOM_BA_BAR | AR_RX_COMPR_BAR);
phybits = 0;
if (bits & HAL_RX_FILTER_PHYRADAR) {
phybits |= AR_PHY_ERR_RADAR;
}
if (bits & HAL_RX_FILTER_PHYERR) {
phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
}
OS_REG_WRITE(ah, AR_PHY_ERR, phybits);
if (phybits) {
OS_REG_WRITE(ah, AR_RXCFG,
OS_REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
} else {
OS_REG_WRITE(ah, AR_RXCFG,
OS_REG_READ(ah, AR_RXCFG) &~ AR_RXCFG_ZLFDMA);
}
}
/*
* Select to pass PLCP headr or EVM data.
*/
HAL_BOOL
ar9300_set_rx_sel_evm(struct ath_hal *ah, HAL_BOOL sel_evm, HAL_BOOL just_query)
{
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_BOOL old_value = ahp->ah_get_plcp_hdr == 0;
if (just_query) {
return old_value;
}
if (sel_evm) {
OS_REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
} else {
OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
}
ahp->ah_get_plcp_hdr = !sel_evm;
return old_value;
}
void ar9300_promisc_mode(struct ath_hal *ah, HAL_BOOL enable)
{
u_int32_t reg_val = 0;
reg_val = OS_REG_READ(ah, AR_RX_FILTER);
if (enable){
reg_val |= AR_RX_PROM;
} else{ /*Disable promisc mode */
reg_val &= ~AR_RX_PROM;
}
OS_REG_WRITE(ah, AR_RX_FILTER, reg_val);
}
void
ar9300_read_pktlog_reg(
struct ath_hal *ah,
u_int32_t *rxfilter_val,
u_int32_t *rxcfg_val,
u_int32_t *phy_err_mask_val,
u_int32_t *mac_pcu_phy_err_regval)
{
*rxfilter_val = OS_REG_READ(ah, AR_RX_FILTER);
*rxcfg_val = OS_REG_READ(ah, AR_RXCFG);
*phy_err_mask_val = OS_REG_READ(ah, AR_PHY_ERR);
*mac_pcu_phy_err_regval = OS_REG_READ(ah, 0x8338);
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
"%s[%d] rxfilter_val 0x%08x , rxcfg_val 0x%08x, "
"phy_err_mask_val 0x%08x mac_pcu_phy_err_regval 0x%08x\n",
__func__, __LINE__,
*rxfilter_val, *rxcfg_val, *phy_err_mask_val, *mac_pcu_phy_err_regval);
}
void
ar9300_write_pktlog_reg(
struct ath_hal *ah,
HAL_BOOL enable,
u_int32_t rxfilter_val,
u_int32_t rxcfg_val,
u_int32_t phy_err_mask_val,
u_int32_t mac_pcu_phy_err_reg_val)
{
if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
/* HW fix for rx hang and corruption. */
rxfilter_val |= AR_RX_CONTROL_WRAPPER;
}
if (enable) { /* Enable pktlog phyerr setting */
OS_REG_WRITE(ah, AR_RX_FILTER, 0xffff | AR_RX_COMPR_BAR | rxfilter_val);
OS_REG_WRITE(ah, AR_PHY_ERR, 0xFFFFFFFF);
OS_REG_WRITE(ah, AR_RXCFG, rxcfg_val | AR_RXCFG_ZLFDMA);
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, mac_pcu_phy_err_reg_val | 0xFF);
} else { /* Disable phyerr and Restore regs */
OS_REG_WRITE(ah, AR_RX_FILTER, rxfilter_val);
OS_REG_WRITE(ah, AR_PHY_ERR, phy_err_mask_val);
OS_REG_WRITE(ah, AR_RXCFG, rxcfg_val);
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, mac_pcu_phy_err_reg_val);
}
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
"%s[%d] ena %d rxfilter_val 0x%08x , rxcfg_val 0x%08x, "
"phy_err_mask_val 0x%08x mac_pcu_phy_err_regval 0x%08x\n",
__func__, __LINE__,
enable, rxfilter_val, rxcfg_val,
phy_err_mask_val, mac_pcu_phy_err_reg_val);
}
@@ -0,0 +1,195 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_desc.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300desc.h"
/*
* Process an RX descriptor, and return the status to the caller.
* Copy some hardware specific items into the software portion
* of the descriptor.
*
* NB: the caller is responsible for validating the memory contents
* of the descriptor (e.g. flushing any cached copy).
*/
HAL_STATUS
ar9300_proc_rx_desc_fast(struct ath_hal *ah, struct ath_desc *ds,
u_int32_t pa, struct ath_desc *nds, struct ath_rx_status *rxs,
void *buf_addr)
{
struct ar9300_rxs *rxsp = AR9300RXS(buf_addr);
/*
ath_hal_printf(ah,"CHH=RX: ds_info 0x%x status1: 0x%x status11: 0x%x\n",
rxsp->ds_info,rxsp->status1,rxsp->status11);
*/
if ((rxsp->status11 & AR_rx_done) == 0) {
return HAL_EINPROGRESS;
}
if (MS(rxsp->ds_info, AR_desc_id) != 0x168c) {
#if __PKT_SERIOUS_ERRORS__
/*BUG: 63564-HT */
HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "%s: Rx Descriptor error 0x%x\n",
__func__, rxsp->ds_info);
#endif
return HAL_EINVAL;
}
if ((rxsp->ds_info & (AR_tx_rx_desc | AR_ctrl_stat)) != 0) {
#if __PKT_SERIOUS_ERRORS__
HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
"%s: Rx Descriptor wrong info 0x%x\n", __func__, rxsp->ds_info);
#endif
return HAL_EINPROGRESS;
}
rxs->rs_status = 0;
rxs->rs_flags = 0;
rxs->rs_datalen = rxsp->status2 & AR_data_len;
rxs->rs_tstamp = rxsp->status3;
/* XXX what about key_cache_miss? */
rxs->rs_rssi = MS(rxsp->status5, AR_rx_rssi_combined);
rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_rx_rssi_ant00);
rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_rx_rssi_ant01);
rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_rx_rssi_ant02);
rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_rx_rssi_ant10);
rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_rx_rssi_ant11);
rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_rx_rssi_ant12);
if (rxsp->status11 & AR_rx_key_idx_valid) {
rxs->rs_keyix = MS(rxsp->status11, AR_key_idx);
} else {
rxs->rs_keyix = HAL_RXKEYIX_INVALID;
}
/* NB: caller expected to do rate table mapping */
rxs->rs_rate = MS(rxsp->status1, AR_rx_rate);
rxs->rs_more = (rxsp->status2 & AR_rx_more) ? 1 : 0;
rxs->rs_isaggr = (rxsp->status11 & AR_rx_aggr) ? 1 : 0;
rxs->rs_moreaggr = (rxsp->status11 & AR_rx_more_aggr) ? 1 : 0;
rxs->rs_antenna = (MS(rxsp->status4, AR_rx_antenna) & 0x7);
rxs->rs_flags = (rxsp->status11 & AR_apsd_trig) ? HAL_RX_IS_APSD : 0;
rxs->rs_flags |= (rxsp->status4 & AR_gi) ? HAL_RX_GI : 0;
rxs->rs_flags |= (rxsp->status4 & AR_2040) ? HAL_RX_2040 : 0;
/* Copy EVM information */
rxs->rs_evm0 = rxsp->status6;
rxs->rs_evm1 = rxsp->status7;
rxs->rs_evm2 = rxsp->status8;
rxs->rs_evm3 = rxsp->status9;
rxs->rs_evm4 = (rxsp->status10 & 0xffff);
if (rxsp->status11 & AR_pre_delim_crc_err) {
rxs->rs_flags |= HAL_RX_DELIM_CRC_PRE;
}
if (rxsp->status11 & AR_post_delim_crc_err) {
rxs->rs_flags |= HAL_RX_DELIM_CRC_POST;
}
if (rxsp->status11 & AR_decrypt_busy_err) {
rxs->rs_flags |= HAL_RX_DECRYPT_BUSY;
}
if (rxsp->status11 & AR_hi_rx_chain) {
rxs->rs_flags |= HAL_RX_HI_RX_CHAIN;
}
if (rxsp->status11 & AR_key_miss) {
rxs->rs_status |= HAL_RXERR_KEYMISS;
}
if ((rxsp->status11 & AR_rx_frame_ok) == 0) {
/*
* These four bits should not be set together. The
* 9300 spec states a Michael error can only occur if
* decrypt_crc_err not set (and TKIP is used). Experience
* indicates however that you can also get Michael errors
* when a CRC error is detected, but these are specious.
* Consequently we filter them out here so we don't
* confuse and/or complicate drivers.
*/
if (rxsp->status11 & AR_crc_err) {
rxs->rs_status |= HAL_RXERR_CRC;
/*
* ignore CRC flag for spectral phy reports
*/
if (rxsp->status11 & AR_phyerr) {
u_int phyerr = MS(rxsp->status11, AR_phy_err_code);
if (phyerr == HAL_PHYERR_SPECTRAL) {
rxs->rs_status |= HAL_RXERR_PHY;
rxs->rs_phyerr = phyerr;
}
}
} else if (rxsp->status11 & AR_phyerr) {
u_int phyerr;
/*
* Packets with OFDM_RESTART on post delimiter are CRC OK and
* usable and MAC ACKs them.
* To avoid packet from being lost, we remove the PHY Err flag
* so that lmac layer does not drop them.
* (EV 70071)
*/
phyerr = MS(rxsp->status11, AR_phy_err_code);
if ((phyerr == HAL_PHYERR_OFDM_RESTART) &&
(rxsp->status11 & AR_post_delim_crc_err)) {
rxs->rs_phyerr = 0;
} else {
rxs->rs_status |= HAL_RXERR_PHY;
rxs->rs_phyerr = phyerr;
}
} else if (rxsp->status11 & AR_decrypt_crc_err) {
rxs->rs_status |= HAL_RXERR_DECRYPT;
} else if (rxsp->status11 & AR_michael_err) {
rxs->rs_status |= HAL_RXERR_MIC;
}
}
return HAL_OK;
}
HAL_STATUS
ar9300_proc_rx_desc(struct ath_hal *ah, struct ath_desc *ds,
u_int32_t pa, struct ath_desc *nds, u_int64_t tsf,
struct ath_rx_status *rxs)
{
return HAL_ENOTSUPP;
}
/*
* rx path in ISR is different for ar9300 from ar5416, and
* ath_rx_proc_descfast will not be called if edmasupport is true.
* So this function ath_hal_get_rxkeyidx will not be
* called for ar9300.
* This function in ar9300's HAL is just a stub one because we need
* to link something to the callback interface of the HAL module.
*/
HAL_STATUS
ar9300_get_rx_key_idx(struct ath_hal *ah, struct ath_desc *ds, u_int8_t *keyix,
u_int8_t *status)
{
*status = 0;
*keyix = HAL_RXKEYIX_INVALID;
return HAL_ENOTSUPP;
}
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#ifdef AH_SUPPORT_AR9300
#include "ah.h"
#include "ah_internal.h"
#include "ah_devid.h"
#include "ar9300.h"
#include "ar9300reg.h"
#include "ar9300phy.h"
#include "ar9300desc.h"
#endif /* AH_SUPPORT_AR9300 */
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "wbuf.h"
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#ifndef _ATH_AR9300_SIM_H_
#define _ATH_AR9300_SIM_H_
#endif // _ATH_AR9300_SIM_H_
@@ -0,0 +1,588 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#ifdef AH_SUPPORT_AR9300
#include "ah.h"
#include "ah_desc.h"
#include "ah_internal.h"
#include "ar9300/ar9300phy.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300desc.h"
#if ATH_SUPPORT_SPECTRAL
/*
* Default 9300 spectral scan parameters
*/
#define AR9300_SPECTRAL_SCAN_ENA 0
#define AR9300_SPECTRAL_SCAN_ACTIVE 0
#define AR9300_SPECTRAL_SCAN_FFT_PERIOD 8
#define AR9300_SPECTRAL_SCAN_PERIOD 1
#define AR9300_SPECTRAL_SCAN_COUNT 16 /* used to be 128 */
#define AR9300_SPECTRAL_SCAN_SHORT_REPEAT 1
/* constants */
#define MAX_RADAR_DC_PWR_THRESH 127
#define MAX_RADAR_RSSI_THRESH 0x3f
#define MAX_RADAR_HEIGHT 0x3f
#define MAX_CCA_THRESH 127
#define ENABLE_ALL_PHYERR 0xffffffff
void ar9300_disable_cck(struct ath_hal *ah);
void ar9300_disable_radar(struct ath_hal *ah);
void ar9300_disable_restart(struct ath_hal *ah);
void ar9300_set_radar_dc_thresh(struct ath_hal *ah);
void ar9300_disable_weak_signal(struct ath_hal *ah);
void ar9300_disable_strong_signal(struct ath_hal *ah);
void ar9300_prep_spectral_scan(struct ath_hal *ah);
void ar9300_disable_dc_offset(struct ath_hal *ah);
void ar9300_enable_cck_detect(struct ath_hal *ah);
void
ar9300_disable_cck(struct ath_hal *ah)
{
u_int32_t val;
val = OS_REG_READ(ah, AR_PHY_MODE);
val &= ~(AR_PHY_MODE_DYN_CCK_DISABLE);
OS_REG_WRITE(ah, AR_PHY_MODE, val);
}
void
ar9300_disable_radar(struct ath_hal *ah)
{
u_int32_t val;
/* Enable radar FFT */
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
val |= AR_PHY_RADAR_0_FFT_ENA;
/* set radar detect thresholds to max to effectively disable radar */
val &= ~AR_PHY_RADAR_0_RRSSI;
val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI);
val &= ~AR_PHY_RADAR_0_HEIGHT;
val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT);
val &= ~(AR_PHY_RADAR_0_ENA);
OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
/* disable extension radar detect */
val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);
val = OS_REG_READ(ah, AR_RX_FILTER);
val |= (1 << 13);
OS_REG_WRITE(ah, AR_RX_FILTER, val);
}
void ar9300_disable_restart(struct ath_hal *ah)
{
u_int32_t val;
val = OS_REG_READ(ah, AR_PHY_RESTART);
val &= ~AR_PHY_RESTART_ENA;
OS_REG_WRITE(ah, AR_PHY_RESTART, val);
val = OS_REG_READ(ah, AR_PHY_RESTART);
}
void ar9300_set_radar_dc_thresh(struct ath_hal *ah)
{
u_int32_t val;
val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
val &= ~AR_PHY_RADAR_DC_PWR_THRESH;
val |= SM(MAX_RADAR_DC_PWR_THRESH, AR_PHY_RADAR_DC_PWR_THRESH);
OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val);
val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
}
void
ar9300_disable_weak_signal(struct ath_hal *ah)
{
/* set firpwr to max (signed) */
OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR, 0x7f);
OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR_SIGN_BIT);
/* set firstep to max */
OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP, 0x3f);
/* set relpwr to max (signed) */
OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELPWR, 0x1f);
OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELPWR_SIGN_BIT);
/* set relstep to max (signed) */
OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELSTEP, 0x1f);
OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT);
/* set firpwr_low to max (signed) */
OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRPWR, 0x7f);
OS_REG_CLR_BIT(
ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRPWR_SIGN_BIT);
/* set firstep_low to max */
OS_REG_RMW_FIELD(
ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, 0x3f);
/* set relstep_low to max (signed) */
OS_REG_RMW_FIELD(
ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_RELSTEP, 0x1f);
OS_REG_CLR_BIT(
ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_RELSTEP_SIGN_BIT);
}
void
ar9300_disable_strong_signal(struct ath_hal *ah)
{
u_int32_t val;
val = OS_REG_READ(ah, AR_PHY_TIMING5);
val |= AR_PHY_TIMING5_RSSI_THR1A_ENA;
OS_REG_WRITE(ah, AR_PHY_TIMING5, val);
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_RSSI_THR1A, 0x7f);
}
void
ar9300_set_cca_threshold(struct ath_hal *ah, u_int8_t thresh62)
{
OS_REG_RMW_FIELD(ah, AR_PHY_CCA_0, AR_PHY_CCA_THRESH62, thresh62);
OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, thresh62);
/*
OS_REG_RMW_FIELD(ah,
AR_PHY_EXTCHN_PWRTHR1, AR_PHY_EXT_CCA0_THRESH62, thresh62);
*/
OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CCA_THRESH62, thresh62);
}
static void ar9300_classify_strong_bins(struct ath_hal *ah)
{
OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH, 0x1);
}
void ar9300_disable_dc_offset(struct ath_hal *ah)
{
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET, 0);
}
void ar9300_enable_cck_detect(struct ath_hal *ah)
{
OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK, 0);
OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DYNAMIC, 1);
}
void ar9300_prep_spectral_scan(struct ath_hal *ah)
{
ar9300_disable_radar(ah);
ar9300_classify_strong_bins(ah);
ar9300_disable_dc_offset(ah);
if (AH_PRIVATE(ah)->ah_curchan &&
IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan))
{ /* fast clock */
ar9300_enable_cck_detect(ah);
}
#ifdef DEMO_MODE
ar9300_disable_strong_signal(ah);
ar9300_disable_weak_signal(ah);
ar9300_set_radar_dc_thresh(ah);
ar9300_set_cca_threshold(ah, MAX_CCA_THRESH);
/*ar9300_disable_restart(ah);*/
#endif
OS_REG_WRITE(ah, AR_PHY_ERR, HAL_PHYERR_SPECTRAL);
}
//#define TEST_NOISE_PWR_WITHOUT_EEPROM 1
#ifdef TEST_NOISE_PWR_WITHOUT_EEPROM
struct nf_cal {
int cal;
int pwr;
};
struct nf_cal_table_t {
int freq;
struct nf_cal chain[AH_MAX_CHAINS];
};
static const struct nf_cal_table_t nf_cal_table[] =
{
/* ch 1 */ {2412, { {N2DBM(-101, 00), N2DBM( -94, 25)},
{N2DBM(-107, 75), N2DBM( -99, 75)},
} },
/* ch 6 */ {2437, { {N2DBM(-102, 25), N2DBM( -94, 25)},
{N2DBM(-106, 00), N2DBM( -97, 25)},
} },
/* ch 11 */ {2462, { {N2DBM(-101, 50), N2DBM( -95, 00)},
{N2DBM(-105, 50), N2DBM( -98, 00)},
} },
/* ch 36 */ {5180, { {N2DBM(-114, 25), N2DBM( -95, 00)},
{N2DBM(-114, 75), N2DBM( -94, 00)},
} },
/* ch 44 */ {5220, { {N2DBM(-113, 00), N2DBM( -95, 00)},
{N2DBM(-115, 00), N2DBM( -94, 50)},
} },
/* ch 64 */ {5320, { {N2DBM(-113, 00), N2DBM( -95, 00)}, // not cal'ed
{N2DBM(-115, 00), N2DBM( -94, 50)},
} },
/* ch 100*/ {5500, { {N2DBM(-111, 50), N2DBM( -93, 75)},
{N2DBM(-112, 00), N2DBM( -95, 25)},
} },
/* ch 120*/ {5600, { {N2DBM(-111, 50), N2DBM( -93, 75)},
{N2DBM(-112, 00), N2DBM( -95, 25)},
} },
/* ch 140*/ {5700, { {N2DBM(-111, 75), N2DBM( -95, 00)},
{N2DBM(-111, 75), N2DBM( -96, 00)},
} },
/* ch 157*/ {5785, { {N2DBM(-112, 50), N2DBM( -94, 75)},
{N2DBM(-111, 75), N2DBM( -95, 50)},
} },
/* ch 165*/ {5825, { {N2DBM(-111, 50), N2DBM( -95, 00)},
{N2DBM(-112, 00), N2DBM( -95, 00)},
} },
{0}
};
static int
ar9300_noise_floor_get(struct ath_hal *ah, int freq_mhz, int ch)
{
int i;
for (i = 0; nf_cal_table[i].freq != 0; i++) {
if (nf_cal_table[i + 0].freq == freq_mhz ||
nf_cal_table[i + 1].freq > freq_mhz ||
nf_cal_table[i + 1].freq == 0) {
return nf_cal_table[i].chain[ch].cal;
}
}
ath_hal_printf(ah,
"%s: **Warning: device %d.%d: "
"no nf cal offset found for freq %d chain %d\n",
__func__, (AH_PRIVATE(ah))->ah_macVersion,
(AH_PRIVATE(ah))->ah_macRev, freq_mhz, ch);
return 0;
}
static int
ar9300_noise_floor_power_get(struct ath_hal *ah, int freq_mhz, int ch)
{
int i;
for (i = 0; nf_cal_table[i].freq != 0; i++) {
if (nf_cal_table[i + 0].freq == freq_mhz ||
nf_cal_table[i + 1].freq > freq_mhz ||
nf_cal_table[i + 1].freq == 0) {
return nf_cal_table[i].chain[ch].pwr;
}
}
ath_hal_printf(ah,
"%s: **Warning: device %d.%d: "
"no nf pwr offset found for freq %d chain %d\n",
__func__, (AH_PRIVATE(ah))->ah_macVersion,
(AH_PRIVATE(ah))->ah_macRev, freq_mhz, ch);
return 0;
}
#else
#define ar9300_noise_floor_get(_ah,_f,_ich) ar9300_noise_floor_cal_or_power_get((_ah), (_f), (_ich), 1/*use_cal*/)
#define ar9300_noise_floor_power_get(_ah,_f,_ich) ar9300_noise_floor_cal_or_power_get((_ah), (_f), (_ich), 0/*use_cal*/)
#endif
void
ar9300_configure_spectral_scan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
{
u_int32_t val, i;
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_BOOL asleep = ahp->ah_chip_full_sleep;
int16_t nf_buf[NUM_NF_READINGS];
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
}
ar9300_prep_spectral_scan(ah);
if (ss->ss_spectral_pri) {
for (i = 0; i < NUM_NF_READINGS; i++) {
nf_buf[i] = NOISE_PWR_DBM_2_INT(ss->ss_nf_cal[i]);
}
ar9300_load_nf(ah, nf_buf);
#ifdef DEMO_MODE
ar9300_disable_strong_signal(ah);
ar9300_disable_weak_signal(ah);
ar9300_set_radar_dc_thresh(ah);
ar9300_set_cca_threshold(ah, MAX_CCA_THRESH);
/*ar9300_disable_restart(ah);*/
#endif
}
val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) {
val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD;
val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
}
if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
}
if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) {
val &= ~AR_PHY_SPECTRAL_SCAN_COUNT;
/* Remnants of a Merlin bug, 128 translates to 0 for
* continuous scanning. Instead we do piecemeal captures
* of 64 samples for Osprey.
*/
if (ss->ss_count == 128) {
val |= SM(0, AR_PHY_SPECTRAL_SCAN_COUNT);
} else {
val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT);
}
}
if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
}
if (ss->ss_short_report == AH_TRUE) {
val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
} else {
val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
}
/* if noise power cal, force high priority */
if (ss->ss_spectral_pri) {
val |= AR_PHY_SPECTRAL_SCAN_PRIORITY_HI;
} else {
val &= ~AR_PHY_SPECTRAL_SCAN_PRIORITY_HI;
}
/* enable spectral scan */
OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENABLE);
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
}
}
/*
* Get the spectral parameter values and return them in the pe
* structure
*/
void
ar9300_get_spectral_params(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
{
u_int32_t val;
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
int i, ichain, rx_chain_status;
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_BOOL asleep = ahp->ah_chip_full_sleep;
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
}
val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD);
ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT);
ss->ss_short_report = (val & AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT) ? 1:0;
ss->ss_spectral_pri = ( val & AR_PHY_SPECTRAL_SCAN_PRIORITY_HI) ? 1:0;
OS_MEMZERO(ss->ss_nf_cal, sizeof(ss->ss_nf_cal));
OS_MEMZERO(ss->ss_nf_pwr, sizeof(ss->ss_nf_cal));
ss->ss_nf_temp_data = 0;
if (chan != NULL) {
rx_chain_status = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK) & 0x7;
for (i = 0; i < NUM_NF_READINGS; i++) {
ichain = i % 3;
if (rx_chain_status & (1 << ichain)) {
ss->ss_nf_cal[i] =
ar9300_noise_floor_get(ah, chan->channel, ichain);
ss->ss_nf_pwr[i] =
ar9300_noise_floor_power_get(ah, chan->channel, ichain);
}
}
ss->ss_nf_temp_data = OS_REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, AR_PHY_BB_THERM_ADC_4_LATEST_THERM);
} else {
HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
"%s: chan is NULL - no ss nf values\n", __func__);
}
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
}
}
HAL_BOOL
ar9300_is_spectral_active(struct ath_hal *ah)
{
u_int32_t val;
val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE);
}
HAL_BOOL
ar9300_is_spectral_enabled(struct ath_hal *ah)
{
u_int32_t val;
val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
return MS(val, AR_PHY_SPECTRAL_SCAN_ENABLE);
}
void ar9300_start_spectral_scan(struct ath_hal *ah)
{
u_int32_t val;
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_BOOL asleep = ahp->ah_chip_full_sleep;
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
}
ar9300_prep_spectral_scan(ah);
/* activate spectral scan */
val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
/* This is a hardware bug fix, the enable and active bits should
* not be set/reset in the same write operation to the register
*/
if (!(val & AR_PHY_SPECTRAL_SCAN_ENABLE)) {
val |= AR_PHY_SPECTRAL_SCAN_ENABLE;
OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
}
val |= AR_PHY_SPECTRAL_SCAN_ACTIVE;
OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
/* Reset the PHY_ERR_MASK */
val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG);
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR);
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
}
}
void ar9300_stop_spectral_scan(struct ath_hal *ah)
{
u_int32_t val;
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_BOOL asleep = ahp->ah_chip_full_sleep;
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
}
val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
/* deactivate spectral scan */
/* HW Bug fix -- Do not disable the spectral scan
* only turn off the active bit
*/
//val &= ~AR_PHY_SPECTRAL_SCAN_ENABLE;
val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE;
OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH,
ahp->ah_radar1);
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET,
ahp->ah_dc_offset);
OS_REG_WRITE(ah, AR_PHY_ERR, 0);
if (AH_PRIVATE(ah)->ah_curchan &&
IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan))
{ /* fast clock */
OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK,
ahp->ah_disable_cck);
}
val = OS_REG_READ(ah, AR_PHY_ERR);
val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR);
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val);
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
}
}
u_int32_t ar9300_get_spectral_config(struct ath_hal *ah)
{
u_int32_t val;
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_BOOL asleep = ahp->ah_chip_full_sleep;
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
}
val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
}
return val;
}
int16_t ar9300_get_ctl_chan_nf(struct ath_hal *ah)
{
int16_t nf;
struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
if ( (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) {
/* Noise floor calibration value is ready */
nf = MS(OS_REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
} else {
/* NF calibration is not done, return nominal value */
nf = ahpriv->nfp->nominal;
}
if (nf & 0x100) {
nf = (0 - ((nf ^ 0x1ff) + 1));
}
return nf;
}
int16_t ar9300_get_ext_chan_nf(struct ath_hal *ah)
{
int16_t nf;
struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) {
/* Noise floor calibration value is ready */
nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
} else {
/* NF calibration is not done, return nominal value */
nf = ahpriv->nfp->nominal;
}
if (nf & 0x100) {
nf = (0 - ((nf ^ 0x1ff) + 1));
}
return nf;
}
#endif
#endif /* ATH_SUPPORT_SPECTRAL */
@@ -0,0 +1,171 @@
/*
* 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: head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c 235972 2012-05-25 05:01:27Z adrian $
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ah_devid.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300phy.h"
#include "ar9300/ar9300_stub.h"
#include "ar9300/ar9300_stub_funcs.h"
void
ar9300_set_stub_functions(struct ath_hal *ah)
{
ath_hal_printf(ah, "%s: setting stub functions\n", __func__);
ah->ah_getRateTable = ar9300_Stub_GetRateTable;
// ah->ah_detach = ar9300_Stub_detach;
/* Reset Functions */
ah->ah_reset = ar9300_Stub_Reset;
ah->ah_phyDisable = ar9300_Stub_PhyDisable;
ah->ah_disable = ar9300_Stub_Disable;
ah->ah_configPCIE = ar9300_Stub_ConfigPCIE;
ah->ah_disablePCIE = ar9300_Stub_DisablePCIE;
ah->ah_setPCUConfig = ar9300_Stub_SetPCUConfig;
ah->ah_perCalibration = ar9300_Stub_PerCalibration;
ah->ah_perCalibrationN = ar9300_Stub_PerCalibrationN;
ah->ah_resetCalValid = ar9300_Stub_ResetCalValid;
ah->ah_setTxPowerLimit = ar9300_Stub_SetTxPowerLimit;
ah->ah_getChanNoise = ath_hal_getChanNoise;
/* Transmit functions */
ah->ah_updateTxTrigLevel = ar9300_Stub_UpdateTxTrigLevel;
ah->ah_setupTxQueue = ar9300_Stub_SetupTxQueue;
ah->ah_setTxQueueProps = ar9300_Stub_SetTxQueueProps;
ah->ah_getTxQueueProps = ar9300_Stub_GetTxQueueProps;
ah->ah_releaseTxQueue = ar9300_Stub_ReleaseTxQueue;
ah->ah_resetTxQueue = ar9300_Stub_ResetTxQueue;
ah->ah_getTxDP = ar9300_Stub_GetTxDP;
ah->ah_setTxDP = ar9300_Stub_SetTxDP;
ah->ah_numTxPending = ar9300_Stub_NumTxPending;
ah->ah_startTxDma = ar9300_Stub_StartTxDma;
ah->ah_stopTxDma = ar9300_Stub_StopTxDma;
ah->ah_setupTxDesc = ar9300_Stub_SetupTxDesc;
ah->ah_setupXTxDesc = ar9300_Stub_SetupXTxDesc;
ah->ah_fillTxDesc = ar9300_Stub_FillTxDesc;
ah->ah_procTxDesc = ar9300_Stub_ProcTxDesc;
ah->ah_getTxIntrQueue = ar9300_Stub_GetTxIntrQueue;
ah->ah_reqTxIntrDesc = ar9300_Stub_IntrReqTxDesc;
ah->ah_getTxCompletionRates = ar9300_Stub_GetTxCompletionRates;
/* RX Functions */
ah->ah_getRxDP = ar9300_Stub_GetRxDP;
ah->ah_setRxDP = ar9300_Stub_SetRxDP;
ah->ah_enableReceive = ar9300_Stub_EnableReceive;
ah->ah_stopDmaReceive = ar9300_Stub_StopDmaReceive;
ah->ah_startPcuReceive = ar9300_Stub_StartPcuReceive;
ah->ah_stopPcuReceive = ar9300_Stub_StopPcuReceive;
ah->ah_setMulticastFilter = ar9300_Stub_SetMulticastFilter;
ah->ah_setMulticastFilterIndex = ar9300_Stub_SetMulticastFilterIndex;
ah->ah_clrMulticastFilterIndex = ar9300_Stub_ClrMulticastFilterIndex;
ah->ah_getRxFilter = ar9300_Stub_GetRxFilter;
ah->ah_setRxFilter = ar9300_Stub_SetRxFilter;
ah->ah_setupRxDesc = ar9300_Stub_SetupRxDesc;
ah->ah_procRxDesc = ar9300_Stub_ProcRxDesc;
ah->ah_rxMonitor = ar9300_Stub_RxMonitor;
ah->ah_aniPoll = ar9300_Stub_AniPoll;
ah->ah_procMibEvent = ar9300_Stub_ProcessMibIntr;
/* Misc Functions */
ah->ah_getCapability = ar9300_Stub_GetCapability;
ah->ah_setCapability = ar9300_Stub_SetCapability;
ah->ah_getDiagState = ar9300_Stub_GetDiagState;
ah->ah_getMacAddress = ar9300_Stub_GetMacAddress;
ah->ah_setMacAddress = ar9300_Stub_SetMacAddress;
ah->ah_getBssIdMask = ar9300_Stub_GetBssIdMask;
ah->ah_setBssIdMask = ar9300_Stub_SetBssIdMask;
ah->ah_setRegulatoryDomain = ar9300_Stub_SetRegulatoryDomain;
ah->ah_setLedState = ar9300_Stub_SetLedState;
ah->ah_writeAssocid = ar9300_Stub_WriteAssocid;
ah->ah_gpioCfgInput = ar9300_Stub_GpioCfgInput;
ah->ah_gpioCfgOutput = ar9300_Stub_GpioCfgOutput;
ah->ah_gpioGet = ar9300_Stub_GpioGet;
ah->ah_gpioSet = ar9300_Stub_GpioSet;
ah->ah_gpioSetIntr = ar9300_Stub_GpioSetIntr;
ah->ah_getTsf32 = ar9300_Stub_GetTsf32;
ah->ah_getTsf64 = ar9300_Stub_GetTsf64;
ah->ah_resetTsf = ar9300_Stub_ResetTsf;
ah->ah_detectCardPresent = ar9300_Stub_DetectCardPresent;
ah->ah_updateMibCounters = ar9300_Stub_UpdateMibCounters;
ah->ah_getRfGain = ar9300_Stub_GetRfgain;
ah->ah_getDefAntenna = ar9300_Stub_GetDefAntenna;
ah->ah_setDefAntenna = ar9300_Stub_SetDefAntenna;
ah->ah_getAntennaSwitch = ar9300_Stub_GetAntennaSwitch;
ah->ah_setAntennaSwitch = ar9300_Stub_SetAntennaSwitch;
ah->ah_setSifsTime = ar9300_Stub_SetSifsTime;
ah->ah_getSifsTime = ar9300_Stub_GetSifsTime;
ah->ah_setSlotTime = ar9300_Stub_SetSlotTime;
ah->ah_getSlotTime = ar9300_Stub_GetSlotTime;
ah->ah_setAckTimeout = ar9300_Stub_SetAckTimeout;
ah->ah_getAckTimeout = ar9300_Stub_GetAckTimeout;
ah->ah_setAckCTSRate = ar9300_Stub_SetAckCTSRate;
ah->ah_getAckCTSRate = ar9300_Stub_GetAckCTSRate;
ah->ah_setCTSTimeout = ar9300_Stub_SetCTSTimeout;
ah->ah_getCTSTimeout = ar9300_Stub_GetCTSTimeout;
ah->ah_setDecompMask = ar9300_Stub_SetDecompMask;
ah->ah_setCoverageClass = ar9300_Stub_SetCoverageClass;
ah->ah_setQuiet = ar9300_Stub_SetQuiet;
ah->ah_getMibCycleCounts = ar9300_Stub_GetMibCycleCounts;
/* DFS Functions */
ah->ah_enableDfs = ar9300_Stub_EnableDfs;
ah->ah_getDfsThresh = ar9300_Stub_GetDfsThresh;
ah->ah_procRadarEvent = ar9300_Stub_ProcessRadarEvent;
ah->ah_isFastClockEnabled = ar9300_Stub_IsFastClockEnabled;
ah->ah_get11nExtBusy = ar9300_Stub_Get11nExtBusy;
/* Key Cache Functions */
ah->ah_getKeyCacheSize = ar9300_Stub_GetKeyCacheSize;
ah->ah_resetKeyCacheEntry = ar9300_Stub_ResetKeyCacheEntry;
ah->ah_isKeyCacheEntryValid = ar9300_Stub_IsKeyCacheEntryValid;
ah->ah_setKeyCacheEntry = ar9300_Stub_SetKeyCacheEntry;
ah->ah_setKeyCacheEntryMac = ar9300_Stub_SetKeyCacheEntryMac;
/* Power Management Functions */
ah->ah_setPowerMode = ar9300_Stub_SetPowerMode;
ah->ah_getPowerMode = ar9300_Stub_GetPowerMode;
/* Beacon Functions */
ah->ah_setBeaconTimers = ar9300_Stub_SetBeaconTimers;
ah->ah_beaconInit = ar9300_Stub_BeaconInit;
ah->ah_setStationBeaconTimers = ar9300_Stub_SetStaBeaconTimers;
ah->ah_resetStationBeaconTimers = ar9300_Stub_ResetStaBeaconTimers;
ah->ah_getNextTBTT = ar9300_Stub_GetNextTBTT;
/* Interrupt Functions */
ah->ah_isInterruptPending = ar9300_Stub_IsInterruptPending;
ah->ah_getPendingInterrupts = ar9300_Stub_GetPendingInterrupts;
ah->ah_getInterrupts = ar9300_Stub_GetInterrupts;
ah->ah_setInterrupts = ar9300_Stub_SetInterrupts;
AH_PRIVATE(ah)->ah_getChannelEdges = ar9300_Stub_GetChannelEdges;
AH_PRIVATE(ah)->ah_getWirelessModes = ar9300_Stub_GetWirelessModes;
AH_PRIVATE(ah)->ah_eepromRead = ar9300_Stub_EepromRead;
#ifdef AH_SUPPORT_WRITE_EEPROM
AH_PRIVATE(ah)->ah_eepromWrite = ar9300_Stub_EepromWrite;
#endif
AH_PRIVATE(ah)->ah_getChipPowerLimits = ar9300_Stub_GetChipPowerLimits;
}
@@ -0,0 +1,7 @@
#ifndef __AR9300_STUB_H__
#define __AR9300_STUB_H__
extern void ar9300_set_stub_functions(struct ath_hal *ah);
#endif /* __AR9300_STUB_H__ */
@@ -0,0 +1,237 @@
#ifndef __AR9300_STUB_FUNCS_H__
#define __AR9300_STUB_FUNCS_H__
extern uint32_t ar9300_Stub_GetRadioRev(struct ath_hal *ah);
#if 0
extern void ar9300_Stub_InitState(struct ath_hal_5212 *, uint16_t devid, HAL_SOFTC,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status);
#endif
extern void ar9300_Stub_Detach(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_ChipTest(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_GetChannelEdges(struct ath_hal *ah,
uint16_t flags, uint16_t *low, uint16_t *high);
extern HAL_BOOL ar9300_Stub_FillCapabilityInfo(struct ath_hal *ah);
extern void ar9300_Stub_SetBeaconTimers(struct ath_hal *ah,
const HAL_BEACON_TIMERS *);
extern void ar9300_Stub_BeaconInit(struct ath_hal *ah,
uint32_t next_beacon, uint32_t beacon_period);
extern void ar9300_Stub_ResetStaBeaconTimers(struct ath_hal *ah);
extern void ar9300_Stub_SetStaBeaconTimers(struct ath_hal *ah,
const HAL_BEACON_STATE *);
extern uint64_t ar9300_Stub_GetNextTBTT(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_IsInterruptPending(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_GetPendingInterrupts(struct ath_hal *ah, HAL_INT *);
extern HAL_INT ar9300_Stub_GetInterrupts(struct ath_hal *ah);
extern HAL_INT ar9300_Stub_SetInterrupts(struct ath_hal *ah, HAL_INT ints);
extern uint32_t ar9300_Stub_GetKeyCacheSize(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_IsKeyCacheEntryValid(struct ath_hal *, uint16_t entry);
extern HAL_BOOL ar9300_Stub_ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry);
extern HAL_BOOL ar9300_Stub_SetKeyCacheEntryMac(struct ath_hal *,
uint16_t entry, const uint8_t *mac);
extern HAL_BOOL ar9300_Stub_SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry,
const HAL_KEYVAL *k, const uint8_t *mac, int xorKey);
extern void ar9300_Stub_GetMacAddress(struct ath_hal *ah, uint8_t *mac);
extern HAL_BOOL ar9300_Stub_SetMacAddress(struct ath_hal *ah, const uint8_t *);
extern void ar9300_Stub_GetBssIdMask(struct ath_hal *ah, uint8_t *mac);
extern HAL_BOOL ar9300_Stub_SetBssIdMask(struct ath_hal *, const uint8_t *);
extern HAL_BOOL ar9300_Stub_EepromRead(struct ath_hal *, u_int off, uint16_t *data);
extern HAL_BOOL ar9300_Stub_EepromWrite(struct ath_hal *, u_int off, uint16_t data);
extern HAL_BOOL ar9300_Stub_SetRegulatoryDomain(struct ath_hal *ah,
uint16_t regDomain, HAL_STATUS *stats);
extern u_int ar9300_Stub_GetWirelessModes(struct ath_hal *ah);
extern void ar9300_Stub_EnableRfKill(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_GpioCfgOutput(struct ath_hal *, uint32_t gpio,
HAL_GPIO_MUX_TYPE);
extern HAL_BOOL ar9300_Stub_GpioCfgInput(struct ath_hal *, uint32_t gpio);
extern HAL_BOOL ar9300_Stub_GpioSet(struct ath_hal *, uint32_t gpio, uint32_t val);
extern uint32_t ar9300_Stub_GpioGet(struct ath_hal *ah, uint32_t gpio);
extern void ar9300_Stub_GpioSetIntr(struct ath_hal *ah, u_int, uint32_t ilevel);
extern void ar9300_Stub_SetLedState(struct ath_hal *ah, HAL_LED_STATE state);
extern void ar9300_Stub_WriteAssocid(struct ath_hal *ah, const uint8_t *bssid,
uint16_t assocId);
extern uint32_t ar9300_Stub_GetTsf32(struct ath_hal *ah);
extern uint64_t ar9300_Stub_GetTsf64(struct ath_hal *ah);
extern void ar9300_Stub_SetTsf64(struct ath_hal *ah, uint64_t tsf64);
extern void ar9300_Stub_ResetTsf(struct ath_hal *ah);
extern void ar9300_Stub_SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *pSet);
extern uint32_t ar9300_Stub_GetRandomSeed(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_DetectCardPresent(struct ath_hal *ah);
extern void ar9300_Stub_EnableMibCounters(struct ath_hal *);
extern void ar9300_Stub_DisableMibCounters(struct ath_hal *);
extern void ar9300_Stub_UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS* stats);
extern HAL_BOOL ar9300_Stub_IsJapanChannelSpreadSupported(struct ath_hal *ah);
extern uint32_t ar9300_Stub_GetCurRssi(struct ath_hal *ah);
extern u_int ar9300_Stub_GetDefAntenna(struct ath_hal *ah);
extern void ar9300_Stub_SetDefAntenna(struct ath_hal *ah, u_int antenna);
extern HAL_ANT_SETTING ar9300_Stub_GetAntennaSwitch(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
extern HAL_BOOL ar9300_Stub_IsSleepAfterBeaconBroken(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_SetSifsTime(struct ath_hal *, u_int);
extern u_int ar9300_Stub_GetSifsTime(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_SetSlotTime(struct ath_hal *, u_int);
extern u_int ar9300_Stub_GetSlotTime(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_SetAckTimeout(struct ath_hal *, u_int);
extern u_int ar9300_Stub_GetAckTimeout(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_SetAckCTSRate(struct ath_hal *, u_int);
extern u_int ar9300_Stub_GetAckCTSRate(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_SetCTSTimeout(struct ath_hal *, u_int);
extern u_int ar9300_Stub_GetCTSTimeout(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_SetDecompMask(struct ath_hal *, uint16_t, int);
void ar9300_Stub_SetCoverageClass(struct ath_hal *, uint8_t, int);
extern void ar9300_Stub_SetPCUConfig(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_Use32KHzclock(struct ath_hal *ah, HAL_OPMODE opmode);
extern void ar9300_Stub_SetupClock(struct ath_hal *ah, HAL_OPMODE opmode);
extern void ar9300_Stub_RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode);
extern int16_t ar9300_Stub_GetNfAdjust(struct ath_hal *,
const HAL_CHANNEL_INTERNAL *);
extern void ar9300_Stub_SetCompRegs(struct ath_hal *ah);
extern HAL_STATUS ar9300_Stub_GetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE,
uint32_t, uint32_t *);
extern HAL_BOOL ar9300_Stub_SetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE,
uint32_t, uint32_t, HAL_STATUS *);
extern HAL_BOOL ar9300_Stub_GetDiagState(struct ath_hal *ah, int request,
const void *args, uint32_t argsize,
void **result, uint32_t *resultsize);
extern HAL_STATUS ar9300_Stub_SetQuiet(struct ath_hal *ah, uint32_t period,
uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag);
extern HAL_BOOL ar9300_Stub_GetMibCycleCounts(struct ath_hal *,
HAL_SURVEY_SAMPLE *);
extern HAL_BOOL ar9300_Stub_SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode,
int setChip);
extern HAL_POWER_MODE ar9300_Stub_GetPowerMode(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_GetPowerStatus(struct ath_hal *ah);
extern uint32_t ar9300_Stub_GetRxDP(struct ath_hal *ath, HAL_RX_QUEUE);
extern void ar9300_Stub_SetRxDP(struct ath_hal *ah, uint32_t rxdp,
HAL_RX_QUEUE);
extern void ar9300_Stub_EnableReceive(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_StopDmaReceive(struct ath_hal *ah);
extern void ar9300_Stub_StartPcuReceive(struct ath_hal *ah);
extern void ar9300_Stub_StopPcuReceive(struct ath_hal *ah);
extern void ar9300_Stub_SetMulticastFilter(struct ath_hal *ah,
uint32_t filter0, uint32_t filter1);
extern HAL_BOOL ar9300_Stub_ClrMulticastFilterIndex(struct ath_hal *, uint32_t ix);
extern HAL_BOOL ar9300_Stub_SetMulticastFilterIndex(struct ath_hal *, uint32_t ix);
extern uint32_t ar9300_Stub_GetRxFilter(struct ath_hal *ah);
extern void ar9300_Stub_SetRxFilter(struct ath_hal *ah, uint32_t bits);
extern HAL_BOOL ar9300_Stub_SetupRxDesc(struct ath_hal *,
struct ath_desc *, uint32_t size, u_int flags);
extern HAL_STATUS ar9300_Stub_ProcRxDesc(struct ath_hal *ah, struct ath_desc *,
uint32_t, struct ath_desc *, uint64_t,
struct ath_rx_status *);
extern HAL_BOOL ar9300_Stub_Reset(struct ath_hal *ah, HAL_OPMODE opmode,
struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
HAL_STATUS *status);
extern HAL_BOOL ar9300_Stub_SetChannel(struct ath_hal *,
const struct ieee80211_channel *);
extern void ar9300_Stub_SetOperatingMode(struct ath_hal *ah, int opmode);
extern HAL_BOOL ar9300_Stub_PhyDisable(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_Disable(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_ChipReset(struct ath_hal *ah,
const struct ieee80211_channel *);
extern HAL_BOOL ar9300_Stub_PerCalibration(struct ath_hal *ah,
struct ieee80211_channel *chan, HAL_BOOL *isIQdone);
extern HAL_BOOL ar9300_Stub_PerCalibrationN(struct ath_hal *ah,
struct ieee80211_channel *chan, u_int chainMask,
HAL_BOOL longCal, HAL_BOOL *isCalDone);
extern HAL_BOOL ar9300_Stub_ResetCalValid(struct ath_hal *ah,
const struct ieee80211_channel *);
extern int16_t ar9300_Stub_GetNoiseFloor(struct ath_hal *ah);
extern void ar9300_Stub_InitNfCalHistBuffer(struct ath_hal *);
extern int16_t ar9300_Stub_GetNfHistMid(const int16_t calData[]);
extern void ar9300_Stub_SetSpurMitigation(struct ath_hal *,
const struct ieee80211_channel *);
extern HAL_BOOL ar9300_Stub_SetAntennaSwitchInternal(struct ath_hal *ah,
HAL_ANT_SETTING settings, const struct ieee80211_channel *);
extern HAL_BOOL ar9300_Stub_SetTxPowerLimit(struct ath_hal *ah, uint32_t limit);
extern HAL_BOOL ar9300_Stub_GetChipPowerLimits(struct ath_hal *ah,
struct ieee80211_channel *chan);
extern void ar9300_Stub_InitializeGainValues(struct ath_hal *);
extern HAL_RFGAIN ar9300_Stub_GetRfgain(struct ath_hal *ah);
extern void ar9300_Stub_RequestRfgain(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_UpdateTxTrigLevel(struct ath_hal *,
HAL_BOOL IncTrigLevel);
extern HAL_BOOL ar9300_Stub_SetTxQueueProps(struct ath_hal *ah, int q,
const HAL_TXQ_INFO *qInfo);
extern HAL_BOOL ar9300_Stub_GetTxQueueProps(struct ath_hal *ah, int q,
HAL_TXQ_INFO *qInfo);
extern int ar9300_Stub_SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type,
const HAL_TXQ_INFO *qInfo);
extern HAL_BOOL ar9300_Stub_ReleaseTxQueue(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar9300_Stub_ResetTxQueue(struct ath_hal *ah, u_int q);
extern uint32_t ar9300_Stub_GetTxDP(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar9300_Stub_SetTxDP(struct ath_hal *ah, u_int q, uint32_t txdp);
extern HAL_BOOL ar9300_Stub_StartTxDma(struct ath_hal *ah, u_int q);
extern uint32_t ar9300_Stub_NumTxPending(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar9300_Stub_StopTxDma(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar9300_Stub_SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower,
u_int txRate0, u_int txTries0,
u_int keyIx, u_int antMode, u_int flags,
u_int rtsctsRate, u_int rtsctsDuration,
u_int compicvLen, u_int compivLen, u_int comp);
extern HAL_BOOL ar9300_Stub_SetupXTxDesc(struct ath_hal *, struct ath_desc *,
u_int txRate1, u_int txRetries1,
u_int txRate2, u_int txRetries2,
u_int txRate3, u_int txRetries3);
extern HAL_BOOL ar9300_Stub_FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList,
u_int descId, u_int qcuId,
HAL_BOOL firstSeg, HAL_BOOL lastSeg,
const struct ath_desc *ds0);
extern HAL_STATUS ar9300_Stub_ProcTxDesc(struct ath_hal *ah,
struct ath_desc *, struct ath_tx_status *);
extern void ar9300_Stub_GetTxIntrQueue(struct ath_hal *ah, uint32_t *);
extern void ar9300_Stub_IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *);
extern HAL_BOOL ar9300_Stub_GetTxCompletionRates(struct ath_hal *ah,
const struct ath_desc *ds0, int *rates, int *tries);
extern const HAL_RATE_TABLE * ar9300_Stub_GetRateTable(struct ath_hal *, u_int mode);
#if 0
extern void ar9300_Stub_AniAttach(struct ath_hal *, const struct ar9300_Stub_AniParams *,
const struct ar9300_Stub_AniParams *, HAL_BOOL ena);
#endif
extern void ar9300_Stub_AniDetach(struct ath_hal *);
extern struct ar9300_Stub_AniState *ar5212AniGetCurrentState(struct ath_hal *);
extern struct ar9300_Stub_Stats *ar5212AniGetCurrentStats(struct ath_hal *);
extern HAL_BOOL ar9300_Stub_AniControl(struct ath_hal *, HAL_ANI_CMD cmd, int param);
#if 0
extern HAL_BOOL ar9300_Stub_AniSetParams(struct ath_hal *,
const struct ar9300_Stub_AniParams *, const struct ar9300_Stub_AniParams *);
#endif
struct ath_rx_status;
extern void ar9300_Stub_AniPhyErrReport(struct ath_hal *ah,
const struct ath_rx_status *rs);
extern void ar9300_Stub_ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *);
extern void ar9300_Stub_RxMonitor(struct ath_hal *, const HAL_NODE_STATS *,
const struct ieee80211_channel *);
extern void ar9300_Stub_AniPoll(struct ath_hal *, const struct ieee80211_channel *);
extern void ar9300_Stub_AniReset(struct ath_hal *, const struct ieee80211_channel *,
HAL_OPMODE, int);
extern HAL_BOOL ar9300_Stub_IsNFCalInProgress(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_WaitNFCalComplete(struct ath_hal *ah, int i);
extern void ar9300_Stub_EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern void ar9300_Stub_GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern HAL_BOOL ar9300_Stub_ProcessRadarEvent(struct ath_hal *ah,
struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf,
HAL_DFS_EVENT *event);
extern HAL_BOOL ar9300_Stub_IsFastClockEnabled(struct ath_hal *ah);
extern uint32_t ar9300_Stub_Get11nExtBusy(struct ath_hal *ah);
extern void ar9300_Stub_ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore,
HAL_BOOL powerOff);
extern void ar9300_Stub_DisablePCIE(struct ath_hal *ah);
#endif /* __AR9300_STUB_FUNCS_H__ */
@@ -0,0 +1,181 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300desc.h"
typedef struct gen_timer_configuation {
u_int32_t next_addr;
u_int32_t period_addr;
u_int32_t mode_addr;
u_int32_t mode_mask;
} GEN_TIMER_CONFIGURATION;
#define AR_GEN_TIMERS2_CFG(num) \
AR_GEN_TIMERS2_ ## num ## _NEXT, \
AR_GEN_TIMERS2_ ## num ## _PERIOD, \
AR_GEN_TIMERS2_MODE, \
(1 << num)
static const GEN_TIMER_CONFIGURATION gen_timer_configuration[] =
{
{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
{AR_GEN_TIMERS2_CFG(0)},
{AR_GEN_TIMERS2_CFG(1)},
{AR_GEN_TIMERS2_CFG(2)},
{AR_GEN_TIMERS2_CFG(3)},
{AR_GEN_TIMERS2_CFG(4)},
{AR_GEN_TIMERS2_CFG(5)},
{AR_GEN_TIMERS2_CFG(6)},
{AR_GEN_TIMERS2_CFG(7)}
};
#define AR_GENTMR_BIT(_index) (1 << (_index))
int
ar9300_alloc_generic_timer(struct ath_hal *ah, HAL_GEN_TIMER_DOMAIN tsf)
{
struct ath_hal_9300 *ahp = AH9300(ah);
u_int32_t i, mask;
u_int32_t avail_timer_start, avail_timer_end;
if (tsf == HAL_GEN_TIMER_TSF) {
avail_timer_start = AR_FIRST_NDP_TIMER;
avail_timer_end = AR_GEN_TIMER_BANK_1_LEN;
} else {
avail_timer_start = AR_GEN_TIMER_BANK_1_LEN;
avail_timer_end = AR_NUM_GEN_TIMERS;
}
/* Find the first availabe timer index */
i = avail_timer_start;
mask = ahp->ah_avail_gen_timers >> i;
for ( ; mask && (i < avail_timer_end) ; mask >>= 1, i++ ) {
if (mask & 0x1) {
ahp->ah_avail_gen_timers &= ~(AR_GENTMR_BIT(i));
if ((tsf == HAL_GEN_TIMER_TSF2) && !ahp->ah_enable_tsf2) {
ahp->ah_enable_tsf2 = AH_TRUE;
ar9300_start_tsf2(ah);
}
return i;
}
}
return -1;
}
void ar9300_start_tsf2(struct ath_hal *ah)
{
struct ath_hal_9300 *ahp = AH9300(ah);
if (ahp->ah_enable_tsf2) {
/* Delay might be needed after TSF2 reset */
OS_REG_SET_BIT(ah, AR_DIRECT_CONNECT, AR_DC_AP_STA_EN);
OS_REG_SET_BIT(ah, AR_RESET_TSF, AR_RESET_TSF2_ONCE);
}
}
void
ar9300_free_generic_timer(struct ath_hal *ah, int index)
{
struct ath_hal_9300 *ahp = AH9300(ah);
ar9300_stop_generic_timer(ah, index);
ahp->ah_avail_gen_timers |= AR_GENTMR_BIT(index);
}
void
ar9300_start_generic_timer(
struct ath_hal *ah,
int index,
u_int32_t timer_next,
u_int32_t timer_period)
{
if ((index < AR_FIRST_NDP_TIMER) || (index >= AR_NUM_GEN_TIMERS)) {
return;
}
/*
* Program generic timer registers
*/
OS_REG_WRITE(ah, gen_timer_configuration[index].next_addr, timer_next);
OS_REG_WRITE(ah, gen_timer_configuration[index].period_addr, timer_period);
OS_REG_SET_BIT(ah,
gen_timer_configuration[index].mode_addr,
gen_timer_configuration[index].mode_mask);
if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
/*
* Starting from Jupiter, each generic timer can select which tsf to
* use. But we still follow the old rule, 0 - 7 use tsf and 8 - 15
* use tsf2.
*/
if ((index < AR_GEN_TIMER_BANK_1_LEN)) {
OS_REG_CLR_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, (1 << index));
}
else {
OS_REG_SET_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, (1 << index));
}
}
/* Enable both trigger and thresh interrupt masks */
OS_REG_SET_BIT(ah, AR_IMR_S5,
(SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_THRESH) |
SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_TRIG)));
}
void
ar9300_stop_generic_timer(struct ath_hal *ah, int index)
{
if ((index < AR_FIRST_NDP_TIMER) || (index >= AR_NUM_GEN_TIMERS)) {
return;
}
/*
* Clear generic timer enable bits.
*/
OS_REG_CLR_BIT(ah,
gen_timer_configuration[index].mode_addr,
gen_timer_configuration[index].mode_mask);
/* Disable both trigger and thresh interrupt masks */
OS_REG_CLR_BIT(ah, AR_IMR_S5,
(SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_THRESH) |
SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_TRIG)));
}
void
ar9300_get_gen_timer_interrupts(
struct ath_hal *ah,
u_int32_t *trigger,
u_int32_t *thresh)
{
struct ath_hal_9300 *ahp = AH9300(ah);
*trigger = ahp->ah_intr_gen_timer_trigger;
*thresh = ahp->ah_intr_gen_timer_thresh;
}
@@ -0,0 +1,525 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* 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.
*/
#include "ah.h"
#include "ah_internal.h"
#include "ar9300phy.h"
#include "ar9300reg.h"
#include "ar9300eep.h"
#ifdef ATH_TX99_DIAG
void
ar9300_tx99_tgt_channel_pwr_update(struct ath_hal *ah, HAL_CHANNEL *c, u_int32_t txpower)
{
#define PWR_MAS(_r, _s) (((_r) & 0x3f) << (_s))
static int16_t pPwrArray[ar9300_rate_size] = { 0 };
int32_t i;
//u_int8_t ht40PowerIncForPdadc = 2;
for (i = 0; i < ar9300_rate_size; i++)
pPwrArray[i] = txpower;
OS_REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
/* Write the OFDM power per rate set */
/* 6 (LSB), 9, 12, 18 (MSB) */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_6_24], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_6_24], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_6_24], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_6_24], 0)
);
/* 24 (LSB), 36, 48, 54 (MSB) */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_54], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_48], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_36], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_6_24], 0)
);
/* Write the CCK power per rate set */
/* 1L (LSB), reserved, 2L, 2S (MSB) */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16)
// | PWR_MAS(txPowerTimes2, 8) /* this is reserved for Osprey */
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
);
/* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_11S], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_11L], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_5S], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
);
/* Write the HT20 power per rate set */
/* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
PWR_MAS(pPwrArray[ALL_TARGET_HT20_5], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_4], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
);
/* 6 (LSB), 7, 12, 13 (MSB) */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
PWR_MAS(pPwrArray[ALL_TARGET_HT20_13], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_12], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_7], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_6], 0)
);
/* 14 (LSB), 15, 20, 21 */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
PWR_MAS(pPwrArray[ALL_TARGET_HT20_21], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_20], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_15], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_14], 0)
);
/* Mixed HT20 and HT40 rates */
/* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
PWR_MAS(pPwrArray[ALL_TARGET_HT40_23], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_22], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_23], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_HT20_22], 0)
);
/* Write the HT40 power per rate set */
// correct PAR difference between HT40 and HT20/LEGACY
/* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
PWR_MAS(pPwrArray[ALL_TARGET_HT40_5], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_4], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
);
/* 6 (LSB), 7, 12, 13 (MSB) */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
PWR_MAS(pPwrArray[ALL_TARGET_HT40_13], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_12], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_7], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_6], 0)
);
/* 14 (LSB), 15, 20, 21 */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE(12),
PWR_MAS(pPwrArray[ALL_TARGET_HT40_21], 24)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_20], 16)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_15], 8)
| PWR_MAS(pPwrArray[ALL_TARGET_HT40_14], 0)
);
#undef PWR_MAS
}
void
ar9300_tx99_tgt_chainmsk_setup(struct ath_hal *ah, int tx_chainmask)
{
if (tx_chainmask == 0x5) {
OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, OS_REG_READ(ah, AR_PHY_ANALOG_SWAP) | AR_PHY_SWAP_ALT_CHAIN);
}
OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, tx_chainmask);
OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, tx_chainmask);
OS_REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
if (tx_chainmask == 0x5) {
OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, OS_REG_READ(ah, AR_PHY_ANALOG_SWAP) | AR_PHY_SWAP_ALT_CHAIN);
}
}
void
ar9300_tx99_tgt_set_single_carrier(struct ath_hal *ah, int tx_chain_mask, int chtype)
{
OS_REG_WRITE(ah, AR_PHY_TST_DAC_CONST, OS_REG_READ(ah, AR_PHY_TST_DAC_CONST) | (0x7ff<<11) | 0x7ff);
OS_REG_WRITE(ah, AR_PHY_TEST_CTL_STATUS, OS_REG_READ(ah, AR_PHY_TEST_CTL_STATUS) | (1<<7) | (1<<1));
OS_REG_WRITE(ah, AR_PHY_ADDAC_PARA_CTL, (OS_REG_READ(ah, AR_PHY_ADDAC_PARA_CTL) | (1<<31) | (1<<15)) & ~(1<<13));
/* 11G mode */
if (!chtype)
{
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
| (0x1 << 3) | (0x1 << 2));
if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP)
& ~(0x1 << 4));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2)
| (0x1 << 26) | (0x7 << 24))
& ~(0x1 << 22));
} else {
OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP)
& ~(0x1 << 4));
OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, (OS_REG_READ(ah, AR_HORNET_CH0_TOP2)
| (0x1 << 26) | (0x7 << 24))
& ~(0x1 << 22));
}
/* chain zero */
if((tx_chain_mask & 0x01) == 0x01) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX1)
| (0x1 << 31) | (0x5 << 15)
| (0x3 << 9)) & ~(0x1 << 27)
& ~(0x1 << 12));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 7)) & ~(0x1 << 11));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3)
| (0x1 << 29) | (0x1 << 25)
| (0x1 << 23) | (0x1 << 19)
| (0x1 << 10) | (0x1 << 9)
| (0x1 << 8) | (0x1 << 3))
& ~(0x1 << 28)& ~(0x1 << 24)
& ~(0x1 << 22)& ~(0x1 << 7));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1)
| (0x1 << 23))& ~(0x1 << 21));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB1)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 6) | (0x1 << 5)
| (0x1 << 4) | (0x1 << 3)
| (0x1 << 2));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB2)
| (0x1 << 31));
}
if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
/* chain one */
if ((tx_chain_mask & 0x02) == 0x02 ) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX1)
| (0x1 << 31) | (0x5 << 15)
| (0x3 << 9)) & ~(0x1 << 27)
& ~(0x1 << 12));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 7)) & ~(0x1 << 11));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3)
| (0x1 << 29) | (0x1 << 25)
| (0x1 << 23) | (0x1 << 19)
| (0x1 << 10) | (0x1 << 9)
| (0x1 << 8) | (0x1 << 3))
& ~(0x1 << 28)& ~(0x1 << 24)
& ~(0x1 << 22)& ~(0x1 << 7));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1)
| (0x1 << 23))& ~(0x1 << 21));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB1)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 6) | (0x1 << 5)
| (0x1 << 4) | (0x1 << 3)
| (0x1 << 2));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB2)
| (0x1 << 31));
}
}
if (AR_SREV_OSPREY(ah)) {
/* chain two */
if ((tx_chain_mask & 0x04) == 0x04 ) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX1)
| (0x1 << 31) | (0x5 << 15)
| (0x3 << 9)) & ~(0x1 << 27)
& ~(0x1 << 12));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 7)) & ~(0x1 << 11));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3)
| (0x1 << 29) | (0x1 << 25)
| (0x1 << 23) | (0x1 << 19)
| (0x1 << 10) | (0x1 << 9)
| (0x1 << 8) | (0x1 << 3))
& ~(0x1 << 28)& ~(0x1 << 24)
& ~(0x1 << 22)& ~(0x1 << 7));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1)
| (0x1 << 23))& ~(0x1 << 21));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB1)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 6) | (0x1 << 5)
| (0x1 << 4) | (0x1 << 3)
| (0x1 << 2));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB2)
| (0x1 << 31));
}
}
OS_REG_WRITE(ah, AR_PHY_SWITCH_COM_2, 0x11111);
OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0x111);
}
else
{
/* chain zero */
if((tx_chain_mask & 0x01) == 0x01) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX1)
| (0x1 << 31) | (0x1 << 27)
| (0x3 << 23) | (0x1 << 19)
| (0x1 << 15) | (0x3 << 9))
& ~(0x1 << 12));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 7) | (0x1 << 3)
| (0x1 << 2) | (0x1 << 1))
& ~(0x1 << 11)& ~(0x1 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3)
| (0x1 << 29) | (0x1 << 25)
| (0x1 << 23) | (0x1 << 19)
| (0x1 << 10) | (0x1 << 9)
| (0x1 << 8) | (0x1 << 3))
& ~(0x1 << 28)& ~(0x1 << 24)
& ~(0x1 << 22)& ~(0x1 << 7));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1)
| (0x1 << 23))& ~(0x1 << 21));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF2)
| (0x3 << 3) | (0x3 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF3, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF3)
| (0x3 << 29) | (0x3 << 26)
| (0x2 << 23) | (0x2 << 20)
| (0x2 << 17))& ~(0x1 << 14));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB1)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 6) | (0x1 << 5)
| (0x1 << 4) | (0x1 << 3)
| (0x1 << 2));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB2)
| (0x1 << 31));
if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP)
& ~(0x1 << 4));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2)
| (0x1 << 26) | (0x7 << 24)
| (0x3 << 22));
} else {
OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP)
& ~(0x1 << 4));
OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, OS_REG_READ(ah, AR_HORNET_CH0_TOP2)
| (0x1 << 26) | (0x7 << 24)
| (0x3 << 22));
}
if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2)
| (0x1 << 3) | (0x1 << 2)
| (0x1 << 1)) & ~(0x1 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3)
| (0x1 << 19) | (0x1 << 3));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1)
| (0x1 << 23));
}
if (AR_SREV_OSPREY(ah)) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2)
| (0x1 << 3) | (0x1 << 2)
| (0x1 << 1)) & ~(0x1 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3)
| (0x1 << 19) | (0x1 << 3));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1)
| (0x1 << 23));
}
}
if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
/* chain one */
if ((tx_chain_mask & 0x02) == 0x02 ) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
| (0x1 << 3) | (0x1 << 2)
| (0x1 << 1)) & ~(0x1 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3)
| (0x1 << 19) | (0x1 << 3));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1)
| (0x1 << 23));
if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP)
& ~(0x1 << 4));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2)
| (0x1 << 26) | (0x7 << 24)
| (0x3 << 22));
} else {
OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP)
& ~(0x1 << 4));
OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, OS_REG_READ(ah, AR_HORNET_CH0_TOP2)
| (0x1 << 26) | (0x7 << 24)
| (0x3 << 22));
}
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX1)
| (0x1 << 31) | (0x1 << 27)
| (0x3 << 23) | (0x1 << 19)
| (0x1 << 15) | (0x3 << 9))
& ~(0x1 << 12));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 7) | (0x1 << 3)
| (0x1 << 2) | (0x1 << 1))
& ~(0x1 << 11)& ~(0x1 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3)
| (0x1 << 29) | (0x1 << 25)
| (0x1 << 23) | (0x1 << 19)
| (0x1 << 10) | (0x1 << 9)
| (0x1 << 8) | (0x1 << 3))
& ~(0x1 << 28)& ~(0x1 << 24)
& ~(0x1 << 22)& ~(0x1 << 7));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1)
| (0x1 << 23))& ~(0x1 << 21));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF2, OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF2)
| (0x3 << 3) | (0x3 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF3, (OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF3)
| (0x3 << 29) | (0x3 << 26)
| (0x2 << 23) | (0x2 << 20)
| (0x2 << 17))& ~(0x1 << 14));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB1)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 6) | (0x1 << 5)
| (0x1 << 4) | (0x1 << 3)
| (0x1 << 2));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB2)
| (0x1 << 31));
if (AR_SREV_OSPREY(ah)) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2)
| (0x1 << 3) | (0x1 << 2)
| (0x1 << 1)) & ~(0x1 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3)
| (0x1 << 19) | (0x1 << 3));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1)
| (0x1 << 23));
}
}
}
if (AR_SREV_OSPREY(ah)) {
/* chain two */
if ((tx_chain_mask & 0x04) == 0x04 ) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
| (0x1 << 3) | (0x1 << 2)
| (0x1 << 1)) & ~(0x1 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3)
| (0x1 << 19) | (0x1 << 3));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1)
| (0x1 << 23));
if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP)
& ~(0x1 << 4));
OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2)
| (0x1 << 26) | (0x7 << 24)
| (0x3 << 22));
} else {
OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP)
& ~(0x1 << 4));
OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, OS_REG_READ(ah, AR_HORNET_CH0_TOP2)
| (0x1 << 26) | (0x7 << 24)
| (0x3 << 22));
}
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2)
| (0x1 << 3) | (0x1 << 2)
| (0x1 << 1)) & ~(0x1 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3)
| (0x1 << 19) | (0x1 << 3));
OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1)
| (0x1 << 23));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX1)
| (0x1 << 31) | (0x1 << 27)
| (0x3 << 23) | (0x1 << 19)
| (0x1 << 15) | (0x3 << 9))
& ~(0x1 << 12));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 7) | (0x1 << 3)
| (0x1 << 2) | (0x1 << 1))
& ~(0x1 << 11)& ~(0x1 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3)
| (0x1 << 29) | (0x1 << 25)
| (0x1 << 23) | (0x1 << 19)
| (0x1 << 10) | (0x1 << 9)
| (0x1 << 8) | (0x1 << 3))
& ~(0x1 << 28)& ~(0x1 << 24)
& ~(0x1 << 22)& ~(0x1 << 7));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1)
| (0x1 << 23))& ~(0x1 << 21));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF2, OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF2)
| (0x3 << 3) | (0x3 << 0));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF3, (OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF3)
| (0x3 << 29) | (0x3 << 26)
| (0x2 << 23) | (0x2 << 20)
| (0x2 << 17))& ~(0x1 << 14));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB1)
| (0x1 << 12) | (0x1 << 10)
| (0x1 << 9) | (0x1 << 8)
| (0x1 << 6) | (0x1 << 5)
| (0x1 << 4) | (0x1 << 3)
| (0x1 << 2));
OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB2)
| (0x1 << 31));
}
}
OS_REG_WRITE(ah, AR_PHY_SWITCH_COM_2, 0x22222);
OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0x222);
}
}
void
ar9300_tx99_tgt_start(struct ath_hal *ah, u_int8_t data)
{
a_uint32_t val;
a_uint32_t qnum = (a_uint32_t)data;
/* Disable AGC to A2 */
OS_REG_WRITE(ah, AR_PHY_TEST, (OS_REG_READ(ah, AR_PHY_TEST) | PHY_AGC_CLR) );
OS_REG_WRITE(ah, 0x9864, OS_REG_READ(ah, 0x9864) | 0x7f000);
OS_REG_WRITE(ah, 0x9924, OS_REG_READ(ah, 0x9924) | 0x7f00fe);
OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_READ(ah, AR_DIAG_SW) &~ AR_DIAG_RX_DIS);
//OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_READ(ah, AR_DIAG_SW) | (AR_DIAG_FORCE_RX_CLEAR+AR_DIAG_IGNORE_VIRT_CS));
OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); // set receive disable
//set CW_MIN and CW_MAX both to 0, AIFS=2
OS_REG_WRITE(ah, AR_DLCL_IFS(qnum), 0);
OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 20); //50 OK
OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, 20);
OS_REG_WRITE(ah, AR_TIME_OUT, 0x00000400); //200 ok for HT20, 400 ok for HT40
OS_REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff);
/* set QCU modes to early termination */
val = OS_REG_READ(ah, AR_QMISC(qnum));
OS_REG_WRITE(ah, AR_QMISC(qnum), val | AR_Q_MISC_DCU_EARLY_TERM_REQ);
}
void
ar9300_tx99_tgt_stop(struct ath_hal *ah)
{
OS_REG_WRITE(ah, AR_PHY_TEST, OS_REG_READ(ah, AR_PHY_TEST) &~ PHY_AGC_CLR);
OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_READ(ah, AR_DIAG_SW) &~ (AR_DIAG_FORCE_RX_CLEAR | AR_DIAG_IGNORE_VIRT_CS));
}
#endif
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#ifdef AH_SUPPORT_AR9300
#include "ah.h"
#include "ah_internal.h"
#include "ah_desc.h"
#include "ar9300.h"
#include "ar9300desc.h"
#include "ar9300reg.h"
#include "ar9300phy.h"
#endif /* AH_SUPPORT_AR9300 */
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#ifndef _ATH_AR9000_TxBF_CAL_H_
#define _ATH_AR9300_TxBF_CAL_H_
#endif
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#ifdef AH_SUPPORT_AR9300
#include "ah.h"
#include "ah_internal.h"
#include "ar9300reg.h"
#endif /* AH_SUPPORT_AR9300 */
@@ -0,0 +1,909 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_desc.h"
#include "ah_internal.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300phy.h"
#include "ar9300/ar9300desc.h"
#define TU_TO_USEC(_tu) ((_tu) << 10)
#define ONE_EIGHTH_TU_TO_USEC(_tu8) ((_tu8) << 7)
/*
* Update Tx FIFO trigger level.
*
* Set b_inc_trig_level to TRUE to increase the trigger level.
* Set b_inc_trig_level to FALSE to decrease the trigger level.
*
* Returns TRUE if the trigger level was updated
*/
HAL_BOOL
ar9300_update_tx_trig_level(struct ath_hal *ah, HAL_BOOL b_inc_trig_level)
{
struct ath_hal_9300 *ahp = AH9300(ah);
u_int32_t txcfg, cur_level, new_level;
HAL_INT omask;
if (AH9300(ah)->ah_tx_trig_level >= MAX_TX_FIFO_THRESHOLD &&
b_inc_trig_level)
{
return AH_FALSE;
}
/*
* Disable interrupts while futzing with the fifo level.
*/
omask = ar9300_set_interrupts(ah, ahp->ah_mask_reg &~ HAL_INT_GLOBAL, 0);
txcfg = OS_REG_READ(ah, AR_TXCFG);
cur_level = MS(txcfg, AR_FTRIG);
new_level = cur_level;
if (b_inc_trig_level) { /* increase the trigger level */
if (cur_level < MAX_TX_FIFO_THRESHOLD) {
new_level++;
}
} else if (cur_level > MIN_TX_FIFO_THRESHOLD) {
new_level--;
}
if (new_level != cur_level) {
/* Update the trigger level */
OS_REG_WRITE(ah,
AR_TXCFG, (txcfg &~ AR_FTRIG) | SM(new_level, AR_FTRIG));
}
/* re-enable chip interrupts */
ar9300_set_interrupts(ah, omask, 0);
AH9300(ah)->ah_tx_trig_level = new_level;
return (new_level != cur_level);
}
/*
* Returns the value of Tx Trigger Level
*/
u_int16_t
ar9300_get_tx_trig_level(struct ath_hal *ah)
{
return (AH9300(ah)->ah_tx_trig_level);
}
/*
* Set the properties of the tx queue with the parameters
* from q_info.
*/
HAL_BOOL
ar9300_set_tx_queue_props(struct ath_hal *ah, int q, const HAL_TXQ_INFO *q_info)
{
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
if (q >= p_cap->halTotalQueues) {
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: invalid queue num %u\n", __func__, q);
return AH_FALSE;
}
return ath_hal_setTxQProps(ah, &ahp->ah_txq[q], q_info);
}
/*
* Return the properties for the specified tx queue.
*/
HAL_BOOL
ar9300_get_tx_queue_props(struct ath_hal *ah, int q, HAL_TXQ_INFO *q_info)
{
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
if (q >= p_cap->halTotalQueues) {
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: invalid queue num %u\n", __func__, q);
return AH_FALSE;
}
return ath_hal_getTxQProps(ah, q_info, &ahp->ah_txq[q]);
}
enum {
AH_TX_QUEUE_MINUS_OFFSET_BEACON = 1,
AH_TX_QUEUE_MINUS_OFFSET_CAB = 2,
AH_TX_QUEUE_MINUS_OFFSET_UAPSD = 3,
AH_TX_QUEUE_MINUS_OFFSET_PAPRD = 4,
};
/*
* Allocate and initialize a tx DCU/QCU combination.
*/
int
ar9300_setup_tx_queue(struct ath_hal *ah, HAL_TX_QUEUE type,
const HAL_TXQ_INFO *q_info)
{
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_TX_QUEUE_INFO *qi;
HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
int q;
/* XXX move queue assignment to driver */
switch (type) {
case HAL_TX_QUEUE_BEACON:
/* highest priority */
q = p_cap->halTotalQueues - AH_TX_QUEUE_MINUS_OFFSET_BEACON;
break;
case HAL_TX_QUEUE_CAB:
/* next highest priority */
q = p_cap->halTotalQueues - AH_TX_QUEUE_MINUS_OFFSET_CAB;
break;
case HAL_TX_QUEUE_UAPSD:
q = p_cap->halTotalQueues - AH_TX_QUEUE_MINUS_OFFSET_UAPSD;
break;
case HAL_TX_QUEUE_PAPRD:
q = p_cap->halTotalQueues - AH_TX_QUEUE_MINUS_OFFSET_PAPRD;
break;
case HAL_TX_QUEUE_DATA:
/*
* don't infringe on top 4 queues, reserved for:
* beacon, CAB, UAPSD, PAPRD
*/
for (q = 0;
q < p_cap->halTotalQueues - AH_TX_QUEUE_MINUS_OFFSET_PAPRD;
q++)
{
if (ahp->ah_txq[q].tqi_type == HAL_TX_QUEUE_INACTIVE) {
break;
}
}
if (q == p_cap->halTotalQueues - 3) {
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: no available tx queue\n", __func__);
return -1;
}
break;
default:
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: bad tx queue type %u\n", __func__, type);
return -1;
}
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: queue %u\n", __func__, q);
qi = &ahp->ah_txq[q];
if (qi->tqi_type != HAL_TX_QUEUE_INACTIVE) {
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: tx queue %u already active\n", __func__, q);
return -1;
}
OS_MEMZERO(qi, sizeof(HAL_TX_QUEUE_INFO));
qi->tqi_type = type;
if (q_info == AH_NULL) {
/* by default enable OK+ERR+DESC+URN interrupts */
qi->tqi_qflags = HAL_TXQ_TXOKINT_ENABLE
| HAL_TXQ_TXERRINT_ENABLE
| HAL_TXQ_TXDESCINT_ENABLE
| HAL_TXQ_TXURNINT_ENABLE;
qi->tqi_aifs = INIT_AIFS;
qi->tqi_cwmin = HAL_TXQ_USEDEFAULT; /* NB: do at reset */
qi->tqi_cwmax = INIT_CWMAX;
qi->tqi_shretry = INIT_SH_RETRY;
qi->tqi_lgretry = INIT_LG_RETRY;
qi->tqi_physCompBuf = 0;
} else {
qi->tqi_physCompBuf = q_info->tqi_compBuf;
(void) ar9300_set_tx_queue_props(ah, q, q_info);
}
/* NB: must be followed by ar9300_reset_tx_queue */
return q;
}
/*
* Update the h/w interrupt registers to reflect a tx q's configuration.
*/
static void
set_tx_q_interrupts(struct ath_hal *ah, HAL_TX_QUEUE_INFO *qi)
{
struct ath_hal_9300 *ahp = AH9300(ah);
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s: tx ok 0x%x err 0x%x eol 0x%x urn 0x%x\n",
__func__,
ahp->ah_tx_ok_interrupt_mask,
ahp->ah_tx_err_interrupt_mask,
ahp->ah_tx_eol_interrupt_mask,
ahp->ah_tx_urn_interrupt_mask);
OS_REG_WRITE(ah, AR_IMR_S0,
SM(ahp->ah_tx_ok_interrupt_mask, AR_IMR_S0_QCU_TXOK));
OS_REG_WRITE(ah, AR_IMR_S1,
SM(ahp->ah_tx_err_interrupt_mask, AR_IMR_S1_QCU_TXERR)
| SM(ahp->ah_tx_eol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
OS_REG_RMW_FIELD(ah,
AR_IMR_S2, AR_IMR_S2_QCU_TXURN, ahp->ah_tx_urn_interrupt_mask);
ahp->ah_mask2Reg = OS_REG_READ(ah, AR_IMR_S2);
}
/*
* Free a tx DCU/QCU combination.
*/
HAL_BOOL
ar9300_release_tx_queue(struct ath_hal *ah, u_int q)
{
struct ath_hal_9300 *ahp = AH9300(ah);
HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
HAL_TX_QUEUE_INFO *qi;
if (q >= p_cap->halTotalQueues) {
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: invalid queue num %u\n", __func__, q);
return AH_FALSE;
}
qi = &ahp->ah_txq[q];
if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: inactive queue %u\n", __func__, q);
return AH_FALSE;
}
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: release queue %u\n", __func__, q);
qi->tqi_type = HAL_TX_QUEUE_INACTIVE;
ahp->ah_tx_ok_interrupt_mask &= ~(1 << q);
ahp->ah_tx_err_interrupt_mask &= ~(1 << q);
ahp->ah_tx_eol_interrupt_mask &= ~(1 << q);
ahp->ah_tx_urn_interrupt_mask &= ~(1 << q);
set_tx_q_interrupts(ah, qi);
return AH_TRUE;
}
/*
* Set the retry, aifs, cwmin/max, ready_time regs for specified queue
* Assumes:
* phw_channel has been set to point to the current channel
*/
HAL_BOOL
ar9300_reset_tx_queue(struct ath_hal *ah, u_int q)
{
struct ath_hal_9300 *ahp = AH9300(ah);
// struct ath_hal_private *ap = AH_PRIVATE(ah);
HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
HAL_TX_QUEUE_INFO *qi;
u_int32_t cw_min, chan_cw_min, value;
if (q >= p_cap->halTotalQueues) {
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: invalid queue num %u\n", __func__, q);
return AH_FALSE;
}
qi = &ahp->ah_txq[q];
if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: inactive queue %u\n", __func__, q);
return AH_TRUE; /* XXX??? */
}
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: reset queue %u\n", __func__, q);
if (qi->tqi_cwmin == HAL_TXQ_USEDEFAULT) {
/*
* Select cwmin according to channel type.
* NB: chan can be NULL during attach
*/
if (chan && IEEE80211_IS_CHAN_B(chan)) {
chan_cw_min = INIT_CWMIN_11B;
} else {
chan_cw_min = INIT_CWMIN;
}
/* make sure that the CWmin is of the form (2^n - 1) */
for (cw_min = 1; cw_min < chan_cw_min; cw_min = (cw_min << 1) | 1) {}
} else {
cw_min = qi->tqi_cwmin;
}
/* set cw_min/Max and AIFS values */
if (q > 3 || (!AH9300(ah)->ah_fccaifs))
/* values should not be overwritten if domain is FCC and manual rate
less than 24Mb is set, this check is making sure this */
{
OS_REG_WRITE(ah, AR_DLCL_IFS(q), SM(cw_min, AR_D_LCL_IFS_CWMIN)
| SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
| SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
}
/* Set retry limit values */
OS_REG_WRITE(ah, AR_DRETRY_LIMIT(q),
SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
/* enable early termination on the QCU */
OS_REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
/* enable DCU to wait for next fragment from QCU */
if (AR_SREV_WASP(ah) && (AH_PRIVATE((ah))->ah_macRev <= AR_SREV_REVISION_WASP_12)) {
/* WAR for EV#85395: Wasp Rx overrun issue - reduces Tx queue backoff
* threshold to 1 to avoid Rx overruns - Fixed in Wasp 1.3 */
OS_REG_WRITE(ah, AR_DMISC(q),
AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
} else {
OS_REG_WRITE(ah, AR_DMISC(q),
AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
}
/* multiqueue support */
if (qi->tqi_cbrPeriod) {
OS_REG_WRITE(ah,
AR_QCBRCFG(q),
SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
SM(qi->tqi_cbrOverflowLimit,
AR_Q_CBRCFG_OVF_THRESH));
OS_REG_WRITE(ah, AR_QMISC(q),
OS_REG_READ(ah, AR_QMISC(q)) |
AR_Q_MISC_FSP_CBR |
(qi->tqi_cbrOverflowLimit ?
AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
}
if (qi->tqi_readyTime && (qi->tqi_type != HAL_TX_QUEUE_CAB)) {
OS_REG_WRITE(ah, AR_QRDYTIMECFG(q),
SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
AR_Q_RDYTIMECFG_EN);
}
OS_REG_WRITE(ah, AR_DCHNTIME(q), SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
(qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
if (qi->tqi_burstTime &&
(qi->tqi_qflags & HAL_TXQ_RDYTIME_EXP_POLICY_ENABLE))
{
OS_REG_WRITE(ah, AR_QMISC(q), OS_REG_READ(ah, AR_QMISC(q)) |
AR_Q_MISC_RDYTIME_EXP_POLICY);
}
if (qi->tqi_qflags & HAL_TXQ_BACKOFF_DISABLE) {
OS_REG_WRITE(ah, AR_DMISC(q), OS_REG_READ(ah, AR_DMISC(q)) |
AR_D_MISC_POST_FR_BKOFF_DIS);
}
if (qi->tqi_qflags & HAL_TXQ_FRAG_BURST_BACKOFF_ENABLE) {
OS_REG_WRITE(ah, AR_DMISC(q), OS_REG_READ(ah, AR_DMISC(q)) |
AR_D_MISC_FRAG_BKOFF_EN);
}
switch (qi->tqi_type) {
case HAL_TX_QUEUE_BEACON: /* beacon frames */
OS_REG_WRITE(ah, AR_QMISC(q),
OS_REG_READ(ah, AR_QMISC(q))
| AR_Q_MISC_FSP_DBA_GATED
| AR_Q_MISC_BEACON_USE
| AR_Q_MISC_CBR_INCR_DIS1);
OS_REG_WRITE(ah, AR_DMISC(q),
OS_REG_READ(ah, AR_DMISC(q))
| (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
| AR_D_MISC_BEACON_USE
| AR_D_MISC_POST_FR_BKOFF_DIS);
/* XXX cwmin and cwmax should be 0 for beacon queue */
if (AH_PRIVATE(ah)->ah_opmode != HAL_M_IBSS) {
OS_REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
| SM(0, AR_D_LCL_IFS_CWMAX)
| SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
}
break;
case HAL_TX_QUEUE_CAB: /* CAB frames */
/*
* No longer Enable AR_Q_MISC_RDYTIME_EXP_POLICY,
* bug #6079. There is an issue with the CAB Queue
* not properly refreshing the Tx descriptor if
* the TXE clear setting is used.
*/
OS_REG_WRITE(ah, AR_QMISC(q),
OS_REG_READ(ah, AR_QMISC(q))
| AR_Q_MISC_FSP_DBA_GATED
| AR_Q_MISC_CBR_INCR_DIS1
| AR_Q_MISC_CBR_INCR_DIS0);
value = TU_TO_USEC(qi->tqi_readyTime)
- (ah->ah_config.ah_sw_beacon_response_time
- ah->ah_config.ah_dma_beacon_response_time)
- ah->ah_config.ah_additional_swba_backoff;
OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_EN);
OS_REG_WRITE(ah, AR_DMISC(q), OS_REG_READ(ah, AR_DMISC(q))
| (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
break;
case HAL_TX_QUEUE_PSPOLL:
/*
* We may configure ps_poll QCU to be TIM-gated in the
* future; TIM_GATED bit is not enabled currently because
* of a hardware problem in Oahu that overshoots the TIM
* bitmap in beacon and may find matching associd bit in
* non-TIM elements and send PS-poll PS poll processing
* will be done in software
*/
OS_REG_WRITE(ah, AR_QMISC(q),
OS_REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
break;
case HAL_TX_QUEUE_UAPSD:
OS_REG_WRITE(ah, AR_DMISC(q), OS_REG_READ(ah, AR_DMISC(q))
| AR_D_MISC_POST_FR_BKOFF_DIS);
break;
default: /* NB: silence compiler */
break;
}
#ifndef AH_DISABLE_WME
/*
* Yes, this is a hack and not the right way to do it, but
* it does get the lockout bits and backoff set for the
* high-pri WME queues for testing. We need to either extend
* the meaning of queue_info->mode, or create something like
* queue_info->dcumode.
*/
if (qi->tqi_intFlags & HAL_TXQ_USE_LOCKOUT_BKOFF_DIS) {
OS_REG_WRITE(ah, AR_DMISC(q),
OS_REG_READ(ah, AR_DMISC(q)) |
SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
AR_D_MISC_ARB_LOCKOUT_CNTRL) |
AR_D_MISC_POST_FR_BKOFF_DIS);
}
#endif
OS_REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
/*
* Always update the secondary interrupt mask registers - this
* could be a new queue getting enabled in a running system or
* hw getting re-initialized during a reset!
*
* Since we don't differentiate between tx interrupts corresponding
* to individual queues - secondary tx mask regs are always unmasked;
* tx interrupts are enabled/disabled for all queues collectively
* using the primary mask reg
*/
if (qi->tqi_qflags & HAL_TXQ_TXOKINT_ENABLE) {
ahp->ah_tx_ok_interrupt_mask |= (1 << q);
} else {
ahp->ah_tx_ok_interrupt_mask &= ~(1 << q);
}
if (qi->tqi_qflags & HAL_TXQ_TXERRINT_ENABLE) {
ahp->ah_tx_err_interrupt_mask |= (1 << q);
} else {
ahp->ah_tx_err_interrupt_mask &= ~(1 << q);
}
if (qi->tqi_qflags & HAL_TXQ_TXEOLINT_ENABLE) {
ahp->ah_tx_eol_interrupt_mask |= (1 << q);
} else {
ahp->ah_tx_eol_interrupt_mask &= ~(1 << q);
}
if (qi->tqi_qflags & HAL_TXQ_TXURNINT_ENABLE) {
ahp->ah_tx_urn_interrupt_mask |= (1 << q);
} else {
ahp->ah_tx_urn_interrupt_mask &= ~(1 << q);
}
set_tx_q_interrupts(ah, qi);
return AH_TRUE;
}
/*
* Get the TXDP for the specified queue
*/
u_int32_t
ar9300_get_tx_dp(struct ath_hal *ah, u_int q)
{
HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
return OS_REG_READ(ah, AR_QTXDP(q));
}
/*
* Set the tx_dp for the specified queue
*/
HAL_BOOL
ar9300_set_tx_dp(struct ath_hal *ah, u_int q, u_int32_t txdp)
{
HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
HALASSERT(AH9300(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
HALASSERT(txdp != 0);
OS_REG_WRITE(ah, AR_QTXDP(q), txdp);
return AH_TRUE;
}
/*
* Transmit Enable is read-only now
*/
HAL_BOOL
ar9300_start_tx_dma(struct ath_hal *ah, u_int q)
{
return AH_TRUE;
}
/*
* Return the number of pending frames or 0 if the specified
* queue is stopped.
*/
u_int32_t
ar9300_num_tx_pending(struct ath_hal *ah, u_int q)
{
u_int32_t npend;
HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
npend = OS_REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
if (npend == 0) {
/*
* Pending frame count (PFC) can momentarily go to zero
* while TXE remains asserted. In other words a PFC of
* zero is not sufficient to say that the queue has stopped.
*/
if (OS_REG_READ(ah, AR_Q_TXE) & (1 << q)) {
npend = 1; /* arbitrarily return 1 */
}
}
#ifdef DEBUG
if (npend && (AH9300(ah)->ah_txq[q].tqi_type == HAL_TX_QUEUE_CAB)) {
if (OS_REG_READ(ah, AR_Q_RDYTIMESHDN) & (1 << q)) {
HALDEBUG(ah, HAL_DEBUG_QUEUE, "RTSD on CAB queue\n");
/* Clear the ready_time shutdown status bits */
OS_REG_WRITE(ah, AR_Q_RDYTIMESHDN, 1 << q);
}
}
#endif
HALASSERT((npend == 0) ||
(AH9300(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE));
return npend;
}
/*
* Stop transmit on the specified queue
*/
HAL_BOOL
ar9300_stop_tx_dma(struct ath_hal *ah, u_int q, u_int timeout)
{
/*
* Directly call abort. It is better, hardware-wise, to stop all
* queues at once than individual ones.
*/
return ar9300_abort_tx_dma(ah);
#if 0
#define AH_TX_STOP_DMA_TIMEOUT 4000 /* usec */
#define AH_TIME_QUANTUM 100 /* usec */
u_int wait;
HALASSERT(q < AH_PRIVATE(ah)->ah_caps.hal_total_queues);
HALASSERT(AH9300(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
if (timeout == 0) {
timeout = AH_TX_STOP_DMA_TIMEOUT;
}
OS_REG_WRITE(ah, AR_Q_TXD, 1 << q);
for (wait = timeout / AH_TIME_QUANTUM; wait != 0; wait--) {
if (ar9300_num_tx_pending(ah, q) == 0) {
break;
}
OS_DELAY(AH_TIME_QUANTUM); /* XXX get actual value */
}
#ifdef AH_DEBUG
if (wait == 0) {
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: queue %u DMA did not stop in 100 msec\n", __func__, q);
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: QSTS 0x%x Q_TXE 0x%x Q_TXD 0x%x Q_CBR 0x%x\n",
__func__,
OS_REG_READ(ah, AR_QSTS(q)),
OS_REG_READ(ah, AR_Q_TXE),
OS_REG_READ(ah, AR_Q_TXD),
OS_REG_READ(ah, AR_QCBRCFG(q)));
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: Q_MISC 0x%x Q_RDYTIMECFG 0x%x Q_RDYTIMESHDN 0x%x\n",
__func__,
OS_REG_READ(ah, AR_QMISC(q)),
OS_REG_READ(ah, AR_QRDYTIMECFG(q)),
OS_REG_READ(ah, AR_Q_RDYTIMESHDN));
}
#endif /* AH_DEBUG */
/* 2413+ and up can kill packets at the PCU level */
if (ar9300_num_tx_pending(ah, q)) {
u_int32_t tsf_low, j;
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: Num of pending TX Frames %d on Q %d\n",
__func__, ar9300_num_tx_pending(ah, q), q);
/* Kill last PCU Tx Frame */
/* TODO - save off and restore current values of Q1/Q2? */
for (j = 0; j < 2; j++) {
tsf_low = OS_REG_READ(ah, AR_TSF_L32);
OS_REG_WRITE(ah, AR_QUIET2, SM(10, AR_QUIET2_QUIET_DUR));
OS_REG_WRITE(ah, AR_QUIET_PERIOD, 100);
OS_REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsf_low >> 10);
OS_REG_SET_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
if ((OS_REG_READ(ah, AR_TSF_L32) >> 10) == (tsf_low >> 10)) {
break;
}
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: TSF have moved while trying to set "
"quiet time TSF: 0x%08x\n",
__func__, tsf_low);
/* TSF shouldn't count twice or reg access is taking forever */
HALASSERT(j < 1);
}
OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
/* Allow the quiet mechanism to do its work */
OS_DELAY(200);
OS_REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
/* Verify all transmit is dead */
wait = timeout / AH_TIME_QUANTUM;
while (ar9300_num_tx_pending(ah, q)) {
if ((--wait) == 0) {
HALDEBUG(ah, HAL_DEBUG_TX,
"%s: Failed to stop Tx DMA in %d msec "
"after killing last frame\n",
__func__, timeout / 1000);
break;
}
OS_DELAY(AH_TIME_QUANTUM);
}
OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
}
OS_REG_WRITE(ah, AR_Q_TXD, 0);
return (wait != 0);
#undef AH_TX_STOP_DMA_TIMEOUT
#undef AH_TIME_QUANTUM
#endif
}
/*
* Really Stop transmit on the specified queue
*/
HAL_BOOL
ar9300_stop_tx_dma_indv_que(struct ath_hal *ah, u_int q, u_int timeout)
{
#define AH_TX_STOP_DMA_TIMEOUT 4000 /* usec */
#define AH_TIME_QUANTUM 100 /* usec */
u_int wait;
HALASSERT(q < AH_PRIVATE(ah)->ah_caps.hal_total_queues);
HALASSERT(AH9300(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
if (timeout == 0) {
timeout = AH_TX_STOP_DMA_TIMEOUT;
}
OS_REG_WRITE(ah, AR_Q_TXD, 1 << q);
for (wait = timeout / AH_TIME_QUANTUM; wait != 0; wait--) {
if (ar9300_num_tx_pending(ah, q) == 0) {
break;
}
OS_DELAY(AH_TIME_QUANTUM); /* XXX get actual value */
}
#ifdef AH_DEBUG
if (wait == 0) {
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: queue %u DMA did not stop in 100 msec\n", __func__, q);
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: QSTS 0x%x Q_TXE 0x%x Q_TXD 0x%x Q_CBR 0x%x\n",
__func__,
OS_REG_READ(ah, AR_QSTS(q)),
OS_REG_READ(ah, AR_Q_TXE),
OS_REG_READ(ah, AR_Q_TXD),
OS_REG_READ(ah, AR_QCBRCFG(q)));
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: Q_MISC 0x%x Q_RDYTIMECFG 0x%x Q_RDYTIMESHDN 0x%x\n",
__func__,
OS_REG_READ(ah, AR_QMISC(q)),
OS_REG_READ(ah, AR_QRDYTIMECFG(q)),
OS_REG_READ(ah, AR_Q_RDYTIMESHDN));
}
#endif /* AH_DEBUG */
/* 2413+ and up can kill packets at the PCU level */
if (ar9300_num_tx_pending(ah, q)) {
u_int32_t tsf_low, j;
HALDEBUG(ah, HAL_DEBUG_QUEUE, "%s: Num of pending TX Frames %d on Q %d\n",
__func__, ar9300_num_tx_pending(ah, q), q);
/* Kill last PCU Tx Frame */
/* TODO - save off and restore current values of Q1/Q2? */
for (j = 0; j < 2; j++) {
tsf_low = OS_REG_READ(ah, AR_TSF_L32);
OS_REG_WRITE(ah, AR_QUIET2, SM(10, AR_QUIET2_QUIET_DUR));
OS_REG_WRITE(ah, AR_QUIET_PERIOD, 100);
OS_REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsf_low >> 10);
OS_REG_SET_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
if ((OS_REG_READ(ah, AR_TSF_L32) >> 10) == (tsf_low >> 10)) {
break;
}
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: TSF have moved while trying to set "
"quiet time TSF: 0x%08x\n",
__func__, tsf_low);
/* TSF shouldn't count twice or reg access is taking forever */
HALASSERT(j < 1);
}
OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
/* Allow the quiet mechanism to do its work */
OS_DELAY(200);
OS_REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
/* Verify all transmit is dead */
wait = timeout / AH_TIME_QUANTUM;
while (ar9300_num_tx_pending(ah, q)) {
if ((--wait) == 0) {
HALDEBUG(ah, HAL_DEBUG_TX,
"%s: Failed to stop Tx DMA in %d msec "
"after killing last frame\n",
__func__, timeout / 1000);
break;
}
OS_DELAY(AH_TIME_QUANTUM);
}
OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
}
OS_REG_WRITE(ah, AR_Q_TXD, 0);
return (wait != 0);
#undef AH_TX_STOP_DMA_TIMEOUT
#undef AH_TIME_QUANTUM
}
/*
* Abort transmit on all queues
*/
#define AR9300_ABORT_LOOPS 1000
#define AR9300_ABORT_WAIT 5
HAL_BOOL
ar9300_abort_tx_dma(struct ath_hal *ah)
{
int i, q;
/*
* set txd on all queues
*/
OS_REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
/*
* set tx abort bits (also disable rx)
*/
OS_REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_FORCE_CH_IDLE_HIGH | AR_DIAG_RX_DIS |
AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR));
OS_REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
/* Let TXE (all queues) clear before waiting on any pending frames */
for (i = 0; i < AR9300_ABORT_LOOPS; i++) {
if (OS_REG_READ(ah, AR_Q_TXE) == 0) {
break;
}
OS_DELAY(AR9300_ABORT_WAIT);
}
if (i == AR9300_ABORT_LOOPS) {
HALDEBUG(ah, HAL_DEBUG_TX, "%s[%d] reached max wait on TXE\n",
__func__, __LINE__);
}
/*
* wait on all tx queues
*/
for (q = 0; q < AR_NUM_QCU; q++) {
for (i = 0; i < AR9300_ABORT_LOOPS; i++) {
if (!ar9300_num_tx_pending(ah, q)) {
break;
}
OS_DELAY(AR9300_ABORT_WAIT);
}
if (i == AR9300_ABORT_LOOPS) {
HALDEBUG(ah, HAL_DEBUG_TX,
"%s[%d] reached max wait on pending tx, q %d\n",
__func__, __LINE__, q);
return AH_FALSE;
}
}
/*
* clear tx abort bits
*/
OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_FORCE_CH_IDLE_HIGH | AR_DIAG_RX_DIS |
AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR));
OS_REG_CLR_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
/*
* clear txd
*/
OS_REG_WRITE(ah, AR_Q_TXD, 0);
return AH_TRUE;
}
/*
* Determine which tx queues need interrupt servicing.
*/
void
ar9300_get_tx_intr_queue(struct ath_hal *ah, u_int32_t *txqs)
{
HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
"ar9300_get_tx_intr_queue: Should not be called\n");
#if 0
struct ath_hal_9300 *ahp = AH9300(ah);
*txqs &= ahp->ah_intr_txqs;
ahp->ah_intr_txqs &= ~(*txqs);
#endif
}
void
ar9300_reset_tx_status_ring(struct ath_hal *ah)
{
struct ath_hal_9300 *ahp = AH9300(ah);
ahp->ts_tail = 0;
/* Zero out the status descriptors */
OS_MEMZERO((void *)ahp->ts_ring, ahp->ts_size * sizeof(struct ar9300_txs));
HALDEBUG(ah, HAL_DEBUG_QUEUE,
"%s: TS Start 0x%x End 0x%x Virt %p, Size %d\n", __func__,
ahp->ts_paddr_start, ahp->ts_paddr_end, ahp->ts_ring, ahp->ts_size);
OS_REG_WRITE(ah, AR_Q_STATUS_RING_START, ahp->ts_paddr_start);
OS_REG_WRITE(ah, AR_Q_STATUS_RING_END, ahp->ts_paddr_end);
}
void
ar9300_setup_tx_status_ring(struct ath_hal *ah, void *ts_start,
u_int32_t ts_paddr_start, u_int16_t size)
{
struct ath_hal_9300 *ahp = AH9300(ah);
ahp->ts_paddr_start = ts_paddr_start;
ahp->ts_paddr_end = ts_paddr_start + (size * sizeof(struct ar9300_txs));
ahp->ts_size = size;
ahp->ts_ring = (struct ar9300_txs *)ts_start;
ar9300_reset_tx_status_ring(ah);
}
@@ -0,0 +1,959 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_desc.h"
#include "ah_internal.h"
#include "ar9300/ar9300desc.h"
#include "ar9300/ar9300.h"
#include "ar9300/ar9300reg.h"
#include "ar9300/ar9300phy.h"
#include "ah_devid.h"
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
static void ar9300_swap_tx_desc(void *ds);
#endif
void
ar9300_tx_req_intr_desc(struct ath_hal *ah, void *ds)
{
HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
"%s:Desc Interrupt not supported\n", __func__);
}
static inline u_int16_t
ar9300_calc_ptr_chk_sum(struct ar9300_txc *ads)
{
u_int checksum;
u_int16_t ptrchecksum;
/* checksum = __bswap32(ads->ds_info) + ads->ds_link */
checksum = ads->ds_info + ads->ds_link
+ ads->ds_data0 + ads->ds_ctl3
+ ads->ds_data1 + ads->ds_ctl5
+ ads->ds_data2 + ads->ds_ctl7
+ ads->ds_data3 + ads->ds_ctl9;
ptrchecksum = ((checksum & 0xffff) + (checksum >> 16)) & AR_tx_ptr_chk_sum;
return ptrchecksum;
}
HAL_BOOL
ar9300_fill_tx_desc(
struct ath_hal *ah,
void *ds,
HAL_DMA_ADDR *buf_addr,
u_int32_t *seg_len,
u_int desc_id,
u_int qcu,
HAL_KEY_TYPE key_type,
HAL_BOOL first_seg,
HAL_BOOL last_seg,
const void *ds0)
{
struct ar9300_txc *ads = AR9300TXC(ds);
/* Fill TXC info field */
ads->ds_info = TXC_INFO(qcu);
/* Set the buffer addresses */
ads->ds_data0 = buf_addr[0];
ads->ds_data1 = buf_addr[1];
ads->ds_data2 = buf_addr[2];
ads->ds_data3 = buf_addr[3];
/* Set the buffer lengths */
ads->ds_ctl3 = (seg_len[0] << AR_buf_len_S) & AR_buf_len;
ads->ds_ctl5 = (seg_len[1] << AR_buf_len_S) & AR_buf_len;
ads->ds_ctl7 = (seg_len[2] << AR_buf_len_S) & AR_buf_len;
ads->ds_ctl9 = (seg_len[3] << AR_buf_len_S) & AR_buf_len;
/* Fill in pointer checksum and descriptor id */
ads->ds_ctl10 = (desc_id << AR_tx_desc_id_S) | ar9300_calc_ptr_chk_sum(ads);
if (first_seg) {
/*
* First descriptor, don't clobber xmit control data
* setup by ar9300_set_11n_tx_desc.
*
* Note: AR_encr_type is already setup in the first descriptor by
* set_11n_tx_desc().
*/
ads->ds_ctl12 |= (last_seg ? 0 : AR_tx_more);
} else if (last_seg) { /* !first_seg && last_seg */
/*
* Last descriptor in a multi-descriptor frame,
* copy the multi-rate transmit parameters from
* the first frame for processing on completion.
*/
ads->ds_ctl11 = 0;
ads->ds_ctl12 = 0;
#ifdef AH_NEED_DESC_SWAP
ads->ds_ctl13 = __bswap32(AR9300TXC_CONST(ds0)->ds_ctl13);
ads->ds_ctl14 = __bswap32(AR9300TXC_CONST(ds0)->ds_ctl14);
ads->ds_ctl17 = __bswap32(SM(key_type, AR_encr_type));
#else
ads->ds_ctl13 = AR9300TXC_CONST(ds0)->ds_ctl13;
ads->ds_ctl14 = AR9300TXC_CONST(ds0)->ds_ctl14;
ads->ds_ctl17 = SM(key_type, AR_encr_type);
#endif
} else { /* !first_seg && !last_seg */
/*
* XXX Intermediate descriptor in a multi-descriptor frame.
*/
ads->ds_ctl11 = 0;
ads->ds_ctl12 = AR_tx_more;
ads->ds_ctl13 = 0;
ads->ds_ctl14 = 0;
ads->ds_ctl17 = SM(key_type, AR_encr_type);
}
return AH_TRUE;
}
void
ar9300_set_desc_link(struct ath_hal *ah, void *ds, u_int32_t link)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_link = link;
/* TODO - checksum is calculated twice for subframes
* Once in filldesc and again when linked. Need to fix.
*/
/* Fill in pointer checksum. Preserve descriptor id */
ads->ds_ctl10 &= ~AR_tx_ptr_chk_sum;
ads->ds_ctl10 |= ar9300_calc_ptr_chk_sum(ads);
}
void
ar9300_get_desc_link_ptr(struct ath_hal *ah, void *ds, u_int32_t **link)
{
struct ar9300_txc *ads = AR9300TXC(ds);
*link = &ads->ds_link;
}
void
ar9300_clear_tx_desc_status(struct ath_hal *ah, void *ds)
{
struct ar9300_txs *ads = AR9300TXS(ds);
ads->status1 = ads->status2 = 0;
ads->status3 = ads->status4 = 0;
ads->status5 = ads->status6 = 0;
ads->status7 = ads->status8 = 0;
}
#ifdef ATH_SWRETRY
void
ar9300_clear_dest_mask(struct ath_hal *ah, void *ds)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl11 |= AR_clr_dest_mask;
}
#endif
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
/* XXX what words need swapping */
/* Swap transmit descriptor */
static __inline void
ar9300_swap_tx_desc(void *dsp)
{
struct ar9300_txs *ds = (struct ar9300_txs *)dsp;
ds->ds_info = __bswap32(ds->ds_info);
ds->status1 = __bswap32(ds->status1);
ds->status2 = __bswap32(ds->status2);
ds->status3 = __bswap32(ds->status3);
ds->status4 = __bswap32(ds->status4);
ds->status5 = __bswap32(ds->status5);
ds->status6 = __bswap32(ds->status6);
ds->status7 = __bswap32(ds->status7);
ds->status8 = __bswap32(ds->status8);
}
#endif
/*
* Extract the transmit rate code.
*/
void
ar9300_get_tx_rate_code(struct ath_hal *ah, void *ds, struct ath_tx_status *ts)
{
struct ar9300_txc *ads = AR9300TXC(ds);
switch (ts->ts_finaltsi) {
case 0:
ts->ts_rate = MS(ads->ds_ctl14, AR_xmit_rate0);
break;
case 1:
ts->ts_rate = MS(ads->ds_ctl14, AR_xmit_rate1);
break;
case 2:
ts->ts_rate = MS(ads->ds_ctl14, AR_xmit_rate2);
break;
case 3:
ts->ts_rate = MS(ads->ds_ctl14, AR_xmit_rate3);
break;
}
ar9300_set_selfgenrate_limit(ah, ts->ts_rate);
}
/*
* Get TX Status descriptor contents.
*/
void
ar9300_get_raw_tx_desc(struct ath_hal *ah, u_int32_t *txstatus)
{
struct ath_hal_9300 *ahp = AH9300(ah);
struct ar9300_txs *ads;
ads = &ahp->ts_ring[ahp->ts_tail];
OS_MEMCPY(txstatus, ads, sizeof(struct ar9300_txs));
}
/*
* Processing of HW TX descriptor.
*/
HAL_STATUS
ar9300_proc_tx_desc(struct ath_hal *ah, void *txstatus)
{
struct ath_hal_9300 *ahp = AH9300(ah);
struct ar9300_txs *ads;
struct ath_tx_status *ts = (struct ath_tx_status *)txstatus;
u_int32_t dsinfo;
ads = &ahp->ts_ring[ahp->ts_tail];
if ((ads->status8 & AR_tx_done) == 0) {
return HAL_EINPROGRESS;
}
/*
* Sanity check
*/
#if 0
ath_hal_printf(ah,
"CHH: tail=%d\n", ahp->ts_tail);
ath_hal_printf(ah,
"CHH: ds_info 0x%x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
ads->ds_info,
ads->status1,
ads->status2,
ads->status3,
ads->status4,
ads->status5,
ads->status6,
ads->status7,
ads->status8);
#endif
/* Increment the tail to point to the next status element. */
ahp->ts_tail = (ahp->ts_tail + 1) & (ahp->ts_size-1);
/*
** For big endian systems, ds_info is not swapped as the other
** registers are. Ensure we use the bswap32 version (which is
** defined to "nothing" in little endian systems
*/
dsinfo = ads->ds_info;
if ((MS(dsinfo, AR_desc_id) != ATHEROS_VENDOR_ID) ||
(MS(dsinfo, AR_tx_rx_desc) != 1))
{
HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "%s: Tx Descriptor error %x\n",
__func__, dsinfo);
HALASSERT(0);
/* Zero out the status for reuse */
OS_MEMZERO(ads, sizeof(struct ar9300_txs));
return HAL_EIO;
}
/* Update software copies of the HW status */
ts->ts_queue_id = MS(dsinfo, AR_tx_qcu_num);
ts->ts_desc_id = MS(ads->status1, AR_tx_desc_id);
ts->ts_seqnum = MS(ads->status8, AR_seq_num);
ts->ts_tstamp = ads->status4;
ts->ts_status = 0;
ts->ts_flags = 0;
if (ads->status3 & AR_excessive_retries) {
ts->ts_status |= HAL_TXERR_XRETRY;
}
if (ads->status3 & AR_filtered) {
ts->ts_status |= HAL_TXERR_FILT;
}
if (ads->status3 & AR_fifounderrun) {
ts->ts_status |= HAL_TXERR_FIFO;
ar9300_update_tx_trig_level(ah, AH_TRUE);
}
if (ads->status8 & AR_tx_op_exceeded) {
ts->ts_status |= HAL_TXERR_XTXOP;
}
if (ads->status3 & AR_tx_timer_expired) {
ts->ts_status |= HAL_TXERR_TIMER_EXPIRED;
}
if (ads->status3 & AR_desc_cfg_err) {
ts->ts_flags |= HAL_TX_DESC_CFG_ERR;
}
if (ads->status3 & AR_tx_data_underrun) {
ts->ts_flags |= HAL_TX_DATA_UNDERRUN;
ar9300_update_tx_trig_level(ah, AH_TRUE);
}
if (ads->status3 & AR_tx_delim_underrun) {
ts->ts_flags |= HAL_TX_DELIM_UNDERRUN;
ar9300_update_tx_trig_level(ah, AH_TRUE);
}
if (ads->status2 & AR_tx_ba_status) {
ts->ts_flags |= HAL_TX_BA;
ts->ts_ba_low = ads->status5;
ts->ts_ba_high = ads->status6;
}
/*
* Extract the transmit rate.
*/
ts->ts_finaltsi = MS(ads->status8, AR_final_tx_idx);
ts->ts_rssi = MS(ads->status7, AR_tx_rssi_combined);
ts->ts_rssi_ctl[0] = MS(ads->status2, AR_tx_rssi_ant00);
ts->ts_rssi_ctl[1] = MS(ads->status2, AR_tx_rssi_ant01);
ts->ts_rssi_ctl[2] = MS(ads->status2, AR_tx_rssi_ant02);
ts->ts_rssi_ext[0] = MS(ads->status7, AR_tx_rssi_ant10);
ts->ts_rssi_ext[1] = MS(ads->status7, AR_tx_rssi_ant11);
ts->ts_rssi_ext[2] = MS(ads->status7, AR_tx_rssi_ant12);
ts->ts_shortretry = MS(ads->status3, AR_rts_fail_cnt);
ts->ts_longretry = MS(ads->status3, AR_data_fail_cnt);
ts->ts_virtcol = MS(ads->status3, AR_virt_retry_cnt);
ts->ts_antenna = 0;
/* extract TID from block ack */
ts->ts_tid = MS(ads->status8, AR_tx_tid);
/* Zero out the status for reuse */
OS_MEMZERO(ads, sizeof(struct ar9300_txs));
return HAL_OK;
}
/*
* Calculate air time of a transmit packet
* if comp_wastedt is 1, calculate air time only for failed subframes
* this is required for VOW_DCS ( dynamic channel selection )
*/
u_int32_t
ar9300_calc_tx_airtime(struct ath_hal *ah, void *ds, struct ath_tx_status *ts,
HAL_BOOL comp_wastedt, u_int8_t nbad, u_int8_t nframes )
{
struct ar9300_txc *ads = AR9300TXC(ds);
int finalindex_tries;
u_int32_t airtime, lastrate_dur;
/*
* Number of attempts made on the final index
* Note: If no BA was recv, then the data_fail_cnt is the number of tries
* made on the final index. If BA was recv, then add 1 to account for the
* successful attempt.
*/
if ( !comp_wastedt ){
finalindex_tries = ts->ts_longretry + (ts->ts_flags & HAL_TX_BA)? 1 : 0;
} else {
finalindex_tries = ts->ts_longretry ;
}
/*
* Calculate time of transmit on air for packet including retries
* at different rates.
*/
switch (ts->ts_finaltsi) {
case 0:
lastrate_dur = MS(ads->ds_ctl15, AR_packet_dur0);
airtime = (lastrate_dur * finalindex_tries);
break;
case 1:
lastrate_dur = MS(ads->ds_ctl15, AR_packet_dur1);
airtime = (lastrate_dur * finalindex_tries) +
(MS(ads->ds_ctl13, AR_xmit_data_tries0) *
MS(ads->ds_ctl15, AR_packet_dur0));
break;
case 2:
lastrate_dur = MS(ads->ds_ctl16, AR_packet_dur2);
airtime = (lastrate_dur * finalindex_tries) +
(MS(ads->ds_ctl13, AR_xmit_data_tries1) *
MS(ads->ds_ctl15, AR_packet_dur1)) +
(MS(ads->ds_ctl13, AR_xmit_data_tries0) *
MS(ads->ds_ctl15, AR_packet_dur0));
break;
case 3:
lastrate_dur = MS(ads->ds_ctl16, AR_packet_dur3);
airtime = (lastrate_dur * finalindex_tries) +
(MS(ads->ds_ctl13, AR_xmit_data_tries2) *
MS(ads->ds_ctl16, AR_packet_dur2)) +
(MS(ads->ds_ctl13, AR_xmit_data_tries1) *
MS(ads->ds_ctl15, AR_packet_dur1)) +
(MS(ads->ds_ctl13, AR_xmit_data_tries0) *
MS(ads->ds_ctl15, AR_packet_dur0));
break;
default:
HALASSERT(0);
return 0;
}
if ( comp_wastedt && (ts->ts_flags & HAL_TX_BA)){
airtime += nbad?((lastrate_dur*nbad) / nframes):0;
}
return airtime;
}
#ifdef AH_PRIVATE_DIAG
void
ar9300__cont_tx_mode(struct ath_hal *ah, void *ds, int mode)
{
#if 0
static int qnum = 0;
int i;
unsigned int qbits, val, val1, val2;
int prefetch;
struct ar9300_txs *ads = AR9300TXS(ds);
if (mode == 10) {
return;
}
if (mode == 7) { /* print status from the cont tx desc */
if (ads) {
val1 = ads->ds_txstatus1;
val2 = ads->ds_txstatus2;
HALDEBUG(ah, HAL_DEBUG_TXDESC, "s0(%x) s1(%x)\n",
(unsigned)val1, (unsigned)val2);
}
HALDEBUG(ah, HAL_DEBUG_TXDESC, "txe(%x) txd(%x)\n",
OS_REG_READ(ah, AR_Q_TXE),
OS_REG_READ(ah, AR_Q_TXD)
);
for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
val = OS_REG_READ(ah, AR_QTXDP(i));
val2 = OS_REG_READ(ah, AR_QSTS(i)) & AR_Q_STS_PEND_FR_CNT;
HALDEBUG(ah, HAL_DEBUG_TXDESC, "[%d] %x %d\n", i, val, val2);
}
return;
}
if (mode == 8) { /* set TXE for qnum */
OS_REG_WRITE(ah, AR_Q_TXE, 1 << qnum);
return;
}
if (mode == 9) {
prefetch = (int)ds;
return;
}
if (mode >= 1) { /* initiate cont tx operation */
/* Disable AGC to A2 */
qnum = (int) ds;
OS_REG_WRITE(ah, AR_PHY_TEST,
(OS_REG_READ(ah, AR_PHY_TEST) | PHY_AGC_CLR) );
OS_REG_WRITE(ah, 0x9864, OS_REG_READ(ah, 0x9864) | 0x7f000);
OS_REG_WRITE(ah, 0x9924, OS_REG_READ(ah, 0x9924) | 0x7f00fe);
OS_REG_WRITE(ah, AR_DIAG_SW,
(OS_REG_READ(ah, AR_DIAG_SW) |
(AR_DIAG_FORCE_RX_CLEAR + AR_DIAG_IGNORE_VIRT_CS)) );
OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* set receive disable */
if (mode == 3 || mode == 4) {
int txcfg;
if (mode == 3) {
OS_REG_WRITE(ah, AR_DLCL_IFS(qnum), 0);
OS_REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff);
OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 100);
OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, 100);
OS_REG_WRITE(ah, AR_TIME_OUT, 2);
OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, 100);
}
OS_REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff);
/* enable prefetch on qnum */
OS_REG_WRITE(ah, AR_D_FPCTL, 0x10 | qnum);
txcfg = 5 | (6 << AR_FTRIG_S);
OS_REG_WRITE(ah, AR_TXCFG, txcfg);
OS_REG_WRITE(ah, AR_QMISC(qnum), /* set QCU modes */
AR_Q_MISC_DCU_EARLY_TERM_REQ
+ AR_Q_MISC_FSP_ASAP
+ AR_Q_MISC_CBR_INCR_DIS1
+ AR_Q_MISC_CBR_INCR_DIS0
);
/* stop tx dma all all except qnum */
qbits = 0x3ff;
qbits &= ~(1 << qnum);
for (i = 0; i < 10; i++) {
if (i == qnum) {
continue;
}
OS_REG_WRITE(ah, AR_Q_TXD, 1 << i);
}
OS_REG_WRITE(ah, AR_Q_TXD, qbits);
/* clear and freeze MIB counters */
OS_REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
OS_REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
OS_REG_WRITE(ah, AR_DMISC(qnum),
(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
+ (AR_D_MISC_ARB_LOCKOUT_IGNORE)
+ (AR_D_MISC_POST_FR_BKOFF_DIS)
+ (AR_D_MISC_VIR_COL_HANDLING_IGNORE <<
AR_D_MISC_VIR_COL_HANDLING_S));
for (i = 0; i < HAL_NUM_TX_QUEUES + 2; i++) { /* disconnect QCUs */
if (i == qnum) {
continue;
}
OS_REG_WRITE(ah, AR_DQCUMASK(i), 0);
}
}
}
if (mode == 0) {
OS_REG_WRITE(ah, AR_PHY_TEST,
(OS_REG_READ(ah, AR_PHY_TEST) & ~PHY_AGC_CLR));
OS_REG_WRITE(ah, AR_DIAG_SW,
(OS_REG_READ(ah, AR_DIAG_SW) &
~(AR_DIAG_FORCE_RX_CLEAR + AR_DIAG_IGNORE_VIRT_CS)));
}
#endif
}
#endif
void
ar9300_set_paprd_tx_desc(struct ath_hal *ah, void *ds, int chain_num)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl12 |= SM((1 << chain_num), AR_paprd_chain_mask);
}
HAL_STATUS
ar9300_is_tx_done(struct ath_hal *ah)
{
struct ath_hal_9300 *ahp = AH9300(ah);
struct ar9300_txs *ads;
ads = &ahp->ts_ring[ahp->ts_tail];
if (ads->status8 & AR_tx_done) {
return HAL_OK;
}
return HAL_EINPROGRESS;
}
void
ar9300_set_11n_tx_desc(
struct ath_hal *ah,
void *ds,
u_int pkt_len,
HAL_PKT_TYPE type,
u_int tx_power,
u_int key_ix,
HAL_KEY_TYPE key_type,
u_int flags)
{
struct ar9300_txc *ads = AR9300TXC(ds);
struct ath_hal_9300 *ahp = AH9300(ah);
HALASSERT(is_valid_pkt_type(type));
HALASSERT(is_valid_key_type(key_type));
tx_power += ahp->ah_tx_power_index_offset;
if (tx_power > 63) {
tx_power = 63;
}
ads->ds_ctl11 =
(pkt_len & AR_frame_len)
| (flags & HAL_TXDESC_VMF ? AR_virt_more_frag : 0)
| SM(tx_power, AR_xmit_power0)
| (flags & HAL_TXDESC_VEOL ? AR_veol : 0)
| (flags & HAL_TXDESC_CLRDMASK ? AR_clr_dest_mask : 0)
| (key_ix != HAL_TXKEYIX_INVALID ? AR_dest_idx_valid : 0)
| (flags & HAL_TXDESC_LOWRXCHAIN ? AR_low_rx_chain : 0);
ads->ds_ctl12 =
(key_ix != HAL_TXKEYIX_INVALID ? SM(key_ix, AR_dest_idx) : 0)
| SM(type, AR_frame_type)
| (flags & HAL_TXDESC_NOACK ? AR_no_ack : 0)
| (flags & HAL_TXDESC_EXT_ONLY ? AR_ext_only : 0)
| (flags & HAL_TXDESC_EXT_AND_CTL ? AR_ext_and_ctl : 0);
ads->ds_ctl17 =
SM(key_type, AR_encr_type) | (flags & HAL_TXDESC_LDPC ? AR_ldpc : 0);
ads->ds_ctl18 = 0;
ads->ds_ctl19 = AR_not_sounding; /* set not sounding for normal frame */
/*
* Clear Ness1/2/3 (Number of Extension Spatial Streams) fields.
* Ness0 is cleared in ctl19. See EV66059 (BB panic).
*/
ads->ds_ctl20 = 0;
ads->ds_ctl21 = 0;
ads->ds_ctl22 = 0;
}
void ar9300_set_rx_chainmask(struct ath_hal *ah, int rxchainmask)
{
OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rxchainmask);
}
void ar9300_update_loc_ctl_reg(struct ath_hal *ah, int pos_bit)
{
u_int32_t reg_val;
reg_val = OS_REG_READ(ah, AR_LOC_CTL_REG);
if (pos_bit) {
if (!(reg_val & AR_LOC_CTL_REG_FS)) {
/* set fast timestamp bit in the regiter */
OS_REG_WRITE(ah, AR_LOC_CTL_REG, (reg_val | AR_LOC_CTL_REG_FS));
OS_REG_WRITE(ah, AR_LOC_TIMER_REG, 0);
}
}
else {
OS_REG_WRITE(ah, AR_LOC_CTL_REG, (reg_val & ~AR_LOC_CTL_REG_FS));
}
}
#if 0
#define HT_RC_2_MCS(_rc) ((_rc) & 0x0f)
static const u_int8_t ba_duration_delta[] = {
24, /* 0: BPSK */
12, /* 1: QPSK 1/2 */
12, /* 2: QPSK 3/4 */
4, /* 3: 16-QAM 1/2 */
4, /* 4: 16-QAM 3/4 */
4, /* 5: 64-QAM 2/3 */
4, /* 6: 64-QAM 3/4 */
4, /* 7: 64-QAM 5/6 */
24, /* 8: BPSK */
12, /* 9: QPSK 1/2 */
12, /* 10: QPSK 3/4 */
4, /* 11: 16-QAM 1/2 */
4, /* 12: 16-QAM 3/4 */
4, /* 13: 64-QAM 2/3 */
4, /* 14: 64-QAM 3/4 */
4, /* 15: 64-QAM 5/6 */
};
#endif
static u_int8_t
ar9300_get_tx_mode(u_int rate_flags)
{
/* Check whether STBC is enabled if TxBF is not enabled */
if (rate_flags & HAL_RATESERIES_STBC){
return AR9300_STBC_MODE;
}
return AR9300_DEF_MODE;
}
void
ar9300_set_11n_rate_scenario(
struct ath_hal *ah,
void *ds,
void *lastds,
u_int dur_update_en,
u_int rts_cts_rate,
u_int rts_cts_duration,
HAL_11N_RATE_SERIES series[],
u_int nseries,
u_int flags,
u_int32_t smart_antenna)
{
struct ath_hal_private *ap = AH_PRIVATE(ah);
struct ar9300_txc *ads = AR9300TXC(ds);
struct ar9300_txc *last_ads = AR9300TXC(lastds);
u_int32_t ds_ctl11;
u_int8_t ant, cal_pkt = 0;
u_int mode, tx_mode = AR9300_DEF_MODE;
HALASSERT(nseries == 4);
(void)nseries;
(void)rts_cts_duration; /* use H/W to calculate RTSCTSDuration */
ds_ctl11 = ads->ds_ctl11;
/*
* Rate control settings override
*/
if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
if (flags & HAL_TXDESC_RTSENA) {
ds_ctl11 &= ~AR_cts_enable;
ds_ctl11 |= AR_rts_enable;
} else {
ds_ctl11 &= ~AR_rts_enable;
ds_ctl11 |= AR_cts_enable;
}
} else {
ds_ctl11 = (ds_ctl11 & ~(AR_rts_enable | AR_cts_enable));
}
mode = ath_hal_get_curmode(ah, ap->ah_curchan);
cal_pkt = (ads->ds_ctl12 & AR_paprd_chain_mask)?1:0;
if (ah->ah_config.ath_hal_desc_tpc) {
int16_t txpower;
if (!cal_pkt) {
/* Series 0 TxPower */
tx_mode = ar9300_get_tx_mode(series[0].RateFlags);
txpower = ar9300_get_rate_txpower(ah, mode, series[0].RateIndex,
series[0].ChSel, tx_mode);
} else {
txpower = AH9300(ah)->paprd_training_power;
}
ds_ctl11 &= ~AR_xmit_power0;
ds_ctl11 |=
set_11n_tx_power(0, AH_MIN(txpower, series[0].tx_power_cap));
}
ads->ds_ctl11 = ds_ctl11;
ads->ds_ctl13 = set_11n_tries(series, 0)
| set_11n_tries(series, 1)
| set_11n_tries(series, 2)
| set_11n_tries(series, 3)
| (dur_update_en ? AR_dur_update_ena : 0)
| SM(0, AR_burst_dur);
ads->ds_ctl14 = set_11n_rate(series, 0)
| set_11n_rate(series, 1)
| set_11n_rate(series, 2)
| set_11n_rate(series, 3);
ads->ds_ctl15 = set_11n_pkt_dur_rts_cts(series, 0)
| set_11n_pkt_dur_rts_cts(series, 1);
ads->ds_ctl16 = set_11n_pkt_dur_rts_cts(series, 2)
| set_11n_pkt_dur_rts_cts(series, 3);
ads->ds_ctl18 = set_11n_rate_flags(series, 0)
| set_11n_rate_flags(series, 1)
| set_11n_rate_flags(series, 2)
| set_11n_rate_flags(series, 3)
| SM(rts_cts_rate, AR_rts_cts_rate);
/* set not sounding for normal frame */
ads->ds_ctl19 = AR_not_sounding;
if (ah->ah_config.ath_hal_desc_tpc) {
int16_t txpower;
if (!cal_pkt) {
/* Series 1 TxPower */
tx_mode = ar9300_get_tx_mode(series[1].RateFlags);
txpower = ar9300_get_rate_txpower(
ah, mode, series[1].RateIndex, series[1].ChSel, tx_mode);
} else {
txpower = AH9300(ah)->paprd_training_power;
}
ads->ds_ctl20 |=
set_11n_tx_power(1, AH_MIN(txpower, series[1].tx_power_cap));
/* Series 2 TxPower */
if (!cal_pkt) {
tx_mode = ar9300_get_tx_mode(series[2].RateFlags);
txpower = ar9300_get_rate_txpower(
ah, mode, series[2].RateIndex, series[2].ChSel, tx_mode);
} else {
txpower = AH9300(ah)->paprd_training_power;
}
ads->ds_ctl21 |=
set_11n_tx_power(2, AH_MIN(txpower, series[2].tx_power_cap));
/* Series 3 TxPower */
if (!cal_pkt) {
tx_mode = ar9300_get_tx_mode(series[3].RateFlags);
txpower = ar9300_get_rate_txpower(
ah, mode, series[3].RateIndex, series[3].ChSel, tx_mode);
} else {
txpower = AH9300(ah)->paprd_training_power;
}
ads->ds_ctl22 |=
set_11n_tx_power(3, AH_MIN(txpower, series[3].tx_power_cap));
}
if (smart_antenna != 0xffffffff)
{
/* TX DESC dword 19 to 23 are used for smart antenna configuaration
* ctl19 for rate series 0 ... ctrl22 for series 3
* bits[2:0] used to configure smart anntenna
*/
ant = (smart_antenna&0x000000ff);
ads->ds_ctl19 |= ant; /* rateseries 0 */
ant = (smart_antenna&0x0000ff00) >> 8;
ads->ds_ctl20 |= ant; /* rateseries 1 */
ant = (smart_antenna&0x00ff0000) >> 16;
ads->ds_ctl21 |= ant; /* rateseries 2 */
ant = (smart_antenna&0xff000000) >> 24;
ads->ds_ctl22 |= ant; /* rateseries 3 */
}
#ifdef AH_NEED_DESC_SWAP
last_ads->ds_ctl13 = __bswap32(ads->ds_ctl13);
last_ads->ds_ctl14 = __bswap32(ads->ds_ctl14);
#else
last_ads->ds_ctl13 = ads->ds_ctl13;
last_ads->ds_ctl14 = ads->ds_ctl14;
#endif
}
void
ar9300_set_11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
u_int aggr_len, u_int num_delims)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl12 |= (AR_is_aggr | AR_more_aggr);
ads->ds_ctl17 &= ~AR_aggr_len;
ads->ds_ctl17 &= ~AR_pad_delim;
/* XXX should use a stack variable! */
ads->ds_ctl17 |= SM(aggr_len, AR_aggr_len);
ads->ds_ctl17 |= SM(num_delims, AR_pad_delim);
}
void
ar9300_set_11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
u_int num_delims)
{
struct ar9300_txc *ads = AR9300TXC(ds);
unsigned int ctl17;
ads->ds_ctl12 |= (AR_is_aggr | AR_more_aggr);
/*
* We use a stack variable to manipulate ctl6 to reduce uncached
* read modify, modfiy, write.
*/
ctl17 = ads->ds_ctl17;
ctl17 &= ~AR_pad_delim;
ctl17 |= SM(num_delims, AR_pad_delim);
ads->ds_ctl17 = ctl17;
}
void
ar9300_set_11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl12 |= AR_is_aggr;
ads->ds_ctl12 &= ~AR_more_aggr;
ads->ds_ctl17 &= ~AR_pad_delim;
}
void
ar9300_clr_11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl12 &= (~AR_is_aggr & ~AR_more_aggr);
}
void
ar9300_set_11n_burst_duration(struct ath_hal *ah, struct ath_desc *ds,
u_int burst_duration)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl13 &= ~AR_burst_dur;
ads->ds_ctl13 |= SM(burst_duration, AR_burst_dur);
}
void
ar9300_set_11n_rifs_burst_middle(struct ath_hal *ah, void *ds)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl12 |= AR_more_rifs | AR_no_ack;
}
void
ar9300_set_11n_rifs_burst_last(struct ath_hal *ah, void *ds)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl12 &= (~AR_more_aggr & ~AR_more_rifs);
}
void
ar9300_clr_11n_rifs_burst(struct ath_hal *ah, void *ds)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl12 &= (~AR_more_rifs & ~AR_no_ack);
}
void
ar9300_set_11n_aggr_rifs_burst(struct ath_hal *ah, void *ds)
{
struct ar9300_txc *ads = AR9300TXC(ds);
ads->ds_ctl12 |= AR_no_ack;
ads->ds_ctl12 &= ~AR_more_rifs;
}
void
ar9300_set_11n_virtual_more_frag(struct ath_hal *ah, struct ath_desc *ds,
u_int vmf)
{
struct ar9300_txc *ads = AR9300TXC(ds);
if (vmf) {
ads->ds_ctl11 |= AR_virt_more_frag;
} else {
ads->ds_ctl11 &= ~AR_virt_more_frag;
}
}
void
ar9300_get_desc_info(struct ath_hal *ah, HAL_DESC_INFO *desc_info)
{
desc_info->txctl_numwords = TXCTL_NUMWORDS(ah);
desc_info->txctl_offset = TXCTL_OFFSET(ah);
desc_info->txstatus_numwords = TXSTATUS_NUMWORDS(ah);
desc_info->txstatus_offset = TXSTATUS_OFFSET(ah);
desc_info->rxctl_numwords = RXCTL_NUMWORDS(ah);
desc_info->rxctl_offset = RXCTL_OFFSET(ah);
desc_info->rxstatus_numwords = RXSTATUS_NUMWORDS(ah);
desc_info->rxstatus_offset = RXSTATUS_OFFSET(ah);
}
@@ -0,0 +1,587 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/* Contains descriptor definitions for Osprey */
#ifndef _ATH_AR9300_DESC_H_
#define _ATH_AR9300_DESC_H_
#ifdef _KERNEL
#include "ar9300_freebsd_inc.h"
#endif
/* Osprey Status Descriptor. */
struct ar9300_txs {
u_int32_t ds_info;
u_int32_t status1;
u_int32_t status2;
u_int32_t status3;
u_int32_t status4;
u_int32_t status5;
u_int32_t status6;
u_int32_t status7;
u_int32_t status8;
};
struct ar9300_rxs {
u_int32_t ds_info;
u_int32_t status1;
u_int32_t status2;
u_int32_t status3;
u_int32_t status4;
u_int32_t status5;
u_int32_t status6;
u_int32_t status7;
u_int32_t status8;
u_int32_t status9;
u_int32_t status10;
u_int32_t status11;
};
/* Transmit Control Descriptor */
struct ar9300_txc {
u_int32_t ds_info; /* descriptor information */
u_int32_t ds_link; /* link pointer */
u_int32_t ds_data0; /* data pointer to 1st buffer */
u_int32_t ds_ctl3; /* DMA control 3 */
u_int32_t ds_data1; /* data pointer to 2nd buffer */
u_int32_t ds_ctl5; /* DMA control 5 */
u_int32_t ds_data2; /* data pointer to 3rd buffer */
u_int32_t ds_ctl7; /* DMA control 7 */
u_int32_t ds_data3; /* data pointer to 4th buffer */
u_int32_t ds_ctl9; /* DMA control 9 */
u_int32_t ds_ctl10; /* DMA control 10 */
u_int32_t ds_ctl11; /* DMA control 11 */
u_int32_t ds_ctl12; /* DMA control 12 */
u_int32_t ds_ctl13; /* DMA control 13 */
u_int32_t ds_ctl14; /* DMA control 14 */
u_int32_t ds_ctl15; /* DMA control 15 */
u_int32_t ds_ctl16; /* DMA control 16 */
u_int32_t ds_ctl17; /* DMA control 17 */
u_int32_t ds_ctl18; /* DMA control 18 */
u_int32_t ds_ctl19; /* DMA control 19 */
u_int32_t ds_ctl20; /* DMA control 20 */
u_int32_t ds_ctl21; /* DMA control 21 */
u_int32_t ds_ctl22; /* DMA control 22 */
u_int32_t ds_pad[9]; /* pad to cache line (128 bytes/32 dwords) */
};
#define AR9300RXS(_rxs) ((struct ar9300_rxs *)(_rxs))
#define AR9300TXS(_txs) ((struct ar9300_txs *)(_txs))
#define AR9300TXC(_ds) ((struct ar9300_txc *)(_ds))
#define AR9300TXC_CONST(_ds) ((const struct ar9300_txc *)(_ds))
/* ds_info */
#define AR_desc_len 0x000000ff
#define AR_rx_priority 0x00000100
#define AR_tx_qcu_num 0x00000f00
#define AR_tx_qcu_num_S 8
#define AR_ctrl_stat 0x00004000
#define AR_ctrl_stat_S 14
#define AR_tx_rx_desc 0x00008000
#define AR_tx_rx_desc_S 15
#define AR_desc_id 0xffff0000
#define AR_desc_id_S 16
/***********
* TX Desc *
***********/
/* ds_ctl3 */
/* ds_ctl5 */
/* ds_ctl7 */
/* ds_ctl9 */
#define AR_buf_len 0x0fff0000
#define AR_buf_len_S 16
/* ds_ctl10 */
#define AR_tx_desc_id 0xffff0000
#define AR_tx_desc_id_S 16
#define AR_tx_ptr_chk_sum 0x0000ffff
/* ds_ctl11 */
#define AR_frame_len 0x00000fff
#define AR_virt_more_frag 0x00001000
#define AR_tx_ctl_rsvd00 0x00002000
#define AR_low_rx_chain 0x00004000
#define AR_tx_clear_retry 0x00008000
#define AR_xmit_power0 0x003f0000
#define AR_xmit_power0_S 16
#define AR_rts_enable 0x00400000
#define AR_veol 0x00800000
#define AR_clr_dest_mask 0x01000000
#define AR_tx_bf0 0x02000000
#define AR_tx_bf1 0x04000000
#define AR_tx_bf2 0x08000000
#define AR_tx_bf3 0x10000000
#define AR_TxBfSteered 0x1e000000 /* for tx_bf*/
#define AR_tx_intr_req 0x20000000
#define AR_dest_idx_valid 0x40000000
#define AR_cts_enable 0x80000000
/* ds_ctl12 */
#define AR_tx_ctl_rsvd02 0x000001ff
#define AR_paprd_chain_mask 0x00000e00
#define AR_paprd_chain_mask_S 9
#define AR_tx_more 0x00001000
#define AR_dest_idx 0x000fe000
#define AR_dest_idx_S 13
#define AR_frame_type 0x00f00000
#define AR_frame_type_S 20
#define AR_no_ack 0x01000000
#define AR_insert_ts 0x02000000
#define AR_corrupt_fcs 0x04000000
#define AR_ext_only 0x08000000
#define AR_ext_and_ctl 0x10000000
#define AR_more_aggr 0x20000000
#define AR_is_aggr 0x40000000
#define AR_more_rifs 0x80000000
#define AR_loc_mode 0x00000100 /* Positioning bit in TX desc */
/* ds_ctl13 */
#define AR_burst_dur 0x00007fff
#define AR_burst_dur_S 0
#define AR_dur_update_ena 0x00008000
#define AR_xmit_data_tries0 0x000f0000
#define AR_xmit_data_tries0_S 16
#define AR_xmit_data_tries1 0x00f00000
#define AR_xmit_data_tries1_S 20
#define AR_xmit_data_tries2 0x0f000000
#define AR_xmit_data_tries2_S 24
#define AR_xmit_data_tries3 0xf0000000
#define AR_xmit_data_tries3_S 28
/* ds_ctl14 */
#define AR_xmit_rate0 0x000000ff
#define AR_xmit_rate0_S 0
#define AR_xmit_rate1 0x0000ff00
#define AR_xmit_rate1_S 8
#define AR_xmit_rate2 0x00ff0000
#define AR_xmit_rate2_S 16
#define AR_xmit_rate3 0xff000000
#define AR_xmit_rate3_S 24
/* ds_ctl15 */
#define AR_packet_dur0 0x00007fff
#define AR_packet_dur0_S 0
#define AR_rts_cts_qual0 0x00008000
#define AR_packet_dur1 0x7fff0000
#define AR_packet_dur1_S 16
#define AR_rts_cts_qual1 0x80000000
/* ds_ctl16 */
#define AR_packet_dur2 0x00007fff
#define AR_packet_dur2_S 0
#define AR_rts_cts_qual2 0x00008000
#define AR_packet_dur3 0x7fff0000
#define AR_packet_dur3_S 16
#define AR_rts_cts_qual3 0x80000000
/* ds_ctl17 */
#define AR_aggr_len 0x0000ffff
#define AR_aggr_len_S 0
#define AR_tx_ctl_rsvd60 0x00030000
#define AR_pad_delim 0x03fc0000
#define AR_pad_delim_S 18
#define AR_encr_type 0x1c000000
#define AR_encr_type_S 26
#define AR_tx_dc_ap_sta_sel 0x40000000
#define AR_tx_ctl_rsvd61 0xc0000000
#define AR_calibrating 0x40000000
#define AR_ldpc 0x80000000
/* ds_ctl18 */
#define AR_2040_0 0x00000001
#define AR_gi0 0x00000002
#define AR_chain_sel0 0x0000001c
#define AR_chain_sel0_S 2
#define AR_2040_1 0x00000020
#define AR_gi1 0x00000040
#define AR_chain_sel1 0x00000380
#define AR_chain_sel1_S 7
#define AR_2040_2 0x00000400
#define AR_gi2 0x00000800
#define AR_chain_sel2 0x00007000
#define AR_chain_sel2_S 12
#define AR_2040_3 0x00008000
#define AR_gi3 0x00010000
#define AR_chain_sel3 0x000e0000
#define AR_chain_sel3_S 17
#define AR_rts_cts_rate 0x0ff00000
#define AR_rts_cts_rate_S 20
#define AR_stbc0 0x10000000
#define AR_stbc1 0x20000000
#define AR_stbc2 0x40000000
#define AR_stbc3 0x80000000
/* ds_ctl19 */
#define AR_tx_ant0 0x00ffffff
#define AR_tx_ant_sel0 0x80000000
#define AR_RTS_HTC_TRQ 0x10000000 /* bit 28 for rts_htc_TRQ*/ /*for tx_bf*/
#define AR_not_sounding 0x20000000
#define AR_ness 0xc0000000
#define AR_ness_S 30
/* ds_ctl20 */
#define AR_tx_ant1 0x00ffffff
#define AR_xmit_power1 0x3f000000
#define AR_xmit_power1_S 24
#define AR_tx_ant_sel1 0x80000000
#define AR_ness1 0xc0000000
#define AR_ness1_S 30
/* ds_ctl21 */
#define AR_tx_ant2 0x00ffffff
#define AR_xmit_power2 0x3f000000
#define AR_xmit_power2_S 24
#define AR_tx_ant_sel2 0x80000000
#define AR_ness2 0xc0000000
#define AR_ness2_S 30
/* ds_ctl22 */
#define AR_tx_ant3 0x00ffffff
#define AR_xmit_power3 0x3f000000
#define AR_xmit_power3_S 24
#define AR_tx_ant_sel3 0x80000000
#define AR_ness3 0xc0000000
#define AR_ness3_S 30
/*************
* TX Status *
*************/
/* ds_status1 */
#define AR_tx_status_rsvd 0x0000ffff
/* ds_status2 */
#define AR_tx_rssi_ant00 0x000000ff
#define AR_tx_rssi_ant00_S 0
#define AR_tx_rssi_ant01 0x0000ff00
#define AR_tx_rssi_ant01_S 8
#define AR_tx_rssi_ant02 0x00ff0000
#define AR_tx_rssi_ant02_S 16
#define AR_tx_status_rsvd00 0x3f000000
#define AR_tx_ba_status 0x40000000
#define AR_tx_status_rsvd01 0x80000000
/* ds_status3 */
#define AR_frm_xmit_ok 0x00000001
#define AR_excessive_retries 0x00000002
#define AR_fifounderrun 0x00000004
#define AR_filtered 0x00000008
#define AR_rts_fail_cnt 0x000000f0
#define AR_rts_fail_cnt_S 4
#define AR_data_fail_cnt 0x00000f00
#define AR_data_fail_cnt_S 8
#define AR_virt_retry_cnt 0x0000f000
#define AR_virt_retry_cnt_S 12
#define AR_tx_delim_underrun 0x00010000
#define AR_tx_data_underrun 0x00020000
#define AR_desc_cfg_err 0x00040000
#define AR_tx_timer_expired 0x00080000
#define AR_tx_status_rsvd10 0xfff00000
/* ds_status7 */
#define AR_tx_rssi_ant10 0x000000ff
#define AR_tx_rssi_ant10_S 0
#define AR_tx_rssi_ant11 0x0000ff00
#define AR_tx_rssi_ant11_S 8
#define AR_tx_rssi_ant12 0x00ff0000
#define AR_tx_rssi_ant12_S 16
#define AR_tx_rssi_combined 0xff000000
#define AR_tx_rssi_combined_S 24
/* ds_status8 */
#define AR_tx_done 0x00000001
#define AR_seq_num 0x00001ffe
#define AR_seq_num_S 1
#define AR_tx_status_rsvd80 0x0001e000
#define AR_tx_op_exceeded 0x00020000
#define AR_tx_status_rsvd81 0x001c0000
#define AR_TXBFStatus 0x001c0000
#define AR_TXBFStatus_S 18
#define AR_tx_bf_bw_mismatch 0x00040000
#define AR_tx_bf_stream_miss 0x00080000
#define AR_final_tx_idx 0x00600000
#define AR_final_tx_idx_S 21
#define AR_tx_bf_dest_miss 0x00800000
#define AR_tx_bf_expired 0x01000000
#define AR_power_mgmt 0x02000000
#define AR_tx_status_rsvd83 0x0c000000
#define AR_tx_tid 0xf0000000
#define AR_tx_tid_S 28
#define AR_tx_fast_ts 0x08000000 /* 27th bit for locationing */
/*************
* Rx Status *
*************/
/* ds_status1 */
#define AR_rx_rssi_ant00 0x000000ff
#define AR_rx_rssi_ant00_S 0
#define AR_rx_rssi_ant01 0x0000ff00
#define AR_rx_rssi_ant01_S 8
#define AR_rx_rssi_ant02 0x00ff0000
#define AR_rx_rssi_ant02_S 16
#define AR_rx_rate 0xff000000
#define AR_rx_rate_S 24
/* ds_status2 */
#define AR_data_len 0x00000fff
#define AR_rx_more 0x00001000
#define AR_num_delim 0x003fc000
#define AR_num_delim_S 14
#define AR_hw_upload_data 0x00400000
#define AR_hw_upload_data_S 22
#define AR_rx_status_rsvd10 0xff800000
/* ds_status4 */
#define AR_gi 0x00000001
#define AR_2040 0x00000002
#define AR_parallel40 0x00000004
#define AR_parallel40_S 2
#define AR_rx_stbc 0x00000008
#define AR_rx_not_sounding 0x00000010
#define AR_rx_ness 0x00000060
#define AR_rx_ness_S 5
#define AR_hw_upload_data_valid 0x00000080
#define AR_hw_upload_data_valid_S 7
#define AR_rx_antenna 0xffffff00
#define AR_rx_antenna_S 8
/* ds_status5 */
#define AR_rx_rssi_ant10 0x000000ff
#define AR_rx_rssi_ant10_S 0
#define AR_rx_rssi_ant11 0x0000ff00
#define AR_rx_rssi_ant11_S 8
#define AR_rx_rssi_ant12 0x00ff0000
#define AR_rx_rssi_ant12_S 16
#define AR_rx_rssi_combined 0xff000000
#define AR_rx_rssi_combined_S 24
/* ds_status6 */
#define AR_rx_evm0 status6
/* ds_status7 */
#define AR_rx_evm1 status7
/* ds_status8 */
#define AR_rx_evm2 status8
/* ds_status9 */
#define AR_rx_evm3 status9
/* ds_status11 */
#define AR_rx_done 0x00000001
#define AR_rx_frame_ok 0x00000002
#define AR_crc_err 0x00000004
#define AR_decrypt_crc_err 0x00000008
#define AR_phyerr 0x00000010
#define AR_michael_err 0x00000020
#define AR_pre_delim_crc_err 0x00000040
#define AR_apsd_trig 0x00000080
#define AR_rx_key_idx_valid 0x00000100
#define AR_key_idx 0x0000fe00
#define AR_key_idx_S 9
#define AR_phy_err_code 0x0000ff00
#define AR_phy_err_code_S 8
#define AR_rx_more_aggr 0x00010000
#define AR_rx_aggr 0x00020000
#define AR_post_delim_crc_err 0x00040000
#define AR_rx_status_rsvd71 0x01f80000
#define AR_hw_upload_data_type 0x06000000
#define AR_hw_upload_data_type_S 25
#define AR_position_bit 0x08000000 /* positioning bit */
#define AR_hi_rx_chain 0x10000000
#define AR_rx_first_aggr 0x20000000
#define AR_decrypt_busy_err 0x40000000
#define AR_key_miss 0x80000000
#define TXCTL_OFFSET(ah) 11
#define TXCTL_NUMWORDS(ah) 12
#define TXSTATUS_OFFSET(ah) 2
#define TXSTATUS_NUMWORDS(ah) 7
#define RXCTL_OFFSET(ah) 0
#define RXCTL_NUMWORDS(ah) 0
#define RXSTATUS_OFFSET(ah) 1
#define RXSTATUS_NUMWORDS(ah) 11
#define TXC_INFO(_qcu) (ATHEROS_VENDOR_ID << AR_desc_id_S) \
| (1 << AR_tx_rx_desc_S) \
| (1 << AR_ctrl_stat_S) \
| (_qcu << AR_tx_qcu_num_S) \
| (0x17)
#define VALID_KEY_TYPES \
((1 << HAL_KEY_TYPE_CLEAR) | (1 << HAL_KEY_TYPE_WEP)|\
(1 << HAL_KEY_TYPE_AES) | (1 << HAL_KEY_TYPE_TKIP))
#define is_valid_key_type(_t) ((1 << (_t)) & VALID_KEY_TYPES)
#define set_11n_tries(_series, _index) \
(SM((_series)[_index].Tries, AR_xmit_data_tries##_index))
#define set_11n_rate(_series, _index) \
(SM((_series)[_index].Rate, AR_xmit_rate##_index))
#define set_11n_pkt_dur_rts_cts(_series, _index) \
(SM((_series)[_index].PktDuration, AR_packet_dur##_index) |\
((_series)[_index].RateFlags & HAL_RATESERIES_RTS_CTS ?\
AR_rts_cts_qual##_index : 0))
#define not_two_stream_rate(_rate) (((_rate) >0x8f) || ((_rate)<0x88))
#define set_11n_tx_bf_ldpc( _series) \
((( not_two_stream_rate((_series)[0].Rate) && (not_two_stream_rate((_series)[1].Rate)|| \
(!(_series)[1].Tries)) && (not_two_stream_rate((_series)[2].Rate)||(!(_series)[2].Tries)) \
&& (not_two_stream_rate((_series)[3].Rate)||(!(_series)[3].Tries)))) \
? AR_ldpc : 0)
#define set_11n_rate_flags(_series, _index) \
((_series)[_index].RateFlags & HAL_RATESERIES_2040 ? AR_2040_##_index : 0) \
|((_series)[_index].RateFlags & HAL_RATESERIES_HALFGI ? AR_gi##_index : 0) \
|((_series)[_index].RateFlags & HAL_RATESERIES_STBC ? AR_stbc##_index : 0) \
|SM((_series)[_index].ChSel, AR_chain_sel##_index)
#define set_11n_tx_power(_index, _txpower) \
SM(_txpower, AR_xmit_power##_index)
#define IS_3CHAIN_TX(_ah) (AH9300(_ah)->ah_tx_chainmask == 7)
/*
* Descriptor Access Functions
*/
/* XXX valid Tx rates will change for 3 stream support */
#define VALID_PKT_TYPES \
((1<<HAL_PKT_TYPE_NORMAL)|(1<<HAL_PKT_TYPE_ATIM)|\
(1<<HAL_PKT_TYPE_PSPOLL)|(1<<HAL_PKT_TYPE_PROBE_RESP)|\
(1<<HAL_PKT_TYPE_BEACON))
#define is_valid_pkt_type(_t) ((1<<(_t)) & VALID_PKT_TYPES)
#define VALID_TX_RATES \
((1<<0x0b)|(1<<0x0f)|(1<<0x0a)|(1<<0x0e)|(1<<0x09)|(1<<0x0d)|\
(1<<0x08)|(1<<0x0c)|(1<<0x1b)|(1<<0x1a)|(1<<0x1e)|(1<<0x19)|\
(1<<0x1d)|(1<<0x18)|(1<<0x1c))
#define is_valid_tx_rate(_r) ((1<<(_r)) & VALID_TX_RATES)
#ifdef _KERNEL
/* TX common functions */
extern HAL_BOOL ar9300_update_tx_trig_level(struct ath_hal *,
HAL_BOOL IncTrigLevel);
extern u_int16_t ar9300_get_tx_trig_level(struct ath_hal *);
extern HAL_BOOL ar9300_set_tx_queue_props(struct ath_hal *ah, int q,
const HAL_TXQ_INFO *q_info);
extern HAL_BOOL ar9300_get_tx_queue_props(struct ath_hal *ah, int q,
HAL_TXQ_INFO *q_info);
extern int ar9300_setup_tx_queue(struct ath_hal *ah, HAL_TX_QUEUE type,
const HAL_TXQ_INFO *q_info);
extern HAL_BOOL ar9300_release_tx_queue(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar9300_reset_tx_queue(struct ath_hal *ah, u_int q);
extern u_int32_t ar9300_get_tx_dp(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar9300_set_tx_dp(struct ath_hal *ah, u_int q, u_int32_t txdp);
extern HAL_BOOL ar9300_start_tx_dma(struct ath_hal *ah, u_int q);
extern u_int32_t ar9300_num_tx_pending(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar9300_stop_tx_dma(struct ath_hal *ah, u_int q, u_int timeout);
extern HAL_BOOL ar9300_stop_tx_dma_indv_que(struct ath_hal *ah, u_int q, u_int timeout);
extern HAL_BOOL ar9300_abort_tx_dma(struct ath_hal *ah);
extern void ar9300_get_tx_intr_queue(struct ath_hal *ah, u_int32_t *);
extern void ar9300_tx_req_intr_desc(struct ath_hal *ah, void *ds);
extern HAL_BOOL ar9300_fill_tx_desc(struct ath_hal *ah, void *ds, HAL_DMA_ADDR *buf_addr,
u_int32_t *seg_len, u_int desc_id, u_int qcu, HAL_KEY_TYPE key_type, HAL_BOOL first_seg,
HAL_BOOL last_seg, const void *ds0);
extern void ar9300_set_desc_link(struct ath_hal *, void *ds, u_int32_t link);
extern void ar9300_get_desc_link_ptr(struct ath_hal *, void *ds, u_int32_t **link);
extern void ar9300_clear_tx_desc_status(struct ath_hal *ah, void *ds);
#ifdef ATH_SWRETRY
extern void ar9300_clear_dest_mask(struct ath_hal *ah, void *ds);
#endif
extern HAL_STATUS ar9300_proc_tx_desc(struct ath_hal *ah, void *);
extern void ar9300_get_raw_tx_desc(struct ath_hal *ah, u_int32_t *);
extern void ar9300_get_tx_rate_code(struct ath_hal *ah, void *, struct ath_tx_status *);
extern u_int32_t ar9300_calc_tx_airtime(struct ath_hal *ah, void *, struct ath_tx_status *,
HAL_BOOL comp_wastedt, u_int8_t nbad, u_int8_t nframes);
extern void ar9300_setup_tx_status_ring(struct ath_hal *ah, void *, u_int32_t , u_int16_t);
extern void ar9300_set_paprd_tx_desc(struct ath_hal *ah, void *ds, int chain_num);
HAL_STATUS ar9300_is_tx_done(struct ath_hal *ah);
extern void ar9300_set_11n_tx_desc(struct ath_hal *ah, void *ds,
u_int pkt_len, HAL_PKT_TYPE type, u_int tx_power,
u_int key_ix, HAL_KEY_TYPE key_type, u_int flags);
extern void ar9300_set_rx_chainmask(struct ath_hal *ah, int rxchainmask);
extern void ar9300_update_loc_ctl_reg(struct ath_hal *ah, int pos_bit);
/* for tx_bf*/
#define ar9300_set_11n_txbf_cal(ah, ds, cal_pos, code_rate, cec, opt)
/* for tx_bf*/
extern void ar9300_set_11n_rate_scenario(struct ath_hal *ah, void *ds,
void *lastds, u_int dur_update_en, u_int rts_cts_rate, u_int rts_cts_duration, HAL_11N_RATE_SERIES series[],
u_int nseries, u_int flags, u_int32_t smartAntenna);
extern void ar9300_set_11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
u_int aggr_len, u_int num_delims);
extern void ar9300_set_11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
u_int num_delims);
extern void ar9300_set_11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
extern void ar9300_clr_11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
extern void ar9300_set_11n_burst_duration(struct ath_hal *ah,
struct ath_desc *ds, u_int burst_duration);
extern void ar9300_set_11n_rifs_burst_middle(struct ath_hal *ah, void *ds);
extern void ar9300_set_11n_rifs_burst_last(struct ath_hal *ah, void *ds);
extern void ar9300_clr_11n_rifs_burst(struct ath_hal *ah, void *ds);
extern void ar9300_set_11n_aggr_rifs_burst(struct ath_hal *ah, void *ds);
extern void ar9300_set_11n_virtual_more_frag(struct ath_hal *ah,
struct ath_desc *ds, u_int vmf);
#ifdef AH_PRIVATE_DIAG
extern void ar9300__cont_tx_mode(struct ath_hal *ah, void *ds, int mode);
#endif
/* RX common functions */
extern u_int32_t ar9300_get_rx_dp(struct ath_hal *ath, HAL_RX_QUEUE qtype);
extern void ar9300_set_rx_dp(struct ath_hal *ah, u_int32_t rxdp, HAL_RX_QUEUE qtype);
extern void ar9300_enable_receive(struct ath_hal *ah);
extern HAL_BOOL ar9300_stop_dma_receive(struct ath_hal *ah, u_int timeout);
extern void ar9300_start_pcu_receive(struct ath_hal *ah, HAL_BOOL is_scanning);
extern void ar9300_stop_pcu_receive(struct ath_hal *ah);
extern void ar9300_set_multicast_filter(struct ath_hal *ah,
u_int32_t filter0, u_int32_t filter1);
extern u_int32_t ar9300_get_rx_filter(struct ath_hal *ah);
extern void ar9300_set_rx_filter(struct ath_hal *ah, u_int32_t bits);
extern HAL_BOOL ar9300_set_rx_sel_evm(struct ath_hal *ah, HAL_BOOL, HAL_BOOL);
extern HAL_BOOL ar9300_set_rx_abort(struct ath_hal *ah, HAL_BOOL);
extern HAL_STATUS ar9300_proc_rx_desc(struct ath_hal *ah,
struct ath_desc *, u_int32_t, struct ath_desc *, u_int64_t, struct ath_rx_status *);
extern HAL_STATUS ar9300_get_rx_key_idx(struct ath_hal *ah,
struct ath_desc *, u_int8_t *, u_int8_t *);
extern HAL_STATUS ar9300_proc_rx_desc_fast(struct ath_hal *ah, struct ath_desc *,
u_int32_t, struct ath_desc *, struct ath_rx_status *, void *);
extern void ar9300_promisc_mode(struct ath_hal *ah, HAL_BOOL enable);
extern void ar9300_read_pktlog_reg(struct ath_hal *ah, u_int32_t *, u_int32_t *, u_int32_t *, u_int32_t *);
extern void ar9300_write_pktlog_reg(struct ath_hal *ah, HAL_BOOL , u_int32_t , u_int32_t , u_int32_t , u_int32_t );
#endif
#endif /* _ATH_AR9300_DESC_H_ */
@@ -0,0 +1,709 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#ifndef _ATH_AR9300_EEP_H_
#define _ATH_AR9300_EEP_H_
#include "opt_ah.h"
#include "ah.h"
#if defined(WIN32) || defined(WIN64)
#pragma pack (push, ar9300, 1)
#endif
/* FreeBSD extras - should be in ah_eeprom.h ? */
#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001
#define AR_EEPROM_EEPCAP_AES_DIS 0x0002
#define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004
#define AR_EEPROM_EEPCAP_BURST_DIS 0x0008
#define AR_EEPROM_EEPCAP_MAXQCU 0x01F0
#define AR_EEPROM_EEPCAP_MAXQCU_S 4
#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200
#define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000
#define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12
#define MSTATE 100
#define MOUTPUT 2048
#define MDEFAULT 15
#define MVALUE 100
enum CompressAlgorithm
{
_compress_none = 0,
_compress_lzma,
_compress_pairs,
_compress_block,
_compress4,
_compress5,
_compress6,
_compress7,
};
enum
{
calibration_data_none = 0,
calibration_data_dram,
calibration_data_flash,
calibration_data_eeprom,
calibration_data_otp,
#ifdef ATH_CAL_NAND_FLASH
calibration_data_nand,
#endif
CalibrationDataDontLoad,
};
#define HOST_CALDATA_SIZE (16*1024)
//
// DO NOT CHANGE THE DEFINTIONS OF THESE SYMBOLS.
// Add additional definitions to the end.
// Yes, the first one is 2. Do not use 0 or 1.
//
enum Ar9300EepromTemplate
{
ar9300_eeprom_template_generic = 2,
ar9300_eeprom_template_hb112 = 3,
ar9300_eeprom_template_hb116 = 4,
ar9300_eeprom_template_xb112 = 5,
ar9300_eeprom_template_xb113 = 6,
ar9300_eeprom_template_xb114 = 7,
ar9300_eeprom_template_tb417 = 8,
ar9300_eeprom_template_ap111 = 9,
ar9300_eeprom_template_ap121 = 10,
ar9300_eeprom_template_hornet_generic = 11,
ar9300_eeprom_template_wasp_2 = 12,
ar9300_eeprom_template_wasp_k31 = 13,
ar9300_eeprom_template_osprey_k31 = 14,
ar9300_eeprom_template_aphrodite = 15
};
#define ar9300_eeprom_template_default ar9300_eeprom_template_generic
#define Ar9300EepromFormatDefault 2
#define reference_current 0
#define compression_header_length 4
#define compression_checksum_length 2
#define OSPREY_EEP_VER 0xD000
#define OSPREY_EEP_VER_MINOR_MASK 0xFFF
#define OSPREY_EEP_MINOR_VER_1 0x1
#define OSPREY_EEP_MINOR_VER OSPREY_EEP_MINOR_VER_1
// 16-bit offset location start of calibration struct
#define OSPREY_EEP_START_LOC 256
#define OSPREY_NUM_5G_CAL_PIERS 8
#define OSPREY_NUM_2G_CAL_PIERS 3
#define OSPREY_NUM_5G_20_TARGET_POWERS 8
#define OSPREY_NUM_5G_40_TARGET_POWERS 8
#define OSPREY_NUM_2G_CCK_TARGET_POWERS 2
#define OSPREY_NUM_2G_20_TARGET_POWERS 3
#define OSPREY_NUM_2G_40_TARGET_POWERS 3
//#define OSPREY_NUM_CTLS 21
#define OSPREY_NUM_CTLS_5G 9
#define OSPREY_NUM_CTLS_2G 12
#define OSPREY_CTL_MODE_M 0xF
#define OSPREY_NUM_BAND_EDGES_5G 8
#define OSPREY_NUM_BAND_EDGES_2G 4
#define OSPREY_NUM_PD_GAINS 4
#define OSPREY_PD_GAINS_IN_MASK 4
#define OSPREY_PD_GAIN_ICEPTS 5
#define OSPREY_EEPROM_MODAL_SPURS 5
#define OSPREY_MAX_RATE_POWER 63
#define OSPREY_NUM_PDADC_VALUES 128
#define OSPREY_NUM_RATES 16
#define OSPREY_BCHAN_UNUSED 0xFF
#define OSPREY_MAX_PWR_RANGE_IN_HALF_DB 64
#define OSPREY_OPFLAGS_11A 0x01
#define OSPREY_OPFLAGS_11G 0x02
#define OSPREY_OPFLAGS_5G_HT40 0x04
#define OSPREY_OPFLAGS_2G_HT40 0x08
#define OSPREY_OPFLAGS_5G_HT20 0x10
#define OSPREY_OPFLAGS_2G_HT20 0x20
#define OSPREY_EEPMISC_BIG_ENDIAN 0x01
#define OSPREY_EEPMISC_WOW 0x02
#define OSPREY_CUSTOMER_DATA_SIZE 20
#define FREQ2FBIN(x,y) \
(((y) == HAL_FREQ_BAND_2GHZ) ? ((x) - 2300) : (((x) - 4800) / 5))
#define FBIN2FREQ(x,y) \
(((y) == HAL_FREQ_BAND_2GHZ) ? (2300 + x) : (4800 + 5 * x))
#define OSPREY_MAX_CHAINS 3
#define OSPREY_ANT_16S 25
#define OSPREY_FUTURE_MODAL_SZ 6
#define OSPREY_NUM_ANT_CHAIN_FIELDS 7
#define OSPREY_NUM_ANT_COMMON_FIELDS 4
#define OSPREY_SIZE_ANT_CHAIN_FIELD 3
#define OSPREY_SIZE_ANT_COMMON_FIELD 4
#define OSPREY_ANT_CHAIN_MASK 0x7
#define OSPREY_ANT_COMMON_MASK 0xf
#define OSPREY_CHAIN_0_IDX 0
#define OSPREY_CHAIN_1_IDX 1
#define OSPREY_CHAIN_2_IDX 2
#define OSPREY_1_CHAINMASK 1
#define OSPREY_2LOHI_CHAINMASK 5
#define OSPREY_2LOMID_CHAINMASK 3
#define OSPREY_3_CHAINMASK 7
#define AR928X_NUM_ANT_CHAIN_FIELDS 6
#define AR928X_SIZE_ANT_CHAIN_FIELD 2
#define AR928X_ANT_CHAIN_MASK 0x3
/* Delta from which to start power to pdadc table */
/* This offset is used in both open loop and closed loop power control
* schemes. In open loop power control, it is not really needed, but for
* the "sake of consistency" it was kept.
* For certain AP designs, this value is overwritten by the value in the flag
* "pwrTableOffset" just before writing the pdadc vs pwr into the chip registers.
*/
#define OSPREY_PWR_TABLE_OFFSET 0
//enable flags for voltage and temp compensation
#define ENABLE_TEMP_COMPENSATION 0x01
#define ENABLE_VOLT_COMPENSATION 0x02
#define FLASH_BASE_CALDATA_OFFSET 0x1000
#define AR9300_EEPROM_SIZE 16*1024 // byte addressable
#define FIXED_CCA_THRESHOLD 15
typedef struct eepFlags {
u_int8_t op_flags;
u_int8_t eepMisc;
} __packed EEP_FLAGS;
typedef enum targetPowerHTRates {
HT_TARGET_RATE_0_8_16,
HT_TARGET_RATE_1_3_9_11_17_19,
HT_TARGET_RATE_4,
HT_TARGET_RATE_5,
HT_TARGET_RATE_6,
HT_TARGET_RATE_7,
HT_TARGET_RATE_12,
HT_TARGET_RATE_13,
HT_TARGET_RATE_14,
HT_TARGET_RATE_15,
HT_TARGET_RATE_20,
HT_TARGET_RATE_21,
HT_TARGET_RATE_22,
HT_TARGET_RATE_23
}TARGET_POWER_HT_RATES;
const static int mapRate2Index[24]=
{
0,1,1,1,2,
3,4,5,0,1,
1,1,6,7,8,
9,0,1,1,1,
10,11,12,13
};
typedef enum targetPowerLegacyRates {
LEGACY_TARGET_RATE_6_24,
LEGACY_TARGET_RATE_36,
LEGACY_TARGET_RATE_48,
LEGACY_TARGET_RATE_54
}TARGET_POWER_LEGACY_RATES;
typedef enum targetPowerCckRates {
LEGACY_TARGET_RATE_1L_5L,
LEGACY_TARGET_RATE_5S,
LEGACY_TARGET_RATE_11L,
LEGACY_TARGET_RATE_11S
}TARGET_POWER_CCK_RATES;
#define MAX_MODAL_RESERVED 11
#define MAX_MODAL_FUTURE 5
#define MAX_BASE_EXTENSION_FUTURE 2
#define MAX_TEMP_SLOPE 8
#define OSPREY_CHECKSUM_LOCATION (OSPREY_EEP_START_LOC + 1)
typedef struct osprey_BaseEepHeader {
u_int16_t reg_dmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
u_int8_t txrx_mask; //4 bits tx and 4 bits rx
EEP_FLAGS op_cap_flags;
u_int8_t rf_silent;
u_int8_t blue_tooth_options;
u_int8_t device_cap;
u_int8_t device_type; // takes lower byte in eeprom location
int8_t pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
u_int8_t params_for_tuning_caps[2]; //placeholder, get more details from Don
u_int8_t feature_enable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 1
//bit5 - enable paprd - default to 0
//bit6 - enable TuningCaps - default to 0
//bit7 - enable tx_frame_to_xpa_on - default to 0
u_int8_t misc_configuration; //misc flags: bit0 - turn down drivestrength
// bit 1:2 - 0=don't force, 1=force to thermometer 0, 2=force to thermometer 1, 3=force to thermometer 2
// bit 3 - reduce chain mask from 0x7 to 0x3 on 2 stream rates
// bit 4 - enable quick drop
// bit 5 - enable 8 temp slop
// bit 6; enable xLNA_bias_strength
// bit 7; enable rf_gain_cap
u_int8_t eeprom_write_enable_gpio;
u_int8_t wlan_disable_gpio;
u_int8_t wlan_led_gpio;
u_int8_t rx_band_select_gpio;
u_int8_t txrxgain;
u_int32_t swreg; // SW controlled internal regulator fields
} __packed OSPREY_BASE_EEP_HEADER;
typedef struct osprey_BaseExtension_1 {
u_int8_t ant_div_control;
u_int8_t future[MAX_BASE_EXTENSION_FUTURE];
u_int8_t misc_enable;
int8_t tempslopextension[MAX_TEMP_SLOPE];
int8_t quick_drop_low;
int8_t quick_drop_high;
} __packed OSPREY_BASE_EXTENSION_1;
typedef struct osprey_BaseExtension_2 {
int8_t temp_slope_low;
int8_t temp_slope_high;
u_int8_t xatten1_db_low[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
u_int8_t xatten1_margin_low[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
u_int8_t xatten1_db_high[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
u_int8_t xatten1_margin_high[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
} __packed OSPREY_BASE_EXTENSION_2;
typedef struct spurChanStruct {
u_int16_t spur_chan;
u_int8_t spurRangeLow;
u_int8_t spurRangeHigh;
} __packed SPUR_CHAN;
//Note the order of the fields in this structure has been optimized to put all fields likely to change together
typedef struct ospreyModalEepHeader {
u_int32_t ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
u_int32_t ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
u_int16_t ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
u_int8_t xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
u_int8_t xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
int8_t temp_slope;
int8_t voltSlope;
u_int8_t spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
int8_t noise_floor_thresh_ch[OSPREY_MAX_CHAINS];// 3 //Check if the register is per chain
u_int8_t reserved[MAX_MODAL_RESERVED];
int8_t quick_drop;
u_int8_t xpa_bias_lvl; // 1
u_int8_t tx_frame_to_data_start; // 1
u_int8_t tx_frame_to_pa_on; // 1
u_int8_t txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
int8_t antenna_gain; // 1
u_int8_t switchSettling; // 1
int8_t adcDesiredSize; // 1
u_int8_t tx_end_to_xpa_off; // 1
u_int8_t txEndToRxOn; // 1
u_int8_t tx_frame_to_xpa_on; // 1
u_int8_t thresh62; // 1
u_int32_t paprd_rate_mask_ht20;
u_int32_t paprd_rate_mask_ht40;
u_int16_t switchcomspdt;
u_int8_t xLNA_bias_strength; // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
u_int8_t rf_gain_cap;
u_int8_t tx_gain_cap; // bit0:4 txgain cap, txgain index for max_txgain + 20 (10dBm higher than max txgain)
u_int8_t futureModal[MAX_MODAL_FUTURE];
// last 12 bytes stolen and moved to newly created base extension structure
} __packed OSPREY_MODAL_EEP_HEADER; // == 100 B
typedef struct ospCalDataPerFreqOpLoop {
int8_t ref_power; /* */
u_int8_t volt_meas; /* pdadc voltage at power measurement */
u_int8_t temp_meas; /* pcdac used for power measurement */
int8_t rx_noisefloor_cal; /*range is -60 to -127 create a mapping equation 1db resolution */
int8_t rx_noisefloor_power; /*range is same as noisefloor */
u_int8_t rxTempMeas; /*temp measured when noisefloor cal was performed */
} __packed OSP_CAL_DATA_PER_FREQ_OP_LOOP;
typedef struct CalTargetPowerLegacy {
u_int8_t t_pow2x[4];
} __packed CAL_TARGET_POWER_LEG;
typedef struct ospCalTargetPowerHt {
u_int8_t t_pow2x[14];
} __packed OSP_CAL_TARGET_POWER_HT;
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
typedef struct CalCtlEdgePwr {
u_int8_t flag :2,
t_power :6;
} __packed CAL_CTL_EDGE_PWR;
#else
typedef struct CalCtlEdgePwr {
u_int8_t t_power :6,
flag :2;
} __packed CAL_CTL_EDGE_PWR;
#endif
typedef struct ospCalCtlData_5G {
CAL_CTL_EDGE_PWR ctl_edges[OSPREY_NUM_BAND_EDGES_5G];
} __packed OSP_CAL_CTL_DATA_5G;
typedef struct ospCalCtlData_2G {
CAL_CTL_EDGE_PWR ctl_edges[OSPREY_NUM_BAND_EDGES_2G];
} __packed OSP_CAL_CTL_DATA_2G;
typedef struct ospreyEeprom {
u_int8_t eeprom_version;
u_int8_t template_version;
u_int8_t mac_addr[6];
u_int8_t custData[OSPREY_CUSTOMER_DATA_SIZE];
OSPREY_BASE_EEP_HEADER base_eep_header;
OSPREY_MODAL_EEP_HEADER modal_header_2g;
OSPREY_BASE_EXTENSION_1 base_ext1;
u_int8_t cal_freq_pier_2g[OSPREY_NUM_2G_CAL_PIERS];
OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_2g[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS];
u_int8_t cal_target_freqbin_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
u_int8_t cal_target_freqbin_2g[OSPREY_NUM_2G_20_TARGET_POWERS];
u_int8_t cal_target_freqbin_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS];
u_int8_t cal_target_freqbin_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS];
CAL_TARGET_POWER_LEG cal_target_power_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
CAL_TARGET_POWER_LEG cal_target_power_2g[OSPREY_NUM_2G_20_TARGET_POWERS];
OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS];
OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS];
u_int8_t ctl_index_2g[OSPREY_NUM_CTLS_2G];
u_int8_t ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
OSP_CAL_CTL_DATA_2G ctl_power_data_2g[OSPREY_NUM_CTLS_2G];
OSPREY_MODAL_EEP_HEADER modal_header_5g;
OSPREY_BASE_EXTENSION_2 base_ext2;
u_int8_t cal_freq_pier_5g[OSPREY_NUM_5G_CAL_PIERS];
OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_5g[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS];
u_int8_t cal_target_freqbin_5g[OSPREY_NUM_5G_20_TARGET_POWERS];
u_int8_t cal_target_freqbin_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS];
u_int8_t cal_target_freqbin_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS];
CAL_TARGET_POWER_LEG cal_target_power_5g[OSPREY_NUM_5G_20_TARGET_POWERS];
OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS];
OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS];
u_int8_t ctl_index_5g[OSPREY_NUM_CTLS_5G];
u_int8_t ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
OSP_CAL_CTL_DATA_5G ctl_power_data_5g[OSPREY_NUM_CTLS_5G];
} __packed ar9300_eeprom_t;
/*
** SWAP Functions
** used to read EEPROM data, which is apparently stored in little
** endian form. We have included both forms of the swap functions,
** one for big endian and one for little endian. The indices of the
** array elements are the differences
*/
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
#define AR9300_EEPROM_MAGIC 0x5aa5
#define SWAP16(_x) ( (u_int16_t)( (((const u_int8_t *)(&_x))[0] ) |\
( ( (const u_int8_t *)( &_x ) )[1]<< 8) ) )
#define SWAP32(_x) ((u_int32_t)( \
(((const u_int8_t *)(&_x))[0]) | \
(((const u_int8_t *)(&_x))[1]<< 8) | \
(((const u_int8_t *)(&_x))[2]<<16) | \
(((const u_int8_t *)(&_x))[3]<<24)))
#else // AH_BYTE_ORDER
#define AR9300_EEPROM_MAGIC 0xa55a
#define SWAP16(_x) ( (u_int16_t)( (((const u_int8_t *)(&_x))[1] ) |\
( ( (const u_int8_t *)( &_x ) )[0]<< 8) ) )
#define SWAP32(_x) ((u_int32_t)( \
(((const u_int8_t *)(&_x))[3]) | \
(((const u_int8_t *)(&_x))[2]<< 8) | \
(((const u_int8_t *)(&_x))[1]<<16) | \
(((const u_int8_t *)(&_x))[0]<<24)))
#endif // AH_BYTE_ORDER
// OTP registers for OSPREY
#define AR_GPIO_IN_OUT 0x4048 // GPIO input / output register
#define OTP_MEM_START_ADDRESS 0x14000
#define OTP_STATUS0_OTP_SM_BUSY 0x00015f18
#define OTP_STATUS1_EFUSE_READ_DATA 0x00015f1c
#define OTP_LDO_CONTROL_ENABLE 0x00015f24
#define OTP_LDO_STATUS_POWER_ON 0x00015f2c
#define OTP_INTF0_EFUSE_WR_ENABLE_REG_V 0x00015f00
// OTP register for Jupiter
#define GLB_OTP_LDO_CONTROL_ENABLE 0x00020020
#define GLB_OTP_LDO_STATUS_POWER_ON 0x00020028
#define OTP_PGENB_SETUP_HOLD_TIME_DELAY 0x15f34
// OTP register for Jupiter BT
#define BTOTP_MEM_START_ADDRESS 0x64000
#define BTOTP_STATUS0_OTP_SM_BUSY 0x00065f18
#define BTOTP_STATUS1_EFUSE_READ_DATA 0x00065f1c
#define BTOTP_INTF0_EFUSE_WR_ENABLE_REG_V 0x00065f00
#define BTOTP_INTF2 0x00065f08
#define BTOTP_PGENB_SETUP_HOLD_TIME_DELAY 0x65f34
#define BT_RESET_CTL 0x44000
#define BT_CLOCK_CONTROL 0x44028
// OTP register for WASP
#define OTP_MEM_START_ADDRESS_WASP 0x00030000
#define OTP_STATUS0_OTP_SM_BUSY_WASP (OTP_MEM_START_ADDRESS_WASP + 0x1018)
#define OTP_STATUS1_EFUSE_READ_DATA_WASP (OTP_MEM_START_ADDRESS_WASP + 0x101C)
#define OTP_LDO_CONTROL_ENABLE_WASP (OTP_MEM_START_ADDRESS_WASP + 0x1024)
#define OTP_LDO_STATUS_POWER_ON_WASP (OTP_MEM_START_ADDRESS_WASP + 0x102C)
#define OTP_INTF0_EFUSE_WR_ENABLE_REG_V_WASP (OTP_MEM_START_ADDRESS_WASP + 0x1000)
// Below control the access timing of OTP read/write
#define OTP_PG_STROBE_PW_REG_V_WASP (OTP_MEM_START_ADDRESS_WASP + 0x1008)
#define OTP_RD_STROBE_PW_REG_V_WASP (OTP_MEM_START_ADDRESS_WASP + 0x100C)
#define OTP_VDDQ_HOLD_TIME_DELAY_WASP (OTP_MEM_START_ADDRESS_WASP + 0x1030)
#define OTP_PGENB_SETUP_HOLD_TIME_DELAY_WASP (OTP_MEM_START_ADDRESS_WASP + 0x1034)
#define OTP_STROBE_PULSE_INTERVAL_DELAY_WASP (OTP_MEM_START_ADDRESS_WASP + 0x1038)
#define OTP_CSB_ADDR_LOAD_SETUP_HOLD_DELAY_WASP (OTP_MEM_START_ADDRESS_WASP + 0x103C)
#define AR9300_EEPROM_MAGIC_OFFSET 0x0
/* reg_off = 4 * (eep_off) */
#define AR9300_EEPROM_S 2
#define AR9300_EEPROM_OFFSET 0x2000
#ifdef AR9100
#define AR9300_EEPROM_START_ADDR 0x1fff1000
#else
#define AR9300_EEPROM_START_ADDR 0x503f1200
#endif
#define AR9300_FLASH_CAL_START_OFFSET 0x1000
#define AR9300_EEPROM_MAX 0xae0
#define IS_EEP_MINOR_V3(_ahp) (ar9300_eeprom_get((_ahp), EEP_MINOR_REV) >= AR9300_EEP_MINOR_VER_3)
#define ar9300_get_ntxchains(_txchainmask) \
(((_txchainmask >> 2) & 1) + ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
/* RF silent fields in \ */
#define EEP_RFSILENT_ENABLED 0x0001 /* bit 0: enabled/disabled */
#define EEP_RFSILENT_ENABLED_S 0 /* bit 0: enabled/disabled */
#define EEP_RFSILENT_POLARITY 0x0002 /* bit 1: polarity */
#define EEP_RFSILENT_POLARITY_S 1 /* bit 1: polarity */
#define EEP_RFSILENT_GPIO_SEL 0x00fc /* bits 2..7: gpio PIN */
#define EEP_RFSILENT_GPIO_SEL_S 2 /* bits 2..7: gpio PIN */
#define AR9300_EEP_VER 0xE
#define AR9300_BCHAN_UNUSED 0xFF
#define AR9300_MAX_RATE_POWER 63
typedef enum {
CALDATA_AUTO=0,
CALDATA_EEPROM,
CALDATA_FLASH,
CALDATA_OTP
} CALDATA_TYPE;
typedef enum {
EEP_NFTHRESH_5,
EEP_NFTHRESH_2,
EEP_MAC_MSW,
EEP_MAC_MID,
EEP_MAC_LSW,
EEP_REG_0,
EEP_REG_1,
EEP_OP_CAP,
EEP_OP_MODE,
EEP_RF_SILENT,
EEP_OB_5,
EEP_DB_5,
EEP_OB_2,
EEP_DB_2,
EEP_MINOR_REV,
EEP_TX_MASK,
EEP_RX_MASK,
EEP_FSTCLK_5G,
EEP_RXGAIN_TYPE,
EEP_OL_PWRCTRL,
EEP_TXGAIN_TYPE,
EEP_RC_CHAIN_MASK,
EEP_DAC_HPWR_5G,
EEP_FRAC_N_5G,
EEP_DEV_TYPE,
EEP_TEMPSENSE_SLOPE,
EEP_TEMPSENSE_SLOPE_PAL_ON,
EEP_PWR_TABLE_OFFSET,
EEP_DRIVE_STRENGTH,
EEP_INTERNAL_REGULATOR,
EEP_SWREG,
EEP_PAPRD_ENABLED,
EEP_ANTDIV_control,
EEP_CHAIN_MASK_REDUCE,
} EEPROM_PARAM;
#define AR9300_RATES_OFDM_OFFSET 0
#define AR9300_RATES_CCK_OFFSET 4
#define AR9300_RATES_HT20_OFFSET 8
#define AR9300_RATES_HT40_OFFSET 22
typedef enum ar9300_Rates {
ALL_TARGET_LEGACY_6_24,
ALL_TARGET_LEGACY_36,
ALL_TARGET_LEGACY_48,
ALL_TARGET_LEGACY_54,
ALL_TARGET_LEGACY_1L_5L,
ALL_TARGET_LEGACY_5S,
ALL_TARGET_LEGACY_11L,
ALL_TARGET_LEGACY_11S,
ALL_TARGET_HT20_0_8_16,
ALL_TARGET_HT20_1_3_9_11_17_19,
ALL_TARGET_HT20_4,
ALL_TARGET_HT20_5,
ALL_TARGET_HT20_6,
ALL_TARGET_HT20_7,
ALL_TARGET_HT20_12,
ALL_TARGET_HT20_13,
ALL_TARGET_HT20_14,
ALL_TARGET_HT20_15,
ALL_TARGET_HT20_20,
ALL_TARGET_HT20_21,
ALL_TARGET_HT20_22,
ALL_TARGET_HT20_23,
ALL_TARGET_HT40_0_8_16,
ALL_TARGET_HT40_1_3_9_11_17_19,
ALL_TARGET_HT40_4,
ALL_TARGET_HT40_5,
ALL_TARGET_HT40_6,
ALL_TARGET_HT40_7,
ALL_TARGET_HT40_12,
ALL_TARGET_HT40_13,
ALL_TARGET_HT40_14,
ALL_TARGET_HT40_15,
ALL_TARGET_HT40_20,
ALL_TARGET_HT40_21,
ALL_TARGET_HT40_22,
ALL_TARGET_HT40_23,
ar9300_rate_size
} AR9300_RATES;
/**************************************************************************
* fbin2freq
*
* Get channel value from binary representation held in eeprom
* RETURNS: the frequency in MHz
*/
static inline u_int16_t
fbin2freq(u_int8_t fbin, HAL_BOOL is_2ghz)
{
/*
* Reserved value 0xFF provides an empty definition both as
* an fbin and as a frequency - do not convert
*/
if (fbin == AR9300_BCHAN_UNUSED)
{
return fbin;
}
return (u_int16_t)((is_2ghz) ? (2300 + fbin) : (4800 + 5 * fbin));
}
extern int CompressionHeaderUnpack(u_int8_t *best, int *code, int *reference, int *length, int *major, int *minor);
extern void Ar9300EepromFormatConvert(ar9300_eeprom_t *mptr);
extern HAL_BOOL ar9300_eeprom_restore(struct ath_hal *ah);
extern int ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr, int /*msize*/);
extern int ar9300_eeprom_base_address(struct ath_hal *ah);
extern int ar9300_eeprom_volatile(struct ath_hal *ah);
extern int ar9300_eeprom_low_limit(struct ath_hal *ah);
extern u_int16_t ar9300_compression_checksum(u_int8_t *data, int dsize);
extern int ar9300_compression_header_unpack(u_int8_t *best, int *code, int *reference, int *length, int *major, int *minor);
extern u_int16_t ar9300_eeprom_struct_size(void);
extern ar9300_eeprom_t *ar9300EepromStructInit(int default_index);
extern ar9300_eeprom_t *ar9300EepromStructGet(void);
extern ar9300_eeprom_t *ar9300_eeprom_struct_default(int default_index);
extern ar9300_eeprom_t *ar9300_eeprom_struct_default_find_by_id(int ver);
extern int ar9300_eeprom_struct_default_many(void);
extern int ar9300EepromUpdateCalPier(int pierIdx, int freq, int chain,
int pwrCorrection, int volt_meas, int temp_meas);
extern int ar9300_power_control_override(struct ath_hal *ah, int frequency, int *correction, int *voltage, int *temperature);
extern void ar9300EepromDisplayCalData(int for2GHz);
extern void ar9300EepromDisplayAll(void);
extern void ar9300_set_target_power_from_eeprom(struct ath_hal *ah, u_int16_t freq,
u_int8_t *target_power_val_t2);
extern HAL_BOOL ar9300_eeprom_set_power_per_rate_table(struct ath_hal *ah,
ar9300_eeprom_t *p_eep_data,
const struct ieee80211_channel *chan,
u_int8_t *p_pwr_array,
u_int16_t cfg_ctl,
u_int16_t antenna_reduction,
u_int16_t twice_max_regulatory_power,
u_int16_t power_limit,
u_int8_t chainmask);
extern int ar9300_transmit_power_reg_write(struct ath_hal *ah, u_int8_t *p_pwr_array);
extern u_int8_t ar9300_eeprom_get_legacy_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index, u_int16_t freq, HAL_BOOL is_2ghz);
extern u_int8_t ar9300_eeprom_get_ht20_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index, u_int16_t freq, HAL_BOOL is_2ghz);
extern u_int8_t ar9300_eeprom_get_ht40_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index, u_int16_t freq, HAL_BOOL is_2ghz);
extern u_int8_t ar9300_eeprom_get_cck_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index, u_int16_t freq);
extern HAL_BOOL ar9300_internal_regulator_apply(struct ath_hal *ah);
extern HAL_BOOL ar9300_drive_strength_apply(struct ath_hal *ah);
extern HAL_BOOL ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel);
extern int32_t ar9300_thermometer_get(struct ath_hal *ah);
extern HAL_BOOL ar9300_thermometer_apply(struct ath_hal *ah);
extern HAL_BOOL ar9300_xpa_timing_control_apply(struct ath_hal *ah, HAL_BOOL is_2ghz);
extern HAL_BOOL ar9300_x_lNA_bias_strength_apply(struct ath_hal *ah, HAL_BOOL is_2ghz);
extern int32_t ar9300MacAdressGet(u_int8_t *mac);
extern int32_t ar9300CustomerDataGet(u_int8_t *data, int32_t len);
extern int32_t ar9300ReconfigDriveStrengthGet(void);
extern int32_t ar9300EnableTempCompensationGet(void);
extern int32_t ar9300EnableVoltCompensationGet(void);
extern int32_t ar9300FastClockEnableGet(void);
extern int32_t ar9300EnableDoublingGet(void);
extern u_int16_t *ar9300_regulatory_domain_get(struct ath_hal *ah);
extern int32_t ar9300_eeprom_write_enable_gpio_get(struct ath_hal *ah);
extern int32_t ar9300_wlan_led_gpio_get(struct ath_hal *ah);
extern int32_t ar9300_wlan_disable_gpio_get(struct ath_hal *ah);
extern int32_t ar9300_rx_band_select_gpio_get(struct ath_hal *ah);
extern int32_t ar9300_rx_gain_index_get(struct ath_hal *ah);
extern int32_t ar9300_tx_gain_index_get(struct ath_hal *ah);
extern int32_t ar9300_xpa_bias_level_get(struct ath_hal *ah, HAL_BOOL is_2ghz);
extern HAL_BOOL ar9300_xpa_bias_level_apply(struct ath_hal *ah, HAL_BOOL is_2ghz);
extern u_int32_t ar9300_ant_ctrl_common_get(struct ath_hal *ah, HAL_BOOL is_2ghz);
extern u_int32_t ar9300_ant_ctrl_common2_get(struct ath_hal *ah, HAL_BOOL is_2ghz);
extern u_int16_t ar9300_ant_ctrl_chain_get(struct ath_hal *ah, int chain, HAL_BOOL is_2ghz);
extern HAL_BOOL ar9300_ant_ctrl_apply(struct ath_hal *ah, HAL_BOOL is_2ghz);
/* since valid noise floor values are negative, returns 1 on error */
extern int32_t ar9300_noise_floor_cal_or_power_get(
struct ath_hal *ah, int32_t frequency, int32_t ichain, HAL_BOOL use_cal);
#define ar9300NoiseFloorGet(ah, frequency, ichain) \
ar9300_noise_floor_cal_or_power_get(ah, frequency, ichain, 1/*use_cal*/)
#define ar9300NoiseFloorPowerGet(ah, frequency, ichain) \
ar9300_noise_floor_cal_or_power_get(ah, frequency, ichain, 0/*use_cal*/)
extern void ar9300_eeprom_template_preference(int32_t value);
extern int32_t ar9300_eeprom_template_install(struct ath_hal *ah, int32_t value);
extern void ar9300_calibration_data_set(struct ath_hal *ah, int32_t source);
extern int32_t ar9300_calibration_data_get(struct ath_hal *ah);
extern int32_t ar9300_calibration_data_address_get(struct ath_hal *ah);
extern void ar9300_calibration_data_address_set(struct ath_hal *ah, int32_t source);
extern HAL_BOOL ar9300_calibration_data_read_flash(struct ath_hal *ah, long address, u_int8_t *buffer, int many);
extern HAL_BOOL ar9300_calibration_data_read_eeprom(struct ath_hal *ah, long address, u_int8_t *buffer, int many);
extern HAL_BOOL ar9300_calibration_data_read_otp(struct ath_hal *ah, long address, u_int8_t *buffer, int many, HAL_BOOL is_wifi);
extern HAL_BOOL ar9300_calibration_data_read(struct ath_hal *ah, long address, u_int8_t *buffer, int many);
extern int32_t ar9300_eeprom_size(struct ath_hal *ah);
extern int32_t ar9300_otp_size(struct ath_hal *ah);
extern HAL_BOOL ar9300_calibration_data_read_array(struct ath_hal *ah, int address, u_int8_t *buffer, int many);
#if defined(WIN32) || defined(WIN64)
#pragma pack (pop, ar9300)
#endif
#endif /* _ATH_AR9300_EEP_H_ */
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#ifndef __AR9300PAPRD_H__
#define __AR9300PAPRD_H__
#include <ah.h>
#include "ar9300.h"
#include "ar9300phy.h"
#define AH_PAPRD_AM_PM_MASK 0x1ffffff
#define AH_PAPRD_IDEAL_AGC2_PWR_RANGE 0xe0
extern int ar9300_paprd_init_table(struct ath_hal *ah, struct ieee80211_channel *chan);
extern HAL_STATUS ar9300_paprd_setup_gain_table(struct ath_hal *ah, int chain_num);
extern HAL_STATUS ar9300_paprd_create_curve(struct ath_hal *ah, struct ieee80211_channel *chan, int chain_num);
extern int ar9300_paprd_is_done(struct ath_hal *ah);
extern void ar9300_enable_paprd(struct ath_hal *ah, HAL_BOOL enable_flag, struct ieee80211_channel * chan);
extern void ar9300_swizzle_paprd_entries(struct ath_hal *ah, unsigned int txchain);
extern void ar9300_populate_paprd_single_table(struct ath_hal *ah, struct ieee80211_channel *chan, int chain_num);
extern void ar9300_paprd_dec_tx_pwr(struct ath_hal *ah);
extern int ar9300_paprd_thermal_send(struct ath_hal *ah);
#endif
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
#ifndef _ATH_AR9300_RADAR_H_
#define _ATH_AR9300_RADAR_H_
#define HAL_RADAR_SMASK 0x0000FFFF /* Sequence number mask */
#define HAL_RADAR_SSHIFT 16 /* Shift for Reader seq # stored in upper
16 bits, writer's is lower 16 bits */
#define HAL_RADAR_IMASK 0x0000FFFF /* Index number mask */
#define HAL_RADAR_ISHIFT 16 /* Shift for index stored in upper 16 bits
of reader reset value */
#define HAL_RADAR_FIRPWR -45
#define HAL_RADAR_RRSSI 14
#define HAL_RADAR_HEIGHT 20
#define HAL_RADAR_PRSSI 24
#define HAL_RADAR_INBAND 6
#define HAL_RADAR_TSMASK 0x7FFF /* Mask for time stamp from descriptor */
#define HAL_RADAR_TSSHIFT 15 /* Shift for time stamp from descriptor */
#define HAL_AR_RADAR_RSSI_THR 5 /* in dB */
#define HAL_AR_RADAR_RESET_INT 1 /* in secs */
#define HAL_AR_RADAR_MAX_HISTORY 500
#define HAL_AR_REGION_WIDTH 128
#define HAL_AR_RSSI_THRESH_STRONG_PKTS 17 /* in dB */
#define HAL_AR_RSSI_DOUBLE_THRESHOLD 15 /* in dB */
#define HAL_AR_MAX_NUM_ACK_REGIONS 9
#define HAL_AR_ACK_DETECT_PAR_THRESH 20
#define HAL_AR_PKT_COUNT_THRESH 20
#endif
@@ -0,0 +1,748 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300templateAP121_h__
#define __ar9300templateAP121_h__
static ar9300_eeprom_t ar9300_template_ap121=
{
2, // eeprom_version;
ar9300_eeprom_template_ap121, // template_version;
{0x00,0x03,0x7f,0x0,0x0,0x0}, //mac_addr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{"ap121-010-00000"},
// {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER base_eep_header=
{
{0,0x1f}, // reg_dmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x11, // txrx_mask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G , 0}, // op_cap_flags;
0, // rf_silent;
0, // blue_tooth_options;
0, // device_cap;
4, // device_type; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x0d, //feature_enable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
//bit5 - enable paprd -- default to 0
0, //misc_configuration: bit0 - turn down drivestrength
6, // eeprom_write_enable_gpio
0, // wlan_disable_gpio
8, // wlan_led_gpio
0xff, // rx_band_select_gpio
0x10, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modal_header_2g=
{
0x110, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x44444, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
25, // temp_slope;
0, // voltSlope;
{FREQ2FBIN(2464, 1),0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x80c0e0, // paprd_rate_mask_ht20 // 4
0x1ffffff, // paprd_rate_mask_ht40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
6, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 cal_freq_pier_2g[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2462, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_2g[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 cal_target_freqbin_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_2g[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_power_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{34,34,34,34}},
{{34,34,34,34}}
},
//static CAL_TARGET_POWER_LEG cal_target_power_2g[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{34,34,32,32}},
{{34,34,32,32}},
{{34,34,32,32}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,32,30,32,32,30,28,28,28,28,24}},
{{32,32,32,32,32,30,32,32,30,28,28,28,28,24}},
{{32,32,32,32,32,30,32,32,30,28,28,28,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,30,30,28,30,30,28,26,26,26,26,22}},
{{30,30,30,30,30,28,30,30,28,26,26,26,26,22}},
{{30,30,30,30,30,28,30,30,28,26,26,26,26,22}},
},
//static A_UINT8 ctl_index_2g[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctl_power_data_2g[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modal_header_5g=
{
0x220, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x44444, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
45, // temp_slope;
0, // voltSlope;
{0,0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0xf0e0e0, // paprd_rate_mask_ht20 // 4
0xf0e0e0, // paprd_rate_mask_ht40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
40, // temp_slope_low
50, // temp_slope_high
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 cal_freq_pier_5g[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5180, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5700, 0),
//pPiers[7] =
FREQ2FBIN(5785, 0),
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_5g[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG cal_target_power_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,28,24,20,30,28,24,20,20,20,20,16}},
{{30,30,30,28,24,20,30,28,24,20,20,20,20,16}},
{{30,30,30,26,22,18,30,26,22,18,18,18,18,16}},
{{30,30,30,26,22,18,30,26,22,18,18,18,18,16}},
{{30,30,30,24,20,16,30,24,20,16,16,16,16,14}},
{{30,30,30,24,20,16,30,24,20,16,16,16,16,14}},
{{30,30,30,22,18,14,30,22,18,14,14,14,14,12}},
{{30,30,30,22,18,14,30,22,18,14,14,14,14,12}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{28,28,28,26,22,18,28,26,22,18,18,18,18,14}},
{{28,28,28,26,22,18,28,26,22,18,18,18,18,14}},
{{28,28,28,24,20,16,28,24,20,16,16,16,16,12}},
{{28,28,28,24,20,16,28,24,20,16,16,16,16,12}},
{{28,28,28,22,18,14,28,22,18,14,14,14,14,10}},
{{28,28,28,22,18,14,28,22,18,14,14,14,14,10}},
{{28,28,28,20,16,12,28,20,16,12,12,12,12,8}},
{{28,28,28,20,16,12,28,20,16,12,12,12,12,8}},
},
//static A_UINT8 ctl_index_5g[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctl_edges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctl_edges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctl_edges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctl_edges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctl_edges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctl_edges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctl_edges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctl_edges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctl_edges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctl_edges[6].bChannel*/0xFF,
/* Data[3].ctl_edges[7].bChannel*/0xFF},
{/* Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctl_edges[4].bChannel*/0xFF,
/* Data[4].ctl_edges[5].bChannel*/0xFF,
/* Data[4].ctl_edges[6].bChannel*/0xFF,
/* Data[4].ctl_edges[7].bChannel*/0xFF},
{/* Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctl_edges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctl_edges[6].bChannel*/0xFF,
/* Data[5].ctl_edges[7].bChannel*/0xFF},
{/* Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctl_edges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctl_edges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctl_edges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctl_edges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctl_edges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctl_edges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctl_edges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctl_edges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctl_edges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,749 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300templateAphrodite_h__
#define __ar9300templateAphrodite_h__
static ar9300_eeprom_t ar9300_template_aphrodite=
{
0, // eeprom_version;
ar9300_eeprom_template_aphrodite, // template_version;
{0x00,0x03,0x7f,0x0,0x0,0x11}, //mac_addr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER base_eep_header=
{
{0,0x1f}, // reg_dmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x11, // txrx_mask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 0}, // op_cap_flags;
0, // rf_silent;
0, // blue_tooth_options;
0, // device_cap;
4, // device_type; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x10, //feature_enable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
0, //misc_configuration: bit0 - turn down drivestrength
3, // eeprom_write_enable_gpio
0, // wlan_disable_gpio
8, // wlan_led_gpio
0xff, // rx_band_select_gpio
0, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modal_header_2g=
{
0x0, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x0, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x0,0x150,0x150}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
36, // temp_slope;
0, // voltSlope;
{0,0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0c80C080, // paprd_rate_mask_ht20 // 4
0x0080C080, // paprd_rate_mask_ht40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
0, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 cal_freq_pier_2g[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_2g[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 cal_target_freqbin_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2484, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_2g[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_power_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{36,36,36,36}},
{{36,36,36,36}}
},
//static CAL_TARGET_POWER_LEG cal_target_power_2g[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{32,32,28,24}},
{{32,32,28,24}},
{{32,32,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
},
//static A_UINT8 ctl_index_2g[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctl_power_data_2g[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 0}, {0, 0}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {0, 0}, {0, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modal_header_5g=
{
0x110, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x22222, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x000,0x000,0x000}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
68, // temp_slope;
0, // voltSlope;
{0,0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0cf0e0e0, // paprd_rate_mask_ht20 // 4
0x6cf0e0e0, // paprd_rate_mask_ht40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
0,
0,
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 cal_freq_pier_5g[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5180, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5725, 0),
//pPiers[7] =
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_5g[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5220, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG cal_target_power_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
},
//static A_UINT8 ctl_index_5g[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctl_edges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctl_edges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctl_edges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctl_edges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctl_edges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctl_edges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctl_edges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctl_edges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctl_edges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctl_edges[6].bChannel*/0xFF,
/* Data[3].ctl_edges[7].bChannel*/0xFF},
{/* Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctl_edges[4].bChannel*/0xFF,
/* Data[4].ctl_edges[5].bChannel*/0xFF,
/* Data[4].ctl_edges[6].bChannel*/0xFF,
/* Data[4].ctl_edges[7].bChannel*/0xFF},
{/* Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctl_edges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctl_edges[6].bChannel*/0xFF,
/* Data[5].ctl_edges[7].bChannel*/0xFF},
{/* Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctl_edges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctl_edges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctl_edges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctl_edges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctl_edges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctl_edges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctl_edges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctl_edges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctl_edges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,737 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300template_cus157_h__
#define __ar9300template_cus157_h__
static ar9300_eeprom_t Ar9300Template_cus157=
{
2, // eepromVersion;
ar9300_eeprom_template_cus157, // templateVersion;
{0x00,0x03,0x7f,0x0,0x0,0x0}, //macAddr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{"cus157-030-f0000"},
// {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER baseEepHeader=
{
{0,0x1f}, // regDmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x77, // txrxMask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 0}, // opCapFlags;
0, // rfSilent;
0, // blueToothOptions;
0, // deviceCap;
5, // deviceType; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x0d, //featureEnable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
//bit5 - enable paprd -- default to 0
0, //miscConfiguration: bit0 - turn down drivestrength
6, // eepromWriteEnableGpio
0, // wlanDisableGpio
8, // wlanLedGpio
0xff, // rxBandSelectGpio
0x10, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modalHeader2G=
{
0x110, // antCtrlCommon; // 4 idle, t1, t2, b (4 bits per setting)
0x44444, // antCtrlCommon2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // antCtrlChain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1DB[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1Margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
25, // tempSlope;
0, // voltSlope;
{FREQ2FBIN(2464, 1),0,0,0,0}, // spurChans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noiseFloorThreshCh[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpaBiasLvl; // 1
0x0e, // txFrameToDataStart; // 1
0x0e, // txFrameToPaOn; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antennaGain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // txFrameToXpaOn; // 1
28, // thresh62; // 1
0x80C080, // paprdRateMaskHt20 // 4
0x80C080, // paprdRateMaskHt40
0, // ant_div_control
{0,0,0,0,0,0,0,0,0} //futureModal[9];
},
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0}}, // base_ext1
//static A_UINT8 calFreqPier2G[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2462, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP calPierData2G[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 calTarget_freqbin_Cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG calTarget_freqbin_2G[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT calTarget_freqbin_2GHT20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT calTarget_freqbin_2GHT40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG calTargetPowerCck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{34,34,34,34}},
{{34,34,34,34}}
},
//static CAL_TARGET_POWER_LEG calTargetPower2G[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{34,34,34,30}},
{{34,34,34,30}},
{{34,34,34,30}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower2GHT20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,30,30,32,32,30,30,32,32,30,30}},
{{32,32,32,32,30,30,32,32,30,30,32,32,30,30}},
{{32,32,32,32,30,30,32,32,30,30,32,32,30,30}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower2GHT40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,30,30,28,30,30,28,28,30,30,28,26}},
{{30,30,30,30,30,28,30,30,28,28,30,30,28,26}},
{{30,30,30,30,30,28,30,30,28,28,30,30,28,26}},
},
//static A_UINT8 ctlIndex_2G[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctlEdges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctlEdges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctlEdges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctlEdges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctlEdges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctlEdges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctlEdges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctlEdges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctlEdges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctlPowerData_2G[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modalHeader5G=
{
0x220, // antCtrlCommon; // 4 idle, t1, t2, b (4 bits per setting)
0x44444, // antCtrlCommon2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // antCtrlChain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1DB[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1Margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
45, // tempSlope;
0, // voltSlope;
{0,0,0,0,0}, // spurChans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noiseFloorThreshCh[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpaBiasLvl; // 1
0x0e, // txFrameToDataStart; // 1
0x0e, // txFrameToPaOn; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antennaGain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // txFrameToXpaOn; // 1
28, // thresh62; // 1
0xf0e0e0, // paprdRateMaskHt20 // 4
0xf0e0e0, // paprdRateMaskHt40 // 4
{0,0,0,0,0,0,0,0,0,0} //futureModal[10];
},
{ // base_ext2
40, // tempSlopeLow
50, // tempSlopeHigh
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 calFreqPier5G[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5180, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5700, 0),
//pPiers[7] =
FREQ2FBIN(5785, 0),
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP calPierData5G[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG calTarget_freqbin_5G[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG calTargetPower5G[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{30,30,26,22}},
{{30,30,26,22}},
{{30,30,30,24}},
{{30,30,30,24}},
{{30,30,26,22}},
{{30,24,20,18}},
{{30,24,20,18}},
{{30,24,20,18}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,28,24,20,30,28,24,18,30,26,22,16}},
{{30,30,30,28,24,20,30,28,24,18,30,26,22,16}},
{{30,30,30,26,22,18,30,26,22,16,30,24,20,14}},
{{30,30,30,26,22,18,30,26,22,16,30,24,20,14}},
{{30,30,30,24,20,16,30,24,20,14,30,22,18,12}},
{{30,30,30,24,20,16,30,24,20,14,30,22,18,12}},
{{28,28,28,22,18,14,28,22,18,12,28,20,16,10}},
{{28,28,28,22,18,14,28,22,18,12,28,20,16,10}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{28,28,28,26,22,18,28,24,20,16,20,16,16,16}},
{{28,28,28,26,22,18,28,24,20,16,20,16,16,16}},
{{28,28,28,28,24,20,28,28,24,20,22,20,20,20}},
{{28,28,28,28,24,20,28,28,24,20,22,20,20,20}},
{{28,28,28,24,20,16,28,24,20,16,18,16,16,16}},
{{28,28,28,22,18,14,22,20,16,12,14,12,12,10}},
{{28,28,28,22,18,14,22,20,16,12,14,12,12,10}},
{{28,28,28,22,18,14,22,20,16,12,14,12,12,10}},
},
//static A_UINT8 ctlIndex_5G[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctlEdges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctlEdges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctlEdges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctlEdges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctlEdges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctlEdges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctlEdges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctlEdges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctlEdges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctlEdges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctlEdges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctlEdges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctlEdges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctlEdges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctlEdges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctlEdges[6].bChannel*/0xFF,
/* Data[3].ctlEdges[7].bChannel*/0xFF},
{/* Data[4].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctlEdges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctlEdges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctlEdges[4].bChannel*/0xFF,
/* Data[4].ctlEdges[5].bChannel*/0xFF,
/* Data[4].ctlEdges[6].bChannel*/0xFF,
/* Data[4].ctlEdges[7].bChannel*/0xFF},
{/* Data[5].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctlEdges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctlEdges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctlEdges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctlEdges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctlEdges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctlEdges[6].bChannel*/0xFF,
/* Data[5].ctlEdges[7].bChannel*/0xFF},
{/* Data[6].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctlEdges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctlEdges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctlEdges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctlEdges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctlEdges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctlEdges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctlEdges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctlEdges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctlEdges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctlEdges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctlEdges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctlEdges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctlEdges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctlEdges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctlEdges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctlEdges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,748 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300templateGeneric_h__
#define __ar9300templateGeneric_h__
static ar9300_eeprom_t ar9300_template_generic=
{
2, // eeprom_version;
ar9300_eeprom_template_generic, // template_version;
{0,2,3,4,5,6}, //mac_addr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER base_eep_header=
{
{0,0x1f}, // reg_dmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x77, // txrx_mask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 0}, // op_cap_flags;
0, // rf_silent;
0, // blue_tooth_options;
0, // device_cap;
5, // device_type; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x0c, //feature_enable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
0, //misc_configuration: bit0 - turn down drivestrength
3, // eeprom_write_enable_gpio
0, // wlan_disable_gpio
8, // wlan_led_gpio
0xff, // rx_band_select_gpio
0, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modal_header_2g=
{
0x110, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x22222, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
36, // temp_slope;
0, // voltSlope;
{0,0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0c80C080, // paprd_rate_mask_ht20 // 4
0x0080C080, // paprd_rate_mask_ht40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
0, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 cal_freq_pier_2g[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_2g[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 cal_target_freqbin_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2484, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_2g[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_power_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{36,36,36,36}},
{{36,36,36,36}}
},
//static CAL_TARGET_POWER_LEG cal_target_power_2g[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{32,32,28,24}},
{{32,32,28,24}},
{{32,32,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
},
//static A_UINT8 ctl_index_2g[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctl_power_data_2g[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modal_header_5g=
{
0x110, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x22222, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x000,0x000,0x000}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
68, // temp_slope;
0, // voltSlope;
{0,0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0cf0e0e0, // paprd_rate_mask_ht20 // 4
0x6cf0e0e0, // paprd_rate_mask_ht40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
0,
0,
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 cal_freq_pier_5g[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5180, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5725, 0),
//pPiers[7] =
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_5g[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5220, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG cal_target_power_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
},
//static A_UINT8 ctl_index_5g[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctl_edges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctl_edges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctl_edges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctl_edges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctl_edges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctl_edges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctl_edges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctl_edges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctl_edges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctl_edges[6].bChannel*/0xFF,
/* Data[3].ctl_edges[7].bChannel*/0xFF},
{/* Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctl_edges[4].bChannel*/0xFF,
/* Data[4].ctl_edges[5].bChannel*/0xFF,
/* Data[4].ctl_edges[6].bChannel*/0xFF,
/* Data[4].ctl_edges[7].bChannel*/0xFF},
{/* Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctl_edges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctl_edges[6].bChannel*/0xFF,
/* Data[5].ctl_edges[7].bChannel*/0xFF},
{/* Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctl_edges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctl_edges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctl_edges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctl_edges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctl_edges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctl_edges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctl_edges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctl_edges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctl_edges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,751 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300templateHB112_h__
#define __ar9300templateHB112_h__
static ar9300_eeprom_t ar9300_template_hb112=
{
2, // eeprom_version;
ar9300_eeprom_template_hb112, // template_version;
{0x00,0x03,0x7f,0x0,0x0,0x0}, //mac_addr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{"cus157-241-f0000"},
// {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER base_eep_header=
{
{0,0x1f}, // reg_dmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x77, // txrx_mask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 0}, // op_cap_flags;
0, // rf_silent;
0, // blue_tooth_options;
0, // device_cap;
5, // device_type; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x0d, //feature_enable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
//bit5 - enable paprd -- default to 0
0, //misc_configuration: bit0 - turn down drivestrength
6, // eeprom_write_enable_gpio
0, // wlan_disable_gpio
8, // wlan_led_gpio
0xff, // rx_band_select_gpio
0x10, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modal_header_2g=
{
0x110, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x44444, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
25, // temp_slope;
0, // voltSlope;
{FREQ2FBIN(2464, 1),0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0c80C080, // paprd_rate_mask_ht20 // 4
0x0080C080, // paprd_rate_mask_ht40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
0, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 cal_freq_pier_2g[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2462, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_2g[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 cal_target_freqbin_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_2g[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_power_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{34,34,34,34}},
{{34,34,34,34}}
},
//static CAL_TARGET_POWER_LEG cal_target_power_2g[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{34,34,32,32}},
{{34,34,32,32}},
{{34,34,32,32}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,32,30,32,32,30,28,28,28,28,24}},
{{32,32,32,32,32,30,32,32,30,28,28,28,28,24}},
{{32,32,32,32,32,30,32,32,30,28,28,28,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,30,30,28,30,30,28,26,26,26,26,22}},
{{30,30,30,30,30,28,30,30,28,26,26,26,26,22}},
{{30,30,30,30,30,28,30,30,28,26,26,26,26,22}},
},
//static A_UINT8 ctl_index_2g[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctl_power_data_2g[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modal_header_5g=
{
0x220, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x44444, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
45, // temp_slope;
0, // voltSlope;
{0,0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0cf0e0e0, // paprd_rate_mask_ht20 // 4
0x6cf0e0e0, // paprd_rate_mask_ht40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
40, // temp_slope_low
50, // temp_slope_high
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 cal_freq_pier_5g[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5180, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5700, 0),
//pPiers[7] =
FREQ2FBIN(5785, 0),
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_5g[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG cal_target_power_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,28,24,20,30,28,24,20,20,20,20,16}},
{{30,30,30,28,24,20,30,28,24,20,20,20,20,16}},
{{30,30,30,26,22,18,30,26,22,18,18,18,18,16}},
{{30,30,30,26,22,18,30,26,22,18,18,18,18,16}},
{{30,30,30,24,20,16,30,24,20,16,16,16,16,14}},
{{30,30,30,24,20,16,30,24,20,16,16,16,16,14}},
{{30,30,30,22,18,14,30,22,18,14,14,14,14,12}},
{{30,30,30,22,18,14,30,22,18,14,14,14,14,12}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{28,28,28,26,22,18,28,26,22,18,18,18,18,14}},
{{28,28,28,26,22,18,28,26,22,18,18,18,18,14}},
{{28,28,28,24,20,16,28,24,20,16,16,16,16,12}},
{{28,28,28,24,20,16,28,24,20,16,16,16,16,12}},
{{28,28,28,22,18,14,28,22,18,14,14,14,14,10}},
{{28,28,28,22,18,14,28,22,18,14,14,14,14,10}},
{{28,28,28,20,16,12,28,20,16,12,12,12,12,8}},
{{28,28,28,20,16,12,28,20,16,12,12,12,12,8}},
},
//static A_UINT8 ctl_index_5g[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctl_edges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctl_edges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctl_edges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctl_edges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctl_edges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctl_edges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctl_edges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctl_edges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctl_edges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctl_edges[6].bChannel*/0xFF,
/* Data[3].ctl_edges[7].bChannel*/0xFF},
{/* Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctl_edges[4].bChannel*/0xFF,
/* Data[4].ctl_edges[5].bChannel*/0xFF,
/* Data[4].ctl_edges[6].bChannel*/0xFF,
/* Data[4].ctl_edges[7].bChannel*/0xFF},
{/* Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctl_edges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctl_edges[6].bChannel*/0xFF,
/* Data[5].ctl_edges[7].bChannel*/0xFF},
{/* Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctl_edges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctl_edges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctl_edges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctl_edges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctl_edges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctl_edges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctl_edges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctl_edges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctl_edges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,751 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300templateHB116_h__
#define __ar9300templateHB116_h__
static ar9300_eeprom_t ar9300_template_hb116=
{
2, // eeprom_version;
ar9300_eeprom_template_hb116, // template_version;
{0x00,0x03,0x7f,0x0,0x0,0x0}, //mac_addr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{"hb116-041-f0000"},
// {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER base_eep_header=
{
{0,0x1f}, // reg_dmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x33, // txrx_mask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 0}, // op_cap_flags;
0, // rf_silent;
0, // blue_tooth_options;
0, // device_cap;
5, // device_type; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x0d, //feature_enable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
//bit5 - enable paprd -- default to 0
0, //misc_configuration: bit0 - turn down drivestrength
6, // eeprom_write_enable_gpio
0, // wlan_disable_gpio
8, // wlan_led_gpio
0xff, // rx_band_select_gpio
0x10, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modal_header_2g=
{
0x110, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x44444, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x10,0x10,0x10}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0x1f,0x1f,0x1f}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0x12,0x12,0x12}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
25, // temp_slope;
0, // voltSlope;
{FREQ2FBIN(2464, 1),0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0c80C080, // paprd_rate_mask_ht20 // 4
0x0080C080, // paprd_rate_mask_ht40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
0, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 cal_freq_pier_2g[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2462, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_2g[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 cal_target_freqbin_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_2g[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_power_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{34,34,34,34}},
{{34,34,34,34}}
},
//static CAL_TARGET_POWER_LEG cal_target_power_2g[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{34,34,32,32}},
{{34,34,32,32}},
{{34,34,32,32}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,32,30,32,32,30,28,0,0,0,0}},
{{32,32,32,32,32,30,32,32,30,28,0,0,0,0}},
{{32,32,32,32,32,30,32,32,30,28,0,0,0,0}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,30,30,28,30,30,28,26,0,0,0,0}},
{{30,30,30,30,30,28,30,30,28,26,0,0,0,0}},
{{30,30,30,30,30,28,30,30,28,26,0,0,0,0}},
},
//static A_UINT8 ctl_index_2g[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctl_power_data_2g[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modal_header_5g=
{
0x220, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x44444, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0x19,0x19,0x19}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0x14,0x14,0x14}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
70, // temp_slope;
0, // voltSlope;
{0,0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0cf0e0e0, // paprd_rate_mask_ht20 // 4
0x6cf0e0e0, // paprd_rate_mask_ht40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
35, // temp_slope_low
50, // temp_slope_high
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 cal_freq_pier_5g[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5160, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5700, 0),
//pPiers[7] =
FREQ2FBIN(5785, 0),
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_5g[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG cal_target_power_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,28,24,20,30,28,24,20,0,0,0,0}},
{{30,30,30,28,24,20,30,28,24,20,0,0,0,0}},
{{30,30,30,26,22,18,30,26,22,18,0,0,0,0}},
{{30,30,30,26,22,18,30,26,22,18,0,0,0,0}},
{{30,30,30,24,20,16,30,24,20,16,0,0,0,0}},
{{30,30,30,24,20,16,30,24,20,16,0,0,0,0}},
{{30,30,30,22,18,14,30,22,18,14,0,0,0,0}},
{{30,30,30,22,18,14,30,22,18,14,0,0,0,0}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{28,28,28,26,22,18,28,26,22,18,0,0,0,0}},
{{28,28,28,26,22,18,28,26,22,18,0,0,0,0}},
{{28,28,28,24,20,16,28,24,20,16,0,0,0,0}},
{{28,28,28,24,20,16,28,24,20,16,0,0,0,0}},
{{28,28,28,22,18,14,28,22,18,14,0,0,0,0}},
{{28,28,28,22,18,14,28,22,18,14,0,0,0,0}},
{{28,28,28,20,16,12,28,20,16,12,0,0,0,0}},
{{28,28,28,20,16,12,28,20,16,12,0,0,0,0}},
},
//static A_UINT8 ctl_index_5g[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctl_edges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctl_edges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctl_edges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctl_edges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctl_edges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctl_edges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctl_edges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctl_edges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctl_edges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctl_edges[6].bChannel*/0xFF,
/* Data[3].ctl_edges[7].bChannel*/0xFF},
{/* Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctl_edges[4].bChannel*/0xFF,
/* Data[4].ctl_edges[5].bChannel*/0xFF,
/* Data[4].ctl_edges[6].bChannel*/0xFF,
/* Data[4].ctl_edges[7].bChannel*/0xFF},
{/* Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctl_edges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctl_edges[6].bChannel*/0xFF,
/* Data[5].ctl_edges[7].bChannel*/0xFF},
{/* Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctl_edges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctl_edges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctl_edges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctl_edges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctl_edges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctl_edges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctl_edges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctl_edges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctl_edges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,751 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300templateOsprey_k31_h__
#define __ar9300templateOsprey_k31_h__
static ar9300_eeprom_t ar9300_template_osprey_k31=
{
2, // eepromVersion;
ar9300_eeprom_template_osprey_k31, // templateVersion;
//NC, Mac Address Colon from HB116
{0,3,0x7f,41,22,0xb4}, //macAddr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
//NC, No Serial Number
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER baseEepHeader=
{
{0,0x1f}, // regDmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x33, // txrxMask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 0}, // opCapFlags;
0, // rfSilent;
0, // blueToothOptions;
0, // deviceCap;
5, // deviceType; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x1d, //featureEnable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
0, //miscConfiguration: bit0 - turn down drivestrength
6, // eepromWriteEnableGpio
0, // wlanDisableGpio
8, // wlanLedGpio
0xff, // rxBandSelectGpio
10, // txrxgain
0x709142fe, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modalHeader2G=
{
0x110, // antCtrlCommon; // 4 idle, t1, t2, b (4 bits per setting)
0xeeeee, // antCtrlCommon2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // antCtrlChain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1DB[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1Margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
25, // tempSlope;
0, // voltSlope;
{0xa4,0,0,0,0}, // spurChans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noiseFloorThreshCh[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0xf, // xpaBiasLvl; // 1
0x0e, // txFrameToDataStart; // 1
0x0e, // txFrameToPaOn; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antennaGain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // txFrameToXpaOn; // 1
28, // thresh62; // 1
0x0c80C080, // papdRateMaskHt20 // 4
0x0080C080, // papdRateMaskHt40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
0, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 calFreqPier2G[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2462, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP calPierData2G[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{235,0,148,150,162,0}, {235,0,147,150,163,0}, {235,0,147,150,163,0}},
{{232,0,147,148,162,0}, {233,0,147,148,163,0}, {234,0,147,148,163,0}},
{{0,0,0,136,162,0}, {0,0,0,136,163,0}, {0,0,0,136,163,0}},
},
//A_UINT8 calTarget_freqbin_Cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG calTarget_freqbin_2G[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT calTarget_freqbin_2GHT20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT calTarget_freqbin_2GHT40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG calTargetPowerCck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{34,34,34,34}},
{{34,34,34,34}}
},
//static CAL_TARGET_POWER_LEG calTargetPower2G[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{34,34,32,32}},
{{34,34,32,32}},
{{34,34,32,32}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower2GHT20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,32,30,32,32,30,28,0,0,0,0}},
{{32,32,32,32,32,30,32,32,30,28,0,0,0,0}},
{{32,32,32,32,32,30,32,32,30,28,0,0,0,0}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower2GHT40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,30,30,28,30,30,28,26,0,0,0,0}},
{{30,30,30,30,30,28,30,30,28,26,0,0,0,0}},
{{30,30,30,30,30,28,30,30,28,26,0,0,0,0}},
},
//static A_UINT8 ctlIndex_2G[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctlEdges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctlEdges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctlEdges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctlEdges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctlEdges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctlEdges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctlEdges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctlEdges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctlEdges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctlPowerData_2G[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modalHeader5G=
{
0x220, // antCtrlCommon; // 4 idle, t1, t2, b (4 bits per setting)
0x11111, // antCtrlCommon2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // antCtrlChain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1DB[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1Margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
45, // tempSlope;
0, // voltSlope;
{0,0,0,0,0}, // spurChans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noiseFloorThreshCh[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpaBiasLvl; // 1
0x0e, // txFrameToDataStart; // 1
0x0e, // txFrameToPaOn; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antennaGain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // txFrameToXpaOn; // 1
28, // thresh62; // 1
0x0cf0e0e0, // papdRateMaskHt20 // 4
0x6cf0e0e0, // papdRateMaskHt40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
0,
0,
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 calFreqPier5G[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5160, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5700, 0),
//pPiers[7] =
FREQ2FBIN(5785, 0)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP calPierData5G[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{170,0,149,0,0,0},{170,0,149,147,167,0},{170,0,149,0,0,0},{170,0,147,0,0,0}, {170,0,146,148,164,0}, {170,0,146,0,0,0}, {170,0,147,145,163,0}, {170,0,146,143,162,0}},
{{170,0,149,0,0,0},{170,0,149,147,167,0},{170,0,149,0,0,0},{170,0,147,0,0,0}, {170,0,146,148,164,0}, {170,0,146,0,0,0}, {170,0,147,145,163,0}, {170,0,146,143,162,0}},
{{0,0,0,0,0,0}, {0,0,0,136,167,0},{0,0,0,0,0}, {0,0,0,0,0}, {0 ,0,0 ,137,164,0}, {0,0,0,0,0}, {0 ,0,0 ,136,163,0}, {0 ,0,0 ,136,162,0}},
},
//static CAL_TARGET_POWER_LEG calTarget_freqbin_5G[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG calTargetPower5G[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
{{30,30,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,28,24,20,30,28,24,20,0,0,0,0}},
{{30,30,30,28,24,20,30,28,24,20,0,0,0,0}},
{{30,30,30,26,22,18,30,26,22,18,0,0,0,0}},
{{30,30,30,26,22,18,30,26,22,18,0,0,0,0}},
{{30,30,30,24,20,16,30,24,20,16,0,0,0,0}},
{{30,30,30,24,20,16,30,24,20,16,0,0,0,0}},
{{30,30,30,22,18,14,30,22,18,14,0,0,0,0}},
{{30,30,30,22,18,14,30,22,18,14,0,0,0,0}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0}},
{{28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0}},
{{28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0}},
{{28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0}},
{{28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0}},
{{28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0}},
{{28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0}},
{{28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0}},
},
//static A_UINT8 ctlIndex_5G[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctlEdges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctlEdges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctlEdges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctlEdges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctlEdges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctlEdges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctlEdges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctlEdges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctlEdges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctlEdges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctlEdges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctlEdges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctlEdges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctlEdges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctlEdges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctlEdges[6].bChannel*/0xFF,
/* Data[3].ctlEdges[7].bChannel*/0xFF},
{/* Data[4].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctlEdges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctlEdges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctlEdges[4].bChannel*/0xFF,
/* Data[4].ctlEdges[5].bChannel*/0xFF,
/* Data[4].ctlEdges[6].bChannel*/0xFF,
/* Data[4].ctlEdges[7].bChannel*/0xFF},
{/* Data[5].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctlEdges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctlEdges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctlEdges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctlEdges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctlEdges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctlEdges[6].bChannel*/0xFF,
/* Data[5].ctlEdges[7].bChannel*/0xFF},
{/* Data[6].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctlEdges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctlEdges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctlEdges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctlEdges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctlEdges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctlEdges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctlEdges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctlEdges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctlEdges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctlEdges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctlEdges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctlEdges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctlEdges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctlEdges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctlEdges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctlEdges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,747 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300template_wasp_2_h__
#define __ar9300template_wasp_2_h__
static ar9300_eeprom_t ar9300_template_wasp_2=
{
2, // eepromVersion;
ar9300_eeprom_template_wasp_2, // templateVersion;
{0x00,0x03,0x7f,0x0,0x0,0x0}, //mac_addr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER baseEepHeader=
{
{0,0x1f}, // regDmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x33, // txrxMask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 3}, // opCapFlags;
0, // rfSilent;
0, // blueToothOptions;
0, // deviceCap;
4, // deviceType; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x0c, //featureEnable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
0, //miscConfiguration: bit0 - turn down drivestrength
3, // eepromWriteEnableGpio
0, // wlanDisableGpio
8, // wlanLedGpio
0xff, // rxBandSelectGpio
0, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modalHeader2G=
{
0x220, // antCtrlCommon; // 4 idle, t1, t2, b (4 bits per setting)
0x88888, // antCtrlCommon2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // antCtrlChain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1DB[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1Margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
36, // tempSlope;
0, // voltSlope;
{0,0,0,0,0}, // spurChans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noiseFloorThreshCh[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpaBiasLvl; // 1
0x0e, // txFrameToDataStart; // 1
0x0e, // txFrameToPaOn; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antennaGain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // txFrameToXpaOn; // 1
28, // thresh62; // 1
0x0c80C080, // papdRateMaskHt20 // 4
0x0080C080, // papdRateMaskHt40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
0, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 calFreqPier2G[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP calPierData2G[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 calTarget_freqbin_Cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2484, 1)
},
//static CAL_TARGET_POWER_LEG calTarget_freqbin_2G[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT calTarget_freqbin_2GHT20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT calTarget_freqbin_2GHT40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG calTargetPowerCck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{36,36,36,36}},
{{36,36,36,36}}
},
//static CAL_TARGET_POWER_LEG calTargetPower2G[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{32,32,28,24}},
{{32,32,28,24}},
{{32,32,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower2GHT20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower2GHT40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
},
//static A_UINT8 ctlIndex_2G[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctlEdges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctlEdges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctlEdges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctlEdges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctlEdges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctlEdges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctlEdges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctlEdges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctlEdges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctlPowerData_2G[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modalHeader5G=
{
0x440, // antCtrlCommon; // 4 idle, t1, t2, b (4 bits per setting)
0x11111, // antCtrlCommon2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x000,0x000,0x000}, // antCtrlChain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1DB[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1Margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
68, // tempSlope;
0, // voltSlope;
{0,0,0,0,0}, // spurChans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noiseFloorThreshCh[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpaBiasLvl; // 1
0x0e, // txFrameToDataStart; // 1
0x0e, // txFrameToPaOn; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antennaGain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // txFrameToXpaOn; // 1
28, // thresh62; // 1
0x0cf0e0e0, // papdRateMaskHt20 // 4
0x6cf0e0e0, // papdRateMaskHt40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
0,
0,
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 calFreqPier5G[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5180, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5725, 0),
//pPiers[7] =
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP calPierData5G[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG calTarget_freqbin_5G[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5220, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG calTargetPower5G[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
},
//static A_UINT8 ctlIndex_5G[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctlEdges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctlEdges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctlEdges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctlEdges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctlEdges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctlEdges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctlEdges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctlEdges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctlEdges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctlEdges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctlEdges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctlEdges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctlEdges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctlEdges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctlEdges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctlEdges[6].bChannel*/0xFF,
/* Data[3].ctlEdges[7].bChannel*/0xFF},
{/* Data[4].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctlEdges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctlEdges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctlEdges[4].bChannel*/0xFF,
/* Data[4].ctlEdges[5].bChannel*/0xFF,
/* Data[4].ctlEdges[6].bChannel*/0xFF,
/* Data[4].ctlEdges[7].bChannel*/0xFF},
{/* Data[5].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctlEdges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctlEdges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctlEdges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctlEdges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctlEdges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctlEdges[6].bChannel*/0xFF,
/* Data[5].ctlEdges[7].bChannel*/0xFF},
{/* Data[6].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctlEdges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctlEdges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctlEdges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctlEdges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctlEdges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctlEdges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctlEdges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctlEdges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctlEdges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctlEdges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctlEdges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctlEdges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctlEdges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctlEdges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctlEdges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctlEdges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,748 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300template_wasp_k31_h__
#define __ar9300template_wasp_k31_h__
static ar9300_eeprom_t ar9300_template_wasp_k31=
{
2, // eepromVersion;
ar9300_eeprom_template_wasp_k31, // templateVersion;
{0x00,0x03,0x7f,0x0,0x0,0x0}, //mac_addr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER baseEepHeader=
{
{0,0x1f}, // regDmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x33, // txrxMask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 3}, // opCapFlags;
0, // rfSilent;
0, // blueToothOptions;
0, // deviceCap;
4, // deviceType; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x0c, //featureEnable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
0, //miscConfiguration: bit0 - turn down drivestrength
3, // eepromWriteEnableGpio
0, // wlanDisableGpio
8, // wlanLedGpio
0xff, // rxBandSelectGpio
0, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modalHeader2G=
{
0x110, // antCtrlCommon; // 4 idle, t1, t2, b (4 bits per setting)
0x22222, // antCtrlCommon2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // antCtrlChain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1DB[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1Margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
36, // tempSlope;
0, // voltSlope;
{0,0,0,0,0}, // spurChans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noiseFloorThreshCh[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpaBiasLvl; // 1
0x0e, // txFrameToDataStart; // 1
0x0e, // txFrameToPaOn; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antennaGain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // txFrameToXpaOn; // 1
28, // thresh62; // 1
0x0c80C080, // papdRateMaskHt20 // 4
0x0080C080, // papdRateMaskHt40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
0, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 calFreqPier2G[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP calPierData2G[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 calTarget_freqbin_Cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2484, 1)
},
//static CAL_TARGET_POWER_LEG calTarget_freqbin_2G[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT calTarget_freqbin_2GHT20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT calTarget_freqbin_2GHT40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG calTargetPowerCck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{36,36,36,36}},
{{36,36,36,36}}
},
//static CAL_TARGET_POWER_LEG calTargetPower2G[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{32,32,28,24}},
{{32,32,28,24}},
{{32,32,28,24}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower2GHT20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower2GHT40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
{{32,32,32,32,28,20,32,32,28,20,32,32,28,20}},
},
//static A_UINT8 ctlIndex_2G[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctlEdges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctlEdges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctlEdges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctlEdges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctlEdges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctlEdges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctlEdges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctlEdges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctlEdges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctlEdges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctlEdges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctlEdges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctlPowerData_2G[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modalHeader5G=
{
0x440, // antCtrlCommon; // 4 idle, t1, t2, b (4 bits per setting)
0x11111, // antCtrlCommon2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x000,0x000,0x000}, // antCtrlChain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1DB[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1Margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
68, // tempSlope;
0, // voltSlope;
{0,0,0,0,0}, // spurChans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noiseFloorThreshCh[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpaBiasLvl; // 1
0x0e, // txFrameToDataStart; // 1
0x0e, // txFrameToPaOn; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antennaGain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // txFrameToXpaOn; // 1
28, // thresh62; // 1
0x0cf0e0e0, // papdRateMaskHt20 // 4
0x6cf0e0e0, // papdRateMaskHt40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
0,
0,
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 calFreqPier5G[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5180, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5725, 0),
//pPiers[7] =
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP calPierData5G[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG calTarget_freqbin_5G[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5220, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG calTargetPower5G[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
{{20,20,20,10}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
},
//static OSP_CAL_TARGET_POWER_HT calTargetPower5GHT40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
{{20,20,10,10,0,0,10,10,0,0,10,10,0,0}},
},
//static A_UINT8 ctlIndex_5G[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctlEdges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctlEdges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctlEdges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctlEdges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctlEdges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctlEdges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctlEdges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctlEdges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctlEdges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctlEdges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctlEdges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctlEdges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctlEdges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctlEdges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctlEdges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctlEdges[6].bChannel*/0xFF,
/* Data[3].ctlEdges[7].bChannel*/0xFF},
{/* Data[4].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctlEdges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctlEdges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctlEdges[4].bChannel*/0xFF,
/* Data[4].ctlEdges[5].bChannel*/0xFF,
/* Data[4].ctlEdges[6].bChannel*/0xFF,
/* Data[4].ctlEdges[7].bChannel*/0xFF},
{/* Data[5].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctlEdges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctlEdges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctlEdges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctlEdges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctlEdges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctlEdges[6].bChannel*/0xFF,
/* Data[5].ctlEdges[7].bChannel*/0xFF},
{/* Data[6].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctlEdges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctlEdges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctlEdges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctlEdges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctlEdges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctlEdges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctlEdges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctlEdges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctlEdges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctlEdges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctlEdges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctlEdges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctlEdges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctlEdges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctlEdges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctlEdges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctlEdges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctlEdges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctlEdges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctlEdges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctlEdges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctlEdges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctlEdges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,750 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300templateXB112_h__
#define __ar9300templateXB112_h__
static ar9300_eeprom_t ar9300_template_xb112=
{
2, // eeprom_version;
ar9300_eeprom_template_xb112, // template_version;
{0x00,0x03,0x7f,0x0,0x0,0x0}, //mac_addr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{"xb112-041-f0000"},
// {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER base_eep_header=
{
{0,0x1f}, // reg_dmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x77, // txrx_mask; //4 bits tx and 4 bits rx
{AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 0}, // op_cap_flags;
0, // rf_silent;
0, // blue_tooth_options;
0, // device_cap;
5, // device_type; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x0d, //feature_enable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
//bit5 - enable paprd -- default to 0
0, //misc_configuration: bit0 - turn down drivestrength
6, // eeprom_write_enable_gpio
0, // wlan_disable_gpio
8, // wlan_led_gpio
0xff, // rx_band_select_gpio
0, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modal_header_2g=
{
0x110, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x22222, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x10,0x10,0x10}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0x1b,0x1b,0x1b}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0x15,0x15,0x15}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
50, // temp_slope;
0, // voltSlope;
{FREQ2FBIN(2464, 1),0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0c80C080, // paprd_rate_mask_ht20 // 4
0x0080C080, // paprd_rate_mask_ht40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
0, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 cal_freq_pier_2g[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2462, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_2g[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 cal_target_freqbin_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_2g[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_power_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{38,38,38,38}},
{{38,38,38,38}}
},
//static CAL_TARGET_POWER_LEG cal_target_power_2g[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{38,38,36,34}},
{{38,38,36,34}},
{{38,38,34,32}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{36,36,36,36,36,34,34,32,30,28,28,28,28,26}},
{{36,36,36,36,36,34,36,34,32,30,30,30,28,26}},
{{36,36,36,36,36,34,34,32,30,28,28,28,28,26}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{36,36,36,36,34,32,32,30,28,26,26,26,26,24}},
{{36,36,36,36,34,32,34,32,30,28,28,28,28,24}},
{{36,36,36,36,34,32,32,30,28,26,26,26,26,24}},
},
//static A_UINT8 ctl_index_2g[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctl_power_data_2g[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modal_header_5g=
{
0x110, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x22222, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x000,0x000,0x000}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0x13,0x19,0x17}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0x19,0x19,0x19}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
70, // temp_slope;
15, // voltSlope;
{0,0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0cf0e0e0, // paprd_rate_mask_ht20 // 4
0x6cf0e0e0, // paprd_rate_mask_ht40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
72, // tempSlopeL;
105, // tempSlopeH;
{0x10,0x14,0x10}, // xatten1_db_low
{0x19,0x19,0x19}, // xatten1_margin_low
{0x1d,0x20,0x24}, // xatten1_db_high
{0x10,0x10,0x10} // xatten1_margin_high
},
//static A_UINT8 cal_freq_pier_5g[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5180, 0),
//pPiers[1] =
FREQ2FBIN(5220, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5600, 0),
//pPiers[6] =
FREQ2FBIN(5700, 0),
//pPiers[7] =
FREQ2FBIN(5785, 0)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_5g[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5220, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5220, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5220, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5600, 0),
FREQ2FBIN(5725, 0),
FREQ2FBIN(5825, 0)
},
//static CAL_TARGET_POWER_LEG cal_target_power_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{32,32,28,26}},
{{32,32,28,26}},
{{32,32,28,26}},
{{32,32,26,24}},
{{32,32,26,24}},
{{32,32,24,22}},
{{30,30,24,22}},
{{30,30,24,22}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,28,26,32,28,26,24,24,24,22,22}},
{{32,32,32,32,28,26,32,28,26,24,24,24,22,22}},
{{32,32,32,32,28,26,32,28,26,24,24,24,22,22}},
{{32,32,32,32,28,26,32,26,24,22,22,22,20,20}},
{{32,32,32,32,28,26,32,26,24,22,20,18,16,16}},
{{32,32,32,32,28,26,32,24,20,16,18,16,14,14}},
{{30,30,30,30,28,26,30,24,20,16,18,16,14,14}},
{{30,30,30,30,28,26,30,24,20,16,18,16,14,14}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,30,28,26,30,28,26,24,24,24,22,22}},
{{32,32,32,30,28,26,30,28,26,24,24,24,22,22}},
{{32,32,32,30,28,26,30,28,26,24,24,24,22,22}},
{{32,32,32,30,28,26,30,26,24,22,22,22,20,20}},
{{32,32,32,30,28,26,30,26,24,22,20,18,16,16}},
{{32,32,32,30,28,26,30,22,20,16,18,16,14,14}},
{{30,30,30,30,28,26,30,22,20,16,18,16,14,14}},
{{30,30,30,30,28,26,30,22,20,16,18,16,14,14}},
},
//static A_UINT8 ctl_index_5g[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctl_edges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctl_edges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctl_edges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctl_edges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctl_edges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctl_edges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctl_edges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctl_edges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctl_edges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctl_edges[6].bChannel*/0xFF,
/* Data[3].ctl_edges[7].bChannel*/0xFF},
{/* Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctl_edges[4].bChannel*/0xFF,
/* Data[4].ctl_edges[5].bChannel*/0xFF,
/* Data[4].ctl_edges[6].bChannel*/0xFF,
/* Data[4].ctl_edges[7].bChannel*/0xFF},
{/* Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctl_edges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctl_edges[6].bChannel*/0xFF,
/* Data[5].ctl_edges[7].bChannel*/0xFF},
{/* Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctl_edges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctl_edges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctl_edges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctl_edges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctl_edges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctl_edges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctl_edges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctl_edges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctl_edges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,750 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
/*
* READ THIS NOTICE!
*
* Values defined in this file may only be changed under exceptional circumstances.
*
* Please ask Fiona Cain before making any changes.
*/
#ifndef __ar9300templateXB113_h__
#define __ar9300templateXB113_h__
static ar9300_eeprom_t ar9300_template_xb113=
{
2, // eeprom_version;
ar9300_eeprom_template_xb113, // template_version;
{0x00,0x03,0x7f,0x0,0x0,0x0}, //mac_addr[6];
//static A_UINT8 custData[OSPREY_CUSTOMER_DATA_SIZE]=
{"xb113-023-f0000"},
// {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//static OSPREY_BASE_EEP_HEADER base_eep_header=
{
{0,0x1f}, // reg_dmn[2]; //Does this need to be outside of this structure, if it gets written after calibration
0x77, // txrx_mask; //4 bits tx and 4 bits rx
{ AR9300_OPFLAGS_11A, 0}, // op_cap_flags;
0, // rf_silent;
0, // blue_tooth_options;
0, // device_cap;
5, // device_type; // takes lower byte in eeprom location
OSPREY_PWR_TABLE_OFFSET, // pwrTableOffset; // offset in dB to be added to beginning of pdadc table in calibration
{0,0}, // params_for_tuning_caps[2]; //placeholder, get more details from Don
0x0d, //feature_enable; //bit0 - enable tx temp comp
//bit1 - enable tx volt comp
//bit2 - enable fastClock - default to 1
//bit3 - enable doubling - default to 1
//bit4 - enable internal regulator - default to 0
//bit5 - enable paprd -- default to 0
0, //misc_configuration: bit0 - turn down drivestrength
6, // eeprom_write_enable_gpio
0, // wlan_disable_gpio
8, // wlan_led_gpio
0xff, // rx_band_select_gpio
0x21, // txrxgain
0, // swreg
},
//static OSPREY_MODAL_EEP_HEADER modal_header_2g=
{
0x110, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x44444, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
25, // temp_slope;
0, // voltSlope;
{FREQ2FBIN(2464, 1),0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2c, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0c80C080, // paprd_rate_mask_ht20 // 4
0x0080C080, // paprd_rate_mask_ht40
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{
0, // ant_div_control
{0,0}, // base_ext1
0, // misc_enable
{0,0,0,0,0,0,0,0}, // temp slop extension
0, // quick drop low
0, // quick drop high
},
//static A_UINT8 cal_freq_pier_2g[OSPREY_NUM_2G_CAL_PIERS]=
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2462, 1)
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_2g[OSPREY_MAX_CHAINS][OSPREY_NUM_2G_CAL_PIERS]=
{ {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//A_UINT8 cal_target_freqbin_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS];
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_2g[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_freqbin_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]
{
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
FREQ2FBIN(2472, 1)
},
//static CAL_TARGET_POWER_LEG cal_target_power_cck[OSPREY_NUM_2G_CCK_TARGET_POWERS]=
{
//1L-5L,5S,11L,11S
{{34,34,34,34}},
{{34,34,34,34}}
},
//static CAL_TARGET_POWER_LEG cal_target_power_2g[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{34,34,32,32}},
{{34,34,32,32}},
{{34,34,32,32}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht20[OSPREY_NUM_2G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{32,32,32,32,32,28,32,32,30,28,0,0,0,0}},
{{32,32,32,32,32,28,32,32,30,28,0,0,0,0}},
{{32,32,32,32,32,28,32,32,30,28,0,0,0,0}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_2g_ht40[OSPREY_NUM_2G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{30,30,30,30,30,28,30,30,28,26,0,0,0,0}},
{{30,30,30,30,30,28,30,30,28,26,0,0,0,0}},
{{30,30,30,30,30,28,30,30,28,26,0,0,0,0}},
},
//static A_UINT8 ctl_index_2g[OSPREY_NUM_CTLS_2G]=
{
0x11,
0x12,
0x15,
0x17,
0x41,
0x42,
0x45,
0x47,
0x31,
0x32,
0x35,
0x37
},
//A_UINT8 ctl_freqbin_2G[OSPREY_NUM_CTLS_2G][OSPREY_NUM_BAND_EDGES_2G];
{
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2457, 1),
FREQ2FBIN(2462, 1)},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2412, 1),
FREQ2FBIN(2417, 1),
FREQ2FBIN(2462, 1),
0xFF},
{FREQ2FBIN(2422, 1),
FREQ2FBIN(2427, 1),
FREQ2FBIN(2447, 1),
FREQ2FBIN(2452, 1)},
{/*Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
/*Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(2484, 1)},
{/*Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
FREQ2FBIN(2472, 1),
0},
{/*Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)},
{/*Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[9].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[9].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[9].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[10].ctl_edges[0].bChannel*/FREQ2FBIN(2412, 1),
/*Data[10].ctl_edges[1].bChannel*/FREQ2FBIN(2417, 1),
/*Data[10].ctl_edges[2].bChannel*/FREQ2FBIN(2472, 1),
0},
{/*Data[11].ctl_edges[0].bChannel*/FREQ2FBIN(2422, 1),
/*Data[11].ctl_edges[1].bChannel*/FREQ2FBIN(2427, 1),
/*Data[11].ctl_edges[2].bChannel*/FREQ2FBIN(2447, 1),
/*Data[11].ctl_edges[3].bChannel*/FREQ2FBIN(2462, 1)}
},
//OSP_CAL_CTL_DATA_2G ctl_power_data_2g[OSPREY_NUM_CTLS_2G];
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {1, 60}}},
{{{1, 60}, {0, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {0, 60}, {0, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
{{{0, 60}, {1, 60}, {1, 60}, {1, 60}}},
},
#else
{
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 1}}},
{{{60, 1}, {60, 0}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 0}, {60, 0}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
{{{60, 0}, {60, 1}, {60, 1}, {60, 1}}},
},
#endif
//static OSPREY_MODAL_EEP_HEADER modal_header_5g=
{
0x220, // ant_ctrl_common; // 4 idle, t1, t2, b (4 bits per setting)
0x11111, // ant_ctrl_common2; // 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12
{0x150,0x150,0x150}, // ant_ctrl_chain[OSPREY_MAX_CHAINS]; // 6 idle, t, r, rx1, rx12, b (2 bits each)
{0,0,0}, // xatten1_db[OSPREY_MAX_CHAINS]; // 3 //xatten1_db for merlin (0xa20c/b20c 5:0)
{0,0,0}, // xatten1_margin[OSPREY_MAX_CHAINS]; // 3 //xatten1_margin for merlin (0xa20c/b20c 16:12
68, // temp_slope;
0, // voltSlope;
{FREQ2FBIN(5500, 0),0,0,0,0}, // spur_chans[OSPREY_EEPROM_MODAL_SPURS]; // spur channels in usual fbin coding format
{-1,0,0}, // noise_floor_thresh_ch[OSPREY_MAX_CHAINS]; // 3 //Check if the register is per chain
{0, 0, 0, 0, 0, 0,0,0,0,0,0}, // reserved
0, // quick drop
0xf, // xpa_bias_lvl; // 1
0x0e, // tx_frame_to_data_start; // 1
0x0e, // tx_frame_to_pa_on; // 1
3, // txClip; // 4 bits tx_clip, 4 bits dac_scale_cck
0, // antenna_gain; // 1
0x2d, // switchSettling; // 1
-30, // adcDesiredSize; // 1
0, // txEndToXpaOff; // 1
0x2, // txEndToRxOn; // 1
0xe, // tx_frame_to_xpa_on; // 1
28, // thresh62; // 1
0x0cf0e0e0, // paprd_rate_mask_ht20 // 4
0x6cf0e0e0, // paprd_rate_mask_ht40 // 4
0, // switchcomspdt; // 2
0, // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
0, // rf_gain_cap
0, // tx_gain_cap
{0,0,0,0,0} //futureModal[5];
},
{ // base_ext2
72, // tempSlopeL;
105, // tempSlopeH;
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
},
//static A_UINT8 cal_freq_pier_5g[OSPREY_NUM_5G_CAL_PIERS]=
{
//pPiers[0] =
FREQ2FBIN(5180, 0),
//pPiers[1] =
FREQ2FBIN(5240, 0),
//pPiers[2] =
FREQ2FBIN(5320, 0),
//pPiers[3] =
FREQ2FBIN(5400, 0),
//pPiers[4] =
FREQ2FBIN(5500, 0),
//pPiers[5] =
FREQ2FBIN(5700, 0),
//pPiers[6] =
FREQ2FBIN(5745, 0),
//pPiers[7] =
FREQ2FBIN(5785, 0),
},
//static OSP_CAL_DATA_PER_FREQ_OP_LOOP cal_pier_data_5g[OSPREY_MAX_CHAINS][OSPREY_NUM_5G_CAL_PIERS]=
{
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
{{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}},
},
//static CAL_TARGET_POWER_LEG cal_target_freqbin_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5785, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
FREQ2FBIN(5180, 0),
FREQ2FBIN(5240, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5400, 0),
FREQ2FBIN(5500, 0),
FREQ2FBIN(5700, 0),
FREQ2FBIN(5745, 0),
FREQ2FBIN(5825, 0)
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
FREQ2FBIN(5190, 0),
FREQ2FBIN(5230, 0),
FREQ2FBIN(5320, 0),
FREQ2FBIN(5410, 0),
FREQ2FBIN(5510, 0),
FREQ2FBIN(5670, 0),
FREQ2FBIN(5755, 0),
FREQ2FBIN(5785, 0)
},
//static CAL_TARGET_POWER_LEG cal_target_power_5g[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//6-24,36,48,54
{{42,40,40,34}},
{{42,40,40,34}},
{{42,40,40,34}},
{{42,40,40,34}},
{{42,40,40,34}},
{{42,40,40,34}},
{{42,40,40,34}},
{{42,40,40,34}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht20[OSPREY_NUM_5G_20_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{40,40,40,40,32,28,40,40,32,28,40,40,32,20}},
{{40,40,40,40,32,28,40,40,32,28,40,40,32,20}},
{{40,40,40,40,32,28,40,40,32,28,40,40,32,20}},
{{40,40,40,40,32,28,40,40,32,28,40,40,32,20}},
{{40,40,40,40,32,28,40,40,32,28,40,40,32,20}},
{{40,40,40,40,32,28,40,40,32,28,40,40,32,20}},
{{38,38,38,38,32,28,38,38,32,28,38,38,32,26}},
{{36,36,36,36,32,28,36,36,32,28,36,36,32,26}},
},
//static OSP_CAL_TARGET_POWER_HT cal_target_power_5g_ht40[OSPREY_NUM_5G_40_TARGET_POWERS]=
{
//0_8_16,1-3_9-11_17-19,
// 4,5,6,7,12,13,14,15,20,21,22,23
{{40,40,40,38,30,26,40,40,30,26,40,40,30,24}},
{{40,40,40,38,30,26,40,40,30,26,40,40,30,24}},
{{40,40,40,38,30,26,40,40,30,26,40,40,30,24}},
{{40,40,40,38,30,26,40,40,30,26,40,40,30,24}},
{{40,40,40,38,30,26,40,40,30,26,40,40,30,24}},
{{40,40,40,38,30,26,40,40,30,26,40,40,30,24}},
{{36,36,36,36,30,26,36,36,30,26,36,36,30,24}},
{{34,34,34,34,30,26,34,34,30,26,34,34,30,24}},
},
//static A_UINT8 ctl_index_5g[OSPREY_NUM_CTLS_5G]=
{
//pCtlIndex[0] =
0x10,
//pCtlIndex[1] =
0x16,
//pCtlIndex[2] =
0x18,
//pCtlIndex[3] =
0x40,
//pCtlIndex[4] =
0x46,
//pCtlIndex[5] =
0x48,
//pCtlIndex[6] =
0x30,
//pCtlIndex[7] =
0x36,
//pCtlIndex[8] =
0x38
},
// A_UINT8 ctl_freqbin_5G[OSPREY_NUM_CTLS_5G][OSPREY_NUM_BAND_EDGES_5G];
{
{/* Data[0].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[0].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[0].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[0].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[0].ctl_edges[4].bChannel*/FREQ2FBIN(5600, 0),
/* Data[0].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[0].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[0].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[1].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[1].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[1].ctl_edges[2].bChannel*/FREQ2FBIN(5280, 0),
/* Data[1].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[1].ctl_edges[4].bChannel*/FREQ2FBIN(5520, 0),
/* Data[1].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[1].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[1].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[2].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[2].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[2].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[2].ctl_edges[3].bChannel*/FREQ2FBIN(5310, 0),
/* Data[2].ctl_edges[4].bChannel*/FREQ2FBIN(5510, 0),
/* Data[2].ctl_edges[5].bChannel*/FREQ2FBIN(5550, 0),
/* Data[2].ctl_edges[6].bChannel*/FREQ2FBIN(5670, 0),
/* Data[2].ctl_edges[7].bChannel*/FREQ2FBIN(5755, 0)},
{/* Data[3].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[3].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[3].ctl_edges[2].bChannel*/FREQ2FBIN(5260, 0),
/* Data[3].ctl_edges[3].bChannel*/FREQ2FBIN(5320, 0),
/* Data[3].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[3].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[3].ctl_edges[6].bChannel*/0xFF,
/* Data[3].ctl_edges[7].bChannel*/0xFF},
{/* Data[4].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[4].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[4].ctl_edges[2].bChannel*/FREQ2FBIN(5500, 0),
/* Data[4].ctl_edges[3].bChannel*/FREQ2FBIN(5700, 0),
/* Data[4].ctl_edges[4].bChannel*/0xFF,
/* Data[4].ctl_edges[5].bChannel*/0xFF,
/* Data[4].ctl_edges[6].bChannel*/0xFF,
/* Data[4].ctl_edges[7].bChannel*/0xFF},
{/* Data[5].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[5].ctl_edges[1].bChannel*/FREQ2FBIN(5270, 0),
/* Data[5].ctl_edges[2].bChannel*/FREQ2FBIN(5310, 0),
/* Data[5].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[5].ctl_edges[4].bChannel*/FREQ2FBIN(5590, 0),
/* Data[5].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[5].ctl_edges[6].bChannel*/0xFF,
/* Data[5].ctl_edges[7].bChannel*/0xFF},
{/* Data[6].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[6].ctl_edges[1].bChannel*/FREQ2FBIN(5200, 0),
/* Data[6].ctl_edges[2].bChannel*/FREQ2FBIN(5220, 0),
/* Data[6].ctl_edges[3].bChannel*/FREQ2FBIN(5260, 0),
/* Data[6].ctl_edges[4].bChannel*/FREQ2FBIN(5500, 0),
/* Data[6].ctl_edges[5].bChannel*/FREQ2FBIN(5600, 0),
/* Data[6].ctl_edges[6].bChannel*/FREQ2FBIN(5700, 0),
/* Data[6].ctl_edges[7].bChannel*/FREQ2FBIN(5745, 0)},
{/* Data[7].ctl_edges[0].bChannel*/FREQ2FBIN(5180, 0),
/* Data[7].ctl_edges[1].bChannel*/FREQ2FBIN(5260, 0),
/* Data[7].ctl_edges[2].bChannel*/FREQ2FBIN(5320, 0),
/* Data[7].ctl_edges[3].bChannel*/FREQ2FBIN(5500, 0),
/* Data[7].ctl_edges[4].bChannel*/FREQ2FBIN(5560, 0),
/* Data[7].ctl_edges[5].bChannel*/FREQ2FBIN(5700, 0),
/* Data[7].ctl_edges[6].bChannel*/FREQ2FBIN(5745, 0),
/* Data[7].ctl_edges[7].bChannel*/FREQ2FBIN(5825, 0)},
{/* Data[8].ctl_edges[0].bChannel*/FREQ2FBIN(5190, 0),
/* Data[8].ctl_edges[1].bChannel*/FREQ2FBIN(5230, 0),
/* Data[8].ctl_edges[2].bChannel*/FREQ2FBIN(5270, 0),
/* Data[8].ctl_edges[3].bChannel*/FREQ2FBIN(5510, 0),
/* Data[8].ctl_edges[4].bChannel*/FREQ2FBIN(5550, 0),
/* Data[8].ctl_edges[5].bChannel*/FREQ2FBIN(5670, 0),
/* Data[8].ctl_edges[6].bChannel*/FREQ2FBIN(5755, 0),
/* Data[8].ctl_edges[7].bChannel*/FREQ2FBIN(5795, 0)}
},
//static OSP_CAL_CTL_DATA_5G ctlData_5G[OSPREY_NUM_CTLS_5G]=
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
{
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{0, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{0, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{0, 60},
{0, 60}}},
{{{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60}}},
{{{1, 60},
{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60}}},
{{{1, 60},
{0, 60},
{1, 60},
{1, 60},
{1, 60},
{1, 60},
{0, 60},
{1, 60}}},
}
#else
{
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 0},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 0},
{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 0},
{60, 0}}},
{{{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 1}}},
{{{60, 1},
{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0}}},
{{{60, 1},
{60, 0},
{60, 1},
{60, 1},
{60, 1},
{60, 1},
{60, 0},
{60, 1}}},
}
#endif
};
#endif
@@ -0,0 +1,281 @@
/*
* Copyright (c) 2013 Qualcomm Atheros, 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.
*/
diff --git a/hal/ar9300/ar9300_eeprom.c b/hal/ar9300/ar9300_eeprom.c
index 2fe5506..628026f 100644
--- a/hal/ar9300/ar9300_eeprom.c
+++ b/hal/ar9300/ar9300_eeprom.c
@@ -342,6 +342,8 @@ ar9300_otp_read(struct ath_hal *ah, u_int off, u_int32_t *data, HAL_BOOL is_wifi
int status = 0;
u_int32_t addr;
+ //ath_hal_printf(ah, "%s: reading offset 0x%x\n", __func__, off);
+
addr = (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah))?
OTP_MEM_START_ADDRESS_WASP : OTP_MEM_START_ADDRESS;
if (!is_wifi) {
@@ -372,6 +374,7 @@ ar9300_otp_read(struct ath_hal *ah, u_int off, u_int32_t *data, HAL_BOOL is_wifi
addr = BTOTP_STATUS1_EFUSE_READ_DATA;
}
*data = OS_REG_READ(ah, addr);
+ //ath_hal_printf(ah, "%s: data=0x%x\n", __func__, *data);
return AH_TRUE;
}
@@ -603,6 +606,8 @@ ar9300_eeprom_attach(struct ath_hal *ah)
systime_t current_system_time = OS_GET_TIMESTAMP();
#endif
#endif
+
+ ath_hal_printf(ah, "%s: starting\n", __func__);
ahp->try_dram = 1;
ahp->try_eeprom = 1;
ahp->try_otp = 1;
@@ -679,10 +684,14 @@ ar9300_eeprom_attach(struct ath_hal *ah)
#endif
#endif
+ ath_hal_printf(ah, "%s: calling ar9300_fill_eeprom\n", __func__);
if (!ar9300_fill_eeprom(ah)) {
return HAL_EIO;
}
+ ath_hal_printf(ah, "%s: calibration data type = %d\n", __func__,
+ AH9300(ah)->calibration_data_source);
+
return HAL_OK;
/* return ar9300_check_eeprom(ah); */
#endif
@@ -704,6 +713,7 @@ ar9300_eeprom_attach(struct ath_hal *ah)
ahp->ah_eeprom.mac_addr[4] = 0xD0;
ahp->ah_eeprom.mac_addr[5] = 0x00;
#endif
+ ath_hal_printf(ah, "%s: %s:%d\n", __func__, __FILE__, __LINE__);
return HAL_OK;
#else
#if ATH_DRIVER_SIM
@@ -764,13 +774,17 @@ ar9300_eeprom_attach(struct ath_hal *ah)
return HAL_OK;
}
#endif
+ ath_hal_printf(ah, "%s: %s:%d\n", __func__, __FILE__, __LINE__);
if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
ahp->try_eeprom = 0;
}
+ ath_hal_printf(ah, "%s: %s:%d\n", __func__, __FILE__, __LINE__);
if (!ar9300_eeprom_restore(ah)) {
+ ath_hal_printf(ah, "%s: %s:%d\n", __func__, __FILE__, __LINE__);
return HAL_EIO;
}
+ ath_hal_printf(ah, "%s: %s:%d\n", __func__, __FILE__, __LINE__);
return HAL_OK;
#endif
#endif
@@ -3743,6 +3757,12 @@ ar9300_calibration_data_read_otp(struct ath_hal *ah, long address,
unsigned long byte_addr;
u_int32_t svalue;
+ ath_hal_printf(ah, "%s: called: address=%d, many=%d, is_wifi=%d\n",
+ __func__,
+ (int) address,
+ many,
+ is_wifi);
+
if (((address) < 0) || ((address + many) > 0x400)) {
return AH_FALSE;
}
@@ -3802,6 +3822,8 @@ ar9300_calibration_data_read_array(struct ath_hal *ah, int address,
{
int it;
+ ath_hal_printf(ah, "%s: address=%d, many=%d\n", __func__, address, many);
+
for (it = 0; it < many; it++) {
(void)ar9300_calibration_data_read(ah, address - it, buffer + it, 1);
}
@@ -4001,13 +4023,24 @@ ar9300_eeprom_restore_internal_address(struct ath_hal *ah,
int restored;
u_int16_t checksum, mchecksum;
+ ath_hal_printf(ah, "%s: called, cptr=0x%x, mdata_size=%d, blank=%d\n",
+ __func__, cptr, mdata_size, blank);
+
restored = 0;
for (it = 0; it < MSTATE; it++) {
(void) ar9300_calibration_data_read_array(
ah, cptr, word, compression_header_length);
+ ath_hal_printf(ah, "%s: word = 0x%x, 0x%x, 0x%x, 0x%x\n",
+ __func__,
+ word[0],
+ word[1],
+ word[2],
+ word[3]);
if (word[0] == blank && word[1] == blank && word[2] == blank && word[3] == blank)
{
- break;
+ ath_hal_printf(ah, "%s: word=blank, skipping\n", __func__);
+ cptr -= compression_header_length;
+ continue;
}
ar9300_compression_header_unpack(
word, &code, &reference, &length, &major, &minor);
@@ -4143,19 +4176,18 @@ static int
ar9300_eeprom_restore_from_dram(struct ath_hal *ah, ar9300_eeprom_t *mptr,
int mdata_size)
{
-#if 0
struct ath_hal_9300 *ahp = AH9300(ah);
char *cal_ptr;
-#endif
+#if 0
/* cal data in flash / DRAM isn't currently supported */
ath_hal_printf(ah, "%s: Cal data from DRAM isn't supported\n",
__func__);
return -1;
+#endif
#ifndef WIN32
-#if 0
HALASSERT(mdata_size > 0);
/* if cal_in_flash is true, the address sent by LMAC to HAL
@@ -4164,14 +4196,17 @@ ar9300_eeprom_restore_from_dram(struct ath_hal *ah, ar9300_eeprom_t *mptr,
if(ar9300_eep_data_in_flash(ah))
return -1;
+#if 0
/* check if LMAC sent DRAM address is valid */
if (!(uintptr_t)(AH_PRIVATE(ah)->ah_st)) {
return -1;
}
+#endif
/* When calibration data is from host, Host will copy the
compressed data to the predefined DRAM location saved at ah->ah_st */
ath_hal_printf(ah, "Restoring Cal data from DRAM\n");
+#if 0
#ifdef __NetBSD__
ahp->ah_cal_mem = OS_REMAP(ah, (uintptr_t)(AH_PRIVATE(ah)->ah_st),
HOST_CALDATA_SIZE);
@@ -4184,6 +4219,20 @@ ar9300_eeprom_restore_from_dram(struct ath_hal *ah, ar9300_eeprom_t *mptr,
HALDEBUG(ah, HAL_DEBUG_EEPROM,"%s: can't remap dram region\n", __func__);
return -1;
}
+#endif
+
+ /*
+ * The atheros HAL passes in this buffer anyway, and we copy things
+ * into it. However, the FreeBSD driver doesn't supply this
+ * particular memory. So, let's just assume attach/detach will
+ * provide us with a 16 kilobyte buffer for now, and hope the whole
+ * OTP path works.
+ */
+ if (! ahp->ah_cal_mem) {
+ ath_hal_printf(ah, "%s: FreeBSD: ah_cal_mem isn't set\n", __func__);
+ return -1;
+ }
+
cal_ptr = &((char *)(ahp->ah_cal_mem))[AR9300_FLASH_CAL_START_OFFSET];
OS_MEMCPY(mptr, cal_ptr, mdata_size);
@@ -4201,7 +4250,6 @@ ar9300_eeprom_restore_from_dram(struct ath_hal *ah, ar9300_eeprom_t *mptr,
}
return mdata_size;
-#endif
#else
return -1;
#endif
@@ -4290,6 +4338,11 @@ ar9300_eeprom_restore_from_flash(struct ath_hal *ah, ar9300_eeprom_t *mptr,
}
#endif
+ ath_hal_printf(ah, "%s: eeprom version=%d, template version=%d\n",
+ __func__,
+ (int) mptr->eeprom_version,
+ (int) mptr->template_version);
+
if (mptr->eeprom_version == 0xff ||
mptr->template_version == 0xff ||
mptr->eeprom_version == 0 ||
@@ -4321,10 +4374,11 @@ ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr,
nptr = -1;
- if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
+ if (0 && (AH9300(ah)->calibration_data_try == calibration_data_none ||
AH9300(ah)->calibration_data_try == calibration_data_dram) &&
AH9300(ah)->try_dram && nptr < 0)
{
+ ath_hal_printf(ah, "%s: trying dram\n", __func__);
AH9300(ah)->calibration_data_source = calibration_data_dram;
AH9300(ah)->calibration_data_source_address = 0;
nptr = ar9300_eeprom_restore_from_dram(ah, mptr, mdata_size);
@@ -4334,7 +4388,7 @@ ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr,
}
}
- if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
+ if (0 && (AH9300(ah)->calibration_data_try == calibration_data_none ||
AH9300(ah)->calibration_data_try == calibration_data_eeprom) &&
AH9300(ah)->try_eeprom && nptr < 0)
{
@@ -4343,6 +4397,7 @@ ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr,
* base_address=0x3ff where we used to write the data
*/
AH9300(ah)->calibration_data_source = calibration_data_eeprom;
+ ath_hal_printf(ah, "%s: trying eeprom\n", __func__);
if (AH9300(ah)->calibration_data_try_address != 0) {
AH9300(ah)->calibration_data_source_address =
AH9300(ah)->calibration_data_try_address;
@@ -4374,7 +4429,7 @@ ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr,
* ##### should be an ifdef test for any AP usage,
* either in driver or in nart
*/
- if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
+ if (0 && (AH9300(ah)->calibration_data_try == calibration_data_none ||
AH9300(ah)->calibration_data_try == calibration_data_flash) &&
AH9300(ah)->try_flash && nptr < 0)
{
@@ -4388,10 +4443,17 @@ ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr,
}
}
+ /* XXX FreeBSD? */
+ AH9300(ah)->calibration_data_try = calibration_data_otp;
+ AH9300(ah)->calibration_data_try_address = 0x2ff;
+
if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
AH9300(ah)->calibration_data_try == calibration_data_otp) &&
AH9300(ah)->try_otp && nptr < 0)
{
+ ath_hal_printf(ah, "%s: trying OTP, try_address=0x%x\n",
+ __func__,
+ AH9300(ah)->calibration_data_try_address);
AH9300(ah)->calibration_data_source = calibration_data_otp;
if (AH9300(ah)->calibration_data_try_address != 0) {
AH9300(ah)->calibration_data_source_address =
@@ -4526,6 +4588,8 @@ ar9300_eeprom_restore(struct ath_hal *ah)
int mdata_size;
HAL_BOOL status = AH_FALSE;
+ ath_hal_printf(ah, "%s: called\n", __func__);
+
mptr = &ahp->ah_eeprom;
mdata_size = ar9300_eeprom_struct_size();

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