net: libwx: support separate RSS configuration for every pool

For those devices which support 64 pools, they also support PF and VF
(i.e. different pools) to configure different RSS key and hash table.
Enable multiple RSS, use up to 64 RSS configurations and each pool has a
specific configuration.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Link: https://patch.msgid.link/20250926023843.34340-2-jiawenwu@trustnetic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jiawen Wu 2025-09-26 10:38:40 +08:00 committed by Jakub Kicinski
parent 1fb0e47161
commit 1be6db0497
4 changed files with 98 additions and 33 deletions

View File

@ -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 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 < key_size; i++)
wr32(wx, WX_RDB_VMRSSRK(i, wx->num_vfs),
wx->rss_key[i]);
} else {
for (i = 0; i < 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,52 @@ static void wx_setup_reta(struct wx *wx)
wx_store_reta(wx);
}
void wx_config_rss_field(struct wx *wx)
{
u32 rss_field;
/* Global RSS and multiple RSS have the same type field */
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;
if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) &&
test_bit(WX_FLAG_MULTI_64_FUNC, wx->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 {
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,27 +2150,14 @@ static void wx_setup_psrtype(struct wx *wx)
static void wx_setup_mrqc(struct wx *wx)
{
u32 rss_field = 0;
/* 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);
}
/**

View File

@ -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);

View File

@ -3016,14 +3016,8 @@ 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);
wx->rss_enabled = true;
} else {
wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN, 0);
wx->rss_enabled = false;
}
wx->rss_enabled = !!(features & NETIF_F_RXHASH);
wx_enable_rss(wx, wx->rss_enabled);
netdev->features = features;

View File

@ -168,9 +168,11 @@
#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_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)
@ -180,6 +182,9 @@
#define WX_RDB_RA_CTL_RSS_IPV6_UDP BIT(23)
#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 */