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;

Reply via email to