[][openwrt][mt7988][tops][Add rate limit on QDMA queue]

[Description]
Add rate limit on QDMA queue.
Since TOPS use QDMA qid = 12 which has no rate limit. 10G LAN to 2.5G
WAN will drop packets at WAN interface.
When flow is bind, detect WAN line rate and set rate limit on QDMA
queue 12.

[Release-log]
N/A


Change-Id: I8836602e3140f9af916681b91ad7c4f211d48bd7
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7900703
diff --git a/target/linux/mediatek/patches-5.4/999-4100-mtk-tops-tunnel-offload-support.patch b/target/linux/mediatek/patches-5.4/999-4100-mtk-tops-tunnel-offload-support.patch
index a4a6d95..65781ca 100644
--- a/target/linux/mediatek/patches-5.4/999-4100-mtk-tops-tunnel-offload-support.patch
+++ b/target/linux/mediatek/patches-5.4/999-4100-mtk-tops-tunnel-offload-support.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -245,6 +245,9 @@ static const char * const mtk_clks_sourc
+@@ -246,6 +246,9 @@ static const char * const mtk_clks_sourc
  	"top_netsys_warp_sel",
  };
  
@@ -10,7 +10,7 @@
  void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
  {
  	__raw_writel(val, eth->base + reg);
-@@ -2089,6 +2092,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2172,6 +2175,7 @@ static int mtk_poll_rx(struct napi_struc
  	u64 addr64 = 0;
  	u8 *data, *new_data;
  	struct mtk_rx_dma_v2 *rxd, trxd;
@@ -18,7 +18,7 @@
  	int done = 0;
  
  	if (unlikely(!ring))
-@@ -2132,11 +2136,20 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2215,11 +2219,20 @@ static int mtk_poll_rx(struct napi_struc
  				      0 : RX_DMA_GET_SPORT(trxd.rxd4) - 1;
  		}
  
@@ -43,7 +43,7 @@
  
  		if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
  			goto release_desc;
-@@ -2221,6 +2234,8 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2304,6 +2317,8 @@ static int mtk_poll_rx(struct napi_struc
  		skb_hnat_alg(skb) = 0;
  		skb_hnat_filled(skb) = 0;
  		skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
@@ -94,16 +94,16 @@
  {
 --- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
 +++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
-@@ -1085,6 +1085,8 @@ enum FoeIpAct {
- #define NR_WDMA0_PORT 8
+@@ -1087,6 +1087,8 @@ enum FoeIpAct {
  #define NR_WDMA1_PORT 9
+ #define NR_WDMA2_PORT 13
  #define NR_GMAC3_PORT 15
 +#define NR_TDMA_TPORT 4
 +#define NR_TDMA_QDMA_TPORT 5
  #define LAN_DEV_NAME hnat_priv->lan
  #define LAN2_DEV_NAME hnat_priv->lan2
  #define IS_WAN(dev)                                                            \
-@@ -1208,6 +1210,8 @@ static inline bool hnat_dsa_is_enable(st
+@@ -1210,6 +1212,8 @@ static inline bool hnat_dsa_is_enable(st
  }
  #endif
  
@@ -112,7 +112,7 @@
  void hnat_deinit_debugfs(struct mtk_hnat *h);
  int hnat_init_debugfs(struct mtk_hnat *h);
  int hnat_register_nf_hooks(void);
-@@ -1224,6 +1228,9 @@ extern int qos_ul_toggle;
+@@ -1226,6 +1230,9 @@ extern int qos_ul_toggle;
  extern int hook_toggle;
  extern int mape_toggle;
  extern int qos_toggle;
@@ -192,7 +192,7 @@
  	rcu_read_unlock_bh();
  
  	return 0;
-@@ -1202,6 +1233,37 @@ static struct ethhdr *get_ipv6_ipip_ethh
+@@ -1202,6 +1233,72 @@ static struct ethhdr *get_ipv6_ipip_ethh
  	return eth;
  }
  
@@ -207,8 +207,42 @@
 +	       sizeof(*entry));
 +}
 +
++static inline void hnat_qos_tnl(u32 id, const struct net_device *dev)
++{
++	u32 cfg;
++	u32 max_man = 0;
++	u32 max_exp = 0;
++	const struct mtk_mac *mac;
++
++	if (!dev)
++		return;
++	mac = netdev_priv(dev);
++
++	switch (mac->speed) {
++	case SPEED_100:
++	case SPEED_1000:
++	case SPEED_2500:
++	case SPEED_5000:
++	case SPEED_10000:
++		max_man = mac->speed / SPEED_100;
++		max_exp = 5;
++		break;
++	default:
++		return;
++	}
++
++	cfg = QTX_SCH_MIN_RATE_EN | QTX_SCH_MAX_RATE_EN;
++	cfg |= (1 << QTX_SCH_MIN_RATE_MAN_OFFSET) |
++	       (4 << QTX_SCH_MIN_RATE_EXP_OFFSET) |
++	       (max_man << QTX_SCH_MAX_RATE_MAN_OFFSET) |
++	       (max_exp << QTX_SCH_MAX_RATE_EXP_OFFSET) |
++	       (4 << QTX_SCH_MAX_RATE_WGHT_OFFSET);
++	writel(cfg, hnat_priv->fe_base + QTX_SCH(id % NUM_OF_Q_PER_PAGE));
++}
++
 +static inline void hnat_fill_offload_engine_entry(struct sk_buff *skb,
-+						  struct foe_entry *entry)
++						  struct foe_entry *entry,
++						  const struct net_device *dev)
 +{
 +#if defined(CONFIG_MEDIATEK_NETSYS_V3)
 +	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) {
@@ -224,13 +258,14 @@
 +	}
 +
 +	entry->ipv4_hnapt.iblk2.qid = 12; /* offload engine use QID 12 */
++	hnat_qos_tnl(12, dev); /* set rate limit to line rate */
 +#endif /* defined(CONFIG_MEDIATEK_NETSYS_V3) */
 +}
 +
  static unsigned int skb_to_hnat_info(struct sk_buff *skb,
  				     const struct net_device *dev,
  				     struct foe_entry *foe,
-@@ -1237,6 +1299,11 @@ static unsigned int skb_to_hnat_info(str
+@@ -1238,6 +1335,11 @@ static unsigned int skb_to_hnat_info(str
  	if (whnat && is_hnat_pre_filled(foe))
  		return 0;
  
@@ -242,7 +277,7 @@
  	entry.bfib1.pkt_type = foe->udib1.pkt_type; /* Get packte type state*/
  	entry.bfib1.state = foe->udib1.state;
  
-@@ -1247,6 +1314,7 @@ static unsigned int skb_to_hnat_info(str
+@@ -1248,6 +1350,7 @@ static unsigned int skb_to_hnat_info(str
  	switch (ntohs(eth->h_proto)) {
  	case ETH_P_IP:
  		iph = ip_hdr(skb);
@@ -250,7 +285,7 @@
  		switch (iph->protocol) {
  		case IPPROTO_UDP:
  			udp = 1;
-@@ -1628,6 +1696,10 @@ static unsigned int skb_to_hnat_info(str
+@@ -1629,6 +1732,10 @@ static unsigned int skb_to_hnat_info(str
  	/* Fill Layer2 Info.*/
  	entry = ppe_fill_L2_info(eth, entry, hw_path);
  
@@ -261,12 +296,12 @@
  	/* Fill Info Blk*/
  	entry = ppe_fill_info_blk(eth, entry, hw_path);
  
-@@ -1806,7 +1878,20 @@ static unsigned int skb_to_hnat_info(str
+@@ -1827,7 +1934,20 @@ static unsigned int skb_to_hnat_info(str
  			entry.ipv6_5t_route.act_dp |= UDF_HNAT_PRE_FILLED;
  	}
  
 +#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+	hnat_fill_offload_engine_entry(skb, &entry);
++	hnat_fill_offload_engine_entry(skb, &entry, dev);
 +#endif
 +
 +hnat_entry_skip_bind:
@@ -282,7 +317,7 @@
  	memcpy(foe, &entry, sizeof(entry));
  	/*reset statistic for this entry*/
  	if (hnat_priv->data->per_flow_accounting &&
-@@ -1859,6 +1944,7 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
+@@ -1880,6 +2000,7 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
  		return NF_ACCEPT;
  
  	eth = eth_hdr(skb);
@@ -290,7 +325,7 @@
  	memcpy(&bfib1_tx, &entry->bfib1, sizeof(entry->bfib1));
  
  	/*not bind multicast if PPE mcast not enable*/
-@@ -1878,6 +1964,12 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
+@@ -1899,6 +2020,12 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
  	switch ((int)bfib1_tx.pkt_type) {
  	case IPV4_HNAPT:
  	case IPV4_HNAT:
@@ -303,18 +338,18 @@
  		entry->ipv4_hnapt.smac_hi = swab32(*((u32 *)eth->h_source));
  		entry->ipv4_hnapt.smac_lo = swab16(*((u16 *)&eth->h_source[4]));
  		break;
-@@ -2037,6 +2129,10 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
+@@ -2060,6 +2187,10 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
  		entry->ipv6_5t_route.iblk2.dp = gmac_no;
  	}
  
 +#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+	hnat_fill_offload_engine_entry(skb, entry);
++	hnat_fill_offload_engine_entry(skb, entry, NULL);
 +#endif
 +
  	bfib1_tx.ttl = 1;
  	bfib1_tx.state = BIND;
  	wmb();
-@@ -2058,6 +2154,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
+@@ -2081,6 +2212,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
  	}
  
  	skb_hnat_alg(skb) = 0;
@@ -322,7 +357,7 @@
  	skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
  
  	if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
-@@ -2504,6 +2601,7 @@ static unsigned int mtk_hnat_nf_post_rou
+@@ -2529,6 +2661,7 @@ static unsigned int mtk_hnat_nf_post_rou
  	struct flow_offload_hw_path hw_path = { .dev = (struct net_device*)out,
  						.virt_dev = (struct net_device*)out };
  	const struct net_device *arp_dev = out;
@@ -330,7 +365,7 @@
  
  	if (xlat_toggle && !mtk_464xlat_post_process(skb, out))
  		return 0;
-@@ -2524,10 +2622,18 @@ static unsigned int mtk_hnat_nf_post_rou
+@@ -2549,10 +2682,18 @@ static unsigned int mtk_hnat_nf_post_rou
  
  	if (out->netdev_ops->ndo_flow_offload_check) {
  		out->netdev_ops->ndo_flow_offload_check(&hw_path);
@@ -349,7 +384,7 @@
  		return 0;
  
  	trace_printk("[%s] case hit, %x-->%s, reason=%x\n", __func__,
-@@ -2547,9 +2653,18 @@ static unsigned int mtk_hnat_nf_post_rou
+@@ -2572,9 +2713,18 @@ static unsigned int mtk_hnat_nf_post_rou
  		if (fn && !mtk_hnat_accel_type(skb))
  			break;
  
@@ -369,7 +404,7 @@
  		skb_to_hnat_info(skb, out, entry, &hw_path);
  		break;
  	case HIT_BIND_KEEPALIVE_DUP_OLD_HDR:
-@@ -2820,7 +2935,7 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
+@@ -2845,7 +2995,7 @@ 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);
@@ -438,7 +473,7 @@
  	u8 eth_dest[ETH_ALEN];
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1868,6 +1868,9 @@ extern const struct of_device_id of_mtk_
+@@ -1874,6 +1874,9 @@ extern const struct of_device_id of_mtk_
  extern u32 mtk_hwlro_stats_ebl;
  extern u32 dbg_show_level;