]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: libwx: support separate RSS configuration for every pool
authorJiawen Wu <jiawenwu@trustnetic.com>
Fri, 26 Sep 2025 02:38:40 +0000 (10:38 +0800)
committerJakub Kicinski <kuba@kernel.org>
Tue, 30 Sep 2025 01:11:16 +0000 (18:11 -0700)
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>
drivers/net/ethernet/wangxun/libwx/wx_hw.c
drivers/net/ethernet/wangxun/libwx/wx_hw.h
drivers/net/ethernet/wangxun/libwx/wx_lib.c
drivers/net/ethernet/wangxun/libwx/wx_type.h

index 5cb353a97d6d8090a8465d6d8705d29cac155f50..0bb4cddf7809d2e4b44939ed8bf0ef5eee0b99b9 100644 (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);
 }
 
 /**
index 2393a743b5648a59e97422f41bfca9611823b94d..13857376bbad8754f054008c5534b8f6eaa7b6ce 100644 (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);
index 5086db060c61c7bbd7c70100c9a266d62743c1cb..3adf7048320aee7945d2772a5ef6e369aba47c11 100644 (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;
 
index ec63e7ec8b2421aa7f4d7c43c7f562fa1f1cd545..0450e276ae28d3bc3a1e27f53b5e307c40eff154 100644 (file)
 #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)
 #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 */