xref: /freebsd/sys/dev/ixl/virtchnl.h (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
1ceebc2f3SEric Joyner /******************************************************************************
2ceebc2f3SEric Joyner 
3f4cc2d17SEric Joyner   Copyright (c) 2013-2018, Intel Corporation
4ceebc2f3SEric Joyner   All rights reserved.
5ceebc2f3SEric Joyner 
6ceebc2f3SEric Joyner   Redistribution and use in source and binary forms, with or without
7ceebc2f3SEric Joyner   modification, are permitted provided that the following conditions are met:
8ceebc2f3SEric Joyner 
9ceebc2f3SEric Joyner    1. Redistributions of source code must retain the above copyright notice,
10ceebc2f3SEric Joyner       this list of conditions and the following disclaimer.
11ceebc2f3SEric Joyner 
12ceebc2f3SEric Joyner    2. Redistributions in binary form must reproduce the above copyright
13ceebc2f3SEric Joyner       notice, this list of conditions and the following disclaimer in the
14ceebc2f3SEric Joyner       documentation and/or other materials provided with the distribution.
15ceebc2f3SEric Joyner 
16ceebc2f3SEric Joyner    3. Neither the name of the Intel Corporation nor the names of its
17ceebc2f3SEric Joyner       contributors may be used to endorse or promote products derived from
18ceebc2f3SEric Joyner       this software without specific prior written permission.
19ceebc2f3SEric Joyner 
20ceebc2f3SEric Joyner   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21ceebc2f3SEric Joyner   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22ceebc2f3SEric Joyner   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23ceebc2f3SEric Joyner   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24ceebc2f3SEric Joyner   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25ceebc2f3SEric Joyner   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26ceebc2f3SEric Joyner   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27ceebc2f3SEric Joyner   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28ceebc2f3SEric Joyner   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29ceebc2f3SEric Joyner   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30ceebc2f3SEric Joyner   POSSIBILITY OF SUCH DAMAGE.
31ceebc2f3SEric Joyner 
32ceebc2f3SEric Joyner ******************************************************************************/
33ceebc2f3SEric Joyner 
34ceebc2f3SEric Joyner #ifndef _VIRTCHNL_H_
35ceebc2f3SEric Joyner #define _VIRTCHNL_H_
36ceebc2f3SEric Joyner 
37ceebc2f3SEric Joyner /* Description:
38ceebc2f3SEric Joyner  * This header file describes the VF-PF communication protocol used
39ceebc2f3SEric Joyner  * by the drivers for all devices starting from our 40G product line
40ceebc2f3SEric Joyner  *
41ceebc2f3SEric Joyner  * Admin queue buffer usage:
42ceebc2f3SEric Joyner  * desc->opcode is always aqc_opc_send_msg_to_pf
43ceebc2f3SEric Joyner  * flags, retval, datalen, and data addr are all used normally.
44ceebc2f3SEric Joyner  * The Firmware copies the cookie fields when sending messages between the
45ceebc2f3SEric Joyner  * PF and VF, but uses all other fields internally. Due to this limitation,
46ceebc2f3SEric Joyner  * we must send all messages as "indirect", i.e. using an external buffer.
47ceebc2f3SEric Joyner  *
48ceebc2f3SEric Joyner  * All the VSI indexes are relative to the VF. Each VF can have maximum of
49ceebc2f3SEric Joyner  * three VSIs. All the queue indexes are relative to the VSI.  Each VF can
50ceebc2f3SEric Joyner  * have a maximum of sixteen queues for all of its VSIs.
51ceebc2f3SEric Joyner  *
52ceebc2f3SEric Joyner  * The PF is required to return a status code in v_retval for all messages
53ceebc2f3SEric Joyner  * except RESET_VF, which does not require any response. The return value
54ceebc2f3SEric Joyner  * is of status_code type, defined in the shared type.h.
55ceebc2f3SEric Joyner  *
56ceebc2f3SEric Joyner  * In general, VF driver initialization should roughly follow the order of
57ceebc2f3SEric Joyner  * these opcodes. The VF driver must first validate the API version of the
58ceebc2f3SEric Joyner  * PF driver, then request a reset, then get resources, then configure
59ceebc2f3SEric Joyner  * queues and interrupts. After these operations are complete, the VF
60ceebc2f3SEric Joyner  * driver may start its queues, optionally add MAC and VLAN filters, and
61ceebc2f3SEric Joyner  * process traffic.
62ceebc2f3SEric Joyner  */
63ceebc2f3SEric Joyner 
64ceebc2f3SEric Joyner /* START GENERIC DEFINES
65ceebc2f3SEric Joyner  * Need to ensure the following enums and defines hold the same meaning and
66ceebc2f3SEric Joyner  * value in current and future projects
67ceebc2f3SEric Joyner  */
68ceebc2f3SEric Joyner 
69ceebc2f3SEric Joyner /* Error Codes */
70ceebc2f3SEric Joyner enum virtchnl_status_code {
71ceebc2f3SEric Joyner 	VIRTCHNL_STATUS_SUCCESS				= 0,
72ceebc2f3SEric Joyner 	VIRTCHNL_ERR_PARAM				= -5,
73ceebc2f3SEric Joyner 	VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH		= -38,
74ceebc2f3SEric Joyner 	VIRTCHNL_STATUS_ERR_CQP_COMPL_ERROR		= -39,
75ceebc2f3SEric Joyner 	VIRTCHNL_STATUS_ERR_INVALID_VF_ID		= -40,
76ceebc2f3SEric Joyner 	VIRTCHNL_STATUS_NOT_SUPPORTED			= -64,
77ceebc2f3SEric Joyner };
78ceebc2f3SEric Joyner 
79*2984a8ddSEric Joyner #define VIRTCHNL_LINK_SPEED_2_5GB_SHIFT		0x0
80ceebc2f3SEric Joyner #define VIRTCHNL_LINK_SPEED_100MB_SHIFT		0x1
81ceebc2f3SEric Joyner #define VIRTCHNL_LINK_SPEED_1000MB_SHIFT	0x2
82ceebc2f3SEric Joyner #define VIRTCHNL_LINK_SPEED_10GB_SHIFT		0x3
83ceebc2f3SEric Joyner #define VIRTCHNL_LINK_SPEED_40GB_SHIFT		0x4
84ceebc2f3SEric Joyner #define VIRTCHNL_LINK_SPEED_20GB_SHIFT		0x5
85ceebc2f3SEric Joyner #define VIRTCHNL_LINK_SPEED_25GB_SHIFT		0x6
86*2984a8ddSEric Joyner #define VIRTCHNL_LINK_SPEED_5GB_SHIFT		0x7
87ceebc2f3SEric Joyner 
88ceebc2f3SEric Joyner enum virtchnl_link_speed {
89ceebc2f3SEric Joyner 	VIRTCHNL_LINK_SPEED_UNKNOWN	= 0,
90ceebc2f3SEric Joyner 	VIRTCHNL_LINK_SPEED_100MB	= BIT(VIRTCHNL_LINK_SPEED_100MB_SHIFT),
91ceebc2f3SEric Joyner 	VIRTCHNL_LINK_SPEED_1GB		= BIT(VIRTCHNL_LINK_SPEED_1000MB_SHIFT),
92ceebc2f3SEric Joyner 	VIRTCHNL_LINK_SPEED_10GB	= BIT(VIRTCHNL_LINK_SPEED_10GB_SHIFT),
93ceebc2f3SEric Joyner 	VIRTCHNL_LINK_SPEED_40GB	= BIT(VIRTCHNL_LINK_SPEED_40GB_SHIFT),
94ceebc2f3SEric Joyner 	VIRTCHNL_LINK_SPEED_20GB	= BIT(VIRTCHNL_LINK_SPEED_20GB_SHIFT),
95ceebc2f3SEric Joyner 	VIRTCHNL_LINK_SPEED_25GB	= BIT(VIRTCHNL_LINK_SPEED_25GB_SHIFT),
96*2984a8ddSEric Joyner 	VIRTCHNL_LINK_SPEED_2_5GB	= BIT(VIRTCHNL_LINK_SPEED_2_5GB_SHIFT),
97*2984a8ddSEric Joyner 	VIRTCHNL_LINK_SPEED_5GB		= BIT(VIRTCHNL_LINK_SPEED_5GB_SHIFT),
98ceebc2f3SEric Joyner };
99ceebc2f3SEric Joyner 
100ceebc2f3SEric Joyner /* for hsplit_0 field of Rx HMC context */
101ceebc2f3SEric Joyner /* deprecated with AVF 1.0 */
102ceebc2f3SEric Joyner enum virtchnl_rx_hsplit {
103ceebc2f3SEric Joyner 	VIRTCHNL_RX_HSPLIT_NO_SPLIT      = 0,
104ceebc2f3SEric Joyner 	VIRTCHNL_RX_HSPLIT_SPLIT_L2      = 1,
105ceebc2f3SEric Joyner 	VIRTCHNL_RX_HSPLIT_SPLIT_IP      = 2,
106ceebc2f3SEric Joyner 	VIRTCHNL_RX_HSPLIT_SPLIT_TCP_UDP = 4,
107ceebc2f3SEric Joyner 	VIRTCHNL_RX_HSPLIT_SPLIT_SCTP    = 8,
108ceebc2f3SEric Joyner };
109ceebc2f3SEric Joyner 
110ceebc2f3SEric Joyner #define VIRTCHNL_ETH_LENGTH_OF_ADDRESS	6
111ceebc2f3SEric Joyner /* END GENERIC DEFINES */
112ceebc2f3SEric Joyner 
113ceebc2f3SEric Joyner /* Opcodes for VF-PF communication. These are placed in the v_opcode field
114ceebc2f3SEric Joyner  * of the virtchnl_msg structure.
115ceebc2f3SEric Joyner  */
116ceebc2f3SEric Joyner enum virtchnl_ops {
117ceebc2f3SEric Joyner /* The PF sends status change events to VFs using
118ceebc2f3SEric Joyner  * the VIRTCHNL_OP_EVENT opcode.
119ceebc2f3SEric Joyner  * VFs send requests to the PF using the other ops.
120ceebc2f3SEric Joyner  * Use of "advanced opcode" features must be negotiated as part of capabilities
121ceebc2f3SEric Joyner  * exchange and are not considered part of base mode feature set.
122ceebc2f3SEric Joyner  */
123ceebc2f3SEric Joyner 	VIRTCHNL_OP_UNKNOWN = 0,
124ceebc2f3SEric Joyner 	VIRTCHNL_OP_VERSION = 1, /* must ALWAYS be 1 */
125ceebc2f3SEric Joyner 	VIRTCHNL_OP_RESET_VF = 2,
126ceebc2f3SEric Joyner 	VIRTCHNL_OP_GET_VF_RESOURCES = 3,
127ceebc2f3SEric Joyner 	VIRTCHNL_OP_CONFIG_TX_QUEUE = 4,
128ceebc2f3SEric Joyner 	VIRTCHNL_OP_CONFIG_RX_QUEUE = 5,
129ceebc2f3SEric Joyner 	VIRTCHNL_OP_CONFIG_VSI_QUEUES = 6,
130ceebc2f3SEric Joyner 	VIRTCHNL_OP_CONFIG_IRQ_MAP = 7,
131ceebc2f3SEric Joyner 	VIRTCHNL_OP_ENABLE_QUEUES = 8,
132ceebc2f3SEric Joyner 	VIRTCHNL_OP_DISABLE_QUEUES = 9,
133ceebc2f3SEric Joyner 	VIRTCHNL_OP_ADD_ETH_ADDR = 10,
134ceebc2f3SEric Joyner 	VIRTCHNL_OP_DEL_ETH_ADDR = 11,
135ceebc2f3SEric Joyner 	VIRTCHNL_OP_ADD_VLAN = 12,
136ceebc2f3SEric Joyner 	VIRTCHNL_OP_DEL_VLAN = 13,
137ceebc2f3SEric Joyner 	VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE = 14,
138ceebc2f3SEric Joyner 	VIRTCHNL_OP_GET_STATS = 15,
139ceebc2f3SEric Joyner 	VIRTCHNL_OP_RSVD = 16,
140ceebc2f3SEric Joyner 	VIRTCHNL_OP_EVENT = 17, /* must ALWAYS be 17 */
141ceebc2f3SEric Joyner 	VIRTCHNL_OP_IWARP = 20, /* advanced opcode */
142ceebc2f3SEric Joyner 	VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP = 21, /* advanced opcode */
143ceebc2f3SEric Joyner 	VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP = 22, /* advanced opcode */
144ceebc2f3SEric Joyner 	VIRTCHNL_OP_CONFIG_RSS_KEY = 23,
145ceebc2f3SEric Joyner 	VIRTCHNL_OP_CONFIG_RSS_LUT = 24,
146ceebc2f3SEric Joyner 	VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25,
147ceebc2f3SEric Joyner 	VIRTCHNL_OP_SET_RSS_HENA = 26,
148ceebc2f3SEric Joyner 	VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27,
149ceebc2f3SEric Joyner 	VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28,
150ceebc2f3SEric Joyner 	VIRTCHNL_OP_REQUEST_QUEUES = 29,
151ceebc2f3SEric Joyner 
152ceebc2f3SEric Joyner };
153ceebc2f3SEric Joyner 
154ceebc2f3SEric Joyner /* This macro is used to generate a compilation error if a structure
155ceebc2f3SEric Joyner  * is not exactly the correct length. It gives a divide by zero error if the
156ceebc2f3SEric Joyner  * structure is not of the correct size, otherwise it creates an enum that is
157ceebc2f3SEric Joyner  * never used.
158ceebc2f3SEric Joyner  */
159ceebc2f3SEric Joyner #define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \
160ceebc2f3SEric Joyner 	{virtchnl_static_assert_##X = (n) / ((sizeof(struct X) == (n)) ? 1 : 0)}
161ceebc2f3SEric Joyner 
162ceebc2f3SEric Joyner /* Virtual channel message descriptor. This overlays the admin queue
163ceebc2f3SEric Joyner  * descriptor. All other data is passed in external buffers.
164ceebc2f3SEric Joyner  */
165ceebc2f3SEric Joyner 
166ceebc2f3SEric Joyner struct virtchnl_msg {
167ceebc2f3SEric Joyner 	u8 pad[8];			 /* AQ flags/opcode/len/retval fields */
168ceebc2f3SEric Joyner 	enum virtchnl_ops v_opcode; /* avoid confusion with desc->opcode */
169ceebc2f3SEric Joyner 	enum virtchnl_status_code v_retval;  /* ditto for desc->retval */
170ceebc2f3SEric Joyner 	u32 vfid;			 /* used by PF when sending to VF */
171ceebc2f3SEric Joyner };
172ceebc2f3SEric Joyner 
173ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(20, virtchnl_msg);
174ceebc2f3SEric Joyner 
175ceebc2f3SEric Joyner /* Message descriptions and data structures.*/
176ceebc2f3SEric Joyner 
177ceebc2f3SEric Joyner /* VIRTCHNL_OP_VERSION
178ceebc2f3SEric Joyner  * VF posts its version number to the PF. PF responds with its version number
179ceebc2f3SEric Joyner  * in the same format, along with a return code.
180ceebc2f3SEric Joyner  * Reply from PF has its major/minor versions also in param0 and param1.
181ceebc2f3SEric Joyner  * If there is a major version mismatch, then the VF cannot operate.
182ceebc2f3SEric Joyner  * If there is a minor version mismatch, then the VF can operate but should
183ceebc2f3SEric Joyner  * add a warning to the system log.
184ceebc2f3SEric Joyner  *
185ceebc2f3SEric Joyner  * This enum element MUST always be specified as == 1, regardless of other
186ceebc2f3SEric Joyner  * changes in the API. The PF must always respond to this message without
187ceebc2f3SEric Joyner  * error regardless of version mismatch.
188ceebc2f3SEric Joyner  */
189ceebc2f3SEric Joyner #define VIRTCHNL_VERSION_MAJOR		1
190ceebc2f3SEric Joyner #define VIRTCHNL_VERSION_MINOR		1
191ceebc2f3SEric Joyner #define VIRTCHNL_VERSION_MINOR_NO_VF_CAPS	0
192ceebc2f3SEric Joyner 
193ceebc2f3SEric Joyner struct virtchnl_version_info {
194ceebc2f3SEric Joyner 	u32 major;
195ceebc2f3SEric Joyner 	u32 minor;
196ceebc2f3SEric Joyner };
197ceebc2f3SEric Joyner 
198ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_version_info);
199ceebc2f3SEric Joyner 
200ceebc2f3SEric Joyner #define VF_IS_V10(_v) (((_v)->major == 1) && ((_v)->minor == 0))
201ceebc2f3SEric Joyner #define VF_IS_V11(_ver) (((_ver)->major == 1) && ((_ver)->minor == 1))
202ceebc2f3SEric Joyner 
203ceebc2f3SEric Joyner /* VIRTCHNL_OP_RESET_VF
204ceebc2f3SEric Joyner  * VF sends this request to PF with no parameters
205ceebc2f3SEric Joyner  * PF does NOT respond! VF driver must delay then poll VFGEN_RSTAT register
206ceebc2f3SEric Joyner  * until reset completion is indicated. The admin queue must be reinitialized
207ceebc2f3SEric Joyner  * after this operation.
208ceebc2f3SEric Joyner  *
209ceebc2f3SEric Joyner  * When reset is complete, PF must ensure that all queues in all VSIs associated
210ceebc2f3SEric Joyner  * with the VF are stopped, all queue configurations in the HMC are set to 0,
211ceebc2f3SEric Joyner  * and all MAC and VLAN filters (except the default MAC address) on all VSIs
212ceebc2f3SEric Joyner  * are cleared.
213ceebc2f3SEric Joyner  */
214ceebc2f3SEric Joyner 
215ceebc2f3SEric Joyner /* VSI types that use VIRTCHNL interface for VF-PF communication. VSI_SRIOV
216ceebc2f3SEric Joyner  * vsi_type should always be 6 for backward compatibility. Add other fields
217ceebc2f3SEric Joyner  * as needed.
218ceebc2f3SEric Joyner  */
219ceebc2f3SEric Joyner enum virtchnl_vsi_type {
220ceebc2f3SEric Joyner 	VIRTCHNL_VSI_TYPE_INVALID = 0,
221ceebc2f3SEric Joyner 	VIRTCHNL_VSI_SRIOV = 6,
222ceebc2f3SEric Joyner };
223ceebc2f3SEric Joyner 
224ceebc2f3SEric Joyner /* VIRTCHNL_OP_GET_VF_RESOURCES
225ceebc2f3SEric Joyner  * Version 1.0 VF sends this request to PF with no parameters
226ceebc2f3SEric Joyner  * Version 1.1 VF sends this request to PF with u32 bitmap of its capabilities
227ceebc2f3SEric Joyner  * PF responds with an indirect message containing
228ceebc2f3SEric Joyner  * virtchnl_vf_resource and one or more
229ceebc2f3SEric Joyner  * virtchnl_vsi_resource structures.
230ceebc2f3SEric Joyner  */
231ceebc2f3SEric Joyner 
232ceebc2f3SEric Joyner struct virtchnl_vsi_resource {
233ceebc2f3SEric Joyner 	u16 vsi_id;
234ceebc2f3SEric Joyner 	u16 num_queue_pairs;
235ceebc2f3SEric Joyner 	enum virtchnl_vsi_type vsi_type;
236ceebc2f3SEric Joyner 	u16 qset_handle;
237ceebc2f3SEric Joyner 	u8 default_mac_addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS];
238ceebc2f3SEric Joyner };
239ceebc2f3SEric Joyner 
240ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);
241ceebc2f3SEric Joyner 
242ceebc2f3SEric Joyner /* VF capability flags
243ceebc2f3SEric Joyner  * VIRTCHNL_VF_OFFLOAD_L2 flag is inclusive of base mode L2 offloads including
244ceebc2f3SEric Joyner  * TX/RX Checksum offloading and TSO for non-tunnelled packets.
245ceebc2f3SEric Joyner  */
246ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_L2			0x00000001
247ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_IWARP		0x00000002
248ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_RSVD		0x00000004
249ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_RSS_AQ		0x00000008
250ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_RSS_REG		0x00000010
251ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_WB_ON_ITR		0x00000020
252ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES		0x00000040
253ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_VLAN		0x00010000
254ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_RX_POLLING		0x00020000
255ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2	0x00040000
256ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_RSS_PF		0X00080000
257ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_ENCAP		0X00100000
258ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM		0X00200000
259ceebc2f3SEric Joyner #define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM	0X00400000
260ceebc2f3SEric Joyner 
261ceebc2f3SEric Joyner #define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \
262ceebc2f3SEric Joyner 			       VIRTCHNL_VF_OFFLOAD_VLAN | \
263ceebc2f3SEric Joyner 			       VIRTCHNL_VF_OFFLOAD_RSS_PF)
264ceebc2f3SEric Joyner 
265ceebc2f3SEric Joyner struct virtchnl_vf_resource {
266ceebc2f3SEric Joyner 	u16 num_vsis;
267ceebc2f3SEric Joyner 	u16 num_queue_pairs;
268ceebc2f3SEric Joyner 	u16 max_vectors;
269ceebc2f3SEric Joyner 	u16 max_mtu;
270ceebc2f3SEric Joyner 
271ceebc2f3SEric Joyner 	u32 vf_cap_flags;
272ceebc2f3SEric Joyner 	u32 rss_key_size;
273ceebc2f3SEric Joyner 	u32 rss_lut_size;
274ceebc2f3SEric Joyner 
275ceebc2f3SEric Joyner 	struct virtchnl_vsi_resource vsi_res[1];
276ceebc2f3SEric Joyner };
277ceebc2f3SEric Joyner 
278ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_vf_resource);
279ceebc2f3SEric Joyner 
280ceebc2f3SEric Joyner /* VIRTCHNL_OP_CONFIG_TX_QUEUE
281ceebc2f3SEric Joyner  * VF sends this message to set up parameters for one TX queue.
282ceebc2f3SEric Joyner  * External data buffer contains one instance of virtchnl_txq_info.
283ceebc2f3SEric Joyner  * PF configures requested queue and returns a status code.
284ceebc2f3SEric Joyner  */
285ceebc2f3SEric Joyner 
286ceebc2f3SEric Joyner /* Tx queue config info */
287ceebc2f3SEric Joyner struct virtchnl_txq_info {
288ceebc2f3SEric Joyner 	u16 vsi_id;
289ceebc2f3SEric Joyner 	u16 queue_id;
290ceebc2f3SEric Joyner 	u16 ring_len;		/* number of descriptors, multiple of 8 */
291ceebc2f3SEric Joyner 	u16 headwb_enabled; /* deprecated with AVF 1.0 */
292ceebc2f3SEric Joyner 	u64 dma_ring_addr;
293ceebc2f3SEric Joyner 	u64 dma_headwb_addr; /* deprecated with AVF 1.0 */
294ceebc2f3SEric Joyner };
295ceebc2f3SEric Joyner 
296ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info);
297ceebc2f3SEric Joyner 
298ceebc2f3SEric Joyner /* VIRTCHNL_OP_CONFIG_RX_QUEUE
299ceebc2f3SEric Joyner  * VF sends this message to set up parameters for one RX queue.
300ceebc2f3SEric Joyner  * External data buffer contains one instance of virtchnl_rxq_info.
301ceebc2f3SEric Joyner  * PF configures requested queue and returns a status code.
302ceebc2f3SEric Joyner  */
303ceebc2f3SEric Joyner 
304ceebc2f3SEric Joyner /* Rx queue config info */
305ceebc2f3SEric Joyner struct virtchnl_rxq_info {
306ceebc2f3SEric Joyner 	u16 vsi_id;
307ceebc2f3SEric Joyner 	u16 queue_id;
308ceebc2f3SEric Joyner 	u32 ring_len;		/* number of descriptors, multiple of 32 */
309ceebc2f3SEric Joyner 	u16 hdr_size;
310ceebc2f3SEric Joyner 	u16 splithdr_enabled; /* deprecated with AVF 1.0 */
311ceebc2f3SEric Joyner 	u32 databuffer_size;
312ceebc2f3SEric Joyner 	u32 max_pkt_size;
313ceebc2f3SEric Joyner 	u32 pad1;
314ceebc2f3SEric Joyner 	u64 dma_ring_addr;
315ceebc2f3SEric Joyner 	enum virtchnl_rx_hsplit rx_split_pos; /* deprecated with AVF 1.0 */
316ceebc2f3SEric Joyner 	u32 pad2;
317ceebc2f3SEric Joyner };
318ceebc2f3SEric Joyner 
319ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_rxq_info);
320ceebc2f3SEric Joyner 
321ceebc2f3SEric Joyner /* VIRTCHNL_OP_CONFIG_VSI_QUEUES
322ceebc2f3SEric Joyner  * VF sends this message to set parameters for all active TX and RX queues
323ceebc2f3SEric Joyner  * associated with the specified VSI.
324ceebc2f3SEric Joyner  * PF configures queues and returns status.
325ceebc2f3SEric Joyner  * If the number of queues specified is greater than the number of queues
326ceebc2f3SEric Joyner  * associated with the VSI, an error is returned and no queues are configured.
327ceebc2f3SEric Joyner  */
328ceebc2f3SEric Joyner struct virtchnl_queue_pair_info {
329ceebc2f3SEric Joyner 	/* NOTE: vsi_id and queue_id should be identical for both queues. */
330ceebc2f3SEric Joyner 	struct virtchnl_txq_info txq;
331ceebc2f3SEric Joyner 	struct virtchnl_rxq_info rxq;
332ceebc2f3SEric Joyner };
333ceebc2f3SEric Joyner 
334ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(64, virtchnl_queue_pair_info);
335ceebc2f3SEric Joyner 
336ceebc2f3SEric Joyner struct virtchnl_vsi_queue_config_info {
337ceebc2f3SEric Joyner 	u16 vsi_id;
338ceebc2f3SEric Joyner 	u16 num_queue_pairs;
339ceebc2f3SEric Joyner 	u32 pad;
340ceebc2f3SEric Joyner 	struct virtchnl_queue_pair_info qpair[1];
341ceebc2f3SEric Joyner };
342ceebc2f3SEric Joyner 
343ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_vsi_queue_config_info);
344ceebc2f3SEric Joyner 
345ceebc2f3SEric Joyner /* VIRTCHNL_OP_REQUEST_QUEUES
346ceebc2f3SEric Joyner  * VF sends this message to request the PF to allocate additional queues to
347ceebc2f3SEric Joyner  * this VF.  Each VF gets a guaranteed number of queues on init but asking for
348ceebc2f3SEric Joyner  * additional queues must be negotiated.  This is a best effort request as it
349ceebc2f3SEric Joyner  * is possible the PF does not have enough queues left to support the request.
350ceebc2f3SEric Joyner  * If the PF cannot support the number requested it will respond with the
351ceebc2f3SEric Joyner  * maximum number it is able to support; otherwise it will respond with the
352ceebc2f3SEric Joyner  * number requested.
353ceebc2f3SEric Joyner  */
354ceebc2f3SEric Joyner 
355ceebc2f3SEric Joyner /* VF resource request */
356ceebc2f3SEric Joyner struct virtchnl_vf_res_request {
357ceebc2f3SEric Joyner 	u16 num_queue_pairs;
358ceebc2f3SEric Joyner };
359ceebc2f3SEric Joyner 
360ceebc2f3SEric Joyner /* VIRTCHNL_OP_CONFIG_IRQ_MAP
361ceebc2f3SEric Joyner  * VF uses this message to map vectors to queues.
362ceebc2f3SEric Joyner  * The rxq_map and txq_map fields are bitmaps used to indicate which queues
363ceebc2f3SEric Joyner  * are to be associated with the specified vector.
364ceebc2f3SEric Joyner  * The "other" causes are always mapped to vector 0.
365ceebc2f3SEric Joyner  * PF configures interrupt mapping and returns status.
366ceebc2f3SEric Joyner  */
367ceebc2f3SEric Joyner struct virtchnl_vector_map {
368ceebc2f3SEric Joyner 	u16 vsi_id;
369ceebc2f3SEric Joyner 	u16 vector_id;
370ceebc2f3SEric Joyner 	u16 rxq_map;
371ceebc2f3SEric Joyner 	u16 txq_map;
372ceebc2f3SEric Joyner 	u16 rxitr_idx;
373ceebc2f3SEric Joyner 	u16 txitr_idx;
374ceebc2f3SEric Joyner };
375ceebc2f3SEric Joyner 
376ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_vector_map);
377ceebc2f3SEric Joyner 
378ceebc2f3SEric Joyner struct virtchnl_irq_map_info {
379ceebc2f3SEric Joyner 	u16 num_vectors;
380ceebc2f3SEric Joyner 	struct virtchnl_vector_map vecmap[1];
381ceebc2f3SEric Joyner };
382ceebc2f3SEric Joyner 
383ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(14, virtchnl_irq_map_info);
384ceebc2f3SEric Joyner 
385ceebc2f3SEric Joyner /* VIRTCHNL_OP_ENABLE_QUEUES
386ceebc2f3SEric Joyner  * VIRTCHNL_OP_DISABLE_QUEUES
387ceebc2f3SEric Joyner  * VF sends these message to enable or disable TX/RX queue pairs.
388ceebc2f3SEric Joyner  * The queues fields are bitmaps indicating which queues to act upon.
389ceebc2f3SEric Joyner  * (Currently, we only support 16 queues per VF, but we make the field
390ceebc2f3SEric Joyner  * u32 to allow for expansion.)
391ceebc2f3SEric Joyner  * PF performs requested action and returns status.
392ceebc2f3SEric Joyner  */
393ceebc2f3SEric Joyner struct virtchnl_queue_select {
394ceebc2f3SEric Joyner 	u16 vsi_id;
395ceebc2f3SEric Joyner 	u16 pad;
396ceebc2f3SEric Joyner 	u32 rx_queues;
397ceebc2f3SEric Joyner 	u32 tx_queues;
398ceebc2f3SEric Joyner };
399ceebc2f3SEric Joyner 
400ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_queue_select);
401ceebc2f3SEric Joyner 
402ceebc2f3SEric Joyner /* VIRTCHNL_OP_ADD_ETH_ADDR
403ceebc2f3SEric Joyner  * VF sends this message in order to add one or more unicast or multicast
404ceebc2f3SEric Joyner  * address filters for the specified VSI.
405ceebc2f3SEric Joyner  * PF adds the filters and returns status.
406ceebc2f3SEric Joyner  */
407ceebc2f3SEric Joyner 
408ceebc2f3SEric Joyner /* VIRTCHNL_OP_DEL_ETH_ADDR
409ceebc2f3SEric Joyner  * VF sends this message in order to remove one or more unicast or multicast
410ceebc2f3SEric Joyner  * filters for the specified VSI.
411ceebc2f3SEric Joyner  * PF removes the filters and returns status.
412ceebc2f3SEric Joyner  */
413ceebc2f3SEric Joyner 
414ceebc2f3SEric Joyner struct virtchnl_ether_addr {
415ceebc2f3SEric Joyner 	u8 addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS];
416ceebc2f3SEric Joyner 	u8 pad[2];
417ceebc2f3SEric Joyner };
418ceebc2f3SEric Joyner 
419ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr);
420ceebc2f3SEric Joyner 
421ceebc2f3SEric Joyner struct virtchnl_ether_addr_list {
422ceebc2f3SEric Joyner 	u16 vsi_id;
423ceebc2f3SEric Joyner 	u16 num_elements;
424ceebc2f3SEric Joyner 	struct virtchnl_ether_addr list[1];
425ceebc2f3SEric Joyner };
426ceebc2f3SEric Joyner 
427ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_ether_addr_list);
428ceebc2f3SEric Joyner 
429ceebc2f3SEric Joyner /* VIRTCHNL_OP_ADD_VLAN
430ceebc2f3SEric Joyner  * VF sends this message to add one or more VLAN tag filters for receives.
431ceebc2f3SEric Joyner  * PF adds the filters and returns status.
432ceebc2f3SEric Joyner  * If a port VLAN is configured by the PF, this operation will return an
433ceebc2f3SEric Joyner  * error to the VF.
434ceebc2f3SEric Joyner  */
435ceebc2f3SEric Joyner 
436ceebc2f3SEric Joyner /* VIRTCHNL_OP_DEL_VLAN
437ceebc2f3SEric Joyner  * VF sends this message to remove one or more VLAN tag filters for receives.
438ceebc2f3SEric Joyner  * PF removes the filters and returns status.
439ceebc2f3SEric Joyner  * If a port VLAN is configured by the PF, this operation will return an
440ceebc2f3SEric Joyner  * error to the VF.
441ceebc2f3SEric Joyner  */
442ceebc2f3SEric Joyner 
443ceebc2f3SEric Joyner struct virtchnl_vlan_filter_list {
444ceebc2f3SEric Joyner 	u16 vsi_id;
445ceebc2f3SEric Joyner 	u16 num_elements;
446ceebc2f3SEric Joyner 	u16 vlan_id[1];
447ceebc2f3SEric Joyner };
448ceebc2f3SEric Joyner 
449ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_vlan_filter_list);
450ceebc2f3SEric Joyner 
451ceebc2f3SEric Joyner /* VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE
452ceebc2f3SEric Joyner  * VF sends VSI id and flags.
453ceebc2f3SEric Joyner  * PF returns status code in retval.
454ceebc2f3SEric Joyner  * Note: we assume that broadcast accept mode is always enabled.
455ceebc2f3SEric Joyner  */
456ceebc2f3SEric Joyner struct virtchnl_promisc_info {
457ceebc2f3SEric Joyner 	u16 vsi_id;
458ceebc2f3SEric Joyner 	u16 flags;
459ceebc2f3SEric Joyner };
460ceebc2f3SEric Joyner 
461ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_promisc_info);
462ceebc2f3SEric Joyner 
463ceebc2f3SEric Joyner #define FLAG_VF_UNICAST_PROMISC	0x00000001
464ceebc2f3SEric Joyner #define FLAG_VF_MULTICAST_PROMISC	0x00000002
465ceebc2f3SEric Joyner 
466ceebc2f3SEric Joyner /* VIRTCHNL_OP_GET_STATS
467ceebc2f3SEric Joyner  * VF sends this message to request stats for the selected VSI. VF uses
468ceebc2f3SEric Joyner  * the virtchnl_queue_select struct to specify the VSI. The queue_id
469ceebc2f3SEric Joyner  * field is ignored by the PF.
470ceebc2f3SEric Joyner  *
471ceebc2f3SEric Joyner  * PF replies with struct eth_stats in an external buffer.
472ceebc2f3SEric Joyner  */
473ceebc2f3SEric Joyner 
474ceebc2f3SEric Joyner /* VIRTCHNL_OP_CONFIG_RSS_KEY
475ceebc2f3SEric Joyner  * VIRTCHNL_OP_CONFIG_RSS_LUT
476ceebc2f3SEric Joyner  * VF sends these messages to configure RSS. Only supported if both PF
477ceebc2f3SEric Joyner  * and VF drivers set the VIRTCHNL_VF_OFFLOAD_RSS_PF bit during
478ceebc2f3SEric Joyner  * configuration negotiation. If this is the case, then the RSS fields in
479ceebc2f3SEric Joyner  * the VF resource struct are valid.
480ceebc2f3SEric Joyner  * Both the key and LUT are initialized to 0 by the PF, meaning that
481ceebc2f3SEric Joyner  * RSS is effectively disabled until set up by the VF.
482ceebc2f3SEric Joyner  */
483ceebc2f3SEric Joyner struct virtchnl_rss_key {
484ceebc2f3SEric Joyner 	u16 vsi_id;
485ceebc2f3SEric Joyner 	u16 key_len;
486ceebc2f3SEric Joyner 	u8 key[1];         /* RSS hash key, packed bytes */
487ceebc2f3SEric Joyner };
488ceebc2f3SEric Joyner 
489ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_key);
490ceebc2f3SEric Joyner 
491ceebc2f3SEric Joyner struct virtchnl_rss_lut {
492ceebc2f3SEric Joyner 	u16 vsi_id;
493ceebc2f3SEric Joyner 	u16 lut_entries;
494ceebc2f3SEric Joyner 	u8 lut[1];        /* RSS lookup table */
495ceebc2f3SEric Joyner };
496ceebc2f3SEric Joyner 
497ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_lut);
498ceebc2f3SEric Joyner 
499ceebc2f3SEric Joyner /* VIRTCHNL_OP_GET_RSS_HENA_CAPS
500ceebc2f3SEric Joyner  * VIRTCHNL_OP_SET_RSS_HENA
501ceebc2f3SEric Joyner  * VF sends these messages to get and set the hash filter enable bits for RSS.
502ceebc2f3SEric Joyner  * By default, the PF sets these to all possible traffic types that the
503ceebc2f3SEric Joyner  * hardware supports. The VF can query this value if it wants to change the
504ceebc2f3SEric Joyner  * traffic types that are hashed by the hardware.
505ceebc2f3SEric Joyner  */
506ceebc2f3SEric Joyner struct virtchnl_rss_hena {
507ceebc2f3SEric Joyner 	u64 hena;
508ceebc2f3SEric Joyner };
509ceebc2f3SEric Joyner 
510ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena);
511ceebc2f3SEric Joyner 
512ceebc2f3SEric Joyner /* VIRTCHNL_OP_EVENT
513ceebc2f3SEric Joyner  * PF sends this message to inform the VF driver of events that may affect it.
514ceebc2f3SEric Joyner  * No direct response is expected from the VF, though it may generate other
515ceebc2f3SEric Joyner  * messages in response to this one.
516ceebc2f3SEric Joyner  */
517ceebc2f3SEric Joyner enum virtchnl_event_codes {
518ceebc2f3SEric Joyner 	VIRTCHNL_EVENT_UNKNOWN = 0,
519ceebc2f3SEric Joyner 	VIRTCHNL_EVENT_LINK_CHANGE,
520ceebc2f3SEric Joyner 	VIRTCHNL_EVENT_RESET_IMPENDING,
521ceebc2f3SEric Joyner 	VIRTCHNL_EVENT_PF_DRIVER_CLOSE,
522ceebc2f3SEric Joyner };
523ceebc2f3SEric Joyner 
524ceebc2f3SEric Joyner #define PF_EVENT_SEVERITY_INFO		0
525ceebc2f3SEric Joyner #define PF_EVENT_SEVERITY_ATTENTION	1
526ceebc2f3SEric Joyner #define PF_EVENT_SEVERITY_ACTION_REQUIRED	2
527ceebc2f3SEric Joyner #define PF_EVENT_SEVERITY_CERTAIN_DOOM	255
528ceebc2f3SEric Joyner 
529ceebc2f3SEric Joyner struct virtchnl_pf_event {
530ceebc2f3SEric Joyner 	enum virtchnl_event_codes event;
531ceebc2f3SEric Joyner 	union {
532ceebc2f3SEric Joyner 		struct {
533ceebc2f3SEric Joyner 			enum virtchnl_link_speed link_speed;
534ceebc2f3SEric Joyner 			bool link_status;
535ceebc2f3SEric Joyner 		} link_event;
536ceebc2f3SEric Joyner 	} event_data;
537ceebc2f3SEric Joyner 
538ceebc2f3SEric Joyner 	int severity;
539ceebc2f3SEric Joyner };
540ceebc2f3SEric Joyner 
541ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_pf_event);
542ceebc2f3SEric Joyner 
543ceebc2f3SEric Joyner 
544ceebc2f3SEric Joyner /* VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP
545ceebc2f3SEric Joyner  * VF uses this message to request PF to map IWARP vectors to IWARP queues.
546ceebc2f3SEric Joyner  * The request for this originates from the VF IWARP driver through
547ceebc2f3SEric Joyner  * a client interface between VF LAN and VF IWARP driver.
548ceebc2f3SEric Joyner  * A vector could have an AEQ and CEQ attached to it although
549ceebc2f3SEric Joyner  * there is a single AEQ per VF IWARP instance in which case
550ceebc2f3SEric Joyner  * most vectors will have an INVALID_IDX for aeq and valid idx for ceq.
551ceebc2f3SEric Joyner  * There will never be a case where there will be multiple CEQs attached
552ceebc2f3SEric Joyner  * to a single vector.
553ceebc2f3SEric Joyner  * PF configures interrupt mapping and returns status.
554ceebc2f3SEric Joyner  */
555ceebc2f3SEric Joyner 
556ceebc2f3SEric Joyner /* HW does not define a type value for AEQ; only for RX/TX and CEQ.
557ceebc2f3SEric Joyner  * In order for us to keep the interface simple, SW will define a
558ceebc2f3SEric Joyner  * unique type value for AEQ.
559ceebc2f3SEric Joyner  */
560ceebc2f3SEric Joyner #define QUEUE_TYPE_PE_AEQ  0x80
561ceebc2f3SEric Joyner #define QUEUE_INVALID_IDX  0xFFFF
562ceebc2f3SEric Joyner 
563ceebc2f3SEric Joyner struct virtchnl_iwarp_qv_info {
564ceebc2f3SEric Joyner 	u32 v_idx; /* msix_vector */
565ceebc2f3SEric Joyner 	u16 ceq_idx;
566ceebc2f3SEric Joyner 	u16 aeq_idx;
567ceebc2f3SEric Joyner 	u8 itr_idx;
568ceebc2f3SEric Joyner };
569ceebc2f3SEric Joyner 
570ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_iwarp_qv_info);
571ceebc2f3SEric Joyner 
572ceebc2f3SEric Joyner struct virtchnl_iwarp_qvlist_info {
573ceebc2f3SEric Joyner 	u32 num_vectors;
574ceebc2f3SEric Joyner 	struct virtchnl_iwarp_qv_info qv_info[1];
575ceebc2f3SEric Joyner };
576ceebc2f3SEric Joyner 
577ceebc2f3SEric Joyner VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_iwarp_qvlist_info);
578ceebc2f3SEric Joyner 
579ceebc2f3SEric Joyner 
580ceebc2f3SEric Joyner /* VF reset states - these are written into the RSTAT register:
581ceebc2f3SEric Joyner  * VFGEN_RSTAT on the VF
582ceebc2f3SEric Joyner  * When the PF initiates a reset, it writes 0
583ceebc2f3SEric Joyner  * When the reset is complete, it writes 1
584ceebc2f3SEric Joyner  * When the PF detects that the VF has recovered, it writes 2
585ceebc2f3SEric Joyner  * VF checks this register periodically to determine if a reset has occurred,
586ceebc2f3SEric Joyner  * then polls it to know when the reset is complete.
587ceebc2f3SEric Joyner  * If either the PF or VF reads the register while the hardware
588ceebc2f3SEric Joyner  * is in a reset state, it will return DEADBEEF, which, when masked
589ceebc2f3SEric Joyner  * will result in 3.
590ceebc2f3SEric Joyner  */
591ceebc2f3SEric Joyner enum virtchnl_vfr_states {
592ceebc2f3SEric Joyner 	VIRTCHNL_VFR_INPROGRESS = 0,
593ceebc2f3SEric Joyner 	VIRTCHNL_VFR_COMPLETED,
594ceebc2f3SEric Joyner 	VIRTCHNL_VFR_VFACTIVE,
595ceebc2f3SEric Joyner };
596ceebc2f3SEric Joyner 
597ceebc2f3SEric Joyner /**
598ceebc2f3SEric Joyner  * virtchnl_vc_validate_vf_msg
599ceebc2f3SEric Joyner  * @ver: Virtchnl version info
600ceebc2f3SEric Joyner  * @v_opcode: Opcode for the message
601ceebc2f3SEric Joyner  * @msg: pointer to the msg buffer
602ceebc2f3SEric Joyner  * @msglen: msg length
603ceebc2f3SEric Joyner  *
604ceebc2f3SEric Joyner  * validate msg format against struct for each opcode
605ceebc2f3SEric Joyner  */
606ceebc2f3SEric Joyner static inline int
virtchnl_vc_validate_vf_msg(struct virtchnl_version_info * ver,u32 v_opcode,u8 * msg,u16 msglen)607ceebc2f3SEric Joyner virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
608ceebc2f3SEric Joyner 			    u8 *msg, u16 msglen)
609ceebc2f3SEric Joyner {
610ceebc2f3SEric Joyner 	bool err_msg_format = FALSE;
611ceebc2f3SEric Joyner 	int valid_len = 0;
612ceebc2f3SEric Joyner 
613ceebc2f3SEric Joyner 	/* Validate message length. */
614ceebc2f3SEric Joyner 	switch (v_opcode) {
615ceebc2f3SEric Joyner 	case VIRTCHNL_OP_VERSION:
616ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_version_info);
617ceebc2f3SEric Joyner 		break;
618ceebc2f3SEric Joyner 	case VIRTCHNL_OP_RESET_VF:
619ceebc2f3SEric Joyner 		break;
620ceebc2f3SEric Joyner 	case VIRTCHNL_OP_GET_VF_RESOURCES:
621ceebc2f3SEric Joyner 		if (VF_IS_V11(ver))
622ceebc2f3SEric Joyner 			valid_len = sizeof(u32);
623ceebc2f3SEric Joyner 		break;
624ceebc2f3SEric Joyner 	case VIRTCHNL_OP_CONFIG_TX_QUEUE:
625ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_txq_info);
626ceebc2f3SEric Joyner 		break;
627ceebc2f3SEric Joyner 	case VIRTCHNL_OP_CONFIG_RX_QUEUE:
628ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_rxq_info);
629ceebc2f3SEric Joyner 		break;
630ceebc2f3SEric Joyner 	case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
631ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_vsi_queue_config_info);
632ceebc2f3SEric Joyner 		if (msglen >= valid_len) {
633ceebc2f3SEric Joyner 			struct virtchnl_vsi_queue_config_info *vqc =
634ceebc2f3SEric Joyner 			    (struct virtchnl_vsi_queue_config_info *)msg;
635ceebc2f3SEric Joyner 			valid_len += (vqc->num_queue_pairs *
636ceebc2f3SEric Joyner 				      sizeof(struct
637ceebc2f3SEric Joyner 					     virtchnl_queue_pair_info));
638ceebc2f3SEric Joyner 			if (vqc->num_queue_pairs == 0)
639ceebc2f3SEric Joyner 				err_msg_format = TRUE;
640ceebc2f3SEric Joyner 		}
641ceebc2f3SEric Joyner 		break;
642ceebc2f3SEric Joyner 	case VIRTCHNL_OP_CONFIG_IRQ_MAP:
643ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_irq_map_info);
644ceebc2f3SEric Joyner 		if (msglen >= valid_len) {
645ceebc2f3SEric Joyner 			struct virtchnl_irq_map_info *vimi =
646ceebc2f3SEric Joyner 			    (struct virtchnl_irq_map_info *)msg;
647ceebc2f3SEric Joyner 			valid_len += (vimi->num_vectors *
648ceebc2f3SEric Joyner 				      sizeof(struct virtchnl_vector_map));
649ceebc2f3SEric Joyner 			if (vimi->num_vectors == 0)
650ceebc2f3SEric Joyner 				err_msg_format = TRUE;
651ceebc2f3SEric Joyner 		}
652ceebc2f3SEric Joyner 		break;
653ceebc2f3SEric Joyner 	case VIRTCHNL_OP_ENABLE_QUEUES:
654ceebc2f3SEric Joyner 	case VIRTCHNL_OP_DISABLE_QUEUES:
655ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_queue_select);
656ceebc2f3SEric Joyner 		break;
657ceebc2f3SEric Joyner 	case VIRTCHNL_OP_ADD_ETH_ADDR:
658ceebc2f3SEric Joyner 	case VIRTCHNL_OP_DEL_ETH_ADDR:
659ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_ether_addr_list);
660ceebc2f3SEric Joyner 		if (msglen >= valid_len) {
661ceebc2f3SEric Joyner 			struct virtchnl_ether_addr_list *veal =
662ceebc2f3SEric Joyner 			    (struct virtchnl_ether_addr_list *)msg;
663ceebc2f3SEric Joyner 			valid_len += veal->num_elements *
664ceebc2f3SEric Joyner 			    sizeof(struct virtchnl_ether_addr);
665ceebc2f3SEric Joyner 			if (veal->num_elements == 0)
666ceebc2f3SEric Joyner 				err_msg_format = TRUE;
667ceebc2f3SEric Joyner 		}
668ceebc2f3SEric Joyner 		break;
669ceebc2f3SEric Joyner 	case VIRTCHNL_OP_ADD_VLAN:
670ceebc2f3SEric Joyner 	case VIRTCHNL_OP_DEL_VLAN:
671ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_vlan_filter_list);
672ceebc2f3SEric Joyner 		if (msglen >= valid_len) {
673ceebc2f3SEric Joyner 			struct virtchnl_vlan_filter_list *vfl =
674ceebc2f3SEric Joyner 			    (struct virtchnl_vlan_filter_list *)msg;
675ceebc2f3SEric Joyner 			valid_len += vfl->num_elements * sizeof(u16);
676ceebc2f3SEric Joyner 			if (vfl->num_elements == 0)
677ceebc2f3SEric Joyner 				err_msg_format = TRUE;
678ceebc2f3SEric Joyner 		}
679ceebc2f3SEric Joyner 		break;
680ceebc2f3SEric Joyner 	case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
681ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_promisc_info);
682ceebc2f3SEric Joyner 		break;
683ceebc2f3SEric Joyner 	case VIRTCHNL_OP_GET_STATS:
684ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_queue_select);
685ceebc2f3SEric Joyner 		break;
686ceebc2f3SEric Joyner 	case VIRTCHNL_OP_IWARP:
687ceebc2f3SEric Joyner 		/* These messages are opaque to us and will be validated in
688ceebc2f3SEric Joyner 		 * the RDMA client code. We just need to check for nonzero
689ceebc2f3SEric Joyner 		 * length. The firmware will enforce max length restrictions.
690ceebc2f3SEric Joyner 		 */
691ceebc2f3SEric Joyner 		if (msglen)
692ceebc2f3SEric Joyner 			valid_len = msglen;
693ceebc2f3SEric Joyner 		else
694ceebc2f3SEric Joyner 			err_msg_format = TRUE;
695ceebc2f3SEric Joyner 		break;
696ceebc2f3SEric Joyner 	case VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP:
697ceebc2f3SEric Joyner 		break;
698ceebc2f3SEric Joyner 	case VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP:
699ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_iwarp_qvlist_info);
700ceebc2f3SEric Joyner 		if (msglen >= valid_len) {
701ceebc2f3SEric Joyner 			struct virtchnl_iwarp_qvlist_info *qv =
702ceebc2f3SEric Joyner 				(struct virtchnl_iwarp_qvlist_info *)msg;
703ceebc2f3SEric Joyner 			if (qv->num_vectors == 0) {
704ceebc2f3SEric Joyner 				err_msg_format = TRUE;
705ceebc2f3SEric Joyner 				break;
706ceebc2f3SEric Joyner 			}
707ceebc2f3SEric Joyner 			valid_len += ((qv->num_vectors - 1) *
708ceebc2f3SEric Joyner 				sizeof(struct virtchnl_iwarp_qv_info));
709ceebc2f3SEric Joyner 		}
710ceebc2f3SEric Joyner 		break;
711ceebc2f3SEric Joyner 	case VIRTCHNL_OP_CONFIG_RSS_KEY:
712ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_rss_key);
713ceebc2f3SEric Joyner 		if (msglen >= valid_len) {
714ceebc2f3SEric Joyner 			struct virtchnl_rss_key *vrk =
715ceebc2f3SEric Joyner 				(struct virtchnl_rss_key *)msg;
716ceebc2f3SEric Joyner 			valid_len += vrk->key_len - 1;
717ceebc2f3SEric Joyner 		}
718ceebc2f3SEric Joyner 		break;
719ceebc2f3SEric Joyner 	case VIRTCHNL_OP_CONFIG_RSS_LUT:
720ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_rss_lut);
721ceebc2f3SEric Joyner 		if (msglen >= valid_len) {
722ceebc2f3SEric Joyner 			struct virtchnl_rss_lut *vrl =
723ceebc2f3SEric Joyner 				(struct virtchnl_rss_lut *)msg;
724ceebc2f3SEric Joyner 			valid_len += vrl->lut_entries - 1;
725ceebc2f3SEric Joyner 		}
726ceebc2f3SEric Joyner 		break;
727ceebc2f3SEric Joyner 	case VIRTCHNL_OP_GET_RSS_HENA_CAPS:
728ceebc2f3SEric Joyner 		break;
729ceebc2f3SEric Joyner 	case VIRTCHNL_OP_SET_RSS_HENA:
730ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_rss_hena);
731ceebc2f3SEric Joyner 		break;
732ceebc2f3SEric Joyner 	case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
733ceebc2f3SEric Joyner 	case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
734ceebc2f3SEric Joyner 		break;
735ceebc2f3SEric Joyner 	case VIRTCHNL_OP_REQUEST_QUEUES:
736ceebc2f3SEric Joyner 		valid_len = sizeof(struct virtchnl_vf_res_request);
737ceebc2f3SEric Joyner 		break;
738ceebc2f3SEric Joyner 	/* These are always errors coming from the VF. */
739ceebc2f3SEric Joyner 	case VIRTCHNL_OP_EVENT:
740ceebc2f3SEric Joyner 	case VIRTCHNL_OP_UNKNOWN:
741ceebc2f3SEric Joyner 	default:
742ceebc2f3SEric Joyner 		return VIRTCHNL_ERR_PARAM;
743ceebc2f3SEric Joyner 	}
744ceebc2f3SEric Joyner 	/* few more checks */
745ceebc2f3SEric Joyner 	if (err_msg_format || valid_len != msglen)
746ceebc2f3SEric Joyner 		return VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH;
747ceebc2f3SEric Joyner 
748ceebc2f3SEric Joyner 	return 0;
749ceebc2f3SEric Joyner }
750ceebc2f3SEric Joyner #endif /* _VIRTCHNL_H_ */
751