[][Refine Warp Tx Bind Flow for Panther/Cheetah]
[Description]
Add some processing to refine Warp Tx bind flow.
Under high-pps scenario, we can observe that
PPE.info1.vlan_layer(SW-owned) content is randomly
modified by PPE.info1.packt_cnt(HW-owned).
So the solution is preparing a dummy info1 structure
to hold updated information for not being flushed
by hardware counter. Then the last step would copy all
the content (& STATE=BIND) into DRAM table in one shot.
If without this patch, Warp Tx offload may unexpectedly
encounter wrong-vlan-tag issue, for more details:
http://hwits.mediatek.inc/cr?dbid=33616021&action=View
[Release-log]
N/A
Change-Id: I63b7854c744c81960e301823aa4e0e99c3cfc700
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5741358
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 4cc1691..7640336 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
@@ -1558,13 +1558,13 @@
if (!whnat)
entry.bfib1.state = BIND;
+ wmb();
memcpy(foe, &entry, sizeof(entry));
/*reset statistic for this entry*/
if (hnat_priv->data->per_flow_accounting)
memset(&hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
0, sizeof(struct mib_entry));
- wmb();
skb_hnat_filled(skb) = HNAT_INFO_FILLED;
return 0;
@@ -1574,6 +1574,7 @@
{
struct foe_entry *entry;
struct ethhdr *eth;
+ struct hnat_bind_info_blk bfib1_tx;
if (skb_hnat_alg(skb) || !is_hnat_info_filled(skb) ||
!is_magic_tag_valid(skb) || !IS_SPACE_AVAILABLE_HEAD(skb))
@@ -1604,6 +1605,7 @@
return NF_ACCEPT;
eth = eth_hdr(skb);
+ memcpy(&bfib1_tx, &entry->bfib1, sizeof(entry->bfib1));
/*not bind multicast if PPE mcast not enable*/
if (!hnat_priv->data->mcast) {
@@ -1619,7 +1621,7 @@
/* Some mt_wifi virtual interfaces, such as apcli,
* will change the smac for specail purpose.
*/
- switch (entry->bfib1.pkt_type) {
+ switch (bfib1_tx.pkt_type) {
case IPV4_HNAPT:
case IPV4_HNAT:
entry->ipv4_hnapt.smac_hi = swab32(*((u32 *)eth->h_source));
@@ -1636,8 +1638,8 @@
}
if (skb->vlan_tci) {
- entry->bfib1.vlan_layer = 1;
- entry->bfib1.vpm = 1;
+ bfib1_tx.vlan_layer = 1;
+ bfib1_tx.vpm = 1;
if (IS_IPV4_GRP(entry)) {
entry->ipv4_hnapt.etype = htons(ETH_P_8021Q);
entry->ipv4_hnapt.vlan1 = skb->vlan_tci;
@@ -1646,8 +1648,8 @@
entry->ipv6_5t_route.vlan1 = skb->vlan_tci;
}
} else {
- entry->bfib1.vpm = 0;
- entry->bfib1.vlan_layer = 0;
+ bfib1_tx.vpm = 0;
+ bfib1_tx.vlan_layer = 0;
}
/* MT7622 wifi hw_nat not support QoS */
@@ -1669,8 +1671,8 @@
#endif
} else {
if (IS_GMAC1_MODE && !hnat_dsa_is_enable(hnat_priv)) {
- entry->bfib1.vpm = 1;
- entry->bfib1.vlan_layer = 1;
+ bfib1_tx.vpm = 1;
+ bfib1_tx.vlan_layer = 1;
if (FROM_GE_LAN(skb))
entry->ipv4_hnapt.vlan1 = 1;
@@ -1680,8 +1682,8 @@
if (IS_HQOS_MODE &&
(FROM_GE_LAN(skb) || FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb))) {
- entry->bfib1.vpm = 0;
- entry->bfib1.vlan_layer = 1;
+ bfib1_tx.vpm = 0;
+ bfib1_tx.vlan_layer = 1;
entry->ipv4_hnapt.etype = htons(HQOS_MAGIC_TAG);
entry->ipv4_hnapt.vlan1 = skb_hnat_entry(skb);
entry->ipv4_hnapt.iblk2.fqos = 1;
@@ -1706,8 +1708,8 @@
#endif
} else {
if (IS_GMAC1_MODE && !hnat_dsa_is_enable(hnat_priv)) {
- entry->bfib1.vpm = 1;
- entry->bfib1.vlan_layer = 1;
+ bfib1_tx.vpm = 1;
+ bfib1_tx.vlan_layer = 1;
if (FROM_GE_LAN(skb))
entry->ipv6_5t_route.vlan1 = 1;
@@ -1717,8 +1719,8 @@
if (IS_HQOS_MODE &&
(FROM_GE_LAN(skb) || FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb))) {
- entry->bfib1.vpm = 0;
- entry->bfib1.vlan_layer = 1;
+ bfib1_tx.vpm = 0;
+ bfib1_tx.vlan_layer = 1;
entry->ipv6_5t_route.etype = htons(HQOS_MAGIC_TAG);
entry->ipv6_5t_route.vlan1 = skb_hnat_entry(skb);
entry->ipv6_5t_route.iblk2.fqos = 1;
@@ -1727,7 +1729,9 @@
entry->ipv6_5t_route.iblk2.dp = gmac_no;
}
- entry->bfib1.state = BIND;
+ bfib1_tx.state = BIND;
+ wmb();
+ memcpy(&entry->bfib1, &bfib1_tx, sizeof(bfib1_tx));
return NF_ACCEPT;
}