Second beta release of device driver for SMC/WD 80x3 ethernet boards +
authorDavid Greenman <davidg@Root.COM>
Wed, 23 Jun 1993 16:22:04 +0000 (16:22 +0000)
committerDavid Greenman <davidg@Root.COM>
Wed, 23 Jun 1993 16:22:04 +0000 (16:22 +0000)
some additional comments.

sys/i386/isa/if_ed.c
sys/i386/isa/if_edreg.h

index ec1d682..697e4d0 100644 (file)
  * Modification history
  *
  * $Log:       if_ed.c,v $
  * Modification history
  *
  * $Log:       if_ed.c,v $
+ * Revision 1.9  93/06/23  03:48:14  davidg
+ * fixed minor typo introduced when cleaning up probe routine
+ * 
+ * Revision 1.8  93/06/23  03:37:19  davidg
+ * cleaned up/added some comments. Also improved readability of a part of
+ * the probe routine.
+ * 
  * Revision 1.7  93/06/22  04:45:01  davidg
  * (no additional changes) Second beta release
  * 
  * Revision 1.7  93/06/22  04:45:01  davidg
  * (no additional changes) Second beta release
  * 
@@ -286,16 +293,31 @@ type_WD80x3:
        for (i=0; i<8; i++)
                printf("%x -> %x\n", i, inb(sc->asic_addr + i));
 #endif
        for (i=0; i<8; i++)
                printf("%x -> %x\n", i, inb(sc->asic_addr + i));
 #endif
-
+       /*
+        * Check 83C584 interrupt configuration register if this board has one
+        *      XXX - we could also check the IO address register. But why
+        *              bother...if we get past this, it *has* to be correct.
+        */
        if (sc->type & ED_WD_SOFTCONFIG) {
        if (sc->type & ED_WD_SOFTCONFIG) {
-               iptr = inb(isa_dev->id_iobase + 1) & 4 |
-                       ((inb(isa_dev->id_iobase+4) & 0x60) >> 5);
+               /*
+                * Assemble together the encoded interrupt number.
+                */
+               iptr = (inb(isa_dev->id_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
+                       ((inb(isa_dev->id_iobase + ED_WD_IRR) &
+                               (ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5);
+               /*
+                * Translate it using translation table, and check for correctness.
+                */
                if (ed_intr_mask[iptr] != isa_dev->id_irq) {
                        printf("ed%d: kernel configured irq doesn't match board configured irq\n",
                                isa_dev->id_unit);
                        return(0);
                }
                if (ed_intr_mask[iptr] != isa_dev->id_irq) {
                        printf("ed%d: kernel configured irq doesn't match board configured irq\n",
                                isa_dev->id_unit);
                        return(0);
                }
-               outb(isa_dev->id_iobase+4, inb(isa_dev->id_iobase+4) | 0x80);
+               /*
+                * Enable the interrupt.
+                */
+               outb(isa_dev->id_iobase + ED_WD_IRR,
+                       inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
        }
 
        sc->memwidth = memwidth;
        }
 
        sc->memwidth = memwidth;
@@ -659,6 +681,9 @@ ed_attach(isa_dev)
        else
                ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS);
 
        else
                ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS);
 
+       /*
+        * Attach the interface
+        */
        if_attach(ifp);
 
 #if NBPFILTER > 0
        if_attach(ifp);
 
 #if NBPFILTER > 0
@@ -672,9 +697,10 @@ ed_attach(isa_dev)
        while ((ifa != 0) && (ifa->ifa_addr != 0) &&
            (ifa->ifa_addr->sa_family != AF_LINK))
                ifa = ifa->ifa_next;
        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 fill in the hardware address
+        * If we find an AF_LINK type entry we fill in the hardware address.
+        *      This is useful for netstat(1) to keep track of which interface
+        *      is which.
         */
        if ((ifa != 0) && (ifa->ifa_addr != 0)) {
                /*
         */
        if ((ifa != 0) && (ifa->ifa_addr != 0)) {
                /*
@@ -742,6 +768,10 @@ ed_stop(unit)
        }
 }
 
        }
 }
 
+/*
+ * Device timeout/watchdog routine. Entered if the device neglects to
+ *     generate an interrupt after a transmit has been started on it.
+ */
 int
 ed_watchdog(unit)
        int unit;
 int
 ed_watchdog(unit)
        int unit;
@@ -904,6 +934,9 @@ ed_init(unit)
        (void) splx(s);
 }
  
        (void) splx(s);
 }
  
+/*
+ * This routine actually starts the transmission on the interface
+ */
 static inline void ed_xmit(ifp)
        struct ifnet *ifp;
 {
 static inline void ed_xmit(ifp)
        struct ifnet *ifp;
 {
@@ -928,13 +961,16 @@ static inline void ed_xmit(ifp)
        outb(sc->nic_addr + ED_P0_TBCR1, len >> 8);
 
        /*
        outb(sc->nic_addr + ED_P0_TBCR1, len >> 8);
 
        /*
-        * Set page 0, Remote DMA complete, Transmit Packet, and Start
+        * Set page 0, Remote DMA complete, Transmit Packet, and *Start*
         */
        outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_TXP|ED_CR_STA);
 
        sc->xmit_busy = 1;
        sc->data_buffered = 0;
        
         */
        outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_TXP|ED_CR_STA);
 
        sc->xmit_busy = 1;
        sc->data_buffered = 0;
        
+       /*
+        * Switch buffers if we are doing double-buffered transmits
+        */
        if ((sc->txb_next == 0) && (sc->txb_cnt > 1)) 
                sc->txb_next = 1;
        else
        if ((sc->txb_next == 0) && (sc->txb_cnt > 1)) 
                sc->txb_next = 1;
        else
@@ -966,14 +1002,24 @@ ed_start(ifp)
        u_char laar_tmp;
 
 outloop:
        u_char laar_tmp;
 
 outloop:
+       /*
+        * See if there is room to send more data (i.e. one or both of the
+        *      buffers is empty).
+        */
        if (sc->data_buffered)
                if (sc->xmit_busy) {
        if (sc->data_buffered)
                if (sc->xmit_busy) {
+                       /*
+                        * No room. Indicate this to the outside world
+                        *      and exit.
+                        */
                        ifp->if_flags |= IFF_OACTIVE;
                        return;
                } else {
                        /*
                        ifp->if_flags |= IFF_OACTIVE;
                        return;
                } else {
                        /*
+                        * Data is buffered, but we're not transmitting, so
+                        *      start the xmit on the buffered data.
                         * Note that ed_xmit() resets the data_buffered flag
                         * Note that ed_xmit() resets the data_buffered flag
-                        *  before returning
+                        *      before returning.
                         */
                        ed_xmit(ifp);
                }
                         */
                        ed_xmit(ifp);
                }
@@ -1104,6 +1150,10 @@ outloop:
 
        m_freem(m0);
 
 
        m_freem(m0);
 
+       /*
+        * If we are doing double-buffering, a buffer might be free to
+        *      fill with another packet, so loop back to the top.
+        */
        if (sc->txb_cnt > 1)
                goto outloop;
        else {
        if (sc->txb_cnt > 1)
                goto outloop;
        else {
@@ -1260,7 +1310,7 @@ edintr(unit)
                        sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
 
                        /*
                        sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
 
                        /*
-                        * reset watchdog timer
+                        * clear watchdog timer
                         */
                        sc->arpcom.ac_if.if_timer = 0;
                }
                         */
                        sc->arpcom.ac_if.if_timer = 0;
                }
@@ -1310,7 +1360,7 @@ edintr(unit)
                        sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
 
                        /*
                        sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
 
                        /*
-                        * reset watchdog timer
+                        * clear watchdog timer
                         */
                        sc->arpcom.ac_if.if_timer = 0;
 
                         */
                        sc->arpcom.ac_if.if_timer = 0;
 
@@ -1698,9 +1748,15 @@ ed_ring_to_mbuf(sc,src,dst,total_len)
 
                if (amount == 0) { /* no more data in this mbuf, alloc another */
                        /*
 
                if (amount == 0) { /* no more data in this mbuf, alloc another */
                        /*
-                        * if there is enough data for an mbuf cluster, attempt
-                        * to allocate one of those, otherwise, a regular mbuf
-                        * will do.
+                        * If there is enough data for an mbuf cluster, attempt
+                        *      to allocate one of those, otherwise, a regular
+                        *      mbuf will do.
+                        * Note that a regular mbuf is always required, even if
+                        *      we get a cluster - getting a cluster does not
+                        *      allocate any mbufs, and one is needed to assign
+                        *      the cluster to. The mbuf that has a cluster
+                        *      extension can not be used to contain data - only
+                        *      the cluster can contain data.
                         */ 
                        dst = m;
                        MGET(m, M_DONTWAIT, MT_DATA);
                         */ 
                        dst = m;
                        MGET(m, M_DONTWAIT, MT_DATA);
index a202848..f44ea59 100644 (file)
@@ -1,5 +1,14 @@
 /*
  * National Semiconductor DS8390 NIC register definitions 
 /*
  * National Semiconductor DS8390 NIC register definitions 
+ *
+ * $Log:       if_edreg.h,v $
+ * Revision 1.2  93/06/23  03:03:05  davidg
+ * added some additional definitions for the 83C584 bus interface
+ * chip (SMC/WD boards)
+ * 
+ * Revision 1.1  93/06/23  03:01:07  davidg
+ * Initial revision
+ * 
  */
 
 /*
  */
 
 /*
@@ -573,13 +582,23 @@ struct ed_ring    {
 
 #define ED_WD_ICR_16BIT        0x01    /* 16-bit interface */
 #define ED_WD_ICR_OAR  0x02    /* select register. 0=BIO 1=EAR */
 
 #define ED_WD_ICR_16BIT        0x01    /* 16-bit interface */
 #define ED_WD_ICR_OAR  0x02    /* select register. 0=BIO 1=EAR */
-#define ED_WD_ICR_IR2  0x04    /* select second set of IRQs */
+#define ED_WD_ICR_IR2  0x04    /* high order bit of encoded IRQ */
 #define ED_WD_ICR_MSZ  0x08    /* memory size (0=8k 1=32k) */
 #define ED_WD_ICR_RLA  0x10    /* recall LAN address */
 #define ED_WD_ICR_RX7  0x20    /* recall all but i/o and LAN address */
 #define        ED_WD_ICR_RIO   0x40    /* recall i/o address */
 #define ED_WD_ICR_STO  0x80    /* store to non-volatile memory */
 
 #define ED_WD_ICR_MSZ  0x08    /* memory size (0=8k 1=32k) */
 #define ED_WD_ICR_RLA  0x10    /* recall LAN address */
 #define ED_WD_ICR_RX7  0x20    /* recall all but i/o and LAN address */
 #define        ED_WD_ICR_RIO   0x40    /* recall i/o address */
 #define ED_WD_ICR_STO  0x80    /* store to non-volatile memory */
 
+/*
+ * IO Address Register (IAR)
+ */
+#define ED_WD_IAR      2
+
+/*
+ * EEROM Address Register
+ */
+#define ED_WD_EAR      3
+
 /*
  * Interrupt Request Register (IRR)
  */
 /*
  * Interrupt Request Register (IRR)
  */
@@ -590,6 +609,22 @@ struct ed_ring     {
 #define ED_WD_IRR_OUT2 0x04    /* WD83C584 pin 2 output */
 #define ED_WD_IRR_OUT3 0x08    /* WD83C584 pin 3 output */
 #define ED_WD_IRR_FLASH        0x10    /* Flash RAM is in the ROM socket */
 #define ED_WD_IRR_OUT2 0x04    /* WD83C584 pin 2 output */
 #define ED_WD_IRR_OUT3 0x08    /* WD83C584 pin 3 output */
 #define ED_WD_IRR_FLASH        0x10    /* Flash RAM is in the ROM socket */
+
+/*
+ * The three bit of the encoded IRQ are decoded as follows:
+ *
+ *     IR2 IR1 IR0     IRQ
+ *      0   0   0       2/9
+ *      0   0   1       3
+ *      0   1   0       5
+ *      0   1   1       7
+ *      1   0   0       10
+ *      1   0   1       11
+ *      1   1   0       15
+ *      1   1   1       4
+ */
+#define ED_WD_IRR_IR0  0x20    /* bit 0 of encoded IRQ */
+#define ED_WD_IRR_IR1  0x40    /* bit 1 of encoded IRQ */
 #define ED_WD_IRR_IEN  0x80    /* Interrupt enable */
 
 /*
 #define ED_WD_IRR_IEN  0x80    /* Interrupt enable */
 
 /*