diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2010-05-10 18:17:11 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2010-05-10 18:17:11 +0000 |
commit | 74ec6f5d77854dfd44aaf3ee3e8836f9a15c38ff (patch) | |
tree | 960d54140a157bb43e7e3aaae68be3e4456913e6 /sys | |
parent | 1d1fef4cd5b04df1795c1fc7b0d9b92a1d14cb19 (diff) |
additionnal bits and fixes for RT3090.
some adapters labelled RT3090 have a MAC version equal to RT3071.
still no luck receiving frames on my AzureWave AW-NE762H though :(
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/rt2860.c | 127 | ||||
-rw-r--r-- | sys/dev/ic/rt2860reg.h | 36 |
2 files changed, 110 insertions, 53 deletions
diff --git a/sys/dev/ic/rt2860.c b/sys/dev/ic/rt2860.c index 728055f8917..5651f1c67cc 100644 --- a/sys/dev/ic/rt2860.c +++ b/sys/dev/ic/rt2860.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2860.c,v 1.52 2010/04/20 22:05:43 tedu Exp $ */ +/* $OpenBSD: rt2860.c,v 1.53 2010/05/10 18:17:10 damien Exp $ */ /*- * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr> @@ -222,9 +222,9 @@ rt2860_attach(void *xsc, int id) sc->mac_ver = tmp >> 16; sc->mac_rev = tmp & 0xffff; #ifdef RAL_DEBUG - /* temporarily enable debug for >=RT3090 */ - if (sc->mac_ver >= 0x3090) - rt2860_debug = 1; + /* temporarily enable debug for >=RT3071 */ + if (sc->mac_ver >= 0x3071) + rt2860_debug = 10; #endif if (sc->mac_ver != 0x2860 && (id == PCI_PRODUCT_RALINK_RT2890 || @@ -912,7 +912,7 @@ rt2860_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) return sc->sc_newstate(ic, nstate, arg); } -/* Read 16-bit from eFUSE ROM (>=RT3090 only.) */ +/* Read 16-bit from eFUSE ROM (>=RT3071 only.) */ uint16_t rt3090_efuse_read_2(struct rt2860_softc *sc, uint16_t addr) { @@ -2128,7 +2128,7 @@ rt2860_select_chan_group(struct rt2860_softc *sc, int group) /* set initial AGC value */ if (group == 0) { /* 2GHz band */ - if (sc->mac_rev >= 0x3090) + if (sc->mac_ver >= 0x3071) agc = 0x1c + sc->lna[0] * 2; else agc = 0x2e + sc->lna[0]; @@ -2232,13 +2232,13 @@ rt3090_set_chan(struct rt2860_softc *sc, u_int chan) rf = rt3090_rf_read(sc, 1); rf &= ~0xfc; if (sc->ntxchains == 1) - rf |= 1 << 7 | 1 << 5; /* 1T: disable Tx chains 2 & 3 */ + rf |= RT3070_TX1_PD | RT3070_TX2_PD; else if (sc->ntxchains == 2) - rf |= 1 << 7; /* 2T: disable Tx chain 3 */ + rf |= RT3070_TX2_PD; if (sc->nrxchains == 1) - rf |= 1 << 6 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */ + rf |= RT3070_RX1_PD | RT3070_RX2_PD; else if (sc->nrxchains == 2) - rf |= 1 << 6; /* 2R: disable Rx chain 3 */ + rf |= RT3070_RX2_PD; rt3090_rf_write(sc, 1, rf); /* set RF offset */ @@ -2256,7 +2256,7 @@ rt3090_set_chan(struct rt2860_softc *sc, u_int chan) /* enable RF tuning */ rf = rt3090_rf_read(sc, 7); - rt3090_rf_write(sc, 7, rf | 0x01); + rt3090_rf_write(sc, 7, rf | RT3070_TUNE); } int @@ -2376,42 +2376,55 @@ rt3090_rf_wakeup(struct rt2860_softc *sc) if (sc->mac_ver == 0x3593) { /* enable VCO */ rf = rt3090_rf_read(sc, 1); - rt3090_rf_write(sc, 1, rf | 0x01); + rt3090_rf_write(sc, 1, rf | RT3593_VCO); + /* initiate VCO calibration */ rf = rt3090_rf_read(sc, 3); - rt3090_rf_write(sc, 3, rf | 0x80); + rt3090_rf_write(sc, 3, rf | RT3593_VCOCAL); + /* enable VCO bias current control */ rf = rt3090_rf_read(sc, 6); - rt3090_rf_write(sc, 6, rf | 0x40); + rt3090_rf_write(sc, 6, rf | RT3593_VCO_IC); + /* initiate res calibration */ rf = rt3090_rf_read(sc, 2); - rt3090_rf_write(sc, 2, rf | 0x80); - /* set reference current control */ + rt3090_rf_write(sc, 2, rf | RT3593_RESCAL); + + /* set reference current control to 0.33 mA */ rf = rt3090_rf_read(sc, 22); - rt3090_rf_write(sc, 22, (rf & ~0xe0) | 0x80); + rf &= ~RT3593_CP_IC_MASK; + rf |= 1 << RT3593_CP_IC_SHIFT; + rt3090_rf_write(sc, 22, rf); + /* enable RX CTB */ rf = rt3090_rf_read(sc, 46); - rt3090_rf_write(sc, 46, rf | 0x20); - rf = rt3090_rf_read(sc, 20); - rt3090_rf_write(sc, 20, rf & ~0xee); + rt3090_rf_write(sc, 46, rf | RT3593_RX_CTB); - rf = rt3090_rf_read(sc, 27); - rf &= ~0x77; - if (sc->mac_rev < 0x0211) - rf |= 0x03; - rt3090_rf_write(sc, 27, rf); + rf = rt3090_rf_read(sc, 20); + rf &= ~(RT3593_LDO_RF_VC_MASK | RT3593_LDO_PLL_VC_MASK); + rt3090_rf_write(sc, 20, rf); } else { /* enable RF block */ rf = rt3090_rf_read(sc, 1); - rt3090_rf_write(sc, 1, rf | 0x01); + rt3090_rf_write(sc, 1, rf | RT3070_RF_BLOCK); + /* enable VCO bias current control */ rf = rt3090_rf_read(sc, 7); rt3090_rf_write(sc, 7, rf | 0x30); + rf = rt3090_rf_read(sc, 9); rt3090_rf_write(sc, 9, rf | 0x0e); + /* enable RX CTB */ rf = rt3090_rf_read(sc, 21); - rt3090_rf_write(sc, 21, rf | 0x80); + rt3090_rf_write(sc, 21, rf | RT3070_RX_CTB); + + /* fix Tx to Rx IQ glitch by raising RF voltage */ + rf = rt3090_rf_read(sc, 27); + rf &= ~0x77; + if (sc->mac_rev < 0x0211) + rf |= 0x03; + rt3090_rf_write(sc, 27, rf); } if (sc->patch_dac && sc->mac_rev < 0x0211) { tmp = RAL_READ(sc, RT3070_LDO_CFG0); @@ -2435,7 +2448,7 @@ rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target, /* enable baseband loopback mode */ rf22 = rt3090_rf_read(sc, 22); - rt3090_rf_write(sc, 22, rf22 | 0x01); + rt3090_rf_write(sc, 22, rf22 | RT3070_BB_LOOPBACK); /* set power and frequency of passband test tone */ rt2860_mcu_bbp_write(sc, 24, 0x00); @@ -2480,7 +2493,7 @@ rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target, /* disable baseband loopback mode */ rf22 = rt3090_rf_read(sc, 22); - rt3090_rf_write(sc, 22, rf22 & ~0x01); + rt3090_rf_write(sc, 22, rf22 & ~RT3070_BB_LOOPBACK); return 0; } @@ -2844,7 +2857,7 @@ rt2860_read_eeprom(struct rt2860_softc *sc) /* check whether the ROM is eFUSE ROM or EEPROM */ sc->sc_srom_read = rt2860_eeprom_read_2; - if (sc->mac_ver >= 0x3090) { + if (sc->mac_ver >= 0x3071) { tmp = RAL_READ(sc, RT3070_EFUSE_CTRL); DPRINTF(("EFUSE_CTRL=0x%08x\n", tmp)); if (tmp & RT3070_SEL_EFUSE) @@ -2877,7 +2890,7 @@ rt2860_read_eeprom(struct rt2860_softc *sc) sc->bbp[i].reg = val >> 8; DPRINTF(("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val)); } - if (sc->mac_ver >= 0x3090) { + if (sc->mac_ver >= 0x3071) { /* read vendor RF settings */ for (i = 0; i < 10; i++) { val = rt2860_srom_read(sc, RT3071_EEPROM_RF_BASE + i); @@ -2917,7 +2930,7 @@ rt2860_read_eeprom(struct rt2860_softc *sc) sc->rf_rev = RT3070_RF_3053; sc->ntxchains = 3; sc->nrxchains = 3; - } else if (sc->mac_ver >= 0x3090) { + } else if (sc->mac_ver >= 0x3071) { /* default to RF3020 1T1R */ sc->rf_rev = RT3070_RF_3020; sc->ntxchains = 1; @@ -2950,18 +2963,18 @@ rt2860_read_eeprom(struct rt2860_softc *sc) /* check if we have a hardware radio switch */ sc->rfswitch = val & 1; } - if (sc->sc_flags & RT2860_ADVANCED_PS) { /* read PCIe power save level */ val = rt2860_srom_read(sc, RT2860_EEPROM_PCIE_PSLEVEL); if ((val & 0xff) != 0xff) { sc->pslevel = val & 0x3; val = rt2860_srom_read(sc, RT2860_EEPROM_REV); - if (val >> 8 != 0x92 || !(val & 0x80)) + if ((val & 0xff80) != 0x9280) sc->pslevel = MIN(sc->pslevel, 1); DPRINTF(("EEPROM PCIe PS Level=%d\n", sc->pslevel)); } } + /* read power settings for 2GHz channels */ for (i = 0; i < 14; i += 2) { val = rt2860_srom_read(sc, @@ -3094,7 +3107,7 @@ rt2860_read_eeprom(struct rt2860_softc *sc) sc->rssi_2ghz[0] = val & 0xff; /* Ant A */ sc->rssi_2ghz[1] = val >> 8; /* Ant B */ val = rt2860_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ); - if (sc->mac_ver >= 0x3090) { + if (sc->mac_ver >= 0x3071) { /* * On RT3090 chips (limited to 2 Rx chains), this ROM * field contains the Tx mixer gain for the 2GHz band. @@ -3114,7 +3127,10 @@ rt2860_read_eeprom(struct rt2860_softc *sc) sc->lna[3] = val >> 8; /* channel group 3 */ val = rt2860_srom_read(sc, RT2860_EEPROM_LNA); - sc->lna[0] = val & 0xff; /* channel group 0 */ + if (sc->mac_ver >= 0x3071) + sc->lna[0] = RT3090_DEF_LNA; + else /* channel group 0 */ + sc->lna[0] = val & 0xff; sc->lna[1] = val >> 8; /* channel group 1 */ /* fix broken 5GHz LNA entries */ @@ -3171,7 +3187,7 @@ rt2860_bbp_init(struct rt2860_softc *sc) if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101) rt2860_mcu_bbp_write(sc, 84, 0x19); - if (sc->mac_ver >= 0x3090) { + if (sc->mac_ver >= 0x3071) { rt2860_mcu_bbp_write(sc, 79, 0x13); rt2860_mcu_bbp_write(sc, 80, 0x05); rt2860_mcu_bbp_write(sc, 81, 0x33); @@ -3258,13 +3274,13 @@ rt2860_init(struct ifnet *ifp) #endif } } + RAL_WRITE(sc, RT2860_PWR_PIN_CFG, RT2860_IO_RA_PE); + /* disable DMA */ tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG); tmp &= 0xff0; RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp); - RAL_WRITE(sc, RT2860_WPDMA_RST_IDX, 0xffffffff); - /* PBF hardware reset */ RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe1f); RAL_BARRIER_WRITE(sc); @@ -3321,6 +3337,19 @@ rt2860_init(struct ifnet *ifp) for (i = 0; i < nitems(rt2860_def_mac); i++) RAL_WRITE(sc, rt2860_def_mac[i].reg, rt2860_def_mac[i].val); + if (sc->mac_ver >= 0x3071) { + /* set delay of PA_PE assertion to 1us (unit of 0.25us) */ + RAL_WRITE(sc, RT2860_TX_SW_CFG0, + 4 << RT2860_DLY_PAPE_EN_SHIFT); + } + + if (!(RAL_READ(sc, RT2860_PCI_CFG) & RT2860_PCI_CFG_PCI)) { + sc->sc_flags |= RT2860_PCIE; + /* PCIe has different clock cycle count than PCI */ + tmp = RAL_READ(sc, RT2860_US_CYC_CNT); + tmp = (tmp & ~0xff) | 0x7d; + RAL_WRITE(sc, RT2860_US_CYC_CNT, tmp); + } /* wait while MAC is busy */ for (ntries = 0; ntries < 100; ntries++) { @@ -3335,14 +3364,6 @@ rt2860_init(struct ifnet *ifp) return ETIMEDOUT; } - if (!(RAL_READ(sc, RT2860_PCI_CFG) & RT2860_PCI_CFG_PCI)) { - sc->sc_flags |= RT2860_PCIE; - /* PCIe has different clock cycle count than PCI */ - tmp = RAL_READ(sc, RT2860_US_CYC_CNT); - tmp = (tmp & ~0xff) | 0x7d; - RAL_WRITE(sc, RT2860_US_CYC_CNT, tmp); - } - /* clear Host to MCU mailbox */ RAL_WRITE(sc, RT2860_H2M_BBPAGENT, 0); RAL_WRITE(sc, RT2860_H2M_MAILBOX, 0); @@ -3410,7 +3431,9 @@ rt2860_init(struct ifnet *ifp) } /* select Main antenna for 1T1R devices */ - if (sc->rf_rev == RT3070_RF_3020) + if (sc->rf_rev == RT3070_RF_2020 || + sc->rf_rev == RT3070_RF_3020 || + sc->rf_rev == RT3070_RF_3320) rt3090_set_rx_antenna(sc, 0); /* send LEDs operating mode to microcontroller */ @@ -3418,13 +3441,13 @@ rt2860_init(struct ifnet *ifp) rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1], 0); rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2], 0); - if (sc->mac_ver >= 0x3090) + if (sc->mac_ver >= 0x3071) rt3090_rf_init(sc); rt2860_mcu_cmd(sc, RT2860_MCU_CMD_SLEEP, 0x02ff, 1); rt2860_mcu_cmd(sc, RT2860_MCU_CMD_WAKEUP, 0, 1); - if (sc->mac_ver >= 0x3090) + if (sc->mac_ver >= 0x3071) rt3090_rf_wakeup(sc); /* disable non-existing Rx chains */ @@ -3446,7 +3469,7 @@ rt2860_init(struct ifnet *ifp) bbp1 = (bbp1 & ~(1 << 3)) | 1 << 4; rt2860_mcu_bbp_write(sc, 1, bbp1); - if (sc->mac_ver >= 0x3090) + if (sc->mac_ver >= 0x3071) rt3090_rf_setup(sc); /* select default channel */ @@ -3664,7 +3687,7 @@ rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c) if (chan == 0 || chan == IEEE80211_CHAN_ANY) return; - if (sc->mac_ver >= 0x3090) + if (sc->mac_ver >= 0x3071) rt3090_set_chan(sc, chan); else rt2860_set_chan(sc, chan); diff --git a/sys/dev/ic/rt2860reg.h b/sys/dev/ic/rt2860reg.h index 31f6a4e7ff9..dec490802c7 100644 --- a/sys/dev/ic/rt2860reg.h +++ b/sys/dev/ic/rt2860reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2860reg.h,v 1.29 2010/04/06 19:40:51 damien Exp $ */ +/* $OpenBSD: rt2860reg.h,v 1.30 2010/05/10 18:17:10 damien Exp $ */ /*- * Copyright (c) 2007 @@ -76,6 +76,7 @@ #define RT3070_EFUSE_DATA1 0x0594 #define RT3070_EFUSE_DATA2 0x0598 #define RT3070_EFUSE_DATA3 0x059c +#define RT3090_OSC_CTRL 0x05a4 #define RT3070_LDO_CFG0 0x05d4 #define RT3070_GPIO_SWITCH 0x05dc @@ -699,6 +700,11 @@ #define RT3070_TX0_PD (1 << 3) #define RT3070_RX1_PD (1 << 4) #define RT3070_TX1_PD (1 << 5) +#define RT3070_RX2_PD (1 << 6) +#define RT3070_TX2_PD (1 << 7) + +/* possible flags for RT3020 RF register 7 */ +#define RT3070_TUNE (1 << 0) /* possible flags for RT3020 RF register 15 */ #define RT3070_TX_LO2 (1 << 3) @@ -711,7 +717,35 @@ /* possible flags for RT3020 RF register 21 */ #define RT3070_RX_LO2 (1 << 3) +#define RT3070_RX_CTB (1 << 7) + +/* possible flags for RT3020 RF register 22 */ +#define RT3070_BB_LOOPBACK (1 << 0) + +/* possible flags for RT3053 RF register 1 */ +#define RT3593_VCO (1 << 0) + +/* possible flags for RT3053 RF register 2 */ +#define RT3593_RESCAL (1 << 7) + +/* possible flags for RT3053 RF register 3 */ +#define RT3593_VCOCAL (1 << 7) + +/* possible flags for RT3053 RF register 6 */ +#define RT3593_VCO_IC (1 << 6) + +/* possible flags for RT3053 RF register 20 */ +#define RT3593_LDO_PLL_VC_MASK 0x0e +#define RT3593_LDO_RF_VC_MASK 0xe0 + +/* possible flags for RT3053 RF register 22 */ +#define RT3593_CP_IC_MASK 0xe0 +#define RT3593_CP_IC_SHIFT 5 + +/* possible flags for RT3053 RF register 46 */ +#define RT3593_RX_CTB (1 << 5) +#define RT3090_DEF_LNA 10 /* RT2860 TX descriptor */ struct rt2860_txd { |