virtchnl.h 22.9 KB
Newer Older
G
Greg Rose 已提交
1 2 3
/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
4
 * Copyright(c) 2013 - 2014 Intel Corporation.
G
Greg Rose 已提交
5 6 7 8 9 10 11 12 13 14
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
15 16 17
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
G
Greg Rose 已提交
18 19 20 21 22 23 24 25 26
 * The full GNU General Public License is included in this distribution in
 * the file called "COPYING".
 *
 * Contact Information:
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 ******************************************************************************/

27 28
#ifndef _VIRTCHNL_H_
#define _VIRTCHNL_H_
G
Greg Rose 已提交
29 30 31

/* Description:
 * This header file describes the VF-PF communication protocol used
32
 * by the drivers for all devices starting from our 40G product line
G
Greg Rose 已提交
33 34
 *
 * Admin queue buffer usage:
35
 * desc->opcode is always aqc_opc_send_msg_to_pf
G
Greg Rose 已提交
36
 * flags, retval, datalen, and data addr are all used normally.
37 38 39
 * 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 已提交
40
 *
41
 * All the VSI indexes are relative to the VF. Each VF can have maximum of
G
Greg Rose 已提交
42 43 44 45
 * 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
46 47
 * 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 已提交
48
 *
49 50 51 52 53 54
 * 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 已提交
55 56
 */

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
/* 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,
	VIRTCHNL_ERR_PARAM				= -5,
	VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH		= -38,
	VIRTCHNL_STATUS_ERR_CQP_COMPL_ERROR		= -39,
	VIRTCHNL_STATUS_ERR_INVALID_VF_ID		= -40,
	VIRTCHNL_STATUS_NOT_SUPPORTED			= -64,
};

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
#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

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),
};

/* 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,
};

99 100
/* END GENERIC DEFINES */

G
Greg Rose 已提交
101 102 103
/* Opcodes for VF-PF communication. These are placed in the v_opcode field
 * of the virtchnl_msg structure.
 */
104
enum virtchnl_ops {
105
/* The PF sends status change events to VFs using
106
 * the VIRTCHNL_OP_EVENT opcode.
107
 * VFs send requests to the PF using the other ops.
108 109
 * 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 已提交
110
 */
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
	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 */
129 130 131
	VIRTCHNL_OP_IWARP = 20, /* advanced opcode */
	VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP = 21, /* advanced opcode */
	VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP = 22, /* advanced opcode */
132 133 134 135
	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,
136 137
	VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27,
	VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28,
138
	VIRTCHNL_OP_REQUEST_QUEUES = 29,
G
Greg Rose 已提交
139 140
};

141 142 143 144 145 146 147 148
/* This macro is used to generate a compilation error if a structure
 * is not exactly the correct length. It gives a divide by zero error if the
 * structure is not of the correct size, otherwise it creates an enum that is
 * never used.
 */
#define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \
	{ virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }

G
Greg Rose 已提交
149 150 151 152
/* Virtual channel message descriptor. This overlays the admin queue
 * descriptor. All other data is passed in external buffers.
 */

153
struct virtchnl_msg {
G
Greg Rose 已提交
154
	u8 pad[8];			 /* AQ flags/opcode/len/retval fields */
155
	enum virtchnl_ops v_opcode; /* avoid confusion with desc->opcode */
156
	enum virtchnl_status_code v_retval;  /* ditto for desc->retval */
G
Greg Rose 已提交
157 158 159
	u32 vfid;			 /* used by PF when sending to VF */
};

160 161
VIRTCHNL_CHECK_STRUCT_LEN(20, virtchnl_msg);

G
Greg Rose 已提交
162 163
/* Message descriptions and data structures.*/

164
/* VIRTCHNL_OP_VERSION
G
Greg Rose 已提交
165 166 167 168 169 170 171 172 173 174 175
 * 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.
 */
176 177 178
#define VIRTCHNL_VERSION_MAJOR		1
#define VIRTCHNL_VERSION_MINOR		1
#define VIRTCHNL_VERSION_MINOR_NO_VF_CAPS	0
179

180
struct virtchnl_version_info {
G
Greg Rose 已提交
181 182 183 184
	u32 major;
	u32 minor;
};

185 186
VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_version_info);

187 188 189
#define VF_IS_V10(_v) (((_v)->major == 1) && ((_v)->minor == 0))
#define VF_IS_V11(_ver) (((_ver)->major == 1) && ((_ver)->minor == 1))

190
/* VIRTCHNL_OP_RESET_VF
G
Greg Rose 已提交
191 192 193 194 195 196 197 198 199 200 201
 * 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.
 */

202 203 204 205 206 207 208 209 210
/* 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,
};

211
/* VIRTCHNL_OP_GET_VF_RESOURCES
212 213
 * 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 已提交
214
 * PF responds with an indirect message containing
215 216
 * virtchnl_vf_resource and one or more
 * virtchnl_vsi_resource structures.
G
Greg Rose 已提交
217 218
 */

219
struct virtchnl_vsi_resource {
G
Greg Rose 已提交
220 221
	u16 vsi_id;
	u16 num_queue_pairs;
222
	enum virtchnl_vsi_type vsi_type;
G
Greg Rose 已提交
223 224 225
	u16 qset_handle;
	u8 default_mac_addr[ETH_ALEN];
};
226

227 228
VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);

229
/* VF capability flags
230 231 232 233
 * 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
234
#define VIRTCHNL_VF_OFFLOAD_IWARP		0x00000002
235
#define VIRTCHNL_VF_OFFLOAD_RSVD		0x00000004
236
#define VIRTCHNL_VF_OFFLOAD_RSS_AQ		0x00000008
237 238
#define VIRTCHNL_VF_OFFLOAD_RSS_REG		0x00000010
#define VIRTCHNL_VF_OFFLOAD_WB_ON_ITR		0x00000020
239
#define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES		0x00000040
240
#define VIRTCHNL_VF_OFFLOAD_VLAN		0x00010000
241
#define VIRTCHNL_VF_OFFLOAD_RX_POLLING		0x00020000
242 243 244
#define VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2	0x00040000
#define VIRTCHNL_VF_OFFLOAD_RSS_PF		0X00080000
#define VIRTCHNL_VF_OFFLOAD_ENCAP		0X00100000
245 246
#define VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM		0X00200000
#define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM	0X00400000
247

248 249 250
#define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \
			       VIRTCHNL_VF_OFFLOAD_VLAN | \
			       VIRTCHNL_VF_OFFLOAD_RSS_PF)
251 252

struct virtchnl_vf_resource {
G
Greg Rose 已提交
253 254 255 256 257
	u16 num_vsis;
	u16 num_queue_pairs;
	u16 max_vectors;
	u16 max_mtu;

258
	u32 vf_cap_flags;
259 260
	u32 rss_key_size;
	u32 rss_lut_size;
G
Greg Rose 已提交
261

262
	struct virtchnl_vsi_resource vsi_res[1];
G
Greg Rose 已提交
263 264
};

265 266
VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_vf_resource);

267
/* VIRTCHNL_OP_CONFIG_TX_QUEUE
G
Greg Rose 已提交
268
 * VF sends this message to set up parameters for one TX queue.
269
 * External data buffer contains one instance of virtchnl_txq_info.
G
Greg Rose 已提交
270 271 272 273
 * PF configures requested queue and returns a status code.
 */

/* Tx queue config info */
274
struct virtchnl_txq_info {
G
Greg Rose 已提交
275 276 277
	u16 vsi_id;
	u16 queue_id;
	u16 ring_len;		/* number of descriptors, multiple of 8 */
278
	u16 headwb_enabled; /* deprecated with AVF 1.0 */
G
Greg Rose 已提交
279
	u64 dma_ring_addr;
280
	u64 dma_headwb_addr; /* deprecated with AVF 1.0 */
G
Greg Rose 已提交
281 282
};

283 284
VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info);

285
/* VIRTCHNL_OP_CONFIG_RX_QUEUE
G
Greg Rose 已提交
286
 * VF sends this message to set up parameters for one RX queue.
287
 * External data buffer contains one instance of virtchnl_rxq_info.
G
Greg Rose 已提交
288 289 290 291
 * PF configures requested queue and returns a status code.
 */

/* Rx queue config info */
292
struct virtchnl_rxq_info {
G
Greg Rose 已提交
293 294 295 296
	u16 vsi_id;
	u16 queue_id;
	u32 ring_len;		/* number of descriptors, multiple of 32 */
	u16 hdr_size;
297
	u16 splithdr_enabled; /* deprecated with AVF 1.0 */
G
Greg Rose 已提交
298 299
	u32 databuffer_size;
	u32 max_pkt_size;
300
	u32 pad1;
G
Greg Rose 已提交
301
	u64 dma_ring_addr;
302
	enum virtchnl_rx_hsplit rx_split_pos; /* deprecated with AVF 1.0 */
303
	u32 pad2;
G
Greg Rose 已提交
304 305
};

306 307
VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_rxq_info);

308
/* VIRTCHNL_OP_CONFIG_VSI_QUEUES
G
Greg Rose 已提交
309 310 311 312 313 314
 * 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.
 */
315
struct virtchnl_queue_pair_info {
G
Greg Rose 已提交
316
	/* NOTE: vsi_id and queue_id should be identical for both queues. */
317 318
	struct virtchnl_txq_info txq;
	struct virtchnl_rxq_info rxq;
G
Greg Rose 已提交
319 320
};

321 322
VIRTCHNL_CHECK_STRUCT_LEN(64, virtchnl_queue_pair_info);

323
struct virtchnl_vsi_queue_config_info {
G
Greg Rose 已提交
324 325
	u16 vsi_id;
	u16 num_queue_pairs;
326
	u32 pad;
327
	struct virtchnl_queue_pair_info qpair[1];
G
Greg Rose 已提交
328 329
};

330 331 332 333 334 335
/* 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
336 337
 * maximum number it is able to support.  If the request is successful, PF will
 * then reset the VF to institute required changes.
338 339 340 341 342 343 344
 */

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

345 346
VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_vsi_queue_config_info);

347
/* VIRTCHNL_OP_CONFIG_IRQ_MAP
G
Greg Rose 已提交
348 349 350 351 352 353
 * 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.
 */
354
struct virtchnl_vector_map {
G
Greg Rose 已提交
355 356 357 358 359 360 361 362
	u16 vsi_id;
	u16 vector_id;
	u16 rxq_map;
	u16 txq_map;
	u16 rxitr_idx;
	u16 txitr_idx;
};

363 364
VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_vector_map);

365
struct virtchnl_irq_map_info {
G
Greg Rose 已提交
366
	u16 num_vectors;
367
	struct virtchnl_vector_map vecmap[1];
G
Greg Rose 已提交
368 369
};

370 371
VIRTCHNL_CHECK_STRUCT_LEN(14, virtchnl_irq_map_info);

372 373
/* VIRTCHNL_OP_ENABLE_QUEUES
 * VIRTCHNL_OP_DISABLE_QUEUES
G
Greg Rose 已提交
374 375 376 377 378 379
 * 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.
 */
380
struct virtchnl_queue_select {
G
Greg Rose 已提交
381 382 383 384 385 386
	u16 vsi_id;
	u16 pad;
	u32 rx_queues;
	u32 tx_queues;
};

387 388
VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_queue_select);

389
/* VIRTCHNL_OP_ADD_ETH_ADDR
G
Greg Rose 已提交
390 391 392 393 394
 * 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.
 */

395
/* VIRTCHNL_OP_DEL_ETH_ADDR
G
Greg Rose 已提交
396 397 398 399 400
 * 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.
 */

401
struct virtchnl_ether_addr {
G
Greg Rose 已提交
402 403 404 405
	u8 addr[ETH_ALEN];
	u8 pad[2];
};

406 407
VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr);

408
struct virtchnl_ether_addr_list {
G
Greg Rose 已提交
409 410
	u16 vsi_id;
	u16 num_elements;
411
	struct virtchnl_ether_addr list[1];
G
Greg Rose 已提交
412 413
};

414 415
VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_ether_addr_list);

416
/* VIRTCHNL_OP_ADD_VLAN
G
Greg Rose 已提交
417 418 419 420 421 422
 * 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.
 */

423
/* VIRTCHNL_OP_DEL_VLAN
G
Greg Rose 已提交
424 425 426 427 428 429
 * 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.
 */

430
struct virtchnl_vlan_filter_list {
G
Greg Rose 已提交
431 432 433 434 435
	u16 vsi_id;
	u16 num_elements;
	u16 vlan_id[1];
};

436 437
VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_vlan_filter_list);

438
/* VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE
G
Greg Rose 已提交
439 440 441 442
 * VF sends VSI id and flags.
 * PF returns status code in retval.
 * Note: we assume that broadcast accept mode is always enabled.
 */
443
struct virtchnl_promisc_info {
G
Greg Rose 已提交
444 445 446 447
	u16 vsi_id;
	u16 flags;
};

448 449
VIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_promisc_info);

450 451
#define FLAG_VF_UNICAST_PROMISC	0x00000001
#define FLAG_VF_MULTICAST_PROMISC	0x00000002
G
Greg Rose 已提交
452

453
/* VIRTCHNL_OP_GET_STATS
G
Greg Rose 已提交
454
 * VF sends this message to request stats for the selected VSI. VF uses
455
 * the virtchnl_queue_select struct to specify the VSI. The queue_id
G
Greg Rose 已提交
456 457
 * field is ignored by the PF.
 *
458
 * PF replies with struct eth_stats in an external buffer.
G
Greg Rose 已提交
459 460
 */

461 462
/* VIRTCHNL_OP_CONFIG_RSS_KEY
 * VIRTCHNL_OP_CONFIG_RSS_LUT
463
 * VF sends these messages to configure RSS. Only supported if both PF
464
 * and VF drivers set the VIRTCHNL_VF_OFFLOAD_RSS_PF bit during
465 466 467 468 469
 * 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.
 */
470
struct virtchnl_rss_key {
471 472 473 474 475
	u16 vsi_id;
	u16 key_len;
	u8 key[1];         /* RSS hash key, packed bytes */
};

476 477
VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_key);

478
struct virtchnl_rss_lut {
479 480 481 482 483
	u16 vsi_id;
	u16 lut_entries;
	u8 lut[1];        /* RSS lookup table*/
};

484 485
VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_lut);

486 487
/* VIRTCHNL_OP_GET_RSS_HENA_CAPS
 * VIRTCHNL_OP_SET_RSS_HENA
488 489 490 491 492
 * 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.
 */
493
struct virtchnl_rss_hena {
494 495 496
	u64 hena;
};

497 498
VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena);

499
/* VIRTCHNL_OP_EVENT
G
Greg Rose 已提交
500 501 502 503
 * 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.
 */
504 505 506 507 508
enum virtchnl_event_codes {
	VIRTCHNL_EVENT_UNKNOWN = 0,
	VIRTCHNL_EVENT_LINK_CHANGE,
	VIRTCHNL_EVENT_RESET_IMPENDING,
	VIRTCHNL_EVENT_PF_DRIVER_CLOSE,
G
Greg Rose 已提交
509
};
510 511 512

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

514 515
struct virtchnl_pf_event {
	enum virtchnl_event_codes event;
G
Greg Rose 已提交
516 517
	union {
		struct {
518
			enum virtchnl_link_speed link_speed;
G
Greg Rose 已提交
519 520 521 522 523 524 525
			bool link_status;
		} link_event;
	} event_data;

	int severity;
};

526 527
VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_pf_event);

528
/* VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP
M
Mitch Williams 已提交
529 530 531 532 533 534 535 536 537 538 539
 * 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.
 */

540
struct virtchnl_iwarp_qv_info {
M
Mitch Williams 已提交
541 542 543 544 545 546
	u32 v_idx; /* msix_vector */
	u16 ceq_idx;
	u16 aeq_idx;
	u8 itr_idx;
};

547 548
VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_iwarp_qv_info);

549
struct virtchnl_iwarp_qvlist_info {
M
Mitch Williams 已提交
550
	u32 num_vectors;
551
	struct virtchnl_iwarp_qv_info qv_info[1];
M
Mitch Williams 已提交
552 553
};

554 555
VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_iwarp_qvlist_info);

G
Greg Rose 已提交
556
/* VF reset states - these are written into the RSTAT register:
557
 * VFGEN_RSTAT on the VF
G
Greg Rose 已提交
558 559 560 561 562 563 564 565 566
 * 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.
 */
567 568 569 570
enum virtchnl_vfr_states {
	VIRTCHNL_VFR_INPROGRESS = 0,
	VIRTCHNL_VFR_COMPLETED,
	VIRTCHNL_VFR_VFACTIVE,
G
Greg Rose 已提交
571 572
};

573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 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
/**
 * 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;
708 709 710
	case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
	case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
		break;
711 712 713
	case VIRTCHNL_OP_REQUEST_QUEUES:
		valid_len = sizeof(struct virtchnl_vf_res_request);
		break;
714 715 716 717 718 719 720 721 722 723 724 725
	/* These are always errors coming from the VF. */
	case VIRTCHNL_OP_EVENT:
	case VIRTCHNL_OP_UNKNOWN:
	default:
		return VIRTCHNL_ERR_PARAM;
	}
	/* few more checks */
	if ((valid_len != msglen) || (err_msg_format))
		return VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH;

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