diff mbox series

[net-next,v3,2/2] net: stmmac: dwxgmac2: Add support for HW-accelerated VLAN stripping

Message ID 20250408081354.25881-3-boon.khai.ng@altera.com (mailing list archive)
State New
Headers show
Series Refactoring designware VLAN code. | expand

Commit Message

Ng, Boon Khai April 8, 2025, 8:13 a.m. UTC
This patch adds support for MAC level VLAN tag stripping for the
dwxgmac2 IP. This feature can be configured through ethtool.
If the rx-vlan-offload is off, then the VLAN tag will be stripped
by the driver. If the rx-vlan-offload is on then the VLAN tag
will be stripped by the MAC.

Signed-off-by: Boon Khai Ng <boon.khai.ng@altera.com>
Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 12 ++++++++++++
 .../ethernet/stmicro/stmmac/dwxgmac2_core.c    |  2 ++
 .../ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 18 ++++++++++++++++++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c  |  2 +-
 4 files changed, 33 insertions(+), 1 deletion(-)

Comments

Andrew Lunn April 8, 2025, 7:08 p.m. UTC | #1
> +static u16 dwxgmac2_wrback_get_rx_vlan_tci(struct dma_desc *p)
> +{
> +	return (le32_to_cpu(p->des0) & XGMAC_RDES0_VLAN_TAG_MASK);
> +}

This appears to be identical to dwmac4_wrback_get_rx_vlan_tci() ?

Can it be moved into the shared code, or am i missing something?

	Andrew
Ng, Boon Khai April 9, 2025, 3:12 a.m. UTC | #2
> This appears to be identical to dwmac4_wrback_get_rx_vlan_tci() ?
> 
> Can it be moved into the shared code, or am i missing something?
> 
>         Andrew

Hi Andrew thanks for the quick response.

For the dwmac4 IP it has the following format at the 
Receive Normal Descriptor 0 (RDES0)

           31                                                                                                0
              ------------------------------------- -----------------------------------
RDES0 |   Inner VLAN TAG [31:16]   | Outer VLAN TAG [31:16   |
              ------------------------------------- -----------------------------------

While for dwxgmac2 IP it has the following format at the RDES0
Depending on the Tunneled Frame bit (TNP)

For Non-Tunneled Frame (TNP=0)
           31                                                                                                0
              ------------------------------------- -----------------------------------
RDES0 |   Inner VLAN TAG [31:16 ]  | Outer VLAN TAG [31:16]   |
              ------------------------------------- -----------------------------------

For Tunneled Frame (TNP=1)
           31                                        8 7                          3 2                  0
              -------------------------------- ----------------------- ----------------
RDES0 |   VNID/VSID                    |    Reserved         | OL2L3         |
              -------------------------------- ----------------------- ----------------

While the logic for handling Tunneled Frame and Non-Tunneled
Frame is not yet implemented in the 
dwxgmac2_wrback_get_rx_vlan_tci() function, I believe it is
prudent to maintain separate functions within their respective
descriptor driver files, (dwxgmac2_descs.c and dwmac4_descs.c)
Andrew Lunn April 9, 2025, 12:04 p.m. UTC | #3
On Wed, Apr 09, 2025 at 03:12:53AM +0000, Ng, Boon Khai wrote:
> > This appears to be identical to dwmac4_wrback_get_rx_vlan_tci() ?
> > 
> > Can it be moved into the shared code, or am i missing something?
> > 
> >         Andrew
> 
> Hi Andrew thanks for the quick response.
> 
> For the dwmac4 IP it has the following format at the 
> Receive Normal Descriptor 0 (RDES0)
> 
>            31                                                                                                0
>               ------------------------------------- -----------------------------------
> RDES0 |   Inner VLAN TAG [31:16]   | Outer VLAN TAG [31:16   |
>               ------------------------------------- -----------------------------------
> 
> While for dwxgmac2 IP it has the following format at the RDES0
> Depending on the Tunneled Frame bit (TNP)
> 
> For Non-Tunneled Frame (TNP=0)
>            31                                                                                                0
>               ------------------------------------- -----------------------------------
> RDES0 |   Inner VLAN TAG [31:16 ]  | Outer VLAN TAG [31:16]   |
>               ------------------------------------- -----------------------------------
> 
> For Tunneled Frame (TNP=1)
>            31                                        8 7                          3 2                  0
>               -------------------------------- ----------------------- ----------------
> RDES0 |   VNID/VSID                    |    Reserved         | OL2L3         |
>               -------------------------------- ----------------------- ----------------
> 
> While the logic for handling Tunneled Frame and Non-Tunneled
> Frame is not yet implemented in the 
> dwxgmac2_wrback_get_rx_vlan_tci() function, I believe it is
> prudent to maintain separate functions within their respective
> descriptor driver files, (dwxgmac2_descs.c and dwmac4_descs.c)

Please add a comment, or describe this in the commit message.

	Andrew
Ng, Boon Khai April 10, 2025, 2:19 a.m. UTC | #4
> >
> > While the logic for handling Tunneled Frame and Non-Tunneled Frame is
> > not yet implemented in the
> > dwxgmac2_wrback_get_rx_vlan_tci() function, I believe it is prudent to
> > maintain separate functions within their respective descriptor driver
> > files, (dwxgmac2_descs.c and dwmac4_descs.c)
> 
> Please add a comment, or describe this in the commit message.
> 
>         Andrew

Hi Adrew, 

Thank you for your feedback, sure, I will include the description in the
commit message on v4.

Regarding the overall changes, I believe they effectively consolidated
while maintaining the necessary separation for descriptor function.

Please let me know if there are any additional areas you would like me
to address or further suggestion of improvement.

Thanks you for your guidance and support.

Regards, 
Boon Khai
diff mbox series

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 5e369a9a2595..0d408ee17f33 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -464,6 +464,7 @@ 
 #define XGMAC_RDES3_RSV			BIT(26)
 #define XGMAC_RDES3_L34T		GENMASK(23, 20)
 #define XGMAC_RDES3_L34T_SHIFT		20
+#define XGMAC_RDES3_ET_LT		GENMASK(19, 16)
 #define XGMAC_L34T_IP4TCP		0x1
 #define XGMAC_L34T_IP4UDP		0x2
 #define XGMAC_L34T_IP6TCP		0x9
@@ -473,6 +474,17 @@ 
 #define XGMAC_RDES3_TSD			BIT(6)
 #define XGMAC_RDES3_TSA			BIT(4)
 
+/* RDES0 (write back format) */
+#define XGMAC_RDES0_VLAN_TAG_MASK	GENMASK(15, 0)
+
+/* Error Type or L2 Type(ET/LT) Field Number */
+#define XGMAC_ET_LT_VLAN_STAG		8
+#define XGMAC_ET_LT_VLAN_CTAG		9
+#define XGMAC_ET_LT_DVLAN_CTAG_CTAG	10
+#define XGMAC_ET_LT_DVLAN_STAG_STAG	11
+#define XGMAC_ET_LT_DVLAN_CTAG_STAG	12
+#define XGMAC_ET_LT_DVLAN_STAG_CTAG	13
+
 extern const struct stmmac_ops dwxgmac210_ops;
 extern const struct stmmac_ops dwxlgmac2_ops;
 extern const struct stmmac_dma_ops dwxgmac210_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index d9f41c047e5e..6cadf8de4fdf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -10,6 +10,7 @@ 
 #include "stmmac.h"
 #include "stmmac_fpe.h"
 #include "stmmac_ptp.h"
+#include "stmmac_vlan.h"
 #include "dwxlgmac2.h"
 #include "dwxgmac2.h"
 
@@ -1551,6 +1552,7 @@  int dwxgmac2_setup(struct stmmac_priv *priv)
 	mac->mii.reg_mask = GENMASK(15, 0);
 	mac->mii.clk_csr_shift = 19;
 	mac->mii.clk_csr_mask = GENMASK(21, 19);
+	mac->num_vlan = stmmac_get_num_vlan(priv->ioaddr);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
index 389aad7b5c1e..55921c88efd0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
@@ -4,6 +4,7 @@ 
  * stmmac XGMAC support.
  */
 
+#include <linux/bitfield.h>
 #include <linux/stmmac.h>
 #include "common.h"
 #include "dwxgmac2.h"
@@ -69,6 +70,21 @@  static int dwxgmac2_get_tx_ls(struct dma_desc *p)
 	return (le32_to_cpu(p->des3) & XGMAC_RDES3_LD) > 0;
 }
 
+static u16 dwxgmac2_wrback_get_rx_vlan_tci(struct dma_desc *p)
+{
+	return (le32_to_cpu(p->des0) & XGMAC_RDES0_VLAN_TAG_MASK);
+}
+
+static inline bool dwxgmac2_wrback_get_rx_vlan_valid(struct dma_desc *p)
+{
+	u32 et_lt;
+
+	et_lt = FIELD_GET(XGMAC_RDES3_ET_LT, le32_to_cpu(p->des3));
+
+	return et_lt >= XGMAC_ET_LT_VLAN_STAG &&
+	       et_lt <= XGMAC_ET_LT_DVLAN_STAG_CTAG;
+}
+
 static int dwxgmac2_get_rx_frame_len(struct dma_desc *p, int rx_coe)
 {
 	return (le32_to_cpu(p->des3) & XGMAC_RDES3_PL);
@@ -351,6 +367,8 @@  const struct stmmac_desc_ops dwxgmac210_desc_ops = {
 	.set_tx_owner = dwxgmac2_set_tx_owner,
 	.set_rx_owner = dwxgmac2_set_rx_owner,
 	.get_tx_ls = dwxgmac2_get_tx_ls,
+	.get_rx_vlan_tci = dwxgmac2_wrback_get_rx_vlan_tci,
+	.get_rx_vlan_valid = dwxgmac2_wrback_get_rx_vlan_valid,
 	.get_rx_frame_len = dwxgmac2_get_rx_frame_len,
 	.enable_tx_timestamp = dwxgmac2_enable_tx_timestamp,
 	.get_tx_timestamp_status = dwxgmac2_get_tx_timestamp_status,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 279532609707..eb03d6950903 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7644,7 +7644,7 @@  int stmmac_dvr_probe(struct device *device,
 #ifdef STMMAC_VLAN_TAG_USED
 	/* Both mac100 and gmac support receive VLAN tag detection */
 	ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;
-	if (priv->plat->has_gmac4) {
+	if (priv->plat->has_gmac4 || priv->plat->has_xgmac) {
 		ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
 		priv->hw->hw_vlan_en = true;
 	}