diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 35eb5343d7d7..5a8e875430fe 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -1506,41 +1506,45 @@ wi_info_intr(struct wi_softc *sc) CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO); } +struct wi_mcast_ctx { + struct wi_mcast mlist; + int mcnt; +}; + +static u_int +wi_copy_mcast(void *arg, struct sockaddr_dl *sdl, u_int count) +{ + struct wi_mcast_ctx *ctx = arg; + + if (ctx->mcnt >= 16) + return (0); + IEEE80211_ADDR_COPY(&ctx->mlist.wi_mcast[ctx->mcnt++], LLADDR(sdl)); + + return (1); +} + static int wi_write_multi(struct wi_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap; - struct wi_mcast mlist; - int n; + struct wi_mcast_ctx ctx; if (ic->ic_allmulti > 0 || ic->ic_promisc > 0) { allmulti: - memset(&mlist, 0, sizeof(mlist)); - return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, - sizeof(mlist)); + memset(&ctx.mlist, 0, sizeof(ctx.mlist)); + return wi_write_rid(sc, WI_RID_MCAST_LIST, &ctx.mlist, + sizeof(ctx.mlist)); } - n = 0; + ctx.mcnt = 0; TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - struct ifnet *ifp; - struct ifmultiaddr *ifma; - - ifp = vap->iv_ifp; - if_maddr_rlock(ifp); - CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - if (n >= 16) - goto allmulti; - IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], - (LLADDR((struct sockaddr_dl *)ifma->ifma_addr))); - n++; - } - if_maddr_runlock(ifp); + if_foreach_llmaddr(vap->iv_ifp, wi_copy_mcast, &ctx); + if (ctx.mcnt >= 16) + goto allmulti; } - return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, - IEEE80211_ADDR_LEN * n); + return wi_write_rid(sc, WI_RID_MCAST_LIST, &ctx.mlist, + IEEE80211_ADDR_LEN * ctx.mcnt); } static void