Looked at your diff, and then noticed that run(4) already had support
for the RT3572 MAC/BBP. It has a few more RT3572-specific bits that
match what the Linux driver does. So I ported them over to ral(4).
Could you give the attached diff a go?
Index: rt2860.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/rt2860.c,v
retrieving revision 1.68
diff -u -p -r1.68 rt2860.c
--- rt2860.c 11 Jun 2013 18:15:53 -0000 1.68
+++ rt2860.c 25 Jul 2013 08:24:44 -0000
@@ -130,6 +130,7 @@ void rt2860_set_basicrates(struct rt286
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 rt3572_set_chan(struct rt2860_softc *, u_int);
int rt3090_rf_init(struct rt2860_softc *);
void rt3090_rf_wakeup(struct rt2860_softc *);
int rt3090_filter_calib(struct rt2860_softc *, uint8_t, uint8_t,
@@ -197,6 +198,8 @@ static const struct {
uint8_t val;
} rt3090_def_rf[] = {
RT3070_DEF_RF
+}, rt3572_def_rf[] = {
+ RT3572_DEF_RF
};
int
@@ -2158,13 +2161,15 @@ rt2860_select_chan_group(struct rt2860_s
rt2860_mcu_bbp_write(sc, 75, 0x50);
}
} else {
- if (sc->ext_5ghz_lna) {
+ if (sc->mac_ver == 0x3572)
+ rt2860_mcu_bbp_write(sc, 82, 0x94);
+ else
rt2860_mcu_bbp_write(sc, 82, 0xf2);
+
+ if (sc->ext_5ghz_lna)
rt2860_mcu_bbp_write(sc, 75, 0x46);
- } else {
- rt2860_mcu_bbp_write(sc, 82, 0xf2);
+ else
rt2860_mcu_bbp_write(sc, 75, 0x50);
- }
}
tmp = RAL_READ(sc, RT2860_TX_BAND_CFG);
@@ -2191,7 +2196,12 @@ rt2860_select_chan_group(struct rt2860_s
if (sc->mac_ver == 0x3593 && sc->ntxchains > 2)
tmp |= RT3593_PA_PE_A2_EN;
}
- RAL_WRITE(sc, RT2860_TX_PIN_CFG, tmp);
+ if (sc->mac_ver == 0x3572) {
+ rt3090_rf_write(sc, 8, 0x00);
+ RAL_WRITE(sc, RT2860_TX_PIN_CFG, tmp);
+ rt3090_rf_write(sc, 8, 0x80);
+ } else
+ RAL_WRITE(sc, RT2860_TX_PIN_CFG, tmp);
if (sc->mac_ver == 0x3593) {
tmp = RAL_READ(sc, RT2860_GPIO_CTRL);
@@ -2215,7 +2225,10 @@ rt2860_select_chan_group(struct rt2860_s
else
agc = 0x2e + sc->lna[0];
} else { /* 5GHz band */
- agc = 0x32 + (sc->lna[group] * 5) / 3;
+ if (sc->mac_ver == 0x3572)
+ agc = 0x22 + (sc->lna[group] * 5) / 3;
+ else
+ agc = 0x32 + (sc->lna[group] * 5) / 3;
}
rt2860_mcu_bbp_write(sc, 66, agc);
@@ -2341,6 +2354,154 @@ rt3090_set_chan(struct rt2860_softc *sc,
rt3090_rf_write(sc, 7, rf | RT3070_TUNE);
}
+void
+rt3572_set_chan(struct rt2860_softc *sc, u_int chan)
+{
+ int8_t txpow1, txpow2;
+ uint32_t tmp;
+ uint8_t rf;
+ int i;
+
+ /* find the settings for this channel (we know it exists) */
+ for (i = 0; rt2860_rf2850[i].chan != chan; i++);
+
+ /* use Tx power values from EEPROM */
+ txpow1 = sc->txpow1[i];
+ txpow2 = sc->txpow2[i];
+
+ if (chan <= 14) {
+ rt2860_mcu_bbp_write(sc, 25, sc->bbp25);
+ rt2860_mcu_bbp_write(sc, 26, sc->bbp26);
+ } else {
+ /* enable IQ phase correction */
+ rt2860_mcu_bbp_write(sc, 25, 0x09);
+ rt2860_mcu_bbp_write(sc, 26, 0xff);
+ }
+
+ rt3090_rf_write(sc, 2, rt3090_freqs[i].n);
+ rt3090_rf_write(sc, 3, rt3090_freqs[i].k);
+ rf = rt3090_rf_read(sc, 6);
+ rf = (rf & ~0x0f) | rt3090_freqs[i].r;
+ rf |= (chan <= 14) ? 0x08 : 0x04;
+ rt3090_rf_write(sc, 6, rf);
+
+ /* set PLL mode */
+ rf = rt3090_rf_read(sc, 5);
+ rf &= ~(0x08 | 0x04);
+ rf |= (chan <= 14) ? 0x04 : 0x08;
+ rt3090_rf_write(sc, 5, rf);
+
+ /* set Tx power for chain 0 */
+ if (chan <= 14)
+ rf = 0x60 | txpow1;
+ else
+ rf = 0xe0 | (txpow1 & 0xc) << 1 | (txpow1 & 0x3);
+ rt3090_rf_write(sc, 12, rf);
+
+ /* set Tx power for chain 1 */
+ if (chan <= 14)
+ rf = 0x60 | txpow2;
+ else
+ rf = 0xe0 | (txpow2 & 0xc) << 1 | (txpow2 & 0x3);
+ rt3090_rf_write(sc, 13, rf);
+
+ /* set Tx/Rx streams */
+ rf = rt3090_rf_read(sc, 1);
+ rf &= ~0xfc;
+ if (sc->ntxchains == 1)
+ rf |= 1 << 7 | 1 << 5; /* 1T: disable Tx chains 2 & 3 */
+ else if (sc->ntxchains == 2)
+ rf |= 1 << 7; /* 2T: disable Tx chain 3 */
+ if (sc->nrxchains == 1)
+ rf |= 1 << 6 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */
+ else if (sc->nrxchains == 2)
+ rf |= 1 << 6; /* 2R: disable Rx chain 3 */
+ rt3090_rf_write(sc, 1, rf);
+
+ /* set RF offset */
+ rf = rt3090_rf_read(sc, 23);
+ rf = (rf & ~0x7f) | sc->freq;
+ rt3090_rf_write(sc, 23, rf);
+
+ /* program RF filter */
+ rf = sc->rf24_20mhz;
+ rt3090_rf_write(sc, 24, rf); /* Tx */
+ rt3090_rf_write(sc, 31, rf); /* Rx */
+
+ /* enable RF tuning */
+ rf = rt3090_rf_read(sc, 7);
+ rf = (chan <= 14) ? 0xd8 : ((rf & ~0xc8) | 0x14);
+ rt3090_rf_write(sc, 7, rf);
+
+ /* TSSI */
+ rf = (chan <= 14) ? 0xc3 : 0xc0;
+ rt3090_rf_write(sc, 9, rf);
+
+ /* set loop filter 1 */
+ rt3090_rf_write(sc, 10, 0xf1);
+ /* set loop filter 2 */
+ rt3090_rf_write(sc, 11, (chan <= 14) ? 0xb9 : 0x00);
+
+ /* set tx_mx2_ic */
+ rt3090_rf_write(sc, 15, (chan <= 14) ? 0x53 : 0x43);
+ /* set tx_mx1_ic */
+ if (chan <= 14)
+ rf = 0x48 | sc->txmixgain_2ghz;
+ else
+ rf = 0x78 | sc->txmixgain_5ghz;
+ rt3090_rf_write(sc, 16, rf);
+
+ /* set tx_lo1 */
+ rt3090_rf_write(sc, 17, 0x23);
+ /* set tx_lo2 */
+ if (chan <= 14)
+ rf = 0x93;
+ else if (chan <= 64)
+ rf = 0xb7;
+ else if (chan <= 128)
+ rf = 0x74;
+ else
+ rf = 0x72;
+ rt3090_rf_write(sc, 19, rf);
+
+ /* set rx_lo1 */
+ if (chan <= 14)
+ rf = 0xb3;
+ else if (chan <= 64)
+ rf = 0xf6;
+ else if (chan <= 128)
+ rf = 0xf4;
+ else
+ rf = 0xf3;
+ rt3090_rf_write(sc, 20, rf);
+
+ /* set pfd_delay */
+ if (chan <= 14)
+ rf = 0x15;
+ else if (chan <= 64)
+ rf = 0x3d;
+ else
+ rf = 0x01;
+ rt3090_rf_write(sc, 25, rf);
+
+ /* set rx_lo2 */
+ rt3090_rf_write(sc, 26, (chan <= 14) ? 0x85 : 0x87);
+ /* set ldo_rf_vc */
+ rt3090_rf_write(sc, 27, (chan <= 14) ? 0x00 : 0x01);
+ /* set drv_cc */
+ rt3090_rf_write(sc, 29, (chan <= 14) ? 0x9b : 0x9f);
+
+ tmp = RAL_READ(sc, RT2860_GPIO_CTRL);
+ tmp &= ~0x8080;
+ if (chan <= 14)
+ tmp |= 0x80;
+ RAL_WRITE(sc, RT2860_GPIO_CTRL, tmp);
+
+ /* enable RF tuning */
+ rf = rt3090_rf_read(sc, 7);
+ rt3090_rf_write(sc, 7, rf | 0x01);
+}
+
int
rt3090_rf_init(struct rt2860_softc *sc)
{
@@ -2367,9 +2528,16 @@ 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 < nitems(rt3090_def_rf); i++) {
- rt3090_rf_write(sc, rt3090_def_rf[i].reg,
- rt3090_def_rf[i].val);
+ if (sc->mac_ver == 0x3572) {
+ for (i = 0; i < nitems(rt3090_def_rf); i++) {
+ rt3090_rf_write(sc, rt3090_def_rf[i].reg,
+ rt3090_def_rf[i].val);
+ }
+ } else {
+ for (i = 0; i < nitems(rt3090_def_rf); i++) {
+ rt3090_rf_write(sc, rt3090_def_rf[i].reg,
+ rt3090_def_rf[i].val);
+ }
}
/* select 20MHz bandwidth */
@@ -2396,6 +2564,12 @@ rt3090_rf_init(struct rt2860_softc *sc)
/* go back to 20MHz bandwidth */
bbp = rt2860_mcu_bbp_read(sc, 4);
rt2860_mcu_bbp_write(sc, 4, bbp & ~0x18);
+
+ if (sc->mac_ver == 0x3572) {
+ /* save default BBP registers 25 and 26 values */
+ sc->bbp25 = rt2860_mcu_bbp_read(sc, 25);
+ sc->bbp26 = rt2860_mcu_bbp_read(sc, 26);
+ }
}
if (sc->mac_rev < 0x0211)
rt3090_rf_write(sc, 27, 0x03);
@@ -3756,7 +3930,9 @@ rt2860_switch_chan(struct rt2860_softc *
if (chan == 0 || chan == IEEE80211_CHAN_ANY)
return;
- if (sc->mac_ver >= 0x3071)
+ if (sc->mac_ver == 0x3572)
+ rt3572_set_chan(sc, chan);
+ else if (sc->mac_ver >= 0x3071)
rt3090_set_chan(sc, chan);
else
rt2860_set_chan(sc, chan);
Index: rt2860var.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/rt2860var.h,v
retrieving revision 1.20
diff -u -p -r1.20 rt2860var.h
--- rt2860var.h 7 Sep 2010 16:21:42 -0000 1.20
+++ rt2860var.h 25 Jul 2013 08:24:44 -0000
@@ -156,6 +156,8 @@ struct rt2860_softc {
int8_t rssi_2ghz[3];
int8_t rssi_5ghz[3];
uint8_t lna[4];
+ uint8_t bbp25;
+ uint8_t bbp26;
uint8_t rf24_20mhz;
uint8_t rf24_40mhz;
uint8_t patch_dac;