]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/ether82557.c
kernel: cleanup the software mouse cursor mess
[plan9front.git] / sys / src / 9 / pc / ether82557.c
index 2db2a7cdd522b26596b3681d55a7ce1a8b88dc9a..5577c7a79e2c99bef353717d8e194acd1e1eafc7 100644 (file)
@@ -16,8 +16,7 @@
 #include "io.h"
 #include "../port/error.h"
 #include "../port/netif.h"
-
-#include "etherif.h"
+#include "../port/etherif.h"
 
 enum {
        Nrfd            = 64,           /* receive frame area */
@@ -348,6 +347,8 @@ watchdog(void* arg)
        static void txstart(Ether*);
 
        ether = arg;
+       while(waserror())
+               ;
        for(;;){
                tsleep(&up->sleep, return0, 0, 4000);
 
@@ -357,10 +358,8 @@ watchdog(void* arg)
                 * the future.
                 */
                ctlr = ether->ctlr;
-               if(ctlr == nil || ctlr->state == 0){
-                       print("%s: exiting\n", up->text);
-                       pexit("disabled", 0);
-               }
+               if(ctlr == nil || ctlr->state == 0)
+                       break;
 
                ilock(&ctlr->cblock);
                if(ctlr->tick++){
@@ -369,6 +368,8 @@ watchdog(void* arg)
                }
                iunlock(&ctlr->cblock);
        }
+       print("%s: exiting\n", up->text);
+       pexit("disabled", 1);
 }
 
 static void
@@ -409,6 +410,10 @@ ifstat(Ether* ether, void* a, long n, ulong offset)
 
        ctlr = ether->ctlr;
        lock(&ctlr->dlock);
+       if(waserror()){
+               unlock(&ctlr->dlock);
+               nexterror();
+       }
 
        /*
         * Start the command then
@@ -417,24 +422,26 @@ ifstat(Ether* ether, void* a, long n, ulong offset)
         */
        ctlr->dump[16] = 0;
        command(ctlr, DumpSC, 0);
-       while(ctlr->dump[16] == 0)
-               ;
+       for(i = 0; i < 1000 && ctlr->dump[16] == 0; i++)
+               microdelay(100);
+       if(i == 1000)
+               error("command timeout");
 
-       ether->oerrs = ctlr->dump[1]+ctlr->dump[2]+ctlr->dump[3];
-       ether->crcs = ctlr->dump[10];
-       ether->frames = ctlr->dump[11];
-       ether->buffs = ctlr->dump[12]+ctlr->dump[15];
-       ether->overflows = ctlr->dump[13];
+       memmove(dump, ctlr->dump, sizeof(dump));
 
-       if(n == 0){
-               unlock(&ctlr->dlock);
-               return 0;
-       }
+       ether->oerrs = dump[1]+dump[2]+dump[3];
+       ether->crcs = dump[10];
+       ether->frames = dump[11];
+       ether->buffs = dump[12]+dump[15];
+       ether->overflows = dump[13];
 
-       memmove(dump, ctlr->dump, sizeof(dump));
+       poperror();
        unlock(&ctlr->dlock);
 
-       p = malloc(READSTR);
+       if(n == 0)
+               return 0;
+
+       p = smalloc(READSTR);
        len = snprint(p, READSTR, "transmit good frames: %lud\n", dump[0]);
        len += snprint(p+len, READSTR-len, "transmit maximum collisions errors: %lud\n", dump[1]);
        len += snprint(p+len, READSTR-len, "transmit late collisions errors: %lud\n", dump[2]);
@@ -580,20 +587,15 @@ configure(Ether* ether, int promiscuous)
 static void
 promiscuous(void* arg, int on)
 {
-       configure(arg, on);
+       Ether *ether = arg;
+       configure(ether, on || ether->nmaddr > 0);
 }
 
 static void
-multicast(void* ether, uchar *addr, int add)
+multicast(void* arg, uchar *, int)
 {
-       USED(addr);
-       /*
-        * TODO: if (add) add addr to list of mcast addrs in controller
-        *      else remove addr from list of mcast addrs in controller
-        * enable multicast input (see CbMAS) instead of promiscuous mode.
-        */
-       if (add)
-               configure(ether, 1);
+       Ether *ether = arg;
+       configure(ether, ether->prom || ether->nmaddr > 0);
 }
 
 static void
@@ -653,7 +655,7 @@ receive(Ether* ether)
                                bp = xbp;
                        }
                        if(pbp != nil)
-                               etheriq(ether, pbp, 1);
+                               etheriq(ether, pbp);
                }
                else{
                        rfd->count = 0;
@@ -754,7 +756,7 @@ interrupt(Ureg*, void* arg)
                }
 
                if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
-                       panic("#l%d: status %#ux\n", ether->ctlrno, status);
+                       panic("#l%d: status %#ux", ether->ctlrno, status);
        }
 }
 
@@ -777,6 +779,8 @@ ctlrinit(Ctlr* ctlr)
        link = NullPointer;
        for(i = 0; i < Nrfd; i++){
                bp = rfdalloc(link);
+               if(bp == nil)
+                       panic("i82557: can't allocate rfd buffer");
                if(ctlr->rfdhead == nil)
                        ctlr->rfdtail = bp;
                bp->next = ctlr->rfdhead;
@@ -795,6 +799,8 @@ ctlrinit(Ctlr* ctlr)
         */
        ilock(&ctlr->cblock);
        ctlr->cbr = malloc(ctlr->ncb*sizeof(Cb));
+       if(ctlr->cbr == nil)
+               panic("i82557: can't allocate cbr");
        for(i = 0; i < ctlr->ncb; i++){
                ctlr->cbr[i].status = CbC|CbOK;
                ctlr->cbr[i].command = CbS|CbNOP;
@@ -911,6 +917,8 @@ reread:
        if(ctlr->eepromsz == 0){
                ctlr->eepromsz = 8-size;
                ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
+               if(ctlr->eeprom == nil)
+                       panic("i82557: can't allocate eeprom");
                goto reread;
        }
 
@@ -922,7 +930,7 @@ i82557pci(void)
 {
        Pcidev *p;
        Ctlr *ctlr;
-       int i, nop, port;
+       int nop, port;
 
        p = nil;
        nop = 0;
@@ -948,17 +956,6 @@ i82557pci(void)
                        break;
                }
 
-               if(pcigetpms(p) > 0){
-                       pcisetpms(p, 0);
-       
-                       for(i = 0; i < 6; i++)
-                               pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
-                       pcicfgw8(p, PciINTL, p->intl);
-                       pcicfgw8(p, PciLTR, p->ltr);
-                       pcicfgw8(p, PciCLS, p->cls);
-                       pcicfgw16(p, PciPCR, p->pcr);
-               }
-
                /*
                 * bar[0] is the memory-mapped register address (4KB),
                 * bar[1] is the I/O port register address (32 bytes) and
@@ -971,6 +968,11 @@ i82557pci(void)
                }
 
                ctlr = malloc(sizeof(Ctlr));
+               if(ctlr == nil){
+                       print("i82557: can't allocate memory\n");
+                       iofree(port);
+                       continue;
+               }
                ctlr->port = port;
                ctlr->pcidev = p;
                ctlr->nop = nop;
@@ -980,8 +982,6 @@ i82557pci(void)
                else
                        ctlrhead = ctlr;
                ctlrtail = ctlr;
-
-               pcisetbme(p);
        }
 }
 
@@ -1062,6 +1062,9 @@ reset(Ether* ether)
        if(ctlr == nil)
                return -1;
 
+       pcienable(ctlr->pcidev);
+       pcisetbme(ctlr->pcidev);
+
        /*
         * Initialise the Ctlr structure.
         * Perform a software reset after which should ensure busmastering
@@ -1195,26 +1198,26 @@ reset(Ether* ether)
                         */
                        miir(ctlr, phyaddr, 0x01);
                        bmsr = miir(ctlr, phyaddr, 0x01);
-                       if((miir(ctlr, phyaddr, 0) & 0x1000) && !(bmsr & 0x0020)){
-                               miiw(ctlr, phyaddr, 0x1A, 0x2010);
-                               x = miir(ctlr, phyaddr, 0);
-                               miiw(ctlr, phyaddr, 0, 0x0200|x);
-                               for(i = 0; i < 3000; i++){
-                                       delay(1);
-                                       if(miir(ctlr, phyaddr, 0x01) & 0x0020)
-                                               break;
-                               }
-                               miiw(ctlr, phyaddr, 0x1A, 0x2000);
-                                       
-                               anar = miir(ctlr, phyaddr, 0x04);
-                               anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
-                               anar &= anlpar;
-                               bmcr = 0;
-                               if(anar & 0x380)
-                                       bmcr = 0x2000;
-                               if(anar & 0x0140)
-                                       bmcr |= 0x0100;
+                       if((miir(ctlr, phyaddr, 0) & 0x1000) && (bmsr & 0x0020))
+                               break;
+                       miiw(ctlr, phyaddr, 0x1A, 0x2010);
+                       x = miir(ctlr, phyaddr, 0);
+                       miiw(ctlr, phyaddr, 0, 0x1200|x);
+                       for(i = 0; i < 3000; i++){
+                               delay(1);
+                               if(miir(ctlr, phyaddr, 0x01) & 0x0020)
+                                       break;
                        }
+                       miiw(ctlr, phyaddr, 0x1A, 0x2000);
+                                       
+                       anar = miir(ctlr, phyaddr, 0x04);
+                       anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
+                       anar &= anlpar;
+                       bmcr = 0;
+                       if(anar & 0x380)
+                               bmcr = 0x2000;
+                       if(anar & 0x0140)
+                               bmcr |= 0x0100;
                        break;
                }
 
@@ -1318,7 +1321,6 @@ reset(Ether* ether)
         */
        ether->attach = attach;
        ether->transmit = transmit;
-       ether->interrupt = interrupt;
        ether->ifstat = ifstat;
        ether->shutdown = shutdown;
 
@@ -1326,6 +1328,8 @@ reset(Ether* ether)
        ether->multicast = multicast;
        ether->arg = ether;
 
+       intrenable(ether->irq, interrupt, ether, ether->tbdf, ether->name);
+
        return 0;
 }