[][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);
+