1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26#ifndef _SYS_VIO_MAILBOX_H
27#define	_SYS_VIO_MAILBOX_H
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33#include <sys/ldc.h>
34
35/* Message types */
36#define		VIO_TYPE_CTRL	0x1
37#define		VIO_TYPE_DATA	0x2
38#define		VIO_TYPE_ERR	0x4
39
40/* Message sub-types */
41#define		VIO_SUBTYPE_INFO	0x1
42#define		VIO_SUBTYPE_ACK		0x2
43#define		VIO_SUBTYPE_NACK	0x4
44
45/*
46 * VIO specific control envelopes:  0x0000 - 0x00FF
47 * VNET specific control envelopes: 0x0100 - 0x01FF
48 * VDSK specific control envelopes: 0x0200 - 0x02FF
49 * UNUSED envelopes:                0x0300 - 0x0FFF
50 */
51
52/*
53 * Generic Control Subtype Envelopes:
54 * 	type == VIO_TYPE_CTRL
55 *	subtype == VIO_SUBTYPE_{INFO|ACK|NACK}
56 *
57 * 	0x0000 - 0x003F
58 */
59#define	VIO_VER_INFO		0x0001
60#define	VIO_ATTR_INFO		0x0002
61#define	VIO_DRING_REG		0x0003
62#define	VIO_DRING_UNREG		0x0004
63#define	VIO_RDX			0x0005
64#define	VIO_DDS_INFO		0x0006
65
66/*
67 * Generic subtype Data envelopes
68 * 	type == VIO_TYPE_DATA
69 * 	subtype == VIO_SUBTYPE_{INFO|ACK|NACK}
70 *
71 * 	0x0040 - 0x007F
72 */
73#define	VIO_PKT_DATA		0x0040
74#define	VIO_DESC_DATA		0x0041
75#define	VIO_DRING_DATA		0x0042
76
77
78/*
79 * Generic subtype Error envelopes
80 * 	type == VIO_TYPE_ERR
81 * 	subtype == VIO_SUBTYPE_{INFO|ACK|NACK}
82 *
83 * 	0x0080 - 0x00FF
84 *
85 * Currently unused
86 */
87
88/*
89 * Supported Device Types
90 */
91#define	VDEV_NETWORK		0x1
92#define	VDEV_NETWORK_SWITCH	0x2
93#define	VDEV_DISK		0x3
94#define	VDEV_DISK_SERVER	0x4
95
96/*
97 * VIO data transfer mode
98 */
99#define	VIO_PKT_MODE	0x1
100#define	VIO_DESC_MODE	0x2
101#define	VIO_DRING_MODE_V1_0	0x3
102#define	VIO_DRING_MODE_V1_2	0x4
103
104/*
105 * VIO Descriptor Ring registration options
106 * (intended use for Descriptor Ring)
107 */
108#define	VIO_TX_DRING		0x1
109#define	VIO_RX_DRING		0x2
110#define	VIO_RX_DRING_DATA	0x4
111
112/*
113 * Size of message payload
114 */
115#define	VIO_MSGTAG_SZ		(sizeof (vio_msg_tag_t))	/* bytes */
116#define	VIO_PAYLOAD_SZ		(LDC_PAYLOAD_SIZE_UNRELIABLE - VIO_MSGTAG_SZ)
117#define	VIO_PAYLOAD_ELEMS	(VIO_PAYLOAD_SZ / LDC_ELEM_SIZE) /* num words */
118
119/*
120 * Peer dring processing state. Either actively processing dring
121 * or stopped.
122 */
123#define	VIO_DP_ACTIVE		1
124#define	VIO_DP_STOPPED		2
125
126/*
127 * VIO device message tag.
128 *
129 * These 64 bits are used as a common header for all VIO message types.
130 */
131typedef union vio_msg_tag {
132	struct {
133		uint8_t		_msgtype;
134		uint8_t		_subtype;
135		uint16_t	_subtype_env;
136		uint32_t	_sid;		/* session id */
137	} _hdr;
138	uint64_t	tagword;
139} vio_msg_tag_t;
140
141#define	vio_msgtype		_hdr._msgtype
142#define	vio_subtype		_hdr._subtype
143#define	vio_subtype_env		_hdr._subtype_env
144#define	vio_sid			_hdr._sid
145
146/*
147 * VIO version negotation message.
148 *
149 * tag.msgtype == VIO_TYPE_CTRL
150 * tag.submsgtype = VIO_SUBTYPE_{INFO|ACK|NACK}
151 * tag.subtype_env == VIO_VER_INFO
152 */
153
154/* Structure to store a version tuple */
155typedef struct vio_ver {
156	uint16_t		major;		/* major version number */
157	uint16_t		minor;		/* minor version number */
158} vio_ver_t;
159
160typedef struct vio_ver_msg {
161	/* Common tag */
162	vio_msg_tag_t		tag;
163
164	/* version specific payload */
165	uint16_t		ver_major;	/* major version number */
166	uint16_t		ver_minor;	/* minor version number */
167
168	uint8_t			dev_class;	/* type of device */
169
170	/* padding */
171	uint8_t			resv1;
172	uint16_t		resv2;
173	uint64_t		resv3[VIO_PAYLOAD_ELEMS - 1];
174} vio_ver_msg_t;
175
176/*
177 * VIO Descriptor Ring Register message.
178 *
179 * tag.msgtype == VIO_TYPE_CTRL
180 * tag.submsgtype = VIO_SUBTYPE_{INFO|ACK|NACK}
181 * tag.subtype_env == VIO_DRING_REG
182 */
183typedef struct vio_dring_reg_msg {
184	/* Common tag */
185	vio_msg_tag_t		tag;
186
187	/* Descriptor ring information */
188	uint64_t		dring_ident;	/* =0 for SUBTYPE_INFO msg */
189	uint32_t		num_descriptors; /* # of desc in the ring */
190	uint32_t		descriptor_size; /* size of each entry */
191	uint16_t		options;	/* dring mode */
192	uint16_t		resv;		/* padding */
193	uint32_t		ncookies;	/* # cookies exporting ring */
194
195	/*
196	 * The rest of the structure is variable in size. The first member that
197	 * follows is the descriptor ring cookie(s), that is used in all dring
198	 * modes. Following that are the members that are needed only in
199	 * RxDringData mode. If the dring mode is not RxDringData and the # of
200	 * dring cookies is 1, the message can be sent by LDC without
201	 * fragmentation. As dring cookie array is variable in size depending
202	 * on ncookies, the subsequent members are defined in a separate
203	 * structure vio_dring_reg_msg_ext_t as shown below.
204	 */
205
206	ldc_mem_cookie_t	cookie[1];
207} vio_dring_reg_msg_t;
208
209/*
210 * VIO Descriptor Ring Register Extended message; used in RxDringData mode.
211 */
212typedef struct vio_dring_reg_extended_msg {
213	uint32_t		data_ncookies;	/* # of data area cookies */
214	uint32_t		data_area_size;	/* size of data area */
215
216	/*
217	 * The data_cookie[] array is variable in size based on data_ncookies.
218	 */
219	ldc_mem_cookie_t	data_cookie[1]; /* data cookies */
220} vio_dring_reg_ext_msg_t;
221
222/*
223 * VIO Descriptor Ring Unregister message.
224 *
225 * tag.msgtype == VIO_TYPE_CTRL
226 * tag.submsgtype = VIO_SUBTYPE_{INFO|ACK|NACK}
227 * tag.subtype_env == VIO_DRING_UNREG
228 */
229typedef struct vio_dring_unreg_msg {
230	/* Common tag */
231	vio_msg_tag_t	tag;
232
233	/* Descriptor ring information */
234	uint64_t	dring_ident;
235	uint64_t	resv[VIO_PAYLOAD_ELEMS - 1];
236} vio_dring_unreg_msg_t;
237
238/*
239 * Definition of a generic VIO message (with no payload) which can be cast
240 * to other message types.
241 */
242typedef struct vio_msg {
243	/* Common tag */
244	vio_msg_tag_t		tag;
245
246	/* no payload */
247	uint64_t		resv[VIO_PAYLOAD_ELEMS];
248} vio_msg_t;
249
250/*
251 * VIO Ready to Receive message.
252 *
253 * tag.msgtype == VIO_TYPE_CTRL
254 * tag.submsgtype = VIO_SUBTYPE_{INFO|ACK}
255 * tag.subtype_env == VIO_RDX
256 */
257typedef vio_msg_t	vio_rdx_msg_t;
258
259/*
260 * VIO error message.
261 *
262 * tag.msgtype == VIO_TYPE_ERR
263 * tag.subtype == VIO_SUBTYPE_{INFO|ACK|NACK}
264 * tag.subtype_env == TBD
265 */
266typedef vio_msg_t	vio_err_msg_t;
267
268/*
269 * VIO descriptor ring data message.
270 *
271 * tag.msgtype == VIO_TYPE_DATA
272 * tag.subtype == VIO_SUBTYPE_{INFO|ACK|NACK}
273 * tag.subtype_env == VIO_DRING_DATA
274 */
275typedef struct vio_dring_msg {
276	/* Common message tag */
277	vio_msg_tag_t		tag;
278
279	/* Data dring info */
280	uint64_t		seq_num;
281	uint64_t		dring_ident;	/* ident of modified DRing */
282	uint32_t		start_idx;	/* Indx of first updated elem */
283	int32_t			end_idx;	/* Indx of last updated elem */
284
285	uint8_t			dring_process_state;	/* Processing state */
286
287	/*
288	 * Padding.
289	 */
290	uint8_t			resv1;
291	uint16_t		resv2;
292	uint32_t		resv3;
293	uint64_t		resv4[VIO_PAYLOAD_ELEMS - 4];
294} vio_dring_msg_t;
295
296/*
297 * VIO Common header for inband descriptor messages.
298 *
299 * Clients will then combine this header with a device specific payload.
300 */
301typedef struct vio_inband_desc_msg_hdr {
302	/* Common message tag */
303	vio_msg_tag_t		tag;
304
305	uint64_t		seq_num;	/* sequence number */
306	uint64_t		desc_handle;	/* opaque descriptor handle */
307} vio_inband_desc_msg_hdr_t;
308
309/*
310 * VIO raw data message.
311 *
312 * tag.msgtype == VIO_TYPE_DATA
313 * tag.subtype == VIO_SUBTYPE_{INFO|ACK|NACK}
314 * tag.subtype_env == VIO_PKT_DATA
315 *
316 * Note the data payload is so small to keep this message
317 * within the size LDC can cope with without fragmentation.
318 * If it turns out in the future that we are not concerned
319 * with fragmentation then we can increase the size of this
320 * field.
321 */
322typedef struct vio_raw_data_msg {
323	/* Common message tag */
324	vio_msg_tag_t		tag;
325
326	/* Raw data packet payload */
327	uint64_t		seq_num;	/* sequence number */
328	uint64_t		data[VIO_PAYLOAD_ELEMS - 1];
329} vio_raw_data_msg_t;
330
331#define	VIO_PKT_DATA_HDRSIZE	\
332	(sizeof (vio_msg_tag_t) + sizeof (uint64_t))
333
334/*
335 * Definitions of the valid states a Descriptor can be in.
336 */
337#define	VIO_DESC_FREE		0x1
338#define	VIO_DESC_READY		0x2
339#define	VIO_DESC_ACCEPTED	0x3
340#define	VIO_DESC_DONE		0x4
341#define	VIO_DESC_INITIALIZING	0x5
342#define	VIO_DESC_MASK		0xf
343
344/* Macro to populate the generic fields of the DRing data msg */
345#define	VIO_INIT_DRING_DATA_TAG(dmsg)	\
346		dmsg.tag.vio_msgtype = VIO_TYPE_DATA;	\
347		dmsg.tag.vio_subtype = VIO_SUBTYPE_INFO;	\
348		dmsg.tag.vio_subtype_env = VIO_DRING_DATA;
349
350
351#ifdef __cplusplus
352}
353#endif
354
355#endif	/* _SYS_VIO_MAILBOX_H */
356