]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/ether79c970.c
kernel: cleanup the software mouse cursor mess
[plan9front.git] / sys / src / 9 / pc / ether79c970.c
index e77b1cd3ba42faa723a0f1375fb62f40b25c9375..d9e17e0b45688f2442a46d4887f7637ee6e5fec6 100644 (file)
@@ -12,8 +12,7 @@
 #include "io.h"
 #include "../port/error.h"
 #include "../port/netif.h"
-
-#include "etherif.h"
+#include "../port/etherif.h"
 
 enum {
        Lognrdre        = 6,
@@ -299,7 +298,7 @@ promiscuous(void* arg, int on)
 
        ctlr->iow(ctlr, Rap, 15);
        x = ctlr->ior(ctlr, Rdp) & ~Prom;
-       if(on)
+       if(on || ether->nmaddr > 0)
                x |= Prom;
        ctlr->iow(ctlr, Rdp, x);
        ctlr->iow(ctlr, Rap, 0);
@@ -315,7 +314,8 @@ promiscuous(void* arg, int on)
 static void
 multicast(void* arg, uchar*, int)
 {
-       promiscuous(arg, 1);
+       Ether *ether = arg;
+       promiscuous(arg, ether->prom);
 }
 
 static void
@@ -404,6 +404,7 @@ intrloop:
         * until a descriptor is encountered still owned by the chip.
         */
        if(csr0 & Rint){
+               ilock(ctlr);
                i = ctlr->rdrx;
                dre = &ctlr->rdr[i];
                while(!(dre->md1 & Own)){
@@ -423,7 +424,7 @@ intrloop:
                                if(bb != nil){
                                        len = (dre->md2 & 0x0FFF)-4;
                                        bb->wp = bb->rp+len;
-                                       etheriq(ether, bb, 1);
+                                       etheriq(ether, bb);
                                }
                                dre->addr = PADDR(bp->rp);
                        }
@@ -435,16 +436,17 @@ intrloop:
                        dre->md2 = 0;
                        dre->md1 = Own|(-Rbsize & 0xFFFF);
 
-                       ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
-                       dre = &ctlr->rdr[ctlr->rdrx];
+                       i = ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
+                       dre = &ctlr->rdr[i];
                }
+               iunlock(ctlr);
        }
 
        /*
         * Transmitter interrupt: wakeup anyone waiting for a free descriptor.
         */
        if(csr0 & Tint){
-               lock(ctlr);
+               ilock(ctlr);
                while(ctlr->ntq){
                        i = ctlr->tdri;
                        dre = &ctlr->tdr[i];
@@ -474,7 +476,7 @@ intrloop:
                        ctlr->tdri = NEXT(ctlr->tdri, Ntdre);
                }
                txstart(ether);
-               unlock(ctlr);
+               iunlock(ctlr);
        }
        goto intrloop;
 }
@@ -542,9 +544,10 @@ reset(Ether* ether)
        ether->port = ctlr->port;
        ether->irq = ctlr->pcidev->intl;
        ether->tbdf = ctlr->pcidev->tbdf;
-       pcisetbme(ctlr->pcidev);
        ilock(ctlr);
        ctlr->init = 1;
+       pcienable(ctlr->pcidev);
+       pcisetbme(ctlr->pcidev);
 
        io32r(ctlr, Sreset);
        io16r(ctlr, Sreset);
@@ -569,7 +572,10 @@ reset(Ether* ether)
        switch(x&0xFFFFFFF){
        case 0x2420003: /* PCnet/PCI 79C970 */
        case 0x2621003: /* PCnet/PCI II 79C970A */
+               ether->mbps = 10;
+               break;
        case 0x2625003: /* PCnet-FAST III 79C973 */
+               ether->mbps = 100;
                break;
        default:
                print("#l%d: unknown PCnet card version 0x%.7ux\n",
@@ -612,6 +618,15 @@ reset(Ether* ether)
                ether->ea[5] = x>>8;
        }
 
+       /* VMware */
+       x = ether->ea[0]<<16 | ether->ea[1]<<8 | ether->ea[2];
+       switch(x){
+       case 0x0569:
+       case 0x0C29:
+       case 0x5056:
+               ether->mbps = 1000;
+       }
+
        /*
         * Start to fill in the initialisation block
         * (must be DWORD aligned).
@@ -657,7 +672,6 @@ reset(Ether* ether)
         */
        ether->attach = attach;
        ether->transmit = transmit;
-       ether->interrupt = interrupt;
        ether->ifstat = ifstat;
 
        ether->arg = ether;
@@ -665,6 +679,8 @@ reset(Ether* ether)
        ether->multicast = multicast;
 //     ether->shutdown = shutdown;
 
+       intrenable(ether->irq, interrupt, ether, ether->tbdf, ether->name);
+
        return 0;
 }