From 73b25af4f81c0b4cad7f80f28a17c1f17cbd2bb9 Mon Sep 17 00:00:00 2001 From: Damien Bergamini Date: Tue, 11 May 2010 19:34:21 +0000 Subject: enable fast PLL clock for 5GHz on AR9280 >=2.0 (unless EEPROM says the opposite) and on AR9380 2.0. tested on my AR9280 2.1 with a NETGEAR WNHDE111 AP. --- sys/dev/ic/ar5008.c | 24 ++++++++++++++++++++++-- sys/dev/ic/ar9003.c | 34 +++++++++++++++++++++++++++++----- sys/dev/ic/ar9280reg.h | 32 +++++++++++++++++++++++++++++--- sys/dev/ic/ar9380.c | 5 ++++- sys/dev/ic/ar9380reg.h | 27 +++++++++++++++++++++++++-- sys/dev/ic/athn.c | 19 ++++++++----------- sys/dev/ic/athnvar.h | 8 +++++++- 7 files changed, 124 insertions(+), 25 deletions(-) (limited to 'sys/dev/ic') diff --git a/sys/dev/ic/ar5008.c b/sys/dev/ic/ar5008.c index d7651f9b1bb..a92f7be528a 100644 --- a/sys/dev/ic/ar5008.c +++ b/sys/dev/ic/ar5008.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5008.c,v 1.1 2010/05/10 17:44:21 damien Exp $ */ +/* $OpenBSD: ar5008.c,v 1.2 2010/05/11 19:34:20 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini @@ -1455,7 +1455,8 @@ ar5008_set_rf_mode(struct athn_softc *sc, struct ieee80211_channel *c) if (!AR_SREV_9280_10_OR_LATER(sc)) { reg |= IEEE80211_IS_CHAN_2GHZ(c) ? AR_PHY_MODE_RF2GHZ : AR_PHY_MODE_RF5GHZ; - } else if (AR_SREV_9280_20(sc) && 0 /* XXX */) { + } else if (IEEE80211_IS_CHAN_5GHZ(c) && + (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) { reg |= AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE; } AR_WRITE(sc, AR_PHY_MODE, reg); @@ -2121,6 +2122,25 @@ ar5008_hw_init(struct athn_softc *sc, struct ieee80211_channel *c, if (!AR_SINGLE_CHIP(sc)) ar5416_reset_bb_gain(sc, c); + if (IEEE80211_IS_CHAN_5GHZ(c) && + (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) { + /* Update modal values for fast PLL clock. */ +#ifndef IEEE80211_NO_HT + if (extc != NULL) + pvals = ini->fastvals_5g40; + else +#endif + pvals = ini->fastvals_5g20; + DPRINTFN(4, ("writing fast pll clock init vals\n")); + for (i = 0; i < ini->nfastregs; i++) { + AR_WRITE(sc, ini->fastregs[i], pvals[i]); + if (AR_IS_ANALOG_REG(ini->fastregs[i])) + DELAY(100); + if ((i & 0x1f) == 0) + DELAY(1); + } + } + /* * Set the RX_ABORT and RX_DIS bits to prevent frames with corrupted * descriptor status. diff --git a/sys/dev/ic/ar9003.c b/sys/dev/ic/ar9003.c index 5c9edc7dad5..5c98e37b452 100644 --- a/sys/dev/ic/ar9003.c +++ b/sys/dev/ic/ar9003.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar9003.c,v 1.3 2010/05/11 18:13:37 damien Exp $ */ +/* $OpenBSD: ar9003.c,v 1.4 2010/05/11 19:34:20 damien Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -1464,10 +1464,15 @@ ar9003_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) void ar9003_set_rf_mode(struct athn_softc *sc, struct ieee80211_channel *c) { - if (IEEE80211_IS_CHAN_2GHZ(c)) - AR_WRITE(sc, AR_PHY_MODE, AR_PHY_MODE_DYNAMIC); - else - AR_WRITE(sc, AR_PHY_MODE, AR_PHY_MODE_OFDM); + uint32_t reg; + + reg = IEEE80211_IS_CHAN_2GHZ(c) ? + AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; + if (IEEE80211_IS_CHAN_5GHZ(c) && + (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) { + reg |= AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE; + } + AR_WRITE(sc, AR_PHY_MODE, reg); } static __inline uint32_t @@ -2216,6 +2221,25 @@ ar9003_hw_init(struct athn_softc *sc, struct ieee80211_channel *c, if (sc->tx_gain != NULL) ar9003_reset_tx_gain(sc, c); + if (IEEE80211_IS_CHAN_5GHZ(c) && + (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) { + /* Update modal values for fast PLL clock. */ +#ifndef IEEE80211_NO_HT + if (extc != NULL) + pvals = ini->fastvals_5g40; + else +#endif + pvals = ini->fastvals_5g20; + DPRINTFN(4, ("writing fast pll clock init vals\n")); + for (i = 0; i < ini->nfastregs; i++) { + AR_WRITE(sc, X(ini->fastregs[i]), pvals[i]); + if (AR_IS_ANALOG_REG(X(ini->fastregs[i]))) + DELAY(100); + if ((i & 0x1f) == 0) + DELAY(1); + } + } + /* * Set the RX_ABORT and RX_DIS bits to prevent frames with corrupted * descriptor status. diff --git a/sys/dev/ic/ar9280reg.h b/sys/dev/ic/ar9280reg.h index fe7d03a828f..61e9254b0e2 100644 --- a/sys/dev/ic/ar9280reg.h +++ b/sys/dev/ic/ar9280reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ar9280reg.h,v 1.1 2009/11/14 16:55:11 damien Exp $ */ +/* $OpenBSD: ar9280reg.h,v 1.2 2010/05/11 19:34:20 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini @@ -595,7 +595,7 @@ static const uint32_t ar9280_2_0_cm_vals[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00100000, 0x0010f400, 0x00000100, 0x0001e800, 0x00000000, 0x00000000, 0x00000000, 0x400000ff, 0x00080922, - 0xa8a00010, 0x00000000, 0x40000000, 0x003e4180, 0x00000000, + 0x88a00010, 0x00000000, 0x40000000, 0x003e4180, 0x00000000, 0x0000002c, 0x0000002c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000007, 0x00000302, 0x00000e00, 0x00ff0000, 0x00000000, 0x000107ff, @@ -630,6 +630,26 @@ static const uint32_t ar9280_2_0_cm_vals[] = { 0xffeffffe, 0xffeffffe, 0x00010000, 0x02060aeb, 0x2a850160 }; +static const uint16_t ar9280_2_0_fast_clock_regs[] = { + P(0x01030), P(0x01070), P(0x010b0), P(0x08014), P(0x0801c), + P(0x08318), P(0x09820), P(0x09824), P(0x09828), P(0x09834), + P(0x09844), P(0x09914), P(0x09918) +}; + +static const uint32_t ar9280_2_0_fast_clock_vals_5g20[] = { + 0x00000268, 0x0000018c, 0x00000fd0, 0x044c044c, 0x148ec02b, + 0x000044c0, 0x02020200, 0x01000f0f, 0x0b020001, 0x00000f0f, + 0x03721821, 0x00000898, 0x0000000b +}; + +#ifndef IEEE80211_NO_HT +static const uint32_t ar9280_2_0_fast_clock_vals_5g40[] = { + 0x000004d0, 0x00000318, 0x00001fa0, 0x08980898, 0x148ec057, + 0x00008980, 0x02020200, 0x01000f0f, 0x0b020001, 0x00000f0f, + 0x03721821, 0x00001130, 0x00000016 +}; +#endif + static const struct athn_ini ar9280_2_0_ini = { nitems(ar9280_2_0_regs), ar9280_2_0_regs, @@ -641,7 +661,13 @@ static const struct athn_ini ar9280_2_0_ini = { ar9280_2_0_vals_2g20, nitems(ar9280_2_0_cm_regs), ar9280_2_0_cm_regs, - ar9280_2_0_cm_vals + ar9280_2_0_cm_vals, + nitems(ar9280_2_0_fast_clock_regs), + ar9280_2_0_fast_clock_regs, + ar9280_2_0_fast_clock_vals_5g20, +#ifndef IEEE80211_NO_HT + ar9280_2_0_fast_clock_vals_5g40 +#endif }; /* diff --git a/sys/dev/ic/ar9380.c b/sys/dev/ic/ar9380.c index b743f71cc13..1da32ed69b8 100644 --- a/sys/dev/ic/ar9380.c +++ b/sys/dev/ic/ar9380.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar9380.c,v 1.2 2010/05/11 17:59:39 damien Exp $ */ +/* $OpenBSD: ar9380.c,v 1.3 2010/05/11 19:34:20 damien Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -148,6 +148,9 @@ ar9380_setup(struct athn_softc *sc) sc->txchainmask = MS(base->txrxMask, AR_EEP_TX_MASK); sc->rxchainmask = MS(base->txrxMask, AR_EEP_RX_MASK); + /* Fast PLL clock is always supported. */ + sc->flags |= ATHN_FLAG_FAST_PLL_CLOCK; + /* Select initialization values based on ROM. */ type = MS(eep->baseEepHeader.txrxgain, AR_EEP_RX_GAIN); if (type == AR_EEP_RX_GAIN_WO_XLNA) diff --git a/sys/dev/ic/ar9380reg.h b/sys/dev/ic/ar9380reg.h index cbae09a01fd..d8d9e6a4e67 100644 --- a/sys/dev/ic/ar9380reg.h +++ b/sys/dev/ic/ar9380reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ar9380reg.h,v 1.4 2010/05/11 17:59:39 damien Exp $ */ +/* $OpenBSD: ar9380reg.h,v 1.5 2010/05/11 19:34:20 damien Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -606,6 +606,23 @@ static const uint32_t ar9380_2_0_cm_vals[] = { 0x000c0000, 0x14021402, 0x00001402, 0x00000000, 0x00000000 }; +static const uint16_t ar9380_2_0_fast_clock_regs[] = { + P(0x01030), P(0x01070), P(0x010b0), P(0x08014), P(0x0801c), + P(0x08318), P(0x09e00), P(0x0a230), P(0x0a254) +}; + +static const uint32_t ar9380_2_0_fast_clock_vals_5g20[] = { + 0x00000268, 0x0000018c, 0x00000fd0, 0x044c044c, 0x148ec02b, + 0x000044c0, 0x03721821, 0x0000000b, 0x00000898 +}; + +#ifndef IEEE80211_NO_HT +static const uint32_t ar9380_2_0_fast_clock_vals_5g40[] = { + 0x000004d0, 0x00000318, 0x00001fa0, 0x08980898, 0x148ec057, + 0x00008980, 0x03721821, 0x00000016, 0x00001130 +}; +#endif + static const struct athn_ini ar9380_2_0_ini = { nitems(ar9380_2_0_regs), ar9380_2_0_regs, @@ -617,7 +634,13 @@ static const struct athn_ini ar9380_2_0_ini = { ar9380_2_0_vals_2g20, nitems(ar9380_2_0_cm_regs), ar9380_2_0_cm_regs, - ar9380_2_0_cm_vals + ar9380_2_0_cm_vals, + nitems(ar9380_2_0_fast_clock_regs), + ar9380_2_0_fast_clock_regs, + ar9380_2_0_fast_clock_vals_5g20, +#ifndef IEEE80211_NO_HT + ar9380_2_0_fast_clock_vals_5g40 +#endif }; /* diff --git a/sys/dev/ic/athn.c b/sys/dev/ic/athn.c index b687eb8979c..7797eedae30 100644 --- a/sys/dev/ic/athn.c +++ b/sys/dev/ic/athn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: athn.c,v 1.37 2010/05/10 17:44:21 damien Exp $ */ +/* $OpenBSD: athn.c,v 1.38 2010/05/11 19:34:20 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini @@ -705,14 +705,11 @@ athn_init_pll(struct athn_softc *sc, const struct ieee80211_channel *c) } else if (AR_SREV_9280_10_OR_LATER(sc)) { pll = SM(AR_RTC_9160_PLL_REFDIV, 0x05); if (c != NULL && IEEE80211_IS_CHAN_5GHZ(c)) { - if (AR_SREV_9280_20(sc)) { - /* Workaround for AR9280 2.0/5GHz. */ - if ((c->ic_freq % 20) == 0 || - (c->ic_freq % 10) == 0) - pll = 0x2850; - else - pll = 0x142c; - } else + if (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK) + pll = 0x142c; + else if (AR_SREV_9280_20(sc)) + pll = 0x2850; + else pll |= SM(AR_RTC_9160_PLL_DIV, 0x28); } else pll |= SM(AR_RTC_9160_PLL_DIV, 0x2c); @@ -2107,10 +2104,10 @@ athn_hw_reset(struct athn_softc *sc, struct ieee80211_channel *c, athn_init_dma(sc); - /* Program OBS bus to see MAC interrupts. */ + /* Program observation bus to see MAC interrupts. */ AR_WRITE(sc, sc->obs_off, 8); - /* Setup interrupt mitigation. */ + /* Setup Rx interrupt mitigation. */ AR_WRITE(sc, AR_RIMT, SM(AR_RIMT_FIRST, 2000) | SM(AR_RIMT_LAST, 500)); ops->init_baseband(sc); diff --git a/sys/dev/ic/athnvar.h b/sys/dev/ic/athnvar.h index 6cbd6a255ec..66a4c4d377a 100644 --- a/sys/dev/ic/athnvar.h +++ b/sys/dev/ic/athnvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: athnvar.h,v 1.10 2010/05/10 17:44:21 damien Exp $ */ +/* $OpenBSD: athnvar.h,v 1.11 2010/05/11 19:34:20 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini @@ -177,6 +177,12 @@ struct athn_ini { int ncmregs; const uint16_t *cmregs; const uint32_t *cmvals; + int nfastregs; + const uint16_t *fastregs; + const uint32_t *fastvals_5g20; +#ifndef IEEE80211_NO_HT + const uint32_t *fastvals_5g40; +#endif }; struct athn_gain { -- cgit v1.2.3