svn commit: r353827 - head/sys/dev/sk
Gleb Smirnoff
glebius at FreeBSD.org
Mon Oct 21 18:07:51 UTC 2019
Author: glebius
Date: Mon Oct 21 18:07:49 2019
New Revision: 353827
URL: https://svnweb.freebsd.org/changeset/base/353827
Log:
Convert to if_foreach_llmaddr() KPI.
Modified:
head/sys/dev/sk/if_sk.c
Modified: head/sys/dev/sk/if_sk.c
==============================================================================
--- head/sys/dev/sk/if_sk.c Mon Oct 21 18:07:44 2019 (r353826)
+++ head/sys/dev/sk/if_sk.c Mon Oct 21 18:07:49 2019 (r353827)
@@ -718,21 +718,49 @@ sk_rxfilter(sc_if)
sk_rxfilter_yukon(sc_if);
}
+struct sk_add_maddr_genesis_ctx {
+ struct sk_if_softc *sc_if;
+ uint32_t hashes[2];
+ uint32_t mode;
+};
+
+static u_int
+sk_add_maddr_genesis(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+ struct sk_add_maddr_genesis_ctx *ctx = arg;
+ int h;
+
+ /*
+ * Program the first XM_RXFILT_MAX multicast groups
+ * into the perfect filter.
+ */
+ if (cnt + 1 < XM_RXFILT_MAX) {
+ sk_setfilt(ctx->sc_if, (uint16_t *)LLADDR(sdl), cnt + 1);
+ ctx->mode |= XM_MODE_RX_USE_PERFECT;
+ return (1);
+ }
+ h = sk_xmchash((const uint8_t *)LLADDR(sdl));
+ if (h < 32)
+ ctx->hashes[0] |= (1 << h);
+ else
+ ctx->hashes[1] |= (1 << (h - 32));
+ ctx->mode |= XM_MODE_RX_USE_HASH;
+
+ return (1);
+}
+
static void
-sk_rxfilter_genesis(sc_if)
- struct sk_if_softc *sc_if;
+sk_rxfilter_genesis(struct sk_if_softc *sc_if)
{
struct ifnet *ifp = sc_if->sk_ifp;
- u_int32_t hashes[2] = { 0, 0 }, mode;
- int h = 0, i;
- struct ifmultiaddr *ifma;
+ struct sk_add_maddr_genesis_ctx ctx = { sc_if, { 0, 0 } };
+ int i;
u_int16_t dummy[] = { 0, 0, 0 };
- u_int16_t maddr[(ETHER_ADDR_LEN+1)/2];
SK_IF_LOCK_ASSERT(sc_if);
- mode = SK_XM_READ_4(sc_if, XM_MODE);
- mode &= ~(XM_MODE_RX_PROMISC | XM_MODE_RX_USE_HASH |
+ ctx.mode = SK_XM_READ_4(sc_if, XM_MODE);
+ ctx.mode &= ~(XM_MODE_RX_PROMISC | XM_MODE_RX_USE_HASH |
XM_MODE_RX_USE_PERFECT);
/* First, zot all the existing perfect filters. */
for (i = 1; i < XM_RXFILT_MAX; i++)
@@ -741,53 +769,39 @@ sk_rxfilter_genesis(sc_if)
/* Now program new ones. */
if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
if (ifp->if_flags & IFF_ALLMULTI)
- mode |= XM_MODE_RX_USE_HASH;
+ ctx.mode |= XM_MODE_RX_USE_HASH;
if (ifp->if_flags & IFF_PROMISC)
- mode |= XM_MODE_RX_PROMISC;
- hashes[0] = 0xFFFFFFFF;
- hashes[1] = 0xFFFFFFFF;
- } else {
- i = 1;
- if_maddr_rlock(ifp);
+ ctx.mode |= XM_MODE_RX_PROMISC;
+ ctx.hashes[0] = 0xFFFFFFFF;
+ ctx.hashes[1] = 0xFFFFFFFF;
+ } else
/* XXX want to maintain reverse semantics */
- CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs,
- ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- /*
- * Program the first XM_RXFILT_MAX multicast groups
- * into the perfect filter.
- */
- bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
- maddr, ETHER_ADDR_LEN);
- if (i < XM_RXFILT_MAX) {
- sk_setfilt(sc_if, maddr, i);
- mode |= XM_MODE_RX_USE_PERFECT;
- i++;
- continue;
- }
- h = sk_xmchash((const uint8_t *)maddr);
- if (h < 32)
- hashes[0] |= (1 << h);
- else
- hashes[1] |= (1 << (h - 32));
- mode |= XM_MODE_RX_USE_HASH;
- }
- if_maddr_runlock(ifp);
- }
+ if_foreach_llmaddr(ifp, sk_add_maddr_genesis, &ctx);
- SK_XM_WRITE_4(sc_if, XM_MODE, mode);
- SK_XM_WRITE_4(sc_if, XM_MAR0, hashes[0]);
- SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]);
+ SK_XM_WRITE_4(sc_if, XM_MODE, ctx.mode);
+ SK_XM_WRITE_4(sc_if, XM_MAR0, ctx.hashes[0]);
+ SK_XM_WRITE_4(sc_if, XM_MAR2, ctx.hashes[1]);
}
+static u_int
+sk_hash_maddr_yukon(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+ uint32_t crc, *hashes = arg;
+
+ crc = ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN);
+ /* Just want the 6 least significant bits. */
+ crc &= 0x3f;
+ /* Set the corresponding bit in the hash table. */
+ hashes[crc >> 5] |= 1 << (crc & 0x1f);
+
+ return (1);
+}
+
static void
-sk_rxfilter_yukon(sc_if)
- struct sk_if_softc *sc_if;
+sk_rxfilter_yukon(struct sk_if_softc *sc_if)
{
struct ifnet *ifp;
- u_int32_t crc, hashes[2] = { 0, 0 }, mode;
- struct ifmultiaddr *ifma;
+ uint32_t hashes[2] = { 0, 0 }, mode;
SK_IF_LOCK_ASSERT(sc_if);
@@ -801,18 +815,7 @@ sk_rxfilter_yukon(sc_if)
hashes[1] = 0xFFFFFFFF;
} else {
mode |= YU_RCR_UFLEN;
- if_maddr_rlock(ifp);
- CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- crc = ether_crc32_be(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN);
- /* Just want the 6 least significant bits. */
- crc &= 0x3f;
- /* Set the corresponding bit in the hash table. */
- hashes[crc >> 5] |= 1 << (crc & 0x1f);
- }
- if_maddr_runlock(ifp);
+ if_foreach_llmaddr(ifp, sk_hash_maddr_yukon, hashes);
if (hashes[0] != 0 || hashes[1] != 0)
mode |= YU_RCR_MUFLEN;
}
More information about the svn-src-head
mailing list