#include "io.h"
#include "../port/error.h"
#include "../port/netif.h"
-
-#include "etherif.h"
+#include "../port/etherif.h"
enum {
Lognrdre = 6,
ctlr->iow(ctlr, Rap, 15);
x = ctlr->ior(ctlr, Rdp) & ~Prom;
- if(on)
+ if(on || ether->nmaddr > 0)
x |= Prom;
ctlr->iow(ctlr, Rdp, x);
ctlr->iow(ctlr, Rap, 0);
static void
multicast(void* arg, uchar*, int)
{
- promiscuous(arg, 1);
+ Ether *ether = arg;
+ promiscuous(arg, ether->prom);
}
static void
* until a descriptor is encountered still owned by the chip.
*/
if(csr0 & Rint){
+ ilock(ctlr);
i = ctlr->rdrx;
dre = &ctlr->rdr[i];
while(!(dre->md1 & Own)){
if(bb != nil){
len = (dre->md2 & 0x0FFF)-4;
bb->wp = bb->rp+len;
- etheriq(ether, bb, 1);
+ etheriq(ether, bb);
}
dre->addr = PADDR(bp->rp);
}
dre->md2 = 0;
dre->md1 = Own|(-Rbsize & 0xFFFF);
- ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
- dre = &ctlr->rdr[ctlr->rdrx];
+ i = ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
+ dre = &ctlr->rdr[i];
}
+ iunlock(ctlr);
}
/*
* Transmitter interrupt: wakeup anyone waiting for a free descriptor.
*/
if(csr0 & Tint){
- lock(ctlr);
+ ilock(ctlr);
while(ctlr->ntq){
i = ctlr->tdri;
dre = &ctlr->tdr[i];
ctlr->tdri = NEXT(ctlr->tdri, Ntdre);
}
txstart(ether);
- unlock(ctlr);
+ iunlock(ctlr);
}
goto intrloop;
}
ether->port = ctlr->port;
ether->irq = ctlr->pcidev->intl;
ether->tbdf = ctlr->pcidev->tbdf;
- pcisetbme(ctlr->pcidev);
ilock(ctlr);
ctlr->init = 1;
+ pcienable(ctlr->pcidev);
+ pcisetbme(ctlr->pcidev);
io32r(ctlr, Sreset);
io16r(ctlr, Sreset);
switch(x&0xFFFFFFF){
case 0x2420003: /* PCnet/PCI 79C970 */
case 0x2621003: /* PCnet/PCI II 79C970A */
+ ether->mbps = 10;
+ break;
case 0x2625003: /* PCnet-FAST III 79C973 */
+ ether->mbps = 100;
break;
default:
print("#l%d: unknown PCnet card version 0x%.7ux\n",
ether->ea[5] = x>>8;
}
+ /* VMware */
+ x = ether->ea[0]<<16 | ether->ea[1]<<8 | ether->ea[2];
+ switch(x){
+ case 0x0569:
+ case 0x0C29:
+ case 0x5056:
+ ether->mbps = 1000;
+ }
+
/*
* Start to fill in the initialisation block
* (must be DWORD aligned).
*/
ether->attach = attach;
ether->transmit = transmit;
- ether->interrupt = interrupt;
ether->ifstat = ifstat;
ether->arg = ether;
ether->multicast = multicast;
// ether->shutdown = shutdown;
+ intrenable(ether->irq, interrupt, ether, ether->tbdf, ether->name);
+
return 0;
}