xref: /titanic_51/usr/src/uts/sun4v/sys/vsw_ldc.h (revision 34f94fbc7a730740933e4776ade5f74009afe4ce)
106db247cSraghuram /*
206db247cSraghuram  * CDDL HEADER START
306db247cSraghuram  *
406db247cSraghuram  * The contents of this file are subject to the terms of the
506db247cSraghuram  * Common Development and Distribution License (the "License").
606db247cSraghuram  * You may not use this file except in compliance with the License.
706db247cSraghuram  *
806db247cSraghuram  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
906db247cSraghuram  * or http://www.opensolaris.org/os/licensing.
1006db247cSraghuram  * See the License for the specific language governing permissions
1106db247cSraghuram  * and limitations under the License.
1206db247cSraghuram  *
1306db247cSraghuram  * When distributing Covered Code, include this CDDL HEADER in each
1406db247cSraghuram  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1506db247cSraghuram  * If applicable, add the following below this CDDL HEADER, with the
1606db247cSraghuram  * fields enclosed by brackets "[]" replaced with your own identifying
1706db247cSraghuram  * information: Portions Copyright [yyyy] [name of copyright owner]
1806db247cSraghuram  *
1906db247cSraghuram  * CDDL HEADER END
2006db247cSraghuram  */
2106db247cSraghuram 
2206db247cSraghuram /*
230e263307SWENTAO YANG  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
2406db247cSraghuram  */
2506db247cSraghuram 
2606db247cSraghuram /*
2706db247cSraghuram  * This header file contains the basic data structures which the
2806db247cSraghuram  * virtual switch (vsw) uses to communicate with vnet clients.
2906db247cSraghuram  *
3006db247cSraghuram  * The virtual switch reads the machine description (MD) to
3106db247cSraghuram  * determine how many port_t structures to create (each port_t
3206db247cSraghuram  * can support communications to a single network device). The
3306db247cSraghuram  * port_t's are maintained in a linked list.
3406db247cSraghuram  *
3506db247cSraghuram  * Each port in turn contains a number of logical domain channels
3606db247cSraghuram  * (ldc's) which are inter domain communications channels which
377bd3a2e2SSriharsha Basavapatna  * are used for passing small messages between the domains. There
387bd3a2e2SSriharsha Basavapatna  * may be any number of channels associated with each port, though
397bd3a2e2SSriharsha Basavapatna  * currently most devices only have a single channel. The current
407bd3a2e2SSriharsha Basavapatna  * implementation provides support for only one channel per port.
4106db247cSraghuram  *
4206db247cSraghuram  * The ldc is a bi-directional channel, which is divided up into
4306db247cSraghuram  * two directional 'lanes', one outbound from the switch to the
4406db247cSraghuram  * virtual network device, the other inbound to the switch.
4506db247cSraghuram  * Depending on the type of device each lane may have seperate
4606db247cSraghuram  * communication paramaters (such as mtu etc).
4706db247cSraghuram  *
4806db247cSraghuram  * For those network clients which use descriptor rings the
4906db247cSraghuram  * rings are associated with the appropriate lane. I.e. rings
5006db247cSraghuram  * which the switch exports are associated with the outbound lanes
5106db247cSraghuram  * while those which the network clients are exporting to the switch
5206db247cSraghuram  * are associated with the inbound lane.
5306db247cSraghuram  *
5406db247cSraghuram  * In diagram form the data structures look as follows:
5506db247cSraghuram  *
5606db247cSraghuram  * vsw instance
5706db247cSraghuram  *     |
5806db247cSraghuram  *     +----->port_t----->port_t----->port_t----->
5906db247cSraghuram  *		|
607bd3a2e2SSriharsha Basavapatna  *		+--->ldc_t
6106db247cSraghuram  *		       |
6206db247cSraghuram  *		       +--->lane_t (inbound)
6306db247cSraghuram  *		       |       |
647bd3a2e2SSriharsha Basavapatna  *		       |       +--->dring
6506db247cSraghuram  *		       |
6606db247cSraghuram  *		       +--->lane_t (outbound)
6706db247cSraghuram  *			       |
687bd3a2e2SSriharsha Basavapatna  *			       +--->dring
6906db247cSraghuram  *
7006db247cSraghuram  */
7106db247cSraghuram 
7206db247cSraghuram #ifndef	_VSW_LDC_H
7306db247cSraghuram #define	_VSW_LDC_H
7406db247cSraghuram 
7506db247cSraghuram #ifdef	__cplusplus
7606db247cSraghuram extern "C" {
7706db247cSraghuram #endif
7806db247cSraghuram 
7906db247cSraghuram /*
807bd3a2e2SSriharsha Basavapatna  * LDC pkt tranfer MTU - largest msg size used
817bd3a2e2SSriharsha Basavapatna  */
827bd3a2e2SSriharsha Basavapatna #define	VSW_LDC_MTU		64
837bd3a2e2SSriharsha Basavapatna 
847bd3a2e2SSriharsha Basavapatna #define	VSW_DEF_MSG_WORDS	\
857bd3a2e2SSriharsha Basavapatna 	(VNET_DRING_REG_EXT_MSG_SIZE_MAX / sizeof (uint64_t))
867bd3a2e2SSriharsha Basavapatna 
877bd3a2e2SSriharsha Basavapatna /*
8806db247cSraghuram  * Default message type.
8906db247cSraghuram  */
9006db247cSraghuram typedef struct def_msg {
917bd3a2e2SSriharsha Basavapatna 	uint64_t	data[VSW_DEF_MSG_WORDS];
9206db247cSraghuram } def_msg_t;
9306db247cSraghuram 
9406db247cSraghuram /*
9506db247cSraghuram  * Currently only support one major/minor pair.
9606db247cSraghuram  */
9706db247cSraghuram #define	VSW_NUM_VER	1
9806db247cSraghuram 
9906db247cSraghuram typedef struct ver_sup {
100f2b610cfSwentaoy 	uint16_t	ver_major;	/* major version number */
101f2b610cfSwentaoy 	uint16_t	ver_minor;	/* minor version number */
10206db247cSraghuram } ver_sup_t;
10306db247cSraghuram 
10406db247cSraghuram /*
10506db247cSraghuram  * Lane states.
10606db247cSraghuram  */
10706db247cSraghuram #define	VSW_LANE_INACTIV	0x0	/* No params set for lane */
10806db247cSraghuram 
10906db247cSraghuram #define	VSW_VER_INFO_SENT	0x1	/* Version # sent to peer */
11006db247cSraghuram #define	VSW_VER_INFO_RECV	0x2	/* Version # recv from peer */
11106db247cSraghuram #define	VSW_VER_ACK_RECV	0x4
11206db247cSraghuram #define	VSW_VER_ACK_SENT	0x8
11306db247cSraghuram #define	VSW_VER_NACK_RECV	0x10
11406db247cSraghuram #define	VSW_VER_NACK_SENT	0x20
11506db247cSraghuram 
11606db247cSraghuram #define	VSW_ATTR_INFO_SENT	0x40	/* Attributes sent to peer */
11706db247cSraghuram #define	VSW_ATTR_INFO_RECV	0x80	/* Peer attributes received */
11806db247cSraghuram #define	VSW_ATTR_ACK_SENT	0x100
11906db247cSraghuram #define	VSW_ATTR_ACK_RECV	0x200
12006db247cSraghuram #define	VSW_ATTR_NACK_SENT	0x400
12106db247cSraghuram #define	VSW_ATTR_NACK_RECV	0x800
12206db247cSraghuram 
12306db247cSraghuram #define	VSW_DRING_INFO_SENT	0x1000	/* Dring info sent to peer */
12406db247cSraghuram #define	VSW_DRING_INFO_RECV	0x2000	/* Dring info received */
12506db247cSraghuram #define	VSW_DRING_ACK_SENT	0x4000
12606db247cSraghuram #define	VSW_DRING_ACK_RECV	0x8000
12706db247cSraghuram #define	VSW_DRING_NACK_SENT	0x10000
12806db247cSraghuram #define	VSW_DRING_NACK_RECV	0x20000
12906db247cSraghuram 
13006db247cSraghuram #define	VSW_RDX_INFO_SENT	0x40000	/* RDX sent to peer */
13106db247cSraghuram #define	VSW_RDX_INFO_RECV	0x80000	/* RDX received from peer */
13206db247cSraghuram #define	VSW_RDX_ACK_SENT	0x100000
13306db247cSraghuram #define	VSW_RDX_ACK_RECV	0x200000
13406db247cSraghuram #define	VSW_RDX_NACK_SENT	0x400000
13506db247cSraghuram #define	VSW_RDX_NACK_RECV	0x800000
13606db247cSraghuram 
13706db247cSraghuram #define	VSW_MCST_INFO_SENT	0x1000000
13806db247cSraghuram #define	VSW_MCST_INFO_RECV	0x2000000
13906db247cSraghuram #define	VSW_MCST_ACK_SENT	0x4000000
14006db247cSraghuram #define	VSW_MCST_ACK_RECV	0x8000000
14106db247cSraghuram #define	VSW_MCST_NACK_SENT	0x10000000
14206db247cSraghuram #define	VSW_MCST_NACK_RECV	0x20000000
14306db247cSraghuram 
14406db247cSraghuram #define	VSW_LANE_ACTIVE		0x40000000	/* Lane open to xmit data */
14506db247cSraghuram 
14606db247cSraghuram /* Handshake milestones */
14706db247cSraghuram #define	VSW_MILESTONE0		0x1	/* ver info exchanged */
14806db247cSraghuram #define	VSW_MILESTONE1		0x2	/* attribute exchanged */
14906db247cSraghuram #define	VSW_MILESTONE2		0x4	/* dring info exchanged */
15006db247cSraghuram #define	VSW_MILESTONE3		0x8	/* rdx exchanged */
15106db247cSraghuram #define	VSW_MILESTONE4		0x10	/* handshake complete */
15206db247cSraghuram 
15306db247cSraghuram /*
15406db247cSraghuram  * Lane direction (relative to ourselves).
15506db247cSraghuram  */
15606db247cSraghuram #define	INBOUND			0x1
15706db247cSraghuram #define	OUTBOUND		0x2
15806db247cSraghuram 
15906db247cSraghuram /* Peer session id received */
16006db247cSraghuram #define	VSW_PEER_SESSION	0x1
16106db247cSraghuram 
16206db247cSraghuram /*
16306db247cSraghuram  * Maximum number of consecutive reads of data from channel
16406db247cSraghuram  */
16506db247cSraghuram #define	VSW_MAX_CHAN_READ	50
16606db247cSraghuram 
16706db247cSraghuram /*
16806db247cSraghuram  * Currently only support one ldc per port.
16906db247cSraghuram  */
17006db247cSraghuram #define	VSW_PORT_MAX_LDCS	1	/* max # of ldcs per port */
17106db247cSraghuram 
17206db247cSraghuram /*
17306db247cSraghuram  * Used for port add/deletion.
17406db247cSraghuram  */
17506db247cSraghuram #define	VSW_PORT_UPDATED	0x1
17606db247cSraghuram 
17706db247cSraghuram #define	LDC_TX_SUCCESS		0	/* ldc transmit success */
17806db247cSraghuram #define	LDC_TX_FAILURE		1	/* ldc transmit failure */
17906db247cSraghuram #define	LDC_TX_NORESOURCES	2	/* out of descriptors */
18006db247cSraghuram 
18106db247cSraghuram /*
18206db247cSraghuram  * Descriptor ring info
18306db247cSraghuram  *
18406db247cSraghuram  * Each descriptor element has a pre-allocated data buffer
18506db247cSraghuram  * associated with it, into which data being transmitted is
18606db247cSraghuram  * copied. By pre-allocating we speed up the copying process.
18706db247cSraghuram  * The buffer is re-used once the peer has indicated that it is
18806db247cSraghuram  * finished with the descriptor.
18906db247cSraghuram  */
19006db247cSraghuram #define	VSW_RING_EL_DATA_SZ	2048	/* Size of data section (bytes) */
19106db247cSraghuram #define	VSW_PRIV_SIZE	sizeof (vnet_private_desc_t)
19206db247cSraghuram 
19306db247cSraghuram #define	VSW_MAX_COOKIES		((ETHERMTU >> MMU_PAGESHIFT) + 2)
19406db247cSraghuram 
19506db247cSraghuram /*
19606db247cSraghuram  * Size of the mblk in each mblk pool.
19706db247cSraghuram  */
19806db247cSraghuram #define	VSW_MBLK_SZ_128		128
19906db247cSraghuram #define	VSW_MBLK_SZ_256		256
20006db247cSraghuram #define	VSW_MBLK_SZ_2048	2048
20106db247cSraghuram 
20206db247cSraghuram /*
20306db247cSraghuram  * Number of mblks in each mblk pool.
20406db247cSraghuram  */
20506db247cSraghuram #define	VSW_NUM_MBLKS	1024
20606db247cSraghuram 
207*34f94fbcSWENTAO YANG /*
208*34f94fbcSWENTAO YANG  * Number of rcv buffers in RxDringData mode
209*34f94fbcSWENTAO YANG  */
210*34f94fbcSWENTAO YANG #define	VSW_RXDRING_NRBUFS	(vsw_num_descriptors * vsw_nrbufs_factor)
211*34f94fbcSWENTAO YANG 
2127bd3a2e2SSriharsha Basavapatna /* increment recv index */
2137bd3a2e2SSriharsha Basavapatna #define	INCR_DESC_INDEX(dp, i)	\
2147bd3a2e2SSriharsha Basavapatna 		((i) = (((i) + 1) & ((dp)->num_descriptors - 1)))
2157bd3a2e2SSriharsha Basavapatna 
2167bd3a2e2SSriharsha Basavapatna /* decrement recv index */
2177bd3a2e2SSriharsha Basavapatna #define	DECR_DESC_INDEX(dp, i)	\
2187bd3a2e2SSriharsha Basavapatna 		((i) = (((i) - 1) & ((dp)->num_descriptors - 1)))
2197bd3a2e2SSriharsha Basavapatna 
2207bd3a2e2SSriharsha Basavapatna #define	INCR_TXI	INCR_DESC_INDEX
2217bd3a2e2SSriharsha Basavapatna #define	DECR_TXI	DECR_DESC_INDEX
2227bd3a2e2SSriharsha Basavapatna #define	INCR_RXI	INCR_DESC_INDEX
2237bd3a2e2SSriharsha Basavapatna #define	DECR_RXI	DECR_DESC_INDEX
2247bd3a2e2SSriharsha Basavapatna 
2257bd3a2e2SSriharsha Basavapatna /* bounds check rx index */
2267bd3a2e2SSriharsha Basavapatna #define	CHECK_DESC_INDEX(dp, i)	\
2277bd3a2e2SSriharsha Basavapatna 		(((i) >= 0) && ((i) < (dp)->num_descriptors))
2287bd3a2e2SSriharsha Basavapatna 
2297bd3a2e2SSriharsha Basavapatna #define	CHECK_RXI	CHECK_DESC_INDEX
2307bd3a2e2SSriharsha Basavapatna #define	CHECK_TXI	CHECK_DESC_INDEX
2317bd3a2e2SSriharsha Basavapatna 
23206db247cSraghuram /*
23306db247cSraghuram  * Private descriptor
23406db247cSraghuram  */
23506db247cSraghuram typedef struct vsw_private_desc {
23606db247cSraghuram 	/*
23706db247cSraghuram 	 * Below lock must be held when accessing the state of
23806db247cSraghuram 	 * a descriptor on either the private or public sections
23906db247cSraghuram 	 * of the ring.
24006db247cSraghuram 	 */
24106db247cSraghuram 	kmutex_t		dstate_lock;
24206db247cSraghuram 	uint64_t		dstate;
24306db247cSraghuram 	vnet_public_desc_t	*descp;
24406db247cSraghuram 	ldc_mem_handle_t	memhandle;
24506db247cSraghuram 	void			*datap;
24606db247cSraghuram 	uint64_t		datalen;
24706db247cSraghuram 	uint64_t		ncookies;
24806db247cSraghuram 	ldc_mem_cookie_t	memcookie[VSW_MAX_COOKIES];
24906db247cSraghuram 	int			bound;
25006db247cSraghuram } vsw_private_desc_t;
25106db247cSraghuram 
25206db247cSraghuram /*
25306db247cSraghuram  * Descriptor ring structure
25406db247cSraghuram  */
25506db247cSraghuram typedef struct dring_info {
2567bd3a2e2SSriharsha Basavapatna 	kmutex_t		dlock;		/* sync access */
2577bd3a2e2SSriharsha Basavapatna 	uint32_t		num_descriptors; /* # of descriptors */
2587bd3a2e2SSriharsha Basavapatna 	uint32_t		descriptor_size; /* size of descriptor */
2597bd3a2e2SSriharsha Basavapatna 	uint32_t		options;	/* dring options (mode) */
2607bd3a2e2SSriharsha Basavapatna 	ldc_dring_handle_t	dring_handle;	/* dring LDC handle */
2617bd3a2e2SSriharsha Basavapatna 	uint32_t		dring_ncookies;	/* # of dring cookies */
2627bd3a2e2SSriharsha Basavapatna 	ldc_mem_cookie_t	dring_cookie[1]; /* LDC cookie of dring */
2637bd3a2e2SSriharsha Basavapatna 	ldc_mem_handle_t	data_handle;	/* data area  LDC handle */
2647bd3a2e2SSriharsha Basavapatna 	uint32_t		data_ncookies;	/* # of data area cookies */
2657bd3a2e2SSriharsha Basavapatna 	ldc_mem_cookie_t	*data_cookie;	/* data area LDC cookies */
26606db247cSraghuram 	uint64_t		ident;		/* identifier sent to peer */
26706db247cSraghuram 	uint64_t		end_idx;	/* last idx processed */
2687bd3a2e2SSriharsha Basavapatna 	int64_t			last_ack_recv;	/* last ack received */
2697bd3a2e2SSriharsha Basavapatna 	kmutex_t		txlock;		/* protect tx desc alloc */
2707bd3a2e2SSriharsha Basavapatna 	uint32_t		next_txi;	/* next tx descriptor index */
2717bd3a2e2SSriharsha Basavapatna 	uint32_t		next_rxi;	/* next expected recv index */
2727bd3a2e2SSriharsha Basavapatna 	kmutex_t		restart_lock;	/* protect restart_reqd */
27306db247cSraghuram 	boolean_t		restart_reqd;	/* send restart msg */
2740e263307SWENTAO YANG 	uint32_t		restart_peer_txi; /* index to restart peer */
27506db247cSraghuram 	void			*pub_addr;	/* base of public section */
27606db247cSraghuram 	void			*priv_addr;	/* base of private section */
27706db247cSraghuram 	void			*data_addr;	/* base of data section */
27806db247cSraghuram 	size_t			data_sz;	/* size of data section */
279c1c61f44Ssb155480 	size_t			desc_data_sz;	/* size of descr data blk */
280bbfa0259Sha137994 	uint8_t			dring_mtype;	/* dring mem map type */
2817bd3a2e2SSriharsha Basavapatna 	uint32_t		num_bufs;	/* # of buffers */
2827bd3a2e2SSriharsha Basavapatna 	vio_mblk_pool_t		*rx_vmp;	/* rx mblk pool */
2837bd3a2e2SSriharsha Basavapatna 	vio_mblk_t		**rxdp_to_vmp;	/* descr to buf map tbl */
28406db247cSraghuram } dring_info_t;
28506db247cSraghuram 
28606db247cSraghuram /*
28706db247cSraghuram  * Each ldc connection is comprised of two lanes, incoming
28806db247cSraghuram  * from a peer, and outgoing to that peer. Each lane shares
28906db247cSraghuram  * common ldc parameters and also has private lane-specific
29006db247cSraghuram  * parameters.
29106db247cSraghuram  */
29206db247cSraghuram typedef struct lane {
29306db247cSraghuram 	uint64_t	lstate;		/* Lane state */
294f2b610cfSwentaoy 	uint16_t	ver_major;	/* Version major number */
295f2b610cfSwentaoy 	uint16_t	ver_minor;	/* Version minor number */
29606db247cSraghuram 	uint64_t	seq_num;	/* Sequence number */
29706db247cSraghuram 	uint64_t	mtu;		/* ETHERMTU */
29806db247cSraghuram 	uint64_t	addr;		/* Unique physical address */
29906db247cSraghuram 	uint8_t		addr_type;	/* Only MAC address at moment */
30006db247cSraghuram 	uint8_t		xfer_mode;	/* Dring or Pkt based */
30106db247cSraghuram 	uint8_t		ack_freq;	/* Only non zero for Pkt based xfer */
3021107ea93SSriharsha Basavapatna 	uint32_t	physlink_update;	/* physlink updates */
3037bd3a2e2SSriharsha Basavapatna 	uint8_t		dring_mode;	/* Descriptor ring mode */
30406db247cSraghuram 	dring_info_t	*dringp;	/* List of drings for this lane */
30506db247cSraghuram } lane_t;
30606db247cSraghuram 
30706db247cSraghuram /* channel drain states */
30806db247cSraghuram #define	VSW_LDC_INIT		0x1	/* Initial non-drain state */
30906db247cSraghuram #define	VSW_LDC_DRAINING	0x2	/* Channel draining */
31006db247cSraghuram 
311f0ca1d9aSsb155480 /*
312f0ca1d9aSsb155480  * vnet-protocol-version dependent function prototypes.
313f0ca1d9aSsb155480  */
314f0ca1d9aSsb155480 typedef int	(*vsw_ldctx_t) (void *, mblk_t *, mblk_t *, uint32_t);
315f0ca1d9aSsb155480 typedef void	(*vsw_ldcrx_pktdata_t) (void *, void *, uint32_t);
3167bd3a2e2SSriharsha Basavapatna typedef void	(*vsw_ldcrx_dringdata_t) (void *, void *);
317f0ca1d9aSsb155480 
31806db247cSraghuram /* ldc information associated with a vsw-port */
31906db247cSraghuram typedef struct vsw_ldc {
32006db247cSraghuram 	struct vsw_ldc		*ldc_next;	/* next ldc in the list */
32106db247cSraghuram 	struct vsw_port		*ldc_port;	/* associated port */
32206db247cSraghuram 	struct vsw		*ldc_vswp;	/* associated vsw */
32306db247cSraghuram 	kmutex_t		ldc_cblock;	/* sync callback processing */
32406db247cSraghuram 	kmutex_t		ldc_txlock;	/* sync transmits */
32506db247cSraghuram 	kmutex_t		ldc_rxlock;	/* sync rx */
32606db247cSraghuram 	uint64_t		ldc_id;		/* channel number */
32706db247cSraghuram 	ldc_handle_t		ldc_handle;	/* channel handle */
32806db247cSraghuram 	kmutex_t		drain_cv_lock;
32906db247cSraghuram 	kcondvar_t		drain_cv;	/* channel draining */
33006db247cSraghuram 	int			drain_state;
33106db247cSraghuram 	uint32_t		hphase;		/* handshake phase */
33206db247cSraghuram 	int			hcnt;		/* # handshake attempts */
33306db247cSraghuram 	kmutex_t		status_lock;
33406db247cSraghuram 	ldc_status_t		ldc_status;	/* channel status */
33506db247cSraghuram 	uint8_t			reset_active;	/* reset flag */
33606db247cSraghuram 	uint64_t		local_session;	/* Our session id */
33706db247cSraghuram 	uint64_t		peer_session;	/* Our peers session id */
33806db247cSraghuram 	uint8_t			session_status;	/* Session recv'd, sent */
33906db247cSraghuram 	uint32_t		hss_id;		/* Handshake session id */
34006db247cSraghuram 	uint64_t		next_ident;	/* Next dring ident # to use */
34106db247cSraghuram 	lane_t			lane_in;	/* Inbound lane */
34206db247cSraghuram 	lane_t			lane_out;	/* Outbound lane */
34306db247cSraghuram 	uint8_t			dev_class;	/* Peer device class */
3441107ea93SSriharsha Basavapatna 	boolean_t		pls_negotiated;	/* phys link state update ? */
34506db247cSraghuram 	vio_multi_pool_t	vmp;		/* Receive mblk pools */
3467b1f684aSSriharsha Basavapatna 	uint32_t		max_rxpool_size; /* max size of rxpool in use */
347f0ca1d9aSsb155480 	uint64_t		*ldcmsg;	/* msg buffer for ldc_read() */
348f0ca1d9aSsb155480 	uint64_t		msglen;		/* size of ldcmsg */
3497bd3a2e2SSriharsha Basavapatna 	uint32_t		dringdata_msgid; /* msgid in RxDringData mode */
35006db247cSraghuram 
35106db247cSraghuram 	/* tx thread fields */
35206db247cSraghuram 	kthread_t		*tx_thread;	/* tx thread */
35306db247cSraghuram 	uint32_t		tx_thr_flags;	/* tx thread flags */
35406db247cSraghuram 	kmutex_t		tx_thr_lock;	/* lock for tx thread */
35506db247cSraghuram 	kcondvar_t		tx_thr_cv;	/* cond.var for tx thread */
35606db247cSraghuram 	mblk_t			*tx_mhead;	/* tx mblks head */
35706db247cSraghuram 	mblk_t			*tx_mtail;	/* tx mblks tail */
358f0ca1d9aSsb155480 	uint32_t		tx_cnt;		/* # of pkts queued for tx */
35906db247cSraghuram 
3607bd3a2e2SSriharsha Basavapatna 	/* message thread fields */
3617bd3a2e2SSriharsha Basavapatna 	kthread_t		*msg_thread;	/* message thread */
3627bd3a2e2SSriharsha Basavapatna 	uint32_t		msg_thr_flags;	/* message thread flags */
3637bd3a2e2SSriharsha Basavapatna 	kmutex_t		msg_thr_lock;	/* lock for message thread */
3647bd3a2e2SSriharsha Basavapatna 	kcondvar_t		msg_thr_cv;	/* cond.var for msg thread */
3657bd3a2e2SSriharsha Basavapatna 
36606db247cSraghuram 	/* receive thread fields */
3677bd3a2e2SSriharsha Basavapatna 	kthread_t		*rcv_thread;	/* receive thread */
3687bd3a2e2SSriharsha Basavapatna 	uint32_t		rcv_thr_flags;	/* receive thread flags */
3697bd3a2e2SSriharsha Basavapatna 	kmutex_t		rcv_thr_lock;	/* lock for receive thread */
3707bd3a2e2SSriharsha Basavapatna 	kcondvar_t		rcv_thr_cv;	/* cond.var for recv thread */
37106db247cSraghuram 
372f0ca1d9aSsb155480 	vsw_ldctx_t		tx;		/* transmit function */
3737bd3a2e2SSriharsha Basavapatna 	vsw_ldcrx_pktdata_t	rx_pktdata;	/* process raw data msg */
3747bd3a2e2SSriharsha Basavapatna 	vsw_ldcrx_dringdata_t	rx_dringdata;	/* process dring data msg */
375f0ca1d9aSsb155480 
37606db247cSraghuram 	/* channel statistics */
37706db247cSraghuram 	vgen_stats_t		ldc_stats;	/* channel statistics */
37806db247cSraghuram 	kstat_t			*ksp;		/* channel kstats */
37906db247cSraghuram } vsw_ldc_t;
38006db247cSraghuram 
38106db247cSraghuram /* worker thread flags */
3826f09f0feSWENTAO YANG #define	VSW_WTHR_DATARCVD 	0x01	/* data received */
3836f09f0feSWENTAO YANG #define	VSW_WTHR_STOP 		0x02	/* stop worker thread request */
38406db247cSraghuram 
38506db247cSraghuram /* multicast addresses port is interested in */
38606db247cSraghuram typedef struct mcst_addr {
38706db247cSraghuram 	struct mcst_addr	*nextp;
38806db247cSraghuram 	struct ether_addr	mca;	/* multicast address */
38906db247cSraghuram 	uint64_t		addr;	/* mcast addr converted to hash key */
39006db247cSraghuram 	boolean_t		mac_added; /* added into physical device */
39106db247cSraghuram } mcst_addr_t;
39206db247cSraghuram 
39306db247cSraghuram /* Port detach states */
39406db247cSraghuram #define	VSW_PORT_INIT		0x1	/* Initial non-detach state */
39506db247cSraghuram #define	VSW_PORT_DETACHING	0x2	/* In process of being detached */
39606db247cSraghuram #define	VSW_PORT_DETACHABLE	0x4	/* Safe to detach */
39706db247cSraghuram 
39806db247cSraghuram /* port information associated with a vsw */
39906db247cSraghuram typedef struct vsw_port {
40006db247cSraghuram 	int			p_instance;	/* port instance */
40106db247cSraghuram 	struct vsw_port		*p_next;	/* next port in the list */
40206db247cSraghuram 	struct vsw		*p_vswp;	/* associated vsw */
403c1c61f44Ssb155480 	int			num_ldcs;	/* # of ldcs in the port */
404c1c61f44Ssb155480 	uint64_t		*ldc_ids;	/* ldc ids */
4057bd3a2e2SSriharsha Basavapatna 	vsw_ldc_t		*ldcp;		/* ldc for this port */
40606db247cSraghuram 
40706db247cSraghuram 	kmutex_t		tx_lock;	/* transmit lock */
40806db247cSraghuram 	int			(*transmit)(vsw_ldc_t *, mblk_t *);
40906db247cSraghuram 
41006db247cSraghuram 	int			state;		/* port state */
41106db247cSraghuram 	kmutex_t		state_lock;
41206db247cSraghuram 	kcondvar_t		state_cv;
41306db247cSraghuram 
414da14cebeSEric Cheng 	krwlock_t		maccl_rwlock;	/* protect fields below */
415da14cebeSEric Cheng 	mac_client_handle_t	p_mch;		/* mac client handle */
416da14cebeSEric Cheng 	mac_unicast_handle_t	p_muh;		/* mac unicast handle */
417da14cebeSEric Cheng 
41806db247cSraghuram 	kmutex_t		mca_lock;	/* multicast lock */
41906db247cSraghuram 	mcst_addr_t		*mcap;		/* list of multicast addrs */
42006db247cSraghuram 
421da14cebeSEric Cheng 	boolean_t		addr_set;	/* Addr set where */
42206db247cSraghuram 
42306db247cSraghuram 	/*
42406db247cSraghuram 	 * mac address of the port & connected device
42506db247cSraghuram 	 */
42606db247cSraghuram 	struct ether_addr	p_macaddr;
427c1c61f44Ssb155480 	uint16_t		pvid;	/* port vlan id (untagged) */
428da14cebeSEric Cheng 	struct vsw_vlanid	*vids;	/* vlan ids (tagged) */
429c1c61f44Ssb155480 	uint16_t		nvids;	/* # of vids */
430c1c61f44Ssb155480 	mod_hash_t		*vlan_hashp;	/* vlan hash table */
431c1c61f44Ssb155480 	uint32_t		vlan_nchains;	/* # of vlan hash chains */
432678453a8Sspeer 
433678453a8Sspeer 	/* HybridIO related info */
434678453a8Sspeer 	uint32_t		p_hio_enabled;	/* Hybrid mode enabled? */
435678453a8Sspeer 	uint32_t		p_hio_capable;	/* Port capable of HIO */
436bce0a86eSWENTAO YANG 
437bce0a86eSWENTAO YANG 	/* bandwidth limit */
438bce0a86eSWENTAO YANG 	uint64_t		p_bandwidth;	/* bandwidth limit */
43906db247cSraghuram } vsw_port_t;
44006db247cSraghuram 
44106db247cSraghuram /* list of ports per vsw */
44206db247cSraghuram typedef struct vsw_port_list {
44306db247cSraghuram 	vsw_port_t	*head;		/* head of the list */
44406db247cSraghuram 	krwlock_t	lockrw;		/* sync access(rw) to the list */
44506db247cSraghuram 	int		num_ports;	/* number of ports in the list */
44606db247cSraghuram } vsw_port_list_t;
44706db247cSraghuram 
44806db247cSraghuram /*
44906db247cSraghuram  * Taskq control message
45006db247cSraghuram  */
45106db247cSraghuram typedef struct vsw_ctrl_task {
45206db247cSraghuram 	vsw_ldc_t	*ldcp;
45306db247cSraghuram 	def_msg_t	pktp;
45406db247cSraghuram 	uint32_t	hss_id;
45506db247cSraghuram } vsw_ctrl_task_t;
45606db247cSraghuram 
45706db247cSraghuram /*
45806db247cSraghuram  * State of connection to peer. Some of these states
45906db247cSraghuram  * can be mapped to LDC events as follows:
46006db247cSraghuram  *
46106db247cSraghuram  * VSW_CONN_RESET -> LDC_RESET_EVT
46206db247cSraghuram  * VSW_CONN_UP    -> LDC_UP_EVT
46306db247cSraghuram  */
46406db247cSraghuram #define	VSW_CONN_UP		0x1	/* Connection come up */
46506db247cSraghuram #define	VSW_CONN_RESET		0x2	/* Connection reset */
46606db247cSraghuram #define	VSW_CONN_RESTART	0x4	/* Restarting handshake on connection */
46706db247cSraghuram 
46806db247cSraghuram typedef struct vsw_conn_evt {
46906db247cSraghuram 	uint16_t	evt;		/* Connection event */
47006db247cSraghuram 	vsw_ldc_t	*ldcp;
47106db247cSraghuram } vsw_conn_evt_t;
47206db247cSraghuram 
47306db247cSraghuram /*
47406db247cSraghuram  * Ethernet broadcast address definition.
47506db247cSraghuram  */
47606db247cSraghuram static	struct	ether_addr	etherbroadcastaddr = {
47706db247cSraghuram 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff
47806db247cSraghuram };
47906db247cSraghuram 
48006db247cSraghuram #define	IS_BROADCAST(ehp) \
481da14cebeSEric Cheng 	(bcmp(&ehp->ether_dhost, &etherbroadcastaddr, ETHERADDRL) == 0)
48206db247cSraghuram #define	IS_MULTICAST(ehp) \
48306db247cSraghuram 	((ehp->ether_dhost.ether_addr_octet[0] & 01) == 1)
48406db247cSraghuram 
48506db247cSraghuram #define	READ_ENTER(x)	rw_enter(x, RW_READER)
48606db247cSraghuram #define	WRITE_ENTER(x)	rw_enter(x, RW_WRITER)
48706db247cSraghuram #define	RW_EXIT(x)	rw_exit(x)
48806db247cSraghuram 
48906db247cSraghuram #define	VSW_PORT_REFHOLD(portp)	atomic_inc_32(&((portp)->ref_cnt))
49006db247cSraghuram #define	VSW_PORT_REFRELE(portp)	atomic_dec_32(&((portp)->ref_cnt))
49106db247cSraghuram 
49206db247cSraghuram #ifdef	__cplusplus
49306db247cSraghuram }
49406db247cSraghuram #endif
49506db247cSraghuram 
49606db247cSraghuram #endif	/* _VSW_LDC_H */
497