summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-08-03 00:18:35 +0000
committerrwatson <rwatson@FreeBSD.org>2005-08-03 00:18:35 +0000
commit9918d13b80941400bfab87834b1e2f1eea58c7c7 (patch)
tree9a4e586ffbcd1450917ee5e388a4e1eb38254e32
parentefa13b9da9fc80838e2c73140ae27393b3660da4 (diff)
downloadFreeBSD-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
-rw-r--r--sys/dev/aic7xxx/aicasm/Makefile1
-rw-r--r--sys/dev/ath/if_ath.c2
-rw-r--r--sys/dev/awi/awi.c6
-rw-r--r--sys/dev/bfe/if_bfe.c2
-rw-r--r--sys/dev/bge/if_bge.c2
-rw-r--r--sys/dev/dc/if_dc.c8
-rw-r--r--sys/dev/de/if_de.c2
-rw-r--r--sys/dev/ed/if_ed.c2
-rw-r--r--sys/dev/em/if_em.c4
-rw-r--r--sys/dev/ex/if_ex.c6
-rw-r--r--sys/dev/fe/if_fe.c2
-rw-r--r--sys/dev/fxp/if_fxp.c2
-rw-r--r--sys/dev/gem/if_gem.c2
-rw-r--r--sys/dev/hme/if_hme.c2
-rw-r--r--sys/dev/ie/if_ie.c2
-rw-r--r--sys/dev/if_ndis/if_ndis.c3
-rw-r--r--sys/dev/ixgb/if_ixgb.c2
-rw-r--r--sys/dev/lge/if_lge.c2
-rw-r--r--sys/dev/lnc/if_lnc.c2
-rw-r--r--sys/dev/my/if_my.c2
-rw-r--r--sys/dev/nge/if_nge.c2
-rw-r--r--sys/dev/nve/if_nve.c2
-rw-r--r--sys/dev/owi/if_owi.c2
-rw-r--r--sys/dev/pdq/pdq_ifsubr.c2
-rw-r--r--sys/dev/ray/if_ray.c4
-rw-r--r--sys/dev/re/if_re.c2
-rw-r--r--sys/dev/sf/if_sf.c2
-rw-r--r--sys/dev/sk/if_sk.c2
-rw-r--r--sys/dev/sn/if_sn.c6
-rw-r--r--sys/dev/snc/dp83932.c2
-rw-r--r--sys/dev/ti/if_ti.c2
-rw-r--r--sys/dev/tx/if_tx.c2
-rw-r--r--sys/dev/txp/if_txp.c2
-rw-r--r--sys/dev/usb/if_aue.c2
-rw-r--r--sys/dev/usb/if_axe.c2
-rw-r--r--sys/dev/usb/if_cue.c2
-rw-r--r--sys/dev/usb/if_kue.c2
-rw-r--r--sys/dev/usb/if_rue.c2
-rw-r--r--sys/dev/usb/if_udav.c2
-rw-r--r--sys/dev/vge/if_vge.c2
-rw-r--r--sys/dev/vr/if_vr.c2
-rw-r--r--sys/dev/wi/if_wi.c2
-rw-r--r--sys/dev/wl/if_wl.c2
-rw-r--r--sys/dev/xe/if_xe.c2
-rw-r--r--sys/pci/if_dc.c8
-rw-r--r--sys/pci/if_de.c2
-rw-r--r--sys/pci/if_pcn.c2
-rw-r--r--sys/pci/if_rl.c2
-rw-r--r--sys/pci/if_sf.c2
-rw-r--r--sys/pci/if_sis.c4
-rw-r--r--sys/pci/if_sk.c2
-rw-r--r--sys/pci/if_ste.c2
-rw-r--r--sys/pci/if_ti.c2
-rw-r--r--sys/pci/if_tl.c2
-rw-r--r--sys/pci/if_vr.c2
-rw-r--r--sys/pci/if_wb.c2
-rw-r--r--sys/pci/if_xl.c4
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;
OpenPOWER on IntegriCloud