[][Add Dual-PPE Support for NF_HNAT]
[Description]
Add NETSYS V2 Dual-PPE Support for NF_HNAT in order
to achieve peak throughput requirement.
If want to enable dual-ppe mode, just modify dts node
as follows:
&hnat {
... ...
+ mtketh-ppe-num = <2>;
... ...
};
[Release-log]
N/A
Change-Id: Ibf6316f69592ad76aac2e5e36dac907127e23103
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/4526946
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
index 3e87791..de869b6 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
@@ -37,14 +37,22 @@
static void hnat_sma_build_entry(struct timer_list *t)
{
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, SMA, SMA_FWD_CPU_BUILD_ENTRY);
+ int i;
+
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_TB_CFG,
+ SMA, SMA_FWD_CPU_BUILD_ENTRY);
}
void hnat_cache_ebl(int enable)
{
- cr_set_field(hnat_priv->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 0);
- cr_set_field(hnat_priv->ppe_base + PPE_CAH_CTRL, CAH_EN, enable);
+ int i;
+
+ for (i = 0; i < CFG_PPE_NUM; i++) {
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_CAH_CTRL, CAH_X_MODE, 1);
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_CAH_CTRL, CAH_X_MODE, 0);
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_CAH_CTRL, CAH_EN, enable);
+ }
}
static void hnat_reset_timestamp(struct timer_list *t)
@@ -53,19 +61,19 @@
int hash_index;
hnat_cache_ebl(0);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, TCP_AGE, 0);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, UDP_AGE, 0);
+ cr_set_field(hnat_priv->ppe_base[0] + PPE_TB_CFG, TCP_AGE, 0);
+ cr_set_field(hnat_priv->ppe_base[0] + PPE_TB_CFG, UDP_AGE, 0);
writel(0, hnat_priv->fe_base + 0x0010);
for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
- entry = hnat_priv->foe_table_cpu + hash_index;
+ entry = hnat_priv->foe_table_cpu[0] + hash_index;
if (entry->bfib1.state == BIND)
entry->bfib1.time_stamp =
readl(hnat_priv->fe_base + 0x0010) & (0xFFFF);
}
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, TCP_AGE, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, UDP_AGE, 1);
+ cr_set_field(hnat_priv->ppe_base[0] + PPE_TB_CFG, TCP_AGE, 1);
+ cr_set_field(hnat_priv->ppe_base[0] + PPE_TB_CFG, UDP_AGE, 1);
hnat_cache_ebl(1);
mod_timer(&hnat_priv->hnat_reset_timestamp_timer, jiffies + 14400 * HZ);
@@ -139,7 +147,7 @@
BITS_GDM_ALL_FRC_P_CPU_PDMA);
}
-static int hnat_start(void)
+static int hnat_start(int ppe_id)
{
u32 foe_table_sz;
u32 foe_mib_tb_sz;
@@ -148,123 +156,127 @@
/* mapp the FOE table */
for (etry_num_cfg = DEF_ETRY_NUM_CFG ; etry_num_cfg >= 0 ; etry_num_cfg--, hnat_priv->foe_etry_num /= 2) {
foe_table_sz = hnat_priv->foe_etry_num * sizeof(struct foe_entry);
- hnat_priv->foe_table_cpu = dma_alloc_coherent(
- hnat_priv->dev, foe_table_sz, &hnat_priv->foe_table_dev, GFP_KERNEL);
+ hnat_priv->foe_table_cpu[ppe_id] = dma_alloc_coherent(
+ hnat_priv->dev, foe_table_sz,
+ &hnat_priv->foe_table_dev[ppe_id], GFP_KERNEL);
- if (hnat_priv->foe_table_cpu)
+ if (hnat_priv->foe_table_cpu[ppe_id])
break;
}
- if (!hnat_priv->foe_table_cpu)
+ if (!hnat_priv->foe_table_cpu[ppe_id])
return -1;
- dev_info(hnat_priv->dev, "FOE entry number = %d\n", hnat_priv->foe_etry_num);
+ dev_info(hnat_priv->dev, "PPE%d entry number = %d\n",
+ ppe_id, hnat_priv->foe_etry_num);
- writel(hnat_priv->foe_table_dev, hnat_priv->ppe_base + PPE_TB_BASE);
- memset(hnat_priv->foe_table_cpu, 0, foe_table_sz);
+ writel(hnat_priv->foe_table_dev[ppe_id], hnat_priv->ppe_base[ppe_id] + PPE_TB_BASE);
+ memset(hnat_priv->foe_table_cpu[ppe_id], 0, foe_table_sz);
if (hnat_priv->data->version == MTK_HNAT_V1)
- exclude_boundary_entry(hnat_priv->foe_table_cpu);
+ exclude_boundary_entry(hnat_priv->foe_table_cpu[ppe_id]);
if (hnat_priv->data->per_flow_accounting) {
foe_mib_tb_sz = hnat_priv->foe_etry_num * sizeof(struct mib_entry);
- hnat_priv->foe_mib_cpu = dma_alloc_coherent(hnat_priv->dev, foe_mib_tb_sz,
- &hnat_priv->foe_mib_dev, GFP_KERNEL);
- if (!hnat_priv->foe_mib_cpu)
+ hnat_priv->foe_mib_cpu[ppe_id] =
+ dma_alloc_coherent(hnat_priv->dev, foe_mib_tb_sz,
+ &hnat_priv->foe_mib_dev[ppe_id], GFP_KERNEL);
+ if (!hnat_priv->foe_mib_cpu[ppe_id])
return -1;
- writel(hnat_priv->foe_mib_dev, hnat_priv->ppe_base + PPE_MIB_TB_BASE);
- memset(hnat_priv->foe_mib_cpu, 0, foe_mib_tb_sz);
+ writel(hnat_priv->foe_mib_dev[ppe_id],
+ hnat_priv->ppe_base[ppe_id] + PPE_MIB_TB_BASE);
+ memset(hnat_priv->foe_mib_cpu[ppe_id], 0, foe_mib_tb_sz);
- hnat_priv->acct =
+ hnat_priv->acct[ppe_id] =
kzalloc(hnat_priv->foe_etry_num * sizeof(struct hnat_accounting),
GFP_KERNEL);
- if (!hnat_priv->acct)
+ if (!hnat_priv->acct[ppe_id])
return -1;
}
/* setup hashing */
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, TB_ETRY_NUM, etry_num_cfg);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, HASH_MODE, HASH_MODE_1);
- writel(HASH_SEED_KEY, hnat_priv->ppe_base + PPE_HASH_SEED);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, XMODE, 0);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, TB_ENTRY_SIZE, ENTRY_80B);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, SMA, SMA_FWD_CPU_BUILD_ENTRY);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, TB_ETRY_NUM, etry_num_cfg);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, HASH_MODE, HASH_MODE_1);
+ writel(HASH_SEED_KEY, hnat_priv->ppe_base[ppe_id] + PPE_HASH_SEED);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, XMODE, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, TB_ENTRY_SIZE, ENTRY_80B);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, SMA, SMA_FWD_CPU_BUILD_ENTRY);
/* set ip proto */
- writel(0xFFFFFFFF, hnat_priv->ppe_base + PPE_IP_PROT_CHK);
+ writel(0xFFFFFFFF, hnat_priv->ppe_base[ppe_id] + PPE_IP_PROT_CHK);
/* setup caching */
hnat_cache_ebl(1);
/* enable FOE */
- cr_set_bits(hnat_priv->ppe_base + PPE_FLOW_CFG,
+ cr_set_bits(hnat_priv->ppe_base[ppe_id] + PPE_FLOW_CFG,
BIT_UDP_IP4F_NAT_EN | BIT_IPV4_NAT_EN | BIT_IPV4_NAPT_EN |
BIT_IPV4_NAT_FRAG_EN | BIT_IPV4_HASH_GREK |
BIT_IPV4_DSL_EN | BIT_IPV6_6RD_EN |
BIT_IPV6_3T_ROUTE_EN | BIT_IPV6_5T_ROUTE_EN);
if (hnat_priv->data->version == MTK_HNAT_V4)
- cr_set_bits(hnat_priv->ppe_base + PPE_FLOW_CFG,
+ cr_set_bits(hnat_priv->ppe_base[ppe_id] + PPE_FLOW_CFG,
BIT_IPV4_MAPE_EN | BIT_IPV4_MAPT_EN);
/* setup FOE aging */
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, NTU_AGE, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, UNBD_AGE, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_UNB_AGE, UNB_MNP, 1000);
- cr_set_field(hnat_priv->ppe_base + PPE_UNB_AGE, UNB_DLTA, 3);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, TCP_AGE, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, UDP_AGE, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, FIN_AGE, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_BND_AGE_0, UDP_DLTA, 12);
- cr_set_field(hnat_priv->ppe_base + PPE_BND_AGE_0, NTU_DLTA, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_BND_AGE_1, FIN_DLTA, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_BND_AGE_1, TCP_DLTA, 7);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, NTU_AGE, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, UNBD_AGE, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_UNB_AGE, UNB_MNP, 1000);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_UNB_AGE, UNB_DLTA, 3);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, TCP_AGE, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, UDP_AGE, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, FIN_AGE, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_BND_AGE_0, UDP_DLTA, 12);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_BND_AGE_0, NTU_DLTA, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_BND_AGE_1, FIN_DLTA, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_BND_AGE_1, TCP_DLTA, 7);
/* setup FOE ka */
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, SCAN_MODE, 2);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, KA_CFG, 3);
- cr_set_field(hnat_priv->ppe_base + PPE_KA, KA_T, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_KA, TCP_KA, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_KA, UDP_KA, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_BIND_LMT_1, NTU_KA, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, SCAN_MODE, 2);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, KA_CFG, 3);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_KA, KA_T, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_KA, TCP_KA, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_KA, UDP_KA, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_BIND_LMT_1, NTU_KA, 1);
/* setup FOE rate limit */
- cr_set_field(hnat_priv->ppe_base + PPE_BIND_LMT_0, QURT_LMT, 16383);
- cr_set_field(hnat_priv->ppe_base + PPE_BIND_LMT_0, HALF_LMT, 16383);
- cr_set_field(hnat_priv->ppe_base + PPE_BIND_LMT_1, FULL_LMT, 16383);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_BIND_LMT_0, QURT_LMT, 16383);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_BIND_LMT_0, HALF_LMT, 16383);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_BIND_LMT_1, FULL_LMT, 16383);
/* setup binding threshold as 30 packets per second */
- cr_set_field(hnat_priv->ppe_base + PPE_BNDR, BIND_RATE, 0x1E);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_BNDR, BIND_RATE, 0x1E);
/* setup FOE cf gen */
- cr_set_field(hnat_priv->ppe_base + PPE_GLO_CFG, PPE_EN, 1);
- writel(0, hnat_priv->ppe_base + PPE_DFT_CPORT); /* pdma */
- /* writel(0x55555555, hnat_priv->ppe_base + PPE_DFT_CPORT); */ /* qdma */
- cr_set_field(hnat_priv->ppe_base + PPE_GLO_CFG, TTL0_DRP, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_GLO_CFG, PPE_EN, 1);
+ writel(0, hnat_priv->ppe_base[ppe_id] + PPE_DFT_CPORT); /* pdma */
+ /* writel(0x55555555, hnat_priv->ppe_base[ppe_id] + PPE_DFT_CPORT); */ /* qdma */
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_GLO_CFG, TTL0_DRP, 0);
if (hnat_priv->data->version == MTK_HNAT_V4) {
- writel(0xcb777, hnat_priv->ppe_base + PPE_DFT_CPORT1);
- writel(0x7f, hnat_priv->ppe_base + PPE_SBW_CTRL);
+ writel(0xcb777, hnat_priv->ppe_base[ppe_id] + PPE_DFT_CPORT1);
+ writel(0x7f, hnat_priv->ppe_base[ppe_id] + PPE_SBW_CTRL);
}
/*enable ppe mib counter*/
if (hnat_priv->data->per_flow_accounting) {
- cr_set_field(hnat_priv->ppe_base + PPE_MIB_CFG, MIB_EN, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_MIB_CFG, MIB_READ_CLEAR, 1);
- cr_set_field(hnat_priv->ppe_base + PPE_MIB_CAH_CTRL, MIB_CAH_EN, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_MIB_CFG, MIB_EN, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_MIB_CFG, MIB_READ_CLEAR, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_MIB_CAH_CTRL, MIB_CAH_EN, 1);
}
hnat_priv->g_ppdev = dev_get_by_name(&init_net, hnat_priv->ppd);
- dev_info(hnat_priv->dev, "hwnat start\n");
+ dev_info(hnat_priv->dev, "PPE%d hwnat start\n", ppe_id);
return 0;
}
-static int ppe_busy_wait(void)
+static int ppe_busy_wait(int ppe_id)
{
unsigned long t_start = jiffies;
u32 r = 0;
while (1) {
- r = readl((hnat_priv->ppe_base + 0x0));
+ r = readl((hnat_priv->ppe_base[ppe_id] + 0x0));
if (!(r & BIT(31)))
return 0;
if (time_after(jiffies, t_start + HZ))
@@ -277,7 +289,7 @@
return -1;
}
-static void hnat_stop(void)
+static void hnat_stop(int ppe_id)
{
u32 foe_table_sz;
u32 foe_mib_tb_sz;
@@ -290,9 +302,9 @@
dev_info(hnat_priv->dev, "hwnat stop\n");
- if (hnat_priv->foe_table_cpu) {
- entry = hnat_priv->foe_table_cpu;
- end = hnat_priv->foe_table_cpu + hnat_priv->foe_etry_num;
+ if (hnat_priv->foe_table_cpu[ppe_id]) {
+ entry = hnat_priv->foe_table_cpu[ppe_id];
+ end = hnat_priv->foe_table_cpu[ppe_id] + hnat_priv->foe_etry_num;
while (entry < end) {
entry->bfib1.state = INVALID;
entry++;
@@ -302,31 +314,31 @@
hnat_cache_ebl(0);
/* flush cache has to be ahead of hnat disable --*/
- cr_set_field(hnat_priv->ppe_base + PPE_GLO_CFG, PPE_EN, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_GLO_CFG, PPE_EN, 0);
/* disable scan mode and keep-alive */
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, SCAN_MODE, 0);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, KA_CFG, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, SCAN_MODE, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, KA_CFG, 0);
- ppe_busy_wait();
+ ppe_busy_wait(ppe_id);
/* disable FOE */
- cr_clr_bits(hnat_priv->ppe_base + PPE_FLOW_CFG,
+ cr_clr_bits(hnat_priv->ppe_base[ppe_id] + PPE_FLOW_CFG,
BIT_IPV4_NAPT_EN | BIT_IPV4_NAT_EN | BIT_IPV4_NAT_FRAG_EN |
BIT_IPV6_HASH_GREK | BIT_IPV4_DSL_EN |
BIT_IPV6_6RD_EN | BIT_IPV6_3T_ROUTE_EN |
BIT_IPV6_5T_ROUTE_EN | BIT_FUC_FOE | BIT_FMC_FOE);
if (hnat_priv->data->version == MTK_HNAT_V4)
- cr_clr_bits(hnat_priv->ppe_base + PPE_FLOW_CFG,
+ cr_clr_bits(hnat_priv->ppe_base[ppe_id] + PPE_FLOW_CFG,
BIT_IPV4_MAPE_EN | BIT_IPV4_MAPT_EN);
/* disable FOE aging */
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, NTU_AGE, 0);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, UNBD_AGE, 0);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, TCP_AGE, 0);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, UDP_AGE, 0);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, FIN_AGE, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, NTU_AGE, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, UNBD_AGE, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, TCP_AGE, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, UDP_AGE, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, FIN_AGE, 0);
r1 = readl(hnat_priv->fe_base + 0x100);
r2 = readl(hnat_priv->fe_base + 0x10c);
@@ -341,18 +353,20 @@
/* free the FOE table */
foe_table_sz = hnat_priv->foe_etry_num * sizeof(struct foe_entry);
- if (hnat_priv->foe_table_cpu)
- dma_free_coherent(hnat_priv->dev, foe_table_sz, hnat_priv->foe_table_cpu,
- hnat_priv->foe_table_dev);
- writel(0, hnat_priv->ppe_base + PPE_TB_BASE);
+ if (hnat_priv->foe_table_cpu[ppe_id])
+ dma_free_coherent(hnat_priv->dev, foe_table_sz,
+ hnat_priv->foe_table_cpu[ppe_id],
+ hnat_priv->foe_table_dev[ppe_id]);
+ writel(0, hnat_priv->ppe_base[ppe_id] + PPE_TB_BASE);
if (hnat_priv->data->per_flow_accounting) {
foe_mib_tb_sz = hnat_priv->foe_etry_num * sizeof(struct mib_entry);
- if (hnat_priv->foe_mib_cpu)
+ if (hnat_priv->foe_mib_cpu[ppe_id])
dma_free_coherent(hnat_priv->dev, foe_mib_tb_sz,
- hnat_priv->foe_mib_cpu, hnat_priv->foe_mib_dev);
- writel(0, hnat_priv->ppe_base + PPE_MIB_TB_BASE);
- kfree(hnat_priv->acct);
+ hnat_priv->foe_mib_cpu[ppe_id],
+ hnat_priv->foe_mib_dev[ppe_id]);
+ writel(0, hnat_priv->ppe_base[ppe_id] + PPE_MIB_TB_BASE);
+ kfree(hnat_priv->acct[ppe_id]);
}
}
@@ -404,20 +418,24 @@
int hnat_disable_hook(void)
{
- int hash_index;
+ int i, hash_index;
struct foe_entry *entry;
ra_sw_nat_hook_tx = NULL;
ra_sw_nat_hook_rx = NULL;
hnat_unregister_nf_hooks();
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, SMA, SMA_ONLY_FWD_CPU);
- for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
- entry = hnat_priv->foe_table_cpu + hash_index;
- if (entry->bfib1.state == BIND) {
- entry->ipv4_hnapt.udib1.state = INVALID;
- entry->ipv4_hnapt.udib1.time_stamp =
- readl((hnat_priv->fe_base + 0x0010)) & 0xFF;
+ for (i = 0; i < CFG_PPE_NUM; i++) {
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_TB_CFG,
+ SMA, SMA_ONLY_FWD_CPU);
+
+ for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
+ entry = hnat_priv->foe_table_cpu[i] + hash_index;
+ if (entry->bfib1.state == BIND) {
+ entry->ipv4_hnapt.udib1.state = INVALID;
+ entry->ipv4_hnapt.udib1.time_stamp =
+ readl((hnat_priv->fe_base + 0x0010)) & 0xFF;
+ }
}
}
@@ -502,6 +520,15 @@
dev_info(&pdev->dev, "wan dsa port = %d\n", hnat_priv->wan_dsa_port);
}
+ err = of_property_read_u32_index(np, "mtketh-ppe-num", 0, &val);
+
+ if (err < 0)
+ hnat_priv->ppe_num = 1;
+ else
+ hnat_priv->ppe_num = val;
+
+ dev_info(&pdev->dev, "ppe num = %d\n", hnat_priv->ppe_num);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOENT;
@@ -511,8 +538,14 @@
if (!hnat_priv->fe_base)
return -EADDRNOTAVAIL;
- hnat_priv->ppe_base = (hnat_priv->data->version == MTK_HNAT_V4) ?
- hnat_priv->fe_base + 0x2600 : hnat_priv->fe_base + 0xe00;
+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
+ hnat_priv->ppe_base[0] = hnat_priv->fe_base + 0x2200;
+
+ if (CFG_PPE_NUM > 1)
+ hnat_priv->ppe_base[1] = hnat_priv->fe_base + 0x2600;
+#else
+ hnat_priv->ppe_base[0] = hnat_priv->fe_base + 0xe00;
+#endif
err = hnat_init_debugfs(hnat_priv);
if (err)
@@ -538,9 +571,11 @@
hnat_priv->lvid = 1;
hnat_priv->wvid = 2;
- err = hnat_start();
- if (err)
- goto err_out;
+ for (i = 0; i < CFG_PPE_NUM; i++) {
+ err = hnat_start(i);
+ if (err)
+ goto err_out;
+ }
if (hnat_priv->data->whnat) {
err = whnat_adjust_nf_hooks();
@@ -554,8 +589,12 @@
register_netdevice_notifier(&nf_hnat_netdevice_nb);
register_netevent_notifier(&nf_hnat_netevent_nb);
- if (hnat_priv->data->mcast)
- hnat_mcast_enable();
+
+ if (hnat_priv->data->mcast) {
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ hnat_mcast_enable(i);
+ }
+
timer_setup(&hnat_priv->hnat_sma_build_entry_timer, hnat_sma_build_entry, 0);
if (hnat_priv->data->version == MTK_HNAT_V3) {
timer_setup(&hnat_priv->hnat_reset_timestamp_timer, hnat_reset_timestamp, 0);
@@ -571,7 +610,8 @@
return 0;
err_out:
- hnat_stop();
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ hnat_stop(i);
err_out1:
hnat_deinit_debugfs(hnat_priv);
for (i = 0; i < MAX_EXT_DEVS && hnat_priv->ext_if[i]; i++) {
@@ -584,6 +624,8 @@
static int hnat_remove(struct platform_device *pdev)
{
+ int i;
+
unregister_netdevice_notifier(&nf_hnat_netdevice_nb);
unregister_netevent_notifier(&nf_hnat_netevent_nb);
hnat_disable_hook();
@@ -591,7 +633,9 @@
if (hnat_priv->data->mcast)
hnat_mcast_disable();
- hnat_stop();
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ hnat_stop(i);
+
hnat_deinit_debugfs(hnat_priv);
hnat_release_netdev();
del_timer_sync(&hnat_priv->hnat_sma_build_entry_timer);
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
index 336b4ad..734b6bd 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -587,6 +587,13 @@
#define MAX_EXT_DEVS (0x3fU)
#define MAX_IF_NUM 64
+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
+#define MAX_PPE_NUM 2
+#else
+#define MAX_PPE_NUM 1
+#endif
+#define CFG_PPE_NUM (hnat_priv->ppe_num)
+
struct mib_entry {
u32 byt_cnt_l;
u16 byt_cnt_h;
@@ -619,17 +626,17 @@
struct mtk_hnat {
struct device *dev;
void __iomem *fe_base;
- void __iomem *ppe_base;
- struct foe_entry *foe_table_cpu;
- dma_addr_t foe_table_dev;
+ void __iomem *ppe_base[MAX_PPE_NUM];
+ struct foe_entry *foe_table_cpu[MAX_PPE_NUM];
+ dma_addr_t foe_table_dev[MAX_PPE_NUM];
u8 enable;
u8 enable1;
struct dentry *root;
- struct debugfs_regset32 *regset;
+ struct debugfs_regset32 *regset[MAX_PPE_NUM];
- struct mib_entry *foe_mib_cpu;
- dma_addr_t foe_mib_dev;
- struct hnat_accounting *acct;
+ struct mib_entry *foe_mib_cpu[MAX_PPE_NUM];
+ dma_addr_t foe_mib_dev[MAX_PPE_NUM];
+ struct hnat_accounting *acct[MAX_PPE_NUM];
const struct mtk_hnat_data *data;
/*devices we plays for*/
@@ -641,6 +648,7 @@
struct reset_control *rstc;
+ u8 ppe_num;
u8 gmac_num;
u8 wan_dsa_port;
struct ppe_mcast_table *pmcast;
@@ -725,10 +733,10 @@
#define BIT_IPV4_MAPT_EN BIT(22)
/*GDMA_FWD_CFG value*/
-#define BITS_GDM_UFRC_P_PPE (NR_PPE_PORT << 12)
-#define BITS_GDM_BFRC_P_PPE (NR_PPE_PORT << 8)
-#define BITS_GDM_MFRC_P_PPE (NR_PPE_PORT << 4)
-#define BITS_GDM_OFRC_P_PPE (NR_PPE_PORT << 0)
+#define BITS_GDM_UFRC_P_PPE (NR_PPE0_PORT << 12)
+#define BITS_GDM_BFRC_P_PPE (NR_PPE0_PORT << 8)
+#define BITS_GDM_MFRC_P_PPE (NR_PPE0_PORT << 4)
+#define BITS_GDM_OFRC_P_PPE (NR_PPE0_PORT << 0)
#define BITS_GDM_ALL_FRC_P_PPE \
(BITS_GDM_UFRC_P_PPE | BITS_GDM_BFRC_P_PPE | BITS_GDM_MFRC_P_PPE | \
BITS_GDM_OFRC_P_PPE)
@@ -794,8 +802,14 @@
#define NR_PDMA_PORT 0
#define NR_GMAC1_PORT 1
#define NR_GMAC2_PORT 2
+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
+#define NR_WHNAT_WDMA_PORT EINVAL
+#define NR_PPE0_PORT 3
+#define NR_PPE1_PORT 4
+#else
#define NR_WHNAT_WDMA_PORT 3
-#define NR_PPE_PORT 4
+#define NR_PPE0_PORT 4
+#endif
#define NR_QDMA_PORT 5
#define NR_DISCARD 7
#define NR_WDMA0_PORT 8
@@ -917,7 +931,8 @@
int hnat_disable_hook(void);
void hnat_cache_ebl(int enable);
void set_gmac_ppe_fwd(int gmac_no, int enable);
-int entry_delete(int index);
+int entry_detail(int ppe_id, int index);
+int entry_delete(int ppe_id, int index);
static inline u16 foe_timestamp(struct mtk_hnat *h)
{
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
index 4ae9128..d8c76ba 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
@@ -96,9 +96,10 @@
{
struct foe_entry *entry;
- entry = &hnat_priv->foe_table_cpu[skb_hnat_entry(skb)];
+ entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
pr_info("\nRx===<FOE_Entry=%d>=====\n", skb_hnat_entry(skb));
pr_info("RcvIF=%s\n", skb->dev->name);
+ pr_info("PPE_ID=%d\n", skb_hnat_ppe(skb));
pr_info("FOE_Entry=%d\n", skb_hnat_entry(skb));
pr_info("CPU Reason=%s", show_cpu_reason(skb));
pr_info("ALG=%d\n", skb_hnat_alg(skb));
@@ -296,8 +297,10 @@
debug_level);
pr_info(" 1 0~3 Change tracking state\n");
pr_info(" (0:invalid; 1:unbind; 2:bind; 3:fin)\n");
- pr_info(" 2 <entry_idx> Show specific foe entry info. of assigned <entry_idx>\n");
- pr_info(" 3 <entry_idx> Delete specific foe entry of assigned <entry_idx>\n");
+ pr_info(" 2 <entry_idx> Show PPE0 specific foe entry info. of assigned <entry_idx>\n");
+ pr_info(" 3 <entry_idx> Delete PPE0 specific foe entry of assigned <entry_idx>\n");
+ pr_info(" 4 <entry_idx> Show PPE1 specific foe entry info. of assigned <entry_idx>\n");
+ pr_info(" 5 <entry_idx> Delete PPE1 specific foe entry of assigned <entry_idx>\n");
return 0;
}
@@ -313,7 +316,17 @@
return 0;
}
-int entry_detail(int index)
+int wrapped_ppe0_entry_detail(int index) {
+ entry_detail(0, index);
+ return 0;
+}
+
+int wrapped_ppe1_entry_detail(int index) {
+ entry_detail(1, index);
+ return 0;
+}
+
+int entry_detail(int ppe_id, int index)
{
struct foe_entry *entry;
struct mtk_hnat *h = hnat_priv;
@@ -324,14 +337,17 @@
unsigned char h_source[ETH_ALEN];
__be32 saddr, daddr, nsaddr, ndaddr;
- entry = h->foe_table_cpu + index;
+ if (ppe_id >= CFG_PPE_NUM)
+ return -EINVAL;
+
+ entry = h->foe_table_cpu[ppe_id] + index;
saddr = htonl(entry->ipv4_hnapt.sip);
daddr = htonl(entry->ipv4_hnapt.dip);
nsaddr = htonl(entry->ipv4_hnapt.new_sip);
ndaddr = htonl(entry->ipv4_hnapt.new_dip);
p = (uint32_t *)entry;
- pr_info("==========<Flow Table Entry=%d (%p)>===============\n", index,
- entry);
+ pr_info("==========<PPE_ID=%d, Flow Table Entry=%d (%p)>===============\n",
+ ppe_id, index, entry);
if (debug_level >= 2) {
print_cnt = 20;
for (i = 0; i < print_cnt; i++)
@@ -488,18 +504,31 @@
return 0;
}
+int wrapped_ppe0_entry_delete(int index) {
+ entry_delete(0, index);
+ return 0;
+}
+
-int entry_delete(int index)
+int wrapped_ppe1_entry_delete(int index) {
+ entry_delete(1, index);
+ return 0;
+}
+
+int entry_delete(int ppe_id, int index)
{
struct foe_entry *entry;
struct mtk_hnat *h = hnat_priv;
- entry = h->foe_table_cpu + index;
+ if (ppe_id >= CFG_PPE_NUM)
+ return -EINVAL;
+
+ entry = h->foe_table_cpu[ppe_id] + index;
memset(entry, 0, sizeof(struct foe_entry));
/* clear HWNAT cache */
hnat_cache_ebl(1);
- pr_info("delete entry idx = %d\n", index);
+ pr_info("delete ppe id = %d, entry idx = %d\n", ppe_id, index);
return 0;
}
@@ -526,62 +555,92 @@
int binding_threshold(int threshold)
{
+ int i;
+
pr_info("Binding Threshold =%d\n", threshold);
- writel(threshold, hnat_priv->ppe_base + PPE_BNDR);
+
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ writel(threshold, hnat_priv->ppe_base[i] + PPE_BNDR);
+
return 0;
}
int tcp_bind_lifetime(int tcp_life)
{
+ int i;
+
pr_info("tcp_life = %d\n", tcp_life);
+
/* set Delta time for aging out an bind TCP FOE entry */
- cr_set_field(hnat_priv->ppe_base + PPE_BND_AGE_1, TCP_DLTA, tcp_life);
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_BND_AGE_1,
+ TCP_DLTA, tcp_life);
return 0;
}
int fin_bind_lifetime(int fin_life)
{
+ int i;
+
pr_info("fin_life = %d\n", fin_life);
+
/* set Delta time for aging out an bind TCP FIN FOE entry */
- cr_set_field(hnat_priv->ppe_base + PPE_BND_AGE_1, FIN_DLTA, fin_life);
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_BND_AGE_1,
+ FIN_DLTA, fin_life);
return 0;
}
int udp_bind_lifetime(int udp_life)
{
+ int i;
+
pr_info("udp_life = %d\n", udp_life);
+
/* set Delta time for aging out an bind UDP FOE entry */
- cr_set_field(hnat_priv->ppe_base + PPE_BND_AGE_0, UDP_DLTA, udp_life);
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_BND_AGE_0,
+ UDP_DLTA, udp_life);
return 0;
}
int tcp_keep_alive(int tcp_interval)
{
+ int i;
+
if (tcp_interval > 255) {
tcp_interval = 255;
pr_info("TCP keep alive max interval = 255\n");
} else {
pr_info("tcp_interval = %d\n", tcp_interval);
}
+
/* Keep alive time for bind FOE TCP entry */
- cr_set_field(hnat_priv->ppe_base + PPE_KA, TCP_KA, tcp_interval);
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_KA,
+ TCP_KA, tcp_interval);
return 0;
}
int udp_keep_alive(int udp_interval)
{
+ int i;
+
if (udp_interval > 255) {
udp_interval = 255;
pr_info("TCP/UDP keep alive max interval = 255\n");
} else {
pr_info("udp_interval = %d\n", udp_interval);
}
+
/* Keep alive timer for bind FOE UDP entry */
- cr_set_field(hnat_priv->ppe_base + PPE_KA, UDP_KA, udp_interval);
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_KA,
+ UDP_KA, udp_interval);
return 0;
}
@@ -594,8 +653,10 @@
static const debugfs_write_func entry_set_func[] = {
[0] = entry_set_usage,
[1] = entry_set_state,
- [2] = entry_detail,
- [3] = entry_delete,
+ [2] = wrapped_ppe0_entry_detail,
+ [3] = wrapped_ppe0_entry_delete,
+ [4] = wrapped_ppe1_entry_detail,
+ [5] = wrapped_ppe1_entry_delete,
};
static const debugfs_write_func cr_set_func[] = {
@@ -605,7 +666,8 @@
[6] = udp_keep_alive,
};
-static struct hnat_accounting *hnat_get_count(struct mtk_hnat *h, u32 index)
+static struct hnat_accounting *hnat_get_count(struct mtk_hnat *h,
+ int ppe_id, u32 index)
{
struct hnat_accounting *acount;
u32 val, cnt_r0, cnt_r1, cnt_r2;
@@ -614,17 +676,17 @@
if (!hnat_priv->data->per_flow_accounting)
return NULL;
- writel(index | (1 << 16), h->ppe_base + PPE_MIB_SER_CR);
- ret = readx_poll_timeout_atomic(readl, h->ppe_base + PPE_MIB_SER_CR, val,
- !(val & BIT_MIB_BUSY), 20, 10000);
+ writel(index | (1 << 16), h->ppe_base[ppe_id] + PPE_MIB_SER_CR);
+ ret = readx_poll_timeout_atomic(readl, h->ppe_base[ppe_id] + PPE_MIB_SER_CR,
+ val, !(val & BIT_MIB_BUSY), 20, 10000);
if (ret < 0) {
pr_notice("mib busy,please check later\n");
return NULL;
}
- cnt_r0 = readl(h->ppe_base + PPE_MIB_SER_R0);
- cnt_r1 = readl(h->ppe_base + PPE_MIB_SER_R1);
- cnt_r2 = readl(h->ppe_base + PPE_MIB_SER_R2);
- acount = &h->acct[index];
+ cnt_r0 = readl(h->ppe_base[ppe_id] + PPE_MIB_SER_R0);
+ cnt_r1 = readl(h->ppe_base[ppe_id] + PPE_MIB_SER_R1);
+ cnt_r2 = readl(h->ppe_base[ppe_id] + PPE_MIB_SER_R2);
+ acount = &h->acct[ppe_id][index];
acount->bytes += cnt_r0 + ((u64)(cnt_r1 & 0xffff) << 32);
acount->packets +=
((cnt_r1 & 0xffff0000) >> 16) + ((cnt_r2 & 0xffffff) << 16);
@@ -635,7 +697,7 @@
#define PRINT_COUNT(m, acount) {if (acount) \
seq_printf(m, "bytes=%llu|packets=%llu|", \
acount->bytes, acount->packets); }
-static int hnat_debug_show(struct seq_file *m, void *private)
+static int __hnat_debug_show(struct seq_file *m, void *private, int ppe_id)
{
struct mtk_hnat *h = hnat_priv;
struct foe_entry *entry, *end;
@@ -644,15 +706,15 @@
struct hnat_accounting *acount;
u32 entry_index = 0;
- entry = h->foe_table_cpu;
- end = h->foe_table_cpu + hnat_priv->foe_etry_num;
+ entry = h->foe_table_cpu[ppe_id];
+ end = h->foe_table_cpu[ppe_id] + hnat_priv->foe_etry_num;
while (entry < end) {
if (!entry->bfib1.state) {
entry++;
entry_index++;
continue;
}
- acount = hnat_get_count(h, entry_index);
+ acount = hnat_get_count(h, ppe_id, entry_index);
if (IS_IPV4_HNAPT(entry)) {
__be32 saddr = htonl(entry->ipv4_hnapt.sip);
__be32 daddr = htonl(entry->ipv4_hnapt.dip);
@@ -667,8 +729,9 @@
swab16(entry->ipv4_hnapt.dmac_lo);
PRINT_COUNT(m, acount);
seq_printf(m,
- "addr=0x%p|index=%d|state=%s|type=%s|%pI4:%d->%pI4:%d=>%pI4:%d->%pI4:%d|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
- entry, ei(entry, end), es(entry), pt(entry), &saddr,
+ "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|%pI4:%d->%pI4:%d=>%pI4:%d->%pI4:%d|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
+ entry, ppe_id, ei(entry, end),
+ es(entry), pt(entry), &saddr,
entry->ipv4_hnapt.sport, &daddr,
entry->ipv4_hnapt.dport, &nsaddr,
entry->ipv4_hnapt.new_sport, &ndaddr,
@@ -692,8 +755,9 @@
swab16(entry->ipv4_hnapt.dmac_lo);
PRINT_COUNT(m, acount);
seq_printf(m,
- "addr=0x%p|index=%d|state=%s|type=%s|%pI4->%pI4=>%pI4->%pI4|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
- entry, ei(entry, end), es(entry), pt(entry), &saddr,
+ "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|%pI4->%pI4=>%pI4->%pI4|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
+ entry, ppe_id, ei(entry, end),
+ es(entry), pt(entry), &saddr,
&daddr, &nsaddr, &ndaddr, h_source, h_dest,
ntohs(entry->ipv4_hnapt.etype),
entry->ipv4_hnapt.info_blk1,
@@ -719,8 +783,8 @@
swab16(entry->ipv6_5t_route.dmac_lo);
PRINT_COUNT(m, acount);
seq_printf(m,
- "addr=0x%p|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x(sp=%d)->DIP=%08x:%08x:%08x:%08x(dp=%d)|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
- entry, ei(entry, end), es(entry), pt(entry), ipv6_sip0,
+ "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x(sp=%d)->DIP=%08x:%08x:%08x:%08x(dp=%d)|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
+ entry, ppe_id, ei(entry, end), es(entry), pt(entry), ipv6_sip0,
ipv6_sip1, ipv6_sip2, ipv6_sip3,
entry->ipv6_5t_route.sport, ipv6_dip0,
ipv6_dip1, ipv6_dip2, ipv6_dip3,
@@ -747,8 +811,9 @@
swab16(entry->ipv6_5t_route.dmac_lo);
PRINT_COUNT(m, acount);
seq_printf(m,
- "addr=0x%p|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x->DIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
- entry, ei(entry, end), es(entry), pt(entry), ipv6_sip0,
+ "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x->DIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
+ entry, ppe_id, ei(entry, end),
+ es(entry), pt(entry), ipv6_sip0,
ipv6_sip1, ipv6_sip2, ipv6_sip3, ipv6_dip0,
ipv6_dip1, ipv6_dip2, ipv6_dip3, h_source,
h_dest, ntohs(entry->ipv6_5t_route.etype),
@@ -775,8 +840,9 @@
swab16(entry->ipv6_5t_route.dmac_lo);
PRINT_COUNT(m, acount);
seq_printf(m,
- "addr=0x%p|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x(sp=%d)->DIP=%08x:%08x:%08x:%08x(dp=%d)|TSIP=%pI4->TDIP=%pI4|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
- entry, ei(entry, end), es(entry), pt(entry), ipv6_sip0,
+ "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x(sp=%d)->DIP=%08x:%08x:%08x:%08x(dp=%d)|TSIP=%pI4->TDIP=%pI4|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
+ entry, ppe_id, ei(entry, end),
+ es(entry), pt(entry), ipv6_sip0,
ipv6_sip1, ipv6_sip2, ipv6_sip3,
entry->ipv6_5t_route.sport, ipv6_dip0,
ipv6_dip1, ipv6_dip2, ipv6_dip3,
@@ -805,8 +871,9 @@
swab16(entry->ipv4_dslite.dmac_lo);
PRINT_COUNT(m, acount);
seq_printf(m,
- "addr=0x%p|index=%d|state=%s|type=%s|SIP=%pI4->DIP=%pI4|TSIP=%08x:%08x:%08x:%08x->TDIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
- entry, ei(entry, end), es(entry), pt(entry), &saddr,
+ "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%pI4->DIP=%pI4|TSIP=%08x:%08x:%08x:%08x->TDIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
+ entry, ppe_id, ei(entry, end),
+ es(entry), pt(entry), &saddr,
&daddr, ipv6_tsip0, ipv6_tsip1, ipv6_tsip2,
ipv6_tsip3, ipv6_tdip0, ipv6_tdip1, ipv6_tdip2,
ipv6_tdip3, h_source, h_dest,
@@ -836,8 +903,9 @@
swab16(entry->ipv4_dslite.dmac_lo);
PRINT_COUNT(m, acount);
seq_printf(m,
- "addr=0x%p|index=%d|state=%s|type=%s|SIP=%pI4:%d->DIP=%pI4:%d|NSIP=%pI4:%d->NDIP=%pI4:%d|TSIP=%08x:%08x:%08x:%08x->TDIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
- entry, ei(entry, end), es(entry), pt(entry),
+ "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%pI4:%d->DIP=%pI4:%d|NSIP=%pI4:%d->NDIP=%pI4:%d|TSIP=%08x:%08x:%08x:%08x->TDIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
+ entry, ppe_id, ei(entry, end),
+ es(entry), pt(entry),
&saddr, entry->ipv4_dslite.sport,
&daddr, entry->ipv4_dslite.dport,
&nsaddr, entry->ipv4_dslite.new_sport,
@@ -850,7 +918,7 @@
entry->ipv6_5t_route.info_blk2);
#endif
} else
- seq_printf(m, "addr=0x%p|index=%d state=%s\n", entry, ei(entry, end),
+ seq_printf(m, "addr=0x%p|ppe=%d|index=%d state=%s\n", entry, ppe_id, ei(entry, end),
es(entry));
entry++;
entry_index++;
@@ -859,6 +927,16 @@
return 0;
}
+static int hnat_debug_show(struct seq_file *m, void *private)
+{
+ int i;
+
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ __hnat_debug_show(m, private, i);
+
+ return 0;
+}
+
static int hnat_debug_open(struct inode *inode, struct file *file)
{
return single_open(file, hnat_debug_show, file->private_data);
@@ -1103,7 +1181,7 @@
}
}
-int hnat_entry_read(struct seq_file *m, void *private)
+int __hnat_entry_read(struct seq_file *m, void *private, int ppe_id)
{
struct mtk_hnat *h = hnat_priv;
struct foe_entry *entry, *end;
@@ -1112,8 +1190,11 @@
hash_index = 0;
cnt = 0;
- entry = h->foe_table_cpu;
- end = h->foe_table_cpu + hnat_priv->foe_etry_num;
+ entry = h->foe_table_cpu[ppe_id];
+ end = h->foe_table_cpu[ppe_id] + hnat_priv->foe_etry_num;
+
+ seq_printf(m, "============================\n");
+ seq_printf(m, "PPE_ID = %d\n", ppe_id);
while (entry < end) {
if (entry->bfib1.state == dbg_entry_state) {
@@ -1134,6 +1215,16 @@
return 0;
}
+int hnat_entry_read(struct seq_file *m, void *private)
+{
+ int i;
+
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ __hnat_entry_read(m, private, i);
+
+ return 0;
+}
+
ssize_t hnat_entry_write(struct file *file, const char __user *buffer,
size_t count, loff_t *data)
{
@@ -1168,6 +1259,8 @@
case 1:
case 2:
case 3:
+ case 4:
+ case 5:
p_token = strsep(&p_buf, p_delimiter);
if (!p_token)
arg1 = 0;
@@ -1199,7 +1292,7 @@
.release = single_release,
};
-int hnat_setting_read(struct seq_file *m, void *private)
+int __hnat_setting_read(struct seq_file *m, void *private, int ppe_id)
{
struct mtk_hnat *h = hnat_priv;
int i;
@@ -1208,14 +1301,26 @@
cr_max = 319 * 4;
for (i = 0; i < cr_max; i = i + 0x10) {
pr_info("0x%p : 0x%08x 0x%08x 0x%08x 0x%08x\n",
- (void *)h->foe_table_dev + i, readl(h->ppe_base + i),
- readl(h->ppe_base + i + 4), readl(h->ppe_base + i + 8),
- readl(h->ppe_base + i + 0xc));
+ (void *)h->foe_table_dev[ppe_id] + i,
+ readl(h->ppe_base[ppe_id] + i),
+ readl(h->ppe_base[ppe_id] + i + 4),
+ readl(h->ppe_base[ppe_id] + i + 8),
+ readl(h->ppe_base[ppe_id] + i + 0xc));
}
return 0;
}
+int hnat_setting_read(struct seq_file *m, void *private)
+{
+ int i;
+
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ __hnat_setting_read(m, private, i);
+
+ return 0;
+}
+
static int hnat_setting_open(struct inode *inode, struct file *file)
{
return single_open(file, hnat_setting_read, file->private_data);
@@ -1284,7 +1389,7 @@
.release = single_release,
};
-int mcast_table_dump(struct seq_file *m, void *private)
+int __mcast_table_dump(struct seq_file *m, void *private, int ppe_id)
{
struct mtk_hnat *h = hnat_priv;
struct ppe_mcast_h mcast_h;
@@ -1296,12 +1401,14 @@
return 0;
max = h->pmcast->max_entry;
+ pr_info("============================\n");
+ pr_info("PPE_ID = %d\n", ppe_id);
pr_info("MAC | VID | PortMask | QosPortMask\n");
for (i = 0; i < max; i++) {
if (i < 0x10) {
- reg = h->ppe_base + PPE_MCAST_H_0 + i * 8;
+ reg = h->ppe_base[ppe_id] + PPE_MCAST_H_0 + i * 8;
mcast_h.u.value = readl(reg);
- reg = h->ppe_base + PPE_MCAST_L_0 + i * 8;
+ reg = h->ppe_base[ppe_id] + PPE_MCAST_L_0 + i * 8;
mcast_l.addr = readl(reg);
} else {
reg = h->fe_base + PPE_MCAST_H_10 + (i - 0x10) * 8;
@@ -1328,6 +1435,16 @@
return 0;
}
+int mcast_table_dump(struct seq_file *m, void *private)
+{
+ int i;
+
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ __mcast_table_dump(m, private, i);
+
+ return 0;
+}
+
static int mcast_table_open(struct inode *inode, struct file *file)
{
return single_open(file, mcast_table_dump, file->private_data);
@@ -1799,14 +1916,17 @@
.release = single_release,
};
-int get_ppe_mib(int index, u64 *pkt_cnt, u64 *byte_cnt)
+int get_ppe_mib(int ppe_id, int index, u64 *pkt_cnt, u64 *byte_cnt)
{
struct mtk_hnat *h = hnat_priv;
struct hnat_accounting *acount;
struct foe_entry *entry;
- acount = hnat_get_count(h, index);
- entry = hnat_priv->foe_table_cpu + index;
+ if (ppe_id >= CFG_PPE_NUM)
+ return -1;
+
+ acount = hnat_get_count(h, ppe_id, index);
+ entry = hnat_priv->foe_table_cpu[ppe_id] + index;
if (!acount)
return -1;
@@ -1821,11 +1941,14 @@
}
EXPORT_SYMBOL(get_ppe_mib);
-int is_entry_binding(int index)
+int is_entry_binding(int ppe_id, int index)
{
struct foe_entry *entry;
- entry = hnat_priv->foe_table_cpu + index;
+ if (ppe_id >= CFG_PPE_NUM)
+ return -1;
+
+ entry = hnat_priv->foe_table_cpu[ppe_id] + index;
return entry->bfib1.state == BIND;
}
@@ -1886,22 +2009,28 @@
goto err0;
}
h->root = root;
- h->regset = kzalloc(sizeof(*h->regset), GFP_KERNEL);
- if (!h->regset) {
- dev_notice(h->dev, "%s:err at %d\n", __func__, __LINE__);
- ret = -ENOMEM;
- goto err1;
- }
- h->regset->regs = hnat_regs;
- h->regset->nregs = ARRAY_SIZE(hnat_regs);
- h->regset->base = h->ppe_base;
- file = debugfs_create_regset32("regdump", S_IRUGO, root, h->regset);
- if (!file) {
- dev_notice(h->dev, "%s:err at %d\n", __func__, __LINE__);
- ret = -ENOMEM;
- goto err1;
+ for (i = 0; i < CFG_PPE_NUM; i++) {
+ h->regset[i] = kzalloc(sizeof(*h->regset[i]), GFP_KERNEL);
+ if (!h->regset[i]) {
+ dev_notice(h->dev, "%s:err at %d\n", __func__, __LINE__);
+ ret = -ENOMEM;
+ goto err1;
+ }
+ h->regset[i]->regs = hnat_regs;
+ h->regset[i]->nregs = ARRAY_SIZE(hnat_regs);
+ h->regset[i]->base = h->ppe_base[i];
+
+ snprintf(name, sizeof(name), "regdump%ld", i);
+ file = debugfs_create_regset32(name, S_IRUGO,
+ root, h->regset[i]);
+ if (!file) {
+ dev_notice(h->dev, "%s:err at %d\n", __func__, __LINE__);
+ ret = -ENOMEM;
+ goto err1;
+ }
}
+
debugfs_create_file("all_entry", S_IRUGO, root, h, &hnat_debug_fops);
debugfs_create_file("external_interface", S_IRUGO, root, h,
&hnat_ext_fops);
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.c
index 79e4bd0..d11dfcd 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.c
@@ -61,7 +61,7 @@
}
/*set_hnat_mtbl - set ppe multicast register*/
-static int set_hnat_mtbl(struct ppe_mcast_group *group, int index)
+static int set_hnat_mtbl(struct ppe_mcast_group *group, int ppe_id, int index)
{
struct ppe_mcast_h mcast_h;
struct ppe_mcast_l mcast_l;
@@ -83,9 +83,9 @@
trace_printk("%s:index=%d,group info=0x%x,addr=0x%x\n",
__func__, index, mcast_h.u.value, mcast_l.addr);
if (index < 0x10) {
- reg = hnat_priv->ppe_base + PPE_MCAST_H_0 + ((index) * 8);
+ reg = hnat_priv->ppe_base[ppe_id] + PPE_MCAST_H_0 + ((index) * 8);
writel(mcast_h.u.value, reg);
- reg = hnat_priv->ppe_base + PPE_MCAST_L_0 + ((index) * 8);
+ reg = hnat_priv->ppe_base[ppe_id] + PPE_MCAST_L_0 + ((index) * 8);
writel(mcast_l.addr, reg);
} else {
index = index - 0x10;
@@ -112,7 +112,7 @@
struct net_device *dev;
u32 mac_hi;
u16 mac_lo;
- int index;
+ int i, index;
struct ppe_mcast_group *group;
rcu_read_lock();
@@ -164,7 +164,9 @@
if (!group->oif && !group->eif)
/*nobody in this group,clear the entry*/
memset(group, 0, sizeof(struct ppe_mcast_group));
- set_hnat_mtbl(group, index);
+
+ for (i = 0; i < CFG_PPE_NUM; i++)
+ set_hnat_mtbl(group, i, index);
}
return 0;
@@ -254,24 +256,26 @@
static void hnat_mcast_check_timestamp(struct timer_list *t)
{
struct foe_entry *entry;
- int hash_index;
+ int i, hash_index;
u16 e_ts, foe_ts;
- for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
- entry = hnat_priv->foe_table_cpu + hash_index;
- if (entry->bfib1.sta == 1) {
- e_ts = (entry->ipv4_hnapt.m_timestamp) & 0xffff;
- foe_ts = foe_timestamp(hnat_priv);
- if ((foe_ts - e_ts) > 0x3000)
- foe_ts = (~(foe_ts)) & 0xffff;
- if (abs(foe_ts - e_ts) > 20)
- entry_delete(hash_index);
+ for (i = 0; i < CFG_PPE_NUM; i++) {
+ for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
+ entry = hnat_priv->foe_table_cpu[i] + hash_index;
+ if (entry->bfib1.sta == 1) {
+ e_ts = (entry->ipv4_hnapt.m_timestamp) & 0xffff;
+ foe_ts = foe_timestamp(hnat_priv);
+ if ((foe_ts - e_ts) > 0x3000)
+ foe_ts = (~(foe_ts)) & 0xffff;
+ if (abs(foe_ts - e_ts) > 20)
+ entry_delete(i, hash_index);
+ }
}
}
mod_timer(&hnat_priv->hnat_mcast_check_timer, jiffies + 10 * HZ);
}
-int hnat_mcast_enable(void)
+int hnat_mcast_enable(int ppe_id)
{
struct ppe_mcast_table *pmcast;
@@ -304,15 +308,15 @@
}
/* Enable multicast table lookup */
- cr_set_field(hnat_priv->ppe_base + PPE_GLO_CFG, MCAST_TB_EN, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_GLO_CFG, MCAST_TB_EN, 1);
/* multicast port0 map to PDMA */
- cr_set_field(hnat_priv->ppe_base + PPE_MCAST_PPSE, MC_P0_PPSE, 0);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_MCAST_PPSE, MC_P0_PPSE, 0);
/* multicast port1 map to GMAC1 */
- cr_set_field(hnat_priv->ppe_base + PPE_MCAST_PPSE, MC_P1_PPSE, 1);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_MCAST_PPSE, MC_P1_PPSE, 1);
/* multicast port2 map to GMAC2 */
- cr_set_field(hnat_priv->ppe_base + PPE_MCAST_PPSE, MC_P2_PPSE, 2);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_MCAST_PPSE, MC_P2_PPSE, 2);
/* multicast port3 map to QDMA */
- cr_set_field(hnat_priv->ppe_base + PPE_MCAST_PPSE, MC_P3_PPSE, 5);
+ cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_MCAST_PPSE, MC_P3_PPSE, 5);
return 0;
err:
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.h
index 048bc58..f6993a5 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.h
@@ -63,7 +63,7 @@
u32 addr;
};
-int hnat_mcast_enable(void);
+int hnat_mcast_enable(int ppe_id);
int hnat_mcast_disable(void);
#endif
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index 522a675..293f3c0 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -181,7 +181,7 @@
void foe_clear_all_bind_entries(struct net_device *dev)
{
- int hash_index;
+ int i, hash_index;
struct foe_entry *entry;
if (!IS_LAN(dev) && !IS_WAN(dev) &&
@@ -189,13 +189,17 @@
!dev->netdev_ops->ndo_flow_offload_check)
return;
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, SMA, SMA_ONLY_FWD_CPU);
- for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
- entry = hnat_priv->foe_table_cpu + hash_index;
- if (entry->bfib1.state == BIND) {
- entry->ipv4_hnapt.udib1.state = INVALID;
- entry->ipv4_hnapt.udib1.time_stamp =
- readl((hnat_priv->fe_base + 0x0010)) & 0xFF;
+ for (i = 0; i < CFG_PPE_NUM; i++) {
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_TB_CFG,
+ SMA, SMA_ONLY_FWD_CPU);
+
+ for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
+ entry = hnat_priv->foe_table_cpu[i] + hash_index;
+ if (entry->bfib1.state == BIND) {
+ entry->ipv4_hnapt.udib1.state = INVALID;
+ entry->ipv4_hnapt.udib1.time_stamp =
+ readl((hnat_priv->fe_base + 0x0010)) & 0xFF;
+ }
}
}
@@ -246,37 +250,39 @@
u32 *daddr = (u32 *)neigh->primary_key;
unsigned char h_dest[ETH_ALEN];
struct foe_entry *entry;
- int hash_index;
+ int i, hash_index;
u32 dip;
dip = (u32)(*daddr);
- for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
- entry = hnat_priv->foe_table_cpu + hash_index;
- if (entry->bfib1.state == BIND &&
- entry->ipv4_hnapt.new_dip == ntohl(dip)) {
- *((u32 *)h_dest) = swab32(entry->ipv4_hnapt.dmac_hi);
- *((u16 *)&h_dest[4]) =
- swab16(entry->ipv4_hnapt.dmac_lo);
- if (strncmp(h_dest, neigh->ha, ETH_ALEN) != 0) {
- pr_info("%s: state=%d\n", __func__,
- neigh->nud_state);
- cr_set_field(hnat_priv->ppe_base + PPE_TB_CFG, SMA,
- SMA_ONLY_FWD_CPU);
+ for (i = 0; i < CFG_PPE_NUM; i++) {
+ for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
+ entry = hnat_priv->foe_table_cpu[i] + hash_index;
+ if (entry->bfib1.state == BIND &&
+ entry->ipv4_hnapt.new_dip == ntohl(dip)) {
+ *((u32 *)h_dest) = swab32(entry->ipv4_hnapt.dmac_hi);
+ *((u16 *)&h_dest[4]) =
+ swab16(entry->ipv4_hnapt.dmac_lo);
+ if (strncmp(h_dest, neigh->ha, ETH_ALEN) != 0) {
+ pr_info("%s: state=%d\n", __func__,
+ neigh->nud_state);
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_TB_CFG,
+ SMA, SMA_ONLY_FWD_CPU);
- entry->ipv4_hnapt.udib1.state = INVALID;
- entry->ipv4_hnapt.udib1.time_stamp =
- readl((hnat_priv->fe_base + 0x0010)) & 0xFF;
+ entry->ipv4_hnapt.udib1.state = INVALID;
+ entry->ipv4_hnapt.udib1.time_stamp =
+ readl((hnat_priv->fe_base + 0x0010)) & 0xFF;
- /* clear HWNAT cache */
- hnat_cache_ebl(1);
+ /* clear HWNAT cache */
+ hnat_cache_ebl(1);
- mod_timer(&hnat_priv->hnat_sma_build_entry_timer,
- jiffies + 3 * HZ);
+ mod_timer(&hnat_priv->hnat_sma_build_entry_timer,
+ jiffies + 3 * HZ);
- pr_info("Delete old entry: dip =%pI4\n", &dip);
- pr_info("Old mac= %pM\n", h_dest);
- pr_info("New mac= %pM\n", neigh->ha);
+ pr_info("Delete old entry: dip =%pI4\n", &dip);
+ pr_info("Old mac= %pM\n", h_dest);
+ pr_info("New mac= %pM\n", neigh->ha);
+ }
}
}
}
@@ -421,7 +427,7 @@
skb->vlan_proto = 0;
skb->vlan_tci = 0;
fix_skb_packet_type(skb, skb->dev, eth_hdr(skb));
- entry = &hnat_priv->foe_table_cpu[skb_hnat_entry(skb)];
+ entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
entry->bfib1.pkt_type = IPV4_HNAPT;
netif_rx(skb);
return 0;
@@ -439,7 +445,7 @@
struct foe_entry *entry;
struct net_device *dev;
- entry = &hnat_priv->foe_table_cpu[skb_hnat_entry(skb)];
+ entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
if (IS_IPV4_GRP(entry))
index = entry->ipv4_hnapt.act_dp;
@@ -1507,8 +1513,8 @@
memcpy(foe, &entry, sizeof(entry));
/*reset statistic for this entry*/
if (hnat_priv->data->per_flow_accounting)
- memset(&hnat_priv->acct[skb_hnat_entry(skb)], 0,
- sizeof(struct mib_entry));
+ memset(&hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
+ 0, sizeof(struct mib_entry));
wmb();
/* The INFO2.port_mg and 2nd VLAN ID fields of PPE entry are redefined
@@ -1538,7 +1544,7 @@
if (!skb_hnat_is_hashed(skb))
return NF_ACCEPT;
- entry = &hnat_priv->foe_table_cpu[skb_hnat_entry(skb)];
+ entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
if (entry_hnat_is_bound(entry))
return NF_ACCEPT;
@@ -1785,7 +1791,7 @@
trace_printk("[%s] case hit, %x-->%s, reason=%x\n", __func__,
skb_hnat_iface(skb), out->name, skb_hnat_reason(skb));
- entry = &hnat_priv->foe_table_cpu[skb_hnat_entry(skb)];
+ entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
switch (skb_hnat_reason(skb)) {
case HIT_UNBIND_RATE_REACH:
@@ -1841,7 +1847,7 @@
if (unlikely(!skb_hnat_is_hashed(skb)))
return NF_ACCEPT;
- entry = &hnat_priv->foe_table_cpu[skb_hnat_entry(skb)];
+ entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
if (skb_hnat_reason(skb) == HIT_UNBIND_RATE_REACH) {
ip6h = ipv6_hdr(skb);
if (ip6h->nexthdr == NEXTHDR_IPIP) {
@@ -1998,7 +2004,7 @@
if (!skb_hnat_is_hashed(skb))
return NF_ACCEPT;
- entry = &hnat_priv->foe_table_cpu[skb_hnat_entry(skb)];
+ entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
if (unlikely(skb_headroom(skb) < FOE_INFO_LEN)) {
new_skb = skb_realloc_headroom(skb, FOE_INFO_LEN);
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
index bd857f4..c25413d 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
@@ -81,6 +81,8 @@
#define skb_hnat_rx_id(skb) (((struct hnat_desc *)((skb)->head))->rxid)
#define skb_hnat_wc_id(skb) (((struct hnat_desc *)((skb)->head))->wcid)
#define skb_hnat_bss_id(skb) (((struct hnat_desc *)((skb)->head))->bssid)
+#define skb_hnat_ppe(skb) \
+ ((skb_hnat_iface(skb) == FOE_MAGIC_WED1 && CFG_PPE_NUM > 1) ? 1 : 0)
#define do_ext2ge_fast_try(dev, skb) (IS_EXT(dev) && !is_from_extge(skb))
#define set_from_extge(skb) (HNAT_SKB_CB2(skb)->magic = 0x78786688)
#define clr_from_extge(skb) (HNAT_SKB_CB2(skb)->magic = 0x0)