|
@@ -135,6 +135,7 @@ enum { /* Window 0 - setup */
|
|
|
auiAvailable9 = 0x2000,
|
|
|
/* EepromCommand bits */
|
|
|
EepromReadRegister = 0x0080,
|
|
|
+ EepromReadOffRegister = 0x00B0,
|
|
|
EepromRead8bRegister = 0x0230,
|
|
|
EepromBusy = 0x8000,
|
|
|
};
|
|
@@ -419,12 +420,14 @@ typedef struct Ctlr {
|
|
|
ulong dnqueued;
|
|
|
|
|
|
int xcvr; /* transceiver type */
|
|
|
+ int eepromcmd; /* EEPROM read command */
|
|
|
int rxstatus9; /* old-style RxStatus register */
|
|
|
int rxearly; /* RxEarlyThreshold */
|
|
|
int ts; /* threshold shift */
|
|
|
int upenabled;
|
|
|
int dnenabled;
|
|
|
- ulong* cbfns; /* CardBus functions */
|
|
|
+ ulong cbfnpa; /* CardBus functions */
|
|
|
+ ulong* cbfn;
|
|
|
} Ctlr;
|
|
|
|
|
|
static Ctlr* ctlrhead;
|
|
@@ -555,9 +558,9 @@ multicast(void* arg, uchar *addr, int on)
|
|
|
|
|
|
/* On the 575B and C, interrupts need to be acknowledged in CardBus memory space */
|
|
|
static void
|
|
|
-intrack3c575(ulong *cbfns)
|
|
|
+intrackcb(ulong *cbfn)
|
|
|
{
|
|
|
- cbfns[1] = 0x8000;
|
|
|
+ cbfn[1] = 0x8000;
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -599,8 +602,8 @@ attach(Ether* ether)
|
|
|
/*
|
|
|
* If this is a CardBus card, acknowledge any interrupts.
|
|
|
*/
|
|
|
- if(ctlr->cbfns != nil)
|
|
|
- intrack3c575(ctlr->cbfns);
|
|
|
+ if(ctlr->cbfn != nil)
|
|
|
+ intrackcb(ctlr->cbfn);
|
|
|
|
|
|
/*
|
|
|
* Prime the busmaster channel for receiving directly into a
|
|
@@ -1141,8 +1144,8 @@ interrupt(Ureg*, void* arg)
|
|
|
panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status);
|
|
|
|
|
|
COMMAND(port, AcknowledgeInterrupt, interruptLatch);
|
|
|
- if(ctlr->cbfns != nil)
|
|
|
- intrack3c575(ctlr->cbfns);
|
|
|
+ if(ctlr->cbfn != nil)
|
|
|
+ intrackcb(ctlr->cbfn);
|
|
|
|
|
|
}while((status = STATUS(port)) & (interruptMask|interruptLatch));
|
|
|
|
|
@@ -1243,6 +1246,7 @@ tcmadapter(int port, int irq, Pcidev* pcidev)
|
|
|
ctlr->port = port;
|
|
|
ctlr->irq = irq;
|
|
|
ctlr->pcidev = pcidev;
|
|
|
+ ctlr->eepromcmd = EepromReadRegister;
|
|
|
|
|
|
if(ctlrhead != nil)
|
|
|
ctlrtail->next = ctlr;
|
|
@@ -1451,10 +1455,13 @@ static void
|
|
|
tcm59Xpci(void)
|
|
|
{
|
|
|
Pcidev *p;
|
|
|
+ Ctlr *ctlr;
|
|
|
int irq, port;
|
|
|
|
|
|
p = nil;
|
|
|
while(p = pcimatch(p, 0x10B7, 0)){
|
|
|
+ if(p->ccrb != 0x02 || p->ccru != 0)
|
|
|
+ continue;
|
|
|
/*
|
|
|
* Not prepared to deal with memory-mapped
|
|
|
* devices yet.
|
|
@@ -1468,11 +1475,25 @@ tcm59Xpci(void)
|
|
|
continue;
|
|
|
}
|
|
|
irq = p->intl;
|
|
|
- COMMAND(port, GlobalReset, 0);
|
|
|
- while(STATUS(port) & commandInProgress)
|
|
|
- ;
|
|
|
|
|
|
- tcmadapter(port, irq, p);
|
|
|
+ txrxreset(port);
|
|
|
+ COMMAND(port, AcknowledgeInterrupt, 0xFF);
|
|
|
+
|
|
|
+ ctlr = tcmadapter(port, irq, p);
|
|
|
+ switch(p->did){
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ case 0x5157:
|
|
|
+ ctlr->eepromcmd = EepromRead8bRegister;
|
|
|
+ ctlr->cbfnpa = upamalloc(p->mem[2].bar, p->mem[2].size, 0);
|
|
|
+ break;
|
|
|
+ case 0x6056:
|
|
|
+ ctlr->eepromcmd = EepromReadOffRegister;
|
|
|
+ ctlr->cbfnpa = upamalloc(p->mem[2].bar, p->mem[2].size, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if(ctlr->cbfnpa != 0)
|
|
|
+ ctlr->cbfn = KADDR(ctlr->cbfnpa);
|
|
|
pcisetbme(p);
|
|
|
}
|
|
|
}
|
|
@@ -1608,7 +1629,7 @@ miir(int port, int phyad, int regad)
|
|
|
return data & 0xFFFF;
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
+static int
|
|
|
scanphy(int port)
|
|
|
{
|
|
|
int i, x;
|
|
@@ -1620,7 +1641,10 @@ scanphy(int port)
|
|
|
x |= miir(port, i, 3)>>10;
|
|
|
XCVRDEBUG("phy%d: oui %uX reg1 %uX\n", i, x, miir(port, i, 1));
|
|
|
USED(x);
|
|
|
+
|
|
|
+ return i;
|
|
|
}
|
|
|
+ return 24;
|
|
|
}
|
|
|
|
|
|
static struct {
|
|
@@ -1717,10 +1741,7 @@ eepromdata(Ctlr* ctlr, int offset)
|
|
|
COMMAND(port, SelectRegisterWindow, Wsetup);
|
|
|
while(EEPROMBUSY(port))
|
|
|
;
|
|
|
- if(ctlr->pcidev && ctlr->pcidev->did == 0x5157)
|
|
|
- EEPROMCMD(port, EepromRead8bRegister, offset);
|
|
|
- else
|
|
|
- EEPROMCMD(port, EepromReadRegister, offset);
|
|
|
+ EEPROMCMD(port, ctlr->eepromcmd, offset);
|
|
|
while(EEPROMBUSY(port))
|
|
|
;
|
|
|
return EEPROMDATA(port);
|
|
@@ -1776,10 +1797,9 @@ etherelnk3reset(Ether* ether)
|
|
|
*/
|
|
|
switch(ctlr->did = eepromdata(ctlr, 0x03)){
|
|
|
case 0x5157: /* 3C575 Cyclone */
|
|
|
- ctlr->cbfns = KADDR(pcicfgr32(ctlr->pcidev, PciBAR2));
|
|
|
+ case 0x6056:
|
|
|
/*FALLTHROUGH*/
|
|
|
case 0x4500: /* 3C450 HomePNA Tornado */
|
|
|
- case 0x6056:
|
|
|
case 0x7646: /* 3CSOHO100-TX */
|
|
|
case 0x9055: /* 3C905B-TX */
|
|
|
case 0x9200: /* 3C905C-TX */
|
|
@@ -1869,22 +1889,27 @@ etherelnk3reset(Ether* ether)
|
|
|
if(ctlr->xcvr & autoSelect)
|
|
|
ctlr->xcvr = autoselect(ctlr);
|
|
|
break;
|
|
|
- case 0x4500:
|
|
|
case 0x5157:
|
|
|
case 0x6056:
|
|
|
+ case 0x4500:
|
|
|
case 0x7646:
|
|
|
case 0x9055:
|
|
|
case 0x9200:
|
|
|
ctlr->xcvr = xcvrMii;
|
|
|
txrxreset(port);
|
|
|
- XCVRDEBUG("905[BC] reset ops 0x%uX\n", ins(port+ResetOp905B));
|
|
|
- if(ctlr->did == 0x5157) {
|
|
|
- ushort reset_opts;
|
|
|
-
|
|
|
- COMMAND(port, SelectRegisterWindow, Wstation);
|
|
|
- reset_opts = ins(port + ResetOp905B);
|
|
|
- reset_opts |= 0x0010; /* Invert LED */
|
|
|
- outs(port + ResetOp905B, reset_opts);
|
|
|
+ x = ins(port+ResetOp905B);
|
|
|
+ XCVRDEBUG("905[BC] reset ops 0x%uX\n", x);
|
|
|
+ x &= ~0x4010;
|
|
|
+ if(ctlr->did == 0x5157){
|
|
|
+ x |= 0x0010; /* Invert LED */
|
|
|
+ outs(port+ResetOp905B, x);
|
|
|
+ }
|
|
|
+ if(ctlr->did == 0x6056){
|
|
|
+ x |= 0x4000;
|
|
|
+ outs(port+ResetOp905B, x);
|
|
|
+
|
|
|
+ COMMAND(port, SelectRegisterWindow, Wsetup);
|
|
|
+ outs(port, 0x0800);
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
@@ -1894,10 +1919,11 @@ etherelnk3reset(Ether* ether)
|
|
|
case xcvrMii:
|
|
|
/*
|
|
|
* Quick hack.
|
|
|
- scanphy(port);
|
|
|
*/
|
|
|
if(ctlr->did == 0x5157)
|
|
|
phyaddr = 0;
|
|
|
+ else if(ctlr->did == 0x6056)
|
|
|
+ phyaddr = scanphy(port);
|
|
|
else
|
|
|
phyaddr = 24;
|
|
|
for(i = 0; i < 7; i++)
|