]> 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 e4c5ba548ae164b9f64af09e1b2e42ce3e3abb7d..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)
@@ -26,7 +27,6 @@ enum {
        Fprobe  = 1<<0,
        Sringcnt        = 2048,
        Tringcnt        = 512,
-//     Rringcnt        = Nrb,
        Rringcnt        = 512,
        Rringl  = Rringcnt - 8,
 };
@@ -50,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,
@@ -680,7 +681,7 @@ struct Ctlr {
        uchar   rev;
        uchar   nports;
        uchar   portno;
-       uintptr io;
+       uvlong  io;
        uchar   *reg8;
        ushort  *reg16;
        uint    *reg;
@@ -740,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 */
@@ -803,20 +805,6 @@ static     uchar   nilea[Eaddrlen];
 static int     debug;
 static Ctlr    *ctlrtab[Nctlr];
 static int     nctlr;
-static struct {
-       union {
-               struct {
-                       Lock;
-                       Block   *b;
-                       uint    starve;
-               };
-               uchar pad[128];         /* cacheline */
-       };
-       Kproc   *k;
-       Block   *x;
-       uint    nfast;
-       uint    nslow;
-} rbtab[Nctlr];
 
 static int
 icansleep(void *v)
@@ -841,102 +829,18 @@ starve(Kproc *k)
        k->event = 0;
 }
 
-static Status*
-getslot(Sring *r, Kproc *k)
-{
-       if(r->rp + r->m - r->wp & ~r->m)
-               starve(k);
-       return r->r + (r->wp++ & r->m);
-}
-
 static int
 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);
        return 0;
 }
 
-/* assume allocs come from a single thread; 30*0.999x speedup */
-static Block*
-rballoc(int t)
-{
-       Block *b;
-
-       if((b = rbtab[t].x) != nil){
-               rbtab[t].nfast++;
-               rbtab[t].x = b->next;
-               b->next = nil;
-b->ref = 1;
-               return b;
-       }
-
-       ilock(&rbtab[t]);
-       b = rbtab[t].x = rbtab[t].b;
-       rbtab[t].b = nil;
-       if(b == nil)
-               rbtab[t].starve = 1;
-       iunlock(&rbtab[t]);
-       
-       rbtab[t].nslow++;
-       if(b != nil){
-               rbtab[t].x = b->next;
-               b->next = nil;
-b->ref = 1;
-       }
-       return b;
-}
-
-static void
-rbfree(Block *b, int t)
-{
-       b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
-       b->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
-       ilock(&rbtab[t]);
-       b->next = rbtab[t].b;
-       if(b->next == nil && rbtab[t].starve){
-               rbtab[t].starve = 0;
-               unstarve(rbtab[t].k);
-       }
-       rbtab[t].b = b;
-       iunlock(&rbtab[t]);
-}
-
-static void
-rbfree0(Block *b)
-{
-       rbfree(b, 0);
-}
-
-static void
-rbfree1(Block *b)
-{
-       rbfree(b, 1);
-}
-
-static void
-rbfree2(Block *b)
-{
-       rbfree(b, 2);
-}
-
-static void
-rbfree3(Block *b)
-{
-       rbfree(b, 3);
-}
-
-static Freefn freetab[Nctlr] = {
-       rbfree0,
-       rbfree1,
-       rbfree2,
-       rbfree3,
-};
-
 static uint
 macread32(Ctlr *c, uint r)
 {
@@ -1232,13 +1136,11 @@ tproc(void *v)
        Block *b;
        Ctlr *c;
        Ether *e;
-       Kproc *k;
        Sring *r;
-       Status *t;
+       Status *tab[2], *t;
 
        e = v;
        c = e->ctlr;
-       k = &c->txmit;
        r = &c->tx;
 
        txinit(e);
@@ -1248,14 +1150,16 @@ tproc(void *v)
        for(;;){
                if((b = qbread(e->oq, 100000)) == nil)
                        break;
-               if(Pciwaddrh(b->rp) != 0){
-                       t = getslot(r, k);
+               while(getnslot(r, &r->wp, tab, 1 + is64()) == -1)
+                       starve(&c->txmit);
+               t = tab[is64()];
+               c->tbring[t - r->r] = b;
+               if(is64()){
+                       Status *t = tab[0];
                        t->ctl = 0;
                        t->op = Oaddr64 | Hw;
                        putle(t->status, Pciwaddrh(b->rp), 4);
                }
-               t = getslot(r, k);
-               c->tbring[t - r->r] = b;
                putle(t->status, Pciwaddrl(b->rp), 4);
                putle(t->l, BLEN(b), 2);
                t->op = Opkt | Hw;
@@ -1270,9 +1174,7 @@ tproc(void *v)
 static void
 rxinit(Ether *e)
 {
-       int i;
        Ctlr *c;
-       Block *b;
        Sring *r;
        Status *t;
 
@@ -1281,19 +1183,14 @@ rxinit(Ether *e)
        if(c->rxinit == 1)
                return;
        c->rxinit = 1;
-       for(i = 0; i < Nrb; i++){
-               b = allocb(c->rbsz + Rbalign);
-               b->free = freetab[c->qno];
-               freeb(b);
-       }
-
        qinit(c, Qr);
        if(c->type == Yukecu && (c->rev == 2 || c->rev == 3))
                qrwrite(c, Qr + Qtest, Qramdis);
        pinit(c,  Qr, &c->rx);
 
        if((c->flag & Fnewle) == 0){
-               t = getslot(r, &c->rxmit);
+               while(getnslot(r, &r->wp, &t, 1) == -1)
+                       starve(&c->rxmit);
                putle(t->status, 14<<16 | 14, 4);
                t->ctl = 0;
                t->op = Ock | Hw;
@@ -1310,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;
        }
@@ -1325,7 +1222,7 @@ rxscrew(Ether *e, Sring *r, Status *t, uint wp)
 static int
 replenish(Ether *e, Ctlr *c)
 {
-       int req, n, lim;
+       int n, lim;
        uint wp;
        Block *b;
        Sring *r;
@@ -1333,41 +1230,43 @@ replenish(Ether *e, Ctlr *c)
 
        r = &c->rx;
        wp = r->wp;
-       req = 1 + is64();
 
        lim = r->cnt/2;
        if(lim > 128)
                lim = 128;              /* hw limit? */
        for(n = 0; n < lim; n++){
-               b = rballoc(c->qno);
-               if(b == nil || getnslot(r, &wp, tab, req) == -1){
+               b = iallocb(c->rbsz + Rbalign);
+               if(b == nil || getnslot(r, &wp, tab, 1 + is64()) == -1){
+                       freeb(b);
+                       break;
+               }
+               b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
+
+               t = tab[is64()];
+               if(rxscrew(e, r, t, wp) == -1){
                        freeb(b);
                        break;
                }
-               t = tab[0];
+               c->rbring[t - r->r] = b;
+
                if(is64()){
+                       Status *t = tab[0];
                        putle(t->status, Pciwaddrh(b->wp), 4);
                        t->ctl = 0;
                        t->op = Oaddr64 | Hw;
-                       t = tab[1];
                }
-               if(rxscrew(e, r, t, wp) == -1)
-                       break;
-               assert(c->rbring[t - r->r] == nil);
-               c->rbring[t - r->r] = b;
-
                putle(t->status, Pciwaddrl(b->wp), 4);
                putle(t->l, c->rbsz, 2);
                t->ctl = 0;
                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 lim - n == 0;
+       return n == lim;
 }
 
 static void
@@ -1375,21 +1274,18 @@ rproc(void *v)
 {
        Ctlr *c;
        Ether *e;
-       Kproc *k;
 
        e = v;
        c = e->ctlr;
-       k = &c->rxmit;
 
        rxinit(e);
        linkup(c, Rxen);
        while(waserror())
                ;
-       for(;;)
-               if(replenish(e, c) == 0){
-                       starve(k);
-                       print("yuk: rx unstarve?\n");
-               }
+       for(;;){
+               if(replenish(e, c) == 0)
+                       starve(&c->rxmit);
+       }
 }
 
 static void
@@ -1485,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)
@@ -1502,10 +1398,7 @@ txcleanup(Ctlr *c, uint end)
                if(b != nil)
                        freeb(b);
        }
-       if(r->wp - r->rp > 16){         /* BOTCH */
-               print("TX unstarve %ud - %ud \n", r->wp, r->rp);
-               unstarve(&c->txmit);
-       }
+       unstarve(&c->txmit);
 }
 
 static void
@@ -1519,24 +1412,28 @@ rx(Ether *e, uint l, uint x, uint flag)
        c = e->ctlr;
        r = &c->rx;
        for(rp = r->rp;;){
+               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 &&
+       if((cnt != l || x&Rxerror) &&
        !(c->type == Yukfep && c->rev == 0)){
                print("#l%d: yuk rx error %.4ux\n", e->ctlrno, x&0xffff);
                freeb(b);
        }else{
                b->wp += l;
-               b->lim = b->wp;         /* lie like a dog */
                b->flag |= flag;
-               etheriq(e, b, 1);
+               etheriq(e, b);
        }
-       r->rp = rp;
+       unstarve(&c->rxmit);
 }
 
 static uint
@@ -1552,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;
@@ -1560,15 +1457,14 @@ sring(Ether *e)
 
        c = e->ctlr;
        r = &c->status;
-       lim = r->rp & r->m;
-       p = 0;
+       lim = c->reg16[Stathd] & r->m;
        for(;;){
-               if((r->rp & r->m) == lim){
-                       lim = c->reg16[Stathd];
-                       if((r->rp & r->m) == lim)
+               i = r->rp & r->m;
+               if(i == lim){
+                       lim = c->reg16[Stathd] & r->m;
+                       if(i == lim)
                                break;
                }
-               i = r->rp & r->m;
                s = r->r + i;
                op = s->op;
                if((op & Hw) == 0)
@@ -1583,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);
@@ -1602,8 +1497,6 @@ sring(Ether *e)
                s->op = 0;
                r->rp++;
        }
-       while(p && replenish(e, c) != 0)
-               ;
        c->reg[Statctl] = Statirqclr;
 }
 
@@ -1749,15 +1642,13 @@ iproc(void *v)
        uint cause, d;
        Ether *e;
        Ctlr *c;
-       Kproc *k;
 
        e = v;
        c = e->ctlr;
-       k = &c->iproc;
        while(waserror())
                ;
        for(;;){
-               starve(k);
+               starve(&c->iproc);
                cause = c->reg[Eisr];
                if(cause & Iphy)
                        link(e);
@@ -1782,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
@@ -1863,9 +1759,7 @@ 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));
-       p = seprint(p, e, "nfast %ud nslow %ud\n", rbtab[c->qno].nfast, rbtab[c->qno].nslow);
        if(debug){
                p = dumppci(c, p, e);
                p = dumpgmac(c, p, e);
@@ -2236,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;
@@ -2264,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;
 }
 
@@ -2311,9 +2208,12 @@ scan(void)
                        return;
                }
                c = malloc(sizeof *c);
+               if(c == nil){
+                       print("yuk: no memory for Ctlr\n");
+                       return;
+               }
                c->p = p;
                c->qno = nctlr;
-               rbtab[c->qno].k = &c->rxmit;
                c->rbsz = vtab[i].mtu;
                ctlrtab[nctlr++] = c;
        }
@@ -2333,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)
@@ -2351,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;
 }