Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev First crack at shared ROM/shared interrupts on 21040...



details:   https://anonhg.NetBSD.org/src/rev/e6a02a28d043
branches:  trunk
changeset: 476365:e6a02a28d043
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Tue Sep 14 22:25:48 1999 +0000

description:
First crack at shared ROM/shared interrupts on 21040 multi-port boards,
plus quirk identification for non-multiple-port boards.

diffstat:

 sys/dev/eisa/if_tlp_eisa.c |    4 +-
 sys/dev/ic/tulip.c         |    8 +-
 sys/dev/ic/tulipvar.h      |    5 +-
 sys/dev/pci/if_tlp_pci.c   |  322 +++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 309 insertions(+), 30 deletions(-)

diffs (truncated from 469 to 300 lines):

diff -r 8db5a2eff890 -r e6a02a28d043 sys/dev/eisa/if_tlp_eisa.c
--- a/sys/dev/eisa/if_tlp_eisa.c        Tue Sep 14 22:06:44 1999 +0000
+++ b/sys/dev/eisa/if_tlp_eisa.c        Tue Sep 14 22:25:48 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_tlp_eisa.c,v 1.1 1999/09/14 05:58:00 thorpej Exp $  */
+/*     $NetBSD: if_tlp_eisa.c,v 1.2 1999/09/14 22:25:48 thorpej Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -297,5 +297,5 @@
        /*
         * Finish off the attach.
         */
-       tlp_attach(sc, NULL, enaddr);
+       tlp_attach(sc, enaddr);
 }
diff -r 8db5a2eff890 -r e6a02a28d043 sys/dev/ic/tulip.c
--- a/sys/dev/ic/tulip.c        Tue Sep 14 22:06:44 1999 +0000
+++ b/sys/dev/ic/tulip.c        Tue Sep 14 22:25:48 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tulip.c,v 1.8 1999/09/14 05:52:21 thorpej Exp $        */
+/*     $NetBSD: tulip.c,v 1.9 1999/09/14 22:25:50 thorpej Exp $        */
 
 /*-
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -186,9 +186,8 @@
  *     Attach a Tulip interface to the system.
  */
 void
-tlp_attach(sc, name, enaddr)
+tlp_attach(sc, enaddr)
        struct tulip_softc *sc;
-       const char *name;
        const u_int8_t *enaddr;
 {
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
@@ -339,7 +338,8 @@
 
        /* Announce ourselves. */
        printf("%s: %s%sEthernet address %s\n", sc->sc_dev.dv_xname,
-           name != NULL ? name : "", name != NULL ? ", " : "",
+           sc->sc_name[0] != '\0' ? sc->sc_name : "",
+           sc->sc_name[0] != '\0' ? ", " : "",
            ether_sprintf(enaddr));
 
        /*
diff -r 8db5a2eff890 -r e6a02a28d043 sys/dev/ic/tulipvar.h
--- a/sys/dev/ic/tulipvar.h     Tue Sep 14 22:06:44 1999 +0000
+++ b/sys/dev/ic/tulipvar.h     Tue Sep 14 22:25:48 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tulipvar.h,v 1.8 1999/09/14 05:52:22 thorpej Exp $     */
+/*     $NetBSD: tulipvar.h,v 1.9 1999/09/14 22:25:50 thorpej Exp $     */
 
 /*-
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -231,6 +231,7 @@
        tulip_chip_t    sc_chip;        /* chip type */
        int             sc_rev;         /* chip revision */
        int             sc_flags;       /* misc flags. */
+       char            sc_name[16];    /* board name */
        u_int32_t       sc_cacheline;   /* cache line size */
 
        struct mii_data sc_mii;         /* MII/media information */
@@ -385,7 +386,7 @@
 extern const struct tulip_mediasw tlp_sio_mii_mediasw;
 extern const struct tulip_mediasw tlp_pnic_mediasw;
 
-void   tlp_attach __P((struct tulip_softc *, const char *, const u_int8_t *));
+void   tlp_attach __P((struct tulip_softc *, const u_int8_t *));
 int    tlp_intr __P((void *));
 void   tlp_read_srom __P((struct tulip_softc *, int, int, u_int16_t *));
 int    tlp_srom_crcok __P((u_int8_t *));
diff -r 8db5a2eff890 -r e6a02a28d043 sys/dev/pci/if_tlp_pci.c
--- a/sys/dev/pci/if_tlp_pci.c  Tue Sep 14 22:06:44 1999 +0000
+++ b/sys/dev/pci/if_tlp_pci.c  Tue Sep 14 22:25:48 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_tlp_pci.c,v 1.7 1999/09/14 05:59:53 thorpej Exp $   */
+/*     $NetBSD: if_tlp_pci.c,v 1.8 1999/09/14 22:25:49 thorpej Exp $   */
 
 /*-
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -98,8 +98,27 @@
 
        /* PCI-specific goo. */
        void    *sc_ih;                 /* interrupt handle */
+
+       pci_chipset_tag_t sc_pc;        /* our PCI chipset */
+       pcitag_t sc_pcitag;             /* our PCI tag */
+
+       int     sc_pcidev;              /* PCI device number */
+
+       int     sc_flags;               /* flags; see below */
+
+       LIST_HEAD(, tulip_pci_softc) sc_intrslaves;
+       LIST_ENTRY(tulip_pci_softc) sc_intrq;
+
+       /* Our {ROM,interrupt} master. */
+       struct tulip_pci_softc *sc_master;
 };
 
+/* sc_flags */
+#define        TULIP_PCI_SHAREDINTR    0x01    /* interrupt is shared */
+#define        TULIP_PCI_SLAVEINTR     0x02    /* interrupt is slave */
+#define        TULIP_PCI_SHAREDROM     0x04    /* ROM is shared */
+#define        TULIP_PCI_SLAVEROM      0x08    /* slave of shared ROM */
+
 int    tlp_pci_match __P((struct device *, struct cfdata *, void *));
 void   tlp_pci_attach __P((struct device *, struct device *, void *));
 
@@ -171,10 +190,38 @@
          TULIP_CHIP_INVALID },
 };
 
+struct tlp_pci_quirks {
+       void            (*tpq_func) __P((struct tulip_pci_softc *,
+                           const u_int8_t *));
+       u_int8_t        tpq_oui[3];
+};
+
+void   tlp_pci_znyx_21040_quirks __P((struct tulip_pci_softc *,
+           const u_int8_t *));
+void   tlp_pci_smc_21040_quirks __P((struct tulip_pci_softc *,
+           const u_int8_t *));
+void   tlp_pci_cogent_21040_quirks __P((struct tulip_pci_softc *,
+           const u_int8_t *));
+void   tlp_pci_accton_21040_quirks __P((struct tulip_pci_softc *,
+           const u_int8_t *));
+
+const struct tlp_pci_quirks tlp_pci_21040_quirks[] = {
+       { tlp_pci_znyx_21040_quirks,    { 0x00, 0xc0, 0x95 } },
+       { tlp_pci_smc_21040_quirks,     { 0x00, 0x00, 0xc0 } },
+       { tlp_pci_cogent_21040_quirks,  { 0x00, 0x00, 0x92 } },
+       { tlp_pci_accton_21040_quirks,  { 0x00, 0x00, 0xe8 } },
+       { NULL,                         { 0, 0, 0 } }
+};
+
 const char *tlp_pci_chip_names[] = TULIP_CHIP_NAMES;
 
+int    tlp_pci_shared_intr __P((void *));
+
 const struct tulip_pci_product *tlp_pci_lookup
     __P((const struct pci_attach_args *));
+void tlp_pci_get_quirks __P((struct tulip_pci_softc *, const u_int8_t *,
+    const struct tlp_pci_quirks *));
+void tlp_pci_check_slaved __P((struct tulip_pci_softc *, int, int));
 
 const struct tulip_pci_product *
 tlp_pci_lookup(pa)
@@ -192,6 +239,54 @@
        return (NULL);
 }
 
+void
+tlp_pci_get_quirks(psc, enaddr, tpq)
+       struct tulip_pci_softc *psc;
+       const u_int8_t *enaddr;
+       const struct tlp_pci_quirks *tpq;
+{
+
+       for (; tpq->tpq_func != NULL; tpq++) {
+               if (tpq->tpq_oui[0] == enaddr[0] &&
+                   tpq->tpq_oui[1] == enaddr[1] &&
+                   tpq->tpq_oui[2] == enaddr[2]) {
+                       (*tpq->tpq_func)(psc, enaddr);
+                       return;
+               }
+       }
+}
+
+void
+tlp_pci_check_slaved(psc, shared, slaved)
+       struct tulip_pci_softc *psc;
+       int shared, slaved;
+{
+       extern struct cfdriver tlp_cd;
+       struct tulip_pci_softc *cur, *best = NULL;
+       struct tulip_softc *sc = &psc->sc_tulip;
+       int i;
+
+       /*
+        * First of all, find the lowest pcidev numbered device on our
+        * bus marked as a shared ROM.  That should be our master.
+        */
+       for (i = 0; i < tlp_cd.cd_ndevs; i++) {
+               if ((cur = tlp_cd.cd_devs[i]) == NULL)
+                       continue;
+               if (cur->sc_tulip.sc_dev.dv_parent != sc->sc_dev.dv_parent)
+                       continue;
+               if ((cur->sc_flags & shared) == 0)
+                       continue;
+               if (best == NULL || best->sc_pcidev > cur->sc_pcidev)
+                       best = cur;
+       }
+
+       if (best != NULL) {
+               psc->sc_master = best;
+               psc->sc_flags |= (shared | slaved);
+       }
+}
+
 int
 tlp_pci_match(parent, match, aux)
        struct device *parent;
@@ -223,7 +318,12 @@
        const struct tulip_pci_product *tpp;
        u_int8_t enaddr[ETHER_ADDR_LEN];
        u_int32_t val;
-       const char *name = NULL;
+
+       psc->sc_pcidev = pa->pa_device;
+       psc->sc_pc = pa->pa_pc;
+       psc->sc_pcitag = pa->pa_tag;
+
+       LIST_INIT(&psc->sc_intrslaves);
 
        /*
         * Map the device.
@@ -382,25 +482,39 @@
         */
        switch (sc->sc_chip) {
        case TULIP_CHIP_21040:
+               /* Check for a slaved ROM on a multi-port board. */
+               tlp_pci_check_slaved(psc, TULIP_PCI_SHAREDROM,
+                   TULIP_PCI_SLAVEROM);
+               if (psc->sc_flags & TULIP_PCI_SLAVEROM)
+                       memcpy(sc->sc_srom, psc->sc_master->sc_tulip.sc_srom,
+                           sizeof(sc->sc_srom));
+
                /*
-                * None of the 21040 boards have the new-style SROMs.
+                * Parse the Ethernet Address ROM.
                 */
                if (tlp_parse_old_srom(sc, enaddr) == 0) {
-                       printf("%s: unable to decode old-style SROM\n",
+                       printf("%s: unable to decode Ethernet Address ROM\n",
                            sc->sc_dev.dv_xname);
                        return;
                }
 
                /*
+                * If we have a slaved ROM, adjust the Ethernet address.
+                */
+               if (psc->sc_flags & TULIP_PCI_SLAVEROM)
+                       enaddr[5] +=
+                           psc->sc_pcidev - psc->sc_master->sc_pcidev;
+
+               /*
                 * All 21040 boards start out with the same
                 * media switch.
                 */
                sc->sc_mediasw = &tlp_21040_mediasw;
 
                /*
-                * XXX Eventually we should attempt to identify
-                * XXX other boards, and set the media appropriately.
+                * Deal with any quirks this board might have.
                 */
+               tlp_pci_get_quirks(psc, enaddr, tlp_pci_21040_quirks);
                break;
 
        case TULIP_CHIP_82C168:
@@ -438,27 +552,191 @@
        }
 
        /*
-        * Map and establish our interrupt.
+        * Handle shared interrupts.
         */
-       if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin,
-           pa->pa_intrline, &ih)) {
-               printf("%s: unable to map interrupt\n", sc->sc_dev.dv_xname);
-               return;
+       if (psc->sc_flags & TULIP_PCI_SHAREDINTR) {
+               if (psc->sc_master)
+                       psc->sc_flags |= TULIP_PCI_SLAVEINTR;
+               else {
+                       tlp_pci_check_slaved(psc, TULIP_PCI_SHAREDINTR,
+                           TULIP_PCI_SLAVEINTR);
+                       if (psc->sc_master == NULL)
+                               psc->sc_master = psc;
+               }
+               LIST_INSERT_HEAD(&psc->sc_master->sc_intrslaves,
+                   psc, sc_intrq);
        }
-       intrstr = pci_intr_string(pc, ih); 
-       psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, tlp_intr, sc);
-       if (psc->sc_ih == NULL) {
-               printf("%s: unable to establish interrupt",
-                   sc->sc_dev.dv_xname);
-               if (intrstr != NULL)
-                       printf(" at %s", intrstr);
-               printf("\n");
-               return;
+
+       if (psc->sc_flags & TULIP_PCI_SLAVEINTR) {
+               printf("%s: sharing interrupt with %s\n",
+                   sc->sc_dev.dv_xname,
+                   psc->sc_master->sc_tulip.sc_dev.dv_xname);
+       } else {
+               /*



Home | Main Index | Thread Index | Old Index