octeontx2-af: Support ESP/AH RSS hashing

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>
This commit is contained in:
Subbaraya Sundeep 2021-01-23 10:39:12 +05:30 committed by Jakub Kicinski
parent 24f97b6af9
commit b9b7421a01
3 changed files with 65 additions and 1 deletions

View 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 */
};

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

View 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;