Added new probe code to detect generic lance based cards. Should now
[unix-history] / sys / i386 / isa / if_is.c
index 1277b4d..e27ea89 100644 (file)
 
 #include "vm/vm.h"
 
 
 #include "vm/vm.h"
 
-
-
 #define ETHER_MIN_LEN 64
 #define ETHER_MAX_LEN   1518
 #define ETHER_ADDR_LEN  6
 
 #define ETHER_MIN_LEN 64
 #define ETHER_MAX_LEN   1518
 #define ETHER_ADDR_LEN  6
 
+char *card_type[] = {"Unknown",
+                     "BICC Isolan",
+                     "NE2100"};
+
+char *ic_type[] = {"Unknown",
+                   "Am7990 LANCE",
+                   "Am79960 PCnet_ISA"};
+                 
 
 
-/*
- * Ethernet software status per interface.
- *
- * Each interface is referenced by a network interface structure,
- * arpcom.ac_if, which the routing code uses to locate the interface.
- * This structure contains the output queue for the interface, its address, ...
- */
 struct is_softc {
 struct is_softc {
-       struct  arpcom arpcom;          /* Ethernet common part */
-       int iobase;                     /* IO base address of card */
+       struct arpcom arpcom;             /* Ethernet common part */
+       int iobase;
+       int rap;
+       int rdp;
+       int ic_type;                         /* Am 7990 or Am79960 */
+       int card_type;
+       int is_debug;
+       struct init_block  *init_block;   /* Lance initialisation block */
        struct mds      *rd;
        struct mds      *td;
        unsigned char   *rbuf;
        struct mds      *rd;
        struct mds      *td;
        unsigned char   *rbuf;
@@ -87,15 +92,23 @@ struct      is_softc {
        int     last_rd;
        int     last_td;
        int     no_td;
        int     last_rd;
        int     last_td;
        int     no_td;
-        caddr_t bpf;                   /* BPF "magic cookie" */
+       caddr_t bpf;                      /* BPF "magic cookie" */
 
 } is_softc[NIS] ;
 
 
 } is_softc[NIS] ;
 
-struct init_block init_block[NIS];
 
 /* Function prototypes */
 
 /* Function prototypes */
-int is_probe(),is_attach(),is_watchdog();
-int is_ioctl(),is_init(),is_start();
+static int is_probe(struct isa_device *);
+static int is_attach(struct isa_device *);
+static void is_watchdog(int);
+static int is_ioctl(struct ifnet *, int, caddr_t);
+static void is_init(int);
+static void is_start(struct ifnet *);
+static void istint(int);
+static void recv_print(int, int);
+static void xmit_print(int, int);
+
+
 
 static inline void is_rint(int unit);
 static inline void isread(struct is_softc*, unsigned char*, int);
 
 static inline void is_rint(int unit);
 static inline void isread(struct is_softc*, unsigned char*, int);
@@ -108,71 +121,172 @@ struct   isa_driver isdriver = {
        "is"
 };
 
        "is"
 };
 
+void
 iswrcsr(unit,port,val)
        int unit;
        u_short port;
        u_short val;
 {
 iswrcsr(unit,port,val)
        int unit;
        u_short port;
        u_short val;
 {
-       int iobase;
-
-       iobase = is_softc[unit].iobase;
-       outw(iobase+RAP,port);
-       outw(iobase+RDP,val);
+       outw(is_softc[unit].rap,port);
+       outw(is_softc[unit].rdp,val);
 }
 
 u_short isrdcsr(unit,port)
        int unit;
        u_short port;
 {
 }
 
 u_short isrdcsr(unit,port)
        int unit;
        u_short port;
 {
-       int iobase;
-       
-       iobase = is_softc[unit].iobase;
-       outw(iobase+RAP,port);
-       return(inw(iobase+RDP));
+       outw(is_softc[unit].rap,port);
+       return(inw(is_softc[unit].rdp));
 } 
 
 } 
 
+int
 is_probe(isa_dev)
        struct isa_device *isa_dev;
 {
 is_probe(isa_dev)
        struct isa_device *isa_dev;
 {
-       int val,i,s;
        int unit = isa_dev->id_unit ;
        int unit = isa_dev->id_unit ;
-       register struct is_softc *is = &is_softc[unit];
+       int nports;
 
 
-       is->iobase = isa_dev->id_iobase;
+int i;
+       is_softc[unit].iobase = isa_dev->id_iobase;
+
+       /*
+        * It's impossible to do a non-invasive probe of the 
+        * LANCE and PCnet_ISA. The LANCE requires setting the
+        * STOP bit to access the registers and the PCnet_ISA
+        * address port resets to an unknown state!!
+        */
+
+       /*
+        * Check for BICC cards first since for the NE2100 and
+        * PCnet-ISA cards this write will hit the Address PROM. 
+        */
+
+printf("Dumping io space for is%d starting at %x\n",unit,is_softc[unit].iobase);
+for (i=0; i< 32; i++)
+       printf(" %x ",inb(is_softc[unit].iobase+i));
+printf("\n");
+
+       if (nports = bicc_probe(unit))
+               return (nports);
+       if (nports = ne2100_probe(unit))
+               return (nports);
 
 
-       /* Stop the lance chip, put it known state */   
-       iswrcsr(unit,0,STOP);
-       DELAY(100);
 
 
-       /* is there a lance? */
-       iswrcsr(unit,3, 0xffff);
-       if (isrdcsr(unit,3) != 7) {
-               is->iobase = 0;
-               return (0);
+       return (0);
+}
+
+int
+ne2100_probe(unit)
+       int unit;
+{
+struct is_softc *is = &is_softc[unit];
+int i;
+
+       is->rap = is->iobase + NE2100_RAP;
+       is->rdp = is->iobase + NE2100_RDP;
+
+       if (is->ic_type = lance_probe(unit)) {
+               is->card_type = NE2100;
+               /* 
+                * Extract the physical MAC address from ROM
+                */
+               for(i=0;i<ETHER_ADDR_LEN;i++)
+                       is->arpcom.ac_enaddr[i]=inb(is->iobase+i);
+
+               /* 
+                * Return number of I/O ports used by card 
+                */
+               return (24);
        }
        }
-       iswrcsr(unit,3, 0);
+       return (0);
+}
+                       
 
 
-       /* Extract board address */
-       for(i=0;i<ETHER_ADDR_LEN;i++)
-               is->arpcom.ac_enaddr[i]=inb(is->iobase+(i*2));
+int
+bicc_probe(unit)
+       int unit;
+{
+struct is_softc *is = &is_softc[unit];
+int i;
 
 
-       return (1);
+       is->rap = is->iobase + BICC_RAP;
+       is->rdp = is->iobase + BICC_RDP;
+
+       if (is->ic_type = lance_probe(unit)) {
+               is->card_type = BICC;
+
+               /*
+                * Extract the physical ethernet address from ROM
+                */
+
+               for(i=0;i<ETHER_ADDR_LEN;i++)
+                       is->arpcom.ac_enaddr[i]=inb(is->iobase+(i*2));
+
+               /* 
+                * Return number of I/O ports used by card 
+                */
+               return (16);
+       }
+       return (0);
 }
 
 
 }
 
 
+/* 
+ * Determine which, if any, of the LANCE or 
+ * PCnet-ISA are present on the card.
+ */
+
+int
+lance_probe(unit)
+       int unit;
+{
+int type=0;
+
+       /* 
+        * Have to reset the LANCE to get any 
+        * stable information from it.
+        */
+
+       iswrcsr(unit,0,STOP);
+       DELAY(100);
+
+       if (isrdcsr(unit,0) != STOP)
+               /* 
+                * This either isn't a LANCE 
+                * or there's a major problem.
+                */
+               return(0);
+
+       /* 
+        * Depending on which controller it is, CSR3 will have 
+        * different settable bits. Write to them all and see which ones
+        * get set.
+        */
+
+       iswrcsr(unit,3, LANCE_MASK);
+
+       if (isrdcsr(unit,3) == LANCE_MASK)
+               type = LANCE;
+
+       if (isrdcsr(unit,3) == PCnet_ISA_MASK)
+               type = PCnet_ISA;
+
+       return (type);
+}
 
 /*
  * Reset of interface.
  */
 
 /*
  * Reset of interface.
  */
-int is_reset(int unit)
+static void
+is_reset(int unit, int uban)
 {
        int s;
 {
        int s;
+       struct is_softc *is = &is_softc[unit];
+
        if (unit >= NIS)
                return;
        if (unit >= NIS)
                return;
-       s = splnet();
        printf("is%d: reset\n", unit);
        is_init(unit);
        printf("is%d: reset\n", unit);
        is_init(unit);
-       (void) splx(s);
 }
  
 /*
 }
  
 /*
@@ -180,16 +294,15 @@ int is_reset(int unit)
  * record.  System will initialize the interface when it is ready
  * to accept packets.  We get the ethernet address here.
  */
  * record.  System will initialize the interface when it is ready
  * to accept packets.  We get the ethernet address here.
  */
-int is_attach(isa_dev)
+int
+is_attach(isa_dev)
        struct isa_device *isa_dev;
 {
        int unit = isa_dev->id_unit;
        struct is_softc *is = &is_softc[unit];
        struct ifnet *ifp = &is->arpcom.ac_if;
        struct isa_device *isa_dev;
 {
        int unit = isa_dev->id_unit;
        struct is_softc *is = &is_softc[unit];
        struct ifnet *ifp = &is->arpcom.ac_if;
-        struct ifaddr *ifa;
-        struct sockaddr_dl *sdl;
-
-
+       struct ifaddr *ifa;
+       struct sockaddr_dl *sdl;
 
        ifp->if_unit = unit;
        ifp->if_name = isdriver.name ;
 
        ifp->if_unit = unit;
        ifp->if_name = isdriver.name ;
@@ -202,86 +315,132 @@ int is_attach(isa_dev)
        ifp->if_reset = is_reset;
        ifp->if_watchdog = is_watchdog;
 
        ifp->if_reset = is_reset;
        ifp->if_watchdog = is_watchdog;
 
+       /*
+        * XXX -- not sure this is right place to do this
+        * Allocate memory for use by Lance
+        * Memory allocated for:
+        *      initialisation block,
+        *      ring descriptors,
+        *      transmit and receive buffers.
+        */
+
+       /*
+        * XXX - hopefully have better way to get dma'able memory later,
+        * this code assumes that the physical memory address returned
+        * from malloc will be below 16Mb. The Lance's address registers
+        * are only 16 bits wide!
+        */
+
+#define MAXMEM ((NRBUF+NTBUF)*(BUFSIZE) + (NRBUF+NTBUF)*sizeof(struct mds) \
+                 + sizeof(struct init_block) + 8)
+       is->init_block = (struct init_block *)malloc(MAXMEM,M_TEMP,M_NOWAIT);
+       if (!is->init_block) {
+               printf("is%d : Couldn't allocate memory for card\n",unit);
+       }
+       /* 
+        * XXX -- should take corrective action if not
+        * quadword alilgned, the 8 byte slew factor in MAXMEM
+        * allows for this.
+        */
+
+       if ((u_long)is->init_block & 0x3) 
+               printf("is%d: memory allocated not quadword aligned\n");
+
        /* Set up DMA */
        isa_dmacascade(isa_dev->id_drq);
 
        if_attach(ifp);
 
        /* Set up DMA */
        isa_dmacascade(isa_dev->id_drq);
 
        if_attach(ifp);
 
-/*
-         * Search down the ifa address list looking for the AF_LINK type
-entry
-         */
-        ifa = ifp->if_addrlist;
-        while ((ifa != 0) && (ifa->ifa_addr != 0) &&
-            (ifa->ifa_addr->sa_family != AF_LINK))
-                ifa = ifa->ifa_next;
+       /*
+        * Search down the ifa address list looking 
+        * for the AF_LINK type entry
+        */
 
 
-        /*
-         * If we find an AF_LINK type entry, we will fill
+       ifa = ifp->if_addrlist;
+       while ((ifa != 0) && (ifa->ifa_addr != 0) &&
+         (ifa->ifa_addr->sa_family != AF_LINK))
+               ifa = ifa->ifa_next;
+
+       /*
+        * If we find an AF_LINK type entry, we will fill
         * in the hardware address for this interface.
         * in the hardware address for this interface.
-         */
-        if ((ifa != 0) && (ifa->ifa_addr != 0)) {
-                /*
-                 * Fill in the link level address for this interface
-                 */
-                sdl = (struct sockaddr_dl *)ifa->ifa_addr;
-                sdl->sdl_type = IFT_ETHER;
-                sdl->sdl_alen = ETHER_ADDR_LEN;
-                sdl->sdl_slen = 0;
-                bcopy(is->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
-        }
+        */
+
+       if ((ifa != 0) && (ifa->ifa_addr != 0)) {
+
+               /*
+                * Fill in the link level address for this interface
+                */
+
+               sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+               sdl->sdl_type = IFT_ETHER;
+               sdl->sdl_alen = ETHER_ADDR_LEN;
+               sdl->sdl_slen = 0;
+               bcopy(is->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
+       }
 
        printf ("is%d: address %s\n", unit,
                ether_sprintf(is->arpcom.ac_enaddr)) ;
 
        printf ("is%d: address %s\n", unit,
                ether_sprintf(is->arpcom.ac_enaddr)) ;
+       printf("%s, %s\n",ic_type[is->ic_type],card_type[is->card_type]);
 
 #if NBPFILTER > 0
 
 #if NBPFILTER > 0
-        bpfattach(&is->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
+       bpfattach(&is->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
 #endif
 #endif
+       return 1;
 }
 
 }
 
-int
+static void
 is_watchdog(unit)
         int unit;
 {
         log(LOG_ERR, "is%d: device timeout\n", unit);
 is_watchdog(unit)
         int unit;
 {
         log(LOG_ERR, "is%d: device timeout\n", unit);
-
-        is_reset(unit);
+        is_reset(unit, 0);
 }
 
 
 /* Lance initialisation block set up */
 }
 
 
 /* Lance initialisation block set up */
+void
 init_mem(unit)
        int unit;
 {
        int i;
 init_mem(unit)
        int unit;
 {
        int i;
-       u_long temp;
+       void *temp;
        struct is_softc *is = &is_softc[unit];
 
        struct is_softc *is = &is_softc[unit];
 
-       /* Allocate memory */
-/* Temporary hack, will use kmem_alloc in future */
-#define MAXMEM ((NRBUF+NTBUF)*(BUFSIZE) + (NRBUF+NTBUF)*sizeof(struct mds) + 8)
-static u_char lance_mem[NIS][MAXMEM];
+       /*
+        * At this point we assume that the
+        * memory allocated to the Lance is
+        * quadword aligned. If it isn't
+        * then the initialisation is going
+        * fail later on.
+        */
 
 
 
 
-       /* Align message descriptors on quad word boundary 
-               (this is essential) */
+       /* 
+        * Set up lance initialisation block
+        */
 
 
-       temp = (u_long) &lance_mem[unit];
-       temp = (temp+8) - (temp%8);
+       temp = (void *)is->init_block;
+       temp += sizeof(struct init_block);
        is->rd = (struct mds *) temp;
        is->td = (struct mds *) (temp + (NRBUF*sizeof(struct mds)));
        temp += (NRBUF+NTBUF) * sizeof(struct mds);
 
        is->rd = (struct mds *) temp;
        is->td = (struct mds *) (temp + (NRBUF*sizeof(struct mds)));
        temp += (NRBUF+NTBUF) * sizeof(struct mds);
 
-       init_block[unit].mode = 0;
-       
+       is->init_block->mode = 0;
+       for (i=0; i<ETHER_ADDR_LEN; i++) 
+               is->init_block->padr[i] = is->arpcom.ac_enaddr[i];
+       for (i = 0; i < 8; ++i)
+               is->init_block->ladrf[i] = MULTI_INIT_ADDR;
+       is->init_block->rdra = kvtop(is->rd);
+       is->init_block->rlen = ((kvtop(is->rd) >> 16) & 0xff) | (RLEN<<13);
+       is->init_block->tdra = kvtop(is->td);
+       is->init_block->tlen = ((kvtop(is->td) >> 16) & 0xff) | (TLEN<<13);
 
 
 
 
-       init_block[unit].rdra = kvtop(is->rd);
-       init_block[unit].rlen = ((kvtop(is->rd) >> 16) & 0xff) | (RLEN<<13);
-       init_block[unit].tdra = kvtop(is->td);
-       init_block[unit].tlen = ((kvtop(is->td) >> 16) & 0xff) | (TLEN<<13);
+       /* 
+        * Set up receive ring descriptors
+        */
 
 
-       /* Set up receive ring descriptors */
        is->rbuf = (unsigned char *)temp;
        for (i=0; i<NRBUF; i++) {
                (is->rd+i)->addr = kvtop(temp);
        is->rbuf = (unsigned char *)temp;
        for (i=0; i<NRBUF; i++) {
                (is->rd+i)->addr = kvtop(temp);
@@ -291,11 +450,11 @@ static u_char lance_mem[NIS][MAXMEM];
                temp += BUFSIZE;
        }
 
                temp += BUFSIZE;
        }
 
-       /* Set up transmit ring descriptors */
+       /* 
+        * Set up transmit ring descriptors
+        */
+
        is->tbuf = (unsigned char *)temp;
        is->tbuf = (unsigned char *)temp;
-#if ISDEBUG > 4
-       printf("rd = %x,td = %x, rbuf = %x, tbuf = %x,td+1=%x\n",is->rd,is->td,is->rbuf,is->tbuf,is->td+1);
-#endif
        for (i=0; i<NTBUF; i++) {
                (is->td+i)->addr = kvtop(temp);
                (is->td+i)->flags= ((kvtop(temp) >> 16) & 0xff);
        for (i=0; i<NTBUF; i++) {
                (is->td+i)->addr = kvtop(temp);
                (is->td+i)->flags= ((kvtop(temp) >> 16) & 0xff);
@@ -310,6 +469,8 @@ static u_char lance_mem[NIS][MAXMEM];
  * Initialization of interface; set up initialization block
  * and transmit/receive descriptor rings.
  */
  * Initialization of interface; set up initialization block
  * and transmit/receive descriptor rings.
  */
+
+static void
 is_init(unit)
        int unit;
 {
 is_init(unit)
        int unit;
 {
@@ -322,34 +483,25 @@ is_init(unit)
        if (ifp->if_addrlist == (struct ifaddr *)0) return;
 
        s = splnet();
        if (ifp->if_addrlist == (struct ifaddr *)0) return;
 
        s = splnet();
-       is->last_rd = is->last_td = is->no_td = 0;
 
 
-       /* Set up lance's memory area */
-       init_mem(unit);
-
-       /* Stop Lance to get access to other registers */
+       /* 
+        * Lance must be stopped
+        * to access registers.
+        */
        iswrcsr(unit,0,STOP);
 
        iswrcsr(unit,0,STOP);
 
-       /* Get ethernet address */
-       for (i=0; i<ETHER_ADDR_LEN; i++) 
-               init_block[unit].padr[i] = is->arpcom.ac_enaddr[i];
-
-#if NBPFILTER > 0
-        /*
-         * Initialize multicast address hashing registers to accept
-         *       all multicasts (only used when in promiscuous mode)
-         */
-        for (i = 0; i < 8; ++i)
-               init_block[unit].ladrf[i] = 0xff;
-#endif
+       is->last_rd = is->last_td = is->no_td = 0;
 
 
+       /* Set up lance's memory area */
+       init_mem(unit);
 
 
-       /* I wish I knew what this was */
+       /* No byte swapping etc */
        iswrcsr(unit,3,0);
 
        /* Give lance the physical address of its memory area */
        iswrcsr(unit,3,0);
 
        /* Give lance the physical address of its memory area */
-       iswrcsr(unit,1,kvtop(&init_block[unit]));
-       iswrcsr(unit,2,(kvtop(&init_block[unit]) >> 16) & 0xff);
+       iswrcsr(unit,1,kvtop(is->init_block));
+       iswrcsr(unit,2,(kvtop(is->init_block) >> 16) & 0xff);
 
        /* OK, let's try and initialise the Lance */
        iswrcsr(unit,0,INIT);
 
        /* OK, let's try and initialise the Lance */
        iswrcsr(unit,0,INIT);
@@ -379,6 +531,7 @@ is_init(unit)
  * and map it to the interface before starting the output.
  * called only at splimp or interrupt level.
  */
  * and map it to the interface before starting the output.
  * called only at splimp or interrupt level.
  */
+static void
 is_start(ifp)
        struct ifnet *ifp;
 {
 is_start(ifp)
        struct ifnet *ifp;
 {
@@ -457,7 +610,7 @@ is_start(ifp)
 
                         /* copy trailer_header into a data structure */
                         m_copydata(m0, off, sizeof(struct trailer_header),
 
                         /* copy trailer_header into a data structure */
                         m_copydata(m0, off, sizeof(struct trailer_header),
-                                &trailer_header.ether_type);
+                                (caddr_t)&trailer_header.ether_type);
 
                         /* copy residual data */
                        resid = trailer_header.ether_residual -
 
                         /* copy residual data */
                        resid = trailer_header.ether_residual -
@@ -492,8 +645,9 @@ is_start(ifp)
                cdm->flags |= (OWN|STP|ENP);
                cdm->bcnt = -len;
                cdm->mcnt = 0;
                cdm->flags |= (OWN|STP|ENP);
                cdm->bcnt = -len;
                cdm->mcnt = 0;
-#if ISDEBUG > 3
-               xmit_print(unit,is->last_td);
+#ifdef ISDEBUG
+               if (is->is_debug)
+                       xmit_print(unit,is->last_td);
 #endif
                
                iswrcsr(unit,0,TDMD|INEA);
 #endif
                
                iswrcsr(unit,0,TDMD|INEA);
@@ -502,17 +656,19 @@ is_start(ifp)
                }while(++is->no_td < NTBUF);
                is->no_td = NTBUF;
                is->arpcom.ac_if.if_flags |= IFF_OACTIVE;       
                }while(++is->no_td < NTBUF);
                is->no_td = NTBUF;
                is->arpcom.ac_if.if_flags |= IFF_OACTIVE;       
-#if ISDEBUG >4
-       printf("no_td = %x, last_td = %x\n",is->no_td, is->last_td);
+#ifdef ISDEBUG
+               if (is->is_debug)       
+                       printf("no_td = %x, last_td = %x\n",is->no_td, is->last_td);
 #endif
 #endif
-               return(0);      
 }
 
 
 /*
  * Controller interrupt.
  */
 }
 
 
 /*
  * Controller interrupt.
  */
+void
 isintr(unit)
 isintr(unit)
+       int unit;
 {
        register struct is_softc *is = &is_softc[unit];
        u_short isr;
 {
        register struct is_softc *is = &is_softc[unit];
        u_short isr;
@@ -538,14 +694,14 @@ isintr(unit)
                if (!(isr&RXON)) {
                        printf("is%d: !(isr&RXON)\n", unit);
                        is->arpcom.ac_if.if_ierrors++;
                if (!(isr&RXON)) {
                        printf("is%d: !(isr&RXON)\n", unit);
                        is->arpcom.ac_if.if_ierrors++;
-                       is_reset(unit);
-                       return(1);
+                       is_reset(unit, 0);
+                       return;
                }
                if (!(isr&TXON)) {
                        printf("is%d: !(isr&TXON)\n", unit);
                        is->arpcom.ac_if.if_oerrors++;
                }
                if (!(isr&TXON)) {
                        printf("is%d: !(isr&TXON)\n", unit);
                        is->arpcom.ac_if.if_oerrors++;
-                       is_reset(unit);
-                       return(1);
+                       is_reset(unit, 0);
+                       return;
                }
 
                if (isr&RINT) {
                }
 
                if (isr&RINT) {
@@ -562,6 +718,7 @@ isintr(unit)
        }
 }
 
        }
 }
 
+static void
 istint(unit) 
        int unit;
 {
 istint(unit) 
        int unit;
 {
@@ -575,8 +732,9 @@ istint(unit)
                if ((i=is->last_td - is->no_td) < 0)
                        i+=NTBUF;
                cdm = (is->td+i);
                if ((i=is->last_td - is->no_td) < 0)
                        i+=NTBUF;
                cdm = (is->td+i);
-#if ISDEBUG >4
-       printf("Trans cdm = %x\n",cdm);
+#ifdef ISDEBUG
+       if (is->is_debug)
+               printf("Trans cdm = %x\n",cdm);
 #endif
                if (cdm->flags&OWN) {
                        if (loopcount)
 #endif
                if (cdm->flags&OWN) {
                        if (loopcount)
@@ -632,13 +790,14 @@ static inline void is_rint(int unit)
                        is->last_rd = rmd;
                        printf("is%d: Chained buffer\n",unit);
                        if ((cdm->flags & (OWN|ERR|STP|ENP)) != ENP) {
                        is->last_rd = rmd;
                        printf("is%d: Chained buffer\n",unit);
                        if ((cdm->flags & (OWN|ERR|STP|ENP)) != ENP) {
-                               is_reset(unit);
+                               is_reset(unit, 0);
                                return;
                        }
                }else
                        {
                                return;
                        }
                }else
                        {
-#if ISDEBUG >2
-       recv_print(unit,is->last_rd);
+#ifdef ISDEBUG
+                       if (is->is_debug)
+                               recv_print(unit,is->last_rd);
 #endif
                        isread(is,is->rbuf+(BUFSIZE*rmd),(int)cdm->mcnt);
                        is->arpcom.ac_if.if_ipackets++;
 #endif
                        isread(is,is->rbuf+(BUFSIZE*rmd),(int)cdm->mcnt);
                        is->arpcom.ac_if.if_ipackets++;
@@ -647,8 +806,9 @@ static inline void is_rint(int unit)
                cdm->flags |= OWN;
                cdm->mcnt = 0;
                NEXTRDS;
                cdm->flags |= OWN;
                cdm->mcnt = 0;
                NEXTRDS;
-#if ISDEBUG >4
-       printf("is->last_rd = %x, cdm = %x\n",is->last_rd,cdm);
+#ifdef ISDEBUG
+               if (is->is_debug)
+                       printf("is->last_rd = %x, cdm = %x\n",is->last_rd,cdm);
 #endif
        } /* while */
        is->last_rd = rmd;
 #endif
        } /* while */
        is->last_rd = rmd;
@@ -694,7 +854,6 @@ isread(struct is_softc *is, unsigned char *buf, int len)
          * information to be at the front, but we still have to drop
          * the type and length which are at the front of any trailer data.
          */
          * information to be at the front, but we still have to drop
          * the type and length which are at the front of any trailer data.
          */
-        is->arpcom.ac_if.if_ipackets++;
         m = isget(buf, len, off, &is->arpcom.ac_if);
         if (m == 0) return;
 #if NBPFILTER > 0
         m = isget(buf, len, off, &is->arpcom.ac_if);
         if (m == 0) return;
 #if NBPFILTER > 0
@@ -812,6 +971,7 @@ isget(buf, totlen, off0, ifp)
 /*
  * Process an ioctl request.
  */
 /*
  * Process an ioctl request.
  */
+int
 is_ioctl(ifp, cmd, data)
        register struct ifnet *ifp;
        int cmd;
 is_ioctl(ifp, cmd, data)
        register struct ifnet *ifp;
        int cmd;
@@ -892,7 +1052,13 @@ is_ioctl(ifp, cmd, data)
                        if ((ifp->if_flags & IFF_UP) &&
                                (ifp->if_flags & IFF_RUNNING) == 0)
                        is_init(ifp->if_unit);
                        if ((ifp->if_flags & IFF_UP) &&
                                (ifp->if_flags & IFF_RUNNING) == 0)
                        is_init(ifp->if_unit);
-                }
+               }
+#ifdef ISDEBUG
+               if (ifp->if_flags & IFF_DEBUG)
+                       is->is_debug = 1;
+               else
+                       is->is_debug = 0;
+#endif
 #if NBPFILTER > 0
                 if (ifp->if_flags & IFF_PROMISC) {
                         /*
 #if NBPFILTER > 0
                 if (ifp->if_flags & IFF_PROMISC) {
                         /*
@@ -902,7 +1068,7 @@ is_ioctl(ifp, cmd, data)
                          *              hashing array. For now we assume that
                          *              this was done in is_init().
                          */
                          *              hashing array. For now we assume that
                          *              this was done in is_init().
                          */
-                        init_block[unit].mode = PROM;  
+                        is->init_block->mode = PROM;   
                 } else
                         /*
                          * XXX - for multicasts to work, we would need to
                 } else
                         /*
                          * XXX - for multicasts to work, we would need to
@@ -927,6 +1093,8 @@ is_ioctl(ifp, cmd, data)
        return (error);
 }
 
        return (error);
 }
 
+#ifdef ISDEBUG
+void
 recv_print(unit,no)
        int unit,no;
 {
 recv_print(unit,no)
        int unit,no;
 {
@@ -948,7 +1116,8 @@ recv_print(unit,no)
        if (printed)
                printf("\n");
 }
        if (printed)
                printf("\n");
 }
-               
+
+void
 xmit_print(unit,no)
        int unit,no;
 {
 xmit_print(unit,no)
        int unit,no;
 {
@@ -973,5 +1142,6 @@ xmit_print(unit,no)
        if (printed)
                printf("\n");
 }
        if (printed)
                printf("\n");
 }
+#endif /* ISDEBUG */
                
                
-#endif
+#endif /* NIS > 0 */