1254738Sbryanv/*-
2254738Sbryanv * Copyright (c) 2013 Tsubai Masanari
3254738Sbryanv *
4254738Sbryanv * Permission to use, copy, modify, and distribute this software for any
5254738Sbryanv * purpose with or without fee is hereby granted, provided that the above
6254738Sbryanv * copyright notice and this permission notice appear in all copies.
7254738Sbryanv *
8254738Sbryanv * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9254738Sbryanv * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10254738Sbryanv * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11254738Sbryanv * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12254738Sbryanv * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13254738Sbryanv * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14254738Sbryanv * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15254738Sbryanv *
16254738Sbryanv * $OpenBSD: src/sys/dev/pci/if_vmxreg.h,v 1.2 2013/06/12 01:07:33 uebayasi Exp $
17254738Sbryanv *
18254738Sbryanv * $FreeBSD$
19254738Sbryanv */
20254738Sbryanv
21254738Sbryanv#ifndef _IF_VMXREG_H
22254738Sbryanv#define _IF_VMXREG_H
23254738Sbryanv
24254738Sbryanvstruct UPT1_TxStats {
25254738Sbryanv	uint64_t	TSO_packets;
26254738Sbryanv	uint64_t	TSO_bytes;
27254738Sbryanv	uint64_t	ucast_packets;
28254738Sbryanv	uint64_t	ucast_bytes;
29254738Sbryanv	uint64_t	mcast_packets;
30254738Sbryanv	uint64_t	mcast_bytes;
31254738Sbryanv	uint64_t	bcast_packets;
32254738Sbryanv	uint64_t	bcast_bytes;
33254738Sbryanv	uint64_t	error;
34254738Sbryanv	uint64_t	discard;
35254738Sbryanv} __packed;
36254738Sbryanv
37254738Sbryanvstruct UPT1_RxStats {
38254738Sbryanv	uint64_t	LRO_packets;
39254738Sbryanv	uint64_t	LRO_bytes;
40254738Sbryanv	uint64_t	ucast_packets;
41254738Sbryanv	uint64_t	ucast_bytes;
42254738Sbryanv	uint64_t	mcast_packets;
43254738Sbryanv	uint64_t	mcast_bytes;
44254738Sbryanv	uint64_t	bcast_packets;
45254738Sbryanv	uint64_t	bcast_bytes;
46254738Sbryanv	uint64_t	nobuffer;
47254738Sbryanv	uint64_t	error;
48254738Sbryanv} __packed;
49254738Sbryanv
50254738Sbryanv/* Interrupt moderation levels */
51254738Sbryanv#define UPT1_IMOD_NONE		0	/* No moderation */
52254738Sbryanv#define UPT1_IMOD_HIGHEST	7	/* Least interrupts */
53254738Sbryanv#define UPT1_IMOD_ADAPTIVE	8	/* Adaptive interrupt moderation */
54254738Sbryanv
55254738Sbryanv/* Hardware features */
56254738Sbryanv#define UPT1_F_CSUM	0x0001		/* Rx checksum verification */
57254738Sbryanv#define UPT1_F_RSS	0x0002		/* Receive side scaling */
58254738Sbryanv#define UPT1_F_VLAN	0x0004		/* VLAN tag stripping */
59254738Sbryanv#define UPT1_F_LRO	0x0008		/* Large receive offloading */
60254738Sbryanv
61254738Sbryanv#define VMXNET3_BAR0_IMASK(irq)	(0x000 + (irq) * 8)	/* Interrupt mask */
62254738Sbryanv#define VMXNET3_BAR0_TXH(q)	(0x600 + (q) * 8)	/* Tx head */
63254738Sbryanv#define VMXNET3_BAR0_RXH1(q)	(0x800 + (q) * 8)	/* Ring1 Rx head */
64254738Sbryanv#define VMXNET3_BAR0_RXH2(q)	(0xA00 + (q) * 8)	/* Ring2 Rx head */
65254738Sbryanv#define VMXNET3_BAR1_VRRS	0x000	/* VMXNET3 revision report selection */
66254738Sbryanv#define VMXNET3_BAR1_UVRS	0x008	/* UPT version report selection */
67254738Sbryanv#define VMXNET3_BAR1_DSL	0x010	/* Driver shared address low */
68254738Sbryanv#define VMXNET3_BAR1_DSH	0x018	/* Driver shared address high */
69254738Sbryanv#define VMXNET3_BAR1_CMD	0x020	/* Command */
70254738Sbryanv#define VMXNET3_BAR1_MACL	0x028	/* MAC address low */
71254738Sbryanv#define VMXNET3_BAR1_MACH	0x030	/* MAC address high */
72254738Sbryanv#define VMXNET3_BAR1_INTR	0x038	/* Interrupt status */
73254738Sbryanv#define VMXNET3_BAR1_EVENT	0x040	/* Event status */
74254738Sbryanv
75254738Sbryanv#define VMXNET3_CMD_ENABLE	0xCAFE0000	/* Enable VMXNET3 */
76254738Sbryanv#define VMXNET3_CMD_DISABLE	0xCAFE0001	/* Disable VMXNET3 */
77254738Sbryanv#define VMXNET3_CMD_RESET	0xCAFE0002	/* Reset device */
78254738Sbryanv#define VMXNET3_CMD_SET_RXMODE	0xCAFE0003	/* Set interface flags */
79254738Sbryanv#define VMXNET3_CMD_SET_FILTER	0xCAFE0004	/* Set address filter */
80254738Sbryanv#define VMXNET3_CMD_VLAN_FILTER	0xCAFE0005	/* Set VLAN filter */
81254738Sbryanv#define VMXNET3_CMD_GET_STATUS	0xF00D0000	/* Get queue errors */
82254738Sbryanv#define VMXNET3_CMD_GET_STATS	0xF00D0001	/* Get queue statistics */
83254738Sbryanv#define VMXNET3_CMD_GET_LINK	0xF00D0002	/* Get link status */
84254738Sbryanv#define VMXNET3_CMD_GET_MACL	0xF00D0003	/* Get MAC address low */
85254738Sbryanv#define VMXNET3_CMD_GET_MACH	0xF00D0004	/* Get MAC address high */
86254738Sbryanv#define VMXNET3_CMD_GET_INTRCFG	0xF00D0008	/* Get interrupt config */
87254738Sbryanv
88254738Sbryanv#define VMXNET3_DMADESC_ALIGN	128
89254738Sbryanv#define VMXNET3_INIT_GEN	1
90254738Sbryanv
91254738Sbryanvstruct vmxnet3_txdesc {
92254738Sbryanv	uint64_t	addr;
93254738Sbryanv
94254738Sbryanv	uint32_t	len:14;
95254738Sbryanv	uint32_t	gen:1;		/* Generation */
96254738Sbryanv	uint32_t	pad1:1;
97254738Sbryanv	uint32_t	dtype:1;	/* Descriptor type */
98254738Sbryanv	uint32_t	pad2:1;
99254738Sbryanv	uint32_t	offload_pos:14;	/* Offloading position */
100254738Sbryanv
101254738Sbryanv	uint32_t	hlen:10;	/* Header len */
102254738Sbryanv	uint32_t	offload_mode:2;	/* Offloading mode */
103254738Sbryanv	uint32_t	eop:1;		/* End of packet */
104254738Sbryanv	uint32_t	compreq:1;	/* Completion request */
105254738Sbryanv	uint32_t	pad3:1;
106254738Sbryanv	uint32_t	vtag_mode:1;	/* VLAN tag insertion mode */
107254738Sbryanv	uint32_t	vtag:16;	/* VLAN tag */
108254738Sbryanv} __packed;
109254738Sbryanv
110254738Sbryanv/* Offloading modes */
111254738Sbryanv#define VMXNET3_OM_NONE	0
112254738Sbryanv#define VMXNET3_OM_CSUM 2
113254738Sbryanv#define VMXNET3_OM_TSO  3
114254738Sbryanv
115254738Sbryanvstruct vmxnet3_txcompdesc {
116254738Sbryanv	uint32_t	eop_idx:12;	/* EOP index in Tx ring */
117254738Sbryanv	uint32_t	pad1:20;
118254738Sbryanv
119254738Sbryanv	uint32_t	pad2:32;
120254738Sbryanv	uint32_t	pad3:32;
121254738Sbryanv
122254738Sbryanv	uint32_t	rsvd:24;
123254738Sbryanv	uint32_t	type:7;
124254738Sbryanv	uint32_t	gen:1;
125254738Sbryanv} __packed;
126254738Sbryanv
127254738Sbryanvstruct vmxnet3_rxdesc {
128254738Sbryanv	uint64_t	addr;
129254738Sbryanv
130254738Sbryanv	uint32_t	len:14;
131254738Sbryanv	uint32_t	btype:1;	/* Buffer type */
132254738Sbryanv	uint32_t	dtype:1;	/* Descriptor type */
133254738Sbryanv	uint32_t	rsvd:15;
134254738Sbryanv	uint32_t	gen:1;
135254738Sbryanv
136254738Sbryanv	uint32_t	pad1:32;
137254738Sbryanv} __packed;
138254738Sbryanv
139254738Sbryanv/* Buffer types */
140254738Sbryanv#define VMXNET3_BTYPE_HEAD	0	/* Head only */
141254738Sbryanv#define VMXNET3_BTYPE_BODY	1	/* Body only */
142254738Sbryanv
143254738Sbryanvstruct vmxnet3_rxcompdesc {
144254738Sbryanv	uint32_t	rxd_idx:12;	/* Rx descriptor index */
145254738Sbryanv	uint32_t	pad1:2;
146254738Sbryanv	uint32_t	eop:1;		/* End of packet */
147254738Sbryanv	uint32_t	sop:1;		/* Start of packet */
148254738Sbryanv	uint32_t	qid:10;
149254738Sbryanv	uint32_t	rss_type:4;
150254738Sbryanv	uint32_t	no_csum:1;	/* No checksum calculated */
151254738Sbryanv	uint32_t	pad2:1;
152254738Sbryanv
153254738Sbryanv	uint32_t	rss_hash:32;	/* RSS hash value */
154254738Sbryanv
155254738Sbryanv	uint32_t	len:14;
156254738Sbryanv	uint32_t	error:1;
157254738Sbryanv	uint32_t	vlan:1;		/* 802.1Q VLAN frame */
158254738Sbryanv	uint32_t	vtag:16;	/* VLAN tag */
159254738Sbryanv
160254738Sbryanv	uint32_t	csum:16;
161254738Sbryanv	uint32_t	csum_ok:1;	/* TCP/UDP checksum ok */
162254738Sbryanv	uint32_t	udp:1;
163254738Sbryanv	uint32_t	tcp:1;
164254738Sbryanv	uint32_t	ipcsum_ok:1;	/* IP checksum OK */
165254738Sbryanv	uint32_t	ipv6:1;
166254738Sbryanv	uint32_t	ipv4:1;
167254738Sbryanv	uint32_t	fragment:1;	/* IP fragment */
168254738Sbryanv	uint32_t	fcs:1;		/* Frame CRC correct */
169254738Sbryanv	uint32_t	type:7;
170254738Sbryanv	uint32_t	gen:1;
171254738Sbryanv} __packed;
172254738Sbryanv
173263259Sbryanv#define VMXNET3_RCD_RSS_TYPE_NONE	0
174263259Sbryanv#define VMXNET3_RCD_RSS_TYPE_IPV4	1
175263259Sbryanv#define VMXNET3_RCD_RSS_TYPE_TCPIPV4	2
176263259Sbryanv#define VMXNET3_RCD_RSS_TYPE_IPV6	3
177263259Sbryanv#define VMXNET3_RCD_RSS_TYPE_TCPIPV6	4
178263259Sbryanv
179254738Sbryanv#define VMXNET3_REV1_MAGIC	0XBABEFEE1
180254738Sbryanv
181254738Sbryanv#define VMXNET3_GOS_UNKNOWN	0x00
182254738Sbryanv#define VMXNET3_GOS_LINUX	0x04
183254738Sbryanv#define VMXNET3_GOS_WINDOWS	0x08
184254738Sbryanv#define VMXNET3_GOS_SOLARIS	0x0C
185254738Sbryanv#define VMXNET3_GOS_FREEBSD	0x10
186254738Sbryanv#define VMXNET3_GOS_PXE		0x14
187254738Sbryanv
188254738Sbryanv#define VMXNET3_GOS_32BIT	0x01
189254738Sbryanv#define VMXNET3_GOS_64BIT	0x02
190254738Sbryanv
191254738Sbryanv#define VMXNET3_MAX_TX_QUEUES	8
192254738Sbryanv#define VMXNET3_MAX_RX_QUEUES	16
193254738Sbryanv#define VMXNET3_MAX_INTRS \
194254738Sbryanv    (VMXNET3_MAX_TX_QUEUES + VMXNET3_MAX_RX_QUEUES + 1)
195254738Sbryanv
196254738Sbryanv#define VMXNET3_ICTRL_DISABLE_ALL	0x01
197254738Sbryanv
198254738Sbryanv#define VMXNET3_RXMODE_UCAST	0x01
199254738Sbryanv#define VMXNET3_RXMODE_MCAST	0x02
200254738Sbryanv#define VMXNET3_RXMODE_BCAST	0x04
201254738Sbryanv#define VMXNET3_RXMODE_ALLMULTI	0x08
202254738Sbryanv#define VMXNET3_RXMODE_PROMISC	0x10
203254738Sbryanv
204254738Sbryanv#define VMXNET3_EVENT_RQERROR	0x01
205254738Sbryanv#define VMXNET3_EVENT_TQERROR	0x02
206254738Sbryanv#define VMXNET3_EVENT_LINK	0x04
207254738Sbryanv#define VMXNET3_EVENT_DIC	0x08
208254738Sbryanv#define VMXNET3_EVENT_DEBUG	0x10
209254738Sbryanv
210254738Sbryanv#define VMXNET3_MIN_MTU		60
211254738Sbryanv#define VMXNET3_MAX_MTU		9000
212254738Sbryanv
213254738Sbryanv/* Interrupt mask mode. */
214254738Sbryanv#define VMXNET3_IMM_AUTO	0x00
215254738Sbryanv#define VMXNET3_IMM_ACTIVE	0x01
216254738Sbryanv#define VMXNET3_IMM_LAZY	0x02
217254738Sbryanv
218254738Sbryanv/* Interrupt type. */
219254738Sbryanv#define VMXNET3_IT_AUTO		0x00
220254738Sbryanv#define VMXNET3_IT_LEGACY	0x01
221254738Sbryanv#define VMXNET3_IT_MSI		0x02
222254738Sbryanv#define VMXNET3_IT_MSIX		0x03
223254738Sbryanv
224254738Sbryanvstruct vmxnet3_driver_shared {
225254738Sbryanv	uint32_t	magic;
226254738Sbryanv	uint32_t	pad1;
227254738Sbryanv
228254738Sbryanv	/* Misc. control */
229254738Sbryanv	uint32_t	version;		/* Driver version */
230254738Sbryanv	uint32_t	guest;			/* Guest OS */
231254738Sbryanv	uint32_t	vmxnet3_revision;	/* Supported VMXNET3 revision */
232254738Sbryanv	uint32_t	upt_version;		/* Supported UPT version */
233254738Sbryanv	uint64_t	upt_features;
234254738Sbryanv	uint64_t	driver_data;
235254738Sbryanv	uint64_t	queue_shared;
236254738Sbryanv	uint32_t	driver_data_len;
237254738Sbryanv	uint32_t	queue_shared_len;
238254738Sbryanv	uint32_t	mtu;
239254738Sbryanv	uint16_t	nrxsg_max;
240254738Sbryanv	uint8_t		ntxqueue;
241254738Sbryanv	uint8_t		nrxqueue;
242254738Sbryanv	uint32_t	reserved1[4];
243254738Sbryanv
244254738Sbryanv	/* Interrupt control */
245254738Sbryanv	uint8_t		automask;
246254738Sbryanv	uint8_t		nintr;
247254738Sbryanv	uint8_t		evintr;
248254738Sbryanv	uint8_t		modlevel[VMXNET3_MAX_INTRS];
249254738Sbryanv	uint32_t	ictrl;
250254738Sbryanv	uint32_t	reserved2[2];
251254738Sbryanv
252254738Sbryanv	/* Receive filter parameters */
253254738Sbryanv	uint32_t	rxmode;
254254738Sbryanv	uint16_t	mcast_tablelen;
255254738Sbryanv	uint16_t	pad2;
256254738Sbryanv	uint64_t	mcast_table;
257254738Sbryanv	uint32_t	vlan_filter[4096 / 32];
258254738Sbryanv
259254738Sbryanv	struct {
260254738Sbryanv		uint32_t version;
261254738Sbryanv		uint32_t len;
262254738Sbryanv		uint64_t paddr;
263254738Sbryanv	}		rss, pm, plugin;
264254738Sbryanv
265254738Sbryanv	uint32_t	event;
266254738Sbryanv	uint32_t	reserved3[5];
267254738Sbryanv} __packed;
268254738Sbryanv
269254738Sbryanvstruct vmxnet3_txq_shared {
270254738Sbryanv	/* Control */
271254738Sbryanv	uint32_t	npending;
272254738Sbryanv	uint32_t	intr_threshold;
273254738Sbryanv	uint64_t	reserved1;
274254738Sbryanv
275254738Sbryanv	/* Config */
276254738Sbryanv	uint64_t	cmd_ring;
277254738Sbryanv	uint64_t	data_ring;
278254738Sbryanv	uint64_t	comp_ring;
279254738Sbryanv	uint64_t	driver_data;
280254738Sbryanv	uint64_t	reserved2;
281254738Sbryanv	uint32_t	cmd_ring_len;
282254738Sbryanv	uint32_t	data_ring_len;
283254738Sbryanv	uint32_t	comp_ring_len;
284254738Sbryanv	uint32_t	driver_data_len;
285254738Sbryanv	uint8_t		intr_idx;
286254738Sbryanv	uint8_t		pad1[7];
287254738Sbryanv
288254738Sbryanv	/* Queue status */
289254738Sbryanv	uint8_t		stopped;
290254738Sbryanv	uint8_t		pad2[3];
291254738Sbryanv	uint32_t	error;
292254738Sbryanv
293254738Sbryanv	struct		UPT1_TxStats stats;
294254738Sbryanv
295254738Sbryanv	uint8_t		pad3[88];
296254738Sbryanv} __packed;
297254738Sbryanv
298254738Sbryanvstruct vmxnet3_rxq_shared {
299254738Sbryanv	uint8_t		update_rxhead;
300254738Sbryanv	uint8_t		pad1[7];
301254738Sbryanv	uint64_t	reserved1;
302254738Sbryanv
303254738Sbryanv	uint64_t	cmd_ring[2];
304254738Sbryanv	uint64_t	comp_ring;
305254738Sbryanv	uint64_t	driver_data;
306254738Sbryanv	uint64_t	reserved2;
307254738Sbryanv	uint32_t	cmd_ring_len[2];
308254738Sbryanv	uint32_t	comp_ring_len;
309254738Sbryanv	uint32_t	driver_data_len;
310254738Sbryanv	uint8_t		intr_idx;
311254738Sbryanv	uint8_t		pad2[7];
312254738Sbryanv
313254738Sbryanv	uint8_t		stopped;
314254738Sbryanv	uint8_t		pad3[3];
315254738Sbryanv	uint32_t	error;
316254738Sbryanv
317254738Sbryanv	struct		UPT1_RxStats stats;
318254738Sbryanv
319254738Sbryanv	uint8_t		pad4[88];
320254738Sbryanv} __packed;
321254738Sbryanv
322263259Sbryanv#define UPT1_RSS_HASH_TYPE_NONE		0x00
323263259Sbryanv#define UPT1_RSS_HASH_TYPE_IPV4		0x01
324263259Sbryanv#define UPT1_RSS_HASH_TYPE_TCP_IPV4	0x02
325263259Sbryanv#define UPT1_RSS_HASH_TYPE_IPV6		0x04
326263259Sbryanv#define UPT1_RSS_HASH_TYPE_TCP_IPV6	0x08
327263259Sbryanv
328263259Sbryanv#define UPT1_RSS_HASH_FUNC_NONE		0x00
329263259Sbryanv#define UPT1_RSS_HASH_FUNC_TOEPLITZ	0x01
330263259Sbryanv
331263259Sbryanv#define UPT1_RSS_MAX_KEY_SIZE		40
332263259Sbryanv#define UPT1_RSS_MAX_IND_TABLE_SIZE	128
333263259Sbryanv
334263259Sbryanvstruct vmxnet3_rss_shared {
335263259Sbryanv	uint16_t		hash_type;
336263259Sbryanv	uint16_t		hash_func;
337263259Sbryanv	uint16_t		hash_key_size;
338263259Sbryanv	uint16_t		ind_table_size;
339263259Sbryanv	uint8_t			hash_key[UPT1_RSS_MAX_KEY_SIZE];
340263259Sbryanv	uint8_t			ind_table[UPT1_RSS_MAX_IND_TABLE_SIZE];
341263259Sbryanv} __packed;
342263259Sbryanv
343254738Sbryanv#endif /* _IF_VMXREG_H */
344