octeontx2-af: Support ESP/AH RSS hashing
authorSubbaraya Sundeep <sbhatta@marvell.com>
Sat, 23 Jan 2021 05:09:12 +0000 (10:39 +0530)
committerJakub Kicinski <kuba@kernel.org>
Tue, 26 Jan 2021 02:14:58 +0000 (18:14 -0800)
Support SPI and sequence number fields of
ESP/AH header to be hashed for RSS. By default
ESP/AH fields are not considered for RSS and
needs to be set explicitly as below:
ethtool -U eth0 rx-flow-hash esp4 sdfn
or
ethtool -U eth0 rx-flow-hash ah4 sdfn
or
ethtool -U eth0 rx-flow-hash esp6 sdfn
or
ethtool -U eth0 rx-flow-hash ah6 sdfn

To disable hashing of ESP fields:
ethtool -U eth0 rx-flow-hash esp4 sd
or
ethtool -U eth0 rx-flow-hash ah4 sd
or
ethtool -U eth0 rx-flow-hash esp6 sd
or
ethtool -U eth0 rx-flow-hash ah6 sd

Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
Link: https://lore.kernel.org/r/1611378552-13288-1-git-send-email-sundeep.lkml@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c

index f919283ddc34d12dc04453af1d939c245a7fb2a2..89e93eb46ab733de56034f8d630e6fb4bec613fa 100644 (file)
@@ -717,6 +717,8 @@ struct nix_rss_flowkey_cfg {
 #define NIX_FLOW_KEY_TYPE_INNR_ETH_DMAC BIT(17)
 #define NIX_FLOW_KEY_TYPE_VLAN         BIT(20)
 #define NIX_FLOW_KEY_TYPE_IPV4_PROTO   BIT(21)
+#define NIX_FLOW_KEY_TYPE_AH           BIT(22)
+#define NIX_FLOW_KEY_TYPE_ESP          BIT(23)
        u32     flowkey_cfg; /* Flowkey types selected */
        u8      group;       /* RSS context or group */
 };
index a8dfbb6d177465312e827c0235b5aef97efe259d..b54753ef7d940165918594565bf0a2c2ac761d1c 100644 (file)
@@ -2580,6 +2580,7 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)
        struct nix_rx_flowkey_alg *field;
        struct nix_rx_flowkey_alg tmp;
        u32 key_type, valid_key;
+       int l4_key_offset;
 
        if (!alg)
                return -EINVAL;
@@ -2712,6 +2713,12 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)
                                field_marker = false;
                                keyoff_marker = false;
                        }
+
+                       /* TCP/UDP/SCTP and ESP/AH falls at same offset so
+                        * remember the TCP key offset of 40 byte hash key.
+                        */
+                       if (key_type == NIX_FLOW_KEY_TYPE_TCP)
+                               l4_key_offset = key_off;
                        break;
                case NIX_FLOW_KEY_TYPE_NVGRE:
                        field->lid = NPC_LID_LD;
@@ -2783,11 +2790,31 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)
                        field->ltype_mask = 0xF;
                        field->fn_mask = 1; /* Mask out the first nibble */
                        break;
+               case NIX_FLOW_KEY_TYPE_AH:
+               case NIX_FLOW_KEY_TYPE_ESP:
+                       field->hdr_offset = 0;
+                       field->bytesm1 = 7; /* SPI + sequence number */
+                       field->ltype_mask = 0xF;
+                       field->lid = NPC_LID_LE;
+                       field->ltype_match = NPC_LT_LE_ESP;
+                       if (key_type == NIX_FLOW_KEY_TYPE_AH) {
+                               field->lid = NPC_LID_LD;
+                               field->ltype_match = NPC_LT_LD_AH;
+                               field->hdr_offset = 4;
+                               keyoff_marker = false;
+                       }
+                       break;
                }
                field->ena = 1;
 
                /* Found a valid flow key type */
                if (valid_key) {
+                       /* Use the key offset of TCP/UDP/SCTP fields
+                        * for ESP/AH fields.
+                        */
+                       if (key_type == NIX_FLOW_KEY_TYPE_ESP ||
+                           key_type == NIX_FLOW_KEY_TYPE_AH)
+                               key_off = l4_key_offset;
                        field->key_offset = key_off;
                        memcpy(&alg[nr_field], field, sizeof(*field));
                        max_key_off = max(max_key_off, field->bytesm1 + 1);
index aaba0454d188ab5cc8366e2a81f1fee1e3eccf90..e0199f0e4a6c3e5e924f7debdee99f8ceea4e4e8 100644 (file)
@@ -448,10 +448,14 @@ static int otx2_get_rss_hash_opts(struct otx2_nic *pfvf,
                        nfc->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
                break;
        case AH_ESP_V4_FLOW:
+       case AH_ESP_V6_FLOW:
+               if (rss->flowkey_cfg & NIX_FLOW_KEY_TYPE_ESP)
+                       nfc->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+               break;
        case AH_V4_FLOW:
        case ESP_V4_FLOW:
        case IPV4_FLOW:
-       case AH_ESP_V6_FLOW:
+               break;
        case AH_V6_FLOW:
        case ESP_V6_FLOW:
        case IPV6_FLOW:
@@ -459,6 +463,7 @@ static int otx2_get_rss_hash_opts(struct otx2_nic *pfvf,
        default:
                return -EINVAL;
        }
+
        return 0;
 }
 
@@ -527,6 +532,36 @@ static int otx2_set_rss_hash_opts(struct otx2_nic *pfvf,
                        return -EINVAL;
                }
                break;
+       case AH_ESP_V4_FLOW:
+       case AH_ESP_V6_FLOW:
+               switch (nfc->data & rxh_l4) {
+               case 0:
+                       rss_cfg &= ~(NIX_FLOW_KEY_TYPE_ESP |
+                                    NIX_FLOW_KEY_TYPE_AH);
+                       rss_cfg |= NIX_FLOW_KEY_TYPE_VLAN |
+                                  NIX_FLOW_KEY_TYPE_IPV4_PROTO;
+                       break;
+               case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+                       /* If VLAN hashing is also requested for ESP then do not
+                        * allow because of hardware 40 bytes flow key limit.
+                        */
+                       if (rss_cfg & NIX_FLOW_KEY_TYPE_VLAN) {
+                               netdev_err(pfvf->netdev,
+                                          "RSS hash of ESP or AH with VLAN is not supported\n");
+                               return -EOPNOTSUPP;
+                       }
+
+                       rss_cfg |= NIX_FLOW_KEY_TYPE_ESP | NIX_FLOW_KEY_TYPE_AH;
+                       /* Disable IPv4 proto hashing since IPv6 SA+DA(32 bytes)
+                        * and ESP SPI+sequence(8 bytes) uses hardware maximum
+                        * limit of 40 byte flow key.
+                        */
+                       rss_cfg &= ~NIX_FLOW_KEY_TYPE_IPV4_PROTO;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
        case IPV4_FLOW:
        case IPV6_FLOW:
                rss_cfg = NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6;