]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: ethernet: mtk_eth_soc: add the capability to run multiple ppe
authorLorenzo Bianconi <lorenzo@kernel.org>
Tue, 20 Sep 2022 10:11:17 +0000 (12:11 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 22 Sep 2022 13:13:23 +0000 (15:13 +0200)
mt7986 chipset support multiple packet engines for wlan <-> eth
packet forwarding.

Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mediatek/mtk_eth_soc.h
drivers/net/ethernet/mediatek/mtk_ppe.c
drivers/net/ethernet/mediatek/mtk_ppe.h
drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
drivers/net/ethernet/mediatek/mtk_ppe_offload.c

index d09717d4f3bebd5b37d8b060b42bff6269c7adf4..bbafe5598b14539032b001e31d5e0e490aa2566b 100644 (file)
@@ -1919,7 +1919,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
 
                reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
                if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-                       mtk_ppe_check_skb(eth->ppe, skb, hash);
+                       mtk_ppe_check_skb(eth->ppe[0], skb, hash);
 
                if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
                        if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
@@ -2983,15 +2983,18 @@ static int mtk_open(struct net_device *dev)
        /* we run 2 netdevs on the same dma ring so we only bring it up once */
        if (!refcount_read(&eth->dma_refcnt)) {
                const struct mtk_soc_data *soc = eth->soc;
-               u32 gdm_config = MTK_GDMA_TO_PDMA;
+               u32 gdm_config;
+               int i;
 
                err = mtk_start_dma(eth);
                if (err)
                        return err;
 
-               if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
-                       gdm_config = soc->reg_map->gdma_to_ppe;
+               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);
 
                napi_enable(&eth->tx_napi);
@@ -3035,6 +3038,7 @@ static int mtk_stop(struct net_device *dev)
 {
        struct mtk_mac *mac = netdev_priv(dev);
        struct mtk_eth *eth = mac->hw;
+       int i;
 
        phylink_stop(mac->phylink);
 
@@ -3062,8 +3066,8 @@ static int mtk_stop(struct net_device *dev)
 
        mtk_dma_free(eth);
 
-       if (eth->soc->offload_version)
-               mtk_ppe_stop(eth->ppe);
+       for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
+               mtk_ppe_stop(eth->ppe[i]);
 
        return 0;
 }
@@ -4103,12 +4107,19 @@ static int mtk_probe(struct platform_device *pdev)
        }
 
        if (eth->soc->offload_version) {
-               u32 ppe_addr = eth->soc->reg_map->ppe_base;
-
-               eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 2);
-               if (!eth->ppe) {
-                       err = -ENOMEM;
-                       goto err_free_dev;
+               u32 num_ppe;
+
+               num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
+               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;
+
+                       eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
+                                                  eth->soc->offload_version, i);
+                       if (!eth->ppe[i]) {
+                               err = -ENOMEM;
+                               goto err_free_dev;
+                       }
                }
 
                err = mtk_eth_offload_init(eth);
index 6c5e144cb9f0ca3e25ed2d48036e64858b5ec246..54448795159df48ec7cc070908c55f26be8e27b6 100644 (file)
@@ -1114,7 +1114,7 @@ struct mtk_eth {
 
        int                             ip_align;
 
-       struct mtk_ppe                  *ppe;
+       struct mtk_ppe                  *ppe[2];
        struct rhashtable               flow_table;
 
        struct bpf_prog                 __rcu *prog;
index 1cc7d8338722293b349c7e318010ec7ce9a8565a..687d365b601a442dd845a039d8f128d997cae70c 100644 (file)
@@ -682,7 +682,7 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
 }
 
 struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-                int version)
+                            int version, int index)
 {
        const struct mtk_soc_data *soc = eth->soc;
        struct device *dev = eth->dev;
@@ -717,7 +717,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
        if (!ppe->foe_flow)
                return NULL;
 
-       mtk_ppe_debugfs_init(ppe);
+       mtk_ppe_debugfs_init(ppe, index);
 
        return ppe;
 }
@@ -738,10 +738,13 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
                        ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC;
 }
 
-int mtk_ppe_start(struct mtk_ppe *ppe)
+void mtk_ppe_start(struct mtk_ppe *ppe)
 {
        u32 val;
 
+       if (!ppe)
+               return;
+
        mtk_ppe_init_foe_table(ppe);
        ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
 
@@ -809,8 +812,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
        ppe_w32(ppe, MTK_PPE_GLO_CFG, val);
 
        ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
-
-       return 0;
 }
 
 int mtk_ppe_stop(struct mtk_ppe *ppe)
@@ -818,6 +819,9 @@ int mtk_ppe_stop(struct mtk_ppe *ppe)
        u32 val;
        int i;
 
+       if (!ppe)
+               return 0;
+
        for (i = 0; i < MTK_PPE_ENTRIES; i++)
                ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE,
                                                   MTK_FOE_STATE_INVALID);
index 22efed6599c2be90b421cba6a7de869051d07c0f..4c31d854e9868e44c0fcb9a6db22479ea5610a04 100644 (file)
@@ -247,6 +247,7 @@ struct mtk_flow_entry {
        };
        u8 type;
        s8 wed_index;
+       u8 ppe_index;
        u16 hash;
        union {
                struct mtk_foe_entry data;
@@ -265,6 +266,7 @@ struct mtk_ppe {
        struct device *dev;
        void __iomem *base;
        int version;
+       char dirname[5];
 
        struct mtk_foe_entry *foe_table;
        dma_addr_t foe_phys;
@@ -277,8 +279,9 @@ struct mtk_ppe {
        void *acct_table;
 };
 
-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version);
-int mtk_ppe_start(struct mtk_ppe *ppe);
+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
+                            int version, int index);
+void mtk_ppe_start(struct mtk_ppe *ppe);
 int mtk_ppe_stop(struct mtk_ppe *ppe);
 
 void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
@@ -320,6 +323,6 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
 int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
-int mtk_ppe_debugfs_init(struct mtk_ppe *ppe);
+int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
 
 #endif
index eb0b598f14e4bc2b1f132cb48ad914a707ed71c6..0868226ccc2725db57b8ea799b0f81dde22ac1a0 100644 (file)
@@ -187,7 +187,7 @@ mtk_ppe_debugfs_foe_open_bind(struct inode *inode, struct file *file)
                           inode->i_private);
 }
 
-int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
+int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index)
 {
        static const struct file_operations fops_all = {
                .open = mtk_ppe_debugfs_foe_open_all,
@@ -195,17 +195,17 @@ int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
                .llseek = seq_lseek,
                .release = single_release,
        };
-
        static const struct file_operations fops_bind = {
                .open = mtk_ppe_debugfs_foe_open_bind,
                .read = seq_read,
                .llseek = seq_lseek,
                .release = single_release,
        };
-
        struct dentry *root;
 
-       root = debugfs_create_dir("mtk_ppe", NULL);
+       snprintf(ppe->dirname, sizeof(ppe->dirname), "ppe%d", index);
+
+       root = debugfs_create_dir(ppe->dirname, NULL);
        debugfs_create_file("entries", S_IRUGO, root, ppe, &fops_all);
        debugfs_create_file("bind", S_IRUGO, root, ppe, &fops_bind);
 
index 5a1fc4bcd7a57ad4cecf5675beb0e6ee1bf1cffb..86c2100fd3d04b18ca9f00df3fb8980cf31f7622 100644 (file)
@@ -434,7 +434,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
        memcpy(&entry->data, &foe, sizeof(entry->data));
        entry->wed_index = wed_index;
 
-       err = mtk_foe_entry_commit(eth->ppe, entry);
+       err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry);
        if (err < 0)
                goto free;
 
@@ -446,7 +446,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
        return 0;
 
 clear:
-       mtk_foe_entry_clear(eth->ppe, entry);
+       mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry);
 free:
        kfree(entry);
        if (wed_index >= 0)
@@ -464,7 +464,7 @@ mtk_flow_offload_destroy(struct mtk_eth *eth, struct flow_cls_offload *f)
        if (!entry)
                return -ENOENT;
 
-       mtk_foe_entry_clear(eth->ppe, entry);
+       mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry);
        rhashtable_remove_fast(&eth->flow_table, &entry->node,
                               mtk_flow_ht_params);
        if (entry->wed_index >= 0)
@@ -485,7 +485,7 @@ mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
        if (!entry)
                return -ENOENT;
 
-       idle = mtk_foe_entry_idle_time(eth->ppe, entry);
+       idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
        f->stats.lastused = jiffies - idle * HZ;
 
        return 0;
@@ -537,7 +537,7 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
        struct flow_block_cb *block_cb;
        flow_setup_cb_t *cb;
 
-       if (!eth->ppe || !eth->ppe->foe_table)
+       if (!eth->soc->offload_version)
                return -EOPNOTSUPP;
 
        if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
@@ -589,8 +589,5 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
 
 int mtk_eth_offload_init(struct mtk_eth *eth)
 {
-       if (!eth->ppe || !eth->ppe->foe_table)
-               return 0;
-
        return rhashtable_init(&eth->flow_table, &mtk_flow_ht_params);
 }