Commit 534df0c1 authored by Boon Khai Ng's avatar Boon Khai Ng Committed by Jakub Kicinski
Browse files

net: stmmac: dwxgmac2: Add support for HW-accelerated VLAN stripping



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: default avatarBoon Khai Ng <boon.khai.ng@altera.com>
Reviewed-by: default avatarMatthew Gerlach <matthew.gerlach@altera.com>
Link: https://patch.msgid.link/20250507063812.34000-4-boon.khai.ng@altera.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f3acaf73
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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;
}
+18 −0
Original line number Diff line number Diff line
@@ -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 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,
+1 −1
Original line number Diff line number Diff line
@@ -7653,7 +7653,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;
	}
+5 −0
Original line number Diff line number Diff line
@@ -335,6 +335,11 @@ const struct stmmac_vlan_ops dwxlgmac2_vlan_ops = {
const struct stmmac_vlan_ops dwxgmac210_vlan_ops = {
	.update_vlan_hash = dwxgmac2_update_vlan_hash,
	.enable_vlan = vlan_enable,
	.add_hw_vlan_rx_fltr = vlan_add_hw_rx_fltr,
	.del_hw_vlan_rx_fltr = vlan_del_hw_rx_fltr,
	.restore_hw_vlan_rx_fltr = vlan_restore_hw_rx_fltr,
	.rx_hw_vlan = vlan_rx_hw,
	.set_hw_vlan_mode = vlan_set_hw_mode,
};

u32 stmmac_get_num_vlan(void __iomem *ioaddr)