]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/etheryuk.c
[9front] [PATCH] audiohda: add PCI ID for Intel C610/X99
[plan9front.git] / sys / src / 9 / pc / etheryuk.c
index 9e8ad140fa8aa727e34fefbe2859d6c5f704af70..fca2933299e72f8d498a7231196eb5fac16ac441 100644 (file)
@@ -8,9 +8,10 @@
 #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)
@@ -49,6 +50,7 @@ enum {
        Isrc2   = 0x001c/4,
        Eisr    = 0x0024/4,
        Lisr    = 0x0028/4,             /* leave isr */
+       Icr     = 0x002c/4,
        Macadr  = 0x0100,               /* mac address 2ports*3 */
        Pmd     = 0x0119,
        Maccfg  = 0x011a,
@@ -679,7 +681,7 @@ struct Ctlr {
        uchar   rev;
        uchar   nports;
        uchar   portno;
-       uintptr io;
+       uvlong  io;
        uchar   *reg8;
        ushort  *reg16;
        uint    *reg;
@@ -739,6 +741,7 @@ static Chipid idtab[] = {
 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 */
@@ -831,7 +834,7 @@ getnslot(Sring *r, uint *wp, Status **t, uint n)
 {
        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);
@@ -1150,7 +1153,6 @@ tproc(void *v)
                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];
@@ -1205,12 +1207,12 @@ rxscrew(Ether *e, Sring *r, Status *t, uint wp)
        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;
        }
@@ -1245,7 +1247,6 @@ replenish(Ether *e, Ctlr *c)
                        freeb(b);
                        break;
                }
-               assert(c->rbring[t - r->r] == nil);
                c->rbring[t - r->r] = b;
 
                if(is64()){
@@ -1260,9 +1261,9 @@ replenish(Ether *e, Ctlr *c)
                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;
@@ -1380,14 +1381,14 @@ link(Ether *e)
 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)
@@ -1397,8 +1398,7 @@ txcleanup(Ctlr *c, uint end)
                if(b != nil)
                        freeb(b);
        }
-       if(r->wp - r->rp > 16)
-               unstarve(&c->txmit);
+       unstarve(&c->txmit);
 }
 
 static void
@@ -1412,14 +1412,17 @@ rx(Ether *e, uint l, uint x, uint flag)
        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)){
@@ -1428,9 +1431,9 @@ rx(Ether *e, uint l, uint x, uint flag)
        }else{
                b->wp += l;
                b->flag |= flag;
-               etheriq(e, b, 1);
+               etheriq(e, b);
        }
-       r->rp = rp;
+       unstarve(&c->rxmit);
 }
 
 static uint
@@ -1446,7 +1449,7 @@ cksum(Ctlr *c, uint ck, uint css)
 static void
 sring(Ether *e)
 {
-       uint i, p, lim, op, l, x;
+       uint i, lim, op, l, x;
        Ctlr *c;
        Sring *r;
        Status *s;
@@ -1455,7 +1458,6 @@ sring(Ether *e)
        c = e->ctlr;
        r = &c->status;
        lim = c->reg16[Stathd] & r->m;
-       p = 0;
        for(;;){
                i = r->rp & r->m;
                if(i == lim){
@@ -1477,7 +1479,6 @@ sring(Ether *e)
                        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);
@@ -1496,8 +1497,6 @@ sring(Ether *e)
                s->op = 0;
                r->rp++;
        }
-       if(p != 0)
-               unstarve(&c->rxmit);
        c->reg[Statctl] = Statirqclr;
 }
 
@@ -1674,9 +1673,14 @@ interrupt(Ureg*, void *v)
        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
@@ -1755,7 +1759,6 @@ ifstat(Ether *e0, void *a, long n, ulong offset)
                        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);
@@ -2127,12 +2130,15 @@ setup(Ctlr *c)
        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;
@@ -2155,15 +2161,15 @@ setup(Ctlr *c)
        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;
 }
 
@@ -2227,7 +2233,7 @@ pnp(Ether *e)
                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)
@@ -2245,12 +2251,13 @@ pnp(Ether *e)
        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;
 }