octeontx2-af: Add more RSS algorithms

This patch adds support for few more RSS key types for flow key
algorithm to compute rss hash index.

Following flow key types have been added.
- Tunnel types like NVGRE, VXLAN, GENEVE.
- L2 offload type ETH_DMAC, Here we will consider only DMAC 6 bytes.
- And extension header IPV6_EXT (1 byte followed by IPV6 header
- Hashing inner protocol fields for inner DMAC, IPv4/v6, TCP, UDP, SCTP.

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Kiran Kumar K 2019-11-14 10:56:28 +05:30 committed by David S. Miller
parent 8cc89ae925
commit 206ff848a1
2 changed files with 114 additions and 11 deletions

View File

@ -580,6 +580,18 @@ struct nix_rss_flowkey_cfg {
#define NIX_FLOW_KEY_TYPE_TCP BIT(3)
#define NIX_FLOW_KEY_TYPE_UDP BIT(4)
#define NIX_FLOW_KEY_TYPE_SCTP BIT(5)
#define NIX_FLOW_KEY_TYPE_NVGRE BIT(6)
#define NIX_FLOW_KEY_TYPE_VXLAN BIT(7)
#define NIX_FLOW_KEY_TYPE_GENEVE BIT(8)
#define NIX_FLOW_KEY_TYPE_ETH_DMAC BIT(9)
#define NIX_FLOW_KEY_TYPE_IPV6_EXT BIT(10)
#define NIX_FLOW_KEY_TYPE_GTPU BIT(11)
#define NIX_FLOW_KEY_TYPE_INNR_IPV4 BIT(12)
#define NIX_FLOW_KEY_TYPE_INNR_IPV6 BIT(13)
#define NIX_FLOW_KEY_TYPE_INNR_TCP BIT(14)
#define NIX_FLOW_KEY_TYPE_INNR_UDP BIT(15)
#define NIX_FLOW_KEY_TYPE_INNR_SCTP BIT(16)
#define NIX_FLOW_KEY_TYPE_INNR_ETH_DMAC BIT(17)
u32 flowkey_cfg; /* Flowkey types selected */
u8 group; /* RSS context or group */
};

View File

@ -2032,51 +2032,82 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)
if (field_marker)
memset(&tmp, 0, sizeof(tmp));
field_marker = true;
keyoff_marker = true;
switch (key_type) {
case NIX_FLOW_KEY_TYPE_PORT:
field->sel_chan = true;
/* This should be set to 1, when SEL_CHAN is set */
field->bytesm1 = 1;
field_marker = true;
keyoff_marker = true;
break;
case NIX_FLOW_KEY_TYPE_IPV4:
case NIX_FLOW_KEY_TYPE_INNR_IPV4:
field->lid = NPC_LID_LC;
field->ltype_match = NPC_LT_LC_IP;
if (key_type == NIX_FLOW_KEY_TYPE_INNR_IPV4) {
field->lid = NPC_LID_LG;
field->ltype_match = NPC_LT_LG_TU_IP;
}
field->hdr_offset = 12; /* SIP offset */
field->bytesm1 = 7; /* SIP + DIP, 8 bytes */
field->ltype_mask = 0xF; /* Match only IPv4 */
field_marker = true;
keyoff_marker = false;
break;
case NIX_FLOW_KEY_TYPE_IPV6:
case NIX_FLOW_KEY_TYPE_INNR_IPV6:
field->lid = NPC_LID_LC;
field->ltype_match = NPC_LT_LC_IP6;
if (key_type == NIX_FLOW_KEY_TYPE_INNR_IPV6) {
field->lid = NPC_LID_LG;
field->ltype_match = NPC_LT_LG_TU_IP6;
}
field->hdr_offset = 8; /* SIP offset */
field->bytesm1 = 31; /* SIP + DIP, 32 bytes */
field->ltype_mask = 0xF; /* Match only IPv6 */
field_marker = true;
keyoff_marker = true;
break;
case NIX_FLOW_KEY_TYPE_TCP:
case NIX_FLOW_KEY_TYPE_UDP:
case NIX_FLOW_KEY_TYPE_SCTP:
case NIX_FLOW_KEY_TYPE_INNR_TCP:
case NIX_FLOW_KEY_TYPE_INNR_UDP:
case NIX_FLOW_KEY_TYPE_INNR_SCTP:
field->lid = NPC_LID_LD;
if (key_type == NIX_FLOW_KEY_TYPE_INNR_TCP ||
key_type == NIX_FLOW_KEY_TYPE_INNR_UDP ||
key_type == NIX_FLOW_KEY_TYPE_INNR_SCTP)
field->lid = NPC_LID_LH;
field->bytesm1 = 3; /* Sport + Dport, 4 bytes */
if (key_type == NIX_FLOW_KEY_TYPE_TCP && valid_key) {
/* Enum values for NPC_LID_LD and NPC_LID_LG are same,
* so no need to change the ltype_match, just change
* the lid for inner protocols
*/
BUILD_BUG_ON((int)NPC_LT_LD_TCP !=
(int)NPC_LT_LH_TU_TCP);
BUILD_BUG_ON((int)NPC_LT_LD_UDP !=
(int)NPC_LT_LH_TU_UDP);
BUILD_BUG_ON((int)NPC_LT_LD_SCTP !=
(int)NPC_LT_LH_TU_SCTP);
if ((key_type == NIX_FLOW_KEY_TYPE_TCP ||
key_type == NIX_FLOW_KEY_TYPE_INNR_TCP) &&
valid_key) {
field->ltype_match |= NPC_LT_LD_TCP;
group_member = true;
} else if (key_type == NIX_FLOW_KEY_TYPE_UDP &&
} else if ((key_type == NIX_FLOW_KEY_TYPE_UDP ||
key_type == NIX_FLOW_KEY_TYPE_INNR_UDP) &&
valid_key) {
field->ltype_match |= NPC_LT_LD_UDP;
group_member = true;
} else if (key_type == NIX_FLOW_KEY_TYPE_SCTP &&
} else if ((key_type == NIX_FLOW_KEY_TYPE_SCTP ||
key_type == NIX_FLOW_KEY_TYPE_INNR_SCTP) &&
valid_key) {
field->ltype_match |= NPC_LT_LD_SCTP;
group_member = true;
}
field->ltype_mask = ~field->ltype_match;
if (key_type == NIX_FLOW_KEY_TYPE_SCTP) {
if (key_type == NIX_FLOW_KEY_TYPE_SCTP ||
key_type == NIX_FLOW_KEY_TYPE_INNR_SCTP) {
/* Handle the case where any of the group item
* is enabled in the group but not the final one
*/
@ -2084,13 +2115,73 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)
valid_key = true;
group_member = false;
}
field_marker = true;
keyoff_marker = true;
} else {
field_marker = false;
keyoff_marker = false;
}
break;
case NIX_FLOW_KEY_TYPE_NVGRE:
field->lid = NPC_LID_LD;
field->hdr_offset = 4; /* VSID offset */
field->bytesm1 = 2;
field->ltype_match = NPC_LT_LD_NVGRE;
field->ltype_mask = 0xF;
break;
case NIX_FLOW_KEY_TYPE_VXLAN:
case NIX_FLOW_KEY_TYPE_GENEVE:
field->lid = NPC_LID_LE;
field->bytesm1 = 2;
field->hdr_offset = 4;
field->ltype_mask = 0xF;
field_marker = false;
keyoff_marker = false;
if (key_type == NIX_FLOW_KEY_TYPE_VXLAN && valid_key) {
field->ltype_match |= NPC_LT_LE_VXLAN;
group_member = true;
}
if (key_type == NIX_FLOW_KEY_TYPE_GENEVE && valid_key) {
field->ltype_match |= NPC_LT_LE_GENEVE;
group_member = true;
}
if (key_type == NIX_FLOW_KEY_TYPE_GENEVE) {
if (group_member) {
field->ltype_mask = ~field->ltype_match;
field_marker = true;
keyoff_marker = true;
valid_key = true;
group_member = false;
}
}
break;
case NIX_FLOW_KEY_TYPE_ETH_DMAC:
case NIX_FLOW_KEY_TYPE_INNR_ETH_DMAC:
field->lid = NPC_LID_LA;
field->ltype_match = NPC_LT_LA_ETHER;
if (key_type == NIX_FLOW_KEY_TYPE_INNR_ETH_DMAC) {
field->lid = NPC_LID_LF;
field->ltype_match = NPC_LT_LF_TU_ETHER;
}
field->hdr_offset = 0;
field->bytesm1 = 5; /* DMAC 6 Byte */
field->ltype_mask = 0xF;
break;
case NIX_FLOW_KEY_TYPE_IPV6_EXT:
field->lid = NPC_LID_LC;
field->hdr_offset = 40; /* IPV6 hdr */
field->bytesm1 = 0; /* 1 Byte ext hdr*/
field->ltype_match = NPC_LT_LC_IP6_EXT;
field->ltype_mask = 0xF;
break;
case NIX_FLOW_KEY_TYPE_GTPU:
field->lid = NPC_LID_LE;
field->hdr_offset = 4;
field->bytesm1 = 3; /* 4 bytes TID*/
field->ltype_match = NPC_LT_LE_GTPU;
field->ltype_mask = 0xF;
break;
}
field->ena = 1;