-/* $OpenBSD: if_en_pci.c,v 1.3 1996/10/31 01:05:11 niklas Exp $ */
+/* $OpenBSD: if_en_pci.c,v 1.4 1997/03/20 22:03:45 chuck Exp $ */
/*
*
*/
#include <sys/param.h>
-#include <sys/types.h>
+#include <sys/systm.h>
#include <sys/device.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
-#include <sys/systm.h>
#include <net/if.h>
#define PCI_CBMA 0x10
/*
- * tonga (pci bridge)
+ * tonga (pci bridge). ENI cards only!
*/
#define EN_TONGA 0x60 /* PCI config addr of tonga reg */
#define TONGA_SWAP_BYTE 0x40
#define TONGA_SWAP_WORD 0x20
+/*
+ * adaptec pci bridge. ADP cards only!
+ */
+
+#define ADP_PCIREG 0x050040 /* PCI control register */
+
+#define ADP_PCIREG_RESET 0x1 /* reset card */
+#define ADP_PCIREG_IENABLE 0x2 /* interrupt enable */
+#define ADP_PCIREG_SWAP_WORD 0x4 /* swap byte on slave access */
+#define ADP_PCIREG_SWAP_DMA 0x8 /* swap bytes on DMA */
+
/*
* prototypes
*/
+#ifdef __BROKEN_INDIRECT_CONFIG
static int en_pci_match __P((struct device *, void *, void *));
+#else
+static int en_pci_match __P((struct device *, struct cfdata *, void *));
+#endif
static void en_pci_attach __P((struct device *, struct device *, void *));
/*
sizeof(struct en_pci_softc), en_pci_match, en_pci_attach,
};
+#if !defined(MIDWAY_ENIONLY)
+
+static void adp_busreset __P((void *));
+
+/*
+ * bus specific reset function [ADP only!]
+ */
+
+static void adp_busreset(v)
+
+void *v;
+
+{
+ struct en_softc *sc = (struct en_softc *) v;
+ u_int32_t dummy;
+
+ bus_space_write_4(sc->en_memt, sc->en_base, ADP_PCIREG, ADP_PCIREG_RESET);
+ DELAY(1000); /* let it reset */
+ dummy = bus_space_read_4(sc->en_memt, sc->en_base, ADP_PCIREG);
+ bus_space_write_4(sc->en_memt, sc->en_base, ADP_PCIREG,
+ (ADP_PCIREG_SWAP_WORD|ADP_PCIREG_SWAP_DMA|ADP_PCIREG_IENABLE));
+ dummy = bus_space_read_4(sc->en_memt, sc->en_base, ADP_PCIREG);
+ if ((dummy & (ADP_PCIREG_SWAP_WORD|ADP_PCIREG_SWAP_DMA)) !=
+ (ADP_PCIREG_SWAP_WORD|ADP_PCIREG_SWAP_DMA))
+ printf("adp_busreset: Adaptec ATM did NOT reset!\n");
+
+}
+#endif
+
/***********************************************************************/
/*
static int en_pci_match(parent, match, aux)
struct device *parent;
+#ifdef __BROKEN_INDIRECT_CONFIG
void *match;
+#else
+struct cfdata *match;
+#endif
void *aux;
{
struct pci_attach_args *pa = (struct pci_attach_args *) aux;
- if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_EFFICIENTNETS)
- return 0;
+#if !defined(MIDWAY_ADPONLY)
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_EFFICIENTNETS &&
+ (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_EFFICIENTNETS_ENI155PF ||
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_EFFICIENTNETS_ENI155PA))
+ return 1;
+#endif
- if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_EFFICIENTNETS_ENI155P)
+#if !defined(MIDWAY_ENIONLY)
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ADP &&
+ (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADP_AIC5900 ||
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADP_AIC5905))
return 1;
+#endif
return 0;
}
struct en_softc *sc = (void *)self;
struct en_pci_softc *scp = (void *)self;
struct pci_attach_args *pa = aux;
- bus_mem_addr_t membase;
+ bus_addr_t membase;
pci_intr_handle_t ih;
const char *intrstr;
int retval;
printf("\n");
- sc->en_bc = pa->pa_bc;
+ sc->en_memt = pa->pa_memt;
+ sc->is_adaptec = (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ADP) ? 1 : 0;
scp->en_pc = pa->pa_pc;
/*
return;
}
intrstr = pci_intr_string(scp->en_pc, ih);
- scp->sc_ih = pci_intr_establish(scp->en_pc, ih, IPL_NET, en_intr, sc,
- sc->sc_dev.dv_xname);
+ scp->sc_ih = pci_intr_establish(scp->en_pc, ih, IPL_NET, en_intr, sc);
if (scp->sc_ih == NULL) {
printf("%s: couldn't establish interrupt\n", sc->sc_dev.dv_xname);
if (intrstr != NULL)
retval = pci_mem_find(scp->en_pc, pa->pa_tag, PCI_CBMA,
&membase, &sc->en_obmemsz, NULL);
if (retval == 0)
- retval = bus_mem_map(sc->en_bc, membase, sc->en_obmemsz, 0, &sc->en_base);
+ retval = bus_space_map(sc->en_memt, membase, sc->en_obmemsz, 0,
+ &sc->en_base);
if (retval) {
printf("%s: couldn't map memory\n", sc->sc_dev.dv_xname);
}
/*
- * set up swapping
+ * set up pci bridge
*/
- pci_conf_write(scp->en_pc, pa->pa_tag, EN_TONGA,
- (TONGA_SWAP_DMA|TONGA_SWAP_WORD));
+#if !defined(MIDWAY_ENIONLY)
+ if (sc->is_adaptec) {
+ sc->en_busreset = adp_busreset;
+ adp_busreset(sc);
+ }
+#endif
+
+#if !defined(MIDWAY_ADPONLY)
+ if (!sc->is_adaptec) {
+ sc->en_busreset = NULL;
+ pci_conf_write(scp->en_pc, pa->pa_tag, EN_TONGA,
+ (TONGA_SWAP_DMA|TONGA_SWAP_WORD));
+ }
+#endif
/*
* done PCI specific stuff