Module Name: src
Committed By: mlelstv
Date: Fri Sep 16 09:25:30 UTC 2016
Modified Files:
src/sys/dev/ic: rt2860reg.h
src/sys/dev/usb: if_run.c if_runvar.h
src/sys/net80211: ieee80211.h
Log Message:
Merge enough FreeBSD code to make RT5592 work.
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/ic/rt2860reg.h
cvs rdiff -u -r1.15 -r1.16 src/sys/dev/usb/if_run.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/usb/if_runvar.h
cvs rdiff -u -r1.27 -r1.28 src/sys/net80211/ieee80211.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ic/rt2860reg.h
diff -u src/sys/dev/ic/rt2860reg.h:1.5 src/sys/dev/ic/rt2860reg.h:1.6
--- src/sys/dev/ic/rt2860reg.h:1.5 Fri Jul 8 01:24:53 2016
+++ src/sys/dev/ic/rt2860reg.h Fri Sep 16 09:25:30 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: rt2860reg.h,v 1.5 2016/07/08 01:24:53 christos Exp $ */
+/* $NetBSD: rt2860reg.h,v 1.6 2016/09/16 09:25:30 mlelstv Exp $ */
/* $OpenBSD: rt2860reg.h,v 1.32 2014/05/24 10:10:17 stsp Exp $ */
/*-
@@ -83,6 +83,8 @@
#define RT3070_LDO_CFG0 0x05d4
#define RT3070_GPIO_SWITCH 0x05dc
+
+
/* RT5592 registers */
#define RT5592_DEBUG_INDEX 0x05e8
@@ -783,6 +785,12 @@
/* possible flags for RT3053 RF register 51 */
#define RT3593_TX_LO1 (1U << 4)
+/* Possible flags for RT5390 RF register 2. */
+#define RT5390_RESCAL (1 << 7)
+
+/* Possible flags for RT5390 RF register 3. */
+#define RT5390_VCOCAL (1 << 7)
+
/* Possible flags for RT5390 BBP register 4. */
#define RT5390_MAC_IF_CTRL (1U << 6)
Index: src/sys/dev/usb/if_run.c
diff -u src/sys/dev/usb/if_run.c:1.15 src/sys/dev/usb/if_run.c:1.16
--- src/sys/dev/usb/if_run.c:1.15 Fri Jun 10 13:27:15 2016
+++ src/sys/dev/usb/if_run.c Fri Sep 16 09:25:30 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_run.c,v 1.15 2016/06/10 13:27:15 ozaki-r Exp $ */
+/* $NetBSD: if_run.c,v 1.16 2016/09/16 09:25:30 mlelstv Exp $ */
/* $OpenBSD: if_run.c,v 1.90 2012/03/24 15:11:04 jsg Exp $ */
/*-
@@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_run.c,v 1.15 2016/06/10 13:27:15 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_run.c,v 1.16 2016/09/16 09:25:30 mlelstv Exp $");
#include <sys/param.h>
#include <sys/sockio.h>
@@ -74,6 +74,8 @@ int run_debug = 0;
#define DPRINTFN(n, x)
#endif
+#define IEEE80211_HAS_ADDR4(wh) IEEE80211_IS_DSTODS(wh)
+
#define USB_ID(v, p) { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }
static const struct usb_devno run_devs[] = {
USB_ID(ABOCOM, RT2770),
@@ -251,6 +253,7 @@ static const struct usb_devno run_devs[]
USB_ID(RALINK, RT3072),
USB_ID(RALINK, RT3370),
USB_ID(RALINK, RT3572),
+ USB_ID(RALINK, RT5572),
USB_ID(RALINK, RT8070),
USB_ID(SAMSUNG, RT2870_1),
USB_ID(SENAO, RT2870_1),
@@ -329,6 +332,8 @@ static int run_write_region_1(struct ru
const uint8_t *, int);
static int run_set_region_4(struct run_softc *, uint16_t,
uint32_t, int);
+static int run_efuse_read(struct run_softc *, uint16_t,
+ uint16_t *, int);
static int run_efuse_read_2(struct run_softc *, uint16_t,
uint16_t *);
static int run_eeprom_read_2(struct run_softc *, uint16_t,
@@ -343,6 +348,8 @@ static int run_bbp_read(struct run_soft
static int run_bbp_write(struct run_softc *, uint8_t, uint8_t);
static int run_mcu_cmd(struct run_softc *, uint8_t, uint16_t);
static const char * run_get_rf(int);
+static void run_rt3593_get_txpower(struct run_softc *);
+static void run_get_txpower(struct run_softc *);
static int run_read_eeprom(struct run_softc *);
static struct ieee80211_node *
run_node_alloc(struct ieee80211_node_table *);
@@ -378,13 +385,18 @@ static void run_start(struct ifnet *);
static void run_watchdog(struct ifnet *);
static int run_ioctl(struct ifnet *, u_long, void *);
static void run_select_chan_group(struct run_softc *, int);
+static void run_iq_calib(struct run_softc *, u_int);
static void run_set_agc(struct run_softc *, uint8_t);
static void run_set_rx_antenna(struct run_softc *, int);
static void run_rt2870_set_chan(struct run_softc *, u_int);
static void run_rt3070_set_chan(struct run_softc *, u_int);
static void run_rt3572_set_chan(struct run_softc *, u_int);
+static void run_rt3593_set_chan(struct run_softc *, u_int);
+static void run_rt5390_set_chan(struct run_softc *, u_int);
+static void run_rt5592_set_chan(struct run_softc *, u_int);
static int run_set_chan(struct run_softc *,
struct ieee80211_channel *);
+static void run_updateprot(struct run_softc *);
static void run_enable_tsf_sync(struct run_softc *);
static void run_enable_mrr(struct run_softc *);
static void run_set_txpreamble(struct run_softc *);
@@ -395,12 +407,18 @@ static void run_set_macaddr(struct run_
static void run_updateslot(struct ifnet *);
static void run_updateslot_cb(struct run_softc *, void *);
static int8_t run_rssi2dbm(struct run_softc *, uint8_t, uint8_t);
+static void run_rt5390_bbp_init(struct run_softc *);
static int run_bbp_init(struct run_softc *);
static int run_rt3070_rf_init(struct run_softc *);
+static int run_rt3593_rf_init(struct run_softc *);
+static int run_rt5390_rf_init(struct run_softc *);
static int run_rt3070_filter_calib(struct run_softc *, uint8_t,
uint8_t, uint8_t *);
static void run_rt3070_rf_setup(struct run_softc *);
+static void run_rt3593_rf_setup(struct run_softc *);
+static void run_rt5390_rf_setup(struct run_softc *);
static int run_txrx_enable(struct run_softc *);
+static int run_adjust_freq_offset(struct run_softc *);
static int run_init(struct ifnet *);
static void run_stop(struct ifnet *, int);
#ifndef IEEE80211_STA_ONLY
@@ -419,6 +437,25 @@ static const struct {
uint8_t val;
} rt2860_def_bbp[] = {
RT2860_DEF_BBP
+}, rt5390_def_bbp[] = {
+ RT5390_DEF_BBP
+}, rt5592_def_bbp[] = {
+ RT5592_DEF_BBP
+};
+
+/*
+ * Default values for BBP register R196 for RT5592.
+ */
+static const uint8_t rt5592_bbp_r196[] = {
+ 0xe0, 0x1f, 0x38, 0x32, 0x08, 0x28, 0x19, 0x0a, 0xff, 0x00,
+ 0x16, 0x10, 0x10, 0x0b, 0x36, 0x2c, 0x26, 0x24, 0x42, 0x36,
+ 0x30, 0x2d, 0x4c, 0x46, 0x3d, 0x40, 0x3e, 0x42, 0x3d, 0x40,
+ 0x3c, 0x34, 0x2c, 0x2f, 0x3c, 0x35, 0x2e, 0x2a, 0x49, 0x41,
+ 0x36, 0x31, 0x30, 0x30, 0x0e, 0x0d, 0x28, 0x21, 0x1c, 0x16,
+ 0x50, 0x4a, 0x43, 0x40, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7d, 0x14, 0x32, 0x2c, 0x36, 0x4c, 0x43, 0x2c,
+ 0x2e, 0x36, 0x30, 0x6e
};
static const struct rfprog {
@@ -434,6 +471,15 @@ static const struct {
RT3070_RF3052
};
+static const struct rt5592_freqs {
+ uint16_t n;
+ uint8_t k, m, r;
+} rt5592_freqs_20mhz[] = {
+ RT5592_RF5592_20MHZ
+},rt5592_freqs_40mhz[] = {
+ RT5592_RF5592_40MHZ
+};
+
static const struct {
uint8_t reg;
uint8_t val;
@@ -441,6 +487,27 @@ static const struct {
RT3070_DEF_RF
}, rt3572_def_rf[] = {
RT3572_DEF_RF
+},rt3593_def_rf[] = {
+ RT3593_DEF_RF
+},rt5390_def_rf[] = {
+ RT5390_DEF_RF
+},rt5392_def_rf[] = {
+ RT5392_DEF_RF
+},rt5592_def_rf[] = {
+ RT5592_DEF_RF
+},rt5592_2ghz_def_rf[] = {
+ RT5592_2GHZ_DEF_RF
+},rt5592_5ghz_def_rf[] = {
+ RT5592_5GHZ_DEF_RF
+};
+
+static const struct {
+ u_int firstchan;
+ u_int lastchan;
+ uint8_t reg;
+ uint8_t val;
+} rt5592_chan_5ghz[] = {
+ RT5592_CHAN_5GHZ
};
static int
@@ -596,7 +663,9 @@ run_attach(device_t parent, device_t sel
if (sc->rf_rev == RT2860_RF_2750 ||
sc->rf_rev == RT2860_RF_2850 ||
- sc->rf_rev == RT3070_RF_3052) {
+ sc->rf_rev == RT3070_RF_3052 ||
+ sc->rf_rev == RT3070_RF_3053 ||
+ sc->rf_rev == RT5592_RF_5592) {
/* set supported .11a rates */
ic->ic_sup_rates[IEEE80211_MODE_11A] =
ieee80211_std_rateset_11a;
@@ -698,6 +767,9 @@ run_detach(device_t self, int flags)
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
+ callout_stop(&sc->scan_to);
+ callout_stop(&sc->calib_to);
+
callout_destroy(&sc->scan_to);
callout_destroy(&sc->calib_to);
@@ -872,7 +944,7 @@ run_load_microcode(struct run_softc *sc)
return error;
if (tmp & RT2860_MCU_READY)
break;
- DELAY(1000);
+ usbd_delay_ms(sc->sc_udev, 10);
}
if (ntries == 1000) {
aprint_error_dev(sc->sc_dev,
@@ -985,9 +1057,8 @@ run_set_region_4(struct run_softc *sc, u
return error;
}
-/* Read 16-bit from eFUSE ROM (RT3070 only.) */
static int
-run_efuse_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val)
+run_efuse_read(struct run_softc *sc, uint16_t addr, uint16_t *val, int count)
{
uint32_t tmp;
uint16_t reg;
@@ -996,7 +1067,8 @@ run_efuse_read_2(struct run_softc *sc, u
if ((error = run_read(sc, RT3070_EFUSE_CTRL, &tmp)) != 0)
return error;
- addr *= 2;
+ if (count == 2)
+ addr *= 2;
/*-
* Read one 16-byte block into registers EFUSE_DATA[0-3]:
* DATA0: F E D C
@@ -1012,7 +1084,7 @@ run_efuse_read_2(struct run_softc *sc, u
return error;
if (!(tmp & RT3070_EFSROM_KICK))
break;
- DELAY(2);
+ usbd_delay_ms(sc->sc_udev, 2);
}
if (ntries == 100)
return ETIMEDOUT;
@@ -1026,10 +1098,17 @@ run_efuse_read_2(struct run_softc *sc, u
if ((error = run_read(sc, reg, &tmp)) != 0)
return error;
- *val = (addr & 2) ? tmp >> 16 : tmp & 0xffff;
+ *val = (addr & 1) ? tmp >> 16 : tmp & 0xffff;
return 0;
}
+/* Read 16-bit from eFUSE ROM for RT3xxxx. */
+static int
+run_efuse_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val)
+{
+ return (run_efuse_read(sc, addr, val, 2));
+}
+
static int
run_eeprom_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val)
{
@@ -1240,10 +1319,133 @@ run_get_rf(int rev)
case RT3070_RF_3021: return "RT3021";
case RT3070_RF_3022: return "RT3022";
case RT3070_RF_3052: return "RT3052";
+ case RT3070_RF_3053: return "RT3053";
+ case RT5592_RF_5592: return "RT5592";
+ case RT5390_RF_5370: return "RT5370";
+ case RT5390_RF_5372: return "RT5372";
}
return "unknown";
}
+static void
+run_rt3593_get_txpower(struct run_softc *sc)
+{
+ uint16_t addr, val;
+ int i;
+
+ /* Read power settings for 2GHz channels. */
+ for (i = 0; i < 14; i += 2) {
+ addr = (sc->ntxchains == 3) ? RT3593_EEPROM_PWR2GHZ_BASE1 :
+ RT2860_EEPROM_PWR2GHZ_BASE1;
+ run_srom_read(sc, addr + i / 2, &val);
+ sc->txpow1[i + 0] = (int8_t)(val & 0xff);
+ sc->txpow1[i + 1] = (int8_t)(val >> 8);
+
+ addr = (sc->ntxchains == 3) ? RT3593_EEPROM_PWR2GHZ_BASE2 :
+ RT2860_EEPROM_PWR2GHZ_BASE2;
+ run_srom_read(sc, addr + i / 2, &val);
+ sc->txpow2[i + 0] = (int8_t)(val & 0xff);
+ sc->txpow2[i + 1] = (int8_t)(val >> 8);
+
+ if (sc->ntxchains == 3) {
+ run_srom_read(sc, RT3593_EEPROM_PWR2GHZ_BASE3 + i / 2,
+ &val);
+ sc->txpow3[i + 0] = (int8_t)(val & 0xff);
+ sc->txpow3[i + 1] = (int8_t)(val >> 8);
+ }
+ }
+ /* Fix broken Tx power entries. */
+ for (i = 0; i < 14; i++) {
+ if (sc->txpow1[i] > 31)
+ sc->txpow1[i] = 5;
+ if (sc->txpow2[i] > 31)
+ sc->txpow2[i] = 5;
+ if (sc->ntxchains == 3) {
+ if (sc->txpow3[i] > 31)
+ sc->txpow3[i] = 5;
+ }
+ }
+ /* Read power settings for 5GHz channels. */
+ for (i = 0; i < 40; i += 2) {
+ run_srom_read(sc, RT3593_EEPROM_PWR5GHZ_BASE1 + i / 2, &val);
+ sc->txpow1[i + 14] = (int8_t)(val & 0xff);
+ sc->txpow1[i + 15] = (int8_t)(val >> 8);
+
+ run_srom_read(sc, RT3593_EEPROM_PWR5GHZ_BASE2 + i / 2, &val);
+ sc->txpow2[i + 14] = (int8_t)(val & 0xff);
+ sc->txpow2[i + 15] = (int8_t)(val >> 8);
+
+ if (sc->ntxchains == 3) {
+ run_srom_read(sc, RT3593_EEPROM_PWR5GHZ_BASE3 + i / 2,
+ &val);
+ sc->txpow3[i + 14] = (int8_t)(val & 0xff);
+ sc->txpow3[i + 15] = (int8_t)(val >> 8);
+ }
+ }
+}
+
+static void
+run_get_txpower(struct run_softc *sc)
+{
+ uint16_t val;
+ int i;
+
+ /* Read power settings for 2GHz channels. */
+ for (i = 0; i < 14; i += 2) {
+ run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2, &val);
+ sc->txpow1[i + 0] = (int8_t)(val & 0xff);
+ sc->txpow1[i + 1] = (int8_t)(val >> 8);
+
+ if (sc->mac_ver != 0x5390) {
+ run_srom_read(sc,
+ RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val);
+ sc->txpow2[i + 0] = (int8_t)(val & 0xff);
+ sc->txpow2[i + 1] = (int8_t)(val >> 8);
+ }
+ }
+ /* Fix broken Tx power entries. */
+ for (i = 0; i < 14; i++) {
+ if (sc->mac_ver >= 0x5390) {
+ if (sc->txpow1[i] < 0 || sc->txpow1[i] > 39)
+ sc->txpow1[i] = 5;
+ } else {
+ if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31)
+ sc->txpow1[i] = 5;
+ }
+ if (sc->mac_ver > 0x5390) {
+ if (sc->txpow2[i] < 0 || sc->txpow2[i] > 39)
+ sc->txpow2[i] = 5;
+ } else if (sc->mac_ver < 0x5390) {
+ if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31)
+ sc->txpow2[i] = 5;
+ }
+ DPRINTF(("chan %d: power1=%d, power2=%d\n",
+ rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]));
+ }
+ /* Read power settings for 5GHz channels. */
+ 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);
+
+ run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2, &val);
+ sc->txpow2[i + 14] = (int8_t)(val & 0xff);
+ sc->txpow2[i + 15] = (int8_t)(val >> 8);
+ }
+ /* Fix broken Tx power entries. */
+ for (i = 0; i < 40; i++ ) {
+ if (sc->mac_ver != 0x5592) {
+ 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)
+ sc->txpow2[14 + i] = 5;
+ }
+ DPRINTF(("chan %d: power1=%d, power2=%d\n",
+ rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i],
+ sc->txpow2[14 + i]));
+ }
+}
+
static int
run_read_eeprom(struct run_softc *sc)
{
@@ -1284,15 +1486,14 @@ run_read_eeprom(struct run_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 >= 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 vendor RF settings */
+ for (i = 0; i < 8; 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 */
@@ -1358,45 +1559,11 @@ run_read_eeprom(struct run_softc *sc)
sc->rfswitch = val & 1;
}
- /* read power settings for 2GHz channels */
- for (i = 0; i < 14; i += 2) {
- run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2, &val);
- sc->txpow1[i + 0] = (int8_t)(val & 0xff);
- sc->txpow1[i + 1] = (int8_t)(val >> 8);
-
- run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val);
- sc->txpow2[i + 0] = (int8_t)(val & 0xff);
- sc->txpow2[i + 1] = (int8_t)(val >> 8);
- }
- /* fix broken Tx power entries */
- for (i = 0; i < 14; i++) {
- if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31)
- sc->txpow1[i] = 5;
- if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31)
- sc->txpow2[i] = 5;
- DPRINTF(("chan %d: power1=%d, power2=%d\n",
- rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]));
- }
- /* read power settings for 5GHz channels */
- 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);
-
- run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2, &val);
- sc->txpow2[i + 14] = (int8_t)(val & 0xff);
- sc->txpow2[i + 15] = (int8_t)(val >> 8);
- }
- /* fix broken Tx power entries */
- 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)
- sc->txpow2[14 + i] = 5;
- DPRINTF(("chan %d: power1=%d, power2=%d\n",
- rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i],
- sc->txpow2[14 + i]));
- }
+ /* Read Tx power settings. */
+ if (sc->mac_ver == 0x3593)
+ run_rt3593_get_txpower(sc);
+ else
+ run_get_txpower(sc);
/* read Tx power compensation for each Tx rate */
run_srom_read(sc, RT2860_EEPROM_DELTAPWR, &val);
@@ -1438,22 +1605,31 @@ run_read_eeprom(struct run_softc *sc)
sc->rssi_2ghz[1] = val >> 8; /* Ant B */
run_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ, &val);
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;
+ if (sc->mac_ver == 0x3593) {
+ sc->txmixgain_2ghz = 0;
+ sc->rssi_2ghz[2] = val & 0xff; /* Ant C */
+ } else {
+ /*
+ * 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 */
}
+ if (sc->mac_ver == 0x3593)
+ run_srom_read(sc, RT3593_EEPROM_LNA_5GHZ, &val);
sc->lna[2] = val >> 8; /* channel group 2 */
- run_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ, &val);
+ run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_RSSI1_5GHZ :
+ RT3593_EEPROM_RSSI2_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);
+ run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_RSSI2_5GHZ :
+ RT3593_EEPROM_RSSI2_5GHZ, &val);
if (sc->mac_ver == 0x3572) {
/*
* On RT3572 chips (limited to 2 Rx chains), this ROM
@@ -1465,9 +1641,14 @@ run_read_eeprom(struct run_softc *sc)
} else {
sc->rssi_5ghz[2] = val & 0xff; /* Ant C */
}
+ if (sc->mac_ver == 0x3593) {
+ sc->txmixgain_5ghz = 0;
+ run_srom_read(sc, RT3593_EEPROM_LNA_5GHZ, &val);
+ }
sc->lna[3] = val >> 8; /* channel group 3 */
- run_srom_read(sc, RT2860_EEPROM_LNA, &val);
+ run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_LNA :
+ RT3593_EEPROM_LNA, &val);
sc->lna[0] = val & 0xff; /* channel group 0 */
sc->lna[1] = val >> 8; /* channel group 1 */
@@ -2010,7 +2191,7 @@ run_rx_frame(struct run_softc *sc, uint8
struct rt2860_rxwi *rxwi;
struct mbuf *m;
uint32_t flags;
- uint16_t len, phy;
+ uint16_t len, rxwisize, phy;
uint8_t ant, rssi;
int s;
#ifdef RUN_HWCRYPTO
@@ -2032,7 +2213,13 @@ run_rx_frame(struct run_softc *sc, uint8
return;
}
- wh = (struct ieee80211_frame *)(rxwi + 1);
+ rxwisize = sizeof(struct rt2860_rxwi);
+ if (sc->mac_ver == 0x5592)
+ rxwisize += sizeof(uint64_t);
+ else if (sc->mac_ver == 0x3593)
+ rxwisize += sizeof(uint32_t);
+
+ wh = (struct ieee80211_frame *)(((uint8_t *)rxwi) + rxwisize);
#ifdef RUN_HWCRYPTO
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
@@ -2169,7 +2356,8 @@ run_rxeof(struct usbd_xfer *xfer, void *
while (xferlen > 8) {
dmalen = le32toh(*(uint32_t *)buf) & 0xffff;
- if (__predict_false(dmalen == 0 || (dmalen & 3) != 0)) {
+ if (__predict_false((dmalen >= (uint32_t)-8) || dmalen == 0 ||
+ (dmalen & 3) != 0)) {
DPRINTF(("bad DMA length %u (%x)\n", dmalen, dmalen));
break;
}
@@ -2232,7 +2420,8 @@ run_tx(struct run_softc *sc, struct mbuf
struct rt2860_txwi *txwi;
uint16_t dur;
uint8_t type, mcs, tid, qid, qos = 0;
- int error, hasqos, ridx, ctl_ridx, xferlen;
+ int error, hasqos, ridx, ctl_ridx, xferlen, txwisize;
+ uint8_t pad;
wh = mtod(m, struct ieee80211_frame *);
@@ -2278,7 +2467,9 @@ run_tx(struct run_softc *sc, struct mbuf
/* get MCS code from rate index */
mcs = rt2860_rates[ridx].mcs;
- xferlen = sizeof(*txwi) + m->m_pkthdr.len;
+ txwisize = (sc->mac_ver == 0x5592) ?
+ sizeof(*txwi) + sizeof(uint32_t) : sizeof(*txwi);
+ xferlen = txwisize + m->m_pkthdr.len;
/* roundup to 32-bit alignment */
xferlen = (xferlen + 3) & ~3;
@@ -2286,20 +2477,29 @@ run_tx(struct run_softc *sc, struct mbuf
txd->flags = RT2860_TX_QSEL_EDCA;
txd->len = htole16(xferlen);
+ /*
+ * Ether both are true or both are false, the header
+ * are nicely aligned to 32-bit. So, no L2 padding.
+ */
+ if (IEEE80211_HAS_ADDR4(wh) == IEEE80211_QOS_HAS_SEQ(wh))
+ pad = 0;
+ else
+ pad = 2;
+
/* setup TX Wireless Information */
txwi = (struct rt2860_txwi *)(txd + 1);
txwi->flags = 0;
txwi->xflags = hasqos ? 0 : RT2860_TX_NSEQ;
txwi->wcid = (type == IEEE80211_FC0_TYPE_DATA) ?
RUN_AID2WCID(ni->ni_associd) : 0xff;
- txwi->len = htole16(m->m_pkthdr.len);
+ txwi->len = htole16(m->m_pkthdr.len - pad);
if (rt2860_rates[ridx].phy == IEEE80211_T_DS) {
txwi->phy = htole16(RT2860_PHY_CCK);
if (ridx != RT2860_RIDX_CCK1 &&
(ic->ic_flags & IEEE80211_F_SHPREAMBLE))
mcs |= RT2860_PHY_SHPRE;
} else
- txwi->phy = htole16(RT2860_PHY_OFDM);
+ mcs |= RT2860_PHY_OFDM;
txwi->phy |= htole16(mcs);
txwi->txop = RT2860_TX_TXOP_BACKOFF;
@@ -2338,7 +2538,7 @@ run_tx(struct run_softc *sc, struct mbuf
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
}
- m_copydata(m, 0, m->m_pkthdr.len, (void *)(txwi + 1));
+ m_copydata(m, 0, m->m_pkthdr.len, ((uint8_t *)txwi) + txwisize);
m_freem(m);
xferlen += sizeof(*txd) + 4;
@@ -2609,14 +2809,14 @@ run_rt2870_set_chan(struct run_softc *sc
run_rt2870_rf_write(sc, RT2860_RF3, r3);
run_rt2870_rf_write(sc, RT2860_RF4, r4);
- DELAY(200);
+ usbd_delay_ms(sc->sc_udev, 10);
run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1);
run_rt2870_rf_write(sc, RT2860_RF2, r2);
run_rt2870_rf_write(sc, RT2860_RF3, r3 | 1);
run_rt2870_rf_write(sc, RT2860_RF4, r4);
- DELAY(200);
+ usbd_delay_ms(sc->sc_udev, 10);
run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1);
run_rt2870_rf_write(sc, RT2860_RF2, r2);
@@ -2834,7 +3034,515 @@ run_rt3572_set_chan(struct run_softc *sc
run_rt3070_rf_read(sc, 7, &rf);
run_rt3070_rf_write(sc, 7, rf | 0x01);
- DELAY(2000);
+ usbd_delay_ms(sc->sc_udev, 2);
+}
+
+static void
+run_rt3593_set_chan(struct run_softc *sc, u_int chan)
+{
+ int8_t txpow1, txpow2, txpow3;
+ uint8_t h20mhz, 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];
+ txpow3 = (sc->ntxchains == 3) ? sc->txpow3[i] : 0;
+
+ 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, 8, rt3070_freqs[i].n);
+ run_rt3070_rf_write(sc, 9, rt3070_freqs[i].k & 0x0f);
+ run_rt3070_rf_read(sc, 11, &rf);
+ rf = (rf & ~0x03) | (rt3070_freqs[i].r & 0x03);
+ run_rt3070_rf_write(sc, 11, rf);
+
+ /* Set pll_idoh. */
+ run_rt3070_rf_read(sc, 11, &rf);
+ rf &= ~0x4c;
+ rf |= (chan <= 14) ? 0x44 : 0x48;
+ run_rt3070_rf_write(sc, 11, rf);
+
+ if (chan <= 14)
+ rf = txpow1 & 0x1f;
+ else
+ rf = 0x40 | ((txpow1 & 0x18) << 1) | (txpow1 & 0x07);
+ run_rt3070_rf_write(sc, 53, rf);
+
+ if (chan <= 14)
+ rf = txpow2 & 0x1f;
+ else
+ rf = 0x40 | ((txpow2 & 0x18) << 1) | (txpow2 & 0x07);
+ run_rt3070_rf_write(sc, 55, rf);
+
+ if (chan <= 14)
+ rf = txpow3 & 0x1f;
+ else
+ rf = 0x40 | ((txpow3 & 0x18) << 1) | (txpow3 & 0x07);
+ run_rt3070_rf_write(sc, 54, rf);
+
+ rf = RT3070_RF_BLOCK | RT3070_PLL_PD;
+ if (sc->ntxchains == 3)
+ rf |= RT3070_TX0_PD | RT3070_TX1_PD | RT3070_TX2_PD;
+ else
+ rf |= RT3070_TX0_PD | RT3070_TX1_PD;
+ rf |= RT3070_RX0_PD | RT3070_RX1_PD | RT3070_RX2_PD;
+ run_rt3070_rf_write(sc, 1, rf);
+
+ run_adjust_freq_offset(sc);
+
+ run_rt3070_rf_write(sc, 31, (chan <= 14) ? 0xa0 : 0x80);
+
+ h20mhz = (sc->rf24_20mhz & 0x20) >> 5;
+ run_rt3070_rf_read(sc, 30, &rf);
+ rf = (rf & ~0x06) | (h20mhz << 1) | (h20mhz << 2);
+ run_rt3070_rf_write(sc, 30, rf);
+
+ run_rt3070_rf_read(sc, 36, &rf);
+ if (chan <= 14)
+ rf |= 0x80;
+ else
+ rf &= ~0x80;
+ run_rt3070_rf_write(sc, 36, rf);
+
+ /* Set vcolo_bs. */
+ run_rt3070_rf_write(sc, 34, (chan <= 14) ? 0x3c : 0x20);
+ /* Set pfd_delay. */
+ run_rt3070_rf_write(sc, 12, (chan <= 14) ? 0x1a : 0x12);
+
+ /* Set vco bias current control. */
+ run_rt3070_rf_read(sc, 6, &rf);
+ rf &= ~0xc0;
+ if (chan <= 14)
+ rf |= 0x40;
+ else if (chan <= 128)
+ rf |= 0x80;
+ else
+ rf |= 0x40;
+ run_rt3070_rf_write(sc, 6, rf);
+
+ run_rt3070_rf_read(sc, 30, &rf);
+ rf = (rf & ~0x18) | 0x10;
+ run_rt3070_rf_write(sc, 30, rf);
+
+ run_rt3070_rf_write(sc, 10, (chan <= 14) ? 0xd3 : 0xd8);
+ run_rt3070_rf_write(sc, 13, (chan <= 14) ? 0x12 : 0x23);
+
+ run_rt3070_rf_read(sc, 51, &rf);
+ rf = (rf & ~0x03) | 0x01;
+ run_rt3070_rf_write(sc, 51, rf);
+ /* Set tx_mx1_cc. */
+ run_rt3070_rf_read(sc, 51, &rf);
+ rf &= ~0x1c;
+ rf |= (chan <= 14) ? 0x14 : 0x10;
+ run_rt3070_rf_write(sc, 51, rf);
+ /* Set tx_mx1_ic. */
+ run_rt3070_rf_read(sc, 51, &rf);
+ rf &= ~0xe0;
+ rf |= (chan <= 14) ? 0x60 : 0x40;
+ run_rt3070_rf_write(sc, 51, rf);
+ /* Set tx_lo1_ic. */
+ run_rt3070_rf_read(sc, 49, &rf);
+ rf &= ~0x1c;
+ rf |= (chan <= 14) ? 0x0c : 0x08;
+ run_rt3070_rf_write(sc, 49, rf);
+ /* Set tx_lo1_en. */
+ run_rt3070_rf_read(sc, 50, &rf);
+ run_rt3070_rf_write(sc, 50, rf & ~0x20);
+ /* Set drv_cc. */
+ run_rt3070_rf_read(sc, 57, &rf);
+ rf &= ~0xfc;
+ rf |= (chan <= 14) ? 0x6c : 0x3c;
+ run_rt3070_rf_write(sc, 57, rf);
+ /* Set rx_mix1_ic, rxa_lnactr, lna_vc, lna_inbias_en and lna_en. */
+ run_rt3070_rf_write(sc, 44, (chan <= 14) ? 0x93 : 0x9b);
+ /* Set drv_gnd_a, tx_vga_cc_a and tx_mx2_gain. */
+ run_rt3070_rf_write(sc, 52, (chan <= 14) ? 0x45 : 0x05);
+ /* Enable VCO calibration. */
+ run_rt3070_rf_read(sc, 3, &rf);
+ rf &= ~RT5390_VCOCAL;
+ rf |= (chan <= 14) ? RT5390_VCOCAL : 0xbe;
+ run_rt3070_rf_write(sc, 3, rf);
+
+ if (chan <= 14)
+ rf = 0x23;
+ else if (chan <= 64)
+ rf = 0x36;
+ else if (chan <= 128)
+ rf = 0x32;
+ else
+ rf = 0x30;
+ run_rt3070_rf_write(sc, 39, rf);
+ if (chan <= 14)
+ rf = 0xbb;
+ else if (chan <= 64)
+ rf = 0xeb;
+ else if (chan <= 128)
+ rf = 0xb3;
+ else
+ rf = 0x9b;
+ run_rt3070_rf_write(sc, 45, rf);
+
+ /* Set FEQ/AEQ control. */
+ run_bbp_write(sc, 105, 0x34);
+}
+
+static void
+run_rt5390_set_chan(struct run_softc *sc, u_int chan)
+{
+ int8_t txpow1, txpow2;
+ 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];
+
+ run_rt3070_rf_write(sc, 8, rt3070_freqs[i].n);
+ run_rt3070_rf_write(sc, 9, rt3070_freqs[i].k & 0x0f);
+ run_rt3070_rf_read(sc, 11, &rf);
+ rf = (rf & ~0x03) | (rt3070_freqs[i].r & 0x03);
+ run_rt3070_rf_write(sc, 11, rf);
+
+ run_rt3070_rf_read(sc, 49, &rf);
+ rf = (rf & ~0x3f) | (txpow1 & 0x3f);
+ /* The valid range of the RF R49 is 0x00 to 0x27. */
+ if ((rf & 0x3f) > 0x27)
+ rf = (rf & ~0x3f) | 0x27;
+ run_rt3070_rf_write(sc, 49, rf);
+
+ if (sc->mac_ver == 0x5392) {
+ run_rt3070_rf_read(sc, 50, &rf);
+ rf = (rf & ~0x3f) | (txpow2 & 0x3f);
+ /* The valid range of the RF R50 is 0x00 to 0x27. */
+ if ((rf & 0x3f) > 0x27)
+ rf = (rf & ~0x3f) | 0x27;
+ run_rt3070_rf_write(sc, 50, rf);
+ }
+
+ run_rt3070_rf_read(sc, 1, &rf);
+ rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD;
+ if (sc->mac_ver == 0x5392)
+ rf |= RT3070_RX1_PD | RT3070_TX1_PD;
+ run_rt3070_rf_write(sc, 1, rf);
+
+ if (sc->mac_ver != 0x5392) {
+ run_rt3070_rf_read(sc, 2, &rf);
+ rf |= 0x80;
+ run_rt3070_rf_write(sc, 2, rf);
+ usbd_delay_ms(sc->sc_udev, 10);
+ rf &= 0x7f;
+ run_rt3070_rf_write(sc, 2, rf);
+ }
+
+ run_adjust_freq_offset(sc);
+
+ if (sc->mac_ver == 0x5392) {
+ /* Fix for RT5392C. */
+ if (sc->mac_rev >= 0x0223) {
+ if (chan <= 4)
+ rf = 0x0f;
+ else if (chan >= 5 && chan <= 7)
+ rf = 0x0e;
+ else
+ rf = 0x0d;
+ run_rt3070_rf_write(sc, 23, rf);
+
+ if (chan <= 4)
+ rf = 0x0c;
+ else if (chan == 5)
+ rf = 0x0b;
+ else if (chan >= 6 && chan <= 7)
+ rf = 0x0a;
+ else if (chan >= 8 && chan <= 10)
+ rf = 0x09;
+ else
+ rf = 0x08;
+ run_rt3070_rf_write(sc, 59, rf);
+ } else {
+ if (chan <= 11)
+ rf = 0x0f;
+ else
+ rf = 0x0b;
+ run_rt3070_rf_write(sc, 59, rf);
+ }
+ } else {
+ /* Fix for RT5390F. */
+ if (sc->mac_rev >= 0x0502) {
+ if (chan <= 11)
+ rf = 0x43;
+ else
+ rf = 0x23;
+ run_rt3070_rf_write(sc, 55, rf);
+
+ if (chan <= 11)
+ rf = 0x0f;
+ else if (chan == 12)
+ rf = 0x0d;
+ else
+ rf = 0x0b;
+ run_rt3070_rf_write(sc, 59, rf);
+ } else {
+ run_rt3070_rf_write(sc, 55, 0x44);
+ run_rt3070_rf_write(sc, 59, 0x8f);
+ }
+ }
+
+ /* Enable VCO calibration. */
+ run_rt3070_rf_read(sc, 3, &rf);
+ rf |= RT5390_VCOCAL;
+ run_rt3070_rf_write(sc, 3, rf);
+}
+
+static void
+run_rt5592_set_chan(struct run_softc *sc, u_int chan)
+{
+ const struct rt5592_freqs *freqs;
+ uint32_t tmp;
+ uint8_t reg, rf, txpow_bound;
+ int8_t txpow1, txpow2;
+ int i;
+
+ run_read(sc, RT5592_DEBUG_INDEX, &tmp);
+ freqs = (tmp & RT5592_SEL_XTAL) ?
+ rt5592_freqs_40mhz : rt5592_freqs_20mhz;
+
+ /* find the settings for this channel (we know it exists) */
+ for (i = 0; rt2860_rf2850[i].chan != chan; i++, freqs++);
+
+ /* use Tx power values from EEPROM */
+ txpow1 = sc->txpow1[i];
+ txpow2 = sc->txpow2[i];
+
+ run_read(sc, RT3070_LDO_CFG0, &tmp);
+ tmp &= ~0x1c000000;
+ if (chan > 14)
+ tmp |= 0x14000000;
+ run_write(sc, RT3070_LDO_CFG0, tmp);
+
+ /* N setting. */
+ run_rt3070_rf_write(sc, 8, freqs->n & 0xff);
+ run_rt3070_rf_read(sc, 9, &rf);
+ rf &= ~(1 << 4);
+ rf |= ((freqs->n & 0x0100) >> 8) << 4;
+ run_rt3070_rf_write(sc, 9, rf);
+
+ /* K setting. */
+ run_rt3070_rf_read(sc, 9, &rf);
+ rf &= ~0x0f;
+ rf |= (freqs->k & 0x0f);
+ run_rt3070_rf_write(sc, 9, rf);
+
+ /* Mode setting. */
+ run_rt3070_rf_read(sc, 11, &rf);
+ rf &= ~0x0c;
+ rf |= ((freqs->m - 0x8) & 0x3) << 2;
+ run_rt3070_rf_write(sc, 11, rf);
+ run_rt3070_rf_read(sc, 9, &rf);
+ rf &= ~(1 << 7);
+ rf |= (((freqs->m - 0x8) & 0x4) >> 2) << 7;
+ run_rt3070_rf_write(sc, 9, rf);
+
+ /* R setting. */
+ run_rt3070_rf_read(sc, 11, &rf);
+ rf &= ~0x03;
+ rf |= (freqs->r - 0x1);
+ run_rt3070_rf_write(sc, 11, rf);
+
+ if (chan <= 14) {
+ /* Initialize RF registers for 2GHZ. */
+ for (i = 0; i < (int)__arraycount(rt5592_2ghz_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5592_2ghz_def_rf[i].reg,
+ rt5592_2ghz_def_rf[i].val);
+ }
+
+ rf = (chan <= 10) ? 0x07 : 0x06;
+ run_rt3070_rf_write(sc, 23, rf);
+ run_rt3070_rf_write(sc, 59, rf);
+
+ run_rt3070_rf_write(sc, 55, 0x43);
+
+ /*
+ * RF R49/R50 Tx power ALC code.
+ * G-band bit<7:6>=1:0, bit<5:0> range from 0x0 ~ 0x27.
+ */
+ reg = 2;
+ txpow_bound = 0x27;
+ } else {
+ /* Initialize RF registers for 5GHZ. */
+ for (i = 0; i < (int)__arraycount(rt5592_5ghz_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5592_5ghz_def_rf[i].reg,
+ rt5592_5ghz_def_rf[i].val);
+ }
+ for (i = 0; i < (int)__arraycount(rt5592_chan_5ghz); i++) {
+ if (chan >= rt5592_chan_5ghz[i].firstchan &&
+ chan <= rt5592_chan_5ghz[i].lastchan) {
+ run_rt3070_rf_write(sc, rt5592_chan_5ghz[i].reg,
+ rt5592_chan_5ghz[i].val);
+ }
+ }
+
+ /*
+ * RF R49/R50 Tx power ALC code.
+ * A-band bit<7:6>=1:1, bit<5:0> range from 0x0 ~ 0x2b.
+ */
+ reg = 3;
+ txpow_bound = 0x2b;
+ }
+
+ /* RF R49 ch0 Tx power ALC code. */
+ run_rt3070_rf_read(sc, 49, &rf);
+ rf &= ~0xc0;
+ rf |= (reg << 6);
+ rf = (rf & ~0x3f) | (txpow1 & 0x3f);
+ if ((rf & 0x3f) > txpow_bound)
+ rf = (rf & ~0x3f) | txpow_bound;
+ run_rt3070_rf_write(sc, 49, rf);
+
+ /* RF R50 ch1 Tx power ALC code. */
+ run_rt3070_rf_read(sc, 50, &rf);
+ rf &= ~(1 << 7 | 1 << 6);
+ rf |= (reg << 6);
+ rf = (rf & ~0x3f) | (txpow2 & 0x3f);
+ if ((rf & 0x3f) > txpow_bound)
+ rf = (rf & ~0x3f) | txpow_bound;
+ run_rt3070_rf_write(sc, 50, rf);
+
+ /* Enable RF_BLOCK, PLL_PD, RX0_PD, and TX0_PD. */
+ run_rt3070_rf_read(sc, 1, &rf);
+ rf |= (RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD);
+ if (sc->ntxchains > 1)
+ rf |= RT3070_TX1_PD;
+ if (sc->nrxchains > 1)
+ rf |= RT3070_RX1_PD;
+ run_rt3070_rf_write(sc, 1, rf);
+
+ run_rt3070_rf_write(sc, 6, 0xe4);
+
+ run_rt3070_rf_write(sc, 30, 0x10);
+ run_rt3070_rf_write(sc, 31, 0x80);
+ run_rt3070_rf_write(sc, 32, 0x80);
+
+ run_adjust_freq_offset(sc);
+
+ /* Enable VCO calibration. */
+ run_rt3070_rf_read(sc, 3, &rf);
+ rf |= RT5390_VCOCAL;
+ run_rt3070_rf_write(sc, 3, rf);
+}
+
+static void
+run_iq_calib(struct run_softc *sc, u_int chan)
+{
+ uint16_t val;
+
+ /* Tx0 IQ gain. */
+ run_bbp_write(sc, 158, 0x2c);
+ if (chan <= 14)
+ run_efuse_read(sc, RT5390_EEPROM_IQ_GAIN_CAL_TX0_2GHZ, &val, 1);
+ else if (chan <= 64) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_GAIN_CAL_TX0_CH36_TO_CH64_5GHZ,
+ &val, 1);
+ } else if (chan <= 138) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_GAIN_CAL_TX0_CH100_TO_CH138_5GHZ,
+ &val, 1);
+ } else if (chan <= 165) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_GAIN_CAL_TX0_CH140_TO_CH165_5GHZ,
+ &val, 1);
+ } else
+ val = 0;
+ run_bbp_write(sc, 159, val);
+
+ /* Tx0 IQ phase. */
+ run_bbp_write(sc, 158, 0x2d);
+ if (chan <= 14) {
+ run_efuse_read(sc, RT5390_EEPROM_IQ_PHASE_CAL_TX0_2GHZ,
+ &val, 1);
+ } else if (chan <= 64) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_PHASE_CAL_TX0_CH36_TO_CH64_5GHZ,
+ &val, 1);
+ } else if (chan <= 138) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_PHASE_CAL_TX0_CH100_TO_CH138_5GHZ,
+ &val, 1);
+ } else if (chan <= 165) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_PHASE_CAL_TX0_CH140_TO_CH165_5GHZ,
+ &val, 1);
+ } else
+ val = 0;
+ run_bbp_write(sc, 159, val);
+
+ /* Tx1 IQ gain. */
+ run_bbp_write(sc, 158, 0x4a);
+ if (chan <= 14) {
+ run_efuse_read(sc, RT5390_EEPROM_IQ_GAIN_CAL_TX1_2GHZ,
+ &val, 1);
+ } else if (chan <= 64) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH36_TO_CH64_5GHZ,
+ &val, 1);
+ } else if (chan <= 138) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH100_TO_CH138_5GHZ,
+ &val, 1);
+ } else if (chan <= 165) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5GHZ,
+ &val, 1);
+ } else
+ val = 0;
+ run_bbp_write(sc, 159, val);
+
+ /* Tx1 IQ phase. */
+ run_bbp_write(sc, 158, 0x4b);
+ if (chan <= 14) {
+ run_efuse_read(sc, RT5390_EEPROM_IQ_PHASE_CAL_TX1_2GHZ,
+ &val, 1);
+ } else if (chan <= 64) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH36_TO_CH64_5GHZ,
+ &val, 1);
+ } else if (chan <= 138) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH100_TO_CH138_5GHZ,
+ &val, 1);
+ } else if (chan <= 165) {
+ run_efuse_read(sc,
+ RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5GHZ,
+ &val, 1);
+ } else
+ val = 0;
+ run_bbp_write(sc, 159, val);
+
+ /* RF IQ compensation control. */
+ run_bbp_write(sc, 158, 0x04);
+ run_efuse_read(sc, RT5390_EEPROM_RF_IQ_COMPENSATION_CTL,
+ &val, 1);
+ run_bbp_write(sc, 159, val);
+
+ /* RF IQ imbalance compensation control. */
+ run_bbp_write(sc, 158, 0x03);
+ run_efuse_read(sc,
+ RT5390_EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CTL, &val, 1);
+ run_bbp_write(sc, 159, val);
}
static void
@@ -2857,13 +3565,22 @@ static void
run_set_rx_antenna(struct run_softc *sc, int aux)
{
uint32_t tmp;
+ uint8_t bbp152;
- run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, !aux);
- run_read(sc, RT2860_GPIO_CTRL, &tmp);
- tmp &= ~0x0808;
- if (aux)
- tmp |= 0x08;
- run_write(sc, RT2860_GPIO_CTRL, tmp);
+ if (sc->rf_rev == RT5390_RF_5370) {
+ run_bbp_read(sc, 152, &bbp152);
+ bbp152 &= ~0x80;
+ if (aux)
+ bbp152 |= 0x80;
+ run_bbp_write(sc, 152, bbp152);
+ } else {
+ run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, !aux);
+ run_read(sc, RT2860_GPIO_CTRL, &tmp);
+ tmp &= ~0x0808;
+ if (aux)
+ tmp |= 0x08;
+ run_write(sc, RT2860_GPIO_CTRL, tmp);
+ }
}
static int
@@ -2876,7 +3593,13 @@ run_set_chan(struct run_softc *sc, struc
if (chan == 0 || chan == IEEE80211_CHAN_ANY)
return EINVAL;
- if (sc->mac_ver == 0x3572)
+ if (sc->mac_ver == 0x5592)
+ run_rt5592_set_chan(sc, chan);
+ else if (sc->mac_ver >= 0x5390)
+ run_rt5390_set_chan(sc, chan);
+ else if (sc->mac_ver == 0x3593)
+ run_rt3593_set_chan(sc, chan);
+ else if (sc->mac_ver == 0x3572)
run_rt3572_set_chan(sc, chan);
else if (sc->mac_ver >= 0x3070)
run_rt3070_set_chan(sc, chan);
@@ -2896,11 +3619,39 @@ run_set_chan(struct run_softc *sc, struc
/* XXX necessary only when group has changed! */
run_select_chan_group(sc, group);
- DELAY(1000);
+ usbd_delay_ms(sc->sc_udev, 10);
+
+ /* Perform IQ calibration. */
+ if (sc->mac_ver >= 0x5392)
+ run_iq_calib(sc, chan);
+
return 0;
}
static void
+run_updateprot(struct run_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint32_t tmp;
+
+ tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
+ /* setup protection frame rate (MCS code) */
+ tmp |= (ic->ic_curmode == IEEE80211_MODE_11A) ?
+ rt2860_rates[RT2860_RIDX_OFDM6].mcs | RT2860_PHY_OFDM :
+ rt2860_rates[RT2860_RIDX_CCK11].mcs;
+
+ /* CCK frames don't require protection */
+ run_write(sc, RT2860_CCK_PROT_CFG, tmp);
+ if (ic->ic_flags & IEEE80211_F_USEPROT) {
+ if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
+ tmp |= RT2860_PROT_CTRL_RTS_CTS;
+ else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
+ tmp |= RT2860_PROT_CTRL_CTS;
+ }
+ run_write(sc, RT2860_OFDM_PROT_CFG, tmp);
+}
+
+static void
run_enable_tsf_sync(struct run_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -3057,6 +3808,64 @@ run_rssi2dbm(struct run_softc *sc, uint8
return -12 - delta - rssi;
}
+static void
+run_rt5390_bbp_init(struct run_softc *sc)
+{
+ u_int i;
+ uint8_t bbp;
+
+ /* Apply maximum likelihood detection for 2 stream case. */
+ run_bbp_read(sc, 105, &bbp);
+ if (sc->nrxchains > 1)
+ run_bbp_write(sc, 105, bbp | RT5390_MLD);
+
+ /* Avoid data lost and CRC error. */
+ run_bbp_read(sc, 4, &bbp);
+ run_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL);
+
+ if (sc->mac_ver == 0x5592) {
+ for (i = 0; i < (int)__arraycount(rt5592_def_bbp); i++) {
+ run_bbp_write(sc, rt5592_def_bbp[i].reg,
+ rt5592_def_bbp[i].val);
+ }
+ for (i = 0; i < (int)__arraycount(rt5592_bbp_r196); i++) {
+ run_bbp_write(sc, 195, i + 0x80);
+ run_bbp_write(sc, 196, rt5592_bbp_r196[i]);
+ }
+ } else {
+ for (i = 0; i < (int)__arraycount(rt5390_def_bbp); i++) {
+ run_bbp_write(sc, rt5390_def_bbp[i].reg,
+ rt5390_def_bbp[i].val);
+ }
+ }
+ if (sc->mac_ver == 0x5392) {
+ run_bbp_write(sc, 88, 0x90);
+ run_bbp_write(sc, 95, 0x9a);
+ run_bbp_write(sc, 98, 0x12);
+ run_bbp_write(sc, 106, 0x12);
+ run_bbp_write(sc, 134, 0xd0);
+ run_bbp_write(sc, 135, 0xf6);
+ run_bbp_write(sc, 148, 0x84);
+ }
+
+ run_bbp_read(sc, 152, &bbp);
+ run_bbp_write(sc, 152, bbp | 0x80);
+
+ /* Fix BBP254 for RT5592C. */
+ if (sc->mac_ver == 0x5592 && sc->mac_rev >= 0x0221) {
+ run_bbp_read(sc, 254, &bbp);
+ run_bbp_write(sc, 254, bbp | 0x80);
+ }
+
+ /* Disable hardware antenna diversity. */
+ if (sc->mac_ver == 0x5390)
+ run_bbp_write(sc, 154, 0);
+
+ /* Initialize Rx CCK/OFDM frequency offset report. */
+ run_bbp_write(sc, 142, 1);
+ run_bbp_write(sc, 143, 57);
+}
+
static int
run_bbp_init(struct run_softc *sc)
{
@@ -3074,9 +3883,21 @@ run_bbp_init(struct run_softc *sc)
return ETIMEDOUT;
/* initialize BBP registers to default values */
- for (i = 0; i < (int)__arraycount(rt2860_def_bbp); i++) {
- run_bbp_write(sc, rt2860_def_bbp[i].reg,
- rt2860_def_bbp[i].val);
+ if (sc->mac_ver >= 0x5390)
+ run_rt5390_bbp_init(sc);
+ else {
+ for (i = 0; i < (int)__arraycount(rt2860_def_bbp); i++) {
+ run_bbp_write(sc, rt2860_def_bbp[i].reg,
+ rt2860_def_bbp[i].val);
+ }
+ }
+
+ if (sc->mac_ver == 0x3593) {
+ run_bbp_write(sc, 79, 0x13);
+ run_bbp_write(sc, 80, 0x05);
+ run_bbp_write(sc, 81, 0x33);
+ run_bbp_write(sc, 86, 0x46);
+ run_bbp_write(sc, 137, 0x0f);
}
/* fix BBP84 for RT2860E */
@@ -3104,7 +3925,7 @@ run_rt3070_rf_init(struct run_softc *sc)
run_rt3070_rf_read(sc, 30, &rf);
/* toggle RF R30 bit 7 */
run_rt3070_rf_write(sc, 30, rf | 0x80);
- DELAY(1000);
+ usbd_delay_ms(sc->sc_udev, 10);
run_rt3070_rf_write(sc, 30, rf & ~0x80);
/* initialize RF registers to default value */
@@ -3122,17 +3943,15 @@ run_rt3070_rf_init(struct run_softc *sc)
if (sc->mac_ver == 0x3572) {
run_rt3070_rf_read(sc, 6, &rf);
run_rt3070_rf_write(sc, 6, rf | 0x40);
+ run_rt3070_rf_write(sc, 31, 0x14);
- /* increase voltage from 1.2V to 1.35V */
run_read(sc, RT3070_LDO_CFG0, &tmp);
- tmp = (tmp & ~0x1f000000) | 0x0d000000;
+ tmp &= ~0x1f000000;
+ if (sc->mac_rev < 0x0211 && sc->patch_dac)
+ tmp |= 0x0d000000; /* 1.3V */
+ else
+ tmp |= 0x01000000; /* 1.2V */
run_write(sc, RT3070_LDO_CFG0, tmp);
- if (sc->mac_rev >= 0x0211 || !sc->patch_dac) {
- /* decrease voltage back to 1.2V */
- DELAY(1000);
- tmp = (tmp & ~0x1f000000) | 0x01000000;
- run_write(sc, RT3070_LDO_CFG0, tmp);
- }
} else if (sc->mac_ver == 0x3071) {
run_rt3070_rf_read(sc, 6, &rf);
run_rt3070_rf_write(sc, 6, rf | 0x40);
@@ -3228,6 +4047,121 @@ run_rt3070_rf_init(struct run_softc *sc)
}
static int
+run_rt3593_rf_init(struct run_softc *sc)
+{
+ uint32_t tmp;
+ uint8_t rf;
+ int i;
+
+ /* Disable the GPIO bits 4 and 7 for LNA PE control. */
+ run_read(sc, RT3070_GPIO_SWITCH, &tmp);
+ tmp &= ~(1 << 4 | 1 << 7);
+ run_write(sc, RT3070_GPIO_SWITCH, tmp);
+
+ /* Initialize RF registers to default value. */
+ for (i = 0; i < __arraycount(rt3593_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt3593_def_rf[i].reg,
+ rt3593_def_rf[i].val);
+ }
+
+ /* Toggle RF R2 to initiate calibration. */
+ run_rt3070_rf_write(sc, 2, RT5390_RESCAL);
+
+ /* Initialize RF frequency offset. */
+ run_adjust_freq_offset(sc);
+
+ run_rt3070_rf_read(sc, 18, &rf);
+ run_rt3070_rf_write(sc, 18, rf | RT3593_AUTOTUNE_BYPASS);
+
+ /*
+ * Increase voltage from 1.2V to 1.35V, wait for 1 msec to
+ * decrease voltage back to 1.2V.
+ */
+ run_read(sc, RT3070_LDO_CFG0, &tmp);
+ tmp = (tmp & ~0x1f000000) | 0x0d000000;
+ run_write(sc, RT3070_LDO_CFG0, tmp);
+ usbd_delay_ms(sc->sc_udev, 1);
+ tmp = (tmp & ~0x1f000000) | 0x01000000;
+ run_write(sc, RT3070_LDO_CFG0, tmp);
+
+ sc->rf24_20mhz = 0x1f;
+ sc->rf24_40mhz = 0x2f;
+
+ /* Save default BBP registers 25 and 26 values. */
+ run_bbp_read(sc, 25, &sc->bbp25);
+ run_bbp_read(sc, 26, &sc->bbp26);
+
+ run_read(sc, RT3070_OPT_14, &tmp);
+ run_write(sc, RT3070_OPT_14, tmp | 1);
+ return (0);
+}
+
+static int
+run_rt5390_rf_init(struct run_softc *sc)
+{
+ uint32_t tmp;
+ uint8_t rf;
+ int i;
+
+ /* Toggle RF R2 to initiate calibration. */
+ if (sc->mac_ver == 0x5390) {
+ run_rt3070_rf_read(sc, 2, &rf);
+ run_rt3070_rf_write(sc, 2, rf | RT5390_RESCAL);
+ usbd_delay_ms(sc->sc_udev, 10);
+ run_rt3070_rf_write(sc, 2, rf & ~RT5390_RESCAL);
+ } else {
+ run_rt3070_rf_write(sc, 2, RT5390_RESCAL);
+ usbd_delay_ms(sc->sc_udev, 10);
+ }
+
+ /* Initialize RF registers to default value. */
+ if (sc->mac_ver == 0x5592) {
+ for (i = 0; i < __arraycount(rt5592_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5592_def_rf[i].reg,
+ rt5592_def_rf[i].val);
+ }
+ /* Initialize RF frequency offset. */
+ run_adjust_freq_offset(sc);
+ } else if (sc->mac_ver == 0x5392) {
+ for (i = 0; i < __arraycount(rt5392_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5392_def_rf[i].reg,
+ rt5392_def_rf[i].val);
+ }
+ if (sc->mac_rev >= 0x0223) {
+ run_rt3070_rf_write(sc, 23, 0x0f);
+ run_rt3070_rf_write(sc, 24, 0x3e);
+ run_rt3070_rf_write(sc, 51, 0x32);
+ run_rt3070_rf_write(sc, 53, 0x22);
+ run_rt3070_rf_write(sc, 56, 0xc1);
+ run_rt3070_rf_write(sc, 59, 0x0f);
+ }
+ } else {
+ for (i = 0; i < __arraycount(rt5390_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5390_def_rf[i].reg,
+ rt5390_def_rf[i].val);
+ }
+ if (sc->mac_rev >= 0x0502) {
+ run_rt3070_rf_write(sc, 6, 0xe0);
+ run_rt3070_rf_write(sc, 25, 0x80);
+ run_rt3070_rf_write(sc, 46, 0x73);
+ run_rt3070_rf_write(sc, 53, 0x00);
+ run_rt3070_rf_write(sc, 56, 0x42);
+ run_rt3070_rf_write(sc, 61, 0xd1);
+ }
+ }
+
+ sc->rf24_20mhz = 0x1f; /* default value */
+ sc->rf24_40mhz = (sc->mac_ver == 0x5592) ? 0 : 0x2f;
+
+ if (sc->mac_rev < 0x0211)
+ run_rt3070_rf_write(sc, 27, 0x3);
+
+ run_read(sc, RT3070_OPT_14, &tmp);
+ run_write(sc, RT3070_OPT_14, tmp | 1);
+ return (0);
+}
+
+static int
run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
uint8_t *val)
{
@@ -3249,7 +4183,7 @@ run_rt3070_filter_calib(struct run_softc
for (ntries = 0; ntries < 100; ntries++) {
/* transmit test tone */
run_bbp_write(sc, 25, 0x90);
- DELAY(1000);
+ usbd_delay_ms(sc->sc_udev, 10);
/* read received power */
run_bbp_read(sc, 55, &bbp55_pb);
if (bbp55_pb != 0)
@@ -3263,7 +4197,7 @@ run_rt3070_filter_calib(struct run_softc
for (ntries = 0; ntries < 100; ntries++) {
/* transmit test tone */
run_bbp_write(sc, 25, 0x90);
- DELAY(1000);
+ usbd_delay_ms(sc->sc_udev, 10);
/* read received power */
run_bbp_read(sc, 55, &bbp55_sb);
@@ -3370,6 +4304,123 @@ run_rt3070_rf_setup(struct run_softc *sc
}
}
+static void
+run_rt3593_rf_setup(struct run_softc *sc)
+{
+ uint8_t bbp, rf;
+
+ if (sc->mac_rev >= 0x0211) {
+ /* Enable DC filter. */
+ run_bbp_write(sc, 103, 0xc0);
+ }
+ 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);
+
+ run_rt3070_rf_read(sc, 50, &rf);
+ run_rt3070_rf_write(sc, 50, rf & ~RT3593_TX_LO2);
+
+ run_rt3070_rf_read(sc, 51, &rf);
+ rf = (rf & ~(RT3593_TX_LO1 | 0x0c)) |
+ ((sc->txmixgain_2ghz & 0x07) << 2);
+ run_rt3070_rf_write(sc, 51, rf);
+
+ run_rt3070_rf_read(sc, 38, &rf);
+ run_rt3070_rf_write(sc, 38, rf & ~RT5390_RX_LO1);
+
+ run_rt3070_rf_read(sc, 39, &rf);
+ run_rt3070_rf_write(sc, 39, rf & ~RT5390_RX_LO2);
+
+ run_rt3070_rf_read(sc, 1, &rf);
+ run_rt3070_rf_write(sc, 1, rf & ~(RT3070_RF_BLOCK | RT3070_PLL_PD));
+
+ run_rt3070_rf_read(sc, 30, &rf);
+ rf = (rf & ~0x18) | 0x10;
+ run_rt3070_rf_write(sc, 30, rf);
+
+ /* Apply maximum likelihood detection for 2 stream case. */
+ run_bbp_read(sc, 105, &bbp);
+ if (sc->nrxchains > 1)
+ run_bbp_write(sc, 105, bbp | RT5390_MLD);
+
+ /* Avoid data lost and CRC error. */
+ run_bbp_read(sc, 4, &bbp);
+ run_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL);
+
+ run_bbp_write(sc, 92, 0x02);
+ run_bbp_write(sc, 82, 0x82);
+ run_bbp_write(sc, 106, 0x05);
+ run_bbp_write(sc, 104, 0x92);
+ run_bbp_write(sc, 88, 0x90);
+ run_bbp_write(sc, 148, 0xc8);
+ run_bbp_write(sc, 47, 0x48);
+ run_bbp_write(sc, 120, 0x50);
+
+ run_bbp_write(sc, 163, 0x9d);
+
+ /* SNR mapping. */
+ run_bbp_write(sc, 142, 0x06);
+ run_bbp_write(sc, 143, 0xa0);
+ run_bbp_write(sc, 142, 0x07);
+ run_bbp_write(sc, 143, 0xa1);
+ run_bbp_write(sc, 142, 0x08);
+ run_bbp_write(sc, 143, 0xa2);
+
+ run_bbp_write(sc, 31, 0x08);
+ run_bbp_write(sc, 68, 0x0b);
+ run_bbp_write(sc, 105, 0x04);
+}
+
+static void
+run_rt5390_rf_setup(struct run_softc *sc)
+{
+ uint8_t bbp, rf;
+
+ if (sc->mac_rev >= 0x0211) {
+ /* Enable DC filter. */
+ run_bbp_write(sc, 103, 0xc0);
+
+ if (sc->mac_ver != 0x5592) {
+ /* Improve power consumption. */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+ }
+
+ 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);
+
+ run_rt3070_rf_read(sc, 38, &rf);
+ run_rt3070_rf_write(sc, 38, rf & ~RT5390_RX_LO1);
+
+ run_rt3070_rf_read(sc, 39, &rf);
+ run_rt3070_rf_write(sc, 39, rf & ~RT5390_RX_LO2);
+
+ /* Avoid data lost and CRC error. */
+ run_bbp_read(sc, 4, &bbp);
+ run_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL);
+
+ run_rt3070_rf_read(sc, 30, &rf);
+ rf = (rf & ~0x18) | 0x10;
+ run_rt3070_rf_write(sc, 30, rf);
+
+ if (sc->mac_ver != 0x5592) {
+ 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);
+ }
+}
+
static int
run_txrx_enable(struct run_softc *sc)
{
@@ -3382,12 +4433,12 @@ run_txrx_enable(struct run_softc *sc)
return error;
if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
break;
- DELAY(1000);
+ usbd_delay_ms(sc->sc_udev, 50);
}
if (ntries == 200)
return ETIMEDOUT;
- DELAY(50);
+ usbd_delay_ms(sc->sc_udev, 50);
tmp |= RT2860_RX_DMA_EN | RT2860_TX_DMA_EN | RT2860_TX_WB_DDONE;
run_write(sc, RT2860_WPDMA_GLO_CFG, tmp);
@@ -3416,6 +4467,22 @@ run_txrx_enable(struct run_softc *sc)
}
static int
+run_adjust_freq_offset(struct run_softc *sc)
+{
+ uint8_t rf, tmp;
+
+ run_rt3070_rf_read(sc, 17, &rf);
+ tmp = rf;
+ rf = (rf & ~0x7f) | (sc->freq & 0x7f);
+ rf = MIN(rf, 0x5f);
+
+ if (tmp != rf)
+ run_mcu_cmd(sc, 0x74, (tmp << 8 ) | rf);
+
+ return (0);
+}
+
+static int
run_init(struct ifnet *ifp)
{
struct run_softc *sc = ifp->if_softc;
@@ -3429,7 +4496,7 @@ run_init(struct ifnet *ifp)
goto fail;
if (tmp != 0 && tmp != 0xffffffff)
break;
- DELAY(10);
+ usbd_delay_ms(sc->sc_udev, 10);
}
if (ntries == 100) {
error = ETIMEDOUT;
@@ -3466,7 +4533,7 @@ run_init(struct ifnet *ifp)
goto fail;
if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
break;
- DELAY(1000);
+ usbd_delay_ms(sc->sc_udev, 10);
}
if (ntries == 100) {
aprint_error_dev(sc->sc_dev,
@@ -3506,7 +4573,23 @@ run_init(struct ifnet *ifp)
run_write(sc, RT2860_WMM_CWMIN_CFG, 0x00002344);
run_write(sc, RT2860_WMM_CWMAX_CFG, 0x000034aa);
- if (sc->mac_ver >= 0x3070) {
+ if (sc->mac_ver >= 0x5390) {
+ run_write(sc, RT2860_TX_SW_CFG0,
+ 4 << RT2860_DLY_PAPE_EN_SHIFT | 4);
+ if (sc->mac_ver >= 0x5392) {
+ run_write(sc, RT2860_MAX_LEN_CFG, 0x00002fff);
+ if (sc->mac_ver == 0x5592) {
+ run_write(sc, RT2860_HT_FBK_CFG1, 0xedcba980);
+ run_write(sc, RT2860_TXOP_HLDR_ET, 0x00000082);
+ } else {
+ run_write(sc, RT2860_HT_FBK_CFG1, 0xedcb4980);
+ run_write(sc, RT2860_LG_FBK_CFG0, 0xedcba322);
+ }
+ }
+ } else if (sc->mac_ver >= 0x3593) {
+ run_write(sc, RT2860_TX_SW_CFG0,
+ 4 << RT2860_DLY_PAPE_EN_SHIFT | 2);
+ } else 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);
@@ -3528,13 +4611,14 @@ run_init(struct ifnet *ifp)
/* clear Host to MCU mailbox */
run_write(sc, RT2860_H2M_BBPAGENT, 0);
run_write(sc, RT2860_H2M_MAILBOX, 0);
- DELAY(1000);
+ usbd_delay_ms(sc->sc_udev, 10);
if ((error = run_bbp_init(sc)) != 0) {
aprint_error_dev(sc->sc_dev, "could not initialize BBP\n");
goto fail;
}
+ /* abort TSF synchronization */
run_read(sc, RT2860_BCN_TIME_CFG, &tmp);
tmp &= ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN |
RT2860_TBTT_TIMER_EN);
@@ -3553,6 +4637,11 @@ run_init(struct ifnet *ifp)
/* clear shared key mode */
run_set_region_4(sc, RT2860_SKEY_MODE_0_7, 0, 4);
+ /* clear RX WCID search table */
+ run_set_region_4(sc, RT2860_WCID_ENTRY(0), 0, 512);
+ /* clear WCID attribute table */
+ run_set_region_4(sc, RT2860_WCID_ATTR(0), 0, 8 * 32);
+
run_read(sc, RT2860_US_CYC_CNT, &tmp);
tmp = (tmp & ~0xff) | 0x1e;
run_write(sc, RT2860_US_CYC_CNT, tmp);
@@ -3564,14 +4653,16 @@ run_init(struct ifnet *ifp)
run_write(sc, RT2860_WMM_TXOP1_CFG, 48 << 16 | 96);
/* write vendor-specific BBP values (from EEPROM) */
- for (i = 0; i < 8; i++) {
- if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff)
- continue;
- run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val);
+ if (sc->mac_ver < 0x3593) {
+ for (i = 0; i < 10; i++) {
+ if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff)
+ continue;
+ run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val);
+ }
}
/* select Main antenna for 1T1R devices */
- if (sc->rf_rev == RT3070_RF_3020)
+ if (sc->rf_rev == RT3070_RF_3020 || sc->rf_rev == RT5390_RF_5370)
run_set_rx_antenna(sc, 0);
/* send LEDs operating mode to microcontroller */
@@ -3579,7 +4670,11 @@ 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)
+ if (sc->mac_ver >= 0x5390)
+ run_rt5390_rf_init(sc);
+ else if (sc->mac_ver == 0x3593)
+ run_rt3593_rf_init(sc);
+ else if (sc->mac_ver >= 0x3070)
run_rt3070_rf_init(sc);
/* disable non-existing Rx chains */
@@ -3597,12 +4692,19 @@ run_init(struct ifnet *ifp)
bbp1 &= ~(1 << 3 | 1 << 4);
run_bbp_write(sc, 1, bbp1);
- if (sc->mac_ver >= 0x3070)
+ if (sc->mac_ver >= 0x5390)
+ run_rt5390_rf_setup(sc);
+ else if (sc->mac_ver == 0x3593)
+ run_rt3593_rf_setup(sc);
+ else if (sc->mac_ver >= 0x3070)
run_rt3070_rf_setup(sc);
/* select default channel */
run_set_chan(sc, ic->ic_curchan);
+ /* setup initial protection mode */
+ run_updateprot(sc);
+
/* turn radio LED on */
run_set_leds(sc, RT2860_LED_RADIO);
@@ -3698,6 +4800,7 @@ run_setup_beacon(struct run_softc *sc)
struct ieee80211com *ic = &sc->sc_ic;
struct rt2860_txwi txwi;
struct mbuf *m;
+ uint16_t txwisize;
int ridx;
if ((m = ieee80211_beacon_alloc(ic, ic->ic_bss, &sc->sc_bo)) == NULL)
@@ -3715,10 +4818,12 @@ run_setup_beacon(struct run_softc *sc)
txwi.txop = RT2860_TX_TXOP_HT;
txwi.flags = RT2860_TX_TS;
+ txwisize = (sc->mac_ver == 0x5592) ?
+ sizeof(txwi) + sizeof(uint32_t) : sizeof(txwi);
run_write_region_1(sc, RT2860_BCN_BASE(0),
- (uint8_t *)&txwi, sizeof(txwi));
- run_write_region_1(sc, RT2860_BCN_BASE(0) + sizeof(txwi),
- mtod(m, uint8_t *), m->m_pkthdr.len);
+ (uint8_t *)&txwi, txwisize);
+ run_write_region_1(sc, RT2860_BCN_BASE(0) + txwisize,
+ mtod(m, uint8_t *), (m->m_pkthdr.len + 1) & ~1);
m_freem(m);
Index: src/sys/dev/usb/if_runvar.h
diff -u src/sys/dev/usb/if_runvar.h:1.2 src/sys/dev/usb/if_runvar.h:1.3
--- src/sys/dev/usb/if_runvar.h:1.2 Sat Apr 23 10:15:31 2016
+++ src/sys/dev/usb/if_runvar.h Fri Sep 16 09:25:30 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_runvar.h,v 1.2 2016/04/23 10:15:31 skrll Exp $ */
+/* $NetBSD: if_runvar.h,v 1.3 2016/09/16 09:25:30 mlelstv Exp $ */
/* $OpenBSD: if_runvar.h,v 1.8 2010/02/08 18:46:47 damien Exp $ */
/*-
@@ -147,7 +147,7 @@ struct run_softc {
uint16_t mac_ver;
uint16_t mac_rev;
- uint8_t rf_rev;
+ uint16_t rf_rev;
uint8_t freq;
uint8_t ntxchains;
uint8_t nrxchains;
@@ -167,6 +167,7 @@ struct run_softc {
uint8_t txmixgain_5ghz;
int8_t txpow1[54];
int8_t txpow2[54];
+ int8_t txpow3[54];
int8_t rssi_2ghz[3];
int8_t rssi_5ghz[3];
uint8_t lna[4];
Index: src/sys/net80211/ieee80211.h
diff -u src/sys/net80211/ieee80211.h:1.27 src/sys/net80211/ieee80211.h:1.28
--- src/sys/net80211/ieee80211.h:1.27 Wed Apr 27 20:17:00 2016
+++ src/sys/net80211/ieee80211.h Fri Sep 16 09:25:30 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: ieee80211.h,v 1.27 2016/04/27 20:17:00 christos Exp $ */
+/* $NetBSD: ieee80211.h,v 1.28 2016/09/16 09:25:30 mlelstv Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@@ -181,6 +181,9 @@ struct ieee80211_qosframe_addr4 {
#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */
#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */
+#define IEEE80211_IS_DSTODS(wh) \
+ (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
+
#define IEEE80211_FC1_MORE_FRAG 0x04
#define IEEE80211_FC1_RETRY 0x08
#define IEEE80211_FC1_PWR_MGT 0x10
@@ -213,6 +216,12 @@ struct ieee80211_qosframe_addr4 {
#define IEEE80211_QOS_ESOP_S 4
#define IEEE80211_QOS_TID 0x000f
+/* does frame have QoS sequence control data */
+#define IEEE80211_QOS_HAS_SEQ(wh) \
+ (((wh)->i_fc[0] & \
+ (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == \
+ (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
+
/*
* WME/802.11e information element.
*/