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 */ 13 static void 14 iavf_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 */ 30 static void 31 iavf_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 */ 47 static void 48 iavf_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_cfg_msg - fill the RSS configuration into virtchnl message 61 * @rss_cfg: the virtchnl message to be filled with RSS configuration setting 62 * @packet_hdrs: the RSS configuration protocol header types 63 * @hash_flds: the RSS configuration protocol hash fields 64 * 65 * Returns 0 if the RSS configuration virtchnl message is filled successfully 66 */ 67 int 68 iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg, 69 u32 packet_hdrs, u64 hash_flds) 70 { 71 struct virtchnl_proto_hdrs *proto_hdrs = &rss_cfg->proto_hdrs; 72 struct virtchnl_proto_hdr *hdr; 73 74 rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC; 75 76 proto_hdrs->tunnel_level = 0; /* always outer layer */ 77 78 hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; 79 switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3) { 80 case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4: 81 iavf_fill_adv_rss_ip4_hdr(hdr, hash_flds); 82 break; 83 case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6: 84 iavf_fill_adv_rss_ip6_hdr(hdr, hash_flds); 85 break; 86 default: 87 return -EINVAL; 88 } 89 90 hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; 91 switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4) { 92 case IAVF_ADV_RSS_FLOW_SEG_HDR_TCP: 93 iavf_fill_adv_rss_tcp_hdr(hdr, hash_flds); 94 break; 95 default: 96 return -EINVAL; 97 } 98 99 return 0; 100 } 101 102 /** 103 * iavf_find_adv_rss_cfg_by_hdrs - find RSS configuration with header type 104 * @adapter: pointer to the VF adapter structure 105 * @packet_hdrs: protocol header type to find. 106 * 107 * Returns pointer to advance RSS configuration if found or null 108 */ 109 struct iavf_adv_rss * 110 iavf_find_adv_rss_cfg_by_hdrs(struct iavf_adapter *adapter, u32 packet_hdrs) 111 { 112 struct iavf_adv_rss *rss; 113 114 list_for_each_entry(rss, &adapter->adv_rss_list_head, list) 115 if (rss->packet_hdrs == packet_hdrs) 116 return rss; 117 118 return NULL; 119 } 120 121 /** 122 * iavf_print_adv_rss_cfg 123 * @adapter: pointer to the VF adapter structure 124 * @rss: pointer to the advance RSS configuration to print 125 * @action: the string description about how to handle the RSS 126 * @result: the string description about the virtchnl result 127 * 128 * Print the advance RSS configuration 129 **/ 130 void 131 iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss, 132 const char *action, const char *result) 133 { 134 u32 packet_hdrs = rss->packet_hdrs; 135 u64 hash_flds = rss->hash_flds; 136 static char hash_opt[300]; 137 const char *proto; 138 139 if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_TCP) 140 proto = "TCP"; 141 else 142 return; 143 144 memset(hash_opt, 0, sizeof(hash_opt)); 145 146 strcat(hash_opt, proto); 147 if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4) 148 strcat(hash_opt, "v4 "); 149 else 150 strcat(hash_opt, "v6 "); 151 152 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_SA | 153 IAVF_ADV_RSS_HASH_FLD_IPV6_SA)) 154 strcat(hash_opt, "IP SA,"); 155 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_DA | 156 IAVF_ADV_RSS_HASH_FLD_IPV6_DA)) 157 strcat(hash_opt, "IP DA,"); 158 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT) 159 strcat(hash_opt, "src port,"); 160 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT) 161 strcat(hash_opt, "dst port,"); 162 163 if (!action) 164 action = ""; 165 166 if (!result) 167 result = ""; 168 169 dev_info(&adapter->pdev->dev, "%s %s %s\n", action, hash_opt, result); 170 } 171