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