Date: Sun, 21 Feb 2010 08:53:33 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 174936 for review Message-ID: <201002210853.o1L8rXij054451@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/chv.cgi?CH=174936 Change 174936 by hselasky@hselasky_laptop001 on 2010/02/21 08:52:41 USB WLAN: - integrate latest driver code from OpenBSD. - patch by: Akinori Affected files ... .. //depot/projects/usb/src/sys/dev/usb/usbdevs#106 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_run.c#5 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_runreg.h#3 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_runvar.h#4 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/usbdevs#106 (text+ko) ==== @@ -544,6 +544,7 @@ vendor RIM 0x0fca Research In Motion vendor DYNASTREAM 0x0fcf Dynastream Innovations vendor QUALCOMM 0x1004 Qualcomm +vendor MOTOROLA4 0x100d Motorola vendor DESKNOTE 0x1019 Desknote vendor GIGABYTE 0x1044 GIGABYTE vendor WESTERN 0x1058 Western Digital @@ -2090,6 +2091,7 @@ product MOTOROLA2 E398 0x4810 E398 Mobile Phone product MOTOROLA2 USBLAN 0x600c USBLAN product MOTOROLA2 USBLAN2 0x6027 USBLAN +product MOTOROLA4 RT2770 0x9031 RT2770 /* MultiTech products */ product MULTITECH ATLAS 0xf101 MT5634ZBA-USB modem @@ -2749,6 +2751,7 @@ product SITECOMEU RT3070_4 0x003d RT3070 product SITECOMEU RT3070 0x003e RT3070 product SITECOMEU WL608 0x003f WL-608 +product SITECOMEU RT3071 0x0040 RT3071 product SITECOMEU RT3072_1 0x0041 RT3072 product SITECOMEU RT3072_2 0x0042 RT3072 product SITECOMEU RT3072_3 0x0047 RT3072 ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_run.c#5 (text+ko) ==== @@ -1,8 +1,9 @@ /* $FreeBSD$ */ /*- - * Copyright (c) 2008,2009 Damien Bergamini <damien.bergamini@free.fr> - * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy@yahoo.ca> + * Copyright (c) 2008,2010 Damien Bergamini <damien.bergamini@free.fr> + * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy@yahoo.ca> + * USB Consulting, Hans Petter Selasky <hselasky@freebsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,8 +18,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* release date Jan. 09, 2010 */ - #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -188,6 +187,7 @@ { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCAG300N) }, { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCG300N) }, { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGN) }, + { USB_VP(USB_VENDOR_MOTOROLA4, USB_PRODUCT_MOTOROLA4_RT2770) }, { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_1) }, { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_2) }, { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_3) }, @@ -234,6 +234,7 @@ { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_2) }, { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_3) }, { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_4) }, + { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3071) }, { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_1) }, { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_2) }, { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_3) }, @@ -340,10 +341,12 @@ static void run_rt2870_set_chan(struct run_softc *, u_int); static void run_rt3070_set_chan(struct run_softc *, u_int); static int run_set_chan(struct run_softc *, struct ieee80211_channel *); +static void run_set_agc(struct run_softc *, uint8_t); static void run_set_channel(struct ieee80211com *); static void run_scan_start(struct ieee80211com *); static void run_scan_end(struct ieee80211com *); static uint8_t run_rate2mcs(uint8_t rate); +static void run_rt3572_set_chan(struct run_softc *, u_int); static void run_update_beacon(struct ieee80211vap *, int); static void run_update_beacon_locked(struct ieee80211vap *, int); static void run_updateprot(struct ieee80211com *ic); @@ -369,6 +372,7 @@ static void run_init(void *); static void run_init_locked(struct run_softc *); static void run_stop(void *); +static void run_rt3070_rf_setup(struct run_softc *); static void run_delay(struct run_softc *, unsigned int); static const struct { @@ -394,8 +398,8 @@ struct { uint8_t n, r, k; -} run_rf3020_freqs[] = { - RT3070_RF3020 +} rt3070_freqs[] = { + RT3070_RF3052 }; static const struct { @@ -403,6 +407,8 @@ uint8_t val; } rt3070_def_rf[] = { RT3070_DEF_RF +},rt3572_def_rf[] = { + RT3572_DEF_RF }; static const struct usb_config run_config[RUN_N_XFER] = { @@ -498,6 +504,7 @@ struct usb_attach_arg *uaa = device_get_ivars(self); struct ieee80211com *ic; struct ifnet *ifp; + uint32_t ver; int i, ntries, error; uint8_t iface_index, bands; @@ -509,11 +516,10 @@ MTX_NETWORK_LOCK, MTX_DEF); iface_index = RT2860_IFACE_INDEX; - /* Rx transfer has own lock */ error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, run_config, RUN_N_XFER, sc, &sc->sc_mtx); if (error) { - device_printf(self, "could not allocate USB Tx transfers, " + device_printf(self, "could not allocate USB transfers, " "err=%s\n", usbd_errstr(error)); goto detach; } @@ -522,11 +528,11 @@ /* wait for the chip to settle */ for (ntries = 0; ntries < 100; ntries++) { - if (run_read(sc, RT2860_ASIC_VER_ID, &sc->mac_rev) != 0){ + if (run_read(sc, RT2860_ASIC_VER_ID, &ver) != 0){ RUN_UNLOCK(sc); goto detach; } - if (sc->mac_rev != 0 && sc->mac_rev != 0xffffffff) + if (ver != 0 && ver != 0xffffffff) break; run_delay(sc, 10); } @@ -536,13 +542,15 @@ RUN_UNLOCK(sc); goto detach; } + sc->mac_ver = ver >> 16; + sc->mac_rev = ver & 0xffff; /* retrieve RF rev. no and various other things from EEPROM */ run_read_eeprom(sc); printf("%s: MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), " - "address %s\n", device_get_nameunit(sc->sc_dev), sc->mac_rev >> 16, - sc->mac_rev & 0xffff, run_get_rf(sc->rf_rev), sc->ntxchains, + "address %s\n", device_get_nameunit(sc->sc_dev), sc->mac_ver, + sc->mac_rev, run_get_rf(sc->rf_rev), sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid)); if ((error = run_load_microcode(sc)) != 0) { @@ -607,7 +615,9 @@ * Do this by own because h/w supports * more channels than ieee80211_init_channels() */ - if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850) { + if (sc->rf_rev == RT2860_RF_2750 || + sc->rf_rev == RT2860_RF_2850 || + sc->rf_rev == RT3070_RF_3052) { /* set supported .11a rates */ for (i = 14; i < nitems(rt2860_rf2850); i++) { uint8_t chan = rt2860_rf2850[i].chan; @@ -823,10 +833,9 @@ * last half is for rt3071. */ base = sc->fwp->data; - if ((sc->mac_rev >> 16) != 0x2860 && - (sc->mac_rev >> 16) != 0x2872 && - (sc->mac_rev >> 16) != 0x3070 && - (sc->mac_rev >> 16) != 0x3572){ + if ((sc->mac_ver) != 0x2860 && + (sc->mac_ver) != 0x2872 && + (sc->mac_ver) != 0x3070){ base += 4096; printf("%s: You are using firmware RT3071.\n", device_get_nameunit(sc->sc_dev)); @@ -857,7 +866,7 @@ run_delay(sc, 10); run_write(sc, RT2860_H2M_MAILBOX, 0); - if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_BOOT, 0)) != 0) + if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0)) != 0) return error; /* wait until microcontroller is ready */ @@ -1270,7 +1279,7 @@ /* check whether the ROM is eFUSE ROM or EEPROM */ sc->sc_srom_read = run_eeprom_read_2; - if ((sc->mac_rev & 0xfff00000) >= 0x30700000) { + if (sc->mac_ver >= 0x3070) { run_read(sc, RT3070_EFUSE_CTRL, &tmp); DPRINTF("EFUSE_CTRL=0x%08x\n", tmp); if (tmp & RT3070_SEL_EFUSE) @@ -1292,21 +1301,32 @@ sc->sc_bssid[4] = val & 0xff; sc->sc_bssid[5] = val >> 8; - /* read default BBP settings */ - for (i = 0; i < 8; i++) { + /* read vender BBP settings */ + for (i = 0; i < 10; i++) { run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val); sc->bbp[i].val = val & 0xff; sc->bbp[i].reg = val >> 8; DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val); } + if (sc->mac_ver >= 0x3071) { + /* read vendor RF settings */ + for (i = 0; i < 10; i++) { + run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, &val); + sc->rf[i].val = val & 0xff; + sc->rf[i].reg = val >> 8; + DPRINTF("RF%d=0x%02x\n", sc->rf[i].reg, + sc->rf[i].val); + } + } /* read RF frequency offset from EEPROM */ run_srom_read(sc, RT2860_EEPROM_FREQ_LEDS, &val); sc->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0; DPRINTF("EEPROM freq offset %d\n", sc->freq & 0xff); - if ((sc->leds = val >> 8) != 0xff) { + if ((val >> 8) != 0xff) { /* read LEDs operating mode */ + sc->leds = val >> 8; run_srom_read(sc, RT2860_EEPROM_LED1, &sc->led[0]); run_srom_read(sc, RT2860_EEPROM_LED2, &sc->led[1]); run_srom_read(sc, RT2860_EEPROM_LED3, &sc->led[2]); @@ -1324,7 +1344,12 @@ run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); if (val == 0xffff) { DPRINTF("invalid EEPROM antenna info, using default\n"); - if ((sc->mac_rev >> 16) >= 0x3070) { + if (sc->mac_ver == 0x3572) { + /* default to RF3052 2T2R */ + sc->rf_rev = RT3070_RF_3052; + sc->ntxchains = 2; + sc->nrxchains = 2; + } else if (sc->mac_ver >= 0x3070) { /* default to RF3020 1T1R */ sc->rf_rev = RT3070_RF_3020; sc->ntxchains = 1; @@ -1343,13 +1368,18 @@ DPRINTF("EEPROM RF rev=0x%02x chains=%dT%dR\n", sc->rf_rev, sc->ntxchains, sc->nrxchains); - /* check if RF supports automatic Tx access gain control */ run_srom_read(sc, RT2860_EEPROM_CONFIG, &val); DPRINTF("EEPROM CFG 0x%04x\n", val); + /* check if driver should patch the DAC issue */ + if ((val >> 8) != 0xff) + sc->patch_dac = (val >> 15) & 1; if ((val & 0xff) != 0xff) { sc->ext_5ghz_lna = (val >> 3) & 1; sc->ext_2ghz_lna = (val >> 2) & 1; + /* check if RF supports automatic Tx access gain control */ sc->calib_2ghz = sc->calib_5ghz = (val >> 1) & 1; + /* check if we have a hardware radio switch */ + sc->rfswitch = val & 1; } /* read power settings for 2GHz channels */ @@ -1372,7 +1402,7 @@ rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]); } /* read power settings for 5GHz channels */ - for (i = 0; i < 36; i += 2) { + for (i = 0; i < 40; i += 2) { run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2, &val); sc->txpow1[i + 14] = (int8_t)(val & 0xff); sc->txpow1[i + 15] = (int8_t)(val >> 8); @@ -1382,7 +1412,7 @@ sc->txpow2[i + 15] = (int8_t)(val >> 8); } /* fix broken Tx power entries */ - for (i = 0; i < 36; i++) { + for (i = 0; i < 40; i++) { if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15) sc->txpow1[14 + i] = 5; if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15) @@ -1431,14 +1461,32 @@ sc->rssi_2ghz[0] = val & 0xff; /* Ant A */ sc->rssi_2ghz[1] = val >> 8; /* Ant B */ run_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ, &val); - sc->rssi_2ghz[2] = val & 0xff; /* Ant C */ + if (sc->mac_ver >= 0x3070) { + /* + * On RT3070 chips (limited to 2 Rx chains), this ROM + * field contains the Tx mixer gain for the 2GHz band. + */ + if ((val & 0xff) != 0xff) + sc->txmixgain_2ghz = val & 0x7; + DPRINTF("tx mixer gain=%u (2GHz)\n", sc->txmixgain_2ghz); + } else + sc->rssi_2ghz[2] = val & 0xff; /* Ant C */ sc->lna[2] = val >> 8; /* channel group 2 */ run_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ, &val); sc->rssi_5ghz[0] = val & 0xff; /* Ant A */ sc->rssi_5ghz[1] = val >> 8; /* Ant B */ run_srom_read(sc, RT2860_EEPROM_RSSI2_5GHZ, &val); - sc->rssi_5ghz[2] = val & 0xff; /* Ant C */ + if (sc->mac_ver == 0x3572) { + /* + * On RT3572 chips (limited to 2 Rx chains), this ROM + * field contains the Tx mixer gain for the 5GHz band. + */ + if ((val & 0xff) != 0xff) + sc->txmixgain_5ghz = val & 0x7; + DPRINTF("tx mixer gain=%u (5GHz)\n", sc->txmixgain_5ghz); + } else + sc->rssi_5ghz[2] = val & 0xff; /* Ant C */ sc->lna[3] = val >> 8; /* channel group 3 */ run_srom_read(sc, RT2860_EEPROM_LNA, &val); @@ -2625,7 +2673,7 @@ dur = rt2860_rates[ridx].sp_ack_dur; else dur = rt2860_rates[ridx].lp_ack_dur; - *(uint16_t *)wh->i_dur = htole16(dur + sc->sifs); + *(uint16_t *)wh->i_dur = htole16(dur); } /* reserve slots for mgmt packets, just in case */ @@ -2992,9 +3040,26 @@ } static void +run_set_agc(struct run_softc *sc, uint8_t agc) +{ + uint8_t bbp; + + if (sc->mac_ver == 0x3572) { + run_bbp_read(sc, 27, &bbp); + bbp &= ~(0x3 << 5); + run_bbp_write(sc, 27, bbp | 0 << 5); /* select Rx0 */ + run_bbp_write(sc, 66, agc); + run_bbp_write(sc, 27, bbp | 1 << 5); /* select Rx1 */ + run_bbp_write(sc, 66, agc); + } else + run_bbp_write(sc, 66, agc); +} + +static void run_select_chan_group(struct run_softc *sc, int group) { uint32_t tmp; + uint8_t agc; run_bbp_write(sc, 62, 0x37 - sc->lna[group]); run_bbp_write(sc, 63, 0x37 - sc->lna[group]); @@ -3010,13 +3075,14 @@ run_bbp_write(sc, 75, 0x50); } } else { - if (sc->ext_5ghz_lna) { + if (sc->mac_ver == 0x3572) + run_bbp_write(sc, 82, 0x94); + else run_bbp_write(sc, 82, 0xf2); + if (sc->ext_5ghz_lna) run_bbp_write(sc, 75, 0x46); - } else { - run_bbp_write(sc, 82, 0xf2); + else run_bbp_write(sc, 75, 0x50); - } } run_read(sc, RT2860_TX_BAND_CFG, &tmp); @@ -3039,13 +3105,26 @@ if (sc->nrxchains > 1) tmp |= RT2860_LNA_PE_A1_EN; } - run_write(sc, RT2860_TX_PIN_CFG, tmp); + if (sc->mac_ver == 0x3572) { + run_rt3070_rf_write(sc, 8, 0x00); + run_write(sc, RT2860_TX_PIN_CFG, tmp); + run_rt3070_rf_write(sc, 8, 0x80); + } else + run_write(sc, RT2860_TX_PIN_CFG, tmp); /* set initial AGC value */ - if (group == 0) - run_bbp_write(sc, 66, 0x2e + sc->lna[0]); - else - run_bbp_write(sc, 66, 0x32 + (sc->lna[group] * 5) / 3); + if (group == 0) { /* 2GHz band */ + if (sc->mac_ver >= 0x3070) + agc = 0x1c + sc->lna[0] * 2; + else + agc = 0x2e + sc->lna[0]; + } else { /* 5GHz band */ + if (sc->mac_ver == 0x3572) + agc = 0x22 + (sc->lna[group] * 5) / 3; + else + agc = 0x32 + (sc->lna[group] * 5) / 3; + } + run_set_agc(sc, agc); } static void @@ -3108,18 +3187,22 @@ { int8_t txpow1, txpow2; uint8_t rf; + int i; /* RT3070 is 2GHz only */ KASSERT(chan >= 1 && chan <= 14, ("wrong channel selected\n")); + /* find the settings for this channel (we know it exists) */ + for (i = 0; rt2860_rf2850[i].chan != chan; i++); + /* use Tx power values from EEPROM */ - txpow1 = sc->txpow1[chan - 1]; - txpow2 = sc->txpow2[chan - 1]; + txpow1 = sc->txpow1[i]; + txpow2 = sc->txpow2[i]; - run_rt3070_rf_write(sc, 2, run_rf3020_freqs[chan - 1].n); - run_rt3070_rf_write(sc, 3, run_rf3020_freqs[chan - 1].k); + run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n); + run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k); run_rt3070_rf_read(sc, 6, &rf); - rf = (rf & ~0x03) | run_rf3020_freqs[chan - 1].r; + rf = (rf & ~0x03) | rt3070_freqs[i].r; run_rt3070_rf_write(sc, 6, rf); /* set Tx0 power */ @@ -3150,12 +3233,166 @@ run_rt3070_rf_write(sc, 23, rf); /* program RF filter */ - run_rt3070_rf_write(sc, 24, sc->rf24_20mhz); - run_rt3070_rf_write(sc, 31, sc->rf24_20mhz); + run_rt3070_rf_read(sc, 24, &rf); /* Tx */ + rf = (rf & ~0x3f) | sc->rf24_20mhz; + run_rt3070_rf_write(sc, 24, rf); + run_rt3070_rf_read(sc, 31, &rf); /* Rx */ + rf = (rf & ~0x3f) | sc->rf24_20mhz; + run_rt3070_rf_write(sc, 31, rf); + + /* enable RF tuning */ + run_rt3070_rf_read(sc, 7, &rf); + run_rt3070_rf_write(sc, 7, rf | 0x01); +} + +static void +run_rt3572_set_chan(struct run_softc *sc, u_int chan) +{ + int8_t txpow1, txpow2; + uint32_t tmp; + uint8_t rf; + int i; + + /* find the settings for this channel (we know it exists) */ + for (i = 0; rt2860_rf2850[i].chan != chan; i++); + + /* use Tx power values from EEPROM */ + txpow1 = sc->txpow1[i]; + txpow2 = sc->txpow2[i]; + + if (chan <= 14) { + run_bbp_write(sc, 25, sc->bbp25); + run_bbp_write(sc, 26, sc->bbp26); + } else { + /* enable IQ phase correction */ + run_bbp_write(sc, 25, 0x09); + run_bbp_write(sc, 26, 0xff); + } + + run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n); + run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k); + run_rt3070_rf_read(sc, 6, &rf); + rf = (rf & ~0x0f) | rt3070_freqs[i].r; + rf |= (chan <= 14) ? 0x08 : 0x04; + run_rt3070_rf_write(sc, 6, rf); + + /* set PLL mode */ + run_rt3070_rf_read(sc, 5, &rf); + rf &= ~(0x08 | 0x04); + rf |= (chan <= 14) ? 0x04 : 0x08; + run_rt3070_rf_write(sc, 5, rf); + + /* set Tx power for chain 0 */ + if (chan <= 14) + rf = 0x60 | txpow1; + else + rf = 0xe0 | (txpow1 & 0xc) << 1 | (txpow1 & 0x3); + run_rt3070_rf_write(sc, 12, rf); + + /* set Tx power for chain 1 */ + if (chan <= 14) + rf = 0x60 | txpow2; + else + rf = 0xe0 | (txpow2 & 0xc) << 1 | (txpow2 & 0x3); + run_rt3070_rf_write(sc, 13, rf); + + /* set Tx/Rx streams */ + run_rt3070_rf_read(sc, 1, &rf); + rf &= ~0xfc; + if (sc->ntxchains == 1) + rf |= 1 << 7 | 1 << 5; /* 1T: disable Tx chains 2 & 3 */ + else if (sc->ntxchains == 2) + rf |= 1 << 7; /* 2T: disable Tx chain 3 */ + if (sc->nrxchains == 1) + rf |= 1 << 6 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */ + else if (sc->nrxchains == 2) + rf |= 1 << 6; /* 2R: disable Rx chain 3 */ + run_rt3070_rf_write(sc, 1, rf); + + /* set RF offset */ + run_rt3070_rf_read(sc, 23, &rf); + rf = (rf & ~0x7f) | sc->freq; + run_rt3070_rf_write(sc, 23, rf); + + /* program RF filter */ + rf = sc->rf24_20mhz; + run_rt3070_rf_write(sc, 24, rf); /* Tx */ + run_rt3070_rf_write(sc, 31, rf); /* Rx */ + + /* enable RF tuning */ + run_rt3070_rf_read(sc, 7, &rf); + rf = (chan <= 14) ? 0xd8 : ((rf & ~0xc8) | 0x14); + run_rt3070_rf_write(sc, 7, rf); + + /* TSSI */ + rf = (chan <= 14) ? 0xc3 : 0xc0; + run_rt3070_rf_write(sc, 9, rf); + + /* set loop filter 1 */ + run_rt3070_rf_write(sc, 10, 0xf1); + /* set loop filter 2 */ + run_rt3070_rf_write(sc, 11, (chan <= 14) ? 0xb9 : 0x00); + + /* set tx_mx2_ic */ + run_rt3070_rf_write(sc, 15, (chan <= 14) ? 0x53 : 0x43); + /* set tx_mx1_ic */ + if (chan <= 14) + rf = 0x48 | sc->txmixgain_2ghz; + else + rf = 0x78 | sc->txmixgain_5ghz; + run_rt3070_rf_write(sc, 16, rf); + + /* set tx_lo1 */ + run_rt3070_rf_write(sc, 17, 0x23); + /* set tx_lo2 */ + if (chan <= 14) + rf = 0x93; + else if (chan <= 64) + rf = 0xb7; + else if (chan <= 128) + rf = 0x74; + else + rf = 0x72; + run_rt3070_rf_write(sc, 19, rf); + + /* set rx_lo1 */ + if (chan <= 14) + rf = 0xb3; + else if (chan <= 64) + rf = 0xf6; + else if (chan <= 128) + rf = 0xf4; + else + rf = 0xf3; + run_rt3070_rf_write(sc, 20, rf); + + /* set pfd_delay */ + if (chan <= 14) + rf = 0x15; + else if (chan <= 64) + rf = 0x3d; + else + rf = 0x01; + run_rt3070_rf_write(sc, 25, rf); + + /* set rx_lo2 */ + run_rt3070_rf_write(sc, 26, (chan <= 14) ? 0x85 : 0x87); + /* set ldo_rf_vc */ + run_rt3070_rf_write(sc, 27, (chan <= 14) ? 0x00 : 0x01); + /* set drv_cc */ + run_rt3070_rf_write(sc, 29, (chan <= 14) ? 0x9b : 0x9f); + + run_read(sc, RT2860_GPIO_CTRL, &tmp); + tmp &= ~0x8080; + if (chan <= 14) + tmp |= 0x80; + run_write(sc, RT2860_GPIO_CTRL, tmp); /* enable RF tuning */ run_rt3070_rf_read(sc, 7, &rf); run_rt3070_rf_write(sc, 7, rf | 0x01); + + run_delay(sc, 2); } static void @@ -3164,13 +3401,11 @@ uint32_t tmp; if (aux) { - run_read(sc, RT2860_PCI_EECTRL, &tmp); - run_write(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C); + run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 0); run_read(sc, RT2860_GPIO_CTRL, &tmp); run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08); } else { - run_read(sc, RT2860_PCI_EECTRL, &tmp); - run_write(sc, RT2860_PCI_EECTRL, tmp | RT2860_C); + run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 1); run_read(sc, RT2860_GPIO_CTRL, &tmp); run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808); } @@ -3186,14 +3421,13 @@ if (chan == 0 || chan == IEEE80211_CHAN_ANY) return EINVAL; - if ((sc->mac_rev >> 16) >= 0x3070) + if (sc->mac_ver == 0x3572) + run_rt3572_set_chan(sc, chan); + else if (sc->mac_ver >= 0x3070) run_rt3070_set_chan(sc, chan); else run_rt2870_set_chan(sc, chan); - /* 802.11a uses a 16 microseconds short interframe space */ - sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10; - /* determine channel group */ if (chan <= 14) group = 0; @@ -3359,7 +3593,7 @@ struct run_softc *sc = arg; struct ieee80211vap *vap = &sc->sc_rvp->vap; - RUN_LOCK_ASSERT(sc, MA_OWNED); + RUN_LOCK(sc); if(vap->iv_state == IEEE80211_S_RUN && vap->iv_opmode != IEEE80211_M_STA) @@ -3370,6 +3604,8 @@ ieee80211_cancel_scan(vap); } else DPRINTF("timeout by unknown cause\n"); + + RUN_UNLOCK(sc); } static void @@ -3604,15 +3840,14 @@ } /* fix BBP84 for RT2860E */ - if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101) - run_bbp_write(sc, 84, 0x19); + if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101) + run_bbp_write(sc, 84, 0x19); - if ((sc->mac_rev >> 16) >= 0x3070) { + if (sc->mac_ver >= 0x3070) { run_bbp_write(sc, 79, 0x13); run_bbp_write(sc, 80, 0x05); run_bbp_write(sc, 81, 0x33); - /* XXX RT3090 needs more */ - } else if (sc->mac_rev == 0x28600100) { + } else if (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) { run_bbp_write(sc, 69, 0x16); run_bbp_write(sc, 73, 0x12); } @@ -3623,7 +3858,7 @@ run_rt3070_rf_init(struct run_softc *sc) { uint32_t tmp; - uint8_t rf, bbp4; + uint8_t rf, target, bbp4; int i; run_rt3070_rf_read(sc, 30, &rf); @@ -3633,44 +3868,58 @@ run_rt3070_rf_write(sc, 30, rf & ~0x80); /* initialize RF registers to default value */ - for (i = 0; i < nitems(rt3070_def_rf); i++) { - run_rt3070_rf_write(sc, rt3070_def_rf[i].reg, - rt3070_def_rf[i].val); + if (sc->mac_ver == 0x3572) { + for (i = 0; i < nitems(rt3572_def_rf); i++) { + run_rt3070_rf_write(sc, rt3572_def_rf[i].reg, + rt3572_def_rf[i].val); + } + } else { + for (i = 0; i < nitems(rt3070_def_rf); i++) { + run_rt3070_rf_write(sc, rt3070_def_rf[i].reg, + rt3070_def_rf[i].val); + } } - if ((sc->mac_rev >> 16) == 0x3070) { + + if (sc->mac_ver == 0x3070) { /* change voltage from 1.2V to 1.35V for RT3070 */ run_read(sc, RT3070_LDO_CFG0, &tmp); tmp = (tmp & ~0x0f000000) | 0x0d000000; run_write(sc, RT3070_LDO_CFG0, tmp); - } else if ((sc->mac_rev >> 16) == 0x3071) { + } else if (sc->mac_ver == 0x3071) { run_rt3070_rf_read(sc, 6, &rf); run_rt3070_rf_write(sc, 6, rf | 0x40); run_rt3070_rf_write(sc, 31, 0x14); run_read(sc, RT3070_LDO_CFG0, &tmp); tmp &= ~0x1f000000; - if ((sc->mac_rev & 0xffff) < 0x0211) - tmp |= 0x0d000000; + if (sc->mac_rev < 0x0211) + tmp |= 0x0d000000; /* 1.3V */ else - tmp |= 0x01000000; + tmp |= 0x01000000; /* 1.2V */ run_write(sc, RT3070_LDO_CFG0, tmp); /* patch LNA_PE_G1 */ run_read(sc, RT3070_GPIO_SWITCH, &tmp); run_write(sc, RT3070_GPIO_SWITCH, tmp & ~0x20); - } else if((sc->mac_rev >> 16) == 0x3572){ - if ((sc->mac_rev & 0xffff) < 0x0211){ + } else if(sc->mac_ver == 0x3572){ + run_rt3070_rf_read(sc, 6, &rf); + run_rt3070_rf_write(sc, 6, rf | 0x40); + + if (sc->mac_rev < 0x0211){ + /* increase voltage from 1.2V to 1.35V */ run_read(sc, RT3070_LDO_CFG0, &tmp); tmp = (tmp & ~0x0f000000) | 0x0d000000; run_write(sc, RT3070_LDO_CFG0, tmp); } else { + /* increase voltage from 1.2V to 1.35V */ run_read(sc, RT3070_LDO_CFG0, &tmp); tmp = (tmp & ~0x1f000000) | 0x0d000000; run_write(sc, RT3070_LDO_CFG0, tmp); run_delay(sc, 1); /* wait for 1msec */ + /* decrease voltage back to 1.2V */ tmp = (tmp & ~0x1f000000) | 0x01000000; run_write(sc, RT3070_LDO_CFG0, tmp); } @@ -3682,27 +3931,47 @@ /* calibrate filter for 20MHz bandwidth */ sc->rf24_20mhz = 0x1f; /* default value */ - run_rt3070_filter_calib(sc, 0x07, 0x16, &sc->rf24_20mhz); + target = (sc->mac_ver < 0x3071) ? 0x16 : 0x13; + run_rt3070_filter_calib(sc, 0x07, target, &sc->rf24_20mhz); /* 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 */ - run_rt3070_filter_calib(sc, 0x27, 0x19, &sc->rf24_40mhz); + target = (sc->mac_ver < 0x3071) ? 0x19 : 0x15; + run_rt3070_filter_calib(sc, 0x27, target, &sc->rf24_40mhz); /* go back to 20MHz bandwidth */ run_bbp_read(sc, 4, &bbp4); run_bbp_write(sc, 4, bbp4 & ~0x18); - if ((sc->mac_rev & 0xffff) < 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_rev >> 16) == 0x3071) { + 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_rev == 0x3071) { run_rt3070_rf_read(sc, 1, &rf); rf &= ~(RT3070_RX0_PD | RT3070_TX0_PD); rf |= RT3070_RF_BLOCK | RT3070_RX1_PD | RT3070_TX1_PD; @@ -3711,21 +3980,18 @@ 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 & 0xffff) >= 0x0211 && !sc->ext_2ghz_lna) - rf |= 0x20; /* fix for long range Rx issue */ - 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; - if ((sc->mac_rev & 0xffff) < 0x0211) + if (sc->mac_rev < 0x0211) rf |= 0x03; run_rt3070_rf_write(sc, 27, rf); } @@ -3741,7 +4007,8 @@ 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 */ @@ -3796,6 +4063,86 @@ return 0; } +static 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); + } + + 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].reg == 0xff) + continue; + run_rt3070_rf_write(sc, sc->rf[i].reg, sc->rf[i].val); + } + } +} + static int run_txrx_enable(struct run_softc *sc) { @@ -3916,12 +4263,10 @@ run_write(sc, RT2860_WMM_CWMIN_CFG, 0x00002344); run_write(sc, RT2860_WMM_CWMAX_CFG, 0x000034aa); - if ((sc->mac_rev >> 16) >= 0x3070) { + if (sc->mac_ver >= 0x3070) { /* 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 */ @@ -3965,7 +4310,7 @@ tmp = (tmp & ~0xff) | 0x1e; run_write(sc, RT2860_US_CYC_CNT, tmp); - if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101) + if (sc->mac_rev != 0x0101) run_write(sc, RT2860_TXOP_CTRL_CFG, 0x0000583f); run_write(sc, RT2860_WMM_TXOP0_CFG, 0); @@ -3987,6 +4332,9 @@ (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); @@ -4002,8 +4350,8 @@ bbp1 &= ~(1 << 3 | 1 << 4); run_bbp_write(sc, 1, bbp1); - if ((sc->mac_rev >> 16) >= 0x3070) - run_rt3070_rf_init(sc); + if (sc->mac_ver >= 0x3070) + run_rt3070_rf_setup(sc); /* select default channel */ vap->iv_bss->ni_chan = ic->ic_curchan; /* ic_bsschan?? */ ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_runreg.h#3 (text+ko) ==== @@ -308,7 +308,8 @@ #define RT2860_MCU_CMD_LED1 0x52 >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002210853.o1L8rXij054451>
