[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