[][MAC80211][hnat][Fix 2.5G LAN/WAN low t-Put issue for the PPPQ]
[Description]
Fix 2.5G LAN/WAN low t-Put issue for the PPPQ.
In the current PPPQ design, the Lan0~5 ports are limited to 1Gbps.
Consequently, the 2.5G Lan5 is also restricted to 1Gbps, leading to
poor DL and Bi-Di performance.
Therefore, we exclude the 2.5G WAN to 2.5G Lan5 case from the PPPQ in
order to avoid an unnecessary rate-limited operation.
Without this patch, the user may experience the poor perforamce in
the 2.5G LAN/WAN scenario.
[Release-log]
N/A
Change-Id: I6178feaab929a1c6dc14ca738a66e94c04afea9d
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7905304
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3014-flow-offload-add-mtkhnat-qdma-qos.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3014-flow-offload-add-mtkhnat-qdma-qos.patch
index fd9a5d4..82a7cac 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3014-flow-offload-add-mtkhnat-qdma-qos.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3014-flow-offload-add-mtkhnat-qdma-qos.patch
@@ -1,5 +1,23 @@
+From 1a2252c2c16462f065983f18dfb45c2b9e6ca324 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Wed, 23 Aug 2023 12:56:42 +0800
+Subject: [PATCH] 999-3014-flow-offload-add-mtkhnat-qdma-qos
+
+---
+ drivers/net/ethernet/mediatek/Makefile | 2 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 49 +-
+ drivers/net/ethernet/mediatek/mtk_ppe.c | 28 +-
+ drivers/net/ethernet/mediatek/mtk_ppe.h | 28 ++
+ .../net/ethernet/mediatek/mtk_ppe_offload.c | 28 +-
+ .../net/ethernet/mediatek/mtk_qdma_debugfs.c | 439 ++++++++++++++++++
+ include/net/flow_offload.h | 1 +
+ net/netfilter/nf_flow_table_offload.c | 4 +-
+ 9 files changed, 583 insertions(+), 6 deletions(-)
+ create mode 100644 drivers/net/ethernet/mediatek/mtk_qdma_debugfs.c
+
diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile
-index 0c724a5..93cd55f 100644
+index fdbb90f..c7d2296 100644
--- a/drivers/net/ethernet/mediatek/Makefile
+++ b/drivers/net/ethernet/mediatek/Makefile
@@ -5,7 +5,7 @@
@@ -12,10 +30,10 @@
ifdef CONFIG_DEBUG_FS
mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index ca76047..809c735 100644
+index ab09bec..1dcdd17 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4787,6 +4787,8 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5014,6 +5014,8 @@ static int mtk_probe(struct platform_device *pdev)
}
mtk_ppe_debugfs_init(eth);
@@ -24,7 +42,7 @@
}
for (i = 0; i < MTK_MAX_DEVS; i++) {
-@@ -4901,6 +4903,7 @@ static const struct mtk_soc_data mt2701_data = {
+@@ -5126,6 +5128,7 @@ static const struct mtk_soc_data mt2701_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -32,7 +50,7 @@
},
};
-@@ -4920,6 +4923,7 @@ static const struct mtk_soc_data mt7621_data = {
+@@ -5146,6 +5149,7 @@ static const struct mtk_soc_data mt7621_data = {
.rxd_size = sizeof(struct mtk_rx_dma),
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -40,7 +58,7 @@
},
};
-@@ -4940,6 +4944,7 @@ static const struct mtk_soc_data mt7622_data = {
+@@ -5167,6 +5171,7 @@ static const struct mtk_soc_data mt7622_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -48,7 +66,7 @@
},
};
-@@ -4959,6 +4964,7 @@ static const struct mtk_soc_data mt7623_data = {
+@@ -5187,6 +5192,7 @@ static const struct mtk_soc_data mt7623_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -56,7 +74,7 @@
},
};
-@@ -4997,6 +5003,7 @@ static const struct mtk_soc_data mt7986_data = {
+@@ -5227,6 +5233,7 @@ static const struct mtk_soc_data mt7986_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT_V2,
@@ -64,7 +82,7 @@
},
};
-@@ -5017,6 +5024,7 @@ static const struct mtk_soc_data mt7981_data = {
+@@ -5248,6 +5255,7 @@ static const struct mtk_soc_data mt7981_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT_V2,
@@ -72,7 +90,7 @@
},
};
-@@ -5034,6 +5042,7 @@ static const struct mtk_soc_data mt7988_data = {
+@@ -5266,6 +5274,7 @@ static const struct mtk_soc_data mt7988_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT_V2,
@@ -80,7 +98,7 @@
},
};
-@@ -5051,6 +5060,7 @@ static const struct mtk_soc_data rt5350_data = {
+@@ -5284,6 +5293,7 @@ static const struct mtk_soc_data rt5350_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -89,10 +107,10 @@
};
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index c6afff5..bd73c27 100644
+index ee4c851..83a5fec 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -385,10 +385,21 @@
+@@ -398,10 +398,21 @@
/* QDMA TX Queue Configuration Registers */
#define MTK_QTX_CFG(x) (QDMA_BASE + (x * 0x10))
@@ -114,7 +132,7 @@
/* QDMA RX Base Pointer Register */
#define MTK_QRX_BASE_PTR0 (QDMA_BASE + 0x100)
-@@ -406,7 +417,9 @@
+@@ -419,7 +430,9 @@
#define MTK_QRX_DRX_IDX0 (QDMA_BASE + 0x10c)
/* QDMA Page Configuration Register */
@@ -125,7 +143,7 @@
/* QDMA Global Configuration Register */
#define MTK_QDMA_GLO_CFG (QDMA_BASE + 0x204)
-@@ -443,6 +456,9 @@
+@@ -456,6 +469,9 @@
#define FC_THRES_DROP_EN (7 << 16)
#define FC_THRES_MIN 0x4444
@@ -134,8 +152,8 @@
+
/* QDMA Interrupt Status Register */
#define MTK_QDMA_INT_STATUS (QDMA_BASE + 0x218)
- #if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
-@@ -478,6 +494,11 @@
+ #if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
+@@ -492,6 +508,11 @@
/* QDMA Interrupt Mask Register */
#define MTK_QDMA_HRED2 (QDMA_BASE + 0x244)
@@ -147,7 +165,7 @@
/* QDMA TX Forward CPU Pointer Register */
#define MTK_QTX_CTX_PTR (QDMA_BASE +0x300)
-@@ -505,6 +526,14 @@
+@@ -519,6 +540,14 @@
/* QDMA FQ Free Page Buffer Length Register */
#define MTK_QDMA_FQ_BLEN (QDMA_BASE +0x32c)
@@ -162,7 +180,7 @@
/* WDMA Registers */
#define MTK_WDMA_CTX_PTR(x) (WDMA_BASE(x) + 0x8)
#define MTK_WDMA_DTX_PTR(x) (WDMA_BASE(x) + 0xC)
-@@ -1596,6 +1625,7 @@ struct mtk_soc_data {
+@@ -1682,6 +1711,7 @@ struct mtk_soc_data {
u32 rx_dma_l4_valid;
u32 dma_max_len;
u32 dma_len_offset;
@@ -170,7 +188,7 @@
} txrx;
};
-@@ -1736,6 +1766,7 @@ struct mtk_eth {
+@@ -1868,6 +1898,7 @@ struct mtk_eth {
spinlock_t syscfg0_lock;
struct timer_list mtk_dma_monitor_timer;
@@ -178,18 +196,48 @@
u8 ppe_num;
struct mtk_ppe *ppe[MTK_MAX_PPE_NUM];
struct rhashtable flow_table;
-@@ -1815,4 +1846,6 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
- void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
+@@ -1906,6 +1937,20 @@ extern const struct of_device_id of_mtk_match[];
+ extern u32 mtk_hwlro_stats_ebl;
+ extern u32 dbg_show_level;
+
++static inline int
++mtk_ppe_check_pppq_path(struct mtk_foe_entry *foe, int dsa_port)
++{
++ u32 sp;
++
++ if ((dsa_port >= 0 && dsa_port <= 4) ||
++ (dsa_port == 5 && (sp == PSE_WDMA0_PORT ||
++ sp == PSE_WDMA1_PORT ||
++ sp == PSE_WDMA2_PORT)))
++ return 1;
++
++ return 0;
++}
++
+ /* read the hardware status register */
+ void mtk_stats_update_mac(struct mtk_mac *mac);
+
+@@ -1938,4 +1983,6 @@ void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
+ u32 mtk_rss_indr_table(struct mtk_rss_params *rss_params, int index);
int mtk_ppe_debugfs_init(struct mtk_eth *eth);
+
+int mtk_qdma_debugfs_init(struct mtk_eth *eth);
#endif /* MTK_ETH_H */
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index a49275f..1767823 100755
+index 107f5a1..ed677e1 100755
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -406,6 +406,16 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
+@@ -128,7 +128,7 @@ static void mtk_ppe_cache_enable(struct mtk_ppe *ppe, bool enable)
+ enable * MTK_PPE_CACHE_CTL_EN);
+ }
+
+-static u32 mtk_ppe_hash_entry(struct mtk_ppe *ppe, struct mtk_foe_entry *e)
++u32 mtk_ppe_hash_entry(struct mtk_ppe *ppe, struct mtk_foe_entry *e)
+ {
+ u32 hv1, hv2, hv3;
+ u32 hash;
+@@ -420,12 +420,38 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
return 0;
}
@@ -206,20 +254,72 @@
static inline bool mtk_foe_entry_usable(struct mtk_foe_entry *entry)
{
return !(entry->ib1 & MTK_FOE_IB1_STATIC) &&
+ FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1) != MTK_FOE_STATE_BIND;
+ }
+
++bool mtk_foe_entry_match(struct mtk_foe_entry *entry, struct mtk_foe_entry *data)
++{
++ int type, len;
++
++ if ((data->ib1 ^ entry->ib1) & MTK_FOE_IB1_UDP)
++ return false;
++
++ type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
++ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE)
++ len = offsetof(struct mtk_foe_entry, ipv6._rsv);
++ else
++ len = offsetof(struct mtk_foe_entry, ipv4.ib2);
++
++ return !memcmp(&entry->data, &data->data, len - 4);
++}
++
+ static bool
+ mtk_flow_entry_match(struct mtk_flow_entry *entry, struct mtk_foe_entry *data)
+ {
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
-index 8076e5d..c46c4d9 100644
+index 86288b0..53bb6d2 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -356,6 +356,7 @@ int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid);
+@@ -403,9 +403,37 @@ int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid);
int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid);
int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
int bss, int wcid);
+int mtk_foe_entry_set_qid(struct mtk_foe_entry *entry, int qid);
++bool mtk_foe_entry_match(struct mtk_foe_entry *entry, struct mtk_foe_entry *data);
int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
+ struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, struct mtk_foe_accounting *diff);
++u32 mtk_ppe_hash_entry(struct mtk_ppe *ppe, struct mtk_foe_entry *e);
++
++#if defined(CONFIG_MEDIATEK_NETSYS_V2)
++static inline int
++mtk_foe_entry_set_sp(struct mtk_ppe *ppe, struct mtk_foe_entry *entry)
++{
++ struct mtk_foe_entry *hwe;
++ u32 sp, hash;
++ int i;
++
++ sp = 0;
++ hash = mtk_ppe_hash_entry(ppe, entry);
++ for (i = 0; i < ppe->way; i++) {
++ hwe = &ppe->foe_table[hash + i];
++ if (mtk_foe_entry_match(hwe, entry)) {
++ sp = FIELD_GET(MTK_FOE_IB1_UNBIND_SRC_PORT, hwe->ib1);
++ break;
++ }
++ }
++ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_UNBIND_SRC_PORT, sp);
++
++ return 0;
++}
++#else
++static inline int mtk_foe_entry_set_sp(struct mtk_ppe *ppe, struct mtk_foe_entry *entry);
++#endif
+
+ #endif
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-index f258539..3b17819 100755
+index f7af72a..d71878c 100755
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
@@ -9,6 +9,8 @@
@@ -244,7 +344,7 @@
if (dsa_port >= 0)
mtk_foe_entry_set_dsa(foe, dsa_port);
-+ if (eth->qos_toggle == 2 && dsa_port >= 0)
++ if (eth->qos_toggle == 2 && mtk_ppe_check_pppq_path(foe, dsa_port))
+ mtk_foe_entry_set_qid(foe, dsa_port & MTK_QDMA_TX_MASK);
+
if (dev == eth->netdev[0])
@@ -274,60 +374,23 @@
mtk_foe_entry_set_pse_port(foe, pse_port);
return 0;
-@@ -432,7 +455,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
+@@ -447,7 +469,9 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
if (data.pppoe.num == 1)
mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid);
- err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest,
++ mtk_foe_entry_set_sp(eth->ppe[ppe_index], &foe);
++
+ err = mtk_flow_set_output_device(eth, &foe, odev, f->flow->ct, data.eth.h_dest,
&wed_index);
if (err)
return err;
-diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
-index 59b8736..7261b6d 100644
---- a/include/net/flow_offload.h
-+++ b/include/net/flow_offload.h
-@@ -365,6 +378,7 @@ struct flow_cls_offload {
- struct flow_cls_common_offload common;
- enum flow_cls_command command;
- unsigned long cookie;
-+ struct flow_offload *flow;
- struct flow_rule *rule;
- struct flow_stats stats;
- u32 classid;
-diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
-index d94c6fb..886ced5 100644
---- a/net/netfilter/nf_flow_table_offload.c
-+++ b/net/netfilter/nf_flow_table_offload.c
-@@ -810,11 +810,13 @@ static int nf_flow_offload_alloc(const struct flow_offload_work *offload,
- }
-
- static void nf_flow_offload_init(struct flow_cls_offload *cls_flow,
-+ struct flow_offload *flow,
- __be16 proto, int priority,
- enum flow_cls_command cmd,
- const struct flow_offload_tuple *tuple,
- struct netlink_ext_ack *extack)
- {
-+ cls_flow->flow = flow;
- cls_flow->common.protocol = proto;
- cls_flow->common.prio = priority;
- cls_flow->common.extack = extack;
-@@ -836,7 +838,7 @@ static int nf_flow_offload_tuple(struct nf_flowtable *flowtable,
- __be16 proto = ETH_P_ALL;
- int err, i = 0;
-
-- nf_flow_offload_init(&cls_flow, proto, priority, cmd,
-+ nf_flow_offload_init(&cls_flow, flow, proto, priority, cmd,
- &flow->tuplehash[dir].tuple, &extack);
- if (cmd == FLOW_CLS_REPLACE)
- cls_flow.rule = flow_rule->rule;
diff --git a/drivers/net/ethernet/mediatek/mtk_qdma_debugfs.c b/drivers/net/ethernet/mediatek/mtk_qdma_debugfs.c
new file mode 100644
-index 0000000..198b924
+index 0000000..3a7c585
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/mtk_qdma_debugfs.c
-@@ -0,0 +1,435 @@
+@@ -0,0 +1,439 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2022 MediaTek Inc.
@@ -435,8 +498,12 @@
+{
+ struct mtk_eth *eth = m->private;
+
-+ seq_printf(m, "value=%d, HQoS is %s now!\n",
-+ eth->qos_toggle, (eth->qos_toggle) ? "enabled" : "disabled");
++ if (eth->qos_toggle == 0)
++ pr_info("HQoS is disabled now!\n");
++ else if (eth->qos_toggle == 1)
++ pr_info("HQoS is enabled now!\n");
++ else if (eth->qos_toggle == 2)
++ pr_info("Per-port-per-queue mode is enabled!\n");
+
+ return 0;
+}
@@ -763,3 +830,45 @@
+
+ return 0;
+}
+diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
+index 59b8736..c4eb45c 100644
+--- a/include/net/flow_offload.h
++++ b/include/net/flow_offload.h
+@@ -365,6 +365,7 @@ struct flow_cls_offload {
+ struct flow_cls_common_offload common;
+ enum flow_cls_command command;
+ unsigned long cookie;
++ struct flow_offload *flow;
+ struct flow_rule *rule;
+ struct flow_stats stats;
+ u32 classid;
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index 50f2f2e..ba34572 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -810,11 +810,13 @@ static int nf_flow_offload_alloc(const struct flow_offload_work *offload,
+ }
+
+ static void nf_flow_offload_init(struct flow_cls_offload *cls_flow,
++ struct flow_offload *flow,
+ __be16 proto, int priority,
+ enum flow_cls_command cmd,
+ const struct flow_offload_tuple *tuple,
+ struct netlink_ext_ack *extack)
+ {
++ cls_flow->flow = flow;
+ cls_flow->common.protocol = proto;
+ cls_flow->common.prio = priority;
+ cls_flow->common.extack = extack;
+@@ -836,7 +838,7 @@ static int nf_flow_offload_tuple(struct nf_flowtable *flowtable,
+ __be16 proto = ETH_P_ALL;
+ int err, i = 0;
+
+- nf_flow_offload_init(&cls_flow, proto, priority, cmd,
++ nf_flow_offload_init(&cls_flow, flow, proto, priority, cmd,
+ &flow->tuplehash[dir].tuple, &extack);
+ if (cmd == FLOW_CLS_REPLACE)
+ cls_flow.rule = flow_rule->rule;
+--
+2.18.0
+