int HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) { struct rt2860_softc* sc = (struct rt2860_softc*)device_get_softc(dev); struct ifnet* ifp = sc->ifp; // acknowledge interrupts uint32_t status = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_INT_STATUS); rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_INT_STATUS, status); if (status == 0xffffffff || status == 0) // device likely went away || not for us return 0; sc->interrupts++; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) return 0; rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_INT_MASK, 0); // Disable interrupts sc->interrupt_status = status; return 1; }
void rt3090_rf_setup(struct rt2860_softc *sc) { uint8_t bbp; int i; if ((sc->mac_rev & 0x0000ffff) >= 0x0211) { /* enable DC filter */ rt2860_io_bbp_write(sc, 103, 0xc0); /* improve power consumption */ bbp = rt2860_io_bbp_read(sc, 31); rt2860_io_bbp_write(sc, 31, bbp & ~0x03); } rt2860_io_mac_write(sc, RT2860_REG_TX_SW_CFG1, 0); if ((sc->mac_rev & 0x0000ffff) < 0x0211) { rt2860_io_mac_write(sc, RT2860_REG_TX_SW_CFG2, sc->patch_dac ? 0x2c : 0x0f); } else rt2860_io_mac_write(sc, RT2860_REG_TX_SW_CFG2, 0); /* initialize RF registers from ROM */ for (i = 0; i < 10; i++) { if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff) continue; rt3090_rf_write(sc, sc->rf[i].reg, sc->rf[i].val); } }
uint8_t rt3090_rf_read(struct rt2860_softc *sc, uint8_t reg) { uint32_t tmp; int ntries; for (ntries = 0; ntries < 100; ntries++) { if (!(rt2860_io_mac_read(sc, RT3070_RF_CSR_CFG) & RT3070_RF_KICK)) break; DELAY(1); } if (ntries == 100) { device_printf(sc->dev, "could not read RF register\n"); return 0xff; } tmp = RT3070_RF_KICK | reg << 8; rt2860_io_mac_write(sc, RT3070_RF_CSR_CFG, tmp); for (ntries = 0; ntries < 100; ntries++) { tmp = rt2860_io_mac_read(sc, RT3070_RF_CSR_CFG); if (!(tmp & RT3070_RF_KICK)) break; DELAY(1); } if (ntries == 100) { device_printf(sc->dev, "could not read RF register\n"); return 0xff; } return tmp & 0xff; }
void rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux) { uint32_t tmp; if (aux) { tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR); rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp & ~RT2860_REG_EESK); tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG); rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG, (tmp & ~0x0808) | 0x08); } else { tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR); rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp | RT2860_REG_EESK); tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG); rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG, tmp & ~0x0808); } }
static void rt2860_intr_enable(struct rt2860_softc* sc, uint32_t intr_mask) { uint32_t tmp; sc->intr_disable_mask &= ~intr_mask; tmp = sc->intr_enable_mask & ~sc->intr_disable_mask; rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_INT_MASK, tmp); }
void rt3090_rf_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val) { uint32_t tmp; int ntries; for (ntries = 0; ntries < 10; ntries++) { if (!(rt2860_io_mac_read(sc, RT3070_RF_CSR_CFG) & RT3070_RF_KICK)) break; DELAY(10); } if (ntries == 10) { device_printf(sc->dev, "could not write to RF\n"); return; } tmp = RT3070_RF_WRITE | RT3070_RF_KICK | reg << 8 | val; rt2860_io_mac_write(sc, RT3070_RF_CSR_CFG, tmp); }
void rt3090_rf_wakeup(struct rt2860_softc *sc) { uint32_t tmp; uint8_t rf; if ((sc->mac_rev & 0xffff0000) == 0x35930000) { /* enable VCO */ rf = rt3090_rf_read(sc, 1); rt3090_rf_write(sc, 1, rf | RT3593_VCO); /* initiate VCO calibration */ rf = rt3090_rf_read(sc, 3); 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 | RT3593_VCO_IC); /* initiate res calibration */ rf = rt3090_rf_read(sc, 2); rt3090_rf_write(sc, 2, rf | RT3593_RESCAL); /* set reference current control to 0.33 mA */ rf = rt3090_rf_read(sc, 22); 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 | RT3593_RX_CTB); 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 | 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 | 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 & 0x0000ffff) < 0x0211) rf |= 0x03; rt3090_rf_write(sc, 27, rf); } if (sc->patch_dac && (sc->mac_rev & 0x0000ffff) < 0x0211) { tmp = rt2860_io_mac_read(sc, RT3070_LDO_CFG0); tmp = (tmp & ~0x1f000000) | 0x0d000000; rt2860_io_mac_write(sc, RT3070_LDO_CFG0, tmp); } }
int rt3090_rf_init(struct rt2860_softc *sc) { uint32_t tmp; uint8_t rf, bbp; int i; rf = rt3090_rf_read(sc, 30); /* toggle RF R30 bit 7 */ rt3090_rf_write(sc, 30, rf | 0x80); DELAY(1000); rt3090_rf_write(sc, 30, rf & ~0x80); tmp = rt2860_io_mac_read(sc, RT3070_LDO_CFG0); tmp &= ~0x1f000000; if (sc->patch_dac && (sc->mac_rev & 0x0000ffff) < 0x0211) tmp |= 0x0d000000; /* 1.35V */ else tmp |= 0x01000000; /* 1.2V */ rt2860_io_mac_write(sc, RT3070_LDO_CFG0, tmp); /* patch LNA_PE_G1 */ tmp = rt2860_io_mac_read(sc, RT3070_GPIO_SWITCH); rt2860_io_mac_write(sc, RT3070_GPIO_SWITCH, tmp & ~0x20); /* initialize RF registers to default value */ for (i = 0; i < (sizeof(rt3090_def_rf)/2); i++) { rt3090_rf_write(sc, rt3090_def_rf[i].reg, rt3090_def_rf[i].val); } /* select 20MHz bandwidth */ rt3090_rf_write(sc, 31, 0x14); rf = rt3090_rf_read(sc, 6); rt3090_rf_write(sc, 6, rf | 0x40); if ((sc->mac_rev & 0xffff0000) != 0x35930000) { /* calibrate filter for 20MHz bandwidth */ sc->rf24_20mhz = 0x1f; /* default value */ rt3090_filter_calib(sc, 0x07, 0x16, &sc->rf24_20mhz); /* select 40MHz bandwidth */ bbp = rt2860_io_bbp_read(sc, 4); rt2860_io_bbp_write(sc, 4, (bbp & ~0x08) | 0x10); rf = rt3090_rf_read(sc, 31); rt3090_rf_write(sc, 31, rf | 0x20); /* calibrate filter for 40MHz bandwidth */ sc->rf24_40mhz = 0x2f; /* default value */ rt3090_filter_calib(sc, 0x27, 0x19, &sc->rf24_40mhz); /* go back to 20MHz bandwidth */ bbp = rt2860_io_bbp_read(sc, 4); rt2860_io_bbp_write(sc, 4, bbp & ~0x18); } if ((sc->mac_rev & 0x0000ffff) < 0x0211) rt3090_rf_write(sc, 27, 0x03); tmp = rt2860_io_mac_read(sc, RT3070_OPT_14); rt2860_io_mac_write(sc, RT3070_OPT_14, tmp | 1); if (sc->rf_rev == RT2860_EEPROM_RF_3020) rt3090_set_rx_antenna(sc, 0); bbp = rt2860_io_bbp_read(sc, 138); if ((sc->mac_rev & 0xffff0000) == 0x35930000) { if (sc->ntxpath == 1) bbp |= 0x60; /* turn off DAC1 and DAC2 */ else if (sc->ntxpath == 2) bbp |= 0x40; /* turn off DAC2 */ if (sc->nrxpath == 1) bbp &= ~0x06; /* turn off ADC1 and ADC2 */ else if (sc->nrxpath == 2) bbp &= ~0x04; /* turn off ADC2 */ } else { if (sc->ntxpath == 1) bbp |= 0x20; /* turn off DAC1 */ if (sc->nrxpath == 1) bbp &= ~0x02; /* turn off ADC1 */ } rt2860_io_bbp_write(sc, 138, bbp); rf = rt3090_rf_read(sc, 1); rf &= ~(RT3070_RX0_PD | RT3070_TX0_PD); rf |= RT3070_RF_BLOCK | RT3070_RX1_PD | RT3070_TX1_PD; rt3090_rf_write(sc, 1, rf); rf = rt3090_rf_read(sc, 15); rt3090_rf_write(sc, 15, rf & ~RT3070_TX_LO2); rf = rt3090_rf_read(sc, 17); rf &= ~RT3070_TX_LO1; if ((sc->mac_rev & 0x0000ffff) >= 0x0211 && !sc->ext_lna_2ghz) rf |= 0x20; /* fix for long range Rx issue */ if (sc->txmixgain_2ghz >= 2) rf = (rf & ~0x7) | sc->txmixgain_2ghz; rt3090_rf_write(sc, 17, rf); rf = rt3090_rf_read(sc, 20); rt3090_rf_write(sc, 20, rf & ~RT3070_RX_LO1); rf = rt3090_rf_read(sc, 21); rt3090_rf_write(sc, 21, rf & ~RT3070_RX_LO2); return 0; }
/* * rt2860_rf_select_chan_group */ void rt2860_rf_select_chan_group(struct rt2860_softc *sc, struct ieee80211_channel *c) { struct ifnet *ifp; struct ieee80211com *ic; int chan, group; uint32_t tmp; ifp = sc->ifp; ic = ifp->if_l2com; chan = ieee80211_chan2ieee(ic, c); if (chan == 0 || chan == IEEE80211_CHAN_ANY) return; if (chan <= 14) group = 0; else if (chan <= 64) group = 1; else if (chan <= 128) group = 2; else group = 3; rt2860_io_bbp_write(sc, 62, 0x37 - sc->lna_gain[group]); rt2860_io_bbp_write(sc, 63, 0x37 - sc->lna_gain[group]); rt2860_io_bbp_write(sc, 64, 0x37 - sc->lna_gain[group]); rt2860_io_bbp_write(sc, 86, 0x00); if (group == 0) { if (sc->ext_lna_2ghz) { rt2860_io_bbp_write(sc, 82, 0x62); rt2860_io_bbp_write(sc, 75, 0x46); } else { rt2860_io_bbp_write(sc, 82, 0x84); rt2860_io_bbp_write(sc, 75, 0x50); } } else { rt2860_io_bbp_write(sc, 82, 0xf2); if (sc->ext_lna_5ghz) rt2860_io_bbp_write(sc, 75, 0x46); else rt2860_io_bbp_write(sc, 75, 0x50); } if (group == 0) { tmp = 0x2e + sc->lna_gain[group]; } else { if ((ic->ic_flags & IEEE80211_F_SCAN) || !IEEE80211_IS_CHAN_HT40(c)) tmp = 0x32 + sc->lna_gain[group] * 5 / 3; else tmp = 0x3a + sc->lna_gain[group] * 5 / 3; } rt2860_io_bbp_write(sc, 66, tmp); tmp = RT2860_REG_RFTR_ENABLE | RT2860_REG_TRSW_ENABLE | RT2860_REG_LNA_PE_G1_ENABLE | RT2860_REG_LNA_PE_A1_ENABLE | RT2860_REG_LNA_PE_G0_ENABLE | RT2860_REG_LNA_PE_A0_ENABLE; if (group == 0) tmp |= RT2860_REG_PA_PE_G1_ENABLE | RT2860_REG_PA_PE_G0_ENABLE; else tmp |= RT2860_REG_PA_PE_A1_ENABLE | RT2860_REG_PA_PE_A0_ENABLE; if (sc->ntxpath == 1) tmp &= ~(RT2860_REG_PA_PE_G1_ENABLE | RT2860_REG_PA_PE_A1_ENABLE); if (sc->nrxpath == 1) tmp &= ~(RT2860_REG_LNA_PE_G1_ENABLE | RT2860_REG_LNA_PE_A1_ENABLE); rt2860_io_mac_write(sc, RT2860_REG_TX_PIN_CFG, tmp); tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_BAND_CFG); tmp &= ~(RT2860_REG_TX_BAND_BG | RT2860_REG_TX_BAND_A | RT2860_REG_TX_BAND_HT40_ABOVE); if (group == 0) tmp |= RT2860_REG_TX_BAND_BG; else tmp |= RT2860_REG_TX_BAND_A; /* set central channel position */ if (IEEE80211_IS_CHAN_HT40U(c)) tmp |= RT2860_REG_TX_BAND_HT40_BELOW; else if (IEEE80211_IS_CHAN_HT40D(c)) tmp |= RT2860_REG_TX_BAND_HT40_ABOVE; else tmp |= RT2860_REG_TX_BAND_HT40_BELOW; rt2860_io_mac_write(sc, RT2860_REG_TX_BAND_CFG, tmp); /* set bandwidth (20MHz or 40MHz) */ tmp = rt2860_io_bbp_read(sc, 4); tmp &= ~0x18; if (IEEE80211_IS_CHAN_HT40(c)) tmp |= 0x10; rt2860_io_bbp_write(sc, 4, tmp); /* set central channel position */ tmp = rt2860_io_bbp_read(sc, 3); tmp &= ~0x20; if (IEEE80211_IS_CHAN_HT40D(c)) tmp |= 0x20; rt2860_io_bbp_write(sc, 3, tmp); if (sc->mac_rev == 0x28600100) { if (!IEEE80211_IS_CHAN_HT40(c)) { rt2860_io_bbp_write(sc, 69, 0x16); rt2860_io_bbp_write(sc, 70, 0x08); rt2860_io_bbp_write(sc, 73, 0x12); } else { rt2860_io_bbp_write(sc, 69, 0x1a); rt2860_io_bbp_write(sc, 70, 0x0a); rt2860_io_bbp_write(sc, 73, 0x16); } } }