From 74d9d646399cfc30e8a7a2209dff4d89a5acd2d6 Mon Sep 17 00:00:00 2001
From: Ashish Kumar <ashish.kumar4@infineon.com>
Date: Tue, 11 Apr 2023 06:19:27 -0500
Subject: [PATCH 184/296] brcmfmac: offload: clean & add all entries in ICMP,ND
 for ipv6 notification

This is done to align the code execution wrt to existing design where wll
ndoe entries were getting cleared then each new entry was added
independently. This will keep IPv6 address table aligned with host table.


Signed-off-by: Ashish Kumar <ashish.kumar4@infineon.com>
---
 .../broadcom/brcm80211/brcmfmac/common.c      |  6 +++--
 .../broadcom/brcm80211/brcmfmac/common.h      |  4 +--
 .../broadcom/brcm80211/brcmfmac/core.c        | 27 ++++++++++++++-----
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index b68b29d005d0..8c3d28218f23 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -214,8 +214,8 @@ void brcmf_generic_offload_host_ipv4_update(struct brcmf_if *ifp, unsigned int o
 			  is_add ? "added" : "deleted", &ipaddr);
 }
 
-void brcmf_generic_offload_host_ipv6_update(struct brcmf_if *ifp, unsigned int ol_feat,
-					    void *ptr, u8 type, bool is_add)
+int brcmf_generic_offload_host_ipv6_update(struct brcmf_if *ifp, unsigned int ol_feat,
+					   void *ptr, u8 type, bool is_add)
 {
 	struct brcmf_ol_cfg_v1 ol_cfg = {0};
 	u32 ol_feat_skip = ~ol_feat;
@@ -237,6 +237,8 @@ void brcmf_generic_offload_host_ipv6_update(struct brcmf_if *ifp, unsigned int o
 	else
 		brcmf_dbg(TRACE, "successfully %s host address %pI6",
 			  is_add ? "add" : "del", ptr);
+
+	return err;
 }
 
 void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index 5a32f64a462e..c36479a9ed73 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -115,7 +115,7 @@ void brcmf_generic_offload_enable(struct brcmf_if *ifp, unsigned int ol_feat,
 				  bool enable);
 void brcmf_generic_offload_host_ipv4_update(struct brcmf_if *ifp, unsigned int ol_feat,
 					    u32 ipaddr, bool is_add);
-void brcmf_generic_offload_host_ipv6_update(struct brcmf_if *ifp, unsigned int ol_feat,
-					    void *ptr, u8 type, bool is_add);
+int brcmf_generic_offload_host_ipv6_update(struct brcmf_if *ifp, unsigned int ol_feat,
+					   void *ptr, u8 type, bool is_add);
 
 #endif /* BRCMFMAC_COMMON_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index cc80a80c2a61..9b6f2ce96f15 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -363,30 +363,43 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
-static void _brcmf_update_ndtable(struct work_struct *work)
+static void brcmf_update_ipv6_addr(struct work_struct *work)
 {
 	struct brcmf_if *ifp = container_of(work, struct brcmf_if,
 					    ndoffload_work);
 	struct brcmf_pub *drvr = ifp->drvr;
 	int i, ret;
+	struct ipv6_addr addr = {0};
 
 	/* clear the table in firmware */
-	ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0);
+
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_OFFLOADS))
+		ret = brcmf_generic_offload_host_ipv6_update(ifp, BRCMF_OL_ICMP | BRCMF_OL_ND,
+							     &addr, 1, false);
+	else
+		ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0);
+
 	if (ret) {
 		brcmf_dbg(TRACE, "fail to clear nd ip table err:%d\n", ret);
 		return;
 	}
 
 	for (i = 0; i < ifp->ipv6addr_idx; i++) {
-		ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip",
-					       &ifp->ipv6_addr_tbl[i],
-					       sizeof(struct in6_addr));
+		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_OFFLOADS))
+			ret = brcmf_generic_offload_host_ipv6_update(ifp,
+								     BRCMF_OL_ICMP | BRCMF_OL_ND,
+								     &ifp->ipv6_addr_tbl[i],
+								     0, true);
+		else
+			ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip",
+						       &ifp->ipv6_addr_tbl[i],
+						       sizeof(struct in6_addr));
 		if (ret)
 			bphy_err(drvr, "add nd ip err %d\n", ret);
 	}
 }
 #else
-static void _brcmf_update_ndtable(struct work_struct *work)
+static void brcmf_update_ipv6_addr(struct work_struct *work)
 {
 }
 #endif
@@ -959,7 +972,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool locked)
 	dev_net_set(ndev, wiphy_net(cfg_to_wiphy(drvr->config)));
 
 	INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
-	INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable);
+	INIT_WORK(&ifp->ndoffload_work, brcmf_update_ipv6_addr);
 
 	if (locked)
 		err = cfg80211_register_netdevice(ndev);
-- 
2.25.1

