summaryrefslogtreecommitdiffstats
path: root/sys/dev/ral/rt2860.c
diff options
context:
space:
mode:
authorkevlo <kevlo@FreeBSD.org>2015-02-22 15:27:02 +0000
committerkevlo <kevlo@FreeBSD.org>2015-02-22 15:27:02 +0000
commit3d2c9b77bb0643703f84954826e8cfa65fbec079 (patch)
treef4ffc93f80c77fa9763defaef3e9dfb1dc16c46f /sys/dev/ral/rt2860.c
parentd9009c47214d40a42e8be3fa0d3b303e53197828 (diff)
downloadFreeBSD-src-3d2c9b77bb0643703f84954826e8cfa65fbec079.zip
FreeBSD-src-3d2c9b77bb0643703f84954826e8cfa65fbec079.tar.gz
MFC r278551:
Add preliminary support for the Ralink RT5390 and RT5392 chipsets. Committed over the D-Link DWA-525 rev A2 on amd64 with WPA.
Diffstat (limited to 'sys/dev/ral/rt2860.c')
-rw-r--r--sys/dev/ral/rt2860.c405
1 files changed, 349 insertions, 56 deletions
diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c
index b5b0e0a..3eb7187 100644
--- a/sys/dev/ral/rt2860.c
+++ b/sys/dev/ral/rt2860.c
@@ -21,7 +21,7 @@
__FBSDID("$FreeBSD$");
/*-
- * Ralink Technology RT2860/RT3090/RT3390/RT3562 chipset driver
+ * Ralink Technology RT2860/RT3090/RT3390/RT3562/RT5390/RT5392 chipset driver
* http://www.ralinktech.com/
*/
@@ -141,8 +141,11 @@ static void rt2860_set_channel(struct ieee80211com *);
static void rt2860_select_chan_group(struct rt2860_softc *, int);
static void rt2860_set_chan(struct rt2860_softc *, u_int);
static void rt3090_set_chan(struct rt2860_softc *, u_int);
+static void rt5390_set_chan(struct rt2860_softc *, u_int);
static int rt3090_rf_init(struct rt2860_softc *);
+static void rt5390_rf_init(struct rt2860_softc *);
static void rt3090_rf_wakeup(struct rt2860_softc *);
+static void rt5390_rf_wakeup(struct rt2860_softc *);
static int rt3090_filter_calib(struct rt2860_softc *, uint8_t, uint8_t,
uint8_t *);
static void rt3090_rf_setup(struct rt2860_softc *);
@@ -165,6 +168,7 @@ static const char *rt2860_get_rf(uint8_t);
static int rt2860_read_eeprom(struct rt2860_softc *,
uint8_t macaddr[IEEE80211_ADDR_LEN]);
static int rt2860_bbp_init(struct rt2860_softc *);
+static void rt5390_bbp_init(struct rt2860_softc *);
static int rt2860_txrx_enable(struct rt2860_softc *);
static void rt2860_init(void *);
static void rt2860_init_locked(struct rt2860_softc *);
@@ -193,6 +197,8 @@ static const struct {
uint8_t val;
} rt2860_def_bbp[] = {
RT2860_DEF_BBP
+}, rt5390_def_bbp[] = {
+ RT5390_DEF_BBP
};
static const struct rfprog {
@@ -211,8 +217,12 @@ struct {
static const struct {
uint8_t reg;
uint8_t val;
-} rt3090_def_rf[] = {
+} rt3090_def_rf[] = {
RT3070_DEF_RF
+}, rt5390_def_rf[] = {
+ RT5390_DEF_RF
+}, rt5392_def_rf[] = {
+ RT5392_DEF_RF
};
int
@@ -263,12 +273,10 @@ rt2860_attach(device_t dev, int id)
/* retrieve RF rev. no and various other things from EEPROM */
rt2860_read_eeprom(sc, macaddr);
- if (bootverbose) {
- device_printf(sc->sc_dev, "MAC/BBP RT%X (rev 0x%04X), "
- "RF %s (MIMO %dT%dR), address %6D\n",
- sc->mac_ver, sc->mac_rev, rt2860_get_rf(sc->rf_rev),
- sc->ntxchains, sc->nrxchains, macaddr, ":");
- }
+ device_printf(sc->sc_dev, "MAC/BBP RT%X (rev 0x%04X), "
+ "RF %s (MIMO %dT%dR), address %6D\n",
+ sc->mac_ver, sc->mac_rev, rt2860_get_rf(sc->rf_rev),
+ sc->ntxchains, sc->nrxchains, macaddr, ":");
/*
* Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings.
@@ -2081,7 +2089,7 @@ rt2860_mcu_bbp_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val)
}
if (ntries == 100) {
device_printf(sc->sc_dev,
- "could not write to BBP through MCU\n");
+ "could not write to BBP through MCU\n");
return;
}
@@ -2561,10 +2569,110 @@ rt3090_set_chan(struct rt2860_softc *sc, u_int chan)
rt3090_rf_write(sc, 7, rf | RT3070_TUNE);
}
+static 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, ("chan %d not support", chan));
+
+ /* 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);
+}
+
static int
rt3090_rf_init(struct rt2860_softc *sc)
{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
uint32_t tmp;
uint8_t rf, bbp;
int i;
@@ -2588,7 +2696,7 @@ rt3090_rf_init(struct rt2860_softc *sc)
RAL_WRITE(sc, RT3070_GPIO_SWITCH, tmp & ~0x20);
/* initialize RF registers to default value */
- for (i = 0; i < N(rt3090_def_rf); i++) {
+ for (i = 0; i < nitems(rt3090_def_rf); i++) {
rt3090_rf_write(sc, rt3090_def_rf[i].reg,
rt3090_def_rf[i].val);
}
@@ -2667,11 +2775,79 @@ rt3090_rf_init(struct rt2860_softc *sc)
rf = rt3090_rf_read(sc, 21);
rt3090_rf_write(sc, 21, rf & ~RT3070_RX_LO2);
- return 0;
-#undef N
+ return (0);
}
-void
+static 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);
+}
+
+static void
rt3090_rf_wakeup(struct rt2860_softc *sc)
{
uint32_t tmp;
@@ -2737,7 +2913,43 @@ rt3090_rf_wakeup(struct rt2860_softc *sc)
}
}
-int
+static 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);
+ }
+}
+
+static int
rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target,
uint8_t *val)
{
@@ -2766,7 +2978,7 @@ rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target,
break;
}
if (ntries == 100)
- return ETIMEDOUT;
+ return (ETIMEDOUT);
/* set power and frequency of stopband test tone */
rt2860_mcu_bbp_write(sc, 24, 0x06);
@@ -2799,7 +3011,7 @@ rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target,
rf22 = rt3090_rf_read(sc, 22);
rt3090_rf_write(sc, 22, rf22 & ~RT3070_BB_LOOPBACK);
- return 0;
+ return (0);
}
static void
@@ -2825,10 +3037,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);
+ }
}
}
@@ -3167,6 +3381,7 @@ 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";
default: return "unknown";
}
}
@@ -3249,7 +3464,12 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
val = rt2860_srom_read(sc, RT2860_EEPROM_ANTENNA);
if (val == 0xffff) {
DPRINTF(("invalid EEPROM antenna info, using default\n"));
- if (sc->mac_ver == 0x3593) {
+ if (sc->mac_ver >= 0x5390) {
+ /* default to RF5390 */
+ sc->rf_rev = RT5390_RF_5390;
+ sc->ntxchains = (sc->mac_ver == 0x5392) ? 2 : 1;
+ sc->nrxchains = (sc->mac_ver == 0x5392) ? 2 : 1;
+ } else if (sc->mac_ver == 0x3593) {
/* default to RF3053 3T3R */
sc->rf_rev = RT3070_RF_3053;
sc->ntxchains = 3;
@@ -3267,8 +3487,13 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
}
} else {
sc->rf_rev = (val >> 8) & 0xf;
- sc->ntxchains = (val >> 4) & 0xf;
- sc->nrxchains = val & 0xf;
+ if (sc->mac_ver >= 0x5390) {
+ sc->ntxchains = (sc->mac_ver == 0x5392) ? 2 : 1;
+ sc->nrxchains = (sc->mac_ver == 0x5392) ? 2 : 1;
+ } else {
+ 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));
@@ -3306,17 +3531,23 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
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)
+ if (sc->txpow1[i] < 0 ||
+ sc->txpow1[i] > ((sc->mac_ver >= 0x5390) ? 39 : 31))
sc->txpow1[i] = 5;
- if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31)
- sc->txpow2[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]));
}
@@ -3484,10 +3715,9 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
return 0;
}
-int
+static int
rt2860_bbp_init(struct rt2860_softc *sc)
{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
int i, ntries;
/* wait for BBP to wake up */
@@ -3499,13 +3729,17 @@ rt2860_bbp_init(struct rt2860_softc *sc)
if (ntries == 20) {
device_printf(sc->sc_dev,
"timeout waiting for BBP to wake up\n");
- return ETIMEDOUT;
+ return (ETIMEDOUT);
}
/* initialize BBP registers to default values */
- for (i = 0; i < N(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 */
@@ -3522,7 +3756,44 @@ rt2860_bbp_init(struct rt2860_softc *sc)
}
return 0;
-#undef N
+}
+
+static 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);
}
static int
@@ -3589,7 +3860,6 @@ rt2860_init(void *arg)
static void
rt2860_init_locked(struct rt2860_softc *sc)
{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
@@ -3664,9 +3934,11 @@ rt2860_init_locked(struct rt2860_softc *sc)
RAL_BARRIER_WRITE(sc);
RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, 0);
- for (i = 0; i < N(rt2860_def_mac); i++)
+ 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);
@@ -3761,7 +4033,8 @@ rt2860_init_locked(struct rt2860_softc *sc)
/* 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->mac_ver == 0x5390)
rt3090_set_rx_antenna(sc, 0);
/* send LEDs operating mode to microcontroller */
@@ -3769,13 +4042,21 @@ rt2860_init_locked(struct rt2860_softc *sc)
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)
- rt3090_rf_init(sc);
+ if (sc->mac_ver >= 0x5390)
+ rt5390_rf_init(sc);
+ else if (sc->mac_ver >= 0x3071) {
+ if ((error = rt3090_rf_init(sc)) != 0) {
+ rt2860_stop_locked(sc);
+ return;
+ }
+ }
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 */
@@ -3836,7 +4117,6 @@ rt2860_init_locked(struct rt2860_softc *sc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc);
-#undef N
}
static void
@@ -3987,15 +4267,25 @@ 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);
+ }
}
}
@@ -4010,7 +4300,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);
@@ -4026,7 +4318,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);
}
OpenPOWER on IntegriCloud