blob: 244788d8e9ab2f6a1b0b2584f890442a5634e3ba [file] [log] [blame]
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,12 +3928,13 @@ 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,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
},
};
@@ -3936,12 +3938,13 @@ 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,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
},
};
@@ -3946,12 +3949,13 @@ 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,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
},
};
@@ -3955,12 +3959,13 @@ 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,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
},
};
@@ -3974,12 +3979,13 @@ 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,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT_V2,
},
};
@@ -3984,12 +3990,14 @@ 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,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT_V2,
},
};
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);