xref: /linux/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c (revision 06d07429858317ded2db7986113a9e0129cd599b)
15ab91e05SHaiyue Wang // SPDX-License-Identifier: GPL-2.0
25ab91e05SHaiyue Wang /* Copyright (c) 2021, Intel Corporation. */
35ab91e05SHaiyue Wang 
45ab91e05SHaiyue Wang /* advanced RSS configuration ethtool support for iavf */
55ab91e05SHaiyue Wang 
65ab91e05SHaiyue Wang #include "iavf.h"
75ab91e05SHaiyue Wang 
85ab91e05SHaiyue Wang /**
95ab91e05SHaiyue Wang  * iavf_fill_adv_rss_ip4_hdr - fill the IPv4 RSS protocol header
105ab91e05SHaiyue Wang  * @hdr: the virtchnl message protocol header data structure
115ab91e05SHaiyue Wang  * @hash_flds: the RSS configuration protocol hash fields
125ab91e05SHaiyue Wang  */
135ab91e05SHaiyue Wang static void
iavf_fill_adv_rss_ip4_hdr(struct virtchnl_proto_hdr * hdr,u64 hash_flds)145ab91e05SHaiyue Wang iavf_fill_adv_rss_ip4_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
155ab91e05SHaiyue Wang {
165ab91e05SHaiyue Wang 	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV4);
175ab91e05SHaiyue Wang 
185ab91e05SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_SA)
195ab91e05SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, SRC);
205ab91e05SHaiyue Wang 
215ab91e05SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_DA)
225ab91e05SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, DST);
235ab91e05SHaiyue Wang }
245ab91e05SHaiyue Wang 
255ab91e05SHaiyue Wang /**
265ab91e05SHaiyue Wang  * iavf_fill_adv_rss_ip6_hdr - fill the IPv6 RSS protocol header
275ab91e05SHaiyue Wang  * @hdr: the virtchnl message protocol header data structure
285ab91e05SHaiyue Wang  * @hash_flds: the RSS configuration protocol hash fields
295ab91e05SHaiyue Wang  */
305ab91e05SHaiyue Wang static void
iavf_fill_adv_rss_ip6_hdr(struct virtchnl_proto_hdr * hdr,u64 hash_flds)315ab91e05SHaiyue Wang iavf_fill_adv_rss_ip6_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
325ab91e05SHaiyue Wang {
335ab91e05SHaiyue Wang 	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV6);
345ab91e05SHaiyue Wang 
355ab91e05SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_SA)
365ab91e05SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, SRC);
375ab91e05SHaiyue Wang 
385ab91e05SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_DA)
395ab91e05SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, DST);
405ab91e05SHaiyue Wang }
415ab91e05SHaiyue Wang 
425ab91e05SHaiyue Wang /**
435ab91e05SHaiyue Wang  * iavf_fill_adv_rss_tcp_hdr - fill the TCP RSS protocol header
445ab91e05SHaiyue Wang  * @hdr: the virtchnl message protocol header data structure
455ab91e05SHaiyue Wang  * @hash_flds: the RSS configuration protocol hash fields
465ab91e05SHaiyue Wang  */
475ab91e05SHaiyue Wang static void
iavf_fill_adv_rss_tcp_hdr(struct virtchnl_proto_hdr * hdr,u64 hash_flds)485ab91e05SHaiyue Wang iavf_fill_adv_rss_tcp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
495ab91e05SHaiyue Wang {
505ab91e05SHaiyue Wang 	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, TCP);
515ab91e05SHaiyue Wang 
525ab91e05SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT)
535ab91e05SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, SRC_PORT);
545ab91e05SHaiyue Wang 
555ab91e05SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT)
565ab91e05SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, DST_PORT);
575ab91e05SHaiyue Wang }
585ab91e05SHaiyue Wang 
595ab91e05SHaiyue Wang /**
607b8f3f95SHaiyue Wang  * iavf_fill_adv_rss_udp_hdr - fill the UDP RSS protocol header
617b8f3f95SHaiyue Wang  * @hdr: the virtchnl message protocol header data structure
627b8f3f95SHaiyue Wang  * @hash_flds: the RSS configuration protocol hash fields
637b8f3f95SHaiyue Wang  */
647b8f3f95SHaiyue Wang static void
iavf_fill_adv_rss_udp_hdr(struct virtchnl_proto_hdr * hdr,u64 hash_flds)657b8f3f95SHaiyue Wang iavf_fill_adv_rss_udp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
667b8f3f95SHaiyue Wang {
677b8f3f95SHaiyue Wang 	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, UDP);
687b8f3f95SHaiyue Wang 
697b8f3f95SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT)
707b8f3f95SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, SRC_PORT);
717b8f3f95SHaiyue Wang 
727b8f3f95SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT)
737b8f3f95SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, DST_PORT);
747b8f3f95SHaiyue Wang }
757b8f3f95SHaiyue Wang 
767b8f3f95SHaiyue Wang /**
77e41985f0SHaiyue Wang  * iavf_fill_adv_rss_sctp_hdr - fill the SCTP RSS protocol header
78e41985f0SHaiyue Wang  * @hdr: the virtchnl message protocol header data structure
79e41985f0SHaiyue Wang  * @hash_flds: the RSS configuration protocol hash fields
80e41985f0SHaiyue Wang  */
81e41985f0SHaiyue Wang static void
iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr * hdr,u64 hash_flds)82e41985f0SHaiyue Wang iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
83e41985f0SHaiyue Wang {
84e41985f0SHaiyue Wang 	VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, SCTP);
85e41985f0SHaiyue Wang 
86e41985f0SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT)
87e41985f0SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, SRC_PORT);
88e41985f0SHaiyue Wang 
89e41985f0SHaiyue Wang 	if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT)
90e41985f0SHaiyue Wang 		VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, DST_PORT);
91e41985f0SHaiyue Wang }
92e41985f0SHaiyue Wang 
93e41985f0SHaiyue Wang /**
945ab91e05SHaiyue Wang  * iavf_fill_adv_rss_cfg_msg - fill the RSS configuration into virtchnl message
955ab91e05SHaiyue Wang  * @rss_cfg: the virtchnl message to be filled with RSS configuration setting
965ab91e05SHaiyue Wang  * @packet_hdrs: the RSS configuration protocol header types
975ab91e05SHaiyue Wang  * @hash_flds: the RSS configuration protocol hash fields
98*4a3de3fbSAhmed Zaki  * @symm: if true, symmetric hash is required
995ab91e05SHaiyue Wang  *
1005ab91e05SHaiyue Wang  * Returns 0 if the RSS configuration virtchnl message is filled successfully
1015ab91e05SHaiyue Wang  */
1025ab91e05SHaiyue Wang int
iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg * rss_cfg,u32 packet_hdrs,u64 hash_flds,bool symm)1035ab91e05SHaiyue Wang iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
104*4a3de3fbSAhmed Zaki 			  u32 packet_hdrs, u64 hash_flds, bool symm)
1055ab91e05SHaiyue Wang {
1065ab91e05SHaiyue Wang 	struct virtchnl_proto_hdrs *proto_hdrs = &rss_cfg->proto_hdrs;
1075ab91e05SHaiyue Wang 	struct virtchnl_proto_hdr *hdr;
1085ab91e05SHaiyue Wang 
109*4a3de3fbSAhmed Zaki 	if (symm)
110*4a3de3fbSAhmed Zaki 		rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC;
111*4a3de3fbSAhmed Zaki 	else
1125ab91e05SHaiyue Wang 		rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
1135ab91e05SHaiyue Wang 
1145ab91e05SHaiyue Wang 	proto_hdrs->tunnel_level = 0;	/* always outer layer */
1155ab91e05SHaiyue Wang 
1165ab91e05SHaiyue Wang 	hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
1175ab91e05SHaiyue Wang 	switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3) {
1185ab91e05SHaiyue Wang 	case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4:
1195ab91e05SHaiyue Wang 		iavf_fill_adv_rss_ip4_hdr(hdr, hash_flds);
1205ab91e05SHaiyue Wang 		break;
1215ab91e05SHaiyue Wang 	case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6:
1225ab91e05SHaiyue Wang 		iavf_fill_adv_rss_ip6_hdr(hdr, hash_flds);
1235ab91e05SHaiyue Wang 		break;
1245ab91e05SHaiyue Wang 	default:
1255ab91e05SHaiyue Wang 		return -EINVAL;
1265ab91e05SHaiyue Wang 	}
1275ab91e05SHaiyue Wang 
1285ab91e05SHaiyue Wang 	hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
1295ab91e05SHaiyue Wang 	switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4) {
1305ab91e05SHaiyue Wang 	case IAVF_ADV_RSS_FLOW_SEG_HDR_TCP:
1315ab91e05SHaiyue Wang 		iavf_fill_adv_rss_tcp_hdr(hdr, hash_flds);
1325ab91e05SHaiyue Wang 		break;
1337b8f3f95SHaiyue Wang 	case IAVF_ADV_RSS_FLOW_SEG_HDR_UDP:
1347b8f3f95SHaiyue Wang 		iavf_fill_adv_rss_udp_hdr(hdr, hash_flds);
1357b8f3f95SHaiyue Wang 		break;
136e41985f0SHaiyue Wang 	case IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP:
137e41985f0SHaiyue Wang 		iavf_fill_adv_rss_sctp_hdr(hdr, hash_flds);
138e41985f0SHaiyue Wang 		break;
1395ab91e05SHaiyue Wang 	default:
1405ab91e05SHaiyue Wang 		return -EINVAL;
1415ab91e05SHaiyue Wang 	}
1425ab91e05SHaiyue Wang 
1435ab91e05SHaiyue Wang 	return 0;
1445ab91e05SHaiyue Wang }
1455ab91e05SHaiyue Wang 
1465ab91e05SHaiyue Wang /**
1475ab91e05SHaiyue Wang  * iavf_find_adv_rss_cfg_by_hdrs - find RSS configuration with header type
1485ab91e05SHaiyue Wang  * @adapter: pointer to the VF adapter structure
1495ab91e05SHaiyue Wang  * @packet_hdrs: protocol header type to find.
1505ab91e05SHaiyue Wang  *
1515ab91e05SHaiyue Wang  * Returns pointer to advance RSS configuration if found or null
1525ab91e05SHaiyue Wang  */
1535ab91e05SHaiyue Wang struct iavf_adv_rss *
iavf_find_adv_rss_cfg_by_hdrs(struct iavf_adapter * adapter,u32 packet_hdrs)1545ab91e05SHaiyue Wang iavf_find_adv_rss_cfg_by_hdrs(struct iavf_adapter *adapter, u32 packet_hdrs)
1555ab91e05SHaiyue Wang {
1565ab91e05SHaiyue Wang 	struct iavf_adv_rss *rss;
1575ab91e05SHaiyue Wang 
1585ab91e05SHaiyue Wang 	list_for_each_entry(rss, &adapter->adv_rss_list_head, list)
1595ab91e05SHaiyue Wang 		if (rss->packet_hdrs == packet_hdrs)
1605ab91e05SHaiyue Wang 			return rss;
1615ab91e05SHaiyue Wang 
1625ab91e05SHaiyue Wang 	return NULL;
1635ab91e05SHaiyue Wang }
1645ab91e05SHaiyue Wang 
1655ab91e05SHaiyue Wang /**
1665ab91e05SHaiyue Wang  * iavf_print_adv_rss_cfg
1675ab91e05SHaiyue Wang  * @adapter: pointer to the VF adapter structure
1685ab91e05SHaiyue Wang  * @rss: pointer to the advance RSS configuration to print
1695ab91e05SHaiyue Wang  * @action: the string description about how to handle the RSS
1705ab91e05SHaiyue Wang  * @result: the string description about the virtchnl result
1715ab91e05SHaiyue Wang  *
1725ab91e05SHaiyue Wang  * Print the advance RSS configuration
1735ab91e05SHaiyue Wang  **/
1745ab91e05SHaiyue Wang void
iavf_print_adv_rss_cfg(struct iavf_adapter * adapter,struct iavf_adv_rss * rss,const char * action,const char * result)1755ab91e05SHaiyue Wang iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss,
1765ab91e05SHaiyue Wang 		       const char *action, const char *result)
1775ab91e05SHaiyue Wang {
1785ab91e05SHaiyue Wang 	u32 packet_hdrs = rss->packet_hdrs;
1795ab91e05SHaiyue Wang 	u64 hash_flds = rss->hash_flds;
1805ab91e05SHaiyue Wang 	static char hash_opt[300];
1815ab91e05SHaiyue Wang 	const char *proto;
1825ab91e05SHaiyue Wang 
1835ab91e05SHaiyue Wang 	if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_TCP)
1845ab91e05SHaiyue Wang 		proto = "TCP";
1857b8f3f95SHaiyue Wang 	else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_UDP)
1867b8f3f95SHaiyue Wang 		proto = "UDP";
187e41985f0SHaiyue Wang 	else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP)
188e41985f0SHaiyue Wang 		proto = "SCTP";
1895ab91e05SHaiyue Wang 	else
1905ab91e05SHaiyue Wang 		return;
1915ab91e05SHaiyue Wang 
1925ab91e05SHaiyue Wang 	memset(hash_opt, 0, sizeof(hash_opt));
1935ab91e05SHaiyue Wang 
1945ab91e05SHaiyue Wang 	strcat(hash_opt, proto);
1955ab91e05SHaiyue Wang 	if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4)
1965ab91e05SHaiyue Wang 		strcat(hash_opt, "v4 ");
1975ab91e05SHaiyue Wang 	else
1985ab91e05SHaiyue Wang 		strcat(hash_opt, "v6 ");
1995ab91e05SHaiyue Wang 
2005ab91e05SHaiyue Wang 	if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_SA |
2015ab91e05SHaiyue Wang 			 IAVF_ADV_RSS_HASH_FLD_IPV6_SA))
2025ab91e05SHaiyue Wang 		strcat(hash_opt, "IP SA,");
2035ab91e05SHaiyue Wang 	if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_DA |
2045ab91e05SHaiyue Wang 			 IAVF_ADV_RSS_HASH_FLD_IPV6_DA))
2055ab91e05SHaiyue Wang 		strcat(hash_opt, "IP DA,");
2067b8f3f95SHaiyue Wang 	if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT |
207e41985f0SHaiyue Wang 			 IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT |
208e41985f0SHaiyue Wang 			 IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT))
2095ab91e05SHaiyue Wang 		strcat(hash_opt, "src port,");
2107b8f3f95SHaiyue Wang 	if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT |
211e41985f0SHaiyue Wang 			 IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT |
212e41985f0SHaiyue Wang 			 IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT))
2135ab91e05SHaiyue Wang 		strcat(hash_opt, "dst port,");
2145ab91e05SHaiyue Wang 
2155ab91e05SHaiyue Wang 	if (!action)
2165ab91e05SHaiyue Wang 		action = "";
2175ab91e05SHaiyue Wang 
2185ab91e05SHaiyue Wang 	if (!result)
2195ab91e05SHaiyue Wang 		result = "";
2205ab91e05SHaiyue Wang 
2215ab91e05SHaiyue Wang 	dev_info(&adapter->pdev->dev, "%s %s %s\n", action, hash_opt, result);
2225ab91e05SHaiyue Wang }
223