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