Message ID | 20240705062808.805071-1-0x1207@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [net-next,v1] net: stmmac: xgmac: add support for HW-accelerated VLAN stripping | expand |
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@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
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. > > Signed-off-by: Furong Xu <0x1207@gmail.com> Please take a look at this email discussion: https://lore.kernel.org/netdev/20240527093339.30883-1-boon.khai.ng@intel.com/T/ It would be good if you worked with Intel, rather than repeat the same mistakes they made. Andrew --- pw-bot: cr
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); + + 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; }
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. Signed-off-by: Furong Xu <0x1207@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(-)