Skip to content

Commit 2556f80

Browse files
Jiawen Wukuba-moo
authored andcommitted
net: wangxun: add RSS reta and rxfh fields support
Add ethtool ops for Rx flow hashing, query and set RSS indirection table and hash key. Disable UDP RSS by default, and support to configure L4 header fields with TCP/UDP/SCTP for flow hasing. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Link: https://patch.msgid.link/20250926023843.34340-4-jiawenwu@trustnetic.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 58f244b commit 2556f80

6 files changed

Lines changed: 167 additions & 2 deletions

File tree

drivers/net/ethernet/wangxun/libwx/wx_ethtool.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,142 @@ int wx_set_channels(struct net_device *dev,
481481
}
482482
EXPORT_SYMBOL(wx_set_channels);
483483

484+
u32 wx_rss_indir_size(struct net_device *netdev)
485+
{
486+
struct wx *wx = netdev_priv(netdev);
487+
488+
return wx_rss_indir_tbl_entries(wx);
489+
}
490+
EXPORT_SYMBOL(wx_rss_indir_size);
491+
492+
u32 wx_get_rxfh_key_size(struct net_device *netdev)
493+
{
494+
return WX_RSS_KEY_SIZE;
495+
}
496+
EXPORT_SYMBOL(wx_get_rxfh_key_size);
497+
498+
static void wx_get_reta(struct wx *wx, u32 *indir)
499+
{
500+
u32 reta_size = wx_rss_indir_tbl_entries(wx);
501+
u16 rss_m = wx->ring_feature[RING_F_RSS].mask;
502+
503+
if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags))
504+
rss_m = wx->ring_feature[RING_F_RSS].indices - 1;
505+
506+
for (u32 i = 0; i < reta_size; i++)
507+
indir[i] = wx->rss_indir_tbl[i] & rss_m;
508+
}
509+
510+
int wx_get_rxfh(struct net_device *netdev,
511+
struct ethtool_rxfh_param *rxfh)
512+
{
513+
struct wx *wx = netdev_priv(netdev);
514+
515+
rxfh->hfunc = ETH_RSS_HASH_TOP;
516+
517+
if (rxfh->indir)
518+
wx_get_reta(wx, rxfh->indir);
519+
520+
if (rxfh->key)
521+
memcpy(rxfh->key, wx->rss_key, WX_RSS_KEY_SIZE);
522+
523+
return 0;
524+
}
525+
EXPORT_SYMBOL(wx_get_rxfh);
526+
527+
int wx_set_rxfh(struct net_device *netdev,
528+
struct ethtool_rxfh_param *rxfh,
529+
struct netlink_ext_ack *extack)
530+
{
531+
struct wx *wx = netdev_priv(netdev);
532+
u32 reta_entries, i;
533+
534+
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
535+
rxfh->hfunc != ETH_RSS_HASH_TOP)
536+
return -EOPNOTSUPP;
537+
538+
reta_entries = wx_rss_indir_tbl_entries(wx);
539+
/* Fill out the redirection table */
540+
if (rxfh->indir) {
541+
for (i = 0; i < reta_entries; i++)
542+
wx->rss_indir_tbl[i] = rxfh->indir[i];
543+
544+
wx_store_reta(wx);
545+
}
546+
547+
/* Fill out the rss hash key */
548+
if (rxfh->key) {
549+
memcpy(wx->rss_key, rxfh->key, WX_RSS_KEY_SIZE);
550+
wx_store_rsskey(wx);
551+
}
552+
553+
return 0;
554+
}
555+
EXPORT_SYMBOL(wx_set_rxfh);
556+
557+
static const struct wx_rss_flow_map rss_flow_table[] = {
558+
{ TCP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_TCP },
559+
{ TCP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_TCP },
560+
{ UDP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_UDP },
561+
{ UDP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_UDP },
562+
{ SCTP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_SCTP },
563+
{ SCTP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_SCTP },
564+
};
565+
566+
int wx_get_rxfh_fields(struct net_device *dev,
567+
struct ethtool_rxfh_fields *nfc)
568+
{
569+
struct wx *wx = netdev_priv(dev);
570+
571+
nfc->data = RXH_IP_SRC | RXH_IP_DST;
572+
573+
for (u32 i = 0; i < ARRAY_SIZE(rss_flow_table); i++) {
574+
const struct wx_rss_flow_map *entry = &rss_flow_table[i];
575+
576+
if (entry->flow_type == nfc->flow_type) {
577+
if (wx->rss_flags & entry->flag)
578+
nfc->data |= entry->data;
579+
break;
580+
}
581+
}
582+
583+
return 0;
584+
}
585+
EXPORT_SYMBOL(wx_get_rxfh_fields);
586+
587+
int wx_set_rxfh_fields(struct net_device *dev,
588+
const struct ethtool_rxfh_fields *nfc,
589+
struct netlink_ext_ack *extack)
590+
{
591+
struct wx *wx = netdev_priv(dev);
592+
u8 flags = wx->rss_flags;
593+
594+
if (!(nfc->data & RXH_IP_SRC) ||
595+
!(nfc->data & RXH_IP_DST))
596+
return -EINVAL;
597+
598+
for (u32 i = 0; i < ARRAY_SIZE(rss_flow_table); i++) {
599+
const struct wx_rss_flow_map *entry = &rss_flow_table[i];
600+
601+
if (entry->flow_type == nfc->flow_type) {
602+
if (nfc->data & entry->data)
603+
flags |= entry->flag;
604+
else
605+
flags &= ~entry->flag;
606+
607+
if (flags != wx->rss_flags) {
608+
wx->rss_flags = flags;
609+
wx_config_rss_field(wx);
610+
}
611+
612+
return 0;
613+
}
614+
}
615+
616+
return -EINVAL;
617+
}
618+
EXPORT_SYMBOL(wx_set_rxfh_fields);
619+
484620
u32 wx_get_msglevel(struct net_device *netdev)
485621
{
486622
struct wx *wx = netdev_priv(netdev);

drivers/net/ethernet/wangxun/libwx/wx_ethtool.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ void wx_get_channels(struct net_device *dev,
3838
struct ethtool_channels *ch);
3939
int wx_set_channels(struct net_device *dev,
4040
struct ethtool_channels *ch);
41+
u32 wx_rss_indir_size(struct net_device *netdev);
42+
u32 wx_get_rxfh_key_size(struct net_device *netdev);
43+
int wx_get_rxfh(struct net_device *netdev,
44+
struct ethtool_rxfh_param *rxfh);
45+
int wx_set_rxfh(struct net_device *netdev,
46+
struct ethtool_rxfh_param *rxfh,
47+
struct netlink_ext_ack *extack);
48+
int wx_get_rxfh_fields(struct net_device *dev,
49+
struct ethtool_rxfh_fields *cmd);
50+
int wx_set_rxfh_fields(struct net_device *dev,
51+
const struct ethtool_rxfh_fields *nfc,
52+
struct netlink_ext_ack *extack);
4153
u32 wx_get_msglevel(struct net_device *netdev);
4254
void wx_set_msglevel(struct net_device *netdev, u32 data);
4355
int wx_get_ts_info(struct net_device *dev,

drivers/net/ethernet/wangxun/libwx/wx_hw.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,8 +2449,7 @@ int wx_sw_init(struct wx *wx)
24492449
return err;
24502450
}
24512451
wx->rss_flags = WX_RSS_FIELD_IPV4 | WX_RSS_FIELD_IPV4_TCP |
2452-
WX_RSS_FIELD_IPV6 | WX_RSS_FIELD_IPV6_TCP |
2453-
WX_RSS_FIELD_IPV4_UDP | WX_RSS_FIELD_IPV6_UDP;
2452+
WX_RSS_FIELD_IPV6 | WX_RSS_FIELD_IPV6_TCP;
24542453

24552454
wx->mac_table = kcalloc(wx->mac.num_rar_entries,
24562455
sizeof(struct wx_mac_addr),

drivers/net/ethernet/wangxun/libwx/wx_type.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,12 @@ struct vf_macvlans {
12081208
#define WX_RSS_FIELD_IPV4_UDP BIT(6)
12091209
#define WX_RSS_FIELD_IPV6_UDP BIT(7)
12101210

1211+
struct wx_rss_flow_map {
1212+
u8 flow_type;
1213+
u32 data;
1214+
u8 flag;
1215+
};
1216+
12111217
enum wx_pf_flags {
12121218
WX_FLAG_MULTI_64_FUNC,
12131219
WX_FLAG_SWFW_RING,

drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ static const struct ethtool_ops ngbe_ethtool_ops = {
137137
.set_coalesce = wx_set_coalesce,
138138
.get_channels = wx_get_channels,
139139
.set_channels = ngbe_set_channels,
140+
.get_rxfh_fields = wx_get_rxfh_fields,
141+
.set_rxfh_fields = wx_set_rxfh_fields,
142+
.get_rxfh_indir_size = wx_rss_indir_size,
143+
.get_rxfh_key_size = wx_get_rxfh_key_size,
144+
.get_rxfh = wx_get_rxfh,
145+
.set_rxfh = wx_set_rxfh,
140146
.get_msglevel = wx_get_msglevel,
141147
.set_msglevel = wx_set_msglevel,
142148
.get_ts_info = wx_get_ts_info,

drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,12 @@ static const struct ethtool_ops txgbe_ethtool_ops = {
560560
.set_channels = txgbe_set_channels,
561561
.get_rxnfc = txgbe_get_rxnfc,
562562
.set_rxnfc = txgbe_set_rxnfc,
563+
.get_rxfh_fields = wx_get_rxfh_fields,
564+
.set_rxfh_fields = wx_set_rxfh_fields,
565+
.get_rxfh_indir_size = wx_rss_indir_size,
566+
.get_rxfh_key_size = wx_get_rxfh_key_size,
567+
.get_rxfh = wx_get_rxfh,
568+
.set_rxfh = wx_set_rxfh,
563569
.get_msglevel = wx_get_msglevel,
564570
.set_msglevel = wx_set_msglevel,
565571
.get_ts_info = wx_get_ts_info,

0 commit comments

Comments
 (0)