Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*******************************************************************************
0003  *
0004  * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
0005  * Copyright(c) 2013 - 2014 Intel Corporation.
0006  *
0007  * Contact Information:
0008  * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
0009  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
0010  *
0011  ******************************************************************************/
0012 
0013 #ifndef _VIRTCHNL_H_
0014 #define _VIRTCHNL_H_
0015 
0016 /* Description:
0017  * This header file describes the VF-PF communication protocol used
0018  * by the drivers for all devices starting from our 40G product line
0019  *
0020  * Admin queue buffer usage:
0021  * desc->opcode is always aqc_opc_send_msg_to_pf
0022  * flags, retval, datalen, and data addr are all used normally.
0023  * The Firmware copies the cookie fields when sending messages between the
0024  * PF and VF, but uses all other fields internally. Due to this limitation,
0025  * we must send all messages as "indirect", i.e. using an external buffer.
0026  *
0027  * All the VSI indexes are relative to the VF. Each VF can have maximum of
0028  * three VSIs. All the queue indexes are relative to the VSI.  Each VF can
0029  * have a maximum of sixteen queues for all of its VSIs.
0030  *
0031  * The PF is required to return a status code in v_retval for all messages
0032  * except RESET_VF, which does not require any response. The return value
0033  * is of status_code type, defined in the shared type.h.
0034  *
0035  * In general, VF driver initialization should roughly follow the order of
0036  * these opcodes. The VF driver must first validate the API version of the
0037  * PF driver, then request a reset, then get resources, then configure
0038  * queues and interrupts. After these operations are complete, the VF
0039  * driver may start its queues, optionally add MAC and VLAN filters, and
0040  * process traffic.
0041  */
0042 
0043 /* START GENERIC DEFINES
0044  * Need to ensure the following enums and defines hold the same meaning and
0045  * value in current and future projects
0046  */
0047 
0048 /* Error Codes */
0049 enum virtchnl_status_code {
0050     VIRTCHNL_STATUS_SUCCESS             = 0,
0051     VIRTCHNL_STATUS_ERR_PARAM           = -5,
0052     VIRTCHNL_STATUS_ERR_NO_MEMORY           = -18,
0053     VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH     = -38,
0054     VIRTCHNL_STATUS_ERR_CQP_COMPL_ERROR     = -39,
0055     VIRTCHNL_STATUS_ERR_INVALID_VF_ID       = -40,
0056     VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR       = -53,
0057     VIRTCHNL_STATUS_ERR_NOT_SUPPORTED       = -64,
0058 };
0059 
0060 /* Backward compatibility */
0061 #define VIRTCHNL_ERR_PARAM VIRTCHNL_STATUS_ERR_PARAM
0062 #define VIRTCHNL_STATUS_NOT_SUPPORTED VIRTCHNL_STATUS_ERR_NOT_SUPPORTED
0063 
0064 #define VIRTCHNL_LINK_SPEED_2_5GB_SHIFT     0x0
0065 #define VIRTCHNL_LINK_SPEED_100MB_SHIFT     0x1
0066 #define VIRTCHNL_LINK_SPEED_1000MB_SHIFT    0x2
0067 #define VIRTCHNL_LINK_SPEED_10GB_SHIFT      0x3
0068 #define VIRTCHNL_LINK_SPEED_40GB_SHIFT      0x4
0069 #define VIRTCHNL_LINK_SPEED_20GB_SHIFT      0x5
0070 #define VIRTCHNL_LINK_SPEED_25GB_SHIFT      0x6
0071 #define VIRTCHNL_LINK_SPEED_5GB_SHIFT       0x7
0072 
0073 enum virtchnl_link_speed {
0074     VIRTCHNL_LINK_SPEED_UNKNOWN = 0,
0075     VIRTCHNL_LINK_SPEED_100MB   = BIT(VIRTCHNL_LINK_SPEED_100MB_SHIFT),
0076     VIRTCHNL_LINK_SPEED_1GB     = BIT(VIRTCHNL_LINK_SPEED_1000MB_SHIFT),
0077     VIRTCHNL_LINK_SPEED_10GB    = BIT(VIRTCHNL_LINK_SPEED_10GB_SHIFT),
0078     VIRTCHNL_LINK_SPEED_40GB    = BIT(VIRTCHNL_LINK_SPEED_40GB_SHIFT),
0079     VIRTCHNL_LINK_SPEED_20GB    = BIT(VIRTCHNL_LINK_SPEED_20GB_SHIFT),
0080     VIRTCHNL_LINK_SPEED_25GB    = BIT(VIRTCHNL_LINK_SPEED_25GB_SHIFT),
0081     VIRTCHNL_LINK_SPEED_2_5GB   = BIT(VIRTCHNL_LINK_SPEED_2_5GB_SHIFT),
0082     VIRTCHNL_LINK_SPEED_5GB     = BIT(VIRTCHNL_LINK_SPEED_5GB_SHIFT),
0083 };
0084 
0085 /* for hsplit_0 field of Rx HMC context */
0086 /* deprecated with AVF 1.0 */
0087 enum virtchnl_rx_hsplit {
0088     VIRTCHNL_RX_HSPLIT_NO_SPLIT      = 0,
0089     VIRTCHNL_RX_HSPLIT_SPLIT_L2      = 1,
0090     VIRTCHNL_RX_HSPLIT_SPLIT_IP      = 2,
0091     VIRTCHNL_RX_HSPLIT_SPLIT_TCP_UDP = 4,
0092     VIRTCHNL_RX_HSPLIT_SPLIT_SCTP    = 8,
0093 };
0094 
0095 /* END GENERIC DEFINES */
0096 
0097 /* Opcodes for VF-PF communication. These are placed in the v_opcode field
0098  * of the virtchnl_msg structure.
0099  */
0100 enum virtchnl_ops {
0101 /* The PF sends status change events to VFs using
0102  * the VIRTCHNL_OP_EVENT opcode.
0103  * VFs send requests to the PF using the other ops.
0104  * Use of "advanced opcode" features must be negotiated as part of capabilities
0105  * exchange and are not considered part of base mode feature set.
0106  */
0107     VIRTCHNL_OP_UNKNOWN = 0,
0108     VIRTCHNL_OP_VERSION = 1, /* must ALWAYS be 1 */
0109     VIRTCHNL_OP_RESET_VF = 2,
0110     VIRTCHNL_OP_GET_VF_RESOURCES = 3,
0111     VIRTCHNL_OP_CONFIG_TX_QUEUE = 4,
0112     VIRTCHNL_OP_CONFIG_RX_QUEUE = 5,
0113     VIRTCHNL_OP_CONFIG_VSI_QUEUES = 6,
0114     VIRTCHNL_OP_CONFIG_IRQ_MAP = 7,
0115     VIRTCHNL_OP_ENABLE_QUEUES = 8,
0116     VIRTCHNL_OP_DISABLE_QUEUES = 9,
0117     VIRTCHNL_OP_ADD_ETH_ADDR = 10,
0118     VIRTCHNL_OP_DEL_ETH_ADDR = 11,
0119     VIRTCHNL_OP_ADD_VLAN = 12,
0120     VIRTCHNL_OP_DEL_VLAN = 13,
0121     VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE = 14,
0122     VIRTCHNL_OP_GET_STATS = 15,
0123     VIRTCHNL_OP_RSVD = 16,
0124     VIRTCHNL_OP_EVENT = 17, /* must ALWAYS be 17 */
0125     VIRTCHNL_OP_IWARP = 20, /* advanced opcode */
0126     VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP = 21, /* advanced opcode */
0127     VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP = 22, /* advanced opcode */
0128     VIRTCHNL_OP_CONFIG_RSS_KEY = 23,
0129     VIRTCHNL_OP_CONFIG_RSS_LUT = 24,
0130     VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25,
0131     VIRTCHNL_OP_SET_RSS_HENA = 26,
0132     VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27,
0133     VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28,
0134     VIRTCHNL_OP_REQUEST_QUEUES = 29,
0135     VIRTCHNL_OP_ENABLE_CHANNELS = 30,
0136     VIRTCHNL_OP_DISABLE_CHANNELS = 31,
0137     VIRTCHNL_OP_ADD_CLOUD_FILTER = 32,
0138     VIRTCHNL_OP_DEL_CLOUD_FILTER = 33,
0139     /* opcode 34 - 44 are reserved */
0140     VIRTCHNL_OP_ADD_RSS_CFG = 45,
0141     VIRTCHNL_OP_DEL_RSS_CFG = 46,
0142     VIRTCHNL_OP_ADD_FDIR_FILTER = 47,
0143     VIRTCHNL_OP_DEL_FDIR_FILTER = 48,
0144     VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS = 51,
0145     VIRTCHNL_OP_ADD_VLAN_V2 = 52,
0146     VIRTCHNL_OP_DEL_VLAN_V2 = 53,
0147     VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 = 54,
0148     VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2 = 55,
0149     VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 = 56,
0150     VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2 = 57,
0151     VIRTCHNL_OP_MAX,
0152 };
0153 
0154 /* These macros are used to generate compilation errors if a structure/union
0155  * is not exactly the correct length. It gives a divide by zero error if the
0156  * structure/union is not of the correct size, otherwise it creates an enum
0157  * that is never used.
0158  */
0159 #define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \
0160     { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
0161 #define VIRTCHNL_CHECK_UNION_LEN(n, X) enum virtchnl_static_asset_enum_##X \
0162     { virtchnl_static_assert_##X = (n)/((sizeof(union X) == (n)) ? 1 : 0) }
0163 
0164 /* Virtual channel message descriptor. This overlays the admin queue
0165  * descriptor. All other data is passed in external buffers.
0166  */
0167 
0168 struct virtchnl_msg {
0169     u8 pad[8];           /* AQ flags/opcode/len/retval fields */
0170     enum virtchnl_ops v_opcode; /* avoid confusion with desc->opcode */
0171     enum virtchnl_status_code v_retval;  /* ditto for desc->retval */
0172     u32 vfid;            /* used by PF when sending to VF */
0173 };
0174 
0175 VIRTCHNL_CHECK_STRUCT_LEN(20, virtchnl_msg);
0176 
0177 /* Message descriptions and data structures. */
0178 
0179 /* VIRTCHNL_OP_VERSION
0180  * VF posts its version number to the PF. PF responds with its version number
0181  * in the same format, along with a return code.
0182  * Reply from PF has its major/minor versions also in param0 and param1.
0183  * If there is a major version mismatch, then the VF cannot operate.
0184  * If there is a minor version mismatch, then the VF can operate but should
0185  * add a warning to the system log.
0186  *
0187  * This enum element MUST always be specified as == 1, regardless of other
0188  * changes in the API. The PF must always respond to this message without
0189  * error regardless of version mismatch.
0190  */
0191 #define VIRTCHNL_VERSION_MAJOR      1
0192 #define VIRTCHNL_VERSION_MINOR      1
0193 #define VIRTCHNL_VERSION_MINOR_NO_VF_CAPS   0
0194 
0195 struct virtchnl_version_info {
0196     u32 major;
0197     u32 minor;
0198 };
0199 
0200 VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_version_info);
0201 
0202 #define VF_IS_V10(_v) (((_v)->major == 1) && ((_v)->minor == 0))
0203 #define VF_IS_V11(_ver) (((_ver)->major == 1) && ((_ver)->minor == 1))
0204 
0205 /* VIRTCHNL_OP_RESET_VF
0206  * VF sends this request to PF with no parameters
0207  * PF does NOT respond! VF driver must delay then poll VFGEN_RSTAT register
0208  * until reset completion is indicated. The admin queue must be reinitialized
0209  * after this operation.
0210  *
0211  * When reset is complete, PF must ensure that all queues in all VSIs associated
0212  * with the VF are stopped, all queue configurations in the HMC are set to 0,
0213  * and all MAC and VLAN filters (except the default MAC address) on all VSIs
0214  * are cleared.
0215  */
0216 
0217 /* VSI types that use VIRTCHNL interface for VF-PF communication. VSI_SRIOV
0218  * vsi_type should always be 6 for backward compatibility. Add other fields
0219  * as needed.
0220  */
0221 enum virtchnl_vsi_type {
0222     VIRTCHNL_VSI_TYPE_INVALID = 0,
0223     VIRTCHNL_VSI_SRIOV = 6,
0224 };
0225 
0226 /* VIRTCHNL_OP_GET_VF_RESOURCES
0227  * Version 1.0 VF sends this request to PF with no parameters
0228  * Version 1.1 VF sends this request to PF with u32 bitmap of its capabilities
0229  * PF responds with an indirect message containing
0230  * virtchnl_vf_resource and one or more
0231  * virtchnl_vsi_resource structures.
0232  */
0233 
0234 struct virtchnl_vsi_resource {
0235     u16 vsi_id;
0236     u16 num_queue_pairs;
0237     enum virtchnl_vsi_type vsi_type;
0238     u16 qset_handle;
0239     u8 default_mac_addr[ETH_ALEN];
0240 };
0241 
0242 VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);
0243 
0244 /* VF capability flags
0245  * VIRTCHNL_VF_OFFLOAD_L2 flag is inclusive of base mode L2 offloads including
0246  * TX/RX Checksum offloading and TSO for non-tunnelled packets.
0247  */
0248 #define VIRTCHNL_VF_OFFLOAD_L2          BIT(0)
0249 #define VIRTCHNL_VF_OFFLOAD_IWARP       BIT(1)
0250 #define VIRTCHNL_VF_OFFLOAD_RSS_AQ      BIT(3)
0251 #define VIRTCHNL_VF_OFFLOAD_RSS_REG     BIT(4)
0252 #define VIRTCHNL_VF_OFFLOAD_WB_ON_ITR       BIT(5)
0253 #define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES      BIT(6)
0254 /* used to negotiate communicating link speeds in Mbps */
0255 #define VIRTCHNL_VF_CAP_ADV_LINK_SPEED      BIT(7)
0256 #define VIRTCHNL_VF_OFFLOAD_VLAN_V2     BIT(15)
0257 #define VIRTCHNL_VF_OFFLOAD_VLAN        BIT(16)
0258 #define VIRTCHNL_VF_OFFLOAD_RX_POLLING      BIT(17)
0259 #define VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2   BIT(18)
0260 #define VIRTCHNL_VF_OFFLOAD_RSS_PF      BIT(19)
0261 #define VIRTCHNL_VF_OFFLOAD_ENCAP       BIT(20)
0262 #define VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM      BIT(21)
0263 #define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM   BIT(22)
0264 #define VIRTCHNL_VF_OFFLOAD_ADQ         BIT(23)
0265 #define VIRTCHNL_VF_OFFLOAD_USO         BIT(25)
0266 #define VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF      BIT(27)
0267 #define VIRTCHNL_VF_OFFLOAD_FDIR_PF     BIT(28)
0268 
0269 #define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \
0270                    VIRTCHNL_VF_OFFLOAD_VLAN | \
0271                    VIRTCHNL_VF_OFFLOAD_RSS_PF)
0272 
0273 struct virtchnl_vf_resource {
0274     u16 num_vsis;
0275     u16 num_queue_pairs;
0276     u16 max_vectors;
0277     u16 max_mtu;
0278 
0279     u32 vf_cap_flags;
0280     u32 rss_key_size;
0281     u32 rss_lut_size;
0282 
0283     struct virtchnl_vsi_resource vsi_res[1];
0284 };
0285 
0286 VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_vf_resource);
0287 
0288 /* VIRTCHNL_OP_CONFIG_TX_QUEUE
0289  * VF sends this message to set up parameters for one TX queue.
0290  * External data buffer contains one instance of virtchnl_txq_info.
0291  * PF configures requested queue and returns a status code.
0292  */
0293 
0294 /* Tx queue config info */
0295 struct virtchnl_txq_info {
0296     u16 vsi_id;
0297     u16 queue_id;
0298     u16 ring_len;       /* number of descriptors, multiple of 8 */
0299     u16 headwb_enabled; /* deprecated with AVF 1.0 */
0300     u64 dma_ring_addr;
0301     u64 dma_headwb_addr; /* deprecated with AVF 1.0 */
0302 };
0303 
0304 VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info);
0305 
0306 /* VIRTCHNL_OP_CONFIG_RX_QUEUE
0307  * VF sends this message to set up parameters for one RX queue.
0308  * External data buffer contains one instance of virtchnl_rxq_info.
0309  * PF configures requested queue and returns a status code.
0310  */
0311 
0312 /* Rx queue config info */
0313 struct virtchnl_rxq_info {
0314     u16 vsi_id;
0315     u16 queue_id;
0316     u32 ring_len;       /* number of descriptors, multiple of 32 */
0317     u16 hdr_size;
0318     u16 splithdr_enabled; /* deprecated with AVF 1.0 */
0319     u32 databuffer_size;
0320     u32 max_pkt_size;
0321     u32 pad1;
0322     u64 dma_ring_addr;
0323     enum virtchnl_rx_hsplit rx_split_pos; /* deprecated with AVF 1.0 */
0324     u32 pad2;
0325 };
0326 
0327 VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_rxq_info);
0328 
0329 /* VIRTCHNL_OP_CONFIG_VSI_QUEUES
0330  * VF sends this message to set parameters for all active TX and RX queues
0331  * associated with the specified VSI.
0332  * PF configures queues and returns status.
0333  * If the number of queues specified is greater than the number of queues
0334  * associated with the VSI, an error is returned and no queues are configured.
0335  */
0336 struct virtchnl_queue_pair_info {
0337     /* NOTE: vsi_id and queue_id should be identical for both queues. */
0338     struct virtchnl_txq_info txq;
0339     struct virtchnl_rxq_info rxq;
0340 };
0341 
0342 VIRTCHNL_CHECK_STRUCT_LEN(64, virtchnl_queue_pair_info);
0343 
0344 struct virtchnl_vsi_queue_config_info {
0345     u16 vsi_id;
0346     u16 num_queue_pairs;
0347     u32 pad;
0348     struct virtchnl_queue_pair_info qpair[1];
0349 };
0350 
0351 VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_vsi_queue_config_info);
0352 
0353 /* VIRTCHNL_OP_REQUEST_QUEUES
0354  * VF sends this message to request the PF to allocate additional queues to
0355  * this VF.  Each VF gets a guaranteed number of queues on init but asking for
0356  * additional queues must be negotiated.  This is a best effort request as it
0357  * is possible the PF does not have enough queues left to support the request.
0358  * If the PF cannot support the number requested it will respond with the
0359  * maximum number it is able to support.  If the request is successful, PF will
0360  * then reset the VF to institute required changes.
0361  */
0362 
0363 /* VF resource request */
0364 struct virtchnl_vf_res_request {
0365     u16 num_queue_pairs;
0366 };
0367 
0368 /* VIRTCHNL_OP_CONFIG_IRQ_MAP
0369  * VF uses this message to map vectors to queues.
0370  * The rxq_map and txq_map fields are bitmaps used to indicate which queues
0371  * are to be associated with the specified vector.
0372  * The "other" causes are always mapped to vector 0.
0373  * PF configures interrupt mapping and returns status.
0374  */
0375 struct virtchnl_vector_map {
0376     u16 vsi_id;
0377     u16 vector_id;
0378     u16 rxq_map;
0379     u16 txq_map;
0380     u16 rxitr_idx;
0381     u16 txitr_idx;
0382 };
0383 
0384 VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_vector_map);
0385 
0386 struct virtchnl_irq_map_info {
0387     u16 num_vectors;
0388     struct virtchnl_vector_map vecmap[1];
0389 };
0390 
0391 VIRTCHNL_CHECK_STRUCT_LEN(14, virtchnl_irq_map_info);
0392 
0393 /* VIRTCHNL_OP_ENABLE_QUEUES
0394  * VIRTCHNL_OP_DISABLE_QUEUES
0395  * VF sends these message to enable or disable TX/RX queue pairs.
0396  * The queues fields are bitmaps indicating which queues to act upon.
0397  * (Currently, we only support 16 queues per VF, but we make the field
0398  * u32 to allow for expansion.)
0399  * PF performs requested action and returns status.
0400  */
0401 struct virtchnl_queue_select {
0402     u16 vsi_id;
0403     u16 pad;
0404     u32 rx_queues;
0405     u32 tx_queues;
0406 };
0407 
0408 VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_queue_select);
0409 
0410 /* VIRTCHNL_OP_ADD_ETH_ADDR
0411  * VF sends this message in order to add one or more unicast or multicast
0412  * address filters for the specified VSI.
0413  * PF adds the filters and returns status.
0414  */
0415 
0416 /* VIRTCHNL_OP_DEL_ETH_ADDR
0417  * VF sends this message in order to remove one or more unicast or multicast
0418  * filters for the specified VSI.
0419  * PF removes the filters and returns status.
0420  */
0421 
0422 /* VIRTCHNL_ETHER_ADDR_LEGACY
0423  * Prior to adding the @type member to virtchnl_ether_addr, there were 2 pad
0424  * bytes. Moving forward all VF drivers should not set type to
0425  * VIRTCHNL_ETHER_ADDR_LEGACY. This is only here to not break previous/legacy
0426  * behavior. The control plane function (i.e. PF) can use a best effort method
0427  * of tracking the primary/device unicast in this case, but there is no
0428  * guarantee and functionality depends on the implementation of the PF.
0429  */
0430 
0431 /* VIRTCHNL_ETHER_ADDR_PRIMARY
0432  * All VF drivers should set @type to VIRTCHNL_ETHER_ADDR_PRIMARY for the
0433  * primary/device unicast MAC address filter for VIRTCHNL_OP_ADD_ETH_ADDR and
0434  * VIRTCHNL_OP_DEL_ETH_ADDR. This allows for the underlying control plane
0435  * function (i.e. PF) to accurately track and use this MAC address for
0436  * displaying on the host and for VM/function reset.
0437  */
0438 
0439 /* VIRTCHNL_ETHER_ADDR_EXTRA
0440  * All VF drivers should set @type to VIRTCHNL_ETHER_ADDR_EXTRA for any extra
0441  * unicast and/or multicast filters that are being added/deleted via
0442  * VIRTCHNL_OP_DEL_ETH_ADDR/VIRTCHNL_OP_ADD_ETH_ADDR respectively.
0443  */
0444 struct virtchnl_ether_addr {
0445     u8 addr[ETH_ALEN];
0446     u8 type;
0447 #define VIRTCHNL_ETHER_ADDR_LEGACY  0
0448 #define VIRTCHNL_ETHER_ADDR_PRIMARY 1
0449 #define VIRTCHNL_ETHER_ADDR_EXTRA   2
0450 #define VIRTCHNL_ETHER_ADDR_TYPE_MASK   3 /* first two bits of type are valid */
0451     u8 pad;
0452 };
0453 
0454 VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr);
0455 
0456 struct virtchnl_ether_addr_list {
0457     u16 vsi_id;
0458     u16 num_elements;
0459     struct virtchnl_ether_addr list[1];
0460 };
0461 
0462 VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_ether_addr_list);
0463 
0464 /* VIRTCHNL_OP_ADD_VLAN
0465  * VF sends this message to add one or more VLAN tag filters for receives.
0466  * PF adds the filters and returns status.
0467  * If a port VLAN is configured by the PF, this operation will return an
0468  * error to the VF.
0469  */
0470 
0471 /* VIRTCHNL_OP_DEL_VLAN
0472  * VF sends this message to remove one or more VLAN tag filters for receives.
0473  * PF removes the filters and returns status.
0474  * If a port VLAN is configured by the PF, this operation will return an
0475  * error to the VF.
0476  */
0477 
0478 struct virtchnl_vlan_filter_list {
0479     u16 vsi_id;
0480     u16 num_elements;
0481     u16 vlan_id[1];
0482 };
0483 
0484 VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_vlan_filter_list);
0485 
0486 /* This enum is used for all of the VIRTCHNL_VF_OFFLOAD_VLAN_V2_CAPS related
0487  * structures and opcodes.
0488  *
0489  * VIRTCHNL_VLAN_UNSUPPORTED - This field is not supported and if a VF driver
0490  * populates it the PF should return VIRTCHNL_STATUS_ERR_NOT_SUPPORTED.
0491  *
0492  * VIRTCHNL_VLAN_ETHERTYPE_8100 - This field supports 0x8100 ethertype.
0493  * VIRTCHNL_VLAN_ETHERTYPE_88A8 - This field supports 0x88A8 ethertype.
0494  * VIRTCHNL_VLAN_ETHERTYPE_9100 - This field supports 0x9100 ethertype.
0495  *
0496  * VIRTCHNL_VLAN_ETHERTYPE_AND - Used when multiple ethertypes can be supported
0497  * by the PF concurrently. For example, if the PF can support
0498  * VIRTCHNL_VLAN_ETHERTYPE_8100 AND VIRTCHNL_VLAN_ETHERTYPE_88A8 filters it
0499  * would OR the following bits:
0500  *
0501  *  VIRTHCNL_VLAN_ETHERTYPE_8100 |
0502  *  VIRTCHNL_VLAN_ETHERTYPE_88A8 |
0503  *  VIRTCHNL_VLAN_ETHERTYPE_AND;
0504  *
0505  * The VF would interpret this as VLAN filtering can be supported on both 0x8100
0506  * and 0x88A8 VLAN ethertypes.
0507  *
0508  * VIRTCHNL_ETHERTYPE_XOR - Used when only a single ethertype can be supported
0509  * by the PF concurrently. For example if the PF can support
0510  * VIRTCHNL_VLAN_ETHERTYPE_8100 XOR VIRTCHNL_VLAN_ETHERTYPE_88A8 stripping
0511  * offload it would OR the following bits:
0512  *
0513  *  VIRTCHNL_VLAN_ETHERTYPE_8100 |
0514  *  VIRTCHNL_VLAN_ETHERTYPE_88A8 |
0515  *  VIRTCHNL_VLAN_ETHERTYPE_XOR;
0516  *
0517  * The VF would interpret this as VLAN stripping can be supported on either
0518  * 0x8100 or 0x88a8 VLAN ethertypes. So when requesting VLAN stripping via
0519  * VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 the specified ethertype will override
0520  * the previously set value.
0521  *
0522  * VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1 - Used to tell the VF to insert and/or
0523  * strip the VLAN tag using the L2TAG1 field of the Tx/Rx descriptors.
0524  *
0525  * VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2 - Used to tell the VF to insert hardware
0526  * offloaded VLAN tags using the L2TAG2 field of the Tx descriptor.
0527  *
0528  * VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2 - Used to tell the VF to strip hardware
0529  * offloaded VLAN tags using the L2TAG2_2 field of the Rx descriptor.
0530  *
0531  * VIRTCHNL_VLAN_PRIO - This field supports VLAN priority bits. This is used for
0532  * VLAN filtering if the underlying PF supports it.
0533  *
0534  * VIRTCHNL_VLAN_TOGGLE_ALLOWED - This field is used to say whether a
0535  * certain VLAN capability can be toggled. For example if the underlying PF/CP
0536  * allows the VF to toggle VLAN filtering, stripping, and/or insertion it should
0537  * set this bit along with the supported ethertypes.
0538  */
0539 enum virtchnl_vlan_support {
0540     VIRTCHNL_VLAN_UNSUPPORTED =     0,
0541     VIRTCHNL_VLAN_ETHERTYPE_8100 =      BIT(0),
0542     VIRTCHNL_VLAN_ETHERTYPE_88A8 =      BIT(1),
0543     VIRTCHNL_VLAN_ETHERTYPE_9100 =      BIT(2),
0544     VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1 = BIT(8),
0545     VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2 = BIT(9),
0546     VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2_2 =   BIT(10),
0547     VIRTCHNL_VLAN_PRIO =            BIT(24),
0548     VIRTCHNL_VLAN_FILTER_MASK =     BIT(28),
0549     VIRTCHNL_VLAN_ETHERTYPE_AND =       BIT(29),
0550     VIRTCHNL_VLAN_ETHERTYPE_XOR =       BIT(30),
0551     VIRTCHNL_VLAN_TOGGLE =          BIT(31),
0552 };
0553 
0554 /* This structure is used as part of the VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS
0555  * for filtering, insertion, and stripping capabilities.
0556  *
0557  * If only outer capabilities are supported (for filtering, insertion, and/or
0558  * stripping) then this refers to the outer most or single VLAN from the VF's
0559  * perspective.
0560  *
0561  * If only inner capabilities are supported (for filtering, insertion, and/or
0562  * stripping) then this refers to the outer most or single VLAN from the VF's
0563  * perspective. Functionally this is the same as if only outer capabilities are
0564  * supported. The VF driver is just forced to use the inner fields when
0565  * adding/deleting filters and enabling/disabling offloads (if supported).
0566  *
0567  * If both outer and inner capabilities are supported (for filtering, insertion,
0568  * and/or stripping) then outer refers to the outer most or single VLAN and
0569  * inner refers to the second VLAN, if it exists, in the packet.
0570  *
0571  * There is no support for tunneled VLAN offloads, so outer or inner are never
0572  * referring to a tunneled packet from the VF's perspective.
0573  */
0574 struct virtchnl_vlan_supported_caps {
0575     u32 outer;
0576     u32 inner;
0577 };
0578 
0579 /* The PF populates these fields based on the supported VLAN filtering. If a
0580  * field is VIRTCHNL_VLAN_UNSUPPORTED then it's not supported and the PF will
0581  * reject any VIRTCHNL_OP_ADD_VLAN_V2 or VIRTCHNL_OP_DEL_VLAN_V2 messages using
0582  * the unsupported fields.
0583  *
0584  * Also, a VF is only allowed to toggle its VLAN filtering setting if the
0585  * VIRTCHNL_VLAN_TOGGLE bit is set.
0586  *
0587  * The ethertype(s) specified in the ethertype_init field are the ethertypes
0588  * enabled for VLAN filtering. VLAN filtering in this case refers to the outer
0589  * most VLAN from the VF's perspective. If both inner and outer filtering are
0590  * allowed then ethertype_init only refers to the outer most VLAN as only
0591  * VLAN ethertype supported for inner VLAN filtering is
0592  * VIRTCHNL_VLAN_ETHERTYPE_8100. By default, inner VLAN filtering is disabled
0593  * when both inner and outer filtering are allowed.
0594  *
0595  * The max_filters field tells the VF how many VLAN filters it's allowed to have
0596  * at any one time. If it exceeds this amount and tries to add another filter,
0597  * then the request will be rejected by the PF. To prevent failures, the VF
0598  * should keep track of how many VLAN filters it has added and not attempt to
0599  * add more than max_filters.
0600  */
0601 struct virtchnl_vlan_filtering_caps {
0602     struct virtchnl_vlan_supported_caps filtering_support;
0603     u32 ethertype_init;
0604     u16 max_filters;
0605     u8 pad[2];
0606 };
0607 
0608 VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vlan_filtering_caps);
0609 
0610 /* This enum is used for the virtchnl_vlan_offload_caps structure to specify
0611  * if the PF supports a different ethertype for stripping and insertion.
0612  *
0613  * VIRTCHNL_ETHERTYPE_STRIPPING_MATCHES_INSERTION - The ethertype(s) specified
0614  * for stripping affect the ethertype(s) specified for insertion and visa versa
0615  * as well. If the VF tries to configure VLAN stripping via
0616  * VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 with VIRTCHNL_VLAN_ETHERTYPE_8100 then
0617  * that will be the ethertype for both stripping and insertion.
0618  *
0619  * VIRTCHNL_ETHERTYPE_MATCH_NOT_REQUIRED - The ethertype(s) specified for
0620  * stripping do not affect the ethertype(s) specified for insertion and visa
0621  * versa.
0622  */
0623 enum virtchnl_vlan_ethertype_match {
0624     VIRTCHNL_ETHERTYPE_STRIPPING_MATCHES_INSERTION = 0,
0625     VIRTCHNL_ETHERTYPE_MATCH_NOT_REQUIRED = 1,
0626 };
0627 
0628 /* The PF populates these fields based on the supported VLAN offloads. If a
0629  * field is VIRTCHNL_VLAN_UNSUPPORTED then it's not supported and the PF will
0630  * reject any VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 or
0631  * VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2 messages using the unsupported fields.
0632  *
0633  * Also, a VF is only allowed to toggle its VLAN offload setting if the
0634  * VIRTCHNL_VLAN_TOGGLE_ALLOWED bit is set.
0635  *
0636  * The VF driver needs to be aware of how the tags are stripped by hardware and
0637  * inserted by the VF driver based on the level of offload support. The PF will
0638  * populate these fields based on where the VLAN tags are expected to be
0639  * offloaded via the VIRTHCNL_VLAN_TAG_LOCATION_* bits. The VF will need to
0640  * interpret these fields. See the definition of the
0641  * VIRTCHNL_VLAN_TAG_LOCATION_* bits above the virtchnl_vlan_support
0642  * enumeration.
0643  */
0644 struct virtchnl_vlan_offload_caps {
0645     struct virtchnl_vlan_supported_caps stripping_support;
0646     struct virtchnl_vlan_supported_caps insertion_support;
0647     u32 ethertype_init;
0648     u8 ethertype_match;
0649     u8 pad[3];
0650 };
0651 
0652 VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_vlan_offload_caps);
0653 
0654 /* VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS
0655  * VF sends this message to determine its VLAN capabilities.
0656  *
0657  * PF will mark which capabilities it supports based on hardware support and
0658  * current configuration. For example, if a port VLAN is configured the PF will
0659  * not allow outer VLAN filtering, stripping, or insertion to be configured so
0660  * it will block these features from the VF.
0661  *
0662  * The VF will need to cross reference its capabilities with the PFs
0663  * capabilities in the response message from the PF to determine the VLAN
0664  * support.
0665  */
0666 struct virtchnl_vlan_caps {
0667     struct virtchnl_vlan_filtering_caps filtering;
0668     struct virtchnl_vlan_offload_caps offloads;
0669 };
0670 
0671 VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_vlan_caps);
0672 
0673 struct virtchnl_vlan {
0674     u16 tci;    /* tci[15:13] = PCP and tci[11:0] = VID */
0675     u16 tci_mask;   /* only valid if VIRTCHNL_VLAN_FILTER_MASK set in
0676              * filtering caps
0677              */
0678     u16 tpid;   /* 0x8100, 0x88a8, etc. and only type(s) set in
0679              * filtering caps. Note that tpid here does not refer to
0680              * VIRTCHNL_VLAN_ETHERTYPE_*, but it refers to the
0681              * actual 2-byte VLAN TPID
0682              */
0683     u8 pad[2];
0684 };
0685 
0686 VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_vlan);
0687 
0688 struct virtchnl_vlan_filter {
0689     struct virtchnl_vlan inner;
0690     struct virtchnl_vlan outer;
0691     u8 pad[16];
0692 };
0693 
0694 VIRTCHNL_CHECK_STRUCT_LEN(32, virtchnl_vlan_filter);
0695 
0696 /* VIRTCHNL_OP_ADD_VLAN_V2
0697  * VIRTCHNL_OP_DEL_VLAN_V2
0698  *
0699  * VF sends these messages to add/del one or more VLAN tag filters for Rx
0700  * traffic.
0701  *
0702  * The PF attempts to add the filters and returns status.
0703  *
0704  * The VF should only ever attempt to add/del virtchnl_vlan_filter(s) using the
0705  * supported fields negotiated via VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS.
0706  */
0707 struct virtchnl_vlan_filter_list_v2 {
0708     u16 vport_id;
0709     u16 num_elements;
0710     u8 pad[4];
0711     struct virtchnl_vlan_filter filters[1];
0712 };
0713 
0714 VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_vlan_filter_list_v2);
0715 
0716 /* VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2
0717  * VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2
0718  * VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2
0719  * VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2
0720  *
0721  * VF sends this message to enable or disable VLAN stripping or insertion. It
0722  * also needs to specify an ethertype. The VF knows which VLAN ethertypes are
0723  * allowed and whether or not it's allowed to enable/disable the specific
0724  * offload via the VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS message. The VF needs to
0725  * parse the virtchnl_vlan_caps.offloads fields to determine which offload
0726  * messages are allowed.
0727  *
0728  * For example, if the PF populates the virtchnl_vlan_caps.offloads in the
0729  * following manner the VF will be allowed to enable and/or disable 0x8100 inner
0730  * VLAN insertion and/or stripping via the opcodes listed above. Inner in this
0731  * case means the outer most or single VLAN from the VF's perspective. This is
0732  * because no outer offloads are supported. See the comments above the
0733  * virtchnl_vlan_supported_caps structure for more details.
0734  *
0735  * virtchnl_vlan_caps.offloads.stripping_support.inner =
0736  *          VIRTCHNL_VLAN_TOGGLE |
0737  *          VIRTCHNL_VLAN_ETHERTYPE_8100;
0738  *
0739  * virtchnl_vlan_caps.offloads.insertion_support.inner =
0740  *          VIRTCHNL_VLAN_TOGGLE |
0741  *          VIRTCHNL_VLAN_ETHERTYPE_8100;
0742  *
0743  * In order to enable inner (again note that in this case inner is the outer
0744  * most or single VLAN from the VF's perspective) VLAN stripping for 0x8100
0745  * VLANs, the VF would populate the virtchnl_vlan_setting structure in the
0746  * following manner and send the VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 message.
0747  *
0748  * virtchnl_vlan_setting.inner_ethertype_setting =
0749  *          VIRTCHNL_VLAN_ETHERTYPE_8100;
0750  *
0751  * virtchnl_vlan_setting.vport_id = vport_id or vsi_id assigned to the VF on
0752  * initialization.
0753  *
0754  * The reason that VLAN TPID(s) are not being used for the
0755  * outer_ethertype_setting and inner_ethertype_setting fields is because it's
0756  * possible a device could support VLAN insertion and/or stripping offload on
0757  * multiple ethertypes concurrently, so this method allows a VF to request
0758  * multiple ethertypes in one message using the virtchnl_vlan_support
0759  * enumeration.
0760  *
0761  * For example, if the PF populates the virtchnl_vlan_caps.offloads in the
0762  * following manner the VF will be allowed to enable 0x8100 and 0x88a8 outer
0763  * VLAN insertion and stripping simultaneously. The
0764  * virtchnl_vlan_caps.offloads.ethertype_match field will also have to be
0765  * populated based on what the PF can support.
0766  *
0767  * virtchnl_vlan_caps.offloads.stripping_support.outer =
0768  *          VIRTCHNL_VLAN_TOGGLE |
0769  *          VIRTCHNL_VLAN_ETHERTYPE_8100 |
0770  *          VIRTCHNL_VLAN_ETHERTYPE_88A8 |
0771  *          VIRTCHNL_VLAN_ETHERTYPE_AND;
0772  *
0773  * virtchnl_vlan_caps.offloads.insertion_support.outer =
0774  *          VIRTCHNL_VLAN_TOGGLE |
0775  *          VIRTCHNL_VLAN_ETHERTYPE_8100 |
0776  *          VIRTCHNL_VLAN_ETHERTYPE_88A8 |
0777  *          VIRTCHNL_VLAN_ETHERTYPE_AND;
0778  *
0779  * In order to enable outer VLAN stripping for 0x8100 and 0x88a8 VLANs, the VF
0780  * would populate the virthcnl_vlan_offload_structure in the following manner
0781  * and send the VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 message.
0782  *
0783  * virtchnl_vlan_setting.outer_ethertype_setting =
0784  *          VIRTHCNL_VLAN_ETHERTYPE_8100 |
0785  *          VIRTHCNL_VLAN_ETHERTYPE_88A8;
0786  *
0787  * virtchnl_vlan_setting.vport_id = vport_id or vsi_id assigned to the VF on
0788  * initialization.
0789  *
0790  * There is also the case where a PF and the underlying hardware can support
0791  * VLAN offloads on multiple ethertypes, but not concurrently. For example, if
0792  * the PF populates the virtchnl_vlan_caps.offloads in the following manner the
0793  * VF will be allowed to enable and/or disable 0x8100 XOR 0x88a8 outer VLAN
0794  * offloads. The ethertypes must match for stripping and insertion.
0795  *
0796  * virtchnl_vlan_caps.offloads.stripping_support.outer =
0797  *          VIRTCHNL_VLAN_TOGGLE |
0798  *          VIRTCHNL_VLAN_ETHERTYPE_8100 |
0799  *          VIRTCHNL_VLAN_ETHERTYPE_88A8 |
0800  *          VIRTCHNL_VLAN_ETHERTYPE_XOR;
0801  *
0802  * virtchnl_vlan_caps.offloads.insertion_support.outer =
0803  *          VIRTCHNL_VLAN_TOGGLE |
0804  *          VIRTCHNL_VLAN_ETHERTYPE_8100 |
0805  *          VIRTCHNL_VLAN_ETHERTYPE_88A8 |
0806  *          VIRTCHNL_VLAN_ETHERTYPE_XOR;
0807  *
0808  * virtchnl_vlan_caps.offloads.ethertype_match =
0809  *          VIRTCHNL_ETHERTYPE_STRIPPING_MATCHES_INSERTION;
0810  *
0811  * In order to enable outer VLAN stripping for 0x88a8 VLANs, the VF would
0812  * populate the virtchnl_vlan_setting structure in the following manner and send
0813  * the VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2. Also, this will change the
0814  * ethertype for VLAN insertion if it's enabled. So, for completeness, a
0815  * VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 with the same ethertype should be sent.
0816  *
0817  * virtchnl_vlan_setting.outer_ethertype_setting = VIRTHCNL_VLAN_ETHERTYPE_88A8;
0818  *
0819  * virtchnl_vlan_setting.vport_id = vport_id or vsi_id assigned to the VF on
0820  * initialization.
0821  */
0822 struct virtchnl_vlan_setting {
0823     u32 outer_ethertype_setting;
0824     u32 inner_ethertype_setting;
0825     u16 vport_id;
0826     u8 pad[6];
0827 };
0828 
0829 VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vlan_setting);
0830 
0831 /* VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE
0832  * VF sends VSI id and flags.
0833  * PF returns status code in retval.
0834  * Note: we assume that broadcast accept mode is always enabled.
0835  */
0836 struct virtchnl_promisc_info {
0837     u16 vsi_id;
0838     u16 flags;
0839 };
0840 
0841 VIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_promisc_info);
0842 
0843 #define FLAG_VF_UNICAST_PROMISC 0x00000001
0844 #define FLAG_VF_MULTICAST_PROMISC   0x00000002
0845 
0846 /* VIRTCHNL_OP_GET_STATS
0847  * VF sends this message to request stats for the selected VSI. VF uses
0848  * the virtchnl_queue_select struct to specify the VSI. The queue_id
0849  * field is ignored by the PF.
0850  *
0851  * PF replies with struct eth_stats in an external buffer.
0852  */
0853 
0854 /* VIRTCHNL_OP_CONFIG_RSS_KEY
0855  * VIRTCHNL_OP_CONFIG_RSS_LUT
0856  * VF sends these messages to configure RSS. Only supported if both PF
0857  * and VF drivers set the VIRTCHNL_VF_OFFLOAD_RSS_PF bit during
0858  * configuration negotiation. If this is the case, then the RSS fields in
0859  * the VF resource struct are valid.
0860  * Both the key and LUT are initialized to 0 by the PF, meaning that
0861  * RSS is effectively disabled until set up by the VF.
0862  */
0863 struct virtchnl_rss_key {
0864     u16 vsi_id;
0865     u16 key_len;
0866     u8 key[1];         /* RSS hash key, packed bytes */
0867 };
0868 
0869 VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_key);
0870 
0871 struct virtchnl_rss_lut {
0872     u16 vsi_id;
0873     u16 lut_entries;
0874     u8 lut[1];        /* RSS lookup table */
0875 };
0876 
0877 VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_lut);
0878 
0879 /* VIRTCHNL_OP_GET_RSS_HENA_CAPS
0880  * VIRTCHNL_OP_SET_RSS_HENA
0881  * VF sends these messages to get and set the hash filter enable bits for RSS.
0882  * By default, the PF sets these to all possible traffic types that the
0883  * hardware supports. The VF can query this value if it wants to change the
0884  * traffic types that are hashed by the hardware.
0885  */
0886 struct virtchnl_rss_hena {
0887     u64 hena;
0888 };
0889 
0890 VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena);
0891 
0892 /* VIRTCHNL_OP_ENABLE_CHANNELS
0893  * VIRTCHNL_OP_DISABLE_CHANNELS
0894  * VF sends these messages to enable or disable channels based on
0895  * the user specified queue count and queue offset for each traffic class.
0896  * This struct encompasses all the information that the PF needs from
0897  * VF to create a channel.
0898  */
0899 struct virtchnl_channel_info {
0900     u16 count; /* number of queues in a channel */
0901     u16 offset; /* queues in a channel start from 'offset' */
0902     u32 pad;
0903     u64 max_tx_rate;
0904 };
0905 
0906 VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_channel_info);
0907 
0908 struct virtchnl_tc_info {
0909     u32 num_tc;
0910     u32 pad;
0911     struct  virtchnl_channel_info list[1];
0912 };
0913 
0914 VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_tc_info);
0915 
0916 /* VIRTCHNL_ADD_CLOUD_FILTER
0917  * VIRTCHNL_DEL_CLOUD_FILTER
0918  * VF sends these messages to add or delete a cloud filter based on the
0919  * user specified match and action filters. These structures encompass
0920  * all the information that the PF needs from the VF to add/delete a
0921  * cloud filter.
0922  */
0923 
0924 struct virtchnl_l4_spec {
0925     u8  src_mac[ETH_ALEN];
0926     u8  dst_mac[ETH_ALEN];
0927     __be16  vlan_id;
0928     __be16  pad; /* reserved for future use */
0929     __be32  src_ip[4];
0930     __be32  dst_ip[4];
0931     __be16  src_port;
0932     __be16  dst_port;
0933 };
0934 
0935 VIRTCHNL_CHECK_STRUCT_LEN(52, virtchnl_l4_spec);
0936 
0937 union virtchnl_flow_spec {
0938     struct  virtchnl_l4_spec tcp_spec;
0939     u8  buffer[128]; /* reserved for future use */
0940 };
0941 
0942 VIRTCHNL_CHECK_UNION_LEN(128, virtchnl_flow_spec);
0943 
0944 enum virtchnl_action {
0945     /* action types */
0946     VIRTCHNL_ACTION_DROP = 0,
0947     VIRTCHNL_ACTION_TC_REDIRECT,
0948     VIRTCHNL_ACTION_PASSTHRU,
0949     VIRTCHNL_ACTION_QUEUE,
0950     VIRTCHNL_ACTION_Q_REGION,
0951     VIRTCHNL_ACTION_MARK,
0952     VIRTCHNL_ACTION_COUNT,
0953 };
0954 
0955 enum virtchnl_flow_type {
0956     /* flow types */
0957     VIRTCHNL_TCP_V4_FLOW = 0,
0958     VIRTCHNL_TCP_V6_FLOW,
0959 };
0960 
0961 struct virtchnl_filter {
0962     union   virtchnl_flow_spec data;
0963     union   virtchnl_flow_spec mask;
0964     enum    virtchnl_flow_type flow_type;
0965     enum    virtchnl_action action;
0966     u32 action_meta;
0967     u8  field_flags;
0968     u8  pad[3];
0969 };
0970 
0971 VIRTCHNL_CHECK_STRUCT_LEN(272, virtchnl_filter);
0972 
0973 /* VIRTCHNL_OP_EVENT
0974  * PF sends this message to inform the VF driver of events that may affect it.
0975  * No direct response is expected from the VF, though it may generate other
0976  * messages in response to this one.
0977  */
0978 enum virtchnl_event_codes {
0979     VIRTCHNL_EVENT_UNKNOWN = 0,
0980     VIRTCHNL_EVENT_LINK_CHANGE,
0981     VIRTCHNL_EVENT_RESET_IMPENDING,
0982     VIRTCHNL_EVENT_PF_DRIVER_CLOSE,
0983 };
0984 
0985 #define PF_EVENT_SEVERITY_INFO      0
0986 #define PF_EVENT_SEVERITY_CERTAIN_DOOM  255
0987 
0988 struct virtchnl_pf_event {
0989     enum virtchnl_event_codes event;
0990     union {
0991         /* If the PF driver does not support the new speed reporting
0992          * capabilities then use link_event else use link_event_adv to
0993          * get the speed and link information. The ability to understand
0994          * new speeds is indicated by setting the capability flag
0995          * VIRTCHNL_VF_CAP_ADV_LINK_SPEED in vf_cap_flags parameter
0996          * in virtchnl_vf_resource struct and can be used to determine
0997          * which link event struct to use below.
0998          */
0999         struct {
1000             enum virtchnl_link_speed link_speed;
1001             bool link_status;
1002         } link_event;
1003         struct {
1004             /* link_speed provided in Mbps */
1005             u32 link_speed;
1006             u8 link_status;
1007             u8 pad[3];
1008         } link_event_adv;
1009     } event_data;
1010 
1011     int severity;
1012 };
1013 
1014 VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_pf_event);
1015 
1016 /* VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP
1017  * VF uses this message to request PF to map IWARP vectors to IWARP queues.
1018  * The request for this originates from the VF IWARP driver through
1019  * a client interface between VF LAN and VF IWARP driver.
1020  * A vector could have an AEQ and CEQ attached to it although
1021  * there is a single AEQ per VF IWARP instance in which case
1022  * most vectors will have an INVALID_IDX for aeq and valid idx for ceq.
1023  * There will never be a case where there will be multiple CEQs attached
1024  * to a single vector.
1025  * PF configures interrupt mapping and returns status.
1026  */
1027 
1028 struct virtchnl_iwarp_qv_info {
1029     u32 v_idx; /* msix_vector */
1030     u16 ceq_idx;
1031     u16 aeq_idx;
1032     u8 itr_idx;
1033     u8 pad[3];
1034 };
1035 
1036 VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_iwarp_qv_info);
1037 
1038 struct virtchnl_iwarp_qvlist_info {
1039     u32 num_vectors;
1040     struct virtchnl_iwarp_qv_info qv_info[1];
1041 };
1042 
1043 VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_iwarp_qvlist_info);
1044 
1045 /* VF reset states - these are written into the RSTAT register:
1046  * VFGEN_RSTAT on the VF
1047  * When the PF initiates a reset, it writes 0
1048  * When the reset is complete, it writes 1
1049  * When the PF detects that the VF has recovered, it writes 2
1050  * VF checks this register periodically to determine if a reset has occurred,
1051  * then polls it to know when the reset is complete.
1052  * If either the PF or VF reads the register while the hardware
1053  * is in a reset state, it will return DEADBEEF, which, when masked
1054  * will result in 3.
1055  */
1056 enum virtchnl_vfr_states {
1057     VIRTCHNL_VFR_INPROGRESS = 0,
1058     VIRTCHNL_VFR_COMPLETED,
1059     VIRTCHNL_VFR_VFACTIVE,
1060 };
1061 
1062 /* Type of RSS algorithm */
1063 enum virtchnl_rss_algorithm {
1064     VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC    = 0,
1065     VIRTCHNL_RSS_ALG_R_ASYMMETRIC       = 1,
1066     VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC = 2,
1067     VIRTCHNL_RSS_ALG_XOR_SYMMETRIC      = 3,
1068 };
1069 
1070 #define VIRTCHNL_MAX_NUM_PROTO_HDRS 32
1071 #define PROTO_HDR_SHIFT         5
1072 #define PROTO_HDR_FIELD_START(proto_hdr_type) ((proto_hdr_type) << PROTO_HDR_SHIFT)
1073 #define PROTO_HDR_FIELD_MASK ((1UL << PROTO_HDR_SHIFT) - 1)
1074 
1075 /* VF use these macros to configure each protocol header.
1076  * Specify which protocol headers and protocol header fields base on
1077  * virtchnl_proto_hdr_type and virtchnl_proto_hdr_field.
1078  * @param hdr: a struct of virtchnl_proto_hdr
1079  * @param hdr_type: ETH/IPV4/TCP, etc
1080  * @param field: SRC/DST/TEID/SPI, etc
1081  */
1082 #define VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, field) \
1083     ((hdr)->field_selector |= BIT((field) & PROTO_HDR_FIELD_MASK))
1084 #define VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, field) \
1085     ((hdr)->field_selector &= ~BIT((field) & PROTO_HDR_FIELD_MASK))
1086 #define VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val) \
1087     ((hdr)->field_selector & BIT((val) & PROTO_HDR_FIELD_MASK))
1088 #define VIRTCHNL_GET_PROTO_HDR_FIELD(hdr)   ((hdr)->field_selector)
1089 
1090 #define VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
1091     (VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, \
1092         VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field))
1093 #define VIRTCHNL_DEL_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
1094     (VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, \
1095         VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field))
1096 
1097 #define VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, hdr_type) \
1098     ((hdr)->type = VIRTCHNL_PROTO_HDR_ ## hdr_type)
1099 #define VIRTCHNL_GET_PROTO_HDR_TYPE(hdr) \
1100     (((hdr)->type) >> PROTO_HDR_SHIFT)
1101 #define VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) \
1102     ((hdr)->type == ((val) >> PROTO_HDR_SHIFT))
1103 #define VIRTCHNL_TEST_PROTO_HDR(hdr, val) \
1104     (VIRTCHNL_TEST_PROTO_HDR_TYPE((hdr), (val)) && \
1105      VIRTCHNL_TEST_PROTO_HDR_FIELD((hdr), (val)))
1106 
1107 /* Protocol header type within a packet segment. A segment consists of one or
1108  * more protocol headers that make up a logical group of protocol headers. Each
1109  * logical group of protocol headers encapsulates or is encapsulated using/by
1110  * tunneling or encapsulation protocols for network virtualization.
1111  */
1112 enum virtchnl_proto_hdr_type {
1113     VIRTCHNL_PROTO_HDR_NONE,
1114     VIRTCHNL_PROTO_HDR_ETH,
1115     VIRTCHNL_PROTO_HDR_S_VLAN,
1116     VIRTCHNL_PROTO_HDR_C_VLAN,
1117     VIRTCHNL_PROTO_HDR_IPV4,
1118     VIRTCHNL_PROTO_HDR_IPV6,
1119     VIRTCHNL_PROTO_HDR_TCP,
1120     VIRTCHNL_PROTO_HDR_UDP,
1121     VIRTCHNL_PROTO_HDR_SCTP,
1122     VIRTCHNL_PROTO_HDR_GTPU_IP,
1123     VIRTCHNL_PROTO_HDR_GTPU_EH,
1124     VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN,
1125     VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP,
1126     VIRTCHNL_PROTO_HDR_PPPOE,
1127     VIRTCHNL_PROTO_HDR_L2TPV3,
1128     VIRTCHNL_PROTO_HDR_ESP,
1129     VIRTCHNL_PROTO_HDR_AH,
1130     VIRTCHNL_PROTO_HDR_PFCP,
1131 };
1132 
1133 /* Protocol header field within a protocol header. */
1134 enum virtchnl_proto_hdr_field {
1135     /* ETHER */
1136     VIRTCHNL_PROTO_HDR_ETH_SRC =
1137         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ETH),
1138     VIRTCHNL_PROTO_HDR_ETH_DST,
1139     VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE,
1140     /* S-VLAN */
1141     VIRTCHNL_PROTO_HDR_S_VLAN_ID =
1142         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_S_VLAN),
1143     /* C-VLAN */
1144     VIRTCHNL_PROTO_HDR_C_VLAN_ID =
1145         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_C_VLAN),
1146     /* IPV4 */
1147     VIRTCHNL_PROTO_HDR_IPV4_SRC =
1148         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV4),
1149     VIRTCHNL_PROTO_HDR_IPV4_DST,
1150     VIRTCHNL_PROTO_HDR_IPV4_DSCP,
1151     VIRTCHNL_PROTO_HDR_IPV4_TTL,
1152     VIRTCHNL_PROTO_HDR_IPV4_PROT,
1153     /* IPV6 */
1154     VIRTCHNL_PROTO_HDR_IPV6_SRC =
1155         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV6),
1156     VIRTCHNL_PROTO_HDR_IPV6_DST,
1157     VIRTCHNL_PROTO_HDR_IPV6_TC,
1158     VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT,
1159     VIRTCHNL_PROTO_HDR_IPV6_PROT,
1160     /* TCP */
1161     VIRTCHNL_PROTO_HDR_TCP_SRC_PORT =
1162         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_TCP),
1163     VIRTCHNL_PROTO_HDR_TCP_DST_PORT,
1164     /* UDP */
1165     VIRTCHNL_PROTO_HDR_UDP_SRC_PORT =
1166         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_UDP),
1167     VIRTCHNL_PROTO_HDR_UDP_DST_PORT,
1168     /* SCTP */
1169     VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT =
1170         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_SCTP),
1171     VIRTCHNL_PROTO_HDR_SCTP_DST_PORT,
1172     /* GTPU_IP */
1173     VIRTCHNL_PROTO_HDR_GTPU_IP_TEID =
1174         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_IP),
1175     /* GTPU_EH */
1176     VIRTCHNL_PROTO_HDR_GTPU_EH_PDU =
1177         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_EH),
1178     VIRTCHNL_PROTO_HDR_GTPU_EH_QFI,
1179     /* PPPOE */
1180     VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID =
1181         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PPPOE),
1182     /* L2TPV3 */
1183     VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID =
1184         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_L2TPV3),
1185     /* ESP */
1186     VIRTCHNL_PROTO_HDR_ESP_SPI =
1187         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ESP),
1188     /* AH */
1189     VIRTCHNL_PROTO_HDR_AH_SPI =
1190         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_AH),
1191     /* PFCP */
1192     VIRTCHNL_PROTO_HDR_PFCP_S_FIELD =
1193         PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PFCP),
1194     VIRTCHNL_PROTO_HDR_PFCP_SEID,
1195 };
1196 
1197 struct virtchnl_proto_hdr {
1198     enum virtchnl_proto_hdr_type type;
1199     u32 field_selector; /* a bit mask to select field for header type */
1200     u8 buffer[64];
1201     /**
1202      * binary buffer in network order for specific header type.
1203      * For example, if type = VIRTCHNL_PROTO_HDR_IPV4, a IPv4
1204      * header is expected to be copied into the buffer.
1205      */
1206 };
1207 
1208 VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_proto_hdr);
1209 
1210 struct virtchnl_proto_hdrs {
1211     u8 tunnel_level;
1212     u8 pad[3];
1213     /**
1214      * specify where protocol header start from.
1215      * 0 - from the outer layer
1216      * 1 - from the first inner layer
1217      * 2 - from the second inner layer
1218      * ....
1219      **/
1220     int count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */
1221     struct virtchnl_proto_hdr proto_hdr[VIRTCHNL_MAX_NUM_PROTO_HDRS];
1222 };
1223 
1224 VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
1225 
1226 struct virtchnl_rss_cfg {
1227     struct virtchnl_proto_hdrs proto_hdrs;     /* protocol headers */
1228     enum virtchnl_rss_algorithm rss_algorithm; /* RSS algorithm type */
1229     u8 reserved[128];              /* reserve for future */
1230 };
1231 
1232 VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
1233 
1234 /* action configuration for FDIR */
1235 struct virtchnl_filter_action {
1236     enum virtchnl_action type;
1237     union {
1238         /* used for queue and qgroup action */
1239         struct {
1240             u16 index;
1241             u8 region;
1242         } queue;
1243         /* used for count action */
1244         struct {
1245             /* share counter ID with other flow rules */
1246             u8 shared;
1247             u32 id; /* counter ID */
1248         } count;
1249         /* used for mark action */
1250         u32 mark_id;
1251         u8 reserve[32];
1252     } act_conf;
1253 };
1254 
1255 VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_filter_action);
1256 
1257 #define VIRTCHNL_MAX_NUM_ACTIONS  8
1258 
1259 struct virtchnl_filter_action_set {
1260     /* action number must be less then VIRTCHNL_MAX_NUM_ACTIONS */
1261     int count;
1262     struct virtchnl_filter_action actions[VIRTCHNL_MAX_NUM_ACTIONS];
1263 };
1264 
1265 VIRTCHNL_CHECK_STRUCT_LEN(292, virtchnl_filter_action_set);
1266 
1267 /* pattern and action for FDIR rule */
1268 struct virtchnl_fdir_rule {
1269     struct virtchnl_proto_hdrs proto_hdrs;
1270     struct virtchnl_filter_action_set action_set;
1271 };
1272 
1273 VIRTCHNL_CHECK_STRUCT_LEN(2604, virtchnl_fdir_rule);
1274 
1275 /* Status returned to VF after VF requests FDIR commands
1276  * VIRTCHNL_FDIR_SUCCESS
1277  * VF FDIR related request is successfully done by PF
1278  * The request can be OP_ADD/DEL.
1279  *
1280  * VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE
1281  * OP_ADD_FDIR_FILTER request is failed due to no Hardware resource.
1282  *
1283  * VIRTCHNL_FDIR_FAILURE_RULE_EXIST
1284  * OP_ADD_FDIR_FILTER request is failed due to the rule is already existed.
1285  *
1286  * VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT
1287  * OP_ADD_FDIR_FILTER request is failed due to conflict with existing rule.
1288  *
1289  * VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST
1290  * OP_DEL_FDIR_FILTER request is failed due to this rule doesn't exist.
1291  *
1292  * VIRTCHNL_FDIR_FAILURE_RULE_INVALID
1293  * OP_ADD_FDIR_FILTER request is failed due to parameters validation
1294  * or HW doesn't support.
1295  *
1296  * VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT
1297  * OP_ADD/DEL_FDIR_FILTER request is failed due to timing out
1298  * for programming.
1299  */
1300 enum virtchnl_fdir_prgm_status {
1301     VIRTCHNL_FDIR_SUCCESS = 0,
1302     VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE,
1303     VIRTCHNL_FDIR_FAILURE_RULE_EXIST,
1304     VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT,
1305     VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST,
1306     VIRTCHNL_FDIR_FAILURE_RULE_INVALID,
1307     VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT,
1308 };
1309 
1310 /* VIRTCHNL_OP_ADD_FDIR_FILTER
1311  * VF sends this request to PF by filling out vsi_id,
1312  * validate_only and rule_cfg. PF will return flow_id
1313  * if the request is successfully done and return add_status to VF.
1314  */
1315 struct virtchnl_fdir_add {
1316     u16 vsi_id;  /* INPUT */
1317     /*
1318      * 1 for validating a fdir rule, 0 for creating a fdir rule.
1319      * Validate and create share one ops: VIRTCHNL_OP_ADD_FDIR_FILTER.
1320      */
1321     u16 validate_only; /* INPUT */
1322     u32 flow_id;       /* OUTPUT */
1323     struct virtchnl_fdir_rule rule_cfg; /* INPUT */
1324     enum virtchnl_fdir_prgm_status status; /* OUTPUT */
1325 };
1326 
1327 VIRTCHNL_CHECK_STRUCT_LEN(2616, virtchnl_fdir_add);
1328 
1329 /* VIRTCHNL_OP_DEL_FDIR_FILTER
1330  * VF sends this request to PF by filling out vsi_id
1331  * and flow_id. PF will return del_status to VF.
1332  */
1333 struct virtchnl_fdir_del {
1334     u16 vsi_id;  /* INPUT */
1335     u16 pad;
1336     u32 flow_id; /* INPUT */
1337     enum virtchnl_fdir_prgm_status status; /* OUTPUT */
1338 };
1339 
1340 VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_fdir_del);
1341 
1342 /**
1343  * virtchnl_vc_validate_vf_msg
1344  * @ver: Virtchnl version info
1345  * @v_opcode: Opcode for the message
1346  * @msg: pointer to the msg buffer
1347  * @msglen: msg length
1348  *
1349  * validate msg format against struct for each opcode
1350  */
1351 static inline int
1352 virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
1353                 u8 *msg, u16 msglen)
1354 {
1355     bool err_msg_format = false;
1356     int valid_len = 0;
1357 
1358     /* Validate message length. */
1359     switch (v_opcode) {
1360     case VIRTCHNL_OP_VERSION:
1361         valid_len = sizeof(struct virtchnl_version_info);
1362         break;
1363     case VIRTCHNL_OP_RESET_VF:
1364         break;
1365     case VIRTCHNL_OP_GET_VF_RESOURCES:
1366         if (VF_IS_V11(ver))
1367             valid_len = sizeof(u32);
1368         break;
1369     case VIRTCHNL_OP_CONFIG_TX_QUEUE:
1370         valid_len = sizeof(struct virtchnl_txq_info);
1371         break;
1372     case VIRTCHNL_OP_CONFIG_RX_QUEUE:
1373         valid_len = sizeof(struct virtchnl_rxq_info);
1374         break;
1375     case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
1376         valid_len = sizeof(struct virtchnl_vsi_queue_config_info);
1377         if (msglen >= valid_len) {
1378             struct virtchnl_vsi_queue_config_info *vqc =
1379                 (struct virtchnl_vsi_queue_config_info *)msg;
1380             valid_len += (vqc->num_queue_pairs *
1381                       sizeof(struct
1382                          virtchnl_queue_pair_info));
1383             if (vqc->num_queue_pairs == 0)
1384                 err_msg_format = true;
1385         }
1386         break;
1387     case VIRTCHNL_OP_CONFIG_IRQ_MAP:
1388         valid_len = sizeof(struct virtchnl_irq_map_info);
1389         if (msglen >= valid_len) {
1390             struct virtchnl_irq_map_info *vimi =
1391                 (struct virtchnl_irq_map_info *)msg;
1392             valid_len += (vimi->num_vectors *
1393                       sizeof(struct virtchnl_vector_map));
1394             if (vimi->num_vectors == 0)
1395                 err_msg_format = true;
1396         }
1397         break;
1398     case VIRTCHNL_OP_ENABLE_QUEUES:
1399     case VIRTCHNL_OP_DISABLE_QUEUES:
1400         valid_len = sizeof(struct virtchnl_queue_select);
1401         break;
1402     case VIRTCHNL_OP_ADD_ETH_ADDR:
1403     case VIRTCHNL_OP_DEL_ETH_ADDR:
1404         valid_len = sizeof(struct virtchnl_ether_addr_list);
1405         if (msglen >= valid_len) {
1406             struct virtchnl_ether_addr_list *veal =
1407                 (struct virtchnl_ether_addr_list *)msg;
1408             valid_len += veal->num_elements *
1409                 sizeof(struct virtchnl_ether_addr);
1410             if (veal->num_elements == 0)
1411                 err_msg_format = true;
1412         }
1413         break;
1414     case VIRTCHNL_OP_ADD_VLAN:
1415     case VIRTCHNL_OP_DEL_VLAN:
1416         valid_len = sizeof(struct virtchnl_vlan_filter_list);
1417         if (msglen >= valid_len) {
1418             struct virtchnl_vlan_filter_list *vfl =
1419                 (struct virtchnl_vlan_filter_list *)msg;
1420             valid_len += vfl->num_elements * sizeof(u16);
1421             if (vfl->num_elements == 0)
1422                 err_msg_format = true;
1423         }
1424         break;
1425     case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
1426         valid_len = sizeof(struct virtchnl_promisc_info);
1427         break;
1428     case VIRTCHNL_OP_GET_STATS:
1429         valid_len = sizeof(struct virtchnl_queue_select);
1430         break;
1431     case VIRTCHNL_OP_IWARP:
1432         /* These messages are opaque to us and will be validated in
1433          * the RDMA client code. We just need to check for nonzero
1434          * length. The firmware will enforce max length restrictions.
1435          */
1436         if (msglen)
1437             valid_len = msglen;
1438         else
1439             err_msg_format = true;
1440         break;
1441     case VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP:
1442         break;
1443     case VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP:
1444         valid_len = sizeof(struct virtchnl_iwarp_qvlist_info);
1445         if (msglen >= valid_len) {
1446             struct virtchnl_iwarp_qvlist_info *qv =
1447                 (struct virtchnl_iwarp_qvlist_info *)msg;
1448             if (qv->num_vectors == 0) {
1449                 err_msg_format = true;
1450                 break;
1451             }
1452             valid_len += ((qv->num_vectors - 1) *
1453                 sizeof(struct virtchnl_iwarp_qv_info));
1454         }
1455         break;
1456     case VIRTCHNL_OP_CONFIG_RSS_KEY:
1457         valid_len = sizeof(struct virtchnl_rss_key);
1458         if (msglen >= valid_len) {
1459             struct virtchnl_rss_key *vrk =
1460                 (struct virtchnl_rss_key *)msg;
1461             valid_len += vrk->key_len - 1;
1462         }
1463         break;
1464     case VIRTCHNL_OP_CONFIG_RSS_LUT:
1465         valid_len = sizeof(struct virtchnl_rss_lut);
1466         if (msglen >= valid_len) {
1467             struct virtchnl_rss_lut *vrl =
1468                 (struct virtchnl_rss_lut *)msg;
1469             valid_len += vrl->lut_entries - 1;
1470         }
1471         break;
1472     case VIRTCHNL_OP_GET_RSS_HENA_CAPS:
1473         break;
1474     case VIRTCHNL_OP_SET_RSS_HENA:
1475         valid_len = sizeof(struct virtchnl_rss_hena);
1476         break;
1477     case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
1478     case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
1479         break;
1480     case VIRTCHNL_OP_REQUEST_QUEUES:
1481         valid_len = sizeof(struct virtchnl_vf_res_request);
1482         break;
1483     case VIRTCHNL_OP_ENABLE_CHANNELS:
1484         valid_len = sizeof(struct virtchnl_tc_info);
1485         if (msglen >= valid_len) {
1486             struct virtchnl_tc_info *vti =
1487                 (struct virtchnl_tc_info *)msg;
1488             valid_len += (vti->num_tc - 1) *
1489                      sizeof(struct virtchnl_channel_info);
1490             if (vti->num_tc == 0)
1491                 err_msg_format = true;
1492         }
1493         break;
1494     case VIRTCHNL_OP_DISABLE_CHANNELS:
1495         break;
1496     case VIRTCHNL_OP_ADD_CLOUD_FILTER:
1497         valid_len = sizeof(struct virtchnl_filter);
1498         break;
1499     case VIRTCHNL_OP_DEL_CLOUD_FILTER:
1500         valid_len = sizeof(struct virtchnl_filter);
1501         break;
1502     case VIRTCHNL_OP_ADD_RSS_CFG:
1503     case VIRTCHNL_OP_DEL_RSS_CFG:
1504         valid_len = sizeof(struct virtchnl_rss_cfg);
1505         break;
1506     case VIRTCHNL_OP_ADD_FDIR_FILTER:
1507         valid_len = sizeof(struct virtchnl_fdir_add);
1508         break;
1509     case VIRTCHNL_OP_DEL_FDIR_FILTER:
1510         valid_len = sizeof(struct virtchnl_fdir_del);
1511         break;
1512     case VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS:
1513         break;
1514     case VIRTCHNL_OP_ADD_VLAN_V2:
1515     case VIRTCHNL_OP_DEL_VLAN_V2:
1516         valid_len = sizeof(struct virtchnl_vlan_filter_list_v2);
1517         if (msglen >= valid_len) {
1518             struct virtchnl_vlan_filter_list_v2 *vfl =
1519                 (struct virtchnl_vlan_filter_list_v2 *)msg;
1520 
1521             valid_len += (vfl->num_elements - 1) *
1522                 sizeof(struct virtchnl_vlan_filter);
1523 
1524             if (vfl->num_elements == 0) {
1525                 err_msg_format = true;
1526                 break;
1527             }
1528         }
1529         break;
1530     case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2:
1531     case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2:
1532     case VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2:
1533     case VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2:
1534         valid_len = sizeof(struct virtchnl_vlan_setting);
1535         break;
1536     /* These are always errors coming from the VF. */
1537     case VIRTCHNL_OP_EVENT:
1538     case VIRTCHNL_OP_UNKNOWN:
1539     default:
1540         return VIRTCHNL_STATUS_ERR_PARAM;
1541     }
1542     /* few more checks */
1543     if (err_msg_format || valid_len != msglen)
1544         return VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH;
1545 
1546     return 0;
1547 }
1548 #endif /* _VIRTCHNL_H_ */