diff options
Diffstat (limited to 'drivers/net/ethernet/intel/iavf/iavf_adv_rss.c')
| -rw-r--r-- | drivers/net/ethernet/intel/iavf/iavf_adv_rss.c | 119 |
1 files changed, 96 insertions, 23 deletions
diff --git a/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c b/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c index a9e1da35e248..4d12dfe1b481 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c +++ b/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c @@ -91,6 +91,55 @@ iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds) } /** + * iavf_fill_adv_rss_gtp_hdr - Fill GTP-related RSS protocol headers + * @proto_hdrs: pointer to the virtchnl protocol headers structure to populate + * @packet_hdrs: bitmask of packet header types to configure + * @hash_flds: RSS hash field configuration + * + * This function populates the virtchnl protocol header structure with + * appropriate GTP-related header types based on the specified packet_hdrs. + * It supports GTPC, GTPU with extension headers, and uplink/downlink PDU + * types. For certain GTPU types, it also appends an IPv4 header to enable + * hashing on the destination IP address. + * + * Return: 0 on success or -EOPNOTSUPP if the packet_hdrs value is unsupported. + */ +static int +iavf_fill_adv_rss_gtp_hdr(struct virtchnl_proto_hdrs *proto_hdrs, + u32 packet_hdrs, u64 hash_flds) +{ + struct virtchnl_proto_hdr *hdr; + + hdr = &proto_hdrs->proto_hdr[proto_hdrs->count - 1]; + + switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP) { + case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID: + case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC: + VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPC); + break; + case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH: + VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH); + break; + case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP: + VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_UP); + hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; + iavf_fill_adv_rss_ip4_hdr(hdr, IAVF_ADV_RSS_HASH_FLD_IPV4_DA); + break; + case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN: + VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_DWN); + fallthrough; + case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP: + hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; + iavf_fill_adv_rss_ip4_hdr(hdr, IAVF_ADV_RSS_HASH_FLD_IPV4_DA); + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +/** * 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 @@ -103,6 +152,8 @@ int iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg, u32 packet_hdrs, u64 hash_flds, bool symm) { + const u32 packet_l3_hdrs = packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3; + const u32 packet_l4_hdrs = packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4; struct virtchnl_proto_hdrs *proto_hdrs = &rss_cfg->proto_hdrs; struct virtchnl_proto_hdr *hdr; @@ -113,31 +164,41 @@ iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg, 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; + if (packet_l3_hdrs) { + hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; + switch (packet_l3_hdrs) { + 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; + if (packet_l4_hdrs) { + hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; + switch (packet_l4_hdrs) { + 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; + } + } + + if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP) { + hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; + if (iavf_fill_adv_rss_gtp_hdr(proto_hdrs, packet_hdrs, hash_flds)) + return -EINVAL; } return 0; @@ -186,6 +247,8 @@ iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss, proto = "UDP"; else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP) proto = "SCTP"; + else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP) + proto = "GTP"; else return; @@ -211,6 +274,16 @@ iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss, IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT | IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT)) strcat(hash_opt, "dst port,"); + if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPC_TEID) + strcat(hash_opt, "gtp-c,"); + if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_IP_TEID) + strcat(hash_opt, "gtp-u ip,"); + if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_EH_TEID) + strcat(hash_opt, "gtp-u ext,"); + if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_UP_TEID) + strcat(hash_opt, "gtp-u ul,"); + if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_DWN_TEID) + strcat(hash_opt, "gtp-u dl,"); if (!action) action = ""; |
