summaryrefslogtreecommitdiffstats
path: root/sys/pci
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 /sys/pci
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
Diffstat (limited to 'sys/pci')
-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
13 files changed, 36 insertions, 0 deletions
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