summaryrefslogtreecommitdiff
path: root/sys/dev/usb/if_run.c
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2010-02-08 20:15:16 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2010-02-08 20:15:16 +0000
commitbd5a2a0458886f83c8f6c0f9734c2f281dd2eae6 (patch)
tree4103eb8427456a9cb2edafda65c86b53c54bce0e /sys/dev/usb/if_run.c
parentcda2cea620fa357a5342031ef83d5cc39536d129 (diff)
final bits for RT3572 and some fixes for RT3070 and RT3071.
Diffstat (limited to 'sys/dev/usb/if_run.c')
-rw-r--r--sys/dev/usb/if_run.c137
1 files changed, 117 insertions, 20 deletions
diff --git a/sys/dev/usb/if_run.c b/sys/dev/usb/if_run.c
index 797a7af28df..01e8c1cd13f 100644
--- a/sys/dev/usb/if_run.c
+++ b/sys/dev/usb/if_run.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_run.c,v 1.54 2010/02/08 18:46:47 damien Exp $ */
+/* $OpenBSD: if_run.c,v 1.55 2010/02/08 20:15:15 damien Exp $ */
/*-
* Copyright (c) 2008-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -322,6 +322,7 @@ int run_bbp_init(struct run_softc *);
int run_rt3070_rf_init(struct run_softc *);
int run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t,
uint8_t *);
+void run_rt3070_rf_setup(struct run_softc *);
int run_txrx_enable(struct run_softc *);
int run_init(struct ifnet *);
void run_stop(struct ifnet *, int);
@@ -2969,6 +2970,8 @@ run_rt3070_rf_init(struct run_softc *sc)
/* select 40MHz bandwidth */
run_bbp_read(sc, 4, &bbp4);
run_bbp_write(sc, 4, (bbp4 & ~0x08) | 0x10);
+ run_rt3070_rf_read(sc, 31, &rf);
+ run_rt3070_rf_write(sc, 31, rf | 0x20);
/* calibrate filter for 40MHz bandwidth */
sc->rf24_40mhz = 0x2f; /* default value */
@@ -2979,16 +2982,27 @@ run_rt3070_rf_init(struct run_softc *sc)
run_bbp_read(sc, 4, &bbp4);
run_bbp_write(sc, 4, bbp4 & ~0x18);
- if (sc->mac_rev < 0x0211)
+ if (sc->mac_ver == 0x3572) {
+ /* save default BBP registers 25 and 26 values */
+ run_bbp_read(sc, 25, &sc->bbp25);
+ run_bbp_read(sc, 26, &sc->bbp26);
+
+ } else if (sc->mac_rev < 0x0211)
run_rt3070_rf_write(sc, 27, 0x03);
run_read(sc, RT3070_OPT_14, &tmp);
run_write(sc, RT3070_OPT_14, tmp | 1);
- if (sc->mac_ver == 0x3572) {
- /* save default BBP registers 25 and 26 values */
- run_bbp_read(sc, 25, &sc->bbp25);
- run_bbp_read(sc, 26, &sc->bbp26);
+ if (sc->mac_ver == 0x3070 || sc->mac_ver == 0x3071) {
+ run_rt3070_rf_read(sc, 17, &rf);
+ rf &= ~RT3070_TX_LO1;
+ if ((sc->mac_ver == 0x3070 ||
+ (sc->mac_ver == 0x3071 && sc->mac_rev >= 0x0211)) &&
+ !sc->ext_2ghz_lna)
+ rf |= 0x20; /* fix for long range Rx issue */
+ if (sc->txmixgain_2ghz >= 1)
+ rf = (rf & ~0x7) | sc->txmixgain_2ghz;
+ run_rt3070_rf_write(sc, 17, rf);
}
if (sc->mac_ver == 0x3071) {
run_rt3070_rf_read(sc, 1, &rf);
@@ -2999,20 +3013,13 @@ run_rt3070_rf_init(struct run_softc *sc)
run_rt3070_rf_read(sc, 15, &rf);
run_rt3070_rf_write(sc, 15, rf & ~RT3070_TX_LO2);
- run_rt3070_rf_read(sc, 17, &rf);
- rf &= ~RT3070_TX_LO1;
- if (sc->mac_rev >= 0x0211 && !sc->ext_2ghz_lna)
- rf |= 0x20; /* fix for long range Rx issue */
- if (sc->txmixgain_2ghz >= 2)
- rf = (rf & ~0x7) | sc->txmixgain_2ghz;
- run_rt3070_rf_write(sc, 17, rf);
-
run_rt3070_rf_read(sc, 20, &rf);
run_rt3070_rf_write(sc, 20, rf & ~RT3070_RX_LO1);
run_rt3070_rf_read(sc, 21, &rf);
run_rt3070_rf_write(sc, 21, rf & ~RT3070_RX_LO2);
-
+ }
+ if (sc->mac_ver == 0x3070 || sc->mac_ver == 0x3071) {
/* fix Tx to Rx IQ glitch by raising RF voltage */
run_rt3070_rf_read(sc, 27, &rf);
rf &= ~0x77;
@@ -3032,7 +3039,8 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
int ntries;
/* program filter */
- rf24 = init; /* initial filter value */
+ run_rt3070_rf_read(sc, 24, &rf24);
+ rf24 = (rf24 & 0xc0) | init; /* initial filter value */
run_rt3070_rf_write(sc, 24, rf24);
/* enable baseband loopback mode */
@@ -3087,6 +3095,94 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
return 0;
}
+void
+run_rt3070_rf_setup(struct run_softc *sc)
+{
+ uint8_t bbp, rf;
+ int i;
+
+ if (sc->mac_ver == 0x3572) {
+ /* enable DC filter */
+ if (sc->mac_rev >= 0x0201)
+ run_bbp_write(sc, 103, 0xc0);
+
+ run_bbp_read(sc, 138, &bbp);
+ if (sc->ntxchains == 1)
+ bbp |= 0x20; /* turn off DAC1 */
+ if (sc->nrxchains == 1)
+ bbp &= ~0x02; /* turn off ADC1 */
+ run_bbp_write(sc, 138, bbp);
+
+ if (sc->mac_rev >= 0x0211) {
+ /* improve power consumption */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+
+ run_rt3070_rf_read(sc, 16, &rf);
+ rf = (rf & ~0x07) | sc->txmixgain_2ghz;
+ run_rt3070_rf_write(sc, 16, rf);
+
+ } else if (sc->mac_ver == 0x3071) {
+ /* enable DC filter */
+ if (sc->mac_rev >= 0x0201)
+ run_bbp_write(sc, 103, 0xc0);
+
+ run_bbp_read(sc, 138, &bbp);
+ if (sc->ntxchains == 1)
+ bbp |= 0x20; /* turn off DAC1 */
+ if (sc->nrxchains == 1)
+ bbp &= ~0x02; /* turn off ADC1 */
+ run_bbp_write(sc, 138, bbp);
+
+ if (sc->mac_rev >= 0x0211) {
+ /* improve power consumption */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+
+ run_write(sc, RT2860_TX_SW_CFG1, 0);
+ if (sc->mac_rev < 0x0211) {
+ run_write(sc, RT2860_TX_SW_CFG2,
+ sc->patch_dac ? 0x2c : 0x0f);
+ } else
+ run_write(sc, RT2860_TX_SW_CFG2, 0);
+
+ } else if (sc->mac_ver == 0x3070) {
+ if (sc->mac_rev >= 0x0201) {
+ /* enable DC filter */
+ run_bbp_write(sc, 103, 0xc0);
+
+ /* improve power consumption */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+
+ run_rt3070_rf_read(sc, 17, &rf);
+ rf &= ~RT3070_TX_LO1;
+ if (!sc->ext_2ghz_lna)
+ rf |= 0x20; /* fix for long range Rx issue */
+ if (sc->txmixgain_2ghz >= 1)
+ rf = (rf & ~0x07) | sc->txmixgain_2ghz;
+ run_rt3070_rf_write(sc, 17, rf);
+
+ if (sc->mac_rev < 0x0211) {
+ run_write(sc, RT2860_TX_SW_CFG1, 0);
+ run_write(sc, RT2860_TX_SW_CFG2, 0x2c);
+ } else
+ run_write(sc, RT2860_TX_SW_CFG2, 0);
+ }
+
+ /* initialize RF registers from ROM for >=RT3071*/
+ if (sc->mac_ver >= 0x3071) {
+ for (i = 0; i < 10; i++) {
+ if (sc->rf[i].reg == 0 || sc->rf[i].val == 0xff)
+ continue;
+ run_rt3070_rf_write(sc, sc->rf[i].reg, sc->rf[i].val);
+ }
+ }
+}
+
int
run_txrx_enable(struct run_softc *sc)
{
@@ -3223,8 +3319,6 @@ run_init(struct ifnet *ifp)
/* set delay of PA_PE assertion to 1us (unit of 0.25us) */
run_write(sc, RT2860_TX_SW_CFG0,
4 << RT2860_DLY_PAPE_EN_SHIFT);
- run_write(sc, RT2860_TX_SW_CFG1, 0);
- run_write(sc, RT2860_TX_SW_CFG2, 0x1f);
}
/* wait while MAC is busy */
@@ -3268,7 +3362,7 @@ run_init(struct ifnet *ifp)
tmp = (tmp & ~0xff) | 0x1e;
run_write(sc, RT2860_US_CYC_CNT, tmp);
- if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101)
+ if (sc->mac_rev != 0x0101)
run_write(sc, RT2860_TXOP_CTRL_CFG, 0x0000583f);
run_write(sc, RT2860_WMM_TXOP0_CFG, 0);
@@ -3290,6 +3384,9 @@ run_init(struct ifnet *ifp)
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1]);
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2]);
+ if (sc->mac_ver >= 0x3070)
+ run_rt3070_rf_init(sc);
+
/* disable non-existing Rx chains */
run_bbp_read(sc, 3, &bbp3);
bbp3 &= ~(1 << 3 | 1 << 4);
@@ -3306,7 +3403,7 @@ run_init(struct ifnet *ifp)
run_bbp_write(sc, 1, bbp1);
if (sc->mac_ver >= 0x3070)
- run_rt3070_rf_init(sc);
+ run_rt3070_rf_setup(sc);
/* select default channel */
ic->ic_bss->ni_chan = ic->ic_ibss_chan;