1f4e667ebSPrzemek Kitszel // SPDX-License-Identifier: GPL-2.0 2f4e667ebSPrzemek Kitszel /* Copyright (C) 2022, Intel Corporation. */ 3f4e667ebSPrzemek Kitszel 4*e0d2795aSPrzemek Kitszel #include "rss.h" 5f4e667ebSPrzemek Kitszel #include "ice_vf_lib_private.h" 6f4e667ebSPrzemek Kitszel #include "ice.h" 7f4e667ebSPrzemek Kitszel 8f4e667ebSPrzemek Kitszel #define FIELD_SELECTOR(proto_hdr_field) \ 9f4e667ebSPrzemek Kitszel BIT((proto_hdr_field) & PROTO_HDR_FIELD_MASK) 10f4e667ebSPrzemek Kitszel 11f4e667ebSPrzemek Kitszel struct ice_vc_hdr_match_type { 12f4e667ebSPrzemek Kitszel u32 vc_hdr; /* virtchnl headers (VIRTCHNL_PROTO_HDR_XXX) */ 13f4e667ebSPrzemek Kitszel u32 ice_hdr; /* ice headers (ICE_FLOW_SEG_HDR_XXX) */ 14f4e667ebSPrzemek Kitszel }; 15f4e667ebSPrzemek Kitszel 16f4e667ebSPrzemek Kitszel static const struct ice_vc_hdr_match_type ice_vc_hdr_list[] = { 17f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_NONE, ICE_FLOW_SEG_HDR_NONE}, 18f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, ICE_FLOW_SEG_HDR_ETH}, 19f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_S_VLAN, ICE_FLOW_SEG_HDR_VLAN}, 20f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_C_VLAN, ICE_FLOW_SEG_HDR_VLAN}, 21f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, ICE_FLOW_SEG_HDR_IPV4 | 22f4e667ebSPrzemek Kitszel ICE_FLOW_SEG_HDR_IPV_OTHER}, 23f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, ICE_FLOW_SEG_HDR_IPV6 | 24f4e667ebSPrzemek Kitszel ICE_FLOW_SEG_HDR_IPV_OTHER}, 25f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_TCP, ICE_FLOW_SEG_HDR_TCP}, 26f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_UDP, ICE_FLOW_SEG_HDR_UDP}, 27f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_SCTP, ICE_FLOW_SEG_HDR_SCTP}, 28f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_PPPOE, ICE_FLOW_SEG_HDR_PPPOE}, 29f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_IP, ICE_FLOW_SEG_HDR_GTPU_IP}, 30f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_EH, ICE_FLOW_SEG_HDR_GTPU_EH}, 31f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN, 32f4e667ebSPrzemek Kitszel ICE_FLOW_SEG_HDR_GTPU_DWN}, 33f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP, 34f4e667ebSPrzemek Kitszel ICE_FLOW_SEG_HDR_GTPU_UP}, 35f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_L2TPV3, ICE_FLOW_SEG_HDR_L2TPV3}, 36f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ESP, ICE_FLOW_SEG_HDR_ESP}, 37f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_AH, ICE_FLOW_SEG_HDR_AH}, 38f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_PFCP, ICE_FLOW_SEG_HDR_PFCP_SESSION}, 39f4e667ebSPrzemek Kitszel }; 40f4e667ebSPrzemek Kitszel 41f4e667ebSPrzemek Kitszel struct ice_vc_hash_field_match_type { 42f4e667ebSPrzemek Kitszel u32 vc_hdr; /* virtchnl headers 43f4e667ebSPrzemek Kitszel * (VIRTCHNL_PROTO_HDR_XXX) 44f4e667ebSPrzemek Kitszel */ 45f4e667ebSPrzemek Kitszel u32 vc_hash_field; /* virtchnl hash fields selector 46f4e667ebSPrzemek Kitszel * FIELD_SELECTOR((VIRTCHNL_PROTO_HDR_ETH_XXX)) 47f4e667ebSPrzemek Kitszel */ 48f4e667ebSPrzemek Kitszel u64 ice_hash_field; /* ice hash fields 49f4e667ebSPrzemek Kitszel * (BIT_ULL(ICE_FLOW_FIELD_IDX_XXX)) 50f4e667ebSPrzemek Kitszel */ 51f4e667ebSPrzemek Kitszel }; 52f4e667ebSPrzemek Kitszel 53f4e667ebSPrzemek Kitszel static const struct 54f4e667ebSPrzemek Kitszel ice_vc_hash_field_match_type ice_vc_hash_field_list[] = { 55f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC), 56f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA)}, 57f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), 58f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA)}, 59f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) | 60f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), 61f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_ETH}, 62f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, 63f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE), 64f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE)}, 65f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_S_VLAN, 66f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID), 67f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN)}, 68f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_C_VLAN, 69f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID), 70f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN)}, 71f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC), 72f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)}, 73f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), 74f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)}, 75f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 76f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), 77f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_IPV4}, 78f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 79f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 80f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | 81f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 82f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | 83f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 84f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | 85f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 86f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 87f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | 88f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 89f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_IPV4 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 90f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 91f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 92f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC), 93f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)}, 94f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), 95f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)}, 96f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 97f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), 98f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_IPV6}, 99f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 100f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 101f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | 102f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 103f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | 104f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 105f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | 106f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 107f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 108f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | 109f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 110f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_IPV6 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 111f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 112f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 113f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_TCP, 114f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT), 115f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, 116f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_TCP, 117f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), 118f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, 119f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_TCP, 120f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) | 121f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), 122f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_TCP_PORT}, 123f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_UDP, 124f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT), 125f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, 126f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_UDP, 127f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), 128f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, 129f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_UDP, 130f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) | 131f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), 132f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_UDP_PORT}, 133f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_SCTP, 134f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT), 135f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, 136f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_SCTP, 137f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), 138f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, 139f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_SCTP, 140f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) | 141f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), 142f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_SCTP_PORT}, 143f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_PPPOE, 144f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID), 145f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID)}, 146f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_IP, 147f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_GTPU_IP_TEID), 148f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID)}, 149f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_L2TPV3, 150f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID), 151f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID)}, 152f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ESP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI), 153f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_ESP_SPI)}, 154f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_AH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI), 155f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_AH_SPI)}, 156f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_PFCP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID), 157f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_PFCP_SEID)}, 158f4e667ebSPrzemek Kitszel }; 159f4e667ebSPrzemek Kitszel 160f4e667ebSPrzemek Kitszel /** 161f4e667ebSPrzemek Kitszel * ice_vc_validate_pattern 162f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 163f4e667ebSPrzemek Kitszel * @proto: virtchnl protocol headers 164f4e667ebSPrzemek Kitszel * 165f4e667ebSPrzemek Kitszel * validate the pattern is supported or not. 166f4e667ebSPrzemek Kitszel * 167f4e667ebSPrzemek Kitszel * Return: true on success, false on error. 168f4e667ebSPrzemek Kitszel */ 169f4e667ebSPrzemek Kitszel bool 170f4e667ebSPrzemek Kitszel ice_vc_validate_pattern(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto) 171f4e667ebSPrzemek Kitszel { 172f4e667ebSPrzemek Kitszel bool is_ipv4 = false; 173f4e667ebSPrzemek Kitszel bool is_ipv6 = false; 174f4e667ebSPrzemek Kitszel bool is_udp = false; 175f4e667ebSPrzemek Kitszel u16 ptype = -1; 176f4e667ebSPrzemek Kitszel int i = 0; 177f4e667ebSPrzemek Kitszel 178f4e667ebSPrzemek Kitszel while (i < proto->count && 179f4e667ebSPrzemek Kitszel proto->proto_hdr[i].type != VIRTCHNL_PROTO_HDR_NONE) { 180f4e667ebSPrzemek Kitszel switch (proto->proto_hdr[i].type) { 181f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_ETH: 182f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_MAC_PAY; 183f4e667ebSPrzemek Kitszel break; 184f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_IPV4: 185f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV4_PAY; 186f4e667ebSPrzemek Kitszel is_ipv4 = true; 187f4e667ebSPrzemek Kitszel break; 188f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_IPV6: 189f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV6_PAY; 190f4e667ebSPrzemek Kitszel is_ipv6 = true; 191f4e667ebSPrzemek Kitszel break; 192f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_UDP: 193f4e667ebSPrzemek Kitszel if (is_ipv4) 194f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV4_UDP_PAY; 195f4e667ebSPrzemek Kitszel else if (is_ipv6) 196f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV6_UDP_PAY; 197f4e667ebSPrzemek Kitszel is_udp = true; 198f4e667ebSPrzemek Kitszel break; 199f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_TCP: 200f4e667ebSPrzemek Kitszel if (is_ipv4) 201f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV4_TCP_PAY; 202f4e667ebSPrzemek Kitszel else if (is_ipv6) 203f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV6_TCP_PAY; 204f4e667ebSPrzemek Kitszel break; 205f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_SCTP: 206f4e667ebSPrzemek Kitszel if (is_ipv4) 207f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV4_SCTP_PAY; 208f4e667ebSPrzemek Kitszel else if (is_ipv6) 209f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV6_SCTP_PAY; 210f4e667ebSPrzemek Kitszel break; 211f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_GTPU_IP: 212f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_GTPU_EH: 213f4e667ebSPrzemek Kitszel if (is_ipv4) 214f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV4_GTPU; 215f4e667ebSPrzemek Kitszel else if (is_ipv6) 216f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV6_GTPU; 217f4e667ebSPrzemek Kitszel goto out; 218f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_L2TPV3: 219f4e667ebSPrzemek Kitszel if (is_ipv4) 220f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV4_L2TPV3; 221f4e667ebSPrzemek Kitszel else if (is_ipv6) 222f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV6_L2TPV3; 223f4e667ebSPrzemek Kitszel goto out; 224f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_ESP: 225f4e667ebSPrzemek Kitszel if (is_ipv4) 226f4e667ebSPrzemek Kitszel ptype = is_udp ? ICE_MAC_IPV4_NAT_T_ESP : 227f4e667ebSPrzemek Kitszel ICE_MAC_IPV4_ESP; 228f4e667ebSPrzemek Kitszel else if (is_ipv6) 229f4e667ebSPrzemek Kitszel ptype = is_udp ? ICE_MAC_IPV6_NAT_T_ESP : 230f4e667ebSPrzemek Kitszel ICE_MAC_IPV6_ESP; 231f4e667ebSPrzemek Kitszel goto out; 232f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_AH: 233f4e667ebSPrzemek Kitszel if (is_ipv4) 234f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV4_AH; 235f4e667ebSPrzemek Kitszel else if (is_ipv6) 236f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV6_AH; 237f4e667ebSPrzemek Kitszel goto out; 238f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_PFCP: 239f4e667ebSPrzemek Kitszel if (is_ipv4) 240f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV4_PFCP_SESSION; 241f4e667ebSPrzemek Kitszel else if (is_ipv6) 242f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV6_PFCP_SESSION; 243f4e667ebSPrzemek Kitszel goto out; 244f4e667ebSPrzemek Kitszel default: 245f4e667ebSPrzemek Kitszel break; 246f4e667ebSPrzemek Kitszel } 247f4e667ebSPrzemek Kitszel i++; 248f4e667ebSPrzemek Kitszel } 249f4e667ebSPrzemek Kitszel 250f4e667ebSPrzemek Kitszel out: 251f4e667ebSPrzemek Kitszel return ice_hw_ptype_ena(&vf->pf->hw, ptype); 252f4e667ebSPrzemek Kitszel } 253f4e667ebSPrzemek Kitszel 254f4e667ebSPrzemek Kitszel /** 255f4e667ebSPrzemek Kitszel * ice_vc_parse_rss_cfg - parses hash fields and headers from 256f4e667ebSPrzemek Kitszel * a specific virtchnl RSS cfg 257f4e667ebSPrzemek Kitszel * @hw: pointer to the hardware 258f4e667ebSPrzemek Kitszel * @rss_cfg: pointer to the virtchnl RSS cfg 259f4e667ebSPrzemek Kitszel * @hash_cfg: pointer to the HW hash configuration 260f4e667ebSPrzemek Kitszel * 261f4e667ebSPrzemek Kitszel * Return true if all the protocol header and hash fields in the RSS cfg could 262f4e667ebSPrzemek Kitszel * be parsed, else return false 263f4e667ebSPrzemek Kitszel * 264f4e667ebSPrzemek Kitszel * This function parses the virtchnl RSS cfg to be the intended 265f4e667ebSPrzemek Kitszel * hash fields and the intended header for RSS configuration 266f4e667ebSPrzemek Kitszel */ 267f4e667ebSPrzemek Kitszel static bool ice_vc_parse_rss_cfg(struct ice_hw *hw, 268f4e667ebSPrzemek Kitszel struct virtchnl_rss_cfg *rss_cfg, 269f4e667ebSPrzemek Kitszel struct ice_rss_hash_cfg *hash_cfg) 270f4e667ebSPrzemek Kitszel { 271f4e667ebSPrzemek Kitszel const struct ice_vc_hash_field_match_type *hf_list; 272f4e667ebSPrzemek Kitszel const struct ice_vc_hdr_match_type *hdr_list; 273f4e667ebSPrzemek Kitszel int i, hf_list_len, hdr_list_len; 274f4e667ebSPrzemek Kitszel u32 *addl_hdrs = &hash_cfg->addl_hdrs; 275f4e667ebSPrzemek Kitszel u64 *hash_flds = &hash_cfg->hash_flds; 276f4e667ebSPrzemek Kitszel 277f4e667ebSPrzemek Kitszel /* set outer layer RSS as default */ 278f4e667ebSPrzemek Kitszel hash_cfg->hdr_type = ICE_RSS_OUTER_HEADERS; 279f4e667ebSPrzemek Kitszel 280f4e667ebSPrzemek Kitszel if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC) 281f4e667ebSPrzemek Kitszel hash_cfg->symm = true; 282f4e667ebSPrzemek Kitszel else 283f4e667ebSPrzemek Kitszel hash_cfg->symm = false; 284f4e667ebSPrzemek Kitszel 285f4e667ebSPrzemek Kitszel hf_list = ice_vc_hash_field_list; 286f4e667ebSPrzemek Kitszel hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list); 287f4e667ebSPrzemek Kitszel hdr_list = ice_vc_hdr_list; 288f4e667ebSPrzemek Kitszel hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list); 289f4e667ebSPrzemek Kitszel 290f4e667ebSPrzemek Kitszel for (i = 0; i < rss_cfg->proto_hdrs.count; i++) { 291f4e667ebSPrzemek Kitszel struct virtchnl_proto_hdr *proto_hdr = 292f4e667ebSPrzemek Kitszel &rss_cfg->proto_hdrs.proto_hdr[i]; 293f4e667ebSPrzemek Kitszel bool hdr_found = false; 294f4e667ebSPrzemek Kitszel int j; 295f4e667ebSPrzemek Kitszel 296f4e667ebSPrzemek Kitszel /* Find matched ice headers according to virtchnl headers. */ 297f4e667ebSPrzemek Kitszel for (j = 0; j < hdr_list_len; j++) { 298f4e667ebSPrzemek Kitszel struct ice_vc_hdr_match_type hdr_map = hdr_list[j]; 299f4e667ebSPrzemek Kitszel 300f4e667ebSPrzemek Kitszel if (proto_hdr->type == hdr_map.vc_hdr) { 301f4e667ebSPrzemek Kitszel *addl_hdrs |= hdr_map.ice_hdr; 302f4e667ebSPrzemek Kitszel hdr_found = true; 303f4e667ebSPrzemek Kitszel } 304f4e667ebSPrzemek Kitszel } 305f4e667ebSPrzemek Kitszel 306f4e667ebSPrzemek Kitszel if (!hdr_found) 307f4e667ebSPrzemek Kitszel return false; 308f4e667ebSPrzemek Kitszel 309f4e667ebSPrzemek Kitszel /* Find matched ice hash fields according to 310f4e667ebSPrzemek Kitszel * virtchnl hash fields. 311f4e667ebSPrzemek Kitszel */ 312f4e667ebSPrzemek Kitszel for (j = 0; j < hf_list_len; j++) { 313f4e667ebSPrzemek Kitszel struct ice_vc_hash_field_match_type hf_map = hf_list[j]; 314f4e667ebSPrzemek Kitszel 315f4e667ebSPrzemek Kitszel if (proto_hdr->type == hf_map.vc_hdr && 316f4e667ebSPrzemek Kitszel proto_hdr->field_selector == hf_map.vc_hash_field) { 317f4e667ebSPrzemek Kitszel *hash_flds |= hf_map.ice_hash_field; 318f4e667ebSPrzemek Kitszel break; 319f4e667ebSPrzemek Kitszel } 320f4e667ebSPrzemek Kitszel } 321f4e667ebSPrzemek Kitszel } 322f4e667ebSPrzemek Kitszel 323f4e667ebSPrzemek Kitszel return true; 324f4e667ebSPrzemek Kitszel } 325f4e667ebSPrzemek Kitszel 326f4e667ebSPrzemek Kitszel /** 327f4e667ebSPrzemek Kitszel * ice_vf_adv_rss_offload_ena - determine if capabilities support advanced 328f4e667ebSPrzemek Kitszel * RSS offloads 329f4e667ebSPrzemek Kitszel * @caps: VF driver negotiated capabilities 330f4e667ebSPrzemek Kitszel * 331f4e667ebSPrzemek Kitszel * Return true if VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF capability is set, 332f4e667ebSPrzemek Kitszel * else return false 333f4e667ebSPrzemek Kitszel */ 334f4e667ebSPrzemek Kitszel static bool ice_vf_adv_rss_offload_ena(u32 caps) 335f4e667ebSPrzemek Kitszel { 336f4e667ebSPrzemek Kitszel return !!(caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF); 337f4e667ebSPrzemek Kitszel } 338f4e667ebSPrzemek Kitszel 339f4e667ebSPrzemek Kitszel /** 340f4e667ebSPrzemek Kitszel * ice_vc_handle_rss_cfg 341f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 342f4e667ebSPrzemek Kitszel * @msg: pointer to the message buffer 343f4e667ebSPrzemek Kitszel * @add: add a RSS config if true, otherwise delete a RSS config 344f4e667ebSPrzemek Kitszel * 345f4e667ebSPrzemek Kitszel * This function adds/deletes a RSS config 346f4e667ebSPrzemek Kitszel */ 347*e0d2795aSPrzemek Kitszel int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add) 348f4e667ebSPrzemek Kitszel { 349f4e667ebSPrzemek Kitszel u32 v_opcode = add ? VIRTCHNL_OP_ADD_RSS_CFG : VIRTCHNL_OP_DEL_RSS_CFG; 350f4e667ebSPrzemek Kitszel struct virtchnl_rss_cfg *rss_cfg = (struct virtchnl_rss_cfg *)msg; 351f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 352f4e667ebSPrzemek Kitszel struct device *dev = ice_pf_to_dev(vf->pf); 353f4e667ebSPrzemek Kitszel struct ice_hw *hw = &vf->pf->hw; 354f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 355f4e667ebSPrzemek Kitszel 356f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 357f4e667ebSPrzemek Kitszel dev_dbg(dev, "VF %d attempting to configure RSS, but RSS is not supported by the PF\n", 358f4e667ebSPrzemek Kitszel vf->vf_id); 359f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED; 360f4e667ebSPrzemek Kitszel goto error_param; 361f4e667ebSPrzemek Kitszel } 362f4e667ebSPrzemek Kitszel 363f4e667ebSPrzemek Kitszel if (!ice_vf_adv_rss_offload_ena(vf->driver_caps)) { 364f4e667ebSPrzemek Kitszel dev_dbg(dev, "VF %d attempting to configure RSS, but Advanced RSS offload is not supported\n", 365f4e667ebSPrzemek Kitszel vf->vf_id); 366f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 367f4e667ebSPrzemek Kitszel goto error_param; 368f4e667ebSPrzemek Kitszel } 369f4e667ebSPrzemek Kitszel 370f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 371f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 372f4e667ebSPrzemek Kitszel goto error_param; 373f4e667ebSPrzemek Kitszel } 374f4e667ebSPrzemek Kitszel 375f4e667ebSPrzemek Kitszel if (rss_cfg->proto_hdrs.count > VIRTCHNL_MAX_NUM_PROTO_HDRS || 376f4e667ebSPrzemek Kitszel rss_cfg->rss_algorithm < VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC || 377f4e667ebSPrzemek Kitszel rss_cfg->rss_algorithm > VIRTCHNL_RSS_ALG_XOR_SYMMETRIC) { 378f4e667ebSPrzemek Kitszel dev_dbg(dev, "VF %d attempting to configure RSS, but RSS configuration is not valid\n", 379f4e667ebSPrzemek Kitszel vf->vf_id); 380f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 381f4e667ebSPrzemek Kitszel goto error_param; 382f4e667ebSPrzemek Kitszel } 383f4e667ebSPrzemek Kitszel 384f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 385f4e667ebSPrzemek Kitszel if (!vsi) { 386f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 387f4e667ebSPrzemek Kitszel goto error_param; 388f4e667ebSPrzemek Kitszel } 389f4e667ebSPrzemek Kitszel 390f4e667ebSPrzemek Kitszel if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) { 391f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 392f4e667ebSPrzemek Kitszel goto error_param; 393f4e667ebSPrzemek Kitszel } 394f4e667ebSPrzemek Kitszel 395f4e667ebSPrzemek Kitszel if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_R_ASYMMETRIC) { 396f4e667ebSPrzemek Kitszel struct ice_vsi_ctx *ctx; 397f4e667ebSPrzemek Kitszel u8 lut_type, hash_type; 398f4e667ebSPrzemek Kitszel int status; 399f4e667ebSPrzemek Kitszel 400f4e667ebSPrzemek Kitszel lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI; 401f4e667ebSPrzemek Kitszel hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_HASH_XOR : 402f4e667ebSPrzemek Kitszel ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; 403f4e667ebSPrzemek Kitszel 404f4e667ebSPrzemek Kitszel ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 405f4e667ebSPrzemek Kitszel if (!ctx) { 406f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 407f4e667ebSPrzemek Kitszel goto error_param; 408f4e667ebSPrzemek Kitszel } 409f4e667ebSPrzemek Kitszel 410f4e667ebSPrzemek Kitszel ctx->info.q_opt_rss = 411f4e667ebSPrzemek Kitszel FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_LUT_M, lut_type) | 412f4e667ebSPrzemek Kitszel FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_HASH_M, hash_type); 413f4e667ebSPrzemek Kitszel 414f4e667ebSPrzemek Kitszel /* Preserve existing queueing option setting */ 415f4e667ebSPrzemek Kitszel ctx->info.q_opt_rss |= (vsi->info.q_opt_rss & 416f4e667ebSPrzemek Kitszel ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_M); 417f4e667ebSPrzemek Kitszel ctx->info.q_opt_tc = vsi->info.q_opt_tc; 418f4e667ebSPrzemek Kitszel ctx->info.q_opt_flags = vsi->info.q_opt_rss; 419f4e667ebSPrzemek Kitszel 420f4e667ebSPrzemek Kitszel ctx->info.valid_sections = 421f4e667ebSPrzemek Kitszel cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID); 422f4e667ebSPrzemek Kitszel 423f4e667ebSPrzemek Kitszel status = ice_update_vsi(hw, vsi->idx, ctx, NULL); 424f4e667ebSPrzemek Kitszel if (status) { 425f4e667ebSPrzemek Kitszel dev_err(dev, "update VSI for RSS failed, err %d aq_err %s\n", 426f4e667ebSPrzemek Kitszel status, libie_aq_str(hw->adminq.sq_last_status)); 427f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 428f4e667ebSPrzemek Kitszel } else { 429f4e667ebSPrzemek Kitszel vsi->info.q_opt_rss = ctx->info.q_opt_rss; 430f4e667ebSPrzemek Kitszel } 431f4e667ebSPrzemek Kitszel 432f4e667ebSPrzemek Kitszel kfree(ctx); 433f4e667ebSPrzemek Kitszel } else { 434f4e667ebSPrzemek Kitszel struct ice_rss_hash_cfg cfg; 435f4e667ebSPrzemek Kitszel 436f4e667ebSPrzemek Kitszel /* Only check for none raw pattern case */ 437f4e667ebSPrzemek Kitszel if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) { 438f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 439f4e667ebSPrzemek Kitszel goto error_param; 440f4e667ebSPrzemek Kitszel } 441f4e667ebSPrzemek Kitszel cfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE; 442f4e667ebSPrzemek Kitszel cfg.hash_flds = ICE_HASH_INVALID; 443f4e667ebSPrzemek Kitszel cfg.hdr_type = ICE_RSS_ANY_HEADERS; 444f4e667ebSPrzemek Kitszel 445f4e667ebSPrzemek Kitszel if (!ice_vc_parse_rss_cfg(hw, rss_cfg, &cfg)) { 446f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 447f4e667ebSPrzemek Kitszel goto error_param; 448f4e667ebSPrzemek Kitszel } 449f4e667ebSPrzemek Kitszel 450f4e667ebSPrzemek Kitszel if (add) { 451f4e667ebSPrzemek Kitszel if (ice_add_rss_cfg(hw, vsi, &cfg)) { 452f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 453f4e667ebSPrzemek Kitszel dev_err(dev, "ice_add_rss_cfg failed for vsi = %d, v_ret = %d\n", 454f4e667ebSPrzemek Kitszel vsi->vsi_num, v_ret); 455f4e667ebSPrzemek Kitszel } 456f4e667ebSPrzemek Kitszel } else { 457f4e667ebSPrzemek Kitszel int status; 458f4e667ebSPrzemek Kitszel 459f4e667ebSPrzemek Kitszel status = ice_rem_rss_cfg(hw, vsi->idx, &cfg); 460f4e667ebSPrzemek Kitszel /* We just ignore -ENOENT, because if two configurations 461f4e667ebSPrzemek Kitszel * share the same profile remove one of them actually 462f4e667ebSPrzemek Kitszel * removes both, since the profile is deleted. 463f4e667ebSPrzemek Kitszel */ 464f4e667ebSPrzemek Kitszel if (status && status != -ENOENT) { 465f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 466f4e667ebSPrzemek Kitszel dev_err(dev, "ice_rem_rss_cfg failed for VF ID:%d, error:%d\n", 467f4e667ebSPrzemek Kitszel vf->vf_id, status); 468f4e667ebSPrzemek Kitszel } 469f4e667ebSPrzemek Kitszel } 470f4e667ebSPrzemek Kitszel } 471f4e667ebSPrzemek Kitszel 472f4e667ebSPrzemek Kitszel error_param: 473f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, v_opcode, v_ret, NULL, 0); 474f4e667ebSPrzemek Kitszel } 475f4e667ebSPrzemek Kitszel 476f4e667ebSPrzemek Kitszel /** 477f4e667ebSPrzemek Kitszel * ice_vc_config_rss_key 478f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 479f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 480f4e667ebSPrzemek Kitszel * 481f4e667ebSPrzemek Kitszel * Configure the VF's RSS key 482f4e667ebSPrzemek Kitszel */ 483*e0d2795aSPrzemek Kitszel int ice_vc_config_rss_key(struct ice_vf *vf, u8 *msg) 484f4e667ebSPrzemek Kitszel { 485f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 486f4e667ebSPrzemek Kitszel struct virtchnl_rss_key *vrk = 487f4e667ebSPrzemek Kitszel (struct virtchnl_rss_key *)msg; 488f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 489f4e667ebSPrzemek Kitszel 490f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 491f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 492f4e667ebSPrzemek Kitszel goto error_param; 493f4e667ebSPrzemek Kitszel } 494f4e667ebSPrzemek Kitszel 495f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vrk->vsi_id)) { 496f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 497f4e667ebSPrzemek Kitszel goto error_param; 498f4e667ebSPrzemek Kitszel } 499f4e667ebSPrzemek Kitszel 500f4e667ebSPrzemek Kitszel if (vrk->key_len != ICE_VSIQF_HKEY_ARRAY_SIZE) { 501f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 502f4e667ebSPrzemek Kitszel goto error_param; 503f4e667ebSPrzemek Kitszel } 504f4e667ebSPrzemek Kitszel 505f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 506f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 507f4e667ebSPrzemek Kitszel goto error_param; 508f4e667ebSPrzemek Kitszel } 509f4e667ebSPrzemek Kitszel 510f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 511f4e667ebSPrzemek Kitszel if (!vsi) { 512f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 513f4e667ebSPrzemek Kitszel goto error_param; 514f4e667ebSPrzemek Kitszel } 515f4e667ebSPrzemek Kitszel 516f4e667ebSPrzemek Kitszel if (ice_set_rss_key(vsi, vrk->key)) 517f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 518f4e667ebSPrzemek Kitszel error_param: 519f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_KEY, v_ret, 520f4e667ebSPrzemek Kitszel NULL, 0); 521f4e667ebSPrzemek Kitszel } 522f4e667ebSPrzemek Kitszel 523f4e667ebSPrzemek Kitszel /** 524f4e667ebSPrzemek Kitszel * ice_vc_config_rss_lut 525f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 526f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 527f4e667ebSPrzemek Kitszel * 528f4e667ebSPrzemek Kitszel * Configure the VF's RSS LUT 529f4e667ebSPrzemek Kitszel */ 530*e0d2795aSPrzemek Kitszel int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg) 531f4e667ebSPrzemek Kitszel { 532f4e667ebSPrzemek Kitszel struct virtchnl_rss_lut *vrl = (struct virtchnl_rss_lut *)msg; 533f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 534f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 535f4e667ebSPrzemek Kitszel 536f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 537f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 538f4e667ebSPrzemek Kitszel goto error_param; 539f4e667ebSPrzemek Kitszel } 540f4e667ebSPrzemek Kitszel 541f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vrl->vsi_id)) { 542f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 543f4e667ebSPrzemek Kitszel goto error_param; 544f4e667ebSPrzemek Kitszel } 545f4e667ebSPrzemek Kitszel 546f4e667ebSPrzemek Kitszel if (vrl->lut_entries != ICE_LUT_VSI_SIZE) { 547f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 548f4e667ebSPrzemek Kitszel goto error_param; 549f4e667ebSPrzemek Kitszel } 550f4e667ebSPrzemek Kitszel 551f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 552f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 553f4e667ebSPrzemek Kitszel goto error_param; 554f4e667ebSPrzemek Kitszel } 555f4e667ebSPrzemek Kitszel 556f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 557f4e667ebSPrzemek Kitszel if (!vsi) { 558f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 559f4e667ebSPrzemek Kitszel goto error_param; 560f4e667ebSPrzemek Kitszel } 561f4e667ebSPrzemek Kitszel 562f4e667ebSPrzemek Kitszel if (ice_set_rss_lut(vsi, vrl->lut, ICE_LUT_VSI_SIZE)) 563f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 564f4e667ebSPrzemek Kitszel error_param: 565f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_LUT, v_ret, 566f4e667ebSPrzemek Kitszel NULL, 0); 567f4e667ebSPrzemek Kitszel } 568f4e667ebSPrzemek Kitszel 569f4e667ebSPrzemek Kitszel /** 570f4e667ebSPrzemek Kitszel * ice_vc_config_rss_hfunc 571f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 572f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 573f4e667ebSPrzemek Kitszel * 574f4e667ebSPrzemek Kitszel * Configure the VF's RSS Hash function 575f4e667ebSPrzemek Kitszel */ 576*e0d2795aSPrzemek Kitszel int ice_vc_config_rss_hfunc(struct ice_vf *vf, u8 *msg) 577f4e667ebSPrzemek Kitszel { 578f4e667ebSPrzemek Kitszel struct virtchnl_rss_hfunc *vrh = (struct virtchnl_rss_hfunc *)msg; 579f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 580f4e667ebSPrzemek Kitszel u8 hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; 581f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 582f4e667ebSPrzemek Kitszel 583f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 584f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 585f4e667ebSPrzemek Kitszel goto error_param; 586f4e667ebSPrzemek Kitszel } 587f4e667ebSPrzemek Kitszel 588f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vrh->vsi_id)) { 589f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 590f4e667ebSPrzemek Kitszel goto error_param; 591f4e667ebSPrzemek Kitszel } 592f4e667ebSPrzemek Kitszel 593f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 594f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 595f4e667ebSPrzemek Kitszel goto error_param; 596f4e667ebSPrzemek Kitszel } 597f4e667ebSPrzemek Kitszel 598f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 599f4e667ebSPrzemek Kitszel if (!vsi) { 600f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 601f4e667ebSPrzemek Kitszel goto error_param; 602f4e667ebSPrzemek Kitszel } 603f4e667ebSPrzemek Kitszel 604f4e667ebSPrzemek Kitszel if (vrh->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC) 605f4e667ebSPrzemek Kitszel hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ; 606f4e667ebSPrzemek Kitszel 607f4e667ebSPrzemek Kitszel if (ice_set_rss_hfunc(vsi, hfunc)) 608f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 609f4e667ebSPrzemek Kitszel error_param: 610f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_HFUNC, v_ret, 611f4e667ebSPrzemek Kitszel NULL, 0); 612f4e667ebSPrzemek Kitszel } 613f4e667ebSPrzemek Kitszel 614f4e667ebSPrzemek Kitszel /** 615f4e667ebSPrzemek Kitszel * ice_vc_get_rss_hashcfg - return the RSS Hash configuration 616f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 617f4e667ebSPrzemek Kitszel */ 618*e0d2795aSPrzemek Kitszel int ice_vc_get_rss_hashcfg(struct ice_vf *vf) 619f4e667ebSPrzemek Kitszel { 620f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 621f4e667ebSPrzemek Kitszel struct virtchnl_rss_hashcfg *vrh = NULL; 622f4e667ebSPrzemek Kitszel int len = 0, ret; 623f4e667ebSPrzemek Kitszel 624f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 625f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 626f4e667ebSPrzemek Kitszel goto err; 627f4e667ebSPrzemek Kitszel } 628f4e667ebSPrzemek Kitszel 629f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 630f4e667ebSPrzemek Kitszel dev_err(ice_pf_to_dev(vf->pf), "RSS not supported by PF\n"); 631f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 632f4e667ebSPrzemek Kitszel goto err; 633f4e667ebSPrzemek Kitszel } 634f4e667ebSPrzemek Kitszel 635f4e667ebSPrzemek Kitszel len = sizeof(struct virtchnl_rss_hashcfg); 636f4e667ebSPrzemek Kitszel vrh = kzalloc(len, GFP_KERNEL); 637f4e667ebSPrzemek Kitszel if (!vrh) { 638f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 639f4e667ebSPrzemek Kitszel len = 0; 640f4e667ebSPrzemek Kitszel goto err; 641f4e667ebSPrzemek Kitszel } 642f4e667ebSPrzemek Kitszel 643f4e667ebSPrzemek Kitszel vrh->hashcfg = ICE_DEFAULT_RSS_HASHCFG; 644f4e667ebSPrzemek Kitszel err: 645f4e667ebSPrzemek Kitszel /* send the response back to the VF */ 646f4e667ebSPrzemek Kitszel ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_RSS_HASHCFG_CAPS, v_ret, 647f4e667ebSPrzemek Kitszel (u8 *)vrh, len); 648f4e667ebSPrzemek Kitszel kfree(vrh); 649f4e667ebSPrzemek Kitszel return ret; 650f4e667ebSPrzemek Kitszel } 651f4e667ebSPrzemek Kitszel 652f4e667ebSPrzemek Kitszel /** 653f4e667ebSPrzemek Kitszel * ice_vc_set_rss_hashcfg - set RSS Hash configuration bits for the VF 654f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 655f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 656f4e667ebSPrzemek Kitszel */ 657*e0d2795aSPrzemek Kitszel int ice_vc_set_rss_hashcfg(struct ice_vf *vf, u8 *msg) 658f4e667ebSPrzemek Kitszel { 659f4e667ebSPrzemek Kitszel struct virtchnl_rss_hashcfg *vrh = (struct virtchnl_rss_hashcfg *)msg; 660f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 661f4e667ebSPrzemek Kitszel struct ice_pf *pf = vf->pf; 662f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 663f4e667ebSPrzemek Kitszel struct device *dev; 664f4e667ebSPrzemek Kitszel int status; 665f4e667ebSPrzemek Kitszel 666f4e667ebSPrzemek Kitszel dev = ice_pf_to_dev(pf); 667f4e667ebSPrzemek Kitszel 668f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 669f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 670f4e667ebSPrzemek Kitszel goto err; 671f4e667ebSPrzemek Kitszel } 672f4e667ebSPrzemek Kitszel 673f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 674f4e667ebSPrzemek Kitszel dev_err(dev, "RSS not supported by PF\n"); 675f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 676f4e667ebSPrzemek Kitszel goto err; 677f4e667ebSPrzemek Kitszel } 678f4e667ebSPrzemek Kitszel 679f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 680f4e667ebSPrzemek Kitszel if (!vsi) { 681f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 682f4e667ebSPrzemek Kitszel goto err; 683f4e667ebSPrzemek Kitszel } 684f4e667ebSPrzemek Kitszel 685f4e667ebSPrzemek Kitszel /* clear all previously programmed RSS configuration to allow VF drivers 686f4e667ebSPrzemek Kitszel * the ability to customize the RSS configuration and/or completely 687f4e667ebSPrzemek Kitszel * disable RSS 688f4e667ebSPrzemek Kitszel */ 689f4e667ebSPrzemek Kitszel status = ice_rem_vsi_rss_cfg(&pf->hw, vsi->idx); 690f4e667ebSPrzemek Kitszel if (status && !vrh->hashcfg) { 691f4e667ebSPrzemek Kitszel /* only report failure to clear the current RSS configuration if 692f4e667ebSPrzemek Kitszel * that was clearly the VF's intention (i.e. vrh->hashcfg = 0) 693f4e667ebSPrzemek Kitszel */ 694f4e667ebSPrzemek Kitszel v_ret = ice_err_to_virt_err(status); 695f4e667ebSPrzemek Kitszel goto err; 696f4e667ebSPrzemek Kitszel } else if (status) { 697f4e667ebSPrzemek Kitszel /* allow the VF to update the RSS configuration even on failure 698f4e667ebSPrzemek Kitszel * to clear the current RSS confguration in an attempt to keep 699f4e667ebSPrzemek Kitszel * RSS in a working state 700f4e667ebSPrzemek Kitszel */ 701f4e667ebSPrzemek Kitszel dev_warn(dev, "Failed to clear the RSS configuration for VF %u\n", 702f4e667ebSPrzemek Kitszel vf->vf_id); 703f4e667ebSPrzemek Kitszel } 704f4e667ebSPrzemek Kitszel 705f4e667ebSPrzemek Kitszel if (vrh->hashcfg) { 706f4e667ebSPrzemek Kitszel status = ice_add_avf_rss_cfg(&pf->hw, vsi, vrh->hashcfg); 707f4e667ebSPrzemek Kitszel v_ret = ice_err_to_virt_err(status); 708f4e667ebSPrzemek Kitszel } 709f4e667ebSPrzemek Kitszel 710f4e667ebSPrzemek Kitszel /* save the requested VF configuration */ 711f4e667ebSPrzemek Kitszel if (!v_ret) 712f4e667ebSPrzemek Kitszel vf->rss_hashcfg = vrh->hashcfg; 713f4e667ebSPrzemek Kitszel 714f4e667ebSPrzemek Kitszel /* send the response to the VF */ 715f4e667ebSPrzemek Kitszel err: 716f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_SET_RSS_HASHCFG, v_ret, 717f4e667ebSPrzemek Kitszel NULL, 0); 718f4e667ebSPrzemek Kitszel } 719f4e667ebSPrzemek Kitszel 720