Home | History | Annotate | Download | only in sys
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #ifndef _VNET_GEN_H
     28 #define	_VNET_GEN_H
     29 
     30 #ifdef __cplusplus
     31 extern "C" {
     32 #endif
     33 
     34 #include <sys/vgen_stats.h>
     35 
     36 #define	VGEN_SUCCESS		(0)	/* successful return */
     37 #define	VGEN_FAILURE		(-1)	/* unsuccessful return */
     38 
     39 #define	VGEN_NUM_VER		1	/* max # of vgen versions */
     40 
     41 #define	VGEN_LOCAL	1	/* local ldc end-point */
     42 #define	VGEN_PEER	2	/* peer ldc end-point */
     43 
     44 /* vgen_t flags */
     45 #define	VGEN_STOPPED		0x0
     46 #define	VGEN_STARTED		0x1
     47 
     48 #define	KMEM_FREE(_p)		kmem_free((_p), sizeof (*(_p)))
     49 
     50 #define	VGEN_INIT_MCTAB_SIZE	16	/* initial size of multicast table */
     51 
     52 #define	READ_ENTER(x)	rw_enter(x, RW_READER)
     53 #define	WRITE_ENTER(x)	rw_enter(x, RW_WRITER)
     54 #define	RW_EXIT(x)	rw_exit(x)
     55 
     56 /* channel flags */
     57 #define	CHANNEL_ATTACHED	0x1
     58 #define	CHANNEL_STARTED		0x2
     59 
     60 /* transmit return values */
     61 #define	VGEN_TX_SUCCESS		0	/* transmit success */
     62 #define	VGEN_TX_FAILURE		1	/* transmit failure */
     63 #define	VGEN_TX_NORESOURCES	2	/* out of tbufs/txds */
     64 
     65 /* private descriptor flags */
     66 #define	VGEN_PRIV_DESC_FREE	0x0	/* desc is available */
     67 #define	VGEN_PRIV_DESC_BUSY	0x1	/* desc in use */
     68 
     69 #define	LDC_TO_VNET(ldcp)  ((ldcp)->portp->vgenp->vnetp)
     70 #define	LDC_TO_VGEN(ldcp)  ((ldcp)->portp->vgenp)
     71 
     72 /* receive thread flags */
     73 #define	VGEN_WTHR_DATARCVD 	0x01	/* data received */
     74 #define	VGEN_WTHR_STOP 		0x02	/* stop worker thread request */
     75 #define	VGEN_WTHR_PROCESSING	0x04	/* worker thread awake & processing */
     76 
     77 #define	VGEN_LDC_UP_DELAY	100	/* usec delay between ldc_up retries */
     78 #define	VGEN_LDC_CLOSE_DELAY	100	/* usec delay between ldc_cl retries */
     79 
     80 #define	VGEN_NUM_VMPOOLS	3	/* number of vio mblk pools */
     81 
     82 #define	VGEN_DBLK_SZ_128	128	/* data buffer size 128 bytes */
     83 #define	VGEN_DBLK_SZ_256	256	/* data buffer size 256 bytes */
     84 #define	VGEN_DBLK_SZ_2048	2048	/* data buffer size 2K bytes */
     85 #define	VGEN_NRBUFS		512	/* number of receive bufs */
     86 
     87 #define	VGEN_TXDBLK_SZ		2048	/* Tx data buffer size */
     88 
     89 /* get the address of next tbuf */
     90 #define	NEXTTBUF(ldcp, tbufp)	(((tbufp) + 1) == (ldcp)->tbufendp    \
     91 		? (ldcp)->tbufp : ((tbufp) + 1))
     92 
     93 /* increment recv index */
     94 #define	INCR_RXI(i, ldcp)	\
     95 		((i) = (((i) + 1) & ((ldcp)->num_rxds - 1)))
     96 
     97 /* decrement recv index */
     98 #define	DECR_RXI(i, ldcp)	\
     99 		((i) = (((i) - 1) & ((ldcp)->num_rxds - 1)))
    100 
    101 /* increment tx index */
    102 #define	INCR_TXI(i, ldcp)	\
    103 		((i) = (((i) + 1) & ((ldcp)->num_txds - 1)))
    104 
    105 /* decrement tx index */
    106 #define	DECR_TXI(i, ldcp)	\
    107 		((i) = (((i) - 1) & ((ldcp)->num_txds - 1)))
    108 
    109 /* bounds check rx index */
    110 #define	CHECK_RXI(i, ldcp)	\
    111 		(((i) >= 0) && ((i) < (ldcp)->num_rxds))
    112 
    113 /* bounds check tx index */
    114 #define	CHECK_TXI(i, ldcp)	\
    115 		(((i) >= 0) && ((i) < (ldcp)->num_txds))
    116 
    117 /* private descriptor */
    118 typedef struct vgen_priv_desc {
    119 	uint64_t		flags;		/* flag bits */
    120 	vnet_public_desc_t	*descp;		/* associated public desc */
    121 	ldc_mem_handle_t	memhandle;	/* mem handle for data */
    122 	caddr_t			datap;		/* prealloc'd tx data buffer */
    123 	uint64_t		datalen;	/* total actual datalen */
    124 	uint64_t		ncookies;	/* num ldc_mem_cookies */
    125 	ldc_mem_cookie_t	memcookie[MAX_COOKIES];	/* data cookies */
    126 } vgen_private_desc_t;
    127 
    128 /*
    129  * Handshake parameters (per vio_mailbox.h) of each ldc end point, used
    130  * during handshake negotiation.
    131  */
    132 typedef struct vgen_handshake_params {
    133 	/* version specific params */
    134 	uint16_t	ver_major;		/* major version number */
    135 	uint16_t	ver_minor;		/* minor version number */
    136 	uint8_t		dev_class;		/* device class */
    137 
    138 	/* attributes specific params */
    139 	uint64_t		mtu;		/* max transfer unit size */
    140 	uint64_t		addr;		/* address of the device */
    141 	uint8_t			addr_type;	/* type of address */
    142 	uint8_t			xfer_mode;	/* SHM or PKT */
    143 	uint16_t		ack_freq;	/* dring data ack freq */
    144 	uint32_t		physlink_update; /* physlink updates */
    145 
    146 	/* descriptor ring params */
    147 	uint32_t		num_desc;	/* # of descriptors in ring */
    148 	uint32_t		desc_size;	/* size of descriptor */
    149 	ldc_mem_cookie_t	dring_cookie;	/* desc ring cookie */
    150 	uint32_t		num_dcookies;	/* # of dring cookies */
    151 	uint64_t		dring_ident;	/* ident=0 for INFO msg */
    152 	boolean_t		dring_ready;	/* dring ready flag */
    153 } vgen_hparams_t;
    154 
    155 /* version info */
    156 typedef struct vgen_ver {
    157 	uint16_t	ver_major;		/* major version number */
    158 	uint16_t	ver_minor;		/* minor version number */
    159 } vgen_ver_t;
    160 
    161 /*
    162  * vnet-protocol-version dependent function prototypes.
    163  */
    164 typedef int	(*vgen_ldctx_t) (void *, mblk_t *);
    165 typedef void	(*vgen_ldcrx_pktdata_t) (void *, void *, uint32_t);
    166 
    167 /* Channel information associated with a vgen-port */
    168 typedef struct vgen_ldc {
    169 
    170 	struct vgen_ldc		*nextp;		/* next ldc in the list */
    171 	struct vgen_port	*portp;		/* associated port */
    172 
    173 	/*
    174 	 * Locks:
    175 	 * locking hierarchy when more than one lock is held concurrently:
    176 	 * cblock > rxlock > txlock > tclock.
    177 	 */
    178 	kmutex_t		cblock;		/* sync callback processing */
    179 	kmutex_t		txlock;		/* protect txd alloc */
    180 	kmutex_t		tclock;		/* tx reclaim lock */
    181 	kmutex_t		wrlock;		/* sync transmits */
    182 	kmutex_t		rxlock;		/* sync reception */
    183 	kmutex_t		pollq_lock;	/* sync polling and rxworker */
    184 
    185 	/* channel info from ldc layer */
    186 	uint64_t		ldc_id;		/* channel number */
    187 	uint64_t		ldc_handle;	/* channel handle */
    188 	ldc_status_t		ldc_status;	/* channel status */
    189 
    190 	/* handshake info */
    191 	vgen_ver_t		vgen_versions[VGEN_NUM_VER]; /* versions */
    192 	int			hphase;		/* handshake phase */
    193 	int			hstate;		/* handshake state bits */
    194 	link_state_t		link_state;	/* channel link state */
    195 #ifdef	VNET_IOC_DEBUG
    196 	boolean_t		link_down_forced; /* forced link down */
    197 #endif
    198 	uint32_t		local_sid;	/* local session id */
    199 	uint32_t		peer_sid;	/* session id of peer */
    200 	vgen_hparams_t		local_hparams;	/* local handshake params */
    201 	vgen_hparams_t		peer_hparams;	/* peer's handshake params */
    202 	timeout_id_t		htid;		/* handshake wd timeout id */
    203 	timeout_id_t		cancel_htid;	/* cancel handshake watchdog */
    204 
    205 	/* transmit and receive descriptor ring info */
    206 	ldc_dring_handle_t	tx_dhandle;	/* tx descriptor ring handle */
    207 	ldc_mem_cookie_t	tx_dcookie;	/* tx descriptor ring cookie */
    208 	ldc_dring_handle_t	rx_dhandle;	/* mapped rx dhandle */
    209 	ldc_mem_cookie_t	rx_dcookie;	/* rx descriptor ring cookie */
    210 	vnet_public_desc_t	*txdp;		/* transmit frame descriptors */
    211 	vnet_public_desc_t	*txdendp;	/* txd ring end */
    212 	vgen_private_desc_t	*tbufp;		/* associated tx resources */
    213 	vgen_private_desc_t	*tbufendp;	/* tbuf ring end */
    214 	vgen_private_desc_t	*next_tbufp;	/* next free tbuf */
    215 	vgen_private_desc_t	*cur_tbufp;	/* next reclaim tbuf */
    216 	uint64_t		next_txseq;	/* next tx sequence number */
    217 	uint32_t		num_txdcookies;	/* # of tx dring cookies */
    218 	uint32_t		num_rxdcookies;	/* # of rx dring cookies */
    219 	uint8_t			dring_mtype;	/* dring mem map type */
    220 	uint32_t		next_txi;	/* next tx descriptor index */
    221 	uint32_t		num_txds;	/* number of tx descriptors */
    222 	clock_t			reclaim_lbolt;	/* time of last tx reclaim */
    223 	timeout_id_t		wd_tid;		/* tx watchdog timeout id */
    224 	vnet_public_desc_t	*rxdp;		/* receive frame descriptors */
    225 	uint64_t		next_rxseq;	/* next expected recv seqnum */
    226 	uint32_t		next_rxi;	/* next expected recv index */
    227 	uint32_t		num_rxds;	/* number of rx descriptors */
    228 	caddr_t			tx_datap;	/* prealloc'd tx data area */
    229 	size_t			tx_data_sz;	/* alloc'd size of tx databuf */
    230 	vio_multi_pool_t	vmp;		/* rx mblk pools */
    231 	uint32_t		max_rxpool_size; /* max size of rxpool in use */
    232 	uint64_t		*ldcmsg;	/* msg buffer for ldc_read() */
    233 	uint64_t		msglen;		/* size of ldcmsg */
    234 
    235 	/* misc */
    236 	uint32_t		flags;		/* flags */
    237 	boolean_t		need_resched;	/* reschedule tx */
    238 	boolean_t		need_ldc_reset; /* ldc_reset needed */
    239 	uint32_t		hretries;	/* handshake retry count */
    240 	boolean_t		resched_peer;	/* send tx msg to peer */
    241 	uint32_t		resched_peer_txi; /* tx index to resched peer */
    242 
    243 	vgen_ldctx_t		tx;		/* transmit function */
    244 	vgen_ldcrx_pktdata_t	rx_pktdata;	/* process rx raw data msg */
    245 
    246 	/* receive thread field */
    247 	kthread_t		*rcv_thread;	/* receive thread */
    248 	uint32_t		rcv_thr_flags;	/* receive thread flags */
    249 	kmutex_t		rcv_thr_lock;	/* lock for receive thread */
    250 	kcondvar_t		rcv_thr_cv;	/* cond.var for recv thread */
    251 
    252 	/* receive polling fields */
    253 	boolean_t		polling_on;	/* polling enabled ? */
    254 	mblk_t			*pollq_headp;	/* head of pkts in pollq */
    255 	mblk_t			*pollq_tailp;	/* tail of pkts in pollq */
    256 
    257 	/* channel statistics */
    258 	vgen_stats_t		stats;		/* channel statistics */
    259 	kstat_t			*ksp;		/* channel kstats */
    260 
    261 } vgen_ldc_t;
    262 
    263 /* Channel list structure */
    264 typedef struct vgen_ldclist_s {
    265 	vgen_ldc_t	*headp;		/* head of the list */
    266 	krwlock_t	rwlock;		/* sync access to the list */
    267 } vgen_ldclist_t;
    268 
    269 /* port information  structure */
    270 typedef struct vgen_port {
    271 	struct vgen_port	*nextp;		/* next port in the list */
    272 	struct vgen		*vgenp;		/* associated vgen_t */
    273 	int			port_num;	/* port number */
    274 	boolean_t		is_vsw_port;	/* connected to vswitch ? */
    275 	int			num_ldcs;	/* # of channels in this port */
    276 	uint64_t		*ldc_ids;	/* channel ids */
    277 	vgen_ldclist_t		ldclist;	/* list of ldcs for this port */
    278 	ether_addr_t		macaddr;	/* mac address of peer */
    279 	uint16_t		pvid;		/* port vlan id (untagged) */
    280 	uint16_t		*vids;		/* vlan ids (tagged) */
    281 	uint16_t		nvids;		/* # of vids */
    282 	mod_hash_t		*vlan_hashp;	/* vlan hash table */
    283 	uint32_t		vlan_nchains;	/* # of vlan hash chains */
    284 	uint32_t		use_vsw_port;	/* Use vsw_port or not */
    285 	uint32_t		flags;		/* status of this port */
    286 	vio_net_callbacks_t	vcb;		/* vnet callbacks */
    287 	vio_net_handle_t	vhp;		/* handle from vnet */
    288 	kmutex_t		lock;		/* synchornize ops */
    289 } vgen_port_t;
    290 
    291 /* port list structure */
    292 typedef struct vgen_portlist {
    293 	vgen_port_t	*headp;		/* head of ports */
    294 	vgen_port_t	*tailp;		/* tail */
    295 	krwlock_t	rwlock;		/* sync access to the port list */
    296 } vgen_portlist_t;
    297 
    298 /* vgen instance information  */
    299 typedef struct vgen {
    300 	vnet_t			*vnetp;		/* associated vnet instance */
    301 	int			instance;	/* vnet instance */
    302 	dev_info_t		*vnetdip;	/* dip of vnet */
    303 	uint64_t		regprop;	/* "reg" property */
    304 	ether_addr_t		macaddr;	/* mac addr of vnet */
    305 	kmutex_t		lock;		/* synchornize ops */
    306 	int			flags;		/* flags */
    307 	vgen_portlist_t		vgenports;	/* Port List */
    308 	mdeg_node_spec_t	*mdeg_parentp;
    309 	mdeg_handle_t		mdeg_dev_hdl;	/* mdeg cb handle for device */
    310 	mdeg_handle_t		mdeg_port_hdl;	/* mdeg cb handle for port */
    311 	vgen_port_t		*vsw_portp;	/* port connected to vsw */
    312 	struct ether_addr	*mctab;		/* multicast addr table */
    313 	uint32_t		mcsize;		/* allocated size of mctab */
    314 	uint32_t		mccount;	/* # of valid addrs in mctab */
    315 	vio_mblk_pool_t		*rmp;		/* rx mblk pools to be freed */
    316 	uint32_t		pri_num_types;	/* # of priority eth types */
    317 	uint16_t		*pri_types;	/* priority eth types */
    318 	vio_mblk_pool_t		*pri_tx_vmp;	/* tx priority mblk pool */
    319 	uint32_t		max_frame_size;	/* max frame size supported */
    320 
    321 	uint32_t		vsw_port_refcnt; /* refcnt for vsw_port */
    322 	boolean_t		pls_negotiated;	/* phys link state update ? */
    323 	link_state_t		phys_link_state; /* physical link state */
    324 } vgen_t;
    325 
    326 #ifdef __cplusplus
    327 }
    328 #endif
    329 
    330 #endif	/* _VNET_GEN_H */
    331