Add support for RT5390 and RT5392 chipsets to the ral(4) driver.
authorstsp <stsp@openbsd.org>
Wed, 17 Aug 2016 11:50:52 +0000 (11:50 +0000)
committerstsp <stsp@openbsd.org>
Wed, 17 Aug 2016 11:50:52 +0000 (11:50 +0000)
Tested by procter@ on RT2860 and by me on RT2790 and RT3090.
Ported from FreeBSD by James Hastings.

sys/dev/ic/rt2860.c
sys/dev/ic/rt2860reg.h
sys/dev/ic/rt2860var.h
sys/dev/pci/if_ral_pci.c

index 3b2f16a..51936f7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rt2860.c,v 1.90 2016/04/13 10:49:26 mpi Exp $ */
+/*     $OpenBSD: rt2860.c,v 1.91 2016/08/17 11:50:52 stsp Exp $        */
 
 /*-
  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -17,7 +17,7 @@
  */
 
 /*-
- * Ralink Technology RT2860/RT3090/RT3390/RT3562 chipset driver
+ * Ralink Technology RT2860/RT3090/RT3390/RT3562/RT5390/RT5392 chipset driver
  * http://www.ralinktech.com/
  */
 
@@ -121,8 +121,11 @@ void               rt2860_set_basicrates(struct rt2860_softc *);
 void           rt2860_select_chan_group(struct rt2860_softc *, int);
 void           rt2860_set_chan(struct rt2860_softc *, u_int);
 void           rt3090_set_chan(struct rt2860_softc *, u_int);
+void           rt5390_set_chan(struct rt2860_softc *, u_int);
 int            rt3090_rf_init(struct rt2860_softc *);
+void           rt5390_rf_init(struct rt2860_softc *);
 void           rt3090_rf_wakeup(struct rt2860_softc *);
+void           rt5390_rf_wakeup(struct rt2860_softc *);
 int            rt3090_filter_calib(struct rt2860_softc *, uint8_t, uint8_t,
                    uint8_t *);
 void           rt3090_rf_setup(struct rt2860_softc *);
@@ -140,9 +143,10 @@ void               rt2860_delete_key(struct ieee80211com *,
 #if NBPFILTER > 0
 int8_t         rt2860_rssi2dbm(struct rt2860_softc *, uint8_t, uint8_t);
 #endif
-const char *   rt2860_get_rf(uint8_t);
+const char *   rt2860_get_rf(uint16_t);
 int            rt2860_read_eeprom(struct rt2860_softc *);
 int            rt2860_bbp_init(struct rt2860_softc *);
+void           rt5390_bbp_init(struct rt2860_softc *);
 int            rt2860_txrx_enable(struct rt2860_softc *);
 int            rt2860_init(struct ifnet *);
 void           rt2860_stop(struct ifnet *, int);
@@ -168,6 +172,8 @@ static const struct {
        uint8_t val;
 } rt2860_def_bbp[] = {
        RT2860_DEF_BBP
+},rt5390_def_bbp[] = {
+       RT5390_DEF_BBP
 };
 
 static const struct rfprog {
@@ -190,6 +196,10 @@ static const struct {
        RT3070_DEF_RF
 }, rt3572_def_rf[] = {
        RT3572_DEF_RF
+}, rt5390_def_rf[] = {
+       RT5390_DEF_RF
+}, rt5392_def_rf[] = {
+       RT5392_DEF_RF
 };
 
 int
@@ -2086,6 +2096,9 @@ rt2860_select_chan_group(struct rt2860_softc *sc, int group)
        uint32_t tmp;
        uint8_t agc;
 
+       /* Wait for BBP to settle */
+       DELAY(1000);
+
        rt2860_mcu_bbp_write(sc, 62, 0x37 - sc->lna[group]);
        rt2860_mcu_bbp_write(sc, 63, 0x37 - sc->lna[group]);
        rt2860_mcu_bbp_write(sc, 64, 0x37 - sc->lna[group]);
@@ -2293,6 +2306,107 @@ rt3090_set_chan(struct rt2860_softc *sc, u_int chan)
        rt3090_rf_write(sc, 7, rf | RT3070_TUNE);
 }
 
+void
+rt5390_set_chan(struct rt2860_softc *sc, u_int chan)
+{
+       uint8_t h20mhz, rf, tmp;
+       int8_t txpow1, txpow2;
+       int i;
+
+       /* RT5390 is 2GHz only */
+       KASSERT(chan >= 1 && chan <= 14);
+
+       /* 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];
+
+       rt3090_rf_write(sc, 8, rt3090_freqs[i].n);
+       rt3090_rf_write(sc, 9, rt3090_freqs[i].k & 0x0f);
+       rf = rt3090_rf_read(sc, 11);
+       rf = (rf & ~0x03) | (rt3090_freqs[i].r & 0x03);
+       rt3090_rf_write(sc, 11, rf);
+
+       rf = rt3090_rf_read(sc, 49);
+       rf = (rf & ~0x3f) | (txpow1 & 0x3f);
+       /* the valid range of the RF R49 is 0x00~0x27 */
+       if ((rf & 0x3f) > 0x27)
+               rf = (rf & ~0x3f) | 0x27;
+       rt3090_rf_write(sc, 49, rf);
+       if (sc->mac_ver == 0x5392) {
+               rf = rt3090_rf_read(sc, 50);
+               rf = (rf & ~0x3f) | (txpow2 & 0x3f);
+               /* the valid range of the RF R50 is 0x00~0x27 */
+               if ((rf & 0x3f) > 0x27)
+                       rf = (rf & ~0x3f) | 0x27;
+               rt3090_rf_write(sc, 50, rf);
+       }
+
+       rf = rt3090_rf_read(sc, 1);
+       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;
+       rt3090_rf_write(sc, 1, rf);
+
+       rf = rt3090_rf_read(sc, 2);
+       rt3090_rf_write(sc, 2, rf | RT3593_RESCAL);
+       DELAY(1000);
+       rt3090_rf_write(sc, 2, rf & ~RT3593_RESCAL);
+
+       rf = rt3090_rf_read(sc, 17);
+       tmp = rf;
+       rf = (rf & ~0x7f) | (sc->freq & 0x7f);
+       rf = MIN(rf, 0x5f);
+       if (tmp != rf)
+               rt2860_mcu_cmd(sc, 0x74, (tmp << 8 ) | rf, 0);
+
+       if (sc->mac_ver == 0x5390) {
+               if (chan <= 4)
+                       rf = 0x73;
+               else if (chan >= 5 && chan <= 6)
+                       rf = 0x63;
+               else if (chan >= 7 && chan <= 10)
+                       rf = 0x53;
+               else
+                       rf = 43;
+               rt3090_rf_write(sc, 55, rf);
+
+               if (chan == 1)
+                       rf = 0x0c;
+               else if (chan == 2)
+                       rf = 0x0b;
+               else if (chan == 3)
+                       rf = 0x0a;
+               else if (chan >= 4 && chan <= 6)
+                       rf = 0x09;
+               else if (chan >= 7 && chan <= 12)
+                       rf = 0x08;
+               else if (chan == 13)
+                       rf = 0x07;
+               else
+                       rf = 0x06;
+               rt3090_rf_write(sc, 59, rf);
+       }
+
+       /* Tx/Rx h20M */
+       h20mhz = (sc->rf24_20mhz & 0x20) >> 5;
+       rf = rt3090_rf_read(sc, 30);
+       rf = (rf & ~0x06) | (h20mhz << 1) | (h20mhz << 2);
+       rt3090_rf_write(sc, 30, rf);
+
+       /* Rx BB filter VCM */
+       rf = rt3090_rf_read(sc, 30);
+       rf = (rf & ~0x18) | 0x10;
+       rt3090_rf_write(sc, 30, rf);
+
+       /* Initiate VCO calibration. */
+       rf = rt3090_rf_read(sc, 3);
+       rf |= RT3593_VCOCAL;
+       rt3090_rf_write(sc, 3, rf);
+}
+
 int
 rt3090_rf_init(struct rt2860_softc *sc)
 {
@@ -2408,6 +2522,79 @@ rt3090_rf_init(struct rt2860_softc *sc)
        return 0;
 }
 
+void
+rt5390_rf_init(struct rt2860_softc *sc)
+{
+       uint8_t rf, bbp;
+       int i;
+
+       rf = rt3090_rf_read(sc, 2);
+       /* Toggle RF R2 bit 7. */
+       rt3090_rf_write(sc, 2, rf | RT3593_RESCAL);
+       DELAY(1000);
+       rt3090_rf_write(sc, 2, rf & ~RT3593_RESCAL);
+
+       /* Initialize RF registers to default value. */
+       if (sc->mac_ver == 0x5392) {
+               for (i = 0; i < nitems(rt5392_def_rf); i++) {
+                       rt3090_rf_write(sc, rt5392_def_rf[i].reg,
+                           rt5392_def_rf[i].val);
+        }
+       } else {
+               for (i = 0; i < nitems(rt5390_def_rf); i++) {
+                       rt3090_rf_write(sc, rt5390_def_rf[i].reg,
+                           rt5390_def_rf[i].val);
+               }
+       }
+
+       sc->rf24_20mhz = 0x1f;
+       sc->rf24_40mhz = 0x2f;
+
+       if (sc->mac_rev < 0x0211)
+               rt3090_rf_write(sc, 27, 0x03);
+
+       /* Set led open drain enable. */
+       RAL_WRITE(sc, RT3070_OPT_14, RAL_READ(sc, RT3070_OPT_14) | 1);
+
+       RAL_WRITE(sc, RT2860_TX_SW_CFG1, 0);
+       RAL_WRITE(sc, RT2860_TX_SW_CFG2, 0);
+
+       if (sc->mac_ver == 0x5390)
+               rt3090_set_rx_antenna(sc, 0);
+
+       /* Patch RSSI inaccurate issue. */
+       rt2860_mcu_bbp_write(sc, 79, 0x13);
+       rt2860_mcu_bbp_write(sc, 80, 0x05);
+       rt2860_mcu_bbp_write(sc, 81, 0x33);
+
+       /* Enable DC filter. */
+       if (sc->mac_rev >= 0x0211)
+               rt2860_mcu_bbp_write(sc, 103, 0xc0);
+
+       bbp = rt2860_mcu_bbp_read(sc, 138);
+       if (sc->ntxchains == 1)
+               bbp |= 0x20;    /* Turn off DAC1. */
+       if (sc->nrxchains == 1)
+               bbp &= ~0x02;   /* Turn off ADC1. */
+       rt2860_mcu_bbp_write(sc, 138, bbp);
+
+       /* Enable RX LO1 and LO2. */
+       rt3090_rf_write(sc, 38, rt3090_rf_read(sc, 38) & ~RT5390_RX_LO1);
+       rt3090_rf_write(sc, 39, rt3090_rf_read(sc, 39) & ~RT5390_RX_LO2);
+
+       /* Avoid data lost and CRC error. */
+       rt2860_mcu_bbp_write(sc, 4,
+           rt2860_mcu_bbp_read(sc, 4) | RT5390_MAC_IF_CTRL);
+
+       rf = rt3090_rf_read(sc, 30);
+       rf = (rf & ~0x18) | 0x10;
+       rt3090_rf_write(sc, 30, rf);
+
+       /* Disable hardware antenna diversity. */
+       if (sc->mac_ver == 0x5390)
+               rt2860_mcu_bbp_write(sc, 154, 0);
+}
+
 void
 rt3090_rf_wakeup(struct rt2860_softc *sc)
 {
@@ -2474,6 +2661,42 @@ rt3090_rf_wakeup(struct rt2860_softc *sc)
        }
 }
 
+void
+rt5390_rf_wakeup(struct rt2860_softc *sc)
+{
+       uint32_t tmp;
+       uint8_t rf;
+       
+       rf = rt3090_rf_read(sc, 1);
+       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;
+       rt3090_rf_write(sc, 1, rf);
+
+       rf = rt3090_rf_read(sc, 6);
+       rf |= RT3593_VCO_IC | RT3593_VCOCAL;
+       if (sc->mac_ver == 0x5390)
+               rf &= ~RT3593_VCO_IC;
+       rt3090_rf_write(sc, 6, rf);
+
+       rt3090_rf_write(sc, 2, rt3090_rf_read(sc, 2) | RT3593_RESCAL);
+
+       rf = rt3090_rf_read(sc, 22);
+       rf = (rf & ~0xe0) | 0x20;
+       rt3090_rf_write(sc, 22, rf);
+
+       rt3090_rf_write(sc, 42, rt3090_rf_read(sc, 42) | RT5390_RX_CTB);
+       rt3090_rf_write(sc, 20, rt3090_rf_read(sc, 20) & ~0x77);
+       rt3090_rf_write(sc, 3, rt3090_rf_read(sc, 3) | RT3593_VCOCAL);
+
+       if (sc->patch_dac && sc->mac_rev < 0x0211) {
+               tmp = RAL_READ(sc, RT3070_LDO_CFG0);
+               tmp = (tmp & ~0x1f000000) | 0x0d000000;
+               RAL_WRITE(sc, RT3070_LDO_CFG0, tmp);
+       }
+}
+
 int
 rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target,
     uint8_t *val)
@@ -2562,10 +2785,12 @@ rt3090_rf_setup(struct rt2860_softc *sc)
                RAL_WRITE(sc, RT2860_TX_SW_CFG2, 0);
 
        /* initialize RF registers from ROM */
-       for (i = 0; i < 10; i++) {
-               if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff)
-                       continue;
-               rt3090_rf_write(sc, sc->rf[i].reg, sc->rf[i].val);
+       if (sc->mac_ver < 0x5390) {
+               for (i = 0; i < 10; i++) {
+                       if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff)
+                               continue;
+                       rt3090_rf_write(sc, sc->rf[i].reg, sc->rf[i].val);
+               }
        }
 }
 
@@ -2869,7 +3094,7 @@ b4inc(uint32_t b32, int8_t delta)
 }
 
 const char *
-rt2860_get_rf(uint8_t rev)
+rt2860_get_rf(uint16_t rev)
 {
        switch (rev) {
        case RT2860_RF_2820:    return "RT2820";
@@ -2883,6 +3108,8 @@ rt2860_get_rf(uint8_t rev)
        case RT3070_RF_3052:    return "RT3052";
        case RT3070_RF_3320:    return "RT3320";
        case RT3070_RF_3053:    return "RT3053";
+       case RT5390_RF_5390:    return "RT5390";
+       case RT5390_RF_5392:    return "RT5392";
        default:                return "unknown";
        }
 }
@@ -2964,29 +3191,12 @@ rt2860_read_eeprom(struct rt2860_softc *sc)
 
        /* read RF information */
        val = rt2860_srom_read(sc, RT2860_EEPROM_ANTENNA);
-       if (val == 0xffff) {
-               DPRINTF(("invalid EEPROM antenna info, using default\n"));
-               if (sc->mac_ver == 0x3593) {
-                       /* default to RF3053 3T3R */
-                       sc->rf_rev = RT3070_RF_3053;
-                       sc->ntxchains = 3;
-                       sc->nrxchains = 3;
-               } else if (sc->mac_ver >= 0x3071) {
-                       /* default to RF3020 1T1R */
-                       sc->rf_rev = RT3070_RF_3020;
-                       sc->ntxchains = 1;
-                       sc->nrxchains = 1;
-               } else {
-                       /* default to RF2820 1T2R */
-                       sc->rf_rev = RT2860_RF_2820;
-                       sc->ntxchains = 1;
-                       sc->nrxchains = 2;
-               }
-       } else {
+       if (sc->mac_ver >= 0x5390)
+               sc->rf_rev = rt2860_srom_read(sc, RT2860_EEPROM_CHIPID);
+       else
                sc->rf_rev = (val >> 8) & 0xf;
-               sc->ntxchains = (val >> 4) & 0xf;
-               sc->nrxchains = val & 0xf;
-       }
+       sc->ntxchains = (val >> 4) & 0xf;
+       sc->nrxchains = val & 0xf;
        DPRINTF(("EEPROM RF rev=0x%02x chains=%dT%dR\n",
            sc->rf_rev, sc->ntxchains, sc->nrxchains));
 
@@ -3023,17 +3233,23 @@ rt2860_read_eeprom(struct rt2860_softc *sc)
                sc->txpow1[i + 0] = (int8_t)(val & 0xff);
                sc->txpow1[i + 1] = (int8_t)(val >> 8);
 
-               val = rt2860_srom_read(sc,
-                   RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2);
-               sc->txpow2[i + 0] = (int8_t)(val & 0xff);
-               sc->txpow2[i + 1] = (int8_t)(val >> 8);
+               if (sc->mac_ver != 0x5390) {
+                       val = rt2860_srom_read(sc,
+                           RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2);
+                       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;
+               if (sc->txpow1[i] < 0 ||
+                   sc->txpow1[i] > ((sc->mac_ver >= 0x5390) ? 39 : 31))
+                       sc->txpow1[i] = 5;
+               if (sc->mac_ver != 0x5390) {
+                       if (sc->txpow2[i] < 0 ||
+                           sc->txpow2[i] > ((sc->mac_ver == 0x5392) ? 39 : 31))
+                               sc->txpow2[i] = 5;
+               }
                DPRINTF(("chan %d: power1=%d, power2=%d\n",
                    rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]));
        }
@@ -3219,9 +3435,13 @@ rt2860_bbp_init(struct rt2860_softc *sc)
        }
 
        /* initialize BBP registers to default values */
-       for (i = 0; i < nitems(rt2860_def_bbp); i++) {
-               rt2860_mcu_bbp_write(sc, rt2860_def_bbp[i].reg,
-                   rt2860_def_bbp[i].val);
+       if (sc->mac_ver >= 0x5390)
+               rt5390_bbp_init(sc);
+       else {
+               for (i = 0; i < nitems(rt2860_def_bbp); i++) {
+                       rt2860_mcu_bbp_write(sc, rt2860_def_bbp[i].reg,
+                           rt2860_def_bbp[i].val);
+               }
        }
 
        /* fix BBP84 for RT2860E */
@@ -3240,6 +3460,44 @@ rt2860_bbp_init(struct rt2860_softc *sc)
        return 0;
 }
 
+void
+rt5390_bbp_init(struct rt2860_softc *sc)
+{
+       uint8_t bbp;
+       int i;
+
+       /* Apply maximum likelihood detection for 2 stream case. */
+       if (sc->nrxchains > 1) {
+               bbp = rt2860_mcu_bbp_read(sc, 105);
+               rt2860_mcu_bbp_write(sc, 105, bbp | RT5390_MLD);
+       }
+
+       /* Avoid data lost and CRC error. */
+       bbp = rt2860_mcu_bbp_read(sc, 4);
+       rt2860_mcu_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL);
+
+       for (i = 0; i < nitems(rt5390_def_bbp); i++) {
+               rt2860_mcu_bbp_write(sc, rt5390_def_bbp[i].reg,
+                   rt5390_def_bbp[i].val);
+       }
+
+       if (sc->mac_ver == 0x5392) {
+               rt2860_mcu_bbp_write(sc, 84, 0x9a);
+               rt2860_mcu_bbp_write(sc, 95, 0x9a);
+               rt2860_mcu_bbp_write(sc, 98, 0x12);
+               rt2860_mcu_bbp_write(sc, 106, 0x05);
+               rt2860_mcu_bbp_write(sc, 134, 0xd0);
+               rt2860_mcu_bbp_write(sc, 135, 0xf6);
+       }
+
+       bbp = rt2860_mcu_bbp_read(sc, 152);
+       rt2860_mcu_bbp_write(sc, 152, bbp | 0x80);
+
+       /* Disable hardware antenna diversity. */
+       if (sc->mac_ver == 0x5390)
+               rt2860_mcu_bbp_write(sc, 154, 0);
+}
+
 int
 rt2860_txrx_enable(struct rt2860_softc *sc)
 {
@@ -3375,7 +3633,9 @@ rt2860_init(struct ifnet *ifp)
 
        for (i = 0; i < nitems(rt2860_def_mac); i++)
                RAL_WRITE(sc, rt2860_def_mac[i].reg, rt2860_def_mac[i].val);
-       if (sc->mac_ver >= 0x3071) {
+       if (sc->mac_ver >= 0x5390)
+               RAL_WRITE(sc, RT2860_TX_SW_CFG0, 0x00000404);
+       else if (sc->mac_ver >= 0x3071) {
                /* set delay of PA_PE assertion to 1us (unit of 0.25us) */
                RAL_WRITE(sc, RT2860_TX_SW_CFG0,
                    4 << RT2860_DLY_PAPE_EN_SHIFT);
@@ -3471,7 +3731,8 @@ rt2860_init(struct ifnet *ifp)
        /* select Main antenna for 1T1R devices */
        if (sc->rf_rev == RT3070_RF_2020 ||
            sc->rf_rev == RT3070_RF_3020 ||
-           sc->rf_rev == RT3070_RF_3320)
+           sc->rf_rev == RT3070_RF_3320 ||
+           sc->rf_rev == RT5390_RF_5390)
                rt3090_set_rx_antenna(sc, 0);
 
        /* send LEDs operating mode to microcontroller */
@@ -3479,13 +3740,17 @@ rt2860_init(struct ifnet *ifp)
        rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1], 0);
        rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2], 0);
 
-       if (sc->mac_ver >= 0x3071)
+       if (sc->mac_ver >= 0x5390)
+               rt5390_rf_init(sc);
+       else if (sc->mac_ver >= 0x3071)
                rt3090_rf_init(sc);
 
        rt2860_mcu_cmd(sc, RT2860_MCU_CMD_SLEEP, 0x02ff, 1);
        rt2860_mcu_cmd(sc, RT2860_MCU_CMD_WAKEUP, 0, 1);
 
-       if (sc->mac_ver >= 0x3071)
+       if (sc->mac_ver >= 0x5390)
+               rt5390_rf_wakeup(sc);
+       else if (sc->mac_ver >= 0x3071)
                rt3090_rf_wakeup(sc);
 
        /* disable non-existing Rx chains */
@@ -3692,17 +3957,30 @@ void
 rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux)
 {
        uint32_t tmp;
-
        if (aux) {
-               tmp = RAL_READ(sc, RT2860_PCI_EECTRL);
-               RAL_WRITE(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C);
-               tmp = RAL_READ(sc, RT2860_GPIO_CTRL);
-               RAL_WRITE(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08);
+               if (sc->mac_ver == 0x5390) {
+                       rt2860_mcu_bbp_write(sc, 152,
+                           rt2860_mcu_bbp_read(sc, 152) & ~0x80);
+               } else {
+                       tmp = RAL_READ(sc, RT2860_PCI_EECTRL);
+                       RAL_WRITE(sc, RT2860_PCI_EECTRL,
+                           tmp & ~RT2860_C);
+                       tmp = RAL_READ(sc, RT2860_GPIO_CTRL);
+                       RAL_WRITE(sc, RT2860_GPIO_CTRL,
+                           (tmp & ~0x0808) | 0x08);
+               }
        } else {
-               tmp = RAL_READ(sc, RT2860_PCI_EECTRL);
-               RAL_WRITE(sc, RT2860_PCI_EECTRL, tmp | RT2860_C);
-               tmp = RAL_READ(sc, RT2860_GPIO_CTRL);
-               RAL_WRITE(sc, RT2860_GPIO_CTRL, tmp & ~0x0808);
+               if (sc->mac_ver == 0x5390) {
+                       rt2860_mcu_bbp_write(sc, 152,
+                           rt2860_mcu_bbp_read(sc, 152) | 0x80);
+               } else {
+                       tmp = RAL_READ(sc, RT2860_PCI_EECTRL);
+                       RAL_WRITE(sc, RT2860_PCI_EECTRL,
+                           tmp | RT2860_C);
+                       tmp = RAL_READ(sc, RT2860_GPIO_CTRL);
+                       RAL_WRITE(sc, RT2860_GPIO_CTRL,
+                           tmp & ~0x0808);
+               }
        }
 }
 
@@ -3716,7 +3994,9 @@ rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c)
        if (chan == 0 || chan == IEEE80211_CHAN_ANY)
                return;
 
-       if (sc->mac_ver >= 0x3071)
+       if (sc->mac_ver >= 0x5390)
+               rt5390_set_chan(sc, chan);
+       else if (sc->mac_ver >= 0x3071)
                rt3090_set_chan(sc, chan);
        else
                rt2860_set_chan(sc, chan);
@@ -3732,7 +4012,8 @@ rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c)
                group = 3;
 
        /* XXX necessary only when group has changed! */
-       rt2860_select_chan_group(sc, group);
+       if (sc->mac_ver <= 0x5390)
+               rt2860_select_chan_group(sc, group);
 
        DELAY(1000);
 }
index 2cc9ec3..d5f44a7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rt2860reg.h,v 1.32 2014/05/24 10:10:17 stsp Exp $     */
+/*     $OpenBSD: rt2860reg.h,v 1.33 2016/08/17 11:50:52 stsp Exp $     */
 
 /*-
  * Copyright (c) 2007
 /* possible flags for RT5390 RF register 39. */
 #define RT5390_RX_LO2  (1 << 7)
 
+/* possible flags for RT5390 RF register 42 */
+#define RT5390_RX_CTB  (1 << 6)
+
 /* possible flags for RT3053 RF register 46 */
 #define RT3593_RX_CTB  (1 << 5)
 
@@ -910,20 +913,22 @@ struct rt2860_rxwi {
 #define RT2860_RF3     1
 #define RT2860_RF4     3
 
-#define RT2860_RF_2820 1       /* 2T3R */
-#define RT2860_RF_2850 2       /* dual-band 2T3R */
-#define RT2860_RF_2720 3       /* 1T2R */
-#define RT2860_RF_2750 4       /* dual-band 1T2R */
-#define RT3070_RF_3020 5       /* 1T1R */
-#define RT3070_RF_2020 6       /* b/g */
-#define RT3070_RF_3021 7       /* 1T2R */
-#define RT3070_RF_3022 8       /* 2T2R */
-#define RT3070_RF_3052 9       /* dual-band 2T2R */
-#define RT3070_RF_3320 11      /* 1T1R */
-#define RT3070_RF_3053 13      /* dual-band 3T3R */
+#define RT2860_RF_2820 0x0001  /* 2T3R */
+#define RT2860_RF_2850 0x0002  /* dual-band 2T3R */
+#define RT2860_RF_2720 0x0003  /* 1T2R */
+#define RT2860_RF_2750 0x0004  /* dual-band 1T2R */
+#define RT3070_RF_3020 0x0005  /* 1T1R */
+#define RT3070_RF_2020 0x0006  /* b/g */
+#define RT3070_RF_3021 0x0007  /* 1T2R */
+#define RT3070_RF_3022 0x0008  /* 2T2R */
+#define RT3070_RF_3052 0x0009  /* dual-band 2T2R */
+#define RT3070_RF_3320 0x000b  /* 1T1R */
+#define RT3070_RF_3053 0x000d  /* dual-band 3T3R */
 #define RT5592_RF_5592 0x000f  /* dual-band 2T2R */
 #define RT5390_RF_5370 0x5370  /* 1T1R */
 #define RT5390_RF_5372 0x5372  /* 2T2R */
+#define RT5390_RF_5390 0x5390  /* 1T1R */
+#define RT5390_RF_5392 0x5392  /* 2T2R */
 
 /* USB commands for RT2870 only */
 #define RT2870_RESET           1
@@ -934,6 +939,7 @@ struct rt2860_rxwi {
 
 #define RT2860_EEPROM_DELAY    1       /* minimum hold time (microsecond) */
 
+#define RT2860_EEPROM_CHIPID           0x00
 #define RT2860_EEPROM_VERSION          0x01
 #define RT2860_EEPROM_MAC01            0x02
 #define RT2860_EEPROM_MAC23            0x03
@@ -1077,14 +1083,17 @@ static const struct rt2860_rate {
  */
 #define RT2860_DEF_MAC                                 \
        { RT2860_BCN_OFFSET0,           0xf8f0e8e0 },   \
+       { RT2860_BCN_OFFSET1,           0x6f77d0c8 },   \
        { RT2860_LEGACY_BASIC_RATE,     0x0000013f },   \
        { RT2860_HT_BASIC_RATE,         0x00008003 },   \
        { RT2860_MAC_SYS_CTRL,          0x00000000 },   \
+       { RT2860_RX_FILTR_CFG,          0x00017f97 },   \
        { RT2860_BKOFF_SLOT_CFG,        0x00000209 },   \
        { RT2860_TX_SW_CFG0,            0x00000000 },   \
        { RT2860_TX_SW_CFG1,            0x00080606 },   \
        { RT2860_TX_LINK_CFG,           0x00001020 },   \
        { RT2860_TX_TIMEOUT_CFG,        0x000a2090 },   \
+       { RT2860_MAX_LEN_CFG,           0x00001f00 },   \
        { RT2860_LED_CFG,               0x7f031e46 },   \
        { RT2860_WMM_AIFSN_CFG,         0x00002273 },   \
        { RT2860_WMM_CWMIN_CFG,         0x00002344 },   \
@@ -1144,6 +1153,7 @@ static const struct rt2860_rate {
 #define RT2860_DEF_BBP \
        {  65, 0x2c },  \
        {  66, 0x38 },  \
+       {  68, 0x0b },  \
        {  69, 0x12 },  \
        {  70, 0x0a },  \
        {  73, 0x10 },  \
@@ -1441,7 +1451,7 @@ static const struct rt2860_rate {
        {  4, 0x40 },   \
        {  5, 0x03 },   \
        {  6, 0x02 },   \
-       {  7, 0x70 },   \
+       {  7, 0x60 },   \
        {  9, 0x0f },   \
        { 10, 0x41 },   \
        { 11, 0x21 },   \
index 7888091..2d6321b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rt2860var.h,v 1.23 2016/03/21 21:16:30 stsp Exp $     */
+/*     $OpenBSD: rt2860var.h,v 1.24 2016/08/17 11:50:52 stsp Exp $     */
 
 /*-
  * Copyright (c) 2007
@@ -149,7 +149,7 @@ struct rt2860_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;
index bbdf64f..c306a92 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_ral_pci.c,v 1.24 2015/11/24 17:11:39 mpi Exp $  */
+/*     $OpenBSD: if_ral_pci.c,v 1.25 2016/08/17 11:50:52 stsp Exp $  */
 
 /*-
  * Copyright (c) 2005-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -135,7 +135,12 @@ const struct pci_matchid ral_pci_devices[] = {
        { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3092 },
        { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3562 },
        { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3592 },
-       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3593 }
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3593 },
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT5390 },
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT5392 },
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT5390_1 },
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT5390_2 },
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT5390_3 }
 };
 
 int