summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2010-05-11 19:34:21 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2010-05-11 19:34:21 +0000
commit73b25af4f81c0b4cad7f80f28a17c1f17cbd2bb9 (patch)
tree80ac5fbce86af779028df2e23f18cbf63604e7e6
parent7cdc4f9eb78d328200a38185a05e059793b770a0 (diff)
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.
-rw-r--r--sys/dev/ic/ar5008.c24
-rw-r--r--sys/dev/ic/ar9003.c34
-rw-r--r--sys/dev/ic/ar9280reg.h32
-rw-r--r--sys/dev/ic/ar9380.c5
-rw-r--r--sys/dev/ic/ar9380reg.h27
-rw-r--r--sys/dev/ic/athn.c19
-rw-r--r--sys/dev/ic/athnvar.h8
7 files changed, 124 insertions, 25 deletions
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 <damien.bergamini@free.fr>
@@ -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 <damien.bergamini@free.fr>
@@ -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 <damien.bergamini@free.fr>
@@ -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 <damien.bergamini@free.fr>
@@ -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 <damien.bergamini@free.fr>
@@ -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 <damien.bergamini@free.fr>
@@ -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 <damien.bergamini@free.fr>
@@ -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 {