#include "io.h"
#include "../port/error.h"
#include "../port/netif.h"
-
-#include "etherif.h"
+#include "../port/etherif.h"
enum {
Nrfd = 64, /* receive frame area */
static void txstart(Ether*);
ether = arg;
+ while(waserror())
+ ;
for(;;){
tsleep(&up->sleep, return0, 0, 4000);
* the future.
*/
ctlr = ether->ctlr;
- if(ctlr == nil || ctlr->state == 0){
- print("%s: exiting\n", up->text);
- pexit("disabled", 0);
- }
+ if(ctlr == nil || ctlr->state == 0)
+ break;
ilock(&ctlr->cblock);
if(ctlr->tick++){
}
iunlock(&ctlr->cblock);
}
+ print("%s: exiting\n", up->text);
+ pexit("disabled", 1);
}
static void
ctlr = ether->ctlr;
lock(&ctlr->dlock);
+ if(waserror()){
+ unlock(&ctlr->dlock);
+ nexterror();
+ }
/*
* Start the command then
*/
ctlr->dump[16] = 0;
command(ctlr, DumpSC, 0);
- while(ctlr->dump[16] == 0)
- ;
+ for(i = 0; i < 1000 && ctlr->dump[16] == 0; i++)
+ microdelay(100);
+ if(i == 1000)
+ error("command timeout");
- ether->oerrs = ctlr->dump[1]+ctlr->dump[2]+ctlr->dump[3];
- ether->crcs = ctlr->dump[10];
- ether->frames = ctlr->dump[11];
- ether->buffs = ctlr->dump[12]+ctlr->dump[15];
- ether->overflows = ctlr->dump[13];
+ memmove(dump, ctlr->dump, sizeof(dump));
- if(n == 0){
- unlock(&ctlr->dlock);
- return 0;
- }
+ ether->oerrs = dump[1]+dump[2]+dump[3];
+ ether->crcs = dump[10];
+ ether->frames = dump[11];
+ ether->buffs = dump[12]+dump[15];
+ ether->overflows = dump[13];
- memmove(dump, ctlr->dump, sizeof(dump));
+ poperror();
unlock(&ctlr->dlock);
+ if(n == 0)
+ return 0;
+
p = smalloc(READSTR);
len = snprint(p, READSTR, "transmit good frames: %lud\n", dump[0]);
len += snprint(p+len, READSTR-len, "transmit maximum collisions errors: %lud\n", dump[1]);
static void
promiscuous(void* arg, int on)
{
- configure(arg, on);
+ Ether *ether = arg;
+ configure(ether, on || ether->nmaddr > 0);
}
static void
-multicast(void* ether, uchar *addr, int add)
+multicast(void* arg, uchar *, int)
{
- USED(addr);
- /*
- * TODO: if (add) add addr to list of mcast addrs in controller
- * else remove addr from list of mcast addrs in controller
- * enable multicast input (see CbMAS) instead of promiscuous mode.
- */
- if (add)
- configure(ether, 1);
+ Ether *ether = arg;
+ configure(ether, ether->prom || ether->nmaddr > 0);
}
static void
bp = xbp;
}
if(pbp != nil)
- etheriq(ether, pbp, 1);
+ etheriq(ether, pbp);
}
else{
rfd->count = 0;
}
if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
- panic("#l%d: status %#ux\n", ether->ctlrno, status);
+ panic("#l%d: status %#ux", ether->ctlrno, status);
}
}
link = NullPointer;
for(i = 0; i < Nrfd; i++){
bp = rfdalloc(link);
+ if(bp == nil)
+ panic("i82557: can't allocate rfd buffer");
if(ctlr->rfdhead == nil)
ctlr->rfdtail = bp;
bp->next = ctlr->rfdhead;
*/
ilock(&ctlr->cblock);
ctlr->cbr = malloc(ctlr->ncb*sizeof(Cb));
+ if(ctlr->cbr == nil)
+ panic("i82557: can't allocate cbr");
for(i = 0; i < ctlr->ncb; i++){
ctlr->cbr[i].status = CbC|CbOK;
ctlr->cbr[i].command = CbS|CbNOP;
if(ctlr->eepromsz == 0){
ctlr->eepromsz = 8-size;
ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
+ if(ctlr->eeprom == nil)
+ panic("i82557: can't allocate eeprom");
goto reread;
}
{
Pcidev *p;
Ctlr *ctlr;
- int i, nop, port;
+ int nop, port;
p = nil;
nop = 0;
break;
}
- if(pcigetpms(p) > 0){
- pcisetpms(p, 0);
-
- for(i = 0; i < 6; i++)
- pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
- pcicfgw8(p, PciINTL, p->intl);
- pcicfgw8(p, PciLTR, p->ltr);
- pcicfgw8(p, PciCLS, p->cls);
- pcicfgw16(p, PciPCR, p->pcr);
- }
-
/*
* bar[0] is the memory-mapped register address (4KB),
* bar[1] is the I/O port register address (32 bytes) and
}
ctlr = malloc(sizeof(Ctlr));
+ if(ctlr == nil){
+ print("i82557: can't allocate memory\n");
+ iofree(port);
+ continue;
+ }
ctlr->port = port;
ctlr->pcidev = p;
ctlr->nop = nop;
else
ctlrhead = ctlr;
ctlrtail = ctlr;
-
- pcisetbme(p);
}
}
if(ctlr == nil)
return -1;
+ pcienable(ctlr->pcidev);
+ pcisetbme(ctlr->pcidev);
+
/*
* Initialise the Ctlr structure.
* Perform a software reset after which should ensure busmastering
*/
miir(ctlr, phyaddr, 0x01);
bmsr = miir(ctlr, phyaddr, 0x01);
- if((miir(ctlr, phyaddr, 0) & 0x1000) && !(bmsr & 0x0020)){
- miiw(ctlr, phyaddr, 0x1A, 0x2010);
- x = miir(ctlr, phyaddr, 0);
- miiw(ctlr, phyaddr, 0, 0x0200|x);
- for(i = 0; i < 3000; i++){
- delay(1);
- if(miir(ctlr, phyaddr, 0x01) & 0x0020)
- break;
- }
- miiw(ctlr, phyaddr, 0x1A, 0x2000);
-
- anar = miir(ctlr, phyaddr, 0x04);
- anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
- anar &= anlpar;
- bmcr = 0;
- if(anar & 0x380)
- bmcr = 0x2000;
- if(anar & 0x0140)
- bmcr |= 0x0100;
+ if((miir(ctlr, phyaddr, 0) & 0x1000) && (bmsr & 0x0020))
+ break;
+ miiw(ctlr, phyaddr, 0x1A, 0x2010);
+ x = miir(ctlr, phyaddr, 0);
+ miiw(ctlr, phyaddr, 0, 0x1200|x);
+ for(i = 0; i < 3000; i++){
+ delay(1);
+ if(miir(ctlr, phyaddr, 0x01) & 0x0020)
+ break;
}
+ miiw(ctlr, phyaddr, 0x1A, 0x2000);
+
+ anar = miir(ctlr, phyaddr, 0x04);
+ anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
+ anar &= anlpar;
+ bmcr = 0;
+ if(anar & 0x380)
+ bmcr = 0x2000;
+ if(anar & 0x0140)
+ bmcr |= 0x0100;
break;
}
*/
ether->attach = attach;
ether->transmit = transmit;
- ether->interrupt = interrupt;
ether->ifstat = ifstat;
ether->shutdown = shutdown;
ether->multicast = multicast;
ether->arg = ether;
+ intrenable(ether->irq, interrupt, ether, ether->tbdf, ether->name);
+
return 0;
}