File Index
Files and directories
Sign in
FILE

iavf_adv_rss.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2021, Intel Corporation. */
  3
  4/* advanced RSS configuration ethtool support for iavf */
  5
  6#include "iavf.h"
  7
  8/**
  9 * iavf_fill_adv_rss_ip4_hdr - fill the IPv4 RSS protocol header
 10 * @hdr: the virtchnl message protocol header data structure
 11 * @hash_flds: the RSS configuration protocol hash fields
 12 */
 13static void
 14iavf_fill_adv_rss_ip4_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
 15{
 16	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV4);
 17
 18	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_SA)
 19		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, SRC);
 20
 21	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_DA)
 22		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, DST);
 23}
 24
 25/**
 26 * iavf_fill_adv_rss_ip6_hdr - fill the IPv6 RSS protocol header
 27 * @hdr: the virtchnl message protocol header data structure
 28 * @hash_flds: the RSS configuration protocol hash fields
 29 */
 30static void
 31iavf_fill_adv_rss_ip6_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
 32{
 33	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV6);
 34
 35	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_SA)
 36		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, SRC);
 37
 38	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_DA)
 39		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, DST);
 40}
 41
 42/**
 43 * iavf_fill_adv_rss_tcp_hdr - fill the TCP RSS protocol header
 44 * @hdr: the virtchnl message protocol header data structure
 45 * @hash_flds: the RSS configuration protocol hash fields
 46 */
 47static void
 48iavf_fill_adv_rss_tcp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
 49{
 50	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, TCP);
 51
 52	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT)
 53		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, SRC_PORT);
 54
 55	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT)
 56		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, DST_PORT);
 57}
 58
 59/**
 60 * iavf_fill_adv_rss_udp_hdr - fill the UDP RSS protocol header
 61 * @hdr: the virtchnl message protocol header data structure
 62 * @hash_flds: the RSS configuration protocol hash fields
 63 */
 64static void
 65iavf_fill_adv_rss_udp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
 66{
 67	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, UDP);
 68
 69	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT)
 70		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, SRC_PORT);
 71
 72	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT)
 73		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, DST_PORT);
 74}
 75
 76/**
 77 * iavf_fill_adv_rss_sctp_hdr - fill the SCTP RSS protocol header
 78 * @hdr: the virtchnl message protocol header data structure
 79 * @hash_flds: the RSS configuration protocol hash fields
 80 */
 81static void
 82iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
 83{
 84	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, SCTP);
 85
 86	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT)
 87		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, SRC_PORT);
 88
 89	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT)
 90		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, DST_PORT);
 91}
 92
 93/**
 94 * iavf_fill_adv_rss_gtp_hdr - Fill GTP-related RSS protocol headers
 95 * @proto_hdrs: pointer to the virtchnl protocol headers structure to populate
 96 * @packet_hdrs: bitmask of packet header types to configure
 97 * @hash_flds: RSS hash field configuration
 98 *
 99 * This function populates the virtchnl protocol header structure with
100 * appropriate GTP-related header types based on the specified packet_hdrs.
101 * It supports GTPC, GTPU with extension headers, and uplink/downlink PDU
102 * types. For certain GTPU types, it also appends an IPv4 header to enable
103 * hashing on the destination IP address.
104 *
105 * Return: 0 on success or -EOPNOTSUPP if the packet_hdrs value is unsupported.
106 */
107static int
108iavf_fill_adv_rss_gtp_hdr(struct virtchnl_proto_hdrs *proto_hdrs,
109			  u32 packet_hdrs, u64 hash_flds)
110{
111	struct virtchnl_proto_hdr *hdr;
112
113	hdr = &proto_hdrs->proto_hdr[proto_hdrs->count - 1];
114
115	switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP) {
116	case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID:
117	case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC:
118		VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPC);
119		break;
120	case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH:
121		VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH);
122		break;
123	case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP:
124		VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_UP);
125		hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
126		iavf_fill_adv_rss_ip4_hdr(hdr, IAVF_ADV_RSS_HASH_FLD_IPV4_DA);
127		break;
128	case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN:
129		VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_DWN);
130		fallthrough;
131	case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP:
132		hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
133		iavf_fill_adv_rss_ip4_hdr(hdr, IAVF_ADV_RSS_HASH_FLD_IPV4_DA);
134		break;
135	default:
136		return -EOPNOTSUPP;
137	}
138
139	return 0;
140}
141
142/**
143 * iavf_fill_adv_rss_cfg_msg - fill the RSS configuration into virtchnl message
144 * @rss_cfg: the virtchnl message to be filled with RSS configuration setting
145 * @packet_hdrs: the RSS configuration protocol header types
146 * @hash_flds: the RSS configuration protocol hash fields
147 * @symm: if true, symmetric hash is required
148 *
149 * Returns 0 if the RSS configuration virtchnl message is filled successfully
150 */
151int
152iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
153			  u32 packet_hdrs, u64 hash_flds, bool symm)
154{
155	const u32 packet_l3_hdrs = packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3;
156	const u32 packet_l4_hdrs = packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4;
157	struct virtchnl_proto_hdrs *proto_hdrs = &rss_cfg->proto_hdrs;
158	struct virtchnl_proto_hdr *hdr;
159
160	if (symm)
161		rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC;
162	else
163		rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
164
165	proto_hdrs->tunnel_level = 0;	/* always outer layer */
166
167	if (packet_l3_hdrs) {
168		hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
169		switch (packet_l3_hdrs) {
170		case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4:
171			iavf_fill_adv_rss_ip4_hdr(hdr, hash_flds);
172			break;
173		case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6:
174			iavf_fill_adv_rss_ip6_hdr(hdr, hash_flds);
175			break;
176		default:
177			return -EINVAL;
178		}
179	}
180
181	if (packet_l4_hdrs) {
182		hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
183		switch (packet_l4_hdrs) {
184		case IAVF_ADV_RSS_FLOW_SEG_HDR_TCP:
185			iavf_fill_adv_rss_tcp_hdr(hdr, hash_flds);
186			break;
187		case IAVF_ADV_RSS_FLOW_SEG_HDR_UDP:
188			iavf_fill_adv_rss_udp_hdr(hdr, hash_flds);
189			break;
190		case IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP:
191			iavf_fill_adv_rss_sctp_hdr(hdr, hash_flds);
192			break;
193		default:
194			return -EINVAL;
195		}
196	}
197
198	if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP) {
199		hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
200		if (iavf_fill_adv_rss_gtp_hdr(proto_hdrs, packet_hdrs, hash_flds))
201			return -EINVAL;
202	}
203
204	return 0;
205}
206
207/**
208 * iavf_find_adv_rss_cfg_by_hdrs - find RSS configuration with header type
209 * @adapter: pointer to the VF adapter structure
210 * @packet_hdrs: protocol header type to find.
211 *
212 * Returns pointer to advance RSS configuration if found or null
213 */
214struct iavf_adv_rss *
215iavf_find_adv_rss_cfg_by_hdrs(struct iavf_adapter *adapter, u32 packet_hdrs)
216{
217	struct iavf_adv_rss *rss;
218
219	list_for_each_entry(rss, &adapter->adv_rss_list_head, list)
220		if (rss->packet_hdrs == packet_hdrs)
221			return rss;
222
223	return NULL;
224}
225
226/**
227 * iavf_print_adv_rss_cfg
228 * @adapter: pointer to the VF adapter structure
229 * @rss: pointer to the advance RSS configuration to print
230 * @action: the string description about how to handle the RSS
231 * @result: the string description about the virtchnl result
232 *
233 * Print the advance RSS configuration
234 **/
235void
236iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss,
237		       const char *action, const char *result)
238{
239	u32 packet_hdrs = rss->packet_hdrs;
240	u64 hash_flds = rss->hash_flds;
241	static char hash_opt[300];
242	const char *proto;
243
244	if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_TCP)
245		proto = "TCP";
246	else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_UDP)
247		proto = "UDP";
248	else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP)
249		proto = "SCTP";
250	else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP)
251		proto = "GTP";
252	else
253		return;
254
255	memset(hash_opt, 0, sizeof(hash_opt));
256
257	strcat(hash_opt, proto);
258	if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4)
259		strcat(hash_opt, "v4 ");
260	else
261		strcat(hash_opt, "v6 ");
262
263	if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_SA |
264			 IAVF_ADV_RSS_HASH_FLD_IPV6_SA))
265		strcat(hash_opt, "IP SA,");
266	if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_DA |
267			 IAVF_ADV_RSS_HASH_FLD_IPV6_DA))
268		strcat(hash_opt, "IP DA,");
269	if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT |
270			 IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT |
271			 IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT))
272		strcat(hash_opt, "src port,");
273	if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT |
274			 IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT |
275			 IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT))
276		strcat(hash_opt, "dst port,");
277	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPC_TEID)
278		strcat(hash_opt, "gtp-c,");
279	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_IP_TEID)
280		strcat(hash_opt, "gtp-u ip,");
281	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_EH_TEID)
282		strcat(hash_opt, "gtp-u ext,");
283	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_UP_TEID)
284		strcat(hash_opt, "gtp-u ul,");
285	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_DWN_TEID)
286		strcat(hash_opt, "gtp-u dl,");
287
288	if (!action)
289		action = "";
290
291	if (!result)
292		result = "";
293
294	dev_info(&adapter->pdev->dev, "%s %s %s\n", action, hash_opt, result);
295}
~/ Read-only file preview.