diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/if_run.c | 137 |
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; |