1333149Serj/****************************************************************************** 2333149Serj 3349163Serj Copyright (c) 2013-2019, Intel Corporation 4333149Serj All rights reserved. 5333149Serj 6333149Serj Redistribution and use in source and binary forms, with or without 7333149Serj modification, are permitted provided that the following conditions are met: 8333149Serj 9333149Serj 1. Redistributions of source code must retain the above copyright notice, 10333149Serj this list of conditions and the following disclaimer. 11333149Serj 12333149Serj 2. Redistributions in binary form must reproduce the above copyright 13333149Serj notice, this list of conditions and the following disclaimer in the 14333149Serj documentation and/or other materials provided with the distribution. 15333149Serj 16333149Serj 3. Neither the name of the Intel Corporation nor the names of its 17333149Serj contributors may be used to endorse or promote products derived from 18333149Serj this software without specific prior written permission. 19333149Serj 20333149Serj THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21333149Serj AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22333149Serj IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23333149Serj ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24333149Serj LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25333149Serj CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26333149Serj SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27333149Serj INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28333149Serj CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29333149Serj ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30333149Serj POSSIBILITY OF SUCH DAMAGE. 31333149Serj 32333149Serj******************************************************************************/ 33333149Serj/*$FreeBSD: stable/11/sys/dev/ixl/virtchnl.h 349163 2019-06-18 00:08:02Z erj $*/ 34333149Serj 35349163Serj 36333149Serj#ifndef _VIRTCHNL_H_ 37333149Serj#define _VIRTCHNL_H_ 38333149Serj 39333149Serj/* Description: 40333149Serj * This header file describes the VF-PF communication protocol used 41333149Serj * by the drivers for all devices starting from our 40G product line 42333149Serj * 43333149Serj * Admin queue buffer usage: 44333149Serj * desc->opcode is always aqc_opc_send_msg_to_pf 45333149Serj * flags, retval, datalen, and data addr are all used normally. 46333149Serj * The Firmware copies the cookie fields when sending messages between the 47333149Serj * PF and VF, but uses all other fields internally. Due to this limitation, 48333149Serj * we must send all messages as "indirect", i.e. using an external buffer. 49333149Serj * 50333149Serj * All the VSI indexes are relative to the VF. Each VF can have maximum of 51333149Serj * three VSIs. All the queue indexes are relative to the VSI. Each VF can 52333149Serj * have a maximum of sixteen queues for all of its VSIs. 53333149Serj * 54333149Serj * The PF is required to return a status code in v_retval for all messages 55333149Serj * except RESET_VF, which does not require any response. The return value 56333149Serj * is of status_code type, defined in the shared type.h. 57333149Serj * 58333149Serj * In general, VF driver initialization should roughly follow the order of 59333149Serj * these opcodes. The VF driver must first validate the API version of the 60333149Serj * PF driver, then request a reset, then get resources, then configure 61333149Serj * queues and interrupts. After these operations are complete, the VF 62333149Serj * driver may start its queues, optionally add MAC and VLAN filters, and 63333149Serj * process traffic. 64333149Serj */ 65333149Serj 66333149Serj/* START GENERIC DEFINES 67333149Serj * Need to ensure the following enums and defines hold the same meaning and 68333149Serj * value in current and future projects 69333149Serj */ 70333149Serj 71333149Serj/* Error Codes */ 72333149Serjenum virtchnl_status_code { 73333149Serj VIRTCHNL_STATUS_SUCCESS = 0, 74349163Serj VIRTCHNL_STATUS_ERR_PARAM = -5, 75349163Serj VIRTCHNL_STATUS_ERR_NO_MEMORY = -18, 76333149Serj VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH = -38, 77333149Serj VIRTCHNL_STATUS_ERR_CQP_COMPL_ERROR = -39, 78333149Serj VIRTCHNL_STATUS_ERR_INVALID_VF_ID = -40, 79349163Serj VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR = -53, 80349163Serj VIRTCHNL_STATUS_ERR_NOT_SUPPORTED = -64, 81333149Serj}; 82333149Serj 83349163Serj/* Backward compatibility */ 84349163Serj#define VIRTCHNL_ERR_PARAM VIRTCHNL_STATUS_ERR_PARAM 85349163Serj#define VIRTCHNL_STATUS_NOT_SUPPORTED VIRTCHNL_STATUS_ERR_NOT_SUPPORTED 86349163Serj 87349163Serj#define VIRTCHNL_LINK_SPEED_2_5GB_SHIFT 0x0 88333149Serj#define VIRTCHNL_LINK_SPEED_100MB_SHIFT 0x1 89333149Serj#define VIRTCHNL_LINK_SPEED_1000MB_SHIFT 0x2 90333149Serj#define VIRTCHNL_LINK_SPEED_10GB_SHIFT 0x3 91333149Serj#define VIRTCHNL_LINK_SPEED_40GB_SHIFT 0x4 92333149Serj#define VIRTCHNL_LINK_SPEED_20GB_SHIFT 0x5 93333149Serj#define VIRTCHNL_LINK_SPEED_25GB_SHIFT 0x6 94349163Serj#define VIRTCHNL_LINK_SPEED_5GB_SHIFT 0x7 95333149Serj 96333149Serjenum virtchnl_link_speed { 97333149Serj VIRTCHNL_LINK_SPEED_UNKNOWN = 0, 98333149Serj VIRTCHNL_LINK_SPEED_100MB = BIT(VIRTCHNL_LINK_SPEED_100MB_SHIFT), 99333149Serj VIRTCHNL_LINK_SPEED_1GB = BIT(VIRTCHNL_LINK_SPEED_1000MB_SHIFT), 100333149Serj VIRTCHNL_LINK_SPEED_10GB = BIT(VIRTCHNL_LINK_SPEED_10GB_SHIFT), 101333149Serj VIRTCHNL_LINK_SPEED_40GB = BIT(VIRTCHNL_LINK_SPEED_40GB_SHIFT), 102333149Serj VIRTCHNL_LINK_SPEED_20GB = BIT(VIRTCHNL_LINK_SPEED_20GB_SHIFT), 103333149Serj VIRTCHNL_LINK_SPEED_25GB = BIT(VIRTCHNL_LINK_SPEED_25GB_SHIFT), 104349163Serj VIRTCHNL_LINK_SPEED_2_5GB = BIT(VIRTCHNL_LINK_SPEED_2_5GB_SHIFT), 105349163Serj VIRTCHNL_LINK_SPEED_5GB = BIT(VIRTCHNL_LINK_SPEED_5GB_SHIFT), 106333149Serj}; 107333149Serj 108333149Serj/* for hsplit_0 field of Rx HMC context */ 109333149Serj/* deprecated with AVF 1.0 */ 110333149Serjenum virtchnl_rx_hsplit { 111333149Serj VIRTCHNL_RX_HSPLIT_NO_SPLIT = 0, 112333149Serj VIRTCHNL_RX_HSPLIT_SPLIT_L2 = 1, 113333149Serj VIRTCHNL_RX_HSPLIT_SPLIT_IP = 2, 114333149Serj VIRTCHNL_RX_HSPLIT_SPLIT_TCP_UDP = 4, 115333149Serj VIRTCHNL_RX_HSPLIT_SPLIT_SCTP = 8, 116333149Serj}; 117333149Serj 118333149Serj#define VIRTCHNL_ETH_LENGTH_OF_ADDRESS 6 119333149Serj/* END GENERIC DEFINES */ 120333149Serj 121333149Serj/* Opcodes for VF-PF communication. These are placed in the v_opcode field 122333149Serj * of the virtchnl_msg structure. 123333149Serj */ 124333149Serjenum virtchnl_ops { 125333149Serj/* The PF sends status change events to VFs using 126333149Serj * the VIRTCHNL_OP_EVENT opcode. 127333149Serj * VFs send requests to the PF using the other ops. 128333149Serj * Use of "advanced opcode" features must be negotiated as part of capabilities 129333149Serj * exchange and are not considered part of base mode feature set. 130333149Serj */ 131333149Serj VIRTCHNL_OP_UNKNOWN = 0, 132333149Serj VIRTCHNL_OP_VERSION = 1, /* must ALWAYS be 1 */ 133333149Serj VIRTCHNL_OP_RESET_VF = 2, 134333149Serj VIRTCHNL_OP_GET_VF_RESOURCES = 3, 135333149Serj VIRTCHNL_OP_CONFIG_TX_QUEUE = 4, 136333149Serj VIRTCHNL_OP_CONFIG_RX_QUEUE = 5, 137333149Serj VIRTCHNL_OP_CONFIG_VSI_QUEUES = 6, 138333149Serj VIRTCHNL_OP_CONFIG_IRQ_MAP = 7, 139333149Serj VIRTCHNL_OP_ENABLE_QUEUES = 8, 140333149Serj VIRTCHNL_OP_DISABLE_QUEUES = 9, 141333149Serj VIRTCHNL_OP_ADD_ETH_ADDR = 10, 142333149Serj VIRTCHNL_OP_DEL_ETH_ADDR = 11, 143333149Serj VIRTCHNL_OP_ADD_VLAN = 12, 144333149Serj VIRTCHNL_OP_DEL_VLAN = 13, 145333149Serj VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE = 14, 146333149Serj VIRTCHNL_OP_GET_STATS = 15, 147333149Serj VIRTCHNL_OP_RSVD = 16, 148333149Serj VIRTCHNL_OP_EVENT = 17, /* must ALWAYS be 17 */ 149349163Serj /* opcode 19 is reserved */ 150333149Serj VIRTCHNL_OP_IWARP = 20, /* advanced opcode */ 151333149Serj VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP = 21, /* advanced opcode */ 152333149Serj VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP = 22, /* advanced opcode */ 153333149Serj VIRTCHNL_OP_CONFIG_RSS_KEY = 23, 154333149Serj VIRTCHNL_OP_CONFIG_RSS_LUT = 24, 155333149Serj VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25, 156333149Serj VIRTCHNL_OP_SET_RSS_HENA = 26, 157333149Serj VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27, 158333149Serj VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28, 159333149Serj VIRTCHNL_OP_REQUEST_QUEUES = 29, 160349163Serj VIRTCHNL_OP_ENABLE_CHANNELS = 30, 161349163Serj VIRTCHNL_OP_DISABLE_CHANNELS = 31, 162349163Serj VIRTCHNL_OP_ADD_CLOUD_FILTER = 32, 163349163Serj VIRTCHNL_OP_DEL_CLOUD_FILTER = 33, 164333149Serj}; 165333149Serj 166349163Serj/* These macros are used to generate compilation errors if a structure/union 167333149Serj * is not exactly the correct length. It gives a divide by zero error if the 168349163Serj * structure/union is not of the correct size, otherwise it creates an enum 169349163Serj * that is never used. 170333149Serj */ 171333149Serj#define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \ 172349163Serj { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) } 173349163Serj#define VIRTCHNL_CHECK_UNION_LEN(n, X) enum virtchnl_static_asset_enum_##X \ 174349163Serj { virtchnl_static_assert_##X = (n)/((sizeof(union X) == (n)) ? 1 : 0) } 175333149Serj 176333149Serj/* Virtual channel message descriptor. This overlays the admin queue 177333149Serj * descriptor. All other data is passed in external buffers. 178333149Serj */ 179333149Serj 180333149Serjstruct virtchnl_msg { 181333149Serj u8 pad[8]; /* AQ flags/opcode/len/retval fields */ 182333149Serj enum virtchnl_ops v_opcode; /* avoid confusion with desc->opcode */ 183333149Serj enum virtchnl_status_code v_retval; /* ditto for desc->retval */ 184333149Serj u32 vfid; /* used by PF when sending to VF */ 185333149Serj}; 186333149Serj 187333149SerjVIRTCHNL_CHECK_STRUCT_LEN(20, virtchnl_msg); 188333149Serj 189349163Serj/* Message descriptions and data structures. */ 190333149Serj 191333149Serj/* VIRTCHNL_OP_VERSION 192333149Serj * VF posts its version number to the PF. PF responds with its version number 193333149Serj * in the same format, along with a return code. 194333149Serj * Reply from PF has its major/minor versions also in param0 and param1. 195333149Serj * If there is a major version mismatch, then the VF cannot operate. 196333149Serj * If there is a minor version mismatch, then the VF can operate but should 197333149Serj * add a warning to the system log. 198333149Serj * 199333149Serj * This enum element MUST always be specified as == 1, regardless of other 200333149Serj * changes in the API. The PF must always respond to this message without 201333149Serj * error regardless of version mismatch. 202333149Serj */ 203333149Serj#define VIRTCHNL_VERSION_MAJOR 1 204333149Serj#define VIRTCHNL_VERSION_MINOR 1 205333149Serj#define VIRTCHNL_VERSION_MINOR_NO_VF_CAPS 0 206333149Serj 207333149Serjstruct virtchnl_version_info { 208333149Serj u32 major; 209333149Serj u32 minor; 210333149Serj}; 211333149Serj 212333149SerjVIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_version_info); 213333149Serj 214333149Serj#define VF_IS_V10(_v) (((_v)->major == 1) && ((_v)->minor == 0)) 215333149Serj#define VF_IS_V11(_ver) (((_ver)->major == 1) && ((_ver)->minor == 1)) 216333149Serj 217333149Serj/* VIRTCHNL_OP_RESET_VF 218333149Serj * VF sends this request to PF with no parameters 219333149Serj * PF does NOT respond! VF driver must delay then poll VFGEN_RSTAT register 220333149Serj * until reset completion is indicated. The admin queue must be reinitialized 221333149Serj * after this operation. 222333149Serj * 223333149Serj * When reset is complete, PF must ensure that all queues in all VSIs associated 224333149Serj * with the VF are stopped, all queue configurations in the HMC are set to 0, 225333149Serj * and all MAC and VLAN filters (except the default MAC address) on all VSIs 226333149Serj * are cleared. 227333149Serj */ 228333149Serj 229333149Serj/* VSI types that use VIRTCHNL interface for VF-PF communication. VSI_SRIOV 230333149Serj * vsi_type should always be 6 for backward compatibility. Add other fields 231333149Serj * as needed. 232333149Serj */ 233333149Serjenum virtchnl_vsi_type { 234333149Serj VIRTCHNL_VSI_TYPE_INVALID = 0, 235333149Serj VIRTCHNL_VSI_SRIOV = 6, 236333149Serj}; 237333149Serj 238333149Serj/* VIRTCHNL_OP_GET_VF_RESOURCES 239333149Serj * Version 1.0 VF sends this request to PF with no parameters 240333149Serj * Version 1.1 VF sends this request to PF with u32 bitmap of its capabilities 241333149Serj * PF responds with an indirect message containing 242333149Serj * virtchnl_vf_resource and one or more 243333149Serj * virtchnl_vsi_resource structures. 244333149Serj */ 245333149Serj 246333149Serjstruct virtchnl_vsi_resource { 247333149Serj u16 vsi_id; 248333149Serj u16 num_queue_pairs; 249333149Serj enum virtchnl_vsi_type vsi_type; 250333149Serj u16 qset_handle; 251333149Serj u8 default_mac_addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS]; 252333149Serj}; 253333149Serj 254333149SerjVIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource); 255333149Serj 256333149Serj/* VF capability flags 257333149Serj * VIRTCHNL_VF_OFFLOAD_L2 flag is inclusive of base mode L2 offloads including 258333149Serj * TX/RX Checksum offloading and TSO for non-tunnelled packets. 259333149Serj */ 260333149Serj#define VIRTCHNL_VF_OFFLOAD_L2 0x00000001 261333149Serj#define VIRTCHNL_VF_OFFLOAD_IWARP 0x00000002 262333149Serj#define VIRTCHNL_VF_OFFLOAD_RSVD 0x00000004 263333149Serj#define VIRTCHNL_VF_OFFLOAD_RSS_AQ 0x00000008 264333149Serj#define VIRTCHNL_VF_OFFLOAD_RSS_REG 0x00000010 265333149Serj#define VIRTCHNL_VF_OFFLOAD_WB_ON_ITR 0x00000020 266333149Serj#define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES 0x00000040 267349163Serj#define VIRTCHNL_VF_OFFLOAD_CRC 0x00000080 268333149Serj#define VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000 269333149Serj#define VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000 270333149Serj#define VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 0x00040000 271333149Serj#define VIRTCHNL_VF_OFFLOAD_RSS_PF 0X00080000 272333149Serj#define VIRTCHNL_VF_OFFLOAD_ENCAP 0X00100000 273333149Serj#define VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM 0X00200000 274333149Serj#define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM 0X00400000 275349163Serj#define VIRTCHNL_VF_OFFLOAD_ADQ 0X00800000 276349163Serj/* Define below the capability flags that are not offloads */ 277349163Serj#define VIRTCHNL_VF_CAP_ADV_LINK_SPEED 0x00000080 278333149Serj#define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \ 279333149Serj VIRTCHNL_VF_OFFLOAD_VLAN | \ 280333149Serj VIRTCHNL_VF_OFFLOAD_RSS_PF) 281333149Serj 282333149Serjstruct virtchnl_vf_resource { 283333149Serj u16 num_vsis; 284333149Serj u16 num_queue_pairs; 285333149Serj u16 max_vectors; 286333149Serj u16 max_mtu; 287333149Serj 288333149Serj u32 vf_cap_flags; 289333149Serj u32 rss_key_size; 290333149Serj u32 rss_lut_size; 291333149Serj 292333149Serj struct virtchnl_vsi_resource vsi_res[1]; 293333149Serj}; 294333149Serj 295333149SerjVIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_vf_resource); 296333149Serj 297333149Serj/* VIRTCHNL_OP_CONFIG_TX_QUEUE 298333149Serj * VF sends this message to set up parameters for one TX queue. 299333149Serj * External data buffer contains one instance of virtchnl_txq_info. 300333149Serj * PF configures requested queue and returns a status code. 301333149Serj */ 302333149Serj 303333149Serj/* Tx queue config info */ 304333149Serjstruct virtchnl_txq_info { 305333149Serj u16 vsi_id; 306333149Serj u16 queue_id; 307333149Serj u16 ring_len; /* number of descriptors, multiple of 8 */ 308333149Serj u16 headwb_enabled; /* deprecated with AVF 1.0 */ 309333149Serj u64 dma_ring_addr; 310333149Serj u64 dma_headwb_addr; /* deprecated with AVF 1.0 */ 311333149Serj}; 312333149Serj 313333149SerjVIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info); 314333149Serj 315333149Serj/* VIRTCHNL_OP_CONFIG_RX_QUEUE 316333149Serj * VF sends this message to set up parameters for one RX queue. 317333149Serj * External data buffer contains one instance of virtchnl_rxq_info. 318349163Serj * PF configures requested queue and returns a status code. The 319349163Serj * crc_disable flag disables CRC stripping on the VF. Setting 320349163Serj * the crc_disable flag to 1 will disable CRC stripping for each 321349163Serj * queue in the VF where the flag is set. The VIRTCHNL_VF_OFFLOAD_CRC 322349163Serj * offload must have been set prior to sending this info or the PF 323349163Serj * will ignore the request. This flag should be set the same for 324349163Serj * all of the queues for a VF. 325333149Serj */ 326333149Serj 327333149Serj/* Rx queue config info */ 328333149Serjstruct virtchnl_rxq_info { 329333149Serj u16 vsi_id; 330333149Serj u16 queue_id; 331333149Serj u32 ring_len; /* number of descriptors, multiple of 32 */ 332333149Serj u16 hdr_size; 333333149Serj u16 splithdr_enabled; /* deprecated with AVF 1.0 */ 334333149Serj u32 databuffer_size; 335333149Serj u32 max_pkt_size; 336349163Serj u8 crc_disable; 337349163Serj u8 pad1[3]; 338333149Serj u64 dma_ring_addr; 339333149Serj enum virtchnl_rx_hsplit rx_split_pos; /* deprecated with AVF 1.0 */ 340333149Serj u32 pad2; 341333149Serj}; 342333149Serj 343333149SerjVIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_rxq_info); 344333149Serj 345333149Serj/* VIRTCHNL_OP_CONFIG_VSI_QUEUES 346349163Serj * VF sends this message to set parameters for active TX and RX queues 347333149Serj * associated with the specified VSI. 348333149Serj * PF configures queues and returns status. 349333149Serj * If the number of queues specified is greater than the number of queues 350333149Serj * associated with the VSI, an error is returned and no queues are configured. 351349163Serj * NOTE: The VF is not required to configure all queues in a single request. 352349163Serj * It may send multiple messages. PF drivers must correctly handle all VF 353349163Serj * requests. 354333149Serj */ 355333149Serjstruct virtchnl_queue_pair_info { 356333149Serj /* NOTE: vsi_id and queue_id should be identical for both queues. */ 357333149Serj struct virtchnl_txq_info txq; 358333149Serj struct virtchnl_rxq_info rxq; 359333149Serj}; 360333149Serj 361333149SerjVIRTCHNL_CHECK_STRUCT_LEN(64, virtchnl_queue_pair_info); 362333149Serj 363333149Serjstruct virtchnl_vsi_queue_config_info { 364333149Serj u16 vsi_id; 365333149Serj u16 num_queue_pairs; 366333149Serj u32 pad; 367333149Serj struct virtchnl_queue_pair_info qpair[1]; 368333149Serj}; 369333149Serj 370333149SerjVIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_vsi_queue_config_info); 371333149Serj 372333149Serj/* VIRTCHNL_OP_REQUEST_QUEUES 373333149Serj * VF sends this message to request the PF to allocate additional queues to 374333149Serj * this VF. Each VF gets a guaranteed number of queues on init but asking for 375333149Serj * additional queues must be negotiated. This is a best effort request as it 376333149Serj * is possible the PF does not have enough queues left to support the request. 377333149Serj * If the PF cannot support the number requested it will respond with the 378333149Serj * maximum number it is able to support; otherwise it will respond with the 379333149Serj * number requested. 380333149Serj */ 381333149Serj 382333149Serj/* VF resource request */ 383333149Serjstruct virtchnl_vf_res_request { 384333149Serj u16 num_queue_pairs; 385333149Serj}; 386333149Serj 387333149Serj/* VIRTCHNL_OP_CONFIG_IRQ_MAP 388333149Serj * VF uses this message to map vectors to queues. 389333149Serj * The rxq_map and txq_map fields are bitmaps used to indicate which queues 390333149Serj * are to be associated with the specified vector. 391349163Serj * The "other" causes are always mapped to vector 0. The VF may not request 392349163Serj * that vector 0 be used for traffic. 393333149Serj * PF configures interrupt mapping and returns status. 394349163Serj * NOTE: due to hardware requirements, all active queues (both TX and RX) 395349163Serj * should be mapped to interrupts, even if the driver intends to operate 396349163Serj * only in polling mode. In this case the interrupt may be disabled, but 397349163Serj * the ITR timer will still run to trigger writebacks. 398333149Serj */ 399333149Serjstruct virtchnl_vector_map { 400333149Serj u16 vsi_id; 401333149Serj u16 vector_id; 402333149Serj u16 rxq_map; 403333149Serj u16 txq_map; 404333149Serj u16 rxitr_idx; 405333149Serj u16 txitr_idx; 406333149Serj}; 407333149Serj 408333149SerjVIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_vector_map); 409333149Serj 410333149Serjstruct virtchnl_irq_map_info { 411333149Serj u16 num_vectors; 412333149Serj struct virtchnl_vector_map vecmap[1]; 413333149Serj}; 414333149Serj 415333149SerjVIRTCHNL_CHECK_STRUCT_LEN(14, virtchnl_irq_map_info); 416333149Serj 417333149Serj/* VIRTCHNL_OP_ENABLE_QUEUES 418333149Serj * VIRTCHNL_OP_DISABLE_QUEUES 419333149Serj * VF sends these message to enable or disable TX/RX queue pairs. 420333149Serj * The queues fields are bitmaps indicating which queues to act upon. 421333149Serj * (Currently, we only support 16 queues per VF, but we make the field 422333149Serj * u32 to allow for expansion.) 423333149Serj * PF performs requested action and returns status. 424349163Serj * NOTE: The VF is not required to enable/disable all queues in a single 425349163Serj * request. It may send multiple messages. 426349163Serj * PF drivers must correctly handle all VF requests. 427333149Serj */ 428333149Serjstruct virtchnl_queue_select { 429333149Serj u16 vsi_id; 430333149Serj u16 pad; 431333149Serj u32 rx_queues; 432333149Serj u32 tx_queues; 433333149Serj}; 434333149Serj 435333149SerjVIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_queue_select); 436333149Serj 437333149Serj/* VIRTCHNL_OP_ADD_ETH_ADDR 438333149Serj * VF sends this message in order to add one or more unicast or multicast 439333149Serj * address filters for the specified VSI. 440333149Serj * PF adds the filters and returns status. 441333149Serj */ 442333149Serj 443333149Serj/* VIRTCHNL_OP_DEL_ETH_ADDR 444333149Serj * VF sends this message in order to remove one or more unicast or multicast 445333149Serj * filters for the specified VSI. 446333149Serj * PF removes the filters and returns status. 447333149Serj */ 448333149Serj 449333149Serjstruct virtchnl_ether_addr { 450333149Serj u8 addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS]; 451333149Serj u8 pad[2]; 452333149Serj}; 453333149Serj 454333149SerjVIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr); 455333149Serj 456333149Serjstruct virtchnl_ether_addr_list { 457333149Serj u16 vsi_id; 458333149Serj u16 num_elements; 459333149Serj struct virtchnl_ether_addr list[1]; 460333149Serj}; 461333149Serj 462333149SerjVIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_ether_addr_list); 463333149Serj 464333149Serj/* VIRTCHNL_OP_ADD_VLAN 465333149Serj * VF sends this message to add one or more VLAN tag filters for receives. 466333149Serj * PF adds the filters and returns status. 467333149Serj * If a port VLAN is configured by the PF, this operation will return an 468333149Serj * error to the VF. 469333149Serj */ 470333149Serj 471333149Serj/* VIRTCHNL_OP_DEL_VLAN 472333149Serj * VF sends this message to remove one or more VLAN tag filters for receives. 473333149Serj * PF removes the filters and returns status. 474333149Serj * If a port VLAN is configured by the PF, this operation will return an 475333149Serj * error to the VF. 476333149Serj */ 477333149Serj 478333149Serjstruct virtchnl_vlan_filter_list { 479333149Serj u16 vsi_id; 480333149Serj u16 num_elements; 481333149Serj u16 vlan_id[1]; 482333149Serj}; 483333149Serj 484333149SerjVIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_vlan_filter_list); 485333149Serj 486333149Serj/* VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE 487333149Serj * VF sends VSI id and flags. 488333149Serj * PF returns status code in retval. 489333149Serj * Note: we assume that broadcast accept mode is always enabled. 490333149Serj */ 491333149Serjstruct virtchnl_promisc_info { 492333149Serj u16 vsi_id; 493333149Serj u16 flags; 494333149Serj}; 495333149Serj 496333149SerjVIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_promisc_info); 497333149Serj 498333149Serj#define FLAG_VF_UNICAST_PROMISC 0x00000001 499333149Serj#define FLAG_VF_MULTICAST_PROMISC 0x00000002 500333149Serj 501333149Serj/* VIRTCHNL_OP_GET_STATS 502333149Serj * VF sends this message to request stats for the selected VSI. VF uses 503333149Serj * the virtchnl_queue_select struct to specify the VSI. The queue_id 504333149Serj * field is ignored by the PF. 505333149Serj * 506349163Serj * PF replies with struct virtchnl_eth_stats in an external buffer. 507333149Serj */ 508333149Serj 509349163Serjstruct virtchnl_eth_stats { 510349163Serj u64 rx_bytes; /* received bytes */ 511349163Serj u64 rx_unicast; /* received unicast pkts */ 512349163Serj u64 rx_multicast; /* received multicast pkts */ 513349163Serj u64 rx_broadcast; /* received broadcast pkts */ 514349163Serj u64 rx_discards; 515349163Serj u64 rx_unknown_protocol; 516349163Serj u64 tx_bytes; /* transmitted bytes */ 517349163Serj u64 tx_unicast; /* transmitted unicast pkts */ 518349163Serj u64 tx_multicast; /* transmitted multicast pkts */ 519349163Serj u64 tx_broadcast; /* transmitted broadcast pkts */ 520349163Serj u64 tx_discards; 521349163Serj u64 tx_errors; 522349163Serj}; 523349163Serj 524333149Serj/* VIRTCHNL_OP_CONFIG_RSS_KEY 525333149Serj * VIRTCHNL_OP_CONFIG_RSS_LUT 526333149Serj * VF sends these messages to configure RSS. Only supported if both PF 527333149Serj * and VF drivers set the VIRTCHNL_VF_OFFLOAD_RSS_PF bit during 528333149Serj * configuration negotiation. If this is the case, then the RSS fields in 529333149Serj * the VF resource struct are valid. 530333149Serj * Both the key and LUT are initialized to 0 by the PF, meaning that 531333149Serj * RSS is effectively disabled until set up by the VF. 532333149Serj */ 533333149Serjstruct virtchnl_rss_key { 534333149Serj u16 vsi_id; 535333149Serj u16 key_len; 536333149Serj u8 key[1]; /* RSS hash key, packed bytes */ 537333149Serj}; 538333149Serj 539333149SerjVIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_key); 540333149Serj 541333149Serjstruct virtchnl_rss_lut { 542333149Serj u16 vsi_id; 543333149Serj u16 lut_entries; 544333149Serj u8 lut[1]; /* RSS lookup table */ 545333149Serj}; 546333149Serj 547333149SerjVIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_lut); 548333149Serj 549333149Serj/* VIRTCHNL_OP_GET_RSS_HENA_CAPS 550333149Serj * VIRTCHNL_OP_SET_RSS_HENA 551333149Serj * VF sends these messages to get and set the hash filter enable bits for RSS. 552333149Serj * By default, the PF sets these to all possible traffic types that the 553333149Serj * hardware supports. The VF can query this value if it wants to change the 554333149Serj * traffic types that are hashed by the hardware. 555333149Serj */ 556333149Serjstruct virtchnl_rss_hena { 557333149Serj u64 hena; 558333149Serj}; 559333149Serj 560333149SerjVIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena); 561333149Serj 562349163Serj/* VIRTCHNL_OP_ENABLE_CHANNELS 563349163Serj * VIRTCHNL_OP_DISABLE_CHANNELS 564349163Serj * VF sends these messages to enable or disable channels based on 565349163Serj * the user specified queue count and queue offset for each traffic class. 566349163Serj * This struct encompasses all the information that the PF needs from 567349163Serj * VF to create a channel. 568349163Serj */ 569349163Serjstruct virtchnl_channel_info { 570349163Serj u16 count; /* number of queues in a channel */ 571349163Serj u16 offset; /* queues in a channel start from 'offset' */ 572349163Serj u32 pad; 573349163Serj u64 max_tx_rate; 574349163Serj}; 575349163Serj 576349163SerjVIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_channel_info); 577349163Serj 578349163Serjstruct virtchnl_tc_info { 579349163Serj u32 num_tc; 580349163Serj u32 pad; 581349163Serj struct virtchnl_channel_info list[1]; 582349163Serj}; 583349163Serj 584349163SerjVIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_tc_info); 585349163Serj 586349163Serj/* VIRTCHNL_ADD_CLOUD_FILTER 587349163Serj * VIRTCHNL_DEL_CLOUD_FILTER 588349163Serj * VF sends these messages to add or delete a cloud filter based on the 589349163Serj * user specified match and action filters. These structures encompass 590349163Serj * all the information that the PF needs from the VF to add/delete a 591349163Serj * cloud filter. 592349163Serj */ 593349163Serj 594349163Serjstruct virtchnl_l4_spec { 595349163Serj u8 src_mac[ETH_ALEN]; 596349163Serj u8 dst_mac[ETH_ALEN]; 597349163Serj __be16 vlan_id; 598349163Serj __be16 pad; /* reserved for future use */ 599349163Serj __be32 src_ip[4]; 600349163Serj __be32 dst_ip[4]; 601349163Serj __be16 src_port; 602349163Serj __be16 dst_port; 603349163Serj}; 604349163Serj 605349163SerjVIRTCHNL_CHECK_STRUCT_LEN(52, virtchnl_l4_spec); 606349163Serj 607349163Serjunion virtchnl_flow_spec { 608349163Serj struct virtchnl_l4_spec tcp_spec; 609349163Serj u8 buffer[128]; /* reserved for future use */ 610349163Serj}; 611349163Serj 612349163SerjVIRTCHNL_CHECK_UNION_LEN(128, virtchnl_flow_spec); 613349163Serj 614349163Serjenum virtchnl_action { 615349163Serj /* action types */ 616349163Serj VIRTCHNL_ACTION_DROP = 0, 617349163Serj VIRTCHNL_ACTION_TC_REDIRECT, 618349163Serj}; 619349163Serj 620349163Serjenum virtchnl_flow_type { 621349163Serj /* flow types */ 622349163Serj VIRTCHNL_TCP_V4_FLOW = 0, 623349163Serj VIRTCHNL_TCP_V6_FLOW, 624349163Serj}; 625349163Serj 626349163Serjstruct virtchnl_filter { 627349163Serj union virtchnl_flow_spec data; 628349163Serj union virtchnl_flow_spec mask; 629349163Serj enum virtchnl_flow_type flow_type; 630349163Serj enum virtchnl_action action; 631349163Serj u32 action_meta; 632349163Serj u8 field_flags; 633349163Serj}; 634349163Serj 635349163SerjVIRTCHNL_CHECK_STRUCT_LEN(272, virtchnl_filter); 636349163Serj 637333149Serj/* VIRTCHNL_OP_EVENT 638333149Serj * PF sends this message to inform the VF driver of events that may affect it. 639333149Serj * No direct response is expected from the VF, though it may generate other 640333149Serj * messages in response to this one. 641333149Serj */ 642333149Serjenum virtchnl_event_codes { 643333149Serj VIRTCHNL_EVENT_UNKNOWN = 0, 644333149Serj VIRTCHNL_EVENT_LINK_CHANGE, 645333149Serj VIRTCHNL_EVENT_RESET_IMPENDING, 646333149Serj VIRTCHNL_EVENT_PF_DRIVER_CLOSE, 647333149Serj}; 648333149Serj 649333149Serj#define PF_EVENT_SEVERITY_INFO 0 650333149Serj#define PF_EVENT_SEVERITY_ATTENTION 1 651333149Serj#define PF_EVENT_SEVERITY_ACTION_REQUIRED 2 652333149Serj#define PF_EVENT_SEVERITY_CERTAIN_DOOM 255 653333149Serj 654333149Serjstruct virtchnl_pf_event { 655333149Serj enum virtchnl_event_codes event; 656333149Serj union { 657349163Serj /* If the PF driver does not support the new speed reporting 658349163Serj * capabilities then use link_event else use link_event_adv to 659349163Serj * get the speed and link information. The ability to understand 660349163Serj * new speeds is indicated by setting the capability flag 661349163Serj * VIRTCHNL_VF_CAP_ADV_LINK_SPEED in vf_cap_flags parameter 662349163Serj * in virtchnl_vf_resource struct and can be used to determine 663349163Serj * which link event struct to use below. 664349163Serj */ 665333149Serj struct { 666333149Serj enum virtchnl_link_speed link_speed; 667349163Serj u8 link_status; 668333149Serj } link_event; 669349163Serj struct { 670349163Serj /* link_speed provided in Mbps */ 671349163Serj u32 link_speed; 672349163Serj u8 link_status; 673349163Serj } link_event_adv; 674333149Serj } event_data; 675333149Serj 676333149Serj int severity; 677333149Serj}; 678333149Serj 679333149SerjVIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_pf_event); 680333149Serj 681333149Serj 682333149Serj/* VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP 683333149Serj * VF uses this message to request PF to map IWARP vectors to IWARP queues. 684333149Serj * The request for this originates from the VF IWARP driver through 685333149Serj * a client interface between VF LAN and VF IWARP driver. 686333149Serj * A vector could have an AEQ and CEQ attached to it although 687333149Serj * there is a single AEQ per VF IWARP instance in which case 688333149Serj * most vectors will have an INVALID_IDX for aeq and valid idx for ceq. 689333149Serj * There will never be a case where there will be multiple CEQs attached 690333149Serj * to a single vector. 691333149Serj * PF configures interrupt mapping and returns status. 692333149Serj */ 693333149Serjstruct virtchnl_iwarp_qv_info { 694333149Serj u32 v_idx; /* msix_vector */ 695333149Serj u16 ceq_idx; 696333149Serj u16 aeq_idx; 697333149Serj u8 itr_idx; 698333149Serj}; 699333149Serj 700333149SerjVIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_iwarp_qv_info); 701333149Serj 702333149Serjstruct virtchnl_iwarp_qvlist_info { 703333149Serj u32 num_vectors; 704333149Serj struct virtchnl_iwarp_qv_info qv_info[1]; 705333149Serj}; 706333149Serj 707333149SerjVIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_iwarp_qvlist_info); 708333149Serj 709333149Serj 710349163Serj/* Since VF messages are limited by u16 size, precalculate the maximum possible 711349163Serj * values of nested elements in virtchnl structures that virtual channel can 712349163Serj * possibly handle in a single message. 713349163Serj */ 714349163Serjenum virtchnl_vector_limits { 715349163Serj VIRTCHNL_OP_CONFIG_VSI_QUEUES_MAX = 716349163Serj ((u16)(~0) - sizeof(struct virtchnl_vsi_queue_config_info)) / 717349163Serj sizeof(struct virtchnl_queue_pair_info), 718349163Serj 719349163Serj VIRTCHNL_OP_CONFIG_IRQ_MAP_MAX = 720349163Serj ((u16)(~0) - sizeof(struct virtchnl_irq_map_info)) / 721349163Serj sizeof(struct virtchnl_vector_map), 722349163Serj 723349163Serj VIRTCHNL_OP_ADD_DEL_ETH_ADDR_MAX = 724349163Serj ((u16)(~0) - sizeof(struct virtchnl_ether_addr_list)) / 725349163Serj sizeof(struct virtchnl_ether_addr), 726349163Serj 727349163Serj VIRTCHNL_OP_ADD_DEL_VLAN_MAX = 728349163Serj ((u16)(~0) - sizeof(struct virtchnl_vlan_filter_list)) / 729349163Serj sizeof(u16), 730349163Serj 731349163Serj VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP_MAX = 732349163Serj ((u16)(~0) - sizeof(struct virtchnl_iwarp_qvlist_info)) / 733349163Serj sizeof(struct virtchnl_iwarp_qv_info), 734349163Serj 735349163Serj VIRTCHNL_OP_ENABLE_CHANNELS_MAX = 736349163Serj ((u16)(~0) - sizeof(struct virtchnl_tc_info)) / 737349163Serj sizeof(struct virtchnl_channel_info), 738349163Serj}; 739349163Serj 740333149Serj/* VF reset states - these are written into the RSTAT register: 741333149Serj * VFGEN_RSTAT on the VF 742333149Serj * When the PF initiates a reset, it writes 0 743333149Serj * When the reset is complete, it writes 1 744333149Serj * When the PF detects that the VF has recovered, it writes 2 745333149Serj * VF checks this register periodically to determine if a reset has occurred, 746333149Serj * then polls it to know when the reset is complete. 747333149Serj * If either the PF or VF reads the register while the hardware 748333149Serj * is in a reset state, it will return DEADBEEF, which, when masked 749333149Serj * will result in 3. 750333149Serj */ 751333149Serjenum virtchnl_vfr_states { 752333149Serj VIRTCHNL_VFR_INPROGRESS = 0, 753333149Serj VIRTCHNL_VFR_COMPLETED, 754333149Serj VIRTCHNL_VFR_VFACTIVE, 755333149Serj}; 756333149Serj 757333149Serj/** 758333149Serj * virtchnl_vc_validate_vf_msg 759333149Serj * @ver: Virtchnl version info 760333149Serj * @v_opcode: Opcode for the message 761333149Serj * @msg: pointer to the msg buffer 762333149Serj * @msglen: msg length 763333149Serj * 764333149Serj * validate msg format against struct for each opcode 765333149Serj */ 766333149Serjstatic inline int 767333149Serjvirtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, 768333149Serj u8 *msg, u16 msglen) 769333149Serj{ 770333149Serj bool err_msg_format = FALSE; 771333149Serj int valid_len = 0; 772333149Serj 773333149Serj /* Validate message length. */ 774333149Serj switch (v_opcode) { 775333149Serj case VIRTCHNL_OP_VERSION: 776333149Serj valid_len = sizeof(struct virtchnl_version_info); 777333149Serj break; 778333149Serj case VIRTCHNL_OP_RESET_VF: 779333149Serj break; 780333149Serj case VIRTCHNL_OP_GET_VF_RESOURCES: 781333149Serj if (VF_IS_V11(ver)) 782333149Serj valid_len = sizeof(u32); 783333149Serj break; 784333149Serj case VIRTCHNL_OP_CONFIG_TX_QUEUE: 785333149Serj valid_len = sizeof(struct virtchnl_txq_info); 786333149Serj break; 787333149Serj case VIRTCHNL_OP_CONFIG_RX_QUEUE: 788333149Serj valid_len = sizeof(struct virtchnl_rxq_info); 789333149Serj break; 790333149Serj case VIRTCHNL_OP_CONFIG_VSI_QUEUES: 791333149Serj valid_len = sizeof(struct virtchnl_vsi_queue_config_info); 792333149Serj if (msglen >= valid_len) { 793333149Serj struct virtchnl_vsi_queue_config_info *vqc = 794333149Serj (struct virtchnl_vsi_queue_config_info *)msg; 795349163Serj 796349163Serj if (vqc->num_queue_pairs == 0 || vqc->num_queue_pairs > 797349163Serj VIRTCHNL_OP_CONFIG_VSI_QUEUES_MAX) { 798349163Serj err_msg_format = TRUE; 799349163Serj break; 800349163Serj } 801349163Serj 802333149Serj valid_len += (vqc->num_queue_pairs * 803333149Serj sizeof(struct 804333149Serj virtchnl_queue_pair_info)); 805333149Serj } 806333149Serj break; 807333149Serj case VIRTCHNL_OP_CONFIG_IRQ_MAP: 808333149Serj valid_len = sizeof(struct virtchnl_irq_map_info); 809333149Serj if (msglen >= valid_len) { 810333149Serj struct virtchnl_irq_map_info *vimi = 811333149Serj (struct virtchnl_irq_map_info *)msg; 812349163Serj 813349163Serj if (vimi->num_vectors == 0 || vimi->num_vectors > 814349163Serj VIRTCHNL_OP_CONFIG_IRQ_MAP_MAX) { 815349163Serj err_msg_format = TRUE; 816349163Serj break; 817349163Serj } 818349163Serj 819333149Serj valid_len += (vimi->num_vectors * 820333149Serj sizeof(struct virtchnl_vector_map)); 821333149Serj } 822333149Serj break; 823333149Serj case VIRTCHNL_OP_ENABLE_QUEUES: 824333149Serj case VIRTCHNL_OP_DISABLE_QUEUES: 825333149Serj valid_len = sizeof(struct virtchnl_queue_select); 826333149Serj break; 827333149Serj case VIRTCHNL_OP_ADD_ETH_ADDR: 828333149Serj case VIRTCHNL_OP_DEL_ETH_ADDR: 829333149Serj valid_len = sizeof(struct virtchnl_ether_addr_list); 830333149Serj if (msglen >= valid_len) { 831333149Serj struct virtchnl_ether_addr_list *veal = 832333149Serj (struct virtchnl_ether_addr_list *)msg; 833349163Serj 834349163Serj if (veal->num_elements == 0 || veal->num_elements > 835349163Serj VIRTCHNL_OP_ADD_DEL_ETH_ADDR_MAX) { 836349163Serj err_msg_format = TRUE; 837349163Serj break; 838349163Serj } 839349163Serj 840333149Serj valid_len += veal->num_elements * 841333149Serj sizeof(struct virtchnl_ether_addr); 842333149Serj } 843333149Serj break; 844333149Serj case VIRTCHNL_OP_ADD_VLAN: 845333149Serj case VIRTCHNL_OP_DEL_VLAN: 846333149Serj valid_len = sizeof(struct virtchnl_vlan_filter_list); 847333149Serj if (msglen >= valid_len) { 848333149Serj struct virtchnl_vlan_filter_list *vfl = 849333149Serj (struct virtchnl_vlan_filter_list *)msg; 850349163Serj 851349163Serj if (vfl->num_elements == 0 || vfl->num_elements > 852349163Serj VIRTCHNL_OP_ADD_DEL_VLAN_MAX) { 853349163Serj err_msg_format = TRUE; 854349163Serj break; 855349163Serj } 856349163Serj 857333149Serj valid_len += vfl->num_elements * sizeof(u16); 858333149Serj } 859333149Serj break; 860333149Serj case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: 861333149Serj valid_len = sizeof(struct virtchnl_promisc_info); 862333149Serj break; 863333149Serj case VIRTCHNL_OP_GET_STATS: 864333149Serj valid_len = sizeof(struct virtchnl_queue_select); 865333149Serj break; 866333149Serj case VIRTCHNL_OP_IWARP: 867333149Serj /* These messages are opaque to us and will be validated in 868333149Serj * the RDMA client code. We just need to check for nonzero 869333149Serj * length. The firmware will enforce max length restrictions. 870333149Serj */ 871333149Serj if (msglen) 872333149Serj valid_len = msglen; 873333149Serj else 874333149Serj err_msg_format = TRUE; 875333149Serj break; 876333149Serj case VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP: 877333149Serj break; 878333149Serj case VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP: 879333149Serj valid_len = sizeof(struct virtchnl_iwarp_qvlist_info); 880333149Serj if (msglen >= valid_len) { 881333149Serj struct virtchnl_iwarp_qvlist_info *qv = 882333149Serj (struct virtchnl_iwarp_qvlist_info *)msg; 883349163Serj 884349163Serj if (qv->num_vectors == 0 || qv->num_vectors > 885349163Serj VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP_MAX) { 886333149Serj err_msg_format = TRUE; 887333149Serj break; 888333149Serj } 889349163Serj 890333149Serj valid_len += ((qv->num_vectors - 1) * 891333149Serj sizeof(struct virtchnl_iwarp_qv_info)); 892333149Serj } 893333149Serj break; 894333149Serj case VIRTCHNL_OP_CONFIG_RSS_KEY: 895333149Serj valid_len = sizeof(struct virtchnl_rss_key); 896333149Serj if (msglen >= valid_len) { 897333149Serj struct virtchnl_rss_key *vrk = 898333149Serj (struct virtchnl_rss_key *)msg; 899333149Serj valid_len += vrk->key_len - 1; 900333149Serj } 901333149Serj break; 902333149Serj case VIRTCHNL_OP_CONFIG_RSS_LUT: 903333149Serj valid_len = sizeof(struct virtchnl_rss_lut); 904333149Serj if (msglen >= valid_len) { 905333149Serj struct virtchnl_rss_lut *vrl = 906333149Serj (struct virtchnl_rss_lut *)msg; 907333149Serj valid_len += vrl->lut_entries - 1; 908333149Serj } 909333149Serj break; 910333149Serj case VIRTCHNL_OP_GET_RSS_HENA_CAPS: 911333149Serj break; 912333149Serj case VIRTCHNL_OP_SET_RSS_HENA: 913333149Serj valid_len = sizeof(struct virtchnl_rss_hena); 914333149Serj break; 915333149Serj case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING: 916333149Serj case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING: 917333149Serj break; 918333149Serj case VIRTCHNL_OP_REQUEST_QUEUES: 919333149Serj valid_len = sizeof(struct virtchnl_vf_res_request); 920333149Serj break; 921349163Serj case VIRTCHNL_OP_ENABLE_CHANNELS: 922349163Serj valid_len = sizeof(struct virtchnl_tc_info); 923349163Serj if (msglen >= valid_len) { 924349163Serj struct virtchnl_tc_info *vti = 925349163Serj (struct virtchnl_tc_info *)msg; 926349163Serj 927349163Serj if (vti->num_tc == 0 || vti->num_tc > 928349163Serj VIRTCHNL_OP_ENABLE_CHANNELS_MAX) { 929349163Serj err_msg_format = TRUE; 930349163Serj break; 931349163Serj } 932349163Serj 933349163Serj valid_len += (vti->num_tc - 1) * 934349163Serj sizeof(struct virtchnl_channel_info); 935349163Serj } 936349163Serj break; 937349163Serj case VIRTCHNL_OP_DISABLE_CHANNELS: 938349163Serj break; 939349163Serj case VIRTCHNL_OP_ADD_CLOUD_FILTER: 940349163Serj /* fall through */ 941349163Serj case VIRTCHNL_OP_DEL_CLOUD_FILTER: 942349163Serj valid_len = sizeof(struct virtchnl_filter); 943349163Serj break; 944333149Serj /* These are always errors coming from the VF. */ 945333149Serj case VIRTCHNL_OP_EVENT: 946333149Serj case VIRTCHNL_OP_UNKNOWN: 947333149Serj default: 948349163Serj return VIRTCHNL_STATUS_ERR_PARAM; 949333149Serj } 950333149Serj /* few more checks */ 951333149Serj if (err_msg_format || valid_len != msglen) 952333149Serj return VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH; 953333149Serj 954333149Serj return 0; 955333149Serj} 956333149Serj#endif /* _VIRTCHNL_H_ */ 957