merge
This commit is contained in:
commit
166afefab9
1 changed files with 77 additions and 26 deletions
|
@ -133,14 +133,16 @@ enum {
|
||||||
struct Ctlr
|
struct Ctlr
|
||||||
{
|
{
|
||||||
int attach;
|
int attach;
|
||||||
|
char* txerr;
|
||||||
|
ulong txwdog;
|
||||||
|
|
||||||
Hio *io;
|
Hio* io;
|
||||||
|
|
||||||
Ring rx;
|
Ring rx;
|
||||||
Ring tx;
|
Ring tx;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ulong dummy;
|
static int reset(Ether*);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
txintr(Ctlr *ctlr)
|
txintr(Ctlr *ctlr)
|
||||||
|
@ -153,17 +155,21 @@ txintr(Ctlr *ctlr)
|
||||||
s = io->xstat;
|
s = io->xstat;
|
||||||
if((s & Xdma) != 0)
|
if((s & Xdma) != 0)
|
||||||
return;
|
return;
|
||||||
p = IO(Desc, ctlr->tx.head->next);
|
if((s & Xmaxtry) != 0)
|
||||||
while((p->count & Busy) != 0){
|
ctlr->txerr = "transmission failed";
|
||||||
|
if((s & Xunder) != 0)
|
||||||
|
ctlr->txerr = "transmitter underflowed";
|
||||||
|
for(p = IO(Desc, ctlr->tx.head->next); (p->count & Busy) != 0; p = IO(Desc, p->next)){
|
||||||
if((p->count & Done) == 0){
|
if((p->count & Done) == 0){
|
||||||
io->nxbdp = PADDR(p);
|
io->nxbdp = PADDR(p);
|
||||||
io->xstat = Xdma;
|
io->xstat = Xdma;
|
||||||
|
ctlr->txwdog = MACHP(0)->ticks;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ctlr->tx.head = p;
|
|
||||||
p->count = Eor|Eop;
|
p->count = Eor|Eop;
|
||||||
p = IO(Desc, p->next);
|
ctlr->tx.head = p;
|
||||||
ctlr->tx.free++;
|
ctlr->tx.free++;
|
||||||
|
ctlr->txwdog = 0;
|
||||||
}
|
}
|
||||||
wakeup(&ctlr->tx);
|
wakeup(&ctlr->tx);
|
||||||
}
|
}
|
||||||
|
@ -180,8 +186,10 @@ interrupt(Ureg *, void *arg)
|
||||||
ctlr = edev->ctlr;
|
ctlr = edev->ctlr;
|
||||||
io = ctlr->io;
|
io = ctlr->io;
|
||||||
s = io->ctl;
|
s = io->ctl;
|
||||||
if(s & Cover)
|
if(s & Cover){
|
||||||
io->ctl = Cnormal | Cover;
|
io->ctl = Cnormal | Cover;
|
||||||
|
edev->overflows++;
|
||||||
|
}
|
||||||
if(s & Cint) {
|
if(s & Cint) {
|
||||||
io->ctl = Cnormal | Cint;
|
io->ctl = Cnormal | Cint;
|
||||||
txintr(ctlr);
|
txintr(ctlr);
|
||||||
|
@ -193,14 +201,31 @@ static int
|
||||||
notempty(void *arg)
|
notempty(void *arg)
|
||||||
{
|
{
|
||||||
Ctlr *ctlr = arg;
|
Ctlr *ctlr = arg;
|
||||||
|
|
||||||
return (IO(Desc, ctlr->rx.head->next)->count & Empty) == 0;
|
return (IO(Desc, ctlr->rx.head->next)->count & Empty) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char*
|
||||||
|
checkerr(Ctlr *ctlr)
|
||||||
|
{
|
||||||
|
ulong t;
|
||||||
|
|
||||||
|
if(ctlr->txerr != nil)
|
||||||
|
return ctlr->txerr;
|
||||||
|
t = ctlr->txwdog;
|
||||||
|
if(t != 0 && TK2MS(MACHP(0)->ticks - t) > 1000)
|
||||||
|
return "transmitter dma timeout";
|
||||||
|
if((ctlr->io->rstat & Rdma) == 0)
|
||||||
|
return "recevier dma stopped";
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rxproc(void *arg)
|
rxproc(void *arg)
|
||||||
{
|
{
|
||||||
Ether *edev = arg;
|
Ether *edev = arg;
|
||||||
Ctlr *ctlr;
|
Ctlr *ctlr;
|
||||||
|
char *err;
|
||||||
Block *b;
|
Block *b;
|
||||||
Desc *p;
|
Desc *p;
|
||||||
int n;
|
int n;
|
||||||
|
@ -210,16 +235,22 @@ rxproc(void *arg)
|
||||||
|
|
||||||
ctlr = edev->ctlr;
|
ctlr = edev->ctlr;
|
||||||
for(p = IO(Desc, ctlr->rx.head->next);; p = IO(Desc, p->next)){
|
for(p = IO(Desc, ctlr->rx.head->next);; p = IO(Desc, p->next)){
|
||||||
while((p->count & Empty) != 0)
|
while((p->count & Empty) != 0){
|
||||||
sleep(&ctlr->rx, notempty, ctlr);
|
err = checkerr(ctlr);
|
||||||
n = Rbsize - (p->count & 0x3fff)-3;
|
if(err != nil){
|
||||||
if(n >= ETHERMINTU){
|
print("%s: %s; reseting\n", up->text, err);
|
||||||
if((p->base[n+2] & Rok) != 0){
|
splhi();
|
||||||
b = allocb(n);
|
reset(edev);
|
||||||
b->wp += n;
|
spllo();
|
||||||
memmove(b->rp, p->base+2, n);
|
|
||||||
etheriq(edev, b, 1);
|
|
||||||
}
|
}
|
||||||
|
tsleep(&ctlr->rx, notempty, ctlr, 500);
|
||||||
|
}
|
||||||
|
n = Rbsize - (p->count & 0x3fff)-3;
|
||||||
|
if(n >= ETHERMINTU && (p->base[n+2] & Rok) != 0){
|
||||||
|
b = allocb(n);
|
||||||
|
b->wp += n;
|
||||||
|
memmove(b->rp, p->base+2, n);
|
||||||
|
etheriq(edev, b, 1);
|
||||||
}
|
}
|
||||||
p->addr = PADDR(p->base);
|
p->addr = PADDR(p->base);
|
||||||
p->count = Ioc|Empty|Rbsize;
|
p->count = Ioc|Empty|Rbsize;
|
||||||
|
@ -250,7 +281,6 @@ txproc(void *arg)
|
||||||
for(p = IO(Desc, ctlr->tx.tail->next); (b = qbread(edev->oq, 1000000)) != nil; p = IO(Desc, p->next)){
|
for(p = IO(Desc, ctlr->tx.tail->next); (b = qbread(edev->oq, 1000000)) != nil; p = IO(Desc, p->next)){
|
||||||
while(ctlr->tx.free == 0)
|
while(ctlr->tx.free == 0)
|
||||||
sleep(&ctlr->tx, notbusy, ctlr);
|
sleep(&ctlr->tx, notbusy, ctlr);
|
||||||
ctlr->tx.free--;
|
|
||||||
|
|
||||||
n = BLEN(b);
|
n = BLEN(b);
|
||||||
if(n > ETHERMAXTU)
|
if(n > ETHERMAXTU)
|
||||||
|
@ -264,6 +294,7 @@ txproc(void *arg)
|
||||||
ctlr->tx.tail = p;
|
ctlr->tx.tail = p;
|
||||||
|
|
||||||
splhi();
|
splhi();
|
||||||
|
ctlr->tx.free--;
|
||||||
txintr(ctlr);
|
txintr(ctlr);
|
||||||
spllo();
|
spllo();
|
||||||
|
|
||||||
|
@ -303,21 +334,20 @@ allocring(Ring *r, int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
init(Ether *edev)
|
reset(Ether *edev)
|
||||||
{
|
{
|
||||||
Ctlr *ctlr;
|
Ctlr *ctlr;
|
||||||
Desc *p;
|
Desc *p;
|
||||||
Hio *io;
|
Hio *io;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
io = IO(Hio, edev->port);
|
|
||||||
ctlr = edev->ctlr;
|
ctlr = edev->ctlr;
|
||||||
ctlr->io = io;
|
io = ctlr->io;
|
||||||
|
|
||||||
|
ctlr->txerr = nil;
|
||||||
|
ctlr->txwdog = 0;
|
||||||
|
|
||||||
io->csx = Xreg0;
|
io->csx = Xreg0;
|
||||||
allocring(&ctlr->rx, 256);
|
|
||||||
allocring(&ctlr->tx, 64);
|
|
||||||
|
|
||||||
io->rstat = 0;
|
io->rstat = 0;
|
||||||
io->xstat = 0;
|
io->xstat = 0;
|
||||||
io->ctl = Cnormal | Creset | Cint;
|
io->ctl = Cnormal | Creset | Cint;
|
||||||
|
@ -336,15 +366,19 @@ init(Ether *edev)
|
||||||
} while(p != ctlr->rx.head);
|
} while(p != ctlr->rx.head);
|
||||||
io->crbdp = PADDR(p);
|
io->crbdp = PADDR(p);
|
||||||
io->nrbdp = p->next;
|
io->nrbdp = p->next;
|
||||||
|
ctlr->rx.tail = p;
|
||||||
|
ctlr->rx.free = ctlr->rx.size;
|
||||||
|
|
||||||
p = ctlr->tx.tail;
|
p = ctlr->tx.tail;
|
||||||
do {
|
do {
|
||||||
p->addr = 0;
|
p->addr = PADDR(p->base);
|
||||||
p->count = Eor|Eop;
|
p->count = Eor|Eop;
|
||||||
p = IO(Desc, p->next);
|
p = IO(Desc, p->next);
|
||||||
} while(p != ctlr->tx.tail);
|
} while(p != ctlr->tx.tail);
|
||||||
io->cxbdp = PADDR(p);
|
io->cxbdp = PADDR(p);
|
||||||
io->nxbdp = p->next;
|
io->nxbdp = p->next;
|
||||||
|
ctlr->tx.head = p;
|
||||||
|
ctlr->tx.free = ctlr->tx.size;
|
||||||
|
|
||||||
for(i=0; i<6; i++)
|
for(i=0; i<6; i++)
|
||||||
io->eaddr[i] = edev->ea[i];
|
io->eaddr[i] = edev->ea[i];
|
||||||
|
@ -354,7 +388,24 @@ init(Ether *edev)
|
||||||
|
|
||||||
io->rstat = Rdma;
|
io->rstat = Rdma;
|
||||||
|
|
||||||
|
wakeup(&ctlr->rx);
|
||||||
|
wakeup(&ctlr->tx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
init(Ether *edev)
|
||||||
|
{
|
||||||
|
Ctlr *ctlr;
|
||||||
|
|
||||||
|
ctlr = edev->ctlr;
|
||||||
|
ctlr->io = IO(Hio, edev->port);
|
||||||
|
allocring(&ctlr->rx, 256);
|
||||||
|
allocring(&ctlr->tx, 64);
|
||||||
|
|
||||||
|
return reset(edev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -379,8 +430,8 @@ attach(Ether *edev)
|
||||||
if(ctlr->attach)
|
if(ctlr->attach)
|
||||||
return;
|
return;
|
||||||
ctlr->attach = 1;
|
ctlr->attach = 1;
|
||||||
kproc("#0rx", rxproc, edev);
|
kproc("#l0rx", rxproc, edev);
|
||||||
kproc("#0tx", txproc, edev);
|
kproc("#l0tx", txproc, edev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Reference in a new issue