Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2021, Intel Corporation. */ /* advanced RSS configuration ethtool support for iavf */ #include "iavf.h" /** * iavf_fill_adv_rss_ip4_hdr - fill the IPv4 RSS protocol header * @hdr: the virtchnl message protocol header data structure * @hash_flds: the RSS configuration protocol hash fields */ static void iavf_fill_adv_rss_ip4_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds) { VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV4); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_SA) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, SRC); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_DA) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, DST); } /** * iavf_fill_adv_rss_ip6_hdr - fill the IPv6 RSS protocol header * @hdr: the virtchnl message protocol header data structure * @hash_flds: the RSS configuration protocol hash fields */ static void iavf_fill_adv_rss_ip6_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds) { VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV6); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_SA) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, SRC); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_DA) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, DST); } /** * iavf_fill_adv_rss_tcp_hdr - fill the TCP RSS protocol header * @hdr: the virtchnl message protocol header data structure * @hash_flds: the RSS configuration protocol hash fields */ static void iavf_fill_adv_rss_tcp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds) { VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, TCP); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, SRC_PORT); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, DST_PORT); } /** * iavf_fill_adv_rss_udp_hdr - fill the UDP RSS protocol header * @hdr: the virtchnl message protocol header data structure * @hash_flds: the RSS configuration protocol hash fields */ static void iavf_fill_adv_rss_udp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds) { VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, UDP); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, SRC_PORT); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, DST_PORT); } /** * iavf_fill_adv_rss_sctp_hdr - fill the SCTP RSS protocol header * @hdr: the virtchnl message protocol header data structure * @hash_flds: the RSS configuration protocol hash fields */ static void iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds) { VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, SCTP); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, SRC_PORT); if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT) VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, DST_PORT); } /** * iavf_fill_adv_rss_cfg_msg - fill the RSS configuration into virtchnl message * @rss_cfg: the virtchnl message to be filled with RSS configuration setting * @packet_hdrs: the RSS configuration protocol header types * @hash_flds: the RSS configuration protocol hash fields * * Returns 0 if the RSS configuration virtchnl message is filled successfully */ int iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg, u32 packet_hdrs, u64 hash_flds) { struct virtchnl_proto_hdrs *proto_hdrs = &rss_cfg->proto_hdrs; struct virtchnl_proto_hdr *hdr; rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC; proto_hdrs->tunnel_level = 0; /* always outer layer */ hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3) { case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4: iavf_fill_adv_rss_ip4_hdr(hdr, hash_flds); break; case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6: iavf_fill_adv_rss_ip6_hdr(hdr, hash_flds); break; default: return -EINVAL; } hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4) { case IAVF_ADV_RSS_FLOW_SEG_HDR_TCP: iavf_fill_adv_rss_tcp_hdr(hdr, hash_flds); break; case IAVF_ADV_RSS_FLOW_SEG_HDR_UDP: iavf_fill_adv_rss_udp_hdr(hdr, hash_flds); break; case IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP: iavf_fill_adv_rss_sctp_hdr(hdr, hash_flds); break; default: return -EINVAL; } return 0; } /** * iavf_find_adv_rss_cfg_by_hdrs - find RSS configuration with header type * @adapter: pointer to the VF adapter structure * @packet_hdrs: protocol header type to find. * * Returns pointer to advance RSS configuration if found or null */ struct iavf_adv_rss * iavf_find_adv_rss_cfg_by_hdrs(struct iavf_adapter *adapter, u32 packet_hdrs) { struct iavf_adv_rss *rss; list_for_each_entry(rss, &adapter->adv_rss_list_head, list) if (rss->packet_hdrs == packet_hdrs) return rss; return NULL; } /** * iavf_print_adv_rss_cfg * @adapter: pointer to the VF adapter structure * @rss: pointer to the advance RSS configuration to print * @action: the string description about how to handle the RSS * @result: the string description about the virtchnl result * * Print the advance RSS configuration **/ void iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss, const char *action, const char *result) { u32 packet_hdrs = rss->packet_hdrs; u64 hash_flds = rss->hash_flds; static char hash_opt[300]; const char *proto; if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_TCP) proto = "TCP"; else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_UDP) proto = "UDP"; else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP) proto = "SCTP"; else return; memset(hash_opt, 0, sizeof(hash_opt)); strcat(hash_opt, proto); if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4) strcat(hash_opt, "v4 "); else strcat(hash_opt, "v6 "); if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_SA | IAVF_ADV_RSS_HASH_FLD_IPV6_SA)) strcat(hash_opt, "IP SA,"); if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_DA | IAVF_ADV_RSS_HASH_FLD_IPV6_DA)) strcat(hash_opt, "IP DA,"); if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT | IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT | IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT)) strcat(hash_opt, "src port,"); if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT | IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT | IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT)) strcat(hash_opt, "dst port,"); if (!action) action = ""; if (!result) result = ""; dev_info(&adapter->pdev->dev, "%s %s %s\n", action, hash_opt, result); } |