This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.1'.
[unix-history] / sys / i386 / isa / if_ed.c
index 70aeac2..ffda077 100644 (file)
  *   the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000,
  *   and a variety of similar clones.
  *
  *   the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000,
  *   and a variety of similar clones.
  *
- * Thanks to Charles Hannum for proving to me with example code that the
- *     NE1000/2000 support could be added with minimal impact. Without
- *     this, I wouldn't have proceeded in this direction.
- *     
  */
 
 /*
  */
 
 /*
- * $Id: if_ed.c,v 1.27 1994/01/03 17:17:19 davidg Exp $
+ * $Id: if_ed.c,v 1.33.2.1 1994/03/07 02:02:34 rgrimes Exp $
  */
 
 #include "ed.h"
  */
 
 #include "ed.h"
@@ -39,7 +35,6 @@
 #include "net/if.h"
 #include "net/if_dl.h"
 #include "net/if_types.h"
 #include "net/if.h"
 #include "net/if_dl.h"
 #include "net/if_types.h"
-#include "net/netisr.h"
 
 #ifdef INET
 #include "netinet/in.h"
 
 #ifdef INET
 #include "netinet/in.h"
@@ -165,8 +160,8 @@ static unsigned short ed_790_intr_mask[] = {
        0,
        IRQ9,
        IRQ3,
        0,
        IRQ9,
        IRQ3,
-       IRQ4,
        IRQ5,
        IRQ5,
+       IRQ7,
        IRQ10,
        IRQ11,
        IRQ15
        IRQ10,
        IRQ11,
        IRQ15
@@ -258,7 +253,7 @@ ed_probe_WD80x3(isa_dev)
        sc->is790 = 0;
 
 #ifdef TOSH_ETHER
        sc->is790 = 0;
 
 #ifdef TOSH_ETHER
-       outb(sc->asic_addr + ED_WD_MSR, 0x2); /* set the power enable bit */
+       outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_POW);
        DELAY(10000);
 #endif
        /*
        DELAY(10000);
 #endif
        /*
@@ -283,7 +278,7 @@ ed_probe_WD80x3(isa_dev)
 
        /* reset card to force it into a known state. */
 #ifdef TOSH_ETHER
 
        /* reset card to force it into a known state. */
 #ifdef TOSH_ETHER
-       outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST | 0x2);
+       outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST | ED_WD_MSR_POW);
 #else
        outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST);
 #endif
 #else
        outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST);
 #endif
@@ -298,16 +293,20 @@ ed_probe_WD80x3(isa_dev)
        /*
         * Set initial values for width/size.
         */
        /*
         * Set initial values for width/size.
         */
+       memsize = 8192;
+       isa16bit = 0;
        switch (sc->type) {
        case ED_TYPE_WD8003S:
                sc->type_str = "WD8003S";
        switch (sc->type) {
        case ED_TYPE_WD8003S:
                sc->type_str = "WD8003S";
-               memsize = 8192;
-               isa16bit = 0;
                break;
        case ED_TYPE_WD8003E:
                sc->type_str = "WD8003E";
                break;
        case ED_TYPE_WD8003E:
                sc->type_str = "WD8003E";
-               memsize = 8192;
-               isa16bit = 0;
+               break;
+       case ED_TYPE_WD8003EB:
+               sc->type_str = "WD8003EB";
+               break;
+       case ED_TYPE_WD8003W:
+               sc->type_str = "WD8003W";
                break;
        case ED_TYPE_WD8013EBT:
                sc->type_str = "WD8013EBT";
                break;
        case ED_TYPE_WD8013EBT:
                sc->type_str = "WD8013EBT";
@@ -326,8 +325,6 @@ ed_probe_WD80x3(isa_dev)
                        memsize = 16384;
                        sc->type_str = "WD8013EP";
                } else {
                        memsize = 16384;
                        sc->type_str = "WD8013EP";
                } else {
-                       isa16bit = 0;
-                       memsize = 8192;
                        sc->type_str = "WD8003EP";
                }
                break;
                        sc->type_str = "WD8003EP";
                }
                break;
@@ -364,16 +361,14 @@ ed_probe_WD80x3(isa_dev)
                memsize = 32768;
                isa16bit = 1;
                break;
                memsize = 32768;
                isa16bit = 1;
                break;
-       case ED_TYPE_TOSHIBA2:
-               sc->type_str = "Toshiba2";
+       case ED_TYPE_TOSHIBA4:
+               sc->type_str = "Toshiba4";
                memsize = 32768;
                isa16bit = 1;
                break;
 #endif
        default:
                sc->type_str = "";
                memsize = 32768;
                isa16bit = 1;
                break;
 #endif
        default:
                sc->type_str = "";
-               memsize = 8192;
-               isa16bit = 0;
                break;
        }
        /*
                break;
        }
        /*
@@ -382,7 +377,7 @@ ed_probe_WD80x3(isa_dev)
         */
        if (isa16bit && (sc->type != ED_TYPE_WD8013EBT)
 #ifdef TOSH_ETHER
         */
        if (isa16bit && (sc->type != ED_TYPE_WD8013EBT)
 #ifdef TOSH_ETHER
-           && (sc->type != ED_TYPE_TOSHIBA1) && (sc->type != ED_TYPE_TOSHIBA2)
+           && (sc->type != ED_TYPE_TOSHIBA1) && (sc->type != ED_TYPE_TOSHIBA4)
 #endif
            && ((inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) {
                isa16bit = 0;
 #endif
            && ((inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) {
                isa16bit = 0;
@@ -419,14 +414,15 @@ ed_probe_WD80x3(isa_dev)
                 * Assemble together the encoded interrupt number.
                 */
                iptr = (inb(isa_dev->id_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
                 * 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);
+                           ((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 %d doesn't match board configured irq %d\n",
                /*
                 * Translate it using translation table, and check for correctness.
                 */
                if (ed_intr_mask[iptr] != isa_dev->id_irq) {
                        printf("ed%d: kernel configured irq %d doesn't match board configured irq %d\n",
-                               isa_dev->id_unit, ffs(isa_dev->id_irq) - 1, ffs(ed_intr_mask[iptr]) - 1);
+                           isa_dev->id_unit, ffs(isa_dev->id_irq) - 1,
+                           ffs(ed_intr_mask[iptr]) - 1);
                        return(0);
                }
                /*
                        return(0);
                }
                /*
@@ -436,17 +432,25 @@ ed_probe_WD80x3(isa_dev)
                        inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
        }
        if (sc->is790) {
                        inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
        }
        if (sc->is790) {
-               outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04) | 0x80);
-               iptr = ((inb(isa_dev->id_iobase + 0x0d) & 0x0c ) >> 2) | 
-                       ((inb(isa_dev->id_iobase + 0x0d) & 0x40) >> 4);
-               outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04) & ~0x80);
+               outb(isa_dev->id_iobase + ED_WD790_HWR,
+                   inb(isa_dev->id_iobase + ED_WD790_HWR) | ED_WD790_HWR_SWH);
+               iptr = (((inb(isa_dev->id_iobase + ED_WD790_GCR) & ED_WD790_GCR_IR2) >> 4) |
+                           (inb(isa_dev->id_iobase + ED_WD790_GCR) &
+                           (ED_WD790_GCR_IR1|ED_WD790_GCR_IR0)) >> 2);
+               outb(isa_dev->id_iobase + ED_WD790_HWR,
+                   inb(isa_dev->id_iobase + ED_WD790_HWR) & ~ED_WD790_HWR_SWH);
 
                if (ed_790_intr_mask[iptr] != isa_dev->id_irq) {
                        printf("ed%d: kernel configured irq %d doesn't match board configured irq %d %d\n",
 
                if (ed_790_intr_mask[iptr] != isa_dev->id_irq) {
                        printf("ed%d: kernel configured irq %d doesn't match board configured irq %d %d\n",
-                               isa_dev->id_unit, ffs(isa_dev->id_irq) - 1, ffs(ed_790_intr_mask[iptr]) -1, iptr);
+                           isa_dev->id_unit, ffs(isa_dev->id_irq) - 1,
+                           ffs(ed_790_intr_mask[iptr]) - 1, iptr);
                        return 0;
                }
                        return 0;
                }
-               outb(isa_dev->id_iobase + 0x06, inb(isa_dev->id_iobase + 0x06) | 0x01);
+               /*
+                * Enable interrupts.
+                */
+               outb(isa_dev->id_iobase + ED_WD790_ICR,
+                   inb(isa_dev->id_iobase + ED_WD790_ICR) | ED_WD790_ICR_EIL);
        }
 
        sc->isa16bit = isa16bit;
        }
 
        sc->isa16bit = isa16bit;
@@ -501,7 +505,7 @@ ed_probe_WD80x3(isa_dev)
 #ifdef TOSH_ETHER
                        outb(sc->asic_addr + ED_WD_MSR + 1, ((kvtop(sc->mem_start) >> 8) & 0xe0) | 4);
                        outb(sc->asic_addr + ED_WD_MSR + 2, ((kvtop(sc->mem_start) >> 16) & 0x0f));
 #ifdef TOSH_ETHER
                        outb(sc->asic_addr + ED_WD_MSR + 1, ((kvtop(sc->mem_start) >> 8) & 0xe0) | 4);
                        outb(sc->asic_addr + ED_WD_MSR + 2, ((kvtop(sc->mem_start) >> 16) & 0x0f));
-                       outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB | 0x2);
+                       outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB | ED_WD_MSR_POW);
 
 #else
                        outb(sc->asic_addr + ED_WD_MSR, ((kvtop(sc->mem_start) >> 13) &
 
 #else
                        outb(sc->asic_addr + ED_WD_MSR, ((kvtop(sc->mem_start) >> 13) &
@@ -523,6 +527,7 @@ ed_probe_WD80x3(isa_dev)
                        if (sc->is790) {
                                sc->wd_laar_proto = inb(sc->asic_addr + ED_WD_LAAR);
                                outb(sc->asic_addr + ED_WD_LAAR, ED_WD_LAAR_M16EN);
                        if (sc->is790) {
                                sc->wd_laar_proto = inb(sc->asic_addr + ED_WD_LAAR);
                                outb(sc->asic_addr + ED_WD_LAAR, ED_WD_LAAR_M16EN);
+                               (void) inb(0x84);
                        } else {
                                outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
                                     ED_WD_LAAR_L16EN | ED_WD_LAAR_M16EN |
                        } else {
                                outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
                                     ED_WD_LAAR_L16EN | ED_WD_LAAR_M16EN |
@@ -531,7 +536,7 @@ ed_probe_WD80x3(isa_dev)
                } else  {
                        if ((sc->type & ED_WD_SOFTCONFIG) ||
 #ifdef TOSH_ETHER
                } else  {
                        if ((sc->type & ED_WD_SOFTCONFIG) ||
 #ifdef TOSH_ETHER
-                           (sc->type == ED_TYPE_TOSHIBA1) || (sc->type == ED_TYPE_TOSHIBA2) ||
+                           (sc->type == ED_TYPE_TOSHIBA1) || (sc->type == ED_TYPE_TOSHIBA4) ||
 #endif
                            (sc->type == ED_TYPE_WD8013EBT) && (!sc->is790)) {
                                outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
 #endif
                            (sc->type == ED_TYPE_WD8013EBT) && (!sc->is790)) {
                                outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
@@ -552,9 +557,11 @@ ed_probe_WD80x3(isa_dev)
                                /*
                                 * Disable 16 bit access to shared memory
                                 */
                                /*
                                 * Disable 16 bit access to shared memory
                                 */
-                               if (isa16bit)
+                               if (isa16bit) {
                                        outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto &=
                                             ~ED_WD_LAAR_M16EN));
                                        outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto &=
                                             ~ED_WD_LAAR_M16EN));
+                                       (void) inb(0x84);
+                               }
 
                                return(0);
                        }
 
                                return(0);
                        }
@@ -567,10 +574,11 @@ ed_probe_WD80x3(isa_dev)
                 *      memory. and 2) so that other 8 bit devices with shared
                 *      memory can be used in this 128k region, too.
                 */
                 *      memory. and 2) so that other 8 bit devices with shared
                 *      memory can be used in this 128k region, too.
                 */
-               if (isa16bit)
+               if (isa16bit) {
                        outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto &=
                             ~ED_WD_LAAR_M16EN));
                        outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto &=
                             ~ED_WD_LAAR_M16EN));
-
+                       (void) inb(0x84);
+               }
        }
 
        return (ED_WD_IO_PORTS);
        }
 
        return (ED_WD_IO_PORTS);
@@ -1067,7 +1075,7 @@ ed_attach(isa_dev)
        printf("%s ",sc->isa16bit ? "(16 bit)" : "(8 bit)");
 
        printf("%s\n", ((sc->vendor == ED_VENDOR_3COM) &&
        printf("%s ",sc->isa16bit ? "(16 bit)" : "(8 bit)");
 
        printf("%s\n", ((sc->vendor == ED_VENDOR_3COM) &&
-               (ifp->if_flags & IFF_ALTPHYS)) ? "tranceiver disabled" : "");
+               (ifp->if_flags & IFF_ALTPHYS)) ? " tranceiver disabled" : "");
 
        /*
         * If BPF is in the kernel, call the attach for it
 
        /*
         * If BPF is in the kernel, call the attach for it
@@ -1449,9 +1457,17 @@ outloop:
                         *      may cause a call-back to ed_start)
                         * XXX - the call-back to 'start' is a bug, IMHO.
                         */
                         *      may cause a call-back to ed_start)
                         * XXX - the call-back to 'start' is a bug, IMHO.
                         */
-                       case ED_VENDOR_WD_SMC:
+                       case ED_VENDOR_WD_SMC: {
                                outb(sc->asic_addr + ED_WD_LAAR,
                                    (sc->wd_laar_proto | ED_WD_LAAR_M16EN));
                                outb(sc->asic_addr + ED_WD_LAAR,
                                    (sc->wd_laar_proto | ED_WD_LAAR_M16EN));
+                               (void) inb(0x84);
+                               if (sc->is790) {
+                                       outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB);
+                                       (void) inb(0x84);
+                               }
+                               (void) inb(0x84);
+                               break;
+                           }
                        }
                }
 
                        }
                }
 
@@ -1470,9 +1486,15 @@ outloop:
                                outb(sc->asic_addr + ED_3COM_GACFR,
                                    ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
                                break;
                                outb(sc->asic_addr + ED_3COM_GACFR,
                                    ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
                                break;
-                       case ED_VENDOR_WD_SMC:
+                       case ED_VENDOR_WD_SMC: {
                                outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto);
                                outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto);
+                               (void) inb(0x84);
+                               if (sc->is790) {
+                                       outb(sc->asic_addr + ED_WD_MSR, 0x00);
+                                       (void) inb(0x84);
+                               }
                                break;
                                break;
+                           }
                        }
                }
        } else {
                        }
                }
        } else {
@@ -1828,6 +1850,12 @@ edintr(unit)
                                        outb(sc->asic_addr + ED_WD_LAAR,
                                             (sc->wd_laar_proto |=
                                             ED_WD_LAAR_M16EN));
                                        outb(sc->asic_addr + ED_WD_LAAR,
                                             (sc->wd_laar_proto |=
                                             ED_WD_LAAR_M16EN));
+                                       (void) inb(0x84);
+                                       if (sc->is790) {
+                                               outb(sc->asic_addr + ED_WD_MSR,
+                                                   ED_WD_MSR_MENB);
+                                               (void) inb(0x84);
+                                       }
                                }
 
                                ed_rint (unit);
                                }
 
                                ed_rint (unit);
@@ -1839,6 +1867,11 @@ edintr(unit)
                                        outb(sc->asic_addr + ED_WD_LAAR,
                                             (sc->wd_laar_proto &=
                                             ~ED_WD_LAAR_M16EN));
                                        outb(sc->asic_addr + ED_WD_LAAR,
                                             (sc->wd_laar_proto &=
                                             ~ED_WD_LAAR_M16EN));
+                                       (void) inb(0x84);
+                                       if (sc->is790) {
+                                               outb(sc->asic_addr + ED_WD_MSR, 0x00);
+                                               (void) inb(0x84);
+                                       }
                                }
                        }
                }
                                }
                        }
                }
@@ -1945,6 +1978,15 @@ ed_ioctl(ifp, command, data)
                }
                break;
 
                }
                break;
 
+       case SIOCGIFADDR:
+               {
+                       struct sockaddr *sa;
+                       sa = (struct sockaddr *)&ifr->ifr_data;
+                       bcopy((caddr_t)sc->arpcom.ac_enaddr,
+                           (caddr_t) sa->sa_data, ETHER_ADDR_LEN);
+               }
+               break;
+
        case SIOCSIFFLAGS:
                /*
                 * If interface is marked down and it is running, then stop it
        case SIOCSIFFLAGS:
                /*
                 * If interface is marked down and it is running, then stop it