virtchnl.h 34.8 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0-only */
G
Greg Rose 已提交
2 3 4
/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
5
 * Copyright(c) 2013 - 2014 Intel Corporation.
G
Greg Rose 已提交
6 7 8 9 10 11 12
 *
 * Contact Information:
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 ******************************************************************************/

13 14
#ifndef _VIRTCHNL_H_
#define _VIRTCHNL_H_
G
Greg Rose 已提交
15 16 17

/* Description:
 * This header file describes the VF-PF communication protocol used
18
 * by the drivers for all devices starting from our 40G product line
G
Greg Rose 已提交
19 20
 *
 * Admin queue buffer usage:
21
 * desc->opcode is always aqc_opc_send_msg_to_pf
G
Greg Rose 已提交
22
 * flags, retval, datalen, and data addr are all used normally.
23 24 25
 * The Firmware copies the cookie fields when sending messages between the
 * PF and VF, but uses all other fields internally. Due to this limitation,
 * we must send all messages as "indirect", i.e. using an external buffer.
G
Greg Rose 已提交
26
 *
27
 * All the VSI indexes are relative to the VF. Each VF can have maximum of
G
Greg Rose 已提交
28 29 30 31
 * three VSIs. All the queue indexes are relative to the VSI.  Each VF can
 * have a maximum of sixteen queues for all of its VSIs.
 *
 * The PF is required to return a status code in v_retval for all messages
32 33
 * except RESET_VF, which does not require any response. The return value
 * is of status_code type, defined in the shared type.h.
G
Greg Rose 已提交
34
 *
35 36 37 38 39 40
 * In general, VF driver initialization should roughly follow the order of
 * these opcodes. The VF driver must first validate the API version of the
 * PF driver, then request a reset, then get resources, then configure
 * queues and interrupts. After these operations are complete, the VF
 * driver may start its queues, optionally add MAC and VLAN filters, and
 * process traffic.
G
Greg Rose 已提交
41 42
 */

43 44 45 46 47 48 49 50
/* START GENERIC DEFINES
 * Need to ensure the following enums and defines hold the same meaning and
 * value in current and future projects
 */

/* Error Codes */
enum virtchnl_status_code {
	VIRTCHNL_STATUS_SUCCESS				= 0,
M
Mitch Williams 已提交
51 52
	VIRTCHNL_STATUS_ERR_PARAM			= -5,
	VIRTCHNL_STATUS_ERR_NO_MEMORY			= -18,
53 54 55
	VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH		= -38,
	VIRTCHNL_STATUS_ERR_CQP_COMPL_ERROR		= -39,
	VIRTCHNL_STATUS_ERR_INVALID_VF_ID		= -40,
M
Mitch Williams 已提交
56 57
	VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR		= -53,
	VIRTCHNL_STATUS_ERR_NOT_SUPPORTED		= -64,
58 59
};

M
Mitch Williams 已提交
60 61 62 63
/* Backward compatibility */
#define VIRTCHNL_ERR_PARAM VIRTCHNL_STATUS_ERR_PARAM
#define VIRTCHNL_STATUS_NOT_SUPPORTED VIRTCHNL_STATUS_ERR_NOT_SUPPORTED

64
#define VIRTCHNL_LINK_SPEED_2_5GB_SHIFT		0x0
65 66 67 68 69 70
#define VIRTCHNL_LINK_SPEED_100MB_SHIFT		0x1
#define VIRTCHNL_LINK_SPEED_1000MB_SHIFT	0x2
#define VIRTCHNL_LINK_SPEED_10GB_SHIFT		0x3
#define VIRTCHNL_LINK_SPEED_40GB_SHIFT		0x4
#define VIRTCHNL_LINK_SPEED_20GB_SHIFT		0x5
#define VIRTCHNL_LINK_SPEED_25GB_SHIFT		0x6
71
#define VIRTCHNL_LINK_SPEED_5GB_SHIFT		0x7
72 73 74 75 76 77 78 79 80

enum virtchnl_link_speed {
	VIRTCHNL_LINK_SPEED_UNKNOWN	= 0,
	VIRTCHNL_LINK_SPEED_100MB	= BIT(VIRTCHNL_LINK_SPEED_100MB_SHIFT),
	VIRTCHNL_LINK_SPEED_1GB		= BIT(VIRTCHNL_LINK_SPEED_1000MB_SHIFT),
	VIRTCHNL_LINK_SPEED_10GB	= BIT(VIRTCHNL_LINK_SPEED_10GB_SHIFT),
	VIRTCHNL_LINK_SPEED_40GB	= BIT(VIRTCHNL_LINK_SPEED_40GB_SHIFT),
	VIRTCHNL_LINK_SPEED_20GB	= BIT(VIRTCHNL_LINK_SPEED_20GB_SHIFT),
	VIRTCHNL_LINK_SPEED_25GB	= BIT(VIRTCHNL_LINK_SPEED_25GB_SHIFT),
81 82
	VIRTCHNL_LINK_SPEED_2_5GB	= BIT(VIRTCHNL_LINK_SPEED_2_5GB_SHIFT),
	VIRTCHNL_LINK_SPEED_5GB		= BIT(VIRTCHNL_LINK_SPEED_5GB_SHIFT),
83 84 85 86 87 88 89 90 91 92 93 94
};

/* for hsplit_0 field of Rx HMC context */
/* deprecated with AVF 1.0 */
enum virtchnl_rx_hsplit {
	VIRTCHNL_RX_HSPLIT_NO_SPLIT      = 0,
	VIRTCHNL_RX_HSPLIT_SPLIT_L2      = 1,
	VIRTCHNL_RX_HSPLIT_SPLIT_IP      = 2,
	VIRTCHNL_RX_HSPLIT_SPLIT_TCP_UDP = 4,
	VIRTCHNL_RX_HSPLIT_SPLIT_SCTP    = 8,
};

95 96
/* END GENERIC DEFINES */

G
Greg Rose 已提交
97 98 99
/* Opcodes for VF-PF communication. These are placed in the v_opcode field
 * of the virtchnl_msg structure.
 */
100
enum virtchnl_ops {
101
/* The PF sends status change events to VFs using
102
 * the VIRTCHNL_OP_EVENT opcode.
103
 * VFs send requests to the PF using the other ops.
104 105
 * Use of "advanced opcode" features must be negotiated as part of capabilities
 * exchange and are not considered part of base mode feature set.
G
Greg Rose 已提交
106
 */
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
	VIRTCHNL_OP_UNKNOWN = 0,
	VIRTCHNL_OP_VERSION = 1, /* must ALWAYS be 1 */
	VIRTCHNL_OP_RESET_VF = 2,
	VIRTCHNL_OP_GET_VF_RESOURCES = 3,
	VIRTCHNL_OP_CONFIG_TX_QUEUE = 4,
	VIRTCHNL_OP_CONFIG_RX_QUEUE = 5,
	VIRTCHNL_OP_CONFIG_VSI_QUEUES = 6,
	VIRTCHNL_OP_CONFIG_IRQ_MAP = 7,
	VIRTCHNL_OP_ENABLE_QUEUES = 8,
	VIRTCHNL_OP_DISABLE_QUEUES = 9,
	VIRTCHNL_OP_ADD_ETH_ADDR = 10,
	VIRTCHNL_OP_DEL_ETH_ADDR = 11,
	VIRTCHNL_OP_ADD_VLAN = 12,
	VIRTCHNL_OP_DEL_VLAN = 13,
	VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE = 14,
	VIRTCHNL_OP_GET_STATS = 15,
	VIRTCHNL_OP_RSVD = 16,
	VIRTCHNL_OP_EVENT = 17, /* must ALWAYS be 17 */
125 126 127
	VIRTCHNL_OP_IWARP = 20, /* advanced opcode */
	VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP = 21, /* advanced opcode */
	VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP = 22, /* advanced opcode */
128 129 130 131
	VIRTCHNL_OP_CONFIG_RSS_KEY = 23,
	VIRTCHNL_OP_CONFIG_RSS_LUT = 24,
	VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25,
	VIRTCHNL_OP_SET_RSS_HENA = 26,
132 133
	VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27,
	VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28,
134
	VIRTCHNL_OP_REQUEST_QUEUES = 29,
135 136
	VIRTCHNL_OP_ENABLE_CHANNELS = 30,
	VIRTCHNL_OP_DISABLE_CHANNELS = 31,
137 138
	VIRTCHNL_OP_ADD_CLOUD_FILTER = 32,
	VIRTCHNL_OP_DEL_CLOUD_FILTER = 33,
Q
Qi Zhang 已提交
139 140 141
	/* opcode 34 - 46 are reserved */
	VIRTCHNL_OP_ADD_FDIR_FILTER = 47,
	VIRTCHNL_OP_DEL_FDIR_FILTER = 48,
142
	VIRTCHNL_OP_MAX,
G
Greg Rose 已提交
143 144
};

145
/* These macros are used to generate compilation errors if a structure/union
146
 * is not exactly the correct length. It gives a divide by zero error if the
147 148
 * structure/union is not of the correct size, otherwise it creates an enum
 * that is never used.
149 150 151
 */
#define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \
	{ virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
152 153
#define VIRTCHNL_CHECK_UNION_LEN(n, X) enum virtchnl_static_asset_enum_##X \
	{ virtchnl_static_assert_##X = (n)/((sizeof(union X) == (n)) ? 1 : 0) }
154

G
Greg Rose 已提交
155 156 157 158
/* Virtual channel message descriptor. This overlays the admin queue
 * descriptor. All other data is passed in external buffers.
 */

159
struct virtchnl_msg {
G
Greg Rose 已提交
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 */
G
Greg Rose 已提交
163 164 165
	u32 vfid;			 /* used by PF when sending to VF */
};

166 167
VIRTCHNL_CHECK_STRUCT_LEN(20, virtchnl_msg);

A
Alice Michael 已提交
168
/* Message descriptions and data structures. */
G
Greg Rose 已提交
169

170
/* VIRTCHNL_OP_VERSION
G
Greg Rose 已提交
171 172 173 174 175 176 177 178 179 180 181
 * VF posts its version number to the PF. PF responds with its version number
 * in the same format, along with a return code.
 * Reply from PF has its major/minor versions also in param0 and param1.
 * If there is a major version mismatch, then the VF cannot operate.
 * If there is a minor version mismatch, then the VF can operate but should
 * add a warning to the system log.
 *
 * This enum element MUST always be specified as == 1, regardless of other
 * changes in the API. The PF must always respond to this message without
 * error regardless of version mismatch.
 */
182 183 184
#define VIRTCHNL_VERSION_MAJOR		1
#define VIRTCHNL_VERSION_MINOR		1
#define VIRTCHNL_VERSION_MINOR_NO_VF_CAPS	0
185

186
struct virtchnl_version_info {
G
Greg Rose 已提交
187 188 189 190
	u32 major;
	u32 minor;
};

191 192
VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_version_info);

193 194 195
#define VF_IS_V10(_v) (((_v)->major == 1) && ((_v)->minor == 0))
#define VF_IS_V11(_ver) (((_ver)->major == 1) && ((_ver)->minor == 1))

196
/* VIRTCHNL_OP_RESET_VF
G
Greg Rose 已提交
197 198 199 200 201 202 203 204 205 206 207
 * VF sends this request to PF with no parameters
 * PF does NOT respond! VF driver must delay then poll VFGEN_RSTAT register
 * until reset completion is indicated. The admin queue must be reinitialized
 * after this operation.
 *
 * When reset is complete, PF must ensure that all queues in all VSIs associated
 * with the VF are stopped, all queue configurations in the HMC are set to 0,
 * and all MAC and VLAN filters (except the default MAC address) on all VSIs
 * are cleared.
 */

208 209 210 211 212 213 214 215 216
/* VSI types that use VIRTCHNL interface for VF-PF communication. VSI_SRIOV
 * vsi_type should always be 6 for backward compatibility. Add other fields
 * as needed.
 */
enum virtchnl_vsi_type {
	VIRTCHNL_VSI_TYPE_INVALID = 0,
	VIRTCHNL_VSI_SRIOV = 6,
};

217
/* VIRTCHNL_OP_GET_VF_RESOURCES
218 219
 * Version 1.0 VF sends this request to PF with no parameters
 * Version 1.1 VF sends this request to PF with u32 bitmap of its capabilities
G
Greg Rose 已提交
220
 * PF responds with an indirect message containing
221 222
 * virtchnl_vf_resource and one or more
 * virtchnl_vsi_resource structures.
G
Greg Rose 已提交
223 224
 */

225
struct virtchnl_vsi_resource {
G
Greg Rose 已提交
226 227
	u16 vsi_id;
	u16 num_queue_pairs;
228
	enum virtchnl_vsi_type vsi_type;
G
Greg Rose 已提交
229 230 231
	u16 qset_handle;
	u8 default_mac_addr[ETH_ALEN];
};
232

233 234
VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);

235
/* VF capability flags
236 237 238 239
 * VIRTCHNL_VF_OFFLOAD_L2 flag is inclusive of base mode L2 offloads including
 * TX/RX Checksum offloading and TSO for non-tunnelled packets.
 */
#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 244
#define VIRTCHNL_VF_OFFLOAD_RSS_REG		0x00000010
#define VIRTCHNL_VF_OFFLOAD_WB_ON_ITR		0x00000020
245
#define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES		0x00000040
246
#define VIRTCHNL_VF_OFFLOAD_VLAN		0x00010000
247
#define VIRTCHNL_VF_OFFLOAD_RX_POLLING		0x00020000
248 249 250
#define VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2	0x00040000
#define VIRTCHNL_VF_OFFLOAD_RSS_PF		0X00080000
#define VIRTCHNL_VF_OFFLOAD_ENCAP		0X00100000
251 252
#define VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM		0X00200000
#define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM	0X00400000
253
#define VIRTCHNL_VF_OFFLOAD_ADQ			0X00800000
254
#define VIRTCHNL_VF_OFFLOAD_USO			0X02000000
Q
Qi Zhang 已提交
255
#define VIRTCHNL_VF_OFFLOAD_FDIR_PF		0X10000000
256

257 258
/* Define below the capability flags that are not offloads */
#define VIRTCHNL_VF_CAP_ADV_LINK_SPEED		0x00000080
259 260 261
#define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \
			       VIRTCHNL_VF_OFFLOAD_VLAN | \
			       VIRTCHNL_VF_OFFLOAD_RSS_PF)
262 263

struct virtchnl_vf_resource {
G
Greg Rose 已提交
264 265 266 267 268
	u16 num_vsis;
	u16 num_queue_pairs;
	u16 max_vectors;
	u16 max_mtu;

269
	u32 vf_cap_flags;
270 271
	u32 rss_key_size;
	u32 rss_lut_size;
G
Greg Rose 已提交
272

273
	struct virtchnl_vsi_resource vsi_res[1];
G
Greg Rose 已提交
274 275
};

276 277
VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_vf_resource);

278
/* VIRTCHNL_OP_CONFIG_TX_QUEUE
G
Greg Rose 已提交
279
 * VF sends this message to set up parameters for one TX queue.
280
 * External data buffer contains one instance of virtchnl_txq_info.
G
Greg Rose 已提交
281 282 283 284
 * PF configures requested queue and returns a status code.
 */

/* Tx queue config info */
285
struct virtchnl_txq_info {
G
Greg Rose 已提交
286 287 288
	u16 vsi_id;
	u16 queue_id;
	u16 ring_len;		/* number of descriptors, multiple of 8 */
289
	u16 headwb_enabled; /* deprecated with AVF 1.0 */
G
Greg Rose 已提交
290
	u64 dma_ring_addr;
291
	u64 dma_headwb_addr; /* deprecated with AVF 1.0 */
G
Greg Rose 已提交
292 293
};

294 295
VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info);

296
/* VIRTCHNL_OP_CONFIG_RX_QUEUE
G
Greg Rose 已提交
297
 * VF sends this message to set up parameters for one RX queue.
298
 * External data buffer contains one instance of virtchnl_rxq_info.
G
Greg Rose 已提交
299 300 301 302
 * PF configures requested queue and returns a status code.
 */

/* Rx queue config info */
303
struct virtchnl_rxq_info {
G
Greg Rose 已提交
304 305 306 307
	u16 vsi_id;
	u16 queue_id;
	u32 ring_len;		/* number of descriptors, multiple of 32 */
	u16 hdr_size;
308
	u16 splithdr_enabled; /* deprecated with AVF 1.0 */
G
Greg Rose 已提交
309 310
	u32 databuffer_size;
	u32 max_pkt_size;
311
	u32 pad1;
G
Greg Rose 已提交
312
	u64 dma_ring_addr;
313
	enum virtchnl_rx_hsplit rx_split_pos; /* deprecated with AVF 1.0 */
314
	u32 pad2;
G
Greg Rose 已提交
315 316
};

317 318
VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_rxq_info);

319
/* VIRTCHNL_OP_CONFIG_VSI_QUEUES
G
Greg Rose 已提交
320 321 322 323 324 325
 * VF sends this message to set parameters for all active TX and RX queues
 * associated with the specified VSI.
 * PF configures queues and returns status.
 * If the number of queues specified is greater than the number of queues
 * associated with the VSI, an error is returned and no queues are configured.
 */
326
struct virtchnl_queue_pair_info {
G
Greg Rose 已提交
327
	/* NOTE: vsi_id and queue_id should be identical for both queues. */
328 329
	struct virtchnl_txq_info txq;
	struct virtchnl_rxq_info rxq;
G
Greg Rose 已提交
330 331
};

332 333
VIRTCHNL_CHECK_STRUCT_LEN(64, virtchnl_queue_pair_info);

334
struct virtchnl_vsi_queue_config_info {
G
Greg Rose 已提交
335 336
	u16 vsi_id;
	u16 num_queue_pairs;
337
	u32 pad;
338
	struct virtchnl_queue_pair_info qpair[1];
G
Greg Rose 已提交
339 340
};

A
Alice Michael 已提交
341 342
VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_vsi_queue_config_info);

343 344 345 346 347 348
/* VIRTCHNL_OP_REQUEST_QUEUES
 * VF sends this message to request the PF to allocate additional queues to
 * this VF.  Each VF gets a guaranteed number of queues on init but asking for
 * additional queues must be negotiated.  This is a best effort request as it
 * is possible the PF does not have enough queues left to support the request.
 * If the PF cannot support the number requested it will respond with the
349 350
 * maximum number it is able to support.  If the request is successful, PF will
 * then reset the VF to institute required changes.
351 352 353 354 355 356 357
 */

/* VF resource request */
struct virtchnl_vf_res_request {
	u16 num_queue_pairs;
};

358
/* VIRTCHNL_OP_CONFIG_IRQ_MAP
G
Greg Rose 已提交
359 360 361 362 363 364
 * VF uses this message to map vectors to queues.
 * The rxq_map and txq_map fields are bitmaps used to indicate which queues
 * are to be associated with the specified vector.
 * The "other" causes are always mapped to vector 0.
 * PF configures interrupt mapping and returns status.
 */
365
struct virtchnl_vector_map {
G
Greg Rose 已提交
366 367 368 369 370 371 372 373
	u16 vsi_id;
	u16 vector_id;
	u16 rxq_map;
	u16 txq_map;
	u16 rxitr_idx;
	u16 txitr_idx;
};

374 375
VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_vector_map);

376
struct virtchnl_irq_map_info {
G
Greg Rose 已提交
377
	u16 num_vectors;
378
	struct virtchnl_vector_map vecmap[1];
G
Greg Rose 已提交
379 380
};

381 382
VIRTCHNL_CHECK_STRUCT_LEN(14, virtchnl_irq_map_info);

383 384
/* VIRTCHNL_OP_ENABLE_QUEUES
 * VIRTCHNL_OP_DISABLE_QUEUES
G
Greg Rose 已提交
385 386 387 388 389 390
 * VF sends these message to enable or disable TX/RX queue pairs.
 * The queues fields are bitmaps indicating which queues to act upon.
 * (Currently, we only support 16 queues per VF, but we make the field
 * u32 to allow for expansion.)
 * PF performs requested action and returns status.
 */
391
struct virtchnl_queue_select {
G
Greg Rose 已提交
392 393 394 395 396 397
	u16 vsi_id;
	u16 pad;
	u32 rx_queues;
	u32 tx_queues;
};

398 399
VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_queue_select);

400
/* VIRTCHNL_OP_ADD_ETH_ADDR
G
Greg Rose 已提交
401 402 403 404 405
 * VF sends this message in order to add one or more unicast or multicast
 * address filters for the specified VSI.
 * PF adds the filters and returns status.
 */

406
/* VIRTCHNL_OP_DEL_ETH_ADDR
G
Greg Rose 已提交
407 408 409 410 411
 * VF sends this message in order to remove one or more unicast or multicast
 * filters for the specified VSI.
 * PF removes the filters and returns status.
 */

412
struct virtchnl_ether_addr {
G
Greg Rose 已提交
413 414 415 416
	u8 addr[ETH_ALEN];
	u8 pad[2];
};

417 418
VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr);

419
struct virtchnl_ether_addr_list {
G
Greg Rose 已提交
420 421
	u16 vsi_id;
	u16 num_elements;
422
	struct virtchnl_ether_addr list[1];
G
Greg Rose 已提交
423 424
};

425 426
VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_ether_addr_list);

427
/* VIRTCHNL_OP_ADD_VLAN
G
Greg Rose 已提交
428 429 430 431 432 433
 * VF sends this message to add one or more VLAN tag filters for receives.
 * PF adds the filters and returns status.
 * If a port VLAN is configured by the PF, this operation will return an
 * error to the VF.
 */

434
/* VIRTCHNL_OP_DEL_VLAN
G
Greg Rose 已提交
435 436 437 438 439 440
 * VF sends this message to remove one or more VLAN tag filters for receives.
 * PF removes the filters and returns status.
 * If a port VLAN is configured by the PF, this operation will return an
 * error to the VF.
 */

441
struct virtchnl_vlan_filter_list {
G
Greg Rose 已提交
442 443 444 445 446
	u16 vsi_id;
	u16 num_elements;
	u16 vlan_id[1];
};

447 448
VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_vlan_filter_list);

449
/* VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE
G
Greg Rose 已提交
450 451 452 453
 * VF sends VSI id and flags.
 * PF returns status code in retval.
 * Note: we assume that broadcast accept mode is always enabled.
 */
454
struct virtchnl_promisc_info {
G
Greg Rose 已提交
455 456 457 458
	u16 vsi_id;
	u16 flags;
};

459 460
VIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_promisc_info);

461 462
#define FLAG_VF_UNICAST_PROMISC	0x00000001
#define FLAG_VF_MULTICAST_PROMISC	0x00000002
G
Greg Rose 已提交
463

464
/* VIRTCHNL_OP_GET_STATS
G
Greg Rose 已提交
465
 * VF sends this message to request stats for the selected VSI. VF uses
466
 * the virtchnl_queue_select struct to specify the VSI. The queue_id
G
Greg Rose 已提交
467 468
 * field is ignored by the PF.
 *
469
 * PF replies with struct eth_stats in an external buffer.
G
Greg Rose 已提交
470 471
 */

472 473
/* VIRTCHNL_OP_CONFIG_RSS_KEY
 * VIRTCHNL_OP_CONFIG_RSS_LUT
474
 * VF sends these messages to configure RSS. Only supported if both PF
475
 * and VF drivers set the VIRTCHNL_VF_OFFLOAD_RSS_PF bit during
476 477 478 479 480
 * configuration negotiation. If this is the case, then the RSS fields in
 * the VF resource struct are valid.
 * Both the key and LUT are initialized to 0 by the PF, meaning that
 * RSS is effectively disabled until set up by the VF.
 */
481
struct virtchnl_rss_key {
482 483 484 485 486
	u16 vsi_id;
	u16 key_len;
	u8 key[1];         /* RSS hash key, packed bytes */
};

487 488
VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_key);

489
struct virtchnl_rss_lut {
490 491
	u16 vsi_id;
	u16 lut_entries;
492
	u8 lut[1];        /* RSS lookup table */
493 494
};

495 496
VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_lut);

497 498
/* VIRTCHNL_OP_GET_RSS_HENA_CAPS
 * VIRTCHNL_OP_SET_RSS_HENA
499 500 501 502 503
 * VF sends these messages to get and set the hash filter enable bits for RSS.
 * By default, the PF sets these to all possible traffic types that the
 * hardware supports. The VF can query this value if it wants to change the
 * traffic types that are hashed by the hardware.
 */
504
struct virtchnl_rss_hena {
505 506 507
	u64 hena;
};

508 509
VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena);

510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
/* VIRTCHNL_OP_ENABLE_CHANNELS
 * VIRTCHNL_OP_DISABLE_CHANNELS
 * VF sends these messages to enable or disable channels based on
 * the user specified queue count and queue offset for each traffic class.
 * This struct encompasses all the information that the PF needs from
 * VF to create a channel.
 */
struct virtchnl_channel_info {
	u16 count; /* number of queues in a channel */
	u16 offset; /* queues in a channel start from 'offset' */
	u32 pad;
	u64 max_tx_rate;
};

VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_channel_info);

struct virtchnl_tc_info {
	u32	num_tc;
	u32	pad;
	struct	virtchnl_channel_info list[1];
};

VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_tc_info);

534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
/* VIRTCHNL_ADD_CLOUD_FILTER
 * VIRTCHNL_DEL_CLOUD_FILTER
 * VF sends these messages to add or delete a cloud filter based on the
 * user specified match and action filters. These structures encompass
 * all the information that the PF needs from the VF to add/delete a
 * cloud filter.
 */

struct virtchnl_l4_spec {
	u8	src_mac[ETH_ALEN];
	u8	dst_mac[ETH_ALEN];
	__be16	vlan_id;
	__be16	pad; /* reserved for future use */
	__be32	src_ip[4];
	__be32	dst_ip[4];
	__be16	src_port;
	__be16	dst_port;
};

VIRTCHNL_CHECK_STRUCT_LEN(52, virtchnl_l4_spec);

union virtchnl_flow_spec {
	struct	virtchnl_l4_spec tcp_spec;
	u8	buffer[128]; /* reserved for future use */
};

VIRTCHNL_CHECK_UNION_LEN(128, virtchnl_flow_spec);

enum virtchnl_action {
	/* action types */
	VIRTCHNL_ACTION_DROP = 0,
	VIRTCHNL_ACTION_TC_REDIRECT,
Q
Qi Zhang 已提交
566 567 568 569 570
	VIRTCHNL_ACTION_PASSTHRU,
	VIRTCHNL_ACTION_QUEUE,
	VIRTCHNL_ACTION_Q_REGION,
	VIRTCHNL_ACTION_MARK,
	VIRTCHNL_ACTION_COUNT,
571 572 573 574 575 576 577 578 579 580 581 582 583 584
};

enum virtchnl_flow_type {
	/* flow types */
	VIRTCHNL_TCP_V4_FLOW = 0,
	VIRTCHNL_TCP_V6_FLOW,
};

struct virtchnl_filter {
	union	virtchnl_flow_spec data;
	union	virtchnl_flow_spec mask;
	enum	virtchnl_flow_type flow_type;
	enum	virtchnl_action action;
	u32	action_meta;
585
	u8	field_flags;
586
	u8	pad[3];
587 588 589 590
};

VIRTCHNL_CHECK_STRUCT_LEN(272, virtchnl_filter);

591
/* VIRTCHNL_OP_EVENT
G
Greg Rose 已提交
592 593 594 595
 * PF sends this message to inform the VF driver of events that may affect it.
 * No direct response is expected from the VF, though it may generate other
 * messages in response to this one.
 */
596 597 598 599 600
enum virtchnl_event_codes {
	VIRTCHNL_EVENT_UNKNOWN = 0,
	VIRTCHNL_EVENT_LINK_CHANGE,
	VIRTCHNL_EVENT_RESET_IMPENDING,
	VIRTCHNL_EVENT_PF_DRIVER_CLOSE,
G
Greg Rose 已提交
601
};
602 603 604

#define PF_EVENT_SEVERITY_INFO		0
#define PF_EVENT_SEVERITY_CERTAIN_DOOM	255
G
Greg Rose 已提交
605

606 607
struct virtchnl_pf_event {
	enum virtchnl_event_codes event;
G
Greg Rose 已提交
608
	union {
609 610 611 612 613 614 615 616
		/* If the PF driver does not support the new speed reporting
		 * capabilities then use link_event else use link_event_adv to
		 * get the speed and link information. The ability to understand
		 * new speeds is indicated by setting the capability flag
		 * VIRTCHNL_VF_CAP_ADV_LINK_SPEED in vf_cap_flags parameter
		 * in virtchnl_vf_resource struct and can be used to determine
		 * which link event struct to use below.
		 */
G
Greg Rose 已提交
617
		struct {
618
			enum virtchnl_link_speed link_speed;
G
Greg Rose 已提交
619 620
			bool link_status;
		} link_event;
621 622 623 624
		struct {
			/* link_speed provided in Mbps */
			u32 link_speed;
			u8 link_status;
625
			u8 pad[3];
626
		} link_event_adv;
G
Greg Rose 已提交
627 628 629 630 631
	} event_data;

	int severity;
};

632 633
VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_pf_event);

634
/* VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP
M
Mitch Williams 已提交
635 636 637 638 639 640 641 642 643 644 645
 * VF uses this message to request PF to map IWARP vectors to IWARP queues.
 * The request for this originates from the VF IWARP driver through
 * a client interface between VF LAN and VF IWARP driver.
 * A vector could have an AEQ and CEQ attached to it although
 * there is a single AEQ per VF IWARP instance in which case
 * most vectors will have an INVALID_IDX for aeq and valid idx for ceq.
 * There will never be a case where there will be multiple CEQs attached
 * to a single vector.
 * PF configures interrupt mapping and returns status.
 */

646
struct virtchnl_iwarp_qv_info {
M
Mitch Williams 已提交
647 648 649 650
	u32 v_idx; /* msix_vector */
	u16 ceq_idx;
	u16 aeq_idx;
	u8 itr_idx;
651
	u8 pad[3];
M
Mitch Williams 已提交
652 653
};

654 655
VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_iwarp_qv_info);

656
struct virtchnl_iwarp_qvlist_info {
M
Mitch Williams 已提交
657
	u32 num_vectors;
658
	struct virtchnl_iwarp_qv_info qv_info[1];
M
Mitch Williams 已提交
659 660
};

661 662
VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_iwarp_qvlist_info);

G
Greg Rose 已提交
663
/* VF reset states - these are written into the RSTAT register:
664
 * VFGEN_RSTAT on the VF
G
Greg Rose 已提交
665 666 667 668 669 670 671 672 673
 * When the PF initiates a reset, it writes 0
 * When the reset is complete, it writes 1
 * When the PF detects that the VF has recovered, it writes 2
 * VF checks this register periodically to determine if a reset has occurred,
 * then polls it to know when the reset is complete.
 * If either the PF or VF reads the register while the hardware
 * is in a reset state, it will return DEADBEEF, which, when masked
 * will result in 3.
 */
674 675 676 677
enum virtchnl_vfr_states {
	VIRTCHNL_VFR_INPROGRESS = 0,
	VIRTCHNL_VFR_COMPLETED,
	VIRTCHNL_VFR_VFACTIVE,
G
Greg Rose 已提交
678 679
};

Q
Qi Zhang 已提交
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
#define VIRTCHNL_MAX_NUM_PROTO_HDRS	32
#define PROTO_HDR_SHIFT			5
#define PROTO_HDR_FIELD_START(proto_hdr_type) ((proto_hdr_type) << PROTO_HDR_SHIFT)
#define PROTO_HDR_FIELD_MASK ((1UL << PROTO_HDR_SHIFT) - 1)

/* VF use these macros to configure each protocol header.
 * Specify which protocol headers and protocol header fields base on
 * virtchnl_proto_hdr_type and virtchnl_proto_hdr_field.
 * @param hdr: a struct of virtchnl_proto_hdr
 * @param hdr_type: ETH/IPV4/TCP, etc
 * @param field: SRC/DST/TEID/SPI, etc
 */
#define VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, field) \
	((hdr)->field_selector |= BIT((field) & PROTO_HDR_FIELD_MASK))
#define VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, field) \
	((hdr)->field_selector &= ~BIT((field) & PROTO_HDR_FIELD_MASK))
#define VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val) \
	((hdr)->field_selector & BIT((val) & PROTO_HDR_FIELD_MASK))
#define VIRTCHNL_GET_PROTO_HDR_FIELD(hdr)	((hdr)->field_selector)

#define VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
	(VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, \
		VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field))
#define VIRTCHNL_DEL_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
	(VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, \
		VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field))

#define VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, hdr_type) \
	((hdr)->type = VIRTCHNL_PROTO_HDR_ ## hdr_type)
#define VIRTCHNL_GET_PROTO_HDR_TYPE(hdr) \
	(((hdr)->type) >> PROTO_HDR_SHIFT)
#define VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) \
	((hdr)->type == ((val) >> PROTO_HDR_SHIFT))
#define VIRTCHNL_TEST_PROTO_HDR(hdr, val) \
	(VIRTCHNL_TEST_PROTO_HDR_TYPE((hdr), (val)) && \
	 VIRTCHNL_TEST_PROTO_HDR_FIELD((hdr), (val)))

/* Protocol header type within a packet segment. A segment consists of one or
 * more protocol headers that make up a logical group of protocol headers. Each
 * logical group of protocol headers encapsulates or is encapsulated using/by
 * tunneling or encapsulation protocols for network virtualization.
 */
enum virtchnl_proto_hdr_type {
	VIRTCHNL_PROTO_HDR_NONE,
	VIRTCHNL_PROTO_HDR_ETH,
	VIRTCHNL_PROTO_HDR_S_VLAN,
	VIRTCHNL_PROTO_HDR_C_VLAN,
	VIRTCHNL_PROTO_HDR_IPV4,
	VIRTCHNL_PROTO_HDR_IPV6,
	VIRTCHNL_PROTO_HDR_TCP,
	VIRTCHNL_PROTO_HDR_UDP,
	VIRTCHNL_PROTO_HDR_SCTP,
	VIRTCHNL_PROTO_HDR_GTPU_IP,
	VIRTCHNL_PROTO_HDR_GTPU_EH,
	VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN,
	VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP,
	VIRTCHNL_PROTO_HDR_PPPOE,
	VIRTCHNL_PROTO_HDR_L2TPV3,
	VIRTCHNL_PROTO_HDR_ESP,
	VIRTCHNL_PROTO_HDR_AH,
	VIRTCHNL_PROTO_HDR_PFCP,
};

/* Protocol header field within a protocol header. */
enum virtchnl_proto_hdr_field {
	/* ETHER */
	VIRTCHNL_PROTO_HDR_ETH_SRC =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ETH),
	VIRTCHNL_PROTO_HDR_ETH_DST,
	VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE,
	/* S-VLAN */
	VIRTCHNL_PROTO_HDR_S_VLAN_ID =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_S_VLAN),
	/* C-VLAN */
	VIRTCHNL_PROTO_HDR_C_VLAN_ID =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_C_VLAN),
	/* IPV4 */
	VIRTCHNL_PROTO_HDR_IPV4_SRC =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV4),
	VIRTCHNL_PROTO_HDR_IPV4_DST,
	VIRTCHNL_PROTO_HDR_IPV4_DSCP,
	VIRTCHNL_PROTO_HDR_IPV4_TTL,
	VIRTCHNL_PROTO_HDR_IPV4_PROT,
	/* IPV6 */
	VIRTCHNL_PROTO_HDR_IPV6_SRC =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV6),
	VIRTCHNL_PROTO_HDR_IPV6_DST,
	VIRTCHNL_PROTO_HDR_IPV6_TC,
	VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT,
	VIRTCHNL_PROTO_HDR_IPV6_PROT,
	/* TCP */
	VIRTCHNL_PROTO_HDR_TCP_SRC_PORT =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_TCP),
	VIRTCHNL_PROTO_HDR_TCP_DST_PORT,
	/* UDP */
	VIRTCHNL_PROTO_HDR_UDP_SRC_PORT =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_UDP),
	VIRTCHNL_PROTO_HDR_UDP_DST_PORT,
	/* SCTP */
	VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_SCTP),
	VIRTCHNL_PROTO_HDR_SCTP_DST_PORT,
	/* GTPU_IP */
	VIRTCHNL_PROTO_HDR_GTPU_IP_TEID =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_IP),
	/* GTPU_EH */
	VIRTCHNL_PROTO_HDR_GTPU_EH_PDU =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_EH),
	VIRTCHNL_PROTO_HDR_GTPU_EH_QFI,
	/* PPPOE */
	VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PPPOE),
	/* L2TPV3 */
	VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_L2TPV3),
	/* ESP */
	VIRTCHNL_PROTO_HDR_ESP_SPI =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ESP),
	/* AH */
	VIRTCHNL_PROTO_HDR_AH_SPI =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_AH),
	/* PFCP */
	VIRTCHNL_PROTO_HDR_PFCP_S_FIELD =
		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PFCP),
	VIRTCHNL_PROTO_HDR_PFCP_SEID,
};

struct virtchnl_proto_hdr {
	enum virtchnl_proto_hdr_type type;
	u32 field_selector; /* a bit mask to select field for header type */
	u8 buffer[64];
	/**
	 * binary buffer in network order for specific header type.
	 * For example, if type = VIRTCHNL_PROTO_HDR_IPV4, a IPv4
	 * header is expected to be copied into the buffer.
	 */
};

VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_proto_hdr);

struct virtchnl_proto_hdrs {
	u8 tunnel_level;
	/**
	 * specify where protocol header start from.
	 * 0 - from the outer layer
	 * 1 - from the first inner layer
	 * 2 - from the second inner layer
	 * ....
	 **/
	int count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */
	struct virtchnl_proto_hdr proto_hdr[VIRTCHNL_MAX_NUM_PROTO_HDRS];
};

VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);

/* action configuration for FDIR */
struct virtchnl_filter_action {
	enum virtchnl_action type;
	union {
		/* used for queue and qgroup action */
		struct {
			u16 index;
			u8 region;
		} queue;
		/* used for count action */
		struct {
			/* share counter ID with other flow rules */
			u8 shared;
			u32 id; /* counter ID */
		} count;
		/* used for mark action */
		u32 mark_id;
		u8 reserve[32];
	} act_conf;
};

VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_filter_action);

#define VIRTCHNL_MAX_NUM_ACTIONS  8

struct virtchnl_filter_action_set {
	/* action number must be less then VIRTCHNL_MAX_NUM_ACTIONS */
	int count;
	struct virtchnl_filter_action actions[VIRTCHNL_MAX_NUM_ACTIONS];
};

VIRTCHNL_CHECK_STRUCT_LEN(292, virtchnl_filter_action_set);

/* pattern and action for FDIR rule */
struct virtchnl_fdir_rule {
	struct virtchnl_proto_hdrs proto_hdrs;
	struct virtchnl_filter_action_set action_set;
};

VIRTCHNL_CHECK_STRUCT_LEN(2604, virtchnl_fdir_rule);

/* Status returned to VF after VF requests FDIR commands
 * VIRTCHNL_FDIR_SUCCESS
 * VF FDIR related request is successfully done by PF
 * The request can be OP_ADD/DEL.
 *
 * VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE
 * OP_ADD_FDIR_FILTER request is failed due to no Hardware resource.
 *
 * VIRTCHNL_FDIR_FAILURE_RULE_EXIST
 * OP_ADD_FDIR_FILTER request is failed due to the rule is already existed.
 *
 * VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT
 * OP_ADD_FDIR_FILTER request is failed due to conflict with existing rule.
 *
 * VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST
 * OP_DEL_FDIR_FILTER request is failed due to this rule doesn't exist.
 *
 * VIRTCHNL_FDIR_FAILURE_RULE_INVALID
 * OP_ADD_FDIR_FILTER request is failed due to parameters validation
 * or HW doesn't support.
 *
 * VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT
 * OP_ADD/DEL_FDIR_FILTER request is failed due to timing out
 * for programming.
 */
enum virtchnl_fdir_prgm_status {
	VIRTCHNL_FDIR_SUCCESS = 0,
	VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE,
	VIRTCHNL_FDIR_FAILURE_RULE_EXIST,
	VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT,
	VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST,
	VIRTCHNL_FDIR_FAILURE_RULE_INVALID,
	VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT,
};

/* VIRTCHNL_OP_ADD_FDIR_FILTER
 * VF sends this request to PF by filling out vsi_id,
 * validate_only and rule_cfg. PF will return flow_id
 * if the request is successfully done and return add_status to VF.
 */
struct virtchnl_fdir_add {
	u16 vsi_id;  /* INPUT */
	/*
	 * 1 for validating a fdir rule, 0 for creating a fdir rule.
	 * Validate and create share one ops: VIRTCHNL_OP_ADD_FDIR_FILTER.
	 */
	u16 validate_only; /* INPUT */
	u32 flow_id;       /* OUTPUT */
	struct virtchnl_fdir_rule rule_cfg; /* INPUT */
	enum virtchnl_fdir_prgm_status status; /* OUTPUT */
};

VIRTCHNL_CHECK_STRUCT_LEN(2616, virtchnl_fdir_add);

/* VIRTCHNL_OP_DEL_FDIR_FILTER
 * VF sends this request to PF by filling out vsi_id
 * and flow_id. PF will return del_status to VF.
 */
struct virtchnl_fdir_del {
	u16 vsi_id;  /* INPUT */
	u16 pad;
	u32 flow_id; /* INPUT */
	enum virtchnl_fdir_prgm_status status; /* OUTPUT */
};

VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_fdir_del);

943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
/**
 * virtchnl_vc_validate_vf_msg
 * @ver: Virtchnl version info
 * @v_opcode: Opcode for the message
 * @msg: pointer to the msg buffer
 * @msglen: msg length
 *
 * validate msg format against struct for each opcode
 */
static inline int
virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
			    u8 *msg, u16 msglen)
{
	bool err_msg_format = false;
	int valid_len = 0;

	/* Validate message length. */
	switch (v_opcode) {
	case VIRTCHNL_OP_VERSION:
		valid_len = sizeof(struct virtchnl_version_info);
		break;
	case VIRTCHNL_OP_RESET_VF:
		break;
	case VIRTCHNL_OP_GET_VF_RESOURCES:
		if (VF_IS_V11(ver))
			valid_len = sizeof(u32);
		break;
	case VIRTCHNL_OP_CONFIG_TX_QUEUE:
		valid_len = sizeof(struct virtchnl_txq_info);
		break;
	case VIRTCHNL_OP_CONFIG_RX_QUEUE:
		valid_len = sizeof(struct virtchnl_rxq_info);
		break;
	case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
		valid_len = sizeof(struct virtchnl_vsi_queue_config_info);
		if (msglen >= valid_len) {
			struct virtchnl_vsi_queue_config_info *vqc =
			    (struct virtchnl_vsi_queue_config_info *)msg;
			valid_len += (vqc->num_queue_pairs *
				      sizeof(struct
					     virtchnl_queue_pair_info));
			if (vqc->num_queue_pairs == 0)
				err_msg_format = true;
		}
		break;
	case VIRTCHNL_OP_CONFIG_IRQ_MAP:
		valid_len = sizeof(struct virtchnl_irq_map_info);
		if (msglen >= valid_len) {
			struct virtchnl_irq_map_info *vimi =
			    (struct virtchnl_irq_map_info *)msg;
			valid_len += (vimi->num_vectors *
				      sizeof(struct virtchnl_vector_map));
			if (vimi->num_vectors == 0)
				err_msg_format = true;
		}
		break;
	case VIRTCHNL_OP_ENABLE_QUEUES:
	case VIRTCHNL_OP_DISABLE_QUEUES:
		valid_len = sizeof(struct virtchnl_queue_select);
		break;
	case VIRTCHNL_OP_ADD_ETH_ADDR:
	case VIRTCHNL_OP_DEL_ETH_ADDR:
		valid_len = sizeof(struct virtchnl_ether_addr_list);
		if (msglen >= valid_len) {
			struct virtchnl_ether_addr_list *veal =
			    (struct virtchnl_ether_addr_list *)msg;
			valid_len += veal->num_elements *
			    sizeof(struct virtchnl_ether_addr);
			if (veal->num_elements == 0)
				err_msg_format = true;
		}
		break;
	case VIRTCHNL_OP_ADD_VLAN:
	case VIRTCHNL_OP_DEL_VLAN:
		valid_len = sizeof(struct virtchnl_vlan_filter_list);
		if (msglen >= valid_len) {
			struct virtchnl_vlan_filter_list *vfl =
			    (struct virtchnl_vlan_filter_list *)msg;
			valid_len += vfl->num_elements * sizeof(u16);
			if (vfl->num_elements == 0)
				err_msg_format = true;
		}
		break;
	case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
		valid_len = sizeof(struct virtchnl_promisc_info);
		break;
	case VIRTCHNL_OP_GET_STATS:
		valid_len = sizeof(struct virtchnl_queue_select);
		break;
	case VIRTCHNL_OP_IWARP:
		/* These messages are opaque to us and will be validated in
		 * the RDMA client code. We just need to check for nonzero
		 * length. The firmware will enforce max length restrictions.
		 */
		if (msglen)
			valid_len = msglen;
		else
			err_msg_format = true;
		break;
	case VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP:
		break;
	case VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP:
		valid_len = sizeof(struct virtchnl_iwarp_qvlist_info);
		if (msglen >= valid_len) {
			struct virtchnl_iwarp_qvlist_info *qv =
				(struct virtchnl_iwarp_qvlist_info *)msg;
			if (qv->num_vectors == 0) {
				err_msg_format = true;
				break;
			}
			valid_len += ((qv->num_vectors - 1) *
				sizeof(struct virtchnl_iwarp_qv_info));
		}
		break;
	case VIRTCHNL_OP_CONFIG_RSS_KEY:
		valid_len = sizeof(struct virtchnl_rss_key);
		if (msglen >= valid_len) {
			struct virtchnl_rss_key *vrk =
				(struct virtchnl_rss_key *)msg;
			valid_len += vrk->key_len - 1;
		}
		break;
	case VIRTCHNL_OP_CONFIG_RSS_LUT:
		valid_len = sizeof(struct virtchnl_rss_lut);
		if (msglen >= valid_len) {
			struct virtchnl_rss_lut *vrl =
				(struct virtchnl_rss_lut *)msg;
			valid_len += vrl->lut_entries - 1;
		}
		break;
	case VIRTCHNL_OP_GET_RSS_HENA_CAPS:
		break;
	case VIRTCHNL_OP_SET_RSS_HENA:
		valid_len = sizeof(struct virtchnl_rss_hena);
		break;
1078 1079 1080
	case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
	case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
		break;
1081 1082 1083
	case VIRTCHNL_OP_REQUEST_QUEUES:
		valid_len = sizeof(struct virtchnl_vf_res_request);
		break;
1084 1085 1086 1087 1088
	case VIRTCHNL_OP_ENABLE_CHANNELS:
		valid_len = sizeof(struct virtchnl_tc_info);
		if (msglen >= valid_len) {
			struct virtchnl_tc_info *vti =
				(struct virtchnl_tc_info *)msg;
A
Alice Michael 已提交
1089 1090
			valid_len += (vti->num_tc - 1) *
				     sizeof(struct virtchnl_channel_info);
1091 1092 1093 1094 1095 1096
			if (vti->num_tc == 0)
				err_msg_format = true;
		}
		break;
	case VIRTCHNL_OP_DISABLE_CHANNELS:
		break;
1097 1098 1099 1100 1101 1102
	case VIRTCHNL_OP_ADD_CLOUD_FILTER:
		valid_len = sizeof(struct virtchnl_filter);
		break;
	case VIRTCHNL_OP_DEL_CLOUD_FILTER:
		valid_len = sizeof(struct virtchnl_filter);
		break;
Q
Qi Zhang 已提交
1103 1104 1105 1106 1107 1108
	case VIRTCHNL_OP_ADD_FDIR_FILTER:
		valid_len = sizeof(struct virtchnl_fdir_add);
		break;
	case VIRTCHNL_OP_DEL_FDIR_FILTER:
		valid_len = sizeof(struct virtchnl_fdir_del);
		break;
1109 1110 1111 1112
	/* These are always errors coming from the VF. */
	case VIRTCHNL_OP_EVENT:
	case VIRTCHNL_OP_UNKNOWN:
	default:
M
Mitch Williams 已提交
1113
		return VIRTCHNL_STATUS_ERR_PARAM;
1114 1115
	}
	/* few more checks */
1116
	if (err_msg_format || valid_len != msglen)
1117 1118 1119 1120
		return VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH;

	return 0;
}
1121
#endif /* _VIRTCHNL_H_ */