-/* $OpenBSD: if_de.c,v 1.41 1999/07/18 03:20:18 csapuntz Exp $ */
+/* $OpenBSD: if_de.c,v 1.42 2000/04/27 00:06:41 chris Exp $ */
/* $NetBSD: if_de.c,v 1.45 1997/06/09 00:34:18 thorpej Exp $ */
/*-
#else
#define NEISA 0
#endif
-#if NEISA > 0 && _BSDI_VERSION >= 199401
-#include <i386/eisa/eisa.h>
-#define TULIP_EISA
-#endif
#define DEVAR_INCLUDE "i386/pci/if_devar.h"
#endif /* __bsdi__ */
/*
* Intel CPUs should use I/O mapped access.
*/
-#if defined(__i386__) || defined(TULIP_EISA)
+#if defined(__i386__)
#define TULIP_IOMAPPED
#endif
static int tulip_mii_map_abilities(tulip_softc_t * const sc, unsigned abilities);
static tulip_media_t tulip_mii_phy_readspecific(tulip_softc_t * const sc);
static int tulip_srom_decode(tulip_softc_t * const sc);
-#if defined(IFM_ETHER)
static int tulip_ifmedia_change(struct ifnet * const ifp);
static void tulip_ifmedia_status(struct ifnet * const ifp, struct ifmediareq *req);
-#endif
/* static void tulip_21140_map_media(tulip_softc_t *sc); */
static void
sc->tulip_if.if_baudrate = 10000000;
sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_ENHCAPTEFFCT
|TULIP_CMD_THRSHLD160|TULIP_CMD_BACKOFFCTR;
- sc->tulip_intrmask |= TULIP_STS_LINKPASS;
+ sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
tulip_21041_mediainfo_init(sc);
}
/*
* Code the read the SROM and MII bit streams (I2C)
*/
-static void
-tulip_delay_300ns(
- tulip_softc_t * const sc)
-{
- int idx;
- for (idx = (300 / 33) + 1; idx > 0; idx--)
- (void) TULIP_CSR_READ(sc, csr_busmode);
-}
-#define EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
+#define EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); DELAY(1); } while (0)
static void
tulip_srom_idle(
tulip_srom_idle(sc);
}
-#define MII_EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
+#define MII_EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); DELAY(1); } while (0)
static void
tulip_mii_writebits(
}
}
+static void
+tulip_identify_compex_nic(
+ tulip_softc_t * const sc)
+{
+ strcpy(sc->tulip_boardid, "COMPEX ");
+ if (sc->tulip_chipid == TULIP_21140A) {
+ int root_unit;
+ tulip_softc_t *root_sc = NULL;
+
+ strcat(sc->tulip_boardid, "400TX/PCI ");
+ /*
+ * All 4 chips on these boards share an interrupt. This code
+ * copied from tulip_read_macaddr.
+ */
+ sc->tulip_features |= TULIP_HAVE_SHAREDINTR;
+ for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) {
+ root_sc = TULIP_UNIT_TO_SOFTC(root_unit);
+ if (root_sc == NULL
+ || !(root_sc->tulip_features & TULIP_HAVE_SLAVEDINTR))
+ break;
+ root_sc = NULL;
+ }
+ if (root_sc != NULL
+ && root_sc->tulip_chipid == sc->tulip_chipid
+ && root_sc->tulip_pci_busno == sc->tulip_pci_busno) {
+ sc->tulip_features |= TULIP_HAVE_SLAVEDINTR;
+ sc->tulip_slaves = root_sc->tulip_slaves;
+ root_sc->tulip_slaves = sc;
+ } else if(sc->tulip_features & TULIP_HAVE_SLAVEDINTR) {
+ printf("\nCannot find master device for de%d interrupts",
+ sc->tulip_unit);
+ }
+ } else {
+ strcat(sc->tulip_boardid, "unknown ");
+ }
+ /* sc->tulip_boardsw = &tulip_21140_eb_boardsw; */
+ return;
+}
+
static int
tulip_srom_decode(
tulip_softc_t * const sc)
{ tulip_identify_smc_nic, { 0x00, 0xE0, 0x29 } },
{ tulip_identify_znyx_nic, { 0x00, 0xC0, 0x95 } },
{ tulip_identify_cogent_nic, { 0x00, 0x00, 0x92 } },
- { tulip_identify_cogent_nic, { 0x00, 0x00, 0xD1 } },
+ { tulip_identify_cogent_nic, { 0x00, 0x00, 0xD1 } }, /* Adaptec */
{ tulip_identify_asante_nic, { 0x00, 0x00, 0x94 } },
{ tulip_identify_accton_nic, { 0x00, 0x00, 0xE8 } },
+ { tulip_identify_compex_nic, { 0x00, 0x80, 0x48 } },
{ NULL }
};
sc->tulip_rombuf[idx] = csr & 0xFF;
}
sc->tulip_boardsw = &tulip_21040_boardsw;
-#if defined(TULIP_EISA)
- } else if (sc->tulip_chipid == TULIP_DE425) {
- int cnt;
- for (idx = 0, cnt = 0; idx < sizeof(testpat) && cnt < 32; cnt++) {
- tmpbuf[idx] = TULIP_CSR_READBYTE(sc, csr_enetrom);
- if (tmpbuf[idx] == testpat[idx])
- ++idx;
- else
- idx = 0;
- }
- for (idx = 0; idx < 32; idx++)
- sc->tulip_rombuf[idx] = TULIP_CSR_READBYTE(sc, csr_enetrom);
- sc->tulip_boardsw = &tulip_21040_boardsw;
-#endif /* TULIP_EISA */
} else {
if (sc->tulip_chipid == TULIP_21041) {
/*
return 0;
}
-#if defined(IFM_ETHER)
static void
tulip_ifmedia_add(
tulip_softc_t * const sc)
req->ifm_active = tulip_media_to_ifmedia[sc->tulip_media];
}
-#endif
static void
tulip_addr_filter(
sc->tulip_flags |= TULIP_WANTSETUP|TULIP_WANTTXSTART;
sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
-#if defined(IFF_ALLMULTI)
- sc->tulip_if.if_flags &= ~IFF_ALLMULTI;
+#if defined(IFF_ALLMULTI)
+ if (sc->tulip_if.if_flags & IFF_ALLMULTI)
+ sc->tulip_flags |= TULIP_ALLMULTI;
#endif
- sc->tulip_if.if_start = tulip_ifstart; /* so the setup packet gets queued */
+ sc->tulip_if.if_start = tulip_ifstart; /* so the setup packet gets queued */
+
if (sc->tulip_multicnt > 14) {
u_int32_t *sp = sc->tulip_setupdata;
unsigned hash;
* to properly reset its internal pathways to the right places.
* Grrrr.
*/
- if (sc->tulip_boardsw->bd_media_preset != NULL)
+
+ if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0
+ && sc->tulip_boardsw->bd_media_preset != NULL)
(*sc->tulip_boardsw->bd_media_preset)(sc);
TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
#endif
sc->tulip_flags |= TULIP_RXACT;
accept = 1;
- total_len -= sizeof(struct ether_header);
} else {
ifp->if_ierrors++;
if (DESC_BO(eop->d_status) & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG)) {
MGETHDR(m0, M_DONTWAIT, MT_DATA);
if (m0 != NULL) {
#if defined(TULIP_COPY_RXDATA)
- if (!accept || total_len >= MHLEN) {
+ if (!accept || total_len >= (MHLEN - 2)) {
#endif
MCLGET(m0, M_DONTWAIT);
if ((m0->m_flags & M_EXT) == 0) {
eh.ether_type = ntohs(eh.ether_type);
#endif
#if !defined(TULIP_COPY_RXDATA)
- ms->m_data += sizeof(struct ether_header);
- ms->m_len -= sizeof(struct ether_header);
ms->m_pkthdr.len = total_len;
ms->m_pkthdr.rcvif = ifp;
+#if defined(__NetBSD__)
+ (*ifp->if_input)(ifp, ms);
+#else
+ m_adj(ms, sizeof(struct ether_header));
ether_input(ifp, &eh, ms);
+#endif
#else
#ifdef BIG_PACKET
#error BIG_PACKET is incompatible with TULIP_COPY_RXDATA
#endif
- if (ms == me)
- bcopy(mtod(ms, caddr_t) + sizeof(struct ether_header),
- mtod(m0, caddr_t), total_len);
- else
- m_copydata(ms, 0, total_len, mtod(m0, caddr_t));
+ m0->m_data += 2; /* align data after header */
+ m_copydata(ms, 0, total_len, mtod(m0, caddr_t));
m0->m_len = m0->m_pkthdr.len = total_len;
m0->m_pkthdr.rcvif = ifp;
+#if defined(__NetBSD__)
+ (*ifp->if_input)(ifp, m0);
+#else
+ m_adj(m0, sizeof(struct ether_header));
ether_input(ifp, &eh, m0);
+#endif /* NetBSD */
m0 = ms;
-#endif
+#endif /* TULIP_COPY_RXDATA */
}
ms = m0;
}
ri->ri_nextout->d_status = DESC_BO(TULIP_DSTS_OWNER);
}
- TULIP_CSR_WRITE(sc, csr_txpoll, 1);
-
/*
* This advances the ring for us.
*/
TULIP_PERFEND(txput);
if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
+ TULIP_CSR_WRITE(sc, csr_txpoll, 1);
sc->tulip_if.if_flags |= IFF_OACTIVE;
sc->tulip_if.if_start = tulip_ifstart;
TULIP_PERFEND(txput);
TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
}
}
+ TULIP_CSR_WRITE(sc, csr_txpoll, 1);
TULIP_PERFEND(txput);
return m;
}
}
case SIOCSIFFLAGS: {
-#if !defined(IFM_ETHER)
- int flags = 0;
- if (ifp->if_flags & IFF_LINK0) flags |= 1;
- if (ifp->if_flags & IFF_LINK1) flags |= 2;
- if (ifp->if_flags & IFF_LINK2) flags |= 4;
- if (flags == 7) {
- ifp->if_flags &= ~(IFF_LINK0|IFF_LINK1|IFF_LINK2);
- sc->tulip_media = TULIP_MEDIA_UNKNOWN;
- sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
- sc->tulip_flags &= ~(TULIP_WANTRXACT|TULIP_LINKUP|TULIP_NOAUTOSENSE);
- tulip_reset(sc);
- } else if (flags) {
- tulip_media_t media;
- for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
- if (sc->tulip_mediums[media] != NULL && --flags == 0) {
- sc->tulip_flags |= TULIP_NOAUTOSENSE;
- if (sc->tulip_media != media || (sc->tulip_flags & TULIP_DIDNWAY)) {
- sc->tulip_flags &= ~TULIP_DIDNWAY;
- tulip_linkup(sc, media);
- }
- break;
- }
- }
- if (flags)
- printf(TULIP_PRINTF_FMT ": ignored invalid media request\n", TULIP_PRINTF_ARGS);
- }
-#endif
+ tulip_addr_filter(sc); /* reinit multicast filter */
tulip_init(sc);
break;
}
}
break;
}
-#if defined(SIOCSIFMTU)
-#if !defined(ifr_mtu)
-#define ifr_mtu ifr_metric
-#endif
case SIOCSIFMTU:
/*
* Set the interface MTU.
tulip_init(sc);
#endif
break;
-#endif /* SIOCSIFMTU */
#ifdef SIOCGADDRROM
case SIOCGADDRROM: {
#endif
(*sc->tulip_boardsw->bd_media_probe)(sc);
-#if defined(IFM_ETHER)
ifmedia_init(&sc->tulip_ifmedia, 0,
tulip_ifmedia_change,
tulip_ifmedia_status);
-#else
- {
- tulip_media_t media;
- int cnt;
- printf(TULIP_PRINTF_FMT ": media:", TULIP_PRINTF_ARGS);
- for (media = TULIP_MEDIA_UNKNOWN, cnt = 1; cnt < 7 && media < TULIP_MEDIA_MAX; media++) {
- if (sc->tulip_mediums[media] != NULL) {
- printf(" %d=\"%s\"", cnt, tulip_mediums[media]);
- cnt++;
- }
- }
- if (cnt == 1) {
- sc->tulip_features |= TULIP_HAVE_NOMEDIA;
- printf(" none\n");
- } else {
- printf("\n");
- }
- }
-#endif
sc->tulip_flags &= ~TULIP_DEVICEPROBE;
-#if defined(IFM_ETHER)
tulip_ifmedia_add(sc);
-#endif
tulip_reset(sc);
sc->tulip_csrs.csr_13 = csr_base + 13 * csr_size;
sc->tulip_csrs.csr_14 = csr_base + 14 * csr_size;
sc->tulip_csrs.csr_15 = csr_base + 15 * csr_size;
-#if defined(TULIP_EISA)
- sc->tulip_csrs.csr_enetrom = csr_base + DE425_ENETROM_OFFSET;
-#endif
}
static void
#define PCI_CFIT 0x3c /* Configuration Interrupt */
#define PCI_CFDA 0x40 /* Configuration Driver Area */
-#if defined(TULIP_EISA)
-static const int tulip_eisa_irqs[4] = { IRQ5, IRQ9, IRQ10, IRQ11 };
-#endif
-
#if defined(__FreeBSD__)
#define TULIP_PCI_ATTACH_ARGS pcici_t config_id, int unit
#if _BSDI_VERSION >= 199401
break;
-#if defined(TULIP_EISA)
- case BUS_EISA: {
- unsigned tmp;
-
- if ((slot = eisa_match(cf, ia)) == 0)
- return 0;
- ia->ia_iobase = slot << 12;
- ia->ia_iosize = EISA_NPORT;
- eisa_slotalloc(slot);
- tmp = inb(ia->ia_iobase + DE425_CFG0);
- irq = tulip_eisa_irqs[(tmp >> 1) & 0x03];
- /*
- * Until BSD/OS likes level interrupts, force
- * the DE425 into edge-triggered mode.
- */
- if ((tmp & 1) == 0)
- outb(ia->ia_iobase + DE425_CFG0, tmp | 1);
- /*
- * CBIO needs to map to the EISA slot
- * enable I/O access and Master
- */
- outl(ia->ia_iobase + DE425_CBIO, ia->ia_iobase);
- outl(ia->ia_iobase + DE425_CFCS, 5 | inl(ia->ia_iobase + DE425_CFCS));
- ia->ia_aux = NULL;
- break;
- }
-#endif /* TULIP_EISA */
default:
return 0;
}
static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
-#if defined(TULIP_EISA)
-static char *tulip_eisa_ids[] = {
- "DEC4250",
- NULL
-};
-#endif
-
struct cfdriver decd = {
0, "de", tulip_probe, tulip_pci_attach,
#if _BSDI_VERSION >= 199401
DV_IFNET,
#endif
sizeof(tulip_softc_t),
-#if defined(TULIP_EISA)
- tulip_eisa_ids
-#endif
};
#endif /* __bsdi__ */
revinfo = pci_inl(pa, PCI_CFRV) & 0xFF;
id = pci_inl(pa, PCI_CFID);
cfdainfo = pci_inl(pa, PCI_CFDA);
-#if defined(TULIP_EISA)
- } else {
- revinfo = inl(ia->ia_iobase + DE425_CFRV) & 0xFF;
- csroffset = TULIP_EISA_CSROFFSET;
- csrsize = TULIP_EISA_CSRSIZE;
- chipid = TULIP_DE425;
- cfdainfo = 0;
-#endif /* TULIP_EISA */
}
#else /* __bsdi__ */
revinfo = PCI_CONF_READ(PCI_CFRV) & 0xFF;
printf(": unable to map device registers\n");
return;
}
-#endif /* __NetBSD__ */
+ /* Make sure bus mastering is enabled. */
+ pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
+ pci_conf_read(pa->pa_pc, pa->pa_tag,
+ PCI_COMMAND_STATUS_REG) |
+ PCI_COMMAND_MASTER_ENABLE);
+#endif /* __NetBSD__ || __OpenBSD __ */
tulip_initcsrs(sc, csr_base + csroffset, csrsize);
tulip_initring(sc, &sc->tulip_rxinfo, sc->tulip_rxdescs, TULIP_RXDESCS);