[][kernel][common][hnat][Refactor entry fp and special tag assignment for handling DSA device]

[Description]
Refactor entry fp and special tag assignment for handling DSA device.

With this patch, driver would try to check if the netdevice
is a DSA slave device through linux kernel function rather than
using the device name "lan" as condition, can better support different
type of switch DSA.

[Release-log]
N/A


Change-Id: Ie171739d239b08134632266d69070d0350868a9f
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9337220
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
index 4985dd7..c59e97e 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/if.h>
 #include <linux/if_ether.h>
+#include <net/dsa.h>
 #include <net/netevent.h>
 #include <net/netfilter/nf_conntrack_zones.h>
 #include <linux/mod_devicetable.h>
@@ -1287,30 +1288,19 @@
 		hnat_set_entry_lock(entry, false);
 }
 
-#if defined(CONFIG_NET_DSA_MT7530)
-u32 hnat_dsa_fill_stag(const struct net_device *netdev,
+int hnat_dsa_fill_stag(const struct net_device *netdev,
 		       struct foe_entry *entry,
 		       struct flow_offload_hw_path *hw_path,
 		       u16 eth_proto, int mape);
-
+int hnat_dsa_get_port(struct net_device **dev);
 static inline bool hnat_dsa_is_enable(struct mtk_hnat *priv)
 {
+#if defined(CONFIG_NET_DSA)
 	return (priv->wan_dsa_port != NONE_DSA_PORT);
-}
 #else
-static inline u32 hnat_dsa_fill_stag(const struct net_device *netdev,
-				     struct foe_entry *entry,
-				     struct flow_offload_hw_path *hw_path,
-				     u16 eth_proto, int mape)
-{
-	return 0;
-}
-
-static inline bool hnat_dsa_is_enable(struct mtk_hnat *priv)
-{
 	return false;
-}
 #endif
+}
 
 void hnat_deinit_debugfs(struct mtk_hnat *h);
 int hnat_init_debugfs(struct mtk_hnat *h);
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index e28b349..6960462 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -1234,8 +1234,10 @@
 				     struct foe_entry *foe,
 				     struct flow_offload_hw_path *hw_path)
 {
+	struct net_device *master_dev = (struct net_device *)dev;
 	struct foe_entry entry = { 0 };
 	int whnat = IS_WHNAT(dev);
+	struct mtk_mac *mac;
 	struct ethhdr *eth;
 	struct iphdr *iph;
 	struct ipv6hdr *ip6h;
@@ -1245,11 +1247,10 @@
 	enum ip_conntrack_info ctinfo;
 	int gmac = NR_DISCARD;
 	int udp = 0;
+	int port_id = 0;
 	u32 qid = 0;
-	u32 port_id = 0;
 	u32 payload_len = 0;
 	int mape = 0;
-	struct mtk_mac *mac = netdev_priv(dev);
 
 	if (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPIP)
 		/* point to ethernet header for DS-Lite and MapE */
@@ -1700,33 +1701,25 @@
 	/* Fill Info Blk*/
 	entry = ppe_fill_info_blk(eth, entry, hw_path);
 
-	if (IS_LAN(dev)) {
-		if (IS_BOND_MODE) {
-			gmac = ((skb_hnat_entry(skb) >> 1) % hnat_priv->gmac_num) ?
-				 NR_GMAC2_PORT : NR_GMAC1_PORT;
-		} else if (IS_DSA_LAN(dev)) {
-			port_id = hnat_dsa_fill_stag(dev, &entry, hw_path,
-						     ntohs(eth->h_proto),
-						     mape);
-			gmac = NR_GMAC1_PORT;
-		} else {
-			gmac = HNAT_GMAC_FP(mac->id);
+	if (IS_LAN_GRP(dev) || IS_WAN(dev)) { /* Forward to GMAC Ports */
+		port_id = hnat_dsa_get_port(&master_dev);
+		if (port_id >= 0) {
+			if (hnat_dsa_fill_stag(dev, &entry, hw_path,
+					       ntohs(eth->h_proto), mape) < 0)
+				return 0;
 		}
-	} else if (IS_LAN2(dev)) {
+
+		mac = netdev_priv(master_dev);
 		gmac = HNAT_GMAC_FP(mac->id);
-	} else if (IS_WAN(dev)) {
-		if (mape_toggle && mape == 1) {
+
+		if (IS_LAN(dev) && IS_BOND_MODE) {
+			gmac = ((skb_hnat_entry(skb) >> 1) % hnat_priv->gmac_num) ?
+				 NR_GMAC2_PORT : NR_GMAC1_PORT;
+		} else if (IS_WAN(dev) && mape_toggle && mape == 1) {
 			gmac = NR_PDMA_PORT;
 			/* Set act_dp = wan_dev */
 			entry.ipv4_hnapt.act_dp &= ~UDF_PINGPONG_IFIDX;
 			entry.ipv4_hnapt.act_dp |= dev->ifindex & UDF_PINGPONG_IFIDX;
-		} else if (IS_DSA_WAN(dev)) {
-			port_id = hnat_dsa_fill_stag(dev, &entry, hw_path,
-						     ntohs(eth->h_proto),
-						     mape);
-			gmac = NR_GMAC1_PORT;
-		} else {
-			gmac = HNAT_GMAC_FP(mac->id);
 		}
 	} else if (IS_EXT(dev) && (FROM_GE_PPD(skb) || FROM_GE_LAN_GRP(skb) ||
 		   FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb) || FROM_WED(skb))) {
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_stag.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_stag.c
index 75c3a75..d8e5709 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_stag.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_stag.c
@@ -6,58 +6,77 @@
 
 #include <linux/of_device.h>
 #include <net/netfilter/nf_flow_table.h>
+
 #include "hnat.h"
 
+int hnat_dsa_get_port(struct net_device **dev)
+{
+#if defined(CONFIG_NET_DSA)
+	struct dsa_port *dp;
+
+	dp = dsa_port_from_netdev(*dev);
+	if (IS_ERR(dp))
+		return -ENODEV;
+
+	*dev = dp->cpu_dp->master;
+
+	return dp->index;
+#else
+	return -ENODEV;
+#endif
+}
+
-u32 hnat_dsa_fill_stag(const struct net_device *netdev,
+int hnat_dsa_fill_stag(const struct net_device *netdev,
 		       struct foe_entry *entry,
 		       struct flow_offload_hw_path *hw_path,
 		       u16 eth_proto,
 		       int mape)
 {
-	const struct net_device *ndev;
+#if defined(CONFIG_NET_DSA)
 	const unsigned int *port_reg;
+	const struct dsa_port *dp;
+	struct net_device *ndev;
 	int port_index;
-	u16 sp_tag;
+	u16 dsa_tag;
 
 	if (hw_path->flags & FLOW_OFFLOAD_PATH_VLAN)
 		ndev = hw_path->dev;
 	else
-		ndev = netdev;
+		ndev = (struct net_device *)netdev;
 
 	port_reg = of_get_property(ndev->dev.of_node, "reg", NULL);
 	if (unlikely(!port_reg))
 		return -EINVAL;
 
 	port_index = be32_to_cpup(port_reg);
-	sp_tag = BIT(port_index);
+
+	/* In the case MAPE LAN --> WAN, binding entry is to CPU.
+	 * Do not add special tag.
+	 */
+	if (IS_WAN(ndev) && mape)
+		return port_index;
+
+	dp = dsa_port_from_netdev(ndev);
+	if (IS_ERR(dp))
+		return -ENODEV;
+
+	dsa_tag = BIT(port_index);
 
 	if (!entry->bfib1.vlan_layer)
 		entry->bfib1.vlan_layer = 1;
 	else
 		/* VLAN existence indicator */
-		sp_tag |= BIT(8);
-	entry->bfib1.vpm = 0;
+		dsa_tag |= BIT(8);
 
-	switch (eth_proto) {
-	case ETH_P_IP:
-		if (entry->ipv4_hnapt.bfib1.pkt_type == IPV4_DSLITE
-			|| (entry->ipv4_hnapt.bfib1.pkt_type == IPV4_MAP_E))
-			entry->ipv4_dslite.etype = sp_tag;
-		else
-			entry->ipv4_hnapt.etype = sp_tag;
-		break;
-	case ETH_P_IPV6:
-		/* In the case MAPE LAN --> WAN, binding entry is to CPU.
-		 * Do not add special tag.
-		 */
-		if (!mape)
-			/* etype offset of ipv6 entries are the same. */
-			entry->ipv6_5t_route.etype = sp_tag;
+	if (IS_IPV4_GRP(entry))
+		entry->ipv4_hnapt.etype = dsa_tag;
+	else
+		entry->ipv6_5t_route.etype = dsa_tag;
 
-		break;
-	default:
-		pr_info("DSA + HNAT unsupport protocol\n");
-	}
+	entry->bfib1.vpm = 0;
 
 	return port_index;
+#else
+	return -EINVAL;
+#endif
 }