]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
i40e: Fix flow-type by setting GL_HASH_INSET registers
authorSlawomir Laba <slawomirx.laba@intel.com>
Mon, 24 Oct 2022 10:05:26 +0000 (03:05 -0700)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 28 Nov 2022 14:18:16 +0000 (15:18 +0100)
BugLink: https://bugs.launchpad.net/bugs/1997981
[ Upstream commit 3b32c9932853e11d71f9db012d69e92e4669ba23 ]

Fix setting bits for specific flow_type for GLQF_HASH_INSET register.
In previous version all of the bits were set only in hena register, while
in inset only one bit was set. In order for this working correctly on all
types of cards these bits needs to be set correctly for both hena and inset
registers.

Fixes: eb0dd6e4a3b3 ("i40e: Allow RSS Hash set with less than four parameters")
Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com>
Signed-off-by: Michal Jaron <michalx.jaron@intel.com>
Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://lore.kernel.org/r/20221024100526.1874914-3-jacob.e.keller@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/net/ethernet/intel/i40e/i40e_ethtool.c

index 6d94255bea5f6a44e041deb7dc4600da8ae62bd5..4e32432878053c00db4270cff6d71358df6d8315 100644 (file)
@@ -3504,6 +3504,7 @@ static u64 i40e_get_rss_hash_bits(struct i40e_hw *hw,
        return i_set;
 }
 
+#define FLOW_PCTYPES_SIZE 64
 /**
  * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
  * @pf: pointer to the physical function struct
@@ -3516,9 +3517,11 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
        struct i40e_hw *hw = &pf->hw;
        u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
                   ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
-       u8 flow_pctype = 0;
+       DECLARE_BITMAP(flow_pctypes, FLOW_PCTYPES_SIZE);
        u64 i_set, i_setc;
 
+       bitmap_zero(flow_pctypes, FLOW_PCTYPES_SIZE);
+
        if (pf->flags & I40E_FLAG_MFP_ENABLED) {
                dev_err(&pf->pdev->dev,
                        "Change of RSS hash input set is not supported when MFP mode is enabled\n");
@@ -3534,36 +3537,35 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
 
        switch (nfc->flow_type) {
        case TCP_V4_FLOW:
-               flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
+               set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, flow_pctypes);
                if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+                       set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK,
+                               flow_pctypes);
                break;
        case TCP_V6_FLOW:
-               flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
-               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+               set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, flow_pctypes);
                if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
+                       set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK,
+                               flow_pctypes);
                break;
        case UDP_V4_FLOW:
-               flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
-               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
-
+               set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, flow_pctypes);
+               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
+                       set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP,
+                               flow_pctypes);
+                       set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP,
+                               flow_pctypes);
+               }
                hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4);
                break;
        case UDP_V6_FLOW:
-               flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
-               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
-
+               set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, flow_pctypes);
+               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
+                       set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP,
+                               flow_pctypes);
+                       set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP,
+                               flow_pctypes);
+               }
                hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6);
                break;
        case AH_ESP_V4_FLOW:
@@ -3596,17 +3598,20 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
                return -EINVAL;
        }
 
-       if (flow_pctype) {
-               i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0,
-                                              flow_pctype)) |
-                       ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1,
-                                              flow_pctype)) << 32);
-               i_set = i40e_get_rss_hash_bits(&pf->hw, nfc, i_setc);
-               i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_pctype),
-                                 (u32)i_set);
-               i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_pctype),
-                                 (u32)(i_set >> 32));
-               hena |= BIT_ULL(flow_pctype);
+       if (bitmap_weight(flow_pctypes, FLOW_PCTYPES_SIZE)) {
+               u8 flow_id;
+
+               for_each_set_bit(flow_id, flow_pctypes, FLOW_PCTYPES_SIZE) {
+                       i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id)) |
+                                ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id)) << 32);
+                       i_set = i40e_get_rss_hash_bits(&pf->hw, nfc, i_setc);
+
+                       i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id),
+                                         (u32)i_set);
+                       i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id),
+                                         (u32)(i_set >> 32));
+                       hena |= BIT_ULL(flow_id);
+               }
        }
 
        i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);