summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorthorpej <thorpej@NetBSD.org>1997-11-17 01:58:29 +0000
committerthorpej <thorpej@NetBSD.org>1997-11-17 01:58:29 +0000
commitbbee56718773be9581889084fb89f0e282bbabed (patch)
treeab4bc2aed4b40012ad63e2d56c8baac0873300ba /sys/dev
parent6c986561eeedf1c5154f5b8bff429a1435c26beb (diff)
Fix a couple of bugs/annoyances in match/attach:
- Do PCI space configuration like the other drivers. In particular, don't _disable_ the space we're not using because some lame firmware implementations might not reenable it on warm boot. Also, prefer memory space always. - Make match and info-gathering in attach table-driven. - Rearrange things a bit to be a bit more visually pleasing during boot. Also, fixup some #include problems.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_tl.c283
1 files changed, 141 insertions, 142 deletions
diff --git a/sys/dev/pci/if_tl.c b/sys/dev/pci/if_tl.c
index 1a8f5c59c0b..6a40f419466 100644
--- a/sys/dev/pci/if_tl.c
+++ b/sys/dev/pci/if_tl.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_tl.c,v 1.3 1997/11/16 22:33:19 christos Exp $ */
+/* $NetBSD: if_tl.c,v 1.4 1997/11/17 01:58:29 thorpej Exp $ */
/*
* Copyright (c) 1997 Manuel Bouyer. All rights reserved.
@@ -89,10 +89,10 @@
#if defined(INET)
#include <netinet/if_inarp.h>
#endif
+
#include <machine/bus.h>
-#if defined(__alpha__)
#include <machine/intr.h>
-#endif
+
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
@@ -117,7 +117,6 @@ struct tl_softc {
struct device sc_dev; /* base device */
bus_space_tag_t tl_bustag;
bus_space_handle_t tl_bushandle; /* CSR region handle */
- pci_chipset_tag_t tl_pc;
void* tl_ih;
struct ethercom tl_ec;
u_int8_t tl_enaddr[ETHER_ADDR_LEN]; /* hardware adress */
@@ -155,11 +154,6 @@ struct tl_softc {
typedef struct tl_softc tl_softc_t;
typedef u_long ioctl_cmd_t;
-#define PCI_VENDORID(x) ((x) & 0xFFFF)
-#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF)
-#define PCI_CONF_READ(r) pci_conf_read(pa->pa_pc, pa->pa_tag, (r))
-#define PCI_CONF_WRITE(r, v) pci_conf_write(pa->pa_pc, pa->pa_tag, (r), (v))
-
#define TL_HR_READ(sc, reg) \
bus_space_read_4(sc->tl_bustag, sc->tl_bushandle, (reg))
#define TL_HR_READ_BYTE(sc, reg) \
@@ -170,7 +164,7 @@ typedef u_long ioctl_cmd_t;
bus_space_write_1(sc->tl_bustag, sc->tl_bushandle, (reg), (data))
#define ETHER_MIN_TX (ETHERMIN + sizeof(struct ether_header))
-static int tl_pci_probe __P((struct device *, void *, void *));
+static int tl_pci_match __P((struct device *, void *, void *));
static void tl_pci_attach __P((struct device *, struct device *, void *));
static int tl_intr __P((void *));
@@ -229,44 +223,100 @@ static __inline u_int8_t netsio_read(sc, bits)
tl_softc_t* sc;
u_int8_t bits;
{
- return (tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio) & bits);
+ return (tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio) & bits);
}
struct cfattach tl_ca = {
- sizeof(tl_softc_t), tl_pci_probe, tl_pci_attach
+ sizeof(tl_softc_t), tl_pci_match, tl_pci_attach
};
struct cfdriver tl_cd = {
0, "tl", DV_IFNET
};
+struct tl_product_desc {
+ u_int32_t tp_product;
+ u_int32_t tp_adapter;
+ const char *tp_desc;
+};
+
+const struct tl_product_desc tl_compaq_products[] = {
+ { PCI_PRODUCT_COMPAQ_N100TX, COMPAQ_NETLIGENT_10_100,
+ "Compaq Netelligent 10/100 TX" },
+ { PCI_PRODUCT_COMPAQ_N10T, COMPAQ_NETLIGENT_10,
+ "Compaq Netelligent 10 T" },
+ { PCI_PRODUCT_COMPAQ_IntNF3P, COMPAQ_INT_NETFLEX,
+ "Compaq Integrated NetFlex 3/P" },
+ { PCI_PRODUCT_COMPAQ_IntPL100TX, COMPAQ_INT_NETLIGENT_10_100,
+ "Compaq ProLiant Integrated Netelligent 10/100 TX" },
+ { PCI_PRODUCT_COMPAQ_DPNet100TX, COMPAQ_DUAL_NETLIGENT_10_100,
+ "Compaq Dual Port Netelligent 10/100 TX" },
+ { PCI_PRODUCT_COMPAQ_DP4000, COMPAQ_DSKP4000,
+ "Compaq Deskpro 4000 5233MMX" },
+ { PCI_PRODUCT_COMPAQ_NF3P_BNC, COMPAQ_NETFLEX_BNC,
+ "Compaq NetFlex 3/P w/ BNC" },
+ { PCI_PRODUCT_COMPAQ_NF3P, COMPAQ_NETFLEX,
+ "Compaq NetFlex 3/P" },
+ { 0, 0, NULL },
+};
+
+const struct tl_product_desc tl_ti_products[] = {
+ { PCI_PRODUCT_TI_TLAN, TI_TLAN,
+ "Texas Instruments ThunderLAN" },
+ { 0, 0, NULL },
+};
+
+struct tl_vendor_desc {
+ u_int32_t tv_vendor;
+ const struct tl_product_desc *tv_products;
+};
+
+const struct tl_vendor_desc tl_vendors[] = {
+ { PCI_VENDOR_COMPAQ, tl_compaq_products },
+ { PCI_VENDOR_TI, tl_ti_products },
+ { 0, NULL },
+};
+
+const struct tl_product_desc *tl_lookup_product __P((u_int32_t));
+
+const struct tl_product_desc *
+tl_lookup_product(id)
+ u_int32_t id;
+{
+ const struct tl_product_desc *tp;
+ const struct tl_vendor_desc *tv;
+
+ for (tv = tl_vendors; tv->tv_products != NULL; tv++)
+ if (PCI_VENDOR(id) == tv->tv_vendor)
+ break;
+
+ if ((tp = tv->tv_products) == NULL)
+ return (NULL);
+
+ for (; tp->tp_desc != NULL; tp++)
+ if (PCI_PRODUCT(id) == tp->tp_product)
+ break;
+
+ if (tp->tp_desc == NULL)
+ return (NULL);
+
+ return (tp);
+}
+
static char *nullbuf;
static int
-tl_pci_probe(parent, match, aux)
+tl_pci_match(parent, match, aux)
struct device *parent;
void *match;
void *aux;
{
struct pci_attach_args *pa = (struct pci_attach_args *) aux;
- if ((PCI_VENDORID(pa->pa_id) != PCI_VENDOR_COMPAQ) &&
- (PCI_VENDORID(pa->pa_id) != PCI_VENDOR_TI))
- return 0;
- switch(PCI_CHIPID(pa->pa_id)) {
- case PCI_PRODUCT_COMPAQ_N100TX:
- case PCI_PRODUCT_COMPAQ_N10T:
- case PCI_PRODUCT_COMPAQ_IntNF3P:
- case PCI_PRODUCT_COMPAQ_IntPL100TX:
- case PCI_PRODUCT_COMPAQ_DPNet100TX:
- case PCI_PRODUCT_COMPAQ_DP4000:
- case PCI_PRODUCT_COMPAQ_NF3P_BNC:
- case PCI_PRODUCT_COMPAQ_NF3P:
- case PCI_PRODUCT_TI_TLAN:
- return 1;
- default:
- return 0;
- }
+ if (tl_lookup_product(pa->pa_id) != NULL)
+ return (1);
+
+ return (0);
}
static void
@@ -277,118 +327,47 @@ tl_pci_attach(parent, self, aux)
{
tl_softc_t *sc = (tl_softc_t *)self;
struct pci_attach_args * const pa = (struct pci_attach_args *) aux;
- /* int unit = sc->tl_dev.dv_unit; */
+ const struct tl_product_desc *tp;
struct ifnet * const ifp = &sc->tl_if;
- u_int32_t cfcs = PCI_CONF_READ(PCI_CFCS);
bus_space_tag_t iot, memt;
bus_space_handle_t ioh, memh;
pci_intr_handle_t intrhandle;
- const char *model, *intrstr;
- int i, tmp;
-
- sc->tl_pc = pa->pa_pc;
- cfcs &= ~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE);
-
- /* Map and enable the card */
-#if defined(PCI_PREFER_IOSPACE)
- if (!pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
- &iot, &ioh, NULL, NULL)) {
- cfcs |= PCI_COMMAND_IO_ENABLE;
- } else if (!pci_mapreg_map(pa, PCI_CBMA,
- PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
- 0, &memt, &memh, NULL, NULL) == 0) {
- cfcs |= PCI_COMMAND_MEM_ENABLE;
- } else {
- printf("can't map IO nor MEM space\n");
- return;
- }
- if (cfcs & PCI_COMMAND_IO_ENABLE) {
- sc->tl_bustag = iot, sc->tl_bushandle = ioh;
+ const char *intrstr;
+ int i, tmp, ioh_valid, memh_valid;
+ pcireg_t csr;
+
+ printf("\n");
+
+ /* Map the card space. */
+ ioh_valid = (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
+ &iot, &ioh, NULL, NULL) == 0);
+ memh_valid = (pci_mapreg_map(pa, PCI_CBMA,
+ PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
+ 0, &memt, &memh, NULL, NULL) == 0);
+
+ if (memh_valid) {
+ sc->tl_bustag = memt;
+ sc->tl_bushandle = memh;
+ } else if (ioh_valid) {
+ sc->tl_bustag = iot;
+ sc->tl_bushandle = ioh;
} else {
- sc->tl_bustag = memt, sc->tl_bushandle = memh;
- }
-#else
- if (!pci_mapreg_map(pa, PCI_CBMA,
- PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
- 0, &memt, &memh, NULL, NULL) == 0) {
- cfcs |= PCI_COMMAND_MEM_ENABLE;
- } else if (!pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
- &iot, &ioh, NULL, NULL)) {
- cfcs |= PCI_COMMAND_IO_ENABLE;
- } else {
- printf("can't map MEM nor IO space\n");
- return;
- }
- if (cfcs & PCI_COMMAND_MEM_ENABLE) {
- sc->tl_bustag = memt; sc->tl_bushandle = memh;
- } else {
- sc->tl_bustag = iot; sc->tl_bushandle = ioh;
+ printf("%s: unable to map device registers\n",
+ sc->sc_dev.dv_xname);
+ return;
}
-#endif
- cfcs |= PCI_COMMAND_MASTER_ENABLE;
- PCI_CONF_WRITE(PCI_CFCS, cfcs);
-
- switch(PCI_CHIPID(pa->pa_id)) {
- case PCI_PRODUCT_COMPAQ_N100TX:
- model = "Compaq Netelligent 10/100 TX";
- sc->mii.adapter_id = COMPAQ_NETLIGENT_10_100;
- break;
- case PCI_PRODUCT_COMPAQ_N10T:
- model = "Compaq Netelligent 10 T";
- sc->mii.adapter_id = COMPAQ_NETLIGENT_10;
- break;
- case PCI_PRODUCT_COMPAQ_IntNF3P:
- model = "Compaq Integrated NetFlex 3/P";
- sc->mii.adapter_id = COMPAQ_INT_NETFLEX;
- break;
- case PCI_PRODUCT_COMPAQ_IntPL100TX:
- model = "Compaq ProLiant Integrated Netelligent 10/100 TX";
- sc->mii.adapter_id = COMPAQ_INT_NETLIGENT_10_100;
- break;
- case PCI_PRODUCT_COMPAQ_DPNet100TX:
- model = "Compaq Dual Port Netelligent 10/100 TX";
- sc->mii.adapter_id = COMPAQ_DUAL_NETLIGENT_10_100;
- break;
- case PCI_PRODUCT_COMPAQ_DP4000:
- model = "Compaq Deskpro 4000 5233MMX";
- sc->mii.adapter_id = COMPAQ_DSKP4000;
- break;
- case PCI_PRODUCT_COMPAQ_NF3P_BNC:
- model = "Compaq NetFlex 3/P w/ BNC";
- sc->mii.adapter_id = COMPAQ_NETFLEX_BNC;
- break;
- case PCI_PRODUCT_COMPAQ_NF3P:
- model = "Compaq NetFlex 3/P";
- sc->mii.adapter_id = COMPAQ_NETFLEX;
- break;
- case PCI_PRODUCT_TI_TLAN:
- model = "Texas Instruments ThunderLAN";
- sc->mii.adapter_id = TI_TLAN;
- break;
- default:
- model = "unknown ThunderLAN board!\n";
- }
- printf(": %s\n%s: ",model, sc->sc_dev.dv_xname);
+ /* Enable the device. */
+ csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+ pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
+ csr | PCI_COMMAND_MASTER_ENABLE);
- /* Map and establish interrupts */
- if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
- pa->pa_intrline, &intrhandle)) {
- printf("couldn't map interrupt\n");
- return;
- }
- intrstr = pci_intr_string(pa->pa_pc, intrhandle);
- sc->tl_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
- tl_intr, sc);
- if (sc->tl_ih == NULL) {
- printf("couldn't map interrupt");
- if (intrstr != NULL)
- printf(" at %s", intrstr);
- printf("\n");
- return;
- }
- printf("interrupting at %s\n", intrstr);
+ tp = tl_lookup_product(pa->pa_id);
+ if (tp == NULL)
+ panic("tl_pci_attach: impossible");
+ printf("%s: %s\n", sc->sc_dev.dv_xname, tp->tp_desc);
+ sc->mii.adapter_id = tp->tp_adapter;
tl_reset(sc);
@@ -407,15 +386,42 @@ tl_pci_attach(parent, self, aux)
for (i=0; i<ETHER_ADDR_LEN; i++) {
tmp = i2c_eeprom_read(&sc->i2cbus, 0x83 + i);
if (tmp < 0) {
- printf("%s: error reading MAC adress\n", sc->sc_dev.dv_xname);
+ printf("%s: error reading Ethernet adress\n",
+ sc->sc_dev.dv_xname);
return;
} else {
sc->tl_enaddr[i] = tmp;
}
}
- printf("%s: address %s\n", sc->sc_dev.dv_xname,
+ printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
ether_sprintf(sc->tl_enaddr));
+ /* Map and establish interrupts */
+ if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
+ pa->pa_intrline, &intrhandle)) {
+ printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
+ return;
+ }
+ intrstr = pci_intr_string(pa->pa_pc, intrhandle);
+ sc->tl_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
+ tl_intr, sc);
+ if (sc->tl_ih == NULL) {
+ printf("%s: couldn't establish interrupt",
+ sc->sc_dev.dv_xname);
+ if (intrstr != NULL)
+ printf(" at %s", intrstr);
+ printf("\n");
+ return;
+ }
+ printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
+
+ /*
+ * Add shutdown hook so that DMA is disabled prior to reboot. Not
+ * doing do could allow DMA to corrupt kernel memory during the
+ * reboot before the driver initializes.
+ */
+ (void) shutdownhook_establish(tl_shutdown, sc);
+
sc->mii.adapter_softc = sc;
sc->mii.mii_setbit = tl_mii_set;
sc->mii.mii_clrbit = tl_mii_clr;
@@ -433,7 +439,6 @@ tl_pci_attach(parent, self, aux)
bcopy(sc->sc_dev.dv_xname, sc->tl_if.if_xname, IFNAMSIZ);
sc->tl_if.if_softc = sc;
- sc->tl_pc = pa->pa_pc;
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
ifp->if_ioctl = tl_ifioctl;
ifp->if_start = tl_ifstart;
@@ -446,12 +451,6 @@ tl_pci_attach(parent, self, aux)
sizeof(struct ether_header));
#endif
sc->mii.mii_media_active = IFM_NONE;
- /*
- * Add shutdown hook so that DMA is disabled prior to reboot. Not
- * doing do could allow DMA to corrupt kernel memory during the
- * reboot before the driver initializes.
- */
- shutdownhook_establish(tl_shutdown, sc);
}
static void