diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2010-12-31 17:17:15 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2010-12-31 17:17:15 +0000 |
commit | 86475832be1dd5c523be9ae6c692d54867b08db6 (patch) | |
tree | 081566a2015b1631176bb60db4af2632e1bd917f /sys/dev | |
parent | f0f6a29566d2e88652c1e61ef67cd33426587c7c (diff) |
commit some bits that will be required by AR9271/AR7010
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/ar5008.c | 35 | ||||
-rw-r--r-- | sys/dev/ic/ar9285.c | 176 | ||||
-rw-r--r-- | sys/dev/ic/ar9285reg.h | 16 | ||||
-rw-r--r-- | sys/dev/ic/athn.c | 87 | ||||
-rw-r--r-- | sys/dev/ic/athnreg.h | 20 |
5 files changed, 259 insertions, 75 deletions
diff --git a/sys/dev/ic/ar5008.c b/sys/dev/ic/ar5008.c index 5e03a334897..7b3cce75aff 100644 --- a/sys/dev/ic/ar5008.c +++ b/sys/dev/ic/ar5008.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5008.c,v 1.15 2010/12/31 14:06:05 damien Exp $ */ +/* $OpenBSD: ar5008.c,v 1.16 2010/12/31 17:17:14 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -817,7 +817,7 @@ ar5008_rx_process(struct athn_softc *sc) ieee80211_michael_mic_failure(ic, 0); /* * XXX Check that it is not a control frame - * (invalid MIC failures on valid ctl frames.) + * (invalid MIC failures on valid ctl frames). */ } ifp->if_ierrors++; @@ -1492,7 +1492,7 @@ ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, ds->ds_ctl4 |= AR_TXC4_RTSCTS_QUAL01; ds->ds_ctl5 |= AR_TXC5_RTSCTS_QUAL23; } - /* Select protection rate (suboptimal but ok.) */ + /* Select protection rate (suboptimal but ok). */ protridx = (ic->ic_curmode == IEEE80211_MODE_11A) ? ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK2; if (ds->ds_ctl0 & AR_TXC0_RTS_ENABLE) { @@ -1515,7 +1515,7 @@ ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, ds->ds_ctl7 |= SM(AR_TXC7_RTSCTS_RATE, hwrate); } - /* Finalize first Tx descriptor and fill others (if any.) */ + /* Finalize first Tx descriptor and fill others (if any). */ ds->ds_ctl0 |= SM(AR_TXC0_FRAME_LEN, totlen); for (i = 0; i < bf->bf_map->dm_nsegs; i++, ds++) { @@ -1729,7 +1729,7 @@ ar5008_set_rxchains(struct athn_softc *sc) void ar5008_read_noisefloor(struct athn_softc *sc, int16_t *nf, int16_t *nf_ext) { -/* Sign-extends 9-bit value (assumes upper bits are zeroes.) */ +/* Sign-extends 9-bit value (assumes upper bits are zeroes). */ #define SIGN_EXT(v) (((v) ^ 0x100) - 0x100) uint32_t reg; int i; @@ -2149,7 +2149,7 @@ ar5008_set_viterbi_mask(struct athn_softc *sc, int bin) for (cur = -100; cur >= -6100; cur -= 100) m[-cur / 100] = abs(cur - bin) < 75; - /* Write viterbi mask (XXX needs to be reworked.) */ + /* Write viterbi mask (XXX needs to be reworked). */ reg = m[46] << 30 | m[47] << 28 | m[48] << 26 | m[49] << 24 | m[50] << 22 | m[51] << 20 | m[52] << 18 | m[53] << 16 | @@ -2221,6 +2221,7 @@ ar5008_hw_init(struct athn_softc *sc, struct ieee80211_channel *c, struct athn_ops *ops = &sc->ops; const struct athn_ini *ini = sc->ini; const uint32_t *pvals; + uint32_t reg; int i; AR_WRITE(sc, AR_PHY(0), 0x00000007); @@ -2312,13 +2313,15 @@ ar5008_hw_init(struct athn_softc *sc, struct ieee80211_channel *c, AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT); /* Hardware workarounds for occasional Rx data corruption. */ - if (AR_SREV_9287_10_OR_LATER(sc)) - AR_CLRBITS(sc, AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_HWWAR1); - else if (AR_SREV_9280_10_OR_LATER(sc)) - AR_CLRBITS(sc, AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_HWWAR1 | - AR_PCU_MISC_MODE2_HWWAR2); - - if (AR_SREV_5416_20_OR_LATER(sc) && !AR_SREV_9280_10_OR_LATER(sc)) { + if (AR_SREV_9280_10_OR_LATER(sc)) { + reg = AR_READ(sc, AR_PCU_MISC_MODE2); + if (!AR_SREV_9271(sc)) + reg &= ~AR_PCU_MISC_MODE2_HWWAR1; + if (AR_SREV_9287_10_OR_LATER(sc)) + reg &= ~AR_PCU_MISC_MODE2_HWWAR2; + AR_WRITE(sc, AR_PCU_MISC_MODE2, reg); + + } else if (AR_SREV_5416_20_OR_LATER(sc)) { /* Disable baseband clock gating. */ AR_WRITE(sc, AR_PHY(651), 0x11); @@ -2397,7 +2400,7 @@ ar5008_get_pdadcs(struct athn_softc *sc, uint8_t fbin, boundaries[i] = AR_MAX_RATE_POWER; if (i == 0 && !AR_SREV_5416_20_OR_LATER(sc)) { - /* Fix the gain delta (AR5416 1.0 only.) */ + /* Fix the gain delta (AR5416 1.0 only). */ delta = boundaries[0] - 23; boundaries[0] = 23; } else @@ -2483,7 +2486,7 @@ ar5008_get_lg_tpow(struct athn_softc *sc, struct ieee80211_channel *c, uint8_t fbin; int i, lo, hi; - /* Find interval (lower and upper indices.) */ + /* Find interval (lower and upper indices). */ fbin = athn_chan2fbin(c); for (i = 0; i < nchans; i++) { if (tgt[i].bChannel == AR_BCHAN_UNUSED || @@ -2515,7 +2518,7 @@ ar5008_get_ht_tpow(struct athn_softc *sc, struct ieee80211_channel *c, uint8_t fbin; int i, lo, hi; - /* Find interval (lower and upper indices.) */ + /* Find interval (lower and upper indices). */ fbin = athn_chan2fbin(c); for (i = 0; i < nchans; i++) { if (tgt[i].bChannel == AR_BCHAN_UNUSED || diff --git a/sys/dev/ic/ar9285.c b/sys/dev/ic/ar9285.c index f9085b432a6..73c13740265 100644 --- a/sys/dev/ic/ar9285.c +++ b/sys/dev/ic/ar9285.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar9285.c,v 1.13 2010/12/31 14:06:05 damien Exp $ */ +/* $OpenBSD: ar9285.c,v 1.14 2010/12/31 17:17:14 damien Exp $ */ /*- * Copyright (c) 2009-2010 Damien Bergamini <damien.bergamini@free.fr> @@ -73,8 +73,10 @@ const struct ar_spur_chan *ar9285_get_spur_chans(struct athn_softc *, int); void ar9285_init_from_rom(struct athn_softc *, struct ieee80211_channel *, struct ieee80211_channel *); void ar9285_pa_calib(struct athn_softc *); +void ar9271_pa_calib(struct athn_softc *); int ar9285_cl_cal(struct athn_softc *, struct ieee80211_channel *, struct ieee80211_channel *); +void ar9271_load_ani(struct athn_softc *); int ar9285_init_calib(struct athn_softc *, struct ieee80211_channel *, struct ieee80211_channel *); void ar9285_get_pdadcs(struct athn_softc *, struct ieee80211_channel *, @@ -132,7 +134,12 @@ ar9285_setup(struct athn_softc *sc) /* Select initialization values based on ROM. */ type = eep->baseEepHeader.txGainType; DPRINTF(("Tx gain type=0x%x\n", type)); - if ((AR_READ(sc, AR_AN_SYNTH9) & 0x7) == 0x1) { /* XE rev. */ + if (AR_SREV_9271(sc)) { + if (type == AR_EEP_TXGAIN_HIGH_POWER) + sc->tx_gain = &ar9271_tx_gain_high_power; + else + sc->tx_gain = &ar9271_tx_gain; + } else if ((AR_READ(sc, AR_AN_SYNTH9) & 0x7) == 0x1) { /* XE rev. */ if (type == AR_EEP_TXGAIN_HIGH_POWER) sc->tx_gain = &ar9285_2_0_tx_gain_high_power; else @@ -299,29 +306,45 @@ ar9285_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c, db2[0] = modal->db1_01; db2[1] = db2[2] = db2[3] = db2[4] = db2[0]; } - reg = AR_READ(sc, AR9285_AN_RF2G3); - reg = RW(reg, AR9285_AN_RF2G3_OB_0, ob [0]); - reg = RW(reg, AR9285_AN_RF2G3_OB_1, ob [1]); - reg = RW(reg, AR9285_AN_RF2G3_OB_2, ob [2]); - reg = RW(reg, AR9285_AN_RF2G3_OB_3, ob [3]); - reg = RW(reg, AR9285_AN_RF2G3_OB_4, ob [4]); - reg = RW(reg, AR9285_AN_RF2G3_DB1_0, db1[0]); - reg = RW(reg, AR9285_AN_RF2G3_DB1_1, db1[1]); - reg = RW(reg, AR9285_AN_RF2G3_DB1_2, db1[2]); - AR_WRITE(sc, AR9285_AN_RF2G3, reg); - AR_WRITE_BARRIER(sc); - DELAY(100); - reg = AR_READ(sc, AR9285_AN_RF2G4); - reg = RW(reg, AR9285_AN_RF2G4_DB1_3, db1[3]); - reg = RW(reg, AR9285_AN_RF2G4_DB1_4, db1[4]); - reg = RW(reg, AR9285_AN_RF2G4_DB2_0, db2[0]); - reg = RW(reg, AR9285_AN_RF2G4_DB2_1, db2[1]); - reg = RW(reg, AR9285_AN_RF2G4_DB2_2, db2[2]); - reg = RW(reg, AR9285_AN_RF2G4_DB2_3, db2[3]); - reg = RW(reg, AR9285_AN_RF2G4_DB2_4, db2[4]); - AR_WRITE(sc, AR9285_AN_RF2G4, reg); - AR_WRITE_BARRIER(sc); - DELAY(100); + if (AR_SREV_9271(sc)) { + reg = AR_READ(sc, AR9285_AN_RF2G3); + reg = RW(reg, AR9271_AN_RF2G3_OB_CCK, ob [0]); + reg = RW(reg, AR9271_AN_RF2G3_OB_PSK, ob [1]); + reg = RW(reg, AR9271_AN_RF2G3_OB_QAM, ob [2]); + reg = RW(reg, AR9271_AN_RF2G3_DB1, db1[0]); + AR_WRITE(sc, AR9285_AN_RF2G3, reg); + AR_WRITE_BARRIER(sc); + DELAY(100); + reg = AR_READ(sc, AR9285_AN_RF2G4); + reg = RW(reg, AR9271_AN_RF2G4_DB2, db2[0]); + AR_WRITE(sc, AR9285_AN_RF2G4, reg); + AR_WRITE_BARRIER(sc); + DELAY(100); + } else { + reg = AR_READ(sc, AR9285_AN_RF2G3); + reg = RW(reg, AR9285_AN_RF2G3_OB_0, ob [0]); + reg = RW(reg, AR9285_AN_RF2G3_OB_1, ob [1]); + reg = RW(reg, AR9285_AN_RF2G3_OB_2, ob [2]); + reg = RW(reg, AR9285_AN_RF2G3_OB_3, ob [3]); + reg = RW(reg, AR9285_AN_RF2G3_OB_4, ob [4]); + reg = RW(reg, AR9285_AN_RF2G3_DB1_0, db1[0]); + reg = RW(reg, AR9285_AN_RF2G3_DB1_1, db1[1]); + reg = RW(reg, AR9285_AN_RF2G3_DB1_2, db1[2]); + AR_WRITE(sc, AR9285_AN_RF2G3, reg); + AR_WRITE_BARRIER(sc); + DELAY(100); + reg = AR_READ(sc, AR9285_AN_RF2G4); + reg = RW(reg, AR9285_AN_RF2G4_DB1_3, db1[3]); + reg = RW(reg, AR9285_AN_RF2G4_DB1_4, db1[4]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_0, db2[0]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_1, db2[1]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_2, db2[2]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_3, db2[3]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_4, db2[4]); + AR_WRITE(sc, AR9285_AN_RF2G4, reg); + AR_WRITE_BARRIER(sc); + DELAY(100); + } reg = AR_READ(sc, AR_PHY_SETTLING); reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling); @@ -431,7 +454,6 @@ ar9285_pa_calib(struct athn_softc *sc) AR_CLRBITS(sc, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS_6_1); /* Clear offset 0. */ AR_CLRBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP); - /* Set offsets 6-1. */ for (i = 6; i >= 1; i--) { AR_SETBITS(sc, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS(i)); @@ -454,6 +476,8 @@ ar9285_pa_calib(struct athn_softc *sc) else AR_CLRBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP); + AR_WRITE_BARRIER(sc); + AR_SETBITS(sc, AR9285_AN_RF2G6, 1); AR_CLRBITS(sc, AR_PHY(2), 1 << 27); @@ -468,6 +492,91 @@ ar9285_pa_calib(struct athn_softc *sc) AR_WRITE_BARRIER(sc); } +void +ar9271_pa_calib(struct athn_softc *sc) +{ + /* List of registers that need to be saved/restored. */ + static const uint16_t regs[] = { + AR9285_AN_TOP3, + AR9285_AN_RXTXBB1, + AR9285_AN_RF2G1, + AR9285_AN_RF2G2, + AR9285_AN_TOP2, + AR9285_AN_RF2G8, + AR9285_AN_RF2G7 + }; + uint32_t svg[7], reg, ccomp_svg; + int i; + + /* Save registers. */ + for (i = 0; i < nitems(regs); i++) + svg[i] = AR_READ(sc, regs[i]); + + AR_CLRBITS(sc, AR9285_AN_RF2G6, 1); + AR_SETBITS(sc, AR_PHY(2), 1 << 27); + + AR_SETBITS(sc, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC); + AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1); + AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I); + AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF); + AR_CLRBITS(sc, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL); + AR_CLRBITS(sc, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB); + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL); + /* Power down PA drivers. */ + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1); + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2); + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT); + + reg = AR_READ(sc, AR9285_AN_RF2G8); + reg = RW(reg, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); + AR_WRITE(sc, AR9285_AN_RF2G8, reg); + + reg = AR_READ(sc, AR9285_AN_RF2G7); + reg = RW(reg, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); + AR_WRITE(sc, AR9285_AN_RF2G7, reg); + + reg = AR_READ(sc, AR9285_AN_RF2G3); + /* Save compensation capacitor value. */ + ccomp_svg = MS(reg, AR9271_AN_RF2G3_CCOMP); + /* Program compensation capacitor for dynamic PA. */ + reg = RW(reg, AR9271_AN_RF2G3_CCOMP, 0xfff); + AR_WRITE(sc, AR9285_AN_RF2G3, reg); + + AR_WRITE(sc, AR9285_AN_TOP2, AR9285_AN_TOP2_DEFAULT); + AR_WRITE_BARRIER(sc); + DELAY(30); + + /* Clear offsets 6-0. */ + AR_CLRBITS(sc, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS_6_0); + /* Set offsets 6-1. */ + for (i = 6; i >= 1; i--) { + AR_SETBITS(sc, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS(i)); + AR_WRITE_BARRIER(sc); + DELAY(1); + if (AR_READ(sc, AR9285_AN_RF2G9) & AR9285_AN_RXTXBB1_SPARE9) { + AR_SETBITS(sc, AR9285_AN_RF2G6, + AR9271_AN_RF2G6_OFFS(i)); + } else { + AR_CLRBITS(sc, AR9285_AN_RF2G6, + AR9271_AN_RF2G6_OFFS(i)); + } + } + AR_WRITE_BARRIER(sc); + + AR_SETBITS(sc, AR9285_AN_RF2G6, 1); + AR_CLRBITS(sc, AR_PHY(2), 1 << 27); + + /* Restore registers. */ + for (i = 0; i < nitems(regs); i++) + AR_WRITE(sc, regs[i], svg[i]); + + /* Restore compensation capacitor value. */ + reg = AR_READ(sc, AR9285_AN_RF2G3); + reg = RW(reg, AR9271_AN_RF2G3_CCOMP, ccomp_svg); + AR_WRITE(sc, AR9285_AN_RF2G3, reg); + AR_WRITE_BARRIER(sc); +} + /* * Carrier Leakage Calibration. */ @@ -518,6 +627,21 @@ ar9285_cl_cal(struct athn_softc *sc, struct ieee80211_channel *c, return (0); } +void +ar9271_load_ani(struct athn_softc *sc) +{ + /* Write ANI registers. */ + AR_WRITE(sc, AR_PHY_DESIRED_SZ, 0x6d4000e2); + AR_WRITE(sc, AR_PHY_AGC_CTL1, 0x3139605e); + AR_WRITE(sc, AR_PHY_FIND_SIG, 0x7ec84d2e); + AR_WRITE(sc, AR_PHY_SFCORR_LOW, 0x06903881); + AR_WRITE(sc, AR_PHY_SFCORR, 0x5ac640d0); + AR_WRITE(sc, AR_PHY_CCK_DETECT, 0x803e68c8); + AR_WRITE(sc, AR_PHY_TIMING5, 0xd00a8007); + AR_WRITE(sc, AR_PHY_SFCORR_EXT, 0x05eea6d4); + AR_WRITE_BARRIER(sc); +} + int ar9285_init_calib(struct athn_softc *sc, struct ieee80211_channel *c, struct ieee80211_channel *extc) diff --git a/sys/dev/ic/ar9285reg.h b/sys/dev/ic/ar9285reg.h index a4880937327..a7bc6bf5615 100644 --- a/sys/dev/ic/ar9285reg.h +++ b/sys/dev/ic/ar9285reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ar9285reg.h,v 1.5 2010/12/31 14:37:15 damien Exp $ */ +/* $OpenBSD: ar9285reg.h,v 1.6 2010/12/31 17:17:14 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -67,6 +67,16 @@ #define AR9285_AN_RF2G3_OB_0_M 0x00e00000 #define AR9285_AN_RF2G3_OB_0_S 21 #define AR9285_AN_RF2G3_PDVCCOMP 0x02000000 +#define AR9271_AN_RF2G3_CCOMP_M 0x00000fff +#define AR9271_AN_RF2G3_CCOMP_S 0 +#define AR9271_AN_RF2G3_OB_QAM_M 0x00007000 +#define AR9271_AN_RF2G3_OB_QAM_S 12 +#define AR9271_AN_RF2G3_OB_PSK_M 0x00038000 +#define AR9271_AN_RF2G3_OB_PSK_S 15 +#define AR9271_AN_RF2G3_OB_CCK_M 0x001c0000 +#define AR9271_AN_RF2G3_OB_CCK_S 18 +#define AR9271_AN_RF2G3_DB1_M 0x00e00000 +#define AR9271_AN_RF2G3_DB1_S 21 /* Bits for AR9285_AN_RF2G4. */ #define AR9285_AN_RF2G4_DB2_4_M 0x00003800 @@ -83,6 +93,8 @@ #define AR9285_AN_RF2G4_DB1_4_S 26 #define AR9285_AN_RF2G4_DB1_3_M 0xe0000000 #define AR9285_AN_RF2G4_DB1_3_S 29 +#define AR9271_AN_RF2G4_DB2_M 0xe0000000 +#define AR9271_AN_RF2G4_DB2_S 29 /* Bits for AR9285_AN_RF2G5. */ #define AR9285_AN_RF2G5_IC50TX_M 0x00000700 @@ -93,6 +105,8 @@ #define AR9285_AN_RF2G6_CCOMP_S 11 #define AR9285_AN_RF2G6_OFFS_6_1 0x03f00000 #define AR9285_AN_RF2G6_OFFS(i) (1 << (19 + (i))) +#define AR9271_AN_RF2G6_OFFS_6_0 0x07f00000 +#define AR9271_AN_RF2G6_OFFS(i) (1 << (20 + (i))) /* Bits for AR9285_AN_RF2G7. */ #define AR9285_AN_RF2G7_PWDDB 0x00000002 diff --git a/sys/dev/ic/athn.c b/sys/dev/ic/athn.c index e05ea581614..3f42e96d79d 100644 --- a/sys/dev/ic/athn.c +++ b/sys/dev/ic/athn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: athn.c,v 1.65 2010/12/31 14:52:47 damien Exp $ */ +/* $OpenBSD: athn.c,v 1.66 2010/12/31 17:17:14 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -151,12 +151,14 @@ int ar9280_attach(struct athn_softc *); int ar9285_attach(struct athn_softc *); int ar9287_attach(struct athn_softc *); int ar9380_attach(struct athn_softc *); +void ar9271_load_ani(struct athn_softc *); int ar5416_init_calib(struct athn_softc *, struct ieee80211_channel *, struct ieee80211_channel *); int ar9285_init_calib(struct athn_softc *, struct ieee80211_channel *, struct ieee80211_channel *); int ar9003_init_calib(struct athn_softc *); void ar9285_pa_calib(struct athn_softc *); +void ar9271_pa_calib(struct athn_softc *); void ar9287_1_3_enable_async_fifo(struct athn_softc *); void ar9287_1_3_setup_async_fifo(struct athn_softc *); void ar9003_reset_txsring(struct athn_softc *); @@ -186,11 +188,11 @@ athn_attach(struct athn_softc *sc) error = ar5416_attach(sc); else if (AR_SREV_9280(sc)) error = ar9280_attach(sc); - else if (AR_SREV_9285(sc)) + else if (AR_SREV_9285(sc) || AR_SREV_9271(sc)) error = ar9285_attach(sc); else if (AR_SREV_9287(sc)) error = ar9287_attach(sc); - else if (AR_SREV_9380(sc)) + else if (AR_SREV_9380(sc) || AR_SREV_9485(sc)) error = ar9380_attach(sc); else error = ENOTSUP; @@ -202,15 +204,17 @@ athn_attach(struct athn_softc *sc) /* We can put the chip in sleep state now. */ athn_set_power_sleep(sc); - error = sc->ops.dma_alloc(sc); - if (error != 0) { - printf("%s: could not allocate DMA resources\n", - sc->sc_dev.dv_xname); - return (error); + if (!(sc->flags & ATHN_FLAG_USB)) { + error = sc->ops.dma_alloc(sc); + if (error != 0) { + printf("%s: could not allocate DMA resources\n", + sc->sc_dev.dv_xname); + return (error); + } + /* Steal one Tx buffer for beacons. */ + sc->bcnbuf = SIMPLEQ_FIRST(&sc->txbufs); + SIMPLEQ_REMOVE_HEAD(&sc->txbufs, bf_list); } - /* Steal one Tx buffer for beacons. */ - sc->bcnbuf = SIMPLEQ_FIRST(&sc->txbufs); - SIMPLEQ_REMOVE_HEAD(&sc->txbufs, bf_list); if (sc->flags & ATHN_FLAG_RFSILENT) { DPRINTF(("found RF switch connected to GPIO pin %d\n", @@ -286,7 +290,7 @@ athn_attach(struct athn_softc *sc) IEEE80211_HTCAP_CBW20_40 | IEEE80211_HTCAP_SGI40 | IEEE80211_HTCAP_DSSSCCK40; - if (AR_SREV_9287_10_OR_LATER(sc)) + if (AR_SREV_9271(sc) || AR_SREV_9287_10_OR_LATER(sc)) ic->ic_htcaps |= IEEE80211_HTCAP_SGI20; if (AR_SREV_9380_10_OR_LATER(sc)) ic->ic_htcaps |= IEEE80211_HTCAP_LDPC; @@ -371,12 +375,13 @@ athn_detach(struct athn_softc *sc) timeout_del(&sc->scan_to); timeout_del(&sc->calib_to); - for (qid = 0; qid < ATHN_QID_COUNT; qid++) - athn_tx_reclaim(sc, qid); - - /* Free Tx/Rx DMA resources. */ - sc->ops.dma_free(sc); + if (!(sc->flags & ATHN_FLAG_USB)) { + for (qid = 0; qid < ATHN_QID_COUNT; qid++) + athn_tx_reclaim(sc, qid); + /* Free Tx/Rx DMA resources. */ + sc->ops.dma_free(sc); + } /* Free ROM copy. */ if (sc->eep != NULL) free(sc->eep, M_DEVBUF); @@ -555,16 +560,20 @@ athn_get_mac_name(struct athn_softc *sc) return ("AR9280"); case AR_SREV_VERSION_9285: return ("AR9285"); + case AR_SREV_VERSION_9271: + return ("AR9271"); case AR_SREV_VERSION_9287: return ("AR9287"); case AR_SREV_VERSION_9380: return ("AR9380"); + case AR_SREV_VERSION_9485: + return ("AR9485"); } return ("unknown"); } /* - * Return RF chip name (not for single-chip solutions.) + * Return RF chip name (not for single-chip solutions). */ const char * athn_get_rf_name(struct athn_softc *sc) @@ -708,7 +717,7 @@ athn_set_power_sleep(struct athn_softc *sc) * NB: Clearing RTC_RESET_EN when setting the chip to sleep mode * results in high power consumption on AR5416 chipsets. */ - if (!AR_SREV_5416(sc)) + if (!AR_SREV_5416(sc) && !AR_SREV_9271(sc)) AR_CLRBITS(sc, AR_RTC_RESET, AR_RTC_RESET_EN); AR_WRITE_BARRIER(sc); } @@ -719,6 +728,8 @@ athn_init_pll(struct athn_softc *sc, const struct ieee80211_channel *c) uint32_t pll; if (AR_SREV_9380_10_OR_LATER(sc)) { + if (AR_SREV_9485(sc)) + AR_WRITE(sc, AR_RTC_PLL_CONTROL2, 0x886666); pll = SM(AR_RTC_9160_PLL_REFDIV, 0x5); pll |= SM(AR_RTC_9160_PLL_DIV, 0x2c); } else if (AR_SREV_9280_10_OR_LATER(sc)) { @@ -747,6 +758,12 @@ athn_init_pll(struct athn_softc *sc, const struct ieee80211_channel *c) } DPRINTFN(5, ("AR_RTC_PLL_CONTROL=0x%08x\n", pll)); AR_WRITE(sc, AR_RTC_PLL_CONTROL, pll); + if (AR_SREV_9271(sc)) { + /* Switch core clock to 117MHz. */ + AR_WRITE_BARRIER(sc); + DELAY(500); + AR_WRITE(sc, 0x50050, 0x304); + } AR_WRITE_BARRIER(sc); DELAY(100); AR_WRITE(sc, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); @@ -856,8 +873,10 @@ athn_switch_chan(struct athn_softc *sc, struct ieee80211_channel *c, if (error != 0) goto reset; - /* AR9280 always needs a full reset. */ -/* if (AR_SREV_9280(sc))*/ +#ifdef notyet + /* AR9280 (but not AR9280+AR7010) needs a full reset. */ + if (AR_SREV_9280(sc) && !(sc->flags & ATHN_FLAG_USB)) +#endif goto reset; /* If band or bandwidth changes, we need to do a full reset. */ @@ -871,6 +890,8 @@ athn_switch_chan(struct athn_softc *sc, struct ieee80211_channel *c, goto reset; error = athn_set_chan(sc, c, extc); + if (AR_SREV_9271(sc) && error == 0) + ar9271_load_ani(sc); if (error != 0) { reset: /* Error found, try a full reset. */ DPRINTFN(3, ("needs a full reset\n")); @@ -1175,7 +1196,10 @@ athn_calib_to(void *arg) !AR_SREV_9380_10_OR_LATER(sc) && ticks >= sc->pa_calib_ticks + 240 * hz) { sc->pa_calib_ticks = ticks; - ar9285_pa_calib(sc); + if (AR_SREV_9271(sc)) + ar9271_pa_calib(sc); + else + ar9285_pa_calib(sc); } /* Do periodic (every 30 seconds) temperature compensation. */ @@ -1222,7 +1246,10 @@ athn_init_calib(struct athn_softc *sc, struct ieee80211_channel *c, if (AR_SREV_9285_11_OR_LATER(sc)) { extern int ticks; sc->pa_calib_ticks = ticks; - ar9285_pa_calib(sc); + if (AR_SREV_9271(sc)) + ar9271_pa_calib(sc); + else + ar9285_pa_calib(sc); } /* Do noisefloor calibration. */ ops->noisefloor_calib(sc); @@ -1569,7 +1596,7 @@ athn_init_dma(struct athn_softc *sc) reg = RW(reg, AR_TXCFG_DMASZ, AR_DMASZ_128B); /* Set initial Tx trigger level. */ - if (AR_SREV_9285(sc)) + if (AR_SREV_9285(sc) || AR_SREV_9271(sc)) reg = RW(reg, AR_TXCFG_FTRIG, AR_TXCFG_FTRIG_256B); else if (!AR_SREV_9380_10_OR_LATER(sc)) reg = RW(reg, AR_TXCFG_FTRIG, AR_TXCFG_FTRIG_512B); @@ -1584,9 +1611,13 @@ athn_init_dma(struct athn_softc *sc) AR_WRITE(sc, AR_RXFIFO_CFG, 512); /* Reduce the number of entries in PCU TXBUF to avoid wrap around. */ - AR_WRITE(sc, AR_PCU_TXBUF_CTRL, AR_SREV_9285(sc) ? - AR9285_PCU_TXBUF_CTRL_USABLE_SIZE : - AR_PCU_TXBUF_CTRL_USABLE_SIZE); + if (AR_SREV_9285(sc)) { + AR_WRITE(sc, AR_PCU_TXBUF_CTRL, + AR9285_PCU_TXBUF_CTRL_USABLE_SIZE); + } else if (!AR_SREV_9271(sc)) { + AR_WRITE(sc, AR_PCU_TXBUF_CTRL, + AR_PCU_TXBUF_CTRL_USABLE_SIZE); + } AR_WRITE_BARRIER(sc); /* Reset Tx status ring. */ @@ -2741,7 +2772,7 @@ athn_stop(struct ifnet *ifp, int disable) /* Disable interrupts. */ athn_disable_interrupts(sc); - /* Acknowledge interrupts (avoids interrupt storms.) */ + /* Acknowledge interrupts (avoids interrupt storms). */ AR_WRITE(sc, AR_INTR_SYNC_CAUSE, 0xffffffff); AR_WRITE(sc, AR_INTR_SYNC_MASK, 0); diff --git a/sys/dev/ic/athnreg.h b/sys/dev/ic/athnreg.h index edfa1fd2644..7d7b14a5258 100644 --- a/sys/dev/ic/athnreg.h +++ b/sys/dev/ic/athnreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: athnreg.h,v 1.14 2010/12/31 14:06:05 damien Exp $ */ +/* $OpenBSD: athnreg.h,v 1.15 2010/12/31 17:17:14 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -116,6 +116,7 @@ #define AR_RTC_REG_CONTROL0 0x7008 #define AR_RTC_REG_CONTROL1 0x700c #define AR_RTC_PLL_CONTROL 0x7014 +#define AR_RTC_PLL_CONTROL2 0x703c #define AR_RTC_RESET 0x7040 #define AR_RTC_STATUS 0x7044 #define AR_RTC_SLEEP_CLK 0x7048 @@ -775,6 +776,9 @@ #define AR_SREV_REVISION_9285_10 0 #define AR_SREV_REVISION_9285_11 1 #define AR_SREV_REVISION_9285_12 2 +#define AR_SREV_VERSION_9271 0x140 +#define AR_SREV_REVISION_9271_10 0 +#define AR_SREV_REVISION_9271_11 1 #define AR_SREV_VERSION_9287 0x180 #define AR_SREV_REVISION_9287_10 0 #define AR_SREV_REVISION_9287_11 1 @@ -783,6 +787,8 @@ #define AR_SREV_VERSION_9380 0x1c0 #define AR_SREV_REVISION_9380_10 0 #define AR_SREV_REVISION_9380_20 2 +#define AR_SREV_VERSION_9485 0x240 +#define AR_SREV_REVISION_9485_10 0 /* Bits for AR_AHB_MODE. */ #define AR_AHB_EXACT_WR_EN 0x00000000 @@ -1354,6 +1360,9 @@ ((sc)->mac_ver > AR_SREV_VERSION_9285 || \ (AR_SREV_9285(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9285_12)) +#define AR_SREV_9271(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9271) + #define AR_SREV_9287(sc) \ ((sc)->mac_ver == AR_SREV_VERSION_9287) #define AR_SREV_9287_10_OR_LATER(sc) \ @@ -1388,6 +1397,9 @@ ((sc)->mac_ver > AR_SREV_VERSION_9380 || \ (AR_SREV_9380(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9380_20)) +#define AR_SREV_9485(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9485) + #define AR_SINGLE_CHIP(sc) AR_SREV_9280_10_OR_LATER(sc) #define AR_RADIO_SREV_MAJOR 0xf0 @@ -1440,13 +1452,13 @@ static const uint32_t ar_nonpcie_serdes[] = { * Macros to access registers. */ #define AR_READ(sc, reg) \ - sc->ops.read((sc), (reg)) + (sc)->ops.read((sc), (reg)) #define AR_WRITE(sc, reg, val) \ - sc->ops.write((sc), (reg), (val)) + (sc)->ops.write((sc), (reg), (val)) #define AR_WRITE_BARRIER(sc) \ - sc->ops.write_barrier((sc)) + (sc)->ops.write_barrier((sc)) #define AR_SETBITS(sc, reg, mask) \ AR_WRITE(sc, reg, AR_READ(sc, reg) | (mask)) |