Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
ice: split ice_virtchnl.c git-blame friendly way

Przemek Kitszel says:

Split ice_virtchnl.c into two more files (+headers), in a way
that git-blame works better.
Then move virtchnl files into a new subdir.
No logic changes.

I have developed (or discovered ;)) how to split a file in a way that
both old and new are nice in terms of git-blame
There was not much discussion on [RFC], so I would like to propose
to go forward with this approach.

There are more commits needed to have it nice, so it forms a git-log vs
git-blame tradeoff, but (after the brief moment that this is on the top)
we spend orders of magnitude more time looking at the blame output (and
commit messages linked from that) - so I find it much better to see
actual logic changes instead of "move xx to yy" stuff (typical for
"squashed/single-commit splits").

Cherry-picks/rebases work the same with this method as with simple
"squashed/single-commit" approach (literally all commits squashed into
one (to have better git-log, but shitty git-blame output).

Rationale for the split itself is, as usual, "file is big and we want to
extend it".

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
ice: finish virtchnl.c split into rss.c
ice: extract virt/rss.c: cleanup - p2
ice: extract virt/rss.c: cleanup - p1
ice: split RSS stuff out of virtchnl.c - copy back
ice: split RSS stuff out of virtchnl.c - tmp rename
ice: finish virtchnl.c split into queues.c
ice: extract virt/queues.c: cleanup - p3
ice: extract virt/queues.c: cleanup - p2
ice: extract virt/queues.c: cleanup - p1
ice: split queue stuff out of virtchnl.c - copy back
ice: split queue stuff out of virtchnl.c - tmp rename
ice: add virt/ and move ice_virtchnl* files there
====================

Link: https://patch.msgid.link/20250827224641.415806-1-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+1747 -1688
+5 -3
drivers/net/ethernet/intel/ice/Makefile
··· 47 47 ice_adapter.o 48 48 ice-$(CONFIG_PCI_IOV) += \ 49 49 ice_sriov.o \ 50 - ice_virtchnl.o \ 51 - ice_virtchnl_allowlist.o \ 52 - ice_virtchnl_fdir.o \ 50 + virt/allowlist.o \ 51 + virt/fdir.o \ 52 + virt/queues.o \ 53 + virt/virtchnl.o \ 54 + virt/rss.o \ 53 55 ice_vf_mbx.o \ 54 56 ice_vf_vsi_vlan_ops.o \ 55 57 ice_vf_lib.o
+1 -1
drivers/net/ethernet/intel/ice/ice_sriov.c
··· 9 9 #include "ice_dcb_lib.h" 10 10 #include "ice_flow.h" 11 11 #include "ice_eswitch.h" 12 - #include "ice_virtchnl_allowlist.h" 12 + #include "virt/allowlist.h" 13 13 #include "ice_flex_pipe.h" 14 14 #include "ice_vf_vsi_vlan_ops.h" 15 15 #include "ice_vlan.h"
+2 -2
drivers/net/ethernet/intel/ice/ice_sriov.h
··· 3 3 4 4 #ifndef _ICE_SRIOV_H_ 5 5 #define _ICE_SRIOV_H_ 6 - #include "ice_virtchnl_fdir.h" 6 + #include "virt/fdir.h" 7 7 #include "ice_vf_lib.h" 8 - #include "ice_virtchnl.h" 8 + #include "virt/virtchnl.h" 9 9 10 10 /* Static VF transaction/status register def */ 11 11 #define VF_DEVICE_STATUS 0xAA
+1 -1
drivers/net/ethernet/intel/ice/ice_vf_lib.c
··· 5 5 #include "ice.h" 6 6 #include "ice_lib.h" 7 7 #include "ice_fltr.h" 8 - #include "ice_virtchnl_allowlist.h" 8 + #include "virt/allowlist.h" 9 9 10 10 /* Public functions which may be accessed by all driver files */ 11 11
+1 -1
drivers/net/ethernet/intel/ice/ice_vf_lib.h
··· 13 13 #include <linux/avf/virtchnl.h> 14 14 #include "ice_type.h" 15 15 #include "ice_flow.h" 16 - #include "ice_virtchnl_fdir.h" 16 + #include "virt/fdir.h" 17 17 #include "ice_vsi_vlan_ops.h" 18 18 19 19 #define ICE_MAX_SRIOV_VFS 256
+4 -1679
drivers/net/ethernet/intel/ice/ice_virtchnl.c drivers/net/ethernet/intel/ice/virt/virtchnl.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (C) 2022, Intel Corporation. */ 3 3 4 - #include "ice_virtchnl.h" 4 + #include "virtchnl.h" 5 + #include "queues.h" 6 + #include "rss.h" 5 7 #include "ice_vf_lib_private.h" 6 8 #include "ice.h" 7 9 #include "ice_base.h" 8 10 #include "ice_lib.h" 9 11 #include "ice_fltr.h" 10 - #include "ice_virtchnl_allowlist.h" 12 + #include "allowlist.h" 11 13 #include "ice_vf_vsi_vlan_ops.h" 12 14 #include "ice_vlan.h" 13 15 #include "ice_flex_pipe.h" 14 16 #include "ice_dcb_lib.h" 15 - 16 - #define FIELD_SELECTOR(proto_hdr_field) \ 17 - BIT((proto_hdr_field) & PROTO_HDR_FIELD_MASK) 18 - 19 - struct ice_vc_hdr_match_type { 20 - u32 vc_hdr; /* virtchnl headers (VIRTCHNL_PROTO_HDR_XXX) */ 21 - u32 ice_hdr; /* ice headers (ICE_FLOW_SEG_HDR_XXX) */ 22 - }; 23 - 24 - static const struct ice_vc_hdr_match_type ice_vc_hdr_list[] = { 25 - {VIRTCHNL_PROTO_HDR_NONE, ICE_FLOW_SEG_HDR_NONE}, 26 - {VIRTCHNL_PROTO_HDR_ETH, ICE_FLOW_SEG_HDR_ETH}, 27 - {VIRTCHNL_PROTO_HDR_S_VLAN, ICE_FLOW_SEG_HDR_VLAN}, 28 - {VIRTCHNL_PROTO_HDR_C_VLAN, ICE_FLOW_SEG_HDR_VLAN}, 29 - {VIRTCHNL_PROTO_HDR_IPV4, ICE_FLOW_SEG_HDR_IPV4 | 30 - ICE_FLOW_SEG_HDR_IPV_OTHER}, 31 - {VIRTCHNL_PROTO_HDR_IPV6, ICE_FLOW_SEG_HDR_IPV6 | 32 - ICE_FLOW_SEG_HDR_IPV_OTHER}, 33 - {VIRTCHNL_PROTO_HDR_TCP, ICE_FLOW_SEG_HDR_TCP}, 34 - {VIRTCHNL_PROTO_HDR_UDP, ICE_FLOW_SEG_HDR_UDP}, 35 - {VIRTCHNL_PROTO_HDR_SCTP, ICE_FLOW_SEG_HDR_SCTP}, 36 - {VIRTCHNL_PROTO_HDR_PPPOE, ICE_FLOW_SEG_HDR_PPPOE}, 37 - {VIRTCHNL_PROTO_HDR_GTPU_IP, ICE_FLOW_SEG_HDR_GTPU_IP}, 38 - {VIRTCHNL_PROTO_HDR_GTPU_EH, ICE_FLOW_SEG_HDR_GTPU_EH}, 39 - {VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN, 40 - ICE_FLOW_SEG_HDR_GTPU_DWN}, 41 - {VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP, 42 - ICE_FLOW_SEG_HDR_GTPU_UP}, 43 - {VIRTCHNL_PROTO_HDR_L2TPV3, ICE_FLOW_SEG_HDR_L2TPV3}, 44 - {VIRTCHNL_PROTO_HDR_ESP, ICE_FLOW_SEG_HDR_ESP}, 45 - {VIRTCHNL_PROTO_HDR_AH, ICE_FLOW_SEG_HDR_AH}, 46 - {VIRTCHNL_PROTO_HDR_PFCP, ICE_FLOW_SEG_HDR_PFCP_SESSION}, 47 - }; 48 - 49 - struct ice_vc_hash_field_match_type { 50 - u32 vc_hdr; /* virtchnl headers 51 - * (VIRTCHNL_PROTO_HDR_XXX) 52 - */ 53 - u32 vc_hash_field; /* virtchnl hash fields selector 54 - * FIELD_SELECTOR((VIRTCHNL_PROTO_HDR_ETH_XXX)) 55 - */ 56 - u64 ice_hash_field; /* ice hash fields 57 - * (BIT_ULL(ICE_FLOW_FIELD_IDX_XXX)) 58 - */ 59 - }; 60 - 61 - static const struct 62 - ice_vc_hash_field_match_type ice_vc_hash_field_list[] = { 63 - {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC), 64 - BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA)}, 65 - {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), 66 - BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA)}, 67 - {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) | 68 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), 69 - ICE_FLOW_HASH_ETH}, 70 - {VIRTCHNL_PROTO_HDR_ETH, 71 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE), 72 - BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE)}, 73 - {VIRTCHNL_PROTO_HDR_S_VLAN, 74 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID), 75 - BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN)}, 76 - {VIRTCHNL_PROTO_HDR_C_VLAN, 77 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID), 78 - BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN)}, 79 - {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC), 80 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)}, 81 - {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), 82 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)}, 83 - {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 84 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), 85 - ICE_FLOW_HASH_IPV4}, 86 - {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 87 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 88 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | 89 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 90 - {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | 91 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 92 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | 93 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 94 - {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 95 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | 96 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 97 - ICE_FLOW_HASH_IPV4 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 98 - {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 99 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 100 - {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC), 101 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)}, 102 - {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), 103 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)}, 104 - {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 105 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), 106 - ICE_FLOW_HASH_IPV6}, 107 - {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 108 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 109 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | 110 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 111 - {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | 112 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 113 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | 114 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 115 - {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 116 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | 117 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 118 - ICE_FLOW_HASH_IPV6 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 119 - {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 120 - BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 121 - {VIRTCHNL_PROTO_HDR_TCP, 122 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT), 123 - BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, 124 - {VIRTCHNL_PROTO_HDR_TCP, 125 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), 126 - BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, 127 - {VIRTCHNL_PROTO_HDR_TCP, 128 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) | 129 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), 130 - ICE_FLOW_HASH_TCP_PORT}, 131 - {VIRTCHNL_PROTO_HDR_UDP, 132 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT), 133 - BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, 134 - {VIRTCHNL_PROTO_HDR_UDP, 135 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), 136 - BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, 137 - {VIRTCHNL_PROTO_HDR_UDP, 138 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) | 139 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), 140 - ICE_FLOW_HASH_UDP_PORT}, 141 - {VIRTCHNL_PROTO_HDR_SCTP, 142 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT), 143 - BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, 144 - {VIRTCHNL_PROTO_HDR_SCTP, 145 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), 146 - BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, 147 - {VIRTCHNL_PROTO_HDR_SCTP, 148 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) | 149 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), 150 - ICE_FLOW_HASH_SCTP_PORT}, 151 - {VIRTCHNL_PROTO_HDR_PPPOE, 152 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID), 153 - BIT_ULL(ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID)}, 154 - {VIRTCHNL_PROTO_HDR_GTPU_IP, 155 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_GTPU_IP_TEID), 156 - BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID)}, 157 - {VIRTCHNL_PROTO_HDR_L2TPV3, 158 - FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID), 159 - BIT_ULL(ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID)}, 160 - {VIRTCHNL_PROTO_HDR_ESP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI), 161 - BIT_ULL(ICE_FLOW_FIELD_IDX_ESP_SPI)}, 162 - {VIRTCHNL_PROTO_HDR_AH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI), 163 - BIT_ULL(ICE_FLOW_FIELD_IDX_AH_SPI)}, 164 - {VIRTCHNL_PROTO_HDR_PFCP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID), 165 - BIT_ULL(ICE_FLOW_FIELD_IDX_PFCP_SEID)}, 166 - }; 167 17 168 18 /** 169 19 * ice_vc_vf_broadcast - Broadcast a message to all VFs on PF ··· 185 335 return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_VERSION, 186 336 VIRTCHNL_STATUS_SUCCESS, (u8 *)&info, 187 337 sizeof(struct virtchnl_version_info)); 188 - } 189 - 190 - /** 191 - * ice_vc_get_max_frame_size - get max frame size allowed for VF 192 - * @vf: VF used to determine max frame size 193 - * 194 - * Max frame size is determined based on the current port's max frame size and 195 - * whether a port VLAN is configured on this VF. The VF is not aware whether 196 - * it's in a port VLAN so the PF needs to account for this in max frame size 197 - * checks and sending the max frame size to the VF. 198 - */ 199 - static u16 ice_vc_get_max_frame_size(struct ice_vf *vf) 200 - { 201 - struct ice_port_info *pi = ice_vf_get_port_info(vf); 202 - u16 max_frame_size; 203 - 204 - max_frame_size = pi->phy.link_info.max_frame_size; 205 - 206 - if (ice_vf_is_port_vlan_ena(vf)) 207 - max_frame_size -= VLAN_HLEN; 208 - 209 - return max_frame_size; 210 338 } 211 339 212 340 /** ··· 387 559 } 388 560 389 561 /** 390 - * ice_vc_isvalid_q_id 391 - * @vsi: VSI to check queue ID against 392 - * @qid: VSI relative queue ID 393 - * 394 - * check for the valid queue ID 395 - */ 396 - static bool ice_vc_isvalid_q_id(struct ice_vsi *vsi, u16 qid) 397 - { 398 - /* allocated Tx and Rx queues should be always equal for VF VSI */ 399 - return qid < vsi->alloc_txq; 400 - } 401 - 402 - /** 403 - * ice_vc_isvalid_ring_len 404 - * @ring_len: length of ring 405 - * 406 - * check for the valid ring count, should be multiple of ICE_REQ_DESC_MULTIPLE 407 - * or zero 408 - */ 409 - static bool ice_vc_isvalid_ring_len(u16 ring_len) 410 - { 411 - return ring_len == 0 || 412 - (ring_len >= ICE_MIN_NUM_DESC && 413 - ring_len <= ICE_MAX_NUM_DESC && 414 - !(ring_len % ICE_REQ_DESC_MULTIPLE)); 415 - } 416 - 417 - /** 418 - * ice_vc_validate_pattern 419 - * @vf: pointer to the VF info 420 - * @proto: virtchnl protocol headers 421 - * 422 - * validate the pattern is supported or not. 423 - * 424 - * Return: true on success, false on error. 425 - */ 426 - bool 427 - ice_vc_validate_pattern(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto) 428 - { 429 - bool is_ipv4 = false; 430 - bool is_ipv6 = false; 431 - bool is_udp = false; 432 - u16 ptype = -1; 433 - int i = 0; 434 - 435 - while (i < proto->count && 436 - proto->proto_hdr[i].type != VIRTCHNL_PROTO_HDR_NONE) { 437 - switch (proto->proto_hdr[i].type) { 438 - case VIRTCHNL_PROTO_HDR_ETH: 439 - ptype = ICE_PTYPE_MAC_PAY; 440 - break; 441 - case VIRTCHNL_PROTO_HDR_IPV4: 442 - ptype = ICE_PTYPE_IPV4_PAY; 443 - is_ipv4 = true; 444 - break; 445 - case VIRTCHNL_PROTO_HDR_IPV6: 446 - ptype = ICE_PTYPE_IPV6_PAY; 447 - is_ipv6 = true; 448 - break; 449 - case VIRTCHNL_PROTO_HDR_UDP: 450 - if (is_ipv4) 451 - ptype = ICE_PTYPE_IPV4_UDP_PAY; 452 - else if (is_ipv6) 453 - ptype = ICE_PTYPE_IPV6_UDP_PAY; 454 - is_udp = true; 455 - break; 456 - case VIRTCHNL_PROTO_HDR_TCP: 457 - if (is_ipv4) 458 - ptype = ICE_PTYPE_IPV4_TCP_PAY; 459 - else if (is_ipv6) 460 - ptype = ICE_PTYPE_IPV6_TCP_PAY; 461 - break; 462 - case VIRTCHNL_PROTO_HDR_SCTP: 463 - if (is_ipv4) 464 - ptype = ICE_PTYPE_IPV4_SCTP_PAY; 465 - else if (is_ipv6) 466 - ptype = ICE_PTYPE_IPV6_SCTP_PAY; 467 - break; 468 - case VIRTCHNL_PROTO_HDR_GTPU_IP: 469 - case VIRTCHNL_PROTO_HDR_GTPU_EH: 470 - if (is_ipv4) 471 - ptype = ICE_MAC_IPV4_GTPU; 472 - else if (is_ipv6) 473 - ptype = ICE_MAC_IPV6_GTPU; 474 - goto out; 475 - case VIRTCHNL_PROTO_HDR_L2TPV3: 476 - if (is_ipv4) 477 - ptype = ICE_MAC_IPV4_L2TPV3; 478 - else if (is_ipv6) 479 - ptype = ICE_MAC_IPV6_L2TPV3; 480 - goto out; 481 - case VIRTCHNL_PROTO_HDR_ESP: 482 - if (is_ipv4) 483 - ptype = is_udp ? ICE_MAC_IPV4_NAT_T_ESP : 484 - ICE_MAC_IPV4_ESP; 485 - else if (is_ipv6) 486 - ptype = is_udp ? ICE_MAC_IPV6_NAT_T_ESP : 487 - ICE_MAC_IPV6_ESP; 488 - goto out; 489 - case VIRTCHNL_PROTO_HDR_AH: 490 - if (is_ipv4) 491 - ptype = ICE_MAC_IPV4_AH; 492 - else if (is_ipv6) 493 - ptype = ICE_MAC_IPV6_AH; 494 - goto out; 495 - case VIRTCHNL_PROTO_HDR_PFCP: 496 - if (is_ipv4) 497 - ptype = ICE_MAC_IPV4_PFCP_SESSION; 498 - else if (is_ipv6) 499 - ptype = ICE_MAC_IPV6_PFCP_SESSION; 500 - goto out; 501 - default: 502 - break; 503 - } 504 - i++; 505 - } 506 - 507 - out: 508 - return ice_hw_ptype_ena(&vf->pf->hw, ptype); 509 - } 510 - 511 - /** 512 - * ice_vc_parse_rss_cfg - parses hash fields and headers from 513 - * a specific virtchnl RSS cfg 514 - * @hw: pointer to the hardware 515 - * @rss_cfg: pointer to the virtchnl RSS cfg 516 - * @hash_cfg: pointer to the HW hash configuration 517 - * 518 - * Return true if all the protocol header and hash fields in the RSS cfg could 519 - * be parsed, else return false 520 - * 521 - * This function parses the virtchnl RSS cfg to be the intended 522 - * hash fields and the intended header for RSS configuration 523 - */ 524 - static bool ice_vc_parse_rss_cfg(struct ice_hw *hw, 525 - struct virtchnl_rss_cfg *rss_cfg, 526 - struct ice_rss_hash_cfg *hash_cfg) 527 - { 528 - const struct ice_vc_hash_field_match_type *hf_list; 529 - const struct ice_vc_hdr_match_type *hdr_list; 530 - int i, hf_list_len, hdr_list_len; 531 - u32 *addl_hdrs = &hash_cfg->addl_hdrs; 532 - u64 *hash_flds = &hash_cfg->hash_flds; 533 - 534 - /* set outer layer RSS as default */ 535 - hash_cfg->hdr_type = ICE_RSS_OUTER_HEADERS; 536 - 537 - if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC) 538 - hash_cfg->symm = true; 539 - else 540 - hash_cfg->symm = false; 541 - 542 - hf_list = ice_vc_hash_field_list; 543 - hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list); 544 - hdr_list = ice_vc_hdr_list; 545 - hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list); 546 - 547 - for (i = 0; i < rss_cfg->proto_hdrs.count; i++) { 548 - struct virtchnl_proto_hdr *proto_hdr = 549 - &rss_cfg->proto_hdrs.proto_hdr[i]; 550 - bool hdr_found = false; 551 - int j; 552 - 553 - /* Find matched ice headers according to virtchnl headers. */ 554 - for (j = 0; j < hdr_list_len; j++) { 555 - struct ice_vc_hdr_match_type hdr_map = hdr_list[j]; 556 - 557 - if (proto_hdr->type == hdr_map.vc_hdr) { 558 - *addl_hdrs |= hdr_map.ice_hdr; 559 - hdr_found = true; 560 - } 561 - } 562 - 563 - if (!hdr_found) 564 - return false; 565 - 566 - /* Find matched ice hash fields according to 567 - * virtchnl hash fields. 568 - */ 569 - for (j = 0; j < hf_list_len; j++) { 570 - struct ice_vc_hash_field_match_type hf_map = hf_list[j]; 571 - 572 - if (proto_hdr->type == hf_map.vc_hdr && 573 - proto_hdr->field_selector == hf_map.vc_hash_field) { 574 - *hash_flds |= hf_map.ice_hash_field; 575 - break; 576 - } 577 - } 578 - } 579 - 580 - return true; 581 - } 582 - 583 - /** 584 - * ice_vf_adv_rss_offload_ena - determine if capabilities support advanced 585 - * RSS offloads 586 - * @caps: VF driver negotiated capabilities 587 - * 588 - * Return true if VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF capability is set, 589 - * else return false 590 - */ 591 - static bool ice_vf_adv_rss_offload_ena(u32 caps) 592 - { 593 - return !!(caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF); 594 - } 595 - 596 - /** 597 - * ice_vc_handle_rss_cfg 598 - * @vf: pointer to the VF info 599 - * @msg: pointer to the message buffer 600 - * @add: add a RSS config if true, otherwise delete a RSS config 601 - * 602 - * This function adds/deletes a RSS config 603 - */ 604 - static int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add) 605 - { 606 - u32 v_opcode = add ? VIRTCHNL_OP_ADD_RSS_CFG : VIRTCHNL_OP_DEL_RSS_CFG; 607 - struct virtchnl_rss_cfg *rss_cfg = (struct virtchnl_rss_cfg *)msg; 608 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 609 - struct device *dev = ice_pf_to_dev(vf->pf); 610 - struct ice_hw *hw = &vf->pf->hw; 611 - struct ice_vsi *vsi; 612 - 613 - if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 614 - dev_dbg(dev, "VF %d attempting to configure RSS, but RSS is not supported by the PF\n", 615 - vf->vf_id); 616 - v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED; 617 - goto error_param; 618 - } 619 - 620 - if (!ice_vf_adv_rss_offload_ena(vf->driver_caps)) { 621 - dev_dbg(dev, "VF %d attempting to configure RSS, but Advanced RSS offload is not supported\n", 622 - vf->vf_id); 623 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 624 - goto error_param; 625 - } 626 - 627 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 628 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 629 - goto error_param; 630 - } 631 - 632 - if (rss_cfg->proto_hdrs.count > VIRTCHNL_MAX_NUM_PROTO_HDRS || 633 - rss_cfg->rss_algorithm < VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC || 634 - rss_cfg->rss_algorithm > VIRTCHNL_RSS_ALG_XOR_SYMMETRIC) { 635 - dev_dbg(dev, "VF %d attempting to configure RSS, but RSS configuration is not valid\n", 636 - vf->vf_id); 637 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 638 - goto error_param; 639 - } 640 - 641 - vsi = ice_get_vf_vsi(vf); 642 - if (!vsi) { 643 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 644 - goto error_param; 645 - } 646 - 647 - if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) { 648 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 649 - goto error_param; 650 - } 651 - 652 - if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_R_ASYMMETRIC) { 653 - struct ice_vsi_ctx *ctx; 654 - u8 lut_type, hash_type; 655 - int status; 656 - 657 - lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI; 658 - hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_HASH_XOR : 659 - ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; 660 - 661 - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 662 - if (!ctx) { 663 - v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 664 - goto error_param; 665 - } 666 - 667 - ctx->info.q_opt_rss = 668 - FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_LUT_M, lut_type) | 669 - FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_HASH_M, hash_type); 670 - 671 - /* Preserve existing queueing option setting */ 672 - ctx->info.q_opt_rss |= (vsi->info.q_opt_rss & 673 - ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_M); 674 - ctx->info.q_opt_tc = vsi->info.q_opt_tc; 675 - ctx->info.q_opt_flags = vsi->info.q_opt_rss; 676 - 677 - ctx->info.valid_sections = 678 - cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID); 679 - 680 - status = ice_update_vsi(hw, vsi->idx, ctx, NULL); 681 - if (status) { 682 - dev_err(dev, "update VSI for RSS failed, err %d aq_err %s\n", 683 - status, libie_aq_str(hw->adminq.sq_last_status)); 684 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 685 - } else { 686 - vsi->info.q_opt_rss = ctx->info.q_opt_rss; 687 - } 688 - 689 - kfree(ctx); 690 - } else { 691 - struct ice_rss_hash_cfg cfg; 692 - 693 - /* Only check for none raw pattern case */ 694 - if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) { 695 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 696 - goto error_param; 697 - } 698 - cfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE; 699 - cfg.hash_flds = ICE_HASH_INVALID; 700 - cfg.hdr_type = ICE_RSS_ANY_HEADERS; 701 - 702 - if (!ice_vc_parse_rss_cfg(hw, rss_cfg, &cfg)) { 703 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 704 - goto error_param; 705 - } 706 - 707 - if (add) { 708 - if (ice_add_rss_cfg(hw, vsi, &cfg)) { 709 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 710 - dev_err(dev, "ice_add_rss_cfg failed for vsi = %d, v_ret = %d\n", 711 - vsi->vsi_num, v_ret); 712 - } 713 - } else { 714 - int status; 715 - 716 - status = ice_rem_rss_cfg(hw, vsi->idx, &cfg); 717 - /* We just ignore -ENOENT, because if two configurations 718 - * share the same profile remove one of them actually 719 - * removes both, since the profile is deleted. 720 - */ 721 - if (status && status != -ENOENT) { 722 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 723 - dev_err(dev, "ice_rem_rss_cfg failed for VF ID:%d, error:%d\n", 724 - vf->vf_id, status); 725 - } 726 - } 727 - } 728 - 729 - error_param: 730 - return ice_vc_send_msg_to_vf(vf, v_opcode, v_ret, NULL, 0); 731 - } 732 - 733 - /** 734 - * ice_vc_config_rss_key 735 - * @vf: pointer to the VF info 736 - * @msg: pointer to the msg buffer 737 - * 738 - * Configure the VF's RSS key 739 - */ 740 - static int ice_vc_config_rss_key(struct ice_vf *vf, u8 *msg) 741 - { 742 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 743 - struct virtchnl_rss_key *vrk = 744 - (struct virtchnl_rss_key *)msg; 745 - struct ice_vsi *vsi; 746 - 747 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 748 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 749 - goto error_param; 750 - } 751 - 752 - if (!ice_vc_isvalid_vsi_id(vf, vrk->vsi_id)) { 753 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 754 - goto error_param; 755 - } 756 - 757 - if (vrk->key_len != ICE_VSIQF_HKEY_ARRAY_SIZE) { 758 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 759 - goto error_param; 760 - } 761 - 762 - if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 763 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 764 - goto error_param; 765 - } 766 - 767 - vsi = ice_get_vf_vsi(vf); 768 - if (!vsi) { 769 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 770 - goto error_param; 771 - } 772 - 773 - if (ice_set_rss_key(vsi, vrk->key)) 774 - v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 775 - error_param: 776 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_KEY, v_ret, 777 - NULL, 0); 778 - } 779 - 780 - /** 781 - * ice_vc_config_rss_lut 782 - * @vf: pointer to the VF info 783 - * @msg: pointer to the msg buffer 784 - * 785 - * Configure the VF's RSS LUT 786 - */ 787 - static int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg) 788 - { 789 - struct virtchnl_rss_lut *vrl = (struct virtchnl_rss_lut *)msg; 790 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 791 - struct ice_vsi *vsi; 792 - 793 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 794 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 795 - goto error_param; 796 - } 797 - 798 - if (!ice_vc_isvalid_vsi_id(vf, vrl->vsi_id)) { 799 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 800 - goto error_param; 801 - } 802 - 803 - if (vrl->lut_entries != ICE_LUT_VSI_SIZE) { 804 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 805 - goto error_param; 806 - } 807 - 808 - if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 809 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 810 - goto error_param; 811 - } 812 - 813 - vsi = ice_get_vf_vsi(vf); 814 - if (!vsi) { 815 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 816 - goto error_param; 817 - } 818 - 819 - if (ice_set_rss_lut(vsi, vrl->lut, ICE_LUT_VSI_SIZE)) 820 - v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 821 - error_param: 822 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_LUT, v_ret, 823 - NULL, 0); 824 - } 825 - 826 - /** 827 - * ice_vc_config_rss_hfunc 828 - * @vf: pointer to the VF info 829 - * @msg: pointer to the msg buffer 830 - * 831 - * Configure the VF's RSS Hash function 832 - */ 833 - static int ice_vc_config_rss_hfunc(struct ice_vf *vf, u8 *msg) 834 - { 835 - struct virtchnl_rss_hfunc *vrh = (struct virtchnl_rss_hfunc *)msg; 836 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 837 - u8 hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; 838 - struct ice_vsi *vsi; 839 - 840 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 841 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 842 - goto error_param; 843 - } 844 - 845 - if (!ice_vc_isvalid_vsi_id(vf, vrh->vsi_id)) { 846 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 847 - goto error_param; 848 - } 849 - 850 - if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 851 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 852 - goto error_param; 853 - } 854 - 855 - vsi = ice_get_vf_vsi(vf); 856 - if (!vsi) { 857 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 858 - goto error_param; 859 - } 860 - 861 - if (vrh->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC) 862 - hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ; 863 - 864 - if (ice_set_rss_hfunc(vsi, hfunc)) 865 - v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 866 - error_param: 867 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_HFUNC, v_ret, 868 - NULL, 0); 869 - } 870 - 871 - /** 872 562 * ice_vc_get_qos_caps - Get current QoS caps from PF 873 563 * @vf: pointer to the VF info 874 564 * ··· 465 1119 (u8 *)cap_list, len); 466 1120 kfree(cap_list); 467 1121 return ret; 468 - } 469 - 470 - /** 471 - * ice_vf_cfg_qs_bw - Configure per queue bandwidth 472 - * @vf: pointer to the VF info 473 - * @num_queues: number of queues to be configured 474 - * 475 - * Configure per queue bandwidth. 476 - * 477 - * Return: 0 on success or negative error value. 478 - */ 479 - static int ice_vf_cfg_qs_bw(struct ice_vf *vf, u16 num_queues) 480 - { 481 - struct ice_hw *hw = &vf->pf->hw; 482 - struct ice_vsi *vsi; 483 - int ret; 484 - u16 i; 485 - 486 - vsi = ice_get_vf_vsi(vf); 487 - if (!vsi) 488 - return -EINVAL; 489 - 490 - for (i = 0; i < num_queues; i++) { 491 - u32 p_rate, min_rate; 492 - u8 tc; 493 - 494 - p_rate = vf->qs_bw[i].peak; 495 - min_rate = vf->qs_bw[i].committed; 496 - tc = vf->qs_bw[i].tc; 497 - if (p_rate) 498 - ret = ice_cfg_q_bw_lmt(hw->port_info, vsi->idx, tc, 499 - vf->qs_bw[i].queue_id, 500 - ICE_MAX_BW, p_rate); 501 - else 502 - ret = ice_cfg_q_bw_dflt_lmt(hw->port_info, vsi->idx, tc, 503 - vf->qs_bw[i].queue_id, 504 - ICE_MAX_BW); 505 - if (ret) 506 - return ret; 507 - 508 - if (min_rate) 509 - ret = ice_cfg_q_bw_lmt(hw->port_info, vsi->idx, tc, 510 - vf->qs_bw[i].queue_id, 511 - ICE_MIN_BW, min_rate); 512 - else 513 - ret = ice_cfg_q_bw_dflt_lmt(hw->port_info, vsi->idx, tc, 514 - vf->qs_bw[i].queue_id, 515 - ICE_MIN_BW); 516 - 517 - if (ret) 518 - return ret; 519 - } 520 - 521 - return 0; 522 - } 523 - 524 - /** 525 - * ice_vf_cfg_q_quanta_profile - Configure quanta profile 526 - * @vf: pointer to the VF info 527 - * @quanta_prof_idx: pointer to the quanta profile index 528 - * @quanta_size: quanta size to be set 529 - * 530 - * This function chooses available quanta profile and configures the register. 531 - * The quanta profile is evenly divided by the number of device ports, and then 532 - * available to the specific PF and VFs. The first profile for each PF is a 533 - * reserved default profile. Only quanta size of the rest unused profile can be 534 - * modified. 535 - * 536 - * Return: 0 on success or negative error value. 537 - */ 538 - static int ice_vf_cfg_q_quanta_profile(struct ice_vf *vf, u16 quanta_size, 539 - u16 *quanta_prof_idx) 540 - { 541 - const u16 n_desc = calc_quanta_desc(quanta_size); 542 - struct ice_hw *hw = &vf->pf->hw; 543 - const u16 n_cmd = 2 * n_desc; 544 - struct ice_pf *pf = vf->pf; 545 - u16 per_pf, begin_id; 546 - u8 n_used; 547 - u32 reg; 548 - 549 - begin_id = (GLCOMM_QUANTA_PROF_MAX_INDEX + 1) / hw->dev_caps.num_funcs * 550 - hw->logical_pf_id; 551 - 552 - if (quanta_size == ICE_DFLT_QUANTA) { 553 - *quanta_prof_idx = begin_id; 554 - } else { 555 - per_pf = (GLCOMM_QUANTA_PROF_MAX_INDEX + 1) / 556 - hw->dev_caps.num_funcs; 557 - n_used = pf->num_quanta_prof_used; 558 - if (n_used < per_pf) { 559 - *quanta_prof_idx = begin_id + 1 + n_used; 560 - pf->num_quanta_prof_used++; 561 - } else { 562 - return -EINVAL; 563 - } 564 - } 565 - 566 - reg = FIELD_PREP(GLCOMM_QUANTA_PROF_QUANTA_SIZE_M, quanta_size) | 567 - FIELD_PREP(GLCOMM_QUANTA_PROF_MAX_CMD_M, n_cmd) | 568 - FIELD_PREP(GLCOMM_QUANTA_PROF_MAX_DESC_M, n_desc); 569 - wr32(hw, GLCOMM_QUANTA_PROF(*quanta_prof_idx), reg); 570 - 571 - return 0; 572 1122 } 573 1123 574 1124 /** ··· 646 1404 /* send the response to the VF */ 647 1405 return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_STATS, v_ret, 648 1406 (u8 *)&stats, sizeof(stats)); 649 - } 650 - 651 - /** 652 - * ice_vc_validate_vqs_bitmaps - validate Rx/Tx queue bitmaps from VIRTCHNL 653 - * @vqs: virtchnl_queue_select structure containing bitmaps to validate 654 - * 655 - * Return true on successful validation, else false 656 - */ 657 - static bool ice_vc_validate_vqs_bitmaps(struct virtchnl_queue_select *vqs) 658 - { 659 - if ((!vqs->rx_queues && !vqs->tx_queues) || 660 - vqs->rx_queues >= BIT(ICE_MAX_RSS_QS_PER_VF) || 661 - vqs->tx_queues >= BIT(ICE_MAX_RSS_QS_PER_VF)) 662 - return false; 663 - 664 - return true; 665 - } 666 - 667 - /** 668 - * ice_vf_ena_txq_interrupt - enable Tx queue interrupt via QINT_TQCTL 669 - * @vsi: VSI of the VF to configure 670 - * @q_idx: VF queue index used to determine the queue in the PF's space 671 - */ 672 - void ice_vf_ena_txq_interrupt(struct ice_vsi *vsi, u32 q_idx) 673 - { 674 - struct ice_hw *hw = &vsi->back->hw; 675 - u32 pfq = vsi->txq_map[q_idx]; 676 - u32 reg; 677 - 678 - reg = rd32(hw, QINT_TQCTL(pfq)); 679 - 680 - /* MSI-X index 0 in the VF's space is always for the OICR, which means 681 - * this is most likely a poll mode VF driver, so don't enable an 682 - * interrupt that was never configured via VIRTCHNL_OP_CONFIG_IRQ_MAP 683 - */ 684 - if (!(reg & QINT_TQCTL_MSIX_INDX_M)) 685 - return; 686 - 687 - wr32(hw, QINT_TQCTL(pfq), reg | QINT_TQCTL_CAUSE_ENA_M); 688 - } 689 - 690 - /** 691 - * ice_vf_ena_rxq_interrupt - enable Tx queue interrupt via QINT_RQCTL 692 - * @vsi: VSI of the VF to configure 693 - * @q_idx: VF queue index used to determine the queue in the PF's space 694 - */ 695 - void ice_vf_ena_rxq_interrupt(struct ice_vsi *vsi, u32 q_idx) 696 - { 697 - struct ice_hw *hw = &vsi->back->hw; 698 - u32 pfq = vsi->rxq_map[q_idx]; 699 - u32 reg; 700 - 701 - reg = rd32(hw, QINT_RQCTL(pfq)); 702 - 703 - /* MSI-X index 0 in the VF's space is always for the OICR, which means 704 - * this is most likely a poll mode VF driver, so don't enable an 705 - * interrupt that was never configured via VIRTCHNL_OP_CONFIG_IRQ_MAP 706 - */ 707 - if (!(reg & QINT_RQCTL_MSIX_INDX_M)) 708 - return; 709 - 710 - wr32(hw, QINT_RQCTL(pfq), reg | QINT_RQCTL_CAUSE_ENA_M); 711 - } 712 - 713 - /** 714 - * ice_vc_ena_qs_msg 715 - * @vf: pointer to the VF info 716 - * @msg: pointer to the msg buffer 717 - * 718 - * called from the VF to enable all or specific queue(s) 719 - */ 720 - static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg) 721 - { 722 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 723 - struct virtchnl_queue_select *vqs = 724 - (struct virtchnl_queue_select *)msg; 725 - struct ice_vsi *vsi; 726 - unsigned long q_map; 727 - u16 vf_q_id; 728 - 729 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 730 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 731 - goto error_param; 732 - } 733 - 734 - if (!ice_vc_isvalid_vsi_id(vf, vqs->vsi_id)) { 735 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 736 - goto error_param; 737 - } 738 - 739 - if (!ice_vc_validate_vqs_bitmaps(vqs)) { 740 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 741 - goto error_param; 742 - } 743 - 744 - vsi = ice_get_vf_vsi(vf); 745 - if (!vsi) { 746 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 747 - goto error_param; 748 - } 749 - 750 - /* Enable only Rx rings, Tx rings were enabled by the FW when the 751 - * Tx queue group list was configured and the context bits were 752 - * programmed using ice_vsi_cfg_txqs 753 - */ 754 - q_map = vqs->rx_queues; 755 - for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { 756 - if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) { 757 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 758 - goto error_param; 759 - } 760 - 761 - /* Skip queue if enabled */ 762 - if (test_bit(vf_q_id, vf->rxq_ena)) 763 - continue; 764 - 765 - if (ice_vsi_ctrl_one_rx_ring(vsi, true, vf_q_id, true)) { 766 - dev_err(ice_pf_to_dev(vsi->back), "Failed to enable Rx ring %d on VSI %d\n", 767 - vf_q_id, vsi->vsi_num); 768 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 769 - goto error_param; 770 - } 771 - 772 - ice_vf_ena_rxq_interrupt(vsi, vf_q_id); 773 - set_bit(vf_q_id, vf->rxq_ena); 774 - } 775 - 776 - q_map = vqs->tx_queues; 777 - for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { 778 - if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) { 779 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 780 - goto error_param; 781 - } 782 - 783 - /* Skip queue if enabled */ 784 - if (test_bit(vf_q_id, vf->txq_ena)) 785 - continue; 786 - 787 - ice_vf_ena_txq_interrupt(vsi, vf_q_id); 788 - set_bit(vf_q_id, vf->txq_ena); 789 - } 790 - 791 - /* Set flag to indicate that queues are enabled */ 792 - if (v_ret == VIRTCHNL_STATUS_SUCCESS) 793 - set_bit(ICE_VF_STATE_QS_ENA, vf->vf_states); 794 - 795 - error_param: 796 - /* send the response to the VF */ 797 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_QUEUES, v_ret, 798 - NULL, 0); 799 - } 800 - 801 - /** 802 - * ice_vf_vsi_dis_single_txq - disable a single Tx queue 803 - * @vf: VF to disable queue for 804 - * @vsi: VSI for the VF 805 - * @q_id: VF relative (0-based) queue ID 806 - * 807 - * Attempt to disable the Tx queue passed in. If the Tx queue was successfully 808 - * disabled then clear q_id bit in the enabled queues bitmap and return 809 - * success. Otherwise return error. 810 - */ 811 - int ice_vf_vsi_dis_single_txq(struct ice_vf *vf, struct ice_vsi *vsi, u16 q_id) 812 - { 813 - struct ice_txq_meta txq_meta = { 0 }; 814 - struct ice_tx_ring *ring; 815 - int err; 816 - 817 - if (!test_bit(q_id, vf->txq_ena)) 818 - dev_dbg(ice_pf_to_dev(vsi->back), "Queue %u on VSI %u is not enabled, but stopping it anyway\n", 819 - q_id, vsi->vsi_num); 820 - 821 - ring = vsi->tx_rings[q_id]; 822 - if (!ring) 823 - return -EINVAL; 824 - 825 - ice_fill_txq_meta(vsi, ring, &txq_meta); 826 - 827 - err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, vf->vf_id, ring, &txq_meta); 828 - if (err) { 829 - dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Tx ring %d on VSI %d\n", 830 - q_id, vsi->vsi_num); 831 - return err; 832 - } 833 - 834 - /* Clear enabled queues flag */ 835 - clear_bit(q_id, vf->txq_ena); 836 - 837 - return 0; 838 - } 839 - 840 - /** 841 - * ice_vc_dis_qs_msg 842 - * @vf: pointer to the VF info 843 - * @msg: pointer to the msg buffer 844 - * 845 - * called from the VF to disable all or specific queue(s) 846 - */ 847 - static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) 848 - { 849 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 850 - struct virtchnl_queue_select *vqs = 851 - (struct virtchnl_queue_select *)msg; 852 - struct ice_vsi *vsi; 853 - unsigned long q_map; 854 - u16 vf_q_id; 855 - 856 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) && 857 - !test_bit(ICE_VF_STATE_QS_ENA, vf->vf_states)) { 858 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 859 - goto error_param; 860 - } 861 - 862 - if (!ice_vc_isvalid_vsi_id(vf, vqs->vsi_id)) { 863 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 864 - goto error_param; 865 - } 866 - 867 - if (!ice_vc_validate_vqs_bitmaps(vqs)) { 868 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 869 - goto error_param; 870 - } 871 - 872 - vsi = ice_get_vf_vsi(vf); 873 - if (!vsi) { 874 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 875 - goto error_param; 876 - } 877 - 878 - if (vqs->tx_queues) { 879 - q_map = vqs->tx_queues; 880 - 881 - for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { 882 - if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) { 883 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 884 - goto error_param; 885 - } 886 - 887 - if (ice_vf_vsi_dis_single_txq(vf, vsi, vf_q_id)) { 888 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 889 - goto error_param; 890 - } 891 - } 892 - } 893 - 894 - q_map = vqs->rx_queues; 895 - /* speed up Rx queue disable by batching them if possible */ 896 - if (q_map && 897 - bitmap_equal(&q_map, vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF)) { 898 - if (ice_vsi_stop_all_rx_rings(vsi)) { 899 - dev_err(ice_pf_to_dev(vsi->back), "Failed to stop all Rx rings on VSI %d\n", 900 - vsi->vsi_num); 901 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 902 - goto error_param; 903 - } 904 - 905 - bitmap_zero(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF); 906 - } else if (q_map) { 907 - for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { 908 - if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) { 909 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 910 - goto error_param; 911 - } 912 - 913 - /* Skip queue if not enabled */ 914 - if (!test_bit(vf_q_id, vf->rxq_ena)) 915 - continue; 916 - 917 - if (ice_vsi_ctrl_one_rx_ring(vsi, false, vf_q_id, 918 - true)) { 919 - dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Rx ring %d on VSI %d\n", 920 - vf_q_id, vsi->vsi_num); 921 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 922 - goto error_param; 923 - } 924 - 925 - /* Clear enabled queues flag */ 926 - clear_bit(vf_q_id, vf->rxq_ena); 927 - } 928 - } 929 - 930 - /* Clear enabled queues flag */ 931 - if (v_ret == VIRTCHNL_STATUS_SUCCESS && ice_vf_has_no_qs_ena(vf)) 932 - clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states); 933 - 934 - error_param: 935 - /* send the response to the VF */ 936 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_QUEUES, v_ret, 937 - NULL, 0); 938 - } 939 - 940 - /** 941 - * ice_cfg_interrupt 942 - * @vf: pointer to the VF info 943 - * @vsi: the VSI being configured 944 - * @map: vector map for mapping vectors to queues 945 - * @q_vector: structure for interrupt vector 946 - * configure the IRQ to queue map 947 - */ 948 - static enum virtchnl_status_code 949 - ice_cfg_interrupt(struct ice_vf *vf, struct ice_vsi *vsi, 950 - struct virtchnl_vector_map *map, 951 - struct ice_q_vector *q_vector) 952 - { 953 - u16 vsi_q_id, vsi_q_id_idx; 954 - unsigned long qmap; 955 - 956 - q_vector->num_ring_rx = 0; 957 - q_vector->num_ring_tx = 0; 958 - 959 - qmap = map->rxq_map; 960 - for_each_set_bit(vsi_q_id_idx, &qmap, ICE_MAX_RSS_QS_PER_VF) { 961 - vsi_q_id = vsi_q_id_idx; 962 - 963 - if (!ice_vc_isvalid_q_id(vsi, vsi_q_id)) 964 - return VIRTCHNL_STATUS_ERR_PARAM; 965 - 966 - q_vector->num_ring_rx++; 967 - q_vector->rx.itr_idx = map->rxitr_idx; 968 - vsi->rx_rings[vsi_q_id]->q_vector = q_vector; 969 - ice_cfg_rxq_interrupt(vsi, vsi_q_id, 970 - q_vector->vf_reg_idx, 971 - q_vector->rx.itr_idx); 972 - } 973 - 974 - qmap = map->txq_map; 975 - for_each_set_bit(vsi_q_id_idx, &qmap, ICE_MAX_RSS_QS_PER_VF) { 976 - vsi_q_id = vsi_q_id_idx; 977 - 978 - if (!ice_vc_isvalid_q_id(vsi, vsi_q_id)) 979 - return VIRTCHNL_STATUS_ERR_PARAM; 980 - 981 - q_vector->num_ring_tx++; 982 - q_vector->tx.itr_idx = map->txitr_idx; 983 - vsi->tx_rings[vsi_q_id]->q_vector = q_vector; 984 - ice_cfg_txq_interrupt(vsi, vsi_q_id, 985 - q_vector->vf_reg_idx, 986 - q_vector->tx.itr_idx); 987 - } 988 - 989 - return VIRTCHNL_STATUS_SUCCESS; 990 - } 991 - 992 - /** 993 - * ice_vc_cfg_irq_map_msg 994 - * @vf: pointer to the VF info 995 - * @msg: pointer to the msg buffer 996 - * 997 - * called from the VF to configure the IRQ to queue map 998 - */ 999 - static int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg) 1000 - { 1001 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1002 - u16 num_q_vectors_mapped, vsi_id, vector_id; 1003 - struct virtchnl_irq_map_info *irqmap_info; 1004 - struct virtchnl_vector_map *map; 1005 - struct ice_vsi *vsi; 1006 - int i; 1007 - 1008 - irqmap_info = (struct virtchnl_irq_map_info *)msg; 1009 - num_q_vectors_mapped = irqmap_info->num_vectors; 1010 - 1011 - /* Check to make sure number of VF vectors mapped is not greater than 1012 - * number of VF vectors originally allocated, and check that 1013 - * there is actually at least a single VF queue vector mapped 1014 - */ 1015 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) || 1016 - vf->num_msix < num_q_vectors_mapped || 1017 - !num_q_vectors_mapped) { 1018 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1019 - goto error_param; 1020 - } 1021 - 1022 - vsi = ice_get_vf_vsi(vf); 1023 - if (!vsi) { 1024 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1025 - goto error_param; 1026 - } 1027 - 1028 - for (i = 0; i < num_q_vectors_mapped; i++) { 1029 - struct ice_q_vector *q_vector; 1030 - 1031 - map = &irqmap_info->vecmap[i]; 1032 - 1033 - vector_id = map->vector_id; 1034 - vsi_id = map->vsi_id; 1035 - /* vector_id is always 0-based for each VF, and can never be 1036 - * larger than or equal to the max allowed interrupts per VF 1037 - */ 1038 - if (!(vector_id < vf->num_msix) || 1039 - !ice_vc_isvalid_vsi_id(vf, vsi_id) || 1040 - (!vector_id && (map->rxq_map || map->txq_map))) { 1041 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1042 - goto error_param; 1043 - } 1044 - 1045 - /* No need to map VF miscellaneous or rogue vector */ 1046 - if (!vector_id) 1047 - continue; 1048 - 1049 - /* Subtract non queue vector from vector_id passed by VF 1050 - * to get actual number of VSI queue vector array index 1051 - */ 1052 - q_vector = vsi->q_vectors[vector_id - ICE_NONQ_VECS_VF]; 1053 - if (!q_vector) { 1054 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1055 - goto error_param; 1056 - } 1057 - 1058 - /* lookout for the invalid queue index */ 1059 - v_ret = ice_cfg_interrupt(vf, vsi, map, q_vector); 1060 - if (v_ret) 1061 - goto error_param; 1062 - } 1063 - 1064 - error_param: 1065 - /* send the response to the VF */ 1066 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_IRQ_MAP, v_ret, 1067 - NULL, 0); 1068 - } 1069 - 1070 - /** 1071 - * ice_vc_cfg_q_bw - Configure per queue bandwidth 1072 - * @vf: pointer to the VF info 1073 - * @msg: pointer to the msg buffer which holds the command descriptor 1074 - * 1075 - * Configure VF queues bandwidth. 1076 - * 1077 - * Return: 0 on success or negative error value. 1078 - */ 1079 - static int ice_vc_cfg_q_bw(struct ice_vf *vf, u8 *msg) 1080 - { 1081 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1082 - struct virtchnl_queues_bw_cfg *qbw = 1083 - (struct virtchnl_queues_bw_cfg *)msg; 1084 - struct ice_vsi *vsi; 1085 - u16 i; 1086 - 1087 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) || 1088 - !ice_vc_isvalid_vsi_id(vf, qbw->vsi_id)) { 1089 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1090 - goto err; 1091 - } 1092 - 1093 - vsi = ice_get_vf_vsi(vf); 1094 - if (!vsi) { 1095 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1096 - goto err; 1097 - } 1098 - 1099 - if (qbw->num_queues > ICE_MAX_RSS_QS_PER_VF || 1100 - qbw->num_queues > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) { 1101 - dev_err(ice_pf_to_dev(vf->pf), "VF-%d trying to configure more than allocated number of queues: %d\n", 1102 - vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); 1103 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1104 - goto err; 1105 - } 1106 - 1107 - for (i = 0; i < qbw->num_queues; i++) { 1108 - if (qbw->cfg[i].shaper.peak != 0 && vf->max_tx_rate != 0 && 1109 - qbw->cfg[i].shaper.peak > vf->max_tx_rate) { 1110 - dev_warn(ice_pf_to_dev(vf->pf), "The maximum queue %d rate limit configuration may not take effect because the maximum TX rate for VF-%d is %d\n", 1111 - qbw->cfg[i].queue_id, vf->vf_id, 1112 - vf->max_tx_rate); 1113 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1114 - goto err; 1115 - } 1116 - if (qbw->cfg[i].shaper.committed != 0 && vf->min_tx_rate != 0 && 1117 - qbw->cfg[i].shaper.committed < vf->min_tx_rate) { 1118 - dev_warn(ice_pf_to_dev(vf->pf), "The minimum queue %d rate limit configuration may not take effect because the minimum TX rate for VF-%d is %d\n", 1119 - qbw->cfg[i].queue_id, vf->vf_id, 1120 - vf->min_tx_rate); 1121 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1122 - goto err; 1123 - } 1124 - if (qbw->cfg[i].queue_id > vf->num_vf_qs) { 1125 - dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure invalid queue_id\n", 1126 - vf->vf_id); 1127 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1128 - goto err; 1129 - } 1130 - if (qbw->cfg[i].tc >= ICE_MAX_TRAFFIC_CLASS) { 1131 - dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure a traffic class higher than allowed\n", 1132 - vf->vf_id); 1133 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1134 - goto err; 1135 - } 1136 - } 1137 - 1138 - for (i = 0; i < qbw->num_queues; i++) { 1139 - vf->qs_bw[i].queue_id = qbw->cfg[i].queue_id; 1140 - vf->qs_bw[i].peak = qbw->cfg[i].shaper.peak; 1141 - vf->qs_bw[i].committed = qbw->cfg[i].shaper.committed; 1142 - vf->qs_bw[i].tc = qbw->cfg[i].tc; 1143 - } 1144 - 1145 - if (ice_vf_cfg_qs_bw(vf, qbw->num_queues)) 1146 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1147 - 1148 - err: 1149 - /* send the response to the VF */ 1150 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_QUEUE_BW, 1151 - v_ret, NULL, 0); 1152 - } 1153 - 1154 - /** 1155 - * ice_vc_cfg_q_quanta - Configure per queue quanta 1156 - * @vf: pointer to the VF info 1157 - * @msg: pointer to the msg buffer which holds the command descriptor 1158 - * 1159 - * Configure VF queues quanta. 1160 - * 1161 - * Return: 0 on success or negative error value. 1162 - */ 1163 - static int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg) 1164 - { 1165 - u16 quanta_prof_id, quanta_size, start_qid, num_queues, end_qid, i; 1166 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1167 - struct virtchnl_quanta_cfg *qquanta = 1168 - (struct virtchnl_quanta_cfg *)msg; 1169 - struct ice_vsi *vsi; 1170 - int ret; 1171 - 1172 - start_qid = qquanta->queue_select.start_queue_id; 1173 - num_queues = qquanta->queue_select.num_queues; 1174 - 1175 - if (check_add_overflow(start_qid, num_queues, &end_qid)) { 1176 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1177 - goto err; 1178 - } 1179 - 1180 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1181 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1182 - goto err; 1183 - } 1184 - 1185 - vsi = ice_get_vf_vsi(vf); 1186 - if (!vsi) { 1187 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1188 - goto err; 1189 - } 1190 - 1191 - if (end_qid > ICE_MAX_RSS_QS_PER_VF || 1192 - end_qid > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) { 1193 - dev_err(ice_pf_to_dev(vf->pf), "VF-%d trying to configure more than allocated number of queues: %d\n", 1194 - vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); 1195 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1196 - goto err; 1197 - } 1198 - 1199 - quanta_size = qquanta->quanta_size; 1200 - if (quanta_size > ICE_MAX_QUANTA_SIZE || 1201 - quanta_size < ICE_MIN_QUANTA_SIZE) { 1202 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1203 - goto err; 1204 - } 1205 - 1206 - if (quanta_size % 64) { 1207 - dev_err(ice_pf_to_dev(vf->pf), "quanta size should be the product of 64\n"); 1208 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1209 - goto err; 1210 - } 1211 - 1212 - ret = ice_vf_cfg_q_quanta_profile(vf, quanta_size, 1213 - &quanta_prof_id); 1214 - if (ret) { 1215 - v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED; 1216 - goto err; 1217 - } 1218 - 1219 - for (i = start_qid; i < end_qid; i++) 1220 - vsi->tx_rings[i]->quanta_prof_id = quanta_prof_id; 1221 - 1222 - err: 1223 - /* send the response to the VF */ 1224 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_QUANTA, 1225 - v_ret, NULL, 0); 1226 - } 1227 - 1228 - /** 1229 - * ice_vc_cfg_qs_msg 1230 - * @vf: pointer to the VF info 1231 - * @msg: pointer to the msg buffer 1232 - * 1233 - * called from the VF to configure the Rx/Tx queues 1234 - */ 1235 - static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) 1236 - { 1237 - struct virtchnl_vsi_queue_config_info *qci = 1238 - (struct virtchnl_vsi_queue_config_info *)msg; 1239 - struct virtchnl_queue_pair_info *qpi; 1240 - struct ice_pf *pf = vf->pf; 1241 - struct ice_vsi *vsi; 1242 - int i = -1, q_idx; 1243 - bool ena_ts; 1244 - u8 act_prt; 1245 - 1246 - mutex_lock(&pf->lag_mutex); 1247 - act_prt = ice_lag_prepare_vf_reset(pf->lag); 1248 - 1249 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) 1250 - goto error_param; 1251 - 1252 - if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id)) 1253 - goto error_param; 1254 - 1255 - vsi = ice_get_vf_vsi(vf); 1256 - if (!vsi) 1257 - goto error_param; 1258 - 1259 - if (qci->num_queue_pairs > ICE_MAX_RSS_QS_PER_VF || 1260 - qci->num_queue_pairs > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) { 1261 - dev_err(ice_pf_to_dev(pf), "VF-%d requesting more than supported number of queues: %d\n", 1262 - vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); 1263 - goto error_param; 1264 - } 1265 - 1266 - for (i = 0; i < qci->num_queue_pairs; i++) { 1267 - if (!qci->qpair[i].rxq.crc_disable) 1268 - continue; 1269 - 1270 - if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_CRC) || 1271 - vf->vlan_strip_ena) 1272 - goto error_param; 1273 - } 1274 - 1275 - for (i = 0; i < qci->num_queue_pairs; i++) { 1276 - qpi = &qci->qpair[i]; 1277 - if (qpi->txq.vsi_id != qci->vsi_id || 1278 - qpi->rxq.vsi_id != qci->vsi_id || 1279 - qpi->rxq.queue_id != qpi->txq.queue_id || 1280 - qpi->txq.headwb_enabled || 1281 - !ice_vc_isvalid_ring_len(qpi->txq.ring_len) || 1282 - !ice_vc_isvalid_ring_len(qpi->rxq.ring_len) || 1283 - !ice_vc_isvalid_q_id(vsi, qpi->txq.queue_id)) { 1284 - goto error_param; 1285 - } 1286 - 1287 - q_idx = qpi->rxq.queue_id; 1288 - 1289 - /* make sure selected "q_idx" is in valid range of queues 1290 - * for selected "vsi" 1291 - */ 1292 - if (q_idx >= vsi->alloc_txq || q_idx >= vsi->alloc_rxq) { 1293 - goto error_param; 1294 - } 1295 - 1296 - /* copy Tx queue info from VF into VSI */ 1297 - if (qpi->txq.ring_len > 0) { 1298 - vsi->tx_rings[q_idx]->dma = qpi->txq.dma_ring_addr; 1299 - vsi->tx_rings[q_idx]->count = qpi->txq.ring_len; 1300 - 1301 - /* Disable any existing queue first */ 1302 - if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) 1303 - goto error_param; 1304 - 1305 - /* Configure a queue with the requested settings */ 1306 - if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) { 1307 - dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure TX queue %d\n", 1308 - vf->vf_id, q_idx); 1309 - goto error_param; 1310 - } 1311 - } 1312 - 1313 - /* copy Rx queue info from VF into VSI */ 1314 - if (qpi->rxq.ring_len > 0) { 1315 - u16 max_frame_size = ice_vc_get_max_frame_size(vf); 1316 - struct ice_rx_ring *ring = vsi->rx_rings[q_idx]; 1317 - u32 rxdid; 1318 - 1319 - ring->dma = qpi->rxq.dma_ring_addr; 1320 - ring->count = qpi->rxq.ring_len; 1321 - 1322 - if (qpi->rxq.crc_disable) 1323 - ring->flags |= ICE_RX_FLAGS_CRC_STRIP_DIS; 1324 - else 1325 - ring->flags &= ~ICE_RX_FLAGS_CRC_STRIP_DIS; 1326 - 1327 - if (qpi->rxq.databuffer_size != 0 && 1328 - (qpi->rxq.databuffer_size > ((16 * 1024) - 128) || 1329 - qpi->rxq.databuffer_size < 1024)) 1330 - goto error_param; 1331 - ring->rx_buf_len = qpi->rxq.databuffer_size; 1332 - if (qpi->rxq.max_pkt_size > max_frame_size || 1333 - qpi->rxq.max_pkt_size < 64) 1334 - goto error_param; 1335 - 1336 - ring->max_frame = qpi->rxq.max_pkt_size; 1337 - /* add space for the port VLAN since the VF driver is 1338 - * not expected to account for it in the MTU 1339 - * calculation 1340 - */ 1341 - if (ice_vf_is_port_vlan_ena(vf)) 1342 - ring->max_frame += VLAN_HLEN; 1343 - 1344 - if (ice_vsi_cfg_single_rxq(vsi, q_idx)) { 1345 - dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n", 1346 - vf->vf_id, q_idx); 1347 - goto error_param; 1348 - } 1349 - 1350 - /* If Rx flex desc is supported, select RXDID for Rx 1351 - * queues. Otherwise, use legacy 32byte descriptor 1352 - * format. Legacy 16byte descriptor is not supported. 1353 - * If this RXDID is selected, return error. 1354 - */ 1355 - if (vf->driver_caps & 1356 - VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) { 1357 - rxdid = qpi->rxq.rxdid; 1358 - if (!(BIT(rxdid) & pf->supported_rxdids)) 1359 - goto error_param; 1360 - } else { 1361 - rxdid = ICE_RXDID_LEGACY_1; 1362 - } 1363 - 1364 - ena_ts = ((vf->driver_caps & 1365 - VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) && 1366 - (vf->driver_caps & VIRTCHNL_VF_CAP_PTP) && 1367 - (qpi->rxq.flags & VIRTCHNL_PTP_RX_TSTAMP)); 1368 - 1369 - ice_write_qrxflxp_cntxt(&vsi->back->hw, 1370 - vsi->rxq_map[q_idx], rxdid, 1371 - ICE_RXDID_PRIO, ena_ts); 1372 - } 1373 - } 1374 - 1375 - ice_lag_complete_vf_reset(pf->lag, act_prt); 1376 - mutex_unlock(&pf->lag_mutex); 1377 - 1378 - /* send the response to the VF */ 1379 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, 1380 - VIRTCHNL_STATUS_SUCCESS, NULL, 0); 1381 - error_param: 1382 - /* disable whatever we can */ 1383 - for (; i >= 0; i--) { 1384 - if (ice_vsi_ctrl_one_rx_ring(vsi, false, i, true)) 1385 - dev_err(ice_pf_to_dev(pf), "VF-%d could not disable RX queue %d\n", 1386 - vf->vf_id, i); 1387 - if (ice_vf_vsi_dis_single_txq(vf, vsi, i)) 1388 - dev_err(ice_pf_to_dev(pf), "VF-%d could not disable TX queue %d\n", 1389 - vf->vf_id, i); 1390 - } 1391 - 1392 - ice_lag_complete_vf_reset(pf->lag, act_prt); 1393 - mutex_unlock(&pf->lag_mutex); 1394 - 1395 - ice_lag_move_new_vf_nodes(vf); 1396 - 1397 - /* send the response to the VF */ 1398 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, 1399 - VIRTCHNL_STATUS_ERR_PARAM, NULL, 0); 1400 1407 } 1401 1408 1402 1409 /** ··· 1019 2528 static int ice_vc_del_mac_addr_msg(struct ice_vf *vf, u8 *msg) 1020 2529 { 1021 2530 return ice_vc_handle_mac_addr_msg(vf, msg, false); 1022 - } 1023 - 1024 - /** 1025 - * ice_vc_request_qs_msg 1026 - * @vf: pointer to the VF info 1027 - * @msg: pointer to the msg buffer 1028 - * 1029 - * VFs get a default number of queues but can use this message to request a 1030 - * different number. If the request is successful, PF will reset the VF and 1031 - * return 0. If unsuccessful, PF will send message informing VF of number of 1032 - * available queue pairs via virtchnl message response to VF. 1033 - */ 1034 - static int ice_vc_request_qs_msg(struct ice_vf *vf, u8 *msg) 1035 - { 1036 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1037 - struct virtchnl_vf_res_request *vfres = 1038 - (struct virtchnl_vf_res_request *)msg; 1039 - u16 req_queues = vfres->num_queue_pairs; 1040 - struct ice_pf *pf = vf->pf; 1041 - u16 max_allowed_vf_queues; 1042 - u16 tx_rx_queue_left; 1043 - struct device *dev; 1044 - u16 cur_queues; 1045 - 1046 - dev = ice_pf_to_dev(pf); 1047 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1048 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1049 - goto error_param; 1050 - } 1051 - 1052 - cur_queues = vf->num_vf_qs; 1053 - tx_rx_queue_left = min_t(u16, ice_get_avail_txq_count(pf), 1054 - ice_get_avail_rxq_count(pf)); 1055 - max_allowed_vf_queues = tx_rx_queue_left + cur_queues; 1056 - if (!req_queues) { 1057 - dev_err(dev, "VF %d tried to request 0 queues. Ignoring.\n", 1058 - vf->vf_id); 1059 - } else if (req_queues > ICE_MAX_RSS_QS_PER_VF) { 1060 - dev_err(dev, "VF %d tried to request more than %d queues.\n", 1061 - vf->vf_id, ICE_MAX_RSS_QS_PER_VF); 1062 - vfres->num_queue_pairs = ICE_MAX_RSS_QS_PER_VF; 1063 - } else if (req_queues > cur_queues && 1064 - req_queues - cur_queues > tx_rx_queue_left) { 1065 - dev_warn(dev, "VF %d requested %u more queues, but only %u left.\n", 1066 - vf->vf_id, req_queues - cur_queues, tx_rx_queue_left); 1067 - vfres->num_queue_pairs = min_t(u16, max_allowed_vf_queues, 1068 - ICE_MAX_RSS_QS_PER_VF); 1069 - } else { 1070 - /* request is successful, then reset VF */ 1071 - vf->num_req_qs = req_queues; 1072 - ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); 1073 - dev_info(dev, "VF %d granted request of %u queues.\n", 1074 - vf->vf_id, req_queues); 1075 - return 0; 1076 - } 1077 - 1078 - error_param: 1079 - /* send the response to the VF */ 1080 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 1081 - v_ret, (u8 *)vfres, sizeof(*vfres)); 1082 2531 } 1083 2532 1084 2533 /** ··· 1411 2980 error_param: 1412 2981 return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING, 1413 2982 v_ret, NULL, 0); 1414 - } 1415 - 1416 - /** 1417 - * ice_vc_get_rss_hashcfg - return the RSS Hash configuration 1418 - * @vf: pointer to the VF info 1419 - */ 1420 - static int ice_vc_get_rss_hashcfg(struct ice_vf *vf) 1421 - { 1422 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1423 - struct virtchnl_rss_hashcfg *vrh = NULL; 1424 - int len = 0, ret; 1425 - 1426 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1427 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1428 - goto err; 1429 - } 1430 - 1431 - if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 1432 - dev_err(ice_pf_to_dev(vf->pf), "RSS not supported by PF\n"); 1433 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1434 - goto err; 1435 - } 1436 - 1437 - len = sizeof(struct virtchnl_rss_hashcfg); 1438 - vrh = kzalloc(len, GFP_KERNEL); 1439 - if (!vrh) { 1440 - v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 1441 - len = 0; 1442 - goto err; 1443 - } 1444 - 1445 - vrh->hashcfg = ICE_DEFAULT_RSS_HASHCFG; 1446 - err: 1447 - /* send the response back to the VF */ 1448 - ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_RSS_HASHCFG_CAPS, v_ret, 1449 - (u8 *)vrh, len); 1450 - kfree(vrh); 1451 - return ret; 1452 - } 1453 - 1454 - /** 1455 - * ice_vc_set_rss_hashcfg - set RSS Hash configuration bits for the VF 1456 - * @vf: pointer to the VF info 1457 - * @msg: pointer to the msg buffer 1458 - */ 1459 - static int ice_vc_set_rss_hashcfg(struct ice_vf *vf, u8 *msg) 1460 - { 1461 - struct virtchnl_rss_hashcfg *vrh = (struct virtchnl_rss_hashcfg *)msg; 1462 - enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1463 - struct ice_pf *pf = vf->pf; 1464 - struct ice_vsi *vsi; 1465 - struct device *dev; 1466 - int status; 1467 - 1468 - dev = ice_pf_to_dev(pf); 1469 - 1470 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1471 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1472 - goto err; 1473 - } 1474 - 1475 - if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 1476 - dev_err(dev, "RSS not supported by PF\n"); 1477 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1478 - goto err; 1479 - } 1480 - 1481 - vsi = ice_get_vf_vsi(vf); 1482 - if (!vsi) { 1483 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1484 - goto err; 1485 - } 1486 - 1487 - /* clear all previously programmed RSS configuration to allow VF drivers 1488 - * the ability to customize the RSS configuration and/or completely 1489 - * disable RSS 1490 - */ 1491 - status = ice_rem_vsi_rss_cfg(&pf->hw, vsi->idx); 1492 - if (status && !vrh->hashcfg) { 1493 - /* only report failure to clear the current RSS configuration if 1494 - * that was clearly the VF's intention (i.e. vrh->hashcfg = 0) 1495 - */ 1496 - v_ret = ice_err_to_virt_err(status); 1497 - goto err; 1498 - } else if (status) { 1499 - /* allow the VF to update the RSS configuration even on failure 1500 - * to clear the current RSS confguration in an attempt to keep 1501 - * RSS in a working state 1502 - */ 1503 - dev_warn(dev, "Failed to clear the RSS configuration for VF %u\n", 1504 - vf->vf_id); 1505 - } 1506 - 1507 - if (vrh->hashcfg) { 1508 - status = ice_add_avf_rss_cfg(&pf->hw, vsi, vrh->hashcfg); 1509 - v_ret = ice_err_to_virt_err(status); 1510 - } 1511 - 1512 - /* save the requested VF configuration */ 1513 - if (!v_ret) 1514 - vf->rss_hashcfg = vrh->hashcfg; 1515 - 1516 - /* send the response to the VF */ 1517 - err: 1518 - return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_SET_RSS_HASHCFG, v_ret, 1519 - NULL, 0); 1520 2983 } 1521 2984 1522 2985 /**
drivers/net/ethernet/intel/ice/ice_virtchnl.h drivers/net/ethernet/intel/ice/virt/virtchnl.h
+1 -1
drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.c drivers/net/ethernet/intel/ice/virt/allowlist.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (C) 2021, Intel Corporation. */ 3 3 4 - #include "ice_virtchnl_allowlist.h" 4 + #include "allowlist.h" 5 5 6 6 /* Purpose of this file is to share functionality to allowlist or denylist 7 7 * opcodes used in PF <-> VF communication. Group of opcodes:
drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.h drivers/net/ethernet/intel/ice/virt/allowlist.h
drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c drivers/net/ethernet/intel/ice/virt/fdir.c
drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h drivers/net/ethernet/intel/ice/virt/fdir.h
+975
drivers/net/ethernet/intel/ice/virt/queues.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2022, Intel Corporation. */ 3 + 4 + #include "virtchnl.h" 5 + #include "queues.h" 6 + #include "ice_vf_lib_private.h" 7 + #include "ice.h" 8 + #include "ice_base.h" 9 + #include "ice_lib.h" 10 + 11 + /** 12 + * ice_vc_get_max_frame_size - get max frame size allowed for VF 13 + * @vf: VF used to determine max frame size 14 + * 15 + * Max frame size is determined based on the current port's max frame size and 16 + * whether a port VLAN is configured on this VF. The VF is not aware whether 17 + * it's in a port VLAN so the PF needs to account for this in max frame size 18 + * checks and sending the max frame size to the VF. 19 + */ 20 + u16 ice_vc_get_max_frame_size(struct ice_vf *vf) 21 + { 22 + struct ice_port_info *pi = ice_vf_get_port_info(vf); 23 + u16 max_frame_size; 24 + 25 + max_frame_size = pi->phy.link_info.max_frame_size; 26 + 27 + if (ice_vf_is_port_vlan_ena(vf)) 28 + max_frame_size -= VLAN_HLEN; 29 + 30 + return max_frame_size; 31 + } 32 + 33 + /** 34 + * ice_vc_isvalid_q_id 35 + * @vsi: VSI to check queue ID against 36 + * @qid: VSI relative queue ID 37 + * 38 + * check for the valid queue ID 39 + */ 40 + static bool ice_vc_isvalid_q_id(struct ice_vsi *vsi, u16 qid) 41 + { 42 + /* allocated Tx and Rx queues should be always equal for VF VSI */ 43 + return qid < vsi->alloc_txq; 44 + } 45 + 46 + /** 47 + * ice_vc_isvalid_ring_len 48 + * @ring_len: length of ring 49 + * 50 + * check for the valid ring count, should be multiple of ICE_REQ_DESC_MULTIPLE 51 + * or zero 52 + */ 53 + static bool ice_vc_isvalid_ring_len(u16 ring_len) 54 + { 55 + return ring_len == 0 || 56 + (ring_len >= ICE_MIN_NUM_DESC && 57 + ring_len <= ICE_MAX_NUM_DESC && 58 + !(ring_len % ICE_REQ_DESC_MULTIPLE)); 59 + } 60 + 61 + /** 62 + * ice_vf_cfg_qs_bw - Configure per queue bandwidth 63 + * @vf: pointer to the VF info 64 + * @num_queues: number of queues to be configured 65 + * 66 + * Configure per queue bandwidth. 67 + * 68 + * Return: 0 on success or negative error value. 69 + */ 70 + static int ice_vf_cfg_qs_bw(struct ice_vf *vf, u16 num_queues) 71 + { 72 + struct ice_hw *hw = &vf->pf->hw; 73 + struct ice_vsi *vsi; 74 + int ret; 75 + u16 i; 76 + 77 + vsi = ice_get_vf_vsi(vf); 78 + if (!vsi) 79 + return -EINVAL; 80 + 81 + for (i = 0; i < num_queues; i++) { 82 + u32 p_rate, min_rate; 83 + u8 tc; 84 + 85 + p_rate = vf->qs_bw[i].peak; 86 + min_rate = vf->qs_bw[i].committed; 87 + tc = vf->qs_bw[i].tc; 88 + if (p_rate) 89 + ret = ice_cfg_q_bw_lmt(hw->port_info, vsi->idx, tc, 90 + vf->qs_bw[i].queue_id, 91 + ICE_MAX_BW, p_rate); 92 + else 93 + ret = ice_cfg_q_bw_dflt_lmt(hw->port_info, vsi->idx, tc, 94 + vf->qs_bw[i].queue_id, 95 + ICE_MAX_BW); 96 + if (ret) 97 + return ret; 98 + 99 + if (min_rate) 100 + ret = ice_cfg_q_bw_lmt(hw->port_info, vsi->idx, tc, 101 + vf->qs_bw[i].queue_id, 102 + ICE_MIN_BW, min_rate); 103 + else 104 + ret = ice_cfg_q_bw_dflt_lmt(hw->port_info, vsi->idx, tc, 105 + vf->qs_bw[i].queue_id, 106 + ICE_MIN_BW); 107 + 108 + if (ret) 109 + return ret; 110 + } 111 + 112 + return 0; 113 + } 114 + 115 + /** 116 + * ice_vf_cfg_q_quanta_profile - Configure quanta profile 117 + * @vf: pointer to the VF info 118 + * @quanta_prof_idx: pointer to the quanta profile index 119 + * @quanta_size: quanta size to be set 120 + * 121 + * This function chooses available quanta profile and configures the register. 122 + * The quanta profile is evenly divided by the number of device ports, and then 123 + * available to the specific PF and VFs. The first profile for each PF is a 124 + * reserved default profile. Only quanta size of the rest unused profile can be 125 + * modified. 126 + * 127 + * Return: 0 on success or negative error value. 128 + */ 129 + static int ice_vf_cfg_q_quanta_profile(struct ice_vf *vf, u16 quanta_size, 130 + u16 *quanta_prof_idx) 131 + { 132 + const u16 n_desc = calc_quanta_desc(quanta_size); 133 + struct ice_hw *hw = &vf->pf->hw; 134 + const u16 n_cmd = 2 * n_desc; 135 + struct ice_pf *pf = vf->pf; 136 + u16 per_pf, begin_id; 137 + u8 n_used; 138 + u32 reg; 139 + 140 + begin_id = (GLCOMM_QUANTA_PROF_MAX_INDEX + 1) / hw->dev_caps.num_funcs * 141 + hw->logical_pf_id; 142 + 143 + if (quanta_size == ICE_DFLT_QUANTA) { 144 + *quanta_prof_idx = begin_id; 145 + } else { 146 + per_pf = (GLCOMM_QUANTA_PROF_MAX_INDEX + 1) / 147 + hw->dev_caps.num_funcs; 148 + n_used = pf->num_quanta_prof_used; 149 + if (n_used < per_pf) { 150 + *quanta_prof_idx = begin_id + 1 + n_used; 151 + pf->num_quanta_prof_used++; 152 + } else { 153 + return -EINVAL; 154 + } 155 + } 156 + 157 + reg = FIELD_PREP(GLCOMM_QUANTA_PROF_QUANTA_SIZE_M, quanta_size) | 158 + FIELD_PREP(GLCOMM_QUANTA_PROF_MAX_CMD_M, n_cmd) | 159 + FIELD_PREP(GLCOMM_QUANTA_PROF_MAX_DESC_M, n_desc); 160 + wr32(hw, GLCOMM_QUANTA_PROF(*quanta_prof_idx), reg); 161 + 162 + return 0; 163 + } 164 + 165 + /** 166 + * ice_vc_validate_vqs_bitmaps - validate Rx/Tx queue bitmaps from VIRTCHNL 167 + * @vqs: virtchnl_queue_select structure containing bitmaps to validate 168 + * 169 + * Return true on successful validation, else false 170 + */ 171 + static bool ice_vc_validate_vqs_bitmaps(struct virtchnl_queue_select *vqs) 172 + { 173 + if ((!vqs->rx_queues && !vqs->tx_queues) || 174 + vqs->rx_queues >= BIT(ICE_MAX_RSS_QS_PER_VF) || 175 + vqs->tx_queues >= BIT(ICE_MAX_RSS_QS_PER_VF)) 176 + return false; 177 + 178 + return true; 179 + } 180 + 181 + /** 182 + * ice_vf_ena_txq_interrupt - enable Tx queue interrupt via QINT_TQCTL 183 + * @vsi: VSI of the VF to configure 184 + * @q_idx: VF queue index used to determine the queue in the PF's space 185 + */ 186 + void ice_vf_ena_txq_interrupt(struct ice_vsi *vsi, u32 q_idx) 187 + { 188 + struct ice_hw *hw = &vsi->back->hw; 189 + u32 pfq = vsi->txq_map[q_idx]; 190 + u32 reg; 191 + 192 + reg = rd32(hw, QINT_TQCTL(pfq)); 193 + 194 + /* MSI-X index 0 in the VF's space is always for the OICR, which means 195 + * this is most likely a poll mode VF driver, so don't enable an 196 + * interrupt that was never configured via VIRTCHNL_OP_CONFIG_IRQ_MAP 197 + */ 198 + if (!(reg & QINT_TQCTL_MSIX_INDX_M)) 199 + return; 200 + 201 + wr32(hw, QINT_TQCTL(pfq), reg | QINT_TQCTL_CAUSE_ENA_M); 202 + } 203 + 204 + /** 205 + * ice_vf_ena_rxq_interrupt - enable Tx queue interrupt via QINT_RQCTL 206 + * @vsi: VSI of the VF to configure 207 + * @q_idx: VF queue index used to determine the queue in the PF's space 208 + */ 209 + void ice_vf_ena_rxq_interrupt(struct ice_vsi *vsi, u32 q_idx) 210 + { 211 + struct ice_hw *hw = &vsi->back->hw; 212 + u32 pfq = vsi->rxq_map[q_idx]; 213 + u32 reg; 214 + 215 + reg = rd32(hw, QINT_RQCTL(pfq)); 216 + 217 + /* MSI-X index 0 in the VF's space is always for the OICR, which means 218 + * this is most likely a poll mode VF driver, so don't enable an 219 + * interrupt that was never configured via VIRTCHNL_OP_CONFIG_IRQ_MAP 220 + */ 221 + if (!(reg & QINT_RQCTL_MSIX_INDX_M)) 222 + return; 223 + 224 + wr32(hw, QINT_RQCTL(pfq), reg | QINT_RQCTL_CAUSE_ENA_M); 225 + } 226 + 227 + /** 228 + * ice_vc_ena_qs_msg 229 + * @vf: pointer to the VF info 230 + * @msg: pointer to the msg buffer 231 + * 232 + * called from the VF to enable all or specific queue(s) 233 + */ 234 + int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg) 235 + { 236 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 237 + struct virtchnl_queue_select *vqs = 238 + (struct virtchnl_queue_select *)msg; 239 + struct ice_vsi *vsi; 240 + unsigned long q_map; 241 + u16 vf_q_id; 242 + 243 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 244 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 245 + goto error_param; 246 + } 247 + 248 + if (!ice_vc_isvalid_vsi_id(vf, vqs->vsi_id)) { 249 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 250 + goto error_param; 251 + } 252 + 253 + if (!ice_vc_validate_vqs_bitmaps(vqs)) { 254 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 255 + goto error_param; 256 + } 257 + 258 + vsi = ice_get_vf_vsi(vf); 259 + if (!vsi) { 260 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 261 + goto error_param; 262 + } 263 + 264 + /* Enable only Rx rings, Tx rings were enabled by the FW when the 265 + * Tx queue group list was configured and the context bits were 266 + * programmed using ice_vsi_cfg_txqs 267 + */ 268 + q_map = vqs->rx_queues; 269 + for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { 270 + if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) { 271 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 272 + goto error_param; 273 + } 274 + 275 + /* Skip queue if enabled */ 276 + if (test_bit(vf_q_id, vf->rxq_ena)) 277 + continue; 278 + 279 + if (ice_vsi_ctrl_one_rx_ring(vsi, true, vf_q_id, true)) { 280 + dev_err(ice_pf_to_dev(vsi->back), "Failed to enable Rx ring %d on VSI %d\n", 281 + vf_q_id, vsi->vsi_num); 282 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 283 + goto error_param; 284 + } 285 + 286 + ice_vf_ena_rxq_interrupt(vsi, vf_q_id); 287 + set_bit(vf_q_id, vf->rxq_ena); 288 + } 289 + 290 + q_map = vqs->tx_queues; 291 + for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { 292 + if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) { 293 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 294 + goto error_param; 295 + } 296 + 297 + /* Skip queue if enabled */ 298 + if (test_bit(vf_q_id, vf->txq_ena)) 299 + continue; 300 + 301 + ice_vf_ena_txq_interrupt(vsi, vf_q_id); 302 + set_bit(vf_q_id, vf->txq_ena); 303 + } 304 + 305 + /* Set flag to indicate that queues are enabled */ 306 + if (v_ret == VIRTCHNL_STATUS_SUCCESS) 307 + set_bit(ICE_VF_STATE_QS_ENA, vf->vf_states); 308 + 309 + error_param: 310 + /* send the response to the VF */ 311 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_QUEUES, v_ret, 312 + NULL, 0); 313 + } 314 + 315 + /** 316 + * ice_vf_vsi_dis_single_txq - disable a single Tx queue 317 + * @vf: VF to disable queue for 318 + * @vsi: VSI for the VF 319 + * @q_id: VF relative (0-based) queue ID 320 + * 321 + * Attempt to disable the Tx queue passed in. If the Tx queue was successfully 322 + * disabled then clear q_id bit in the enabled queues bitmap and return 323 + * success. Otherwise return error. 324 + */ 325 + int ice_vf_vsi_dis_single_txq(struct ice_vf *vf, struct ice_vsi *vsi, u16 q_id) 326 + { 327 + struct ice_txq_meta txq_meta = { 0 }; 328 + struct ice_tx_ring *ring; 329 + int err; 330 + 331 + if (!test_bit(q_id, vf->txq_ena)) 332 + dev_dbg(ice_pf_to_dev(vsi->back), "Queue %u on VSI %u is not enabled, but stopping it anyway\n", 333 + q_id, vsi->vsi_num); 334 + 335 + ring = vsi->tx_rings[q_id]; 336 + if (!ring) 337 + return -EINVAL; 338 + 339 + ice_fill_txq_meta(vsi, ring, &txq_meta); 340 + 341 + err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, vf->vf_id, ring, &txq_meta); 342 + if (err) { 343 + dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Tx ring %d on VSI %d\n", 344 + q_id, vsi->vsi_num); 345 + return err; 346 + } 347 + 348 + /* Clear enabled queues flag */ 349 + clear_bit(q_id, vf->txq_ena); 350 + 351 + return 0; 352 + } 353 + 354 + /** 355 + * ice_vc_dis_qs_msg 356 + * @vf: pointer to the VF info 357 + * @msg: pointer to the msg buffer 358 + * 359 + * called from the VF to disable all or specific queue(s) 360 + */ 361 + int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) 362 + { 363 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 364 + struct virtchnl_queue_select *vqs = 365 + (struct virtchnl_queue_select *)msg; 366 + struct ice_vsi *vsi; 367 + unsigned long q_map; 368 + u16 vf_q_id; 369 + 370 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) && 371 + !test_bit(ICE_VF_STATE_QS_ENA, vf->vf_states)) { 372 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 373 + goto error_param; 374 + } 375 + 376 + if (!ice_vc_isvalid_vsi_id(vf, vqs->vsi_id)) { 377 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 378 + goto error_param; 379 + } 380 + 381 + if (!ice_vc_validate_vqs_bitmaps(vqs)) { 382 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 383 + goto error_param; 384 + } 385 + 386 + vsi = ice_get_vf_vsi(vf); 387 + if (!vsi) { 388 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 389 + goto error_param; 390 + } 391 + 392 + if (vqs->tx_queues) { 393 + q_map = vqs->tx_queues; 394 + 395 + for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { 396 + if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) { 397 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 398 + goto error_param; 399 + } 400 + 401 + if (ice_vf_vsi_dis_single_txq(vf, vsi, vf_q_id)) { 402 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 403 + goto error_param; 404 + } 405 + } 406 + } 407 + 408 + q_map = vqs->rx_queues; 409 + /* speed up Rx queue disable by batching them if possible */ 410 + if (q_map && 411 + bitmap_equal(&q_map, vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF)) { 412 + if (ice_vsi_stop_all_rx_rings(vsi)) { 413 + dev_err(ice_pf_to_dev(vsi->back), "Failed to stop all Rx rings on VSI %d\n", 414 + vsi->vsi_num); 415 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 416 + goto error_param; 417 + } 418 + 419 + bitmap_zero(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF); 420 + } else if (q_map) { 421 + for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { 422 + if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) { 423 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 424 + goto error_param; 425 + } 426 + 427 + /* Skip queue if not enabled */ 428 + if (!test_bit(vf_q_id, vf->rxq_ena)) 429 + continue; 430 + 431 + if (ice_vsi_ctrl_one_rx_ring(vsi, false, vf_q_id, 432 + true)) { 433 + dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Rx ring %d on VSI %d\n", 434 + vf_q_id, vsi->vsi_num); 435 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 436 + goto error_param; 437 + } 438 + 439 + /* Clear enabled queues flag */ 440 + clear_bit(vf_q_id, vf->rxq_ena); 441 + } 442 + } 443 + 444 + /* Clear enabled queues flag */ 445 + if (v_ret == VIRTCHNL_STATUS_SUCCESS && ice_vf_has_no_qs_ena(vf)) 446 + clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states); 447 + 448 + error_param: 449 + /* send the response to the VF */ 450 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_QUEUES, v_ret, 451 + NULL, 0); 452 + } 453 + 454 + /** 455 + * ice_cfg_interrupt 456 + * @vf: pointer to the VF info 457 + * @vsi: the VSI being configured 458 + * @map: vector map for mapping vectors to queues 459 + * @q_vector: structure for interrupt vector 460 + * configure the IRQ to queue map 461 + */ 462 + static enum virtchnl_status_code 463 + ice_cfg_interrupt(struct ice_vf *vf, struct ice_vsi *vsi, 464 + struct virtchnl_vector_map *map, 465 + struct ice_q_vector *q_vector) 466 + { 467 + u16 vsi_q_id, vsi_q_id_idx; 468 + unsigned long qmap; 469 + 470 + q_vector->num_ring_rx = 0; 471 + q_vector->num_ring_tx = 0; 472 + 473 + qmap = map->rxq_map; 474 + for_each_set_bit(vsi_q_id_idx, &qmap, ICE_MAX_RSS_QS_PER_VF) { 475 + vsi_q_id = vsi_q_id_idx; 476 + 477 + if (!ice_vc_isvalid_q_id(vsi, vsi_q_id)) 478 + return VIRTCHNL_STATUS_ERR_PARAM; 479 + 480 + q_vector->num_ring_rx++; 481 + q_vector->rx.itr_idx = map->rxitr_idx; 482 + vsi->rx_rings[vsi_q_id]->q_vector = q_vector; 483 + ice_cfg_rxq_interrupt(vsi, vsi_q_id, 484 + q_vector->vf_reg_idx, 485 + q_vector->rx.itr_idx); 486 + } 487 + 488 + qmap = map->txq_map; 489 + for_each_set_bit(vsi_q_id_idx, &qmap, ICE_MAX_RSS_QS_PER_VF) { 490 + vsi_q_id = vsi_q_id_idx; 491 + 492 + if (!ice_vc_isvalid_q_id(vsi, vsi_q_id)) 493 + return VIRTCHNL_STATUS_ERR_PARAM; 494 + 495 + q_vector->num_ring_tx++; 496 + q_vector->tx.itr_idx = map->txitr_idx; 497 + vsi->tx_rings[vsi_q_id]->q_vector = q_vector; 498 + ice_cfg_txq_interrupt(vsi, vsi_q_id, 499 + q_vector->vf_reg_idx, 500 + q_vector->tx.itr_idx); 501 + } 502 + 503 + return VIRTCHNL_STATUS_SUCCESS; 504 + } 505 + 506 + /** 507 + * ice_vc_cfg_irq_map_msg 508 + * @vf: pointer to the VF info 509 + * @msg: pointer to the msg buffer 510 + * 511 + * called from the VF to configure the IRQ to queue map 512 + */ 513 + int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg) 514 + { 515 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 516 + u16 num_q_vectors_mapped, vsi_id, vector_id; 517 + struct virtchnl_irq_map_info *irqmap_info; 518 + struct virtchnl_vector_map *map; 519 + struct ice_vsi *vsi; 520 + int i; 521 + 522 + irqmap_info = (struct virtchnl_irq_map_info *)msg; 523 + num_q_vectors_mapped = irqmap_info->num_vectors; 524 + 525 + /* Check to make sure number of VF vectors mapped is not greater than 526 + * number of VF vectors originally allocated, and check that 527 + * there is actually at least a single VF queue vector mapped 528 + */ 529 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) || 530 + vf->num_msix < num_q_vectors_mapped || 531 + !num_q_vectors_mapped) { 532 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 533 + goto error_param; 534 + } 535 + 536 + vsi = ice_get_vf_vsi(vf); 537 + if (!vsi) { 538 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 539 + goto error_param; 540 + } 541 + 542 + for (i = 0; i < num_q_vectors_mapped; i++) { 543 + struct ice_q_vector *q_vector; 544 + 545 + map = &irqmap_info->vecmap[i]; 546 + 547 + vector_id = map->vector_id; 548 + vsi_id = map->vsi_id; 549 + /* vector_id is always 0-based for each VF, and can never be 550 + * larger than or equal to the max allowed interrupts per VF 551 + */ 552 + if (!(vector_id < vf->num_msix) || 553 + !ice_vc_isvalid_vsi_id(vf, vsi_id) || 554 + (!vector_id && (map->rxq_map || map->txq_map))) { 555 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 556 + goto error_param; 557 + } 558 + 559 + /* No need to map VF miscellaneous or rogue vector */ 560 + if (!vector_id) 561 + continue; 562 + 563 + /* Subtract non queue vector from vector_id passed by VF 564 + * to get actual number of VSI queue vector array index 565 + */ 566 + q_vector = vsi->q_vectors[vector_id - ICE_NONQ_VECS_VF]; 567 + if (!q_vector) { 568 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 569 + goto error_param; 570 + } 571 + 572 + /* lookout for the invalid queue index */ 573 + v_ret = ice_cfg_interrupt(vf, vsi, map, q_vector); 574 + if (v_ret) 575 + goto error_param; 576 + } 577 + 578 + error_param: 579 + /* send the response to the VF */ 580 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_IRQ_MAP, v_ret, 581 + NULL, 0); 582 + } 583 + 584 + /** 585 + * ice_vc_cfg_q_bw - Configure per queue bandwidth 586 + * @vf: pointer to the VF info 587 + * @msg: pointer to the msg buffer which holds the command descriptor 588 + * 589 + * Configure VF queues bandwidth. 590 + * 591 + * Return: 0 on success or negative error value. 592 + */ 593 + int ice_vc_cfg_q_bw(struct ice_vf *vf, u8 *msg) 594 + { 595 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 596 + struct virtchnl_queues_bw_cfg *qbw = 597 + (struct virtchnl_queues_bw_cfg *)msg; 598 + struct ice_vsi *vsi; 599 + u16 i; 600 + 601 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) || 602 + !ice_vc_isvalid_vsi_id(vf, qbw->vsi_id)) { 603 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 604 + goto err; 605 + } 606 + 607 + vsi = ice_get_vf_vsi(vf); 608 + if (!vsi) { 609 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 610 + goto err; 611 + } 612 + 613 + if (qbw->num_queues > ICE_MAX_RSS_QS_PER_VF || 614 + qbw->num_queues > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) { 615 + dev_err(ice_pf_to_dev(vf->pf), "VF-%d trying to configure more than allocated number of queues: %d\n", 616 + vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); 617 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 618 + goto err; 619 + } 620 + 621 + for (i = 0; i < qbw->num_queues; i++) { 622 + if (qbw->cfg[i].shaper.peak != 0 && vf->max_tx_rate != 0 && 623 + qbw->cfg[i].shaper.peak > vf->max_tx_rate) { 624 + dev_warn(ice_pf_to_dev(vf->pf), "The maximum queue %d rate limit configuration may not take effect because the maximum TX rate for VF-%d is %d\n", 625 + qbw->cfg[i].queue_id, vf->vf_id, 626 + vf->max_tx_rate); 627 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 628 + goto err; 629 + } 630 + if (qbw->cfg[i].shaper.committed != 0 && vf->min_tx_rate != 0 && 631 + qbw->cfg[i].shaper.committed < vf->min_tx_rate) { 632 + dev_warn(ice_pf_to_dev(vf->pf), "The minimum queue %d rate limit configuration may not take effect because the minimum TX rate for VF-%d is %d\n", 633 + qbw->cfg[i].queue_id, vf->vf_id, 634 + vf->min_tx_rate); 635 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 636 + goto err; 637 + } 638 + if (qbw->cfg[i].queue_id > vf->num_vf_qs) { 639 + dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure invalid queue_id\n", 640 + vf->vf_id); 641 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 642 + goto err; 643 + } 644 + if (qbw->cfg[i].tc >= ICE_MAX_TRAFFIC_CLASS) { 645 + dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure a traffic class higher than allowed\n", 646 + vf->vf_id); 647 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 648 + goto err; 649 + } 650 + } 651 + 652 + for (i = 0; i < qbw->num_queues; i++) { 653 + vf->qs_bw[i].queue_id = qbw->cfg[i].queue_id; 654 + vf->qs_bw[i].peak = qbw->cfg[i].shaper.peak; 655 + vf->qs_bw[i].committed = qbw->cfg[i].shaper.committed; 656 + vf->qs_bw[i].tc = qbw->cfg[i].tc; 657 + } 658 + 659 + if (ice_vf_cfg_qs_bw(vf, qbw->num_queues)) 660 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 661 + 662 + err: 663 + /* send the response to the VF */ 664 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_QUEUE_BW, 665 + v_ret, NULL, 0); 666 + } 667 + 668 + /** 669 + * ice_vc_cfg_q_quanta - Configure per queue quanta 670 + * @vf: pointer to the VF info 671 + * @msg: pointer to the msg buffer which holds the command descriptor 672 + * 673 + * Configure VF queues quanta. 674 + * 675 + * Return: 0 on success or negative error value. 676 + */ 677 + int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg) 678 + { 679 + u16 quanta_prof_id, quanta_size, start_qid, num_queues, end_qid, i; 680 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 681 + struct virtchnl_quanta_cfg *qquanta = 682 + (struct virtchnl_quanta_cfg *)msg; 683 + struct ice_vsi *vsi; 684 + int ret; 685 + 686 + start_qid = qquanta->queue_select.start_queue_id; 687 + num_queues = qquanta->queue_select.num_queues; 688 + 689 + if (check_add_overflow(start_qid, num_queues, &end_qid)) { 690 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 691 + goto err; 692 + } 693 + 694 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 695 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 696 + goto err; 697 + } 698 + 699 + vsi = ice_get_vf_vsi(vf); 700 + if (!vsi) { 701 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 702 + goto err; 703 + } 704 + 705 + if (end_qid > ICE_MAX_RSS_QS_PER_VF || 706 + end_qid > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) { 707 + dev_err(ice_pf_to_dev(vf->pf), "VF-%d trying to configure more than allocated number of queues: %d\n", 708 + vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); 709 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 710 + goto err; 711 + } 712 + 713 + quanta_size = qquanta->quanta_size; 714 + if (quanta_size > ICE_MAX_QUANTA_SIZE || 715 + quanta_size < ICE_MIN_QUANTA_SIZE) { 716 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 717 + goto err; 718 + } 719 + 720 + if (quanta_size % 64) { 721 + dev_err(ice_pf_to_dev(vf->pf), "quanta size should be the product of 64\n"); 722 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 723 + goto err; 724 + } 725 + 726 + ret = ice_vf_cfg_q_quanta_profile(vf, quanta_size, 727 + &quanta_prof_id); 728 + if (ret) { 729 + v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED; 730 + goto err; 731 + } 732 + 733 + for (i = start_qid; i < end_qid; i++) 734 + vsi->tx_rings[i]->quanta_prof_id = quanta_prof_id; 735 + 736 + err: 737 + /* send the response to the VF */ 738 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_QUANTA, 739 + v_ret, NULL, 0); 740 + } 741 + 742 + /** 743 + * ice_vc_cfg_qs_msg 744 + * @vf: pointer to the VF info 745 + * @msg: pointer to the msg buffer 746 + * 747 + * called from the VF to configure the Rx/Tx queues 748 + */ 749 + int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) 750 + { 751 + struct virtchnl_vsi_queue_config_info *qci = 752 + (struct virtchnl_vsi_queue_config_info *)msg; 753 + struct virtchnl_queue_pair_info *qpi; 754 + struct ice_pf *pf = vf->pf; 755 + struct ice_vsi *vsi; 756 + int i = -1, q_idx; 757 + bool ena_ts; 758 + u8 act_prt; 759 + 760 + mutex_lock(&pf->lag_mutex); 761 + act_prt = ice_lag_prepare_vf_reset(pf->lag); 762 + 763 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) 764 + goto error_param; 765 + 766 + if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id)) 767 + goto error_param; 768 + 769 + vsi = ice_get_vf_vsi(vf); 770 + if (!vsi) 771 + goto error_param; 772 + 773 + if (qci->num_queue_pairs > ICE_MAX_RSS_QS_PER_VF || 774 + qci->num_queue_pairs > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) { 775 + dev_err(ice_pf_to_dev(pf), "VF-%d requesting more than supported number of queues: %d\n", 776 + vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); 777 + goto error_param; 778 + } 779 + 780 + for (i = 0; i < qci->num_queue_pairs; i++) { 781 + if (!qci->qpair[i].rxq.crc_disable) 782 + continue; 783 + 784 + if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_CRC) || 785 + vf->vlan_strip_ena) 786 + goto error_param; 787 + } 788 + 789 + for (i = 0; i < qci->num_queue_pairs; i++) { 790 + qpi = &qci->qpair[i]; 791 + if (qpi->txq.vsi_id != qci->vsi_id || 792 + qpi->rxq.vsi_id != qci->vsi_id || 793 + qpi->rxq.queue_id != qpi->txq.queue_id || 794 + qpi->txq.headwb_enabled || 795 + !ice_vc_isvalid_ring_len(qpi->txq.ring_len) || 796 + !ice_vc_isvalid_ring_len(qpi->rxq.ring_len) || 797 + !ice_vc_isvalid_q_id(vsi, qpi->txq.queue_id)) { 798 + goto error_param; 799 + } 800 + 801 + q_idx = qpi->rxq.queue_id; 802 + 803 + /* make sure selected "q_idx" is in valid range of queues 804 + * for selected "vsi" 805 + */ 806 + if (q_idx >= vsi->alloc_txq || q_idx >= vsi->alloc_rxq) { 807 + goto error_param; 808 + } 809 + 810 + /* copy Tx queue info from VF into VSI */ 811 + if (qpi->txq.ring_len > 0) { 812 + vsi->tx_rings[q_idx]->dma = qpi->txq.dma_ring_addr; 813 + vsi->tx_rings[q_idx]->count = qpi->txq.ring_len; 814 + 815 + /* Disable any existing queue first */ 816 + if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) 817 + goto error_param; 818 + 819 + /* Configure a queue with the requested settings */ 820 + if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) { 821 + dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure TX queue %d\n", 822 + vf->vf_id, q_idx); 823 + goto error_param; 824 + } 825 + } 826 + 827 + /* copy Rx queue info from VF into VSI */ 828 + if (qpi->rxq.ring_len > 0) { 829 + u16 max_frame_size = ice_vc_get_max_frame_size(vf); 830 + struct ice_rx_ring *ring = vsi->rx_rings[q_idx]; 831 + u32 rxdid; 832 + 833 + ring->dma = qpi->rxq.dma_ring_addr; 834 + ring->count = qpi->rxq.ring_len; 835 + 836 + if (qpi->rxq.crc_disable) 837 + ring->flags |= ICE_RX_FLAGS_CRC_STRIP_DIS; 838 + else 839 + ring->flags &= ~ICE_RX_FLAGS_CRC_STRIP_DIS; 840 + 841 + if (qpi->rxq.databuffer_size != 0 && 842 + (qpi->rxq.databuffer_size > ((16 * 1024) - 128) || 843 + qpi->rxq.databuffer_size < 1024)) 844 + goto error_param; 845 + ring->rx_buf_len = qpi->rxq.databuffer_size; 846 + if (qpi->rxq.max_pkt_size > max_frame_size || 847 + qpi->rxq.max_pkt_size < 64) 848 + goto error_param; 849 + 850 + ring->max_frame = qpi->rxq.max_pkt_size; 851 + /* add space for the port VLAN since the VF driver is 852 + * not expected to account for it in the MTU 853 + * calculation 854 + */ 855 + if (ice_vf_is_port_vlan_ena(vf)) 856 + ring->max_frame += VLAN_HLEN; 857 + 858 + if (ice_vsi_cfg_single_rxq(vsi, q_idx)) { 859 + dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n", 860 + vf->vf_id, q_idx); 861 + goto error_param; 862 + } 863 + 864 + /* If Rx flex desc is supported, select RXDID for Rx 865 + * queues. Otherwise, use legacy 32byte descriptor 866 + * format. Legacy 16byte descriptor is not supported. 867 + * If this RXDID is selected, return error. 868 + */ 869 + if (vf->driver_caps & 870 + VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) { 871 + rxdid = qpi->rxq.rxdid; 872 + if (!(BIT(rxdid) & pf->supported_rxdids)) 873 + goto error_param; 874 + } else { 875 + rxdid = ICE_RXDID_LEGACY_1; 876 + } 877 + 878 + ena_ts = ((vf->driver_caps & 879 + VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) && 880 + (vf->driver_caps & VIRTCHNL_VF_CAP_PTP) && 881 + (qpi->rxq.flags & VIRTCHNL_PTP_RX_TSTAMP)); 882 + 883 + ice_write_qrxflxp_cntxt(&vsi->back->hw, 884 + vsi->rxq_map[q_idx], rxdid, 885 + ICE_RXDID_PRIO, ena_ts); 886 + } 887 + } 888 + 889 + ice_lag_complete_vf_reset(pf->lag, act_prt); 890 + mutex_unlock(&pf->lag_mutex); 891 + 892 + /* send the response to the VF */ 893 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, 894 + VIRTCHNL_STATUS_SUCCESS, NULL, 0); 895 + error_param: 896 + /* disable whatever we can */ 897 + for (; i >= 0; i--) { 898 + if (ice_vsi_ctrl_one_rx_ring(vsi, false, i, true)) 899 + dev_err(ice_pf_to_dev(pf), "VF-%d could not disable RX queue %d\n", 900 + vf->vf_id, i); 901 + if (ice_vf_vsi_dis_single_txq(vf, vsi, i)) 902 + dev_err(ice_pf_to_dev(pf), "VF-%d could not disable TX queue %d\n", 903 + vf->vf_id, i); 904 + } 905 + 906 + ice_lag_complete_vf_reset(pf->lag, act_prt); 907 + mutex_unlock(&pf->lag_mutex); 908 + 909 + ice_lag_move_new_vf_nodes(vf); 910 + 911 + /* send the response to the VF */ 912 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, 913 + VIRTCHNL_STATUS_ERR_PARAM, NULL, 0); 914 + } 915 + 916 + /** 917 + * ice_vc_request_qs_msg 918 + * @vf: pointer to the VF info 919 + * @msg: pointer to the msg buffer 920 + * 921 + * VFs get a default number of queues but can use this message to request a 922 + * different number. If the request is successful, PF will reset the VF and 923 + * return 0. If unsuccessful, PF will send message informing VF of number of 924 + * available queue pairs via virtchnl message response to VF. 925 + */ 926 + int ice_vc_request_qs_msg(struct ice_vf *vf, u8 *msg) 927 + { 928 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 929 + struct virtchnl_vf_res_request *vfres = 930 + (struct virtchnl_vf_res_request *)msg; 931 + u16 req_queues = vfres->num_queue_pairs; 932 + struct ice_pf *pf = vf->pf; 933 + u16 max_allowed_vf_queues; 934 + u16 tx_rx_queue_left; 935 + struct device *dev; 936 + u16 cur_queues; 937 + 938 + dev = ice_pf_to_dev(pf); 939 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 940 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 941 + goto error_param; 942 + } 943 + 944 + cur_queues = vf->num_vf_qs; 945 + tx_rx_queue_left = min_t(u16, ice_get_avail_txq_count(pf), 946 + ice_get_avail_rxq_count(pf)); 947 + max_allowed_vf_queues = tx_rx_queue_left + cur_queues; 948 + if (!req_queues) { 949 + dev_err(dev, "VF %d tried to request 0 queues. Ignoring.\n", 950 + vf->vf_id); 951 + } else if (req_queues > ICE_MAX_RSS_QS_PER_VF) { 952 + dev_err(dev, "VF %d tried to request more than %d queues.\n", 953 + vf->vf_id, ICE_MAX_RSS_QS_PER_VF); 954 + vfres->num_queue_pairs = ICE_MAX_RSS_QS_PER_VF; 955 + } else if (req_queues > cur_queues && 956 + req_queues - cur_queues > tx_rx_queue_left) { 957 + dev_warn(dev, "VF %d requested %u more queues, but only %u left.\n", 958 + vf->vf_id, req_queues - cur_queues, tx_rx_queue_left); 959 + vfres->num_queue_pairs = min_t(u16, max_allowed_vf_queues, 960 + ICE_MAX_RSS_QS_PER_VF); 961 + } else { 962 + /* request is successful, then reset VF */ 963 + vf->num_req_qs = req_queues; 964 + ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); 965 + dev_info(dev, "VF %d granted request of %u queues.\n", 966 + vf->vf_id, req_queues); 967 + return 0; 968 + } 969 + 970 + error_param: 971 + /* send the response to the VF */ 972 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 973 + v_ret, (u8 *)vfres, sizeof(*vfres)); 974 + } 975 +
+20
drivers/net/ethernet/intel/ice/virt/queues.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (C) 2022, Intel Corporation. */ 3 + 4 + #ifndef _ICE_VIRT_QUEUES_H_ 5 + #define _ICE_VIRT_QUEUES_H_ 6 + 7 + #include <linux/types.h> 8 + 9 + struct ice_vf; 10 + 11 + u16 ice_vc_get_max_frame_size(struct ice_vf *vf); 12 + int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg); 13 + int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg); 14 + int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg); 15 + int ice_vc_cfg_q_bw(struct ice_vf *vf, u8 *msg); 16 + int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg); 17 + int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg); 18 + int ice_vc_request_qs_msg(struct ice_vf *vf, u8 *msg); 19 + 20 + #endif /* _ICE_VIRT_QUEUES_H_ */
+719
drivers/net/ethernet/intel/ice/virt/rss.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2022, Intel Corporation. */ 3 + 4 + #include "rss.h" 5 + #include "ice_vf_lib_private.h" 6 + #include "ice.h" 7 + 8 + #define FIELD_SELECTOR(proto_hdr_field) \ 9 + BIT((proto_hdr_field) & PROTO_HDR_FIELD_MASK) 10 + 11 + struct ice_vc_hdr_match_type { 12 + u32 vc_hdr; /* virtchnl headers (VIRTCHNL_PROTO_HDR_XXX) */ 13 + u32 ice_hdr; /* ice headers (ICE_FLOW_SEG_HDR_XXX) */ 14 + }; 15 + 16 + static const struct ice_vc_hdr_match_type ice_vc_hdr_list[] = { 17 + {VIRTCHNL_PROTO_HDR_NONE, ICE_FLOW_SEG_HDR_NONE}, 18 + {VIRTCHNL_PROTO_HDR_ETH, ICE_FLOW_SEG_HDR_ETH}, 19 + {VIRTCHNL_PROTO_HDR_S_VLAN, ICE_FLOW_SEG_HDR_VLAN}, 20 + {VIRTCHNL_PROTO_HDR_C_VLAN, ICE_FLOW_SEG_HDR_VLAN}, 21 + {VIRTCHNL_PROTO_HDR_IPV4, ICE_FLOW_SEG_HDR_IPV4 | 22 + ICE_FLOW_SEG_HDR_IPV_OTHER}, 23 + {VIRTCHNL_PROTO_HDR_IPV6, ICE_FLOW_SEG_HDR_IPV6 | 24 + ICE_FLOW_SEG_HDR_IPV_OTHER}, 25 + {VIRTCHNL_PROTO_HDR_TCP, ICE_FLOW_SEG_HDR_TCP}, 26 + {VIRTCHNL_PROTO_HDR_UDP, ICE_FLOW_SEG_HDR_UDP}, 27 + {VIRTCHNL_PROTO_HDR_SCTP, ICE_FLOW_SEG_HDR_SCTP}, 28 + {VIRTCHNL_PROTO_HDR_PPPOE, ICE_FLOW_SEG_HDR_PPPOE}, 29 + {VIRTCHNL_PROTO_HDR_GTPU_IP, ICE_FLOW_SEG_HDR_GTPU_IP}, 30 + {VIRTCHNL_PROTO_HDR_GTPU_EH, ICE_FLOW_SEG_HDR_GTPU_EH}, 31 + {VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN, 32 + ICE_FLOW_SEG_HDR_GTPU_DWN}, 33 + {VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP, 34 + ICE_FLOW_SEG_HDR_GTPU_UP}, 35 + {VIRTCHNL_PROTO_HDR_L2TPV3, ICE_FLOW_SEG_HDR_L2TPV3}, 36 + {VIRTCHNL_PROTO_HDR_ESP, ICE_FLOW_SEG_HDR_ESP}, 37 + {VIRTCHNL_PROTO_HDR_AH, ICE_FLOW_SEG_HDR_AH}, 38 + {VIRTCHNL_PROTO_HDR_PFCP, ICE_FLOW_SEG_HDR_PFCP_SESSION}, 39 + }; 40 + 41 + struct ice_vc_hash_field_match_type { 42 + u32 vc_hdr; /* virtchnl headers 43 + * (VIRTCHNL_PROTO_HDR_XXX) 44 + */ 45 + u32 vc_hash_field; /* virtchnl hash fields selector 46 + * FIELD_SELECTOR((VIRTCHNL_PROTO_HDR_ETH_XXX)) 47 + */ 48 + u64 ice_hash_field; /* ice hash fields 49 + * (BIT_ULL(ICE_FLOW_FIELD_IDX_XXX)) 50 + */ 51 + }; 52 + 53 + static const struct 54 + ice_vc_hash_field_match_type ice_vc_hash_field_list[] = { 55 + {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC), 56 + BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA)}, 57 + {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), 58 + BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA)}, 59 + {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) | 60 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), 61 + ICE_FLOW_HASH_ETH}, 62 + {VIRTCHNL_PROTO_HDR_ETH, 63 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE), 64 + BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE)}, 65 + {VIRTCHNL_PROTO_HDR_S_VLAN, 66 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID), 67 + BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN)}, 68 + {VIRTCHNL_PROTO_HDR_C_VLAN, 69 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID), 70 + BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN)}, 71 + {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC), 72 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)}, 73 + {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), 74 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)}, 75 + {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 76 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), 77 + ICE_FLOW_HASH_IPV4}, 78 + {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 79 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 80 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | 81 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 82 + {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | 83 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 84 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | 85 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 86 + {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 87 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | 88 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 89 + ICE_FLOW_HASH_IPV4 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 90 + {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 91 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 92 + {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC), 93 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)}, 94 + {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), 95 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)}, 96 + {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 97 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), 98 + ICE_FLOW_HASH_IPV6}, 99 + {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 100 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 101 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | 102 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 103 + {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | 104 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 105 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | 106 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 107 + {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 108 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | 109 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 110 + ICE_FLOW_HASH_IPV6 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 111 + {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 112 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 113 + {VIRTCHNL_PROTO_HDR_TCP, 114 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT), 115 + BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, 116 + {VIRTCHNL_PROTO_HDR_TCP, 117 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), 118 + BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, 119 + {VIRTCHNL_PROTO_HDR_TCP, 120 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) | 121 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), 122 + ICE_FLOW_HASH_TCP_PORT}, 123 + {VIRTCHNL_PROTO_HDR_UDP, 124 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT), 125 + BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, 126 + {VIRTCHNL_PROTO_HDR_UDP, 127 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), 128 + BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, 129 + {VIRTCHNL_PROTO_HDR_UDP, 130 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) | 131 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), 132 + ICE_FLOW_HASH_UDP_PORT}, 133 + {VIRTCHNL_PROTO_HDR_SCTP, 134 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT), 135 + BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, 136 + {VIRTCHNL_PROTO_HDR_SCTP, 137 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), 138 + BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, 139 + {VIRTCHNL_PROTO_HDR_SCTP, 140 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) | 141 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), 142 + ICE_FLOW_HASH_SCTP_PORT}, 143 + {VIRTCHNL_PROTO_HDR_PPPOE, 144 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID), 145 + BIT_ULL(ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID)}, 146 + {VIRTCHNL_PROTO_HDR_GTPU_IP, 147 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_GTPU_IP_TEID), 148 + BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID)}, 149 + {VIRTCHNL_PROTO_HDR_L2TPV3, 150 + FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID), 151 + BIT_ULL(ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID)}, 152 + {VIRTCHNL_PROTO_HDR_ESP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI), 153 + BIT_ULL(ICE_FLOW_FIELD_IDX_ESP_SPI)}, 154 + {VIRTCHNL_PROTO_HDR_AH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI), 155 + BIT_ULL(ICE_FLOW_FIELD_IDX_AH_SPI)}, 156 + {VIRTCHNL_PROTO_HDR_PFCP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID), 157 + BIT_ULL(ICE_FLOW_FIELD_IDX_PFCP_SEID)}, 158 + }; 159 + 160 + /** 161 + * ice_vc_validate_pattern 162 + * @vf: pointer to the VF info 163 + * @proto: virtchnl protocol headers 164 + * 165 + * validate the pattern is supported or not. 166 + * 167 + * Return: true on success, false on error. 168 + */ 169 + bool 170 + ice_vc_validate_pattern(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto) 171 + { 172 + bool is_ipv4 = false; 173 + bool is_ipv6 = false; 174 + bool is_udp = false; 175 + u16 ptype = -1; 176 + int i = 0; 177 + 178 + while (i < proto->count && 179 + proto->proto_hdr[i].type != VIRTCHNL_PROTO_HDR_NONE) { 180 + switch (proto->proto_hdr[i].type) { 181 + case VIRTCHNL_PROTO_HDR_ETH: 182 + ptype = ICE_PTYPE_MAC_PAY; 183 + break; 184 + case VIRTCHNL_PROTO_HDR_IPV4: 185 + ptype = ICE_PTYPE_IPV4_PAY; 186 + is_ipv4 = true; 187 + break; 188 + case VIRTCHNL_PROTO_HDR_IPV6: 189 + ptype = ICE_PTYPE_IPV6_PAY; 190 + is_ipv6 = true; 191 + break; 192 + case VIRTCHNL_PROTO_HDR_UDP: 193 + if (is_ipv4) 194 + ptype = ICE_PTYPE_IPV4_UDP_PAY; 195 + else if (is_ipv6) 196 + ptype = ICE_PTYPE_IPV6_UDP_PAY; 197 + is_udp = true; 198 + break; 199 + case VIRTCHNL_PROTO_HDR_TCP: 200 + if (is_ipv4) 201 + ptype = ICE_PTYPE_IPV4_TCP_PAY; 202 + else if (is_ipv6) 203 + ptype = ICE_PTYPE_IPV6_TCP_PAY; 204 + break; 205 + case VIRTCHNL_PROTO_HDR_SCTP: 206 + if (is_ipv4) 207 + ptype = ICE_PTYPE_IPV4_SCTP_PAY; 208 + else if (is_ipv6) 209 + ptype = ICE_PTYPE_IPV6_SCTP_PAY; 210 + break; 211 + case VIRTCHNL_PROTO_HDR_GTPU_IP: 212 + case VIRTCHNL_PROTO_HDR_GTPU_EH: 213 + if (is_ipv4) 214 + ptype = ICE_MAC_IPV4_GTPU; 215 + else if (is_ipv6) 216 + ptype = ICE_MAC_IPV6_GTPU; 217 + goto out; 218 + case VIRTCHNL_PROTO_HDR_L2TPV3: 219 + if (is_ipv4) 220 + ptype = ICE_MAC_IPV4_L2TPV3; 221 + else if (is_ipv6) 222 + ptype = ICE_MAC_IPV6_L2TPV3; 223 + goto out; 224 + case VIRTCHNL_PROTO_HDR_ESP: 225 + if (is_ipv4) 226 + ptype = is_udp ? ICE_MAC_IPV4_NAT_T_ESP : 227 + ICE_MAC_IPV4_ESP; 228 + else if (is_ipv6) 229 + ptype = is_udp ? ICE_MAC_IPV6_NAT_T_ESP : 230 + ICE_MAC_IPV6_ESP; 231 + goto out; 232 + case VIRTCHNL_PROTO_HDR_AH: 233 + if (is_ipv4) 234 + ptype = ICE_MAC_IPV4_AH; 235 + else if (is_ipv6) 236 + ptype = ICE_MAC_IPV6_AH; 237 + goto out; 238 + case VIRTCHNL_PROTO_HDR_PFCP: 239 + if (is_ipv4) 240 + ptype = ICE_MAC_IPV4_PFCP_SESSION; 241 + else if (is_ipv6) 242 + ptype = ICE_MAC_IPV6_PFCP_SESSION; 243 + goto out; 244 + default: 245 + break; 246 + } 247 + i++; 248 + } 249 + 250 + out: 251 + return ice_hw_ptype_ena(&vf->pf->hw, ptype); 252 + } 253 + 254 + /** 255 + * ice_vc_parse_rss_cfg - parses hash fields and headers from 256 + * a specific virtchnl RSS cfg 257 + * @hw: pointer to the hardware 258 + * @rss_cfg: pointer to the virtchnl RSS cfg 259 + * @hash_cfg: pointer to the HW hash configuration 260 + * 261 + * Return true if all the protocol header and hash fields in the RSS cfg could 262 + * be parsed, else return false 263 + * 264 + * This function parses the virtchnl RSS cfg to be the intended 265 + * hash fields and the intended header for RSS configuration 266 + */ 267 + static bool ice_vc_parse_rss_cfg(struct ice_hw *hw, 268 + struct virtchnl_rss_cfg *rss_cfg, 269 + struct ice_rss_hash_cfg *hash_cfg) 270 + { 271 + const struct ice_vc_hash_field_match_type *hf_list; 272 + const struct ice_vc_hdr_match_type *hdr_list; 273 + int i, hf_list_len, hdr_list_len; 274 + u32 *addl_hdrs = &hash_cfg->addl_hdrs; 275 + u64 *hash_flds = &hash_cfg->hash_flds; 276 + 277 + /* set outer layer RSS as default */ 278 + hash_cfg->hdr_type = ICE_RSS_OUTER_HEADERS; 279 + 280 + if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC) 281 + hash_cfg->symm = true; 282 + else 283 + hash_cfg->symm = false; 284 + 285 + hf_list = ice_vc_hash_field_list; 286 + hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list); 287 + hdr_list = ice_vc_hdr_list; 288 + hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list); 289 + 290 + for (i = 0; i < rss_cfg->proto_hdrs.count; i++) { 291 + struct virtchnl_proto_hdr *proto_hdr = 292 + &rss_cfg->proto_hdrs.proto_hdr[i]; 293 + bool hdr_found = false; 294 + int j; 295 + 296 + /* Find matched ice headers according to virtchnl headers. */ 297 + for (j = 0; j < hdr_list_len; j++) { 298 + struct ice_vc_hdr_match_type hdr_map = hdr_list[j]; 299 + 300 + if (proto_hdr->type == hdr_map.vc_hdr) { 301 + *addl_hdrs |= hdr_map.ice_hdr; 302 + hdr_found = true; 303 + } 304 + } 305 + 306 + if (!hdr_found) 307 + return false; 308 + 309 + /* Find matched ice hash fields according to 310 + * virtchnl hash fields. 311 + */ 312 + for (j = 0; j < hf_list_len; j++) { 313 + struct ice_vc_hash_field_match_type hf_map = hf_list[j]; 314 + 315 + if (proto_hdr->type == hf_map.vc_hdr && 316 + proto_hdr->field_selector == hf_map.vc_hash_field) { 317 + *hash_flds |= hf_map.ice_hash_field; 318 + break; 319 + } 320 + } 321 + } 322 + 323 + return true; 324 + } 325 + 326 + /** 327 + * ice_vf_adv_rss_offload_ena - determine if capabilities support advanced 328 + * RSS offloads 329 + * @caps: VF driver negotiated capabilities 330 + * 331 + * Return true if VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF capability is set, 332 + * else return false 333 + */ 334 + static bool ice_vf_adv_rss_offload_ena(u32 caps) 335 + { 336 + return !!(caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF); 337 + } 338 + 339 + /** 340 + * ice_vc_handle_rss_cfg 341 + * @vf: pointer to the VF info 342 + * @msg: pointer to the message buffer 343 + * @add: add a RSS config if true, otherwise delete a RSS config 344 + * 345 + * This function adds/deletes a RSS config 346 + */ 347 + int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add) 348 + { 349 + u32 v_opcode = add ? VIRTCHNL_OP_ADD_RSS_CFG : VIRTCHNL_OP_DEL_RSS_CFG; 350 + struct virtchnl_rss_cfg *rss_cfg = (struct virtchnl_rss_cfg *)msg; 351 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 352 + struct device *dev = ice_pf_to_dev(vf->pf); 353 + struct ice_hw *hw = &vf->pf->hw; 354 + struct ice_vsi *vsi; 355 + 356 + if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 357 + dev_dbg(dev, "VF %d attempting to configure RSS, but RSS is not supported by the PF\n", 358 + vf->vf_id); 359 + v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED; 360 + goto error_param; 361 + } 362 + 363 + if (!ice_vf_adv_rss_offload_ena(vf->driver_caps)) { 364 + dev_dbg(dev, "VF %d attempting to configure RSS, but Advanced RSS offload is not supported\n", 365 + vf->vf_id); 366 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 367 + goto error_param; 368 + } 369 + 370 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 371 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 372 + goto error_param; 373 + } 374 + 375 + if (rss_cfg->proto_hdrs.count > VIRTCHNL_MAX_NUM_PROTO_HDRS || 376 + rss_cfg->rss_algorithm < VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC || 377 + rss_cfg->rss_algorithm > VIRTCHNL_RSS_ALG_XOR_SYMMETRIC) { 378 + dev_dbg(dev, "VF %d attempting to configure RSS, but RSS configuration is not valid\n", 379 + vf->vf_id); 380 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 381 + goto error_param; 382 + } 383 + 384 + vsi = ice_get_vf_vsi(vf); 385 + if (!vsi) { 386 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 387 + goto error_param; 388 + } 389 + 390 + if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) { 391 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 392 + goto error_param; 393 + } 394 + 395 + if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_R_ASYMMETRIC) { 396 + struct ice_vsi_ctx *ctx; 397 + u8 lut_type, hash_type; 398 + int status; 399 + 400 + lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI; 401 + hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_HASH_XOR : 402 + ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; 403 + 404 + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 405 + if (!ctx) { 406 + v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 407 + goto error_param; 408 + } 409 + 410 + ctx->info.q_opt_rss = 411 + FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_LUT_M, lut_type) | 412 + FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_HASH_M, hash_type); 413 + 414 + /* Preserve existing queueing option setting */ 415 + ctx->info.q_opt_rss |= (vsi->info.q_opt_rss & 416 + ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_M); 417 + ctx->info.q_opt_tc = vsi->info.q_opt_tc; 418 + ctx->info.q_opt_flags = vsi->info.q_opt_rss; 419 + 420 + ctx->info.valid_sections = 421 + cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID); 422 + 423 + status = ice_update_vsi(hw, vsi->idx, ctx, NULL); 424 + if (status) { 425 + dev_err(dev, "update VSI for RSS failed, err %d aq_err %s\n", 426 + status, libie_aq_str(hw->adminq.sq_last_status)); 427 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 428 + } else { 429 + vsi->info.q_opt_rss = ctx->info.q_opt_rss; 430 + } 431 + 432 + kfree(ctx); 433 + } else { 434 + struct ice_rss_hash_cfg cfg; 435 + 436 + /* Only check for none raw pattern case */ 437 + if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) { 438 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 439 + goto error_param; 440 + } 441 + cfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE; 442 + cfg.hash_flds = ICE_HASH_INVALID; 443 + cfg.hdr_type = ICE_RSS_ANY_HEADERS; 444 + 445 + if (!ice_vc_parse_rss_cfg(hw, rss_cfg, &cfg)) { 446 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 447 + goto error_param; 448 + } 449 + 450 + if (add) { 451 + if (ice_add_rss_cfg(hw, vsi, &cfg)) { 452 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 453 + dev_err(dev, "ice_add_rss_cfg failed for vsi = %d, v_ret = %d\n", 454 + vsi->vsi_num, v_ret); 455 + } 456 + } else { 457 + int status; 458 + 459 + status = ice_rem_rss_cfg(hw, vsi->idx, &cfg); 460 + /* We just ignore -ENOENT, because if two configurations 461 + * share the same profile remove one of them actually 462 + * removes both, since the profile is deleted. 463 + */ 464 + if (status && status != -ENOENT) { 465 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 466 + dev_err(dev, "ice_rem_rss_cfg failed for VF ID:%d, error:%d\n", 467 + vf->vf_id, status); 468 + } 469 + } 470 + } 471 + 472 + error_param: 473 + return ice_vc_send_msg_to_vf(vf, v_opcode, v_ret, NULL, 0); 474 + } 475 + 476 + /** 477 + * ice_vc_config_rss_key 478 + * @vf: pointer to the VF info 479 + * @msg: pointer to the msg buffer 480 + * 481 + * Configure the VF's RSS key 482 + */ 483 + int ice_vc_config_rss_key(struct ice_vf *vf, u8 *msg) 484 + { 485 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 486 + struct virtchnl_rss_key *vrk = 487 + (struct virtchnl_rss_key *)msg; 488 + struct ice_vsi *vsi; 489 + 490 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 491 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 492 + goto error_param; 493 + } 494 + 495 + if (!ice_vc_isvalid_vsi_id(vf, vrk->vsi_id)) { 496 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 497 + goto error_param; 498 + } 499 + 500 + if (vrk->key_len != ICE_VSIQF_HKEY_ARRAY_SIZE) { 501 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 502 + goto error_param; 503 + } 504 + 505 + if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 506 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 507 + goto error_param; 508 + } 509 + 510 + vsi = ice_get_vf_vsi(vf); 511 + if (!vsi) { 512 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 513 + goto error_param; 514 + } 515 + 516 + if (ice_set_rss_key(vsi, vrk->key)) 517 + v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 518 + error_param: 519 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_KEY, v_ret, 520 + NULL, 0); 521 + } 522 + 523 + /** 524 + * ice_vc_config_rss_lut 525 + * @vf: pointer to the VF info 526 + * @msg: pointer to the msg buffer 527 + * 528 + * Configure the VF's RSS LUT 529 + */ 530 + int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg) 531 + { 532 + struct virtchnl_rss_lut *vrl = (struct virtchnl_rss_lut *)msg; 533 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 534 + struct ice_vsi *vsi; 535 + 536 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 537 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 538 + goto error_param; 539 + } 540 + 541 + if (!ice_vc_isvalid_vsi_id(vf, vrl->vsi_id)) { 542 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 543 + goto error_param; 544 + } 545 + 546 + if (vrl->lut_entries != ICE_LUT_VSI_SIZE) { 547 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 548 + goto error_param; 549 + } 550 + 551 + if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 552 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 553 + goto error_param; 554 + } 555 + 556 + vsi = ice_get_vf_vsi(vf); 557 + if (!vsi) { 558 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 559 + goto error_param; 560 + } 561 + 562 + if (ice_set_rss_lut(vsi, vrl->lut, ICE_LUT_VSI_SIZE)) 563 + v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 564 + error_param: 565 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_LUT, v_ret, 566 + NULL, 0); 567 + } 568 + 569 + /** 570 + * ice_vc_config_rss_hfunc 571 + * @vf: pointer to the VF info 572 + * @msg: pointer to the msg buffer 573 + * 574 + * Configure the VF's RSS Hash function 575 + */ 576 + int ice_vc_config_rss_hfunc(struct ice_vf *vf, u8 *msg) 577 + { 578 + struct virtchnl_rss_hfunc *vrh = (struct virtchnl_rss_hfunc *)msg; 579 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 580 + u8 hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; 581 + struct ice_vsi *vsi; 582 + 583 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 584 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 585 + goto error_param; 586 + } 587 + 588 + if (!ice_vc_isvalid_vsi_id(vf, vrh->vsi_id)) { 589 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 590 + goto error_param; 591 + } 592 + 593 + if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 594 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 595 + goto error_param; 596 + } 597 + 598 + vsi = ice_get_vf_vsi(vf); 599 + if (!vsi) { 600 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 601 + goto error_param; 602 + } 603 + 604 + if (vrh->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC) 605 + hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ; 606 + 607 + if (ice_set_rss_hfunc(vsi, hfunc)) 608 + v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 609 + error_param: 610 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_HFUNC, v_ret, 611 + NULL, 0); 612 + } 613 + 614 + /** 615 + * ice_vc_get_rss_hashcfg - return the RSS Hash configuration 616 + * @vf: pointer to the VF info 617 + */ 618 + int ice_vc_get_rss_hashcfg(struct ice_vf *vf) 619 + { 620 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 621 + struct virtchnl_rss_hashcfg *vrh = NULL; 622 + int len = 0, ret; 623 + 624 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 625 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 626 + goto err; 627 + } 628 + 629 + if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 630 + dev_err(ice_pf_to_dev(vf->pf), "RSS not supported by PF\n"); 631 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 632 + goto err; 633 + } 634 + 635 + len = sizeof(struct virtchnl_rss_hashcfg); 636 + vrh = kzalloc(len, GFP_KERNEL); 637 + if (!vrh) { 638 + v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 639 + len = 0; 640 + goto err; 641 + } 642 + 643 + vrh->hashcfg = ICE_DEFAULT_RSS_HASHCFG; 644 + err: 645 + /* send the response back to the VF */ 646 + ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_RSS_HASHCFG_CAPS, v_ret, 647 + (u8 *)vrh, len); 648 + kfree(vrh); 649 + return ret; 650 + } 651 + 652 + /** 653 + * ice_vc_set_rss_hashcfg - set RSS Hash configuration bits for the VF 654 + * @vf: pointer to the VF info 655 + * @msg: pointer to the msg buffer 656 + */ 657 + int ice_vc_set_rss_hashcfg(struct ice_vf *vf, u8 *msg) 658 + { 659 + struct virtchnl_rss_hashcfg *vrh = (struct virtchnl_rss_hashcfg *)msg; 660 + enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 661 + struct ice_pf *pf = vf->pf; 662 + struct ice_vsi *vsi; 663 + struct device *dev; 664 + int status; 665 + 666 + dev = ice_pf_to_dev(pf); 667 + 668 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 669 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 670 + goto err; 671 + } 672 + 673 + if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 674 + dev_err(dev, "RSS not supported by PF\n"); 675 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 676 + goto err; 677 + } 678 + 679 + vsi = ice_get_vf_vsi(vf); 680 + if (!vsi) { 681 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 682 + goto err; 683 + } 684 + 685 + /* clear all previously programmed RSS configuration to allow VF drivers 686 + * the ability to customize the RSS configuration and/or completely 687 + * disable RSS 688 + */ 689 + status = ice_rem_vsi_rss_cfg(&pf->hw, vsi->idx); 690 + if (status && !vrh->hashcfg) { 691 + /* only report failure to clear the current RSS configuration if 692 + * that was clearly the VF's intention (i.e. vrh->hashcfg = 0) 693 + */ 694 + v_ret = ice_err_to_virt_err(status); 695 + goto err; 696 + } else if (status) { 697 + /* allow the VF to update the RSS configuration even on failure 698 + * to clear the current RSS confguration in an attempt to keep 699 + * RSS in a working state 700 + */ 701 + dev_warn(dev, "Failed to clear the RSS configuration for VF %u\n", 702 + vf->vf_id); 703 + } 704 + 705 + if (vrh->hashcfg) { 706 + status = ice_add_avf_rss_cfg(&pf->hw, vsi, vrh->hashcfg); 707 + v_ret = ice_err_to_virt_err(status); 708 + } 709 + 710 + /* save the requested VF configuration */ 711 + if (!v_ret) 712 + vf->rss_hashcfg = vrh->hashcfg; 713 + 714 + /* send the response to the VF */ 715 + err: 716 + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_SET_RSS_HASHCFG, v_ret, 717 + NULL, 0); 718 + } 719 +
+18
drivers/net/ethernet/intel/ice/virt/rss.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (C) 2022, Intel Corporation. */ 3 + 4 + #ifndef _ICE_VIRT_RSS_H_ 5 + #define _ICE_VIRT_RSS_H_ 6 + 7 + #include <linux/types.h> 8 + 9 + struct ice_vf; 10 + 11 + int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add); 12 + int ice_vc_config_rss_key(struct ice_vf *vf, u8 *msg); 13 + int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg); 14 + int ice_vc_config_rss_hfunc(struct ice_vf *vf, u8 *msg); 15 + int ice_vc_get_rss_hashcfg(struct ice_vf *vf); 16 + int ice_vc_set_rss_hashcfg(struct ice_vf *vf, u8 *msg); 17 + 18 + #endif /* _ICE_VIRT_RSS_H_ */