]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2001-2020 Intel Corporation | |
3 | */ | |
11fdf7f2 TL |
4 | |
5 | #ifndef _VIRTCHNL_H_ | |
6 | #define _VIRTCHNL_H_ | |
7 | ||
8 | /* Description: | |
9 | * This header file describes the VF-PF communication protocol used | |
10 | * by the drivers for all devices starting from our 40G product line | |
11 | * | |
12 | * Admin queue buffer usage: | |
13 | * desc->opcode is always aqc_opc_send_msg_to_pf | |
14 | * flags, retval, datalen, and data addr are all used normally. | |
15 | * The Firmware copies the cookie fields when sending messages between the | |
16 | * PF and VF, but uses all other fields internally. Due to this limitation, | |
17 | * we must send all messages as "indirect", i.e. using an external buffer. | |
18 | * | |
19 | * All the VSI indexes are relative to the VF. Each VF can have maximum of | |
20 | * three VSIs. All the queue indexes are relative to the VSI. Each VF can | |
21 | * have a maximum of sixteen queues for all of its VSIs. | |
22 | * | |
23 | * The PF is required to return a status code in v_retval for all messages | |
24 | * except RESET_VF, which does not require any response. The return value | |
25 | * is of status_code type, defined in the shared type.h. | |
26 | * | |
27 | * In general, VF driver initialization should roughly follow the order of | |
28 | * these opcodes. The VF driver must first validate the API version of the | |
29 | * PF driver, then request a reset, then get resources, then configure | |
30 | * queues and interrupts. After these operations are complete, the VF | |
31 | * driver may start its queues, optionally add MAC and VLAN filters, and | |
32 | * process traffic. | |
33 | */ | |
34 | ||
35 | /* START GENERIC DEFINES | |
36 | * Need to ensure the following enums and defines hold the same meaning and | |
37 | * value in current and future projects | |
38 | */ | |
39 | ||
40 | /* Error Codes */ | |
41 | enum virtchnl_status_code { | |
42 | VIRTCHNL_STATUS_SUCCESS = 0, | |
f67539c2 TL |
43 | VIRTCHNL_STATUS_ERR_PARAM = -5, |
44 | VIRTCHNL_STATUS_ERR_NO_MEMORY = -18, | |
11fdf7f2 TL |
45 | VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH = -38, |
46 | VIRTCHNL_STATUS_ERR_CQP_COMPL_ERROR = -39, | |
47 | VIRTCHNL_STATUS_ERR_INVALID_VF_ID = -40, | |
f67539c2 TL |
48 | VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR = -53, |
49 | VIRTCHNL_STATUS_ERR_NOT_SUPPORTED = -64, | |
11fdf7f2 TL |
50 | }; |
51 | ||
f67539c2 TL |
52 | /* Backward compatibility */ |
53 | #define VIRTCHNL_ERR_PARAM VIRTCHNL_STATUS_ERR_PARAM | |
54 | #define VIRTCHNL_STATUS_NOT_SUPPORTED VIRTCHNL_STATUS_ERR_NOT_SUPPORTED | |
55 | ||
56 | #define VIRTCHNL_LINK_SPEED_2_5GB_SHIFT 0x0 | |
11fdf7f2 TL |
57 | #define VIRTCHNL_LINK_SPEED_100MB_SHIFT 0x1 |
58 | #define VIRTCHNL_LINK_SPEED_1000MB_SHIFT 0x2 | |
59 | #define VIRTCHNL_LINK_SPEED_10GB_SHIFT 0x3 | |
60 | #define VIRTCHNL_LINK_SPEED_40GB_SHIFT 0x4 | |
61 | #define VIRTCHNL_LINK_SPEED_20GB_SHIFT 0x5 | |
62 | #define VIRTCHNL_LINK_SPEED_25GB_SHIFT 0x6 | |
f67539c2 | 63 | #define VIRTCHNL_LINK_SPEED_5GB_SHIFT 0x7 |
11fdf7f2 TL |
64 | |
65 | enum virtchnl_link_speed { | |
66 | VIRTCHNL_LINK_SPEED_UNKNOWN = 0, | |
67 | VIRTCHNL_LINK_SPEED_100MB = BIT(VIRTCHNL_LINK_SPEED_100MB_SHIFT), | |
68 | VIRTCHNL_LINK_SPEED_1GB = BIT(VIRTCHNL_LINK_SPEED_1000MB_SHIFT), | |
69 | VIRTCHNL_LINK_SPEED_10GB = BIT(VIRTCHNL_LINK_SPEED_10GB_SHIFT), | |
70 | VIRTCHNL_LINK_SPEED_40GB = BIT(VIRTCHNL_LINK_SPEED_40GB_SHIFT), | |
71 | VIRTCHNL_LINK_SPEED_20GB = BIT(VIRTCHNL_LINK_SPEED_20GB_SHIFT), | |
72 | VIRTCHNL_LINK_SPEED_25GB = BIT(VIRTCHNL_LINK_SPEED_25GB_SHIFT), | |
f67539c2 TL |
73 | VIRTCHNL_LINK_SPEED_2_5GB = BIT(VIRTCHNL_LINK_SPEED_2_5GB_SHIFT), |
74 | VIRTCHNL_LINK_SPEED_5GB = BIT(VIRTCHNL_LINK_SPEED_5GB_SHIFT), | |
11fdf7f2 TL |
75 | }; |
76 | ||
77 | /* for hsplit_0 field of Rx HMC context */ | |
9f95a23c | 78 | /* deprecated with IAVF 1.0 */ |
11fdf7f2 TL |
79 | enum virtchnl_rx_hsplit { |
80 | VIRTCHNL_RX_HSPLIT_NO_SPLIT = 0, | |
81 | VIRTCHNL_RX_HSPLIT_SPLIT_L2 = 1, | |
82 | VIRTCHNL_RX_HSPLIT_SPLIT_IP = 2, | |
83 | VIRTCHNL_RX_HSPLIT_SPLIT_TCP_UDP = 4, | |
84 | VIRTCHNL_RX_HSPLIT_SPLIT_SCTP = 8, | |
85 | }; | |
86 | ||
87 | #define VIRTCHNL_ETH_LENGTH_OF_ADDRESS 6 | |
88 | /* END GENERIC DEFINES */ | |
89 | ||
90 | /* Opcodes for VF-PF communication. These are placed in the v_opcode field | |
91 | * of the virtchnl_msg structure. | |
92 | */ | |
93 | enum virtchnl_ops { | |
94 | /* The PF sends status change events to VFs using | |
95 | * the VIRTCHNL_OP_EVENT opcode. | |
96 | * VFs send requests to the PF using the other ops. | |
97 | * Use of "advanced opcode" features must be negotiated as part of capabilities | |
98 | * exchange and are not considered part of base mode feature set. | |
99 | */ | |
100 | VIRTCHNL_OP_UNKNOWN = 0, | |
101 | VIRTCHNL_OP_VERSION = 1, /* must ALWAYS be 1 */ | |
102 | VIRTCHNL_OP_RESET_VF = 2, | |
103 | VIRTCHNL_OP_GET_VF_RESOURCES = 3, | |
104 | VIRTCHNL_OP_CONFIG_TX_QUEUE = 4, | |
105 | VIRTCHNL_OP_CONFIG_RX_QUEUE = 5, | |
106 | VIRTCHNL_OP_CONFIG_VSI_QUEUES = 6, | |
107 | VIRTCHNL_OP_CONFIG_IRQ_MAP = 7, | |
108 | VIRTCHNL_OP_ENABLE_QUEUES = 8, | |
109 | VIRTCHNL_OP_DISABLE_QUEUES = 9, | |
110 | VIRTCHNL_OP_ADD_ETH_ADDR = 10, | |
111 | VIRTCHNL_OP_DEL_ETH_ADDR = 11, | |
112 | VIRTCHNL_OP_ADD_VLAN = 12, | |
113 | VIRTCHNL_OP_DEL_VLAN = 13, | |
114 | VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE = 14, | |
115 | VIRTCHNL_OP_GET_STATS = 15, | |
116 | VIRTCHNL_OP_RSVD = 16, | |
117 | VIRTCHNL_OP_EVENT = 17, /* must ALWAYS be 17 */ | |
f67539c2 TL |
118 | /* opcode 19 is reserved */ |
119 | /* opcodes 20, 21, and 22 are reserved */ | |
11fdf7f2 TL |
120 | VIRTCHNL_OP_CONFIG_RSS_KEY = 23, |
121 | VIRTCHNL_OP_CONFIG_RSS_LUT = 24, | |
122 | VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25, | |
123 | VIRTCHNL_OP_SET_RSS_HENA = 26, | |
124 | VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27, | |
125 | VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28, | |
126 | VIRTCHNL_OP_REQUEST_QUEUES = 29, | |
f67539c2 TL |
127 | VIRTCHNL_OP_ENABLE_CHANNELS = 30, |
128 | VIRTCHNL_OP_DISABLE_CHANNELS = 31, | |
129 | VIRTCHNL_OP_ADD_CLOUD_FILTER = 32, | |
130 | VIRTCHNL_OP_DEL_CLOUD_FILTER = 33, | |
131 | /* opcodes 34, 35, 36, 37 and 38 are reserved */ | |
132 | VIRTCHNL_OP_DCF_CMD_DESC = 39, | |
133 | VIRTCHNL_OP_DCF_CMD_BUFF = 40, | |
134 | VIRTCHNL_OP_DCF_DISABLE = 41, | |
135 | VIRTCHNL_OP_DCF_GET_VSI_MAP = 42, | |
136 | VIRTCHNL_OP_DCF_GET_PKG_INFO = 43, | |
137 | VIRTCHNL_OP_GET_SUPPORTED_RXDIDS = 44, | |
138 | VIRTCHNL_OP_ADD_RSS_CFG = 45, | |
139 | VIRTCHNL_OP_DEL_RSS_CFG = 46, | |
140 | VIRTCHNL_OP_ADD_FDIR_FILTER = 47, | |
141 | VIRTCHNL_OP_DEL_FDIR_FILTER = 48, | |
142 | VIRTCHNL_OP_QUERY_FDIR_FILTER = 49, | |
11fdf7f2 TL |
143 | }; |
144 | ||
f67539c2 | 145 | /* These macros are used to generate compilation errors if a structure/union |
11fdf7f2 | 146 | * is not exactly the correct length. It gives a divide by zero error if the |
f67539c2 TL |
147 | * structure/union is not of the correct size, otherwise it creates an enum |
148 | * that is never used. | |
11fdf7f2 TL |
149 | */ |
150 | #define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \ | |
f67539c2 TL |
151 | { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) } |
152 | #define VIRTCHNL_CHECK_UNION_LEN(n, X) enum virtchnl_static_asset_enum_##X \ | |
153 | { virtchnl_static_assert_##X = (n)/((sizeof(union X) == (n)) ? 1 : 0) } | |
11fdf7f2 TL |
154 | |
155 | /* Virtual channel message descriptor. This overlays the admin queue | |
156 | * descriptor. All other data is passed in external buffers. | |
157 | */ | |
158 | ||
159 | struct virtchnl_msg { | |
160 | u8 pad[8]; /* AQ flags/opcode/len/retval fields */ | |
161 | enum virtchnl_ops v_opcode; /* avoid confusion with desc->opcode */ | |
162 | enum virtchnl_status_code v_retval; /* ditto for desc->retval */ | |
163 | u32 vfid; /* used by PF when sending to VF */ | |
164 | }; | |
165 | ||
166 | VIRTCHNL_CHECK_STRUCT_LEN(20, virtchnl_msg); | |
167 | ||
f67539c2 | 168 | /* Message descriptions and data structures. */ |
11fdf7f2 TL |
169 | |
170 | /* VIRTCHNL_OP_VERSION | |
171 | * VF posts its version number to the PF. PF responds with its version number | |
172 | * in the same format, along with a return code. | |
173 | * Reply from PF has its major/minor versions also in param0 and param1. | |
174 | * If there is a major version mismatch, then the VF cannot operate. | |
175 | * If there is a minor version mismatch, then the VF can operate but should | |
176 | * add a warning to the system log. | |
177 | * | |
178 | * This enum element MUST always be specified as == 1, regardless of other | |
179 | * changes in the API. The PF must always respond to this message without | |
180 | * error regardless of version mismatch. | |
181 | */ | |
182 | #define VIRTCHNL_VERSION_MAJOR 1 | |
183 | #define VIRTCHNL_VERSION_MINOR 1 | |
184 | #define VIRTCHNL_VERSION_MINOR_NO_VF_CAPS 0 | |
185 | ||
186 | struct virtchnl_version_info { | |
187 | u32 major; | |
188 | u32 minor; | |
189 | }; | |
190 | ||
191 | VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_version_info); | |
192 | ||
193 | #define VF_IS_V10(_v) (((_v)->major == 1) && ((_v)->minor == 0)) | |
194 | #define VF_IS_V11(_ver) (((_ver)->major == 1) && ((_ver)->minor == 1)) | |
195 | ||
196 | /* VIRTCHNL_OP_RESET_VF | |
197 | * VF sends this request to PF with no parameters | |
198 | * PF does NOT respond! VF driver must delay then poll VFGEN_RSTAT register | |
199 | * until reset completion is indicated. The admin queue must be reinitialized | |
200 | * after this operation. | |
201 | * | |
202 | * When reset is complete, PF must ensure that all queues in all VSIs associated | |
203 | * with the VF are stopped, all queue configurations in the HMC are set to 0, | |
204 | * and all MAC and VLAN filters (except the default MAC address) on all VSIs | |
205 | * are cleared. | |
206 | */ | |
207 | ||
208 | /* VSI types that use VIRTCHNL interface for VF-PF communication. VSI_SRIOV | |
209 | * vsi_type should always be 6 for backward compatibility. Add other fields | |
210 | * as needed. | |
211 | */ | |
212 | enum virtchnl_vsi_type { | |
213 | VIRTCHNL_VSI_TYPE_INVALID = 0, | |
214 | VIRTCHNL_VSI_SRIOV = 6, | |
215 | }; | |
216 | ||
217 | /* VIRTCHNL_OP_GET_VF_RESOURCES | |
218 | * Version 1.0 VF sends this request to PF with no parameters | |
219 | * Version 1.1 VF sends this request to PF with u32 bitmap of its capabilities | |
220 | * PF responds with an indirect message containing | |
221 | * virtchnl_vf_resource and one or more | |
222 | * virtchnl_vsi_resource structures. | |
223 | */ | |
224 | ||
225 | struct virtchnl_vsi_resource { | |
226 | u16 vsi_id; | |
227 | u16 num_queue_pairs; | |
228 | enum virtchnl_vsi_type vsi_type; | |
229 | u16 qset_handle; | |
230 | u8 default_mac_addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS]; | |
231 | }; | |
232 | ||
233 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource); | |
234 | ||
235 | /* VF capability flags | |
236 | * VIRTCHNL_VF_OFFLOAD_L2 flag is inclusive of base mode L2 offloads including | |
237 | * TX/RX Checksum offloading and TSO for non-tunnelled packets. | |
238 | */ | |
239 | #define VIRTCHNL_VF_OFFLOAD_L2 0x00000001 | |
240 | #define VIRTCHNL_VF_OFFLOAD_IWARP 0x00000002 | |
241 | #define VIRTCHNL_VF_OFFLOAD_RSVD 0x00000004 | |
242 | #define VIRTCHNL_VF_OFFLOAD_RSS_AQ 0x00000008 | |
243 | #define VIRTCHNL_VF_OFFLOAD_RSS_REG 0x00000010 | |
244 | #define VIRTCHNL_VF_OFFLOAD_WB_ON_ITR 0x00000020 | |
245 | #define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES 0x00000040 | |
f67539c2 | 246 | #define VIRTCHNL_VF_OFFLOAD_CRC 0x00000080 |
11fdf7f2 TL |
247 | #define VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000 |
248 | #define VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000 | |
249 | #define VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 0x00040000 | |
250 | #define VIRTCHNL_VF_OFFLOAD_RSS_PF 0X00080000 | |
251 | #define VIRTCHNL_VF_OFFLOAD_ENCAP 0X00100000 | |
252 | #define VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM 0X00200000 | |
253 | #define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM 0X00400000 | |
f67539c2 TL |
254 | #define VIRTCHNL_VF_OFFLOAD_ADQ 0X00800000 |
255 | #define VIRTCHNL_VF_OFFLOAD_ADQ_V2 0X01000000 | |
256 | #define VIRTCHNL_VF_OFFLOAD_USO 0X02000000 | |
257 | #define VIRTCHNL_VF_CAP_DCF 0X40000000 | |
258 | #define VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC 0X04000000 | |
259 | #define VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF 0X08000000 | |
260 | #define VIRTCHNL_VF_OFFLOAD_FDIR_PF 0X10000000 | |
261 | /* 0X80000000 is reserved */ | |
11fdf7f2 | 262 | |
f67539c2 TL |
263 | /* Define below the capability flags that are not offloads */ |
264 | #define VIRTCHNL_VF_CAP_ADV_LINK_SPEED 0x00000080 | |
11fdf7f2 TL |
265 | #define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \ |
266 | VIRTCHNL_VF_OFFLOAD_VLAN | \ | |
267 | VIRTCHNL_VF_OFFLOAD_RSS_PF) | |
268 | ||
269 | struct virtchnl_vf_resource { | |
270 | u16 num_vsis; | |
271 | u16 num_queue_pairs; | |
272 | u16 max_vectors; | |
273 | u16 max_mtu; | |
274 | ||
275 | u32 vf_cap_flags; | |
276 | u32 rss_key_size; | |
277 | u32 rss_lut_size; | |
278 | ||
279 | struct virtchnl_vsi_resource vsi_res[1]; | |
280 | }; | |
281 | ||
282 | VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_vf_resource); | |
283 | ||
284 | /* VIRTCHNL_OP_CONFIG_TX_QUEUE | |
285 | * VF sends this message to set up parameters for one TX queue. | |
286 | * External data buffer contains one instance of virtchnl_txq_info. | |
287 | * PF configures requested queue and returns a status code. | |
288 | */ | |
289 | ||
290 | /* Tx queue config info */ | |
291 | struct virtchnl_txq_info { | |
292 | u16 vsi_id; | |
293 | u16 queue_id; | |
294 | u16 ring_len; /* number of descriptors, multiple of 8 */ | |
f67539c2 | 295 | u16 headwb_enabled; /* deprecated with AVF 1.0 */ |
11fdf7f2 | 296 | u64 dma_ring_addr; |
f67539c2 | 297 | u64 dma_headwb_addr; /* deprecated with AVF 1.0 */ |
11fdf7f2 TL |
298 | }; |
299 | ||
300 | VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info); | |
301 | ||
302 | /* VIRTCHNL_OP_CONFIG_RX_QUEUE | |
303 | * VF sends this message to set up parameters for one RX queue. | |
304 | * External data buffer contains one instance of virtchnl_rxq_info. | |
f67539c2 TL |
305 | * PF configures requested queue and returns a status code. The |
306 | * crc_disable flag disables CRC stripping on the VF. Setting | |
307 | * the crc_disable flag to 1 will disable CRC stripping for each | |
308 | * queue in the VF where the flag is set. The VIRTCHNL_VF_OFFLOAD_CRC | |
309 | * offload must have been set prior to sending this info or the PF | |
310 | * will ignore the request. This flag should be set the same for | |
311 | * all of the queues for a VF. | |
11fdf7f2 TL |
312 | */ |
313 | ||
314 | /* Rx queue config info */ | |
315 | struct virtchnl_rxq_info { | |
316 | u16 vsi_id; | |
317 | u16 queue_id; | |
318 | u32 ring_len; /* number of descriptors, multiple of 32 */ | |
319 | u16 hdr_size; | |
f67539c2 | 320 | u16 splithdr_enabled; /* deprecated with AVF 1.0 */ |
11fdf7f2 TL |
321 | u32 databuffer_size; |
322 | u32 max_pkt_size; | |
f67539c2 TL |
323 | u8 crc_disable; |
324 | /* only used when VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC is supported */ | |
325 | u8 rxdid; | |
326 | u8 pad1[2]; | |
11fdf7f2 | 327 | u64 dma_ring_addr; |
f67539c2 | 328 | enum virtchnl_rx_hsplit rx_split_pos; /* deprecated with AVF 1.0 */ |
11fdf7f2 TL |
329 | u32 pad2; |
330 | }; | |
331 | ||
332 | VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_rxq_info); | |
333 | ||
334 | /* VIRTCHNL_OP_CONFIG_VSI_QUEUES | |
f67539c2 | 335 | * VF sends this message to set parameters for active TX and RX queues |
11fdf7f2 TL |
336 | * associated with the specified VSI. |
337 | * PF configures queues and returns status. | |
338 | * If the number of queues specified is greater than the number of queues | |
339 | * associated with the VSI, an error is returned and no queues are configured. | |
f67539c2 TL |
340 | * NOTE: The VF is not required to configure all queues in a single request. |
341 | * It may send multiple messages. PF drivers must correctly handle all VF | |
342 | * requests. | |
11fdf7f2 TL |
343 | */ |
344 | struct virtchnl_queue_pair_info { | |
345 | /* NOTE: vsi_id and queue_id should be identical for both queues. */ | |
346 | struct virtchnl_txq_info txq; | |
347 | struct virtchnl_rxq_info rxq; | |
348 | }; | |
349 | ||
350 | VIRTCHNL_CHECK_STRUCT_LEN(64, virtchnl_queue_pair_info); | |
351 | ||
352 | struct virtchnl_vsi_queue_config_info { | |
353 | u16 vsi_id; | |
354 | u16 num_queue_pairs; | |
355 | u32 pad; | |
356 | struct virtchnl_queue_pair_info qpair[1]; | |
357 | }; | |
358 | ||
359 | VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_vsi_queue_config_info); | |
360 | ||
361 | /* VIRTCHNL_OP_REQUEST_QUEUES | |
362 | * VF sends this message to request the PF to allocate additional queues to | |
363 | * this VF. Each VF gets a guaranteed number of queues on init but asking for | |
364 | * additional queues must be negotiated. This is a best effort request as it | |
365 | * is possible the PF does not have enough queues left to support the request. | |
366 | * If the PF cannot support the number requested it will respond with the | |
367 | * maximum number it is able to support. If the request is successful, PF will | |
368 | * then reset the VF to institute required changes. | |
369 | */ | |
370 | ||
371 | /* VF resource request */ | |
372 | struct virtchnl_vf_res_request { | |
373 | u16 num_queue_pairs; | |
374 | }; | |
375 | ||
376 | /* VIRTCHNL_OP_CONFIG_IRQ_MAP | |
377 | * VF uses this message to map vectors to queues. | |
378 | * The rxq_map and txq_map fields are bitmaps used to indicate which queues | |
379 | * are to be associated with the specified vector. | |
f67539c2 TL |
380 | * The "other" causes are always mapped to vector 0. The VF may not request |
381 | * that vector 0 be used for traffic. | |
11fdf7f2 | 382 | * PF configures interrupt mapping and returns status. |
f67539c2 TL |
383 | * NOTE: due to hardware requirements, all active queues (both TX and RX) |
384 | * should be mapped to interrupts, even if the driver intends to operate | |
385 | * only in polling mode. In this case the interrupt may be disabled, but | |
386 | * the ITR timer will still run to trigger writebacks. | |
11fdf7f2 TL |
387 | */ |
388 | struct virtchnl_vector_map { | |
389 | u16 vsi_id; | |
390 | u16 vector_id; | |
391 | u16 rxq_map; | |
392 | u16 txq_map; | |
393 | u16 rxitr_idx; | |
394 | u16 txitr_idx; | |
395 | }; | |
396 | ||
397 | VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_vector_map); | |
398 | ||
399 | struct virtchnl_irq_map_info { | |
400 | u16 num_vectors; | |
401 | struct virtchnl_vector_map vecmap[1]; | |
402 | }; | |
403 | ||
404 | VIRTCHNL_CHECK_STRUCT_LEN(14, virtchnl_irq_map_info); | |
405 | ||
406 | /* VIRTCHNL_OP_ENABLE_QUEUES | |
407 | * VIRTCHNL_OP_DISABLE_QUEUES | |
408 | * VF sends these message to enable or disable TX/RX queue pairs. | |
409 | * The queues fields are bitmaps indicating which queues to act upon. | |
410 | * (Currently, we only support 16 queues per VF, but we make the field | |
411 | * u32 to allow for expansion.) | |
412 | * PF performs requested action and returns status. | |
f67539c2 TL |
413 | * NOTE: The VF is not required to enable/disable all queues in a single |
414 | * request. It may send multiple messages. | |
415 | * PF drivers must correctly handle all VF requests. | |
11fdf7f2 TL |
416 | */ |
417 | struct virtchnl_queue_select { | |
418 | u16 vsi_id; | |
419 | u16 pad; | |
420 | u32 rx_queues; | |
421 | u32 tx_queues; | |
422 | }; | |
423 | ||
424 | VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_queue_select); | |
425 | ||
426 | /* VIRTCHNL_OP_ADD_ETH_ADDR | |
427 | * VF sends this message in order to add one or more unicast or multicast | |
428 | * address filters for the specified VSI. | |
429 | * PF adds the filters and returns status. | |
430 | */ | |
431 | ||
432 | /* VIRTCHNL_OP_DEL_ETH_ADDR | |
433 | * VF sends this message in order to remove one or more unicast or multicast | |
434 | * filters for the specified VSI. | |
435 | * PF removes the filters and returns status. | |
436 | */ | |
437 | ||
438 | struct virtchnl_ether_addr { | |
439 | u8 addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS]; | |
440 | u8 pad[2]; | |
441 | }; | |
442 | ||
443 | VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr); | |
444 | ||
445 | struct virtchnl_ether_addr_list { | |
446 | u16 vsi_id; | |
447 | u16 num_elements; | |
448 | struct virtchnl_ether_addr list[1]; | |
449 | }; | |
450 | ||
451 | VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_ether_addr_list); | |
452 | ||
11fdf7f2 TL |
453 | /* VIRTCHNL_OP_ADD_VLAN |
454 | * VF sends this message to add one or more VLAN tag filters for receives. | |
455 | * PF adds the filters and returns status. | |
456 | * If a port VLAN is configured by the PF, this operation will return an | |
457 | * error to the VF. | |
458 | */ | |
459 | ||
460 | /* VIRTCHNL_OP_DEL_VLAN | |
461 | * VF sends this message to remove one or more VLAN tag filters for receives. | |
462 | * PF removes the filters and returns status. | |
463 | * If a port VLAN is configured by the PF, this operation will return an | |
464 | * error to the VF. | |
465 | */ | |
466 | ||
467 | struct virtchnl_vlan_filter_list { | |
468 | u16 vsi_id; | |
469 | u16 num_elements; | |
470 | u16 vlan_id[1]; | |
471 | }; | |
472 | ||
473 | VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_vlan_filter_list); | |
474 | ||
475 | /* VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE | |
476 | * VF sends VSI id and flags. | |
477 | * PF returns status code in retval. | |
478 | * Note: we assume that broadcast accept mode is always enabled. | |
479 | */ | |
480 | struct virtchnl_promisc_info { | |
481 | u16 vsi_id; | |
482 | u16 flags; | |
483 | }; | |
484 | ||
485 | VIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_promisc_info); | |
486 | ||
487 | #define FLAG_VF_UNICAST_PROMISC 0x00000001 | |
488 | #define FLAG_VF_MULTICAST_PROMISC 0x00000002 | |
489 | ||
490 | /* VIRTCHNL_OP_GET_STATS | |
491 | * VF sends this message to request stats for the selected VSI. VF uses | |
492 | * the virtchnl_queue_select struct to specify the VSI. The queue_id | |
493 | * field is ignored by the PF. | |
494 | * | |
495 | * PF replies with struct virtchnl_eth_stats in an external buffer. | |
496 | */ | |
497 | ||
498 | struct virtchnl_eth_stats { | |
499 | u64 rx_bytes; /* received bytes */ | |
500 | u64 rx_unicast; /* received unicast pkts */ | |
501 | u64 rx_multicast; /* received multicast pkts */ | |
502 | u64 rx_broadcast; /* received broadcast pkts */ | |
503 | u64 rx_discards; | |
504 | u64 rx_unknown_protocol; | |
f67539c2 | 505 | u64 tx_bytes; /* transmitted bytes */ |
11fdf7f2 TL |
506 | u64 tx_unicast; /* transmitted unicast pkts */ |
507 | u64 tx_multicast; /* transmitted multicast pkts */ | |
508 | u64 tx_broadcast; /* transmitted broadcast pkts */ | |
509 | u64 tx_discards; | |
510 | u64 tx_errors; | |
511 | }; | |
512 | ||
513 | /* VIRTCHNL_OP_CONFIG_RSS_KEY | |
514 | * VIRTCHNL_OP_CONFIG_RSS_LUT | |
515 | * VF sends these messages to configure RSS. Only supported if both PF | |
516 | * and VF drivers set the VIRTCHNL_VF_OFFLOAD_RSS_PF bit during | |
517 | * configuration negotiation. If this is the case, then the RSS fields in | |
518 | * the VF resource struct are valid. | |
519 | * Both the key and LUT are initialized to 0 by the PF, meaning that | |
520 | * RSS is effectively disabled until set up by the VF. | |
521 | */ | |
522 | struct virtchnl_rss_key { | |
523 | u16 vsi_id; | |
524 | u16 key_len; | |
525 | u8 key[1]; /* RSS hash key, packed bytes */ | |
526 | }; | |
527 | ||
528 | VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_key); | |
529 | ||
530 | struct virtchnl_rss_lut { | |
531 | u16 vsi_id; | |
532 | u16 lut_entries; | |
533 | u8 lut[1]; /* RSS lookup table */ | |
534 | }; | |
535 | ||
536 | VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_lut); | |
537 | ||
538 | /* VIRTCHNL_OP_GET_RSS_HENA_CAPS | |
539 | * VIRTCHNL_OP_SET_RSS_HENA | |
540 | * VF sends these messages to get and set the hash filter enable bits for RSS. | |
541 | * By default, the PF sets these to all possible traffic types that the | |
542 | * hardware supports. The VF can query this value if it wants to change the | |
543 | * traffic types that are hashed by the hardware. | |
544 | */ | |
545 | struct virtchnl_rss_hena { | |
546 | u64 hena; | |
547 | }; | |
548 | ||
549 | VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena); | |
550 | ||
f67539c2 TL |
551 | /* Type of RSS algorithm */ |
552 | enum virtchnl_rss_algorithm { | |
553 | VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC = 0, | |
554 | VIRTCHNL_RSS_ALG_XOR_ASYMMETRIC = 1, | |
555 | VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC = 2, | |
556 | VIRTCHNL_RSS_ALG_XOR_SYMMETRIC = 3, | |
557 | }; | |
558 | ||
559 | /* This is used by PF driver to enforce how many channels can be supported. | |
560 | * When ADQ_V2 capability is negotiated, it will allow 16 channels otherwise | |
561 | * PF driver will allow only max 4 channels | |
562 | */ | |
563 | #define VIRTCHNL_MAX_ADQ_CHANNELS 4 | |
564 | #define VIRTCHNL_MAX_ADQ_V2_CHANNELS 16 | |
565 | ||
566 | /* VIRTCHNL_OP_ENABLE_CHANNELS | |
567 | * VIRTCHNL_OP_DISABLE_CHANNELS | |
568 | * VF sends these messages to enable or disable channels based on | |
569 | * the user specified queue count and queue offset for each traffic class. | |
570 | * This struct encompasses all the information that the PF needs from | |
571 | * VF to create a channel. | |
572 | */ | |
573 | struct virtchnl_channel_info { | |
574 | u16 count; /* number of queues in a channel */ | |
575 | u16 offset; /* queues in a channel start from 'offset' */ | |
576 | u32 pad; | |
577 | u64 max_tx_rate; | |
578 | }; | |
579 | ||
580 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_channel_info); | |
581 | ||
582 | struct virtchnl_tc_info { | |
583 | u32 num_tc; | |
584 | u32 pad; | |
585 | struct virtchnl_channel_info list[1]; | |
586 | }; | |
587 | ||
588 | VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_tc_info); | |
589 | ||
590 | /* VIRTCHNL_ADD_CLOUD_FILTER | |
591 | * VIRTCHNL_DEL_CLOUD_FILTER | |
592 | * VF sends these messages to add or delete a cloud filter based on the | |
593 | * user specified match and action filters. These structures encompass | |
594 | * all the information that the PF needs from the VF to add/delete a | |
595 | * cloud filter. | |
596 | */ | |
597 | ||
598 | struct virtchnl_l4_spec { | |
599 | u8 src_mac[ETH_ALEN]; | |
600 | u8 dst_mac[ETH_ALEN]; | |
601 | /* vlan_prio is part of this 16 bit field even from OS perspective | |
602 | * vlan_id:12 is actual vlan_id, then vlanid:bit14..12 is vlan_prio | |
603 | * in future, when decided to offload vlan_prio, pass that information | |
604 | * as part of the "vlan_id" field, Bit14..12 | |
605 | */ | |
606 | __be16 vlan_id; | |
607 | __be16 pad; /* reserved for future use */ | |
608 | __be32 src_ip[4]; | |
609 | __be32 dst_ip[4]; | |
610 | __be16 src_port; | |
611 | __be16 dst_port; | |
612 | }; | |
613 | ||
614 | VIRTCHNL_CHECK_STRUCT_LEN(52, virtchnl_l4_spec); | |
615 | ||
616 | union virtchnl_flow_spec { | |
617 | struct virtchnl_l4_spec tcp_spec; | |
618 | u8 buffer[128]; /* reserved for future use */ | |
619 | }; | |
620 | ||
621 | VIRTCHNL_CHECK_UNION_LEN(128, virtchnl_flow_spec); | |
622 | ||
623 | enum virtchnl_action { | |
624 | /* action types */ | |
625 | VIRTCHNL_ACTION_DROP = 0, | |
626 | VIRTCHNL_ACTION_TC_REDIRECT, | |
627 | VIRTCHNL_ACTION_PASSTHRU, | |
628 | VIRTCHNL_ACTION_QUEUE, | |
629 | VIRTCHNL_ACTION_Q_REGION, | |
630 | VIRTCHNL_ACTION_MARK, | |
631 | VIRTCHNL_ACTION_COUNT, | |
632 | }; | |
633 | ||
634 | enum virtchnl_flow_type { | |
635 | /* flow types */ | |
636 | VIRTCHNL_TCP_V4_FLOW = 0, | |
637 | VIRTCHNL_TCP_V6_FLOW, | |
638 | VIRTCHNL_UDP_V4_FLOW, | |
639 | VIRTCHNL_UDP_V6_FLOW, | |
640 | }; | |
641 | ||
642 | struct virtchnl_filter { | |
643 | union virtchnl_flow_spec data; | |
644 | union virtchnl_flow_spec mask; | |
645 | enum virtchnl_flow_type flow_type; | |
646 | enum virtchnl_action action; | |
647 | u32 action_meta; | |
648 | u8 field_flags; | |
649 | }; | |
650 | ||
651 | VIRTCHNL_CHECK_STRUCT_LEN(272, virtchnl_filter); | |
652 | ||
653 | /* VIRTCHNL_OP_DCF_GET_VSI_MAP | |
654 | * VF sends this message to get VSI mapping table. | |
655 | * PF responds with an indirect message containing VF's | |
656 | * HW VSI IDs. | |
657 | * The index of vf_vsi array is the logical VF ID, the | |
658 | * value of vf_vsi array is the VF's HW VSI ID with its | |
659 | * valid configuration. | |
660 | */ | |
661 | struct virtchnl_dcf_vsi_map { | |
662 | u16 pf_vsi; /* PF's HW VSI ID */ | |
663 | u16 num_vfs; /* The actual number of VFs allocated */ | |
664 | #define VIRTCHNL_DCF_VF_VSI_ID_S 0 | |
665 | #define VIRTCHNL_DCF_VF_VSI_ID_M (0xFFF << VIRTCHNL_DCF_VF_VSI_ID_S) | |
666 | #define VIRTCHNL_DCF_VF_VSI_VALID (1 << 15) | |
667 | u16 vf_vsi[1]; | |
668 | }; | |
669 | ||
670 | VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_dcf_vsi_map); | |
671 | ||
672 | #define PKG_NAME_SIZE 32 | |
673 | #define DSN_SIZE 8 | |
674 | ||
675 | struct pkg_version { | |
676 | u8 major; | |
677 | u8 minor; | |
678 | u8 update; | |
679 | u8 draft; | |
680 | }; | |
681 | ||
682 | VIRTCHNL_CHECK_STRUCT_LEN(4, pkg_version); | |
683 | ||
684 | struct virtchnl_pkg_info { | |
685 | struct pkg_version pkg_ver; | |
686 | u32 track_id; | |
687 | char pkg_name[PKG_NAME_SIZE]; | |
688 | u8 dsn[DSN_SIZE]; | |
689 | }; | |
690 | ||
691 | VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_pkg_info); | |
692 | ||
693 | struct virtchnl_supported_rxdids { | |
694 | u64 supported_rxdids; | |
695 | }; | |
696 | ||
697 | VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_supported_rxdids); | |
698 | ||
11fdf7f2 TL |
699 | /* VIRTCHNL_OP_EVENT |
700 | * PF sends this message to inform the VF driver of events that may affect it. | |
701 | * No direct response is expected from the VF, though it may generate other | |
702 | * messages in response to this one. | |
703 | */ | |
704 | enum virtchnl_event_codes { | |
705 | VIRTCHNL_EVENT_UNKNOWN = 0, | |
706 | VIRTCHNL_EVENT_LINK_CHANGE, | |
707 | VIRTCHNL_EVENT_RESET_IMPENDING, | |
708 | VIRTCHNL_EVENT_PF_DRIVER_CLOSE, | |
f67539c2 | 709 | VIRTCHNL_EVENT_DCF_VSI_MAP_UPDATE, |
11fdf7f2 TL |
710 | }; |
711 | ||
712 | #define PF_EVENT_SEVERITY_INFO 0 | |
713 | #define PF_EVENT_SEVERITY_ATTENTION 1 | |
714 | #define PF_EVENT_SEVERITY_ACTION_REQUIRED 2 | |
715 | #define PF_EVENT_SEVERITY_CERTAIN_DOOM 255 | |
716 | ||
717 | struct virtchnl_pf_event { | |
718 | enum virtchnl_event_codes event; | |
719 | union { | |
9f95a23c TL |
720 | /* If the PF driver does not support the new speed reporting |
721 | * capabilities then use link_event else use link_event_adv to | |
722 | * get the speed and link information. The ability to understand | |
723 | * new speeds is indicated by setting the capability flag | |
724 | * VIRTCHNL_VF_CAP_ADV_LINK_SPEED in vf_cap_flags parameter | |
725 | * in virtchnl_vf_resource struct and can be used to determine | |
726 | * which link event struct to use below. | |
727 | */ | |
11fdf7f2 TL |
728 | struct { |
729 | enum virtchnl_link_speed link_speed; | |
9f95a23c | 730 | u8 link_status; |
11fdf7f2 | 731 | } link_event; |
9f95a23c TL |
732 | struct { |
733 | /* link_speed provided in Mbps */ | |
734 | u32 link_speed; | |
735 | u8 link_status; | |
736 | } link_event_adv; | |
f67539c2 TL |
737 | struct { |
738 | u16 vf_id; | |
739 | u16 vsi_id; | |
740 | } vf_vsi_map; | |
11fdf7f2 TL |
741 | } event_data; |
742 | ||
743 | int severity; | |
744 | }; | |
745 | ||
746 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_pf_event); | |
747 | ||
11fdf7f2 | 748 | |
f67539c2 TL |
749 | /* Since VF messages are limited by u16 size, precalculate the maximum possible |
750 | * values of nested elements in virtchnl structures that virtual channel can | |
751 | * possibly handle in a single message. | |
11fdf7f2 | 752 | */ |
f67539c2 TL |
753 | enum virtchnl_vector_limits { |
754 | VIRTCHNL_OP_CONFIG_VSI_QUEUES_MAX = | |
755 | ((u16)(~0) - sizeof(struct virtchnl_vsi_queue_config_info)) / | |
756 | sizeof(struct virtchnl_queue_pair_info), | |
11fdf7f2 | 757 | |
f67539c2 TL |
758 | VIRTCHNL_OP_CONFIG_IRQ_MAP_MAX = |
759 | ((u16)(~0) - sizeof(struct virtchnl_irq_map_info)) / | |
760 | sizeof(struct virtchnl_vector_map), | |
11fdf7f2 | 761 | |
f67539c2 TL |
762 | VIRTCHNL_OP_ADD_DEL_ETH_ADDR_MAX = |
763 | ((u16)(~0) - sizeof(struct virtchnl_ether_addr_list)) / | |
764 | sizeof(struct virtchnl_ether_addr), | |
11fdf7f2 | 765 | |
f67539c2 TL |
766 | VIRTCHNL_OP_ADD_DEL_VLAN_MAX = |
767 | ((u16)(~0) - sizeof(struct virtchnl_vlan_filter_list)) / | |
768 | sizeof(u16), | |
11fdf7f2 | 769 | |
11fdf7f2 | 770 | |
f67539c2 TL |
771 | VIRTCHNL_OP_ENABLE_CHANNELS_MAX = |
772 | ((u16)(~0) - sizeof(struct virtchnl_tc_info)) / | |
773 | sizeof(struct virtchnl_channel_info), | |
774 | }; | |
11fdf7f2 TL |
775 | |
776 | /* VF reset states - these are written into the RSTAT register: | |
777 | * VFGEN_RSTAT on the VF | |
778 | * When the PF initiates a reset, it writes 0 | |
779 | * When the reset is complete, it writes 1 | |
780 | * When the PF detects that the VF has recovered, it writes 2 | |
781 | * VF checks this register periodically to determine if a reset has occurred, | |
782 | * then polls it to know when the reset is complete. | |
783 | * If either the PF or VF reads the register while the hardware | |
784 | * is in a reset state, it will return DEADBEEF, which, when masked | |
785 | * will result in 3. | |
786 | */ | |
787 | enum virtchnl_vfr_states { | |
788 | VIRTCHNL_VFR_INPROGRESS = 0, | |
789 | VIRTCHNL_VFR_COMPLETED, | |
790 | VIRTCHNL_VFR_VFACTIVE, | |
791 | }; | |
792 | ||
f67539c2 TL |
793 | #define VIRTCHNL_MAX_NUM_PROTO_HDRS 32 |
794 | #define PROTO_HDR_SHIFT 5 | |
795 | #define PROTO_HDR_FIELD_START(proto_hdr_type) \ | |
796 | (proto_hdr_type << PROTO_HDR_SHIFT) | |
797 | #define PROTO_HDR_FIELD_MASK ((1UL << PROTO_HDR_SHIFT) - 1) | |
798 | ||
799 | /* VF use these macros to configure each protocol header. | |
800 | * Specify which protocol headers and protocol header fields base on | |
801 | * virtchnl_proto_hdr_type and virtchnl_proto_hdr_field. | |
802 | * @param hdr: a struct of virtchnl_proto_hdr | |
803 | * @param hdr_type: ETH/IPV4/TCP, etc | |
804 | * @param field: SRC/DST/TEID/SPI, etc | |
805 | */ | |
806 | #define VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, field) \ | |
807 | ((hdr)->field_selector |= BIT((field) & PROTO_HDR_FIELD_MASK)) | |
808 | #define VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, field) \ | |
809 | ((hdr)->field_selector &= ~BIT((field) & PROTO_HDR_FIELD_MASK)) | |
810 | #define VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val) \ | |
811 | ((hdr)->field_selector & BIT((val) & PROTO_HDR_FIELD_MASK)) | |
812 | #define VIRTCHNL_GET_PROTO_HDR_FIELD(hdr) ((hdr)->field_selector) | |
813 | ||
814 | #define VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \ | |
815 | (VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, \ | |
816 | VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field)) | |
817 | #define VIRTCHNL_DEL_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \ | |
818 | (VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, \ | |
819 | VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field)) | |
820 | ||
821 | #define VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, hdr_type) \ | |
822 | ((hdr)->type = VIRTCHNL_PROTO_HDR_ ## hdr_type) | |
823 | #define VIRTCHNL_GET_PROTO_HDR_TYPE(hdr) \ | |
824 | (((hdr)->type) >> PROTO_HDR_SHIFT) | |
825 | #define VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) \ | |
826 | ((hdr)->type == ((val) >> PROTO_HDR_SHIFT)) | |
827 | #define VIRTCHNL_TEST_PROTO_HDR(hdr, val) \ | |
828 | (VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) && \ | |
829 | VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val)) | |
830 | ||
831 | /* Protocol header type within a packet segment. A segment consists of one or | |
832 | * more protocol headers that make up a logical group of protocol headers. Each | |
833 | * logical group of protocol headers encapsulates or is encapsulated using/by | |
834 | * tunneling or encapsulation protocols for network virtualization. | |
835 | */ | |
836 | enum virtchnl_proto_hdr_type { | |
837 | VIRTCHNL_PROTO_HDR_NONE, | |
838 | VIRTCHNL_PROTO_HDR_ETH, | |
839 | VIRTCHNL_PROTO_HDR_S_VLAN, | |
840 | VIRTCHNL_PROTO_HDR_C_VLAN, | |
841 | VIRTCHNL_PROTO_HDR_IPV4, | |
842 | VIRTCHNL_PROTO_HDR_IPV6, | |
843 | VIRTCHNL_PROTO_HDR_TCP, | |
844 | VIRTCHNL_PROTO_HDR_UDP, | |
845 | VIRTCHNL_PROTO_HDR_SCTP, | |
846 | VIRTCHNL_PROTO_HDR_GTPU_IP, | |
847 | VIRTCHNL_PROTO_HDR_GTPU_EH, | |
848 | VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN, | |
849 | VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP, | |
850 | VIRTCHNL_PROTO_HDR_PPPOE, | |
851 | VIRTCHNL_PROTO_HDR_L2TPV3, | |
852 | VIRTCHNL_PROTO_HDR_ESP, | |
853 | VIRTCHNL_PROTO_HDR_AH, | |
854 | VIRTCHNL_PROTO_HDR_PFCP, | |
855 | }; | |
856 | ||
857 | /* Protocol header field within a protocol header. */ | |
858 | enum virtchnl_proto_hdr_field { | |
859 | /* ETHER */ | |
860 | VIRTCHNL_PROTO_HDR_ETH_SRC = | |
861 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ETH), | |
862 | VIRTCHNL_PROTO_HDR_ETH_DST, | |
863 | VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE, | |
864 | /* S-VLAN */ | |
865 | VIRTCHNL_PROTO_HDR_S_VLAN_ID = | |
866 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_S_VLAN), | |
867 | /* C-VLAN */ | |
868 | VIRTCHNL_PROTO_HDR_C_VLAN_ID = | |
869 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_C_VLAN), | |
870 | /* IPV4 */ | |
871 | VIRTCHNL_PROTO_HDR_IPV4_SRC = | |
872 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV4), | |
873 | VIRTCHNL_PROTO_HDR_IPV4_DST, | |
874 | VIRTCHNL_PROTO_HDR_IPV4_DSCP, | |
875 | VIRTCHNL_PROTO_HDR_IPV4_TTL, | |
876 | VIRTCHNL_PROTO_HDR_IPV4_PROT, | |
877 | /* IPV6 */ | |
878 | VIRTCHNL_PROTO_HDR_IPV6_SRC = | |
879 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV6), | |
880 | VIRTCHNL_PROTO_HDR_IPV6_DST, | |
881 | VIRTCHNL_PROTO_HDR_IPV6_TC, | |
882 | VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT, | |
883 | VIRTCHNL_PROTO_HDR_IPV6_PROT, | |
884 | /* TCP */ | |
885 | VIRTCHNL_PROTO_HDR_TCP_SRC_PORT = | |
886 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_TCP), | |
887 | VIRTCHNL_PROTO_HDR_TCP_DST_PORT, | |
888 | /* UDP */ | |
889 | VIRTCHNL_PROTO_HDR_UDP_SRC_PORT = | |
890 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_UDP), | |
891 | VIRTCHNL_PROTO_HDR_UDP_DST_PORT, | |
892 | /* SCTP */ | |
893 | VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT = | |
894 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_SCTP), | |
895 | VIRTCHNL_PROTO_HDR_SCTP_DST_PORT, | |
896 | /* GTPU_IP */ | |
897 | VIRTCHNL_PROTO_HDR_GTPU_IP_TEID = | |
898 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_IP), | |
899 | /* GTPU_EH */ | |
900 | VIRTCHNL_PROTO_HDR_GTPU_EH_PDU = | |
901 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_EH), | |
902 | VIRTCHNL_PROTO_HDR_GTPU_EH_QFI, | |
903 | /* PPPOE */ | |
904 | VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID = | |
905 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PPPOE), | |
906 | /* L2TPV3 */ | |
907 | VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID = | |
908 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_L2TPV3), | |
909 | /* ESP */ | |
910 | VIRTCHNL_PROTO_HDR_ESP_SPI = | |
911 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ESP), | |
912 | /* AH */ | |
913 | VIRTCHNL_PROTO_HDR_AH_SPI = | |
914 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_AH), | |
915 | /* PFCP */ | |
916 | VIRTCHNL_PROTO_HDR_PFCP_S_FIELD = | |
917 | PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PFCP), | |
918 | VIRTCHNL_PROTO_HDR_PFCP_SEID, | |
919 | }; | |
920 | ||
921 | struct virtchnl_proto_hdr { | |
922 | enum virtchnl_proto_hdr_type type; | |
923 | u32 field_selector; /* a bit mask to select field for header type */ | |
924 | u8 buffer[64]; | |
925 | /** | |
926 | * binary buffer in network order for specific header type. | |
927 | * For example, if type = VIRTCHNL_PROTO_HDR_IPV4, a IPv4 | |
928 | * header is expected to be copied into the buffer. | |
929 | */ | |
930 | }; | |
931 | ||
932 | VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_proto_hdr); | |
933 | ||
934 | struct virtchnl_proto_hdrs { | |
935 | u8 tunnel_level; | |
936 | /** | |
937 | * specify where protocol header start from. | |
938 | * 0 - from the outer layer | |
939 | * 1 - from the first inner layer | |
940 | * 2 - from the second inner layer | |
941 | * .... | |
942 | **/ | |
943 | int count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */ | |
944 | struct virtchnl_proto_hdr proto_hdr[VIRTCHNL_MAX_NUM_PROTO_HDRS]; | |
945 | }; | |
946 | ||
947 | VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs); | |
948 | ||
949 | struct virtchnl_rss_cfg { | |
950 | struct virtchnl_proto_hdrs proto_hdrs; /* protocol headers */ | |
951 | enum virtchnl_rss_algorithm rss_algorithm; /* rss algorithm type */ | |
952 | u8 reserved[128]; /* reserve for future */ | |
953 | }; | |
954 | ||
955 | VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg); | |
956 | ||
957 | /* action configuration for FDIR */ | |
958 | struct virtchnl_filter_action { | |
959 | enum virtchnl_action type; | |
960 | union { | |
961 | /* used for queue and qgroup action */ | |
962 | struct { | |
963 | u16 index; | |
964 | u8 region; | |
965 | } queue; | |
966 | /* used for count action */ | |
967 | struct { | |
968 | /* share counter ID with other flow rules */ | |
969 | u8 shared; | |
970 | u32 id; /* counter ID */ | |
971 | } count; | |
972 | /* used for mark action */ | |
973 | u32 mark_id; | |
974 | u8 reserve[32]; | |
975 | } act_conf; | |
976 | }; | |
977 | ||
978 | VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_filter_action); | |
979 | ||
980 | #define VIRTCHNL_MAX_NUM_ACTIONS 8 | |
981 | ||
982 | struct virtchnl_filter_action_set { | |
983 | /* action number must be less then VIRTCHNL_MAX_NUM_ACTIONS */ | |
984 | int count; | |
985 | struct virtchnl_filter_action actions[VIRTCHNL_MAX_NUM_ACTIONS]; | |
986 | }; | |
987 | ||
988 | VIRTCHNL_CHECK_STRUCT_LEN(292, virtchnl_filter_action_set); | |
989 | ||
990 | /* pattern and action for FDIR rule */ | |
991 | struct virtchnl_fdir_rule { | |
992 | struct virtchnl_proto_hdrs proto_hdrs; | |
993 | struct virtchnl_filter_action_set action_set; | |
994 | }; | |
995 | ||
996 | VIRTCHNL_CHECK_STRUCT_LEN(2604, virtchnl_fdir_rule); | |
997 | ||
998 | /* query information to retrieve fdir rule counters. | |
999 | * PF will fill out this structure to reset counter. | |
1000 | */ | |
1001 | struct virtchnl_fdir_query_info { | |
1002 | u32 match_packets_valid:1; | |
1003 | u32 match_bytes_valid:1; | |
1004 | u32 reserved:30; /* Reserved, must be zero. */ | |
1005 | u32 pad; | |
1006 | u64 matched_packets; /* Number of packets for this rule. */ | |
1007 | u64 matched_bytes; /* Number of bytes through this rule. */ | |
1008 | }; | |
1009 | ||
1010 | VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_fdir_query_info); | |
1011 | ||
1012 | /* Status returned to VF after VF requests FDIR commands | |
1013 | * VIRTCHNL_FDIR_SUCCESS | |
1014 | * VF FDIR related request is successfully done by PF | |
1015 | * The request can be OP_ADD/DEL/QUERY_FDIR_FILTER. | |
1016 | * | |
1017 | * VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE | |
1018 | * OP_ADD_FDIR_FILTER request is failed due to no Hardware resource. | |
1019 | * | |
1020 | * VIRTCHNL_FDIR_FAILURE_RULE_EXIST | |
1021 | * OP_ADD_FDIR_FILTER request is failed due to the rule is already existed. | |
1022 | * | |
1023 | * VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT | |
1024 | * OP_ADD_FDIR_FILTER request is failed due to conflict with existing rule. | |
1025 | * | |
1026 | * VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST | |
1027 | * OP_DEL_FDIR_FILTER request is failed due to this rule doesn't exist. | |
1028 | * | |
1029 | * VIRTCHNL_FDIR_FAILURE_RULE_INVALID | |
1030 | * OP_ADD_FDIR_FILTER request is failed due to parameters validation | |
1031 | * or HW doesn't support. | |
1032 | * | |
1033 | * VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT | |
1034 | * OP_ADD/DEL_FDIR_FILTER request is failed due to timing out | |
1035 | * for programming. | |
1036 | * | |
1037 | * VIRTCHNL_FDIR_FAILURE_QUERY_INVALID | |
1038 | * OP_QUERY_FDIR_FILTER request is failed due to parameters validation, | |
1039 | * for example, VF query counter of a rule who has no counter action. | |
1040 | */ | |
1041 | enum virtchnl_fdir_prgm_status { | |
1042 | VIRTCHNL_FDIR_SUCCESS = 0, | |
1043 | VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE, | |
1044 | VIRTCHNL_FDIR_FAILURE_RULE_EXIST, | |
1045 | VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT, | |
1046 | VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST, | |
1047 | VIRTCHNL_FDIR_FAILURE_RULE_INVALID, | |
1048 | VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT, | |
1049 | VIRTCHNL_FDIR_FAILURE_QUERY_INVALID, | |
1050 | }; | |
1051 | ||
1052 | /* VIRTCHNL_OP_ADD_FDIR_FILTER | |
1053 | * VF sends this request to PF by filling out vsi_id, | |
1054 | * validate_only and rule_cfg. PF will return flow_id | |
1055 | * if the request is successfully done and return add_status to VF. | |
1056 | */ | |
1057 | struct virtchnl_fdir_add { | |
1058 | u16 vsi_id; /* INPUT */ | |
1059 | /* | |
1060 | * 1 for validating a fdir rule, 0 for creating a fdir rule. | |
1061 | * Validate and create share one ops: VIRTCHNL_OP_ADD_FDIR_FILTER. | |
1062 | */ | |
1063 | u16 validate_only; /* INPUT */ | |
1064 | u32 flow_id; /* OUTPUT */ | |
1065 | struct virtchnl_fdir_rule rule_cfg; /* INPUT */ | |
1066 | enum virtchnl_fdir_prgm_status status; /* OUTPUT */ | |
1067 | }; | |
1068 | ||
1069 | VIRTCHNL_CHECK_STRUCT_LEN(2616, virtchnl_fdir_add); | |
1070 | ||
1071 | /* VIRTCHNL_OP_DEL_FDIR_FILTER | |
1072 | * VF sends this request to PF by filling out vsi_id | |
1073 | * and flow_id. PF will return del_status to VF. | |
1074 | */ | |
1075 | struct virtchnl_fdir_del { | |
1076 | u16 vsi_id; /* INPUT */ | |
1077 | u16 pad; | |
1078 | u32 flow_id; /* INPUT */ | |
1079 | enum virtchnl_fdir_prgm_status status; /* OUTPUT */ | |
1080 | }; | |
1081 | ||
1082 | VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_fdir_del); | |
1083 | ||
1084 | /* VIRTCHNL_OP_QUERY_FDIR_FILTER | |
1085 | * VF sends this request to PF by filling out vsi_id, | |
1086 | * flow_id and reset_counter. PF will return query_info | |
1087 | * and query_status to VF. | |
1088 | */ | |
1089 | struct virtchnl_fdir_query { | |
1090 | u16 vsi_id; /* INPUT */ | |
1091 | u16 pad1[3]; | |
1092 | u32 flow_id; /* INPUT */ | |
1093 | u32 reset_counter:1; /* INPUT */ | |
1094 | struct virtchnl_fdir_query_info query_info; /* OUTPUT */ | |
1095 | enum virtchnl_fdir_prgm_status status; /* OUTPUT */ | |
1096 | u32 pad2; | |
1097 | }; | |
1098 | ||
1099 | VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_fdir_query); | |
11fdf7f2 TL |
1100 | /** |
1101 | * virtchnl_vc_validate_vf_msg | |
1102 | * @ver: Virtchnl version info | |
1103 | * @v_opcode: Opcode for the message | |
1104 | * @msg: pointer to the msg buffer | |
1105 | * @msglen: msg length | |
1106 | * | |
1107 | * validate msg format against struct for each opcode | |
1108 | */ | |
1109 | static inline int | |
1110 | virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, | |
1111 | u8 *msg, u16 msglen) | |
1112 | { | |
1113 | bool err_msg_format = false; | |
f67539c2 | 1114 | u32 valid_len = 0; |
11fdf7f2 TL |
1115 | |
1116 | /* Validate message length. */ | |
1117 | switch (v_opcode) { | |
1118 | case VIRTCHNL_OP_VERSION: | |
1119 | valid_len = sizeof(struct virtchnl_version_info); | |
1120 | break; | |
1121 | case VIRTCHNL_OP_RESET_VF: | |
1122 | break; | |
1123 | case VIRTCHNL_OP_GET_VF_RESOURCES: | |
1124 | if (VF_IS_V11(ver)) | |
1125 | valid_len = sizeof(u32); | |
1126 | break; | |
1127 | case VIRTCHNL_OP_CONFIG_TX_QUEUE: | |
1128 | valid_len = sizeof(struct virtchnl_txq_info); | |
1129 | break; | |
1130 | case VIRTCHNL_OP_CONFIG_RX_QUEUE: | |
1131 | valid_len = sizeof(struct virtchnl_rxq_info); | |
1132 | break; | |
1133 | case VIRTCHNL_OP_CONFIG_VSI_QUEUES: | |
1134 | valid_len = sizeof(struct virtchnl_vsi_queue_config_info); | |
1135 | if (msglen >= valid_len) { | |
1136 | struct virtchnl_vsi_queue_config_info *vqc = | |
1137 | (struct virtchnl_vsi_queue_config_info *)msg; | |
f67539c2 TL |
1138 | |
1139 | if (vqc->num_queue_pairs == 0 || vqc->num_queue_pairs > | |
1140 | VIRTCHNL_OP_CONFIG_VSI_QUEUES_MAX) { | |
1141 | err_msg_format = true; | |
1142 | break; | |
1143 | } | |
1144 | ||
11fdf7f2 TL |
1145 | valid_len += (vqc->num_queue_pairs * |
1146 | sizeof(struct | |
1147 | virtchnl_queue_pair_info)); | |
11fdf7f2 TL |
1148 | } |
1149 | break; | |
1150 | case VIRTCHNL_OP_CONFIG_IRQ_MAP: | |
1151 | valid_len = sizeof(struct virtchnl_irq_map_info); | |
1152 | if (msglen >= valid_len) { | |
1153 | struct virtchnl_irq_map_info *vimi = | |
1154 | (struct virtchnl_irq_map_info *)msg; | |
f67539c2 TL |
1155 | |
1156 | if (vimi->num_vectors == 0 || vimi->num_vectors > | |
1157 | VIRTCHNL_OP_CONFIG_IRQ_MAP_MAX) { | |
1158 | err_msg_format = true; | |
1159 | break; | |
1160 | } | |
1161 | ||
11fdf7f2 TL |
1162 | valid_len += (vimi->num_vectors * |
1163 | sizeof(struct virtchnl_vector_map)); | |
11fdf7f2 TL |
1164 | } |
1165 | break; | |
1166 | case VIRTCHNL_OP_ENABLE_QUEUES: | |
1167 | case VIRTCHNL_OP_DISABLE_QUEUES: | |
1168 | valid_len = sizeof(struct virtchnl_queue_select); | |
1169 | break; | |
1170 | case VIRTCHNL_OP_ADD_ETH_ADDR: | |
1171 | case VIRTCHNL_OP_DEL_ETH_ADDR: | |
1172 | valid_len = sizeof(struct virtchnl_ether_addr_list); | |
1173 | if (msglen >= valid_len) { | |
1174 | struct virtchnl_ether_addr_list *veal = | |
1175 | (struct virtchnl_ether_addr_list *)msg; | |
f67539c2 TL |
1176 | |
1177 | if (veal->num_elements == 0 || veal->num_elements > | |
1178 | VIRTCHNL_OP_ADD_DEL_ETH_ADDR_MAX) { | |
1179 | err_msg_format = true; | |
1180 | break; | |
1181 | } | |
1182 | ||
11fdf7f2 TL |
1183 | valid_len += veal->num_elements * |
1184 | sizeof(struct virtchnl_ether_addr); | |
11fdf7f2 TL |
1185 | } |
1186 | break; | |
1187 | case VIRTCHNL_OP_ADD_VLAN: | |
1188 | case VIRTCHNL_OP_DEL_VLAN: | |
1189 | valid_len = sizeof(struct virtchnl_vlan_filter_list); | |
1190 | if (msglen >= valid_len) { | |
1191 | struct virtchnl_vlan_filter_list *vfl = | |
1192 | (struct virtchnl_vlan_filter_list *)msg; | |
f67539c2 TL |
1193 | |
1194 | if (vfl->num_elements == 0 || vfl->num_elements > | |
1195 | VIRTCHNL_OP_ADD_DEL_VLAN_MAX) { | |
11fdf7f2 | 1196 | err_msg_format = true; |
f67539c2 TL |
1197 | break; |
1198 | } | |
1199 | ||
1200 | valid_len += vfl->num_elements * sizeof(u16); | |
11fdf7f2 TL |
1201 | } |
1202 | break; | |
1203 | case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: | |
1204 | valid_len = sizeof(struct virtchnl_promisc_info); | |
1205 | break; | |
1206 | case VIRTCHNL_OP_GET_STATS: | |
1207 | valid_len = sizeof(struct virtchnl_queue_select); | |
1208 | break; | |
11fdf7f2 TL |
1209 | case VIRTCHNL_OP_CONFIG_RSS_KEY: |
1210 | valid_len = sizeof(struct virtchnl_rss_key); | |
1211 | if (msglen >= valid_len) { | |
1212 | struct virtchnl_rss_key *vrk = | |
1213 | (struct virtchnl_rss_key *)msg; | |
f67539c2 TL |
1214 | |
1215 | if (vrk->key_len == 0) { | |
1216 | /* zero length is allowed as input */ | |
1217 | break; | |
1218 | } | |
1219 | ||
11fdf7f2 TL |
1220 | valid_len += vrk->key_len - 1; |
1221 | } | |
1222 | break; | |
1223 | case VIRTCHNL_OP_CONFIG_RSS_LUT: | |
1224 | valid_len = sizeof(struct virtchnl_rss_lut); | |
1225 | if (msglen >= valid_len) { | |
1226 | struct virtchnl_rss_lut *vrl = | |
1227 | (struct virtchnl_rss_lut *)msg; | |
f67539c2 TL |
1228 | |
1229 | if (vrl->lut_entries == 0) { | |
1230 | /* zero entries is allowed as input */ | |
1231 | break; | |
1232 | } | |
1233 | ||
11fdf7f2 TL |
1234 | valid_len += vrl->lut_entries - 1; |
1235 | } | |
1236 | break; | |
1237 | case VIRTCHNL_OP_GET_RSS_HENA_CAPS: | |
1238 | break; | |
1239 | case VIRTCHNL_OP_SET_RSS_HENA: | |
1240 | valid_len = sizeof(struct virtchnl_rss_hena); | |
1241 | break; | |
1242 | case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING: | |
1243 | case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING: | |
1244 | break; | |
1245 | case VIRTCHNL_OP_REQUEST_QUEUES: | |
1246 | valid_len = sizeof(struct virtchnl_vf_res_request); | |
1247 | break; | |
f67539c2 TL |
1248 | case VIRTCHNL_OP_ENABLE_CHANNELS: |
1249 | valid_len = sizeof(struct virtchnl_tc_info); | |
1250 | if (msglen >= valid_len) { | |
1251 | struct virtchnl_tc_info *vti = | |
1252 | (struct virtchnl_tc_info *)msg; | |
1253 | ||
1254 | if (vti->num_tc == 0 || vti->num_tc > | |
1255 | VIRTCHNL_OP_ENABLE_CHANNELS_MAX) { | |
1256 | err_msg_format = true; | |
1257 | break; | |
1258 | } | |
1259 | ||
1260 | valid_len += (vti->num_tc - 1) * | |
1261 | sizeof(struct virtchnl_channel_info); | |
1262 | } | |
1263 | break; | |
1264 | case VIRTCHNL_OP_DISABLE_CHANNELS: | |
1265 | break; | |
1266 | case VIRTCHNL_OP_ADD_CLOUD_FILTER: | |
1267 | case VIRTCHNL_OP_DEL_CLOUD_FILTER: | |
1268 | valid_len = sizeof(struct virtchnl_filter); | |
1269 | break; | |
1270 | case VIRTCHNL_OP_DCF_CMD_DESC: | |
1271 | case VIRTCHNL_OP_DCF_CMD_BUFF: | |
1272 | /* These two opcodes are specific to handle the AdminQ command, | |
1273 | * so the validation needs to be done in PF's context. | |
1274 | */ | |
1275 | return 0; | |
1276 | case VIRTCHNL_OP_DCF_DISABLE: | |
1277 | case VIRTCHNL_OP_DCF_GET_VSI_MAP: | |
1278 | /* The two opcodes are required by DCF without message buffer, | |
1279 | * so the valid length keeps the default value 0. | |
1280 | */ | |
1281 | break; | |
1282 | case VIRTCHNL_OP_DCF_GET_PKG_INFO: | |
1283 | break; | |
1284 | case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS: | |
1285 | break; | |
1286 | case VIRTCHNL_OP_ADD_RSS_CFG: | |
1287 | case VIRTCHNL_OP_DEL_RSS_CFG: | |
1288 | valid_len = sizeof(struct virtchnl_rss_cfg); | |
1289 | break; | |
1290 | case VIRTCHNL_OP_ADD_FDIR_FILTER: | |
1291 | valid_len = sizeof(struct virtchnl_fdir_add); | |
1292 | break; | |
1293 | case VIRTCHNL_OP_DEL_FDIR_FILTER: | |
1294 | valid_len = sizeof(struct virtchnl_fdir_del); | |
1295 | break; | |
1296 | case VIRTCHNL_OP_QUERY_FDIR_FILTER: | |
1297 | valid_len = sizeof(struct virtchnl_fdir_query); | |
1298 | break; | |
11fdf7f2 TL |
1299 | /* These are always errors coming from the VF. */ |
1300 | case VIRTCHNL_OP_EVENT: | |
1301 | case VIRTCHNL_OP_UNKNOWN: | |
1302 | default: | |
f67539c2 | 1303 | return VIRTCHNL_STATUS_ERR_PARAM; |
11fdf7f2 TL |
1304 | } |
1305 | /* few more checks */ | |
1306 | if (err_msg_format || valid_len != msglen) | |
1307 | return VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH; | |
1308 | ||
1309 | return 0; | |
1310 | } | |
1311 | #endif /* _VIRTCHNL_H_ */ |