PERFORCE change 174936 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Feb 21 08:53:34 UTC 2010
http://p4web.freebsd.org/chv.cgi?CH=174936
Change 174936 by hselasky at 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 at free.fr>
- * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy at yahoo.ca>
+ * Copyright (c) 2008,2010 Damien Bergamini <damien.bergamini at free.fr>
+ * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy at yahoo.ca>
+ * USB Consulting, Hans Petter Selasky <hselasky at 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) <<<
More information about the p4-projects
mailing list