From fb9e735cd7930718024a6d1a0b297e3ff8506a76 Mon Sep 17 00:00:00 2001 From: Constantine Sapuntzakis Date: Wed, 28 Oct 1998 23:40:43 +0000 Subject: Partial merge from netBSD 102498. Seems to fix autonegotation difficulties on Bay Networks FA310TX card. --- sys/dev/pci/if_de.c | 134 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 51 deletions(-) (limited to 'sys/dev/pci') diff --git a/sys/dev/pci/if_de.c b/sys/dev/pci/if_de.c index 9156d9fedcd..830e9407cbc 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.35 1998/10/08 05:51:18 jason Exp $ */ +/* $OpenBSD: if_de.c,v 1.36 1998/10/28 23:40:42 csapuntz Exp $ */ /* $NetBSD: if_de.c,v 1.45 1997/06/09 00:34:18 thorpej Exp $ */ /*- @@ -152,11 +152,11 @@ #define TULIP_IOMAPPED #endif -#if 0 /* * This turns on all sort of debugging stuff and make the * driver much larger. */ +#if 0 #define TULIP_DEBUG #endif @@ -434,8 +434,8 @@ tulip_linkup( * No reason to change media if we have the right media. */ tulip_reset(sc); - tulip_init(sc); } + tulip_init(sc); } static void @@ -667,7 +667,8 @@ tulip_media_poll( sc->tulip_dbg.dbg_link_failures++; #endif sc->tulip_media = TULIP_MEDIA_UNKNOWN; - tulip_reset(sc); /* restart probe */ + if (sc->tulip_if.if_flags & IFF_UP) + tulip_reset(sc); /* restart probe */ } return; } @@ -725,12 +726,14 @@ tulip_media_poll( */ if (event == TULIP_MEDIAPOLL_TXPROBE_OK || event == TULIP_MEDIAPOLL_LINKPASS) { if (event == TULIP_MEDIAPOLL_LINKPASS && - sc->tulip_chipid != TULIP_LC82C168) + sc->tulip_chipid != TULIP_LC82C168) { + /* XXX check media status just to be sure */ sc->tulip_probe_media = TULIP_MEDIA_10BASET; #if defined(TULIP_DEBUG) - else + } else { sc->tulip_dbg.dbg_txprobes_ok[sc->tulip_probe_media]++; #endif + } tulip_linkup(sc, sc->tulip_probe_media); tulip_timeout(sc); return; @@ -949,6 +952,8 @@ tulip_21040_mediainfo_init( if (media == TULIP_MEDIA_10BASET || media == TULIP_MEDIA_UNKNOWN) { TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[0], 21040, 10BASET); TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[1], 21040, 10BASET_FD); + + sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL; } if (media == TULIP_MEDIA_AUIBNC || media == TULIP_MEDIA_UNKNOWN) { @@ -1059,7 +1064,7 @@ tulip_21041_media_noprobe( 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; } static void @@ -2149,11 +2154,20 @@ tulip_crc32( const unsigned char *databuf, size_t datalen) { - u_int idx, bit, data, crc = 0xFFFFFFFFUL; + u_int idx, crc = 0xFFFFFFFFUL; + static const u_int crctab[] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + }; + + for (idx = 0; idx < datalen; idx++) { + crc ^= *databuf++; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + } - for (idx = 0; idx < datalen; idx++) - for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1) - crc = (crc >> 1) ^ (((crc ^ data) & 1) ? TULIP_CRC32_POLY : 0); return crc; } @@ -2329,7 +2343,6 @@ tulip_identify_cogent_nic( strcat(sc->tulip_boardid, "EM110TX "); sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw; #endif - sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw; } else if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100FX_ID) { strcat(sc->tulip_boardid, "EM100FX "); sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw; @@ -2360,11 +2373,13 @@ tulip_identify_accton_nic( switch (sc->tulip_chipid) { case TULIP_21140A: strcat(sc->tulip_boardid, "EN1207 "); - sc->tulip_boardsw = &tulip_21140_accton_boardsw; + if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw) + sc->tulip_boardsw = &tulip_21140_accton_boardsw; break; case TULIP_21140: strcat(sc->tulip_boardid, "EN1207TX "); - sc->tulip_boardsw = &tulip_21140_eb_boardsw; + if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw) + sc->tulip_boardsw = &tulip_21140_eb_boardsw; break; case TULIP_21040: strcat(sc->tulip_boardid, "EN1203 "); @@ -2605,7 +2620,7 @@ tulip_srom_decode( switch (type & 0x3f) { case 0: { /* 21140[A] GPR block */ tulip_media_t media; - srom_media = (tulip_srom_media_t) dp[0]; + srom_media = (tulip_srom_media_t)(dp[0] & 0x3f); for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) { if (tulip_srom_mediums[idx3].sm_srom_type == srom_media) break; @@ -2671,8 +2686,10 @@ tulip_srom_decode( mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, phyno); } if (mi->mi_phyaddr == TULIP_MII_NOPHY) { +#if defined(TULIP_DEBUG) printf(TULIP_PRINTF_FMT ": can't find phy %d\n", TULIP_PRINTF_ARGS, phyno); +#endif break; } sc->tulip_features |= TULIP_HAVE_MII; @@ -2692,7 +2709,7 @@ tulip_srom_decode( } case 2: { /* 2114[23] SIA block */ tulip_media_t media; - srom_media = (tulip_srom_media_t) dp[0]; + srom_media = (tulip_srom_media_t)(dp[0] & 0x3f); for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) { if (tulip_srom_mediums[idx3].sm_srom_type == srom_media) break; @@ -2702,10 +2719,10 @@ tulip_srom_decode( break; mi->mi_type = TULIP_MEDIAINFO_SIA; sc->tulip_mediums[media] = mi; - if (type & 0x40) { - mi->mi_sia_connectivity = dp[0] + dp[1] * 256; - mi->mi_sia_tx_rx = dp[2] + dp[3] * 256; - mi->mi_sia_general = dp[4] + dp[5] * 256; + if (dp[0] & 0x40) { + mi->mi_sia_connectivity = dp[1] + dp[2] * 256; + mi->mi_sia_tx_rx = dp[3] + dp[4] * 256; + mi->mi_sia_general = dp[5] + dp[6] * 256; dp += 6; } else { switch (media) { @@ -2719,10 +2736,12 @@ tulip_srom_decode( } case TULIP_MEDIA_10BASET: { TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, 10BASET); + sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL; break; } case TULIP_MEDIA_10BASET_FD: { TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, 10BASET_FD); + sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL; break; } default: { @@ -2730,8 +2749,8 @@ tulip_srom_decode( } } } - mi->mi_sia_gp_control = (dp[0] + dp[1] * 256) << 16; - mi->mi_sia_gp_data = (dp[2] + dp[3] * 256) << 16; + mi->mi_sia_gp_control = (dp[1] + dp[2] * 256) << 16; + mi->mi_sia_gp_data = (dp[3] + dp[4] * 256) << 16; mi++; bad_media: break; @@ -2768,8 +2787,10 @@ tulip_srom_decode( mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, phyno); } if (mi->mi_phyaddr == TULIP_MII_NOPHY) { +#if defined(TULIP_DEBUG) printf(TULIP_PRINTF_FMT ": can't find phy %d\n", TULIP_PRINTF_ARGS, phyno); +#endif break; } sc->tulip_features |= TULIP_HAVE_MII; @@ -2811,6 +2832,8 @@ tulip_srom_decode( mi->mi_actmask = TULIP_SROM_2114X_BITPOS(data); mi->mi_actdata = (data & TULIP_SROM_2114X_POLARITY) ? 0 : mi->mi_actmask; } + if (TULIP_IS_MEDIA_TP(media)) + sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL; mi++; break; } @@ -3295,6 +3318,10 @@ tulip_reset( tulip_desc_t *di; u_int32_t inreset = (sc->tulip_flags & TULIP_INRESET); +#if defined(TULIP_DEBUG) + printf ("de0: resetting...\n"); +#endif + /* * Brilliant. Simply brilliant. When switching modes/speeds * on a 2114*, you need to set the appriopriate MII/PCS/SCL/PS @@ -3314,6 +3341,7 @@ tulip_reset( sc->tulip_flags |= TULIP_INRESET; sc->tulip_flags &= ~(TULIP_NEEDRESET|TULIP_RXBUFSLOW); sc->tulip_if.if_flags &= ~IFF_OACTIVE; + sc->tulip_if.if_start = tulip_ifstart; } TULIP_CSR_WRITE(sc, csr_txlist, TULIP_KVATOPHYS(sc, &sc->tulip_txinfo.ri_first[0])); @@ -3394,7 +3422,7 @@ 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_TXUNDERFLOW|TULIP_STS_TXBABBLE|TULIP_STS_LINKFAIL + |TULIP_STS_TXUNDERFLOW|TULIP_STS_TXBABBLE |TULIP_STS_RXSTOPPED; if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0) @@ -3850,7 +3878,7 @@ tulip_print_abnormal_interrupt( const char * const *msgp = tulip_status_bits; const char *sep; u_int32_t mask; - const char thrsh[] = "72|128\0\0\096|256\0\0\0128|512\0\0160|1024\0"; + const char thrsh[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024\0"; csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1; printf(TULIP_PRINTF_FMT ": abnormal interrupt:", TULIP_PRINTF_ARGS); @@ -3897,7 +3925,7 @@ tulip_intr_handler( sc->tulip_system_errors++; break; } - if (csr & (TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL)) { + if (csr & (TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL) & sc->tulip_intrmask) { #if defined(TULIP_DEBUG) sc->tulip_dbg.dbg_link_intrs++; #endif @@ -3971,6 +3999,7 @@ tulip_intr_handler( tulip_reset(sc); tulip_init(sc); } + TULIP_PERFEND(intr); } #if defined(TULIP_USE_SOFTINTR) @@ -4141,7 +4170,7 @@ tulip_mbuf_compress( 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; @@ -4154,31 +4183,31 @@ tulip_mbuf_compress( while (len > 0) { if (mlen == MHLEN) { MGETHDR(*mp, M_DONTWAIT, MT_DATA); - } else { + } else { MGET(*mp, M_DONTWAIT, MT_DATA); - } + } if (*mp == NULL) { m_freem(m0); m0 = NULL; - break; - } + break; + } if (len > MLEN) { MCLGET(*mp, M_DONTWAIT); if (((*mp)->m_flags & M_EXT) == 0) { m_freem(m0); m0 = NULL; - break; - } + 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; @@ -4190,7 +4219,7 @@ tulip_txput( struct mbuf *m) { TULIP_PERFSTART(txput) - tulip_ringinfo_t * const ri = &sc->tulip_txinfo; + tulip_ringinfo_t * const ri = &sc->tulip_txinfo; tulip_desc_t *eop, *nextout; int segcnt, free; u_int32_t d_status; @@ -4374,6 +4403,7 @@ tulip_txput( if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) { sc->tulip_if.if_flags |= IFF_OACTIVE; + sc->tulip_if.if_start = tulip_ifstart; TULIP_PERFEND(txput); return NULL; } @@ -4382,7 +4412,6 @@ tulip_txput( * 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; @@ -4431,7 +4460,7 @@ tulip_txput_setup( sc->tulip_flags |= TULIP_WANTTXSTART; sc->tulip_if.if_start = tulip_ifstart; return; - } + } #endif /* * Try to reclaim some free descriptors.. @@ -4513,7 +4542,7 @@ tulip_ifioctl( caddr_t data) { TULIP_PERFSTART(ifioctl) - tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp); + 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; @@ -4703,6 +4732,8 @@ tulip_ifstart( break; } } + if (sc->tulip_if.if_snd.ifq_head == NULL) + sc->tulip_if.if_start = tulip_ifstart_one; } TULIP_PERFEND(ifstart); @@ -5379,18 +5410,19 @@ tulip_pci_attach( #endif /* __bsdi__ */ if (PCI_VENDORID(id) == DEC_VENDORID) { - if (PCI_CHIPID(id) == CHIPID_21040) chipid = TULIP_21040; - else if (PCI_CHIPID(id) == CHIPID_21140) { - chipid = (revinfo >= 0x20) ? TULIP_21140A : TULIP_21140; - } else if (PCI_CHIPID(id) == CHIPID_21142) { - chipid = (revinfo >= 0x20) ? TULIP_21143 : TULIP_21142; - } - else if (PCI_CHIPID(id) == CHIPID_21041) chipid = TULIP_21041; - else if (PCI_CHIPID(id) == CHIPID_21142) chipid = TULIP_21142; - } - else if (PCI_VENDOR(id) == PCI_VENDOR_LITEON && - PCI_CHIPID(id) == PCI_PRODUCT_LITEON_PNIC) + if (PCI_CHIPID(id) == CHIPID_21040) + chipid = TULIP_21040; + else if (PCI_CHIPID(id) == CHIPID_21041) + chipid = TULIP_21041; + else if (PCI_CHIPID(id) == CHIPID_21140) + chipid = (revinfo >= 0x20) ? TULIP_21140A : TULIP_21140; + else if (PCI_CHIPID(id) == CHIPID_21142) + chipid = (revinfo >= 0x20) ? TULIP_21143 : TULIP_21142; + } + if (PCI_VENDOR(id) == PCI_VENDOR_LITEON && + PCI_CHIPID(id) == PCI_PRODUCT_LITEON_PNIC) chipid = TULIP_LC82C168; + if (chipid == TULIP_CHIPID_UNKNOWN) return; @@ -5430,11 +5462,11 @@ tulip_pci_attach( sc->tulip_features |= TULIP_HAVE_POWERMGMT; if (chipid == TULIP_21041 || chipid == TULIP_21142 || chipid == TULIP_21143) { sc->tulip_features |= TULIP_HAVE_DUALSENSE; - if (chipid != TULIP_21041 || sc->tulip_revinfo >= 0x20) + if (chipid != TULIP_21041 || revinfo >= 0x20) 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) + if (chipid != TULIP_21041 && revinfo >= 0x20) sc->tulip_features |= TULIP_HAVE_SIA100; } if (chipid == TULIP_LC82C168) -- cgit v1.2.3