From 8bd97b07724abd3a1962cf8bebc4ebc43f561b5b Mon Sep 17 00:00:00 2001
From: Gleb Smirnoff <glebius@FreeBSD.org>
Date: Mon, 21 Oct 2019 18:11:08 +0000
Subject: [PATCH] Convert to if_foreach_llmaddr() KPI.

---
 sys/dev/cxgb/common/cxgb_xgmac.c | 49 +++++++++++++++++++-------------
 sys/dev/cxgb/cxgb_adapter.h      | 24 ----------------
 2 files changed, 30 insertions(+), 43 deletions(-)

diff --git a/sys/dev/cxgb/common/cxgb_xgmac.c b/sys/dev/cxgb/common/cxgb_xgmac.c
index 1dedc37f6f50..1df50fa873e9 100644
--- a/sys/dev/cxgb/common/cxgb_xgmac.c
+++ b/sys/dev/cxgb/common/cxgb_xgmac.c
@@ -408,9 +408,32 @@ static int hash_hw_addr(const u8 *addr)
  *	Configures the MAC Rx mode (promiscuity, etc) and exact and hash
  *	address filters.
  */
+struct t3_mcaddr_ctx {
+	struct cmac *mac;
+	u32 hash_lo, hash_hi;
+};
+
+static u_int
+t3_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+	struct t3_mcaddr_ctx *ctx = arg;
+	int hash;
+
+	if (ctx->mac->nucast + cnt < EXACT_ADDR_FILTERS)
+		set_addr_filter(ctx->mac, ctx->mac->nucast + cnt, LLADDR(sdl));
+	else {
+		hash = hash_hw_addr(LLADDR(sdl));
+		if (hash < 32)
+			ctx->hash_lo |= (1 << hash);
+		else
+			ctx->hash_hi |= (1 << (hash - 32));
+	}
+	return (1);
+}
+
 int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm)
 {
-	u32 hash_lo, hash_hi;
+	struct t3_mcaddr_ctx ctx;
 	adapter_t *adap = mac->adapter;
 	unsigned int oft = mac->offset;
 
@@ -422,27 +445,15 @@ int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm)
 			 mac->promisc_map ? F_COPYALLFRAMES : 0);
 
 	if (allmulti_rx_mode(rm) || mac->multiport)
-		hash_lo = hash_hi = 0xffffffff;
+		ctx.hash_lo = ctx.hash_hi = 0xffffffff;
 	else {
-		u8 *addr;
-		int exact_addr_idx = mac->nucast;
-
-		hash_lo = hash_hi = 0;
-		while ((addr = t3_get_next_mcaddr(rm)))
-			if (exact_addr_idx < EXACT_ADDR_FILTERS)
-				set_addr_filter(mac, exact_addr_idx++, addr);
-			else {
-				int hash = hash_hw_addr(addr);
-
-				if (hash < 32)
-					hash_lo |= (1 << hash);
-				else
-					hash_hi |= (1 << (hash - 32));
-			}
+		ctx.mac = mac;
+		ctx.hash_lo = ctx.hash_hi = 0;
+		if_foreach_llmaddr(rm->port->ifp, t3_hash_maddr, &ctx);
 	}
 
-	t3_write_reg(adap, A_XGM_RX_HASH_LOW + oft, hash_lo);
-	t3_write_reg(adap, A_XGM_RX_HASH_HIGH + oft, hash_hi);
+	t3_write_reg(adap, A_XGM_RX_HASH_LOW + oft, ctx.hash_lo);
+	t3_write_reg(adap, A_XGM_RX_HASH_HIGH + oft, ctx.hash_hi);
 	return 0;
 }
 
diff --git a/sys/dev/cxgb/cxgb_adapter.h b/sys/dev/cxgb/cxgb_adapter.h
index 6e5b8da2dc23..97e7d96ec7aa 100644
--- a/sys/dev/cxgb/cxgb_adapter.h
+++ b/sys/dev/cxgb/cxgb_adapter.h
@@ -463,30 +463,6 @@ t3_os_pci_write_config_2(adapter_t *adapter, int reg, uint16_t val)
 	pci_write_config(adapter->dev, reg, val, 2);
 }
 
-static __inline uint8_t *
-t3_get_next_mcaddr(struct t3_rx_mode *rm)
-{
-	uint8_t *macaddr = NULL;
-	struct ifnet *ifp = rm->port->ifp;
-	struct ifmultiaddr *ifma;
-	int i = 0;
-
-	if_maddr_rlock(ifp);
-	CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
-		if (ifma->ifma_addr->sa_family != AF_LINK)
-			continue;
-		if (i == rm->idx) {
-			macaddr = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
-			break;
-		}
-		i++;
-	}
-	if_maddr_runlock(ifp);
-	
-	rm->idx++;
-	return (macaddr);
-}
-
 static __inline void
 t3_init_rx_mode(struct t3_rx_mode *rm, struct port_info *port)
 {