forked from openwrt/openwrt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
generic: 6.6: (re-)add support multiple PPE to mtk_eth_soc
Now that the issue with WED has been sorted out, re-add support for multiple PPE to the mtk_eth_soc driver. Signed-off-by: Daniel Golle <[email protected]>
- Loading branch information
Showing
7 changed files
with
435 additions
and
34 deletions.
There are no files selected for viewing
371 changes: 371 additions & 0 deletions
371
...eric/backport-6.6/752-26-v6.10-net-ethernet-mtk_eth_soc-ppe-add-support-for-multipl.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,371 @@ | ||
From dee4dd10c79aaca192b73520d8fb64628468ae0f Mon Sep 17 00:00:00 2001 | ||
From: Elad Yifee <[email protected]> | ||
Date: Fri, 7 Jun 2024 11:21:50 +0300 | ||
Subject: [PATCH] net: ethernet: mtk_eth_soc: ppe: add support for multiple | ||
PPEs | ||
|
||
Add the missing pieces to allow multiple PPEs units, one for each GMAC. | ||
mtk_gdm_config has been modified to work on targted mac ID, | ||
the inner loop moved outside of the function to allow unrelated | ||
operations like setting the MAC's PPE index. | ||
Introduce a sanity check in flow_offload_replace to account for | ||
non-MTK ingress devices. | ||
Additional field 'ppe_idx' was added to struct mtk_mac in order | ||
to keep track on the assigned PPE unit. | ||
|
||
Signed-off-by: Elad Yifee <[email protected]> | ||
Link: https://lore.kernel.org/r/[email protected] | ||
Signed-off-by: Jakub Kicinski <[email protected]> | ||
--- | ||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 112 +++++++++++------- | ||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +- | ||
.../net/ethernet/mediatek/mtk_ppe_offload.c | 17 ++- | ||
3 files changed, 92 insertions(+), 45 deletions(-) | ||
|
||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||
@@ -80,7 +80,9 @@ static const struct mtk_reg_map mtk_reg_ | ||
.fq_blen = 0x1b2c, | ||
}, | ||
.gdm1_cnt = 0x2400, | ||
- .gdma_to_ppe = 0x4444, | ||
+ .gdma_to_ppe = { | ||
+ [0] = 0x4444, | ||
+ }, | ||
.ppe_base = 0x0c00, | ||
.wdma_base = { | ||
[0] = 0x2800, | ||
@@ -144,7 +146,10 @@ static const struct mtk_reg_map mt7986_r | ||
.tx_sch_rate = 0x4798, | ||
}, | ||
.gdm1_cnt = 0x1c00, | ||
- .gdma_to_ppe = 0x3333, | ||
+ .gdma_to_ppe = { | ||
+ [0] = 0x3333, | ||
+ [1] = 0x4444, | ||
+ }, | ||
.ppe_base = 0x2000, | ||
.wdma_base = { | ||
[0] = 0x4800, | ||
@@ -192,7 +197,11 @@ static const struct mtk_reg_map mt7988_r | ||
.tx_sch_rate = 0x4798, | ||
}, | ||
.gdm1_cnt = 0x1c00, | ||
- .gdma_to_ppe = 0x3333, | ||
+ .gdma_to_ppe = { | ||
+ [0] = 0x3333, | ||
+ [1] = 0x4444, | ||
+ [2] = 0xcccc, | ||
+ }, | ||
.ppe_base = 0x2000, | ||
.wdma_base = { | ||
[0] = 0x4800, | ||
@@ -2015,6 +2024,7 @@ static int mtk_poll_rx(struct napi_struc | ||
struct mtk_rx_dma_v2 *rxd, trxd; | ||
int done = 0, bytes = 0; | ||
dma_addr_t dma_addr = DMA_MAPPING_ERROR; | ||
+ int ppe_idx = 0; | ||
|
||
while (done < budget) { | ||
unsigned int pktlen, *rxdcsum; | ||
@@ -2058,6 +2068,7 @@ static int mtk_poll_rx(struct napi_struc | ||
goto release_desc; | ||
|
||
netdev = eth->netdev[mac]; | ||
+ ppe_idx = eth->mac[mac]->ppe_idx; | ||
|
||
if (unlikely(test_bit(MTK_RESETTING, ð->state))) | ||
goto release_desc; | ||
@@ -2181,7 +2192,7 @@ static int mtk_poll_rx(struct napi_struc | ||
} | ||
|
||
if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) | ||
- mtk_ppe_check_skb(eth->ppe[0], skb, hash); | ||
+ mtk_ppe_check_skb(eth->ppe[ppe_idx], skb, hash); | ||
|
||
skb_record_rx_queue(skb, 0); | ||
napi_gro_receive(napi, skb); | ||
@@ -3276,37 +3287,27 @@ static int mtk_start_dma(struct mtk_eth | ||
return 0; | ||
} | ||
|
||
-static void mtk_gdm_config(struct mtk_eth *eth, u32 config) | ||
+static void mtk_gdm_config(struct mtk_eth *eth, u32 id, u32 config) | ||
{ | ||
- int i; | ||
+ u32 val; | ||
|
||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) | ||
return; | ||
|
||
- for (i = 0; i < MTK_MAX_DEVS; i++) { | ||
- u32 val; | ||
- | ||
- if (!eth->netdev[i]) | ||
- continue; | ||
+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(id)); | ||
|
||
- val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); | ||
+ /* default setup the forward port to send frame to PDMA */ | ||
+ val &= ~0xffff; | ||
|
||
- /* default setup the forward port to send frame to PDMA */ | ||
- val &= ~0xffff; | ||
+ /* Enable RX checksum */ | ||
+ val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN; | ||
|
||
- /* Enable RX checksum */ | ||
- val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN; | ||
+ val |= config; | ||
|
||
- val |= config; | ||
+ if (eth->netdev[id] && netdev_uses_dsa(eth->netdev[id])) | ||
+ val |= MTK_GDMA_SPECIAL_TAG; | ||
|
||
- if (netdev_uses_dsa(eth->netdev[i])) | ||
- val |= MTK_GDMA_SPECIAL_TAG; | ||
- | ||
- mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); | ||
- } | ||
- /* Reset and enable PSE */ | ||
- mtk_w32(eth, RST_GL_PSE, MTK_RST_GL); | ||
- mtk_w32(eth, 0, MTK_RST_GL); | ||
+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(id)); | ||
} | ||
|
||
|
||
@@ -3366,7 +3367,10 @@ static int mtk_open(struct net_device *d | ||
{ | ||
struct mtk_mac *mac = netdev_priv(dev); | ||
struct mtk_eth *eth = mac->hw; | ||
- int i, err; | ||
+ struct mtk_mac *target_mac; | ||
+ int i, err, ppe_num; | ||
+ | ||
+ ppe_num = eth->soc->ppe_num; | ||
|
||
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); | ||
if (err) { | ||
@@ -3390,18 +3394,38 @@ static int mtk_open(struct net_device *d | ||
for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) | ||
mtk_ppe_start(eth->ppe[i]); | ||
|
||
- gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe | ||
- : MTK_GDMA_TO_PDMA; | ||
- mtk_gdm_config(eth, gdm_config); | ||
+ for (i = 0; i < MTK_MAX_DEVS; i++) { | ||
+ if (!eth->netdev[i]) | ||
+ break; | ||
+ | ||
+ target_mac = netdev_priv(eth->netdev[i]); | ||
+ if (!soc->offload_version) { | ||
+ target_mac->ppe_idx = 0; | ||
+ gdm_config = MTK_GDMA_TO_PDMA; | ||
+ } else if (ppe_num >= 3 && target_mac->id == 2) { | ||
+ target_mac->ppe_idx = 2; | ||
+ gdm_config = soc->reg_map->gdma_to_ppe[2]; | ||
+ } else if (ppe_num >= 2 && target_mac->id == 1) { | ||
+ target_mac->ppe_idx = 1; | ||
+ gdm_config = soc->reg_map->gdma_to_ppe[1]; | ||
+ } else { | ||
+ target_mac->ppe_idx = 0; | ||
+ gdm_config = soc->reg_map->gdma_to_ppe[0]; | ||
+ } | ||
+ mtk_gdm_config(eth, target_mac->id, gdm_config); | ||
+ } | ||
+ /* Reset and enable PSE */ | ||
+ mtk_w32(eth, RST_GL_PSE, MTK_RST_GL); | ||
+ mtk_w32(eth, 0, MTK_RST_GL); | ||
|
||
napi_enable(ð->tx_napi); | ||
napi_enable(ð->rx_napi); | ||
mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); | ||
mtk_rx_irq_enable(eth, soc->rx.irq_done_mask); | ||
refcount_set(ð->dma_refcnt, 1); | ||
- } | ||
- else | ||
+ } else { | ||
refcount_inc(ð->dma_refcnt); | ||
+ } | ||
|
||
phylink_start(mac->phylink); | ||
netif_tx_start_all_queues(dev); | ||
@@ -3478,7 +3502,8 @@ static int mtk_stop(struct net_device *d | ||
if (!refcount_dec_and_test(ð->dma_refcnt)) | ||
return 0; | ||
|
||
- mtk_gdm_config(eth, MTK_GDMA_DROP_ALL); | ||
+ for (i = 0; i < MTK_MAX_DEVS; i++) | ||
+ mtk_gdm_config(eth, i, MTK_GDMA_DROP_ALL); | ||
|
||
mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); | ||
mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask); | ||
@@ -4957,23 +4982,24 @@ static int mtk_probe(struct platform_dev | ||
} | ||
|
||
if (eth->soc->offload_version) { | ||
- u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1; | ||
+ u8 ppe_num = eth->soc->ppe_num; | ||
|
||
- num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe); | ||
- for (i = 0; i < num_ppe; i++) { | ||
- u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; | ||
+ ppe_num = min_t(u8, ARRAY_SIZE(eth->ppe), ppe_num); | ||
+ for (i = 0; i < ppe_num; i++) { | ||
+ u32 ppe_addr = eth->soc->reg_map->ppe_base; | ||
|
||
+ ppe_addr += (i == 2 ? 0xc00 : i * 0x400); | ||
eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i); | ||
|
||
if (!eth->ppe[i]) { | ||
err = -ENOMEM; | ||
goto err_deinit_ppe; | ||
} | ||
- } | ||
+ err = mtk_eth_offload_init(eth, i); | ||
|
||
- err = mtk_eth_offload_init(eth); | ||
- if (err) | ||
- goto err_deinit_ppe; | ||
+ if (err) | ||
+ goto err_deinit_ppe; | ||
+ } | ||
} | ||
|
||
for (i = 0; i < MTK_MAX_DEVS; i++) { | ||
@@ -5076,6 +5102,7 @@ static const struct mtk_soc_data mt7621_ | ||
.required_pctl = false, | ||
.version = 1, | ||
.offload_version = 1, | ||
+ .ppe_num = 1, | ||
.hash_offset = 2, | ||
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, | ||
.tx = { | ||
@@ -5104,6 +5131,7 @@ static const struct mtk_soc_data mt7622_ | ||
.required_pctl = false, | ||
.version = 1, | ||
.offload_version = 2, | ||
+ .ppe_num = 1, | ||
.hash_offset = 2, | ||
.has_accounting = true, | ||
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, | ||
@@ -5132,6 +5160,7 @@ static const struct mtk_soc_data mt7623_ | ||
.required_pctl = true, | ||
.version = 1, | ||
.offload_version = 1, | ||
+ .ppe_num = 1, | ||
.hash_offset = 2, | ||
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, | ||
.disable_pll_modes = true, | ||
@@ -5187,6 +5216,7 @@ static const struct mtk_soc_data mt7981_ | ||
.required_pctl = false, | ||
.version = 2, | ||
.offload_version = 2, | ||
+ .ppe_num = 2, | ||
.hash_offset = 4, | ||
.has_accounting = true, | ||
.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, | ||
@@ -5216,6 +5246,7 @@ static const struct mtk_soc_data mt7986_ | ||
.required_pctl = false, | ||
.version = 2, | ||
.offload_version = 2, | ||
+ .ppe_num = 2, | ||
.hash_offset = 4, | ||
.has_accounting = true, | ||
.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, | ||
@@ -5245,6 +5276,7 @@ static const struct mtk_soc_data mt7988_ | ||
.required_pctl = false, | ||
.version = 3, | ||
.offload_version = 2, | ||
+ .ppe_num = 3, | ||
.hash_offset = 4, | ||
.has_accounting = true, | ||
.foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, | ||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||
@@ -1132,7 +1132,7 @@ struct mtk_reg_map { | ||
u32 tx_sch_rate; /* tx scheduler rate control registers */ | ||
} qdma; | ||
u32 gdm1_cnt; | ||
- u32 gdma_to_ppe; | ||
+ u32 gdma_to_ppe[3]; | ||
u32 ppe_base; | ||
u32 wdma_base[3]; | ||
u32 pse_iq_sta; | ||
@@ -1170,6 +1170,7 @@ struct mtk_soc_data { | ||
u8 offload_version; | ||
u8 hash_offset; | ||
u8 version; | ||
+ u8 ppe_num; | ||
u16 foe_entry_size; | ||
netdev_features_t hw_features; | ||
bool has_accounting; | ||
@@ -1294,7 +1295,7 @@ struct mtk_eth { | ||
|
||
struct metadata_dst *dsa_meta[MTK_MAX_DSA_PORTS]; | ||
|
||
- struct mtk_ppe *ppe[2]; | ||
+ struct mtk_ppe *ppe[3]; | ||
struct rhashtable flow_table; | ||
|
||
struct bpf_prog __rcu *prog; | ||
@@ -1319,6 +1320,7 @@ struct mtk_eth { | ||
struct mtk_mac { | ||
int id; | ||
phy_interface_t interface; | ||
+ u8 ppe_idx; | ||
int speed; | ||
struct device_node *of_node; | ||
struct phylink *phylink; | ||
@@ -1440,7 +1442,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk | ||
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); | ||
int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); | ||
|
||
-int mtk_eth_offload_init(struct mtk_eth *eth); | ||
+int mtk_eth_offload_init(struct mtk_eth *eth, u8 id); | ||
int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, | ||
void *type_data); | ||
int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls, | ||
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c | ||
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c | ||
@@ -245,10 +245,10 @@ mtk_flow_offload_replace(struct mtk_eth | ||
int ppe_index) | ||
{ | ||
struct flow_rule *rule = flow_cls_offload_flow_rule(f); | ||
+ struct net_device *idev = NULL, *odev = NULL; | ||
struct flow_action_entry *act; | ||
struct mtk_flow_data data = {}; | ||
struct mtk_foe_entry foe; | ||
- struct net_device *odev = NULL; | ||
struct mtk_flow_entry *entry; | ||
int offload_type = 0; | ||
int wed_index = -1; | ||
@@ -264,6 +264,17 @@ mtk_flow_offload_replace(struct mtk_eth | ||
struct flow_match_meta match; | ||
|
||
flow_rule_match_meta(rule, &match); | ||
+ if (mtk_is_netsys_v2_or_greater(eth)) { | ||
+ idev = __dev_get_by_index(&init_net, match.key->ingress_ifindex); | ||
+ if (idev) { | ||
+ struct mtk_mac *mac = netdev_priv(idev); | ||
+ | ||
+ if (WARN_ON(mac->ppe_idx >= eth->soc->ppe_num)) | ||
+ return -EINVAL; | ||
+ | ||
+ ppe_index = mac->ppe_idx; | ||
+ } | ||
+ } | ||
} else { | ||
return -EOPNOTSUPP; | ||
} | ||
@@ -630,7 +641,9 @@ int mtk_eth_setup_tc(struct net_device * | ||
} | ||
} | ||
|
||
-int mtk_eth_offload_init(struct mtk_eth *eth) | ||
+int mtk_eth_offload_init(struct mtk_eth *eth, u8 id) | ||
{ | ||
+ if (!eth->ppe[id] || !eth->ppe[id]->foe_table) | ||
+ return 0; | ||
return rhashtable_init(ð->flow_table, &mtk_flow_ht_params); | ||
} |
Oops, something went wrong.