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. */