summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4v/sys/vnet_gen.h
blob: 577667762b3adc5d7455ae9425ecc35741310d33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _VNET_GEN_H
#define	_VNET_GEN_H

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/vgen_stats.h>

#define	VGEN_SUCCESS		(0)	/* successful return */
#define	VGEN_FAILURE		(-1)	/* unsuccessful return */

#define	VGEN_NUM_VER		1	/* max # of vgen versions */

#define	VGEN_LOCAL	1	/* local ldc end-point */
#define	VGEN_PEER	2	/* peer ldc end-point */

/* vgen_t flags */
#define	VGEN_STOPPED		0x0
#define	VGEN_STARTED		0x1

#define	KMEM_FREE(_p)		kmem_free((_p), sizeof (*(_p)))

#define	VGEN_INIT_MCTAB_SIZE	16	/* initial size of multicast table */

#define	READ_ENTER(x)	rw_enter(x, RW_READER)
#define	WRITE_ENTER(x)	rw_enter(x, RW_WRITER)
#define	RW_EXIT(x)	rw_exit(x)

/* channel flags */
#define	CHANNEL_ATTACHED	0x1
#define	CHANNEL_STARTED		0x2

/* transmit return values */
#define	VGEN_TX_SUCCESS		0	/* transmit success */
#define	VGEN_TX_FAILURE		1	/* transmit failure */
#define	VGEN_TX_NORESOURCES	2	/* out of tbufs/txds */

/* private descriptor flags */
#define	VGEN_PRIV_DESC_FREE	0x0	/* desc is available */
#define	VGEN_PRIV_DESC_BUSY	0x1	/* desc in use */

#define	LDC_TO_VNET(ldcp)  ((ldcp)->portp->vgenp->vnetp)
#define	LDC_TO_VGEN(ldcp)  ((ldcp)->portp->vgenp)

/* receive thread flags */
#define	VGEN_WTHR_DATARCVD 	0x01	/* data received */
#define	VGEN_WTHR_STOP 		0x02	/* stop worker thread request */
#define	VGEN_WTHR_PROCESSING	0x04	/* worker thread awake & processing */

#define	VGEN_LDC_UP_DELAY	100	/* usec delay between ldc_up retries */
#define	VGEN_LDC_CLOSE_DELAY	100	/* usec delay between ldc_cl retries */

#define	VGEN_NUM_VMPOOLS	3	/* number of vio mblk pools */

#define	VGEN_DBLK_SZ_128	128	/* data buffer size 128 bytes */
#define	VGEN_DBLK_SZ_256	256	/* data buffer size 256 bytes */
#define	VGEN_DBLK_SZ_2048	2048	/* data buffer size 2K bytes */
#define	VGEN_NRBUFS		512	/* number of receive bufs */

#define	VGEN_TXDBLK_SZ		2048	/* Tx data buffer size */

/* get the address of next tbuf */
#define	NEXTTBUF(ldcp, tbufp)	(((tbufp) + 1) == (ldcp)->tbufendp    \
		? (ldcp)->tbufp : ((tbufp) + 1))

/* increment recv index */
#define	INCR_RXI(i, ldcp)	\
		((i) = (((i) + 1) & ((ldcp)->num_rxds - 1)))

/* decrement recv index */
#define	DECR_RXI(i, ldcp)	\
		((i) = (((i) - 1) & ((ldcp)->num_rxds - 1)))

/* increment tx index */
#define	INCR_TXI(i, ldcp)	\
		((i) = (((i) + 1) & ((ldcp)->num_txds - 1)))

/* decrement tx index */
#define	DECR_TXI(i, ldcp)	\
		((i) = (((i) - 1) & ((ldcp)->num_txds - 1)))

/* bounds check rx index */
#define	CHECK_RXI(i, ldcp)	\
		(((i) >= 0) && ((i) < (ldcp)->num_rxds))

/* bounds check tx index */
#define	CHECK_TXI(i, ldcp)	\
		(((i) >= 0) && ((i) < (ldcp)->num_txds))

/* private descriptor */
typedef struct vgen_priv_desc {
	uint64_t		flags;		/* flag bits */
	vnet_public_desc_t	*descp;		/* associated public desc */
	ldc_mem_handle_t	memhandle;	/* mem handle for data */
	caddr_t			datap;		/* prealloc'd tx data buffer */
	uint64_t		datalen;	/* total actual datalen */
	uint64_t		ncookies;	/* num ldc_mem_cookies */
	ldc_mem_cookie_t	memcookie[MAX_COOKIES];	/* data cookies */
} vgen_private_desc_t;

/*
 * Handshake parameters (per vio_mailbox.h) of each ldc end point, used
 * during handshake negotiation.
 */
typedef struct vgen_handshake_params {
	/* version specific params */
	uint16_t	ver_major;		/* major version number */
	uint16_t	ver_minor;		/* minor version number */
	uint8_t		dev_class;		/* device class */

	/* attributes specific params */
	uint64_t		mtu;		/* max transfer unit size */
	uint64_t		addr;		/* address of the device */
	uint8_t			addr_type;	/* type of address */
	uint8_t			xfer_mode;	/* SHM or PKT */
	uint16_t		ack_freq;	/* dring data ack freq */
	uint32_t		physlink_update; /* physlink updates */

	/* descriptor ring params */
	uint32_t		num_desc;	/* # of descriptors in ring */
	uint32_t		desc_size;	/* size of descriptor */
	ldc_mem_cookie_t	dring_cookie;	/* desc ring cookie */
	uint32_t		num_dcookies;	/* # of dring cookies */
	uint64_t		dring_ident;	/* ident=0 for INFO msg */
	boolean_t		dring_ready;	/* dring ready flag */
} vgen_hparams_t;

/* version info */
typedef struct vgen_ver {
	uint16_t	ver_major;		/* major version number */
	uint16_t	ver_minor;		/* minor version number */
} vgen_ver_t;

/*
 * vnet-protocol-version dependent function prototypes.
 */
typedef int	(*vgen_ldctx_t) (void *, mblk_t *);
typedef void	(*vgen_ldcrx_pktdata_t) (void *, void *, uint32_t);

/* Channel information associated with a vgen-port */
typedef struct vgen_ldc {

	struct vgen_ldc		*nextp;		/* next ldc in the list */
	struct vgen_port	*portp;		/* associated port */

	/*
	 * Locks:
	 * locking hierarchy when more than one lock is held concurrently:
	 * cblock > rxlock > txlock > tclock.
	 */
	kmutex_t		cblock;		/* sync callback processing */
	kmutex_t		txlock;		/* protect txd alloc */
	kmutex_t		tclock;		/* tx reclaim lock */
	kmutex_t		wrlock;		/* sync transmits */
	kmutex_t		rxlock;		/* sync reception */
	kmutex_t		pollq_lock;	/* sync polling and rxworker */

	/* channel info from ldc layer */
	uint64_t		ldc_id;		/* channel number */
	uint64_t		ldc_handle;	/* channel handle */
	ldc_status_t		ldc_status;	/* channel status */

	/* handshake info */
	vgen_ver_t		vgen_versions[VGEN_NUM_VER]; /* versions */
	int			hphase;		/* handshake phase */
	int			hstate;		/* handshake state bits */
	link_state_t		link_state;	/* channel link state */
#ifdef	VNET_IOC_DEBUG
	boolean_t		link_down_forced; /* forced link down */
#endif
	uint32_t		local_sid;	/* local session id */
	uint32_t		peer_sid;	/* session id of peer */
	vgen_hparams_t		local_hparams;	/* local handshake params */
	vgen_hparams_t		peer_hparams;	/* peer's handshake params */
	timeout_id_t		htid;		/* handshake wd timeout id */
	timeout_id_t		cancel_htid;	/* cancel handshake watchdog */

	/* transmit and receive descriptor ring info */
	ldc_dring_handle_t	tx_dhandle;	/* tx descriptor ring handle */
	ldc_mem_cookie_t	tx_dcookie;	/* tx descriptor ring cookie */
	ldc_dring_handle_t	rx_dhandle;	/* mapped rx dhandle */
	ldc_mem_cookie_t	rx_dcookie;	/* rx descriptor ring cookie */
	vnet_public_desc_t	*txdp;		/* transmit frame descriptors */
	vnet_public_desc_t	*txdendp;	/* txd ring end */
	vgen_private_desc_t	*tbufp;		/* associated tx resources */
	vgen_private_desc_t	*tbufendp;	/* tbuf ring end */
	vgen_private_desc_t	*next_tbufp;	/* next free tbuf */
	vgen_private_desc_t	*cur_tbufp;	/* next reclaim tbuf */
	uint64_t		next_txseq;	/* next tx sequence number */
	uint32_t		num_txdcookies;	/* # of tx dring cookies */
	uint32_t		num_rxdcookies;	/* # of rx dring cookies */
	uint8_t			dring_mtype;	/* dring mem map type */
	uint32_t		next_txi;	/* next tx descriptor index */
	uint32_t		num_txds;	/* number of tx descriptors */
	clock_t			reclaim_lbolt;	/* time of last tx reclaim */
	timeout_id_t		wd_tid;		/* tx watchdog timeout id */
	vnet_public_desc_t	*rxdp;		/* receive frame descriptors */
	uint64_t		next_rxseq;	/* next expected recv seqnum */
	uint32_t		next_rxi;	/* next expected recv index */
	uint32_t		num_rxds;	/* number of rx descriptors */
	caddr_t			tx_datap;	/* prealloc'd tx data area */
	size_t			tx_data_sz;	/* alloc'd size of tx databuf */
	vio_multi_pool_t	vmp;		/* rx mblk pools */
	uint32_t		max_rxpool_size; /* max size of rxpool in use */
	uint64_t		*ldcmsg;	/* msg buffer for ldc_read() */
	uint64_t		msglen;		/* size of ldcmsg */

	/* misc */
	uint32_t		flags;		/* flags */
	boolean_t		need_resched;	/* reschedule tx */
	boolean_t		need_ldc_reset; /* ldc_reset needed */
	uint32_t		hretries;	/* handshake retry count */
	boolean_t		resched_peer;	/* send tx msg to peer */
	uint32_t		resched_peer_txi; /* tx index to resched peer */

	vgen_ldctx_t		tx;		/* transmit function */
	vgen_ldcrx_pktdata_t	rx_pktdata;	/* process rx raw data msg */

	/* receive thread field */
	kthread_t		*rcv_thread;	/* receive thread */
	uint32_t		rcv_thr_flags;	/* receive thread flags */
	kmutex_t		rcv_thr_lock;	/* lock for receive thread */
	kcondvar_t		rcv_thr_cv;	/* cond.var for recv thread */

	/* receive polling fields */
	boolean_t		polling_on;	/* polling enabled ? */
	mblk_t			*pollq_headp;	/* head of pkts in pollq */
	mblk_t			*pollq_tailp;	/* tail of pkts in pollq */

	/* channel statistics */
	vgen_stats_t		stats;		/* channel statistics */
	kstat_t			*ksp;		/* channel kstats */

} vgen_ldc_t;

/* Channel list structure */
typedef struct vgen_ldclist_s {
	vgen_ldc_t	*headp;		/* head of the list */
	krwlock_t	rwlock;		/* sync access to the list */
} vgen_ldclist_t;

/* port information  structure */
typedef struct vgen_port {
	struct vgen_port	*nextp;		/* next port in the list */
	struct vgen		*vgenp;		/* associated vgen_t */
	int			port_num;	/* port number */
	boolean_t		is_vsw_port;	/* connected to vswitch ? */
	int			num_ldcs;	/* # of channels in this port */
	uint64_t		*ldc_ids;	/* channel ids */
	vgen_ldclist_t		ldclist;	/* list of ldcs for this port */
	ether_addr_t		macaddr;	/* mac address of peer */
	uint16_t		pvid;		/* port vlan id (untagged) */
	uint16_t		*vids;		/* vlan ids (tagged) */
	uint16_t		nvids;		/* # of vids */
	mod_hash_t		*vlan_hashp;	/* vlan hash table */
	uint32_t		vlan_nchains;	/* # of vlan hash chains */
	uint32_t		use_vsw_port;	/* Use vsw_port or not */
	uint32_t		flags;		/* status of this port */
	vio_net_callbacks_t	vcb;		/* vnet callbacks */
	vio_net_handle_t	vhp;		/* handle from vnet */
	kmutex_t		lock;		/* synchornize ops */
} vgen_port_t;

/* port list structure */
typedef struct vgen_portlist {
	vgen_port_t	*headp;		/* head of ports */
	vgen_port_t	*tailp;		/* tail */
	krwlock_t	rwlock;		/* sync access to the port list */
} vgen_portlist_t;

/* vgen instance information  */
typedef struct vgen {
	vnet_t			*vnetp;		/* associated vnet instance */
	int			instance;	/* vnet instance */
	dev_info_t		*vnetdip;	/* dip of vnet */
	uint64_t		regprop;	/* "reg" property */
	ether_addr_t		macaddr;	/* mac addr of vnet */
	kmutex_t		lock;		/* synchornize ops */
	int			flags;		/* flags */
	vgen_portlist_t		vgenports;	/* Port List */
	mdeg_node_spec_t	*mdeg_parentp;
	mdeg_handle_t		mdeg_dev_hdl;	/* mdeg cb handle for device */
	mdeg_handle_t		mdeg_port_hdl;	/* mdeg cb handle for port */
	vgen_port_t		*vsw_portp;	/* port connected to vsw */
	struct ether_addr	*mctab;		/* multicast addr table */
	uint32_t		mcsize;		/* allocated size of mctab */
	uint32_t		mccount;	/* # of valid addrs in mctab */
	vio_mblk_pool_t		*rmp;		/* rx mblk pools to be freed */
	uint32_t		pri_num_types;	/* # of priority eth types */
	uint16_t		*pri_types;	/* priority eth types */
	vio_mblk_pool_t		*pri_tx_vmp;	/* tx priority mblk pool */
	uint32_t		max_frame_size;	/* max frame size supported */

	uint32_t		vsw_port_refcnt; /* refcnt for vsw_port */
	boolean_t		pls_negotiated;	/* phys link state update ? */
	link_state_t		phys_link_state; /* physical link state */
} vgen_t;

#ifdef __cplusplus
}
#endif

#endif	/* _VNET_GEN_H */