[][MAC80211][PPE][Backward compatible two way hash]

[Description]
Refactor ETH and PPE driver for backward compatbile two way hash.

[Release-log]
N/A

Change-Id: I4e97ec79acd8a61634c25374623d5c847aa3b070
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6205755
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9998-ethernet-update-ppe-backward-compatible-two-way-hash.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9998-ethernet-update-ppe-backward-compatible-two-way-hash.patch
new file mode 100644
index 0000000..d655632
--- /dev/null
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9998-ethernet-update-ppe-backward-compatible-two-way-hash.patch
@@ -0,0 +1,192 @@
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 2c54c9c..d3ba9eb 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3814,7 +3814,8 @@ static int mtk_probe(struct platform_device *pdev)
+ 
+ 		for (i = 0; i < eth->ppe_num; i++) {
+ 			eth->ppe[i] = mtk_ppe_init(eth,
+-					   eth->base + MTK_ETH_PPE_BASE + i * 0x400, 2, i);
++						   eth->base + MTK_ETH_PPE_BASE + i * 0x400,
++						   2, eth->soc->hash_way, i);
+ 			if (!eth->ppe[i]) {
+ 				err = -ENOMEM;
+ 				goto err_free_dev;
+@@ -3927,6 +3928,7 @@ static const struct mtk_soc_data mt2701_data = {
+ 	.required_clks = MT7623_CLKS_BITMAP,
+ 	.required_pctl = true,
+ 	.has_sram = false,
++	.hash_way = 2,
+ 	.offload_version = 2,
+ };
+ 
+@@ -3936,6 +3938,7 @@ static const struct mtk_soc_data mt7621_data = {
+ 	.required_clks = MT7621_CLKS_BITMAP,
+ 	.required_pctl = false,
+ 	.has_sram = false,
++	.hash_way = 2,
+ 	.offload_version = 2,
+ };
+ 
+@@ -3946,6 +3949,7 @@ static const struct mtk_soc_data mt7622_data = {
+ 	.required_clks = MT7622_CLKS_BITMAP,
+ 	.required_pctl = false,
+ 	.has_sram = false,
++	.hash_way = 2,
+ 	.offload_version = 2,
+ };
+ 
+@@ -3955,6 +3959,7 @@ static const struct mtk_soc_data mt7623_data = {
+ 	.required_clks = MT7623_CLKS_BITMAP,
+ 	.required_pctl = true,
+ 	.has_sram = false,
++	.hash_way = 2,
+ 	.offload_version = 2,
+ };
+ 
+@@ -3974,6 +3979,7 @@ static const struct mtk_soc_data mt7986_data = {
+ 	.required_clks = MT7986_CLKS_BITMAP,
+ 	.required_pctl = false,
+ 	.has_sram = true,
++	.hash_way = 4,
+ 	.offload_version = 2,
+ };
+ 
+@@ -3984,6 +3990,8 @@ static const struct mtk_soc_data mt7981_data = {
+ 	.required_clks = MT7981_CLKS_BITMAP,
+ 	.required_pctl = false,
+ 	.has_sram = true,
++	.hash_way = 4,
++	.offload_version = 2,
+ };
+ 
+ static const struct mtk_soc_data rt5350_data = {
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+index 4a69bd0..35a7543 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1188,6 +1188,7 @@ struct mtk_soc_data {
+ 	u32		caps;
+ 	u32		required_clks;
+ 	bool		required_pctl;
++	u8		hash_way;
+ 	u8		offload_version;
+ 	netdev_features_t hw_features;
+ 	bool		has_sram;
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
+index e4d50eb..918aa22 100755
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -88,7 +88,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_foe_entry *e)
++static u32 mtk_ppe_hash_entry(struct mtk_ppe *ppe, struct mtk_foe_entry *e)
+ {
+ 	u32 hv1, hv2, hv3;
+ 	u32 hash;
+@@ -122,7 +122,7 @@ static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e)
+ 	hash = (hash >> 24) | ((hash & 0xffffff) << 8);
+ 	hash ^= hv1 ^ hv2 ^ hv3;
+ 	hash ^= hash >> 16;
+-	hash <<= 2;
++	hash <<= (ffs(ppe->way) - 1);
+ 	hash &= MTK_PPE_ENTRIES - 1;
+ 
+ 	return hash;
+@@ -542,10 +542,10 @@ int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
+ 	if (type == MTK_PPE_PKT_TYPE_BRIDGE)
+ 		return mtk_foe_entry_commit_l2(ppe, entry);
+ 
+-	hash = mtk_ppe_hash_entry(&entry->data);
++	hash = mtk_ppe_hash_entry(ppe, &entry->data);
+ 	entry->hash = 0xffff;
+ 	spin_lock_bh(&ppe_lock);
+-	hlist_add_head(&entry->list, &ppe->foe_flow[hash / 4]);
++	hlist_add_head(&entry->list, &ppe->foe_flow[hash / ppe->way]);
+ 	spin_unlock_bh(&ppe_lock);
+ 
+ 	return 0;
+@@ -569,7 +569,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
+ 	flow_info->l2_data.base_flow = entry;
+ 	flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW;
+ 	flow_info->hash = hash;
+-	hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / 4]);
++	hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / ppe->way]);
+ 	hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows);
+ 
+ 	hwe = &ppe->foe_table[hash];
+@@ -593,7 +593,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
+ 
+ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
+ {
+-	struct hlist_head *head = &ppe->foe_flow[hash / 4];
++	struct hlist_head *head = &ppe->foe_flow[hash / ppe->way];
+ 	struct mtk_foe_entry *hwe = &ppe->foe_table[hash];
+ 	struct mtk_flow_entry *entry;
+ 	struct mtk_foe_bridge key = {};
+@@ -676,12 +676,12 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
+ 	return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
+ }
+ 
+-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
+-		 int version, int id)
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int way, int id)
+ {
+ 	struct device *dev = eth->dev;
+ 	struct mtk_foe_entry *foe;
+ 	struct mtk_ppe *ppe;
++	struct hlist_head *flow;
+ 
+ 	ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL);
+ 	if (!ppe)
+@@ -695,6 +696,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int versio
+ 	ppe->eth = eth;
+ 	ppe->dev = dev;
+ 	ppe->version = version;
++	ppe->way = way;
+ 	ppe->id = id;
+ 
+ 	foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
+@@ -704,6 +706,13 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int versio
+ 
+ 	ppe->foe_table = foe;
+ 
++	flow = devm_kzalloc(dev, (MTK_PPE_ENTRIES / way) * sizeof(*flow),
++			    GFP_KERNEL);
++	if (!flow)
++		return NULL;
++
++	ppe->foe_flow = flow;
++
+ 	return ppe;
+ }
+ 
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
+index 21cc551..3d6928c 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -276,19 +276,20 @@ struct mtk_ppe {
+ 	void __iomem *base;
+ 	int version;
+ 	int id;
++	int way;
+ 
+ 	struct mtk_foe_entry *foe_table;
+ 	dma_addr_t foe_phys;
+ 
+ 	u16 foe_check_time[MTK_PPE_ENTRIES];
+-	struct hlist_head foe_flow[MTK_PPE_ENTRIES / 2];
++	struct hlist_head *foe_flow;
+ 
+ 	struct rhashtable l2_flows;
+ 
+ 	void *acct_table;
+ };
+ 
+-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int id);
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int way, int id);
+ int mtk_ppe_start(struct mtk_ppe *ppe);
+ int mtk_ppe_stop(struct mtk_ppe *ppe);
+