[PATCH net-next v1] net: stmmac: xgmac: add support for HW-accelerated VLAN stripping

Michal Kubiak michal.kubiak at intel.com
Fri Jul 5 03:28:25 PDT 2024


On Fri, Jul 05, 2024 at 02:28:08PM +0800, Furong Xu wrote:
> Commit 750011e239a5 ("net: stmmac: Add support for HW-accelerated VLAN
> stripping") introduced MAC level VLAN tag stripping for gmac4 core.
> This patch extend the support to xgmac core.

typo: extends
Or maybe: This patch adds the same support for xgmac core.

> 
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
>  .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  7 ++++
>  .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 39 +++++++++++++++++++
>  .../ethernet/stmicro/stmmac/dwxgmac2_descs.c  | 19 +++++++++
>  .../net/ethernet/stmicro/stmmac/stmmac_main.c |  2 +-
>  4 files changed, 66 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> index 6a2c7d22df1e..db3217784cb0 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> @@ -60,6 +60,10 @@
>  #define XGMAC_VLAN_TAG			0x00000050
>  #define XGMAC_VLAN_EDVLP		BIT(26)
>  #define XGMAC_VLAN_VTHM			BIT(25)
> +#define XGMAC_VLAN_TAG_CTRL_EVLRXS	BIT(24)
> +#define XGMAC_VLAN_TAG_CTRL_EVLS	GENMASK(22, 21)
> +#define XGMAC_VLAN_TAG_STRIP_NONE	0x0
> +#define XGMAC_VLAN_TAG_STRIP_ALL	0x3
>  #define XGMAC_VLAN_DOVLTC		BIT(20)
>  #define XGMAC_VLAN_ESVL			BIT(18)
>  #define XGMAC_VLAN_ETV			BIT(16)
> @@ -477,6 +481,7 @@
>  #define XGMAC_TDES3_VLTV		BIT(16)
>  #define XGMAC_TDES3_VT			GENMASK(15, 0)
>  #define XGMAC_TDES3_FL			GENMASK(14, 0)
> +#define XGMAC_RDES0_VLAN_TAG		GENMASK(15, 0)
>  #define XGMAC_RDES2_HL			GENMASK(9, 0)
>  #define XGMAC_RDES3_OWN			BIT(31)
>  #define XGMAC_RDES3_CTXT		BIT(30)
> @@ -490,6 +495,8 @@
>  #define XGMAC_L34T_IP4UDP		0x2
>  #define XGMAC_L34T_IP6TCP		0x9
>  #define XGMAC_L34T_IP6UDP		0xA
> +#define XGMAC_RDES3_L2T			GENMASK(19, 16)
> +#define XGMAC_L2T_SINGLE_C_VLAN		0x9
>  #define XGMAC_RDES3_ES			BIT(15)
>  #define XGMAC_RDES3_PL			GENMASK(13, 0)
>  #define XGMAC_RDES3_TSD			BIT(6)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> index 6a987cf598e4..89ac9ad6164a 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> @@ -1530,6 +1530,41 @@ static void dwxgmac3_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *
>  	writel(value, ioaddr + XGMAC_FPE_CTRL_STS);
>  }
>  
> +static void dwxgmac2_rx_hw_vlan(struct mac_device_info *hw,
> +				struct dma_desc *rx_desc, struct sk_buff *skb)
> +{
> +	u16 vid;
> +
> +	if (!hw->desc->get_rx_vlan_valid(rx_desc))
> +		return;
> +
> +	vid = hw->desc->get_rx_vlan_tci(rx_desc);
> +
> +	__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
> +}
> +
> +static void dwxgmac2_set_hw_vlan_mode(struct mac_device_info *hw)
> +{
> +	void __iomem *ioaddr = hw->pcsr;
> +	u32 value = readl(ioaddr + XGMAC_VLAN_TAG);

RCT format of declarations is not met.
(However, in this particular case it can be debatable because it would
require introducing a new line).

> +
> +	value &= ~XGMAC_VLAN_TAG_CTRL_EVLS;
> +
> +	if (hw->hw_vlan_en)
> +		/* Always strip VLAN on Receive */
> +		value |= FIELD_PREP(XGMAC_VLAN_TAG_CTRL_EVLS,
> +				    XGMAC_VLAN_TAG_STRIP_ALL);
> +	else
> +		/* Do not strip VLAN on Receive */
> +		value |= FIELD_PREP(XGMAC_VLAN_TAG_CTRL_EVLS,
> +				    XGMAC_VLAN_TAG_STRIP_NONE);
> +
> +	/* Enable outer VLAN Tag in Rx DMA descriptor */
> +	value |= XGMAC_VLAN_TAG_CTRL_EVLRXS;
> +
> +	writel(value, ioaddr + XGMAC_VLAN_TAG);
> +}
> +
>  const struct stmmac_ops dwxgmac210_ops = {
>  	.core_init = dwxgmac2_core_init,
>  	.set_mac = dwxgmac2_set_mac,
> @@ -1571,6 +1606,8 @@ const struct stmmac_ops dwxgmac210_ops = {
>  	.config_l4_filter = dwxgmac2_config_l4_filter,
>  	.set_arp_offload = dwxgmac2_set_arp_offload,
>  	.fpe_configure = dwxgmac3_fpe_configure,
> +	.rx_hw_vlan = dwxgmac2_rx_hw_vlan,
> +	.set_hw_vlan_mode = dwxgmac2_set_hw_vlan_mode,
>  };
>  
>  static void dwxlgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
> @@ -1628,6 +1665,8 @@ const struct stmmac_ops dwxlgmac2_ops = {
>  	.config_l4_filter = dwxgmac2_config_l4_filter,
>  	.set_arp_offload = dwxgmac2_set_arp_offload,
>  	.fpe_configure = dwxgmac3_fpe_configure,
> +	.rx_hw_vlan = dwxgmac2_rx_hw_vlan,
> +	.set_hw_vlan_mode = dwxgmac2_set_hw_vlan_mode,
>  };
>  
>  int dwxgmac2_setup(struct stmmac_priv *priv)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
> index fc82862a612c..f5293f75fbb4 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
> @@ -67,6 +67,23 @@ 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);
> +}
> +
> +static bool dwxgmac2_wrback_get_rx_vlan_valid(struct dma_desc *p)
> +{
> +	u32 l2_type;
> +
> +	if (!(le32_to_cpu(p->des3) & XGMAC_RDES3_LD))
> +		return false;
> +
> +	l2_type = FIELD_GET(XGMAC_RDES3_L2T, le32_to_cpu(p->des3));
> +
> +	return (l2_type == XGMAC_L2T_SINGLE_C_VLAN);
> +}
> +
>  static int dwxgmac2_get_rx_frame_len(struct dma_desc *p, int rx_coe)
>  {
>  	return (le32_to_cpu(p->des3) & XGMAC_RDES3_PL);
> @@ -349,6 +366,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 4b6a359e5a94..6f594c455d0f 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -7663,7 +7663,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;
>  	}
> -- 
> 2.34.1
> 
>

The patch looks mostly OK, but I would request to improve a description in
the commit message.

Thanks,
Michal



More information about the linux-arm-kernel mailing list