* [PATCH net-next 0/2] net: wangxun: support to configure RSS
@ 2025-08-27 6:46 Jiawen Wu
2025-08-27 6:46 ` [PATCH net-next 1/2] net: libwx: support multiple RSS for every pool Jiawen Wu
2025-08-27 6:46 ` [PATCH net-next 2/2] net: wangxun: add RSS reta and rxfh fields support Jiawen Wu
0 siblings, 2 replies; 5+ messages in thread
From: Jiawen Wu @ 2025-08-27 6:46 UTC (permalink / raw)
To: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman
Cc: Mengyuan Lou, Jiawen Wu
Implement ethtool ops for RSS configuration, and support multiple RSS
for multiple pools.
Jiawen Wu (2):
net: libwx: support multiple RSS for every pool
net: wangxun: add RSS reta and rxfh fields support
.../net/ethernet/wangxun/libwx/wx_ethtool.c | 152 ++++++++++++++++++
.../net/ethernet/wangxun/libwx/wx_ethtool.h | 12 ++
drivers/net/ethernet/wangxun/libwx/wx_hw.c | 111 ++++++++++---
drivers/net/ethernet/wangxun/libwx/wx_hw.h | 5 +
drivers/net/ethernet/wangxun/libwx/wx_lib.c | 10 +-
drivers/net/ethernet/wangxun/libwx/wx_type.h | 24 +++
.../net/ethernet/wangxun/ngbe/ngbe_ethtool.c | 6 +
.../ethernet/wangxun/txgbe/txgbe_ethtool.c | 6 +
8 files changed, 295 insertions(+), 31 deletions(-)
--
2.48.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net-next 1/2] net: libwx: support multiple RSS for every pool
2025-08-27 6:46 [PATCH net-next 0/2] net: wangxun: support to configure RSS Jiawen Wu
@ 2025-08-27 6:46 ` Jiawen Wu
2025-08-28 15:50 ` Simon Horman
2025-08-27 6:46 ` [PATCH net-next 2/2] net: wangxun: add RSS reta and rxfh fields support Jiawen Wu
1 sibling, 1 reply; 5+ messages in thread
From: Jiawen Wu @ 2025-08-27 6:46 UTC (permalink / raw)
To: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman
Cc: Mengyuan Lou, Jiawen Wu
For those devices which support 64 pools, they also support PF and VF
(i.e. different pools) to configure different RSS key. Enable multiple
RSS, use up to 64 RSS keys and that is one key per pool.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ethernet/wangxun/libwx/wx_hw.c | 111 ++++++++++++++-----
drivers/net/ethernet/wangxun/libwx/wx_hw.h | 5 +
drivers/net/ethernet/wangxun/libwx/wx_lib.c | 10 +-
drivers/net/ethernet/wangxun/libwx/wx_type.h | 18 +++
4 files changed, 113 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
index bcd07a715752..9c56e2b11672 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
@@ -1998,8 +1998,17 @@ static void wx_restore_vlan(struct wx *wx)
wx_vlan_rx_add_vid(wx->netdev, htons(ETH_P_8021Q), vid);
}
-static void wx_store_reta(struct wx *wx)
+u32 wx_rss_indir_tbl_entries(struct wx *wx)
{
+ if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags))
+ return 64;
+ else
+ return 128;
+}
+
+void wx_store_reta(struct wx *wx)
+{
+ u32 reta_entries = wx_rss_indir_tbl_entries(wx);
u8 *indir_tbl = wx->rss_indir_tbl;
u32 reta = 0;
u32 i;
@@ -2007,36 +2016,55 @@ static void wx_store_reta(struct wx *wx)
/* Fill out the redirection table as follows:
* - 8 bit wide entries containing 4 bit RSS index
*/
- for (i = 0; i < WX_MAX_RETA_ENTRIES; i++) {
+ for (i = 0; i < reta_entries; i++) {
reta |= indir_tbl[i] << (i & 0x3) * 8;
if ((i & 3) == 3) {
- wr32(wx, WX_RDB_RSSTBL(i >> 2), reta);
+ if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) &&
+ test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags))
+ wr32(wx, WX_RDB_VMRSSTBL(i >> 2, wx->num_vfs), reta);
+ else
+ wr32(wx, WX_RDB_RSSTBL(i >> 2), reta);
reta = 0;
}
}
}
+void wx_store_rsskey(struct wx *wx)
+{
+ u32 random_key_size = WX_RSS_KEY_SIZE / 4;
+ u32 i;
+
+ if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) &&
+ test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
+ for (i = 0; i < random_key_size; i++)
+ wr32(wx, WX_RDB_VMRSSRK(i, wx->num_vfs),
+ *(wx->rss_key + i));
+ } else {
+ for (i = 0; i < random_key_size; i++)
+ wr32(wx, WX_RDB_RSSRK(i), wx->rss_key[i]);
+ }
+}
+
static void wx_setup_reta(struct wx *wx)
{
u16 rss_i = wx->ring_feature[RING_F_RSS].indices;
- u32 random_key_size = WX_RSS_KEY_SIZE / 4;
+ u32 reta_entries = wx_rss_indir_tbl_entries(wx);
u32 i, j;
if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags)) {
- if (wx->mac.type == wx_mac_em)
- rss_i = 1;
+ if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags))
+ rss_i = rss_i < 2 ? 2 : rss_i;
else
- rss_i = rss_i < 4 ? 4 : rss_i;
+ rss_i = 1;
}
/* Fill out hash function seeds */
- for (i = 0; i < random_key_size; i++)
- wr32(wx, WX_RDB_RSSRK(i), wx->rss_key[i]);
+ wx_store_rsskey(wx);
/* Fill out redirection table */
memset(wx->rss_indir_tbl, 0, sizeof(wx->rss_indir_tbl));
- for (i = 0, j = 0; i < WX_MAX_RETA_ENTRIES; i++, j++) {
+ for (i = 0, j = 0; i < reta_entries; i++, j++) {
if (j == rss_i)
j = 0;
@@ -2046,6 +2074,50 @@ static void wx_setup_reta(struct wx *wx)
wx_store_reta(wx);
}
+void wx_config_rss_field(struct wx *wx)
+{
+ u32 rss_field;
+
+ if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) &&
+ test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
+ rss_field = rd32(wx, WX_RDB_PL_CFG(wx->num_vfs));
+ rss_field &= ~WX_RDB_PL_CFG_RSS_MASK;
+ rss_field |= wx->rss_flags << WX_RSS_FIELD_SHIFT;
+ wr32(wx, WX_RDB_PL_CFG(wx->num_vfs), rss_field);
+
+ /* Enable global RSS and multiple RSS to make the RSS
+ * field of each pool take effect.
+ */
+ wr32m(wx, WX_RDB_RA_CTL,
+ WX_RDB_RA_CTL_MULTI_RSS | WX_RDB_RA_CTL_RSS_EN,
+ WX_RDB_RA_CTL_MULTI_RSS | WX_RDB_RA_CTL_RSS_EN);
+ } else {
+ rss_field = rd32(wx, WX_RDB_RA_CTL);
+ rss_field &= ~WX_RDB_RA_CTL_RSS_MASK;
+ rss_field |= wx->rss_flags << WX_RSS_FIELD_SHIFT;
+ wr32(wx, WX_RDB_RA_CTL, rss_field);
+ }
+}
+
+void wx_enable_rss(struct wx *wx, bool enable)
+{
+ if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) &&
+ test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
+ if (enable)
+ wr32m(wx, WX_RDB_PL_CFG(wx->num_vfs),
+ WX_RDB_PL_CFG_RSS_EN, WX_RDB_PL_CFG_RSS_EN);
+ else
+ wr32m(wx, WX_RDB_PL_CFG(wx->num_vfs),
+ WX_RDB_PL_CFG_RSS_EN, 0);
+ } else {
+ if (enable)
+ wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN,
+ WX_RDB_RA_CTL_RSS_EN);
+ else
+ wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN, 0);
+ }
+}
+
#define WX_RDB_RSS_PL_2 FIELD_PREP(GENMASK(31, 29), 1)
#define WX_RDB_RSS_PL_4 FIELD_PREP(GENMASK(31, 29), 2)
static void wx_setup_psrtype(struct wx *wx)
@@ -2076,8 +2148,6 @@ static void wx_setup_psrtype(struct wx *wx)
static void wx_setup_mrqc(struct wx *wx)
{
- u32 rss_field = 0;
-
/* VT, and RSS do not coexist at the same time */
if (test_bit(WX_FLAG_VMDQ_ENABLED, wx->flags))
return;
@@ -2085,22 +2155,11 @@ static void wx_setup_mrqc(struct wx *wx)
/* Disable indicating checksum in descriptor, enables RSS hash */
wr32m(wx, WX_PSR_CTL, WX_PSR_CTL_PCSD, WX_PSR_CTL_PCSD);
- /* Perform hash on these packet types */
- rss_field = WX_RDB_RA_CTL_RSS_IPV4 |
- WX_RDB_RA_CTL_RSS_IPV4_TCP |
- WX_RDB_RA_CTL_RSS_IPV4_UDP |
- WX_RDB_RA_CTL_RSS_IPV6 |
- WX_RDB_RA_CTL_RSS_IPV6_TCP |
- WX_RDB_RA_CTL_RSS_IPV6_UDP;
-
netdev_rss_key_fill(wx->rss_key, sizeof(wx->rss_key));
+ wx_config_rss_field(wx);
+ wx_enable_rss(wx, wx->rss_enabled);
wx_setup_reta(wx);
-
- if (wx->rss_enabled)
- rss_field |= WX_RDB_RA_CTL_RSS_EN;
-
- wr32(wx, WX_RDB_RA_CTL, rss_field);
}
/**
@@ -2393,6 +2452,8 @@ int wx_sw_init(struct wx *wx)
wx_err(wx, "rss key allocation failed\n");
return err;
}
+ wx->rss_flags = WX_RSS_FIELD_IPV4 | WX_RSS_FIELD_IPV4_TCP |
+ WX_RSS_FIELD_IPV6 | WX_RSS_FIELD_IPV6_TCP;
wx->mac_table = kcalloc(wx->mac.num_rar_entries,
sizeof(struct wx_mac_addr),
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.h b/drivers/net/ethernet/wangxun/libwx/wx_hw.h
index 2393a743b564..13857376bbad 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_hw.h
+++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.h
@@ -39,6 +39,11 @@ void wx_set_rx_mode(struct net_device *netdev);
int wx_change_mtu(struct net_device *netdev, int new_mtu);
void wx_disable_rx_queue(struct wx *wx, struct wx_ring *ring);
void wx_enable_rx_queue(struct wx *wx, struct wx_ring *ring);
+u32 wx_rss_indir_tbl_entries(struct wx *wx);
+void wx_store_reta(struct wx *wx);
+void wx_store_rsskey(struct wx *wx);
+void wx_config_rss_field(struct wx *wx);
+void wx_enable_rss(struct wx *wx, bool enable);
void wx_configure_rx(struct wx *wx);
void wx_configure(struct wx *wx);
void wx_start_hw(struct wx *wx);
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
index 5086db060c61..5ec26349c91b 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
@@ -3016,14 +3016,12 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
struct wx *wx = netdev_priv(netdev);
bool need_reset = false;
- if (features & NETIF_F_RXHASH) {
- wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN,
- WX_RDB_RA_CTL_RSS_EN);
+ if (features & NETIF_F_RXHASH)
wx->rss_enabled = true;
- } else {
- wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN, 0);
+ else
wx->rss_enabled = false;
- }
+
+ wx_enable_rss(wx, wx->rss_enabled);
netdev->features = features;
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
index ec63e7ec8b24..9fd0f3a5a48c 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
+++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
@@ -168,9 +168,12 @@
#define WX_RDB_PL_CFG_L2HDR BIT(3)
#define WX_RDB_PL_CFG_TUN_TUNHDR BIT(4)
#define WX_RDB_PL_CFG_TUN_OUTL2HDR BIT(5)
+#define WX_RDB_PL_CFG_RSS_EN BIT(24)
+#define WX_RDB_PL_CFG_RSS_MASK GENMASK(23, 16)
#define WX_RDB_RSSTBL(_i) (0x19400 + ((_i) * 4))
#define WX_RDB_RSSRK(_i) (0x19480 + ((_i) * 4))
#define WX_RDB_RA_CTL 0x194F4
+#define WX_RDB_RA_CTL_MULTI_RSS BIT(0)
#define WX_RDB_RA_CTL_RSS_EN BIT(2) /* RSS Enable */
#define WX_RDB_RA_CTL_RSS_IPV4_TCP BIT(16)
#define WX_RDB_RA_CTL_RSS_IPV4 BIT(17)
@@ -178,8 +181,12 @@
#define WX_RDB_RA_CTL_RSS_IPV6_TCP BIT(21)
#define WX_RDB_RA_CTL_RSS_IPV4_UDP BIT(22)
#define WX_RDB_RA_CTL_RSS_IPV6_UDP BIT(23)
+#define WX_RDB_RA_CTL_RSS_MASK GENMASK(23, 16)
#define WX_RDB_FDIR_MATCH 0x19558
#define WX_RDB_FDIR_MISS 0x1955C
+/* VM RSS */
+#define WX_RDB_VMRSSRK(_i, _p) (0x1A000 + ((_i) * 4) + ((_p) * 0x40))
+#define WX_RDB_VMRSSTBL(_i, _p) (0x1B000 + ((_i) * 4) + ((_p) * 0x40))
/******************************* PSR Registers *******************************/
/* psr control */
@@ -1192,6 +1199,16 @@ struct vf_macvlans {
u8 vf_macvlan[ETH_ALEN];
};
+#define WX_RSS_FIELD_SHIFT 16
+#define WX_RSS_FIELD_IPV4_TCP BIT(0)
+#define WX_RSS_FIELD_IPV4 BIT(1)
+#define WX_RSS_FIELD_IPV4_SCTP BIT(2)
+#define WX_RSS_FIELD_IPV6_SCTP BIT(3)
+#define WX_RSS_FIELD_IPV6_TCP BIT(4)
+#define WX_RSS_FIELD_IPV6 BIT(5)
+#define WX_RSS_FIELD_IPV4_UDP BIT(6)
+#define WX_RSS_FIELD_IPV6_UDP BIT(7)
+
enum wx_pf_flags {
WX_FLAG_MULTI_64_FUNC,
WX_FLAG_SWFW_RING,
@@ -1302,6 +1319,7 @@ struct wx {
#define WX_MAX_RETA_ENTRIES 128
#define WX_RSS_INDIR_TBL_MAX 64
u8 rss_indir_tbl[WX_MAX_RETA_ENTRIES];
+ u8 rss_flags;
bool rss_enabled;
#define WX_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */
u32 *rss_key;
--
2.48.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next 2/2] net: wangxun: add RSS reta and rxfh fields support
2025-08-27 6:46 [PATCH net-next 0/2] net: wangxun: support to configure RSS Jiawen Wu
2025-08-27 6:46 ` [PATCH net-next 1/2] net: libwx: support multiple RSS for every pool Jiawen Wu
@ 2025-08-27 6:46 ` Jiawen Wu
2025-08-27 15:10 ` Alexander Lobakin
1 sibling, 1 reply; 5+ messages in thread
From: Jiawen Wu @ 2025-08-27 6:46 UTC (permalink / raw)
To: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman
Cc: Mengyuan Lou, Jiawen Wu
Add ethtool ops for Rx flow hashing, query and set RSS indirection table
and hash key. And support to configure L4 header fields with
TCP/UDP/SCTP for flow hasing.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
.../net/ethernet/wangxun/libwx/wx_ethtool.c | 152 ++++++++++++++++++
.../net/ethernet/wangxun/libwx/wx_ethtool.h | 12 ++
drivers/net/ethernet/wangxun/libwx/wx_type.h | 6 +
.../net/ethernet/wangxun/ngbe/ngbe_ethtool.c | 6 +
.../ethernet/wangxun/txgbe/txgbe_ethtool.c | 6 +
5 files changed, 182 insertions(+)
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
index 9572b9f28e59..a0a46b1b4f9e 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
@@ -481,6 +481,158 @@ int wx_set_channels(struct net_device *dev,
}
EXPORT_SYMBOL(wx_set_channels);
+u32 wx_rss_indir_size(struct net_device *netdev)
+{
+ struct wx *wx = netdev_priv(netdev);
+
+ return wx_rss_indir_tbl_entries(wx);
+}
+EXPORT_SYMBOL(wx_rss_indir_size);
+
+u32 wx_get_rxfh_key_size(struct net_device *netdev)
+{
+ return WX_RSS_KEY_SIZE;
+}
+EXPORT_SYMBOL(wx_get_rxfh_key_size);
+
+static void wx_get_reta(struct wx *wx, u32 *indir)
+{
+ int i, reta_size = wx_rss_indir_tbl_entries(wx);
+ u16 rss_m = wx->ring_feature[RING_F_RSS].mask;
+
+ if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags))
+ rss_m = wx->ring_feature[RING_F_RSS].indices - 1;
+
+ for (i = 0; i < reta_size; i++)
+ indir[i] = wx->rss_indir_tbl[i] & rss_m;
+}
+
+int wx_get_rxfh(struct net_device *netdev,
+ struct ethtool_rxfh_param *rxfh)
+{
+ struct wx *wx = netdev_priv(netdev);
+
+ rxfh->hfunc = ETH_RSS_HASH_TOP;
+
+ if (rxfh->indir)
+ wx_get_reta(wx, rxfh->indir);
+
+ if (rxfh->key)
+ memcpy(rxfh->key, wx->rss_key, WX_RSS_KEY_SIZE);
+
+ return 0;
+}
+EXPORT_SYMBOL(wx_get_rxfh);
+
+int wx_set_rxfh(struct net_device *netdev,
+ struct ethtool_rxfh_param *rxfh,
+ struct netlink_ext_ack *extack)
+{
+ struct wx *wx = netdev_priv(netdev);
+ u32 reta_entries;
+ int i;
+
+ if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
+ rxfh->hfunc != ETH_RSS_HASH_TOP)
+ return -EOPNOTSUPP;
+
+ reta_entries = wx_rss_indir_tbl_entries(wx);
+ /* Fill out the redirection table */
+ if (rxfh->indir) {
+ int max_queues = min_t(int, wx->num_rx_queues,
+ WX_RSS_INDIR_TBL_MAX);
+
+ /*Allow at least 2 queues w/ SR-IOV.*/
+ if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) &&
+ max_queues < 2)
+ max_queues = 2;
+
+ /* Verify user input. */
+ for (i = 0; i < reta_entries; i++)
+ if (rxfh->indir[i] >= max_queues)
+ return -EINVAL;
+
+ for (i = 0; i < reta_entries; i++)
+ wx->rss_indir_tbl[i] = rxfh->indir[i];
+
+ wx_store_reta(wx);
+ }
+
+ /* Fill out the rss hash key */
+ if (rxfh->key) {
+ memcpy(wx->rss_key, rxfh->key, WX_RSS_KEY_SIZE);
+ wx_store_rsskey(wx);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(wx_set_rxfh);
+
+static const struct wx_rss_flow_map rss_flow_table[] = {
+ { TCP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_TCP},
+ { TCP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_TCP},
+ { UDP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_UDP},
+ { UDP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_UDP},
+ { SCTP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_SCTP},
+ { SCTP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_SCTP},
+};
+
+int wx_get_rxfh_fields(struct net_device *dev,
+ struct ethtool_rxfh_fields *nfc)
+{
+ struct wx *wx = netdev_priv(dev);
+ int i;
+
+ nfc->data = RXH_IP_SRC | RXH_IP_DST;
+
+ for (i = 0; i < ARRAY_SIZE(rss_flow_table); i++) {
+ const struct wx_rss_flow_map *entry = &rss_flow_table[i];
+
+ if (entry->flow_type == nfc->flow_type) {
+ if (wx->rss_flags & entry->flag)
+ nfc->data |= entry->data;
+ break;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(wx_get_rxfh_fields);
+
+int wx_set_rxfh_fields(struct net_device *dev,
+ const struct ethtool_rxfh_fields *nfc,
+ struct netlink_ext_ack *extack)
+{
+ struct wx *wx = netdev_priv(dev);
+ u8 flags = wx->rss_flags;
+ int i;
+
+ if (!(nfc->data & RXH_IP_SRC) ||
+ !(nfc->data & RXH_IP_DST))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(rss_flow_table); i++) {
+ const struct wx_rss_flow_map *entry = &rss_flow_table[i];
+
+ if (entry->flow_type == nfc->flow_type) {
+ if (nfc->data & entry->data)
+ flags |= entry->flag;
+ else
+ flags &= ~entry->flag;
+
+ if (flags != wx->rss_flags) {
+ wx->rss_flags = flags;
+ wx_config_rss_field(wx);
+ }
+
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(wx_set_rxfh_fields);
+
u32 wx_get_msglevel(struct net_device *netdev)
{
struct wx *wx = netdev_priv(netdev);
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h
index 9e002e699eca..2ddd4039d5d2 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h
+++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h
@@ -38,6 +38,18 @@ void wx_get_channels(struct net_device *dev,
struct ethtool_channels *ch);
int wx_set_channels(struct net_device *dev,
struct ethtool_channels *ch);
+u32 wx_rss_indir_size(struct net_device *netdev);
+u32 wx_get_rxfh_key_size(struct net_device *netdev);
+int wx_get_rxfh(struct net_device *netdev,
+ struct ethtool_rxfh_param *rxfh);
+int wx_set_rxfh(struct net_device *netdev,
+ struct ethtool_rxfh_param *rxfh,
+ struct netlink_ext_ack *extack);
+int wx_get_rxfh_fields(struct net_device *dev,
+ struct ethtool_rxfh_fields *cmd);
+int wx_set_rxfh_fields(struct net_device *dev,
+ const struct ethtool_rxfh_fields *nfc,
+ struct netlink_ext_ack *extack);
u32 wx_get_msglevel(struct net_device *netdev);
void wx_set_msglevel(struct net_device *netdev, u32 data);
int wx_get_ts_info(struct net_device *dev,
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
index 9fd0f3a5a48c..7971bc22e869 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
+++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
@@ -1209,6 +1209,12 @@ struct vf_macvlans {
#define WX_RSS_FIELD_IPV4_UDP BIT(6)
#define WX_RSS_FIELD_IPV6_UDP BIT(7)
+struct wx_rss_flow_map {
+ u8 flow_type;
+ u32 data;
+ u32 flag;
+};
+
enum wx_pf_flags {
WX_FLAG_MULTI_64_FUNC,
WX_FLAG_SWFW_RING,
diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c
index 4363bab33496..662f28bdde8a 100644
--- a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c
+++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c
@@ -137,6 +137,12 @@ static const struct ethtool_ops ngbe_ethtool_ops = {
.set_coalesce = wx_set_coalesce,
.get_channels = wx_get_channels,
.set_channels = ngbe_set_channels,
+ .get_rxfh_fields = wx_get_rxfh_fields,
+ .set_rxfh_fields = wx_set_rxfh_fields,
+ .get_rxfh_indir_size = wx_rss_indir_size,
+ .get_rxfh_key_size = wx_get_rxfh_key_size,
+ .get_rxfh = wx_get_rxfh,
+ .set_rxfh = wx_set_rxfh,
.get_msglevel = wx_get_msglevel,
.set_msglevel = wx_set_msglevel,
.get_ts_info = wx_get_ts_info,
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
index b496ec502fed..e285b088c7b2 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
@@ -560,6 +560,12 @@ static const struct ethtool_ops txgbe_ethtool_ops = {
.set_channels = txgbe_set_channels,
.get_rxnfc = txgbe_get_rxnfc,
.set_rxnfc = txgbe_set_rxnfc,
+ .get_rxfh_fields = wx_get_rxfh_fields,
+ .set_rxfh_fields = wx_set_rxfh_fields,
+ .get_rxfh_indir_size = wx_rss_indir_size,
+ .get_rxfh_key_size = wx_get_rxfh_key_size,
+ .get_rxfh = wx_get_rxfh,
+ .set_rxfh = wx_set_rxfh,
.get_msglevel = wx_get_msglevel,
.set_msglevel = wx_set_msglevel,
.get_ts_info = wx_get_ts_info,
--
2.48.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net-next 2/2] net: wangxun: add RSS reta and rxfh fields support
2025-08-27 6:46 ` [PATCH net-next 2/2] net: wangxun: add RSS reta and rxfh fields support Jiawen Wu
@ 2025-08-27 15:10 ` Alexander Lobakin
0 siblings, 0 replies; 5+ messages in thread
From: Alexander Lobakin @ 2025-08-27 15:10 UTC (permalink / raw)
To: Jiawen Wu
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mengyuan Lou
From: Jiawen Wu <jiawenwu@trustnetic.com>
Date: Wed, 27 Aug 2025 14:46:34 +0800
> Add ethtool ops for Rx flow hashing, query and set RSS indirection table
> and hash key. And support to configure L4 header fields with
> TCP/UDP/SCTP for flow hasing.
>
> Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
> ---
> .../net/ethernet/wangxun/libwx/wx_ethtool.c | 152 ++++++++++++++++++
> .../net/ethernet/wangxun/libwx/wx_ethtool.h | 12 ++
> drivers/net/ethernet/wangxun/libwx/wx_type.h | 6 +
> .../net/ethernet/wangxun/ngbe/ngbe_ethtool.c | 6 +
> .../ethernet/wangxun/txgbe/txgbe_ethtool.c | 6 +
> 5 files changed, 182 insertions(+)
>
> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> index 9572b9f28e59..a0a46b1b4f9e 100644
> --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> @@ -481,6 +481,158 @@ int wx_set_channels(struct net_device *dev,
> }
> EXPORT_SYMBOL(wx_set_channels);
>
> +u32 wx_rss_indir_size(struct net_device *netdev)
> +{
> + struct wx *wx = netdev_priv(netdev);
> +
> + return wx_rss_indir_tbl_entries(wx);
> +}
> +EXPORT_SYMBOL(wx_rss_indir_size);
> +
> +u32 wx_get_rxfh_key_size(struct net_device *netdev)
> +{
> + return WX_RSS_KEY_SIZE;
> +}
> +EXPORT_SYMBOL(wx_get_rxfh_key_size);
> +
> +static void wx_get_reta(struct wx *wx, u32 *indir)
> +{
> + int i, reta_size = wx_rss_indir_tbl_entries(wx);
Nit: you can embed iterator declarations inside the corresponding loop
declarations.
for (u32 i = 0; ...
> + u16 rss_m = wx->ring_feature[RING_F_RSS].mask;
> +
> + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags))
> + rss_m = wx->ring_feature[RING_F_RSS].indices - 1;
> +
> + for (i = 0; i < reta_size; i++)
> + indir[i] = wx->rss_indir_tbl[i] & rss_m;
> +}
[...]
> + reta_entries = wx_rss_indir_tbl_entries(wx);
> + /* Fill out the redirection table */
> + if (rxfh->indir) {
> + int max_queues = min_t(int, wx->num_rx_queues,
> + WX_RSS_INDIR_TBL_MAX);
I guess you can't have negative number of queues, why int?
> +
> + /*Allow at least 2 queues w/ SR-IOV.*/
> + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) &&
> + max_queues < 2)
> + max_queues = 2;
> +
> + /* Verify user input. */
> + for (i = 0; i < reta_entries; i++)
> + if (rxfh->indir[i] >= max_queues)
> + return -EINVAL;
> +
> + for (i = 0; i < reta_entries; i++)
> + wx->rss_indir_tbl[i] = rxfh->indir[i];
> +
> + wx_store_reta(wx);
> + }
> +
> + /* Fill out the rss hash key */
> + if (rxfh->key) {
> + memcpy(wx->rss_key, rxfh->key, WX_RSS_KEY_SIZE);
> + wx_store_rsskey(wx);
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(wx_set_rxfh);
> +
> +static const struct wx_rss_flow_map rss_flow_table[] = {
> + { TCP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_TCP},
> + { TCP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_TCP},
> + { UDP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_UDP},
> + { UDP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_UDP},
> + { SCTP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_SCTP},
> + { SCTP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_SCTP},
If you start declarations with `{ ` (with a space), do the same at the
end of them:
`IPV4_TCP },`
Thanks,
Olek
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next 1/2] net: libwx: support multiple RSS for every pool
2025-08-27 6:46 ` [PATCH net-next 1/2] net: libwx: support multiple RSS for every pool Jiawen Wu
@ 2025-08-28 15:50 ` Simon Horman
0 siblings, 0 replies; 5+ messages in thread
From: Simon Horman @ 2025-08-28 15:50 UTC (permalink / raw)
To: Jiawen Wu
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mengyuan Lou
On Wed, Aug 27, 2025 at 02:46:33PM +0800, Jiawen Wu wrote:
> For those devices which support 64 pools, they also support PF and VF
> (i.e. different pools) to configure different RSS key. Enable multiple
> RSS, use up to 64 RSS keys and that is one key per pool.
>
> Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
...
> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
...
> @@ -2046,6 +2074,50 @@ static void wx_setup_reta(struct wx *wx)
> wx_store_reta(wx);
> }
>
> +void wx_config_rss_field(struct wx *wx)
> +{
> + u32 rss_field;
> +
> + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) &&
> + test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
> + rss_field = rd32(wx, WX_RDB_PL_CFG(wx->num_vfs));
> + rss_field &= ~WX_RDB_PL_CFG_RSS_MASK;
> + rss_field |= wx->rss_flags << WX_RSS_FIELD_SHIFT;
Hi Jiawen,
I expect you can use something like the following here,
and drop WX_RX_FIELD_SHIFT entirely.
rss_field |= FIELD_PREP(WX_RDB_PL_CFG_RSS_MASK, wx->rss_flags);
> + wr32(wx, WX_RDB_PL_CFG(wx->num_vfs), rss_field);
> +
> + /* Enable global RSS and multiple RSS to make the RSS
> + * field of each pool take effect.
> + */
> + wr32m(wx, WX_RDB_RA_CTL,
> + WX_RDB_RA_CTL_MULTI_RSS | WX_RDB_RA_CTL_RSS_EN,
> + WX_RDB_RA_CTL_MULTI_RSS | WX_RDB_RA_CTL_RSS_EN);
> + } else {
> + rss_field = rd32(wx, WX_RDB_RA_CTL);
> + rss_field &= ~WX_RDB_RA_CTL_RSS_MASK;
> + rss_field |= wx->rss_flags << WX_RSS_FIELD_SHIFT;
> + wr32(wx, WX_RDB_RA_CTL, rss_field);
> + }
> +}
...
> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
> index ec63e7ec8b24..9fd0f3a5a48c 100644
> --- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
> +++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
> @@ -168,9 +168,12 @@
> #define WX_RDB_PL_CFG_L2HDR BIT(3)
> #define WX_RDB_PL_CFG_TUN_TUNHDR BIT(4)
> #define WX_RDB_PL_CFG_TUN_OUTL2HDR BIT(5)
> +#define WX_RDB_PL_CFG_RSS_EN BIT(24)
> +#define WX_RDB_PL_CFG_RSS_MASK GENMASK(23, 16)
> #define WX_RDB_RSSTBL(_i) (0x19400 + ((_i) * 4))
> #define WX_RDB_RSSRK(_i) (0x19480 + ((_i) * 4))
> #define WX_RDB_RA_CTL 0x194F4
> +#define WX_RDB_RA_CTL_MULTI_RSS BIT(0)
> #define WX_RDB_RA_CTL_RSS_EN BIT(2) /* RSS Enable */
> #define WX_RDB_RA_CTL_RSS_IPV4_TCP BIT(16)
> #define WX_RDB_RA_CTL_RSS_IPV4 BIT(17)
...
> @@ -1192,6 +1199,16 @@ struct vf_macvlans {
> u8 vf_macvlan[ETH_ALEN];
> };
>
> +#define WX_RSS_FIELD_SHIFT 16
> +#define WX_RSS_FIELD_IPV4_TCP BIT(0)
> +#define WX_RSS_FIELD_IPV4 BIT(1)
> +#define WX_RSS_FIELD_IPV4_SCTP BIT(2)
> +#define WX_RSS_FIELD_IPV6_SCTP BIT(3)
> +#define WX_RSS_FIELD_IPV6_TCP BIT(4)
> +#define WX_RSS_FIELD_IPV6 BIT(5)
> +#define WX_RSS_FIELD_IPV4_UDP BIT(6)
> +#define WX_RSS_FIELD_IPV6_UDP BIT(7)
> +
> enum wx_pf_flags {
> WX_FLAG_MULTI_64_FUNC,
> WX_FLAG_SWFW_RING,
...
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-08-28 15:50 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-27 6:46 [PATCH net-next 0/2] net: wangxun: support to configure RSS Jiawen Wu
2025-08-27 6:46 ` [PATCH net-next 1/2] net: libwx: support multiple RSS for every pool Jiawen Wu
2025-08-28 15:50 ` Simon Horman
2025-08-27 6:46 ` [PATCH net-next 2/2] net: wangxun: add RSS reta and rxfh fields support Jiawen Wu
2025-08-27 15:10 ` Alexander Lobakin
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).