From: Felix Fietkau <nbd@nbd.name>
To: netdev@vger.kernel.org, John Crispin <john@phrozen.org>,
Sean Wang <sean.wang@mediatek.com>,
Mark Lee <Mark-MC.Lee@mediatek.com>,
Lorenzo Bianconi <lorenzo@kernel.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Matthias Brugger <matthias.bgg@gmail.com>,
Russell King <linux@armlinux.org.uk>
Cc: Vladimir Oltean <olteanv@gmail.com>,
linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH net-next v4 4/4] net: ethernet: mtk_eth_soc: enable hardware DSA untagging
Date: Mon, 14 Nov 2022 13:42:14 +0100 [thread overview]
Message-ID: <20221114124214.58199-5-nbd@nbd.name> (raw)
In-Reply-To: <20221114124214.58199-1-nbd@nbd.name>
- pass the tag to DSA via metadata dst
- disabled on 7986 for now, since it's not working yet
- disabled if a MAC is enabled that does not use DSA
This improves performance by bypassing the DSA tag driver and avoiding extra
skb data mangling
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 66 ++++++++++++++++++---
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++
2 files changed, 67 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index a118c715b09b..3e9f5536f0f3 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -23,6 +23,7 @@
#include <linux/jhash.h>
#include <linux/bitfield.h>
#include <net/dsa.h>
+#include <net/dst_metadata.h>
#include "mtk_eth_soc.h"
#include "mtk_wed.h"
@@ -1939,13 +1940,19 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
__vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)),
RX_DMA_VID(trxd.rxd3));
}
+ }
+
+ /* When using VLAN untagging in combination with DSA, the
+ * hardware treats the MTK special tag as a VLAN and untags it.
+ */
+ if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) {
+ unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0);
- /* If the device is attached to a dsa switch, the special
- * tag inserted in VLAN field by hw switch can * be offloaded
- * by RX HW VLAN offload. Clear vlan info.
- */
- if (netdev_uses_dsa(netdev))
- __vlan_hwaccel_clear_tag(skb);
+ if (port < ARRAY_SIZE(eth->dsa_meta) &&
+ eth->dsa_meta[port])
+ skb_dst_set_noref(skb, ð->dsa_meta[port]->dst);
+
+ __vlan_hwaccel_clear_tag(skb);
}
skb_record_rx_queue(skb, 0);
@@ -2990,11 +2997,46 @@ static void mtk_gdm_config(struct mtk_eth *eth, u32 config)
mtk_w32(eth, 0, MTK_RST_GL);
}
+
+static bool mtk_uses_dsa(struct net_device *dev)
+{
+#if IS_ENABLED(CONFIG_NET_DSA)
+ return netdev_uses_dsa(dev) &&
+ dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_MTK;
+#else
+ return false;
+#endif
+}
+
static int mtk_open(struct net_device *dev)
{
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
- int err;
+ int i, err;
+
+ if (mtk_uses_dsa(dev) && !eth->prog) {
+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
+ struct metadata_dst *md_dst = eth->dsa_meta[i];
+
+ if (md_dst)
+ continue;
+
+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
+ GFP_KERNEL);
+ if (!md_dst)
+ return -ENOMEM;
+
+ md_dst->u.port_info.port_id = i;
+ eth->dsa_meta[i] = md_dst;
+ }
+ } else {
+ /* Hardware special tag parsing needs to be disabled if at least
+ * one MAC does not use DSA.
+ */
+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+ val &= ~MTK_CDMP_STAG_EN;
+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
+ }
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
if (err) {
@@ -3321,6 +3363,10 @@ static int mtk_hw_init(struct mtk_eth *eth)
*/
val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
+ }
/* Enable RX VLan Offloading */
mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
@@ -3538,6 +3584,12 @@ static int mtk_free_dev(struct mtk_eth *eth)
free_netdev(eth->netdev[i]);
}
+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
+ if (!eth->dsa_meta[i])
+ break;
+ metadata_dst_free(eth->dsa_meta[i]);
+ }
+
return 0;
}
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 589f27ddc401..a572416e25de 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -22,6 +22,9 @@
#include <linux/bpf_trace.h>
#include "mtk_ppe.h"
+#define MTK_MAX_DSA_PORTS 7
+#define MTK_DSA_PORT_MASK GENMASK(2, 0)
+
#define MTK_QDMA_PAGE_SIZE 2048
#define MTK_MAX_RX_LENGTH 1536
#define MTK_MAX_RX_LENGTH_2K 2048
@@ -91,6 +94,9 @@
#define MTK_CDMQ_IG_CTRL 0x1400
#define MTK_CDMQ_STAG_EN BIT(0)
+/* CDMQ Exgress Control Register */
+#define MTK_CDMQ_EG_CTRL 0x1404
+
/* CDMP Ingress Control Register */
#define MTK_CDMP_IG_CTRL 0x400
#define MTK_CDMP_STAG_EN BIT(0)
@@ -1121,6 +1127,8 @@ struct mtk_eth {
int ip_align;
+ struct metadata_dst *dsa_meta[MTK_MAX_DSA_PORTS];
+
struct mtk_ppe *ppe[2];
struct rhashtable flow_table;
--
2.38.1
WARNING: multiple messages have this Message-ID (diff)
From: Felix Fietkau <nbd@nbd.name>
To: netdev@vger.kernel.org, John Crispin <john@phrozen.org>,
Sean Wang <sean.wang@mediatek.com>,
Mark Lee <Mark-MC.Lee@mediatek.com>,
Lorenzo Bianconi <lorenzo@kernel.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Matthias Brugger <matthias.bgg@gmail.com>,
Russell King <linux@armlinux.org.uk>
Cc: Vladimir Oltean <olteanv@gmail.com>,
linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH net-next v4 4/4] net: ethernet: mtk_eth_soc: enable hardware DSA untagging
Date: Mon, 14 Nov 2022 13:42:14 +0100 [thread overview]
Message-ID: <20221114124214.58199-5-nbd@nbd.name> (raw)
In-Reply-To: <20221114124214.58199-1-nbd@nbd.name>
- pass the tag to DSA via metadata dst
- disabled on 7986 for now, since it's not working yet
- disabled if a MAC is enabled that does not use DSA
This improves performance by bypassing the DSA tag driver and avoiding extra
skb data mangling
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 66 ++++++++++++++++++---
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++
2 files changed, 67 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index a118c715b09b..3e9f5536f0f3 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -23,6 +23,7 @@
#include <linux/jhash.h>
#include <linux/bitfield.h>
#include <net/dsa.h>
+#include <net/dst_metadata.h>
#include "mtk_eth_soc.h"
#include "mtk_wed.h"
@@ -1939,13 +1940,19 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
__vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)),
RX_DMA_VID(trxd.rxd3));
}
+ }
+
+ /* When using VLAN untagging in combination with DSA, the
+ * hardware treats the MTK special tag as a VLAN and untags it.
+ */
+ if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) {
+ unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0);
- /* If the device is attached to a dsa switch, the special
- * tag inserted in VLAN field by hw switch can * be offloaded
- * by RX HW VLAN offload. Clear vlan info.
- */
- if (netdev_uses_dsa(netdev))
- __vlan_hwaccel_clear_tag(skb);
+ if (port < ARRAY_SIZE(eth->dsa_meta) &&
+ eth->dsa_meta[port])
+ skb_dst_set_noref(skb, ð->dsa_meta[port]->dst);
+
+ __vlan_hwaccel_clear_tag(skb);
}
skb_record_rx_queue(skb, 0);
@@ -2990,11 +2997,46 @@ static void mtk_gdm_config(struct mtk_eth *eth, u32 config)
mtk_w32(eth, 0, MTK_RST_GL);
}
+
+static bool mtk_uses_dsa(struct net_device *dev)
+{
+#if IS_ENABLED(CONFIG_NET_DSA)
+ return netdev_uses_dsa(dev) &&
+ dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_MTK;
+#else
+ return false;
+#endif
+}
+
static int mtk_open(struct net_device *dev)
{
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
- int err;
+ int i, err;
+
+ if (mtk_uses_dsa(dev) && !eth->prog) {
+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
+ struct metadata_dst *md_dst = eth->dsa_meta[i];
+
+ if (md_dst)
+ continue;
+
+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
+ GFP_KERNEL);
+ if (!md_dst)
+ return -ENOMEM;
+
+ md_dst->u.port_info.port_id = i;
+ eth->dsa_meta[i] = md_dst;
+ }
+ } else {
+ /* Hardware special tag parsing needs to be disabled if at least
+ * one MAC does not use DSA.
+ */
+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+ val &= ~MTK_CDMP_STAG_EN;
+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
+ }
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
if (err) {
@@ -3321,6 +3363,10 @@ static int mtk_hw_init(struct mtk_eth *eth)
*/
val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
+ }
/* Enable RX VLan Offloading */
mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
@@ -3538,6 +3584,12 @@ static int mtk_free_dev(struct mtk_eth *eth)
free_netdev(eth->netdev[i]);
}
+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
+ if (!eth->dsa_meta[i])
+ break;
+ metadata_dst_free(eth->dsa_meta[i]);
+ }
+
return 0;
}
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 589f27ddc401..a572416e25de 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -22,6 +22,9 @@
#include <linux/bpf_trace.h>
#include "mtk_ppe.h"
+#define MTK_MAX_DSA_PORTS 7
+#define MTK_DSA_PORT_MASK GENMASK(2, 0)
+
#define MTK_QDMA_PAGE_SIZE 2048
#define MTK_MAX_RX_LENGTH 1536
#define MTK_MAX_RX_LENGTH_2K 2048
@@ -91,6 +94,9 @@
#define MTK_CDMQ_IG_CTRL 0x1400
#define MTK_CDMQ_STAG_EN BIT(0)
+/* CDMQ Exgress Control Register */
+#define MTK_CDMQ_EG_CTRL 0x1404
+
/* CDMP Ingress Control Register */
#define MTK_CDMP_IG_CTRL 0x400
#define MTK_CDMP_STAG_EN BIT(0)
@@ -1121,6 +1127,8 @@ struct mtk_eth {
int ip_align;
+ struct metadata_dst *dsa_meta[MTK_MAX_DSA_PORTS];
+
struct mtk_ppe *ppe[2];
struct rhashtable flow_table;
--
2.38.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2022-11-14 12:43 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-14 12:42 [PATCH net-next v4 0/4] mtk_eth_soc rx vlan offload improvement + dsa hardware untag support Felix Fietkau
2022-11-14 12:42 ` Felix Fietkau
2022-11-14 12:42 ` [PATCH net-next v4 1/4] net: dsa: add support for DSA rx offloading via metadata dst Felix Fietkau
2022-11-14 16:59 ` Vladimir Oltean
2022-11-14 17:59 ` Florian Fainelli
2022-11-14 18:19 ` Vladimir Oltean
2022-11-14 12:42 ` [PATCH net-next v4 2/4] net: ethernet: mtk_eth_soc: pass correct VLAN protocol ID to the network stack Felix Fietkau
2022-11-14 12:42 ` Felix Fietkau
2022-11-14 12:42 ` [PATCH net-next v4 3/4] net: ethernet: mtk_eth_soc: add support for configuring vlan rx offload Felix Fietkau
2022-11-14 12:42 ` Felix Fietkau
2022-11-14 12:42 ` Felix Fietkau [this message]
2022-11-14 12:42 ` [PATCH net-next v4 4/4] net: ethernet: mtk_eth_soc: enable hardware DSA untagging Felix Fietkau
2022-11-16 4:30 ` [PATCH net-next v4 0/4] mtk_eth_soc rx vlan offload improvement + dsa hardware untag support patchwork-bot+netdevbpf
2022-11-16 4:30 ` patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221114124214.58199-5-nbd@nbd.name \
--to=nbd@nbd.name \
--cc=Mark-MC.Lee@mediatek.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=john@phrozen.org \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux@armlinux.org.uk \
--cc=lorenzo@kernel.org \
--cc=matthias.bgg@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=sean.wang@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.