xref: /linux/drivers/net/ethernet/intel/ice/virt/rss.c (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
1f4e667ebSPrzemek Kitszel // SPDX-License-Identifier: GPL-2.0
2f4e667ebSPrzemek Kitszel /* Copyright (C) 2022, Intel Corporation. */
3f4e667ebSPrzemek Kitszel 
4*e0d2795aSPrzemek Kitszel #include "rss.h"
5f4e667ebSPrzemek Kitszel #include "ice_vf_lib_private.h"
6f4e667ebSPrzemek Kitszel #include "ice.h"
7f4e667ebSPrzemek Kitszel 
8f4e667ebSPrzemek Kitszel #define FIELD_SELECTOR(proto_hdr_field) \
9f4e667ebSPrzemek Kitszel 		BIT((proto_hdr_field) & PROTO_HDR_FIELD_MASK)
10f4e667ebSPrzemek Kitszel 
11f4e667ebSPrzemek Kitszel struct ice_vc_hdr_match_type {
12f4e667ebSPrzemek Kitszel 	u32 vc_hdr;	/* virtchnl headers (VIRTCHNL_PROTO_HDR_XXX) */
13f4e667ebSPrzemek Kitszel 	u32 ice_hdr;	/* ice headers (ICE_FLOW_SEG_HDR_XXX) */
14f4e667ebSPrzemek Kitszel };
15f4e667ebSPrzemek Kitszel 
16f4e667ebSPrzemek Kitszel static const struct ice_vc_hdr_match_type ice_vc_hdr_list[] = {
17f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_NONE,	ICE_FLOW_SEG_HDR_NONE},
18f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_ETH,	ICE_FLOW_SEG_HDR_ETH},
19f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_S_VLAN,	ICE_FLOW_SEG_HDR_VLAN},
20f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_C_VLAN,	ICE_FLOW_SEG_HDR_VLAN},
21f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV4,	ICE_FLOW_SEG_HDR_IPV4 |
22f4e667ebSPrzemek Kitszel 					ICE_FLOW_SEG_HDR_IPV_OTHER},
23f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV6,	ICE_FLOW_SEG_HDR_IPV6 |
24f4e667ebSPrzemek Kitszel 					ICE_FLOW_SEG_HDR_IPV_OTHER},
25f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_TCP,	ICE_FLOW_SEG_HDR_TCP},
26f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_UDP,	ICE_FLOW_SEG_HDR_UDP},
27f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_SCTP,	ICE_FLOW_SEG_HDR_SCTP},
28f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_PPPOE,	ICE_FLOW_SEG_HDR_PPPOE},
29f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_GTPU_IP,	ICE_FLOW_SEG_HDR_GTPU_IP},
30f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_GTPU_EH,	ICE_FLOW_SEG_HDR_GTPU_EH},
31f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN,
32f4e667ebSPrzemek Kitszel 					ICE_FLOW_SEG_HDR_GTPU_DWN},
33f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP,
34f4e667ebSPrzemek Kitszel 					ICE_FLOW_SEG_HDR_GTPU_UP},
35f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_L2TPV3,	ICE_FLOW_SEG_HDR_L2TPV3},
36f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_ESP,	ICE_FLOW_SEG_HDR_ESP},
37f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_AH,		ICE_FLOW_SEG_HDR_AH},
38f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_PFCP,	ICE_FLOW_SEG_HDR_PFCP_SESSION},
39f4e667ebSPrzemek Kitszel };
40f4e667ebSPrzemek Kitszel 
41f4e667ebSPrzemek Kitszel struct ice_vc_hash_field_match_type {
42f4e667ebSPrzemek Kitszel 	u32 vc_hdr;		/* virtchnl headers
43f4e667ebSPrzemek Kitszel 				 * (VIRTCHNL_PROTO_HDR_XXX)
44f4e667ebSPrzemek Kitszel 				 */
45f4e667ebSPrzemek Kitszel 	u32 vc_hash_field;	/* virtchnl hash fields selector
46f4e667ebSPrzemek Kitszel 				 * FIELD_SELECTOR((VIRTCHNL_PROTO_HDR_ETH_XXX))
47f4e667ebSPrzemek Kitszel 				 */
48f4e667ebSPrzemek Kitszel 	u64 ice_hash_field;	/* ice hash fields
49f4e667ebSPrzemek Kitszel 				 * (BIT_ULL(ICE_FLOW_FIELD_IDX_XXX))
50f4e667ebSPrzemek Kitszel 				 */
51f4e667ebSPrzemek Kitszel };
52f4e667ebSPrzemek Kitszel 
53f4e667ebSPrzemek Kitszel static const struct
54f4e667ebSPrzemek Kitszel ice_vc_hash_field_match_type ice_vc_hash_field_list[] = {
55f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC),
56f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA)},
57f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST),
58f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA)},
59f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) |
60f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST),
61f4e667ebSPrzemek Kitszel 		ICE_FLOW_HASH_ETH},
62f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_ETH,
63f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE),
64f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE)},
65f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_S_VLAN,
66f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID),
67f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN)},
68f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_C_VLAN,
69f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID),
70f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN)},
71f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC),
72f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
73f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
74f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
75f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
76f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
77f4e667ebSPrzemek Kitszel 		ICE_FLOW_HASH_IPV4},
78f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
79f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
80f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) |
81f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
82f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
83f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
84f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) |
85f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
86f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
87f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
88f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
89f4e667ebSPrzemek Kitszel 		ICE_FLOW_HASH_IPV4 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
90f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
91f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
92f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC),
93f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
94f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
95f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
96f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
97f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
98f4e667ebSPrzemek Kitszel 		ICE_FLOW_HASH_IPV6},
99f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
100f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
101f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) |
102f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
103f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
104f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
105f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) |
106f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
107f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
108f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
109f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
110f4e667ebSPrzemek Kitszel 		ICE_FLOW_HASH_IPV6 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
111f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
112f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
113f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_TCP,
114f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT),
115f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
116f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_TCP,
117f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
118f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
119f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_TCP,
120f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) |
121f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
122f4e667ebSPrzemek Kitszel 		ICE_FLOW_HASH_TCP_PORT},
123f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_UDP,
124f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT),
125f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
126f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_UDP,
127f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
128f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
129f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_UDP,
130f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) |
131f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
132f4e667ebSPrzemek Kitszel 		ICE_FLOW_HASH_UDP_PORT},
133f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_SCTP,
134f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT),
135f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
136f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_SCTP,
137f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
138f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
139f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_SCTP,
140f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) |
141f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
142f4e667ebSPrzemek Kitszel 		ICE_FLOW_HASH_SCTP_PORT},
143f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_PPPOE,
144f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID),
145f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID)},
146f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_GTPU_IP,
147f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_GTPU_IP_TEID),
148f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID)},
149f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_L2TPV3,
150f4e667ebSPrzemek Kitszel 		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID),
151f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID)},
152f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_ESP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI),
153f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_ESP_SPI)},
154f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_AH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI),
155f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_AH_SPI)},
156f4e667ebSPrzemek Kitszel 	{VIRTCHNL_PROTO_HDR_PFCP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID),
157f4e667ebSPrzemek Kitszel 		BIT_ULL(ICE_FLOW_FIELD_IDX_PFCP_SEID)},
158f4e667ebSPrzemek Kitszel };
159f4e667ebSPrzemek Kitszel 
160f4e667ebSPrzemek Kitszel /**
161f4e667ebSPrzemek Kitszel  * ice_vc_validate_pattern
162f4e667ebSPrzemek Kitszel  * @vf: pointer to the VF info
163f4e667ebSPrzemek Kitszel  * @proto: virtchnl protocol headers
164f4e667ebSPrzemek Kitszel  *
165f4e667ebSPrzemek Kitszel  * validate the pattern is supported or not.
166f4e667ebSPrzemek Kitszel  *
167f4e667ebSPrzemek Kitszel  * Return: true on success, false on error.
168f4e667ebSPrzemek Kitszel  */
169f4e667ebSPrzemek Kitszel bool
170f4e667ebSPrzemek Kitszel ice_vc_validate_pattern(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto)
171f4e667ebSPrzemek Kitszel {
172f4e667ebSPrzemek Kitszel 	bool is_ipv4 = false;
173f4e667ebSPrzemek Kitszel 	bool is_ipv6 = false;
174f4e667ebSPrzemek Kitszel 	bool is_udp = false;
175f4e667ebSPrzemek Kitszel 	u16 ptype = -1;
176f4e667ebSPrzemek Kitszel 	int i = 0;
177f4e667ebSPrzemek Kitszel 
178f4e667ebSPrzemek Kitszel 	while (i < proto->count &&
179f4e667ebSPrzemek Kitszel 	       proto->proto_hdr[i].type != VIRTCHNL_PROTO_HDR_NONE) {
180f4e667ebSPrzemek Kitszel 		switch (proto->proto_hdr[i].type) {
181f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_ETH:
182f4e667ebSPrzemek Kitszel 			ptype = ICE_PTYPE_MAC_PAY;
183f4e667ebSPrzemek Kitszel 			break;
184f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_IPV4:
185f4e667ebSPrzemek Kitszel 			ptype = ICE_PTYPE_IPV4_PAY;
186f4e667ebSPrzemek Kitszel 			is_ipv4 = true;
187f4e667ebSPrzemek Kitszel 			break;
188f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_IPV6:
189f4e667ebSPrzemek Kitszel 			ptype = ICE_PTYPE_IPV6_PAY;
190f4e667ebSPrzemek Kitszel 			is_ipv6 = true;
191f4e667ebSPrzemek Kitszel 			break;
192f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_UDP:
193f4e667ebSPrzemek Kitszel 			if (is_ipv4)
194f4e667ebSPrzemek Kitszel 				ptype = ICE_PTYPE_IPV4_UDP_PAY;
195f4e667ebSPrzemek Kitszel 			else if (is_ipv6)
196f4e667ebSPrzemek Kitszel 				ptype = ICE_PTYPE_IPV6_UDP_PAY;
197f4e667ebSPrzemek Kitszel 			is_udp = true;
198f4e667ebSPrzemek Kitszel 			break;
199f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_TCP:
200f4e667ebSPrzemek Kitszel 			if (is_ipv4)
201f4e667ebSPrzemek Kitszel 				ptype = ICE_PTYPE_IPV4_TCP_PAY;
202f4e667ebSPrzemek Kitszel 			else if (is_ipv6)
203f4e667ebSPrzemek Kitszel 				ptype = ICE_PTYPE_IPV6_TCP_PAY;
204f4e667ebSPrzemek Kitszel 			break;
205f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_SCTP:
206f4e667ebSPrzemek Kitszel 			if (is_ipv4)
207f4e667ebSPrzemek Kitszel 				ptype = ICE_PTYPE_IPV4_SCTP_PAY;
208f4e667ebSPrzemek Kitszel 			else if (is_ipv6)
209f4e667ebSPrzemek Kitszel 				ptype = ICE_PTYPE_IPV6_SCTP_PAY;
210f4e667ebSPrzemek Kitszel 			break;
211f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_GTPU_IP:
212f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_GTPU_EH:
213f4e667ebSPrzemek Kitszel 			if (is_ipv4)
214f4e667ebSPrzemek Kitszel 				ptype = ICE_MAC_IPV4_GTPU;
215f4e667ebSPrzemek Kitszel 			else if (is_ipv6)
216f4e667ebSPrzemek Kitszel 				ptype = ICE_MAC_IPV6_GTPU;
217f4e667ebSPrzemek Kitszel 			goto out;
218f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_L2TPV3:
219f4e667ebSPrzemek Kitszel 			if (is_ipv4)
220f4e667ebSPrzemek Kitszel 				ptype = ICE_MAC_IPV4_L2TPV3;
221f4e667ebSPrzemek Kitszel 			else if (is_ipv6)
222f4e667ebSPrzemek Kitszel 				ptype = ICE_MAC_IPV6_L2TPV3;
223f4e667ebSPrzemek Kitszel 			goto out;
224f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_ESP:
225f4e667ebSPrzemek Kitszel 			if (is_ipv4)
226f4e667ebSPrzemek Kitszel 				ptype = is_udp ? ICE_MAC_IPV4_NAT_T_ESP :
227f4e667ebSPrzemek Kitszel 						ICE_MAC_IPV4_ESP;
228f4e667ebSPrzemek Kitszel 			else if (is_ipv6)
229f4e667ebSPrzemek Kitszel 				ptype = is_udp ? ICE_MAC_IPV6_NAT_T_ESP :
230f4e667ebSPrzemek Kitszel 						ICE_MAC_IPV6_ESP;
231f4e667ebSPrzemek Kitszel 			goto out;
232f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_AH:
233f4e667ebSPrzemek Kitszel 			if (is_ipv4)
234f4e667ebSPrzemek Kitszel 				ptype = ICE_MAC_IPV4_AH;
235f4e667ebSPrzemek Kitszel 			else if (is_ipv6)
236f4e667ebSPrzemek Kitszel 				ptype = ICE_MAC_IPV6_AH;
237f4e667ebSPrzemek Kitszel 			goto out;
238f4e667ebSPrzemek Kitszel 		case VIRTCHNL_PROTO_HDR_PFCP:
239f4e667ebSPrzemek Kitszel 			if (is_ipv4)
240f4e667ebSPrzemek Kitszel 				ptype = ICE_MAC_IPV4_PFCP_SESSION;
241f4e667ebSPrzemek Kitszel 			else if (is_ipv6)
242f4e667ebSPrzemek Kitszel 				ptype = ICE_MAC_IPV6_PFCP_SESSION;
243f4e667ebSPrzemek Kitszel 			goto out;
244f4e667ebSPrzemek Kitszel 		default:
245f4e667ebSPrzemek Kitszel 			break;
246f4e667ebSPrzemek Kitszel 		}
247f4e667ebSPrzemek Kitszel 		i++;
248f4e667ebSPrzemek Kitszel 	}
249f4e667ebSPrzemek Kitszel 
250f4e667ebSPrzemek Kitszel out:
251f4e667ebSPrzemek Kitszel 	return ice_hw_ptype_ena(&vf->pf->hw, ptype);
252f4e667ebSPrzemek Kitszel }
253f4e667ebSPrzemek Kitszel 
254f4e667ebSPrzemek Kitszel /**
255f4e667ebSPrzemek Kitszel  * ice_vc_parse_rss_cfg - parses hash fields and headers from
256f4e667ebSPrzemek Kitszel  * a specific virtchnl RSS cfg
257f4e667ebSPrzemek Kitszel  * @hw: pointer to the hardware
258f4e667ebSPrzemek Kitszel  * @rss_cfg: pointer to the virtchnl RSS cfg
259f4e667ebSPrzemek Kitszel  * @hash_cfg: pointer to the HW hash configuration
260f4e667ebSPrzemek Kitszel  *
261f4e667ebSPrzemek Kitszel  * Return true if all the protocol header and hash fields in the RSS cfg could
262f4e667ebSPrzemek Kitszel  * be parsed, else return false
263f4e667ebSPrzemek Kitszel  *
264f4e667ebSPrzemek Kitszel  * This function parses the virtchnl RSS cfg to be the intended
265f4e667ebSPrzemek Kitszel  * hash fields and the intended header for RSS configuration
266f4e667ebSPrzemek Kitszel  */
267f4e667ebSPrzemek Kitszel static bool ice_vc_parse_rss_cfg(struct ice_hw *hw,
268f4e667ebSPrzemek Kitszel 				 struct virtchnl_rss_cfg *rss_cfg,
269f4e667ebSPrzemek Kitszel 				 struct ice_rss_hash_cfg *hash_cfg)
270f4e667ebSPrzemek Kitszel {
271f4e667ebSPrzemek Kitszel 	const struct ice_vc_hash_field_match_type *hf_list;
272f4e667ebSPrzemek Kitszel 	const struct ice_vc_hdr_match_type *hdr_list;
273f4e667ebSPrzemek Kitszel 	int i, hf_list_len, hdr_list_len;
274f4e667ebSPrzemek Kitszel 	u32 *addl_hdrs = &hash_cfg->addl_hdrs;
275f4e667ebSPrzemek Kitszel 	u64 *hash_flds = &hash_cfg->hash_flds;
276f4e667ebSPrzemek Kitszel 
277f4e667ebSPrzemek Kitszel 	/* set outer layer RSS as default */
278f4e667ebSPrzemek Kitszel 	hash_cfg->hdr_type = ICE_RSS_OUTER_HEADERS;
279f4e667ebSPrzemek Kitszel 
280f4e667ebSPrzemek Kitszel 	if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC)
281f4e667ebSPrzemek Kitszel 		hash_cfg->symm = true;
282f4e667ebSPrzemek Kitszel 	else
283f4e667ebSPrzemek Kitszel 		hash_cfg->symm = false;
284f4e667ebSPrzemek Kitszel 
285f4e667ebSPrzemek Kitszel 	hf_list = ice_vc_hash_field_list;
286f4e667ebSPrzemek Kitszel 	hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list);
287f4e667ebSPrzemek Kitszel 	hdr_list = ice_vc_hdr_list;
288f4e667ebSPrzemek Kitszel 	hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list);
289f4e667ebSPrzemek Kitszel 
290f4e667ebSPrzemek Kitszel 	for (i = 0; i < rss_cfg->proto_hdrs.count; i++) {
291f4e667ebSPrzemek Kitszel 		struct virtchnl_proto_hdr *proto_hdr =
292f4e667ebSPrzemek Kitszel 					&rss_cfg->proto_hdrs.proto_hdr[i];
293f4e667ebSPrzemek Kitszel 		bool hdr_found = false;
294f4e667ebSPrzemek Kitszel 		int j;
295f4e667ebSPrzemek Kitszel 
296f4e667ebSPrzemek Kitszel 		/* Find matched ice headers according to virtchnl headers. */
297f4e667ebSPrzemek Kitszel 		for (j = 0; j < hdr_list_len; j++) {
298f4e667ebSPrzemek Kitszel 			struct ice_vc_hdr_match_type hdr_map = hdr_list[j];
299f4e667ebSPrzemek Kitszel 
300f4e667ebSPrzemek Kitszel 			if (proto_hdr->type == hdr_map.vc_hdr) {
301f4e667ebSPrzemek Kitszel 				*addl_hdrs |= hdr_map.ice_hdr;
302f4e667ebSPrzemek Kitszel 				hdr_found = true;
303f4e667ebSPrzemek Kitszel 			}
304f4e667ebSPrzemek Kitszel 		}
305f4e667ebSPrzemek Kitszel 
306f4e667ebSPrzemek Kitszel 		if (!hdr_found)
307f4e667ebSPrzemek Kitszel 			return false;
308f4e667ebSPrzemek Kitszel 
309f4e667ebSPrzemek Kitszel 		/* Find matched ice hash fields according to
310f4e667ebSPrzemek Kitszel 		 * virtchnl hash fields.
311f4e667ebSPrzemek Kitszel 		 */
312f4e667ebSPrzemek Kitszel 		for (j = 0; j < hf_list_len; j++) {
313f4e667ebSPrzemek Kitszel 			struct ice_vc_hash_field_match_type hf_map = hf_list[j];
314f4e667ebSPrzemek Kitszel 
315f4e667ebSPrzemek Kitszel 			if (proto_hdr->type == hf_map.vc_hdr &&
316f4e667ebSPrzemek Kitszel 			    proto_hdr->field_selector == hf_map.vc_hash_field) {
317f4e667ebSPrzemek Kitszel 				*hash_flds |= hf_map.ice_hash_field;
318f4e667ebSPrzemek Kitszel 				break;
319f4e667ebSPrzemek Kitszel 			}
320f4e667ebSPrzemek Kitszel 		}
321f4e667ebSPrzemek Kitszel 	}
322f4e667ebSPrzemek Kitszel 
323f4e667ebSPrzemek Kitszel 	return true;
324f4e667ebSPrzemek Kitszel }
325f4e667ebSPrzemek Kitszel 
326f4e667ebSPrzemek Kitszel /**
327f4e667ebSPrzemek Kitszel  * ice_vf_adv_rss_offload_ena - determine if capabilities support advanced
328f4e667ebSPrzemek Kitszel  * RSS offloads
329f4e667ebSPrzemek Kitszel  * @caps: VF driver negotiated capabilities
330f4e667ebSPrzemek Kitszel  *
331f4e667ebSPrzemek Kitszel  * Return true if VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF capability is set,
332f4e667ebSPrzemek Kitszel  * else return false
333f4e667ebSPrzemek Kitszel  */
334f4e667ebSPrzemek Kitszel static bool ice_vf_adv_rss_offload_ena(u32 caps)
335f4e667ebSPrzemek Kitszel {
336f4e667ebSPrzemek Kitszel 	return !!(caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF);
337f4e667ebSPrzemek Kitszel }
338f4e667ebSPrzemek Kitszel 
339f4e667ebSPrzemek Kitszel /**
340f4e667ebSPrzemek Kitszel  * ice_vc_handle_rss_cfg
341f4e667ebSPrzemek Kitszel  * @vf: pointer to the VF info
342f4e667ebSPrzemek Kitszel  * @msg: pointer to the message buffer
343f4e667ebSPrzemek Kitszel  * @add: add a RSS config if true, otherwise delete a RSS config
344f4e667ebSPrzemek Kitszel  *
345f4e667ebSPrzemek Kitszel  * This function adds/deletes a RSS config
346f4e667ebSPrzemek Kitszel  */
347*e0d2795aSPrzemek Kitszel int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add)
348f4e667ebSPrzemek Kitszel {
349f4e667ebSPrzemek Kitszel 	u32 v_opcode = add ? VIRTCHNL_OP_ADD_RSS_CFG : VIRTCHNL_OP_DEL_RSS_CFG;
350f4e667ebSPrzemek Kitszel 	struct virtchnl_rss_cfg *rss_cfg = (struct virtchnl_rss_cfg *)msg;
351f4e667ebSPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
352f4e667ebSPrzemek Kitszel 	struct device *dev = ice_pf_to_dev(vf->pf);
353f4e667ebSPrzemek Kitszel 	struct ice_hw *hw = &vf->pf->hw;
354f4e667ebSPrzemek Kitszel 	struct ice_vsi *vsi;
355f4e667ebSPrzemek Kitszel 
356f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) {
357f4e667ebSPrzemek Kitszel 		dev_dbg(dev, "VF %d attempting to configure RSS, but RSS is not supported by the PF\n",
358f4e667ebSPrzemek Kitszel 			vf->vf_id);
359f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
360f4e667ebSPrzemek Kitszel 		goto error_param;
361f4e667ebSPrzemek Kitszel 	}
362f4e667ebSPrzemek Kitszel 
363f4e667ebSPrzemek Kitszel 	if (!ice_vf_adv_rss_offload_ena(vf->driver_caps)) {
364f4e667ebSPrzemek Kitszel 		dev_dbg(dev, "VF %d attempting to configure RSS, but Advanced RSS offload is not supported\n",
365f4e667ebSPrzemek Kitszel 			vf->vf_id);
366f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
367f4e667ebSPrzemek Kitszel 		goto error_param;
368f4e667ebSPrzemek Kitszel 	}
369f4e667ebSPrzemek Kitszel 
370f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
371f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
372f4e667ebSPrzemek Kitszel 		goto error_param;
373f4e667ebSPrzemek Kitszel 	}
374f4e667ebSPrzemek Kitszel 
375f4e667ebSPrzemek Kitszel 	if (rss_cfg->proto_hdrs.count > VIRTCHNL_MAX_NUM_PROTO_HDRS ||
376f4e667ebSPrzemek Kitszel 	    rss_cfg->rss_algorithm < VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC ||
377f4e667ebSPrzemek Kitszel 	    rss_cfg->rss_algorithm > VIRTCHNL_RSS_ALG_XOR_SYMMETRIC) {
378f4e667ebSPrzemek Kitszel 		dev_dbg(dev, "VF %d attempting to configure RSS, but RSS configuration is not valid\n",
379f4e667ebSPrzemek Kitszel 			vf->vf_id);
380f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
381f4e667ebSPrzemek Kitszel 		goto error_param;
382f4e667ebSPrzemek Kitszel 	}
383f4e667ebSPrzemek Kitszel 
384f4e667ebSPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
385f4e667ebSPrzemek Kitszel 	if (!vsi) {
386f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
387f4e667ebSPrzemek Kitszel 		goto error_param;
388f4e667ebSPrzemek Kitszel 	}
389f4e667ebSPrzemek Kitszel 
390f4e667ebSPrzemek Kitszel 	if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) {
391f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
392f4e667ebSPrzemek Kitszel 		goto error_param;
393f4e667ebSPrzemek Kitszel 	}
394f4e667ebSPrzemek Kitszel 
395f4e667ebSPrzemek Kitszel 	if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_R_ASYMMETRIC) {
396f4e667ebSPrzemek Kitszel 		struct ice_vsi_ctx *ctx;
397f4e667ebSPrzemek Kitszel 		u8 lut_type, hash_type;
398f4e667ebSPrzemek Kitszel 		int status;
399f4e667ebSPrzemek Kitszel 
400f4e667ebSPrzemek Kitszel 		lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI;
401f4e667ebSPrzemek Kitszel 		hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_HASH_XOR :
402f4e667ebSPrzemek Kitszel 				ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ;
403f4e667ebSPrzemek Kitszel 
404f4e667ebSPrzemek Kitszel 		ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
405f4e667ebSPrzemek Kitszel 		if (!ctx) {
406f4e667ebSPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
407f4e667ebSPrzemek Kitszel 			goto error_param;
408f4e667ebSPrzemek Kitszel 		}
409f4e667ebSPrzemek Kitszel 
410f4e667ebSPrzemek Kitszel 		ctx->info.q_opt_rss =
411f4e667ebSPrzemek Kitszel 			FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_LUT_M, lut_type) |
412f4e667ebSPrzemek Kitszel 			FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_HASH_M, hash_type);
413f4e667ebSPrzemek Kitszel 
414f4e667ebSPrzemek Kitszel 		/* Preserve existing queueing option setting */
415f4e667ebSPrzemek Kitszel 		ctx->info.q_opt_rss |= (vsi->info.q_opt_rss &
416f4e667ebSPrzemek Kitszel 					  ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_M);
417f4e667ebSPrzemek Kitszel 		ctx->info.q_opt_tc = vsi->info.q_opt_tc;
418f4e667ebSPrzemek Kitszel 		ctx->info.q_opt_flags = vsi->info.q_opt_rss;
419f4e667ebSPrzemek Kitszel 
420f4e667ebSPrzemek Kitszel 		ctx->info.valid_sections =
421f4e667ebSPrzemek Kitszel 				cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID);
422f4e667ebSPrzemek Kitszel 
423f4e667ebSPrzemek Kitszel 		status = ice_update_vsi(hw, vsi->idx, ctx, NULL);
424f4e667ebSPrzemek Kitszel 		if (status) {
425f4e667ebSPrzemek Kitszel 			dev_err(dev, "update VSI for RSS failed, err %d aq_err %s\n",
426f4e667ebSPrzemek Kitszel 				status, libie_aq_str(hw->adminq.sq_last_status));
427f4e667ebSPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
428f4e667ebSPrzemek Kitszel 		} else {
429f4e667ebSPrzemek Kitszel 			vsi->info.q_opt_rss = ctx->info.q_opt_rss;
430f4e667ebSPrzemek Kitszel 		}
431f4e667ebSPrzemek Kitszel 
432f4e667ebSPrzemek Kitszel 		kfree(ctx);
433f4e667ebSPrzemek Kitszel 	} else {
434f4e667ebSPrzemek Kitszel 		struct ice_rss_hash_cfg cfg;
435f4e667ebSPrzemek Kitszel 
436f4e667ebSPrzemek Kitszel 		/* Only check for none raw pattern case */
437f4e667ebSPrzemek Kitszel 		if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) {
438f4e667ebSPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
439f4e667ebSPrzemek Kitszel 			goto error_param;
440f4e667ebSPrzemek Kitszel 		}
441f4e667ebSPrzemek Kitszel 		cfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE;
442f4e667ebSPrzemek Kitszel 		cfg.hash_flds = ICE_HASH_INVALID;
443f4e667ebSPrzemek Kitszel 		cfg.hdr_type = ICE_RSS_ANY_HEADERS;
444f4e667ebSPrzemek Kitszel 
445f4e667ebSPrzemek Kitszel 		if (!ice_vc_parse_rss_cfg(hw, rss_cfg, &cfg)) {
446f4e667ebSPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
447f4e667ebSPrzemek Kitszel 			goto error_param;
448f4e667ebSPrzemek Kitszel 		}
449f4e667ebSPrzemek Kitszel 
450f4e667ebSPrzemek Kitszel 		if (add) {
451f4e667ebSPrzemek Kitszel 			if (ice_add_rss_cfg(hw, vsi, &cfg)) {
452f4e667ebSPrzemek Kitszel 				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
453f4e667ebSPrzemek Kitszel 				dev_err(dev, "ice_add_rss_cfg failed for vsi = %d, v_ret = %d\n",
454f4e667ebSPrzemek Kitszel 					vsi->vsi_num, v_ret);
455f4e667ebSPrzemek Kitszel 			}
456f4e667ebSPrzemek Kitszel 		} else {
457f4e667ebSPrzemek Kitszel 			int status;
458f4e667ebSPrzemek Kitszel 
459f4e667ebSPrzemek Kitszel 			status = ice_rem_rss_cfg(hw, vsi->idx, &cfg);
460f4e667ebSPrzemek Kitszel 			/* We just ignore -ENOENT, because if two configurations
461f4e667ebSPrzemek Kitszel 			 * share the same profile remove one of them actually
462f4e667ebSPrzemek Kitszel 			 * removes both, since the profile is deleted.
463f4e667ebSPrzemek Kitszel 			 */
464f4e667ebSPrzemek Kitszel 			if (status && status != -ENOENT) {
465f4e667ebSPrzemek Kitszel 				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
466f4e667ebSPrzemek Kitszel 				dev_err(dev, "ice_rem_rss_cfg failed for VF ID:%d, error:%d\n",
467f4e667ebSPrzemek Kitszel 					vf->vf_id, status);
468f4e667ebSPrzemek Kitszel 			}
469f4e667ebSPrzemek Kitszel 		}
470f4e667ebSPrzemek Kitszel 	}
471f4e667ebSPrzemek Kitszel 
472f4e667ebSPrzemek Kitszel error_param:
473f4e667ebSPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, v_opcode, v_ret, NULL, 0);
474f4e667ebSPrzemek Kitszel }
475f4e667ebSPrzemek Kitszel 
476f4e667ebSPrzemek Kitszel /**
477f4e667ebSPrzemek Kitszel  * ice_vc_config_rss_key
478f4e667ebSPrzemek Kitszel  * @vf: pointer to the VF info
479f4e667ebSPrzemek Kitszel  * @msg: pointer to the msg buffer
480f4e667ebSPrzemek Kitszel  *
481f4e667ebSPrzemek Kitszel  * Configure the VF's RSS key
482f4e667ebSPrzemek Kitszel  */
483*e0d2795aSPrzemek Kitszel int ice_vc_config_rss_key(struct ice_vf *vf, u8 *msg)
484f4e667ebSPrzemek Kitszel {
485f4e667ebSPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
486f4e667ebSPrzemek Kitszel 	struct virtchnl_rss_key *vrk =
487f4e667ebSPrzemek Kitszel 		(struct virtchnl_rss_key *)msg;
488f4e667ebSPrzemek Kitszel 	struct ice_vsi *vsi;
489f4e667ebSPrzemek Kitszel 
490f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
491f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
492f4e667ebSPrzemek Kitszel 		goto error_param;
493f4e667ebSPrzemek Kitszel 	}
494f4e667ebSPrzemek Kitszel 
495f4e667ebSPrzemek Kitszel 	if (!ice_vc_isvalid_vsi_id(vf, vrk->vsi_id)) {
496f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
497f4e667ebSPrzemek Kitszel 		goto error_param;
498f4e667ebSPrzemek Kitszel 	}
499f4e667ebSPrzemek Kitszel 
500f4e667ebSPrzemek Kitszel 	if (vrk->key_len != ICE_VSIQF_HKEY_ARRAY_SIZE) {
501f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
502f4e667ebSPrzemek Kitszel 		goto error_param;
503f4e667ebSPrzemek Kitszel 	}
504f4e667ebSPrzemek Kitszel 
505f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) {
506f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
507f4e667ebSPrzemek Kitszel 		goto error_param;
508f4e667ebSPrzemek Kitszel 	}
509f4e667ebSPrzemek Kitszel 
510f4e667ebSPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
511f4e667ebSPrzemek Kitszel 	if (!vsi) {
512f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
513f4e667ebSPrzemek Kitszel 		goto error_param;
514f4e667ebSPrzemek Kitszel 	}
515f4e667ebSPrzemek Kitszel 
516f4e667ebSPrzemek Kitszel 	if (ice_set_rss_key(vsi, vrk->key))
517f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
518f4e667ebSPrzemek Kitszel error_param:
519f4e667ebSPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_KEY, v_ret,
520f4e667ebSPrzemek Kitszel 				     NULL, 0);
521f4e667ebSPrzemek Kitszel }
522f4e667ebSPrzemek Kitszel 
523f4e667ebSPrzemek Kitszel /**
524f4e667ebSPrzemek Kitszel  * ice_vc_config_rss_lut
525f4e667ebSPrzemek Kitszel  * @vf: pointer to the VF info
526f4e667ebSPrzemek Kitszel  * @msg: pointer to the msg buffer
527f4e667ebSPrzemek Kitszel  *
528f4e667ebSPrzemek Kitszel  * Configure the VF's RSS LUT
529f4e667ebSPrzemek Kitszel  */
530*e0d2795aSPrzemek Kitszel int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg)
531f4e667ebSPrzemek Kitszel {
532f4e667ebSPrzemek Kitszel 	struct virtchnl_rss_lut *vrl = (struct virtchnl_rss_lut *)msg;
533f4e667ebSPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
534f4e667ebSPrzemek Kitszel 	struct ice_vsi *vsi;
535f4e667ebSPrzemek Kitszel 
536f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
537f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
538f4e667ebSPrzemek Kitszel 		goto error_param;
539f4e667ebSPrzemek Kitszel 	}
540f4e667ebSPrzemek Kitszel 
541f4e667ebSPrzemek Kitszel 	if (!ice_vc_isvalid_vsi_id(vf, vrl->vsi_id)) {
542f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
543f4e667ebSPrzemek Kitszel 		goto error_param;
544f4e667ebSPrzemek Kitszel 	}
545f4e667ebSPrzemek Kitszel 
546f4e667ebSPrzemek Kitszel 	if (vrl->lut_entries != ICE_LUT_VSI_SIZE) {
547f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
548f4e667ebSPrzemek Kitszel 		goto error_param;
549f4e667ebSPrzemek Kitszel 	}
550f4e667ebSPrzemek Kitszel 
551f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) {
552f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
553f4e667ebSPrzemek Kitszel 		goto error_param;
554f4e667ebSPrzemek Kitszel 	}
555f4e667ebSPrzemek Kitszel 
556f4e667ebSPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
557f4e667ebSPrzemek Kitszel 	if (!vsi) {
558f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
559f4e667ebSPrzemek Kitszel 		goto error_param;
560f4e667ebSPrzemek Kitszel 	}
561f4e667ebSPrzemek Kitszel 
562f4e667ebSPrzemek Kitszel 	if (ice_set_rss_lut(vsi, vrl->lut, ICE_LUT_VSI_SIZE))
563f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
564f4e667ebSPrzemek Kitszel error_param:
565f4e667ebSPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_LUT, v_ret,
566f4e667ebSPrzemek Kitszel 				     NULL, 0);
567f4e667ebSPrzemek Kitszel }
568f4e667ebSPrzemek Kitszel 
569f4e667ebSPrzemek Kitszel /**
570f4e667ebSPrzemek Kitszel  * ice_vc_config_rss_hfunc
571f4e667ebSPrzemek Kitszel  * @vf: pointer to the VF info
572f4e667ebSPrzemek Kitszel  * @msg: pointer to the msg buffer
573f4e667ebSPrzemek Kitszel  *
574f4e667ebSPrzemek Kitszel  * Configure the VF's RSS Hash function
575f4e667ebSPrzemek Kitszel  */
576*e0d2795aSPrzemek Kitszel int ice_vc_config_rss_hfunc(struct ice_vf *vf, u8 *msg)
577f4e667ebSPrzemek Kitszel {
578f4e667ebSPrzemek Kitszel 	struct virtchnl_rss_hfunc *vrh = (struct virtchnl_rss_hfunc *)msg;
579f4e667ebSPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
580f4e667ebSPrzemek Kitszel 	u8 hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ;
581f4e667ebSPrzemek Kitszel 	struct ice_vsi *vsi;
582f4e667ebSPrzemek Kitszel 
583f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
584f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
585f4e667ebSPrzemek Kitszel 		goto error_param;
586f4e667ebSPrzemek Kitszel 	}
587f4e667ebSPrzemek Kitszel 
588f4e667ebSPrzemek Kitszel 	if (!ice_vc_isvalid_vsi_id(vf, vrh->vsi_id)) {
589f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
590f4e667ebSPrzemek Kitszel 		goto error_param;
591f4e667ebSPrzemek Kitszel 	}
592f4e667ebSPrzemek Kitszel 
593f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) {
594f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
595f4e667ebSPrzemek Kitszel 		goto error_param;
596f4e667ebSPrzemek Kitszel 	}
597f4e667ebSPrzemek Kitszel 
598f4e667ebSPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
599f4e667ebSPrzemek Kitszel 	if (!vsi) {
600f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
601f4e667ebSPrzemek Kitszel 		goto error_param;
602f4e667ebSPrzemek Kitszel 	}
603f4e667ebSPrzemek Kitszel 
604f4e667ebSPrzemek Kitszel 	if (vrh->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC)
605f4e667ebSPrzemek Kitszel 		hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ;
606f4e667ebSPrzemek Kitszel 
607f4e667ebSPrzemek Kitszel 	if (ice_set_rss_hfunc(vsi, hfunc))
608f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
609f4e667ebSPrzemek Kitszel error_param:
610f4e667ebSPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_HFUNC, v_ret,
611f4e667ebSPrzemek Kitszel 				     NULL, 0);
612f4e667ebSPrzemek Kitszel }
613f4e667ebSPrzemek Kitszel 
614f4e667ebSPrzemek Kitszel /**
615f4e667ebSPrzemek Kitszel  * ice_vc_get_rss_hashcfg - return the RSS Hash configuration
616f4e667ebSPrzemek Kitszel  * @vf: pointer to the VF info
617f4e667ebSPrzemek Kitszel  */
618*e0d2795aSPrzemek Kitszel int ice_vc_get_rss_hashcfg(struct ice_vf *vf)
619f4e667ebSPrzemek Kitszel {
620f4e667ebSPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
621f4e667ebSPrzemek Kitszel 	struct virtchnl_rss_hashcfg *vrh = NULL;
622f4e667ebSPrzemek Kitszel 	int len = 0, ret;
623f4e667ebSPrzemek Kitszel 
624f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
625f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
626f4e667ebSPrzemek Kitszel 		goto err;
627f4e667ebSPrzemek Kitszel 	}
628f4e667ebSPrzemek Kitszel 
629f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) {
630f4e667ebSPrzemek Kitszel 		dev_err(ice_pf_to_dev(vf->pf), "RSS not supported by PF\n");
631f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
632f4e667ebSPrzemek Kitszel 		goto err;
633f4e667ebSPrzemek Kitszel 	}
634f4e667ebSPrzemek Kitszel 
635f4e667ebSPrzemek Kitszel 	len = sizeof(struct virtchnl_rss_hashcfg);
636f4e667ebSPrzemek Kitszel 	vrh = kzalloc(len, GFP_KERNEL);
637f4e667ebSPrzemek Kitszel 	if (!vrh) {
638f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
639f4e667ebSPrzemek Kitszel 		len = 0;
640f4e667ebSPrzemek Kitszel 		goto err;
641f4e667ebSPrzemek Kitszel 	}
642f4e667ebSPrzemek Kitszel 
643f4e667ebSPrzemek Kitszel 	vrh->hashcfg = ICE_DEFAULT_RSS_HASHCFG;
644f4e667ebSPrzemek Kitszel err:
645f4e667ebSPrzemek Kitszel 	/* send the response back to the VF */
646f4e667ebSPrzemek Kitszel 	ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_RSS_HASHCFG_CAPS, v_ret,
647f4e667ebSPrzemek Kitszel 				    (u8 *)vrh, len);
648f4e667ebSPrzemek Kitszel 	kfree(vrh);
649f4e667ebSPrzemek Kitszel 	return ret;
650f4e667ebSPrzemek Kitszel }
651f4e667ebSPrzemek Kitszel 
652f4e667ebSPrzemek Kitszel /**
653f4e667ebSPrzemek Kitszel  * ice_vc_set_rss_hashcfg - set RSS Hash configuration bits for the VF
654f4e667ebSPrzemek Kitszel  * @vf: pointer to the VF info
655f4e667ebSPrzemek Kitszel  * @msg: pointer to the msg buffer
656f4e667ebSPrzemek Kitszel  */
657*e0d2795aSPrzemek Kitszel int ice_vc_set_rss_hashcfg(struct ice_vf *vf, u8 *msg)
658f4e667ebSPrzemek Kitszel {
659f4e667ebSPrzemek Kitszel 	struct virtchnl_rss_hashcfg *vrh = (struct virtchnl_rss_hashcfg *)msg;
660f4e667ebSPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
661f4e667ebSPrzemek Kitszel 	struct ice_pf *pf = vf->pf;
662f4e667ebSPrzemek Kitszel 	struct ice_vsi *vsi;
663f4e667ebSPrzemek Kitszel 	struct device *dev;
664f4e667ebSPrzemek Kitszel 	int status;
665f4e667ebSPrzemek Kitszel 
666f4e667ebSPrzemek Kitszel 	dev = ice_pf_to_dev(pf);
667f4e667ebSPrzemek Kitszel 
668f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
669f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
670f4e667ebSPrzemek Kitszel 		goto err;
671f4e667ebSPrzemek Kitszel 	}
672f4e667ebSPrzemek Kitszel 
673f4e667ebSPrzemek Kitszel 	if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
674f4e667ebSPrzemek Kitszel 		dev_err(dev, "RSS not supported by PF\n");
675f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
676f4e667ebSPrzemek Kitszel 		goto err;
677f4e667ebSPrzemek Kitszel 	}
678f4e667ebSPrzemek Kitszel 
679f4e667ebSPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
680f4e667ebSPrzemek Kitszel 	if (!vsi) {
681f4e667ebSPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
682f4e667ebSPrzemek Kitszel 		goto err;
683f4e667ebSPrzemek Kitszel 	}
684f4e667ebSPrzemek Kitszel 
685f4e667ebSPrzemek Kitszel 	/* clear all previously programmed RSS configuration to allow VF drivers
686f4e667ebSPrzemek Kitszel 	 * the ability to customize the RSS configuration and/or completely
687f4e667ebSPrzemek Kitszel 	 * disable RSS
688f4e667ebSPrzemek Kitszel 	 */
689f4e667ebSPrzemek Kitszel 	status = ice_rem_vsi_rss_cfg(&pf->hw, vsi->idx);
690f4e667ebSPrzemek Kitszel 	if (status && !vrh->hashcfg) {
691f4e667ebSPrzemek Kitszel 		/* only report failure to clear the current RSS configuration if
692f4e667ebSPrzemek Kitszel 		 * that was clearly the VF's intention (i.e. vrh->hashcfg = 0)
693f4e667ebSPrzemek Kitszel 		 */
694f4e667ebSPrzemek Kitszel 		v_ret = ice_err_to_virt_err(status);
695f4e667ebSPrzemek Kitszel 		goto err;
696f4e667ebSPrzemek Kitszel 	} else if (status) {
697f4e667ebSPrzemek Kitszel 		/* allow the VF to update the RSS configuration even on failure
698f4e667ebSPrzemek Kitszel 		 * to clear the current RSS confguration in an attempt to keep
699f4e667ebSPrzemek Kitszel 		 * RSS in a working state
700f4e667ebSPrzemek Kitszel 		 */
701f4e667ebSPrzemek Kitszel 		dev_warn(dev, "Failed to clear the RSS configuration for VF %u\n",
702f4e667ebSPrzemek Kitszel 			 vf->vf_id);
703f4e667ebSPrzemek Kitszel 	}
704f4e667ebSPrzemek Kitszel 
705f4e667ebSPrzemek Kitszel 	if (vrh->hashcfg) {
706f4e667ebSPrzemek Kitszel 		status = ice_add_avf_rss_cfg(&pf->hw, vsi, vrh->hashcfg);
707f4e667ebSPrzemek Kitszel 		v_ret = ice_err_to_virt_err(status);
708f4e667ebSPrzemek Kitszel 	}
709f4e667ebSPrzemek Kitszel 
710f4e667ebSPrzemek Kitszel 	/* save the requested VF configuration */
711f4e667ebSPrzemek Kitszel 	if (!v_ret)
712f4e667ebSPrzemek Kitszel 		vf->rss_hashcfg = vrh->hashcfg;
713f4e667ebSPrzemek Kitszel 
714f4e667ebSPrzemek Kitszel 	/* send the response to the VF */
715f4e667ebSPrzemek Kitszel err:
716f4e667ebSPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_SET_RSS_HASHCFG, v_ret,
717f4e667ebSPrzemek Kitszel 				     NULL, 0);
718f4e667ebSPrzemek Kitszel }
719f4e667ebSPrzemek Kitszel 
720