etherrt2860: add rt3090 support and make style more consistent
This commit is contained in:
parent
776056dcd0
commit
9a5763624f
1 changed files with 657 additions and 109 deletions
|
@ -783,6 +783,33 @@ enum {
|
|||
Rf3053 = 13 /* dual-band 3T3R */,
|
||||
};
|
||||
|
||||
enum {
|
||||
Rt3070RfBlock = (1 << 0),
|
||||
Rt3070Rx0Pd = (1 << 2),
|
||||
Rt3070Tx0Pd = (1 << 3),
|
||||
Rt3070Rx1Pd = (1 << 4),
|
||||
Rt3070Tx1Pd = (1 << 5),
|
||||
Rt3070Rx2Pd = (1 << 6),
|
||||
Rt3070Tx2Pd = (1 << 7),
|
||||
Rt3070Tune = (1 << 0),
|
||||
Rt3070TxLo2 = (1 << 3),
|
||||
Rt3070TxLo1 = (1 << 3),
|
||||
Rt3070RxLo1 = (1 << 3),
|
||||
Rt3070RxLo2 = (1 << 3),
|
||||
Rt3070RxCtb = (1 << 7),
|
||||
Rt3070BbLoopback = (1 << 0),
|
||||
|
||||
Rt3593Vco = (1 << 0),
|
||||
Rt3593Rescal = (1 << 7),
|
||||
Rt3593Vcocal = (1 << 7),
|
||||
Rt3593VcoIc = (1 << 6),
|
||||
Rt3593LdoPllVcMask = 0x0e,
|
||||
Rt3593LdoRfVcMask = 0xe0,
|
||||
Rt3593CpIcMask = 0xe0,
|
||||
Rt3593CpIcShift = 5,
|
||||
Rt3593RxCtb = (1 << 5)
|
||||
};
|
||||
|
||||
static const char* rfnames[] = {
|
||||
[Rf2820] "RT2820",
|
||||
[Rf2850] "RT2850",
|
||||
|
@ -976,7 +1003,6 @@ enum {
|
|||
ConnPciE = 1 << 1,
|
||||
};
|
||||
|
||||
|
||||
static const struct rt2860_rate {
|
||||
u8int rate;
|
||||
u8int mcs;
|
||||
|
@ -1122,6 +1148,91 @@ static const struct rfprog {
|
|||
{ 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 },
|
||||
};
|
||||
|
||||
struct {
|
||||
u8int n;
|
||||
u8int r;
|
||||
u8int k;
|
||||
} rt3090_freqs[] = {
|
||||
{ 0xf1, 2, 2 },
|
||||
{ 0xf1, 2, 7 },
|
||||
{ 0xf2, 2, 2 },
|
||||
{ 0xf2, 2, 7 },
|
||||
{ 0xf3, 2, 2 },
|
||||
{ 0xf3, 2, 7 },
|
||||
{ 0xf4, 2, 2 },
|
||||
{ 0xf4, 2, 7 },
|
||||
{ 0xf5, 2, 2 },
|
||||
{ 0xf5, 2, 7 },
|
||||
{ 0xf6, 2, 2 },
|
||||
{ 0xf6, 2, 7 },
|
||||
{ 0xf7, 2, 2 },
|
||||
{ 0xf8, 2, 4 },
|
||||
{ 0x56, 0, 4 },
|
||||
{ 0x56, 0, 6 },
|
||||
{ 0x56, 0, 8 },
|
||||
{ 0x57, 0, 0 },
|
||||
{ 0x57, 0, 2 },
|
||||
{ 0x57, 0, 4 },
|
||||
{ 0x57, 0, 8 },
|
||||
{ 0x57, 0, 10 },
|
||||
{ 0x58, 0, 0 },
|
||||
{ 0x58, 0, 4 },
|
||||
{ 0x58, 0, 6 },
|
||||
{ 0x58, 0, 8 },
|
||||
{ 0x5b, 0, 8 },
|
||||
{ 0x5b, 0, 10 },
|
||||
{ 0x5c, 0, 0 },
|
||||
{ 0x5c, 0, 4 },
|
||||
{ 0x5c, 0, 6 },
|
||||
{ 0x5c, 0, 8 },
|
||||
{ 0x5d, 0, 0 },
|
||||
{ 0x5d, 0, 2 },
|
||||
{ 0x5d, 0, 4 },
|
||||
{ 0x5d, 0, 8 },
|
||||
{ 0x5d, 0, 10 },
|
||||
{ 0x5e, 0, 0 },
|
||||
{ 0x5e, 0, 4 },
|
||||
{ 0x5e, 0, 6 },
|
||||
{ 0x5e, 0, 8 },
|
||||
{ 0x5f, 0, 0 },
|
||||
{ 0x5f, 0, 9 },
|
||||
{ 0x5f, 0, 11 },
|
||||
{ 0x60, 0, 1 },
|
||||
{ 0x60, 0, 5 },
|
||||
{ 0x60, 0, 7 },
|
||||
{ 0x60, 0, 9 },
|
||||
{ 0x61, 0, 1 },
|
||||
{ 0x61, 0, 3 },
|
||||
{ 0x61, 0, 5 },
|
||||
{ 0x61, 0, 7 },
|
||||
{ 0x61, 0, 9 }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
u8int reg;
|
||||
u8int val;
|
||||
} rt3090_def_rf[] = {
|
||||
{ 4, 0x40 },
|
||||
{ 5, 0x03 },
|
||||
{ 6, 0x02 },
|
||||
{ 7, 0x70 },
|
||||
{ 9, 0x0f },
|
||||
{ 10, 0x41 },
|
||||
{ 11, 0x21 },
|
||||
{ 12, 0x7b },
|
||||
{ 14, 0x90 },
|
||||
{ 15, 0x58 },
|
||||
{ 16, 0xb3 },
|
||||
{ 17, 0x92 },
|
||||
{ 18, 0x2c },
|
||||
{ 19, 0x02 },
|
||||
{ 20, 0xba },
|
||||
{ 21, 0xdb },
|
||||
{ 24, 0x16 },
|
||||
{ 25, 0x01 },
|
||||
{ 29, 0x1f }
|
||||
};
|
||||
|
||||
/* vendors */
|
||||
enum {
|
||||
Ralink = 0x1814,
|
||||
|
@ -1131,6 +1242,7 @@ enum {
|
|||
enum {
|
||||
RalinkRT2890 = 0x0681,
|
||||
RalinkRT2790 = 0x0781,
|
||||
RalinkRT3090 = 0x3090,
|
||||
AwtRT2890 = 0x1059,
|
||||
};
|
||||
|
||||
|
@ -1139,6 +1251,7 @@ enum {
|
|||
|
||||
static int rbplant(Ctlr*, int);
|
||||
static void setchan(Ctlr*, uint);
|
||||
static void rt3090setchan(Ctlr*, uint);
|
||||
static void selchangroup(Ctlr*, int);
|
||||
static void setleds(Ctlr*, u16int);
|
||||
|
||||
|
@ -1242,6 +1355,9 @@ rxon(Ether *edev, Wnode *bss)
|
|||
edev->ctlrno, ctlr->bssid, ctlr->aid, ctlr->channel, ctlr->wcid);
|
||||
|
||||
/* Set channel */
|
||||
if(ctlr->mac_ver >= 0x3071)
|
||||
rt3090setchan(ctlr, ctlr->channel);
|
||||
else
|
||||
setchan(ctlr, ctlr->channel);
|
||||
selchangroup(ctlr, 0);
|
||||
microdelay(1000);
|
||||
|
@ -1600,7 +1716,7 @@ txrxon(Ctlr *ctlr)
|
|||
/*
|
||||
* Write to one of the 4 programmable 24-bit RF registers.
|
||||
*/
|
||||
static char*
|
||||
static void
|
||||
rfwrite(Ctlr *ctlr, u8int reg, u32int val)
|
||||
{
|
||||
u32int tmp;
|
||||
|
@ -1611,14 +1727,66 @@ rfwrite(Ctlr *ctlr, u8int reg, u32int val)
|
|||
break;
|
||||
microdelay(1);
|
||||
}
|
||||
if(ntries == 100)
|
||||
return "could not write to RF";
|
||||
if(ntries == 100){
|
||||
print("could not write to RF\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* RF registers are 24-bit on the RT2860 */
|
||||
tmp = RfRegCtrl | 24 << RfRegWidthShift |
|
||||
(val & 0x3fffff) << 2 | (reg & 3);
|
||||
csr32w(ctlr, RfCsrCfg0, tmp);
|
||||
return nil;
|
||||
}
|
||||
|
||||
u8int
|
||||
rt3090rfread(Ctlr *ctlr, u8int reg)
|
||||
{
|
||||
u32int tmp;
|
||||
int ntries;
|
||||
|
||||
for(ntries = 0; ntries < 100; ntries++){
|
||||
if(!(csr32r(ctlr, Rt3070RfCsrCfg) & Rt3070RfKick))
|
||||
break;
|
||||
microdelay(1);
|
||||
}
|
||||
if(ntries == 100){
|
||||
print("could not read RF register\n");
|
||||
return 0xff;
|
||||
}
|
||||
tmp = Rt3070RfKick | reg << 8;
|
||||
csr32w(ctlr, Rt3070RfCsrCfg, tmp);
|
||||
|
||||
for(ntries = 0; ntries < 100; ntries++){
|
||||
tmp = csr32r(ctlr, Rt3070RfCsrCfg);
|
||||
if(!(tmp & Rt3070RfKick))
|
||||
break;
|
||||
microdelay(1);
|
||||
}
|
||||
if(ntries == 100){
|
||||
print("could not read RF register\n");
|
||||
return 0xff;
|
||||
}
|
||||
return tmp & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
rt3090rfwrite(Ctlr *ctlr, u8int reg, u8int val)
|
||||
{
|
||||
u32int tmp;
|
||||
int ntries;
|
||||
|
||||
for(ntries = 0; ntries < 10; ntries++){
|
||||
if(!(csr32r(ctlr, Rt3070RfCsrCfg) & Rt3070RfKick))
|
||||
break;
|
||||
microdelay(10);
|
||||
}
|
||||
if(ntries == 10){
|
||||
print("could not write to RF\n");
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = Rt3070RfWrite | Rt3070RfKick | reg << 8 | val;
|
||||
csr32w(ctlr, Rt3070RfCsrCfg, tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1761,6 +1929,356 @@ setchan(Ctlr *ctlr, uint chan)
|
|||
rfwrite(ctlr, Rf4, r4);
|
||||
}
|
||||
|
||||
static void
|
||||
rt3090setchan(Ctlr *ctlr, uint chan)
|
||||
{
|
||||
s8int txpow1, txpow2;
|
||||
u8int rf;
|
||||
int i;
|
||||
|
||||
assert(chan >= 1 && chan <= 14); /* RT3090 is 2GHz only */
|
||||
|
||||
/* 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 = ctlr->txpow1[i];
|
||||
txpow2 = ctlr->txpow2[i];
|
||||
|
||||
rt3090rfwrite(ctlr, 2, rt3090_freqs[i].n);
|
||||
rf = rt3090rfread(ctlr, 3);
|
||||
rf = (rf & ~0x0f) | rt3090_freqs[i].k;
|
||||
rt3090rfwrite(ctlr, 3, rf);
|
||||
rf = rt3090rfread(ctlr, 6);
|
||||
rf = (rf & ~0x03) | rt3090_freqs[i].r;
|
||||
rt3090rfwrite(ctlr, 6, rf);
|
||||
|
||||
/* set Tx0 power */
|
||||
rf = rt3090rfread(ctlr, 12);
|
||||
rf = (rf & ~0x1f) | txpow1;
|
||||
rt3090rfwrite(ctlr, 12, rf);
|
||||
|
||||
/* set Tx1 power */
|
||||
rf = rt3090rfread(ctlr, 13);
|
||||
rf = (rf & ~0x1f) | txpow2;
|
||||
rt3090rfwrite(ctlr, 13, rf);
|
||||
|
||||
rf = rt3090rfread(ctlr, 1);
|
||||
rf &= ~0xfc;
|
||||
if(ctlr->ntxchains == 1)
|
||||
rf |= Rt3070Tx1Pd | Rt3070Tx2Pd;
|
||||
else if(ctlr->ntxchains == 2)
|
||||
rf |= Rt3070Tx2Pd;
|
||||
if(ctlr->nrxchains == 1)
|
||||
rf |= Rt3070Rx1Pd | Rt3070Rx2Pd;
|
||||
else if(ctlr->nrxchains == 2)
|
||||
rf |= Rt3070Rx2Pd;
|
||||
rt3090rfwrite(ctlr, 1, rf);
|
||||
|
||||
/* set RF offset */
|
||||
rf = rt3090rfread(ctlr, 23);
|
||||
rf = (rf & ~0x7f) | ctlr->freq;
|
||||
rt3090rfwrite(ctlr, 23, rf);
|
||||
|
||||
/* program RF filter */
|
||||
rf = rt3090rfread(ctlr, 24); /* Tx */
|
||||
rf = (rf & ~0x3f) | ctlr->rf24_20mhz;
|
||||
rt3090rfwrite(ctlr, 24, rf);
|
||||
rf = rt3090rfread(ctlr, 31); /* Rx */
|
||||
rf = (rf & ~0x3f) | ctlr->rf24_20mhz;
|
||||
rt3090rfwrite(ctlr, 31, rf);
|
||||
|
||||
/* enable RF tuning */
|
||||
rf = rt3090rfread(ctlr, 7);
|
||||
rt3090rfwrite(ctlr, 7, rf | Rt3070Tune);
|
||||
}
|
||||
|
||||
static int
|
||||
rt3090filtercalib(Ctlr *ctlr, u8int init, u8int target, u8int *val)
|
||||
{
|
||||
u8int rf22, rf24;
|
||||
u8int bbp55_pb, bbp55_sb, delta;
|
||||
int ntries;
|
||||
|
||||
/* program filter */
|
||||
rf24 = rt3090rfread(ctlr, 24);
|
||||
rf24 = (rf24 & 0xc0) | init; /* initial filter value */
|
||||
rt3090rfwrite(ctlr, 24, rf24);
|
||||
|
||||
/* enable baseband loopback mode */
|
||||
rf22 = rt3090rfread(ctlr, 22);
|
||||
rt3090rfwrite(ctlr, 22, rf22 | Rt3070BbLoopback);
|
||||
|
||||
/* set power and frequency of passband test tone */
|
||||
bbpwrite(ctlr, 24, 0x00);
|
||||
for(ntries = 0, bbp55_pb = 0; ntries < 100; ntries++){
|
||||
/* transmit test tone */
|
||||
bbpwrite(ctlr, 25, 0x90);
|
||||
microdelay(1000);
|
||||
/* read received power */
|
||||
bbp55_pb = bbpread(ctlr, 55);
|
||||
if(bbp55_pb != 0)
|
||||
break;
|
||||
}
|
||||
if(ntries == 100)
|
||||
return -1;
|
||||
|
||||
/* set power and frequency of stopband test tone */
|
||||
bbpwrite(ctlr, 24, 0x06);
|
||||
for(ntries = 0; ntries < 100; ntries++){
|
||||
/* transmit test tone */
|
||||
bbpwrite(ctlr, 25, 0x90);
|
||||
microdelay(1000);
|
||||
/* read received power */
|
||||
bbp55_sb = bbpread(ctlr, 55);
|
||||
|
||||
delta = bbp55_pb - bbp55_sb;
|
||||
if(delta > target)
|
||||
break;
|
||||
|
||||
/* reprogram filter */
|
||||
rf24++;
|
||||
rt3090rfwrite(ctlr, 24, rf24);
|
||||
}
|
||||
if(ntries < 100){
|
||||
if(rf24 != init)
|
||||
rf24--; /* backtrack */
|
||||
*val = rf24;
|
||||
rt3090rfwrite(ctlr, 24, rf24);
|
||||
}
|
||||
|
||||
/* restore initial state */
|
||||
bbpwrite(ctlr, 24, 0x00);
|
||||
|
||||
/* disable baseband loopback mode */
|
||||
rf22 = rt3090rfread(ctlr, 22);
|
||||
rt3090rfwrite(ctlr, 22, rf22 & ~Rt3070BbLoopback);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
rt3090setrxantenna(Ctlr *ctlr, int aux)
|
||||
{
|
||||
u32int tmp;
|
||||
|
||||
if(aux){
|
||||
tmp = csr32r(ctlr, PciEectrl);
|
||||
csr32w(ctlr, PciEectrl, tmp & ~EectrlC);
|
||||
tmp = csr32r(ctlr, GpioCtrl);
|
||||
csr32w(ctlr, GpioCtrl, (tmp & ~0x0808) | 0x08);
|
||||
}else{
|
||||
tmp = csr32r(ctlr, PciEectrl);
|
||||
csr32w(ctlr, PciEectrl, tmp | EectrlC);
|
||||
tmp = csr32r(ctlr, GpioCtrl);
|
||||
csr32w(ctlr, GpioCtrl, tmp & ~0x0808);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
rt3090rfinit(Ctlr *ctlr)
|
||||
{
|
||||
u32int tmp;
|
||||
u8int rf, bbp;
|
||||
int i;
|
||||
|
||||
rf = rt3090rfread(ctlr, 30);
|
||||
/* toggle RF R30 bit 7 */
|
||||
rt3090rfwrite(ctlr, 30, rf | 0x80);
|
||||
microdelay(1000);
|
||||
rt3090rfwrite(ctlr, 30, rf & ~0x80);
|
||||
|
||||
tmp = csr32r(ctlr, Rt3070LdoCfg0);
|
||||
tmp &= ~0x1f000000;
|
||||
if(ctlr->patch_dac && ctlr->mac_rev < 0x0211)
|
||||
tmp |= 0x0d000000; /* 1.35V */
|
||||
else
|
||||
tmp |= 0x01000000; /* 1.2V */
|
||||
csr32w(ctlr, Rt3070LdoCfg0, tmp);
|
||||
|
||||
/* patch LNA_PE_G1 */
|
||||
tmp = csr32r(ctlr, Rt3070GpioSwitch);
|
||||
csr32w(ctlr, Rt3070GpioSwitch, tmp & ~0x20);
|
||||
|
||||
/* initialize RF registers to default value */
|
||||
for(i = 0; i < nelem(rt3090_def_rf); i++){
|
||||
rt3090rfwrite(ctlr, rt3090_def_rf[i].reg,
|
||||
rt3090_def_rf[i].val);
|
||||
}
|
||||
|
||||
/* select 20MHz bandwidth */
|
||||
rt3090rfwrite(ctlr, 31, 0x14);
|
||||
|
||||
rf = rt3090rfread(ctlr, 6);
|
||||
rt3090rfwrite(ctlr, 6, rf | 0x40);
|
||||
|
||||
if(ctlr->mac_ver != 0x3593){
|
||||
/* calibrate filter for 20MHz bandwidth */
|
||||
ctlr->rf24_20mhz = 0x1f; /* default value */
|
||||
rt3090filtercalib(ctlr, 0x07, 0x16, &ctlr->rf24_20mhz);
|
||||
|
||||
/* select 40MHz bandwidth */
|
||||
bbp = bbpread(ctlr, 4);
|
||||
bbpwrite(ctlr, 4, (bbp & ~0x08) | 0x10);
|
||||
rf = rt3090rfread(ctlr, 31);
|
||||
rt3090rfwrite(ctlr, 31, rf | 0x20);
|
||||
|
||||
/* calibrate filter for 40MHz bandwidth */
|
||||
ctlr->rf24_40mhz = 0x2f; /* default value */
|
||||
rt3090filtercalib(ctlr, 0x27, 0x19, &ctlr->rf24_40mhz);
|
||||
|
||||
/* go back to 20MHz bandwidth */
|
||||
bbp = bbpread(ctlr, 4);
|
||||
bbpwrite(ctlr, 4, bbp & ~0x18);
|
||||
}
|
||||
if(ctlr->mac_rev < 0x0211)
|
||||
rt3090rfwrite(ctlr, 27, 0x03);
|
||||
|
||||
tmp = csr32r(ctlr, Rt3070Opt14);
|
||||
csr32w(ctlr, Rt3070Opt14, tmp | 1);
|
||||
|
||||
if(ctlr->rf_rev == Rf3020)
|
||||
rt3090setrxantenna(ctlr, 0);
|
||||
|
||||
bbp = bbpread(ctlr, 138);
|
||||
if(ctlr->mac_ver == 0x3593){
|
||||
if(ctlr->ntxchains == 1)
|
||||
bbp |= 0x60; /* turn off DAC1 and DAC2 */
|
||||
else if(ctlr->ntxchains == 2)
|
||||
bbp |= 0x40; /* turn off DAC2 */
|
||||
if(ctlr->nrxchains == 1)
|
||||
bbp &= ~0x06; /* turn off ADC1 and ADC2 */
|
||||
else if(ctlr->nrxchains == 2)
|
||||
bbp &= ~0x04; /* turn off ADC2 */
|
||||
}else{
|
||||
if(ctlr->ntxchains == 1)
|
||||
bbp |= 0x20; /* turn off DAC1 */
|
||||
if(ctlr->nrxchains == 1)
|
||||
bbp &= ~0x02; /* turn off ADC1 */
|
||||
}
|
||||
bbpwrite(ctlr, 138, bbp);
|
||||
|
||||
rf = rt3090rfread(ctlr, 1);
|
||||
rf &= ~(Rt3070Rx0Pd | Rt3070Tx0Pd);
|
||||
rf |= Rt3070RfBlock | Rt3070Rx1Pd | Rt3070Tx1Pd;
|
||||
rt3090rfwrite(ctlr, 1, rf);
|
||||
|
||||
rf = rt3090rfread(ctlr, 15);
|
||||
rt3090rfwrite(ctlr, 15, rf & ~Rt3070TxLo2);
|
||||
|
||||
rf = rt3090rfread(ctlr, 17);
|
||||
rf &= ~Rt3070TxLo1;
|
||||
if(ctlr->mac_rev >= 0x0211 && !ctlr->ext_2ghz_lna)
|
||||
rf |= 0x20; /* fix for long range Rx issue */
|
||||
if(ctlr->txmixgain_2ghz >= 2)
|
||||
rf = (rf & ~0x7) | ctlr->txmixgain_2ghz;
|
||||
rt3090rfwrite(ctlr, 17, rf);
|
||||
|
||||
rf = rt3090rfread(ctlr, 20);
|
||||
rt3090rfwrite(ctlr, 20, rf & ~Rt3070RxLo1);
|
||||
|
||||
rf = rt3090rfread(ctlr, 21);
|
||||
rt3090rfwrite(ctlr, 21, rf & ~Rt3070RxLo2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
rt3090rfwakeup(Ctlr *ctlr)
|
||||
{
|
||||
u32int tmp;
|
||||
u8int rf;
|
||||
|
||||
if(ctlr->mac_ver == 0x3593){
|
||||
/* enable VCO */
|
||||
rf = rt3090rfread(ctlr, 1);
|
||||
rt3090rfwrite(ctlr, 1, rf | Rt3593Vco);
|
||||
|
||||
/* initiate VCO calibration */
|
||||
rf = rt3090rfread(ctlr, 3);
|
||||
rt3090rfwrite(ctlr, 3, rf | Rt3593Vcocal);
|
||||
|
||||
/* enable VCO bias current control */
|
||||
rf = rt3090rfread(ctlr, 6);
|
||||
rt3090rfwrite(ctlr, 6, rf | Rt3593VcoIc);
|
||||
|
||||
/* initiate res calibration */
|
||||
rf = rt3090rfread(ctlr, 2);
|
||||
rt3090rfwrite(ctlr, 2, rf | Rt3593Rescal);
|
||||
|
||||
/* set reference current control to 0.33 mA */
|
||||
rf = rt3090rfread(ctlr, 22);
|
||||
rf &= ~Rt3593CpIcMask;
|
||||
rf |= 1 << Rt3593CpIcShift;
|
||||
rt3090rfwrite(ctlr, 22, rf);
|
||||
|
||||
/* enable RX CTB */
|
||||
rf = rt3090rfread(ctlr, 46);
|
||||
rt3090rfwrite(ctlr, 46, rf | Rt3593RxCtb);
|
||||
|
||||
rf = rt3090rfread(ctlr, 20);
|
||||
rf &= ~(Rt3593LdoRfVcMask | Rt3593LdoPllVcMask);
|
||||
rt3090rfwrite(ctlr, 20, rf);
|
||||
}else{
|
||||
/* enable RF block */
|
||||
rf = rt3090rfread(ctlr, 1);
|
||||
rt3090rfwrite(ctlr, 1, rf | Rt3070RfBlock);
|
||||
|
||||
/* enable VCO bias current control */
|
||||
rf = rt3090rfread(ctlr, 7);
|
||||
rt3090rfwrite(ctlr, 7, rf | 0x30);
|
||||
|
||||
rf = rt3090rfread(ctlr, 9);
|
||||
rt3090rfwrite(ctlr, 9, rf | 0x0e);
|
||||
|
||||
/* enable RX CTB */
|
||||
rf = rt3090rfread(ctlr, 21);
|
||||
rt3090rfwrite(ctlr, 21, rf | Rt3070RxCtb);
|
||||
|
||||
/* fix Tx to Rx IQ glitch by raising RF voltage */
|
||||
rf = rt3090rfread(ctlr, 27);
|
||||
rf &= ~0x77;
|
||||
if(ctlr->mac_rev < 0x0211)
|
||||
rf |= 0x03;
|
||||
rt3090rfwrite(ctlr, 27, rf);
|
||||
}
|
||||
if(ctlr->patch_dac && ctlr->mac_rev < 0x0211){
|
||||
tmp = csr32r(ctlr, Rt3070LdoCfg0);
|
||||
tmp = (tmp & ~0x1f000000) | 0x0d000000;
|
||||
csr32w(ctlr, Rt3070LdoCfg0, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rt3090rfsetup(Ctlr *ctlr)
|
||||
{
|
||||
u8int bbp;
|
||||
int i;
|
||||
|
||||
if(ctlr->mac_rev >= 0x0211){
|
||||
/* enable DC filter */
|
||||
bbpwrite(ctlr, 103, 0xc0);
|
||||
|
||||
/* improve power consumption */
|
||||
bbp = bbpread(ctlr, 31);
|
||||
bbpwrite(ctlr, 31, bbp & ~0x03);
|
||||
}
|
||||
|
||||
csr32w(ctlr, TxSwCfg1, 0);
|
||||
if(ctlr->mac_rev < 0x0211){
|
||||
csr32w(ctlr, TxSwCfg2,
|
||||
ctlr->patch_dac ? 0x2c : 0x0f);
|
||||
}else
|
||||
csr32w(ctlr, TxSwCfg2, 0);
|
||||
|
||||
/* initialize RF registers from ROM */
|
||||
for(i = 0; i < 10; i++){
|
||||
if(ctlr->rf[i].reg == 0 || ctlr->rf[i].reg == 0xff)
|
||||
continue;
|
||||
rt3090rfwrite(ctlr, ctlr->rf[i].reg, ctlr->rf[i].val);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
updateprot(Ctlr *ctlr)
|
||||
{
|
||||
|
@ -1945,29 +2463,24 @@ rt2860start(Ether *edev)
|
|||
}
|
||||
|
||||
/* select Main antenna for 1T1R devices */
|
||||
/* notyet
|
||||
if(ctlr->rf_rev == Rf2020 ||
|
||||
ctlr->rf_rev == Rf3020 ||
|
||||
ctlr->rf_rev == Rf3320)
|
||||
rt3090_set_rx_antenna(ctlr, 0);
|
||||
*/
|
||||
rt3090setrxantenna(ctlr, 0);
|
||||
|
||||
/* send LEDs operating mode to microcontroller */
|
||||
mcucmd(ctlr, McuCmdLed1, ctlr->led[0], 0);
|
||||
mcucmd(ctlr, McuCmdLed2, ctlr->led[1], 0);
|
||||
mcucmd(ctlr, McuCmdLed3, ctlr->led[2], 0);
|
||||
|
||||
/* XXX: 30xx
|
||||
if(ctlr->mac_ver >= 0x3071)
|
||||
rt3090_rf_init(ctlr);
|
||||
*/
|
||||
rt3090rfinit(ctlr);
|
||||
|
||||
mcucmd(ctlr, McuCmdSleep, 0x02ff, 1);
|
||||
mcucmd(ctlr, McuCmdWakeup, 0, 1);
|
||||
/* XXX: 30xx
|
||||
|
||||
if(ctlr->mac_ver >= 0x3071)
|
||||
rt3090_rf_wakeup(ctlr);
|
||||
*/
|
||||
rt3090rfwakeup(ctlr);
|
||||
|
||||
/* disable non-existing Rx chains */
|
||||
bbp3 = bbpread(ctlr, 3);
|
||||
|
@ -1987,11 +2500,14 @@ rt2860start(Ether *edev)
|
|||
else if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains == 3)
|
||||
bbp1 = (bbp1 & ~(1 << 3)) | 1 << 4;
|
||||
bbpwrite(ctlr, 1, bbp1);
|
||||
/* XXX: 30xx
|
||||
|
||||
if(ctlr->mac_ver >= 0x3071)
|
||||
rt3090_rf_setup(ctlr);
|
||||
*/
|
||||
rt3090rfsetup(ctlr);
|
||||
|
||||
/* select default channel */
|
||||
if(ctlr->mac_ver >= 0x3071)
|
||||
rt3090setchan(ctlr, 3);
|
||||
else
|
||||
setchan(ctlr, 3);
|
||||
|
||||
/* reset RF from MCU */
|
||||
|
@ -2450,11 +2966,41 @@ eeread2(Ctlr *ctlr, u16int addr)
|
|||
|
||||
/* Read 16-bit from eFUSE ROM (>=RT3071 only.) */
|
||||
static u16int
|
||||
efuseread2(Ctlr *, u16int)
|
||||
efuseread2(Ctlr *ctlr, u16int addr)
|
||||
{
|
||||
/* XXX: 30xx */
|
||||
print("efuse rom not implemented\n");
|
||||
return 0;
|
||||
u32int tmp;
|
||||
u16int reg;
|
||||
int ntries;
|
||||
|
||||
addr *= 2;
|
||||
/*-
|
||||
* Read one 16-byte block into registers EFUSE_DATA[0-3]:
|
||||
* DATA0: F E D C
|
||||
* DATA1: B A 9 8
|
||||
* DATA2: 7 6 5 4
|
||||
* DATA3: 3 2 1 0
|
||||
*/
|
||||
tmp = csr32r(ctlr, Rt3070EfuseCtrl);
|
||||
tmp &= ~(Rt3070EfsromModeMask | Rt3070EfsromAinMask);
|
||||
tmp |= (addr & ~0xf) << Rt3070EfsromAinShift | Rt3070EfsromKick;
|
||||
csr32w(ctlr, Rt3070EfuseCtrl, tmp);
|
||||
for(ntries = 0; ntries < 500; ntries++){
|
||||
tmp = csr32r(ctlr, Rt3070EfuseCtrl);
|
||||
if(!(tmp & Rt3070EfsromKick))
|
||||
break;
|
||||
microdelay(2);
|
||||
}
|
||||
if(ntries == 500)
|
||||
return 0xffff;
|
||||
|
||||
if((tmp & Rt3070EfuseAoutMask) == Rt3070EfuseAoutMask)
|
||||
return 0xffff; /* address not found */
|
||||
|
||||
/* determine to which 32-bit register our 16-bit word belongs */
|
||||
reg = Rt3070EfuseData3 - (addr & 0xc);
|
||||
tmp = csr32r(ctlr, reg);
|
||||
|
||||
return (addr & 2) ? tmp >> 16 : tmp & 0xffff;
|
||||
}
|
||||
|
||||
static char*
|
||||
|
@ -2903,6 +3449,7 @@ rt2860init(Ether *edev)
|
|||
break;
|
||||
case RalinkRT2890:
|
||||
case RalinkRT2790:
|
||||
case RalinkRT3090:
|
||||
case AwtRT2890:
|
||||
ctlr->flags = AdvancedPs;
|
||||
break;
|
||||
|
@ -2942,7 +3489,8 @@ rt2860pci(void)
|
|||
switch(pdev->did){
|
||||
default:
|
||||
continue;
|
||||
case 0x0781: /* RT2790 */
|
||||
case RalinkRT2790:
|
||||
case RalinkRT3090:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue