Author: glebius
Date: Mon Oct 21 18:11:11 2019
New Revision: 353841
URL: https://svnweb.freebsd.org/changeset/base/353841

Log:
  Convert to if_foreach_llmaddr() KPI.

Modified:
  head/sys/dev/cxgbe/t4_main.c

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c        Mon Oct 21 18:11:08 2019        
(r353840)
+++ head/sys/dev/cxgbe/t4_main.c        Mon Oct 21 18:11:11 2019        
(r353841)
@@ -4782,7 +4782,55 @@ apply_link_config(struct port_info *pi)
 }
 
 #define FW_MAC_EXACT_CHUNK     7
+struct mcaddr_ctx {
+       struct ifnet *ifp;
+       const uint8_t *mcaddr[FW_MAC_EXACT_CHUNK];
+       uint64_t hash;
+       int i;
+       int del;
+       int rc;
+};
 
+static u_int
+add_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+       struct mcaddr_ctx *ctx = arg;
+       struct vi_info *vi = ctx->ifp->if_softc;
+       struct port_info *pi = vi->pi;
+       struct adapter *sc = pi->adapter;
+
+       if (ctx->rc < 0)
+               return (0);
+
+       ctx->mcaddr[ctx->i] = LLADDR(sdl);
+       MPASS(ETHER_IS_MULTICAST(ctx->mcaddr[ctx->i]));
+       ctx->i++;
+
+       if (ctx->i == FW_MAC_EXACT_CHUNK) {
+               ctx->rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, ctx->del,
+                   ctx->i, ctx->mcaddr, NULL, &ctx->hash, 0);
+               if (ctx->rc < 0) {
+                       int j;
+
+                       for (j = 0; j < ctx->i; j++) {
+                               if_printf(ctx->ifp,
+                                   "failed to add mc address"
+                                   " %02x:%02x:%02x:"
+                                   "%02x:%02x:%02x rc=%d\n",
+                                   ctx->mcaddr[j][0], ctx->mcaddr[j][1],
+                                   ctx->mcaddr[j][2], ctx->mcaddr[j][3],
+                                   ctx->mcaddr[j][4], ctx->mcaddr[j][5],
+                                   -ctx->rc);
+                       }
+                       return (0);
+               }
+               ctx->del = 0;
+               ctx->i = 0;
+       }
+
+       return (1);
+}
+
 /*
  * Program the port's XGMAC based on parameters in ifnet.  The caller also
  * indicates which parameters should be programmed (the rest are left alone).
@@ -4838,66 +4886,51 @@ update_mac_settings(struct ifnet *ifp, int flags)
        }
 
        if (flags & XGMAC_MCADDRS) {
-               const uint8_t *mcaddr[FW_MAC_EXACT_CHUNK];
-               int del = 1;
-               uint64_t hash = 0;
-               struct ifmultiaddr *ifma;
-               int i = 0, j;
+               struct epoch_tracker et;
+               struct mcaddr_ctx ctx;
+               int j;
 
-               if_maddr_rlock(ifp);
-               CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
-                       if (ifma->ifma_addr->sa_family != AF_LINK)
-                               continue;
-                       mcaddr[i] =
-                           LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
-                       MPASS(ETHER_IS_MULTICAST(mcaddr[i]));
-                       i++;
-
-                       if (i == FW_MAC_EXACT_CHUNK) {
-                               rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid,
-                                   del, i, mcaddr, NULL, &hash, 0);
-                               if (rc < 0) {
-                                       rc = -rc;
-                                       for (j = 0; j < i; j++) {
-                                               if_printf(ifp,
-                                                   "failed to add mc address"
-                                                   " %02x:%02x:%02x:"
-                                                   "%02x:%02x:%02x rc=%d\n",
-                                                   mcaddr[j][0], mcaddr[j][1],
-                                                   mcaddr[j][2], mcaddr[j][3],
-                                                   mcaddr[j][4], mcaddr[j][5],
-                                                   rc);
-                                       }
-                                       goto mcfail;
-                               }
-                               del = 0;
-                               i = 0;
-                       }
+               ctx.ifp = ifp;
+               ctx.hash = 0;
+               ctx.i = 0;
+               ctx.del = 1;
+               /*
+                * Unlike other drivers, we accumulate list of pointers into
+                * interface address lists and we need to keep it safe even
+                * after if_foreach_llmaddr() returns, thus we must enter the
+                * network epoch.
+                */
+               NET_EPOCH_ENTER(et);
+               if_foreach_llmaddr(ifp, add_maddr, &ctx);
+               if (ctx.rc < 0) {
+                       NET_EPOCH_EXIT(et);
+                       rc = -ctx.rc;
+                       return (rc);
                }
-               if (i > 0) {
-                       rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, del, i,
-                           mcaddr, NULL, &hash, 0);
+               if (ctx.i > 0) {
+                       rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid,
+                           ctx.del, ctx.i, ctx.mcaddr, NULL, &ctx.hash, 0);
+                       NET_EPOCH_EXIT(et);
                        if (rc < 0) {
                                rc = -rc;
-                               for (j = 0; j < i; j++) {
+                               for (j = 0; j < ctx.i; j++) {
                                        if_printf(ifp,
                                            "failed to add mc address"
                                            " %02x:%02x:%02x:"
                                            "%02x:%02x:%02x rc=%d\n",
-                                           mcaddr[j][0], mcaddr[j][1],
-                                           mcaddr[j][2], mcaddr[j][3],
-                                           mcaddr[j][4], mcaddr[j][5],
+                                           ctx.mcaddr[j][0], ctx.mcaddr[j][1],
+                                           ctx.mcaddr[j][2], ctx.mcaddr[j][3],
+                                           ctx.mcaddr[j][4], ctx.mcaddr[j][5],
                                            rc);
                                }
-                               goto mcfail;
+                               return (rc);
                        }
-               }
+               } else
+                       NET_EPOCH_EXIT(et);
 
-               rc = -t4_set_addr_hash(sc, sc->mbox, vi->viid, 0, hash, 0);
+               rc = -t4_set_addr_hash(sc, sc->mbox, vi->viid, 0, ctx.hash, 0);
                if (rc != 0)
                        if_printf(ifp, "failed to set mc address hash: %d", rc);
-mcfail:
-               if_maddr_runlock(ifp);
        }
 
        return (rc);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to