M pc/devi82365.c => pc/devi82365.c +44 -27
@@ 929,7 929,8 @@ pcmio(int slotno, ISAConf *isa)
Slot *pp;
Conftab *ct, *et, *t;
PCMmap *m;
- int irq;
+ int i, index, irq;
+ char *cp;
irq = isa->irq;
if(irq == 2)
@@ 944,37 945,51 @@ pcmio(int slotno, ISAConf *isa)
et = &pp->ctab[pp->nctab];
- /* assume default is right */
- if(pp->def)
- ct = pp->def;
- else
- ct = pp->ctab;
-
- /* try for best match */
- if(ct->nioregs == 0 || ct->port != isa->port || ((1<<irq) & ct->irqs) == 0){
- for(t = pp->ctab; t < et; t++)
- if(t->nioregs && t->port == isa->port && ((1<<irq) & t->irqs)){
- ct = t;
- break;
- }
- }
- if(ct->nioregs == 0 || ((1<<irq) & ct->irqs) == 0){
- for(t = pp->ctab; t < et; t++)
- if(t->nioregs && ((1<<irq) & t->irqs)){
- ct = t;
- break;
- }
+ ct = 0;
+ for(i = 0; i < isa->nopt; i++){
+ if(strncmp(isa->opt[i], "index=", 6))
+ continue;
+ index = strtol(&isa->opt[i][6], &cp, 0);
+ if(cp == &isa->opt[i][6] || index >= pp->nctab)
+ return -1;
+ ct = &pp->ctab[index];
}
- if(ct->nioregs == 0){
- for(t = pp->ctab; t < et; t++)
- if(t->nioregs){
- ct = t;
- break;
- }
+ if(ct == 0){
+
+ /* assume default is right */
+ if(pp->def)
+ ct = pp->def;
+ else
+ ct = pp->ctab;
+
+ /* try for best match */
+ if(ct->nioregs == 0 || ct->port != isa->port || ((1<<irq) & ct->irqs) == 0){
+ for(t = pp->ctab; t < et; t++)
+ if(t->nioregs && t->port == isa->port && ((1<<irq) & t->irqs)){
+ ct = t;
+ break;
+ }
+ }
+ if(ct->nioregs == 0 || ((1<<irq) & ct->irqs) == 0){
+ for(t = pp->ctab; t < et; t++)
+ if(t->nioregs && ((1<<irq) & t->irqs)){
+ ct = t;
+ break;
+ }
+ }
+ if(ct->nioregs == 0){
+ for(t = pp->ctab; t < et; t++)
+ if(t->nioregs){
+ ct = t;
+ break;
+ }
+ }
}
if(ct == et || ct->nioregs == 0)
return -1;
+ if(isa->port == 0 && ct->port == 0)
+ return -1;
/* route interrupts */
isa->irq = irq;
@@ 1069,6 1084,8 @@ cisread(Slot *pp)
this = pp->cispos;
if(readc(pp, &type) != 1)
break;
+ if(type == 0xFF)
+ break;
if(readc(pp, &link) != 1)
break;
if(parse[type])
M pc/ether589.c => pc/ether589.c +10 -12
@@ 45,21 45,17 @@ extern int etherelnk3reset(Ether*);
static int
configASIC(Ether *ether, int port, int xcvr)
{
- ushort x;
-
/* set Window 0 configuration registers */
COMMAND(port, SelectWindow, 0);
+ outs(port+ConfigControl, 1);
- x = ins(port+ConfigControl);
- outs(port+ConfigControl, x|1);
+ /* IRQ must be 3 on 3C589/3C562 */
+ outs(port + ResourceConfig, 0x3F00);
/* ROM size & base - must be set before we can access ROM */
/* transceiver type is 2 for 'figure it out' */
outs(port + AddressConfig, xcvr);
- /* IRQ must be 3 on 3C589 */
- outs(port + ResourceConfig, 0x3F00);
-
return etherelnk3reset(ether);
}
@@ 75,9 71,11 @@ reset(Ether *ether)
ether->port = 0x240;
port = ether->port;
- slot = pcmspecial("3C589", ether);
- if(slot < 0)
- return -1;
+ if((slot = pcmspecial("3C589", ether)) < 0){
+ if((slot = pcmspecial("3C562", ether)) < 0)
+ return -1;
+ strcpy(ether->type, "3C562");
+ }
/* try configuring as a 10baseT */
if(configASIC(ether, port, Xcvr10BaseT) < 0){
@@ 89,7 87,7 @@ reset(Ether *ether)
if(ins(port+MediaStatus) & LinkBeatOk){
/* reselect window 1 for normal operation */
COMMAND(port, SelectWindow, 1);
- print("10baseT 3C589\n");
+ print("10baseT %s\n", ether->type);
return 0;
}
@@ 99,7 97,7 @@ reset(Ether *ether)
pcmspecialclose(slot);
return -1;
}
- print("BNC 3C589\n");
+ print("BNC %s\n", ether->type);
return 0;
}
M pc/etherelnk3.c => pc/etherelnk3.c +15 -4
@@ 2,6 2,7 @@
* Etherlink III and Fast EtherLink adapters.
* To do:
* check robustness in the face of errors;
+ * RxEarly and busmaster;
* autoSelect;
* PCI latency timer and master enable;
* errata list.
@@ 409,7 410,6 @@ attach(Ether* ether)
x = interruptMask|interruptLatch;
if(ctlr->busmaster)
x &= ~(rxEarly|rxComplete);
-x &= ~rxEarly;
COMMAND(port, SetIndicationEnable, x);
COMMAND(port, SetInterruptEnable, x);
@@ 745,6 745,14 @@ interrupt(Ureg*, void* arg)
}
/*
+ * Currently, this shouldn't happen.
+ */
+ if(status & rxEarly){
+ COMMAND(port, AcknowledgeInterrupt, rxEarly);
+ status &= ~rxEarly;
+ }
+
+ /*
* Panic if there are any interrupts not dealt with.
*/
if(status & interruptMask)
@@ 1039,7 1047,7 @@ tcm59Xpci(Ether* ether)
static int
tcm5XXpcmcia(Ether* ether)
{
- if(cistrcmp(ether->type, "3C589") == 0)
+ if(cistrcmp(ether->type, "3C589") == 0 || cistrcmp(ether->type, "3C562") == 0)
return ether->port;
return 0;
@@ 1048,7 1056,7 @@ tcm5XXpcmcia(Ether* ether)
int
etherelnk3reset(Ether* ether)
{
- int busmaster, i, port, rxstatus9, x, xcvr;
+ int busmaster, i, port, rxearly, rxstatus9, x, xcvr;
Adapter *ap, **app;
uchar ea[Eaddrlen];
Ctlr *ctlr;
@@ 1062,6 1070,7 @@ etherelnk3reset(Ether* ether)
* If an adapter is found save the IRQ and transceiver type.
*/
port = 0;
+ rxearly = 2044;
rxstatus9 = 0;
xcvr = 0;
for(app = &adapter, ap = *app; ap; app = &ap->next, ap = ap->next){
@@ 1079,12 1088,14 @@ etherelnk3reset(Ether* ether)
}
else if(port == 0 && (port = tcm59Xpci(ether))){
COMMAND(port, SelectRegisterWindow, Wfifo);
+ rxearly = 8188;
xcvr = inl(port+InternalConfig) & xcvrMask;
}
else if(port == 0 && (port = tcm5XXeisa(ether))){
x = ins(port+ProductID);
if((x & 0xFF00) == 0x5900){
COMMAND(port, SelectRegisterWindow, Wfifo);
+ rxearly = 8188;
xcvr = inl(port+InternalConfig) & xcvrMask;
}
else{
@@ 1207,7 1218,7 @@ etherelnk3reset(Ether* ether)
*/
ctlr->txthreshold = ETHERMINTU;
COMMAND(port, SetTxStartThresh, ETHERMINTU);
- COMMAND(port, SetRxEarlyThresh, ETHERMAXTU);
+ COMMAND(port, SetRxEarlyThresh, rxearly);
iunlock(&ctlr->wlock);