From: Jie Liu <liujie5@linkdatatechnology.com>
To: stephen@networkplumber.org
Cc: dev@dpdk.org, JieLiu <liujie5@linkdatatechnology.com>
Subject: [PATCH 05/13] net/sxe: support vlan filter
Date: Thu, 24 Apr 2025 19:36:44 -0700 [thread overview]
Message-ID: <20250425023652.37368-5-liujie5@linkdatatechnology.com> (raw)
In-Reply-To: <20250425023652.37368-1-liujie5@linkdatatechnology.com>
From: JieLiu <liujie5@linkdatatechnology.com>
Support vlan filter.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe/base/sxe_offload_common.c | 4 +
drivers/net/sxe/pf/sxe.h | 4 +
drivers/net/sxe/pf/sxe_ethdev.c | 17 ++
drivers/net/sxe/pf/sxe_filter.c | 277 ++++++++++++++++++++++
drivers/net/sxe/pf/sxe_filter.h | 13 +
drivers/net/sxe/pf/sxe_main.c | 2 +
drivers/net/sxe/pf/sxe_rx.c | 5 +
7 files changed, 322 insertions(+)
diff --git a/drivers/net/sxe/base/sxe_offload_common.c b/drivers/net/sxe/base/sxe_offload_common.c
index 91ae1c792c..48f16240df 100644
--- a/drivers/net/sxe/base/sxe_offload_common.c
+++ b/drivers/net/sxe/base/sxe_offload_common.c
@@ -18,6 +18,8 @@ u64 __sxe_rx_queue_offload_capa_get(struct rte_eth_dev *dev)
u64 offloads = 0;
+ offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
+
return offloads;
}
@@ -32,6 +34,8 @@ u64 __sxe_rx_port_offload_capa_get(struct rte_eth_dev *dev)
#ifdef DEV_RX_JUMBO_FRAME
DEV_RX_OFFLOAD_JUMBO_FRAME |
#endif
+ RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
+ RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
RTE_ETH_RX_OFFLOAD_SCATTER;
if (!RTE_ETH_DEV_SRIOV(dev).active)
diff --git a/drivers/net/sxe/pf/sxe.h b/drivers/net/sxe/pf/sxe.h
index 8a578137bd..d6a8058bfc 100644
--- a/drivers/net/sxe/pf/sxe.h
+++ b/drivers/net/sxe/pf/sxe.h
@@ -11,11 +11,13 @@
#include <stdbool.h>
#endif
#include "sxe_types.h"
+#include "sxe_filter.h"
#include "sxe_irq.h"
#include "sxe_phy.h"
#include "sxe_hw.h"
struct sxe_hw;
+struct sxe_vlan_context;
#define SXE_LPBK_DISABLED 0x0
#define SXE_LPBK_ENABLED 0x1
@@ -45,6 +47,8 @@ struct sxe_adapter {
struct sxe_hw hw;
struct sxe_irq_context irq_ctxt;
+
+ struct sxe_vlan_context vlan_ctxt;
struct sxe_phy_context phy_ctxt;
bool rx_batch_alloc_allowed;
diff --git a/drivers/net/sxe/pf/sxe_ethdev.c b/drivers/net/sxe/pf/sxe_ethdev.c
index b09c60ba26..a1c7e11150 100644
--- a/drivers/net/sxe/pf/sxe_ethdev.c
+++ b/drivers/net/sxe/pf/sxe_ethdev.c
@@ -260,6 +260,9 @@ static s32 sxe_dev_start(struct rte_eth_dev *dev)
goto l_error;
}
+ sxe_vlan_filter_configure(dev);
+
+
sxe_txrx_start(dev);
irq->to_pcs_init = true;
@@ -626,6 +629,11 @@ static const struct eth_dev_ops sxe_eth_dev_ops = {
.flow_ctrl_get = sxe_flow_ctrl_get,
.flow_ctrl_set = sxe_flow_ctrl_set,
+ .vlan_filter_set = sxe_vlan_filter_set,
+ .vlan_tpid_set = sxe_vlan_tpid_set,
+ .vlan_offload_set = sxe_vlan_offload_set,
+ .vlan_strip_queue_set = sxe_vlan_strip_queue_set,
+
.get_reg = sxe_get_regs,
.dev_set_link_up = sxe_dev_set_link_up,
@@ -714,6 +722,14 @@ static void sxe_ethdev_mac_mem_free(struct rte_eth_dev *eth_dev)
}
}
+
+#ifdef DPDK_19_11_6
+static void sxe_pf_init(struct sxe_adapter *adapter)
+{
+ memset(&adapter->vlan_ctxt, 0, sizeof(adapter->vlan_ctxt));
+}
+#endif
+
s32 sxe_ethdev_init(struct rte_eth_dev *eth_dev, void *param __rte_unused)
{
s32 ret = 0;
@@ -761,6 +777,7 @@ s32 sxe_ethdev_init(struct rte_eth_dev *eth_dev, void *param __rte_unused)
#ifdef DPDK_19_11_6
eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
+ sxe_pf_init(adapter);
#endif
ret = sxe_hw_base_init(eth_dev);
if (ret) {
diff --git a/drivers/net/sxe/pf/sxe_filter.c b/drivers/net/sxe/pf/sxe_filter.c
index 52abca85c4..1c2bc05b12 100644
--- a/drivers/net/sxe/pf/sxe_filter.c
+++ b/drivers/net/sxe/pf/sxe_filter.c
@@ -281,3 +281,280 @@ static void sxe_hash_mac_addr_parse(u8 *mac_addr, u16 *reg_idx,
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
mac_addr[4], mac_addr[5], *reg_idx, *bit_idx);
}
+
+s32 sxe_vlan_filter_set(struct rte_eth_dev *eth_dev, u16 vlan_id, s32 on)
+{
+ struct sxe_adapter *adapter = eth_dev->data->dev_private;
+ struct sxe_hw *hw = &adapter->hw;
+ struct sxe_vlan_context *vlan_ctxt = &adapter->vlan_ctxt;
+ u8 reg_idx;
+ u8 bit_idx;
+ u32 value;
+
+ reg_idx = (vlan_id >> SXE_VLAN_ID_SHIFT) & SXE_VLAN_ID_REG_MASK;
+ bit_idx = (vlan_id & SXE_VLAN_ID_BIT_MASK);
+
+ value = sxe_hw_vlan_filter_array_read(hw, reg_idx);
+ if (on)
+ value |= (1 << bit_idx);
+ else
+ value &= ~(1 << bit_idx);
+
+ sxe_hw_vlan_filter_array_write(hw, reg_idx, value);
+
+ vlan_ctxt->vlan_hash_table[reg_idx] = value;
+
+ PMD_LOG_INFO(DRV, "vlan_id:0x%x on:%d set done", vlan_id, on);
+
+ return 0;
+}
+
+static void sxe_vlan_tpid_write(struct sxe_hw *hw, u16 tpid)
+{
+ u32 value;
+
+ value = sxe_hw_vlan_type_get(hw);
+ value = (value & (~SXE_VLNCTRL_VET)) | tpid;
+ sxe_hw_vlan_type_set(hw, value);
+
+ value = sxe_hw_txctl_vlan_type_get(hw);
+ value = (value & (~SXE_DMATXCTL_VT_MASK)) |
+ (tpid << SXE_DMATXCTL_VT_SHIFT);
+ sxe_hw_txctl_vlan_type_set(hw, value);
+}
+
+s32 sxe_vlan_tpid_set(struct rte_eth_dev *eth_dev,
+ enum rte_vlan_type vlan_type, u16 tpid)
+{
+ struct sxe_adapter *adapter = eth_dev->data->dev_private;
+ struct sxe_hw *hw = &adapter->hw;
+ s32 ret = 0;
+ u32 txctl;
+ bool double_vlan;
+
+ txctl = sxe_hw_txctl_vlan_type_get(hw);
+ double_vlan = txctl & SXE_DMATXCTL_GDV;
+
+ switch (vlan_type) {
+ case RTE_ETH_VLAN_TYPE_INNER:
+ if (double_vlan) {
+ sxe_vlan_tpid_write(hw, tpid);
+ } else {
+ ret = -ENOTSUP;
+ PMD_LOG_ERR(DRV, "unsupport inner vlan without "
+ "global double vlan.");
+ }
+ break;
+ case RTE_ETH_VLAN_TYPE_OUTER:
+ if (double_vlan) {
+ sxe_hw_vlan_ext_type_set(hw,
+ (tpid << SXE_EXVET_VET_EXT_SHIFT));
+ } else {
+ sxe_vlan_tpid_write(hw, tpid);
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "Unsupported VLAN type %d", vlan_type);
+ break;
+ }
+
+ PMD_LOG_INFO(DRV, "double_vlan:%d vlan_type:%d tpid:0x%x set done ret:%d",
+ double_vlan, vlan_type, tpid, ret);
+ return ret;
+}
+
+static void sxe_vlan_strip_bitmap_set(struct rte_eth_dev *dev, u16 queue_idx, bool on)
+{
+ struct sxe_adapter *adapter = dev->data->dev_private;
+ struct sxe_vlan_context *vlan_ctxt = &adapter->vlan_ctxt;
+
+ sxe_rx_queue_s *rxq;
+
+ if (queue_idx >= SXE_HW_TXRX_RING_NUM_MAX ||
+ queue_idx >= dev->data->nb_rx_queues) {
+ PMD_LOG_ERR(DRV, "invalid queue idx:%u exceed max"
+ " queue number:%u or nb_rx_queues:%u.",
+ queue_idx, SXE_HW_TXRX_RING_NUM_MAX,
+ dev->data->nb_rx_queues);
+ return;
+ }
+
+ if (on)
+ SXE_STRIP_BITMAP_SET(vlan_ctxt, queue_idx);
+ else
+ SXE_STRIP_BITMAP_CLEAR(vlan_ctxt, queue_idx);
+
+ rxq = dev->data->rx_queues[queue_idx];
+
+ if (on) {
+ rxq->vlan_flags = RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
+ rxq->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
+ } else {
+ rxq->vlan_flags = RTE_MBUF_F_RX_VLAN;
+ rxq->offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
+ }
+
+ PMD_LOG_INFO(DRV, "queue idx:%u vlan strip on:%d set bitmap and offload done.",
+ queue_idx, on);
+}
+
+void sxe_vlan_strip_switch_set(struct rte_eth_dev *dev)
+{
+ struct sxe_adapter *adapter = dev->data->dev_private;
+ struct sxe_hw *hw = &adapter->hw;
+ u16 i;
+ sxe_rx_queue_s *rxq;
+ bool on;
+
+ PMD_INIT_FUNC_TRACE();
+
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ rxq = dev->data->rx_queues[i];
+
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
+ on = true;
+ else
+ on = false;
+ sxe_hw_vlan_tag_strip_switch(hw, i, on);
+
+ sxe_vlan_strip_bitmap_set(dev, i, on);
+ }
+}
+
+static void sxe_vlan_filter_disable(struct rte_eth_dev *dev)
+{
+ struct sxe_adapter *adapter = dev->data->dev_private;
+ struct sxe_hw *hw = &adapter->hw;
+
+ PMD_INIT_FUNC_TRACE();
+
+ sxe_hw_vlan_filter_switch(hw, 0);
+}
+
+static void sxe_vlan_filter_enable(struct rte_eth_dev *dev)
+{
+ struct sxe_adapter *adapter = dev->data->dev_private;
+ struct sxe_hw *hw = &adapter->hw;
+ struct sxe_vlan_context *vlan_ctxt = &adapter->vlan_ctxt;
+ u32 vlan_ctl;
+ u16 i;
+
+ PMD_INIT_FUNC_TRACE();
+
+ vlan_ctl = sxe_hw_vlan_type_get(hw);
+ vlan_ctl &= ~SXE_VLNCTRL_CFI;
+ vlan_ctl |= SXE_VLNCTRL_VFE;
+ sxe_hw_vlan_type_set(hw, vlan_ctl);
+
+ for (i = 0; i < SXE_VFT_TBL_SIZE; i++)
+ sxe_hw_vlan_filter_array_write(hw, i, vlan_ctxt->vlan_hash_table[i]);
+}
+
+static void sxe_vlan_extend_disable(struct rte_eth_dev *dev)
+{
+ struct sxe_adapter *adapter = dev->data->dev_private;
+ struct sxe_hw *hw = &adapter->hw;
+ u32 ctrl;
+
+ PMD_INIT_FUNC_TRACE();
+
+ ctrl = sxe_hw_txctl_vlan_type_get(hw);
+ ctrl &= ~SXE_DMATXCTL_GDV;
+ sxe_hw_txctl_vlan_type_set(hw, ctrl);
+
+ ctrl = sxe_hw_ext_vlan_get(hw);
+ ctrl &= ~SXE_EXTENDED_VLAN;
+ sxe_hw_ext_vlan_set(hw, ctrl);
+}
+
+static void sxe_vlan_extend_enable(struct rte_eth_dev *dev)
+{
+ struct sxe_adapter *adapter = dev->data->dev_private;
+ struct sxe_hw *hw = &adapter->hw;
+ u32 ctrl;
+
+ PMD_INIT_FUNC_TRACE();
+
+ ctrl = sxe_hw_txctl_vlan_type_get(hw);
+ ctrl |= SXE_DMATXCTL_GDV;
+ sxe_hw_txctl_vlan_type_set(hw, ctrl);
+
+ ctrl = sxe_hw_ext_vlan_get(hw);
+ ctrl |= SXE_EXTENDED_VLAN;
+ sxe_hw_ext_vlan_set(hw, ctrl);
+}
+
+static s32 sxe_vlan_offload_configure(struct rte_eth_dev *dev, s32 mask)
+{
+ struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+
+ if (mask & RTE_ETH_VLAN_STRIP_MASK)
+ sxe_vlan_strip_switch_set(dev);
+
+ if (mask & RTE_ETH_VLAN_FILTER_MASK) {
+ if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)
+ sxe_vlan_filter_enable(dev);
+ else
+ sxe_vlan_filter_disable(dev);
+ }
+
+ if (mask & RTE_ETH_VLAN_EXTEND_MASK) {
+ if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)
+ sxe_vlan_extend_enable(dev);
+ else
+ sxe_vlan_extend_disable(dev);
+ }
+
+ PMD_LOG_INFO(DRV, "mask:0x%x rx mode offload:0x%" SXE_PRIX64
+ " vlan offload set done", mask, rxmode->offloads);
+
+ return 0;
+}
+
+s32 sxe_vlan_offload_set(struct rte_eth_dev *dev, s32 vlan_mask)
+{
+ s32 mask;
+ s32 ret = 0;
+
+ if (vlan_mask & RTE_ETH_VLAN_STRIP_MASK) {
+ PMD_LOG_WARN(DRV, "please set vlan strip before device start, not at this stage.");
+ ret = -1;
+ goto l_out;
+ }
+ mask = vlan_mask & ~RTE_ETH_VLAN_STRIP_MASK;
+
+ sxe_vlan_offload_configure(dev, mask);
+
+ PMD_LOG_INFO(DRV, "vlan offload mask:0x%x set done.", vlan_mask);
+
+l_out:
+ return ret;
+}
+
+void sxe_vlan_strip_queue_set(struct rte_eth_dev *dev, u16 queue, s32 on)
+{
+ UNUSED(dev);
+ UNUSED(queue);
+ UNUSED(on);
+ PMD_LOG_WARN(DRV, "please set vlan strip before device start, not at this stage.");
+}
+
+void sxe_vlan_filter_configure(struct rte_eth_dev *dev)
+{
+ struct sxe_adapter *adapter = dev->data->dev_private;
+ struct sxe_hw *hw = &adapter->hw;
+ u32 vlan_mask;
+ u32 vlan_ctl;
+
+ vlan_mask = RTE_ETH_VLAN_STRIP_MASK | RTE_ETH_VLAN_FILTER_MASK |
+ RTE_ETH_VLAN_EXTEND_MASK;
+ sxe_vlan_offload_configure(dev, vlan_mask);
+
+ if (dev->data->dev_conf.rxmode.mq_mode == RTE_ETH_MQ_RX_VMDQ_ONLY) {
+ vlan_ctl = sxe_hw_vlan_type_get(hw);
+ vlan_ctl |= SXE_VLNCTRL_VFE;
+ sxe_hw_vlan_type_set(hw, vlan_ctl);
+ LOG_DEBUG_BDF("vmdq mode enable vlan filter done.");
+ }
+}
diff --git a/drivers/net/sxe/pf/sxe_filter.h b/drivers/net/sxe/pf/sxe_filter.h
index d7cf571b65..2e1211677e 100644
--- a/drivers/net/sxe/pf/sxe_filter.h
+++ b/drivers/net/sxe/pf/sxe_filter.h
@@ -51,10 +51,23 @@ void sxe_mac_addr_remove(struct rte_eth_dev *dev, u32 rar_idx);
s32 sxe_mac_addr_set(struct rte_eth_dev *dev,
struct rte_ether_addr *mac_addr);
+s32 sxe_vlan_filter_set(struct rte_eth_dev *eth_dev, u16 vlan_id, s32 on);
+
+s32 sxe_vlan_tpid_set(struct rte_eth_dev *eth_dev,
+ enum rte_vlan_type vlan_type, u16 tpid);
+
+s32 sxe_vlan_offload_set(struct rte_eth_dev *dev, s32 vlan_mask);
+
+void sxe_vlan_strip_queue_set(struct rte_eth_dev *dev, u16 queue, s32 on);
+
+void sxe_vlan_filter_configure(struct rte_eth_dev *dev);
+
s32 sxe_set_mc_addr_list(struct rte_eth_dev *dev,
struct rte_ether_addr *mc_addr_list,
u32 nb_mc_addr);
+void sxe_vlan_strip_switch_set(struct rte_eth_dev *dev);
+
void sxe_fc_mac_addr_set(struct sxe_adapter *adapter);
#endif
diff --git a/drivers/net/sxe/pf/sxe_main.c b/drivers/net/sxe/pf/sxe_main.c
index 52c6248a82..482d73669d 100644
--- a/drivers/net/sxe/pf/sxe_main.c
+++ b/drivers/net/sxe/pf/sxe_main.c
@@ -212,6 +212,8 @@ s32 sxe_hw_reset(struct sxe_hw *hw)
void sxe_hw_start(struct sxe_hw *hw)
{
+ sxe_hw_vlan_filter_array_clear(hw);
+
sxe_fc_autoneg_localcap_set(hw);
hw->mac.auto_restart = true;
diff --git a/drivers/net/sxe/pf/sxe_rx.c b/drivers/net/sxe/pf/sxe_rx.c
index 976513a166..2f879d92cb 100644
--- a/drivers/net/sxe/pf/sxe_rx.c
+++ b/drivers/net/sxe/pf/sxe_rx.c
@@ -1072,6 +1072,9 @@ static inline void
rxq->crc_len = RTE_ETHER_CRC_LEN;
else
rxq->crc_len = 0;
+
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
+ rx_conf->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
}
}
@@ -1093,6 +1096,8 @@ static inline void
adapter->mtu = dev->data->mtu;
#endif
+ rx_conf->offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
+
if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_SCATTER)
dev->data->scattered_rx = 1;
--
2.18.4
next prev parent reply other threads:[~2025-04-25 2:37 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-25 2:36 [PATCH 01/13] net/sxe: add base driver directory and doc Jie Liu
2025-04-25 2:36 ` [PATCH 02/13] net/sxe: add ethdev probe and remove Jie Liu
2025-04-25 2:36 ` [PATCH 03/13] net/sxe: add tx rx setup and data path Jie Liu
2025-04-25 2:36 ` [PATCH 04/13] net/sxe: add link, flow ctrl, mac ops, mtu ops function Jie Liu
2025-04-25 2:36 ` Jie Liu [this message]
2025-04-25 2:36 ` [PATCH 06/13] net/sxe: add mac layer filter function Jie Liu
2025-04-25 2:36 ` [PATCH 07/13] net/sxe: support rss offload Jie Liu
2025-04-25 2:36 ` [PATCH 08/13] net/sxe: add dcb function Jie Liu
2025-04-25 2:36 ` [PATCH 09/13] net/sxe: support ptp Jie Liu
2025-04-25 2:36 ` [PATCH 10/13] net/sxe: add xstats function Jie Liu
2025-04-25 2:36 ` [PATCH 11/13] net/sxe: add custom cmd led ctrl Jie Liu
2025-04-25 2:36 ` [PATCH 12/13] net/sxe: add simd function Jie Liu
2025-04-25 2:36 ` [PATCH 13/13] net/sxe: add virtual function Jie Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250425023652.37368-5-liujie5@linkdatatechnology.com \
--to=liujie5@linkdatatechnology.com \
--cc=dev@dpdk.org \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).