#include "dat.h"
#include "fns.h"
#include "io.h"
+#include "../port/pci.h"
#include "../port/error.h"
#include "../port/netif.h"
-#include "etherif.h"
+#include "../port/etherif.h"
#define Pciwaddrh(x) 0
#define Pciwaddrl(x) PCIWADDR(x)
Isrc2 = 0x001c/4,
Eisr = 0x0024/4,
Lisr = 0x0028/4, /* leave isr */
+ Icr = 0x002c/4,
Macadr = 0x0100, /* mac address 2ports*3 */
Pmd = 0x0119,
Maccfg = 0x011a,
uchar rev;
uchar nports;
uchar portno;
- uintptr io;
+ uvlong io;
uchar *reg8;
ushort *reg16;
uint *reg;
static Vtab vtab[] = {
0x11ab, 0x4354, 1514, "88e8040", /* unsure on mtu */
0x11ab, 0x4362, 1514, "88e8053",
+ 0x11ab, 0x4363, 1514, "88e8055",
0x11ab, 0x4364, 1514, "88e8056",
0x11ab, 0x4380, 1514, "88e8057",
0x11ab, 0x436b, 1514, "88e8071", /* unsure on mtu */
{
int i;
- if(r->rp + r->m - (n - 1) - wp[0] & ~r->m)
+ if(r->m - (int)(wp[0] - r->rp) < n)
return -1;
for(i = 0; i < n; i++)
t[i] = r->r + (wp[0]++ & r->m);
while(getnslot(r, &r->wp, tab, 1 + is64()) == -1)
starve(&c->txmit);
t = tab[is64()];
- assert(c->tbring[t - r->r] == nil);
c->tbring[t - r->r] = b;
if(is64()){
Status *t = tab[0];
Ctlr *c;
c = e->ctlr;
- if(wp - r->rp > r->cnt){
- print("rxscrew1 wp %ud(%ud) rp %ud %lud\n", wp, r->wp, r->rp, t-r->r);
+ if((int)(wp - r->rp) >= r->cnt){
+ print("rxscrew1 wp %ud(%ud) rp %ud %zd\n", wp, r->wp, r->rp, t-r->r);
return -1;
}
if(c->rbring[t - r->r]){
- print("rxscrew2 wp %ud rp %ud %lud\n", wp, r->rp, t-r->r);
+ print("rxscrew2 wp %ud rp %ud %zd\n", wp, r->rp, t-r->r);
descriptorfu(e, Qr);
return -1;
}
freeb(b);
break;
}
- assert(c->rbring[t - r->r] == nil);
c->rbring[t - r->r] = b;
if(is64()){
t->op = Opkt | Hw;
}
if(n>0){
+ r->wp = wp;
sfence();
prwrite16(c, Qr + Pputidx, wp & r->m);
- r->wp = wp;
dprint("yuk: replenish %d %ud-%ud [%d-%d]\n", n, r->rp, wp, r->rp&r->m, wp&r->m);
}
return n == lim;
static void
txcleanup(Ctlr *c, uint end)
{
- uint rp0, rp;
+ uint rp;
Block *b;
Sring *r;
Status *t;
r = &c->tx;
- rp0 = r->rp & r->m;
- for(rp = rp0; rp != end; rp = r->rp & r->m){
+ end &= r->m;
+ for(rp = r->rp & r->m; rp != end; rp = r->rp & r->m){
t = r->r + rp;
r->rp++;
if((t->ctl & Eop) == 0)
if(b != nil)
freeb(b);
}
- if(r->wp - r->rp > 16)
- unstarve(&c->txmit);
+ unstarve(&c->txmit);
}
static void
c = e->ctlr;
r = &c->rx;
for(rp = r->rp;;){
- if(rp == r->wp)
+ if(rp == r->wp){
+ print("#l%d: yuk rx empty\n", e->ctlrno);
return;
+ }
i = rp++&r->m;
b = c->rbring[i];
c->rbring[i] = nil;
if(b != nil)
break;
}
+ r->rp = rp;
cnt = x>>16 & 0x7fff;
if((cnt != l || x&Rxerror) &&
!(c->type == Yukfep && c->rev == 0)){
}else{
b->wp += l;
b->flag |= flag;
- etheriq(e, b, 1);
+ etheriq(e, b);
}
- r->rp = rp;
+ unstarve(&c->rxmit);
}
static uint
static void
sring(Ether *e)
{
- uint i, p, lim, op, l, x;
+ uint i, lim, op, l, x;
Ctlr *c;
Sring *r;
Status *s;
c = e->ctlr;
r = &c->status;
lim = c->reg16[Stathd] & r->m;
- p = 0;
for(;;){
i = r->rp & r->m;
if(i == lim){
x = getle(s->status, 4);
rx(e, l, x, cksum(c, ck, s->ctl));
ck = Badck;
- p++;
break;
case Otxidx:
l = getle(s->l, 2);
s->op = 0;
r->rp++;
}
- if(p != 0)
- unstarve(&c->rxmit);
c->reg[Statctl] = Statirqclr;
}
e = v;
c = e->ctlr;
+ /* reading Isrc2 masks interrupts */
cause = c->reg[Isrc2];
- if(cause != 0 && cause != ~0)
- unstarve(&c->iproc);
+ if(cause == 0 || cause == ~0){
+ /* reenable interrupts */
+ c->reg[Icr] = 2;
+ return;
+ }
+ unstarve(&c->iproc);
}
static void
p = seprint(p, e, "%s\t%ud\n", stattab[i].name, u);
}
p = seprint(p, e, "stat %.4ux ctl %.3ux\n", gmacread(c, Stat), gmacread(c, Ctl));
- p = seprint(p, e, "irq %.8ux\n", c->reg[Isrc2]);
p = seprint(p, e, "pref %.8ux %.4ux\n", prread32(c, Qr + Pctl), prread16(c, Qr + Pgetidx));
if(debug){
p = dumppci(c, p, e);
Pcidev *p;
p = c->p;
+ if(p->mem[0].bar & 1)
+ return -1;
c->io = p->mem[0].bar&~0xf;
mem = vmap(c->io, p->mem[0].size);
if(mem == nil){
- print("yuk: cant map %#p\n", c->io);
+ print("yuk: cant map %llux\n", c->io);
return -1;
}
+ pcienable(p);
c->p = p;
c->reg = (uint*)mem;
c->reg8 = (uchar*)mem;
c->rx.r = slice(&v, 16*4096, sizeof c->rx.r[0] * c->rx.cnt);
c->nports = 1; /* BOTCH */
- pcisetbme(p);
if(reset(c)){
print("yuk: cant reset\n");
- pciclrbme(p);
free(c->alloc);
vunmap(mem, p->mem[0].size);
+ pcidisable(p);
return -1;
}
macinit(c);
+ pcisetbme(p);
return 0;
}
c = ctlrtab[i];
if(c == nil || c->flag&Fprobe)
continue;
- if(e->port != 0 && e->port != (ulong)c->reg)
+ if(e->port != 0 && e->port != (ulong)(uintptr)c->reg)
continue;
c->flag |= Fprobe;
if(setup(c) != 0)
e->attach = attach;
e->ctl = ctl;
e->ifstat = ifstat;
- e->interrupt = interrupt;
e->multicast = multicast;
e->promiscuous = promiscuous;
e->shutdown = shutdown;
e->transmit = nil;
+ intrenable(e->irq, interrupt, e, e->tbdf, e->name);
+
return 0;
}