All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 1/8] drivers: net: stmmac_main: Add support for HW-accelerated VLAN Stripping
@ 2023-03-30  7:02 Boon Khai Ng
  2023-03-30 17:23 ` Please ignore this review, send out by accident Boon Khai Ng
  0 siblings, 1 reply; 10+ messages in thread
From: Boon Khai Ng @ 2023-03-30  7:02 UTC (permalink / raw)
  To: David S . Miller; +Cc: linux-kernel, Mun Yew Tham, Tien Sung Ang, Boon Khai Ng

Currently, VLAN tag stripping is done by driver in stmmac_rx_vlan().
Add support for VLAN tag stripping by the MAC hardware for MAC drivers
that support it. This is done by adding rx_hw_vlan() and
set_hw_vlan_mode() callbacks at stmmac_ops struct which are called if
registered by the MAC driver.

This patch is applying at the higher level of the driver at stmmac_main
this will be upstreammed by IoTG team and thus it is decoupled from
the next patch.

Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/hwif.h    | 16 ++++++++++++++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 22 ++++++++++++++++++-
 include/linux/stmmac.h                        |  1 +
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 16a7421715cb..3a317ae87880 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -55,6 +55,10 @@ struct stmmac_desc_ops {
 	void (*set_tx_ic)(struct dma_desc *p);
 	/* Last tx segment reports the transmit status */
 	int (*get_tx_ls)(struct dma_desc *p);
+	/* RX VLAN TCI */
+	int (*get_rx_vlan_tci)(struct dma_desc *p);
+	/* RX VLAN valid */
+	bool (*get_rx_vlan_valid)(struct dma_desc *p);
 	/* Return the transmit status looking at the TDES1 */
 	int (*tx_status)(void *data, struct stmmac_extra_stats *x,
 			struct dma_desc *p, void __iomem *ioaddr);
@@ -116,6 +120,10 @@ struct stmmac_desc_ops {
 	stmmac_do_void_callback(__priv, desc, set_tx_ic, __args)
 #define stmmac_get_tx_ls(__priv, __args...) \
 	stmmac_do_callback(__priv, desc, get_tx_ls, __args)
+#define stmmac_get_rx_vlan_tci(__priv, __args...) \
+	stmmac_do_callback(__priv, desc, get_rx_vlan_tci, __args)
+#define stmmac_get_rx_vlan_valid(__priv, __args...) \
+	stmmac_do_callback(__priv, desc, get_tx_vlan_valid, __args)
 #define stmmac_tx_status(__priv, __args...) \
 	stmmac_do_callback(__priv, desc, tx_status, __args)
 #define stmmac_get_tx_len(__priv, __args...) \
@@ -368,6 +376,10 @@ struct stmmac_ops {
 	void (*update_vlan_hash)(struct mac_device_info *hw, u32 hash,
 				 __le16 perfect_match, bool is_double);
 	void (*enable_vlan)(struct mac_device_info *hw, u32 type);
+	void (*rx_hw_vlan)(struct net_device *dev, struct mac_device_info *hw,
+			   struct dma_desc *rx_desc, struct sk_buff *skb);
+	void (*set_hw_vlan_mode)(void __iomem *ioaddr,
+				 netdev_features_t features);
 	int (*add_hw_vlan_rx_fltr)(struct net_device *dev,
 				   struct mac_device_info *hw,
 				   __be16 proto, u16 vid);
@@ -475,6 +487,10 @@ struct stmmac_ops {
 	stmmac_do_void_callback(__priv, mac, update_vlan_hash, __args)
 #define stmmac_enable_vlan(__priv, __args...) \
 	stmmac_do_void_callback(__priv, mac, enable_vlan, __args)
+#define stmmac_rx_hw_vlan(__priv, __args...) \
+	stmmac_do_void_callback(__priv, mac, rx_hw_vlan, __args)
+#define stmmac_set_hw_vlan_mode(__priv, __args...) \
+	stmmac_do_void_callback(__priv, mac, set_hw_vlan_mode, __args)
 #define stmmac_add_hw_vlan_rx_fltr(__priv, __args...) \
 	stmmac_do_callback(__priv, mac, add_hw_vlan_rx_fltr, __args)
 #define stmmac_del_hw_vlan_rx_fltr(__priv, __args...) \
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 17310ade88dd..8ee595d46481 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3421,6 +3421,10 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
 			stmmac_fpe_handshake(priv, true);
 	}
 
+	/* Set HW VLAN Stripping mode */
+	if (priv->plat->use_hw_vlan)
+		stmmac_set_hw_vlan_mode(priv, priv->ioaddr, dev->features);
+
 	return 0;
 }
 
@@ -5399,7 +5403,14 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 		/* Got entire packet into SKB. Finish it. */
 
 		stmmac_get_rx_hwtstamp(priv, p, np, skb);
-		stmmac_rx_vlan(priv->dev, skb);
+
+		/* Switch between rx_hw_vlan or rx_vlan */
+		if (priv->plat->use_hw_vlan)
+			stmmac_rx_hw_vlan(priv, priv->dev,
+					  priv->hw, p, skb);
+		else
+			stmmac_rx_vlan(priv->dev, skb);
+
 		skb->protocol = eth_type_trans(skb, priv->dev);
 
 		if (unlikely(!coe))
@@ -5650,6 +5661,10 @@ static int stmmac_set_features(struct net_device *netdev,
 {
 	struct stmmac_priv *priv = netdev_priv(netdev);
 
+	netdev_features_t changed;
+
+	changed = netdev->features ^ features;
+
 	/* Keep the COE Type in case of csum is supporting */
 	if (features & NETIF_F_RXCSUM)
 		priv->hw->rx_csum = priv->plat->rx_coe;
@@ -5668,6 +5683,9 @@ static int stmmac_set_features(struct net_device *netdev,
 			stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan);
 	}
 
+	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
+		stmmac_set_hw_vlan_mode(priv, priv->ioaddr, features);
+
 	return 0;
 }
 
@@ -7217,6 +7235,8 @@ 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;
+	ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;
+
 	if (priv->dma_cap.vlhash) {
 		ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 		ndev->features |= NETIF_F_HW_VLAN_STAG_FILTER;
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a2414c187483..0f2800eada9d 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -273,5 +273,6 @@ struct plat_stmmacenet_data {
 	bool use_phy_wol;
 	bool sph_disable;
 	bool serdes_up_after_phy_linkup;
+	bool use_hw_vlan;
 };
 #endif
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH v1 8/8] net: stmmac: Add option for VLAN filter fail queue enable
@ 2023-03-30  7:04 Boon Khai Ng
  2023-03-30 17:25 ` Please ignore this review, send out by accident Boon Khai Ng
  0 siblings, 1 reply; 10+ messages in thread
From: Boon Khai Ng @ 2023-03-30  7:04 UTC (permalink / raw)
  To: David S . Miller; +Cc: linux-kernel, Mun Yew Tham, Tien Sung Ang, Boon Khai Ng

This option allows packet that fail VLAN filter to be routed
to specific Rx queue when receive all is also set.

When this option is enabled:
- Enable VFFQ only when entering promiscuous mode, because receive all
  will pass up all rx packets that failed address filtering (similar to
  promiscuous mode).
- VLAN-promiscuous mode is never entered to allow rx packet to fail VLAN
  filters and get routed to selected VFFQ Rx queue.

Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h   |  5 +++++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c  | 16 +++++++++++++---
 .../ethernet/stmicro/stmmac/stmmac_platform.c    |  7 +++++++
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 428f82905273..5043a520a00a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -85,6 +85,11 @@
 #define XGMAC_RXQ_CTRL3			0x000000ac
 #define XGMAC_PSRQ(x)			GENMASK((x) * 8 + 7, (x) * 8)
 #define XGMAC_PSRQ_SHIFT(x)		((x) * 8)
+#define XGMAC_RXQ_CTRL4			0x00000094
+/* VFFQ mask might vary and depending on how many RX Q enabled */
+#define XGMAC_RXQCTRL_VFFQ_MASK		GENMASK(19, 17)
+#define XGMAC_RXQCTRL_VFFQ_SHIFT	17
+#define XGMAC_RXQCTRL_VFFQE		BIT(16)
 #define XGMAC_INT_STATUS		0x000000b0
 #define XGMAC_LPIIS			BIT(5)
 #define XGMAC_PMTIS			BIT(4)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index 4dff53dc771f..a3e95efd1e83 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -658,6 +658,7 @@ static void dwxgmac2_set_filter(struct mac_device_info *hw,
 {
 	void __iomem *ioaddr = (void __iomem *)dev->base_addr;
 	u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);
+	u32 value_ctrl = 0;
 	int mcbitslog2 = hw->mcast_bits_log2;
 	u32 mc_filter[8];
 	int i;
@@ -668,8 +669,17 @@ static void dwxgmac2_set_filter(struct mac_device_info *hw,
 	memset(mc_filter, 0, sizeof(mc_filter));
 
 	if (dev->flags & IFF_PROMISC) {
-		value |= XGMAC_FILTER_PR;
-		value |= XGMAC_FILTER_PCF;
+		if (hw->vlan_fail_q_en) {
+			value_ctrl = readl(ioaddr + XGMAC_RXQ_CTRL4);
+			value_ctrl &= ~XGMAC_RXQCTRL_VFFQ_MASK;
+			value_ctrl |= XGMAC_RXQCTRL_VFFQE |
+				(hw->vlan_fail_q << XGMAC_RXQCTRL_VFFQ_SHIFT);
+			writel(value_ctrl, ioaddr + XGMAC_RXQ_CTRL4);
+			value = XGMAC_FILTER_PR | XGMAC_FILTER_RA;
+		} else {
+			value = XGMAC_FILTER_PR | XGMAC_FILTER_PCF;
+		}
+
 	} else if ((dev->flags & IFF_ALLMULTI) ||
 		   (netdev_mc_count(dev) > hw->multicast_filter_bins)) {
 		value |= XGMAC_FILTER_PM;
@@ -714,7 +724,7 @@ static void dwxgmac2_set_filter(struct mac_device_info *hw,
 
 	writel(value, ioaddr + XGMAC_PACKET_FILTER);
 
-	if (dev->flags & IFF_PROMISC) {
+	if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) {
 		if (!hw->promisc) {
 			hw->promisc = 1;
 			dwxgmac2_vlan_promisc_enable(dev, hw);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 26da3a9da345..8bc69318ae0d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -543,6 +543,13 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 			dev_info(&pdev->dev, "RX VLAN HW Stripping\n");
 			plat->use_hw_vlan = true;
 		}
+
+		/*VLAN filter failed queue state */
+		if (of_property_read_bool(np, "snps,vlan-fail-q-en")) {
+			dev_info(&pdev->dev, "VLAN filter failed queue\n");
+			plat->vlan_fail_q_en = true;
+			plat->vlan_fail_q = plat->rx_queues_to_use - 1;
+		}
 	}
 
 	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH v1 7/8] net: stmmac: Add Double VLAN handling for VLAN Rx filtering
@ 2023-03-30  7:04 Boon Khai Ng
  2023-03-30 17:25 ` Please ignore this review, send out by accident Boon Khai Ng
  0 siblings, 1 reply; 10+ messages in thread
From: Boon Khai Ng @ 2023-03-30  7:04 UTC (permalink / raw)
  To: David S . Miller; +Cc: linux-kernel, Mun Yew Tham, Tien Sung Ang, Boon Khai Ng

Add double VLAN handling for VLAN Rx Filtering.

Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h   |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h |  3 +++
 .../ethernet/stmicro/stmmac/dwxgmac2_core.c    | 18 ++++++++++++++++++
 3 files changed, 22 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index ec9c130276d8..ca2d4515dd0f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -535,6 +535,7 @@ struct mac_device_info {
 	unsigned int promisc;
 	bool vlan_fail_q_en;
 	u8 vlan_fail_q;
+	unsigned int double_vlan;
 };
 
 struct stmmac_rx_routing {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 3f11b2c52324..428f82905273 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -499,6 +499,9 @@
 #define XGMAC_VLAN_TAG_STRIP_ALL	(0x3 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
 
 #define XGMAC_VLAN_TAG_DATA		0x00000054
+#define XGMAC_VLAN_TAG_DATA_ERIVLT	BIT(20)
+#define XGMAC_VLAN_TAG_DATA_ERSVLM	BIT(19)
+#define XGMAC_VLAN_TAG_DATA_DOVLTC	BIT(18)
 #define XGMAC_VLAN_TAG_DATA_ETV		BIT(17)
 #define XGMAC_VLAN_TAG_DATA_VEN		BIT(16)
 #define XGMAC_VLAN_TAG_DATA_VID		GENMASK(15, 0)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index 78bad5242562..4dff53dc771f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -438,6 +438,15 @@ static int dwxgmac2_write_vlan_filter(struct net_device *dev,
 	if (index >= hw->num_vlan)
 		return -EINVAL;
 
+	if (hw->double_vlan) {
+		data |= XGMAC_VLAN_TAG_DATA_DOVLTC;
+		data |= XGMAC_VLAN_TAG_DATA_ERIVLT;
+		data &= ~XGMAC_VLAN_TAG_DATA_ERSVLM;
+	} else {
+		data &= ~XGMAC_VLAN_TAG_DATA_DOVLTC;
+		data &= ~XGMAC_VLAN_TAG_DATA_ERIVLT;
+	}
+
 	writel(data, ioaddr + XGMAC_VLAN_TAG_DATA);
 
 	val = readl(ioaddr + XGMAC_VLAN_TAG);
@@ -1855,6 +1864,14 @@ static u32 dwxgmac2_get_num_vlan(void __iomem *ioaddr)
 	return num_vlan;
 }
 
+static u32 dwxgmac2_is_double_vlan(void __iomem *ioaddr)
+{
+	u32 val;
+
+	val = readl(ioaddr + XGMAC_HW_FEATURE3);
+	return (val & XGMAC_HWFEAT_DVLAN);
+}
+
 int dwxgmac2_setup(struct stmmac_priv *priv)
 {
 	struct mac_device_info *mac = priv->hw;
@@ -1889,6 +1906,7 @@ int dwxgmac2_setup(struct stmmac_priv *priv)
 	mac->mii.clk_csr_shift = 19;
 	mac->mii.clk_csr_mask = GENMASK(21, 19);
 	mac->num_vlan = dwxgmac2_get_num_vlan(priv->ioaddr);
+	mac->double_vlan = dwxgmac2_is_double_vlan(priv->ioaddr);
 	return 0;
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH v1 6/8] net: stmmac: Add support for VLAN promiscuous mode
@ 2023-03-30  7:03 Boon Khai Ng
  2023-03-30 17:25 ` Please ignore this review, send out by accident Boon Khai Ng
  0 siblings, 1 reply; 10+ messages in thread
From: Boon Khai Ng @ 2023-03-30  7:03 UTC (permalink / raw)
  To: David S . Miller; +Cc: linux-kernel, Mun Yew Tham, Tien Sung Ang, Boon Khai Ng

For dwxgmac2, enable VLAN promiscuity when MAC Controller is requested to
enter promiscuous mode.

Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
---
 .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  1 +
 .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 67 +++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 4c92828f21d6..3f11b2c52324 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -69,6 +69,7 @@
 #define XGMAC_VLAN_CT			BIT(1)
 #define XGMAC_VLAN_OB			BIT(0)
 #define XGMAC_VLAN_HASH_TABLE		0x00000058
+#define XGMAC_VLAN_VLHT			GENMASK(15, 0)
 #define XGMAC_VLAN_INCL			0x00000060
 #define XGMAC_VLAN_VLTI			BIT(20)
 #define XGMAC_VLAN_CSVL			BIT(19)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index feb9189ec20e..78bad5242562 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -472,6 +472,12 @@ static int dwxgmac2_add_hw_vlan_rx_fltr(struct net_device *dev,
 	if (vid > 4095)
 		return -EINVAL;
 
+	if (hw->promisc) {
+		netdev_err(dev,
+			   "Adding VLAN in promisc mode not supported\n");
+		return -EPERM;
+	}
+
 	/* Single Rx VLAN Filter */
 	if (hw->num_vlan == 1) {
 		/* For single VLAN filter, VID 0 means VLAN promiscuous */
@@ -522,6 +528,12 @@ static int dwxgmac2_del_hw_vlan_rx_fltr(struct net_device *dev,
 {
 	int i, ret = 0;
 
+	if (hw->promisc) {
+		netdev_err(dev,
+			   "Deleting VLAN in promisc mode not supported\n");
+		return -EPERM;
+	}
+
 	/* Single Rx VLAN Filter */
 	if (hw->num_vlan == 1) {
 		if ((hw->vlan_filter[0] & XGMAC_VLAN_VID) == vid) {
@@ -545,9 +557,45 @@ static int dwxgmac2_del_hw_vlan_rx_fltr(struct net_device *dev,
 	return ret;
 }
 
+static void dwxgmac2_vlan_promisc_enable(struct net_device *dev,
+					 struct mac_device_info *hw)
+{
+	void __iomem *ioaddr = hw->pcsr;
+	u32 value;
+	u32 hash;
+	u32 val;
+	int i;
+
+	/* Single Rx VLAN Filter */
+	if (hw->num_vlan == 1) {
+		dwxgmac2_write_single_vlan(dev, 0);
+		return;
+	}
+
+	/* Extended Rx VLAN Filter Enable */
+	for (i = 0; i < hw->num_vlan; i++) {
+		if (hw->vlan_filter[i] & XGMAC_VLAN_TAG_DATA_VEN) {
+			val = hw->vlan_filter[i] & ~XGMAC_VLAN_TAG_DATA_VEN;
+			dwxgmac2_write_vlan_filter(dev, hw, i, val);
+		}
+	}
+
+	hash = readl(ioaddr + XGMAC_VLAN_HASH_TABLE);
+	if (hash & XGMAC_VLAN_VLHT) {
+		value = readl(ioaddr + XGMAC_VLAN_TAG);
+		if (value & XGMAC_VLAN_VTHM) {
+			value &= ~XGMAC_VLAN_VTHM;
+			writel(value, ioaddr + XGMAC_VLAN_TAG);
+		}
+	}
+}
+
 static void dwxgmac2_restore_hw_vlan_rx_fltr(struct net_device *dev,
 					     struct mac_device_info *hw)
 {
+	void __iomem *ioaddr = hw->pcsr;
+	u32 value;
+	u32 hash;
 	u32 val;
 	int i;
 
@@ -564,6 +612,13 @@ static void dwxgmac2_restore_hw_vlan_rx_fltr(struct net_device *dev,
 			dwxgmac2_write_vlan_filter(dev, hw, i, val);
 		}
 	}
+
+	hash = readl(ioaddr + XGMAC_VLAN_HASH_TABLE);
+	if (hash & XGMAC_VLAN_VLHT) {
+		value = readl(ioaddr + XGMAC_VLAN_TAG);
+		value |= XGMAC_VLAN_VTHM;
+		writel(value, ioaddr + XGMAC_VLAN_TAG);
+	}
 }
 
 static void dwxgmac2_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
@@ -649,6 +704,18 @@ static void dwxgmac2_set_filter(struct mac_device_info *hw,
 		value |= XGMAC_FILTER_VTFE;
 
 	writel(value, ioaddr + XGMAC_PACKET_FILTER);
+
+	if (dev->flags & IFF_PROMISC) {
+		if (!hw->promisc) {
+			hw->promisc = 1;
+			dwxgmac2_vlan_promisc_enable(dev, hw);
+		}
+	} else {
+		if (hw->promisc) {
+			hw->promisc = 0;
+			dwxgmac2_restore_hw_vlan_rx_fltr(dev, hw);
+		}
+	}
 }
 
 static void dwxgmac2_set_mac_loopback(void __iomem *ioaddr, bool enable)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH v1 5/8] net: stmmac: Add support for VLAN Rx filtering
@ 2023-03-30  7:03 Boon Khai Ng
  2023-03-30 17:24 ` Please ignore this review, send out by accident Boon Khai Ng
  0 siblings, 1 reply; 10+ messages in thread
From: Boon Khai Ng @ 2023-03-30  7:03 UTC (permalink / raw)
  To: David S . Miller; +Cc: linux-kernel, Mun Yew Tham, Tien Sung Ang, Boon Khai Ng

Add support for VLAN ID-based filtering by the MAC controller for MAC
drivers that support it. Only the 12-bit VID field is used.

Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
---
 .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  21 +-
 .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 191 +++++++++++++++++-
 2 files changed, 210 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index b7beaa197343..4c92828f21d6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -64,6 +64,10 @@
 #define XGMAC_VLAN_ESVL			BIT(18)
 #define XGMAC_VLAN_ETV			BIT(16)
 #define XGMAC_VLAN_VID			GENMASK(15, 0)
+#define XGMAC_VLAN_OFS			GENMASK(6, 2)
+#define XGMAC_VLAN_OFS_SHIFT		2
+#define XGMAC_VLAN_CT			BIT(1)
+#define XGMAC_VLAN_OB			BIT(0)
 #define XGMAC_VLAN_HASH_TABLE		0x00000058
 #define XGMAC_VLAN_INCL			0x00000060
 #define XGMAC_VLAN_VLTI			BIT(20)
@@ -149,6 +153,7 @@
 #define XGMAC_HWFEAT_FRPES		GENMASK(12, 11)
 #define XGMAC_HWFEAT_FRPPB		GENMASK(10, 9)
 #define XGMAC_HWFEAT_FRPSEL		BIT(3)
+#define XGMAC_HWFEAT_NRVF		GENMASK(2, 0)
 #define XGMAC_MAC_DPP_FSM_INT_STATUS	0x00000150
 #define XGMAC_MAC_FSM_CONTROL		0x00000158
 #define XGMAC_PRTYEN			BIT(1)
@@ -477,7 +482,8 @@
 /* RDES0 (write back format) */
 #define XGMAC_RDES0_VLAN_TAG_MASK	GENMASK(15, 0)
 
-/* MAC VLAN Tag Control */
+/* MAC VLAN Tag Control and VLAN Tag Data */
+#define XGMAC_VLAN_TAG_CTRL		0x00000050
 #define XGMAC_VLAN_TAG_CTRL_OB		BIT(0)
 #define XGMAC_VLAN_TAG_CTRL_CT		BIT(1)
 #define XGMAC_VLAN_TAG_CTRL_OFS_MASK	GENMASK(6, 2)
@@ -491,6 +497,11 @@
 #define XGMAC_VLAN_TAG_STRIP_FAIL	(0x2 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
 #define XGMAC_VLAN_TAG_STRIP_ALL	(0x3 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
 
+#define XGMAC_VLAN_TAG_DATA		0x00000054
+#define XGMAC_VLAN_TAG_DATA_ETV		BIT(17)
+#define XGMAC_VLAN_TAG_DATA_VEN		BIT(16)
+#define XGMAC_VLAN_TAG_DATA_VID		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
@@ -499,4 +510,12 @@
 #define XGMAC_ET_LT_DVLAN_CTAG_STAG	12
 #define XGMAC_ET_LT_DVLAN_STAG_CTAG	13
 
+/* EXT VLAN Filtering HW FEAT */
+#define XGMAC_HWFEAT_NO_EXT		0
+#define XGMAC_HWFEAT_EXT_VLAN_4		1
+#define XGMAC_HWFEAT_EXT_VLAN_8		2
+#define XGMAC_HWFEAT_EXT_VLAN_16	3
+#define XGMAC_HWFEAT_EXT_VLAN_24	4
+#define XGMAC_HWFEAT_EXT_VLAN_32	5
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index 8bd77e30cc24..feb9189ec20e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -415,6 +415,157 @@ static void dwxgmac2_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
 	writel(value, ioaddr + XGMAC_LPI_TIMER_CTRL);
 }
 
+static void dwxgmac2_write_single_vlan(struct net_device *dev, u16 vid)
+{
+	void __iomem *ioaddr = (void __iomem *)dev->base_addr;
+	u32 val;
+
+	val = readl(ioaddr + XGMAC_VLAN_TAG);
+	val &= ~XGMAC_VLAN_VID;
+	val |= XGMAC_VLAN_ETV | vid;
+
+	writel(val, ioaddr + XGMAC_VLAN_TAG);
+}
+
+static int dwxgmac2_write_vlan_filter(struct net_device *dev,
+				      struct mac_device_info *hw,
+				      u8 index, u32 data)
+{
+	void __iomem *ioaddr = (void __iomem *)dev->base_addr;
+	int i, timeout = 10;
+	u32 val;
+
+	if (index >= hw->num_vlan)
+		return -EINVAL;
+
+	writel(data, ioaddr + XGMAC_VLAN_TAG_DATA);
+
+	val = readl(ioaddr + XGMAC_VLAN_TAG);
+	val &= ~(XGMAC_VLAN_TAG_CTRL_OFS_MASK |
+		XGMAC_VLAN_CT |
+		XGMAC_VLAN_OB);
+
+	val |= (index << XGMAC_VLAN_OFS_SHIFT | XGMAC_VLAN_OB);
+
+	writel(val, ioaddr + XGMAC_VLAN_TAG);
+
+	for (i = 0; i < timeout; i++) {
+		val = readl(ioaddr + XGMAC_VLAN_TAG);
+		if (!(val & XGMAC_VLAN_OB))
+			return 0;
+		udelay(1);
+	}
+
+	netdev_err(dev, "Timeout accessing MAC_VLAN_TAG_FILTER\n");
+
+	return -EBUSY;
+}
+
+static int dwxgmac2_add_hw_vlan_rx_fltr(struct net_device *dev,
+					struct mac_device_info *hw,
+					__be16 proto, u16 vid)
+{
+	int index = -1;
+	u32 val = 0;
+	int i, ret;
+
+	if (vid > 4095)
+		return -EINVAL;
+
+	/* Single Rx VLAN Filter */
+	if (hw->num_vlan == 1) {
+		/* For single VLAN filter, VID 0 means VLAN promiscuous */
+		if (vid == 0) {
+			netdev_warn(dev, "Adding VLAN ID 0 is not supported\n");
+			return -EPERM;
+		}
+
+		if (hw->vlan_filter[0] & XGMAC_VLAN_VID) {
+			netdev_err(dev, "Only single VLAN ID supported\n");
+			return -EPERM;
+		}
+
+		hw->vlan_filter[0] = vid;
+		dwxgmac2_write_single_vlan(dev, vid);
+
+		return 0;
+	}
+
+	/* Extended Rx VLAN Filter Enable */
+	val |= XGMAC_VLAN_TAG_DATA_ETV | XGMAC_VLAN_TAG_DATA_VEN | vid;
+
+	for (i = 0; i < hw->num_vlan; i++) {
+		if (hw->vlan_filter[i] == val)
+			return 0;
+
+		else if (!(hw->vlan_filter[i] & XGMAC_VLAN_TAG_DATA_VEN))
+			index = i;
+	}
+
+	if (index == -1) {
+		netdev_err(dev, "MAC_VLAN_TAG_FILTER full (size: %0u)\n",
+			   hw->num_vlan);
+		return -EPERM;
+	}
+
+	ret = dwxgmac2_write_vlan_filter(dev, hw, index, val);
+
+	if (!ret)
+		hw->vlan_filter[index] = val;
+
+	return ret;
+}
+
+static int dwxgmac2_del_hw_vlan_rx_fltr(struct net_device *dev,
+					struct mac_device_info *hw,
+					__be16 proto, u16 vid)
+{
+	int i, ret = 0;
+
+	/* Single Rx VLAN Filter */
+	if (hw->num_vlan == 1) {
+		if ((hw->vlan_filter[0] & XGMAC_VLAN_VID) == vid) {
+			hw->vlan_filter[0] = 0;
+			dwxgmac2_write_single_vlan(dev, 0);
+		}
+		return 0;
+	}
+
+	/* Extended Rx VLAN Filter Enable */
+	for (i = 0; i < hw->num_vlan; i++) {
+		if ((hw->vlan_filter[i] & XGMAC_VLAN_TAG_DATA_VID) == vid) {
+			ret = dwxgmac2_write_vlan_filter(dev, hw, i, 0);
+
+			if (!ret)
+				hw->vlan_filter[i] = 0;
+			else
+				return ret;
+		}
+	}
+	return ret;
+}
+
+static void dwxgmac2_restore_hw_vlan_rx_fltr(struct net_device *dev,
+					     struct mac_device_info *hw)
+{
+	u32 val;
+	int i;
+
+	/* Single Rx VLAN Filter */
+	if (hw->num_vlan == 1) {
+		dwxgmac2_write_single_vlan(dev, hw->vlan_filter[0]);
+		return;
+	}
+
+	/* Extended Rx VLAN Filter Enable */
+	for (i = 0; i < hw->num_vlan; i++) {
+		if (hw->vlan_filter[i] & XGMAC_VLAN_TAG_DATA_VEN) {
+			val = hw->vlan_filter[i];
+			dwxgmac2_write_vlan_filter(dev, hw, i, val);
+		}
+	}
+}
+
 static void dwxgmac2_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
 				int mcbitslog2)
 {
@@ -493,6 +644,10 @@ static void dwxgmac2_set_filter(struct mac_device_info *hw,
 		}
 	}
 
+	/* VLAN Filtering */
+	if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+		value |= XGMAC_FILTER_VTFE;
+
 	writel(value, ioaddr + XGMAC_PACKET_FILTER);
 }
 
@@ -1529,6 +1684,9 @@ const struct stmmac_ops dwxgmac210_ops = {
 	.enable_vlan = dwxgmac2_enable_vlan,
 	.config_l3_filter = dwxgmac2_config_l3_filter,
 	.config_l4_filter = dwxgmac2_config_l4_filter,
+	.add_hw_vlan_rx_fltr = dwxgmac2_add_hw_vlan_rx_fltr,
+	.del_hw_vlan_rx_fltr = dwxgmac2_del_hw_vlan_rx_fltr,
+	.restore_hw_vlan_rx_fltr = dwxgmac2_restore_hw_vlan_rx_fltr,
 	.set_arp_offload = dwxgmac2_set_arp_offload,
 	.est_configure = dwxgmac3_est_configure,
 	.fpe_configure = dwxgmac3_fpe_configure,
@@ -1599,6 +1757,37 @@ const struct stmmac_ops dwxlgmac2_ops = {
 	.set_hw_vlan_mode = dwxgmac2_set_hw_vlan_mode,
 };
 
+static u32 dwxgmac2_get_num_vlan(void __iomem *ioaddr)
+{
+	u32 val, num_vlan;
+
+	val = readl(ioaddr + XGMAC_HW_FEATURE3);
+	switch (val & XGMAC_HWFEAT_NRVF) {
+	case 0:
+		num_vlan = 1;
+		break;
+	case 1:
+		num_vlan = 4;
+		break;
+	case 2:
+		num_vlan = 8;
+		break;
+	case 3:
+		num_vlan = 16;
+		break;
+	case 4:
+		num_vlan = 24;
+		break;
+	case 5:
+		num_vlan = 32;
+		break;
+	default:
+		num_vlan = 1;
+	}
+
+	return num_vlan;
+}
+
 int dwxgmac2_setup(struct stmmac_priv *priv)
 {
 	struct mac_device_info *mac = priv->hw;
@@ -1632,7 +1821,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 = dwxgmac2_get_num_vlan(priv->ioaddr);
 	return 0;
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH v1 4/8] drivers: net: dwmac: Add use_hw_vlan setting
@ 2023-03-30  7:03 Boon Khai Ng
  2023-03-30 17:24 ` Please ignore this review, send out by accident Boon Khai Ng
  0 siblings, 1 reply; 10+ messages in thread
From: Boon Khai Ng @ 2023-03-30  7:03 UTC (permalink / raw)
  To: David S . Miller; +Cc: linux-kernel, Mun Yew Tham, Tien Sung Ang, Boon Khai Ng

This is to handle the use_hw_vlan setting at dwmac-socfpga
level.

Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 067a40fe0a23..26da3a9da345 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -537,6 +537,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 		plat->has_xgmac = 1;
 		plat->pmt = 1;
 		plat->tso_en = of_property_read_bool(np, "snps,tso");
+
+		/* Rx VLAN HW Stripping */
+		if (of_property_read_bool(np, "snps,rx-vlan-offload")) {
+			dev_info(&pdev->dev, "RX VLAN HW Stripping\n");
+			plat->use_hw_vlan = true;
+		}
 	}
 
 	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH v1 3/8] drivers: net: stmmac: Add support for HW-accelerated VLAN Stripping
@ 2023-03-30  7:03 Boon Khai Ng
  2023-03-30 17:24 ` Please ignore this review, send out by accident Boon Khai Ng
  0 siblings, 1 reply; 10+ messages in thread
From: Boon Khai Ng @ 2023-03-30  7:03 UTC (permalink / raw)
  To: David S . Miller; +Cc: linux-kernel, Mun Yew Tham, Tien Sung Ang, Boon Khai Ng

This is to add HW-accelerated VLAN Stripping for XGMAC

Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
---
 .../net/ethernet/stmicro/stmmac/dwxgmac2.h    | 28 ++++++++++++++
 .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 38 +++++++++++++++++++
 .../ethernet/stmicro/stmmac/dwxgmac2_descs.c  | 15 ++++++++
 3 files changed, 81 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 1913385df685..b7beaa197343 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -431,6 +431,7 @@
 #define XGMAC_TDES2_VTIR		GENMASK(15, 14)
 #define XGMAC_TDES2_VTIR_SHIFT		14
 #define XGMAC_TDES2_B1L			GENMASK(13, 0)
+#define XGMAC_TDES2_VLAN_TAG_MASK	GENMASK(15, 14)
 #define XGMAC_TDES3_OWN			BIT(31)
 #define XGMAC_TDES3_CTXT		BIT(30)
 #define XGMAC_TDES3_FD			BIT(29)
@@ -462,6 +463,8 @@
 #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_RDES3_ET_LT_SHIFT		16
 #define XGMAC_L34T_IP4TCP		0x1
 #define XGMAC_L34T_IP4UDP		0x2
 #define XGMAC_L34T_IP6TCP		0x9
@@ -471,4 +474,29 @@
 #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)
+
+/* MAC VLAN Tag Control */
+#define XGMAC_VLAN_TAG_CTRL_OB		BIT(0)
+#define XGMAC_VLAN_TAG_CTRL_CT		BIT(1)
+#define XGMAC_VLAN_TAG_CTRL_OFS_MASK	GENMASK(6, 2)
+#define XGMAC_VLAN_TAG_CTRL_OFS_SHIFT	2
+#define XGMAC_VLAN_TAG_CTRL_EVLS_MASK	GENMASK(22, 21)
+#define XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT	21
+#define XGMAC_VLAN_TAG_CTRL_EVLRXS	BIT(24)
+
+#define XGMAC_VLAN_TAG_STRIP_NONE	(0x0 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
+#define XGMAC_VLAN_TAG_STRIP_PASS	(0x1 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
+#define XGMAC_VLAN_TAG_STRIP_FAIL	(0x2 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
+#define XGMAC_VLAN_TAG_STRIP_ALL	(0x3 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
+
+/* 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
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index c6c4d7948fe5..8bd77e30cc24 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -7,6 +7,7 @@
 #include <linux/bitrev.h>
 #include <linux/crc32.h>
 #include <linux/iopoll.h>
+#include <linux/if_vlan.h>
 #include "stmmac.h"
 #include "stmmac_ptp.h"
 #include "dwxlgmac2.h"
@@ -1174,6 +1175,39 @@ static void dwxgmac2_sarc_configure(void __iomem *ioaddr, int val)
 	writel(value, ioaddr + XGMAC_TX_CONFIG);
 }
 
+static void dwxgmac2_rx_hw_vlan(struct net_device *dev,
+				struct mac_device_info *hw,
+				struct dma_desc *rx_desc, struct sk_buff *skb)
+{
+	if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
+	    hw->desc->get_rx_vlan_valid(rx_desc)) {
+		u16 vid = (u16)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(void __iomem *ioaddr,
+				      netdev_features_t features)
+{
+	u32 val;
+
+	val = readl(ioaddr + XGMAC_VLAN_TAG);
+	val &= ~XGMAC_VLAN_TAG_CTRL_EVLS_MASK;
+
+	if (features & NETIF_F_HW_VLAN_CTAG_RX)
+		/* Always strip VLAN on Receive */
+		val |= XGMAC_VLAN_TAG_STRIP_ALL;
+	else
+		/* Do not strip VLAN on Receive */
+		val |= XGMAC_VLAN_TAG_STRIP_NONE;
+
+	/* Enable outer VLAN Tag in Rx DMA descriptro */
+	val |= XGMAC_VLAN_TAG_CTRL_EVLRXS;
+
+	writel(val, ioaddr + XGMAC_VLAN_TAG);
+}
+
 static void dwxgmac2_enable_vlan(struct mac_device_info *hw, u32 type)
 {
 	void __iomem *ioaddr = hw->pcsr;
@@ -1498,6 +1532,8 @@ const struct stmmac_ops dwxgmac210_ops = {
 	.set_arp_offload = dwxgmac2_set_arp_offload,
 	.est_configure = dwxgmac3_est_configure,
 	.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,
@@ -1559,6 +1595,8 @@ const struct stmmac_ops dwxlgmac2_ops = {
 	.set_arp_offload = dwxgmac2_set_arp_offload,
 	.est_configure = dwxgmac3_est_configure,
 	.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 b1f0c3984a09..2bdd5ef6d048 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
@@ -67,6 +67,19 @@ static int dwxgmac2_get_tx_ls(struct dma_desc *p)
 	return (le32_to_cpu(p->des3) & XGMAC_RDES3_LD) > 0;
 }
 
+static inline int 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)
+{
+	return((((le32_to_cpu(p->des3) & XGMAC_RDES3_ET_LT) >>
+		XGMAC_RDES3_ET_LT_SHIFT) >= XGMAC_ET_LT_VLAN_STAG) &&
+		(((le32_to_cpu(p->des3) & XGMAC_RDES3_ET_LT) >>
+		XGMAC_RDES3_ET_LT_SHIFT) <= 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);
@@ -349,6 +362,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,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH v1 2/8] drivers: net: stmmac_main: fix vlan toggle option.
@ 2023-03-30  7:03 Boon Khai Ng
  2023-03-30 17:24 ` Please ignore this review, send out by accident Boon Khai Ng
  0 siblings, 1 reply; 10+ messages in thread
From: Boon Khai Ng @ 2023-03-30  7:03 UTC (permalink / raw)
  To: David S . Miller; +Cc: linux-kernel, Mun Yew Tham, Tien Sung Ang, Boon Khai Ng

This patch is to fix toggling rx vlan offload from the ethool.

Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 8ee595d46481..664c32d61622 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4565,10 +4565,8 @@ static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb)
 	veth = (struct vlan_ethhdr *)skb->data;
 	vlan_proto = veth->h_vlan_proto;
 
-	if ((vlan_proto == htons(ETH_P_8021Q) &&
-	     dev->features & NETIF_F_HW_VLAN_CTAG_RX) ||
-	    (vlan_proto == htons(ETH_P_8021AD) &&
-	     dev->features & NETIF_F_HW_VLAN_STAG_RX)) {
+	if (vlan_proto == htons(ETH_P_8021Q) ||
+	    vlan_proto == htons(ETH_P_8021AD)) {
 		/* pop the vlan tag */
 		vlanid = ntohs(veth->h_vlan_TCI);
 		memmove(skb->data + VLAN_HLEN, veth, ETH_ALEN * 2);
@@ -5685,6 +5683,8 @@ static int stmmac_set_features(struct net_device *netdev,
 
 	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
 		stmmac_set_hw_vlan_mode(priv, priv->ioaddr, features);
+		priv->plat->use_hw_vlan = features & NETIF_F_HW_VLAN_CTAG_RX;
+	}
 
 	return 0;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH v1 0/8] drivers: net: stmicro: Add VLAN support
@ 2023-03-30  7:02 Boon Khai Ng
  2023-03-30 17:20 ` Please ignore this review, send out by accident Boon Khai Ng
  0 siblings, 1 reply; 10+ messages in thread
From: Boon Khai Ng @ 2023-03-30  7:02 UTC (permalink / raw)
  To: David S . Miller; +Cc: linux-kernel, Mun Yew Tham, Tien Sung Ang, Boon Khai Ng

Hi,
The Designware 10G MAC(dwxgmac) driver has lack of vlan support in term of
hardware, such as the hardware accelerated VLAN stripping, hardware filtering
and vlan fail queue. These patches are meant to enable not only the hardware
support of VLAN features but also the promiscous mode. The driver was not draft
from scratch, however it was ported from the Ethernet Quality-of-Service (dwmac4)
driver, it was tested working on ourside.

Boon Khai Ng (8):
  drivers: net: stmmac_main: Add support for HW-accelerated VLAN
    Stripping
  drivers: net: stmmac_main: fix vlan toggle option.
  drivers: net: stmmac: Add support for HW-accelerated VLAN Stripping
  drivers: net: dwmac: Add use_hw_vlan setting
  net: stmmac: Add support for VLAN Rx filtering
  net: stmmac: Add support for VLAN promiscuous mode
  net: stmmac: Add Double VLAN handling for VLAN Rx filtering
  net: stmmac: Add option for VLAN filter fail queue enable

 drivers/net/ethernet/stmicro/stmmac/common.h  |   1 +
 .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  56 +++
 .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 328 +++++++++++++++++-
 .../ethernet/stmicro/stmmac/dwxgmac2_descs.c  |  15 +
 drivers/net/ethernet/stmicro/stmmac/hwif.h    |  16 +
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  30 +-
 .../ethernet/stmicro/stmmac/stmmac_platform.c |  13 +
 include/linux/stmmac.h                        |   1 +
 8 files changed, 452 insertions(+), 8 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-03-30 17:25 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-30  7:02 [PATCH v1 1/8] drivers: net: stmmac_main: Add support for HW-accelerated VLAN Stripping Boon Khai Ng
2023-03-30 17:23 ` Please ignore this review, send out by accident Boon Khai Ng
  -- strict thread matches above, loose matches on Subject: below --
2023-03-30  7:04 [PATCH v1 8/8] net: stmmac: Add option for VLAN filter fail queue enable Boon Khai Ng
2023-03-30 17:25 ` Please ignore this review, send out by accident Boon Khai Ng
2023-03-30  7:04 [PATCH v1 7/8] net: stmmac: Add Double VLAN handling for VLAN Rx filtering Boon Khai Ng
2023-03-30 17:25 ` Please ignore this review, send out by accident Boon Khai Ng
2023-03-30  7:03 [PATCH v1 6/8] net: stmmac: Add support for VLAN promiscuous mode Boon Khai Ng
2023-03-30 17:25 ` Please ignore this review, send out by accident Boon Khai Ng
2023-03-30  7:03 [PATCH v1 5/8] net: stmmac: Add support for VLAN Rx filtering Boon Khai Ng
2023-03-30 17:24 ` Please ignore this review, send out by accident Boon Khai Ng
2023-03-30  7:03 [PATCH v1 4/8] drivers: net: dwmac: Add use_hw_vlan setting Boon Khai Ng
2023-03-30 17:24 ` Please ignore this review, send out by accident Boon Khai Ng
2023-03-30  7:03 [PATCH v1 3/8] drivers: net: stmmac: Add support for HW-accelerated VLAN Stripping Boon Khai Ng
2023-03-30 17:24 ` Please ignore this review, send out by accident Boon Khai Ng
2023-03-30  7:03 [PATCH v1 2/8] drivers: net: stmmac_main: fix vlan toggle option Boon Khai Ng
2023-03-30 17:24 ` Please ignore this review, send out by accident Boon Khai Ng
2023-03-30  7:02 [PATCH v1 0/8] drivers: net: stmicro: Add VLAN support Boon Khai Ng
2023-03-30 17:20 ` Please ignore this review, send out by accident Boon Khai Ng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.