diff options
author | rwatson <rwatson@FreeBSD.org> | 2005-08-03 00:18:35 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2005-08-03 00:18:35 +0000 |
commit | 9918d13b80941400bfab87834b1e2f1eea58c7c7 (patch) | |
tree | 9a4e586ffbcd1450917ee5e388a4e1eb38254e32 | |
parent | efa13b9da9fc80838e2c73140ae27393b3660da4 (diff) | |
download | FreeBSD-src-9918d13b80941400bfab87834b1e2f1eea58c7c7.zip FreeBSD-src-9918d13b80941400bfab87834b1e2f1eea58c7c7.tar.gz |
Modify device drivers supporting multicast addresses to lock if_addr_mtx
over iteration of their multicast address lists when synchronizing the
hardware address filter with the network stack-maintained list.
Problem reported by: Ed Maste (emaste at phaedrus dot sandvine dot ca>
MFC after: 1 week
57 files changed, 142 insertions, 4 deletions
diff --git a/sys/dev/aic7xxx/aicasm/Makefile b/sys/dev/aic7xxx/aicasm/Makefile index e89fd34..326f6f4 100644 --- a/sys/dev/aic7xxx/aicasm/Makefile +++ b/sys/dev/aic7xxx/aicasm/Makefile @@ -33,6 +33,7 @@ CFLAGS+= ${NOSTDINC} -I/usr/include -I. .ifdef MAKESRCPATH CFLAGS+= -I${MAKESRCPATH} .endif +NOMAN= NO_MAN= YFLAGS= -b ${.TARGET:R} ${.TARGET:M*macro*:S/$(.TARGET)/-p mm/} -d LFLAGS+= ${.TARGET:M*macro*:S/$(.TARGET)/-Pmm/} diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 009fe24..7e91f30 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -1662,6 +1662,7 @@ ath_mode_init(struct ath_softc *sc) /* calculate and install multicast filter */ if ((ifp->if_flags & IFF_ALLMULTI) == 0) { mfilt[0] = mfilt[1] = 0; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { caddr_t dl; @@ -1674,6 +1675,7 @@ ath_mode_init(struct ath_softc *sc) pos &= 0x3f; mfilt[pos / 32] |= (1 << (pos % 32)); } + IF_ADDR_UNLOCK(ifp); } else { mfilt[0] = mfilt[1] = ~0; } diff --git a/sys/dev/awi/awi.c b/sys/dev/awi/awi.c index 4c0ffc2..838e3fb 100644 --- a/sys/dev/awi/awi.c +++ b/sys/dev/awi/awi.c @@ -1146,15 +1146,19 @@ awi_mode_init(struct awi_softc *sc) #ifdef __FreeBSD__ if (ifp->if_flags & IFF_ALLMULTI) goto set_mib; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; - if (n == AWI_GROUP_ADDR_SIZE) + if (n == AWI_GROUP_ADDR_SIZE) { + IF_ADDR_UNLOCK(ifp); goto set_mib; + } IEEE80211_ADDR_COPY(sc->sc_mib_addr.aGroup_Addresses[n], LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); n++; } + IF_ADDR_UNLOCK(ifp); #else ETHER_FIRST_MULTI(step, &sc->sc_ic.ic_ec, enm); while (enm != NULL) { diff --git a/sys/dev/bfe/if_bfe.c b/sys/dev/bfe/if_bfe.c index 1df3168..5f902f8 100644 --- a/sys/dev/bfe/if_bfe.c +++ b/sys/dev/bfe/if_bfe.c @@ -883,12 +883,14 @@ bfe_set_rx_mode(struct bfe_softc *sc) val |= BFE_RXCONF_ALLMULTI; else { val &= ~BFE_RXCONF_ALLMULTI; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; bfe_cam_write(sc, LLADDR((struct sockaddr_dl *)ifma->ifma_addr), i++); } + IF_ADDR_UNLOCK(ifp); } CSR_WRITE_4(sc, BFE_RXCONF, val); diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 1633aa3..c215097 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -1171,6 +1171,7 @@ bge_setmulti(sc) CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), 0); /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1178,6 +1179,7 @@ bge_setmulti(sc) ifma->ifma_addr), ETHER_ADDR_LEN) & 0x7F; hashes[(h & 0x60) >> 5] |= 1 << (h & 0x1F); } + IF_ADDR_UNLOCK(ifp); for (i = 0; i < 4; i++) CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), hashes[i]); diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index f86d4e4..7fd9568 100644 --- a/sys/dev/dc/if_dc.c +++ b/sys/dev/dc/if_dc.c @@ -1110,6 +1110,7 @@ dc_setfilt_21143(struct dc_softc *sc) else DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI); + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1117,6 +1118,7 @@ dc_setfilt_21143(struct dc_softc *sc) LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); sp[h >> 4] |= htole32(1 << (h & 0xF)); } + IF_ADDR_UNLOCK(ifp); if (ifp->if_flags & IFF_BROADCAST) { h = dc_mchash_le(sc, ifp->if_broadcastaddr); @@ -1179,6 +1181,7 @@ dc_setfilt_admtek(struct dc_softc *sc) return; /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1193,6 +1196,7 @@ dc_setfilt_admtek(struct dc_softc *sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, DC_AL_MAR0, hashes[0]); CSR_WRITE_4(sc, DC_AL_MAR1, hashes[1]); @@ -1250,6 +1254,7 @@ dc_setfilt_asix(struct dc_softc *sc) return; /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1259,6 +1264,7 @@ dc_setfilt_asix(struct dc_softc *sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR0); CSR_WRITE_4(sc, DC_AX_FILTDATA, hashes[0]); @@ -1302,6 +1308,7 @@ dc_setfilt_xircom(struct dc_softc *sc) else DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI); + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1309,6 +1316,7 @@ dc_setfilt_xircom(struct dc_softc *sc) LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); sp[h >> 4] |= htole32(1 << (h & 0xF)); } + IF_ADDR_UNLOCK(ifp); if (ifp->if_flags & IFF_BROADCAST) { h = dc_mchash_le(sc, ifp->if_broadcastaddr); diff --git a/sys/dev/de/if_de.c b/sys/dev/de/if_de.c index 5fdff82..421d1aa 100644 --- a/sys/dev/de/if_de.c +++ b/sys/dev/de/if_de.c @@ -3026,6 +3026,7 @@ tulip_addr_filter( #endif multicnt = 0; + IF_ADDR_LOCK(sc->tulip_ifp); TAILQ_FOREACH(ifma, &sc->tulip_ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family == AF_LINK) @@ -3147,6 +3148,7 @@ tulip_addr_filter( #endif } } + IF_ADDR_UNLOCK(sc->tulip_ifp); #if defined(IFF_ALLMULTI) if (sc->tulip_flags & TULIP_ALLMULTI) sc->tulip_ifp->if_flags |= IFF_ALLMULTI; diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c index 4fa719d..46e98d5 100644 --- a/sys/dev/ed/if_ed.c +++ b/sys/dev/ed/if_ed.c @@ -1778,6 +1778,7 @@ ed_ds_getmcaf(struct ed_softc *sc, uint32_t *mcaf) mcaf[0] = 0; mcaf[1] = 0; + IF_ADDR_LOCK(sc->ifp); TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1785,6 +1786,7 @@ ed_ds_getmcaf(struct ed_softc *sc, uint32_t *mcaf) ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; af[index >> 3] |= 1 << (index & 7); } + IF_ADDR_UNLOCK(sc->ifp); } int diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c index 5cbafcd..076b4ff 100644 --- a/sys/dev/em/if_em.c +++ b/sys/dev/em/if_em.c @@ -1596,7 +1596,8 @@ em_set_multi(struct adapter * adapter) E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl); msec_delay(5); } - + + IF_ADDR_LOCK(ifp); #if __FreeBSD_version < 500000 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { #else @@ -1611,6 +1612,7 @@ em_set_multi(struct adapter * adapter) &mta[mcnt*ETH_LENGTH_OF_ADDRESS], ETH_LENGTH_OF_ADDRESS); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) { reg_rctl = E1000_READ_REG(&adapter->hw, RCTL); diff --git a/sys/dev/ex/if_ex.c b/sys/dev/ex/if_ex.c index 300e433..51fc4f4 100644 --- a/sys/dev/ex/if_ex.c +++ b/sys/dev/ex/if_ex.c @@ -840,11 +840,13 @@ ex_setmulti(struct ex_softc *sc) ifp = sc->ifp; count = 0; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) { if (maddr->ifma_addr->sa_family != AF_LINK) continue; count++; } + IF_ADDR_UNLOCK(ifp); if ((ifp->if_flags & IFF_PROMISC) || (ifp->if_flags & IFF_ALLMULTI) || count > 63) { @@ -871,7 +873,8 @@ ex_setmulti(struct ex_softc *sc) CSR_WRITE_2(sc, IO_PORT_REG, 0); CSR_WRITE_2(sc, IO_PORT_REG, 0); CSR_WRITE_2(sc, IO_PORT_REG, (count + 1) * 6); - + + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) { if (maddr->ifma_addr->sa_family != AF_LINK) continue; @@ -882,6 +885,7 @@ ex_setmulti(struct ex_softc *sc) CSR_WRITE_2(sc, IO_PORT_REG, *addr++); CSR_WRITE_2(sc, IO_PORT_REG, *addr++); } + IF_ADDR_UNLOCK(ifp); /* Program our MAC address as well */ /* XXX: Is this necessary? The Linux driver does this diff --git a/sys/dev/fe/if_fe.c b/sys/dev/fe/if_fe.c index 643f3e4..8b54c01 100644 --- a/sys/dev/fe/if_fe.c +++ b/sys/dev/fe/if_fe.c @@ -2060,6 +2060,7 @@ fe_mcaf ( struct fe_softc *sc ) struct ifmultiaddr *ifma; filter = fe_filter_nothing; + IF_ADDR_LOCK(sc->ifp); TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -2072,6 +2073,7 @@ fe_mcaf ( struct fe_softc *sc ) filter.data[index >> 3] |= 1 << (index & 7); } + IF_ADDR_UNLOCK(sc->ifp); return ( filter ); } diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 5aff82a..b0c3b7a 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -2485,6 +2485,7 @@ fxp_mc_addrs(struct fxp_softc *sc) nmcasts = 0; if ((sc->flags & FXP_FLAG_ALL_MCAST) == 0) { + IF_ADDR_LOCK(ifp); #if __FreeBSD_version < 500000 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { #else @@ -2501,6 +2502,7 @@ fxp_mc_addrs(struct fxp_softc *sc) &sc->mcsp->mc_addr[nmcasts][0], ETHER_ADDR_LEN); nmcasts++; } + IF_ADDR_UNLOCK(ifp); } mcsp->mc_cnt = htole16(nmcasts * ETHER_ADDR_LEN); return (nmcasts); diff --git a/sys/dev/gem/if_gem.c b/sys/dev/gem/if_gem.c index f669903..900af18 100644 --- a/sys/dev/gem/if_gem.c +++ b/sys/dev/gem/if_gem.c @@ -1954,6 +1954,7 @@ gem_setladrf(sc) /* Clear hash table */ memset(hash, 0, sizeof(hash)); + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(inm, &ifp->if_multiaddrs, ifma_link) { if (inm->ifma_addr->sa_family != AF_LINK) continue; @@ -1966,6 +1967,7 @@ gem_setladrf(sc) /* Set the corresponding bit in the filter. */ hash[crc >> 4] |= 1 << (15 - (crc & 15)); } + IF_ADDR_UNLOCK(ifp); v |= GEM_MAC_RX_HASH_FILTER; ifp->if_flags &= ~IFF_ALLMULTI; diff --git a/sys/dev/hme/if_hme.c b/sys/dev/hme/if_hme.c index d564bb4..82f43a9 100644 --- a/sys/dev/hme/if_hme.c +++ b/sys/dev/hme/if_hme.c @@ -1679,6 +1679,7 @@ hme_setladrf(struct hme_softc *sc, int reenable) * the word. */ + IF_ADDR_LOCK(sc->sc_ifp); TAILQ_FOREACH(inm, &sc->sc_ifp->if_multiaddrs, ifma_link) { if (inm->ifma_addr->sa_family != AF_LINK) continue; @@ -1691,6 +1692,7 @@ hme_setladrf(struct hme_softc *sc, int reenable) /* Set the corresponding bit in the filter. */ hash[crc >> 4] |= 1 << (crc & 0xf); } + IF_ADDR_UNLOCK(sc->sc_ifp); ifp->if_flags &= ~IFF_ALLMULTI; diff --git a/sys/dev/ie/if_ie.c b/sys/dev/ie/if_ie.c index febdc69..b00b69a 100644 --- a/sys/dev/ie/if_ie.c +++ b/sys/dev/ie/if_ie.c @@ -1676,6 +1676,7 @@ ie_mc_reset(struct ie_softc *sc) * Step through the list of addresses. */ sc->mcast_count = 0; + IF_ADDR_LOCK(sc->ifp); TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1690,6 +1691,7 @@ ie_mc_reset(struct ie_softc *sc) &(sc->mcast_addrs[sc->mcast_count]), 6); sc->mcast_count++; } + IF_ADDR_UNLOCK(sc->ifp); setflag: sc->want_mcsetup = 1; diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 2504592..2053bc5 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -265,6 +265,7 @@ ndis_setmulti(sc) sc->ndis_filter |= NDIS_PACKET_TYPE_MULTICAST; len = 0; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -272,11 +273,13 @@ ndis_setmulti(sc) mclist + (ETHER_ADDR_LEN * len), ETHER_ADDR_LEN); len++; if (len > mclistsz) { + IF_ADDR_UNLOCK(ifp); sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; sc->ndis_filter &= ~NDIS_PACKET_TYPE_MULTICAST; goto out; } } + IF_ADDR_UNLOCK(ifp); len = len * ETHER_ADDR_LEN; error = ndis_set_info(sc, OID_802_3_MULTICAST_LIST, mclist, &len); diff --git a/sys/dev/ixgb/if_ixgb.c b/sys/dev/ixgb/if_ixgb.c index 480c8d3..bd017d1 100644 --- a/sys/dev/ixgb/if_ixgb.c +++ b/sys/dev/ixgb/if_ixgb.c @@ -1071,6 +1071,7 @@ ixgb_set_multi(struct adapter * adapter) IOCTL_DEBUGOUT("ixgb_set_multi: begin"); + IF_ADDR_LOCK(ifp); #if __FreeBSD_version < 500000 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { #else @@ -1083,6 +1084,7 @@ ixgb_set_multi(struct adapter * adapter) &mta[mcnt * IXGB_ETH_LENGTH_OF_ADDRESS], IXGB_ETH_LENGTH_OF_ADDRESS); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt > MAX_NUM_MULTICAST_ADDRESSES) { reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL); diff --git a/sys/dev/lge/if_lge.c b/sys/dev/lge/if_lge.c index 9c7e65d..5fa6391 100644 --- a/sys/dev/lge/if_lge.c +++ b/sys/dev/lge/if_lge.c @@ -390,6 +390,7 @@ lge_setmulti(sc) CSR_WRITE_4(sc, LGE_MAR1, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -400,6 +401,7 @@ lge_setmulti(sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, LGE_MAR0, hashes[0]); CSR_WRITE_4(sc, LGE_MAR1, hashes[1]); diff --git a/sys/dev/lnc/if_lnc.c b/sys/dev/lnc/if_lnc.c index 7357c93..4829639 100644 --- a/sys/dev/lnc/if_lnc.c +++ b/sys/dev/lnc/if_lnc.c @@ -239,6 +239,7 @@ lnc_setladrf(struct lnc_softc *sc) */ bzero(sc->init_block->ladrf, MULTICAST_FILTER_LEN); + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -247,6 +248,7 @@ lnc_setladrf(struct lnc_softc *sc) ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; sc->init_block->ladrf[index >> 3] |= 1 << (index & 7); } + IF_ADDR_UNLOCK(ifp); } void diff --git a/sys/dev/my/if_my.c b/sys/dev/my/if_my.c index d1a4f4c..1741ab7 100644 --- a/sys/dev/my/if_my.c +++ b/sys/dev/my/if_my.c @@ -346,6 +346,7 @@ my_setmulti(struct my_softc * sc) CSR_WRITE_4(sc, MY_MAR1, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -357,6 +358,7 @@ my_setmulti(struct my_softc * sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= MY_AM; diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 43cd378..a4f4514 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -705,6 +705,7 @@ nge_setmulti(sc) * that needs to be updated, and the lower 4 bits represent * which bit within that byte needs to be set. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -716,6 +717,7 @@ nge_setmulti(sc) NGE_FILTADDR_MCAST_LO + (index * 2)); NGE_SETBIT(sc, NGE_RXFILT_DATA, (1 << bit)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, NGE_RXFILT_CTL, filtsave); diff --git a/sys/dev/nve/if_nve.c b/sys/dev/nve/if_nve.c index 31031f5..d0f2872 100644 --- a/sys/dev/nve/if_nve.c +++ b/sys/dev/nve/if_nve.c @@ -1073,6 +1073,7 @@ nve_setmulti(struct nve_softc *sc) return; } /* Setup multicast filter */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { u_char *addrp; @@ -1086,6 +1087,7 @@ nve_setmulti(struct nve_softc *sc) oraddr[i] |= mcaddr; } } + IF_ADDR_UNLOCK(ifp); for (i = 0; i < 6; i++) { hwfilter.acMulticastAddress[i] = andaddr[i] & oraddr[i]; hwfilter.acMulticastMask[i] = andaddr[i] | (~oraddr[i]); diff --git a/sys/dev/owi/if_owi.c b/sys/dev/owi/if_owi.c index 3cb1c48..a0d8bc0 100644 --- a/sys/dev/owi/if_owi.c +++ b/sys/dev/owi/if_owi.c @@ -1213,6 +1213,7 @@ wi_setmulti(sc) return; } + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1225,6 +1226,7 @@ wi_setmulti(sc) break; } } + IF_ADDR_UNLOCK(ifp); mcast.wi_len = (i * 3) + 1; wi_write_record(sc, (struct wi_ltv_gen *)&mcast); diff --git a/sys/dev/pdq/pdq_ifsubr.c b/sys/dev/pdq/pdq_ifsubr.c index fa48594..7fb420b 100644 --- a/sys/dev/pdq/pdq_ifsubr.c +++ b/sys/dev/pdq/pdq_ifsubr.c @@ -273,6 +273,7 @@ pdq_os_addr_fill( PDQ_IFNET(sc)->if_flags &= ~IFF_ALLMULTI; #endif + IF_ADDR_LOCK(PDQ_IFNET(sc)); for (ifma = TAILQ_FIRST(&PDQ_IFNET(sc)->if_multiaddrs); ifma && num_addrs > 0; ifma = TAILQ_NEXT(ifma, ifma_link)) { char *mcaddr; @@ -285,6 +286,7 @@ pdq_os_addr_fill( addr++; num_addrs--; } + IF_ADDR_UNLOCK(PDQ_IFNET(sc)); /* * If not all the address fit into the CAM, turn on all-multicast mode. */ diff --git a/sys/dev/ray/if_ray.c b/sys/dev/ray/if_ray.c index 2417671..463a982 100644 --- a/sys/dev/ray/if_ray.c +++ b/sys/dev/ray/if_ray.c @@ -2704,13 +2704,16 @@ ray_mcast(struct ray_softc *sc, struct ray_comq_entry *com) * The multicast list is only 16 items long so use promiscuous * mode and don't bother updating the multicast list. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) count++; if (count == 0) { + IF_ADDR_UNLOCK(ifp); ray_com_runq_done(sc); return; } else if (count > 16) { ifp->if_flags |= IFF_ALLMULTI; + IF_ADDR_UNLOCK(ifp); ray_com_runq_done(sc); return; } else if (ifp->if_flags & IFF_ALLMULTI) @@ -2732,6 +2735,7 @@ ray_mcast(struct ray_softc *sc, struct ray_comq_entry *com) ); bufp += ETHER_ADDR_LEN; } + IF_ADDR_UNLOCK(ifp); ray_com_ecf(sc, com); } diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index bccbc0e..61c0c89 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -601,6 +601,7 @@ re_setmulti(sc) CSR_WRITE_4(sc, RL_MAR4, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -612,6 +613,7 @@ re_setmulti(sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= RL_RXCFG_RX_MULTI; diff --git a/sys/dev/sf/if_sf.c b/sys/dev/sf/if_sf.c index a64379f..5485fb7 100644 --- a/sys/dev/sf/if_sf.c +++ b/sys/dev/sf/if_sf.c @@ -431,6 +431,7 @@ sf_setmulti(sc) SF_SETBIT(sc, SF_RXFILT, SF_RXFILT_ALLMULTI); } else { i = 1; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -449,6 +450,7 @@ sf_setmulti(sc) sf_sethash(sc, LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 0); } + IF_ADDR_UNLOCK(ifp); } } diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c index bcc4b03..0daf42e 100644 --- a/sys/dev/sk/if_sk.c +++ b/sys/dev/sk/if_sk.c @@ -823,6 +823,7 @@ sk_setmulti(sc_if) hashes[1] = 0xFFFFFFFF; } else { i = 1; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -855,6 +856,7 @@ sk_setmulti(sc_if) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); } switch(sc->sk_type) { diff --git a/sys/dev/sn/if_sn.c b/sys/dev/sn/if_sn.c index 56fb5e8..ddfc099 100644 --- a/sys/dev/sn/if_sn.c +++ b/sys/dev/sn/if_sn.c @@ -1410,9 +1410,12 @@ sn_getmcf(struct ifnet *ifp, uint8_t *mcf) bzero(mcf, MCFSZ); + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) + if (ifma->ifma_addr->sa_family != AF_LINK) { + IF_ADDR_UNLOCK(ifp); return 0; + } index = ether_crc32_le(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), ETHER_ADDR_LEN) & 0x3f; index2 = 0; @@ -1423,5 +1426,6 @@ sn_getmcf(struct ifnet *ifp, uint8_t *mcf) } af[index2 >> 3] |= 1 << (index2 & 7); } + IF_ADDR_UNLOCK(ifp); return 1; /* use multicast filter */ } diff --git a/sys/dev/snc/dp83932.c b/sys/dev/snc/dp83932.c index c32004b..b85170c 100644 --- a/sys/dev/snc/dp83932.c +++ b/sys/dev/snc/dp83932.c @@ -675,6 +675,7 @@ camprogram(sc) ifp->if_flags &= ~IFF_ALLMULTI; /* Loop through multicast addresses */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -688,6 +689,7 @@ camprogram(sc) LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); mcount++; } + IF_ADDR_UNLOCK(ifp); NIC_PUT(sc, SNCR_CDP, LOWER(sc->v_cda)); NIC_PUT(sc, SNCR_CDC, MAXCAM); diff --git a/sys/dev/ti/if_ti.c b/sys/dev/ti/if_ti.c index 1bbfe38..5ce58c5 100644 --- a/sys/dev/ti/if_ti.c +++ b/sys/dev/ti/if_ti.c @@ -1621,6 +1621,7 @@ ti_setmulti(sc) } /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1634,6 +1635,7 @@ ti_setmulti(sc) SLIST_INSERT_HEAD(&sc->ti_mc_listhead, mc, mc_entries); ti_add_mcast(sc, &mc->mc_addr); } + IF_ADDR_UNLOCK(ifp); /* Re-enable interrupts. */ CSR_WRITE_4(sc, TI_MB_HOSTINTR, intrs); diff --git a/sys/dev/tx/if_tx.c b/sys/dev/tx/if_tx.c index f059887..16a386c 100644 --- a/sys/dev/tx/if_tx.c +++ b/sys/dev/tx/if_tx.c @@ -1409,6 +1409,7 @@ epic_set_mc_table(sc) filter[2] = 0; filter[3] = 0; + IF_ADDR_LOCK(ifp); #if __FreeBSD_version < 500000 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { #else @@ -1420,6 +1421,7 @@ epic_set_mc_table(sc) ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; filter[h >> 4] |= 1 << (h & 0xF); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, MC0, filter[0]); CSR_WRITE_4(sc, MC1, filter[1]); diff --git a/sys/dev/txp/if_txp.c b/sys/dev/txp/if_txp.c index 425bbe5..5ca11b3 100644 --- a/sys/dev/txp/if_txp.c +++ b/sys/dev/txp/if_txp.c @@ -1774,6 +1774,7 @@ txp_set_filter(sc) else { hash[0] = hash[1] = 0; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1797,6 +1798,7 @@ txp_set_filter(sc) hashbit = (u_int16_t)(crc & (64 - 1)); hash[hashbit / 32] |= (1 << hashbit % 32); } + IF_ADDR_UNLOCK(ifp); if (mcnt > 0) { filter |= TXP_RXFILT_HASHMULTI; diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c index 3118baa..af5fe5f 100644 --- a/sys/dev/usb/if_aue.c +++ b/sys/dev/usb/if_aue.c @@ -539,6 +539,7 @@ aue_setmulti(struct aue_softc *sc) aue_csr_write_1(sc, AUE_MAR0 + i, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); #if __FreeBSD_version >= 500000 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) #else @@ -551,6 +552,7 @@ aue_setmulti(struct aue_softc *sc) ifma->ifma_addr), ETHER_ADDR_LEN) & ((1 << AUE_BITS) - 1); AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0x7)); } + IF_ADDR_UNLOCK(ifp); return; } diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c index 9551649..c549390 100644 --- a/sys/dev/usb/if_axe.c +++ b/sys/dev/usb/if_axe.c @@ -338,6 +338,7 @@ axe_setmulti(struct axe_softc *sc) } else rxmode &= ~AXE_RXCMD_ALLMULTI; + IF_ADDR_LOCK(ifp); #if __FreeBSD_version >= 500000 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) #else @@ -350,6 +351,7 @@ axe_setmulti(struct axe_softc *sc) ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; hashtbl[h / 8] |= 1 << (h % 8); } + IF_ADDR_UNLOCK(ifp); axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl); axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c index 604f9c5..ae21957 100644 --- a/sys/dev/usb/if_cue.c +++ b/sys/dev/usb/if_cue.c @@ -356,6 +356,7 @@ cue_setmulti(struct cue_softc *sc) sc->cue_mctab[i] = 0; /* now program new ones */ + IF_ADDR_LOCK(ifp); #if __FreeBSD_version >= 500000 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) #else @@ -367,6 +368,7 @@ cue_setmulti(struct cue_softc *sc) h = cue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); } + IF_ADDR_UNLOCK(ifp); /* * Also include the broadcast address in the filter diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c index b4c65e4..fce9adf 100644 --- a/sys/dev/usb/if_kue.c +++ b/sys/dev/usb/if_kue.c @@ -327,6 +327,7 @@ kue_setmulti(struct kue_softc *sc) sc->kue_rxfilt &= ~KUE_RXFILT_ALLMULTI; + IF_ADDR_LOCK(ifp); #if __FreeBSD_version >= 500000 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) #else @@ -345,6 +346,7 @@ kue_setmulti(struct kue_softc *sc) KUE_MCFILT(sc, i), ETHER_ADDR_LEN); i++; } + IF_ADDR_UNLOCK(ifp); if (i == KUE_MCFILTCNT(sc)) sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI; diff --git a/sys/dev/usb/if_rue.c b/sys/dev/usb/if_rue.c index 9990da1..e544e11 100644 --- a/sys/dev/usb/if_rue.c +++ b/sys/dev/usb/if_rue.c @@ -500,6 +500,7 @@ rue_setmulti(struct rue_softc *sc) rue_csr_write_4(sc, RUE_MAR4, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); #if __FreeBSD_version >= 500000 TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link) #else @@ -516,6 +517,7 @@ rue_setmulti(struct rue_softc *sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxcfg |= RUE_RCR_AM; diff --git a/sys/dev/usb/if_udav.c b/sys/dev/usb/if_udav.c index daa426d..19f64cb 100644 --- a/sys/dev/usb/if_udav.c +++ b/sys/dev/usb/if_udav.c @@ -1044,6 +1044,7 @@ udav_setmulti(struct udav_softc *sc) ETHER_NEXT_MULTI(step, enm); } #elif defined(__FreeBSD__) + IF_ADDR_LOCK(ifp); #if __FreeBSD_version >= 500000 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) #else @@ -1056,6 +1057,7 @@ udav_setmulti(struct udav_softc *sc) ifma->ifma_addr)); hashes[h>>3] |= 1 << (h & 0x7); } + IF_ADDR_UNLOCK(ifp); #endif /* disable all multicast */ diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c index 9bf98db..e1ebaaa 100644 --- a/sys/dev/vge/if_vge.c +++ b/sys/dev/vge/if_vge.c @@ -594,6 +594,7 @@ vge_setmulti(sc) } /* Now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -626,6 +627,7 @@ vge_setmulti(sc) CSR_WRITE_4(sc, VGE_MAR0, hashes[0]); CSR_WRITE_4(sc, VGE_MAR1, hashes[1]); } + IF_ADDR_UNLOCK(ifp); return; } diff --git a/sys/dev/vr/if_vr.c b/sys/dev/vr/if_vr.c index 23194f7..654de6f 100644 --- a/sys/dev/vr/if_vr.c +++ b/sys/dev/vr/if_vr.c @@ -533,6 +533,7 @@ vr_setmulti(struct vr_softc *sc) CSR_WRITE_4(sc, VR_MAR1, 0); /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -544,6 +545,7 @@ vr_setmulti(struct vr_softc *sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= VR_RXCFG_RX_MULTI; diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index a4a041a..72f5eca 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -1739,6 +1739,7 @@ allmulti: } n = 0; + IF_ADDR_LOCK(ifp); #if __FreeBSD_version < 500000 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { #else @@ -1752,6 +1753,7 @@ allmulti: (LLADDR((struct sockaddr_dl *)ifma->ifma_addr))); n++; } + IF_ADDR_UNLOCK(ifp); return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, IEEE80211_ADDR_LEN * n); } diff --git a/sys/dev/wl/if_wl.c b/sys/dev/wl/if_wl.c index 562baf4..ce3ed0d 100644 --- a/sys/dev/wl/if_wl.c +++ b/sys/dev/wl/if_wl.c @@ -2121,6 +2121,7 @@ wlconfig(struct wl_softc *sc) outw(PIOP1(base), 0); /* ac_status */ outw(PIOP1(base), AC_MCSETUP|AC_CW_EL); /* ac_command */ outw(PIOR1(base), OFFSET_CU + 8); + IF_ADDR_LOCK(sc->ifp); TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -2131,6 +2132,7 @@ wlconfig(struct wl_softc *sc) outw(PIOP1(base), addrp[4] + (addrp[5] << 8)); ++cnt; } + IF_ADDR_UNLOCK(sc->ifp); outw(PIOR1(base), OFFSET_CU + 6); /* mc-cnt */ outw(PIOP1(base), cnt * WAVELAN_ADDR_SIZE); if (wlcmd(sc, "config()-mcaddress") == 0) diff --git a/sys/dev/xe/if_xe.c b/sys/dev/xe/if_xe.c index f95295f..4385fec 100644 --- a/sys/dev/xe/if_xe.c +++ b/sys/dev/xe/if_xe.c @@ -1274,6 +1274,7 @@ xe_set_multicast(struct xe_softc *scp) { /* Iterate over multicast address list */ count = 0; + IF_ADDR_LOCK(ifp); #if __FreeBSD_version < 500000 LIST_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) { #else @@ -1295,6 +1296,7 @@ xe_set_multicast(struct xe_softc *scp) { /* Nowhere else to put them on CE2 */ break; } + IF_ADDR_UNLOCK(ifp); DEVPRINTF(2, (scp->dev, "set_multicast: count = %u\n", count)); diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c index f86d4e4..7fd9568 100644 --- a/sys/pci/if_dc.c +++ b/sys/pci/if_dc.c @@ -1110,6 +1110,7 @@ dc_setfilt_21143(struct dc_softc *sc) else DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI); + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1117,6 +1118,7 @@ dc_setfilt_21143(struct dc_softc *sc) LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); sp[h >> 4] |= htole32(1 << (h & 0xF)); } + IF_ADDR_UNLOCK(ifp); if (ifp->if_flags & IFF_BROADCAST) { h = dc_mchash_le(sc, ifp->if_broadcastaddr); @@ -1179,6 +1181,7 @@ dc_setfilt_admtek(struct dc_softc *sc) return; /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1193,6 +1196,7 @@ dc_setfilt_admtek(struct dc_softc *sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, DC_AL_MAR0, hashes[0]); CSR_WRITE_4(sc, DC_AL_MAR1, hashes[1]); @@ -1250,6 +1254,7 @@ dc_setfilt_asix(struct dc_softc *sc) return; /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1259,6 +1264,7 @@ dc_setfilt_asix(struct dc_softc *sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR0); CSR_WRITE_4(sc, DC_AX_FILTDATA, hashes[0]); @@ -1302,6 +1308,7 @@ dc_setfilt_xircom(struct dc_softc *sc) else DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI); + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1309,6 +1316,7 @@ dc_setfilt_xircom(struct dc_softc *sc) LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); sp[h >> 4] |= htole32(1 << (h & 0xF)); } + IF_ADDR_UNLOCK(ifp); if (ifp->if_flags & IFF_BROADCAST) { h = dc_mchash_le(sc, ifp->if_broadcastaddr); diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c index 5fdff82..421d1aa 100644 --- a/sys/pci/if_de.c +++ b/sys/pci/if_de.c @@ -3026,6 +3026,7 @@ tulip_addr_filter( #endif multicnt = 0; + IF_ADDR_LOCK(sc->tulip_ifp); TAILQ_FOREACH(ifma, &sc->tulip_ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family == AF_LINK) @@ -3147,6 +3148,7 @@ tulip_addr_filter( #endif } } + IF_ADDR_UNLOCK(sc->tulip_ifp); #if defined(IFF_ALLMULTI) if (sc->tulip_flags & TULIP_ALLMULTI) sc->tulip_ifp->if_flags |= IFF_ALLMULTI; diff --git a/sys/pci/if_pcn.c b/sys/pci/if_pcn.c index 7dec359..f316146 100644 --- a/sys/pci/if_pcn.c +++ b/sys/pci/if_pcn.c @@ -351,6 +351,7 @@ pcn_setmulti(sc) pcn_csr_write(sc, PCN_CSR_MAR0 + i, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -358,6 +359,7 @@ pcn_setmulti(sc) ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; hashes[h >> 4] |= 1 << (h & 0xF); } + IF_ADDR_UNLOCK(ifp); for (i = 0; i < 4; i++) pcn_csr_write(sc, PCN_CSR_MAR0 + i, hashes[i]); diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c index bc01dbc..8d27fb3 100644 --- a/sys/pci/if_rl.c +++ b/sys/pci/if_rl.c @@ -685,6 +685,7 @@ rl_setmulti(struct rl_softc *sc) CSR_WRITE_4(sc, RL_MAR4, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -696,6 +697,7 @@ rl_setmulti(struct rl_softc *sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= RL_RXCFG_RX_MULTI; diff --git a/sys/pci/if_sf.c b/sys/pci/if_sf.c index a64379f..5485fb7 100644 --- a/sys/pci/if_sf.c +++ b/sys/pci/if_sf.c @@ -431,6 +431,7 @@ sf_setmulti(sc) SF_SETBIT(sc, SF_RXFILT, SF_RXFILT_ALLMULTI); } else { i = 1; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -449,6 +450,7 @@ sf_setmulti(sc) sf_sethash(sc, LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 0); } + IF_ADDR_UNLOCK(ifp); } } diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c index b455b83..48a6132 100644 --- a/sys/pci/if_sis.c +++ b/sys/pci/if_sis.c @@ -763,6 +763,7 @@ sis_setmulti_ns(struct sis_softc *sc) CSR_WRITE_4(sc, SIS_RXFILT_DATA, 0); } + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -775,6 +776,7 @@ sis_setmulti_ns(struct sis_softc *sc) bit -= 0x10; SIS_SETBIT(sc, SIS_RXFILT_DATA, (1 << bit)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave); @@ -813,6 +815,7 @@ sis_setmulti_sis(struct sis_softc *sc) for (i = 0; i < n; i++) hashes[i] = 0; i = 0; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -821,6 +824,7 @@ sis_setmulti_sis(struct sis_softc *sc) hashes[h >> 4] |= 1 << (h & 0xf); i++; } + IF_ADDR_UNLOCK(ifp); if (i > n) { ctl |= SIS_RXFILTCTL_ALLMULTI; for (i = 0; i < n; i++) diff --git a/sys/pci/if_sk.c b/sys/pci/if_sk.c index bcc4b03..0daf42e 100644 --- a/sys/pci/if_sk.c +++ b/sys/pci/if_sk.c @@ -823,6 +823,7 @@ sk_setmulti(sc_if) hashes[1] = 0xFFFFFFFF; } else { i = 1; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -855,6 +856,7 @@ sk_setmulti(sc_if) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); } switch(sc->sk_type) { diff --git a/sys/pci/if_ste.c b/sys/pci/if_ste.c index 27d5399..8e73f65 100644 --- a/sys/pci/if_ste.c +++ b/sys/pci/if_ste.c @@ -579,6 +579,7 @@ ste_setmulti(sc) CSR_WRITE_2(sc, STE_MAR3, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -589,6 +590,7 @@ ste_setmulti(sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_2(sc, STE_MAR0, hashes[0] & 0xFFFF); CSR_WRITE_2(sc, STE_MAR1, (hashes[0] >> 16) & 0xFFFF); diff --git a/sys/pci/if_ti.c b/sys/pci/if_ti.c index 1bbfe38..5ce58c5 100644 --- a/sys/pci/if_ti.c +++ b/sys/pci/if_ti.c @@ -1621,6 +1621,7 @@ ti_setmulti(sc) } /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1634,6 +1635,7 @@ ti_setmulti(sc) SLIST_INSERT_HEAD(&sc->ti_mc_listhead, mc, mc_entries); ti_add_mcast(sc, &mc->mc_addr); } + IF_ADDR_UNLOCK(ifp); /* Re-enable interrupts. */ CSR_WRITE_4(sc, TI_MB_HOSTINTR, intrs); diff --git a/sys/pci/if_tl.c b/sys/pci/if_tl.c index 3dde56a..f9d9815 100644 --- a/sys/pci/if_tl.c +++ b/sys/pci/if_tl.c @@ -960,6 +960,7 @@ tl_setmulti(sc) hashes[1] = 0xFFFFFFFF; } else { i = 1; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -982,6 +983,7 @@ tl_setmulti(sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); } tl_dio_write32(sc, TL_HASH1, hashes[0]); diff --git a/sys/pci/if_vr.c b/sys/pci/if_vr.c index 23194f7..654de6f 100644 --- a/sys/pci/if_vr.c +++ b/sys/pci/if_vr.c @@ -533,6 +533,7 @@ vr_setmulti(struct vr_softc *sc) CSR_WRITE_4(sc, VR_MAR1, 0); /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -544,6 +545,7 @@ vr_setmulti(struct vr_softc *sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= VR_RXCFG_RX_MULTI; diff --git a/sys/pci/if_wb.c b/sys/pci/if_wb.c index 0677fca..9c44e2e 100644 --- a/sys/pci/if_wb.c +++ b/sys/pci/if_wb.c @@ -614,6 +614,7 @@ wb_setmulti(sc) CSR_WRITE_4(sc, WB_MAR1, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -625,6 +626,7 @@ wb_setmulti(sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= WB_NETCFG_RX_MULTI; diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c index cca9d4e..72c8ce0 100644 --- a/sys/pci/if_xl.c +++ b/sys/pci/if_xl.c @@ -777,8 +777,10 @@ xl_setmulti(struct xl_softc *sc) return; } + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) mcnt++; + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= XL_RXFILTER_ALLMULTI; @@ -817,6 +819,7 @@ xl_setmulti_hash(struct xl_softc *sc) CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_HASH|i); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -838,6 +841,7 @@ xl_setmulti_hash(struct xl_softc *sc) h | XL_CMD_RX_SET_HASH | XL_HASH_SET); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= XL_RXFILTER_MULTIHASH; |