--- //depot/vendor/freebsd/src/sys/pci/if_de.c 2005/07/21 16:45:20 +++ //depot/user/jhb/acpipci/pci/if_de.c 2005/07/21 16:49:16 @@ -128,6 +128,7 @@ static void tulip_reset(tulip_softc_t * const sc); static void tulip_rx_intr(tulip_softc_t * const sc); static int tulip_srom_decode(tulip_softc_t * const sc); +static void tulip_start(tulip_softc_t * const sc); static struct mbuf * tulip_txput(tulip_softc_t * const sc, struct mbuf *m); static void tulip_txput_setup(tulip_softc_t * const sc); @@ -137,26 +138,28 @@ void *arg) { tulip_softc_t * const sc = arg; - int s = splimp(); TULIP_PERFSTART(timeout) + TULIP_LOCK(sc); sc->tulip_flags &= ~TULIP_TIMEOUTPENDING; sc->tulip_probe_timeout -= 1000 / TULIP_HZ; (sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_TIMER); TULIP_PERFEND(timeout); - splx(s); + TULIP_UNLOCK(sc); } static void tulip_timeout( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); if (sc->tulip_flags & TULIP_TIMEOUTPENDING) return; sc->tulip_flags |= TULIP_TIMEOUTPENDING; - timeout(tulip_timeout_callback, sc, (hz + TULIP_HZ / 2) / TULIP_HZ); + callout_reset(&sc->tulip_callout, (hz + TULIP_HZ / 2) / TULIP_HZ, + tulip_timeout_callback, sc); } @@ -172,6 +175,7 @@ * either is connected so the transmit is the only way * to verify the connectivity. */ + TULIP_LOCK_ASSERT(sc, MA_OWNED); MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) return 0; @@ -207,6 +211,7 @@ { const tulip_media_info_t *mi = sc->tulip_mediums[media]; + TULIP_LOCK_ASSERT(sc, MA_OWNED); if (mi == NULL) return; @@ -299,9 +304,11 @@ tulip_softc_t * const sc, tulip_media_t media) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); if ((sc->tulip_flags & TULIP_LINKUP) == 0) sc->tulip_flags |= TULIP_PRINTLINKUP; sc->tulip_flags |= TULIP_LINKUP; + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags &= ~IFF_OACTIVE; #if 0 /* XXX how does with work with ifmedia? */ if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) { @@ -354,6 +361,7 @@ { struct ifnet *ifp = sc->tulip_ifp; + TULIP_LOCK_ASSERT(sc, MA_OWNED); if ((sc->tulip_flags & TULIP_LINKUP) == 0) return; if (sc->tulip_flags & TULIP_PRINTMEDIA) { @@ -376,6 +384,8 @@ tulip_media_t last_media = TULIP_MEDIA_UNKNOWN; tulip_media_t media; + TULIP_LOCK_ASSERT(sc, MA_OWNED); + /* * If one of the media blocks contained a default media flag, * use that. @@ -438,6 +448,7 @@ const tulip_media_info_t * const mi = sc->tulip_mediums[sc->tulip_media]; tulip_link_status_t linkup = TULIP_LINK_DOWN; + TULIP_LOCK_ASSERT(sc, MA_OWNED); if (mi == NULL) { #if defined(DIAGNOSTIC) || defined(TULIP_DEBUG) panic("tulip_media_link_monitor: %s: botch at line %d\n", @@ -548,6 +559,7 @@ { struct ifnet *ifp = sc->tulip_ifp; + TULIP_LOCK_ASSERT(sc, MA_OWNED); #if defined(TULIP_DEBUG) sc->tulip_dbg.dbg_events[event]++; #endif @@ -595,6 +607,7 @@ } if (event == TULIP_MEDIAPOLL_START) { + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags |= IFF_OACTIVE; if (sc->tulip_probe_state != TULIP_PROBE_INACTIVE) return; @@ -767,6 +780,7 @@ if (++sc->tulip_probe_passes == 3) { if_printf(ifp, "autosense failed: cable problem?\n"); if ((sc->tulip_ifp->if_flags & IFF_UP) == 0) { + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags &= ~IFF_RUNNING; sc->tulip_probe_state = TULIP_PROBE_INACTIVE; return; @@ -835,6 +849,7 @@ tulip_media_select( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); if (sc->tulip_features & TULIP_HAVE_GPR) { TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit); DELAY(10); @@ -859,6 +874,7 @@ tulip_softc_t * const sc, tulip_media_t media) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160 |TULIP_CMD_BACKOFFCTR; sc->tulip_ifp->if_baudrate = 10000000; @@ -882,6 +898,7 @@ tulip_21040_media_probe( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); tulip_21040_mediainfo_init(sc, TULIP_MEDIA_UNKNOWN); return; } @@ -890,6 +907,7 @@ tulip_21040_10baset_only_media_probe( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); tulip_21040_mediainfo_init(sc, TULIP_MEDIA_10BASET); tulip_media_set(sc, TULIP_MEDIA_10BASET); sc->tulip_media = TULIP_MEDIA_10BASET; @@ -899,6 +917,7 @@ tulip_21040_10baset_only_media_select( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_flags |= TULIP_LINKUP; if (sc->tulip_media == TULIP_MEDIA_10BASET_FD) { sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX; @@ -914,6 +933,7 @@ tulip_21040_auibnc_only_media_probe( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); tulip_21040_mediainfo_init(sc, TULIP_MEDIA_AUIBNC); sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP; tulip_media_set(sc, TULIP_MEDIA_AUIBNC); @@ -924,6 +944,7 @@ tulip_21040_auibnc_only_media_select( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); tulip_media_set(sc, TULIP_MEDIA_AUIBNC); sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX; } @@ -955,6 +976,7 @@ { tulip_media_info_t * const mi = sc->tulip_mediainfo; + TULIP_LOCK_ASSERT(sc, MA_OWNED); #ifdef notyet if (sc->tulip_revinfo >= 0x20) { TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041P2, 10BASET); @@ -974,6 +996,7 @@ tulip_21041_media_probe( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_ifp->if_baudrate = 10000000; sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_ENHCAPTEFFCT |TULIP_CMD_THRSHLD160|TULIP_CMD_BACKOFFCTR; @@ -988,6 +1011,7 @@ { u_int32_t sia_status; + TULIP_LOCK_ASSERT(sc, MA_OWNED); #if defined(TULIP_DEBUG) sc->tulip_dbg.dbg_events[event]++; #endif @@ -1006,6 +1030,7 @@ * restart the probe (and reset the tulip to a known state). */ if (event == TULIP_MEDIAPOLL_START) { + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags |= IFF_OACTIVE; sc->tulip_cmdmode &= ~(TULIP_CMD_FULLDUPLEX|TULIP_CMD_RXRUN); #ifdef notyet @@ -1113,6 +1138,7 @@ if_printf(sc->tulip_ifp, "autosense failed: cable problem?\n"); if ((sc->tulip_ifp->if_flags & IFF_UP) == 0) { + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags &= ~IFF_RUNNING; sc->tulip_probe_state = TULIP_PROBE_INACTIVE; return; @@ -1209,6 +1235,8 @@ TULIP_MEDIA_UNKNOWN }; + TULIP_LOCK_ASSERT(sc, MA_OWNED); + /* * Don't read phy specific registers if link is not up. */ @@ -1258,6 +1286,7 @@ { unsigned phyaddr; + TULIP_LOCK_ASSERT(sc, MA_OWNED); for (phyaddr = 1; phyaddr < 32; phyaddr++) { unsigned status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS); if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET) @@ -1280,6 +1309,7 @@ tulip_softc_t * const sc, unsigned abilities) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_abilities = abilities; if (abilities & PHYSTS_100BASETX_FD) { sc->tulip_probe_media = TULIP_MEDIA_100BASETX_FD; @@ -1306,6 +1336,7 @@ { struct ifnet *ifp = sc->tulip_ifp; + TULIP_LOCK_ASSERT(sc, MA_OWNED); switch (sc->tulip_probe_state) { case TULIP_PROBE_MEDIATEST: case TULIP_PROBE_INACTIVE: { @@ -1328,6 +1359,7 @@ ifp->if_xname, phyaddr); sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE; sc->tulip_probe_state = TULIP_PROBE_FAILED; + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags &= ~(IFF_UP|IFF_RUNNING); return; } @@ -1406,6 +1438,7 @@ const tulip_media_info_t *mi = NULL; tulip_media_t media = sc->tulip_media; + TULIP_LOCK_ASSERT(sc, MA_OWNED); if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE) media = sc->tulip_media; else @@ -1496,6 +1529,7 @@ unsigned gpdata, unsigned cmdmode) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_mediums[media] = mip; mip->mi_type = TULIP_MEDIAINFO_GPR; mip->mi_cmdmode = cmdmode; @@ -1508,6 +1542,7 @@ { tulip_media_info_t *mip = sc->tulip_mediainfo; + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_gpinit = TULIP_GP_EB_PINS; sc->tulip_gpdata = TULIP_GP_EB_INIT; TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS); @@ -1554,6 +1589,7 @@ tulip_media_info_t *mip = sc->tulip_mediainfo; unsigned gpdata; + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_gpinit = TULIP_GP_EB_PINS; sc->tulip_gpdata = TULIP_GP_EB_INIT; TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS); @@ -1608,6 +1644,7 @@ tulip_media_info_t *mip = sc->tulip_mediainfo; int idx, cnt = 0; + TULIP_LOCK_ASSERT(sc, MA_OWNED); TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT|TULIP_CMD_MUSTBEONE); TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at @@ -1664,6 +1701,7 @@ tulip_media_info_t *mip = sc->tulip_mediainfo; u_int32_t cmdmode = TULIP_CSR_READ(sc, csr_command); + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_gpinit = TULIP_GP_EM100_PINS; sc->tulip_gpdata = TULIP_GP_EM100_INIT; TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS); @@ -1711,6 +1749,7 @@ tulip_media_info_t *mip = sc->tulip_mediainfo; int cnt10 = 0, cnt100 = 0, idx; + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_gpinit = TULIP_GP_ZX34X_PINS; sc->tulip_gpdata = TULIP_GP_ZX34X_INIT; TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS); @@ -1765,6 +1804,7 @@ tulip_2114x_media_probe( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_cmdmode |= TULIP_CMD_MUSTBEONE |TULIP_CMD_BACKOFFCTR|TULIP_CMD_THRSHLD72; } @@ -1869,6 +1909,7 @@ unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); unsigned lastbit = (csr & MII_DOUT) ? msb : 0; + TULIP_LOCK_ASSERT(sc, MA_OWNED); csr |= MII_WR; MII_EMIT; /* clock low; assert write */ for (; bits > 0; bits--, data <<= 1) { @@ -1889,6 +1930,7 @@ { unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); + TULIP_LOCK_ASSERT(sc, MA_OWNED); if (cmd == MII_WRCMD) { csr |= MII_DOUT; MII_EMIT; /* clock low; change data */ csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */ @@ -1909,6 +1951,7 @@ unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); int idx; + TULIP_LOCK_ASSERT(sc, MA_OWNED); for (idx = 0, data = 0; idx < 16; idx++) { data <<= 1; /* this is NOOP on the first pass through */ csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */ @@ -1930,6 +1973,7 @@ unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); unsigned data; + TULIP_LOCK_ASSERT(sc, MA_OWNED); csr &= ~(MII_RD|MII_CLK); MII_EMIT; tulip_mii_writebits(sc, MII_PREAMBLE, 32); tulip_mii_writebits(sc, MII_RDCMD, 8); @@ -1953,6 +1997,8 @@ unsigned data) { unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); + + TULIP_LOCK_ASSERT(sc, MA_OWNED); csr &= ~(MII_RD|MII_CLK); MII_EMIT; tulip_mii_writebits(sc, MII_PREAMBLE, 32); tulip_mii_writebits(sc, MII_WRCMD, 8); @@ -1975,6 +2021,7 @@ tulip_identify_dec_nic( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); strcpy(sc->tulip_boardid, "DEC "); #define D0 4 if (sc->tulip_chipid <= TULIP_21040) @@ -1992,6 +2039,8 @@ tulip_softc_t * const sc) { unsigned id = 0; + + TULIP_LOCK_ASSERT(sc, MA_OWNED); strcpy(sc->tulip_boardid, "ZNYX ZX3XX "); if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) { unsigned znyx_ptr; @@ -2088,6 +2137,7 @@ int auibnc = 0, utp = 0; char *cp; + TULIP_LOCK_ASSERT(sc, MA_OWNED); strcpy(sc->tulip_boardid, "SMC "); if (sc->tulip_chipid == TULIP_21041) return; @@ -2133,6 +2183,7 @@ tulip_identify_cogent_nic( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); strcpy(sc->tulip_boardid, "Cogent "); if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) { if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100TX_ID) { @@ -2169,6 +2220,7 @@ tulip_identify_accton_nic( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); strcpy(sc->tulip_boardid, "ACCTON "); switch (sc->tulip_chipid) { case TULIP_21140A: @@ -2199,6 +2251,7 @@ tulip_identify_asante_nic( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); strcpy(sc->tulip_boardid, "Asante "); if ((sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) && sc->tulip_boardsw != &tulip_2114x_isv_boardsw) { @@ -2255,6 +2308,7 @@ tulip_identify_compex_nic( tulip_softc_t * const sc) { + TULIP_LOCK_ASSERT(sc, MA_OWNED); strcpy(sc->tulip_boardid, "COMPEX "); if (sc->tulip_chipid == TULIP_21140A) { int root_unit; @@ -2265,6 +2319,10 @@ * All 4 chips on these boards share an interrupt. This code * copied from tulip_read_macaddr. */ + /* + * XXX: Need to lock the slave list here, maybe using the root_sc's + * lock? + */ sc->tulip_features |= TULIP_HAVE_SHAREDINTR; for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) { root_sc = tulips[root_unit]; @@ -2303,6 +2361,7 @@ const u_int8_t *dp; u_int32_t leaf_offset, blocks, data; + TULIP_LOCK_ASSERT(sc, MA_OWNED); for (idx1 = 0; idx1 < shp->sh_adapter_count; idx1++, saip++) { if (shp->sh_adapter_count == 1) break; @@ -2791,6 +2850,7 @@ if (idx == sizeof(sc->tulip_rombuf)) { int root_unit; tulip_softc_t *root_sc = NULL; + /* XXX: root_sc locking again */ for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) { root_sc = tulips[root_unit]; if (root_sc == NULL || (root_sc->tulip_features & (TULIP_HAVE_OKROM|TULIP_HAVE_SLAVEDROM)) == TULIP_HAVE_OKROM) @@ -2882,6 +2942,7 @@ tulip_media_t media; int medias = 0; + TULIP_LOCK_ASSERT(sc, MA_OWNED); for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) { if (sc->tulip_mediums[media] != NULL) { ifmedia_add(&sc->tulip_ifmedia, tulip_media_to_ifmedia[media], @@ -2909,6 +2970,7 @@ { tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc; + TULIP_LOCK(sc); sc->tulip_flags |= TULIP_NEEDRESET; sc->tulip_probe_state = TULIP_PROBE_INACTIVE; sc->tulip_media = TULIP_MEDIA_UNKNOWN; @@ -2920,6 +2982,7 @@ sc->tulip_flags |= TULIP_PRINTMEDIA; sc->tulip_flags &= ~TULIP_DIDNWAY; tulip_linkup(sc, media); + TULIP_UNLOCK(sc); return 0; } } @@ -2927,6 +2990,7 @@ sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_WANTRXACT); tulip_reset(sc); tulip_init(sc); + TULIP_UNLOCK(sc); return 0; } @@ -2940,14 +3004,18 @@ { tulip_softc_t *sc = (tulip_softc_t *)ifp->if_softc; - if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) + TULIP_LOCK(sc); + if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) { + TULIP_UNLOCK(sc); return; + } req->ifm_status = IFM_AVALID; if (sc->tulip_flags & TULIP_LINKUP) req->ifm_status |= IFM_ACTIVE; req->ifm_active = tulip_media_to_ifmedia[sc->tulip_media]; + TULIP_UNLOCK(sc); } static void @@ -2958,6 +3026,7 @@ u_char *addrp; int multicnt; + TULIP_LOCK_ASSERT(sc, MA_OWNED); sc->tulip_flags &= ~(TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY|TULIP_ALLMULTI); sc->tulip_flags |= TULIP_WANTSETUP|TULIP_WANTTXSTART; sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN; @@ -2968,6 +3037,7 @@ #endif multicnt = 0; + /* XXX: ifnet locking */ TAILQ_FOREACH(ifma, &sc->tulip_ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family == AF_LINK) @@ -2995,38 +3065,33 @@ */ bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata)); + /* XXX: ifnet locking */ TAILQ_FOREACH(ifma, &sc->tulip_ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; hash = tulip_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); -#if BYTE_ORDER == BIG_ENDIAN - sp[hash >> 4] |= bswap32(1 << (hash & 0xF)); -#else - sp[hash >> 4] |= 1 << (hash & 0xF); -#endif + sp[hash >> 4] |= htole32(1 << (hash & 0xF)); } /* * No reason to use a hash if we are going to be * receiving every multicast. */ if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) { + /* XXX: ifnet locking */ hash = tulip_mchash(sc->tulip_ifp->if_broadcastaddr); -#if BYTE_ORDER == BIG_ENDIAN - sp[hash >> 4] |= bswap32(1 << (hash & 0xF)); -#else - sp[hash >> 4] |= 1 << (hash & 0xF); -#endif + sp[hash >> 4] |= htole32(1 << (hash & 0xF)); if (sc->tulip_flags & TULIP_WANTHASHONLY) { hash = tulip_mchash(IFP2ENADDR(sc->tulip_ifp)); -#if BYTE_ORDER == BIG_ENDIAN - sp[hash >> 4] |= bswap32(1 << (hash & 0xF)); -#else - sp[hash >> 4] |= 1 << (hash & 0xF); -#endif + sp[hash >> 4] |= htole32(1 << (hash & 0xF)); } else { #if BYTE_ORDER == BIG_ENDIAN + /* + * I'm pretty sure this is wrong and should be using + * htole32() since we run the chip in little endian but + * use big endian for the descriptors. + */ sp[39] = ((u_int16_t *) IFP2ENADDR(sc->tulip_ifp))[0] << 16; sp[40] = ((u_int16_t *) IFP2ENADDR(sc->tulip_ifp))[1] << 16; sp[41] = ((u_int16_t *) IFP2ENADDR(sc->tulip_ifp))[2] << 16; @@ -3045,6 +3110,7 @@ /* * Else can get perfect filtering for 16 addresses. */ + /* XXX: ifnet locking */ TAILQ_FOREACH(ifma, &sc->tulip_ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -3091,6 +3157,7 @@ } #if defined(IFF_ALLMULTI) if (sc->tulip_flags & TULIP_ALLMULTI) + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags |= IFF_ALLMULTI; #endif } @@ -3103,6 +3170,8 @@ tulip_desc_t *di; u_int32_t inreset = (sc->tulip_flags & TULIP_INRESET); + TULIP_LOCK_ASSERT(sc, MA_OWNED); + /* * Brilliant. Simply brilliant. When switching modes/speeds * on a 2114*, you need to set the appriopriate MII/PCS/SCL/PS @@ -3122,6 +3191,7 @@ if (!inreset) { sc->tulip_flags |= TULIP_INRESET; sc->tulip_flags &= ~(TULIP_NEEDRESET|TULIP_RXBUFSLOW); + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags &= ~IFF_OACTIVE; } @@ -3242,9 +3312,13 @@ static void tulip_ifinit( - void * sc) + void *arg) { - tulip_init((tulip_softc_t *)sc); + tulip_softc_t *sc = (tulip_softc_t *)arg; + + TULIP_LOCK(sc); + tulip_init(sc); + TULIP_UNLOCK(sc); } static void @@ -3256,6 +3330,7 @@ /* initialize the media */ tulip_reset(sc); } + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags |= IFF_RUNNING; if (sc->tulip_ifp->if_flags & IFF_PROMISC) { sc->tulip_flags |= TULIP_PROMISC; @@ -3276,6 +3351,7 @@ sc->tulip_cmdmode |= TULIP_CMD_RXRUN; sc->tulip_intrmask |= TULIP_STS_RXSTOPPED; } else { + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags |= IFF_OACTIVE; sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN; sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; @@ -3285,6 +3361,7 @@ if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP) tulip_txput_setup(sc); } else { + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags &= ~IFF_RUNNING; tulip_reset(sc); } @@ -3302,6 +3379,7 @@ int cnt = 0; #endif + TULIP_LOCK_ASSERT(sc, MA_OWNED); for (;;) { TULIP_PERFSTART(rxget) tulip_desc_t *eop = ri->ri_nextin; @@ -3499,6 +3577,7 @@ && m0 != NULL #endif ) { + TULIP_UNLOCK(sc); #if !defined(TULIP_COPY_RXDATA) ms->m_pkthdr.len = total_len; ms->m_pkthdr.rcvif = ifp; @@ -3511,6 +3590,7 @@ (*ifp->if_input)(ifp, m0); m0 = ms; #endif /* ! TULIP_COPY_RXDATA */ + TULIP_LOCK(sc); } ms = m0; } @@ -3597,6 +3677,7 @@ int xmits = 0; int descs = 0; + TULIP_LOCK_ASSERT(sc, MA_OWNED); while (ri->ri_free < ri->ri_max) { u_int32_t d_flag; @@ -3704,6 +3785,7 @@ ri->ri_nextin = ri->ri_first; if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags &= ~IFF_OACTIVE; } /* @@ -3729,6 +3811,7 @@ u_int32_t mask; const char thrsh[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024"; + TULIP_LOCK_ASSERT(sc, MA_OWNED); csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1; if_printf(sc->tulip_ifp, "abnormal interrupt:"); for (sep = " ", mask = 1; mask <= csr; mask <<= 1, msgp++) { @@ -3756,6 +3839,7 @@ TULIP_PERFSTART(intr) u_int32_t csr; + TULIP_LOCK_ASSERT(sc, MA_OWNED); while ((csr = TULIP_CSR_READ(sc, csr_status)) & sc->tulip_intrmask) { TULIP_CSR_WRITE(sc, csr_status, csr); @@ -3834,8 +3918,9 @@ } 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_ifp); + if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0 && + (sc->tulip_ifp->if_flags & IFF_RUNNING)) + tulip_start(sc); } } if (sc->tulip_flags & TULIP_NEEDRESET) { @@ -3851,11 +3936,14 @@ { tulip_softc_t * sc = arg; + /* XXX: have to do locking for slave lists */ for (; sc != NULL; sc = sc->tulip_slaves) { + TULIP_LOCK(sc); #if defined(TULIP_DEBUG) sc->tulip_dbg.dbg_intrs++; #endif tulip_intr_handler(sc); + TULIP_UNLOCK(sc); } } @@ -3865,10 +3953,12 @@ { tulip_softc_t * sc = (tulip_softc_t *) arg; + TULIP_LOCK(sc); #if defined(TULIP_DEBUG) sc->tulip_dbg.dbg_intrs++; #endif tulip_intr_handler(sc); + TULIP_UNLOCK(sc); } static struct mbuf * @@ -3946,6 +4036,7 @@ struct mbuf *m0; #endif + TULIP_LOCK_ASSERT(sc, MA_OWNED); #if defined(TULIP_DEBUG) if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) { if_printf(sc->tulip_ifp, "txput%s: tx not running\n", @@ -4203,6 +4294,7 @@ if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) { TULIP_CSR_WRITE(sc, csr_txpoll, 1); + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags |= IFF_OACTIVE; TULIP_PERFEND(txput); return NULL; @@ -4232,6 +4324,7 @@ sc->tulip_dbg.dbg_txput_finishes[6]++; #endif if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_DOINGSETUP)) { + /* XXX: ifnet locking */ sc->tulip_ifp->if_flags |= IFF_OACTIVE; if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) { sc->tulip_intrmask |= TULIP_STS_TXINTR; @@ -4254,7 +4347,9 @@ { tulip_ringinfo_t * const ri = &sc->tulip_txinfo; tulip_desc_t *nextout; - + + TULIP_LOCK_ASSERT(sc, MA_OWNED); + /* * We will transmit, at most, one setup packet per call to ifstart. */ @@ -4343,14 +4438,14 @@ TULIP_PERFSTART(ifioctl) tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; - int s; int error = 0; - s = splimp(); switch (cmd) { case SIOCSIFFLAGS: { + TULIP_LOCK(sc); tulip_addr_filter(sc); /* reinit multicast filter */ tulip_init(sc); + TULIP_UNLOCK(sc); break; } @@ -4365,8 +4460,10 @@ /* * Update multicast listeners */ + TULIP_LOCK(sc); tulip_addr_filter(sc); /* reset multicast filtering */ tulip_init(sc); + TULIP_UNLOCK(sc); error = 0; break; } @@ -4375,11 +4472,14 @@ /* * Set the interface MTU. */ + TULIP_LOCK(sc); if (ifr->ifr_mtu > ETHERMTU) { error = EINVAL; break; } + /* XXX: ifnet locking? */ ifp->if_mtu = ifr->ifr_mtu; + TULIP_UNLOCK(sc); break; #ifdef SIOCGADDRROM @@ -4400,7 +4500,6 @@ } } - splx(s); TULIP_PERFEND(ifioctl); return error; } @@ -4412,24 +4511,34 @@ TULIP_PERFSTART(ifstart) tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc; - if (sc->tulip_ifp->if_flags & IFF_RUNNING) { + if (ifp->if_flags & IFF_RUNNING) { + TULIP_LOCK(sc); + tulip_start(sc); + TULIP_UNLOCK(sc); + } + + TULIP_PERFEND(ifstart); +} + +static void +tulip_start(tulip_softc_t * const sc) +{ + struct mbuf *m; + + TULIP_LOCK_ASSERT(sc, MA_OWNED); - 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) + tulip_txput_setup(sc); - while (!IFQ_DRV_IS_EMPTY(&sc->tulip_ifp->if_snd)) { - struct mbuf *m; - IFQ_DRV_DEQUEUE(&sc->tulip_ifp->if_snd, m); - if(m == NULL) - break; - if ((m = tulip_txput(sc, m)) != NULL) { - IFQ_DRV_PREPEND(&sc->tulip_ifp->if_snd, m); - break; - } + while (!IFQ_DRV_IS_EMPTY(&sc->tulip_ifp->if_snd)) { + IFQ_DRV_DEQUEUE(&sc->tulip_ifp->if_snd, m); + if(m == NULL) + break; + if ((m = tulip_txput(sc, m)) != NULL) { + IFQ_DRV_PREPEND(&sc->tulip_ifp->if_snd, m); + break; } } - - TULIP_PERFEND(ifstart); } /* @@ -4445,14 +4554,19 @@ { TULIP_PERFSTART(ifwatchdog) tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc; +#if defined(TULIP_DEBUG) + u_int32_t rxintrs; +#endif + TULIP_LOCK(sc); #if defined(TULIP_DEBUG) - u_int32_t rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs; + rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs; if (rxintrs > sc->tulip_dbg.dbg_high_rxintrs_hz) sc->tulip_dbg.dbg_high_rxintrs_hz = rxintrs; sc->tulip_dbg.dbg_last_rxintrs = sc->tulip_dbg.dbg_rxintrs; #endif /* TULIP_DEBUG */ + /* XXX: ifnet locking */ sc->tulip_ifp->if_timer = 1; /* * These should be rare so do a bulk test up front so we can just skip @@ -4512,6 +4626,7 @@ TULIP_PERFMERGE(sc, perf_txintr); TULIP_PERFMERGE(sc, perf_rxintr); TULIP_PERFMERGE(sc, perf_rxget); + TULIP_UNLOCK(sc); } /* @@ -4532,12 +4647,15 @@ /* XXX: driver name/unit should be set some other way */ if_initname(ifp, "de", sc->tulip_unit); ifp->if_softc = sc; - ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_NEEDSGIANT; + ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST; ifp->if_ioctl = tulip_ifioctl; ifp->if_start = tulip_ifstart; ifp->if_watchdog = tulip_ifwatchdog; ifp->if_timer = 1; ifp->if_init = tulip_ifinit; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; + IFQ_SET_READY(&ifp->if_snd); if_printf(ifp, "%s%s pass %d.%d%s\n", sc->tulip_boardid, @@ -4547,6 +4665,7 @@ (sc->tulip_features & (TULIP_HAVE_ISVSROM|TULIP_HAVE_OKSROM)) == TULIP_HAVE_ISVSROM ? " (invalid EESPROM checksum)" : ""); + TULIP_LOCK(sc); #if defined(__alpha__) /* * In case the SRM console told us about a bogus media, @@ -4564,11 +4683,9 @@ tulip_ifmedia_add(sc); tulip_reset(sc); + TULIP_UNLOCK(sc); ether_ifattach(sc->tulip_ifp, sc->tulip_enaddr); - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); } #if defined(TULIP_BUS_DMA) @@ -4916,6 +5033,9 @@ sc->tulip_csrs_bsh = rman_get_bushandle(res); csr_base = 0; + mtx_init(TULIP_MUTEX(sc), MTX_NETWORK_LOCK, device_get_nameunit(dev), + MTX_DEF); + callout_init(&sc->tulip_callout, CALLOUT_MPSAFE); tulips[unit] = sc; tulip_initcsrs(sc, csr_base + csroffset, csrsize); @@ -4923,6 +5043,7 @@ #if defined(TULIP_BUS_DMA) if ((retval = tulip_busdma_init(sc)) != 0) { printf("error initing bus_dma: %d\n", retval); + mtx_destroy(TULIP_MUTEX(sc)); return ENXIO; } #else @@ -4934,6 +5055,7 @@ free((caddr_t) sc->tulip_rxdescs, M_DEVBUF); if (sc->tulip_txdescs) free((caddr_t) sc->tulip_txdescs, M_DEVBUF); + mtx_destroy(TULIP_MUTEX(sc)); return ENXIO; } #endif @@ -4949,7 +5071,10 @@ 33MHz that comes to two microseconds but wait a bit longer anyways) */ - if ((retval = tulip_read_macaddr(sc)) < 0) { + TULIP_LOCK(sc); + retval = tulip_read_macaddr(sc); + TULIP_UNLOCK(sc); + if (retval < 0) { device_printf(dev, "can't read ENET ROM (why=%d) (", retval); for (idx = 0; idx < 32; idx++) printf("%02x", sc->tulip_rombuf[idx]); @@ -4959,37 +5084,41 @@ (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F); device_printf(dev, "address unknown\n"); } else { - int s; void (*intr_rtn)(void *) = tulip_intr_normal; if (sc->tulip_features & TULIP_HAVE_SHAREDINTR) intr_rtn = tulip_intr_shared; +#if defined(__alpha__) + sc->tulip_media = media; +#endif + tulip_attach(sc); + + /* Setup interrupt last. */ if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) { void *ih; rid = 0; res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); - if (res == 0 || bus_setup_intr(dev, res, INTR_TYPE_NET, - intr_rtn, sc, &ih)) { + if (res == 0 || bus_setup_intr(dev, res, INTR_TYPE_NET | + INTR_MPSAFE, intr_rtn, sc, &ih)) { device_printf(dev, "couldn't map interrupt\n"); free((caddr_t) sc->tulip_rxdescs, M_DEVBUF); free((caddr_t) sc->tulip_txdescs, M_DEVBUF); + ether_ifdetach(sc->tulip_ifp); + if_free(sc->tulip_ifp); + mtx_destroy(TULIP_MUTEX(sc)); return ENXIO; } } - s = splimp(); -#if defined(__alpha__) - sc->tulip_media = media; -#endif - tulip_attach(sc); -#if defined(__alpha__) +#if defined(__alpha__) + TULIP_LOCK(sc); if (sc->tulip_media != TULIP_MEDIA_UNKNOWN) tulip_linkup(sc, media); + TULIP_UNLOCK(sc); #endif - splx(s); } return 0; } --- //depot/vendor/freebsd/src/sys/pci/if_devar.h 2005/07/21 16:40:32 +++ //depot/user/jhb/acpipci/pci/if_devar.h 2005/07/21 16:49:16 @@ -582,6 +582,8 @@ tulip_srom_connection_t tulip_conntype; tulip_desc_t *tulip_rxdescs; tulip_desc_t *tulip_txdescs; + struct callout tulip_callout; + struct mtx tulip_mutex; }; #define tulip_curperfstats tulip_perfstats[TULIP_PERF_CURRENT] @@ -865,6 +867,7 @@ TULIP_DATA_PER_DESC, 0, \ BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, (mapp)) #else +/* XXX: should be using bus_space_barrier() here. */ #ifdef __alpha__ #define TULIP_RXDESC_PRESYNC(sc, di, s) alpha_mb() #define TULIP_RXDESC_POSTSYNC(sc, di, s) alpha_mb() @@ -975,4 +978,9 @@ && ((u_int16_t *)a1)[1] == 0xFFFFU \ && ((u_int16_t *)a1)[2] == 0xFFFFU) +#define TULIP_MUTEX(sc) (&(sc)->tulip_mutex) +#define TULIP_LOCK(sc) mtx_lock(TULIP_MUTEX(sc)) +#define TULIP_UNLOCK(sc) mtx_unlock(TULIP_MUTEX(sc)) +#define TULIP_LOCK_ASSERT(sc,w) mtx_assert(TULIP_MUTEX(sc), (w)) + #endif /* _DEVAR_H */