summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Rees <rees@cvs.openbsd.org>1997-11-13 21:14:16 +0000
committerJim Rees <rees@cvs.openbsd.org>1997-11-13 21:14:16 +0000
commita5ab1c0e08e75710d54f07e73c1adbcc7aa56a8d (patch)
treed47461259cfa2ea231dfb64f3ed335d29fef4351
parentaf2624200228954809f8ca7584e236289b4f3f53 (diff)
merge netbsd 1.56.2.1 for de500B (and other 21143) support
-rw-r--r--sys/dev/pci/if_de.c1203
1 files changed, 696 insertions, 507 deletions
diff --git a/sys/dev/pci/if_de.c b/sys/dev/pci/if_de.c
index 24a8249100b..ba8b89e629e 100644
--- a/sys/dev/pci/if_de.c
+++ b/sys/dev/pci/if_de.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_de.c,v 1.24 1997/10/20 20:56:12 pefo Exp $ */
+/* $OpenBSD: if_de.c,v 1.25 1997/11/13 21:14:15 rees Exp $ */
/* $NetBSD: if_de.c,v 1.45 1997/06/09 00:34:18 thorpej Exp $ */
/*-
@@ -177,7 +177,10 @@ static tulip_intrfunc_t tulip_intr_shared(void *arg);
static tulip_intrfunc_t tulip_intr_normal(void *arg);
static void tulip_init(tulip_softc_t * const sc);
static void tulip_reset(tulip_softc_t * const sc);
+static ifnet_ret_t tulip_ifstart_one(struct ifnet *ifp);
static ifnet_ret_t tulip_ifstart(struct ifnet *ifp);
+static struct mbuf *tulip_txput(tulip_softc_t * const sc, struct mbuf *m);
+static void tulip_txput_setup(tulip_softc_t * const sc);
static void tulip_rx_intr(tulip_softc_t * const sc);
static void tulip_addr_filter(tulip_softc_t * const sc);
static unsigned tulip_mii_readreg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno);
@@ -191,7 +194,6 @@ static void tulip_ifmedia_status(struct ifnet * const ifp, struct ifmediareq *re
#endif
/* static void tulip_21140_map_media(tulip_softc_t *sc); */
-
static void
tulip_timeout_callback(
void *arg)
@@ -239,7 +241,6 @@ tulip_fasttimeout(
}
#endif
-
static int
tulip_txprobe(
tulip_softc_t * const sc)
@@ -248,7 +249,7 @@ tulip_txprobe(
/*
* Before we are sure this is the right media we need
* to send a small packet to make sure there's carrier.
- * Strangely, BNC and AUI will 'see" receive data if
+ * Strangely, BNC and AUI will "see" receive data if
* either is connected so the transmit is the only way
* to verify the connectivity.
*/
@@ -269,15 +270,16 @@ tulip_txprobe(
* send it!
*/
sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
+ sc->tulip_intrmask |= TULIP_STS_TXINTR;
sc->tulip_flags |= TULIP_TXPROBE_ACTIVE;
TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
- IF_PREPEND(&sc->tulip_if.if_snd, m);
- tulip_ifstart(&sc->tulip_if);
+ TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
+ if ((m = tulip_txput(sc, m)) != NULL)
+ m_freem(m);
sc->tulip_probe.probe_txprobes++;
return 1;
}
-
#ifdef BIG_PACKET
#define TULIP_SIAGEN_WATCHDOG (sc->tulip_if.if_mtu > ETHERMTU ? TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE : 0)
#else
@@ -304,6 +306,7 @@ tulip_media_set(
TULIP_CSR_WRITE(sc, csr_sia_tx_rx, mi->mi_sia_tx_rx);
if (sc->tulip_features & TULIP_HAVE_SIAGP) {
TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_sia_gp_control|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
+ DELAY(50);
TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_sia_gp_data|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
} else {
TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
@@ -377,7 +380,6 @@ tulip_media_set(
}
}
-
static void
tulip_linkup(
tulip_softc_t * const sc,
@@ -423,13 +425,15 @@ tulip_linkup(
sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_TRYNWAY);
if (sc->tulip_flags & TULIP_INRESET) {
tulip_media_set(sc, sc->tulip_media);
- } else {
+ } else if (sc->tulip_probe_media != sc->tulip_media) {
+ /*
+ * No reason to change media if we have the right media.
+ */
tulip_reset(sc);
tulip_init(sc);
}
}
-
static void
tulip_media_print(
tulip_softc_t * const sc)
@@ -447,7 +451,6 @@ tulip_media_print(
}
}
-
#if defined(TULIP_DO_GPR_SENSE)
static tulip_media_t
tulip_21140_gpr_media_sense(
@@ -511,7 +514,6 @@ tulip_21140_gpr_media_sense(
}
#endif /* TULIP_DO_GPR_SENSE */
-
static tulip_link_status_t
tulip_media_link_monitor(
tulip_softc_t * const sc)
@@ -595,6 +597,10 @@ tulip_media_link_monitor(
return TULIP_LINK_UNKNOWN;
if ((TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) == 0)
linkup = TULIP_LINK_UP;
+#if defined(TULIP_DEBUG)
+ if (sc->tulip_probe_timeout <= 0)
+ printf(TULIP_PRINTF_FMT ": sia status = 0x%08x\n", TULIP_PRINTF_ARGS, TULIP_CSR_READ(sc, csr_sia_status));
+#endif
} else if (mi->mi_type == TULIP_MEDIAINFO_SYM) {
return TULIP_LINK_UNKNOWN;
}
@@ -616,7 +622,6 @@ tulip_media_link_monitor(
return TULIP_LINK_DOWN;
}
-
static void
tulip_media_poll(
tulip_softc_t * const sc,
@@ -893,6 +898,7 @@ tulip_media_poll(
}
case TULIP_MEDIAINFO_RESET:
case TULIP_MEDIAINFO_SYM:
+ case TULIP_MEDIAINFO_NONE:
case TULIP_MEDIAINFO_GPR: {
break;
}
@@ -903,7 +909,6 @@ tulip_media_poll(
tulip_txprobe(sc);
}
-
static void
tulip_media_select(
tulip_softc_t * const sc)
@@ -927,7 +932,6 @@ tulip_media_select(
}
}
-
static void
tulip_21040_mediainfo_init(
tulip_softc_t * const sc,
@@ -1022,7 +1026,6 @@ static const tulip_boardsw_t tulip_21040_auibnc_only_boardsw = {
NULL,
};
-
static void
tulip_21041_mediainfo_init(
tulip_softc_t * const sc)
@@ -1044,7 +1047,6 @@ tulip_21041_mediainfo_init(
TULIP_MEDIAINFO_SIA_INIT(sc, &mi[3], 21041, BNC);
}
-
static void
tulip_21041_media_probe(
tulip_softc_t * const sc)
@@ -1217,7 +1219,6 @@ static const tulip_boardsw_t tulip_21041_boardsw = {
tulip_21041_media_poll
};
-
static const tulip_phy_attr_t tulip_mii_phy_attrlist[] = {
{ 0x20005c00, 0, /* 08-00-17 */
{
@@ -1266,7 +1267,6 @@ static const tulip_phy_attr_t tulip_mii_phy_attrlist[] = {
{ 0 }
};
-
static tulip_media_t
tulip_mii_phy_readspecific(
tulip_softc_t * const sc)
@@ -1328,7 +1328,6 @@ tulip_mii_phy_readspecific(
return table[idx];
}
-
static unsigned
tulip_mii_get_phyaddr(
tulip_softc_t * const sc,
@@ -1353,7 +1352,6 @@ tulip_mii_get_phyaddr(
return TULIP_MII_NOPHY;
}
-
static int
tulip_mii_map_abilities(
tulip_softc_t * const sc,
@@ -1476,7 +1474,6 @@ tulip_mii_autonegotiate(
#endif
}
-
static void
tulip_2114x_media_preset(
tulip_softc_t * const sc)
@@ -1491,7 +1488,7 @@ tulip_2114x_media_preset(
sc->tulip_cmdmode &= ~TULIP_CMD_PORTSELECT;
sc->tulip_flags &= ~TULIP_SQETEST;
- if (media != TULIP_MEDIA_UNKNOWN) {
+ if (media != TULIP_MEDIA_UNKNOWN && media != TULIP_MEDIA_MAX) {
#if defined(TULIP_DEBUG)
if (media < TULIP_MEDIA_MAX && sc->tulip_mediums[media] != NULL) {
#endif
@@ -1549,13 +1546,11 @@ tulip_2114x_media_preset(
TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
}
-
/*
********************************************************************
* Start of 21140/21140A support which does not use the MII interface
*/
-
static void
tulip_null_media_poll(
tulip_softc_t * const sc,
@@ -1584,7 +1579,6 @@ tulip_21140_mediainit(
mip->mi_gpdata = gpdata;
}
-
static void
tulip_21140_evalboard_media_probe(
tulip_softc_t * const sc)
@@ -1630,6 +1624,59 @@ static const tulip_boardsw_t tulip_21140_eb_boardsw = {
tulip_2114x_media_preset,
};
+static void
+tulip_21140_accton_media_probe(
+ tulip_softc_t * const sc)
+{
+ tulip_media_info_t *mip = sc->tulip_mediainfo;
+ unsigned gpdata;
+
+ sc->tulip_gpinit = TULIP_GP_EB_PINS;
+ sc->tulip_gpdata = TULIP_GP_EB_INIT;
+ TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
+ TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT);
+ TULIP_CSR_WRITE(sc, csr_command,
+ TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
+ TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
+ TULIP_CSR_WRITE(sc, csr_command,
+ TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
+ DELAY(1000000);
+ gpdata = TULIP_CSR_READ(sc, csr_gp);
+ if ((gpdata & TULIP_GP_EN1207_UTP_INIT) == 0) {
+ sc->tulip_media = TULIP_MEDIA_10BASET;
+ } else {
+ if ((gpdata & TULIP_GP_EN1207_BNC_INIT) == 0) {
+ sc->tulip_media = TULIP_MEDIA_BNC;
+ } else {
+ sc->tulip_media = TULIP_MEDIA_100BASETX;
+ }
+ }
+ tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_BNC,
+ TULIP_GP_EN1207_BNC_INIT,
+ TULIP_CMD_TXTHRSHLDCTL);
+ tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
+ TULIP_GP_EN1207_UTP_INIT,
+ TULIP_CMD_TXTHRSHLDCTL);
+ tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
+ TULIP_GP_EN1207_UTP_INIT,
+ TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
+ tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
+ TULIP_GP_EN1207_100_INIT,
+ TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
+ |TULIP_CMD_SCRAMBLER);
+ tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
+ TULIP_GP_EN1207_100_INIT,
+ TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
+ |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
+}
+
+static const tulip_boardsw_t tulip_21140_accton_boardsw = {
+ TULIP_21140_EN1207,
+ tulip_21140_accton_media_probe,
+ tulip_media_select,
+ tulip_null_media_poll,
+ tulip_2114x_media_preset,
+};
static void
tulip_21140_smc9332_media_probe(
@@ -1687,7 +1734,6 @@ static const tulip_boardsw_t tulip_21140_smc9332_boardsw = {
tulip_2114x_media_preset,
};
-
static void
tulip_21140_cogent_em100_media_probe(
tulip_softc_t * const sc)
@@ -1735,7 +1781,6 @@ static const tulip_boardsw_t tulip_21140_cogent_em100_boardsw = {
tulip_2114x_media_preset
};
-
static void
tulip_21140_znyx_zx34x_media_probe(
tulip_softc_t * const sc)
@@ -1793,7 +1838,6 @@ static const tulip_boardsw_t tulip_21140_znyx_zx34x_boardsw = {
tulip_2114x_media_preset,
};
-
static void
tulip_2114x_media_probe(
tulip_softc_t * const sc)
@@ -1810,12 +1854,10 @@ static const tulip_boardsw_t tulip_2114x_isv_boardsw = {
tulip_2114x_media_preset,
};
-
/*
* ******** END of chip-specific handlers. ***********
*/
-
/*
* Code the read the SROM and MII bit streams (I2C)
*/
@@ -1828,7 +1870,6 @@ tulip_delay_300ns(
(void) TULIP_CSR_READ(sc, csr_busmode);
}
-
#define EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
static void
@@ -1859,7 +1900,7 @@ static void
tulip_srom_read(
tulip_softc_t * const sc)
{
- int idx;
+ unsigned idx;
const unsigned bitwidth = SROM_BITWIDTH;
const unsigned cmdmask = (SROMCMD_RD << bitwidth);
const unsigned msb = 1 << (bitwidth + 3 - 1);
@@ -1902,7 +1943,6 @@ tulip_srom_read(
tulip_srom_idle(sc);
}
-
#define MII_EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
static void
@@ -2012,10 +2052,9 @@ tulip_mii_writereg(
#endif
}
-
#define tulip_mchash(mca) (tulip_crc32(mca, 6) & 0x1FF)
#define tulip_srom_crcok(databuf) ( \
- ((tulip_crc32(databuf, 126) & 0xFFFF) ^ 0xFFFF)== \
+ ((tulip_crc32(databuf, 126) & 0xFFFFU) ^ 0xFFFFU) == \
((databuf)[126] | ((databuf)[127] << 8)))
static unsigned
@@ -2031,7 +2070,6 @@ tulip_crc32(
return crc;
}
-
static void
tulip_identify_dec_nic(
tulip_softc_t * const sc)
@@ -2048,7 +2086,6 @@ tulip_identify_dec_nic(
#undef D0
}
-
static void
tulip_identify_znyx_nic(
tulip_softc_t * const sc)
@@ -2142,7 +2179,6 @@ tulip_identify_znyx_nic(
}
}
-
static void
tulip_identify_smc_nic(
tulip_softc_t * const sc)
@@ -2159,9 +2195,9 @@ tulip_identify_smc_nic(
strcpy(&sc->tulip_boardid[4], "9332DST ");
sc->tulip_boardsw = &tulip_21140_smc9332_boardsw;
} else if (sc->tulip_features & (TULIP_HAVE_BASEROM|TULIP_HAVE_SLAVEDROM)) {
- strcpy(&sc->tulip_boardid[4], "9332BDT ");
- } else {
strcpy(&sc->tulip_boardid[4], "9334BDT ");
+ } else {
+ strcpy(&sc->tulip_boardid[4], "9332BDT ");
}
return;
}
@@ -2192,7 +2228,6 @@ tulip_identify_smc_nic(
sc->tulip_boardsw = &tulip_21040_auibnc_only_boardsw;
}
-
static void
tulip_identify_cogent_nic(
tulip_softc_t * const sc)
@@ -2224,6 +2259,33 @@ tulip_identify_cogent_nic(
}
}
+static void
+tulip_identify_accton_nic(
+ tulip_softc_t * const sc)
+{
+ strcpy(sc->tulip_boardid, "ACCTON ");
+ switch (sc->tulip_chipid) {
+ case TULIP_21140A:
+ strcat(sc->tulip_boardid, "EN1207 ");
+ sc->tulip_boardsw = &tulip_21140_accton_boardsw;
+ break;
+ case TULIP_21140:
+ strcat(sc->tulip_boardid, "EN1207TX ");
+ sc->tulip_boardsw = &tulip_21140_eb_boardsw;
+ break;
+ case TULIP_21040:
+ strcat(sc->tulip_boardid, "EN1203 ");
+ sc->tulip_boardsw = &tulip_21040_boardsw;
+ break;
+ case TULIP_21041:
+ strcat(sc->tulip_boardid, "EN1203 ");
+ sc->tulip_boardsw = &tulip_21041_boardsw;
+ break;
+ default:
+ sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
+ break;
+ }
+}
static void
tulip_identify_asante_nic(
@@ -2281,15 +2343,14 @@ tulip_identify_asante_nic(
}
}
-
static int
tulip_srom_decode(
tulip_softc_t * const sc)
{
- int idx1, idx2, idx3;
+ unsigned idx1, idx2, idx3;
- /* const */ tulip_srom_header_t *shp = (tulip_srom_header_t *) &sc->tulip_rombuf[0];
- tulip_srom_adapter_info_t *saip = (tulip_srom_adapter_info_t *) (shp + 1);
+ const tulip_srom_header_t *shp = (tulip_srom_header_t *) &sc->tulip_rombuf[0];
+ const tulip_srom_adapter_info_t *saip = (tulip_srom_adapter_info_t *) (shp + 1);
tulip_srom_media_t srom_media;
tulip_media_info_t *mi = sc->tulip_mediainfo;
const u_int8_t *dp;
@@ -2392,7 +2453,6 @@ tulip_srom_decode(
} else {
unsigned length, type;
tulip_media_t gp_media = TULIP_MEDIA_UNKNOWN;
-
if (sc->tulip_features & TULIP_HAVE_GPR)
sc->tulip_gpinit = *dp++;
blocks = *dp++;
@@ -2637,8 +2697,7 @@ tulip_srom_decode(
return mi - sc->tulip_mediainfo;
}
-
-static /* const */ struct {
+static const struct {
void (*vendor_identify_nic)(tulip_softc_t * const sc);
unsigned char vendor_oui[3];
} tulip_vendors[] = {
@@ -2649,6 +2708,7 @@ static /* const */ struct {
{ tulip_identify_znyx_nic, { 0x00, 0xC0, 0x95 } },
{ tulip_identify_cogent_nic, { 0x00, 0x00, 0x92 } },
{ tulip_identify_asante_nic, { 0x00, 0x00, 0x94 } },
+ { tulip_identify_accton_nic, { 0x00, 0x00, 0xE8 } },
{ NULL }
};
@@ -2660,7 +2720,7 @@ static int
tulip_read_macaddr(
tulip_softc_t * const sc)
{
- int cksum, rom_cksum, idx;
+ unsigned cksum, rom_cksum, idx;
u_int32_t csr;
unsigned char tmpbuf[8];
static const u_char testpat[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
@@ -2717,7 +2777,7 @@ tulip_read_macaddr(
* SROM CRC is valid therefore it must be in the
* new format.
*/
- sc->tulip_features |= TULIP_HAVE_ISVSROM;
+ sc->tulip_features |= TULIP_HAVE_ISVSROM|TULIP_HAVE_OKSROM;
} else if (sc->tulip_rombuf[126] == 0xff && sc->tulip_rombuf[127] == 0xFF) {
/*
* No checksum is present. See if the SROM id checks out;
@@ -2730,6 +2790,9 @@ tulip_read_macaddr(
}
if (idx == 18 && sc->tulip_rombuf[18] == 1 && sc->tulip_rombuf[19] != 0)
sc->tulip_features |= TULIP_HAVE_ISVSROM;
+ } else if (sc->tulip_chipid >= TULIP_21142) {
+ sc->tulip_features |= TULIP_HAVE_ISVSROM;
+ sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
}
if ((sc->tulip_features & TULIP_HAVE_ISVSROM) && tulip_srom_decode(sc)) {
if (sc->tulip_chipid != TULIP_21041)
@@ -2875,7 +2938,6 @@ tulip_read_macaddr(
return 0;
}
-
#if defined(IFM_ETHER)
static void
tulip_ifmedia_add(
@@ -2932,7 +2994,6 @@ tulip_ifmedia_change(
return 0;
}
-
/*
* Media status callback
*/
@@ -2962,7 +3023,6 @@ tulip_ifmedia_status(
}
#endif
-
static void
tulip_addr_filter(
tulip_softc_t * const sc)
@@ -2971,12 +3031,13 @@ tulip_addr_filter(
struct ether_multi *enm;
sc->tulip_flags &= ~(TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY|TULIP_ALLMULTI);
- sc->tulip_flags |= TULIP_WANTSETUP;
+ 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;
#endif
+ 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;
@@ -3001,7 +3062,7 @@ tulip_addr_filter(
while (enm != NULL) {
if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) {
hash = tulip_mchash(enm->enm_addrlo);
- sp[hash >> 4] |= FILT_SWAP(1 << (hash & 0xF));
+ sp[hash >> 4] |= 1 << (hash & 0xF);
} else {
sc->tulip_flags |= TULIP_ALLMULTI;
sc->tulip_flags &= ~(TULIP_WANTHASHONLY|TULIP_WANTHASHPERFECT);
@@ -3015,14 +3076,14 @@ tulip_addr_filter(
*/
if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) {
hash = tulip_mchash(etherbroadcastaddr);
- sp[hash >> 4] |= FILT_SWAP(1 << (hash & 0xF));
+ sp[hash >> 4] |= 1 << (hash & 0xF);
if (sc->tulip_flags & TULIP_WANTHASHONLY) {
hash = tulip_mchash(sc->tulip_enaddr);
- sp[hash >> 4] |= FILT_SWAP(1 << (hash & 0xF));
+ sp[hash >> 4] |= 1 << (hash & 0xF);
} else {
- sp[39] = FILT_SWAP(((u_int16_t *) sc->tulip_enaddr)[0]);
- sp[40] = FILT_SWAP(((u_int16_t *) sc->tulip_enaddr)[1]);
- sp[41] = FILT_SWAP(((u_int16_t *) sc->tulip_enaddr)[2]);
+ sp[39] = ((u_int16_t *) sc->tulip_enaddr)[0];
+ sp[40] = ((u_int16_t *) sc->tulip_enaddr)[1];
+ sp[41] = ((u_int16_t *) sc->tulip_enaddr)[2];
}
}
}
@@ -3036,9 +3097,9 @@ tulip_addr_filter(
ETHER_FIRST_MULTI(step, TULIP_ETHERCOM(sc), enm);
for (; enm != NULL; idx++) {
if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) {
- *sp++ = FILT_SWAP(((u_int16_t *) enm->enm_addrlo)[0]);
- *sp++ = FILT_SWAP(((u_int16_t *) enm->enm_addrlo)[1]);
- *sp++ = FILT_SWAP(((u_int16_t *) enm->enm_addrlo)[2]);
+ *sp++ = ((u_int16_t *) enm->enm_addrlo)[0];
+ *sp++ = ((u_int16_t *) enm->enm_addrlo)[1];
+ *sp++ = ((u_int16_t *) enm->enm_addrlo)[2];
} else {
sc->tulip_flags |= TULIP_ALLMULTI;
break;
@@ -3049,17 +3110,17 @@ tulip_addr_filter(
* Add the broadcast address.
*/
idx++;
- *sp++ = FILT_SWAP(0xffff);
- *sp++ = FILT_SWAP(0xffff);
- *sp++ = FILT_SWAP(0xffff);
+ *sp++ = 0xFFFF;
+ *sp++ = 0xFFFF;
+ *sp++ = 0xFFFF;
}
/*
* Pad the rest with our hardware address
*/
for (; idx < 16; idx++) {
- *sp++ = FILT_SWAP(((u_int16_t *) sc->tulip_enaddr)[0]);
- *sp++ = FILT_SWAP(((u_int16_t *) sc->tulip_enaddr)[1]);
- *sp++ = FILT_SWAP(((u_int16_t *) sc->tulip_enaddr)[2]);
+ *sp++ = ((u_int16_t *) sc->tulip_enaddr)[0];
+ *sp++ = ((u_int16_t *) sc->tulip_enaddr)[1];
+ *sp++ = ((u_int16_t *) sc->tulip_enaddr)[2];
}
}
#if defined(IFF_ALLMULTI)
@@ -3068,7 +3129,6 @@ tulip_addr_filter(
#endif
}
-
static void
tulip_reset(
tulip_softc_t * const sc)
@@ -3104,7 +3164,7 @@ tulip_reset(
(1 << (TULIP_BURSTSIZE(sc->tulip_unit) + 8))
|TULIP_BUSMODE_CACHE_ALIGN8
|TULIP_BUSMODE_READMULTIPLE
- |(BYTE_ORDER != LITTLE_ENDIAN ? (TULIP_BUSMODE_DESC_BIGENDIAN/*|TULIP_BUSMODE_BIGENDIAN*/) : 0));
+ |(BYTE_ORDER != LITTLE_ENDIAN ? TULIP_BUSMODE_BIGENDIAN : 0));
sc->tulip_txtimer = 0;
sc->tulip_txq.ifq_maxlen = TULIP_TXDESCS;
@@ -3157,7 +3217,8 @@ tulip_reset(
sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR
|TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED
- |TULIP_STS_TXBABBLE|TULIP_STS_LINKFAIL|TULIP_STS_RXSTOPPED;
+ |TULIP_STS_TXUNDERFLOW|TULIP_STS_TXBABBLE|TULIP_STS_LINKFAIL
+ |TULIP_STS_RXSTOPPED;
if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0)
(*sc->tulip_boardsw->bd_media_select)(sc);
@@ -3171,11 +3232,10 @@ tulip_reset(
TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status));
sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP|TULIP_INRESET
- |TULIP_RXACT|TULIP_TXINTPENDING);
+ |TULIP_RXACT);
tulip_addr_filter(sc);
}
-
static void
tulip_init(
tulip_softc_t * const sc)
@@ -3189,6 +3249,7 @@ tulip_init(
if (sc->tulip_if.if_flags & IFF_PROMISC) {
sc->tulip_flags |= TULIP_PROMISC;
sc->tulip_cmdmode |= TULIP_CMD_PROMISCUOUS;
+ sc->tulip_intrmask |= TULIP_STS_TXINTR;
} else {
sc->tulip_flags &= ~TULIP_PROMISC;
sc->tulip_cmdmode &= ~TULIP_CMD_PROMISCUOUS;
@@ -3208,17 +3269,16 @@ tulip_init(
sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
}
-
TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
- tulip_ifstart(&sc->tulip_if);
+ if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
+ tulip_txput_setup(sc);
} else {
sc->tulip_if.if_flags &= ~IFF_RUNNING;
tulip_reset(sc);
}
}
-
static void
tulip_rx_intr(
tulip_softc_t * const sc)
@@ -3504,9 +3564,16 @@ tulip_tx_intr(
} else {
const u_int32_t d_status = ri->ri_nextin->d_status;
IF_DEQUEUE(&sc->tulip_txq, m);
+ if (m != NULL) {
+#if NBPFILTER > 0
+ if (sc->tulip_bpf != NULL)
+ TULIP_BPF_MTAP(sc, m);
+#endif
m_freem(m);
- if (d_flag & TULIP_DFLAG_TxWANTINTR) {
- sc->tulip_flags &= ~TULIP_TXINTPENDING;
+#if defined(TULIP_DEBUG)
+ } else {
+ printf(TULIP_PRINTF_FMT ": tx_intr: failed to dequeue mbuf?!?\n", TULIP_PRINTF_ARGS);
+#endif
}
if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
tulip_mediapoll_event_t event = TULIP_MEDIAPOLL_TXPROBE_OK;
@@ -3528,11 +3595,6 @@ tulip_tx_intr(
xmits++;
if (d_status & TULIP_DSTS_ERRSUM) {
sc->tulip_if.if_oerrors++;
-
-#if defined(TULIP_DEBUG)
- printf ("Output error, status: %x, %x\n", d_status,
- TULIP_CSR_READ(sc, csr_command));
-#endif
if (d_status & TULIP_DSTS_TxEXCCOLL)
sc->tulip_dot3stats.dot3StatsExcessiveCollisions++;
if (d_status & TULIP_DSTS_TxLATECOLL)
@@ -3541,6 +3603,10 @@ tulip_tx_intr(
sc->tulip_dot3stats.dot3StatsCarrierSenseErrors++;
if (d_status & (TULIP_DSTS_TxUNDERFLOW|TULIP_DSTS_TxBABBLE))
sc->tulip_dot3stats.dot3StatsInternalMacTransmitErrors++;
+ if (d_status & TULIP_DSTS_TxUNDERFLOW)
+ sc->tulip_dot3stats.dot3StatsInternalTransmitUnderflows++;
+ if (d_status & TULIP_DSTS_TxBABBLE)
+ sc->tulip_dot3stats.dot3StatsInternalTransmitBabbles++;
} else {
u_int32_t collisions =
(d_status & TULIP_DSTS_TxCOLLMASK)
@@ -3585,7 +3651,6 @@ tulip_tx_intr(
return descs;
}
-
static void
tulip_print_abnormal_interrupt(
tulip_softc_t * const sc,
@@ -3598,7 +3663,7 @@ tulip_print_abnormal_interrupt(
csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1;
printf(TULIP_PRINTF_FMT ": abnormal interrupt:", TULIP_PRINTF_ARGS);
- for (sep = " ", mask = 1; mask >= csr; mask <<= 1, msgp++) {
+ for (sep = " ", mask = 1; mask <= csr; mask <<= 1, msgp++) {
if ((csr & mask) && *msgp != NULL) {
printf("%s%s", sep, *msgp);
if (mask == TULIP_STS_TXUNDERFLOW && (sc->tulip_flags & TULIP_NEWTXTHRESH)) {
@@ -3621,6 +3686,7 @@ tulip_intr_handler(
tulip_softc_t * const sc,
int *progress_p)
{
+ TULIP_PERFSTART(intr)
u_int32_t csr;
while ((csr = TULIP_CSR_READ(sc, csr_status)) & sc->tulip_intrmask) {
@@ -3704,7 +3770,7 @@ tulip_intr_handler(
}
TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
}
- if (sc->tulip_txinfo.ri_free < sc->tulip_txinfo.ri_max) {
+ if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_TXPROBE_ACTIVE|TULIP_DOINGSETUP|TULIP_PROMISC)) {
tulip_tx_intr(sc);
if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
tulip_ifstart(&sc->tulip_if);
@@ -3748,6 +3814,15 @@ tulip_hardintr_handler(
* mark it as needing a software interrupt
*/
tulip_softintr_mask |= (1U << sc->tulip_unit);
+
+#if defined(__NetBSD__) && NRND > 0
+ /*
+ * This isn't all that random (the value we feed in) but it is
+ * better than a constant probably. It isn't used in entropy
+ * calculation anyway, just to add something to the pool.
+ */
+ rnd_add_uint32(&sc->tulip_rndsource, sc->tulip_flags);
+#endif
}
static void
@@ -3817,10 +3892,10 @@ static tulip_intrfunc_t
tulip_intr_shared(
void *arg)
{
- tulip_softc_t * sc;
+ tulip_softc_t * sc = arg;
int progress = 0;
- for (sc = (tulip_softc_t *) arg; sc != NULL; sc = sc->tulip_slaves) {
+ for (; sc != NULL; sc = sc->tulip_slaves) {
#if defined(TULIP_DEBUG)
sc->tulip_dbg.dbg_intrs++;
#endif
@@ -3861,7 +3936,336 @@ tulip_intr_normal(
#endif
}
+static struct mbuf *
+tulip_mbuf_compress(
+ struct mbuf *m)
+{
+ struct mbuf *m0;
+#if MCLBYTES >= ETHERMTU + 18 && !defined(BIG_PACKET)
+ MGETHDR(m0, M_DONTWAIT, MT_DATA);
+ if (m0 != NULL) {
+ if (m->m_pkthdr.len > MHLEN) {
+ MCLGET(m0, M_DONTWAIT);
+ if ((m0->m_flags & M_EXT) == 0) {
+ m_freem(m);
+ m_freem(m0);
+ return NULL;
+ }
+ }
+ m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
+ m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
+ }
+#else
+ int mlen = MHLEN;
+ int len = m->m_pkthdr.len;
+ struct mbuf **mp = &m0;
+
+ while (len > 0) {
+ if (mlen == MHLEN) {
+ MGETHDR(*mp, M_DONTWAIT, MT_DATA);
+ } else {
+ MGET(*mp, M_DONTWAIT, MT_DATA);
+ }
+ if (*mp == NULL) {
+ m_freem(m0);
+ m0 = NULL;
+ break;
+ }
+ if (len > MLEN) {
+ MCLGET(*mp, M_DONTWAIT);
+ if (((*mp)->m_flags & M_EXT) == 0) {
+ m_freem(m0);
+ m0 = NULL;
+ break;
+ }
+ (*mp)->m_len = len <= MCLBYTES ? len : MCLBYTES;
+ } else {
+ (*mp)->m_len = len <= mlen ? len : mlen;
+ }
+ m_copydata(m, m->m_pkthdr.len - len,
+ (*mp)->m_len, mtod((*mp), caddr_t));
+ len -= (*mp)->m_len;
+ mp = &(*mp)->m_next;
+ mlen = MLEN;
+ }
+#endif
+ m_freem(m);
+ return m0;
+}
+
+static struct mbuf *
+tulip_txput(
+ tulip_softc_t * const sc,
+ struct mbuf *m)
+{
+ TULIP_PERFSTART(txput)
+ tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
+ tulip_desc_t *eop, *nextout;
+ int segcnt, free;
+ u_int32_t d_status;
+ struct mbuf *m0;
+
+#if defined(TULIP_DEBUG)
+ if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
+ printf(TULIP_PRINTF_FMT ": txput%s: tx not running\n",
+ TULIP_PRINTF_ARGS,
+ (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : "");
+ sc->tulip_flags |= TULIP_WANTTXSTART;
+ goto finish;
+ }
+#endif
+
+ /*
+ * Now we try to fill in our transmit descriptors. This is
+ * a bit reminiscent of going on the Ark two by two
+ * since each descriptor for the TULIP can describe
+ * two buffers. So we advance through packet filling
+ * each of the two entries at a time to to fill each
+ * descriptor. Clear the first and last segment bits
+ * in each descriptor (actually just clear everything
+ * but the end-of-ring or chain bits) to make sure
+ * we don't get messed up by previously sent packets.
+ *
+ * We may fail to put the entire packet on the ring if
+ * there is either not enough ring entries free or if the
+ * packet has more than MAX_TXSEG segments. In the former
+ * case we will just wait for the ring to empty. In the
+ * latter case we have to recopy.
+ */
+ again:
+ d_status = 0;
+ eop = nextout = ri->ri_nextout;
+ m0 = m;
+ segcnt = 0;
+ free = ri->ri_free;
+ do {
+ int len = m0->m_len;
+ caddr_t addr = mtod(m0, caddr_t);
+ unsigned clsize = CLBYTES - (((u_long) addr) & (CLBYTES-1));
+
+ while (len > 0) {
+ unsigned slen = min(len, clsize);
+#ifdef BIG_PACKET
+ int partial = 0;
+ if (slen >= 2048)
+ slen = 2040, partial = 1;
+#endif
+ segcnt++;
+ if (segcnt > TULIP_MAX_TXSEG) {
+ /*
+ * The packet exceeds the number of transmit buffer
+ * entries that we can use for one packet, so we have
+ * recopy it into one mbuf and then try again.
+ */
+ m = tulip_mbuf_compress(m);
+ if (m == NULL)
+ goto finish;
+ goto again;
+ }
+ if (segcnt & 1) {
+ if (--free == 0) {
+ /*
+ * See if there's any unclaimed space in the
+ * transmit ring.
+ */
+ if ((free += tulip_tx_intr(sc)) == 0) {
+ /*
+ * There's no more room but since nothing
+ * has been committed at this point, just
+ * show output is active, put back the
+ * mbuf and return.
+ */
+ sc->tulip_flags |= TULIP_WANTTXSTART;
+ goto finish;
+ }
+ }
+ eop = nextout;
+ if (++nextout == ri->ri_last)
+ nextout = ri->ri_first;
+ eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
+ eop->d_status = d_status;
+ eop->d_addr1 = TULIP_KVATOPHYS(sc, addr);
+ eop->d_length1 = slen;
+ } else {
+ /*
+ * Fill in second half of descriptor
+ */
+ eop->d_addr2 = TULIP_KVATOPHYS(sc, addr);
+ eop->d_length2 = slen;
+ }
+ d_status = TULIP_DSTS_OWNER;
+ len -= slen;
+ addr += slen;
+#ifdef BIG_PACKET
+ if (partial)
+ continue;
+#endif
+ clsize = CLBYTES;
+ }
+ } while ((m0 = m0->m_next) != NULL);
+
+
+ /*
+ * The descriptors have been filled in. Now get ready
+ * to transmit.
+ */
+ IF_ENQUEUE(&sc->tulip_txq, m);
+ m = NULL;
+
+ /*
+ * Make sure the next descriptor after this packet is owned
+ * by us since it may have been set up above if we ran out
+ * of room in the ring.
+ */
+ nextout->d_status = 0;
+
+ /*
+ * If we only used the first segment of the last descriptor,
+ * make sure the second segment will not be used.
+ */
+ if (segcnt & 1) {
+ eop->d_addr2 = 0;
+ eop->d_length2 = 0;
+ }
+
+ /*
+ * Mark the last and first segments, indicate we want a transmit
+ * complete interrupt, and tell it to transmit!
+ */
+ eop->d_flag |= TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR;
+
+ /*
+ * Note that ri->ri_nextout is still the start of the packet
+ * and until we set the OWNER bit, we can still back out of
+ * everything we have done.
+ */
+ ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG;
+ ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
+
+ TULIP_CSR_WRITE(sc, csr_txpoll, 1);
+
+ /*
+ * This advances the ring for us.
+ */
+ ri->ri_nextout = nextout;
+ ri->ri_free = free;
+
+ TULIP_PERFEND(txput);
+
+ if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
+ sc->tulip_if.if_flags |= IFF_OACTIVE;
+ TULIP_PERFEND(txput);
+ return NULL;
+ }
+
+ /*
+ * switch back to the single queueing ifstart.
+ */
+ sc->tulip_flags &= ~TULIP_WANTTXSTART;
+ sc->tulip_if.if_start = tulip_ifstart_one;
+ if (sc->tulip_txtimer == 0)
+ sc->tulip_txtimer = TULIP_TXTIMER;
+
+ /*
+ * If we want a txstart, there must be not enough space in the
+ * transmit ring. So we want to enable transmit done interrupts
+ * so we can immediately reclaim some space. When the transmit
+ * interrupt is posted, the interrupt handler will call tx_intr
+ * to reclaim space and then txstart (since WANTTXSTART is set).
+ * txstart will move the packet into the transmit ring and clear
+ * WANTTXSTART thereby causing TXINTR to be cleared.
+ */
+ finish:
+ if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_DOINGSETUP)) {
+ sc->tulip_if.if_flags |= IFF_OACTIVE;
+ sc->tulip_if.if_start = tulip_ifstart;
+ if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) {
+ sc->tulip_intrmask |= TULIP_STS_TXINTR;
+ TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
+ }
+ } else if ((sc->tulip_flags & TULIP_PROMISC) == 0) {
+ if (sc->tulip_intrmask & TULIP_STS_TXINTR) {
+ sc->tulip_intrmask &= ~TULIP_STS_TXINTR;
+ TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
+ }
+ }
+ TULIP_PERFEND(txput);
+ return m;
+}
+
+static void
+tulip_txput_setup(
+ tulip_softc_t * const sc)
+{
+ tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
+ tulip_desc_t *nextout;
+
+ /*
+ * We will transmit, at most, one setup packet per call to ifstart.
+ */
+
+#if defined(TULIP_DEBUG)
+ if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
+ printf(TULIP_PRINTF_FMT ": txput_setup: tx not running\n",
+ TULIP_PRINTF_ARGS);
+ sc->tulip_flags |= TULIP_WANTTXSTART;
+ sc->tulip_if.if_start = tulip_ifstart;
+ return;
+ }
+#endif
+ /*
+ * Try to reclaim some free descriptors..
+ */
+ if (ri->ri_free < 2)
+ tulip_tx_intr(sc);
+ if ((sc->tulip_flags & TULIP_DOINGSETUP) || ri->ri_free == 1) {
+ sc->tulip_flags |= TULIP_WANTTXSTART;
+ sc->tulip_if.if_start = tulip_ifstart;
+ return;
+ }
+ bcopy(sc->tulip_setupdata, sc->tulip_setupbuf,
+ sizeof(sc->tulip_setupbuf));
+ /*
+ * Clear WANTSETUP and set DOINGSETUP. Set know that WANTSETUP is
+ * set and DOINGSETUP is clear doing an XOR of the two will DTRT.
+ */
+ sc->tulip_flags ^= TULIP_WANTSETUP|TULIP_DOINGSETUP;
+ ri->ri_free--;
+ nextout = ri->ri_nextout;
+ nextout->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
+ nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG|TULIP_DFLAG_TxLASTSEG
+ |TULIP_DFLAG_TxSETUPPKT|TULIP_DFLAG_TxWANTINTR;
+ if (sc->tulip_flags & TULIP_WANTHASHPERFECT)
+ nextout->d_flag |= TULIP_DFLAG_TxHASHFILT;
+ else if (sc->tulip_flags & TULIP_WANTHASHONLY)
+ nextout->d_flag |= TULIP_DFLAG_TxHASHFILT|TULIP_DFLAG_TxINVRSFILT;
+
+ nextout->d_length1 = sizeof(sc->tulip_setupbuf);
+ nextout->d_addr1 = TULIP_KVATOPHYS(sc, sc->tulip_setupbuf);
+ nextout->d_length2 = 0;
+ nextout->d_addr2 = 0;
+
+ /*
+ * Advance the ring for the next transmit packet.
+ */
+ if (++ri->ri_nextout == ri->ri_last)
+ ri->ri_nextout = ri->ri_first;
+
+ /*
+ * Make sure the next descriptor is owned by us since it
+ * may have been set up above if we ran out of room in the
+ * ring.
+ */
+ ri->ri_nextout->d_status = 0;
+ nextout->d_status = TULIP_DSTS_OWNER;
+ TULIP_CSR_WRITE(sc, csr_txpoll, 1);
+ if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) {
+ sc->tulip_intrmask |= TULIP_STS_TXINTR;
+ TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
+ }
+}
+
/*
* This routine is entered at splnet() (splsoftnet() on NetBSD)
* and thereby imposes no problems when TULIP_USE_SOFTINTR is
@@ -3869,11 +4273,12 @@ tulip_intr_normal(
*/
static int
tulip_ifioctl(
- struct ifnet * const ifp,
+ struct ifnet * ifp,
ioctl_cmd_t cmd,
caddr_t data)
{
- tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
+ TULIP_PERFSTART(ifioctl)
+ tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
struct ifaddr *ifa = (struct ifaddr *)data;
struct ifreq *ifr = (struct ifreq *) data;
tulip_spl_t s;
@@ -3885,460 +4290,206 @@ tulip_ifioctl(
s = TULIP_RAISESPL();
#endif
switch (cmd) {
- case SIOCSIFADDR: {
- ifp->if_flags |= IFF_UP;
- switch(ifa->ifa_addr->sa_family) {
+ case SIOCSIFADDR: {
+ ifp->if_flags |= IFF_UP;
+ switch(ifa->ifa_addr->sa_family) {
#ifdef INET
- case AF_INET: {
- tulip_init(sc);
- TULIP_ARP_IFINIT(sc, ifa);
- break;
- }
+ case AF_INET: {
+ tulip_init(sc);
+ TULIP_ARP_IFINIT(sc, ifa);
+ break;
+ }
#endif /* INET */
#ifdef NS
- /*
- * This magic copied from if_is.c; I don't use XNS,
- * so I have no way of telling if this actually
- * works or not.
- */
- case AF_NS: {
- struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
- if (ns_nullhost(*ina)) {
- ina->x_host = *(union ns_host *)(sc->tulip_enaddr);
- } else {
- ifp->if_flags &= ~IFF_RUNNING;
- bcopy((caddr_t)ina->x_host.c_host,
- (caddr_t)sc->tulip_enaddr,
- sizeof(sc->tulip_enaddr));
- }
- tulip_init(sc);
- break;
- }
-#endif /* NS */
-
- default: {
- tulip_init(sc);
- break;
- }
+ /*
+ * This magic copied from if_is.c; I don't use XNS,
+ * so I have no way of telling if this actually
+ * works or not.
+ */
+ case AF_NS: {
+ struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
+ if (ns_nullhost(*ina)) {
+ ina->x_host = *(union ns_host *)(sc->tulip_enaddr);
+ } else {
+ ifp->if_flags &= ~IFF_RUNNING;
+ bcopy((caddr_t)ina->x_host.c_host,
+ (caddr_t)sc->tulip_enaddr,
+ sizeof(sc->tulip_enaddr));
}
+ tulip_init(sc);
break;
}
- case SIOCGIFADDR: {
- bcopy((caddr_t) sc->tulip_enaddr,
- (caddr_t) ((struct sockaddr *)&ifr->ifr_data)->sa_data,
- 6);
+#endif /* NS */
+
+ default: {
+ tulip_init(sc);
break;
}
+ }
+ break;
+ }
+ case SIOCGIFADDR: {
+ bcopy((caddr_t) sc->tulip_enaddr,
+ (caddr_t) ((struct sockaddr *)&ifr->ifr_data)->sa_data,
+ 6);
+ break;
+ }
- case SIOCSIFFLAGS: {
+ 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;
+ 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");
}
-#endif
- tulip_init(sc);
- break;
+ if (flags)
+ printf(TULIP_PRINTF_FMT ": ignored invalid media request\n", TULIP_PRINTF_ARGS);
}
+#endif
+ tulip_init(sc);
+ break;
+ }
#if defined(SIOCSIFMEDIA)
- case SIOCSIFMEDIA:
- case SIOCGIFMEDIA: {
- error = ifmedia_ioctl(ifp, ifr, &sc->tulip_ifmedia, cmd);
- break;
- }
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA: {
+ error = ifmedia_ioctl(ifp, ifr, &sc->tulip_ifmedia, cmd);
+ break;
+ }
#endif
- case SIOCADDMULTI:
- case SIOCDELMULTI: {
- /*
- * Update multicast listeners
- */
- if (cmd == SIOCADDMULTI)
- error = ether_addmulti(ifr, TULIP_ETHERCOM(sc));
- else
- error = ether_delmulti(ifr, TULIP_ETHERCOM(sc));
+ case SIOCADDMULTI:
+ case SIOCDELMULTI: {
+ /*
+ * Update multicast listeners
+ */
+ if (cmd == SIOCADDMULTI)
+ error = ether_addmulti(ifr, TULIP_ETHERCOM(sc));
+ else
+ error = ether_delmulti(ifr, TULIP_ETHERCOM(sc));
- if (error == ENETRESET) {
- tulip_addr_filter(sc); /* reset multicast filtering */
- tulip_init(sc);
- error = 0;
- }
- break;
+ if (error == ENETRESET) {
+ tulip_addr_filter(sc); /* reset multicast filtering */
+ tulip_init(sc);
+ error = 0;
}
+ break;
+ }
#if defined(SIOCSIFMTU)
#if !defined(ifr_mtu)
#define ifr_mtu ifr_metric
#endif
- case SIOCSIFMTU:
- /*
- * Set the interface MTU.
- */
- if (ifr->ifr_mtu > ETHERMTU
+ case SIOCSIFMTU:
+ /*
+ * Set the interface MTU.
+ */
+ if (ifr->ifr_mtu > ETHERMTU
#ifdef BIG_PACKET
- && sc->tulip_chipid != TULIP_21140
- && sc->tulip_chipid != TULIP_21140A
- && sc->tulip_chipid != TULIP_21041
+ && sc->tulip_chipid != TULIP_21140
+ && sc->tulip_chipid != TULIP_21140A
+ && sc->tulip_chipid != TULIP_21041
#endif
- ) {
- error = EINVAL;
- break;
- }
- ifp->if_mtu = ifr->ifr_mtu;
+ ) {
+ error = EINVAL;
+ break;
+ }
+ ifp->if_mtu = ifr->ifr_mtu;
#ifdef BIG_PACKET
- tulip_reset(sc);
- tulip_init(sc);
+ tulip_reset(sc);
+ tulip_init(sc);
#endif
- break;
+ break;
#endif /* SIOCSIFMTU */
#ifdef SIOCGADDRROM
- case SIOCGADDRROM: {
- error = copyout(sc->tulip_rombuf, ifr->ifr_data, sizeof(sc->tulip_rombuf));
- break;
- }
+ case SIOCGADDRROM: {
+ error = copyout(sc->tulip_rombuf, ifr->ifr_data, sizeof(sc->tulip_rombuf));
+ break;
+ }
#endif
#ifdef SIOCGCHIPID
- case SIOCGCHIPID: {
- ifr->ifr_metric = (int) sc->tulip_chipid;
- break;
- }
+ case SIOCGCHIPID: {
+ ifr->ifr_metric = (int) sc->tulip_chipid;
+ break;
+ }
#endif
- default: {
- error = EINVAL;
- break;
- }
+ default: {
+ error = EINVAL;
+ break;
+ }
}
TULIP_RESTORESPL(s);
+ TULIP_PERFEND(ifioctl);
return error;
}
-
/*
- * This routine gets called at device spl (from ether_output). This might
+ * These routines gets called at device spl (from ether_output). This might
* pose a problem for TULIP_USE_SOFTINTR if ether_output is called at
* device spl from another driver.
- */
+ */
static ifnet_ret_t
tulip_ifstart(
struct ifnet * const ifp)
{
+ TULIP_PERFSTART(ifstart)
tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
- struct ifqueue * const ifq = &ifp->if_snd;
- tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
- if ((ifp->if_flags & IFF_RUNNING) == 0
- && (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
- return;
+ if (sc->tulip_if.if_flags & IFF_RUNNING) {
- for (;;) {
- tulip_desc_t *eop, *nextout;
- int segcnt, free, recopy;
- u_int32_t d_status;
- struct mbuf *m, *m0, *next_m0;
+ if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
+ tulip_txput_setup(sc);
- if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP) {
-#if defined(TULIP_DEBUG)
- if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
- printf(TULIP_PRINTF_FMT ": ifstart: tx not running\n",
- TULIP_PRINTF_ARGS);
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
-#endif
- if ((sc->tulip_flags & TULIP_DOINGSETUP) || ri->ri_free == 1) {
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
- bcopy(sc->tulip_setupdata, sc->tulip_setupbuf,
- sizeof(sc->tulip_setupbuf));
- sc->tulip_flags &= ~TULIP_WANTSETUP;
- sc->tulip_flags |= TULIP_DOINGSETUP;
- ri->ri_free--;
- nextout = ri->ri_nextout;
- nextout->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
- nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG|TULIP_DFLAG_TxLASTSEG
- |TULIP_DFLAG_TxSETUPPKT|TULIP_DFLAG_TxWANTINTR;
- if (sc->tulip_flags & TULIP_WANTHASHPERFECT)
- nextout->d_flag |= TULIP_DFLAG_TxHASHFILT;
- else if (sc->tulip_flags & TULIP_WANTHASHONLY)
- nextout->d_flag |= TULIP_DFLAG_TxHASHFILT|TULIP_DFLAG_TxINVRSFILT;
- nextout->d_length1 = sizeof(sc->tulip_setupbuf);
- nextout->d_addr1 = TULIP_KVATOPHYS(sc, sc->tulip_setupbuf);
- nextout->d_length2 = 0;
- nextout->d_addr2 = 0;
- /*
- * Advance the ring for the next transmit packet.
- */
- if (++ri->ri_nextout == ri->ri_last)
- ri->ri_nextout = ri->ri_first;
- /*
- * Make sure the next descriptor is owned by us since it
- * may have been set up above if we ran out of room in the
- * ring.
- */
- ri->ri_nextout->d_status = 0;
- nextout->d_status = TULIP_DSTS_OWNER;
- TULIP_CSR_WRITE(sc, csr_txpoll, 1);
- }
-
- IF_DEQUEUE(ifq, m);
- if (m == NULL)
- return;
-
-#if defined(TULIP_DEBUG)
- if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
- printf(TULIP_PRINTF_FMT ": ifstart%s: tx not running\n",
- TULIP_PRINTF_ARGS,
- (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : "");
- ifp->if_flags |= IFF_OACTIVE;
- IF_PREPEND(ifq, m);
- return;
- }
-#endif
-
- /*
- * Now we try to fill in our transmit descriptors. This is
- * a bit reminiscent of going on the Ark two by two
- * since each descriptor for the TULIP can describe
- * two buffers. So we advance through packet filling
- * each of the two entries at a time to to fill each
- * descriptor. Clear the first and last segment bits
- * in each descriptor (actually just clear everything
- * but the end-of-ring or chain bits) to make sure
- * we don't get messed up by previously sent packets.
- *
- * We may fail to put the entire packet on the ring if
- * there is either not enough ring entries free or if the
- * packet has more than MAX_TXSEG segments. In the former
- * case we will just wait for the ring to empty. In the
- * latter case we have to recopy.
- */
- d_status = 0;
- recopy = 0;
- eop = nextout = ri->ri_nextout;
- m0 = m;
- segcnt = 0;
- free = ri->ri_free;
- do {
- int len = m0->m_len;
- caddr_t addr = mtod(m0, caddr_t);
- unsigned clsize = CLBYTES - (((u_long) addr) & (CLBYTES-1));
-
- next_m0 = m0->m_next;
- while (len > 0) {
- unsigned slen = min(len, clsize);
-#ifdef BIG_PACKET
- int partial = 0;
- if (slen >= 2048)
- slen = 2040, partial = 1;
-#endif
- segcnt++;
- if (segcnt > TULIP_MAX_TXSEG) {
- recopy = 1;
- next_m0 = NULL; /* to break out of outside loop */
- break;
- }
- if (segcnt & 1) {
- if (--free == 0) {
- /*
- * See if there's any unclaimed space in the
- * transmit ring.
- */
- if ((free += tulip_tx_intr(sc)) == 0) {
- /*
- * There's no more room but since nothing
- * has been committed at this point, just
- * show output is active, put back the
- * mbuf and return.
- */
- IF_PREPEND(ifq, m);
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
- }
- eop = nextout;
- if (++nextout == ri->ri_last)
- nextout = ri->ri_first;
- eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
- eop->d_status = d_status;
- eop->d_addr1 = TULIP_KVATOPHYS(sc, addr);
- eop->d_length1 = slen;
- } else {
- /*
- * Fill in second half of descriptor
- */
- eop->d_addr2 = TULIP_KVATOPHYS(sc, addr);
- eop->d_length2 = slen;
- }
- d_status = TULIP_DSTS_OWNER;
- len -= slen;
- addr += slen;
-#ifdef BIG_PACKET
- if (partial)
- continue;
-#endif
- clsize = CLBYTES;
- }
- } while ((m0 = next_m0) != NULL);
-
- /*
- * The packet exceeds the number of transmit buffer
- * entries that we can use for one packet, so we have
- * recopy it into one mbuf and then try again.
- */
- if (recopy) {
-#if MCLBYTES >= ETHERMTU + 18
- MGETHDR(m0, M_DONTWAIT, MT_DATA);
- if (m0 != NULL) {
- if (m->m_pkthdr.len > MHLEN) {
- MCLGET(m0, M_DONTWAIT);
- if ((m0->m_flags & M_EXT) == 0) {
- m_freem(m);
- m_freem(m0);
- continue;
- }
- }
- m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
- m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
- }
-#else
- int mlen = MHLEN;
- int len = m->m_pkthdr.len;
- struct mbuf **mp = &m0;
-
- while (len > 0) {
- if (mlen == MHLEN) {
- MGETHDR(*mp, M_DONTWAIT, MT_DATA);
- } else {
- MGET(*mp, M_DONTWAIT, MT_DATA);
- }
- if (*mp == NULL) {
- m_freem(m0);
- m0 = NULL;
- break;
- }
- if (len > MLEN) {
- MCLGET(*mp, M_DONTWAIT);
- if (((*mp)->m_flags & M_EXT) == 0) {
- m_freem(m0);
- m0 = NULL;
- break;
- }
- (*mp)->m_len = len <= MCLBYTES ? len : MCLBYTES;
- } else {
- (*mp)->m_len = len <= mlen ? len : mlen;
- }
- m_copydata(m, m->m_pkthdr.len - len,
- (*mp)->m_len, mtod((*mp), caddr_t));
- len -= (*mp)->m_len;
- mp = &(*mp)->m_next;
- mlen = MLEN;
- }
-#endif
- if (m0 != NULL)
- IF_PREPEND(ifq, m0);
- m_freem(m);
- continue;
- }
-
- /*
- * The descriptors have been filled in. Now get ready
- * to transmit.
- */
-#if NBPFILTER > 0
- if (sc->tulip_bpf != NULL)
- TULIP_BPF_MTAP(sc, m);
-#endif
- IF_ENQUEUE(&sc->tulip_txq, m);
-
- /*
- * Make sure the next descriptor after this packet is owned
- * by us since it may have been set up above if we ran out
- * of room in the ring.
- */
- nextout->d_status = 0;
-
- /*
- * If we only used the first segment of the last descriptor,
- * make sure the second segment will not be used.
- */
- if (segcnt & 1) {
- eop->d_addr2 = 0;
- eop->d_length2 = 0;
- }
-
- /*
- * Mark the last and first segments, indicate we want a transmit
- * complete interrupt if there isn't one queued, give the
- * descriptors to the TULIP, and tell it to transmit!
- */
- if (sc->tulip_flags & TULIP_TXINTPENDING) {
- eop->d_flag |= TULIP_DFLAG_TxLASTSEG;
-#if defined(TULIP_DEBUG)
- sc->tulip_dbg.dbg_txpipe++;
-#endif
- } else {
- eop->d_flag |= TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR;
- if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) {
- sc->tulip_flags |= TULIP_TXINTPENDING;
-#if defined(TULIP_DEBUG)
- sc->tulip_dbg.dbg_txpipestats[sc->tulip_dbg.dbg_txpipe]++;
- sc->tulip_dbg.dbg_txpipe = 0;
-#endif
+ while (sc->tulip_if.if_snd.ifq_head != NULL) {
+ struct mbuf *m;
+ IF_DEQUEUE(&sc->tulip_if.if_snd, m);
+ if ((m = tulip_txput(sc, m)) != NULL) {
+ IF_PREPEND(&sc->tulip_if.if_snd, m);
+ break;
}
}
+ }
- /*
- * Note that ri->ri_nextout is still the start of the packet
- * and until we set the OWNER bit, we can still back out of
- * everything we have done.
- */
- ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG;
- ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
-
- /*
- * This advances the ring for us.
- */
- ri->ri_nextout = nextout;
- ri->ri_free = free;
+ TULIP_PERFEND(ifstart);
+}
- TULIP_CSR_WRITE(sc, csr_txpoll, 1);
+static ifnet_ret_t
+tulip_ifstart_one(
+ struct ifnet * const ifp)
+{
+ TULIP_PERFSTART(ifstart_one)
+ tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
- if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
- if (sc->tulip_txtimer == 0)
- sc->tulip_txtimer = TULIP_TXTIMER;
+ if ((sc->tulip_if.if_flags & IFF_RUNNING)
+ && sc->tulip_if.if_snd.ifq_head != NULL) {
+ struct mbuf *m;
+ IF_DEQUEUE(&sc->tulip_if.if_snd, m);
+ if ((m = tulip_txput(sc, m)) != NULL)
+ IF_PREPEND(&sc->tulip_if.if_snd, m);
}
+ TULIP_PERFEND(ifstart_one);
}
-
/*
* Even though this routine runs at device spl, it does not break
* our use of splnet (splsoftnet under NetBSD) for the majority
@@ -4350,6 +4501,7 @@ static void
tulip_ifwatchdog(
struct ifnet *ifp)
{
+ TULIP_PERFSTART(ifwatchdog)
tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
#if defined(TULIP_DEBUG)
@@ -4396,7 +4548,30 @@ tulip_ifwatchdog(
tulip_reset(sc);
tulip_init(sc);
}
+
+ TULIP_PERFEND(ifwatchdog);
+ TULIP_PERFMERGE(sc, perf_intr_cycles);
+ TULIP_PERFMERGE(sc, perf_ifstart_cycles);
+ TULIP_PERFMERGE(sc, perf_ifioctl_cycles);
+ TULIP_PERFMERGE(sc, perf_ifwatchdog_cycles);
+ TULIP_PERFMERGE(sc, perf_timeout_cycles);
+ TULIP_PERFMERGE(sc, perf_ifstart_one_cycles);
+ TULIP_PERFMERGE(sc, perf_txput_cycles);
+ TULIP_PERFMERGE(sc, perf_txintr_cycles);
+ TULIP_PERFMERGE(sc, perf_rxintr_cycles);
+ TULIP_PERFMERGE(sc, perf_rxget_cycles);
+ TULIP_PERFMERGE(sc, perf_intr);
+ TULIP_PERFMERGE(sc, perf_ifstart);
+ TULIP_PERFMERGE(sc, perf_ifioctl);
+ TULIP_PERFMERGE(sc, perf_ifwatchdog);
+ TULIP_PERFMERGE(sc, perf_timeout);
+ TULIP_PERFMERGE(sc, perf_ifstart_one);
+ TULIP_PERFMERGE(sc, perf_txput);
+ TULIP_PERFMERGE(sc, perf_txintr);
+ TULIP_PERFMERGE(sc, perf_rxintr);
+ TULIP_PERFMERGE(sc, perf_rxget);
}
+
#if defined(__bsdi__) || (defined(__FreeBSD__) && BSD < 199506)
static ifnet_ret_t
tulip_ifwatchdog_wrapper(
@@ -4407,7 +4582,6 @@ tulip_ifwatchdog_wrapper(
#define tulip_ifwatchdog tulip_ifwatchdog_wrapper
#endif
-
/*
* All printf's are real as of now!
*/
@@ -4452,12 +4626,16 @@ tulip_attach(
#if defined(__bsdi__)
"\n"
#endif
- TULIP_PRINTF_FMT ": %s%s pass %d.%d address " TULIP_EADDR_FMT "\n",
+ TULIP_PRINTF_FMT ": %s%s pass %d.%d%s\n",
TULIP_PRINTF_ARGS,
sc->tulip_boardid,
tulip_chipdescs[sc->tulip_chipid],
(sc->tulip_revinfo & 0xF0) >> 4,
sc->tulip_revinfo & 0x0F,
+ (sc->tulip_features & (TULIP_HAVE_ISVSROM|TULIP_HAVE_OKSROM))
+ == TULIP_HAVE_ISVSROM ? " (invalid EESPROM checksum)" : "");
+ printf(TULIP_PRINTF_FMT ": address " TULIP_EADDR_FMT "\n",
+ TULIP_PRINTF_ARGS,
TULIP_EADDR_ARGS(sc->tulip_enaddr));
#endif
@@ -4514,8 +4692,12 @@ tulip_attach(
#if NBPFILTER > 0
TULIP_BPF_ATTACH(sc);
#endif
-}
+#if defined(__NetBSD__) && NRND > 0
+ rnd_attach_source(&sc->tulip_rndsource, sc->tulip_dev.dv_xname,
+ RND_TYPE_NET);
+#endif
+}
static void
tulip_initcsrs(
@@ -4544,7 +4726,6 @@ tulip_initcsrs(
#endif
}
-
static void
tulip_initring(
tulip_softc_t * const sc,
@@ -4559,7 +4740,6 @@ tulip_initring(
ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING;
}
-
/*
* This is the PCI configuration support. Since the 21040 is available
* on both EISA and PCI boards, one must be careful in how defines the
@@ -4646,7 +4826,6 @@ struct pci_device dedevice = {
DATA_SET (pcidevice_set, dedevice);
#endif /* __FreeBSD__ */
-
#if defined(__bsdi__)
#define TULIP_PCI_ATTACH_ARGS struct device * const parent, struct device * const self, void * const aux
#define TULIP_SHUTDOWN_ARGS void *arg
@@ -4831,7 +5010,6 @@ struct cfdriver de_cd = {
#endif /* __NetBSD__ */
-
static void
tulip_shutdown(
TULIP_SHUTDOWN_ARGS)
@@ -4886,7 +5064,6 @@ tulip_pci_attach(
bus_addr_t tulipbase;
bus_size_t tulipsize;
#endif
-
int retval, idx;
u_int32_t revinfo, cfdainfo, id;
#if !defined(TULIP_IOMAPPED) && defined(__FreeBSD__)
@@ -4979,6 +5156,8 @@ tulip_pci_attach(
sc->tulip_features |= TULIP_HAVE_SIANWAY;
if (chipid != TULIP_21041)
sc->tulip_features |= TULIP_HAVE_SIAGP|TULIP_HAVE_RXBADOVRFLW|TULIP_HAVE_STOREFWD;
+ if (chipid != TULIP_21041 && sc->tulip_revinfo >= 0x20)
+ sc->tulip_features |= TULIP_HAVE_SIA100;
}
if (sc->tulip_features & TULIP_HAVE_POWERMGMT
@@ -5004,12 +5183,14 @@ tulip_pci_attach(
* force a probe.
*/
switch ((cfdainfo >> 8) & 0xff) {
- case 1: sc->tulip_media = chipid > TULIP_DE425 ? TULIP_MEDIA_AUI : TULIP_MEDIA_AUIBNC;
- case 2: sc->tulip_media = chipid > TULIP_DE425 ? TULIP_MEDIA_BNC : TULIP_MEDIA_UNKNOWN;
- case 3: sc->tulip_media = TULIP_MEDIA_10BASET;
- case 4: sc->tulip_media = TULIP_MEDIA_10BASET_FD;
- case 5: sc->tulip_media = TULIP_MEDIA_100BASETX;
- case 6: sc->tulip_media = TULIP_MEDIA_100BASETX_FD;
+ case 1: media = chipid > TULIP_DE425 ?
+ TULIP_MEDIA_AUI : TULIP_MEDIA_AUIBNC; break;
+ case 2: media = chipid > TULIP_DE425 ?
+ TULIP_MEDIA_BNC : TULIP_MEDIA_UNKNOWN; break;
+ case 3: media = TULIP_MEDIA_10BASET; break;
+ case 4: media = TULIP_MEDIA_10BASET_FD; break;
+ case 5: media = TULIP_MEDIA_100BASETX; break;
+ case 6: media = TULIP_MEDIA_100BASETX_FD; break;
}
#endif
@@ -5143,25 +5324,29 @@ tulip_pci_attach(
pci_intr_handle_t intrhandle;
const char *intrstr;
+ printf("\n");
+
if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
pa->pa_intrline, &intrhandle)) {
- printf(": couldn't map interrupt\n");
+ printf("%s: couldn't map interrupt\n", sc->tulip_dev.dv_xname);
return;
}
intrstr = pci_intr_string(pa->pa_pc, intrhandle);
sc->tulip_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
intr_rtn, sc, self->dv_xname);
- if (sc->tulip_ih == NULL)
- printf(": couldn't establish interrupt");
- if (intrstr != NULL)
- printf(" at %s", intrstr);
- printf("\n");
- if (sc->tulip_ih == NULL)
+ if (sc->tulip_ih == NULL) {
+ printf("%s: couldn't establish interrupt",
+ sc->tulip_dev.dv_xname);
+ if (intrstr != NULL)
+ printf(" at %s", intrstr);
+ printf("\n");
return;
+ }
+ printf("%s: interrupting at %s\n", sc->tulip_dev.dv_xname, intrstr);
}
sc->tulip_ats = shutdownhook_establish(tulip_shutdown, sc);
if (sc->tulip_ats == NULL)
- printf("\n%s: warning: couldn't establish shutdown hook\n",
+ printf("%s: warning: couldn't establish shutdown hook\n",
sc->tulip_xname);
#endif
#if defined(__FreeBSD__)
@@ -5197,6 +5382,10 @@ tulip_pci_attach(
s = TULIP_RAISESPL();
tulip_reset(sc);
tulip_attach(sc);
+#if defined(__alpha__) && defined(__NetBSD__)
+ if (media != TULIP_MEDIA_UNKNOWN)
+ tulip_linkup(sc, media);
+#endif
TULIP_RESTORESPL(s);
}
}