[][openwrt][mt7988][crypto][Refactor binding path for IPsec encryption]

[Description]
Change original binding flow for IPsec encryption.
To solve unsynchronized sequence number problem, bring the binding
point forward to xfrm framework.
1. Remove original binding flow in last post routing.
2. Export function to bind ipsec flows for crypto driver.

[Release-log]
N/A


Change-Id: I54b6dfcc19cb32f1cd4fb7921e902096a6df683c
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8135609
diff --git a/target/linux/mediatek/patches-5.4/999-4102-mtk-crypto-offload-support.patch b/target/linux/mediatek/patches-5.4/999-4102-mtk-crypto-offload-support.patch
index 75880ed..96deb54 100644
--- a/target/linux/mediatek/patches-5.4/999-4102-mtk-crypto-offload-support.patch
+++ b/target/linux/mediatek/patches-5.4/999-4102-mtk-crypto-offload-support.patch
@@ -1,6 +1,33 @@
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2316,6 +2316,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1840,6 +1840,11 @@ static void mtk_tx_set_dma_desc_v3(struc
+ 	trace_printk("[%s] skb_shinfo(skb)->nr_frags=%x HNAT_SKB_CB2(skb)->magic=%x txd4=%x<-----\n",
+ 		     __func__, skb_shinfo(skb)->nr_frags, HNAT_SKB_CB2(skb)->magic, data);
+ #endif
++	/* forward to eip197 if this packet is going to encrypt */
++	if (unlikely(skb_hnat_cdrt(skb) && is_magic_tag_valid(skb))) {
++		data &= ((~TX_DMA_TPORT_MASK) << TX_DMA_TPORT_SHIFT);
++		data |= (EIP197_QDMA_TPORT & TX_DMA_TPORT_MASK) << TX_DMA_TPORT_SHIFT;
++	}
+ 	WRITE_ONCE(desc->txd4, data);
+ 
+ 	data = 0;
+@@ -1862,6 +1867,14 @@ static void mtk_tx_set_dma_desc_v3(struc
+ 
+ 	WRITE_ONCE(desc->txd7, 0);
+ 	WRITE_ONCE(desc->txd8, 0);
++	if (unlikely(skb_hnat_cdrt(skb) && is_magic_tag_valid(skb))) {
++		/* carry cdrt index for encryption */
++		data = (skb_hnat_cdrt(skb) & TX_DMA_CDRT_MASK) << TX_DMA_CDRT_SHIFT;
++		WRITE_ONCE(desc->txd8, data);
++		skb_hnat_magic_tag(skb) = 0;
++	} else {
++		WRITE_ONCE(desc->txd8, 0);
++	}
+ }
+ 
+ static void mtk_tx_set_dma_desc(struct sk_buff *skb, struct net_device *dev, void *txd,
+@@ -2331,6 +2344,7 @@ static int mtk_poll_rx(struct napi_struc
  
  		skb_hnat_alg(skb) = 0;
  		skb_hnat_filled(skb) = 0;
@@ -20,24 +47,6 @@
  	rcu_read_lock_bh();
  	nexthop = (__force u32)rt_nexthop(rt, ip_hdr(skb)->daddr);
  	neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
-@@ -1097,7 +1100,7 @@ static unsigned int hnat_ipv4_get_nextho
- 	 * outer header, we must update its outer mac header pointer
- 	 * before filling outer mac or it may screw up inner mac
- 	 */
--	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) {
-+	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) || skb_hnat_cdrt(skb)) {
- 		skb_push(skb, sizeof(struct ethhdr));
- 		skb_reset_mac_header(skb);
- 	}
-@@ -1105,7 +1108,7 @@ static unsigned int hnat_ipv4_get_nextho
- 	memcpy(eth_hdr(skb)->h_dest, neigh->ha, ETH_ALEN);
- 	memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN);
- 
--	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
-+	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) || skb_hnat_cdrt(skb))
- 		skb_pull(skb, sizeof(struct ethhdr));
- 
- 	rcu_read_unlock_bh();
 @@ -1299,6 +1302,9 @@ static inline void hnat_fill_offload_eng
  		 */
  		entry->ipv4_hnapt.tport_id = NR_TDMA_QDMA_TPORT;
@@ -48,36 +57,83 @@
  	} else {
  		return;
  	}
-@@ -1344,7 +1350,8 @@ static unsigned int skb_to_hnat_info(str
- 	if (whnat && is_hnat_pre_filled(foe))
- 		return 0;
- 
--	if (skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL)) {
-+	if ((skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL))
-+	    || (skb_hnat_cdrt(skb) && skb_dst(skb) && !dst_xfrm(skb_dst(skb)))) {
- 		hnat_get_filled_unbind_entry(skb, &entry);
- 		goto hnat_entry_bind;
- 	}
-@@ -1744,7 +1751,8 @@ static unsigned int skb_to_hnat_info(str
- 	/* Fill Layer2 Info.*/
- 	entry = ppe_fill_L2_info(eth, entry, hw_path);
- 
--	if (skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
-+	if ((skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
-+	    || (!skb_hnat_cdrt(skb) && skb_dst(skb) && dst_xfrm(skb_dst(skb))))
- 		goto hnat_entry_skip_bind;
- 
- hnat_entry_bind:
-@@ -1950,6 +1958,8 @@ hnat_entry_bind:
- 
- #if defined(CONFIG_MEDIATEK_NETSYS_V3)
- 	hnat_fill_offload_engine_entry(skb, &entry, dev);
-+	if (skb_hnat_cdrt(skb))
-+		entry = ppe_fill_L2_info(eth, entry, hw_path);
- #endif
+@@ -1308,6 +1314,75 @@ static inline void hnat_fill_offload_eng
+ #endif /* defined(CONFIG_MEDIATEK_NETSYS_V3) */
+ }
  
- hnat_entry_skip_bind:
-@@ -2227,6 +2237,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
++int hnat_bind_crypto_entry(struct sk_buff *skb, const struct net_device *dev) {
++	struct foe_entry *foe;
++	struct foe_entry entry = { 0 };
++	struct ethhdr *eth = eth_hdr(skb);
++	u32 gmac = NR_DISCARD;
++
++	if (skb_hnat_tops(skb) && mtk_tnl_encap_offload)
++		mtk_tnl_encap_offload(skb);
++
++	foe = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
++
++	hnat_get_filled_unbind_entry(skb, &entry);
++	entry.bfib1.cah = 1;
++	entry.bfib1.time_stamp = (hnat_priv->data->version == MTK_HNAT_V2 ||
++				 hnat_priv->data->version == MTK_HNAT_V3) ?
++		readl(hnat_priv->fe_base + 0x0010) & (0xFF) :
++		readl(hnat_priv->fe_base + 0x0010) & (0x7FFF);
++	entry.ipv4_hnapt.iblk2.port_ag =
++		(hnat_priv->data->version == MTK_HNAT_V2 ||
++		 hnat_priv->data->version == MTK_HNAT_V3) ? 0xf : 0x3f;
++
++	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
++			gmac = NR_GMAC1_PORT;
++	} else if (IS_LAN2(dev)) {
++		gmac = NR_GMAC2_PORT;
++	} else if (IS_WAN(dev)) {
++		gmac = (IS_GMAC1_MODE) ? NR_GMAC1_PORT : NR_GMAC2_PORT;
++	} else {
++		pr_notice("Unknown case of dp, iif=%x --> %s\n", skb_hnat_iface(skb), dev->name);
++		return -1;
++	}
++
++	entry.ipv4_hnapt.iblk2.mibf = 1;
++	entry.ipv4_hnapt.iblk2.dp = gmac;
++	entry.ipv4_hnapt.iblk2.port_mg =
++		(hnat_priv->data->version == MTK_HNAT_V1_1) ? 0x3f : 0;
++	entry.bfib1.ttl = 1;
++	entry.bfib1.state = BIND;
++
++	hnat_fill_offload_engine_entry(skb, &entry, dev);
++
++	if (!skb_hnat_tops(skb)) {
++		entry.ipv4_hnapt.dmac_hi = swab32(*((u32 *)eth->h_dest));
++		entry.ipv4_hnapt.dmac_lo = swab16(*((u16 *)&eth->h_dest[4]));
++		entry.ipv4_hnapt.smac_hi = swab32(*((u32 *)eth->h_source));
++		entry.ipv4_hnapt.smac_lo = swab16(*((u16 *)&eth->h_source[4]));
++	}
++
++	wmb();
++
++	if (entry_hnat_is_bound(foe))
++		return 0;
++
++	memcpy(foe, &entry, sizeof(entry));
++
++	if (hnat_priv->data->per_flow_accounting &&
++	    skb_hnat_entry(skb) < hnat_priv->foe_etry_num &&
++	    skb_hnat_ppe(skb) < CFG_PPE_NUM)
++		memset(&hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
++		       0, sizeof(struct mib_entry));
++
++	return 0;
++}
++EXPORT_SYMBOL(hnat_bind_crypto_entry);
++
+ static unsigned int skb_to_hnat_info(struct sk_buff *skb,
+ 				     const struct net_device *dev,
+ 				     struct foe_entry *foe,
+@@ -2364,6 +2439,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
  
  	skb_hnat_alg(skb) = 0;
  	skb_hnat_set_tops(skb, 0);
@@ -85,7 +141,7 @@
  	skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
  
  	if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
-@@ -2313,7 +2324,8 @@ static unsigned int mtk_hnat_accel_type(
+@@ -2450,7 +2526,8 @@ static unsigned int mtk_hnat_accel_type(
  	 * is from local_out which is also filtered in sanity check.
  	 */
  	dst = skb_dst(skb);
@@ -95,7 +151,7 @@
  		return 0;
  
  	ct = nf_ct_get(skb, &ctinfo);
-@@ -2709,6 +2721,14 @@ static unsigned int mtk_hnat_nf_post_rou
+@@ -2847,6 +2924,14 @@ static unsigned int mtk_hnat_nf_post_rou
  		}
  	}
  
@@ -110,7 +166,7 @@
  	if (!IS_LAN_GRP(out) && !IS_WAN(out) && !IS_EXT(out))
  		is_virt_dev = true;
  
-@@ -3016,7 +3036,10 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
+@@ -3157,7 +3242,10 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
  	if (iph->protocol == IPPROTO_IPV6) {
  		entry->udib1.pkt_type = IPV6_6RD;
  		hnat_set_head_frags(state, skb, 0, hnat_set_alg);
@@ -164,7 +220,7 @@
  {
 --- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
 +++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
-@@ -1087,6 +1087,8 @@ enum FoeIpAct {
+@@ -1135,6 +1135,8 @@ enum FoeIpAct {
  #define NR_WDMA1_PORT 9
  #define NR_WDMA2_PORT 13
  #define NR_GMAC3_PORT 15
@@ -173,11 +229,35 @@
  #define NR_TDMA_TPORT 4
  #define NR_TDMA_QDMA_TPORT 5
  #define LAN_DEV_NAME hnat_priv->lan
-@@ -1233,6 +1235,7 @@ extern int qos_toggle;
+@@ -1288,6 +1290,8 @@ extern int qos_toggle;
  extern int (*mtk_tnl_encap_offload)(struct sk_buff *skb);
  extern int (*mtk_tnl_decap_offload)(struct sk_buff *skb);
  extern bool (*mtk_tnl_decap_offloadable)(struct sk_buff *skb);
 +extern bool (*mtk_crypto_offloadable)(struct sk_buff *skb);
++extern int hnat_bind_crypto_entry(struct sk_buff *skb, const struct net_device *dev);
  
  int ext_if_add(struct extdev_entry *ext_entry);
  int ext_if_del(struct extdev_entry *ext_entry);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -551,6 +551,10 @@
+ 
+ #define MTK_QDMA_GMAC2_QID	8
+ 
++/* QDMA V2 descriptor txd8 */
++#define TX_DMA_CDRT_SHIFT 	0
++#define TX_DMA_CDRT_MASK	0xff
++
+ /* QDMA V2 descriptor txd6 */
+ #define TX_DMA_INS_VLAN_V2         BIT(16)
+ 
+@@ -560,6 +564,9 @@
+ #define TX_DMA_SPTAG_V3            BIT(27)
+ 
+ /* QDMA V2 descriptor txd4 */
++#define EIP197_QDMA_TPORT          3
++#define TX_DMA_TPORT_SHIFT         0
++#define TX_DMA_TPORT_MASK          0xf
+ #define TX_DMA_FPORT_SHIFT_V2      8
+ #define TX_DMA_FPORT_MASK_V2       0xf
+ #define TX_DMA_SWC_V2              BIT(30)
diff --git a/target/linux/mediatek/patches-5.4/999-4103-mtk-tunnel-crypto-offload-support.patch b/target/linux/mediatek/patches-5.4/999-4103-mtk-tunnel-crypto-offload-support.patch
index b2cc240..5cb8710 100644
--- a/target/linux/mediatek/patches-5.4/999-4103-mtk-tunnel-crypto-offload-support.patch
+++ b/target/linux/mediatek/patches-5.4/999-4103-mtk-tunnel-crypto-offload-support.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
 +++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
-@@ -1091,6 +1091,8 @@ enum FoeIpAct {
+@@ -1139,6 +1139,8 @@ enum FoeIpAct {
  #define NR_EIP197_QDMA_TPORT 3
  #define NR_TDMA_TPORT 4
  #define NR_TDMA_QDMA_TPORT 5
@@ -11,27 +11,27 @@
  #define IS_WAN(dev)                                                            \
 --- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
 +++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
-@@ -1099,7 +1099,8 @@ static unsigned int hnat_ipv4_get_nextho
+@@ -1100,7 +1100,8 @@ static unsigned int hnat_ipv4_get_nextho
  	 * outer header, we must update its outer mac header pointer
  	 * before filling outer mac or it may screw up inner mac
  	 */
--	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) || skb_hnat_cdrt(skb)) {
+-	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) {
 +	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
 +	    || (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb))) {
  		skb_push(skb, sizeof(struct ethhdr));
  		skb_reset_mac_header(skb);
  	}
-@@ -1107,7 +1108,8 @@ static unsigned int hnat_ipv4_get_nextho
+@@ -1108,7 +1109,8 @@ static unsigned int hnat_ipv4_get_nextho
  	memcpy(eth_hdr(skb)->h_dest, neigh->ha, ETH_ALEN);
  	memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN);
  
--	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) || skb_hnat_cdrt(skb))
+-	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
 +	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
 +	    || (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)))
  		skb_pull(skb, sizeof(struct ethhdr));
  
  	rcu_read_unlock_bh();
-@@ -1255,6 +1257,38 @@ static inline void hnat_get_filled_unbin
+@@ -1256,6 +1258,38 @@ static inline void hnat_get_filled_unbin
  	entry->bfib1.ps = 0;
  }
  
@@ -70,7 +70,7 @@
  static inline void hnat_qos_tnl(u32 id, const struct net_device *dev)
  {
  	u32 cfg;
-@@ -1299,9 +1333,15 @@ static inline void hnat_fill_offload_eng
+@@ -1300,9 +1334,15 @@ static inline void hnat_fill_offload_eng
  		 * we fill in hnat tport and tops_entry for tunnel encapsulation
  		 * offloading
  		 */
@@ -88,7 +88,7 @@
  		entry->ipv4_hnapt.tport_id = NR_EIP197_QDMA_TPORT;
  		entry->ipv4_hnapt.cdrt_id = skb_hnat_cdrt(skb);
  	} else {
-@@ -1333,6 +1373,7 @@ static unsigned int skb_to_hnat_info(str
+@@ -1405,6 +1445,7 @@ static unsigned int skb_to_hnat_info(str
  	u32 port_id = 0;
  	u32 payload_len = 0;
  	int mape = 0;
@@ -96,12 +96,11 @@
  
  	ct = nf_ct_get(skb, &ctinfo);
  
-@@ -1349,10 +1390,12 @@ static unsigned int skb_to_hnat_info(str
+@@ -1421,9 +1462,12 @@ static unsigned int skb_to_hnat_info(str
  	if (whnat && is_hnat_pre_filled(foe))
  		return 0;
  
--	if ((skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL))
--	    || (skb_hnat_cdrt(skb) && skb_dst(skb) && !dst_xfrm(skb_dst(skb)))) {
+-	if (skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL)) {
 +	ret = hnat_offload_engine_done(skb, hw_path);
 +	if (ret == 1) {
  		hnat_get_filled_unbind_entry(skb, &entry);
@@ -111,26 +110,18 @@
  	}
  
  	entry.bfib1.pkt_type = foe->udib1.pkt_type; /* Get packte type state*/
-@@ -1751,7 +1794,8 @@ static unsigned int skb_to_hnat_info(str
+@@ -1869,7 +1913,9 @@ static unsigned int skb_to_hnat_info(str
+ 	/* Fill Layer2 Info.*/
  	entry = ppe_fill_L2_info(eth, entry, hw_path);
  
- 	if ((skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
--	    || (!skb_hnat_cdrt(skb) && skb_dst(skb) && dst_xfrm(skb_dst(skb))))
+-	if (skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
++	if ((skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
 +	    || (!skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)
-+	        && skb_dst(skb) && dst_xfrm(skb_dst(skb))))
++		&& skb_dst(skb) && dst_xfrm(skb_dst(skb))))
  		goto hnat_entry_skip_bind;
  
  hnat_entry_bind:
-@@ -1957,7 +2001,7 @@ hnat_entry_bind:
- 
- #if defined(CONFIG_MEDIATEK_NETSYS_V3)
- 	hnat_fill_offload_engine_entry(skb, &entry, dev);
--	if (skb_hnat_cdrt(skb))
-+	if (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb))
- 		entry = ppe_fill_L2_info(eth, entry, hw_path);
- #endif
- 
-@@ -2237,6 +2281,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
+@@ -2442,6 +2488,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
  	skb_hnat_alg(skb) = 0;
  	skb_hnat_set_tops(skb, 0);
  	skb_hnat_set_cdrt(skb, 0);
@@ -138,7 +129,7 @@
  	skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
  
  	if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
-@@ -3037,7 +3082,8 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
+@@ -3245,7 +3292,8 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
  		entry->udib1.pkt_type = IPV6_6RD;
  		hnat_set_head_frags(state, skb, 0, hnat_set_alg);
  	} else if (is_magic_tag_valid(skb)
@@ -150,7 +141,7 @@
  		hnat_set_head_frags(state, skb, 1, hnat_set_alg);
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2324,10 +2324,11 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2344,10 +2344,11 @@ static int mtk_poll_rx(struct napi_struc
  
  		skb_hnat_alg(skb) = 0;
  		skb_hnat_filled(skb) = 0;
@@ -165,7 +156,7 @@
  			trace_printk("[%s] reason=0x%x(force to CPU) from WAN to Ext\n",
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -640,6 +640,9 @@
+@@ -649,6 +649,9 @@
  #define RX_DMA_GET_AGG_CNT_V2(_x)	(((_x) >> 16) & 0xff)
  #define RX_DMA_GET_TOPS_CRSN(_x)	(((_x) >> 24) & 0xff)