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 */,
|
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[] = {
|
static const char* rfnames[] = {
|
||||||
[Rf2820] "RT2820",
|
[Rf2820] "RT2820",
|
||||||
[Rf2850] "RT2850",
|
[Rf2850] "RT2850",
|
||||||
|
@ -976,7 +1003,6 @@ enum {
|
||||||
ConnPciE = 1 << 1,
|
ConnPciE = 1 << 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct rt2860_rate {
|
static const struct rt2860_rate {
|
||||||
u8int rate;
|
u8int rate;
|
||||||
u8int mcs;
|
u8int mcs;
|
||||||
|
@ -1122,6 +1148,91 @@ static const struct rfprog {
|
||||||
{ 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 },
|
{ 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 */
|
/* vendors */
|
||||||
enum {
|
enum {
|
||||||
Ralink = 0x1814,
|
Ralink = 0x1814,
|
||||||
|
@ -1131,6 +1242,7 @@ enum {
|
||||||
enum {
|
enum {
|
||||||
RalinkRT2890 = 0x0681,
|
RalinkRT2890 = 0x0681,
|
||||||
RalinkRT2790 = 0x0781,
|
RalinkRT2790 = 0x0781,
|
||||||
|
RalinkRT3090 = 0x3090,
|
||||||
AwtRT2890 = 0x1059,
|
AwtRT2890 = 0x1059,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1139,6 +1251,7 @@ enum {
|
||||||
|
|
||||||
static int rbplant(Ctlr*, int);
|
static int rbplant(Ctlr*, int);
|
||||||
static void setchan(Ctlr*, uint);
|
static void setchan(Ctlr*, uint);
|
||||||
|
static void rt3090setchan(Ctlr*, uint);
|
||||||
static void selchangroup(Ctlr*, int);
|
static void selchangroup(Ctlr*, int);
|
||||||
static void setleds(Ctlr*, u16int);
|
static void setleds(Ctlr*, u16int);
|
||||||
|
|
||||||
|
@ -1242,6 +1355,9 @@ rxon(Ether *edev, Wnode *bss)
|
||||||
edev->ctlrno, ctlr->bssid, ctlr->aid, ctlr->channel, ctlr->wcid);
|
edev->ctlrno, ctlr->bssid, ctlr->aid, ctlr->channel, ctlr->wcid);
|
||||||
|
|
||||||
/* Set channel */
|
/* Set channel */
|
||||||
|
if(ctlr->mac_ver >= 0x3071)
|
||||||
|
rt3090setchan(ctlr, ctlr->channel);
|
||||||
|
else
|
||||||
setchan(ctlr, ctlr->channel);
|
setchan(ctlr, ctlr->channel);
|
||||||
selchangroup(ctlr, 0);
|
selchangroup(ctlr, 0);
|
||||||
microdelay(1000);
|
microdelay(1000);
|
||||||
|
@ -1600,7 +1716,7 @@ txrxon(Ctlr *ctlr)
|
||||||
/*
|
/*
|
||||||
* Write to one of the 4 programmable 24-bit RF registers.
|
* Write to one of the 4 programmable 24-bit RF registers.
|
||||||
*/
|
*/
|
||||||
static char*
|
static void
|
||||||
rfwrite(Ctlr *ctlr, u8int reg, u32int val)
|
rfwrite(Ctlr *ctlr, u8int reg, u32int val)
|
||||||
{
|
{
|
||||||
u32int tmp;
|
u32int tmp;
|
||||||
|
@ -1611,14 +1727,66 @@ rfwrite(Ctlr *ctlr, u8int reg, u32int val)
|
||||||
break;
|
break;
|
||||||
microdelay(1);
|
microdelay(1);
|
||||||
}
|
}
|
||||||
if(ntries == 100)
|
if(ntries == 100){
|
||||||
return "could not write to RF";
|
print("could not write to RF\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* RF registers are 24-bit on the RT2860 */
|
/* RF registers are 24-bit on the RT2860 */
|
||||||
tmp = RfRegCtrl | 24 << RfRegWidthShift |
|
tmp = RfRegCtrl | 24 << RfRegWidthShift |
|
||||||
(val & 0x3fffff) << 2 | (reg & 3);
|
(val & 0x3fffff) << 2 | (reg & 3);
|
||||||
csr32w(ctlr, RfCsrCfg0, tmp);
|
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
|
static void
|
||||||
|
@ -1761,6 +1929,356 @@ setchan(Ctlr *ctlr, uint chan)
|
||||||
rfwrite(ctlr, Rf4, r4);
|
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
|
static void
|
||||||
updateprot(Ctlr *ctlr)
|
updateprot(Ctlr *ctlr)
|
||||||
{
|
{
|
||||||
|
@ -1945,29 +2463,24 @@ rt2860start(Ether *edev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* select Main antenna for 1T1R devices */
|
/* select Main antenna for 1T1R devices */
|
||||||
/* notyet
|
|
||||||
if(ctlr->rf_rev == Rf2020 ||
|
if(ctlr->rf_rev == Rf2020 ||
|
||||||
ctlr->rf_rev == Rf3020 ||
|
ctlr->rf_rev == Rf3020 ||
|
||||||
ctlr->rf_rev == Rf3320)
|
ctlr->rf_rev == Rf3320)
|
||||||
rt3090_set_rx_antenna(ctlr, 0);
|
rt3090setrxantenna(ctlr, 0);
|
||||||
*/
|
|
||||||
|
|
||||||
/* send LEDs operating mode to microcontroller */
|
/* send LEDs operating mode to microcontroller */
|
||||||
mcucmd(ctlr, McuCmdLed1, ctlr->led[0], 0);
|
mcucmd(ctlr, McuCmdLed1, ctlr->led[0], 0);
|
||||||
mcucmd(ctlr, McuCmdLed2, ctlr->led[1], 0);
|
mcucmd(ctlr, McuCmdLed2, ctlr->led[1], 0);
|
||||||
mcucmd(ctlr, McuCmdLed3, ctlr->led[2], 0);
|
mcucmd(ctlr, McuCmdLed3, ctlr->led[2], 0);
|
||||||
|
|
||||||
/* XXX: 30xx
|
|
||||||
if(ctlr->mac_ver >= 0x3071)
|
if(ctlr->mac_ver >= 0x3071)
|
||||||
rt3090_rf_init(ctlr);
|
rt3090rfinit(ctlr);
|
||||||
*/
|
|
||||||
|
|
||||||
mcucmd(ctlr, McuCmdSleep, 0x02ff, 1);
|
mcucmd(ctlr, McuCmdSleep, 0x02ff, 1);
|
||||||
mcucmd(ctlr, McuCmdWakeup, 0, 1);
|
mcucmd(ctlr, McuCmdWakeup, 0, 1);
|
||||||
/* XXX: 30xx
|
|
||||||
if(ctlr->mac_ver >= 0x3071)
|
if(ctlr->mac_ver >= 0x3071)
|
||||||
rt3090_rf_wakeup(ctlr);
|
rt3090rfwakeup(ctlr);
|
||||||
*/
|
|
||||||
|
|
||||||
/* disable non-existing Rx chains */
|
/* disable non-existing Rx chains */
|
||||||
bbp3 = bbpread(ctlr, 3);
|
bbp3 = bbpread(ctlr, 3);
|
||||||
|
@ -1987,11 +2500,14 @@ rt2860start(Ether *edev)
|
||||||
else if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains == 3)
|
else if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains == 3)
|
||||||
bbp1 = (bbp1 & ~(1 << 3)) | 1 << 4;
|
bbp1 = (bbp1 & ~(1 << 3)) | 1 << 4;
|
||||||
bbpwrite(ctlr, 1, bbp1);
|
bbpwrite(ctlr, 1, bbp1);
|
||||||
/* XXX: 30xx
|
|
||||||
if(ctlr->mac_ver >= 0x3071)
|
if(ctlr->mac_ver >= 0x3071)
|
||||||
rt3090_rf_setup(ctlr);
|
rt3090rfsetup(ctlr);
|
||||||
*/
|
|
||||||
/* select default channel */
|
/* select default channel */
|
||||||
|
if(ctlr->mac_ver >= 0x3071)
|
||||||
|
rt3090setchan(ctlr, 3);
|
||||||
|
else
|
||||||
setchan(ctlr, 3);
|
setchan(ctlr, 3);
|
||||||
|
|
||||||
/* reset RF from MCU */
|
/* reset RF from MCU */
|
||||||
|
@ -2450,11 +2966,41 @@ eeread2(Ctlr *ctlr, u16int addr)
|
||||||
|
|
||||||
/* Read 16-bit from eFUSE ROM (>=RT3071 only.) */
|
/* Read 16-bit from eFUSE ROM (>=RT3071 only.) */
|
||||||
static u16int
|
static u16int
|
||||||
efuseread2(Ctlr *, u16int)
|
efuseread2(Ctlr *ctlr, u16int addr)
|
||||||
{
|
{
|
||||||
/* XXX: 30xx */
|
u32int tmp;
|
||||||
print("efuse rom not implemented\n");
|
u16int reg;
|
||||||
return 0;
|
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*
|
static char*
|
||||||
|
@ -2903,6 +3449,7 @@ rt2860init(Ether *edev)
|
||||||
break;
|
break;
|
||||||
case RalinkRT2890:
|
case RalinkRT2890:
|
||||||
case RalinkRT2790:
|
case RalinkRT2790:
|
||||||
|
case RalinkRT3090:
|
||||||
case AwtRT2890:
|
case AwtRT2890:
|
||||||
ctlr->flags = AdvancedPs;
|
ctlr->flags = AdvancedPs;
|
||||||
break;
|
break;
|
||||||
|
@ -2942,7 +3489,8 @@ rt2860pci(void)
|
||||||
switch(pdev->did){
|
switch(pdev->did){
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
case 0x0781: /* RT2790 */
|
case RalinkRT2790:
|
||||||
|
case RalinkRT3090:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue