xref: /titanic_51/usr/src/uts/sun4u/starfire/sys/idn.h (revision 683b29499b14fddf042df3e4ecb71a1d5bebe3a8)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5b0fc0e77Sgovinda  * Common Development and Distribution License (the "License").
6b0fc0e77Sgovinda  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22d3d50737SRafael Vanoni  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  *
257c478bd9Sstevel@tonic-gate  * Inter-Domain Network
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #ifndef	_SYS_IDN_H
297c478bd9Sstevel@tonic-gate #define	_SYS_IDN_H
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #ifndef _ASM
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #ifdef _KERNEL
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #include <sys/note.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
387c478bd9Sstevel@tonic-gate #include <sys/dditypes.h>
397c478bd9Sstevel@tonic-gate #include <sys/stream.h>
407c478bd9Sstevel@tonic-gate #include <sys/machsystm.h>
417c478bd9Sstevel@tonic-gate #include <sys/ethernet.h>
427c478bd9Sstevel@tonic-gate #include <sys/dlpi.h>
437c478bd9Sstevel@tonic-gate #include <sys/time.h>
447c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
457c478bd9Sstevel@tonic-gate #include <sys/atomic.h>
467c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h>
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate #include <sys/idn_sigb.h>
497c478bd9Sstevel@tonic-gate #include <sys/idn_smr.h>
507c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
537c478bd9Sstevel@tonic-gate extern "C" {
547c478bd9Sstevel@tonic-gate #endif
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate typedef const char * const	procname_t;
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate #define	MB2B(m)		((size_t)(m) << 20)	/* MBytes to Bytes */
597c478bd9Sstevel@tonic-gate #define	B2MB(b)		((uint_t)((b) >> 20))	/* Bytes to MBytes */
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate #ifdef _KERNEL
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate /*
647c478bd9Sstevel@tonic-gate  * IDN_PROP_SMRSIZE	- User specified size in MBytes.
657c478bd9Sstevel@tonic-gate  * IDN_PROP_SMRADDR	- OBP's internal physical address of the region.
667c478bd9Sstevel@tonic-gate  *
677c478bd9Sstevel@tonic-gate  *	OBP properties of "memory" node that define the SMR space.
687c478bd9Sstevel@tonic-gate  */
697c478bd9Sstevel@tonic-gate #define	IDN_PROP_SMRSIZE	"idn-smr-size"
707c478bd9Sstevel@tonic-gate #define	IDN_PROP_SMRADDR	"idn-smr-addr"
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate /*
737c478bd9Sstevel@tonic-gate  * IDN_AWOLMSG_INTERVAL	(driver.conf)
747c478bd9Sstevel@tonic-gate  *
757c478bd9Sstevel@tonic-gate  *	Number of seconds between AWOL messages on a per-domain basis.
767c478bd9Sstevel@tonic-gate  *	The purpose is to throttle the frequency at which these
777c478bd9Sstevel@tonic-gate  *	messages appear.
787c478bd9Sstevel@tonic-gate  *
797c478bd9Sstevel@tonic-gate  * IDN_MSGWAIT_NEGO	(driver.conf)
807c478bd9Sstevel@tonic-gate  * IDN_MSGWAIT_CFG
817c478bd9Sstevel@tonic-gate  * IDN_MSGWAIT_CON
827c478bd9Sstevel@tonic-gate  * IDN_MSGWAIT_FIN
837c478bd9Sstevel@tonic-gate  * IDN_MSGWAIT_CMD
847c478bd9Sstevel@tonic-gate  * IDN_MSGWAIT_DATA
857c478bd9Sstevel@tonic-gate  *
867c478bd9Sstevel@tonic-gate  *	Number of seconds to wait for response to respective
877c478bd9Sstevel@tonic-gate  *	message type.
887c478bd9Sstevel@tonic-gate  *
897c478bd9Sstevel@tonic-gate  * IDN_RETRYFREQ_NEGO	(driver.conf)
907c478bd9Sstevel@tonic-gate  * IDN_RETRYFREQ_CON
917c478bd9Sstevel@tonic-gate  * IDN_RETRYFREQ_FIN
927c478bd9Sstevel@tonic-gate  *
937c478bd9Sstevel@tonic-gate  *	Number of seconds to wait between retries of the respective
947c478bd9Sstevel@tonic-gate  *	message type.
957c478bd9Sstevel@tonic-gate  *
967c478bd9Sstevel@tonic-gate  * IDN_SMR_ALIGN	(not tunable)
977c478bd9Sstevel@tonic-gate  *
987c478bd9Sstevel@tonic-gate  *	The hardware registers that describe the SMR are based on a 64K
997c478bd9Sstevel@tonic-gate  *	aligned physical address.
1007c478bd9Sstevel@tonic-gate  *
1017c478bd9Sstevel@tonic-gate  * IDN_SMR_SIZE		(OBP [only])
1027c478bd9Sstevel@tonic-gate  *
1037c478bd9Sstevel@tonic-gate  *	Total size of the SMR (Shared Memory Region) in bytes.
1047c478bd9Sstevel@tonic-gate  *
1057c478bd9Sstevel@tonic-gate  * IDN_NWR_SIZE		(driver.conf)
1067c478bd9Sstevel@tonic-gate  *
1077c478bd9Sstevel@tonic-gate  *	Total size of the NWR (NetWork Region) portion of the SMR which
1087c478bd9Sstevel@tonic-gate  *	is actually used to support network activity.  The NWR is managed
1097c478bd9Sstevel@tonic-gate  *	as simply a pool of I/O buffers which are distributed by the
1107c478bd9Sstevel@tonic-gate  *	Master domain to the Slaves for the purpose of communicating
1117c478bd9Sstevel@tonic-gate  *	between each other.  If not set then the entire SMR is used
1127c478bd9Sstevel@tonic-gate  *	as the NWR.
1137c478bd9Sstevel@tonic-gate  *	Req: IDN_NWR_SIZE <= IDN_SMR_SIZE
1147c478bd9Sstevel@tonic-gate  *
1157c478bd9Sstevel@tonic-gate  * IDN_SMR_BUFSIZE	(driver.conf)
1167c478bd9Sstevel@tonic-gate  *
1177c478bd9Sstevel@tonic-gate  *	Size of individual SMR buffers.  The SMR is divided into chunks
1187c478bd9Sstevel@tonic-gate  *	of IDN_SMR_BUFSIZE bytes.  The IDN_MTU is based on this size
1197c478bd9Sstevel@tonic-gate  *	and thus the IDN_SMR_BUFSIZE should be chosen based on performance.
1207c478bd9Sstevel@tonic-gate  *
1217c478bd9Sstevel@tonic-gate  * IDN_DATA_SIZE	(NOT tunable)
1227c478bd9Sstevel@tonic-gate  *
1237c478bd9Sstevel@tonic-gate  *	Portion of IDN_SMR_BUFSIZE that can contain raw non-IDN dependent
1247c478bd9Sstevel@tonic-gate  *	data.  We subtract IDN_ALIGNSIZE bytes to allow for fast bcopy
1257c478bd9Sstevel@tonic-gate  *	alignment.
1267c478bd9Sstevel@tonic-gate  *	Req: IDN_DATA_SIZE <=
1277c478bd9Sstevel@tonic-gate  *		(IDN_SMR_BUFSIZE - sizeof (smr_pkthdr_t) - IDN_ALIGNSIZE)
1287c478bd9Sstevel@tonic-gate  *
1297c478bd9Sstevel@tonic-gate  * IDN_MTU		(indirectly tunable via IDN_SMR_BUFSIZE)
1307c478bd9Sstevel@tonic-gate  *
1317c478bd9Sstevel@tonic-gate  * 	This size represents the portion of an SMR I/O buffers that can
1327c478bd9Sstevel@tonic-gate  *	contain (ethernet headerless) data.
1337c478bd9Sstevel@tonic-gate  *	Req: IDN_MTU <= IDN_DATA_SIZE - sizeof (ether_header)
1347c478bd9Sstevel@tonic-gate  *
1357c478bd9Sstevel@tonic-gate  * IDN_WINDOW_MAX	(driver.conf)
1367c478bd9Sstevel@tonic-gate  *
1377c478bd9Sstevel@tonic-gate  *	Maximum number of outstanding packets that are allowed per
1387c478bd9Sstevel@tonic-gate  *	domain.  If this value is exceeded for a particular domain
1397c478bd9Sstevel@tonic-gate  *	no further I/Os will be transmitted to that domain until it
1407c478bd9Sstevel@tonic-gate  *	has acknowledged enough of the previous transmission to bring
1417c478bd9Sstevel@tonic-gate  *	down its outstanding I/O count (idn_domain.dio) below this
1427c478bd9Sstevel@tonic-gate  *	value.  In addition, if this value is exceeded then a Timer
1437c478bd9Sstevel@tonic-gate  *	is scheduled to check for any response from the remote domain.
1447c478bd9Sstevel@tonic-gate  *
1457c478bd9Sstevel@tonic-gate  * IDN_WINDOW_INCR	(driver.conf)
1467c478bd9Sstevel@tonic-gate  *
1477c478bd9Sstevel@tonic-gate  *	As more channels/nets are activated on a particular domain
1487c478bd9Sstevel@tonic-gate  *	the greater the number of possible outstanding data packets
1497c478bd9Sstevel@tonic-gate  *	that can be outstanding to a given domain.  Since this natural
1507c478bd9Sstevel@tonic-gate  *	occurence can result in the outstanding-I/O count to a given
1517c478bd9Sstevel@tonic-gate  *	domain to increase we run the risk of dropping into the
1527c478bd9Sstevel@tonic-gate  *	IDN_WINDOW_MAX region even though the receiving domain
1537c478bd9Sstevel@tonic-gate  *	may be fine with handling the load.  In order to compensate
1547c478bd9Sstevel@tonic-gate  *	for this increased activity and to not incur unjustified
1557c478bd9Sstevel@tonic-gate  *	slips into the IDN_WINDOW_MAX region, the IDN_WINDOW_MAX
1567c478bd9Sstevel@tonic-gate  *	value is adjusted by IDN_WINDOW_INCR for each channel/net
1577c478bd9Sstevel@tonic-gate  *	that is activated for a given domain.
1587c478bd9Sstevel@tonic-gate  *
1597c478bd9Sstevel@tonic-gate  * IDN_WINDOW_EMAX	(not tunable)
1607c478bd9Sstevel@tonic-gate  *
1617c478bd9Sstevel@tonic-gate  *	The effective value of IDN_WINDOW_MAX once it has
1627c478bd9Sstevel@tonic-gate  *	been adjusted by IDN_WINDOW_INCR.
1637c478bd9Sstevel@tonic-gate  *
1647c478bd9Sstevel@tonic-gate  * IDN_RECLAIM_MIN	(driver.conf)
1657c478bd9Sstevel@tonic-gate  *
1667c478bd9Sstevel@tonic-gate  *	Minimum number of outstanding packets that our allowed
1677c478bd9Sstevel@tonic-gate  *	before subsequent sends will attempt to reclaim some number
1687c478bd9Sstevel@tonic-gate  *	of outstanding data packets.
1697c478bd9Sstevel@tonic-gate  *
1707c478bd9Sstevel@tonic-gate  * IDN_RECLAIM_MAX	(driver.conf)
1717c478bd9Sstevel@tonic-gate  *	This value represents the maximum number of outstanding
1727c478bd9Sstevel@tonic-gate  *	packets we will try to reclaim during a send once we've
1737c478bd9Sstevel@tonic-gate  *	passed the IDN_RECLAIM_MIN boundary.
1747c478bd9Sstevel@tonic-gate  *
1757c478bd9Sstevel@tonic-gate  * IDN_MODUNLOADABLE	(ndd)
1767c478bd9Sstevel@tonic-gate  *
1777c478bd9Sstevel@tonic-gate  *	By default the IDN driver is unloadable.  Setting this
1787c478bd9Sstevel@tonic-gate  *	variable will allow the IDN driver to be unloaded provided
1797c478bd9Sstevel@tonic-gate  *	it's not in use.
1807c478bd9Sstevel@tonic-gate  *
1817c478bd9Sstevel@tonic-gate  * IDN_LOWAT/IDN_HIWAT	(driver.conf)
1827c478bd9Sstevel@tonic-gate  *
1837c478bd9Sstevel@tonic-gate  *	Low/High water marks for the STREAM interface to IDN.
1847c478bd9Sstevel@tonic-gate  *
1857c478bd9Sstevel@tonic-gate  * IDN_MBOX_PER_NET	(driver.conf)
1867c478bd9Sstevel@tonic-gate  *
1877c478bd9Sstevel@tonic-gate  *	Number of mailbox entries that are allocated per channel/net.
1887c478bd9Sstevel@tonic-gate  *	This value effectively represents the amount of outstanding
1897c478bd9Sstevel@tonic-gate  *	activity that can reside at a domain.  Increasing this value
1907c478bd9Sstevel@tonic-gate  *	allows more packets to be in transit to a domain, however
1917c478bd9Sstevel@tonic-gate  *	at some point there are diminishing returns since the receiver
1927c478bd9Sstevel@tonic-gate  *	can only consume packets so fast.
1937c478bd9Sstevel@tonic-gate  *
1947c478bd9Sstevel@tonic-gate  * IDN_MAX_NETS		(driver.conf)
1957c478bd9Sstevel@tonic-gate  *
1967c478bd9Sstevel@tonic-gate  *	Maximum number of network interfaces (channels) that IDN
1977c478bd9Sstevel@tonic-gate  *	is currently configured to allow.  The absolute max is
1987c478bd9Sstevel@tonic-gate  *	IDN_MAXMAX_NETS.  We don't automatically default IDN_MAX_NETS
1997c478bd9Sstevel@tonic-gate  *	to IDN_MAXMAX_NETS because it would mean wasted space in
2007c478bd9Sstevel@tonic-gate  *	the mailbox region having to reserve mailboxes that will
2017c478bd9Sstevel@tonic-gate  *	very likely go unused.  The smaller this value the fewer
2027c478bd9Sstevel@tonic-gate  *	the number of mailboxes in the SMR and thus the greater the
2037c478bd9Sstevel@tonic-gate  *	number of possible I/O buffers available.
2047c478bd9Sstevel@tonic-gate  *	Req: IDN_MAX_NETS <= IDN_MAXMAX_NETS
2057c478bd9Sstevel@tonic-gate  *
2067c478bd9Sstevel@tonic-gate  * IDN_CHECKSUM		(driver.conf)
2077c478bd9Sstevel@tonic-gate  *
2087c478bd9Sstevel@tonic-gate  *	If enabled, IDN validates the smr_pkthdr_t of incoming packets
2097c478bd9Sstevel@tonic-gate  *	via a checksum, and calculates the checksum for outgoing packets.
2107c478bd9Sstevel@tonic-gate  *	Only the first 3 fields of smr_pkthdr_t are checksummed and
2117c478bd9Sstevel@tonic-gate  *	must be set to their expected values prior to calculating the
2127c478bd9Sstevel@tonic-gate  *	checksum.  Turned OFF by default when compiled DEBUG.
2137c478bd9Sstevel@tonic-gate  *
2147c478bd9Sstevel@tonic-gate  * IDN_SMR_MAXSIZE	(not tunable)
2157c478bd9Sstevel@tonic-gate  *
2167c478bd9Sstevel@tonic-gate  *	The absolute maximum size of the SMR region that we'll allow.
2177c478bd9Sstevel@tonic-gate  *	Note that the virtual address space comes out kernelmap.
2187c478bd9Sstevel@tonic-gate  */
2197c478bd9Sstevel@tonic-gate #define	IDN_AWOLMSG_INTERVAL	60		/* seconds */
2207c478bd9Sstevel@tonic-gate #define	IDN_MSGWAIT_NEGO	20		/* seconds */
2217c478bd9Sstevel@tonic-gate #define	IDN_MSGWAIT_CFG		40
2227c478bd9Sstevel@tonic-gate #define	IDN_MSGWAIT_CON		20
2237c478bd9Sstevel@tonic-gate #define	IDN_MSGWAIT_FIN		40
2247c478bd9Sstevel@tonic-gate #define	IDN_MSGWAIT_CMD		40
2257c478bd9Sstevel@tonic-gate #define	IDN_MSGWAIT_DATA	30
2267c478bd9Sstevel@tonic-gate #define	IDN_RETRYFREQ_NEGO	2
2277c478bd9Sstevel@tonic-gate #define	IDN_RETRYFREQ_CON	2
2287c478bd9Sstevel@tonic-gate #define	IDN_RETRYFREQ_FIN	3
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate #define	IDN_SMR_BUFSIZE_MIN	512
2317c478bd9Sstevel@tonic-gate #define	IDN_SMR_BUFSIZE_MAX	(512*1024)
2327c478bd9Sstevel@tonic-gate #define	IDN_SMR_BUFSIZE_DEF	(16*1024)
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate #define	IDN_SMR_SHIFT		(16)
2357c478bd9Sstevel@tonic-gate #define	IDN_SMR_ALIGN		(1 << IDN_SMR_SHIFT)	/* 64K */
2367c478bd9Sstevel@tonic-gate #define	IDN_SMR_SIZE		idn_smr_size
2377c478bd9Sstevel@tonic-gate #define	IDN_NWR_SIZE		idn_nwr_size
2387c478bd9Sstevel@tonic-gate #define	IDN_SMR_BUFSIZE		idn_smr_bufsize
2397c478bd9Sstevel@tonic-gate #define	IDN_DATA_SIZE		(IDN_SMR_BUFSIZE \
2407c478bd9Sstevel@tonic-gate 				    - sizeof (smr_pkthdr_t) \
2417c478bd9Sstevel@tonic-gate 				    - IDN_ALIGNSIZE)
2427c478bd9Sstevel@tonic-gate #define	IDN_MTU			(IDN_DATA_SIZE - sizeof (struct ether_header))
2437c478bd9Sstevel@tonic-gate #define	IDN_WINDOW_MAX		idn_window_max
2447c478bd9Sstevel@tonic-gate #define	IDN_WINDOW_INCR		idn_window_incr
2457c478bd9Sstevel@tonic-gate #define	IDN_WINDOW_EMAX		idn_window_emax
2467c478bd9Sstevel@tonic-gate #define	IDN_RECLAIM_MIN		idn_reclaim_min
2477c478bd9Sstevel@tonic-gate #define	IDN_RECLAIM_MAX		idn_reclaim_max
2487c478bd9Sstevel@tonic-gate #define	IDN_MODUNLOADABLE	idn_modunloadable
2497c478bd9Sstevel@tonic-gate #define	IDN_LOWAT		idn_lowat
2507c478bd9Sstevel@tonic-gate #define	IDN_HIWAT		idn_hiwat
2517c478bd9Sstevel@tonic-gate #define	IDN_MBOX_PER_NET	idn_mbox_per_net
2527c478bd9Sstevel@tonic-gate #define	IDN_MAX_NETS		idn_max_nets
2537c478bd9Sstevel@tonic-gate #define	IDN_CHECKSUM		idn_checksum
2547c478bd9Sstevel@tonic-gate #define	IDN_SMR_MAXSIZE		96
2557c478bd9Sstevel@tonic-gate #define	_IDN_SMR_SIZE		32			/* 32M */
2567c478bd9Sstevel@tonic-gate #define	_IDN_NWR_SIZE		_IDN_SMR_SIZE		/* 32M */
2577c478bd9Sstevel@tonic-gate #define	_IDN_SMR_BUFSIZE	(16 * 1024)		/* 16K */
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate #define	IDN_TUNEVAR_NAME(v)	(*(char **)((ulong_t)&(v)+(sizeof (ulong_t))))
2617c478bd9Sstevel@tonic-gate #define	IDN_TUNEVAR_VALUE(v)	(v)
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate /*
2647c478bd9Sstevel@tonic-gate  * History structure to support problem analysis.
2657c478bd9Sstevel@tonic-gate  */
2667c478bd9Sstevel@tonic-gate #define	IDN_HISTORY_NUM		1024
2677c478bd9Sstevel@tonic-gate #define	IDN_HISTORY_LOG(op, d0, d1, d2) \
2687c478bd9Sstevel@tonic-gate 	if (idn_history) { \
2697c478bd9Sstevel@tonic-gate 		mutex_enter(&idnhlog.h_mutex); \
2707c478bd9Sstevel@tonic-gate 		idnhlog.h_log[idnhlog.h_index].e_time = TIMESTAMP(); \
2717c478bd9Sstevel@tonic-gate 		idnhlog.h_log[idnhlog.h_index].e_op = (ushort_t)(op); \
2727c478bd9Sstevel@tonic-gate 		idnhlog.h_log[idnhlog.h_index].e_data[0] = (ushort_t)(d0); \
2737c478bd9Sstevel@tonic-gate 		idnhlog.h_log[idnhlog.h_index].e_data[1] = (ushort_t)(d1); \
2747c478bd9Sstevel@tonic-gate 		idnhlog.h_log[idnhlog.h_index].e_data[2] = (ushort_t)(d2); \
2757c478bd9Sstevel@tonic-gate 		idnhlog.h_index++; \
2767c478bd9Sstevel@tonic-gate 		idnhlog.h_index &= (IDN_HISTORY_NUM - 1); \
2777c478bd9Sstevel@tonic-gate 		mutex_exit(&idnhlog.h_mutex); \
2787c478bd9Sstevel@tonic-gate 	}
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate #define	IDNH_GSTATE	0x0001	/* d0=gstate, d1=, d2= */
2817c478bd9Sstevel@tonic-gate #define	IDNH_DSTATE	0x0002	/* d0=domid, d1=dstate, d2=cpuid */
2827c478bd9Sstevel@tonic-gate #define	IDNH_AWOL	0x0003	/* d0=domid, d1=dstate, d2=cpuid */
2837c478bd9Sstevel@tonic-gate #define	IDNH_MASTERID	0x0004	/* d0=masterid, d1=oldid, d2= */
2847c478bd9Sstevel@tonic-gate #define	IDNH_NEGO	0x0005	/* d0=domid, d1=ds_trans_on, d2=ds_connected */
2857c478bd9Sstevel@tonic-gate #define	IDNH_FIN	0x0006	/* d0=domid, d1=finstate, d2= */
2867c478bd9Sstevel@tonic-gate #define	IDNH_RELINK	0x0007	/* d0=domid, d1=dstate, d2=ds_relink */
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate struct idn_h_entry {
2897c478bd9Sstevel@tonic-gate 	hrtime_t	e_time;
2907c478bd9Sstevel@tonic-gate 	ushort_t	e_op;
2917c478bd9Sstevel@tonic-gate 	ushort_t	e_data[3];
2927c478bd9Sstevel@tonic-gate };
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate struct idn_history {
2957c478bd9Sstevel@tonic-gate 	kmutex_t		h_mutex;
2967c478bd9Sstevel@tonic-gate 	int			h_index;
2977c478bd9Sstevel@tonic-gate 	struct idn_h_entry	h_log[IDN_HISTORY_NUM];
2987c478bd9Sstevel@tonic-gate };
2997c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate /*
3027c478bd9Sstevel@tonic-gate  * IDN_SIGBPIL - Interrupt level at which IDN driver
3037c478bd9Sstevel@tonic-gate  *		 wakes up idn_sigbhandler_thread
3047c478bd9Sstevel@tonic-gate  */
3057c478bd9Sstevel@tonic-gate #define	IDN_SIGBPIL	PIL_3
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate /*
3087c478bd9Sstevel@tonic-gate  * Definition of sigbintr.sb_busy values which
3097c478bd9Sstevel@tonic-gate  * represents state of idn_sigbhandler.
3107c478bd9Sstevel@tonic-gate  */
3117c478bd9Sstevel@tonic-gate #define	IDNSIGB_NOTREADY	((uchar_t)0)
3127c478bd9Sstevel@tonic-gate #define	IDNSIGB_INACTIVE	((uchar_t)1)
3137c478bd9Sstevel@tonic-gate #define	IDNSIGB_STARTED		((uchar_t)2)
3147c478bd9Sstevel@tonic-gate #define	IDNSIGB_ACTIVE		((uchar_t)3)
3157c478bd9Sstevel@tonic-gate #define	IDNSIGB_DIE		((uchar_t)4)
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate /*
3187c478bd9Sstevel@tonic-gate  * Some Xfire based macros that assume 4 cpus per board.
3197c478bd9Sstevel@tonic-gate  */
3207c478bd9Sstevel@tonic-gate #define	CPUID_TO_BOARDID(c)	((c) >> 2)
3217c478bd9Sstevel@tonic-gate #define	MAX_CPU_PER_BRD		4
3227c478bd9Sstevel@tonic-gate #define	CPUSET_TO_BOARDSET(cset, bset) \
3237c478bd9Sstevel@tonic-gate 	{ \
3247c478bd9Sstevel@tonic-gate 		register int	c, b; \
3257c478bd9Sstevel@tonic-gate 		(bset) = 0; \
3267c478bd9Sstevel@tonic-gate 		for (b = 0; b < MAX_BOARDS; b++) \
3277c478bd9Sstevel@tonic-gate 			for (c = 0; c < MAX_CPU_PER_BRD; c++) \
3287c478bd9Sstevel@tonic-gate 				if (CPU_IN_SET((cset), \
3297c478bd9Sstevel@tonic-gate 						(b * MAX_CPU_PER_BRD) + c)) \
3307c478bd9Sstevel@tonic-gate 					(bset) |= 1 << b; \
3317c478bd9Sstevel@tonic-gate 	}
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate /*
3347c478bd9Sstevel@tonic-gate  * Macros to manipulate boardset and domainset masks.
3357c478bd9Sstevel@tonic-gate  */
3367c478bd9Sstevel@tonic-gate typedef ushort_t boardset_t;	/* assumes max of 16 boards */
3377c478bd9Sstevel@tonic-gate typedef ushort_t domainset_t;	/* assumes max of 16 domains */
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate #define	BOARDSET(brd)		((boardset_t)(1 << (brd)))
3407c478bd9Sstevel@tonic-gate #define	BOARDSET_ALL		((boardset_t)~0)
3417c478bd9Sstevel@tonic-gate #define	BOARD_IN_SET(set, brd)	((set) & BOARDSET(brd))
3427c478bd9Sstevel@tonic-gate #define	BOARDSET_ADD(set, brd)	((set) |= BOARDSET(brd))
3437c478bd9Sstevel@tonic-gate #define	BOARDSET_DEL(set, brd)	((set) &= ~BOARDSET(brd))
3447c478bd9Sstevel@tonic-gate #define	DOMAINSET(d)		((domainset_t)1 << (d))
3457c478bd9Sstevel@tonic-gate #define	DOMAINSET_ALL		((domainset_t)~0)
3467c478bd9Sstevel@tonic-gate #define	DOMAIN_IN_SET(s, d)	((s) & DOMAINSET(d))
3477c478bd9Sstevel@tonic-gate #define	DOMAINSET_ADD(s, d)	((s) |= DOMAINSET(d))
3487c478bd9Sstevel@tonic-gate #define	DOMAINSET_DEL(s, d)	((s) &= ~DOMAINSET(d))
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate /*
3517c478bd9Sstevel@tonic-gate  * PFN_TO_SMADDR macro converts a PFN to a IDN_SMR_ALIGN'ed
3527c478bd9Sstevel@tonic-gate  * address suitable for the CIC bar/lar registers.
3537c478bd9Sstevel@tonic-gate  */
3547c478bd9Sstevel@tonic-gate #if (IDN_SMR_SHIFT <= MMU_PAGESHIFT)
3557c478bd9Sstevel@tonic-gate #define	PFN_TO_SMADDR(pfn)	((pfn) << (MMU_PAGESHIFT - IDN_SMR_SHIFT))
3567c478bd9Sstevel@tonic-gate #else
3577c478bd9Sstevel@tonic-gate #define	PFN_TO_SMADDR(pfn)	((pfn) >> (IDN_SMR_SHIFT - MMU_PAGESHIFT))
3587c478bd9Sstevel@tonic-gate #endif
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate /*
3617c478bd9Sstevel@tonic-gate  * Translate a physical address to a unique domain identifier.
3627c478bd9Sstevel@tonic-gate  * IMPORTANT - Assumes each board's memory is configured on a 8GB
3637c478bd9Sstevel@tonic-gate  *	       boundary. PA(8G) = PFN(1M).
3647c478bd9Sstevel@tonic-gate  */
3657c478bd9Sstevel@tonic-gate #define	MEM8G_SHIFT			33	/* (1 << 33) == 8G */
3667c478bd9Sstevel@tonic-gate #define	PADDR_TO_DOMAINID(paddr)	((int)((paddr) >> MEM8G_SHIFT) & 0xf)
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate #define	VALID_NWROFFSET(off, align)	\
3697c478bd9Sstevel@tonic-gate 				(((uint_t)(off) >= 0) && \
3707c478bd9Sstevel@tonic-gate 				((size_t)(off) < MB2B(IDN_NWR_SIZE)) && \
3717c478bd9Sstevel@tonic-gate 				!((uint_t)(off) & ((align) - 1)))
3727c478bd9Sstevel@tonic-gate #define	VALID_NWRADDR(addr, align) \
3737c478bd9Sstevel@tonic-gate 		(((caddr_t)(addr) >= idn.smr.vaddr) && \
3747c478bd9Sstevel@tonic-gate 		VALID_NWROFFSET(((caddr_t)(addr) - idn.smr.vaddr), (align)))
3757c478bd9Sstevel@tonic-gate #define	VALID_DOMAINID(d)	(((d) >= 0) && ((d) < MAX_DOMAINS))
376bf30efa4Smathue #define	VALID_UDOMAINID(d)	((d) < MAX_DOMAINS)
3777c478bd9Sstevel@tonic-gate #define	VALID_CPUID(c)		(((c) >= 0) && ((c) < NCPU))
378bf30efa4Smathue #define	VALID_CHANNEL(c)	(((c) >= 0) && ((c) < IDN_MAX_NETS))
379bf30efa4Smathue #define	VALID_UCHANNEL(c)	((c) < IDN_MAX_NETS)
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate /*
3827c478bd9Sstevel@tonic-gate  * The following are bit values of idn_debug, currently
3837c478bd9Sstevel@tonic-gate  * only useful if compiled with DEBUG.
3847c478bd9Sstevel@tonic-gate  */
3857c478bd9Sstevel@tonic-gate #ifdef DEBUG
3867c478bd9Sstevel@tonic-gate #define	STRING(sss)		char sss[20]
3877c478bd9Sstevel@tonic-gate #define	INUM2STR(mm, ss)	inum2str((mm), (ss))
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate #define	IDNDBG_XDC	0x00000001
3907c478bd9Sstevel@tonic-gate #define	IDNDBG_XF	0x00000002
3917c478bd9Sstevel@tonic-gate #define	IDNDBG_REGS	0x00000004
3927c478bd9Sstevel@tonic-gate #define	IDNDBG_SMR	0x00000008
3937c478bd9Sstevel@tonic-gate #define	IDNDBG_PROTO	0x00000010
3947c478bd9Sstevel@tonic-gate #define	IDNDBG_STR	0x00000020
3957c478bd9Sstevel@tonic-gate #define	IDNDBG_DRV	0x00000040
3967c478bd9Sstevel@tonic-gate #define	IDNDBG_DATA	0x00000080
3977c478bd9Sstevel@tonic-gate #define	IDNDBG_STATE	0x00000100
3987c478bd9Sstevel@tonic-gate #define	IDNDBG_DLPI	0x00000200
3997c478bd9Sstevel@tonic-gate #define	IDNDBG_KERN	0x00000400
4007c478bd9Sstevel@tonic-gate #define	IDNDBG_ALLOC	0x00000800
4017c478bd9Sstevel@tonic-gate #define	IDNDBG_REMAP	0x00001000
4027c478bd9Sstevel@tonic-gate #define	IDNDBG_TIMER	0x00002000
4037c478bd9Sstevel@tonic-gate #define	IDNDBG_CHAN	0x00004000
4047c478bd9Sstevel@tonic-gate #define	IDNDBG_AWOL	0x00008000
4057c478bd9Sstevel@tonic-gate #define	IDNDBG_SYNC	0x00010000
4067c478bd9Sstevel@tonic-gate #define	_IDNDBG_UNUSED0	0x00020000
4077c478bd9Sstevel@tonic-gate #define	IDNDBG_HITLIST	0x00040000
4087c478bd9Sstevel@tonic-gate #define	IDNDBG_XMON	0x00080000
4097c478bd9Sstevel@tonic-gate #define	IDNDBG_TEST	0x80000000
4107c478bd9Sstevel@tonic-gate #define	IDNDBG_ALL	((uint_t)-1)
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate #define	PR_ALL		if (idn_debug)	printf
4137c478bd9Sstevel@tonic-gate #define	PR_XDC		if (idn_debug & IDNDBG_XDC)	printf
4147c478bd9Sstevel@tonic-gate #define	PR_XF		if (idn_debug & IDNDBG_XF)	printf
4157c478bd9Sstevel@tonic-gate #define	PR_REGS		if (idn_debug & IDNDBG_REGS)	printf
4167c478bd9Sstevel@tonic-gate #define	PR_SMR		if (idn_debug & IDNDBG_SMR)	printf
4177c478bd9Sstevel@tonic-gate #define	PR_PROTO	if (idn_debug & IDNDBG_PROTO)	printf
4187c478bd9Sstevel@tonic-gate #define	PR_STR		if (idn_debug & IDNDBG_STR)	printf
4197c478bd9Sstevel@tonic-gate #define	PR_DRV		if (idn_debug & IDNDBG_DRV)	printf
4207c478bd9Sstevel@tonic-gate #define	PR_DATA		if (idn_debug & IDNDBG_DATA)	printf
4217c478bd9Sstevel@tonic-gate #define	PR_STATE	if (idn_debug & IDNDBG_STATE)	printf
4227c478bd9Sstevel@tonic-gate #define	PR_DLPI		if (idn_debug & IDNDBG_DLPI)	printf
4237c478bd9Sstevel@tonic-gate #define	PR_KERN		if (idn_debug & IDNDBG_KERN)	printf
4247c478bd9Sstevel@tonic-gate #define	PR_ALLOC	if (idn_debug & IDNDBG_ALLOC)	printf
4257c478bd9Sstevel@tonic-gate #define	PR_REMAP	if (idn_debug & (IDNDBG_SMR|IDNDBG_REMAP))	printf
4267c478bd9Sstevel@tonic-gate #define	PR_TIMER	if (idn_debug & IDNDBG_TIMER)	printf
4277c478bd9Sstevel@tonic-gate #define	PR_CHAN		if (idn_debug & IDNDBG_CHAN)	printf
4287c478bd9Sstevel@tonic-gate #define	PR_AWOL		if (idn_debug & (IDNDBG_PROTO|IDNDBG_AWOL))	printf
4297c478bd9Sstevel@tonic-gate #define	PR_SYNC		if (idn_debug & IDNDBG_SYNC)	printf
4307c478bd9Sstevel@tonic-gate #define	_PR_UNUSED0	if (idn_debug & _IDNDBG_UNUSED0)	printf
4317c478bd9Sstevel@tonic-gate #define	PR_HITLIST	if (idn_debug & IDNDBG_HITLIST)	printf
4327c478bd9Sstevel@tonic-gate #define	PR_XMON		if (idn_debug & IDNDBG_XMON)	printf
4337c478bd9Sstevel@tonic-gate #define	PR_TEST		if (idn_debug & IDNDBG_TEST)	printf
4347c478bd9Sstevel@tonic-gate #else
4357c478bd9Sstevel@tonic-gate #define	STRING(sss)	char *sss = ""
4367c478bd9Sstevel@tonic-gate #define	INUM2STR(mm, ss)
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate #define	PR_ALL		if (0) printf
4397c478bd9Sstevel@tonic-gate #define	PR_XDC		PR_ALL
4407c478bd9Sstevel@tonic-gate #define	PR_XF		PR_ALL
4417c478bd9Sstevel@tonic-gate #define	PR_REGS		PR_ALL
4427c478bd9Sstevel@tonic-gate #define	PR_SMR		PR_ALL
4437c478bd9Sstevel@tonic-gate #define	PR_PROTO	PR_ALL
4447c478bd9Sstevel@tonic-gate #define	PR_STR		PR_ALL
4457c478bd9Sstevel@tonic-gate #define	PR_DRV		PR_ALL
4467c478bd9Sstevel@tonic-gate #define	PR_DATA		PR_ALL
4477c478bd9Sstevel@tonic-gate #define	PR_STATE	PR_ALL
4487c478bd9Sstevel@tonic-gate #define	PR_DLPI		PR_ALL
4497c478bd9Sstevel@tonic-gate #define	PR_KERN		PR_ALL
4507c478bd9Sstevel@tonic-gate #define	PR_ALLOC	PR_ALL
4517c478bd9Sstevel@tonic-gate #define	PR_REMAP	PR_ALL
4527c478bd9Sstevel@tonic-gate #define	PR_TIMER	PR_ALL
4537c478bd9Sstevel@tonic-gate #define	PR_CHAN		PR_ALL
4547c478bd9Sstevel@tonic-gate #define	PR_AWOL		PR_ALL
4557c478bd9Sstevel@tonic-gate #define	PR_SYNC		PR_ALL
4567c478bd9Sstevel@tonic-gate #define	PR_SNOOP	PR_ALL
4577c478bd9Sstevel@tonic-gate #define	PR_HITLIST	PR_ALL
4587c478bd9Sstevel@tonic-gate #define	PR_XMON		PR_ALL
4597c478bd9Sstevel@tonic-gate #define	PR_TEST		PR_ALL
4607c478bd9Sstevel@tonic-gate #endif /* DEBUG */
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate #ifdef _KERNEL
4637c478bd9Sstevel@tonic-gate /*
4647c478bd9Sstevel@tonic-gate  * IDN drivers fields.
4657c478bd9Sstevel@tonic-gate  *
4667c478bd9Sstevel@tonic-gate  * IDNMINPSZ	Minimum packet size the IDN supports.
4677c478bd9Sstevel@tonic-gate  *
4687c478bd9Sstevel@tonic-gate  * IDNMAXPSZ 	Maximum packet size that IDN supports from upper
4697c478bd9Sstevel@tonic-gate  *		layers.  Is equal to IDN_MTU + ether_header.  Note
4707c478bd9Sstevel@tonic-gate  *		that the IDN driver could support larger packets
4717c478bd9Sstevel@tonic-gate  *		however the infrastructure to support fragmentation
4727c478bd9Sstevel@tonic-gate  *		does not (and should not) exist with respect to
4737c478bd9Sstevel@tonic-gate  *		ethernet packet types.
4747c478bd9Sstevel@tonic-gate  */
4757c478bd9Sstevel@tonic-gate #ifdef DEBUG
4767c478bd9Sstevel@tonic-gate #define	IDNDESC		"Inter-Domain Network (DEBUG)"
4777c478bd9Sstevel@tonic-gate #else
4787c478bd9Sstevel@tonic-gate #define	IDNDESC		"Inter-Domain Network"
4797c478bd9Sstevel@tonic-gate #endif /* DEBUG */
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate #define	IDNIDNUM		8264
4827c478bd9Sstevel@tonic-gate #define	IDNNAME			"idn"
4837c478bd9Sstevel@tonic-gate #define	IDNMINPSZ		0	/* set at idnopen() */
4847c478bd9Sstevel@tonic-gate #define	IDNMAXPSZ		0	/* set at idnopen() */
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate /*
4897c478bd9Sstevel@tonic-gate  * IDN Global States.
4907c478bd9Sstevel@tonic-gate  */
4917c478bd9Sstevel@tonic-gate typedef enum {
4927c478bd9Sstevel@tonic-gate /*  0 */	IDNGS_OFFLINE = 0,	/* idle */
4937c478bd9Sstevel@tonic-gate /*  1 */	IDNGS_CONNECT,		/* connecting initial domain */
4947c478bd9Sstevel@tonic-gate /*  2 */	IDNGS_ONLINE,		/* master selected */
4957c478bd9Sstevel@tonic-gate /*  3 */	IDNGS_DISCONNECT,	/* local is unlinking */
4967c478bd9Sstevel@tonic-gate /*  4 */	IDNGS_RECONFIG,		/* selecting new master */
4977c478bd9Sstevel@tonic-gate /*  5 */	_IDNGS_UNUNSED5,
4987c478bd9Sstevel@tonic-gate /*  6 */	_IDNGS_UNUNSED6,
4997c478bd9Sstevel@tonic-gate /*  7 */	_IDNGS_UNUNSED7,
5007c478bd9Sstevel@tonic-gate /*  8 */	_IDNGS_UNUNSED8,
5017c478bd9Sstevel@tonic-gate /*  9 */	_IDNGS_UNUNSED9,
5027c478bd9Sstevel@tonic-gate /* 10 */	IDNGS_IGNORE		/* ignore requests (fault injection) */
5037c478bd9Sstevel@tonic-gate } idn_gstate_t;
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate #ifdef _KERNEL
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate #define	TIMESTAMP()	(gethrtime() / 1000000ull)
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate /*
5107c478bd9Sstevel@tonic-gate  * Spaced defined in:
5117c478bd9Sstevel@tonic-gate  *	sigblkp[cpu0.cpu_id]->sigb_idn.reserved1.
5127c478bd9Sstevel@tonic-gate  */
5137c478bd9Sstevel@tonic-gate #define	IDNSB_GSTATE_NEW	0
5147c478bd9Sstevel@tonic-gate #define	IDNSB_GSTATE_OLD	1
5157c478bd9Sstevel@tonic-gate #define	IDNSB_MASTERCPU		2
5167c478bd9Sstevel@tonic-gate #define	IDNSB_RESERVED		3
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate #define	IDNSB_HWCHKPT_MAX	4
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate #define	IDNSB_SIZE		72
5217c478bd9Sstevel@tonic-gate /*
5227c478bd9Sstevel@tonic-gate  * This structure gets overlay onto:
5237c478bd9Sstevel@tonic-gate  *	sigblkp[cpu0.cpu_id]->sigb_idn.reserved1.
5247c478bd9Sstevel@tonic-gate  *
5257c478bd9Sstevel@tonic-gate  * This structure must be exactly IDNSB_SIZE bytes.
5267c478bd9Sstevel@tonic-gate  */
5277c478bd9Sstevel@tonic-gate typedef struct idnsb {
5287c478bd9Sstevel@tonic-gate 	uchar_t		id_gstate;
5297c478bd9Sstevel@tonic-gate 	uchar_t		id_pgstate;
5307c478bd9Sstevel@tonic-gate 	uchar_t		id_master_board;
5317c478bd9Sstevel@tonic-gate 	uchar_t		id_pmaster_board;
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate 	uchar_t		reserved_DO_NOT_USE[24];	/* idnevent_t field */
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 	struct {
5367c478bd9Sstevel@tonic-gate 		uchar_t	d_board;
5377c478bd9Sstevel@tonic-gate 		uchar_t	d_state;
5387c478bd9Sstevel@tonic-gate 	} id_status[MAX_DOMAINS];
5397c478bd9Sstevel@tonic-gate 	uint_t		id_hwstate;
5407c478bd9Sstevel@tonic-gate 	ushort_t	id_hwchkpt[IDNSB_HWCHKPT_MAX];
5417c478bd9Sstevel@tonic-gate } idnsb_t;	/* sizeof = 72 (0x48) 18X bytes */
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate #define	IDNSB_DOMAIN_UPDATE(dp) \
5457c478bd9Sstevel@tonic-gate 	{ \
5467c478bd9Sstevel@tonic-gate 		mutex_enter(&idn.idnsb_mutex); \
5477c478bd9Sstevel@tonic-gate 		if (idn.idnsb) { \
5487c478bd9Sstevel@tonic-gate 			int	domid = (dp)->domid; \
5497c478bd9Sstevel@tonic-gate 			if ((dp)->dcpu == IDN_NIL_DCPU) \
5507c478bd9Sstevel@tonic-gate 				idn.idnsb->id_status[domid].d_board = \
5517c478bd9Sstevel@tonic-gate 						(uchar_t)0xff; \
5527c478bd9Sstevel@tonic-gate 			else if ((dp)->dvote.v.board == 0) \
5537c478bd9Sstevel@tonic-gate 				idn.idnsb->id_status[domid].d_board = \
5547c478bd9Sstevel@tonic-gate 					(uchar_t)CPUID_TO_BOARDID((dp)->dcpu); \
5557c478bd9Sstevel@tonic-gate 			else \
5567c478bd9Sstevel@tonic-gate 				idn.idnsb->id_status[domid].d_board = \
5577c478bd9Sstevel@tonic-gate 						(uchar_t)(dp)->dvote.v.board; \
5587c478bd9Sstevel@tonic-gate 			idn.idnsb->id_status[domid].d_state = \
5597c478bd9Sstevel@tonic-gate 				(uchar_t)(dp)->dstate; \
5607c478bd9Sstevel@tonic-gate 		} \
5617c478bd9Sstevel@tonic-gate 		mutex_exit(&idn.idnsb_mutex); \
5627c478bd9Sstevel@tonic-gate 	}
5637c478bd9Sstevel@tonic-gate /*
5647c478bd9Sstevel@tonic-gate  * The following definitions and macros pertain to the
5657c478bd9Sstevel@tonic-gate  * id_hwstate and id_hwchkpt[] fields.
5667c478bd9Sstevel@tonic-gate  *
5677c478bd9Sstevel@tonic-gate  * id_hwstate (m = mark: 1=open, 2=close)
5687c478bd9Sstevel@tonic-gate  *	  0   1   2   3   4   5   6   7
5697c478bd9Sstevel@tonic-gate  *	---------------------------------
5707c478bd9Sstevel@tonic-gate  *	| m | m | m | m | XX unused XXX |
5717c478bd9Sstevel@tonic-gate  *	---------------------------------
5727c478bd9Sstevel@tonic-gate  *	  |   |   |   |
5737c478bd9Sstevel@tonic-gate  *	  |   |   |   +- CACHE
5747c478bd9Sstevel@tonic-gate  *	  |   |   +- CHAN
5757c478bd9Sstevel@tonic-gate  *	  |   +- LINK
5767c478bd9Sstevel@tonic-gate  *	  +- SMR
5777c478bd9Sstevel@tonic-gate  *
5787c478bd9Sstevel@tonic-gate  * Note that nibble 4 is used in DEBUG for noting cache
5797c478bd9Sstevel@tonic-gate  * flush progress through idnxf_flushall_ecache().  This
5807c478bd9Sstevel@tonic-gate  * will override id_hwchkpt[] since it only has room for
5817c478bd9Sstevel@tonic-gate  * 4 items, however the BBSRAM space is there and
5827c478bd9Sstevel@tonic-gate  * unofficially available :-o
5837c478bd9Sstevel@tonic-gate  *
5847c478bd9Sstevel@tonic-gate  * id_hwchkpt[0] = SMR boardset
5857c478bd9Sstevel@tonic-gate  * id_hwchkpt[1] = LINK boardset
5867c478bd9Sstevel@tonic-gate  * id_hwchkpt[2] = CHAN boardset
5877c478bd9Sstevel@tonic-gate  * id_hwchkpt[3] = CACHE boardset.
5887c478bd9Sstevel@tonic-gate  */
5897c478bd9Sstevel@tonic-gate #define	IDNSB_CHKPT_SMR		0
5907c478bd9Sstevel@tonic-gate #define	IDNSB_CHKPT_LINK	1
5917c478bd9Sstevel@tonic-gate #define	IDNSB_CHKPT_CHAN	2
5927c478bd9Sstevel@tonic-gate #define	IDNSB_CHKPT_CACHE	3
5937c478bd9Sstevel@tonic-gate #define	IDNSB_CHKPT_UNUSED	4	/* This is the max you can have */
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate #define	_CHKPT_MARKIT(item, mark) \
5967c478bd9Sstevel@tonic-gate 	{ \
5977c478bd9Sstevel@tonic-gate 		uint_t	mk = (((uint_t)((mark) & 0xf)) << \
5987c478bd9Sstevel@tonic-gate 			(((sizeof (uint_t) << 1) - 1 - (item)) << 2)); \
5997c478bd9Sstevel@tonic-gate 		uint_t	*sp = &idn.idnsb->id_hwstate; \
6007c478bd9Sstevel@tonic-gate 		ASSERT(idn.idnsb); \
6017c478bd9Sstevel@tonic-gate 		*sp &= ~(((uint_t)0xf) << (((sizeof (uint_t) << 1) \
6027c478bd9Sstevel@tonic-gate 			- 1 - (item)) << 2)); \
6037c478bd9Sstevel@tonic-gate 		*sp |= mk; \
6047c478bd9Sstevel@tonic-gate 	}
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate #define	CHECKPOINT_OPENED(item, bset, mark) \
6077c478bd9Sstevel@tonic-gate 	{ \
6087c478bd9Sstevel@tonic-gate 		mutex_enter(&idn.idnsb_mutex); \
6097c478bd9Sstevel@tonic-gate 		if (idn.idnsb) { \
6107c478bd9Sstevel@tonic-gate 			ushort_t *sp = &idn.idnsb->id_hwchkpt[0]; \
6117c478bd9Sstevel@tonic-gate 			_CHKPT_MARKIT((item), (mark));  \
6127c478bd9Sstevel@tonic-gate 			sp[item] |= ((ushort_t)(bset)); \
6137c478bd9Sstevel@tonic-gate 		} \
6147c478bd9Sstevel@tonic-gate 		mutex_exit(&idn.idnsb_mutex); \
6157c478bd9Sstevel@tonic-gate 	}
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate #define	CHECKPOINT_CLOSED(item, bset, mark) \
6187c478bd9Sstevel@tonic-gate 	{ \
6197c478bd9Sstevel@tonic-gate 		mutex_enter(&idn.idnsb_mutex); \
6207c478bd9Sstevel@tonic-gate 		if (idn.idnsb) { \
6217c478bd9Sstevel@tonic-gate 			ushort_t *sp = &idn.idnsb->id_hwchkpt[0]; \
6227c478bd9Sstevel@tonic-gate 			_CHKPT_MARKIT((item), (mark));  \
6237c478bd9Sstevel@tonic-gate 			sp[item] &= (ushort_t)~(bset); \
6247c478bd9Sstevel@tonic-gate 		} \
6257c478bd9Sstevel@tonic-gate 		mutex_exit(&idn.idnsb_mutex); \
6267c478bd9Sstevel@tonic-gate 	}
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate #define	CHECKPOINT_CLEAR(item, mark) \
6297c478bd9Sstevel@tonic-gate 	{ \
6307c478bd9Sstevel@tonic-gate 		mutex_enter(&idn.idnsb_mutex); \
6317c478bd9Sstevel@tonic-gate 		if (idn.idnsb) { \
6327c478bd9Sstevel@tonic-gate 			ushort_t *sp = &idn.idnsb->id_hwchkpt[0]; \
6337c478bd9Sstevel@tonic-gate 			_CHKPT_MARKIT((item), (mark));  \
6347c478bd9Sstevel@tonic-gate 			sp[item] = 0; \
6357c478bd9Sstevel@tonic-gate 		} \
6367c478bd9Sstevel@tonic-gate 		mutex_exit(&idn.idnsb_mutex); \
6377c478bd9Sstevel@tonic-gate 	}
6387c478bd9Sstevel@tonic-gate #ifdef DEBUG
6397c478bd9Sstevel@tonic-gate #define	CHECKPOINT_CACHE_CLEAR_DEBUG(mark) \
6407c478bd9Sstevel@tonic-gate 			CHECKPOINT_CLEAR(IDNSB_CHKPT_UNUSED, (mark))
6417c478bd9Sstevel@tonic-gate #define	CHECKPOINT_CACHE_STEP_DEBUG(bset, mark) \
6427c478bd9Sstevel@tonic-gate 			CHECKPOINT_OPENED(IDNSB_CHKPT_UNUSED, (bset), (mark))
6437c478bd9Sstevel@tonic-gate #else
6447c478bd9Sstevel@tonic-gate #define	CHECKPOINT_CACHE_CLEAR_DEBUG(mark)
6457c478bd9Sstevel@tonic-gate #define	CHECKPOINT_CACHE_STEP_DEBUG(bset, mark)
6467c478bd9Sstevel@tonic-gate #endif /* DEBUG */
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate #ifdef DEBUG
6507c478bd9Sstevel@tonic-gate #define	IDN_GSTATE_TRANSITION(ns) \
6517c478bd9Sstevel@tonic-gate 	{ \
6527c478bd9Sstevel@tonic-gate 		hrtime_t	tstamp; \
6537c478bd9Sstevel@tonic-gate 		/*LINTED*/ \
6547c478bd9Sstevel@tonic-gate 		IDN_HISTORY_LOG(IDNH_GSTATE, (ns), 0, 0); \
6557c478bd9Sstevel@tonic-gate 		tstamp = TIMESTAMP(); \
6567c478bd9Sstevel@tonic-gate 		ASSERT(IDN_GLOCK_IS_EXCL()); \
657bf30efa4Smathue 		PR_STATE("GSTATE:%ld: (l=%d) %s(%d) -> %s(%d)\n", \
6587c478bd9Sstevel@tonic-gate 			(uint64_t)tstamp, __LINE__, \
6597c478bd9Sstevel@tonic-gate 			idngs_str[idn.state], idn.state, \
6607c478bd9Sstevel@tonic-gate 			idngs_str[ns], (ns)); \
6617c478bd9Sstevel@tonic-gate 		mutex_enter(&idn.idnsb_mutex); \
6627c478bd9Sstevel@tonic-gate 		if (idn.idnsb) { \
6637c478bd9Sstevel@tonic-gate 			idn.idnsb->id_pgstate = (uchar_t)idn.state; \
6647c478bd9Sstevel@tonic-gate 			idn.idnsb->id_gstate = (uchar_t)(ns); \
6657c478bd9Sstevel@tonic-gate 		} \
6667c478bd9Sstevel@tonic-gate 		mutex_exit(&idn.idnsb_mutex); \
6677c478bd9Sstevel@tonic-gate 		idn.state = (ns); \
6687c478bd9Sstevel@tonic-gate 	}
6697c478bd9Sstevel@tonic-gate #else
6707c478bd9Sstevel@tonic-gate #define	IDN_GSTATE_TRANSITION(ns) \
6717c478bd9Sstevel@tonic-gate 	{ \
6727c478bd9Sstevel@tonic-gate 		IDN_HISTORY_LOG(IDNH_GSTATE, (ns), 0, 0); \
6737c478bd9Sstevel@tonic-gate 		mutex_enter(&idn.idnsb_mutex); \
6747c478bd9Sstevel@tonic-gate 		if (idn.idnsb) { \
6757c478bd9Sstevel@tonic-gate 			idn.idnsb->id_pgstate = (uchar_t)idn.state; \
6767c478bd9Sstevel@tonic-gate 			idn.idnsb->id_gstate = (uchar_t)(ns); \
6777c478bd9Sstevel@tonic-gate 		} \
6787c478bd9Sstevel@tonic-gate 		mutex_exit(&idn.idnsb_mutex); \
6797c478bd9Sstevel@tonic-gate 		idn.state = (ns); \
6807c478bd9Sstevel@tonic-gate 	}
6817c478bd9Sstevel@tonic-gate #endif /* DEBUG */
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate /*
6847c478bd9Sstevel@tonic-gate  * IDN link/unlink operations occur asynchronously with respect to the
6857c478bd9Sstevel@tonic-gate  * caller.  The following definitions are to support the return of
6867c478bd9Sstevel@tonic-gate  * success/failure back to the original requesting thread.  It's
6877c478bd9Sstevel@tonic-gate  * unlikely to have multiple outstanding link/unlink requests so we
6887c478bd9Sstevel@tonic-gate  * just provide a very small cache of waiting list entries.  If the
6897c478bd9Sstevel@tonic-gate  * cache becomes exhausted then additional ones are kmem_alloc'd.
6907c478bd9Sstevel@tonic-gate  */
6917c478bd9Sstevel@tonic-gate #define	IDNOP_CACHE_SIZE	3
6927c478bd9Sstevel@tonic-gate #define	IDNOP_IN_CACHE(dwl)	\
6937c478bd9Sstevel@tonic-gate 	(((dwl) >= &idn.dopers->_dop_wcache[0]) && \
6947c478bd9Sstevel@tonic-gate 	((dwl) < &idn.dopers->_dop_wcache[IDNOP_CACHE_SIZE]))
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate typedef struct dop_waitlist {
6977c478bd9Sstevel@tonic-gate 	struct dop_waitlist	*dw_next;
6987c478bd9Sstevel@tonic-gate 	domainset_t	dw_reqset;
6997c478bd9Sstevel@tonic-gate 	domainset_t	dw_domset;
7007c478bd9Sstevel@tonic-gate 	short		dw_op;
7017c478bd9Sstevel@tonic-gate 	domainset_t	dw_errset;
7027c478bd9Sstevel@tonic-gate 	idnsb_error_t	*dw_idnerr;
7037c478bd9Sstevel@tonic-gate 	short		dw_errors[MAX_DOMAINS];
7047c478bd9Sstevel@tonic-gate } dop_waitlist_t;
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate typedef uint_t	idn_xdcargs_t[4];
7077c478bd9Sstevel@tonic-gate typedef uint_t	idn_chanset_t;
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate /*
7107c478bd9Sstevel@tonic-gate  * Types of synchronization zones which a connection
7117c478bd9Sstevel@tonic-gate  * could be in.
7127c478bd9Sstevel@tonic-gate  */
7137c478bd9Sstevel@tonic-gate typedef enum {
7147c478bd9Sstevel@tonic-gate 	IDNSYNC_NIL,
7157c478bd9Sstevel@tonic-gate 	IDNSYNC_CONNECT,
7167c478bd9Sstevel@tonic-gate 	IDNSYNC_DISCONNECT
7177c478bd9Sstevel@tonic-gate } idn_synccmd_t;
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate /*
7207c478bd9Sstevel@tonic-gate  * Type of sync-registration that is being requested.
7217c478bd9Sstevel@tonic-gate  */
7227c478bd9Sstevel@tonic-gate typedef enum {
7237c478bd9Sstevel@tonic-gate 	IDNSYNC_REG_REG,
7247c478bd9Sstevel@tonic-gate 	IDNSYNC_REG_NEW,
7257c478bd9Sstevel@tonic-gate 	IDNSYNC_REG_QUERY
7267c478bd9Sstevel@tonic-gate } idn_syncreg_t;
7277c478bd9Sstevel@tonic-gate 
7287c478bd9Sstevel@tonic-gate #define	IDN_SYNC_NUMZONE	3
7297c478bd9Sstevel@tonic-gate #define	IDN_SYNC_GETZONE(s)	((((s) != IDNSYNC_CONNECT) && \
7307c478bd9Sstevel@tonic-gate 				((s) != IDNSYNC_DISCONNECT)) ? \
7317c478bd9Sstevel@tonic-gate 				-1 : (int)(s) - 1)
7327c478bd9Sstevel@tonic-gate #define	IDN_SYNC_GETTRANS(s)	(((s) == IDNSYNC_CONNECT) ? \
7337c478bd9Sstevel@tonic-gate 				idn.domset.ds_trans_on : \
7347c478bd9Sstevel@tonic-gate 				((s) == IDNSYNC_DISCONNECT) ? \
7357c478bd9Sstevel@tonic-gate 				idn.domset.ds_trans_off : 0)
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate /*
7387c478bd9Sstevel@tonic-gate  * Generic states when in a state transition region.
7397c478bd9Sstevel@tonic-gate  * These ultimately map to domain states via
7407c478bd9Sstevel@tonic-gate  * a idn_xphase_t definition.  General model:
7417c478bd9Sstevel@tonic-gate  *
7427c478bd9Sstevel@tonic-gate  *		PEND
7437c478bd9Sstevel@tonic-gate  *		 /\
7447c478bd9Sstevel@tonic-gate  *	        /  \
7457c478bd9Sstevel@tonic-gate  *	       |    |
7467c478bd9Sstevel@tonic-gate  *             V    V
7477c478bd9Sstevel@tonic-gate  *          SENT--->RCVD
7487c478bd9Sstevel@tonic-gate  *	       \    /
7497c478bd9Sstevel@tonic-gate  *	        \  /
7507c478bd9Sstevel@tonic-gate  *	         VV
7517c478bd9Sstevel@tonic-gate  *		FINAL
7527c478bd9Sstevel@tonic-gate  *
7537c478bd9Sstevel@tonic-gate  * Start these types with PEND = 0 so that they're
7547c478bd9Sstevel@tonic-gate  * compatible with idnxs_state_table[] and idn_xphase_t
7557c478bd9Sstevel@tonic-gate  * phases that use the value as an index.
7567c478bd9Sstevel@tonic-gate  */
7577c478bd9Sstevel@tonic-gate typedef enum {
7587c478bd9Sstevel@tonic-gate /* 0 */		IDNXS_PEND = 0,
7597c478bd9Sstevel@tonic-gate /* 1 */		IDNXS_SENT,
7607c478bd9Sstevel@tonic-gate /* 2 */		IDNXS_RCVD,
7617c478bd9Sstevel@tonic-gate /* 3 */		IDNXS_FINAL,
7627c478bd9Sstevel@tonic-gate /* 4 */		IDNXS_NIL
7637c478bd9Sstevel@tonic-gate } idn_xstate_t;
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate /*
7667c478bd9Sstevel@tonic-gate  * Locking protocol:
7677c478bd9Sstevel@tonic-gate  *
7687c478bd9Sstevel@tonic-gate  *	Each routine is called with SYNC_LOCK and
7697c478bd9Sstevel@tonic-gate  *	the respective domain's DLOCK(EXCL) held.
7707c478bd9Sstevel@tonic-gate  *	The routines must return with these locks
7717c478bd9Sstevel@tonic-gate  *	still held.
7727c478bd9Sstevel@tonic-gate  */
7737c478bd9Sstevel@tonic-gate struct idn_msgtype;
7747c478bd9Sstevel@tonic-gate 
7757c478bd9Sstevel@tonic-gate typedef struct {
7767c478bd9Sstevel@tonic-gate 	int	t_state;
7777c478bd9Sstevel@tonic-gate 	int	(*t_check)(int domid, struct idn_msgtype *mtp,
7787c478bd9Sstevel@tonic-gate 				idn_xdcargs_t xargs);
7797c478bd9Sstevel@tonic-gate 	void	(*t_action)(int domid, struct idn_msgtype *mtp,
7807c478bd9Sstevel@tonic-gate 				idn_xdcargs_t xargs);
7817c478bd9Sstevel@tonic-gate 	void	(*t_error)(int domid, struct idn_msgtype *mtp,
7827c478bd9Sstevel@tonic-gate 				idn_xdcargs_t xargs);
7837c478bd9Sstevel@tonic-gate } idn_trans_t;
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate /*
7867c478bd9Sstevel@tonic-gate  * The callback routines (xt_final & xt_exit) are called with
7877c478bd9Sstevel@tonic-gate  * DLOCK and SYNC_LOCK held and they are required to return
7887c478bd9Sstevel@tonic-gate  * with these locks still held.
7897c478bd9Sstevel@tonic-gate  */
7907c478bd9Sstevel@tonic-gate typedef struct {
7917c478bd9Sstevel@tonic-gate 	uint_t		xt_msgtype;
7927c478bd9Sstevel@tonic-gate 	idn_trans_t	xt_trans[4];
7937c478bd9Sstevel@tonic-gate 	void		(*xt_final)(int domid);
7947c478bd9Sstevel@tonic-gate 	void		(*xt_exit)(int domid, uint_t msgtype);
7957c478bd9Sstevel@tonic-gate } idn_xphase_t;
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate /*
7987c478bd9Sstevel@tonic-gate  * Synchronization entry representing the synchronization
7997c478bd9Sstevel@tonic-gate  * state with respect to a given domain for a given zone.
8007c478bd9Sstevel@tonic-gate  */
8017c478bd9Sstevel@tonic-gate typedef struct idn_syncop {
8027c478bd9Sstevel@tonic-gate 	struct idn_syncop	*s_next;
8037c478bd9Sstevel@tonic-gate 	int			s_domid;
8047c478bd9Sstevel@tonic-gate 	idn_synccmd_t		s_cmd;
8057c478bd9Sstevel@tonic-gate 	int			s_msg;
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	domainset_t		s_set_exp;
8087c478bd9Sstevel@tonic-gate 	domainset_t		s_set_rdy;
8097c478bd9Sstevel@tonic-gate 	int			(*s_transfunc)(int domid, void *arg);
8107c478bd9Sstevel@tonic-gate 	void			*s_transarg;
8117c478bd9Sstevel@tonic-gate #ifdef DEBUG
8127c478bd9Sstevel@tonic-gate 	int			s_query[MAX_DOMAINS];
8137c478bd9Sstevel@tonic-gate #endif /* DEBUG */
8147c478bd9Sstevel@tonic-gate } idn_syncop_t;
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate #ifdef DEBUG
8177c478bd9Sstevel@tonic-gate #define	IDN_SYNC_QUERY_INIT(d) \
8187c478bd9Sstevel@tonic-gate 			(bzero((caddr_t)idn_domain[d].dsync.s_query, \
8197c478bd9Sstevel@tonic-gate 				sizeof (idn_domain[d].dsync.s_query)))
8207c478bd9Sstevel@tonic-gate #define	IDN_SYNC_QUERY_UPDATE(md, sd)	(idn_domain[md].dsync.s_query[sd]++)
8217c478bd9Sstevel@tonic-gate #else /* DEBUG */
8227c478bd9Sstevel@tonic-gate #define	IDN_SYNC_QUERY_INIT(d)
8237c478bd9Sstevel@tonic-gate #define	IDN_SYNC_QUERY_UPDATE(md, sd)
8247c478bd9Sstevel@tonic-gate #endif /* DEBUG */
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate typedef struct {
8277c478bd9Sstevel@tonic-gate 	idn_syncop_t	*sc_op;
8287c478bd9Sstevel@tonic-gate 	int		sc_cnt;
8297c478bd9Sstevel@tonic-gate } idn_synczone_t;
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate /*
8347c478bd9Sstevel@tonic-gate  * Vote Ticket used during negotiations and elections.
8357c478bd9Sstevel@tonic-gate  *
8367c478bd9Sstevel@tonic-gate  * 31					  0
8377c478bd9Sstevel@tonic-gate  * -----------------------------------------
8387c478bd9Sstevel@tonic-gate  * |m...|....|pppp|....|Cbbb|bccc|cccB|BBB1|
8397c478bd9Sstevel@tonic-gate  * -----------------------------------------
8407c478bd9Sstevel@tonic-gate  * m	[31]	= master/slave
8417c478bd9Sstevel@tonic-gate  * .	[30:24]	= unused
8427c478bd9Sstevel@tonic-gate  * p	[23:20]	= priority
8437c478bd9Sstevel@tonic-gate  * .	[19:16]	= unused
8447c478bd9Sstevel@tonic-gate  * C	[15]    = connected (has master)
8457c478bd9Sstevel@tonic-gate  * b	[14:11]	= nmembrds-1
8467c478bd9Sstevel@tonic-gate  * c	[10:5]	= ncpus-1
8477c478bd9Sstevel@tonic-gate  * B	[4:1]	= board_id
8487c478bd9Sstevel@tonic-gate  * 1	[0]	= one
8497c478bd9Sstevel@tonic-gate  */
8507c478bd9Sstevel@tonic-gate typedef union {
8517c478bd9Sstevel@tonic-gate 	struct {
8527c478bd9Sstevel@tonic-gate 		uint_t	master    :1;
8537c478bd9Sstevel@tonic-gate 		uint_t	unused0   :7;
8547c478bd9Sstevel@tonic-gate 		uint_t	priority  :4;
8557c478bd9Sstevel@tonic-gate 		uint_t	unused1   :4;
8567c478bd9Sstevel@tonic-gate 		uint_t	connected :1;
8577c478bd9Sstevel@tonic-gate 		uint_t	nmembrds  :4;
8587c478bd9Sstevel@tonic-gate 		uint_t	ncpus	  :6;
8597c478bd9Sstevel@tonic-gate 		uint_t	board	  :4;
8607c478bd9Sstevel@tonic-gate 		uint_t	one	  :1;
8617c478bd9Sstevel@tonic-gate 	} v;
8627c478bd9Sstevel@tonic-gate 	uint_t	ticket;
8637c478bd9Sstevel@tonic-gate } idn_vote_t;
8647c478bd9Sstevel@tonic-gate 
8657c478bd9Sstevel@tonic-gate #define	IDNVOTE_PRI_MASK	0xf
8667c478bd9Sstevel@tonic-gate #define	IDNVOTE_MAXPRI		0xf
8677c478bd9Sstevel@tonic-gate #define	IDNVOTE_MINPRI		0
8687c478bd9Sstevel@tonic-gate #define	IDNVOTE_DEFPRI		1	/* must be larger than MINPRI */
8697c478bd9Sstevel@tonic-gate /*
8707c478bd9Sstevel@tonic-gate  * Initially:
8717c478bd9Sstevel@tonic-gate  *	vote.v.priority = IDNVOTE_DEFPRI
8727c478bd9Sstevel@tonic-gate  *	vote.v.one	= 1
8737c478bd9Sstevel@tonic-gate  */
8747c478bd9Sstevel@tonic-gate #define	IDNVOTE_INITIAL_TICKET	((IDNVOTE_DEFPRI << 20) | 1)
8757c478bd9Sstevel@tonic-gate #define	IDNVOTE_PRIVALUE(vvv) \
8767c478bd9Sstevel@tonic-gate 	((int)vvv.v.priority + ((int)vvv.v.master ? IDNVOTE_MAXPRI : 0))
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate /*
8797c478bd9Sstevel@tonic-gate  * During elections we only use the "elect" attributes of the
8807c478bd9Sstevel@tonic-gate  * election ticket, i.e. those physical attributes pertaining
8817c478bd9Sstevel@tonic-gate  * to the individual domain (priority, nboards, ncpus, board).
8827c478bd9Sstevel@tonic-gate  */
8837c478bd9Sstevel@tonic-gate #define	IDNVOTE_ELECT_MASK	0x00f07fff
8847c478bd9Sstevel@tonic-gate #define	IDNVOTE_ELECT(tkt)	((tkt).ticket & IDNVOTE_ELECT_MASK)
8857c478bd9Sstevel@tonic-gate #define	IDNVOTE_BASICS_MASK	0x00f0ffff
8867c478bd9Sstevel@tonic-gate #define	IDNVOTE_BASICS(tkt)	((tkt).ticket & IDNVOTE_BASICS_MASK)
8877c478bd9Sstevel@tonic-gate 
8887c478bd9Sstevel@tonic-gate /*
8897c478bd9Sstevel@tonic-gate  * Values used in idn_select_master().
8907c478bd9Sstevel@tonic-gate  */
8917c478bd9Sstevel@tonic-gate #define	MASTER_IS_NONE		0	/* index into master_select_table */
8927c478bd9Sstevel@tonic-gate #define	MASTER_IS_OTHER		1
8937c478bd9Sstevel@tonic-gate #define	MASTER_IS_LOCAL		2
8947c478bd9Sstevel@tonic-gate #define	MASTER_IS_REMOTE	3
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate typedef enum {
8977c478bd9Sstevel@tonic-gate 	MASTER_SELECT_VOTE,
8987c478bd9Sstevel@tonic-gate 	MASTER_SELECT_VOTE_RCFG,
8997c478bd9Sstevel@tonic-gate 	MASTER_SELECT_CONNECT,
9007c478bd9Sstevel@tonic-gate 	MASTER_SELECT_REMOTE,
9017c478bd9Sstevel@tonic-gate 	MASTER_SELECT_LOCAL,
9027c478bd9Sstevel@tonic-gate 	MASTER_SELECT_WAIT,
9037c478bd9Sstevel@tonic-gate 	MASTER_SELECT_ERROR
9047c478bd9Sstevel@tonic-gate } idn_master_select_t;
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate /*
9077c478bd9Sstevel@tonic-gate  * Used to synchronize completion of link/unlink with respect to
9087c478bd9Sstevel@tonic-gate  * the original requester (user).  Necessary since link establishment
9097c478bd9Sstevel@tonic-gate  * occurs asynchronously.
9107c478bd9Sstevel@tonic-gate  */
9117c478bd9Sstevel@tonic-gate typedef enum {
9127c478bd9Sstevel@tonic-gate /*  0 */	IDNOP_DISCONNECTED,	/* successfully disconnected */
9137c478bd9Sstevel@tonic-gate /*  1 */	IDNOP_CONNECTED,	/* successfully established */
9147c478bd9Sstevel@tonic-gate /*  2 */	IDNOP_ERROR		/* error trying to link/unlink */
9157c478bd9Sstevel@tonic-gate } idn_opflag_t;
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate /*
9187c478bd9Sstevel@tonic-gate  * IDN Protocol Messages.
9197c478bd9Sstevel@tonic-gate  * These are IDN version (IDN_VERSION) dependent.
9207c478bd9Sstevel@tonic-gate  *
9217c478bd9Sstevel@tonic-gate  *	----- 7, --- 6,5.................0
9227c478bd9Sstevel@tonic-gate  *	|  ack | nack | IDN message type |
9237c478bd9Sstevel@tonic-gate  *	----------------------------------
9247c478bd9Sstevel@tonic-gate  */
9257c478bd9Sstevel@tonic-gate #define	IDN_VERSION	1
9267c478bd9Sstevel@tonic-gate 
9277c478bd9Sstevel@tonic-gate /*
9287c478bd9Sstevel@tonic-gate  * Must be no more than 6-bits.  See DMV private data.
9297c478bd9Sstevel@tonic-gate  */
9307c478bd9Sstevel@tonic-gate #define	IDNP_ACK	0x20
9317c478bd9Sstevel@tonic-gate #define	IDNP_NACK	0x10
9327c478bd9Sstevel@tonic-gate #define	IDNP_NULL	0x00
9337c478bd9Sstevel@tonic-gate #define	IDNP_NEGO	0x01
9347c478bd9Sstevel@tonic-gate #define	IDNP_CON	0x02
9357c478bd9Sstevel@tonic-gate #define	IDNP_CFG	0x03
9367c478bd9Sstevel@tonic-gate #define	IDNP_FIN	0x04
9377c478bd9Sstevel@tonic-gate #define	IDNP_CMD	0x05
9387c478bd9Sstevel@tonic-gate #define	IDNP_DATA	0x06
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate #define	IDN_NUM_MSGTYPES	7
9417c478bd9Sstevel@tonic-gate #define	IDNP_ACKNACK_MASK	(IDNP_ACK | IDNP_NACK)
9427c478bd9Sstevel@tonic-gate #define	IDNP_MSGTYPE_MASK	0x0f
9437c478bd9Sstevel@tonic-gate #define	VALID_MSGTYPE(m)	(((m) >= IDNP_NEGO) && ((m) < IDN_NUM_MSGTYPES))
9447c478bd9Sstevel@tonic-gate 
9457c478bd9Sstevel@tonic-gate typedef struct idn_msgtype {
9467c478bd9Sstevel@tonic-gate 	ushort_t	mt_mtype;
9477c478bd9Sstevel@tonic-gate 	ushort_t	mt_atype;
9487c478bd9Sstevel@tonic-gate 	ushort_t	mt_cookie;
9497c478bd9Sstevel@tonic-gate } idn_msgtype_t;
9507c478bd9Sstevel@tonic-gate 
9517c478bd9Sstevel@tonic-gate /*
9527c478bd9Sstevel@tonic-gate  * IDN private data section of DMV layout (48 bits).
9537c478bd9Sstevel@tonic-gate  *
9547c478bd9Sstevel@tonic-gate  * 47......40,39.....34,33.....28,27..24,23......16,15..............0
9557c478bd9Sstevel@tonic-gate  * | version | msgtype | acktype |  did |   cpuid  |     cookie     |
9567c478bd9Sstevel@tonic-gate  * ------------------------------------------------------------------
9577c478bd9Sstevel@tonic-gate  *
9587c478bd9Sstevel@tonic-gate  * version	Local domain's version of IDN software.
9597c478bd9Sstevel@tonic-gate  * msgtype	Type of IDN message, e.g. nego, syn, etc.
9607c478bd9Sstevel@tonic-gate  * acktype	If msgtype is a ACK or NACK, then acktype is the
9617c478bd9Sstevel@tonic-gate  *		type of ack that we're receiving, e.g. ack/nego|ack.
9627c478bd9Sstevel@tonic-gate  * did		Local domain's ID (netid) - system-wide unique.
9637c478bd9Sstevel@tonic-gate  * cpuid	Local domain's CPU->cpu_id that sending message.
9647c478bd9Sstevel@tonic-gate  * cookie	Cookie assigned by remote domain for authentication.
9657c478bd9Sstevel@tonic-gate  *		For NEGO & NEGO+ACK messages, it's the cookie that
9667c478bd9Sstevel@tonic-gate  *		the sender expects the receiver to use in subsequent
9677c478bd9Sstevel@tonic-gate  *		messages.  The upper-eight bits represent a timer
9687c478bd9Sstevel@tonic-gate  *		cookie to associate timers with expected messages.
9697c478bd9Sstevel@tonic-gate  */
9707c478bd9Sstevel@tonic-gate #endif /* !_ASM */
9717c478bd9Sstevel@tonic-gate 
9727c478bd9Sstevel@tonic-gate #ifdef _KERNEL
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate #define	_IDNPD_COOKIE_MASK	0xffff
9757c478bd9Sstevel@tonic-gate #define	_IDNPD_COOKIE_SHIFT	32
9767c478bd9Sstevel@tonic-gate #define	_IDNPD_VER_MASK		0xff
9777c478bd9Sstevel@tonic-gate #define	_IDNPD_VER_SHIFT	24
9787c478bd9Sstevel@tonic-gate #define	_IDNPD_MTYPE_MASK	0x3f
9797c478bd9Sstevel@tonic-gate #define	_IDNPD_MTYPE_SHIFT	18
9807c478bd9Sstevel@tonic-gate #define	_IDNPD_ATYPE_MASK	0x3f
9817c478bd9Sstevel@tonic-gate #define	_IDNPD_ATYPE_SHIFT	12
9827c478bd9Sstevel@tonic-gate #define	_IDNPD_DOMID_MASK	0xf
9837c478bd9Sstevel@tonic-gate #define	_IDNPD_DOMID_SHIFT	8
9847c478bd9Sstevel@tonic-gate #define	_IDNPD_CPUID_MASK	0xff
9857c478bd9Sstevel@tonic-gate #define	_IDNPD_CPUID_SHIFT	0
9867c478bd9Sstevel@tonic-gate 
9877c478bd9Sstevel@tonic-gate #define	_IDNPD_COOKIE_LEN	16
9887c478bd9Sstevel@tonic-gate 
9897c478bd9Sstevel@tonic-gate #ifndef _ASM
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate #define	IDN_PD2COOKIE(pdata) \
9927c478bd9Sstevel@tonic-gate 	(((uint_t)((pdata) >> _IDNPD_COOKIE_SHIFT)) & _IDNPD_COOKIE_MASK)
9937c478bd9Sstevel@tonic-gate #define	IDN_PD2VER(pdata) \
9947c478bd9Sstevel@tonic-gate 	(((uint_t)((pdata) >> _IDNPD_VER_SHIFT)) & _IDNPD_VER_MASK)
9957c478bd9Sstevel@tonic-gate #define	IDN_PD2MTYPE(pdata) \
9967c478bd9Sstevel@tonic-gate 	(((uint_t)((pdata) >> _IDNPD_MTYPE_SHIFT)) & _IDNPD_MTYPE_MASK)
9977c478bd9Sstevel@tonic-gate #define	IDN_PD2ATYPE(pdata) \
9987c478bd9Sstevel@tonic-gate 	(((uint_t)((pdata) >> _IDNPD_ATYPE_SHIFT)) & _IDNPD_ATYPE_MASK)
9997c478bd9Sstevel@tonic-gate #define	IDN_PD2DOMID(pdata) \
10007c478bd9Sstevel@tonic-gate 	(((uint_t)((pdata) >> _IDNPD_DOMID_SHIFT)) & _IDNPD_DOMID_MASK)
10017c478bd9Sstevel@tonic-gate #define	IDN_PD2CPUID(pdata) \
10027c478bd9Sstevel@tonic-gate 	(((uint_t)((pdata) >> _IDNPD_CPUID_SHIFT)) & _IDNPD_CPUID_MASK)
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate #define	IDN_MAKE_PDATA(mtype, atype, cookie) \
10057c478bd9Sstevel@tonic-gate 	((((uint64_t)(cookie) & UINT64_C(_IDNPD_COOKIE_MASK))	<< \
10067c478bd9Sstevel@tonic-gate 					_IDNPD_COOKIE_SHIFT)	| \
10077c478bd9Sstevel@tonic-gate 	(((uint64_t)idn.version & UINT64_C(_IDNPD_VER_MASK))	<< \
10087c478bd9Sstevel@tonic-gate 					_IDNPD_VER_SHIFT)	| \
10097c478bd9Sstevel@tonic-gate 	(((uint64_t)(mtype) & UINT64_C(_IDNPD_MTYPE_MASK))	<< \
10107c478bd9Sstevel@tonic-gate 					_IDNPD_MTYPE_SHIFT)	| \
10117c478bd9Sstevel@tonic-gate 	(((uint64_t)(atype) & UINT64_C(_IDNPD_ATYPE_MASK))	<< \
10127c478bd9Sstevel@tonic-gate 					_IDNPD_ATYPE_SHIFT)	| \
10137c478bd9Sstevel@tonic-gate 	(((uint64_t)idn.localid & UINT64_C(_IDNPD_DOMID_MASK))	<< \
10147c478bd9Sstevel@tonic-gate 					_IDNPD_DOMID_SHIFT)	| \
10157c478bd9Sstevel@tonic-gate 	(((uint64_t)CPU->cpu_id & UINT64_C(_IDNPD_CPUID_MASK))	<< \
10167c478bd9Sstevel@tonic-gate 					_IDNPD_CPUID_SHIFT))
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate #define	IDN_TCOOKIE(ck)		(((ck) >> 8) & 0xff)
10197c478bd9Sstevel@tonic-gate #define	IDN_DCOOKIE(ck)		((ck) & 0xff)
10207c478bd9Sstevel@tonic-gate #define	IDN_MAKE_COOKIE(d, t)	((((t) & 0xff) << 8) | ((d) & 0xff))
10217c478bd9Sstevel@tonic-gate 
10227c478bd9Sstevel@tonic-gate /*
10237c478bd9Sstevel@tonic-gate  * IDNP_NEGO
10247c478bd9Sstevel@tonic-gate  *
10257c478bd9Sstevel@tonic-gate  * 127........96,95........64,63........32,31.........0
10267c478bd9Sstevel@tonic-gate  * |   vote     |             domainset               |
10277c478bd9Sstevel@tonic-gate  * ----------------------------------------------------
10287c478bd9Sstevel@tonic-gate  * vote		Local/Remote domain's vote ticket.
10297c478bd9Sstevel@tonic-gate  * domainset	Mask of cpuids of domains to which
10307c478bd9Sstevel@tonic-gate  *		sender is connected.  Position in domainset
10317c478bd9Sstevel@tonic-gate  *		designates respective domainid.
10327c478bd9Sstevel@tonic-gate  *		E.g. domainset[6] = 20 -> domainid 6 is
10337c478bd9Sstevel@tonic-gate  *		accessible via cpuid 20.
10347c478bd9Sstevel@tonic-gate  *		The slot for the receiving domain
10357c478bd9Sstevel@tonic-gate  *		contains the masterid of the sending
10367c478bd9Sstevel@tonic-gate  *		domain.  If the sending domain does
10377c478bd9Sstevel@tonic-gate  *		not have a master then the entry will
10387c478bd9Sstevel@tonic-gate  *		contain IDNNEG_NO_MASTER.
10397c478bd9Sstevel@tonic-gate  *
10407c478bd9Sstevel@tonic-gate  * These macros insert a domainid-cpuid pair into the
10417c478bd9Sstevel@tonic-gate  * domainset to be subsequently passed in a NEGO message,
10427c478bd9Sstevel@tonic-gate  * also retrieve the cpuid from the domainset for a
10437c478bd9Sstevel@tonic-gate  * given domainid.
10447c478bd9Sstevel@tonic-gate  *
10457c478bd9Sstevel@tonic-gate  * Usage:
10467c478bd9Sstevel@tonic-gate  *	Sending:
10477c478bd9Sstevel@tonic-gate  *		mask = IDNNEG_DSET_MYMASK();
10487c478bd9Sstevel@tonic-gate  *		IDNNEG_DSET_INIT(dset, mask)
10497c478bd9Sstevel@tonic-gate  *		for (all domains except self)
10507c478bd9Sstevel@tonic-gate  *			IDNNEG_DSET_SET(dset, domain, cpuid, mask);
10517c478bd9Sstevel@tonic-gate  *
10527c478bd9Sstevel@tonic-gate  *	Receiving:
10537c478bd9Sstevel@tonic-gate  *		IDNNEG_DSET_GET_MASK(dset, recv_domid, recv_mask);
10547c478bd9Sstevel@tonic-gate  *		for (all domains except recv_domid)
10557c478bd9Sstevel@tonic-gate  *			IDNNEG_DSET_GET(dset, domid, cpuid, recv_mask);
10567c478bd9Sstevel@tonic-gate  */
10577c478bd9Sstevel@tonic-gate typedef uint_t	idnneg_dset_t[3];
10587c478bd9Sstevel@tonic-gate 
10597c478bd9Sstevel@tonic-gate #define	IDNNEG_NO_MASTER		0x3f
10607c478bd9Sstevel@tonic-gate #define	__IDNNEG_DSET_CLEAR(dset)	(bzero((caddr_t)(dset), \
10617c478bd9Sstevel@tonic-gate 						sizeof (idnneg_dset_t)))
10627c478bd9Sstevel@tonic-gate #define	IDNNEG_DSET_MYMASK()		(idn_domain[idn.localid].dcpu)
10637c478bd9Sstevel@tonic-gate 
10647c478bd9Sstevel@tonic-gate #define	IDNNEG_DSET_INIT(dset, mask) \
10657c478bd9Sstevel@tonic-gate 	{ \
10667c478bd9Sstevel@tonic-gate 		__IDNNEG_DSET_CLEAR(dset); \
10677c478bd9Sstevel@tonic-gate 		IDNNEG_DSET_SET((dset), idn.localid, (mask), idn.localid); \
10687c478bd9Sstevel@tonic-gate 	}
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate #define	IDNNEG_DSET_SET(dset, domid, cpuid, mask) \
10717c478bd9Sstevel@tonic-gate 	{ \
10727c478bd9Sstevel@tonic-gate 		uint_t	_s = ((domid) & 0xf) * 6; \
10737c478bd9Sstevel@tonic-gate 		int	_i = _s >> 5; \
10747c478bd9Sstevel@tonic-gate 		uint_t	_s0 = _s & 0x1f; \
10757c478bd9Sstevel@tonic-gate 		uint_t	_t = ((cpuid) ^ (mask)) & 0x3f; \
10767c478bd9Sstevel@tonic-gate 		/*LINTED*/ \
10777c478bd9Sstevel@tonic-gate 		ASSERT(((domid) == idn.localid) ? \
10787c478bd9Sstevel@tonic-gate 			((mask) == idn.localid) : ((cpuid) != (mask))); \
10797c478bd9Sstevel@tonic-gate 		(dset)[_i] |= _t << _s0; \
10807c478bd9Sstevel@tonic-gate 		if ((_s0 + 6) > 32) \
10817c478bd9Sstevel@tonic-gate 			(dset)[_i + 1] |= _t >> (32 - _s0);  \
10827c478bd9Sstevel@tonic-gate 	}
10837c478bd9Sstevel@tonic-gate 
10847c478bd9Sstevel@tonic-gate #define	__IDNNEG_DSET_GET(dset, domid, cpuid, mask, uncond) \
10857c478bd9Sstevel@tonic-gate 	{ \
10867c478bd9Sstevel@tonic-gate 		uint_t	_s = ((domid) & 0xf) * 6; \
10877c478bd9Sstevel@tonic-gate 		int	_i = _s >> 5; \
10887c478bd9Sstevel@tonic-gate 		uint_t	_s0 = _s & 0x1f; \
10897c478bd9Sstevel@tonic-gate 		uint_t	_s1 = (_s + 6) & 0x1f; \
10907c478bd9Sstevel@tonic-gate 		(cpuid) = ((dset)[_i] >> _s0) & 0x3f; \
10917c478bd9Sstevel@tonic-gate 		if ((_s0 + 6) > 32) \
10927c478bd9Sstevel@tonic-gate 			(cpuid) |= ((dset)[_i + 1] << (6 - _s1)) & 0x3f; \
10937c478bd9Sstevel@tonic-gate 		if ((cpuid) || (uncond)) \
10947c478bd9Sstevel@tonic-gate 			(cpuid) ^= (mask) & 0x3f; \
10957c478bd9Sstevel@tonic-gate 		else \
10967c478bd9Sstevel@tonic-gate 			(cpuid) = -1; \
10977c478bd9Sstevel@tonic-gate 	}
10987c478bd9Sstevel@tonic-gate 
10997c478bd9Sstevel@tonic-gate #define	IDNNEG_DSET_GET_MASK(dset, domid, mask) \
11007c478bd9Sstevel@tonic-gate 		__IDNNEG_DSET_GET((dset), (domid), (mask), (domid), 1)
11017c478bd9Sstevel@tonic-gate 
11027c478bd9Sstevel@tonic-gate #define	IDNNEG_DSET_GET_MASTER(dset, master) \
11037c478bd9Sstevel@tonic-gate 		__IDNNEG_DSET_GET((dset), idn.localid, (master), \
11047c478bd9Sstevel@tonic-gate 				idn.localid+MAX_DOMAINS, 0)
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate #define	IDNNEG_DSET_SET_MASTER(dset, domid, master) \
11077c478bd9Sstevel@tonic-gate 		IDNNEG_DSET_SET((dset), (domid), (master), \
11087c478bd9Sstevel@tonic-gate 				(domid)+MAX_DOMAINS)
11097c478bd9Sstevel@tonic-gate 
11107c478bd9Sstevel@tonic-gate #define	IDNNEG_DSET_GET(dset, domid, cpuid, mask) \
11117c478bd9Sstevel@tonic-gate 		__IDNNEG_DSET_GET((dset), (domid), (cpuid), (mask), 0)
11127c478bd9Sstevel@tonic-gate 
11137c478bd9Sstevel@tonic-gate /*
11147c478bd9Sstevel@tonic-gate  * IDNP_CFG sub-types.
11157c478bd9Sstevel@tonic-gate  *
11167c478bd9Sstevel@tonic-gate  * Format of first 32 bit word in XDC:
11177c478bd9Sstevel@tonic-gate  *	stX  = sub-type.
11187c478bd9Sstevel@tonic-gate  *	staX = sub-type arg.
11197c478bd9Sstevel@tonic-gate  *	X    = position in idn_cfgsubtype_t.param.p[] array.
11207c478bd9Sstevel@tonic-gate  *	num  = number of parameters in this XDC (0-3)
11217c478bd9Sstevel@tonic-gate  *
11227c478bd9Sstevel@tonic-gate  *      31...28,27...24,23...20,19...16,15...12,11....8,7.....3,2....0
11237c478bd9Sstevel@tonic-gate  *	|  st0 .  sta0 |   st1 .  sta1 |   st2 .  sta2 | phase | num |
11247c478bd9Sstevel@tonic-gate  *	--------------------------------------------------------------
11257c478bd9Sstevel@tonic-gate  *
11267c478bd9Sstevel@tonic-gate  * Note that since the first 32-bit word in a (IDNP_CFG) XDC is used
11277c478bd9Sstevel@tonic-gate  * for a sub-type, subsequent three 32-bits words are used for data that
11287c478bd9Sstevel@tonic-gate  * pertains to respective sub-type, i.e. first sub-type corresponds
11297c478bd9Sstevel@tonic-gate  * to first of the 3x32-bit words (pos=0), second sub-type corresponds
11307c478bd9Sstevel@tonic-gate  * to second of the 3x32-bit words (pos=1), etc.  Obviously, a max of
11317c478bd9Sstevel@tonic-gate  * only three sub-types can be sent per xdc.
11327c478bd9Sstevel@tonic-gate  */
11337c478bd9Sstevel@tonic-gate #define	IDNCFG_BARLAR		0x1	/* SMR base/limit pfn */
11347c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_BARLAR_BAR		0	/* BAR */
11357c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_BARLAR_LAR		1	/* LAR */
11367c478bd9Sstevel@tonic-gate #define	IDNCFG_MCADR		0x2	/* MC ADR, arg = board number */
11377c478bd9Sstevel@tonic-gate #define	IDNCFG_NMCADR		0x3	/* Number of MC ADRs to expect */
11387c478bd9Sstevel@tonic-gate #define	IDNCFG_CPUSET		0x4	/* dcpuset of remote domain */
11397c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_CPUSET_UPPER  	0	/* 1st word */
11407c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_CPUSET_LOWER  	1	/* 2nd word */
11417c478bd9Sstevel@tonic-gate #define	IDNCFG_NETID		0x5	/* dnetid, arg = 0 */
11427c478bd9Sstevel@tonic-gate #define	IDNCFG_BOARDSET		0x6	/* board set, arg = 0 */
11437c478bd9Sstevel@tonic-gate #define	IDNCFG_SIZE		0x7	/* SMR size parameters */
11447c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_SIZE_MTU		0	/* IDN_MTU */
11457c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_SIZE_BUF		1	/* IDN_SMR_BUFSIZE */
11467c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_SIZE_SLAB		2	/* IDN_SLAB_BUFCOUNT */
11477c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_SIZE_NWR		3	/* IDN_NWR_SIZE */
11487c478bd9Sstevel@tonic-gate #define	IDNCFG_DATAMBOX		0x8	/* SMR data mailbox info */
11497c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_DATAMBOX_TABLE  	0	/* recvmbox table */
11507c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_DATAMBOX_DOMAIN	1	/* domain's recvmbox */
11517c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_DATAMBOX_INDEX	2	/* domain's index into table */
11527c478bd9Sstevel@tonic-gate #define	IDNCFG_DATASVR		0x9	/* Data server info */
11537c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_DATASVR_MAXNETS	0	/* max # of nets/channels */
11547c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_DATASVR_MBXPERNET	1	/* # mbox per net/channel */
11557c478bd9Sstevel@tonic-gate #define	IDNCFG_OPTIONS		0xa	/* various options */
11567c478bd9Sstevel@tonic-gate #define	  IDNCFGARG_CHECKSUM		0	/* IDN_CHECKSUM */
11577c478bd9Sstevel@tonic-gate 
11587c478bd9Sstevel@tonic-gate #define	IDN_CFGPARAM(st, sta)	((uchar_t)((((st) & 0xf) << 4) | ((sta) & 0xf)))
11597c478bd9Sstevel@tonic-gate #define	IDN_CFGPARAM_TYPE(p)	(((p) >> 4) & 0xf)
11607c478bd9Sstevel@tonic-gate #define	IDN_CFGPARAM_ARG(p)	((p) & 0xf)
11617c478bd9Sstevel@tonic-gate 
11627c478bd9Sstevel@tonic-gate typedef union {
11637c478bd9Sstevel@tonic-gate 	struct {
11647c478bd9Sstevel@tonic-gate 		uchar_t	p[3];
11657c478bd9Sstevel@tonic-gate 		uchar_t	_num_phase;	/* info.num, info.phase used instead */
11667c478bd9Sstevel@tonic-gate 	} param;
11677c478bd9Sstevel@tonic-gate 	struct {
11687c478bd9Sstevel@tonic-gate 		uint_t	_p	: 24;	/* param.p[] used instead */
11697c478bd9Sstevel@tonic-gate 		uint_t	num	: 2;
11707c478bd9Sstevel@tonic-gate 		uint_t	phase	: 6;
11717c478bd9Sstevel@tonic-gate 	} info;
11727c478bd9Sstevel@tonic-gate 	uint_t	val;
11737c478bd9Sstevel@tonic-gate } idn_cfgsubtype_t;
11747c478bd9Sstevel@tonic-gate 
11757c478bd9Sstevel@tonic-gate /*
11767c478bd9Sstevel@tonic-gate  * IDN_MASTER_NCFGITEMS
11777c478bd9Sstevel@tonic-gate  *	Minimum number of config items expected from master.
11787c478bd9Sstevel@tonic-gate  *
11797c478bd9Sstevel@tonic-gate  * IDN_SLAVE_NCFGITEMS
11807c478bd9Sstevel@tonic-gate  *	Number of config items expected from slave.
11817c478bd9Sstevel@tonic-gate  */
11827c478bd9Sstevel@tonic-gate #define	IDN_MASTER_NCFGITEMS	17	/* max = +14 (mcadrs) */
11837c478bd9Sstevel@tonic-gate #define	IDN_SLAVE_NCFGITEMS	12
11847c478bd9Sstevel@tonic-gate 
11857c478bd9Sstevel@tonic-gate /*
11867c478bd9Sstevel@tonic-gate  * IDNP_CMD sub-types.
11877c478bd9Sstevel@tonic-gate  */
11887c478bd9Sstevel@tonic-gate typedef enum {
11897c478bd9Sstevel@tonic-gate /*  1 */	IDNCMD_SLABALLOC = 1,	/* Request to allocate a slab */
11907c478bd9Sstevel@tonic-gate /*  2 */	IDNCMD_SLABFREE,	/* Request to free a slab */
11917c478bd9Sstevel@tonic-gate /*  3 */	IDNCMD_SLABREAP,	/* Reap any free slabs */
11927c478bd9Sstevel@tonic-gate /*  4 */	IDNCMD_NODENAME		/* Query nodename of domain */
11937c478bd9Sstevel@tonic-gate } idn_cmd_t;
11947c478bd9Sstevel@tonic-gate 
11957c478bd9Sstevel@tonic-gate #define	VALID_IDNCMD(c)		(((int)(c) >= (int)IDNCMD_SLABALLOC) && \
11967c478bd9Sstevel@tonic-gate 					((int)(c) <= (int)IDNCMD_NODENAME))
11977c478bd9Sstevel@tonic-gate /*
11987c478bd9Sstevel@tonic-gate  * IDNP_NACK
11997c478bd9Sstevel@tonic-gate  */
12007c478bd9Sstevel@tonic-gate typedef enum {
12017c478bd9Sstevel@tonic-gate /*  1 */	IDNNACK_NOCONN = 1,
12027c478bd9Sstevel@tonic-gate /*  2 */	IDNNACK_BADCHAN,
12037c478bd9Sstevel@tonic-gate /*  3 */	IDNNACK_BADCFG,
12047c478bd9Sstevel@tonic-gate /*  4 */	IDNNACK_BADCMD,
12057c478bd9Sstevel@tonic-gate /*  5 */	IDNNACK_RETRY,
12067c478bd9Sstevel@tonic-gate /*  6 */	IDNNACK_DUP,
12077c478bd9Sstevel@tonic-gate /*  7 */	IDNNACK_EXIT,
12087c478bd9Sstevel@tonic-gate /*  8 */	IDNNACK_RESERVED1,
12097c478bd9Sstevel@tonic-gate /*  9 */	IDNNACK_RESERVED2,
12107c478bd9Sstevel@tonic-gate /* 10 */	IDNNACK_RESERVED3
12117c478bd9Sstevel@tonic-gate } idn_nack_t;
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate /*
12147c478bd9Sstevel@tonic-gate  * IDNP_CON sub-types.
12157c478bd9Sstevel@tonic-gate  */
12167c478bd9Sstevel@tonic-gate typedef enum {
12177c478bd9Sstevel@tonic-gate /*  0 */	IDNCON_OFF = 0,
12187c478bd9Sstevel@tonic-gate /*  1 */	IDNCON_NORMAL,		/* regular connect sequence */
12197c478bd9Sstevel@tonic-gate /*  2 */	IDNCON_QUERY		/* query for connect info */
12207c478bd9Sstevel@tonic-gate } idn_con_t;
12217c478bd9Sstevel@tonic-gate 
12227c478bd9Sstevel@tonic-gate /*
12237c478bd9Sstevel@tonic-gate  * IDNP_FIN sub-types.
12247c478bd9Sstevel@tonic-gate  */
12257c478bd9Sstevel@tonic-gate typedef enum {
12267c478bd9Sstevel@tonic-gate /*  0 */	IDNFIN_OFF = 0,		/* active, no fin */
12277c478bd9Sstevel@tonic-gate /*  1 */	IDNFIN_NORMAL,		/* normal disconnect req */
12287c478bd9Sstevel@tonic-gate /*  2 */	IDNFIN_FORCE_SOFT,	/* normal dis, force if goes AWOL */
12297c478bd9Sstevel@tonic-gate /*  3 */	IDNFIN_FORCE_HARD,	/* force disconnect of AWOL domain */
12307c478bd9Sstevel@tonic-gate /*  4 */	IDNFIN_QUERY		/* query for fin info */
12317c478bd9Sstevel@tonic-gate } idn_fin_t;
12327c478bd9Sstevel@tonic-gate 
12337c478bd9Sstevel@tonic-gate #define	VALID_FIN(f)		(((int)(f) > 0) && \
12347c478bd9Sstevel@tonic-gate 					((int)(f) < (int)IDNFIN_QUERY))
12357c478bd9Sstevel@tonic-gate #define	FIN_IS_FORCE(f)		(((f) == IDNFIN_FORCE_SOFT) || \
12367c478bd9Sstevel@tonic-gate 					((f) == IDNFIN_FORCE_HARD))
12377c478bd9Sstevel@tonic-gate 
12387c478bd9Sstevel@tonic-gate /*
12397c478bd9Sstevel@tonic-gate  * FIN ARG types - reasons a FIN was sent.
12407c478bd9Sstevel@tonic-gate  */
12417c478bd9Sstevel@tonic-gate typedef enum {
12427c478bd9Sstevel@tonic-gate /*  0 */	IDNFIN_ARG_NONE = 0,		/* no argument */
12437c478bd9Sstevel@tonic-gate /*  1 */	IDNFIN_ARG_SMRBAD,		/* SMR is corrupted */
12447c478bd9Sstevel@tonic-gate /*  2 */	IDNFIN_ARG_CPUCFG,		/* missing cpu per board */
12457c478bd9Sstevel@tonic-gate /*  3 */	IDNFIN_ARG_HWERR,		/* error programming hardware */
12467c478bd9Sstevel@tonic-gate /*  4 */	IDNFIN_ARG_CFGERR_FATAL,	/* Fatal error during CONFIG */
12477c478bd9Sstevel@tonic-gate /*  5 */	IDNFIN_ARG_CFGERR_MTU,		/* MTU sizes conflict */
12487c478bd9Sstevel@tonic-gate /*  6 */	IDNFIN_ARG_CFGERR_BUF,		/* SMR_BUF_SIZE conflicts */
12497c478bd9Sstevel@tonic-gate /*  7 */	IDNFIN_ARG_CFGERR_SLAB,		/* SLAB sizes conflict */
12507c478bd9Sstevel@tonic-gate /*  8 */	IDNFIN_ARG_CFGERR_NWR,		/* NWR sizes conflict */
12517c478bd9Sstevel@tonic-gate /*  9 */	IDNFIN_ARG_CFGERR_NETS,		/* MAX_NETS conflict */
12527c478bd9Sstevel@tonic-gate /* 10 */	IDNFIN_ARG_CFGERR_MBOX,		/* MBOX_PER_NET conflict */
12537c478bd9Sstevel@tonic-gate /* 11 */	IDNFIN_ARG_CFGERR_NMCADR,	/* NMCADR mismatches actual */
12547c478bd9Sstevel@tonic-gate /* 12 */	IDNFIN_ARG_CFGERR_MCADR,	/* missing some MCADRs */
12557c478bd9Sstevel@tonic-gate /* 13 */	IDNFIN_ARG_CFGERR_CKSUM,	/* checksum settings conflict */
12567c478bd9Sstevel@tonic-gate /* 14 */	IDNFIN_ARG_CFGERR_SMR		/* SMR sizes conflict */
12577c478bd9Sstevel@tonic-gate } idn_finarg_t;
12587c478bd9Sstevel@tonic-gate 
12597c478bd9Sstevel@tonic-gate #define	IDNFIN_ARG_IS_FATAL(fa)	((fa) > IDNFIN_ARG_NONE)
12607c478bd9Sstevel@tonic-gate 
12617c478bd9Sstevel@tonic-gate #define	SET_FIN_TYPE(x, t) \
12627c478bd9Sstevel@tonic-gate 		((x) &= 0xffff, (x) |= (((uint_t)(t) & 0xffff) << 16))
12637c478bd9Sstevel@tonic-gate #define	SET_FIN_ARG(x, a) \
12647c478bd9Sstevel@tonic-gate 		((x) &= ~0xffff, (x) |= ((uint_t)(a) & 0xffff))
12657c478bd9Sstevel@tonic-gate #define	GET_FIN_TYPE(x)		((idn_fin_t)(((x) >> 16) & 0xffff))
12667c478bd9Sstevel@tonic-gate #define	GET_FIN_ARG(x)		((idn_finarg_t)((x) & 0xffff))
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate #define	FINARG2IDNKERR(fa) \
12697c478bd9Sstevel@tonic-gate 	(((fa) == IDNFIN_ARG_SMRBAD)	   ? IDNKERR_SMR_CORRUPTED : \
12707c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CPUCFG)	   ? IDNKERR_CPU_CONFIG	   : \
12717c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_HWERR)	   ? IDNKERR_HW_ERROR	   : \
12727c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_FATAL)  ? IDNKERR_HW_ERROR	   : \
12737c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_MTU)    ? IDNKERR_CONFIG_MTU	   : \
12747c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_BUF)    ? IDNKERR_CONFIG_BUF	   : \
12757c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_SLAB)   ? IDNKERR_CONFIG_SLAB   : \
12767c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_NWR)    ? IDNKERR_CONFIG_NWR    : \
12777c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_NETS)   ? IDNKERR_CONFIG_NETS   : \
12787c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_MBOX)   ? IDNKERR_CONFIG_MBOX   : \
12797c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_NMCADR) ? IDNKERR_CONFIG_NMCADR : \
12807c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_MCADR)  ? IDNKERR_CONFIG_MCADR  : \
12817c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_CKSUM)  ? IDNKERR_CONFIG_CKSUM  : \
12827c478bd9Sstevel@tonic-gate 	((fa) == IDNFIN_ARG_CFGERR_SMR)	   ? IDNKERR_CONFIG_SMR    : 0)
12837c478bd9Sstevel@tonic-gate 
12847c478bd9Sstevel@tonic-gate /*
12857c478bd9Sstevel@tonic-gate  * FIN SYNC types.
12867c478bd9Sstevel@tonic-gate  */
12877c478bd9Sstevel@tonic-gate #define	IDNFIN_SYNC_OFF		0	/* not set */
12887c478bd9Sstevel@tonic-gate #define	IDNFIN_SYNC_NO		1	/* no-sync necessary */
12897c478bd9Sstevel@tonic-gate #define	IDNFIN_SYNC_YES		2	/* do fin synchronously */
12907c478bd9Sstevel@tonic-gate 
12917c478bd9Sstevel@tonic-gate typedef short	idn_finsync_t;
12927c478bd9Sstevel@tonic-gate 
12937c478bd9Sstevel@tonic-gate /*
12947c478bd9Sstevel@tonic-gate  * IDNP_FIN options.
12957c478bd9Sstevel@tonic-gate  */
12967c478bd9Sstevel@tonic-gate typedef enum {
12977c478bd9Sstevel@tonic-gate /*  0 */	IDNFIN_OPT_NONE = 0,	/* none (used w/query) */
12987c478bd9Sstevel@tonic-gate /*  1 */	IDNFIN_OPT_UNLINK,	/* normal unlink request */
12997c478bd9Sstevel@tonic-gate /*  2 */	IDNFIN_OPT_RELINK	/* disconnect and retry link */
13007c478bd9Sstevel@tonic-gate } idn_finopt_t;
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate #define	VALID_FINOPT(f)		(((f) == IDNFIN_OPT_UNLINK) || \
13037c478bd9Sstevel@tonic-gate 				((f) == IDNFIN_OPT_RELINK))
13047c478bd9Sstevel@tonic-gate 
13057c478bd9Sstevel@tonic-gate #define	FIN_MASTER_DOMID(x)	(((((x) >> 16) & 0xffff) == 0xffff) ? \
13067c478bd9Sstevel@tonic-gate 				IDN_NIL_DOMID : (((x) >> 16) & 0xffff))
13077c478bd9Sstevel@tonic-gate #define	FIN_MASTER_CPUID(x)	((((x) & 0xffff) == 0xffff) ? \
13087c478bd9Sstevel@tonic-gate 				IDN_NIL_DCPU : ((x) & 0xfff))
13097c478bd9Sstevel@tonic-gate #define	MAKE_FIN_MASTER(d, c)	((((uint_t)(d) & 0xffff) << 16) | \
13107c478bd9Sstevel@tonic-gate 				((uint_t)(c) & 0xffff))
13117c478bd9Sstevel@tonic-gate #define	NIL_FIN_MASTER		MAKE_FIN_MASTER(IDN_NIL_DOMID, IDN_NIL_DCPU)
13127c478bd9Sstevel@tonic-gate 
13137c478bd9Sstevel@tonic-gate #ifdef DEBUG
13147c478bd9Sstevel@tonic-gate #define	IDN_FSTATE_TRANSITION(dp, ns) \
13157c478bd9Sstevel@tonic-gate 	{ \
13167c478bd9Sstevel@tonic-gate 		int	_id; \
13177c478bd9Sstevel@tonic-gate 		_id = (dp)->domid; \
13187c478bd9Sstevel@tonic-gate 		if ((dp)->dfin != (ns)) { \
13197c478bd9Sstevel@tonic-gate 			hrtime_t	tstamp; \
13207c478bd9Sstevel@tonic-gate 			tstamp = TIMESTAMP(); \
13217c478bd9Sstevel@tonic-gate 			IDN_HISTORY_LOG(IDNH_FIN, _id, (ns), 0); \
1322bf30efa4Smathue 			PR_STATE("FSTATE:%ld:%d: (l=%d, b/p=%d/%d) " \
13237c478bd9Sstevel@tonic-gate 				"%s(%d) -> %s(%d)\n", \
13247c478bd9Sstevel@tonic-gate 				(uint64_t)tstamp, _id, \
13257c478bd9Sstevel@tonic-gate 				__LINE__, \
13267c478bd9Sstevel@tonic-gate 				((dp)->dcpu == IDN_NIL_DCPU) ? -1 : \
13277c478bd9Sstevel@tonic-gate 					CPUID_TO_BOARDID((dp)->dcpu), \
13287c478bd9Sstevel@tonic-gate 				(dp)->dcpu, \
13297c478bd9Sstevel@tonic-gate 				idnfin_str[(dp)->dfin], (dp)->dfin, \
13307c478bd9Sstevel@tonic-gate 				idnfin_str[ns], (ns)); \
13317c478bd9Sstevel@tonic-gate 			(dp)->dfin = (ns); \
13327c478bd9Sstevel@tonic-gate 		} \
13337c478bd9Sstevel@tonic-gate 	}
13347c478bd9Sstevel@tonic-gate #else
13357c478bd9Sstevel@tonic-gate #define	IDN_FSTATE_TRANSITION(dp, ns) \
13367c478bd9Sstevel@tonic-gate 	{ \
13377c478bd9Sstevel@tonic-gate 		IDN_HISTORY_LOG(IDNH_FIN, (dp)->domid, (ns), 0); \
13387c478bd9Sstevel@tonic-gate 		(dp)->dfin = (ns); \
13397c478bd9Sstevel@tonic-gate 	}
13407c478bd9Sstevel@tonic-gate #endif /* DEBUG */
13417c478bd9Sstevel@tonic-gate 
13427c478bd9Sstevel@tonic-gate #endif /* !_ASM */
13437c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
13447c478bd9Sstevel@tonic-gate 
13457c478bd9Sstevel@tonic-gate #ifndef _ASM
13467c478bd9Sstevel@tonic-gate /*
13477c478bd9Sstevel@tonic-gate  * IDN Per-Domain States.
13487c478bd9Sstevel@tonic-gate  */
13497c478bd9Sstevel@tonic-gate typedef enum {
13507c478bd9Sstevel@tonic-gate /*  0 */	IDNDS_CLOSED,		/* idle */
13517c478bd9Sstevel@tonic-gate /*  1 */	IDNDS_NEGO_PEND,	/* link initiating */
13527c478bd9Sstevel@tonic-gate /*  2 */	IDNDS_NEGO_SENT,	/* link initiated, nego sent */
13537c478bd9Sstevel@tonic-gate /*  3 */	IDNDS_NEGO_RCVD,	/* link wanted, nego+ack sent */
13547c478bd9Sstevel@tonic-gate /*  4 */	IDNDS_CONFIG,		/* passing config info, prgm hw */
13557c478bd9Sstevel@tonic-gate /*  5 */	IDNDS_CON_PEND,		/* connection pending */
13567c478bd9Sstevel@tonic-gate /*  6 */	IDNDS_CON_SENT,		/* con sent */
13577c478bd9Sstevel@tonic-gate /*  7 */	IDNDS_CON_RCVD,		/* con sent & received */
13587c478bd9Sstevel@tonic-gate /*  8 */	IDNDS_CON_READY,	/* ready to establish link */
13597c478bd9Sstevel@tonic-gate /*  9 */	IDNDS_CONNECTED,	/* established - linked */
13607c478bd9Sstevel@tonic-gate /* 10 */	IDNDS_FIN_PEND,		/* unlink initiating */
13617c478bd9Sstevel@tonic-gate /* 11 */	IDNDS_FIN_SENT,		/* unlink initiated, fin sent */
13627c478bd9Sstevel@tonic-gate /* 12 */	IDNDS_FIN_RCVD,		/* unlink wanted by remote */
13637c478bd9Sstevel@tonic-gate /* 13 */	IDNDS_DMAP		/* deprogramming hw */
13647c478bd9Sstevel@tonic-gate } idn_dstate_t;
13657c478bd9Sstevel@tonic-gate 
13667c478bd9Sstevel@tonic-gate #define	IDNDS_IS_CLOSED(dp)	(((dp)->dstate == IDNDS_CLOSED) || \
13677c478bd9Sstevel@tonic-gate 				((dp)->dstate == IDNDS_DMAP))
13687c478bd9Sstevel@tonic-gate #define	IDNDS_IS_CONNECTING(dp) (((dp)->dstate > IDNDS_CLOSED) && \
13697c478bd9Sstevel@tonic-gate 				((dp)->dstate < IDNDS_CONNECTED))
13707c478bd9Sstevel@tonic-gate #define	IDNDS_IS_DISCONNECTING(dp)	((dp)->dstate > IDNDS_CONNECTED)
13717c478bd9Sstevel@tonic-gate #define	IDNDS_CONFIG_DONE(dp)	(((dp)->dstate == IDNDS_CLOSED) || \
13727c478bd9Sstevel@tonic-gate 				((dp)->dstate > IDNDS_CONFIG))
13737c478bd9Sstevel@tonic-gate #define	IDNDS_SYNC_TYPE(dp)	(((dp)->dfin_sync != IDNFIN_SYNC_OFF) ? \
13747c478bd9Sstevel@tonic-gate 				(dp)->dfin_sync : \
13757c478bd9Sstevel@tonic-gate 					((dp)->dstate < IDNDS_CON_READY) ? \
13767c478bd9Sstevel@tonic-gate 					IDNFIN_SYNC_NO : IDNFIN_SYNC_YES)
13777c478bd9Sstevel@tonic-gate 
13787c478bd9Sstevel@tonic-gate #endif /* !_ASM */
13797c478bd9Sstevel@tonic-gate 
13807c478bd9Sstevel@tonic-gate #ifdef _KERNEL
13817c478bd9Sstevel@tonic-gate #ifndef _ASM
13827c478bd9Sstevel@tonic-gate /*
13837c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
13847c478bd9Sstevel@tonic-gate  */
13857c478bd9Sstevel@tonic-gate typedef struct idn_timer {
13867c478bd9Sstevel@tonic-gate 	struct idn_timer	*t_forw,
13877c478bd9Sstevel@tonic-gate 				*t_back;
13887c478bd9Sstevel@tonic-gate 	struct idn_timerq	*t_q;
13897c478bd9Sstevel@tonic-gate 
13907c478bd9Sstevel@tonic-gate 	timeout_id_t		t_id;
13917c478bd9Sstevel@tonic-gate 	short			t_domid;
13927c478bd9Sstevel@tonic-gate 	short			t_onq;
13937c478bd9Sstevel@tonic-gate 	ushort_t		t_type;
13947c478bd9Sstevel@tonic-gate 	ushort_t		t_subtype;
13957c478bd9Sstevel@tonic-gate 	uint_t			t_cookie;
13967c478bd9Sstevel@tonic-gate #ifdef DEBUG
13977c478bd9Sstevel@tonic-gate 	hrtime_t		t_posttime;
13987c478bd9Sstevel@tonic-gate 	hrtime_t		t_exectime;
13997c478bd9Sstevel@tonic-gate #endif /* DEBUG */
14007c478bd9Sstevel@tonic-gate } idn_timer_t;
14017c478bd9Sstevel@tonic-gate 
14027c478bd9Sstevel@tonic-gate #define	IDN_TIMER_PUBLIC_COOKIE		0xf
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate #define	IDN_TIMERQ_IS_LOCKED(tq)	(MUTEX_HELD(&(tq)->tq_mutex))
14057c478bd9Sstevel@tonic-gate #define	IDN_TIMERQ_LOCK(tq)		(mutex_enter(&(tq)->tq_mutex))
14067c478bd9Sstevel@tonic-gate #define	IDN_TIMERQ_UNLOCK(tq)		(mutex_exit(&(tq)->tq_mutex))
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate #define	IDN_TIMERQ_INIT(tq) 		(idn_timerq_init(tq))
14097c478bd9Sstevel@tonic-gate #define	IDN_TIMERQ_DEINIT(tq) 		(idn_timerq_deinit(tq))
14107c478bd9Sstevel@tonic-gate #define	IDN_TIMER_ALLOC()		(idn_timer_alloc())
14117c478bd9Sstevel@tonic-gate #define	IDN_TIMER_FREE(tp)		(idn_timer_free(tp))
14127c478bd9Sstevel@tonic-gate 
14137c478bd9Sstevel@tonic-gate #define	IDN_TIMER_START(tq, tp, tim) \
14147c478bd9Sstevel@tonic-gate 			(idn_timer_start((tq), (tp), (tim)))
14157c478bd9Sstevel@tonic-gate #define	IDN_TIMER_STOP(tq, typ, ck) \
14167c478bd9Sstevel@tonic-gate 			((void) idn_timer_stop((tq), (typ), (ck)))
14177c478bd9Sstevel@tonic-gate #define	IDN_TIMER_STOPALL(tp) \
14187c478bd9Sstevel@tonic-gate 			((void) idn_timer_stopall(tp))
14197c478bd9Sstevel@tonic-gate #define	IDN_TIMER_GET(tq, typ, tp, ck) \
14207c478bd9Sstevel@tonic-gate 	{ \
14217c478bd9Sstevel@tonic-gate 		mutex_enter(&((tq)->tq_mutex)); \
14227c478bd9Sstevel@tonic-gate 		(tp) = idn_timer_get((tq), (typ), (ck)); \
14237c478bd9Sstevel@tonic-gate 		mutex_exit(&((tq)->tq_mutex)); \
14247c478bd9Sstevel@tonic-gate 	}
14257c478bd9Sstevel@tonic-gate #define	IDN_TIMER_DEQUEUE(tq, tp) \
14267c478bd9Sstevel@tonic-gate 			(idn_timer_dequeue((tq), (tp)))
14277c478bd9Sstevel@tonic-gate #ifdef DEBUG
14287c478bd9Sstevel@tonic-gate #define	IDN_TIMER_POST(tp) \
14297c478bd9Sstevel@tonic-gate 	((tp)->t_posttime = gethrtime(), (tp)->t_exectime = 0)
14307c478bd9Sstevel@tonic-gate #define	IDN_TIMER_EXEC(tp)	((tp)->t_exectime = gethrtime())
14317c478bd9Sstevel@tonic-gate #else /* DEBUG */
14327c478bd9Sstevel@tonic-gate #define	IDN_TIMER_POST(tp)
14337c478bd9Sstevel@tonic-gate #define	IDN_TIMER_EXEC(tp)
14347c478bd9Sstevel@tonic-gate #endif /* DEBUG */
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate #define	IDN_MSGTIMER_START(domid, typ, subtyp, tim, ckp) \
14377c478bd9Sstevel@tonic-gate 	{ \
14387c478bd9Sstevel@tonic-gate 		idn_timer_t	*_tp; \
14397c478bd9Sstevel@tonic-gate 		char		_str[15]; \
14407c478bd9Sstevel@tonic-gate 		ushort_t	*_ckp = (ckp); \
14417c478bd9Sstevel@tonic-gate 		inum2str((typ), _str); \
14427c478bd9Sstevel@tonic-gate 		PR_TIMER("msgtimer:%d: START: type = %s (0x%x)\n", \
14437c478bd9Sstevel@tonic-gate 				(domid), _str, (typ)); \
14447c478bd9Sstevel@tonic-gate 		_tp = IDN_TIMER_ALLOC(); \
14457c478bd9Sstevel@tonic-gate 		_tp->t_type	= (ushort_t)(typ); \
14467c478bd9Sstevel@tonic-gate 		_tp->t_subtype	= (ushort_t)(subtyp); \
14477c478bd9Sstevel@tonic-gate 		_tp->t_domid	= (short)(domid); \
14487c478bd9Sstevel@tonic-gate 		_tp->t_cookie	= (_ckp) ? *(_ckp) : 0; \
14497c478bd9Sstevel@tonic-gate 		IDN_TIMER_POST(_tp); \
14507c478bd9Sstevel@tonic-gate 		if (_ckp) { \
14517c478bd9Sstevel@tonic-gate 			*(_ckp) = IDN_TIMER_START(&idn_domain[domid].dtimerq, \
14527c478bd9Sstevel@tonic-gate 						_tp, (tim)); \
14537c478bd9Sstevel@tonic-gate 		} else { \
14547c478bd9Sstevel@tonic-gate 			(void) IDN_TIMER_START(&idn_domain[domid].dtimerq, \
14557c478bd9Sstevel@tonic-gate 						_tp, (tim)); \
14567c478bd9Sstevel@tonic-gate 		} \
14577c478bd9Sstevel@tonic-gate 	}
14587c478bd9Sstevel@tonic-gate #define	IDN_MSGTIMER_STOP(domid, typ, ck) \
14597c478bd9Sstevel@tonic-gate 	{ \
14607c478bd9Sstevel@tonic-gate 		char	_str[15]; \
14617c478bd9Sstevel@tonic-gate 		inum2str((typ), _str); \
14627c478bd9Sstevel@tonic-gate 		PR_TIMER("msgtimer:%d: STOP: type = %s (0x%x), " \
14637c478bd9Sstevel@tonic-gate 			"cookie = 0x%x\n", \
14647c478bd9Sstevel@tonic-gate 				(domid), _str, (typ), (ck)); \
14657c478bd9Sstevel@tonic-gate 		IDN_TIMER_STOP(&idn_domain[domid].dtimerq, (typ), (ck)); \
14667c478bd9Sstevel@tonic-gate 	}
14677c478bd9Sstevel@tonic-gate #define	IDN_MSGTIMER_GET(dp, typ, tp, ck) \
14687c478bd9Sstevel@tonic-gate 			IDN_TIMER_GET(&(dp)->dtimerq, (typ), (tp), (ck))
14697c478bd9Sstevel@tonic-gate 
14707c478bd9Sstevel@tonic-gate /*
14717c478bd9Sstevel@tonic-gate  * IDN_SLABALLOC_WAITTIME
14727c478bd9Sstevel@tonic-gate  *		Max wait time in ticks that local domains waits for
14737c478bd9Sstevel@tonic-gate  *		master to respond to a slab allocation request.  Has
14747c478bd9Sstevel@tonic-gate  *		to be at least as long as wait time for a response to
14757c478bd9Sstevel@tonic-gate  *		the command.
14767c478bd9Sstevel@tonic-gate  */
14777c478bd9Sstevel@tonic-gate #define	IDN_SLABALLOC_WAITTIME	((3 * idn_msg_waittime[IDNP_CMD]) / 2)
14787c478bd9Sstevel@tonic-gate 
14797c478bd9Sstevel@tonic-gate /*
14807c478bd9Sstevel@tonic-gate  * Domain state transition macros.
14817c478bd9Sstevel@tonic-gate  */
14827c478bd9Sstevel@tonic-gate #ifdef DEBUG
14837c478bd9Sstevel@tonic-gate #define	IDN_DSTATE_TRANSITION(dp, ns) \
14847c478bd9Sstevel@tonic-gate 	{ \
14857c478bd9Sstevel@tonic-gate 		int		id; \
14867c478bd9Sstevel@tonic-gate 		hrtime_t	tstamp; \
14877c478bd9Sstevel@tonic-gate 		tstamp = TIMESTAMP(); \
14887c478bd9Sstevel@tonic-gate 		ASSERT(RW_WRITE_HELD(&(dp)->drwlock)); \
14897c478bd9Sstevel@tonic-gate 		id = (dp)->domid; \
14907c478bd9Sstevel@tonic-gate 		IDN_HISTORY_LOG(IDNH_DSTATE, id, (ns), \
14917c478bd9Sstevel@tonic-gate 				(uint_t)(dp)->dcpu); \
1492bf30efa4Smathue 		PR_STATE("DSTATE:%ld:%d: (l=%d, b/p=%d/%d) " \
14937c478bd9Sstevel@tonic-gate 			"%s(%d) -> %s(%d)\n", \
14947c478bd9Sstevel@tonic-gate 			(uint64_t)tstamp, id, \
14957c478bd9Sstevel@tonic-gate 			__LINE__, \
14967c478bd9Sstevel@tonic-gate 			((dp)->dcpu == IDN_NIL_DCPU) ? \
14977c478bd9Sstevel@tonic-gate 				-1 : CPUID_TO_BOARDID((dp)->dcpu), \
14987c478bd9Sstevel@tonic-gate 			(dp)->dcpu, \
14997c478bd9Sstevel@tonic-gate 			idnds_str[(dp)->dstate], (dp)->dstate, \
15007c478bd9Sstevel@tonic-gate 			idnds_str[ns], (ns)); \
15017c478bd9Sstevel@tonic-gate 		(dp)->dstate = (ns); \
15027c478bd9Sstevel@tonic-gate 		IDNSB_DOMAIN_UPDATE(dp); \
15037c478bd9Sstevel@tonic-gate 	}
15047c478bd9Sstevel@tonic-gate #else
15057c478bd9Sstevel@tonic-gate #define	IDN_DSTATE_TRANSITION(dp, ns) \
15067c478bd9Sstevel@tonic-gate 	{ \
15077c478bd9Sstevel@tonic-gate 		IDN_HISTORY_LOG(IDNH_DSTATE, (dp)->domid, \
15087c478bd9Sstevel@tonic-gate 			(ns), (uint_t)(dp)->dcpu); \
15097c478bd9Sstevel@tonic-gate 		(dp)->dstate = (ns); \
15107c478bd9Sstevel@tonic-gate 		IDNSB_DOMAIN_UPDATE(dp); \
15117c478bd9Sstevel@tonic-gate 	}
15127c478bd9Sstevel@tonic-gate #endif /* DEBUG */
15137c478bd9Sstevel@tonic-gate 
15147c478bd9Sstevel@tonic-gate #define	IDN_XSTATE_TRANSITION(dp, xs) \
15157c478bd9Sstevel@tonic-gate 	{ \
15167c478bd9Sstevel@tonic-gate 		int	_xs = (xs); \
15177c478bd9Sstevel@tonic-gate 		(dp)->dxstate = _xs; \
15187c478bd9Sstevel@tonic-gate 		if (_xs != IDNXS_NIL) { \
15197c478bd9Sstevel@tonic-gate 			ASSERT((dp)->dxp); \
15207c478bd9Sstevel@tonic-gate 			IDN_DSTATE_TRANSITION((dp), \
15217c478bd9Sstevel@tonic-gate 				(dp)->dxp->xt_trans[_xs].t_state); \
15227c478bd9Sstevel@tonic-gate 		} \
15237c478bd9Sstevel@tonic-gate 	}
15247c478bd9Sstevel@tonic-gate 
15257c478bd9Sstevel@tonic-gate /*
15267c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
15277c478bd9Sstevel@tonic-gate  * IDN Per-Domain Data
15287c478bd9Sstevel@tonic-gate  *
15297c478bd9Sstevel@tonic-gate  * The comment to the right of the respective field represents
15307c478bd9Sstevel@tonic-gate  * what lock protects that field.  If there is no comment then
15317c478bd9Sstevel@tonic-gate  * no lock is required to access the field.
15327c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
15337c478bd9Sstevel@tonic-gate  */
15347c478bd9Sstevel@tonic-gate 
15357c478bd9Sstevel@tonic-gate #define	MAXDNAME	32
15367c478bd9Sstevel@tonic-gate 
15377c478bd9Sstevel@tonic-gate typedef struct idn_domain {
15387c478bd9Sstevel@tonic-gate 	krwlock_t	drwlock;
15397c478bd9Sstevel@tonic-gate 			/*
15407c478bd9Sstevel@tonic-gate 			 * Assigned domid for domain.  Never
15417c478bd9Sstevel@tonic-gate 			 * changes once idn_domain[] is
15427c478bd9Sstevel@tonic-gate 			 * initialized.  We are guaranteed that
15437c478bd9Sstevel@tonic-gate 			 * all domains in IDN will have a
15447c478bd9Sstevel@tonic-gate 			 * uniqueue domid in the range (0-15).
15457c478bd9Sstevel@tonic-gate 			 */
15467c478bd9Sstevel@tonic-gate 	int		domid;
15477c478bd9Sstevel@tonic-gate 	idn_dstate_t	dstate;			/* drwlock */
15487c478bd9Sstevel@tonic-gate 	idn_xstate_t	dxstate;		/* drwlock */
15497c478bd9Sstevel@tonic-gate 			/*
15507c478bd9Sstevel@tonic-gate 			 * Gotten from uname -n for local
15517c478bd9Sstevel@tonic-gate 			 * domain.  Remote domains pass
15527c478bd9Sstevel@tonic-gate 			 * theirs during Config phase.
15537c478bd9Sstevel@tonic-gate 			 */
15547c478bd9Sstevel@tonic-gate 	char		dname[MAXDNAME];	/* drwlock */
15557c478bd9Sstevel@tonic-gate 			/*
15567c478bd9Sstevel@tonic-gate 			 * IDN-wide unique identifier for the
15577c478bd9Sstevel@tonic-gate 			 * given domain.  This value will be
15587c478bd9Sstevel@tonic-gate 			 * the same as the domid.
15597c478bd9Sstevel@tonic-gate 			 */
15607c478bd9Sstevel@tonic-gate 	ushort_t	dnetid;			/* drwlock */
15617c478bd9Sstevel@tonic-gate 	idn_vote_t	dvote;			/* drwlock */
15627c478bd9Sstevel@tonic-gate 			/*
15637c478bd9Sstevel@tonic-gate 			 * Used during FIN sequenece to
15647c478bd9Sstevel@tonic-gate 			 * determine what type of shutdown
15657c478bd9Sstevel@tonic-gate 			 * (unlink) we're executing with
15667c478bd9Sstevel@tonic-gate 			 * respect to the given domain.
15677c478bd9Sstevel@tonic-gate 			 */
15687c478bd9Sstevel@tonic-gate 	idn_fin_t	dfin;			/* drwlock */
15697c478bd9Sstevel@tonic-gate 			/*
15707c478bd9Sstevel@tonic-gate 			 * A non-zero value for dfin_sync
15717c478bd9Sstevel@tonic-gate 			 * indicates that unlink of respective
15727c478bd9Sstevel@tonic-gate 			 * domain does not need to be performed
15737c478bd9Sstevel@tonic-gate 			 * synchronously among all the IDN
15747c478bd9Sstevel@tonic-gate 			 * member domains.
15757c478bd9Sstevel@tonic-gate 			 */
15767c478bd9Sstevel@tonic-gate 	short		dfin_sync;		/* grwlock */
15777c478bd9Sstevel@tonic-gate 			/*
15787c478bd9Sstevel@tonic-gate 			 * Cookie used to determine the
15797c478bd9Sstevel@tonic-gate 			 * proper context in which we're
15807c478bd9Sstevel@tonic-gate 			 * receiving messages from the given
15817c478bd9Sstevel@tonic-gate 			 * domain.  Assigned cookies are exchanged
15827c478bd9Sstevel@tonic-gate 			 * during initial NEGO messages.
15837c478bd9Sstevel@tonic-gate 			 */
15847c478bd9Sstevel@tonic-gate 	ushort_t	dcookie_send;		/* drwlock */
15857c478bd9Sstevel@tonic-gate 	ushort_t	dcookie_recv;		/* drwlock */
15867c478bd9Sstevel@tonic-gate 	short		dcookie_err;		/* drwlock */
15877c478bd9Sstevel@tonic-gate 	int		dcookie_errcnt;		/* drwlock */
15887c478bd9Sstevel@tonic-gate 			/*
15897c478bd9Sstevel@tonic-gate 			 * Primary target cpu for sending
15907c478bd9Sstevel@tonic-gate 			 * messages.  Can change to help
15917c478bd9Sstevel@tonic-gate 			 * distribute interrupts on receiving
15927c478bd9Sstevel@tonic-gate 			 * side.
15937c478bd9Sstevel@tonic-gate 			 */
15947c478bd9Sstevel@tonic-gate 	int		dcpu;			/* drwlock */
15957c478bd9Sstevel@tonic-gate 			/*
15967c478bd9Sstevel@tonic-gate 			 * Used to store dcpu from a previous
15977c478bd9Sstevel@tonic-gate 			 * life.  Only used when requesting
15987c478bd9Sstevel@tonic-gate 			 * a RELINK with a domain we were just
15997c478bd9Sstevel@tonic-gate 			 * previously linked with.  Thus, it
16007c478bd9Sstevel@tonic-gate 			 * does represent a valid cpu in the
16017c478bd9Sstevel@tonic-gate 			 * remote domain.
16027c478bd9Sstevel@tonic-gate 			 */
16037c478bd9Sstevel@tonic-gate 	int		dcpu_save;		/* drwlock */
16047c478bd9Sstevel@tonic-gate 			/*
16057c478bd9Sstevel@tonic-gate 			 * Used to store from which cpu the
16067c478bd9Sstevel@tonic-gate 			 * last message was received.
16077c478bd9Sstevel@tonic-gate 			 */
16087c478bd9Sstevel@tonic-gate 	int		dcpu_last;
16097c478bd9Sstevel@tonic-gate 			/*
16107c478bd9Sstevel@tonic-gate 			 * Transition phase area.  This field
16117c478bd9Sstevel@tonic-gate 			 * points to the proper phase structure
16127c478bd9Sstevel@tonic-gate 			 * depending on what stage the given
16137c478bd9Sstevel@tonic-gate 			 * domain is in.
16147c478bd9Sstevel@tonic-gate 			 */
16157c478bd9Sstevel@tonic-gate 	idn_xphase_t	*dxp;			/* drwlock */
16167c478bd9Sstevel@tonic-gate 			/*
16177c478bd9Sstevel@tonic-gate 			 * Actual synchronization object for
16187c478bd9Sstevel@tonic-gate 			 * the given domain.
16197c478bd9Sstevel@tonic-gate 			 */
16207c478bd9Sstevel@tonic-gate 	idn_syncop_t	dsync;	/* drwlock & idn.sync.sz_mutex */
16217c478bd9Sstevel@tonic-gate 			/*
16227c478bd9Sstevel@tonic-gate 			 * Slab information for given domain.
16237c478bd9Sstevel@tonic-gate 			 * If the local domain is a master,
16247c478bd9Sstevel@tonic-gate 			 * then this field in each domain is used
16257c478bd9Sstevel@tonic-gate 			 * to store which slabs have been assigned
16267c478bd9Sstevel@tonic-gate 			 * to given domain.  If the local domain
16277c478bd9Sstevel@tonic-gate 			 * is a slave, then this information is
16287c478bd9Sstevel@tonic-gate 			 * NULL for all remote idn_domain[]
16297c478bd9Sstevel@tonic-gate 			 * entries, but for local domain holds
16307c478bd9Sstevel@tonic-gate 			 * those slabs assigned to local domain.
16317c478bd9Sstevel@tonic-gate 			 */
16327c478bd9Sstevel@tonic-gate 	smr_slab_t	*dslab;			/* dslab_rwlock */
16337c478bd9Sstevel@tonic-gate 	short		dnslabs;		/* dslab_rwlock */
16347c478bd9Sstevel@tonic-gate 	short		dslab_state;		/* dslab_rwlock */
16357c478bd9Sstevel@tonic-gate 	krwlock_t	dslab_rwlock;
16367c478bd9Sstevel@tonic-gate 			/*
16377c478bd9Sstevel@tonic-gate 			 * Set of cpus belonging to domain.
16387c478bd9Sstevel@tonic-gate 			 */
16397c478bd9Sstevel@tonic-gate 	cpuset_t	dcpuset;		/* drwlock */
16407c478bd9Sstevel@tonic-gate 
16417c478bd9Sstevel@tonic-gate 	int		dncpus;			/* drwlock */
16427c478bd9Sstevel@tonic-gate 			/*
16437c478bd9Sstevel@tonic-gate 			 * Index into dcpumap to determine
16447c478bd9Sstevel@tonic-gate 			 * which cpu to target next for
16457c478bd9Sstevel@tonic-gate 			 * interrupt.  Intended to allow fair
16467c478bd9Sstevel@tonic-gate 			 * distribution of interrupts on
16477c478bd9Sstevel@tonic-gate 			 * remote domain.
16487c478bd9Sstevel@tonic-gate 			 */
16497c478bd9Sstevel@tonic-gate 	uint_t		dcpuindex;		/* drwlock */
16507c478bd9Sstevel@tonic-gate 			/*
16517c478bd9Sstevel@tonic-gate 			 * Quick look-up map of cpus belonging
16527c478bd9Sstevel@tonic-gate 			 * to domain.  Used to select next target.
16537c478bd9Sstevel@tonic-gate 			 */
16547c478bd9Sstevel@tonic-gate 	uchar_t		*dcpumap;		/* drwlock */
16557c478bd9Sstevel@tonic-gate 			/*
16567c478bd9Sstevel@tonic-gate 			 * Non-zero indicates outstanding
16577c478bd9Sstevel@tonic-gate 			 * I/O's to given domain.
16587c478bd9Sstevel@tonic-gate 			 */
16597c478bd9Sstevel@tonic-gate 	int		dio;			/* drwlock */
16607c478bd9Sstevel@tonic-gate 	int		dioerr;			/* drwlock */
16617c478bd9Sstevel@tonic-gate 			/*
16627c478bd9Sstevel@tonic-gate 			 * Set when we fail to allocate a buffer
16637c478bd9Sstevel@tonic-gate 			 * for a domain.  Dictates whether to
16647c478bd9Sstevel@tonic-gate 			 * reclaim max buffers or not.
16657c478bd9Sstevel@tonic-gate 			 */
16667c478bd9Sstevel@tonic-gate 	lock_t		diowanted;
16677c478bd9Sstevel@tonic-gate 			/*
16687c478bd9Sstevel@tonic-gate 			 * Set when remote domain does not
16697c478bd9Sstevel@tonic-gate 			 * seem to be picking up messages sent
16707c478bd9Sstevel@tonic-gate 			 * to it.  Non-zero indicates we have
16717c478bd9Sstevel@tonic-gate 			 * an outstanding "ping" to domain.
16727c478bd9Sstevel@tonic-gate 			 */
16737c478bd9Sstevel@tonic-gate 	lock_t		diocheck;		/* drwlock */
16747c478bd9Sstevel@tonic-gate 	short		dslabsize;		/* drwlock */
16757c478bd9Sstevel@tonic-gate 	uint_t		dmtu;			/* drwlock */
16767c478bd9Sstevel@tonic-gate 
16777c478bd9Sstevel@tonic-gate 	uint_t		dbufsize;		/* drwlock */
16787c478bd9Sstevel@tonic-gate 	short		dnwrsize;		/* drwlock */
16797c478bd9Sstevel@tonic-gate 	lock_t		dreclaim_inprogress;	/* drwlock */
16807c478bd9Sstevel@tonic-gate 	uchar_t		dreclaim_index;		/* drwlock */
16817c478bd9Sstevel@tonic-gate 			/*
16827c478bd9Sstevel@tonic-gate 			 * The following field is primarily
16837c478bd9Sstevel@tonic-gate 			 * used during CFG exchange to keep
16847c478bd9Sstevel@tonic-gate 			 * track of certain per-domain information.
16857c478bd9Sstevel@tonic-gate 			 */
16867c478bd9Sstevel@tonic-gate 	union {					/* all - drwlock */
16877c478bd9Sstevel@tonic-gate 		struct {
16887c478bd9Sstevel@tonic-gate 			uint_t	_dcfgphase	: 6;
16897c478bd9Sstevel@tonic-gate 			uint_t	_dcfgsnddone	: 1;
16907c478bd9Sstevel@tonic-gate 			uint_t	_dcfgrcvdone	: 1;
16917c478bd9Sstevel@tonic-gate 			uint_t	_dcksum		: 2;
16927c478bd9Sstevel@tonic-gate 			uint_t	_dmaxnets	: 6;
16937c478bd9Sstevel@tonic-gate 			uint_t	_dmboxpernet	: 9;
16947c478bd9Sstevel@tonic-gate 			uint_t	_dncfgitems	: 6;
16957c478bd9Sstevel@tonic-gate 			uint_t	_drecfg		: 1;
16967c478bd9Sstevel@tonic-gate 			} _s;
16977c478bd9Sstevel@tonic-gate 		int	_dtmp;
16987c478bd9Sstevel@tonic-gate 	} _u;
16997c478bd9Sstevel@tonic-gate 			/*
17007c478bd9Sstevel@tonic-gate 			 * Each domain entry maintains a
17017c478bd9Sstevel@tonic-gate 			 * timer queue holding timers for
17027c478bd9Sstevel@tonic-gate 			 * messages outstanding to that domain.
17037c478bd9Sstevel@tonic-gate 			 */
17047c478bd9Sstevel@tonic-gate 	struct idn_timerq {
17057c478bd9Sstevel@tonic-gate 		int		tq_cookie;	/* tq_mutex */
17067c478bd9Sstevel@tonic-gate 		kmutex_t	tq_mutex;
17077c478bd9Sstevel@tonic-gate 		int		tq_count;	/* tq_mutex */
17087c478bd9Sstevel@tonic-gate 		idn_timer_t	*tq_queue;	/* tq_mutex */
17097c478bd9Sstevel@tonic-gate 	} dtimerq;
17107c478bd9Sstevel@tonic-gate 			/*
17117c478bd9Sstevel@tonic-gate 			 * dawol is used to keep
17127c478bd9Sstevel@tonic-gate 			 * track of AWOL details for
17137c478bd9Sstevel@tonic-gate 			 * given domain when it is
17147c478bd9Sstevel@tonic-gate 			 * non-responsive.
17157c478bd9Sstevel@tonic-gate 			 */
17167c478bd9Sstevel@tonic-gate 	struct {
17177c478bd9Sstevel@tonic-gate 		int		a_count;	/* drwlock */
17187c478bd9Sstevel@tonic-gate 		clock_t		a_time;		/* drwlock */
17197c478bd9Sstevel@tonic-gate 		clock_t		a_last;		/* drwlock */
17207c478bd9Sstevel@tonic-gate 		clock_t		a_msg;		/* drwlock */
17217c478bd9Sstevel@tonic-gate 	} dawol;
17227c478bd9Sstevel@tonic-gate 
17237c478bd9Sstevel@tonic-gate 	struct hwconfig	{
17247c478bd9Sstevel@tonic-gate 		short		dh_nboards;	/* drwlock */
17257c478bd9Sstevel@tonic-gate 		short		dh_nmcadr;	/* drwlock */
17267c478bd9Sstevel@tonic-gate 		boardset_t	dh_boardset;	/* drwlock */
17277c478bd9Sstevel@tonic-gate 		uint_t		dh_mcadr[MAX_BOARDS];	/* drwlock */
17287c478bd9Sstevel@tonic-gate 	} dhw;
17297c478bd9Sstevel@tonic-gate 			/*
17307c478bd9Sstevel@tonic-gate 			 * Mailbox information used to
17317c478bd9Sstevel@tonic-gate 			 * send/recv messages to given domain.
17327c478bd9Sstevel@tonic-gate 			 */
17337c478bd9Sstevel@tonic-gate 	struct {
17347c478bd9Sstevel@tonic-gate 		kmutex_t		m_mutex;
17357c478bd9Sstevel@tonic-gate 		struct idn_mboxtbl	*m_tbl;		/* m_mutex */
17367c478bd9Sstevel@tonic-gate 		struct idn_mainmbox	*m_send;	/* m_mutex */
17377c478bd9Sstevel@tonic-gate 		struct idn_mainmbox	*m_recv;	/* m_mutex */
17387c478bd9Sstevel@tonic-gate 	} dmbox;
17397c478bd9Sstevel@tonic-gate } idn_domain_t;
17407c478bd9Sstevel@tonic-gate 
17417c478bd9Sstevel@tonic-gate typedef struct idn_timerq	idn_timerq_t;
17427c478bd9Sstevel@tonic-gate 
17437c478bd9Sstevel@tonic-gate #define	dcfgphase	_u._s._dcfgphase
17447c478bd9Sstevel@tonic-gate #define	dcfgsnddone	_u._s._dcfgsnddone
17457c478bd9Sstevel@tonic-gate #define	dcfgrcvdone	_u._s._dcfgrcvdone
17467c478bd9Sstevel@tonic-gate #define	dcksum		_u._s._dcksum
17477c478bd9Sstevel@tonic-gate #define	dmaxnets	_u._s._dmaxnets
17487c478bd9Sstevel@tonic-gate #define	dmboxpernet	_u._s._dmboxpernet
17497c478bd9Sstevel@tonic-gate #define	dncfgitems	_u._s._dncfgitems
17507c478bd9Sstevel@tonic-gate #define	drecfg		_u._s._drecfg
17517c478bd9Sstevel@tonic-gate #define	dbindport	_u._dbindport
17527c478bd9Sstevel@tonic-gate #define	dconnected	_u._dconnected
17537c478bd9Sstevel@tonic-gate #define	dtmp		_u._dtmp
17547c478bd9Sstevel@tonic-gate 
17557c478bd9Sstevel@tonic-gate #define	IDN_DLOCK_EXCL(dd)	(rw_enter(&idn_domain[dd].drwlock, RW_WRITER))
17567c478bd9Sstevel@tonic-gate #define	IDN_DLOCK_SHARED(dd)	(rw_enter(&idn_domain[dd].drwlock, RW_READER))
17577c478bd9Sstevel@tonic-gate #define	IDN_DLOCK_TRY_SHARED(dd) \
17587c478bd9Sstevel@tonic-gate 				(rw_tryenter(&idn_domain[dd].drwlock, \
17597c478bd9Sstevel@tonic-gate 						RW_READER))
17607c478bd9Sstevel@tonic-gate #define	IDN_DLOCK_DOWNGRADE(dd)	(rw_downgrade(&idn_domain[dd].drwlock))
17617c478bd9Sstevel@tonic-gate #define	IDN_DUNLOCK(dd)		(rw_exit(&idn_domain[dd].drwlock))
17627c478bd9Sstevel@tonic-gate #define	IDN_DLOCK_IS_EXCL(dd)	(RW_WRITE_HELD(&idn_domain[dd].drwlock))
17637c478bd9Sstevel@tonic-gate #define	IDN_DLOCK_IS_SHARED(dd)	(RW_READ_HELD(&idn_domain[dd].drwlock))
17647c478bd9Sstevel@tonic-gate #define	IDN_DLOCK_IS_HELD(dd)	(RW_LOCK_HELD(&idn_domain[dd].drwlock))
17657c478bd9Sstevel@tonic-gate 
17667c478bd9Sstevel@tonic-gate #define	IDN_MBOX_LOCK(dd)	(mutex_enter(&idn_domain[dd].dmbox.m_mutex))
17677c478bd9Sstevel@tonic-gate #define	IDN_MBOX_UNLOCK(dd)	(mutex_exit(&idn_domain[dd].dmbox.m_mutex))
17687c478bd9Sstevel@tonic-gate 
17697c478bd9Sstevel@tonic-gate #define	IDN_RESET_COOKIES(dd) \
17707c478bd9Sstevel@tonic-gate 	(idn_domain[dd].dcookie_send = idn_domain[dd].dcookie_recv = 0)
17717c478bd9Sstevel@tonic-gate 
17727c478bd9Sstevel@tonic-gate #define	DSLAB_STATE_UNKNOWN	0
17737c478bd9Sstevel@tonic-gate #define	DSLAB_STATE_LOCAL	1
17747c478bd9Sstevel@tonic-gate #define	DSLAB_STATE_REMOTE	2
17757c478bd9Sstevel@tonic-gate 
17767c478bd9Sstevel@tonic-gate #define	DSLAB_READ_HELD(d)	RW_READ_HELD(&idn_domain[d].dslab_rwlock)
17777c478bd9Sstevel@tonic-gate #define	DSLAB_WRITE_HELD(d)	RW_WRITE_HELD(&idn_domain[d].dslab_rwlock)
17787c478bd9Sstevel@tonic-gate 
17797c478bd9Sstevel@tonic-gate #define	DSLAB_LOCK_EXCL(d) \
17807c478bd9Sstevel@tonic-gate 		rw_enter(&idn_domain[d].dslab_rwlock, RW_WRITER)
17817c478bd9Sstevel@tonic-gate #define	DSLAB_LOCK_SHARED(d) \
17827c478bd9Sstevel@tonic-gate 		rw_enter(&idn_domain[d].dslab_rwlock, RW_READER)
17837c478bd9Sstevel@tonic-gate #define	DSLAB_LOCK_TRYUPGRADE(d) \
17847c478bd9Sstevel@tonic-gate 		rw_tryupgrade(&idn_domain[d].dslab_rwlock)
17857c478bd9Sstevel@tonic-gate #define	DSLAB_UNLOCK(d)		rw_exit(&idn_domain[d].dslab_rwlock)
17867c478bd9Sstevel@tonic-gate 
17877c478bd9Sstevel@tonic-gate /*
17887c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
17897c478bd9Sstevel@tonic-gate  * Macro to pick another target for the given domain.  This hopefully
17907c478bd9Sstevel@tonic-gate  * improves performance by better distributing the SSI responsibilities
17917c478bd9Sstevel@tonic-gate  * at the target domain.
17927c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
17937c478bd9Sstevel@tonic-gate  */
17947c478bd9Sstevel@tonic-gate #define	BUMP_INDEX(set, index) \
17957c478bd9Sstevel@tonic-gate 	{ \
17967c478bd9Sstevel@tonic-gate 		register int	p; \
17977c478bd9Sstevel@tonic-gate 		for (p = (index)+1; p < NCPU; p++) \
17987c478bd9Sstevel@tonic-gate 			if (CPU_IN_SET((set), p)) \
17997c478bd9Sstevel@tonic-gate 				break; \
18007c478bd9Sstevel@tonic-gate 		if (p >= NCPU) \
18017c478bd9Sstevel@tonic-gate 			for (p = 0; p <= (index); p++) \
18027c478bd9Sstevel@tonic-gate 				if (CPU_IN_SET((set), p)) \
18037c478bd9Sstevel@tonic-gate 					break; \
18047c478bd9Sstevel@tonic-gate 		if (!CPU_IN_SET((set), p)) { \
18057c478bd9Sstevel@tonic-gate 			uint_t	_u32, _l32; \
18067c478bd9Sstevel@tonic-gate 			_u32 = UPPER32_CPUMASK(set); \
18077c478bd9Sstevel@tonic-gate 			_l32 = LOWER32_CPUMASK(set); \
18087c478bd9Sstevel@tonic-gate 			cmn_err(CE_PANIC, \
18097c478bd9Sstevel@tonic-gate 				"IDN: cpu %d not in cpuset 0x%x.%0x\n", \
18107c478bd9Sstevel@tonic-gate 				p, _u32, _l32); \
18117c478bd9Sstevel@tonic-gate 		} \
18127c478bd9Sstevel@tonic-gate 		(index) = p; \
18137c478bd9Sstevel@tonic-gate 	}
18147c478bd9Sstevel@tonic-gate 
18157c478bd9Sstevel@tonic-gate #define	IDN_ASSIGN_DCPU(dp, cookie) \
18167c478bd9Sstevel@tonic-gate 		((dp)->dcpu = (int)((dp)->dcpumap[(cookie) & (NCPU-1)]))
18177c478bd9Sstevel@tonic-gate 
18187c478bd9Sstevel@tonic-gate /*
18197c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
18207c478bd9Sstevel@tonic-gate  * Atomic increment/decrement, swap, compare-swap functions.
18217c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
18227c478bd9Sstevel@tonic-gate  */
18237c478bd9Sstevel@tonic-gate #define	ATOMIC_INC(v)		atomic_inc_32((uint_t *)&(v))
18247c478bd9Sstevel@tonic-gate #define	ATOMIC_DEC(v)		atomic_dec_32((uint_t *)&(v))
18257c478bd9Sstevel@tonic-gate #define	ATOMIC_SUB(v, n)	atomic_add_32((uint_t *)&(v), -(n))
18267c478bd9Sstevel@tonic-gate #define	ATOMIC_CAS(a, c, n)	atomic_cas_32((uint32_t *)(a), (uint32_t)(c), \
18277c478bd9Sstevel@tonic-gate 								(uint32_t)(n))
18287c478bd9Sstevel@tonic-gate #define	ATOMIC_SWAPL(a, v)	atomic_swap_32((uint32_t *)(a), (uint32_t)(v))
18297c478bd9Sstevel@tonic-gate 
18307c478bd9Sstevel@tonic-gate /*
18317c478bd9Sstevel@tonic-gate  * DMV vector interrupt support.
18327c478bd9Sstevel@tonic-gate  *
18337c478bd9Sstevel@tonic-gate  * A fixed-size circular buffer is maintained as a queue of
18347c478bd9Sstevel@tonic-gate  * incoming interrupts.  The low-level idn_dmv_handler() waits
18357c478bd9Sstevel@tonic-gate  * for an entry to become FREE and will atomically mark it INUSE.
18367c478bd9Sstevel@tonic-gate  * Once he has filled in the appropriate fields it will be marked
18377c478bd9Sstevel@tonic-gate  * as READY.  The high-level idn_handler() will be invoked and will
18387c478bd9Sstevel@tonic-gate  * process all messages in the queue that are READY.  Each message
18397c478bd9Sstevel@tonic-gate  * is marked PROCESS, a protojob job created and filled in, and
18407c478bd9Sstevel@tonic-gate  * then the interrupt message is marked FREE for use in the next
18417c478bd9Sstevel@tonic-gate  * interrupt.  The iv_state field is used to hold the relevant
18427c478bd9Sstevel@tonic-gate  * state and is updated atomically.
18437c478bd9Sstevel@tonic-gate  */
18447c478bd9Sstevel@tonic-gate #define	IDN_PIL			PIL_8
18457c478bd9Sstevel@tonic-gate #define	IDN_DMV_PENDING_MAX	128	/* per cpu */
18467c478bd9Sstevel@tonic-gate 
18477c478bd9Sstevel@tonic-gate #endif /* !_ASM */
18487c478bd9Sstevel@tonic-gate 
18497c478bd9Sstevel@tonic-gate #ifndef _ASM
18507c478bd9Sstevel@tonic-gate 
18517c478bd9Sstevel@tonic-gate /*
18527c478bd9Sstevel@tonic-gate  * The size of this structure must be a power of 2
18537c478bd9Sstevel@tonic-gate  * so that we can do a simple shift to calculate
18547c478bd9Sstevel@tonic-gate  * our offset into based on cpuid.
18557c478bd9Sstevel@tonic-gate  */
18567c478bd9Sstevel@tonic-gate typedef struct idn_dmv_cpu {
18577c478bd9Sstevel@tonic-gate 	uint32_t	idn_dmv_current;
18587c478bd9Sstevel@tonic-gate 	int32_t		idn_dmv_lostintr;
18597c478bd9Sstevel@tonic-gate 	lock_t		idn_dmv_active;
18607c478bd9Sstevel@tonic-gate 	char		_padding[(2 * sizeof (uint64_t)) - \
18617c478bd9Sstevel@tonic-gate 				sizeof (uint32_t) - \
18627c478bd9Sstevel@tonic-gate 				sizeof (lock_t) - \
18637c478bd9Sstevel@tonic-gate 				sizeof (int32_t)];
18647c478bd9Sstevel@tonic-gate } idn_dmv_cpu_t;
18657c478bd9Sstevel@tonic-gate 
18667c478bd9Sstevel@tonic-gate typedef struct idn_dmv_data {
1867b0fc0e77Sgovinda 	uint64_t	idn_soft_inum;
18687c478bd9Sstevel@tonic-gate 	uint64_t	idn_dmv_qbase;
18697c478bd9Sstevel@tonic-gate 	idn_dmv_cpu_t	idn_dmv_cpu[NCPU];
18707c478bd9Sstevel@tonic-gate } idn_dmv_data_t;
18717c478bd9Sstevel@tonic-gate 
18727c478bd9Sstevel@tonic-gate /*
18737c478bd9Sstevel@tonic-gate  * Requirements of the following data structure:
18747c478bd9Sstevel@tonic-gate  *	- MUST be double-word (8 bytes) aligned.
18757c478bd9Sstevel@tonic-gate  *	- _iv_head field MUST start on double-word boundary.
18767c478bd9Sstevel@tonic-gate  *	- iv_xargs0 MUST start on double-word boundary
18777c478bd9Sstevel@tonic-gate  *	  with iv_xargs1 immediately following.
18787c478bd9Sstevel@tonic-gate  *	- iv_xargs2 MUST start on double-word boundary
18797c478bd9Sstevel@tonic-gate  *	  with iv_xargs3 immediately following.
18807c478bd9Sstevel@tonic-gate  */
18817c478bd9Sstevel@tonic-gate typedef struct idn_dmv_msg {
18827c478bd9Sstevel@tonic-gate 	uint32_t	iv_next;	/* offset */
18837c478bd9Sstevel@tonic-gate 	uchar_t		iv_inuse;
18847c478bd9Sstevel@tonic-gate 	uchar_t		iv_ready;
18857c478bd9Sstevel@tonic-gate 	ushort_t	_padding;
18867c478bd9Sstevel@tonic-gate 	uint32_t	iv_head	  : 16;
18877c478bd9Sstevel@tonic-gate 	uint32_t	iv_cookie : 16;
18887c478bd9Sstevel@tonic-gate 	uint32_t	iv_ver    : 8;
18897c478bd9Sstevel@tonic-gate 	uint32_t	iv_mtype  : 6;
18907c478bd9Sstevel@tonic-gate 	uint32_t	iv_atype  : 6;
18917c478bd9Sstevel@tonic-gate 	uint32_t	iv_domid  : 4;
18927c478bd9Sstevel@tonic-gate 	uint32_t	iv_cpuid  : 8;
18937c478bd9Sstevel@tonic-gate 	uint32_t	iv_xargs0;
18947c478bd9Sstevel@tonic-gate 	uint32_t	iv_xargs1;
18957c478bd9Sstevel@tonic-gate 	uint32_t	iv_xargs2;
18967c478bd9Sstevel@tonic-gate 	uint32_t	iv_xargs3;
18977c478bd9Sstevel@tonic-gate } idn_dmv_msg_t;
18987c478bd9Sstevel@tonic-gate 
18997c478bd9Sstevel@tonic-gate extern uint_t	idn_dmv_inum;
19007c478bd9Sstevel@tonic-gate extern uint_t	idn_soft_inum;
19017c478bd9Sstevel@tonic-gate 
19027c478bd9Sstevel@tonic-gate /*
19037c478bd9Sstevel@tonic-gate  * An IDN-network address has the following format:
19047c478bd9Sstevel@tonic-gate  *
19057c478bd9Sstevel@tonic-gate  *	31......16,15........0
19067c478bd9Sstevel@tonic-gate  *	| channel |  dnetid  |
19077c478bd9Sstevel@tonic-gate  *	----------------------
19087c478bd9Sstevel@tonic-gate  * channel	- network interface.
19097c478bd9Sstevel@tonic-gate  * netid	- idn_domain[].dnetid
19107c478bd9Sstevel@tonic-gate  */
19117c478bd9Sstevel@tonic-gate #define	IDN_MAXMAX_NETS		32
19127c478bd9Sstevel@tonic-gate #define	IDN_BROADCAST_ALLCHAN	((ushort_t)-1)
19137c478bd9Sstevel@tonic-gate #define	IDN_BROADCAST_ALLNETID	((ushort_t)-1)
19147c478bd9Sstevel@tonic-gate 
19157c478bd9Sstevel@tonic-gate typedef union {
19167c478bd9Sstevel@tonic-gate 	struct {
19177c478bd9Sstevel@tonic-gate 		ushort_t	chan;
19187c478bd9Sstevel@tonic-gate 		ushort_t	netid;
19197c478bd9Sstevel@tonic-gate 	} net;
19207c478bd9Sstevel@tonic-gate 	uint_t	netaddr;
19217c478bd9Sstevel@tonic-gate } idn_netaddr_t;
19227c478bd9Sstevel@tonic-gate 
19237c478bd9Sstevel@tonic-gate #define	CHANSET_ALL	(~((idn_chanset_t)0))
19247c478bd9Sstevel@tonic-gate #define	CHANSET(c) \
19257c478bd9Sstevel@tonic-gate 		((idn_chanset_t)1 << ((c) & 31))
19267c478bd9Sstevel@tonic-gate #define	CHAN_IN_SET(m, c) \
19277c478bd9Sstevel@tonic-gate 		(((m) & ((idn_chanset_t)1 << ((c) & 31))) != 0)
19287c478bd9Sstevel@tonic-gate #define	CHANSET_ADD(m, c) \
19297c478bd9Sstevel@tonic-gate 		((m) |= ((idn_chanset_t)1 << ((c) & 31)))
19307c478bd9Sstevel@tonic-gate #define	CHANSET_DEL(m, c) \
19317c478bd9Sstevel@tonic-gate 		((m) &= ~((idn_chanset_t)1 << ((c) & 31)))
19327c478bd9Sstevel@tonic-gate #define	CHANSET_ZERO(m)	((m) = 0)
19337c478bd9Sstevel@tonic-gate 
19347c478bd9Sstevel@tonic-gate typedef enum {
19357c478bd9Sstevel@tonic-gate /*  0 */	IDNCHAN_OPEN,
19367c478bd9Sstevel@tonic-gate /*  1 */	IDNCHAN_SOFT_CLOSE,
19377c478bd9Sstevel@tonic-gate /*  2 */	IDNCHAN_HARD_CLOSE,
19387c478bd9Sstevel@tonic-gate /*  3 */	IDNCHAN_OFFLINE,
19397c478bd9Sstevel@tonic-gate /*  4 */	IDNCHAN_ONLINE
19407c478bd9Sstevel@tonic-gate } idn_chanop_t;
19417c478bd9Sstevel@tonic-gate 
19427c478bd9Sstevel@tonic-gate /*
19437c478bd9Sstevel@tonic-gate  * Retry support.
19447c478bd9Sstevel@tonic-gate  */
19457c478bd9Sstevel@tonic-gate #define	IDN_RETRY_TOKEN(d, x)		((((d) & 0xf) << 16) | \
19467c478bd9Sstevel@tonic-gate 					(0xffff & (uint_t)(x)))
19477c478bd9Sstevel@tonic-gate #define	IDN_RETRY_TOKEN2DOMID(t)	((int)(((t) >> 16) & 0xf))
19487c478bd9Sstevel@tonic-gate #define	IDN_RETRY_TOKEN2TYPE(t)		((idn_retry_t)((t) & 0xffff))
19497c478bd9Sstevel@tonic-gate #define	IDN_RETRY_TYPEALL		((idn_retry_t)0xffff)
19507c478bd9Sstevel@tonic-gate #define	IDN_RETRY_INTERVAL		hz	/* 1 sec */
19517c478bd9Sstevel@tonic-gate #define	IDN_RETRY_RECFG_MULTIPLE	10
19527c478bd9Sstevel@tonic-gate 
19537c478bd9Sstevel@tonic-gate #define	IDN_RETRYINTERVAL_NEGO		(2 * hz)
19547c478bd9Sstevel@tonic-gate #define	IDN_RETRYINTERVAL_CON		(2 * hz)
19557c478bd9Sstevel@tonic-gate #define	IDN_RETRYINTERVAL_FIN		(2 * hz)
19567c478bd9Sstevel@tonic-gate 
19577c478bd9Sstevel@tonic-gate typedef struct idn_retry_job {
19587c478bd9Sstevel@tonic-gate 	struct idn_retry_job	*rj_prev;
19597c478bd9Sstevel@tonic-gate 	struct idn_retry_job	*rj_next;
19607c478bd9Sstevel@tonic-gate 	void			(*rj_func)(uint_t token, void *arg);
19617c478bd9Sstevel@tonic-gate 	void			*rj_arg;
19627c478bd9Sstevel@tonic-gate 	uint_t			rj_token;
19637c478bd9Sstevel@tonic-gate 	short			rj_onq;
19647c478bd9Sstevel@tonic-gate 	timeout_id_t		rj_id;
19657c478bd9Sstevel@tonic-gate } idn_retry_job_t;
19667c478bd9Sstevel@tonic-gate 
19677c478bd9Sstevel@tonic-gate #define	IDNRETRY_ALLOCJOB() \
19687c478bd9Sstevel@tonic-gate 	((idn_retry_job_t *)kmem_cache_alloc(idn.retryqueue.rq_cache, KM_SLEEP))
19697c478bd9Sstevel@tonic-gate #define	IDNRETRY_FREEJOB(j) \
19707c478bd9Sstevel@tonic-gate 	(kmem_cache_free(idn.retryqueue.rq_cache, (void *)(j)))
19717c478bd9Sstevel@tonic-gate 
19727c478bd9Sstevel@tonic-gate typedef enum {
19737c478bd9Sstevel@tonic-gate /*  0 */	IDNRETRY_NIL = 0,
19747c478bd9Sstevel@tonic-gate /*  1 */	IDNRETRY_NEGO,
19757c478bd9Sstevel@tonic-gate /*  2 */	IDNRETRY_CON,
19767c478bd9Sstevel@tonic-gate /*  3 */	IDNRETRY_CONQ,		/* for CON queries */
19777c478bd9Sstevel@tonic-gate /*  4 */	IDNRETRY_FIN,
19787c478bd9Sstevel@tonic-gate /*  5 */	IDNRETRY_FINQ,		/* for FIN queries */
19797c478bd9Sstevel@tonic-gate /*  6 */	IDN_NUM_RETRYTYPES
19807c478bd9Sstevel@tonic-gate } idn_retry_t;
19817c478bd9Sstevel@tonic-gate 
19827c478bd9Sstevel@tonic-gate /*
19837c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
19847c478bd9Sstevel@tonic-gate  */
19857c478bd9Sstevel@tonic-gate typedef struct {
19867c478bd9Sstevel@tonic-gate 	int		m_domid;
19877c478bd9Sstevel@tonic-gate 	int		m_cpuid;
19887c478bd9Sstevel@tonic-gate 	ushort_t	m_msgtype;
19897c478bd9Sstevel@tonic-gate 	ushort_t	m_acktype;
19907c478bd9Sstevel@tonic-gate 	ushort_t	m_cookie;
19917c478bd9Sstevel@tonic-gate 	idn_xdcargs_t	m_xargs;
19927c478bd9Sstevel@tonic-gate } idn_protomsg_t;
19937c478bd9Sstevel@tonic-gate 
19947c478bd9Sstevel@tonic-gate typedef struct idn_protojob {
19957c478bd9Sstevel@tonic-gate 	struct idn_protojob	*j_next;
19967c478bd9Sstevel@tonic-gate 	int			j_cache;
19977c478bd9Sstevel@tonic-gate 	idn_protomsg_t		j_msg;
19987c478bd9Sstevel@tonic-gate } idn_protojob_t;
19997c478bd9Sstevel@tonic-gate 
20007c478bd9Sstevel@tonic-gate typedef struct idn_protoqueue {
20017c478bd9Sstevel@tonic-gate 	struct idn_protoqueue	*q_next;
20027c478bd9Sstevel@tonic-gate 	idn_protojob_t		*q_joblist;
20037c478bd9Sstevel@tonic-gate 	idn_protojob_t		*q_joblist_tail;
20047c478bd9Sstevel@tonic-gate 	int			q_die;
20057c478bd9Sstevel@tonic-gate 	int			q_id;
20067c478bd9Sstevel@tonic-gate 	ksema_t			*q_morgue;
20077c478bd9Sstevel@tonic-gate 	kthread_id_t		q_threadp;
20087c478bd9Sstevel@tonic-gate 	kcondvar_t		q_cv;
20097c478bd9Sstevel@tonic-gate 	kmutex_t		q_mutex;
20107c478bd9Sstevel@tonic-gate } idn_protoqueue_t;
20117c478bd9Sstevel@tonic-gate 
20127c478bd9Sstevel@tonic-gate #define	IDN_PROTOCOL_NSERVERS		4
20137c478bd9Sstevel@tonic-gate #define	IDN_PROTOCOL_SERVER_HASH(d)	((d) % idn.nservers)
20147c478bd9Sstevel@tonic-gate #define	IDN_PROTOJOB_CHUNKS		(idn.nservers)
20157c478bd9Sstevel@tonic-gate 
20167c478bd9Sstevel@tonic-gate /*
20177c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
20187c478bd9Sstevel@tonic-gate  * Data Server definitions.
20197c478bd9Sstevel@tonic-gate  *
20207c478bd9Sstevel@tonic-gate  *	idn_datasvr_t 	- Describes data server thread.
20217c478bd9Sstevel@tonic-gate  *	. ds_id			- Per-domain identifier for data server.
20227c478bd9Sstevel@tonic-gate  *	. ds_domid		- Domain which data server is handling.
20237c478bd9Sstevel@tonic-gate  *	. ds_state		- Flag to enable/disable/terminate
20247c478bd9Sstevel@tonic-gate  *				  data server.
20257c478bd9Sstevel@tonic-gate  *	. ds_mboxp		- Pointer to data server's (local)
20267c478bd9Sstevel@tonic-gate  *				  mailbox to be serviced.
20277c478bd9Sstevel@tonic-gate  *	. ds_waittime		- cv_timedwait sleep time before
20287c478bd9Sstevel@tonic-gate  *				  checking respective mailbox.
20297c478bd9Sstevel@tonic-gate  *	. ds_threadp		- Pointer to data server thread.
20307c478bd9Sstevel@tonic-gate  *	. ds_cv			- Condvar for sleeping.
20317c478bd9Sstevel@tonic-gate  *	. ds_morguep		- Semaphore for terminating thread.
20327c478bd9Sstevel@tonic-gate  *
20337c478bd9Sstevel@tonic-gate  *	idn_mboxhdr_t	- Resides in SMR space (MUST be cache_linesize).
20347c478bd9Sstevel@tonic-gate  *	. mh_svr_active		- Non-zero indicates data server is
20357c478bd9Sstevel@tonic-gate  *				  actively reading mailbox for messages.
20367c478bd9Sstevel@tonic-gate  *	. mh_svr_ready		- Non-zero indicates data server has
20377c478bd9Sstevel@tonic-gate  *				  allocated and is ready to accept data.
20387c478bd9Sstevel@tonic-gate  *	. mh_cookie		- Identifier primarily for debug purposes.
20397c478bd9Sstevel@tonic-gate  *
20407c478bd9Sstevel@tonic-gate  *	idn_mboxmsg_t	- Entry in the SMR space circular queue use to
20417c478bd9Sstevel@tonic-gate  *			  represent a data packet.
20427c478bd9Sstevel@tonic-gate  *	. mm_owner		- Non-zero indicates entry is available
20437c478bd9Sstevel@tonic-gate  *				  to be processed by receiver's data server.
20447c478bd9Sstevel@tonic-gate  *	. mm_flag		- Indicates whether entry needs to be
20457c478bd9Sstevel@tonic-gate  *				  reclaimed by the sender.  Also holds error
20467c478bd9Sstevel@tonic-gate  *				  indications (e.g. bad offset).
20477c478bd9Sstevel@tonic-gate  *	. mm_offset		- SMR offset of respective data packet.
20487c478bd9Sstevel@tonic-gate  *
20497c478bd9Sstevel@tonic-gate  *	idn_mboxtbl_t	- Encapsulation of a per-domain mailbox (SMR space).
20507c478bd9Sstevel@tonic-gate  *	. mt_header		- Header information for synchronization.
20517c478bd9Sstevel@tonic-gate  *	. mt_queue		- Circular queue of idn_mboxmsg_t entries.
20527c478bd9Sstevel@tonic-gate  *
20537c478bd9Sstevel@tonic-gate  *	idn_mainmbox_t	- Encapsulation of main SMR recv/send mailboxes.
20547c478bd9Sstevel@tonic-gate  *	. mm_mutex		- Protects mm_* entries, enqueuing, and
20557c478bd9Sstevel@tonic-gate  *				  dequeuing of messages.  Also protects
20567c478bd9Sstevel@tonic-gate  *				  updates to the route table pointed to
20577c478bd9Sstevel@tonic-gate  *				  by mm_routetbl.
20587c478bd9Sstevel@tonic-gate  *	. mm_count		- send: Current number of messages
20597c478bd9Sstevel@tonic-gate  *					enqueued.
20607c478bd9Sstevel@tonic-gate  *				- recv: Cumulative number of messages
20617c478bd9Sstevel@tonic-gate  *					processed.
20627c478bd9Sstevel@tonic-gate  *	. mm_max_count		- send: Maximum number of messages
20637c478bd9Sstevel@tonic-gate  *					enqueued per iteration.
20647c478bd9Sstevel@tonic-gate  *				  recv: Maximum number of messages
20657c478bd9Sstevel@tonic-gate  *					dequeued per iteration.
20667c478bd9Sstevel@tonic-gate  *	. mm_smr_mboxp		- Pointer to SMR (vaddr) space where
20677c478bd9Sstevel@tonic-gate  *				  respective mailbox resides.
20687c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
20697c478bd9Sstevel@tonic-gate  */
20707c478bd9Sstevel@tonic-gate #define	IDN_MBOXHDR_COOKIE_TOP		((uint_t)0xc0c0)
20717c478bd9Sstevel@tonic-gate #define	IDN_MAKE_MBOXHDR_COOKIE(pd, sd, ch) \
20727c478bd9Sstevel@tonic-gate 				((IDN_MBOXHDR_COOKIE_TOP << 16) \
20737c478bd9Sstevel@tonic-gate 				| (((uint_t)(pd) & 0xf) << 12) \
20747c478bd9Sstevel@tonic-gate 				| (((uint_t)(sd) & 0xf) << 8) \
20757c478bd9Sstevel@tonic-gate 				| ((uint_t)(ch) & 0xf))
20767c478bd9Sstevel@tonic-gate #define	IDN_GET_MBOXHDR_COOKIE(mhp) \
20777c478bd9Sstevel@tonic-gate 				((mhp)->mh_cookie & ~0xff00)
20787c478bd9Sstevel@tonic-gate #define	VALID_MBOXHDR(mhp, ch, cksum) \
20797c478bd9Sstevel@tonic-gate 	((IDN_GET_MBOXHDR_COOKIE(mhp) == \
20807c478bd9Sstevel@tonic-gate 			IDN_MAKE_MBOXHDR_COOKIE(0, 0, (ch))) && \
20817c478bd9Sstevel@tonic-gate 	((cksum) == (*(mhp)).mh_cksum))
20827c478bd9Sstevel@tonic-gate /*
20837c478bd9Sstevel@tonic-gate  * The number of entries in a mailbox queue must be chosen so
20847c478bd9Sstevel@tonic-gate  * that (IDN_MMBOX_NUMENTRIES * sizeof (idn_mboxmsg_t)) is a multiple
20857c478bd9Sstevel@tonic-gate  * of a cacheline size (64).
20867c478bd9Sstevel@tonic-gate  */
20877c478bd9Sstevel@tonic-gate #define	IDN_MMBOX_NUMENTRIES		IDN_MBOX_PER_NET
20887c478bd9Sstevel@tonic-gate /*
20897c478bd9Sstevel@tonic-gate  * We step through the mailboxes in effectively cacheline size
20907c478bd9Sstevel@tonic-gate  * incremenents so that the source and receiving cpus are not competing
20917c478bd9Sstevel@tonic-gate  * for the same cacheline when transmitting/receiving messages into/from
20927c478bd9Sstevel@tonic-gate  * the mailboxes.  The hard requirement is that the step value be even
20937c478bd9Sstevel@tonic-gate  * since the mailbox size will be chosen odd.  This allows us to wraparound
20947c478bd9Sstevel@tonic-gate  * the mailbox uniquely touching each entry until we've exhausted them
20957c478bd9Sstevel@tonic-gate  * all at which point we'll end up where we initially started and repeat
20967c478bd9Sstevel@tonic-gate  * again.
20977c478bd9Sstevel@tonic-gate  */
20987c478bd9Sstevel@tonic-gate #define	IDN_MMBOXINDEX_STEP	(((64 / sizeof (idn_mboxmsg_t)) + 1) & 0xfffe)
20997c478bd9Sstevel@tonic-gate #define	IDN_MMBOXINDEX_INC(i) \
21007c478bd9Sstevel@tonic-gate 	{ \
21017c478bd9Sstevel@tonic-gate 		if (((i) += IDN_MMBOXINDEX_STEP) >= IDN_MMBOX_NUMENTRIES) \
21027c478bd9Sstevel@tonic-gate 			(i) -= IDN_MMBOX_NUMENTRIES; \
21037c478bd9Sstevel@tonic-gate 	}
21047c478bd9Sstevel@tonic-gate 
21057c478bd9Sstevel@tonic-gate #define	IDN_MMBOXINDEX_DIFF(i, j) \
21067c478bd9Sstevel@tonic-gate 	(((i) >= (j)) ? (((i) - (j)) / IDN_MMBOXINDEX_STEP) \
21077c478bd9Sstevel@tonic-gate 		: ((((i) + IDN_MMBOX_NUMENTRIES) - (j)) / IDN_MMBOXINDEX_STEP))
21087c478bd9Sstevel@tonic-gate 
21097c478bd9Sstevel@tonic-gate /*
21107c478bd9Sstevel@tonic-gate  * Require IDN_MBOXAREA_SIZE <= IDN_SLAB_SIZE so we don't waste
21117c478bd9Sstevel@tonic-gate  * slab space.
21127c478bd9Sstevel@tonic-gate  *
21137c478bd9Sstevel@tonic-gate  * Each domain maintains a MAX_DOMAIN(16) entry mbox_table.  Each
21147c478bd9Sstevel@tonic-gate  * entry represents a receive mailbox for a possible domain to which
21157c478bd9Sstevel@tonic-gate  * the given domain may have a connection.  The send mailbox for each
21167c478bd9Sstevel@tonic-gate  * respective domain is given to the local domain at the time of
21177c478bd9Sstevel@tonic-gate  * connection establishment.
21187c478bd9Sstevel@tonic-gate  */
21197c478bd9Sstevel@tonic-gate 
21207c478bd9Sstevel@tonic-gate /*
21217c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21227c478bd9Sstevel@tonic-gate  */
21237c478bd9Sstevel@tonic-gate #define	IDN_MBOXTBL_SIZE \
21247c478bd9Sstevel@tonic-gate 	(IDNROUNDUP(((IDN_MBOX_PER_NET * sizeof (idn_mboxmsg_t)) \
21257c478bd9Sstevel@tonic-gate 			+ sizeof (idn_mboxhdr_t)), IDN_ALIGNSIZE))
21267c478bd9Sstevel@tonic-gate 
21277c478bd9Sstevel@tonic-gate /*
21287c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21297c478bd9Sstevel@tonic-gate  * Each domain has idn_max_nets worth of possible mailbox tables
21307c478bd9Sstevel@tonic-gate  * for each domain to which it might possibly be connected.
21317c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21327c478bd9Sstevel@tonic-gate  */
21337c478bd9Sstevel@tonic-gate #define	IDN_MBOXAREA_SIZE \
21347c478bd9Sstevel@tonic-gate 	(IDN_MBOXTBL_SIZE * IDN_MAX_NETS * MAX_DOMAINS * MAX_DOMAINS)
21357c478bd9Sstevel@tonic-gate #define	IDN_MBOXAREA_OFFSET(d) \
21367c478bd9Sstevel@tonic-gate 	((d) * IDN_MBOXTBL_SIZE * IDN_MAX_NETS * MAX_DOMAINS)
21377c478bd9Sstevel@tonic-gate 
21387c478bd9Sstevel@tonic-gate /*
21397c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21407c478bd9Sstevel@tonic-gate  * Return the base of the mailbox area (set of tables) assigned
21417c478bd9Sstevel@tonic-gate  * to the given domain id.
21427c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21437c478bd9Sstevel@tonic-gate  */
21447c478bd9Sstevel@tonic-gate #define	IDN_MBOXAREA_BASE(m, d) \
21457c478bd9Sstevel@tonic-gate 	((idn_mboxtbl_t *)(((ulong_t)(m)) + IDN_MBOXAREA_OFFSET(d)))
21467c478bd9Sstevel@tonic-gate 
21477c478bd9Sstevel@tonic-gate /*
21487c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21497c478bd9Sstevel@tonic-gate  * Return the pointer to the respective receive mailbox (table set)
21507c478bd9Sstevel@tonic-gate  * for the given domain id relative to the given base mailbox table.
21517c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21527c478bd9Sstevel@tonic-gate  */
21537c478bd9Sstevel@tonic-gate #define	IDN_MBOXTBL_PTR(t, d)	\
21547c478bd9Sstevel@tonic-gate 	((idn_mboxtbl_t *)(((ulong_t)(t)) + ((d) * IDN_MBOXTBL_SIZE \
21557c478bd9Sstevel@tonic-gate 				* IDN_MAX_NETS)))
21567c478bd9Sstevel@tonic-gate /*
21577c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21587c478bd9Sstevel@tonic-gate  * Return the pointer to the actual target mailbox based on the
21597c478bd9Sstevel@tonic-gate  * given channel in the given mailbox table.
21607c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21617c478bd9Sstevel@tonic-gate  */
21627c478bd9Sstevel@tonic-gate #define	IDN_MBOXTBL_PTR_CHAN(t, c) \
21637c478bd9Sstevel@tonic-gate 	((idn_mboxtbl_t *)(((ulong_t)(t)) + ((c) * IDN_MBOXTBL_SIZE)))
21647c478bd9Sstevel@tonic-gate 
21657c478bd9Sstevel@tonic-gate #define	IDN_MBOXTBL_PTR_INC(t)	\
21667c478bd9Sstevel@tonic-gate 	((t) = (idn_mboxtbl_t *)(((ulong_t)(t)) + IDN_MBOXTBL_SIZE))
21677c478bd9Sstevel@tonic-gate 
21687c478bd9Sstevel@tonic-gate #define	IDN_MBOXCHAN_INC(i) \
21697c478bd9Sstevel@tonic-gate 	{ \
21707c478bd9Sstevel@tonic-gate 		if (++(i) == IDN_MAX_NETS) \
21717c478bd9Sstevel@tonic-gate 			(i) = 0; \
21727c478bd9Sstevel@tonic-gate 	}
21737c478bd9Sstevel@tonic-gate 
21747c478bd9Sstevel@tonic-gate /*
21757c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21767c478bd9Sstevel@tonic-gate  * Return the absolute location within the entire mailbox area
21777c478bd9Sstevel@tonic-gate  * of the mboxtbl for the given primary and secondary domain and
21787c478bd9Sstevel@tonic-gate  * channel.  Only relevant when done by the master.
21797c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
21807c478bd9Sstevel@tonic-gate  */
21817c478bd9Sstevel@tonic-gate #define	IDN_MBOXTBL_ABS_PTR(mt, pd, sd, ch) \
21827c478bd9Sstevel@tonic-gate 		(IDN_MBOXTBL_PTR_CHAN( \
21837c478bd9Sstevel@tonic-gate 			IDN_MBOXTBL_PTR( \
21847c478bd9Sstevel@tonic-gate 				IDN_MBOXAREA_BASE((mt), (pd)), \
21857c478bd9Sstevel@tonic-gate 				(sd)), \
21867c478bd9Sstevel@tonic-gate 			(ch)))
21877c478bd9Sstevel@tonic-gate 
21887c478bd9Sstevel@tonic-gate #define	IDN_BFRAME_SHIFT	idn.bframe_shift
21897c478bd9Sstevel@tonic-gate #define	IDN_BFRAME2OFFSET(bf)	((bf) << IDN_BFRAME_SHIFT)
21907c478bd9Sstevel@tonic-gate #define	IDN_BFRAME2ADDR(bf)	IDN_OFFSET2ADDR(IDN_BFRAME2OFFSET(bf))
21917c478bd9Sstevel@tonic-gate #define	IDN_OFFSET2BFRAME(off)	(((off) >> IDN_BFRAME_SHIFT) & 0xffffff)
21927c478bd9Sstevel@tonic-gate #define	IDN_ADDR2BFRAME(addr)	IDN_OFFSET2BFRAME(IDN_ADDR2OFFSET(addr))
21937c478bd9Sstevel@tonic-gate 
21947c478bd9Sstevel@tonic-gate typedef struct idn_mboxmsg {
21957c478bd9Sstevel@tonic-gate 	uint_t		ms_owner  : 1,
21967c478bd9Sstevel@tonic-gate 			ms_flag   : 7,
21977c478bd9Sstevel@tonic-gate 			ms_bframe : 24;
21987c478bd9Sstevel@tonic-gate } idn_mboxmsg_t;
21997c478bd9Sstevel@tonic-gate 
22007c478bd9Sstevel@tonic-gate typedef idn_mboxmsg_t	idn_mboxq_t[1];
22017c478bd9Sstevel@tonic-gate 
2202e0731422SRichard Lowe #define	IDN_CKSUM_MBOX_COUNT	(offsetof(idn_mboxhdr_t, mh_svr_ready) / 2)
2203e0731422SRichard Lowe 
22047c478bd9Sstevel@tonic-gate #define	IDN_CKSUM_MBOX(h)	\
22057c478bd9Sstevel@tonic-gate 			(IDN_CHECKSUM ? \
22067c478bd9Sstevel@tonic-gate 			idn_cksum((ushort_t *)(h), IDN_CKSUM_MBOX_COUNT) : 0)
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate typedef struct idn_mboxhdr {
22097c478bd9Sstevel@tonic-gate 	uint_t		mh_cookie;
22107c478bd9Sstevel@tonic-gate 	uint_t		mh_svr_ready_ptr;
22117c478bd9Sstevel@tonic-gate 	uint_t		mh_svr_active_ptr;
22127c478bd9Sstevel@tonic-gate 	ushort_t	mh_svr_ready;
22137c478bd9Sstevel@tonic-gate 	ushort_t	mh_svr_active;
22147c478bd9Sstevel@tonic-gate 
22157c478bd9Sstevel@tonic-gate 	uint_t		_padding[(64 -
22167c478bd9Sstevel@tonic-gate 				(4*sizeof (uint_t)) -
22177c478bd9Sstevel@tonic-gate 				(2*sizeof (ushort_t))) / sizeof (uint_t)];
22187c478bd9Sstevel@tonic-gate 
22197c478bd9Sstevel@tonic-gate 	uint_t		mh_cksum;
22207c478bd9Sstevel@tonic-gate } idn_mboxhdr_t;
22217c478bd9Sstevel@tonic-gate 
22227c478bd9Sstevel@tonic-gate typedef struct idn_mboxtbl {
22237c478bd9Sstevel@tonic-gate 	idn_mboxhdr_t	mt_header;
22247c478bd9Sstevel@tonic-gate 	idn_mboxq_t	mt_queue;
22257c478bd9Sstevel@tonic-gate } idn_mboxtbl_t;
22267c478bd9Sstevel@tonic-gate 
22277c478bd9Sstevel@tonic-gate #define	IDN_CHAN_DOMAIN_REGISTER(csp, dom) \
22287c478bd9Sstevel@tonic-gate 	(DOMAINSET_ADD((csp)->ch_reg_domset, (dom)))
22297c478bd9Sstevel@tonic-gate 
22307c478bd9Sstevel@tonic-gate #define	IDN_CHAN_DOMAIN_UNREGISTER(csp, dom) \
22317c478bd9Sstevel@tonic-gate 	(DOMAINSET_DEL((csp)->ch_reg_domset, (dom)))
22327c478bd9Sstevel@tonic-gate 
22337c478bd9Sstevel@tonic-gate #define	IDN_CHAN_DOMAIN_IS_REGISTERED(csp, dom) \
22347c478bd9Sstevel@tonic-gate 	(DOMAIN_IN_SET((csp)->ch_reg_domset, (dom)))
22357c478bd9Sstevel@tonic-gate 
22367c478bd9Sstevel@tonic-gate #define	IDN_CHANSVR_SCANSET_ADD_PENDING(csp, dom) \
22377c478bd9Sstevel@tonic-gate 	{ \
22387c478bd9Sstevel@tonic-gate 		register int _d; \
22397c478bd9Sstevel@tonic-gate 		register uint64_t _domset; \
22407c478bd9Sstevel@tonic-gate 		(dom) &= MAX_DOMAINS - 1;   	/* Assumes power of 2 */ \
22417c478bd9Sstevel@tonic-gate 		_domset = 0ull; \
22427c478bd9Sstevel@tonic-gate 		for (_d = 0; _d < (csp)->ch_recv_domcount; _d++) { \
22437c478bd9Sstevel@tonic-gate 			if ((int)(((csp)->ch_recv_scanset_pending >> \
22447c478bd9Sstevel@tonic-gate 						(_d * 4)) & 0xf) == (dom)) \
22457c478bd9Sstevel@tonic-gate 				break; \
22467c478bd9Sstevel@tonic-gate 			else \
22477c478bd9Sstevel@tonic-gate 				_domset = (_domset << 4) | 0xfull; \
22487c478bd9Sstevel@tonic-gate 		} \
22497c478bd9Sstevel@tonic-gate 		if (_d == (csp)->ch_recv_domcount) { \
22507c478bd9Sstevel@tonic-gate 			_domset &= (csp)->ch_recv_scanset_pending; \
22517c478bd9Sstevel@tonic-gate 			_domset |= (uint64_t)(dom) << \
22527c478bd9Sstevel@tonic-gate 					((csp)->ch_recv_domcount * 4); \
22537c478bd9Sstevel@tonic-gate 			(csp)->ch_recv_domcount++; \
22547c478bd9Sstevel@tonic-gate 			(csp)->ch_recv_scanset_pending = 0ull; \
22557c478bd9Sstevel@tonic-gate 			for (_d = 0; _d < 16; \
22567c478bd9Sstevel@tonic-gate 					_d += (csp)->ch_recv_domcount) { \
22577c478bd9Sstevel@tonic-gate 				(csp)->ch_recv_scanset_pending |= _domset; \
22587c478bd9Sstevel@tonic-gate 				_domset <<= (csp)->ch_recv_domcount * 4; \
22597c478bd9Sstevel@tonic-gate 			} \
22607c478bd9Sstevel@tonic-gate 		} \
22617c478bd9Sstevel@tonic-gate 	}
22627c478bd9Sstevel@tonic-gate #define	IDN_CHANSVR_SCANSET_DEL_PENDING(csp, dom) \
22637c478bd9Sstevel@tonic-gate 	{ \
22647c478bd9Sstevel@tonic-gate 		register int _d; \
22657c478bd9Sstevel@tonic-gate 		register uint64_t _domset; \
22667c478bd9Sstevel@tonic-gate 		(dom) &= MAX_DOMAINS - 1;	/* Assumes power of 2 */ \
22677c478bd9Sstevel@tonic-gate 		_domset = 0ull; \
22687c478bd9Sstevel@tonic-gate 		for (_d = 0; _d < (csp)->ch_recv_domcount; _d++) { \
22697c478bd9Sstevel@tonic-gate 			if ((int)(((csp)->ch_recv_scanset_pending >> \
22707c478bd9Sstevel@tonic-gate 						(_d * 4)) & 0xf) == (dom)) \
22717c478bd9Sstevel@tonic-gate 				break; \
22727c478bd9Sstevel@tonic-gate 			else \
22737c478bd9Sstevel@tonic-gate 				_domset = (_domset << 4) | 0xfull; \
22747c478bd9Sstevel@tonic-gate 		} \
22757c478bd9Sstevel@tonic-gate 		if (_d < (csp)->ch_recv_domcount) { \
22767c478bd9Sstevel@tonic-gate 			_domset &= (csp)->ch_recv_scanset_pending; \
22777c478bd9Sstevel@tonic-gate 			(csp)->ch_recv_scanset_pending >>= 4; \
22787c478bd9Sstevel@tonic-gate 			(csp)->ch_recv_domcount--; \
22797c478bd9Sstevel@tonic-gate 			for (; _d < (csp)->ch_recv_domcount; _d++) \
22807c478bd9Sstevel@tonic-gate 				_domset |= (csp)->ch_recv_scanset_pending &\
22817c478bd9Sstevel@tonic-gate 						(0xfull << (_d * 4)); \
22827c478bd9Sstevel@tonic-gate 			(csp)->ch_recv_scanset_pending = 0ull; \
22837c478bd9Sstevel@tonic-gate 			if ((csp)->ch_recv_domcount) { \
22847c478bd9Sstevel@tonic-gate 				for (_d = 0; _d < 16; \
22857c478bd9Sstevel@tonic-gate 					_d += (csp)->ch_recv_domcount) { \
22867c478bd9Sstevel@tonic-gate 					(csp)->ch_recv_scanset_pending |= \
22877c478bd9Sstevel@tonic-gate 						_domset; \
22887c478bd9Sstevel@tonic-gate 					_domset <<= \
22897c478bd9Sstevel@tonic-gate 						(csp)->ch_recv_domcount * 4; \
22907c478bd9Sstevel@tonic-gate 				} \
22917c478bd9Sstevel@tonic-gate 			} \
22927c478bd9Sstevel@tonic-gate 		} \
22937c478bd9Sstevel@tonic-gate 	}
22947c478bd9Sstevel@tonic-gate 
22957c478bd9Sstevel@tonic-gate #define	IDN_CHAN_TRYLOCK_GLOBAL(csp)	\
22967c478bd9Sstevel@tonic-gate 		mutex_tryenter(&(csp)->ch_mutex)
22977c478bd9Sstevel@tonic-gate #define	IDN_CHAN_LOCK_GLOBAL(csp)	\
22987c478bd9Sstevel@tonic-gate 		mutex_enter(&(csp)->ch_mutex)
22997c478bd9Sstevel@tonic-gate #define	IDN_CHAN_UNLOCK_GLOBAL(csp)	\
23007c478bd9Sstevel@tonic-gate 		mutex_exit(&(csp)->ch_mutex)
23017c478bd9Sstevel@tonic-gate #define	IDN_CHAN_GLOBAL_IS_LOCKED(csp)	\
23027c478bd9Sstevel@tonic-gate 		(MUTEX_HELD(&(csp)->ch_mutex))
23037c478bd9Sstevel@tonic-gate 
23047c478bd9Sstevel@tonic-gate #define	IDN_CHAN_LOCAL_IS_LOCKED(csp)	\
23057c478bd9Sstevel@tonic-gate 		(MUTEX_HELD(&(csp)->ch_send.c_mutex) && \
23067c478bd9Sstevel@tonic-gate 		MUTEX_HELD(&(csp)->ch_recv.c_mutex))
23077c478bd9Sstevel@tonic-gate #define	IDN_CHAN_LOCK_LOCAL(csp)	\
23087c478bd9Sstevel@tonic-gate 		(mutex_enter(&(csp)->ch_recv.c_mutex, \
23097c478bd9Sstevel@tonic-gate 		mutex_enter(&(csp)->ch_send.c_mutex))
23107c478bd9Sstevel@tonic-gate #define	IDN_CHAN_UNLOCK_LOCAL(csp) 	\
23117c478bd9Sstevel@tonic-gate 		(mutex_exit(&(csp)->ch_send.c_mutex), \
23127c478bd9Sstevel@tonic-gate 		mutex_exit(&(csp)->ch_recv.c_mutex))
23137c478bd9Sstevel@tonic-gate 
23147c478bd9Sstevel@tonic-gate #define	IDN_CHAN_RECV_IS_LOCKED(csp)	\
23157c478bd9Sstevel@tonic-gate 		(MUTEX_HELD(&(csp)->ch_recv.c_mutex))
23167c478bd9Sstevel@tonic-gate #define	IDN_CHAN_TRYLOCK_RECV(csp) 	\
23177c478bd9Sstevel@tonic-gate 		(mutex_tryenter(&(csp)->ch_recv.c_mutex))
23187c478bd9Sstevel@tonic-gate #define	IDN_CHAN_LOCK_RECV(csp) 	\
23197c478bd9Sstevel@tonic-gate 		(mutex_enter(&(csp)->ch_recv.c_mutex))
23207c478bd9Sstevel@tonic-gate #define	IDN_CHAN_UNLOCK_RECV(csp) 	\
23217c478bd9Sstevel@tonic-gate 		(mutex_exit(&(csp)->ch_recv.c_mutex))
23227c478bd9Sstevel@tonic-gate 
23237c478bd9Sstevel@tonic-gate #define	IDN_CHAN_SEND_IS_LOCKED(csp)	\
23247c478bd9Sstevel@tonic-gate 		(MUTEX_HELD(&(csp)->ch_send.c_mutex))
23257c478bd9Sstevel@tonic-gate #define	IDN_CHAN_TRYLOCK_SEND(csp) 	\
23267c478bd9Sstevel@tonic-gate 		(mutex_tryenter(&(csp)->ch_send.c_mutex))
23277c478bd9Sstevel@tonic-gate #define	IDN_CHAN_LOCK_SEND(csp) 	\
23287c478bd9Sstevel@tonic-gate 		(mutex_enter(&(csp)->ch_send.c_mutex))
23297c478bd9Sstevel@tonic-gate #define	IDN_CHAN_UNLOCK_SEND(csp) 	\
23307c478bd9Sstevel@tonic-gate 		(mutex_exit(&(csp)->ch_send.c_mutex))
23317c478bd9Sstevel@tonic-gate 
23327c478bd9Sstevel@tonic-gate /*
23337c478bd9Sstevel@tonic-gate  * A channel table is an array of pointers to mailboxes
23347c478bd9Sstevel@tonic-gate  * for the respective domains for the given channel.
23357c478bd9Sstevel@tonic-gate  * Used a cache for the frequently used items.  Respective
23367c478bd9Sstevel@tonic-gate  * fields in mainmbox are updated just prior to sleeping.
23377c478bd9Sstevel@tonic-gate  */
23387c478bd9Sstevel@tonic-gate 
23397c478bd9Sstevel@tonic-gate /*
23407c478bd9Sstevel@tonic-gate  * Reading c_state requires either c_mutex or ch_mutex.
23417c478bd9Sstevel@tonic-gate  * Writing c_state requires both c_mutex and ch_mutex in the order:
23427c478bd9Sstevel@tonic-gate  *	ch_mutex
23437c478bd9Sstevel@tonic-gate  *	c_mutex
23447c478bd9Sstevel@tonic-gate  */
23457c478bd9Sstevel@tonic-gate typedef struct idn_chaninfo {
23467c478bd9Sstevel@tonic-gate 	kmutex_t	c_mutex;
23477c478bd9Sstevel@tonic-gate 	uchar_t		c_state;	/* protected by c_mutex */
23487c478bd9Sstevel@tonic-gate 	uchar_t		c_checkin;	/* asynchronous flag */
23497c478bd9Sstevel@tonic-gate 	kcondvar_t	c_cv;
23507c478bd9Sstevel@tonic-gate 	ushort_t	c_waiters;	/* protected by c_mutex */
23517c478bd9Sstevel@tonic-gate 	ushort_t	c_inprogress;	/* protected by c_mutex */
23527c478bd9Sstevel@tonic-gate } idn_chaninfo_t;
23537c478bd9Sstevel@tonic-gate 
23547c478bd9Sstevel@tonic-gate /*
23557c478bd9Sstevel@tonic-gate  * Reading/Writing ch_state requires ch_mutex.
23567c478bd9Sstevel@tonic-gate  * When updating both recv and send c_state's for the locks
23577c478bd9Sstevel@tonic-gate  * must be grabbed in the following order:
23587c478bd9Sstevel@tonic-gate  *	ch_mutex
23597c478bd9Sstevel@tonic-gate  *	ch_recv.c_mutex
23607c478bd9Sstevel@tonic-gate  *	ch_send.c_mutex
23617c478bd9Sstevel@tonic-gate  * This order is necessary to prevent deadlocks.
23627c478bd9Sstevel@tonic-gate  * In general ch_state is intended to represent c_state of
23637c478bd9Sstevel@tonic-gate  * individual send/recv sides.  During state transitions the
23647c478bd9Sstevel@tonic-gate  * ch_state and c_state values may be slightly different,
23657c478bd9Sstevel@tonic-gate  * but eventually should end up identical.
23667c478bd9Sstevel@tonic-gate  */
23677c478bd9Sstevel@tonic-gate typedef struct idn_chansvr {
23687c478bd9Sstevel@tonic-gate 	uchar_t		ch_id;
23697c478bd9Sstevel@tonic-gate 	uchar_t		ch_state;	/* protected by ch_mutex */
23707c478bd9Sstevel@tonic-gate 	lock_t		ch_initlck;
23717c478bd9Sstevel@tonic-gate 	lock_t		ch_actvlck;
23727c478bd9Sstevel@tonic-gate 	domainset_t	ch_reg_domset;
23737c478bd9Sstevel@tonic-gate 	kmutex_t	ch_mutex;
23747c478bd9Sstevel@tonic-gate 
23757c478bd9Sstevel@tonic-gate 	idn_chaninfo_t	ch_send;
23767c478bd9Sstevel@tonic-gate 	int		_padding2[(64 -
23777c478bd9Sstevel@tonic-gate 				(2*sizeof (uchar_t)) - (2*sizeof (lock_t)) -
23787c478bd9Sstevel@tonic-gate 				sizeof (uint_t) - sizeof (kmutex_t) -
23797c478bd9Sstevel@tonic-gate 				sizeof (idn_chaninfo_t)) / sizeof (int)];
23807c478bd9Sstevel@tonic-gate 
23817c478bd9Sstevel@tonic-gate 	idn_chaninfo_t	ch_recv;
23827c478bd9Sstevel@tonic-gate 
23837c478bd9Sstevel@tonic-gate 	uint64_t	ch_recv_scanset;
23847c478bd9Sstevel@tonic-gate 	uint64_t	ch_recv_scanset_pending;
23857c478bd9Sstevel@tonic-gate 
23867c478bd9Sstevel@tonic-gate 	domainset_t	ch_recv_domset;
23877c478bd9Sstevel@tonic-gate 	domainset_t	ch_recv_domset_pending;
23887c478bd9Sstevel@tonic-gate 	short		ch_recv_domcount;
23897c478bd9Sstevel@tonic-gate 	kcondvar_t	ch_recv_cv;
23907c478bd9Sstevel@tonic-gate 	int		ch_recv_waittime;
23917c478bd9Sstevel@tonic-gate 	int		ch_recv_changed;
23927c478bd9Sstevel@tonic-gate 
23937c478bd9Sstevel@tonic-gate 	kthread_id_t	ch_recv_threadp;
23947c478bd9Sstevel@tonic-gate 	ksema_t		*ch_recv_morguep;
23957c478bd9Sstevel@tonic-gate 	int		ch_bound_cpuid;
23967c478bd9Sstevel@tonic-gate 	int		ch_bound_cpuid_pending;
23977c478bd9Sstevel@tonic-gate } idn_chansvr_t;
23987c478bd9Sstevel@tonic-gate 
23997c478bd9Sstevel@tonic-gate typedef struct idn_mainmbox {
24007c478bd9Sstevel@tonic-gate 	kmutex_t	mm_mutex;
24017c478bd9Sstevel@tonic-gate 	short		mm_channel;
24027c478bd9Sstevel@tonic-gate 	short		mm_domid;
24037c478bd9Sstevel@tonic-gate 	ushort_t	mm_flags;
24047c478bd9Sstevel@tonic-gate 	short		mm_type;
24057c478bd9Sstevel@tonic-gate 
24067c478bd9Sstevel@tonic-gate 	idn_chansvr_t	*mm_csp;	/* non-NULL indicates reg'd */
24077c478bd9Sstevel@tonic-gate 	int		mm_count;
24087c478bd9Sstevel@tonic-gate 	int		mm_dropped;
24097c478bd9Sstevel@tonic-gate 	idn_mboxtbl_t	*mm_smr_mboxp;		/* SMR vaddr */
24107c478bd9Sstevel@tonic-gate 
24117c478bd9Sstevel@tonic-gate 	ushort_t	*mm_smr_activep;	/* SMR pointer */
24127c478bd9Sstevel@tonic-gate 	ushort_t	*mm_smr_readyp;		/* SMR pointer */
24137c478bd9Sstevel@tonic-gate 	int		mm_qiget;	/* next msg to get */
24147c478bd9Sstevel@tonic-gate 	int		mm_qiput;	/* next slot to put msg */
24157c478bd9Sstevel@tonic-gate } idn_mainmbox_t;
24167c478bd9Sstevel@tonic-gate 
24177c478bd9Sstevel@tonic-gate /*
24187c478bd9Sstevel@tonic-gate  * mm_flags
24197c478bd9Sstevel@tonic-gate  */
24207c478bd9Sstevel@tonic-gate #define	IDNMMBOX_FLAG_CORRUPTED		0x01
24217c478bd9Sstevel@tonic-gate /*
24227c478bd9Sstevel@tonic-gate  * mm_type
24237c478bd9Sstevel@tonic-gate  */
24247c478bd9Sstevel@tonic-gate #define	IDNMMBOX_TYPE_RECV		0x1
24257c478bd9Sstevel@tonic-gate #define	IDNMMBOX_TYPE_SEND		0x2
24267c478bd9Sstevel@tonic-gate 
24277c478bd9Sstevel@tonic-gate #define	IDNMBOX_IS_RECV(m)	((m) == IDNMMBOX_TYPE_RECV)
24287c478bd9Sstevel@tonic-gate #define	IDNMBOX_IS_SEND(m)	((m) == IDNMMBOX_TYPE_SEND)
24297c478bd9Sstevel@tonic-gate 
24307c478bd9Sstevel@tonic-gate /*
24317c478bd9Sstevel@tonic-gate  * Period between sending wakeup xdc's to remote domain.
24327c478bd9Sstevel@tonic-gate  */
24337c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_WAKEUP_PERIOD	(hz >> 1)
24347c478bd9Sstevel@tonic-gate /*
24357c478bd9Sstevel@tonic-gate  * ms_flag bit values.
24367c478bd9Sstevel@tonic-gate  */
24377c478bd9Sstevel@tonic-gate #define	IDN_MBOXMSG_FLAG_RECLAIM	0x1	/* needs to be reclaimed */
24387c478bd9Sstevel@tonic-gate #define	IDN_MBOXMSG_FLAG_INPROCESS	0x2
24397c478bd9Sstevel@tonic-gate #define	IDN_MBOXMSG_FLAG_ERR_BADOFFSET	0x4
24407c478bd9Sstevel@tonic-gate #define	IDN_MBOXMSG_FLAG_ERR_NOMBOX	0x8
24417c478bd9Sstevel@tonic-gate #define	IDN_MBOXMSG_FLAG_ERRMASK	0xc
24427c478bd9Sstevel@tonic-gate /*
24437c478bd9Sstevel@tonic-gate  * ch_state/c_state bit values.
24447c478bd9Sstevel@tonic-gate  */
24457c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_STATE_ATTACHED	0x01
24467c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_STATE_ENABLED	0x02
24477c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_STATE_ACTIVE	0x04
24487c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_STATE_FLUSH		0x10
24497c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_STATE_CORRUPTED	0x20
24507c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_STATE_MASK		0x07	/* ATTACHED/ENABLED/ACTIVE */
24517c478bd9Sstevel@tonic-gate 
24527c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_PENDING_BITS	(IDN_CHANSVC_STATE_ATTACHED | \
24537c478bd9Sstevel@tonic-gate 					IDN_CHANSVC_STATE_ENABLED)
24547c478bd9Sstevel@tonic-gate 
24557c478bd9Sstevel@tonic-gate /*
24567c478bd9Sstevel@tonic-gate  * GLOBAL
24577c478bd9Sstevel@tonic-gate  */
24587c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_IS_ATTACHED(csp)	\
24597c478bd9Sstevel@tonic-gate 		((csp)->ch_state & IDN_CHANSVC_STATE_ATTACHED)
24607c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_IS_DETACHED(csp)	\
24617c478bd9Sstevel@tonic-gate 		(!IDN_CHANNEL_IS_ATTACHED(csp))
24627c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_IS_PENDING(csp)	\
24637c478bd9Sstevel@tonic-gate 		(((csp)->ch_state & IDN_CHANSVC_STATE_MASK) == \
24647c478bd9Sstevel@tonic-gate 			IDN_CHANSVC_PENDING_BITS)
24657c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_IS_ACTIVE(csp)	\
24667c478bd9Sstevel@tonic-gate 		((csp)->ch_state & IDN_CHANSVC_STATE_ACTIVE)
24677c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_IS_ENABLED(csp)	\
24687c478bd9Sstevel@tonic-gate 		((csp)->ch_state & IDN_CHANSVC_STATE_ENABLED)
24697c478bd9Sstevel@tonic-gate /*
24707c478bd9Sstevel@tonic-gate  * SEND
24717c478bd9Sstevel@tonic-gate  */
24727c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_IS_SEND_ACTIVE(csp)	\
24737c478bd9Sstevel@tonic-gate 		((csp)->ch_send.c_state & IDN_CHANSVC_STATE_ACTIVE)
24747c478bd9Sstevel@tonic-gate /*
24757c478bd9Sstevel@tonic-gate  * RECV
24767c478bd9Sstevel@tonic-gate  */
24777c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_IS_RECV_ACTIVE(csp)	\
24787c478bd9Sstevel@tonic-gate 		((csp)->ch_recv.c_state & IDN_CHANSVC_STATE_ACTIVE)
24797c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_IS_RECV_CORRUPTED(csp) \
24807c478bd9Sstevel@tonic-gate 		((csp)->ch_recv.c_state & IDN_CHANSVC_STATE_CORRUPTED)
24817c478bd9Sstevel@tonic-gate 
24827c478bd9Sstevel@tonic-gate 
24837c478bd9Sstevel@tonic-gate #define	IDN_CHAN_SEND_INPROGRESS(csp)	((csp)->ch_send.c_inprogress++)
24847c478bd9Sstevel@tonic-gate #define	IDN_CHAN_SEND_DONE(csp) \
24857c478bd9Sstevel@tonic-gate 	{ \
24867c478bd9Sstevel@tonic-gate 		ASSERT((csp)->ch_send.c_inprogress > 0); \
24877c478bd9Sstevel@tonic-gate 		if ((--((csp)->ch_send.c_inprogress) == 0) && \
24887c478bd9Sstevel@tonic-gate 					((csp)->ch_send.c_waiters != 0)) \
24897c478bd9Sstevel@tonic-gate 			cv_broadcast(&(csp)->ch_send.c_cv); \
24907c478bd9Sstevel@tonic-gate 	}
24917c478bd9Sstevel@tonic-gate #define	IDN_CHAN_RECV_INPROGRESS(csp)	((csp)->ch_recv.c_inprogress++)
24927c478bd9Sstevel@tonic-gate #define	IDN_CHAN_RECV_DONE(csp) \
24937c478bd9Sstevel@tonic-gate 	{ \
24947c478bd9Sstevel@tonic-gate 		ASSERT((csp)->ch_recv.c_inprogress > 0); \
24957c478bd9Sstevel@tonic-gate 		if ((--((csp)->ch_recv.c_inprogress) == 0) && \
24967c478bd9Sstevel@tonic-gate 					((csp)->ch_recv.c_waiters != 0)) \
24977c478bd9Sstevel@tonic-gate 			cv_broadcast(&(csp)->ch_recv.c_cv); \
24987c478bd9Sstevel@tonic-gate 	}
24997c478bd9Sstevel@tonic-gate 
25007c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_MARK_ATTACHED(csp)	\
25017c478bd9Sstevel@tonic-gate 		((csp)->ch_state = IDN_CHANSVC_STATE_ATTACHED)
25027c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_MARK_DETACHED(csp)	\
25037c478bd9Sstevel@tonic-gate 		((csp)->ch_state = 0)
25047c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_MARK_PENDING(csp)	\
25057c478bd9Sstevel@tonic-gate 		((csp)->ch_state |= IDN_CHANSVC_STATE_ENABLED)
25067c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_MARK_DISABLED(csp)	\
25077c478bd9Sstevel@tonic-gate 		((csp)->ch_state &= ~IDN_CHANSVC_STATE_ENABLED)
25087c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_MARK_ACTIVE(csp)	\
25097c478bd9Sstevel@tonic-gate 		((csp)->ch_state |= IDN_CHANSVC_STATE_ACTIVE)
25107c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_MARK_IDLE(csp)	\
25117c478bd9Sstevel@tonic-gate 		((csp)->ch_state &= ~IDN_CHANSVC_STATE_ACTIVE)
25127c478bd9Sstevel@tonic-gate 
25137c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_MARK_RECV_ACTIVE(csp)	\
25147c478bd9Sstevel@tonic-gate 		((csp)->ch_recv.c_state |= IDN_CHANSVC_STATE_ACTIVE)
25157c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_MARK_RECV_CORRUPTED(csp)	\
25167c478bd9Sstevel@tonic-gate 		((csp)->ch_recv.c_state |= IDN_CHANSVC_STATE_CORRUPTED)
25177c478bd9Sstevel@tonic-gate #define	IDN_CHANSVC_MARK_SEND_ACTIVE(csp)	\
25187c478bd9Sstevel@tonic-gate 		((csp)->ch_send.c_state |= IDN_CHANSVC_STATE_ACTIVE)
25197c478bd9Sstevel@tonic-gate 
25207c478bd9Sstevel@tonic-gate typedef enum {
25217c478bd9Sstevel@tonic-gate 	IDNCHAN_ACTION_DETACH,		/* DETACH (ATTACHED = 0) */
25227c478bd9Sstevel@tonic-gate 	IDNCHAN_ACTION_STOP,		/* DISABLE (ENABLED = 0) */
25237c478bd9Sstevel@tonic-gate 	IDNCHAN_ACTION_SUSPEND,		/* IDLE (ACTIVE = 0) */
25247c478bd9Sstevel@tonic-gate 	IDNCHAN_ACTION_RESUME,
25257c478bd9Sstevel@tonic-gate 	IDNCHAN_ACTION_RESTART,
25267c478bd9Sstevel@tonic-gate 	IDNCHAN_ACTION_ATTACH
25277c478bd9Sstevel@tonic-gate } idn_chanaction_t;
25287c478bd9Sstevel@tonic-gate 
25297c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_SUSPEND(c, w)	\
25307c478bd9Sstevel@tonic-gate 		(idn_chan_action((c), IDNCHAN_ACTION_SUSPEND, (w)))
25317c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_RESUME(c)		\
25327c478bd9Sstevel@tonic-gate 		(idn_chan_action((c), IDNCHAN_ACTION_RESUME, 0))
25337c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_STOP(c, w)	\
25347c478bd9Sstevel@tonic-gate 		(idn_chan_action((c), IDNCHAN_ACTION_STOP, (w)))
25357c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_RESTART(c)		\
25367c478bd9Sstevel@tonic-gate 		(idn_chan_action((c), IDNCHAN_ACTION_RESTART, 0))
25377c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_DETACH(c, w)	\
25387c478bd9Sstevel@tonic-gate 		(idn_chan_action((c), IDNCHAN_ACTION_DETACH, (w)))
25397c478bd9Sstevel@tonic-gate #define	IDN_CHANNEL_ATTACH(c)		\
25407c478bd9Sstevel@tonic-gate 		(idn_chan_action((c), IDNCHAN_ACTION_ATTACH, 0))
25417c478bd9Sstevel@tonic-gate 
25427c478bd9Sstevel@tonic-gate /*
25437c478bd9Sstevel@tonic-gate  * ds_waittime range values.
25447c478bd9Sstevel@tonic-gate  * When a packet arrives the waittime starts at MIN and gradually
25457c478bd9Sstevel@tonic-gate  * shifts up to MAX until another packet arrives.  If still no
25467c478bd9Sstevel@tonic-gate  * packet arrives then we go to a hard sleep
25477c478bd9Sstevel@tonic-gate  */
25487c478bd9Sstevel@tonic-gate #define	IDN_NETSVR_SPIN_COUNT		idn_netsvr_spin_count
25497c478bd9Sstevel@tonic-gate #define	IDN_NETSVR_WAIT_MIN		idn_netsvr_wait_min
25507c478bd9Sstevel@tonic-gate #define	IDN_NETSVR_WAIT_MAX		idn_netsvr_wait_max
25517c478bd9Sstevel@tonic-gate #define	IDN_NETSVR_WAIT_SHIFT		idn_netsvr_wait_shift
25527c478bd9Sstevel@tonic-gate 
25537c478bd9Sstevel@tonic-gate /*
25547c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
25557c478bd9Sstevel@tonic-gate  * IDN Global Data
25567c478bd9Sstevel@tonic-gate  *
25577c478bd9Sstevel@tonic-gate  * The comment to the right of the respective field represents
25587c478bd9Sstevel@tonic-gate  * what lock protects that field.  If there is no comment then
25597c478bd9Sstevel@tonic-gate  * no lock is required to access the field.
25607c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
25617c478bd9Sstevel@tonic-gate  */
25627c478bd9Sstevel@tonic-gate typedef struct idn_global {				/* protected by... */
25637c478bd9Sstevel@tonic-gate 	krwlock_t	grwlock;
25647c478bd9Sstevel@tonic-gate 			/*
25657c478bd9Sstevel@tonic-gate 			 * Global state of IDN w.r.t.
25667c478bd9Sstevel@tonic-gate 			 * the local domain.
25677c478bd9Sstevel@tonic-gate 			 */
25687c478bd9Sstevel@tonic-gate 	idn_gstate_t	state;			/* grwlock */
25697c478bd9Sstevel@tonic-gate 			/*
25707c478bd9Sstevel@tonic-gate 			 * Version of the IDN driver.
25717c478bd9Sstevel@tonic-gate 			 * Is passed in DMV header so that
25727c478bd9Sstevel@tonic-gate 			 * other domains can validate they
25737c478bd9Sstevel@tonic-gate 			 * support protocol used by local
25747c478bd9Sstevel@tonic-gate 			 * domain.
25757c478bd9Sstevel@tonic-gate 			 */
25767c478bd9Sstevel@tonic-gate 	int		version;
25777c478bd9Sstevel@tonic-gate 			/*
25787c478bd9Sstevel@tonic-gate 			 * Set to 1 if SMR region properly
25797c478bd9Sstevel@tonic-gate 			 * allocated and available.
25807c478bd9Sstevel@tonic-gate 			 */
25817c478bd9Sstevel@tonic-gate 	int		enabled;
25827c478bd9Sstevel@tonic-gate 			/*
25837c478bd9Sstevel@tonic-gate 			 * Local domains "domain id".
25847c478bd9Sstevel@tonic-gate 			 */
25857c478bd9Sstevel@tonic-gate 	int		localid;
25867c478bd9Sstevel@tonic-gate 			/*
25877c478bd9Sstevel@tonic-gate 			 * Domain id of the Master domain.
25887c478bd9Sstevel@tonic-gate 			 * Set to IDN_NIL_DOMID if none
25897c478bd9Sstevel@tonic-gate 			 * currently exists.
25907c478bd9Sstevel@tonic-gate 			 */
25917c478bd9Sstevel@tonic-gate 	int		masterid;		/* grwlock */
25927c478bd9Sstevel@tonic-gate 			/*
25937c478bd9Sstevel@tonic-gate 			 * Primarily used during Reconfiguration
25947c478bd9Sstevel@tonic-gate 			 * to track the expected new Master.
25957c478bd9Sstevel@tonic-gate 			 * Once the current IDN is dismantled
25967c478bd9Sstevel@tonic-gate 			 * the local domain will attempt to
25977c478bd9Sstevel@tonic-gate 			 * connect to this new domain.
25987c478bd9Sstevel@tonic-gate 			 */
25997c478bd9Sstevel@tonic-gate 	int		new_masterid;		/* grwlock */
26007c478bd9Sstevel@tonic-gate 			/*
26017c478bd9Sstevel@tonic-gate 			 * Number of protocol servers configured.
26027c478bd9Sstevel@tonic-gate 			 */
26037c478bd9Sstevel@tonic-gate 	int		nservers;
26047c478bd9Sstevel@tonic-gate 
26057c478bd9Sstevel@tonic-gate 	dev_info_t	*dip;
26067c478bd9Sstevel@tonic-gate 
26077c478bd9Sstevel@tonic-gate 	struct {
26087c478bd9Sstevel@tonic-gate 		/*
26097c478bd9Sstevel@tonic-gate 		 * dmv_inum
26107c478bd9Sstevel@tonic-gate 		 *	Interrupt number assigned by
26117c478bd9Sstevel@tonic-gate 		 *	DMV subsystem to IDN's DMV
26127c478bd9Sstevel@tonic-gate 		 *	handler.
26137c478bd9Sstevel@tonic-gate 		 * soft_inum
26147c478bd9Sstevel@tonic-gate 		 *	Soft interrupt number assigned
26157c478bd9Sstevel@tonic-gate 		 *	by OS (add_softintr) for Soft
26167c478bd9Sstevel@tonic-gate 		 *	interrupt dispatched by DMV
26177c478bd9Sstevel@tonic-gate 		 *	handler.
26187c478bd9Sstevel@tonic-gate 		 */
26197c478bd9Sstevel@tonic-gate 		uint_t	dmv_inum;
2620b0fc0e77Sgovinda 		uint64_t soft_inum;
26217c478bd9Sstevel@tonic-gate 		caddr_t	dmv_data;
26227c478bd9Sstevel@tonic-gate 		size_t	dmv_data_len;
26237c478bd9Sstevel@tonic-gate 	} intr;
26247c478bd9Sstevel@tonic-gate 			/*
26257c478bd9Sstevel@tonic-gate 			 * first_swlink
26267c478bd9Sstevel@tonic-gate 			 *	Used as synchronization to
26277c478bd9Sstevel@tonic-gate 			 *	know whether channels need
26287c478bd9Sstevel@tonic-gate 			 *	to be activated or not.
26297c478bd9Sstevel@tonic-gate 			 * first_hwlink
26307c478bd9Sstevel@tonic-gate 			 *	Used as mechanism to determine
26317c478bd9Sstevel@tonic-gate 			 *	whether local domain needs
26327c478bd9Sstevel@tonic-gate 			 *	to publicize its SMR, assuming
26337c478bd9Sstevel@tonic-gate 			 *	it is the Master.
26347c478bd9Sstevel@tonic-gate 			 * first_hwmaster
26357c478bd9Sstevel@tonic-gate 			 *	Domainid of the domain that
26367c478bd9Sstevel@tonic-gate 			 *	was the master at the time
26377c478bd9Sstevel@tonic-gate 			 * 	the hardware was programmed.
26387c478bd9Sstevel@tonic-gate 			 *	We need to keep this so that
26397c478bd9Sstevel@tonic-gate 			 *	we deprogram with respect to
26407c478bd9Sstevel@tonic-gate 			 *	the correct domain that the
26417c478bd9Sstevel@tonic-gate 			 *	hardware was originally
26427c478bd9Sstevel@tonic-gate 			 *	programmed to.
26437c478bd9Sstevel@tonic-gate 			 */
26447c478bd9Sstevel@tonic-gate 	lock_t		first_swlink;
26457c478bd9Sstevel@tonic-gate 	lock_t		first_hwlink;
26467c478bd9Sstevel@tonic-gate 	short		first_hwmasterid;
26477c478bd9Sstevel@tonic-gate 			/*
26487c478bd9Sstevel@tonic-gate 			 * The xmit* fields are used to set-up a background
26497c478bd9Sstevel@tonic-gate 			 * thread to monitor when a channel is ready to be
26507c478bd9Sstevel@tonic-gate 			 * enabled again.  This is necessary since IDN
26517c478bd9Sstevel@tonic-gate 			 * can't rely on hardware to interrupt it when
26527c478bd9Sstevel@tonic-gate 			 * things are ready to go.  We need this ability
26537c478bd9Sstevel@tonic-gate 			 * to wakeup our STREAMS queues.
26547c478bd9Sstevel@tonic-gate 			 * Criteria for reenabling queues.
26557c478bd9Sstevel@tonic-gate 			 *	gstate == IDNGS_ONLINE
26567c478bd9Sstevel@tonic-gate 			 *	channel = !check-in
26577c478bd9Sstevel@tonic-gate 			 *	buffers are available
26587c478bd9Sstevel@tonic-gate 			 *
26597c478bd9Sstevel@tonic-gate 			 * xmit_chanset_wanted
26607c478bd9Sstevel@tonic-gate 			 *	Indicates which channels wish to have
26617c478bd9Sstevel@tonic-gate 			 *	their queues reenabled when ready.
26627c478bd9Sstevel@tonic-gate 			 * xmit_tid
26637c478bd9Sstevel@tonic-gate 			 *	Timeout-id of monitor.
26647c478bd9Sstevel@tonic-gate 			 */
26657c478bd9Sstevel@tonic-gate 	kmutex_t	xmit_lock;
26667c478bd9Sstevel@tonic-gate 	idn_chanset_t	xmit_chanset_wanted;	/* xmit_lock */
26677c478bd9Sstevel@tonic-gate 	timeout_id_t	xmit_tid;		/* xmit_lock */
26687c478bd9Sstevel@tonic-gate 
26697c478bd9Sstevel@tonic-gate 	struct {
26707c478bd9Sstevel@tonic-gate 		/*
26717c478bd9Sstevel@tonic-gate 		 * ready
26727c478bd9Sstevel@tonic-gate 		 *	Indicates SMR region allocated
26737c478bd9Sstevel@tonic-gate 		 *	and available from OBP.
26747c478bd9Sstevel@tonic-gate 		 * vaddr
26757c478bd9Sstevel@tonic-gate 		 *	Virtual address assigned to SMR.
26767c478bd9Sstevel@tonic-gate 		 * locpfn
26777c478bd9Sstevel@tonic-gate 		 *	Page Frame Number associated
26787c478bd9Sstevel@tonic-gate 		 *	with local domain's SMR.
26797c478bd9Sstevel@tonic-gate 		 * rempfn
26807c478bd9Sstevel@tonic-gate 		 *	Page Frame Number associated
26817c478bd9Sstevel@tonic-gate 		 *	with remote (Master) domain's SMR.
26827c478bd9Sstevel@tonic-gate 		 * rempfnlim
26837c478bd9Sstevel@tonic-gate 		 *	PFN past end of remote domain's
26847c478bd9Sstevel@tonic-gate 		 *	SMR.
26857c478bd9Sstevel@tonic-gate 		 * prom_paddr/prom_size
26867c478bd9Sstevel@tonic-gate 		 *	Physical address and size of
26877c478bd9Sstevel@tonic-gate 		 *	SMR that were assigned by OBP.
26887c478bd9Sstevel@tonic-gate 		 */
26897c478bd9Sstevel@tonic-gate 		int		ready;
26907c478bd9Sstevel@tonic-gate 		caddr_t		vaddr;
26917c478bd9Sstevel@tonic-gate 		pfn_t		locpfn;
26927c478bd9Sstevel@tonic-gate 		pfn_t		rempfn;		/* grwlock */
26937c478bd9Sstevel@tonic-gate 
26947c478bd9Sstevel@tonic-gate 		pfn_t		rempfnlim;	/* grwlock */
26957c478bd9Sstevel@tonic-gate 		uint64_t	prom_paddr;
26967c478bd9Sstevel@tonic-gate 
26977c478bd9Sstevel@tonic-gate 		uint64_t	prom_size;
26987c478bd9Sstevel@tonic-gate 	} smr;
26997c478bd9Sstevel@tonic-gate 
27007c478bd9Sstevel@tonic-gate 			/*
27017c478bd9Sstevel@tonic-gate 			 * idnsb_mutex
27027c478bd9Sstevel@tonic-gate 			 *	Protects access to IDN's
27037c478bd9Sstevel@tonic-gate 			 *	sigblock area.
27047c478bd9Sstevel@tonic-gate 			 * idnsb_eventp
27057c478bd9Sstevel@tonic-gate 			 *	IDN's private area in sigblock
27067c478bd9Sstevel@tonic-gate 			 *	used for signaling events
27077c478bd9Sstevel@tonic-gate 			 *	regarding IDN state to SSP.
27087c478bd9Sstevel@tonic-gate 			 * idnsb
27097c478bd9Sstevel@tonic-gate 			 *	Area within IDN's private
27107c478bd9Sstevel@tonic-gate 			 *	sigblock area used for tracking
27117c478bd9Sstevel@tonic-gate 			 *	certain IDN state which might
27127c478bd9Sstevel@tonic-gate 			 *	be useful during arbstop
27137c478bd9Sstevel@tonic-gate 			 *	conditions (if caused by IDN!).
27147c478bd9Sstevel@tonic-gate 			 */
27157c478bd9Sstevel@tonic-gate 	kmutex_t	idnsb_mutex;
27167c478bd9Sstevel@tonic-gate 	idnsb_event_t	*idnsb_eventp;
27177c478bd9Sstevel@tonic-gate 	idnsb_t		*idnsb;
27187c478bd9Sstevel@tonic-gate 
27197c478bd9Sstevel@tonic-gate 	struct sigbintr {
27207c478bd9Sstevel@tonic-gate 		/*
27217c478bd9Sstevel@tonic-gate 		 * sb_mutex
27227c478bd9Sstevel@tonic-gate 		 *	Protects sigbintr elements
27237c478bd9Sstevel@tonic-gate 		 *	to synchronize execution of
27247c478bd9Sstevel@tonic-gate 		 *	sigblock (IDN) mailbox handling.
27257c478bd9Sstevel@tonic-gate 		 * sb_cpuid
27267c478bd9Sstevel@tonic-gate 		 *	Cpu whose sigblock mailbox
27277c478bd9Sstevel@tonic-gate 		 *	originally received IDN request
27287c478bd9Sstevel@tonic-gate 		 *	from SSP.  Necessary to know
27297c478bd9Sstevel@tonic-gate 		 *	where to put response.
27307c478bd9Sstevel@tonic-gate 		 * sb_busy
27317c478bd9Sstevel@tonic-gate 		 *	Flag indicating state of
27327c478bd9Sstevel@tonic-gate 		 *	sigblock handler thread.
27337c478bd9Sstevel@tonic-gate 		 *	Synchronize activity between
27347c478bd9Sstevel@tonic-gate 		 *	SSP and current IDN requests that
27357c478bd9Sstevel@tonic-gate 		 *	are in progress.
27367c478bd9Sstevel@tonic-gate 		 * sb_cv
27377c478bd9Sstevel@tonic-gate 		 *	Condition variable for sigblock
27387c478bd9Sstevel@tonic-gate 		 *	handler thread to wait on.
27397c478bd9Sstevel@tonic-gate 		 * sb_inum
27407c478bd9Sstevel@tonic-gate 		 *	Soft interrupt number assigned
27417c478bd9Sstevel@tonic-gate 		 *	by OS to handle soft interrupt
27427c478bd9Sstevel@tonic-gate 		 *	request make by low-level (IDN)
27437c478bd9Sstevel@tonic-gate 		 *	sigblock handler to dispatch actual
27447c478bd9Sstevel@tonic-gate 		 *	processing of sigblock (mailbox)
27457c478bd9Sstevel@tonic-gate 		 *	request.
27467c478bd9Sstevel@tonic-gate 		 */
27477c478bd9Sstevel@tonic-gate 		kmutex_t	sb_mutex;
27487c478bd9Sstevel@tonic-gate 		uchar_t		sb_cpuid;	/* sigbintr.sb_mutex */
27497c478bd9Sstevel@tonic-gate 		uchar_t		sb_busy;	/* sigbintr.sb_mutex */
27507c478bd9Sstevel@tonic-gate 		kcondvar_t	sb_cv;		/* sigbintr.sb_mutex */
2751b0fc0e77Sgovinda 		uint64_t	sb_inum;	/* sigbintr.sb_mutex */
27527c478bd9Sstevel@tonic-gate 	} sigbintr;
27537c478bd9Sstevel@tonic-gate 
27547c478bd9Sstevel@tonic-gate 			/*
27557c478bd9Sstevel@tonic-gate 			 * struprwlock, strup, sip, siplock
27567c478bd9Sstevel@tonic-gate 			 *	Standard network streams
27577c478bd9Sstevel@tonic-gate 			 *	handling structures to manage
27587c478bd9Sstevel@tonic-gate 			 *	instances of IDN driver.
27597c478bd9Sstevel@tonic-gate 			 */
27607c478bd9Sstevel@tonic-gate 	krwlock_t	struprwlock;
27617c478bd9Sstevel@tonic-gate 	struct idnstr	*strup;			/* struprwlock */
27627c478bd9Sstevel@tonic-gate 
27637c478bd9Sstevel@tonic-gate 	struct idn	*sip;			/* siplock */
27647c478bd9Sstevel@tonic-gate 	kmutex_t	sipwenlock;
27657c478bd9Sstevel@tonic-gate 	kmutex_t	siplock;
27667c478bd9Sstevel@tonic-gate 
27677c478bd9Sstevel@tonic-gate 			/*
27687c478bd9Sstevel@tonic-gate 			 * Area where IDN maintains its kstats.
27697c478bd9Sstevel@tonic-gate 			 */
27707c478bd9Sstevel@tonic-gate 	kstat_t		*ksp;
27717c478bd9Sstevel@tonic-gate 			/*
27727c478bd9Sstevel@tonic-gate 			 * Number of domains that local domain
27737c478bd9Sstevel@tonic-gate 			 * has "open".
27747c478bd9Sstevel@tonic-gate 			 */
27757c478bd9Sstevel@tonic-gate 	int		ndomains;		/* grwlock */
27767c478bd9Sstevel@tonic-gate 			/*
27777c478bd9Sstevel@tonic-gate 			 * Number of domains that local domain
27787c478bd9Sstevel@tonic-gate 			 * has registered as non-responsive.
27797c478bd9Sstevel@tonic-gate 			 */
27807c478bd9Sstevel@tonic-gate 	int		nawols;			/* grwlock */
27817c478bd9Sstevel@tonic-gate 			/*
27827c478bd9Sstevel@tonic-gate 			 * Number of network channels (interfaces)
27837c478bd9Sstevel@tonic-gate 			 * which are currently active.
27847c478bd9Sstevel@tonic-gate 			 */
27857c478bd9Sstevel@tonic-gate 	int		nchannels;		/* grwlock */
27867c478bd9Sstevel@tonic-gate 			/*
27877c478bd9Sstevel@tonic-gate 			 * Bitmask representing channels
27887c478bd9Sstevel@tonic-gate 			 * that are currently active.
27897c478bd9Sstevel@tonic-gate 			 */
27907c478bd9Sstevel@tonic-gate 	idn_chanset_t	chanset;		/* grwlock */
27917c478bd9Sstevel@tonic-gate 			/*
27927c478bd9Sstevel@tonic-gate 			 * Array of channel (network/data) servers
27937c478bd9Sstevel@tonic-gate 			 * that have been created.  Not necessarily
27947c478bd9Sstevel@tonic-gate 			 * all active.
27957c478bd9Sstevel@tonic-gate 			 */
27967c478bd9Sstevel@tonic-gate 	idn_chansvr_t	*chan_servers;		/* elmts = ch_mutex */
27977c478bd9Sstevel@tonic-gate 			/*
27987c478bd9Sstevel@tonic-gate 			 * Pointer to sigblock handler thread
27997c478bd9Sstevel@tonic-gate 			 * which ultimately processes SSP
28007c478bd9Sstevel@tonic-gate 			 * IDN requests.
28017c478bd9Sstevel@tonic-gate 			 */
28027c478bd9Sstevel@tonic-gate 	kthread_id_t	sigb_threadp;
28037c478bd9Sstevel@tonic-gate 			/*
28047c478bd9Sstevel@tonic-gate 			 * Pointer to area used by Master
28057c478bd9Sstevel@tonic-gate 			 * to hold mailbox structures.
28067c478bd9Sstevel@tonic-gate 			 * Actual memory is in SMR.
28077c478bd9Sstevel@tonic-gate 			 */
28087c478bd9Sstevel@tonic-gate 	idn_mboxtbl_t	*mboxarea;		/* grwlock */
28097c478bd9Sstevel@tonic-gate 
28107c478bd9Sstevel@tonic-gate 	struct {
28117c478bd9Sstevel@tonic-gate 		/*
28127c478bd9Sstevel@tonic-gate 		 * IDN_SYNC_LOCK - Provides serialization
28137c478bd9Sstevel@tonic-gate 		 * mechanism when performing synchronous
28147c478bd9Sstevel@tonic-gate 		 * operations across domains.
28157c478bd9Sstevel@tonic-gate 		 */
28167c478bd9Sstevel@tonic-gate 		kmutex_t	sz_mutex;
28177c478bd9Sstevel@tonic-gate 		/*
28187c478bd9Sstevel@tonic-gate 		 * Actual synchronization zones for
28197c478bd9Sstevel@tonic-gate 		 * CONNECT/DISCONNECT phases.
28207c478bd9Sstevel@tonic-gate 		 */
28217c478bd9Sstevel@tonic-gate 		idn_synczone_t	sz_zone[IDN_SYNC_NUMZONE];
28227c478bd9Sstevel@tonic-gate 	} sync;					/* sz_mutex */
28237c478bd9Sstevel@tonic-gate 
28247c478bd9Sstevel@tonic-gate 	struct {
28257c478bd9Sstevel@tonic-gate 		/*
28267c478bd9Sstevel@tonic-gate 		 * ds_trans_on
28277c478bd9Sstevel@tonic-gate 		 *	Set of domains which are trying
28287c478bd9Sstevel@tonic-gate 		 *	to establish a link w/local.
28297c478bd9Sstevel@tonic-gate 		 * ds_ready_on
28307c478bd9Sstevel@tonic-gate 		 *	Set of domains which local knows
28317c478bd9Sstevel@tonic-gate 		 *	are ready for linking, but has
28327c478bd9Sstevel@tonic-gate 		 *	not yet confirmed w/peers.
28337c478bd9Sstevel@tonic-gate 		 * ds_connected
28347c478bd9Sstevel@tonic-gate 		 *	Set of domains that local has
28357c478bd9Sstevel@tonic-gate 		 *	confirmed as being ready.
28367c478bd9Sstevel@tonic-gate 		 * ds_trans_off
28377c478bd9Sstevel@tonic-gate 		 *	Set of domains which are trying
28387c478bd9Sstevel@tonic-gate 		 *	to unlink from local.
28397c478bd9Sstevel@tonic-gate 		 * ds_ready_off
28407c478bd9Sstevel@tonic-gate 		 *	Set of domains which local knows
28417c478bd9Sstevel@tonic-gate 		 *	are ready for unlink, but has
28427c478bd9Sstevel@tonic-gate 		 *	not yet confirmed w/peers.
28437c478bd9Sstevel@tonic-gate 		 * ds_relink
28447c478bd9Sstevel@tonic-gate 		 *	Set of domains we're expecting
28457c478bd9Sstevel@tonic-gate 		 *	to relink with subsequent to
28467c478bd9Sstevel@tonic-gate 		 *	a RECONFIG (new master selection).
28477c478bd9Sstevel@tonic-gate 		 * ds_hwlinked
28487c478bd9Sstevel@tonic-gate 		 *	Set of domains for which local
28497c478bd9Sstevel@tonic-gate 		 *	has programmed its hardware.
28507c478bd9Sstevel@tonic-gate 		 * ds_flush
28517c478bd9Sstevel@tonic-gate 		 *	Set of domains requiring that
28527c478bd9Sstevel@tonic-gate 		 *	local flush its ecache prior
28537c478bd9Sstevel@tonic-gate 		 *	to unlinking.
28547c478bd9Sstevel@tonic-gate 		 * ds_awol
28557c478bd9Sstevel@tonic-gate 		 *	Set of domains believed to be
28567c478bd9Sstevel@tonic-gate 		 *	AWOL - haven't responded to
28577c478bd9Sstevel@tonic-gate 		 *	any queries.
28587c478bd9Sstevel@tonic-gate 		 * ds_hitlist
28597c478bd9Sstevel@tonic-gate 		 *	Set of domains which local domain
28607c478bd9Sstevel@tonic-gate 		 *	is unlinking from and wishes to ignore
28617c478bd9Sstevel@tonic-gate 		 *	any extraneous indirect link requests
28627c478bd9Sstevel@tonic-gate 		 *	from other domains, e.g. during a
28637c478bd9Sstevel@tonic-gate 		 *	Reconfig.
28647c478bd9Sstevel@tonic-gate 		 */
28657c478bd9Sstevel@tonic-gate 		domainset_t	ds_trans_on;	/* sz_mutex */
28667c478bd9Sstevel@tonic-gate 		domainset_t	ds_ready_on;	/* sz_mutex */
28677c478bd9Sstevel@tonic-gate 
28687c478bd9Sstevel@tonic-gate 		domainset_t	ds_connected;	/* sz_mutex */
28697c478bd9Sstevel@tonic-gate 		domainset_t	ds_trans_off;	/* sz_mutex */
28707c478bd9Sstevel@tonic-gate 
28717c478bd9Sstevel@tonic-gate 		domainset_t	ds_ready_off;	/* sz_mutex */
28727c478bd9Sstevel@tonic-gate 		domainset_t	ds_relink;	/* sz_mutex */
28737c478bd9Sstevel@tonic-gate 
28747c478bd9Sstevel@tonic-gate 		domainset_t	ds_hwlinked;	/* sz_mutex */
28757c478bd9Sstevel@tonic-gate 		domainset_t	ds_flush;	/* sz_mutex */
28767c478bd9Sstevel@tonic-gate 
28777c478bd9Sstevel@tonic-gate 		domainset_t	ds_awol;	/* sz_mutex */
28787c478bd9Sstevel@tonic-gate 		domainset_t	ds_hitlist;	/* sz_mutex */
28797c478bd9Sstevel@tonic-gate 	} domset;
28807c478bd9Sstevel@tonic-gate 			/*
28817c478bd9Sstevel@tonic-gate 			 * Bitmask identifying all cpus in
28827c478bd9Sstevel@tonic-gate 			 * the local IDN.
28837c478bd9Sstevel@tonic-gate 			 */
28847c478bd9Sstevel@tonic-gate 	cpuset_t	dc_cpuset;
28857c478bd9Sstevel@tonic-gate 			/*
28867c478bd9Sstevel@tonic-gate 			 * Bitmask identifying all boards in
28877c478bd9Sstevel@tonic-gate 			 * the local IDN.
28887c478bd9Sstevel@tonic-gate 			 */
28897c478bd9Sstevel@tonic-gate 	boardset_t	dc_boardset;
28907c478bd9Sstevel@tonic-gate 
28917c478bd9Sstevel@tonic-gate 	struct dopers {
28927c478bd9Sstevel@tonic-gate 		/*
28937c478bd9Sstevel@tonic-gate 		 * Waiting area for IDN requests,
28947c478bd9Sstevel@tonic-gate 		 * i.e. link & unlinks.  IDN requests
28957c478bd9Sstevel@tonic-gate 		 * are performed asynchronously so
28967c478bd9Sstevel@tonic-gate 		 * we need a place to wait until the
28977c478bd9Sstevel@tonic-gate 		 * operation has completed.
28987c478bd9Sstevel@tonic-gate 		 *
28997c478bd9Sstevel@tonic-gate 		 * dop_domset
29007c478bd9Sstevel@tonic-gate 		 *	Identifies which domains the
29017c478bd9Sstevel@tonic-gate 		 *	current waiter is interested in.
29027c478bd9Sstevel@tonic-gate 		 * dop_waitcount
29037c478bd9Sstevel@tonic-gate 		 *	Number of waiters in the room.
29047c478bd9Sstevel@tonic-gate 		 * dop_waitlist
29057c478bd9Sstevel@tonic-gate 		 *	Actual waiting area.
29067c478bd9Sstevel@tonic-gate 		 * dop_freelist
29077c478bd9Sstevel@tonic-gate 		 *	Freelist (small cache) of
29087c478bd9Sstevel@tonic-gate 		 *	structs for waiting area.
29097c478bd9Sstevel@tonic-gate 		 */
29107c478bd9Sstevel@tonic-gate 		kmutex_t	dop_mutex;
29117c478bd9Sstevel@tonic-gate 		kcondvar_t	dop_cv;		/* dop_mutex */
29127c478bd9Sstevel@tonic-gate 		domainset_t	dop_domset;	/* dop_mutex */
29137c478bd9Sstevel@tonic-gate 		int		dop_waitcount;	/* dop_mutex */
29147c478bd9Sstevel@tonic-gate 		dop_waitlist_t	*dop_waitlist;	/* dop_mutex */
29157c478bd9Sstevel@tonic-gate 		dop_waitlist_t	*dop_freelist;	/* dop_mutex */
29167c478bd9Sstevel@tonic-gate 							/* dop_mutex */
29177c478bd9Sstevel@tonic-gate 		dop_waitlist_t	_dop_wcache[IDNOP_CACHE_SIZE];
29187c478bd9Sstevel@tonic-gate 	} *dopers;
29197c478bd9Sstevel@tonic-gate 
29207c478bd9Sstevel@tonic-gate 	struct {
29217c478bd9Sstevel@tonic-gate 		/*
29227c478bd9Sstevel@tonic-gate 		 * Protocol Server:
29237c478bd9Sstevel@tonic-gate 		 *
29247c478bd9Sstevel@tonic-gate 		 * p_server
29257c478bd9Sstevel@tonic-gate 		 *	Linked list of queues
29267c478bd9Sstevel@tonic-gate 		 *	describing protocol
29277c478bd9Sstevel@tonic-gate 		 *	servers in use.
29287c478bd9Sstevel@tonic-gate 		 * p_jobpool
29297c478bd9Sstevel@tonic-gate 		 *	Kmem cache of structs
29307c478bd9Sstevel@tonic-gate 		 *	used to enqueue protocol
29317c478bd9Sstevel@tonic-gate 		 *	jobs for protocol servers.
29327c478bd9Sstevel@tonic-gate 		 * p_morgue
29337c478bd9Sstevel@tonic-gate 		 *	Synchronization (check-in)
29347c478bd9Sstevel@tonic-gate 		 *	area used when terminating
29357c478bd9Sstevel@tonic-gate 		 *	protocol servers (threads).
29367c478bd9Sstevel@tonic-gate 		 */
29377c478bd9Sstevel@tonic-gate 		struct idn_protoqueue	*p_serverq;
29387c478bd9Sstevel@tonic-gate 		kmem_cache_t		*p_jobpool;
29397c478bd9Sstevel@tonic-gate 		ksema_t			p_morgue;
29407c478bd9Sstevel@tonic-gate 	} protocol;
29417c478bd9Sstevel@tonic-gate 
29427c478bd9Sstevel@tonic-gate 	struct idn_retry_queue {
29437c478bd9Sstevel@tonic-gate 		/*
29447c478bd9Sstevel@tonic-gate 		 * rq_jobs
29457c478bd9Sstevel@tonic-gate 		 *	Queue of Retry jobs
29467c478bd9Sstevel@tonic-gate 		 *	that are outstanding.
29477c478bd9Sstevel@tonic-gate 		 * rq_count
29487c478bd9Sstevel@tonic-gate 		 *	Number of jobs on retry
29497c478bd9Sstevel@tonic-gate 		 *	queue.
29507c478bd9Sstevel@tonic-gate 		 * rq_cache
29517c478bd9Sstevel@tonic-gate 		 *	Kmem cache for structs
29527c478bd9Sstevel@tonic-gate 		 *	used to describe retry
29537c478bd9Sstevel@tonic-gate 		 *	jobs.
29547c478bd9Sstevel@tonic-gate 		 */
29557c478bd9Sstevel@tonic-gate 		idn_retry_job_t	*rq_jobs;	/* rq_mutex */
29567c478bd9Sstevel@tonic-gate 		int		rq_count;	/* rq_mutex */
29577c478bd9Sstevel@tonic-gate 		kmutex_t	rq_mutex;	/* rq_mutex */
29587c478bd9Sstevel@tonic-gate 
29597c478bd9Sstevel@tonic-gate 		kcondvar_t	rq_cv;		/* rq_mutex */
29607c478bd9Sstevel@tonic-gate 		kmem_cache_t	*rq_cache;
29617c478bd9Sstevel@tonic-gate 	} retryqueue;
29627c478bd9Sstevel@tonic-gate 
29637c478bd9Sstevel@tonic-gate 	struct slabpool {
29647c478bd9Sstevel@tonic-gate 		/*
29657c478bd9Sstevel@tonic-gate 		 * Slabpool:
29667c478bd9Sstevel@tonic-gate 		 *
29677c478bd9Sstevel@tonic-gate 		 * ntotslabs
29687c478bd9Sstevel@tonic-gate 		 *	Total number of slabs
29697c478bd9Sstevel@tonic-gate 		 *	in SMR (free & in-use).
29707c478bd9Sstevel@tonic-gate 		 * npools
29717c478bd9Sstevel@tonic-gate 		 *	Number of pools available
29727c478bd9Sstevel@tonic-gate 		 *	in list.  One smr_slabtbl
29737c478bd9Sstevel@tonic-gate 		 *	exists for each pool.
29747c478bd9Sstevel@tonic-gate 		 */
29757c478bd9Sstevel@tonic-gate 		int		ntotslabs;
29767c478bd9Sstevel@tonic-gate 		int		npools;
29777c478bd9Sstevel@tonic-gate 		struct smr_slabtbl {
29787c478bd9Sstevel@tonic-gate 			/*
29797c478bd9Sstevel@tonic-gate 			 * sarray
29807c478bd9Sstevel@tonic-gate 			 *	Array of slab structs
29817c478bd9Sstevel@tonic-gate 			 *	representing slabs in SMR.
29827c478bd9Sstevel@tonic-gate 			 * nfree
29837c478bd9Sstevel@tonic-gate 			 *	Number of slabs actually
29847c478bd9Sstevel@tonic-gate 			 *	available in sarray.
29857c478bd9Sstevel@tonic-gate 			 * nslabs
29867c478bd9Sstevel@tonic-gate 			 *	Number of slabs represented
29877c478bd9Sstevel@tonic-gate 			 *	in sarray (free & in-use).
29887c478bd9Sstevel@tonic-gate 			 */
29897c478bd9Sstevel@tonic-gate 			smr_slab_t	*sarray;
29907c478bd9Sstevel@tonic-gate 			int		nfree;
29917c478bd9Sstevel@tonic-gate 			int		nslabs;
29927c478bd9Sstevel@tonic-gate 		} *pool;
29937c478bd9Sstevel@tonic-gate 		/*
29947c478bd9Sstevel@tonic-gate 		 * Holds array of smr_slab_t structs kmem_alloc'd
29957c478bd9Sstevel@tonic-gate 		 * for slabpool.
29967c478bd9Sstevel@tonic-gate 		 */
29977c478bd9Sstevel@tonic-gate 		smr_slab_t	*savep;
29987c478bd9Sstevel@tonic-gate 	} *slabpool;
29997c478bd9Sstevel@tonic-gate 
30007c478bd9Sstevel@tonic-gate 	struct slabwaiter {
30017c478bd9Sstevel@tonic-gate 		/*
30027c478bd9Sstevel@tonic-gate 		 * Waiting area for threads
30037c478bd9Sstevel@tonic-gate 		 * requesting slab allocations.
30047c478bd9Sstevel@tonic-gate 		 * Used by Slaves for all requests,
30057c478bd9Sstevel@tonic-gate 		 * but used by Master only for
30067c478bd9Sstevel@tonic-gate 		 * redundant requests, i.e. multiple
30077c478bd9Sstevel@tonic-gate 		 * requests on behalf of the same
30087c478bd9Sstevel@tonic-gate 		 * domain.  One slabwaiter area
30097c478bd9Sstevel@tonic-gate 		 * exist for each possible domain.
30107c478bd9Sstevel@tonic-gate 		 *
30117c478bd9Sstevel@tonic-gate 		 * w_nwaiters
30127c478bd9Sstevel@tonic-gate 		 *	Number of threads waiting
30137c478bd9Sstevel@tonic-gate 		 *	in waiting area.
30147c478bd9Sstevel@tonic-gate 		 * w_done
30157c478bd9Sstevel@tonic-gate 		 *	Flag to indicate that
30167c478bd9Sstevel@tonic-gate 		 *	allocation request has
30177c478bd9Sstevel@tonic-gate 		 *	completed.
30187c478bd9Sstevel@tonic-gate 		 * w_serrno
30197c478bd9Sstevel@tonic-gate 		 *	Non-zero indicates an
30207c478bd9Sstevel@tonic-gate 		 *	errno value to represent
30217c478bd9Sstevel@tonic-gate 		 *	error that occurred during
30227c478bd9Sstevel@tonic-gate 		 *	attempt to allocate slab.
30237c478bd9Sstevel@tonic-gate 		 * w_closed
30247c478bd9Sstevel@tonic-gate 		 *	Indicates that waiting area is
30257c478bd9Sstevel@tonic-gate 		 *	closed and won't allow any new
30267c478bd9Sstevel@tonic-gate 		 *	waiters.  This occurs during
30277c478bd9Sstevel@tonic-gate 		 *	the small window where we're
30287c478bd9Sstevel@tonic-gate 		 *	trying to suspend a channel.
30297c478bd9Sstevel@tonic-gate 		 * w_cv
30307c478bd9Sstevel@tonic-gate 		 *	Condvar for waiting on.
30317c478bd9Sstevel@tonic-gate 		 * w_sp
30327c478bd9Sstevel@tonic-gate 		 *	Holds slab structure of
30337c478bd9Sstevel@tonic-gate 		 *	successfully allocated slab.
30347c478bd9Sstevel@tonic-gate 		 */
30357c478bd9Sstevel@tonic-gate 		kmutex_t	w_mutex;
30367c478bd9Sstevel@tonic-gate 		short		w_nwaiters;	/* w_mutex */
30377c478bd9Sstevel@tonic-gate 		short		w_done;		/* w_mutex */
30387c478bd9Sstevel@tonic-gate 		short		w_serrno;	/* w_mutex */
30397c478bd9Sstevel@tonic-gate 		short		w_closed;	/* w_mutex */
30407c478bd9Sstevel@tonic-gate 		kcondvar_t	w_cv;		/* w_mutex */
30417c478bd9Sstevel@tonic-gate 		smr_slab_t	*w_sp;		/* w_mutex */
30427c478bd9Sstevel@tonic-gate 	} *slabwaiter;
30437c478bd9Sstevel@tonic-gate 			/*
30447c478bd9Sstevel@tonic-gate 			 * Kmem cache used for allocating
30457c478bd9Sstevel@tonic-gate 			 * timer structures for outstanding
30467c478bd9Sstevel@tonic-gate 			 * IDN requests.
30477c478bd9Sstevel@tonic-gate 			 */
30487c478bd9Sstevel@tonic-gate 	kmem_cache_t	*timer_cache;
30497c478bd9Sstevel@tonic-gate 			/*
30507c478bd9Sstevel@tonic-gate 			 * Effectively constant used in
30517c478bd9Sstevel@tonic-gate 			 * translating buffer frames in
30527c478bd9Sstevel@tonic-gate 			 * mailbox message frames to
30537c478bd9Sstevel@tonic-gate 			 * offsets within SMR.
30547c478bd9Sstevel@tonic-gate 			 */
30557c478bd9Sstevel@tonic-gate 	int		bframe_shift;
30567c478bd9Sstevel@tonic-gate } idn_global_t;
30577c478bd9Sstevel@tonic-gate 
30587c478bd9Sstevel@tonic-gate typedef struct idn_retry_queue	idn_retry_queue_t;
30597c478bd9Sstevel@tonic-gate 
30607c478bd9Sstevel@tonic-gate #define	IDN_GET_MASTERID()	(idn.masterid)
30617c478bd9Sstevel@tonic-gate #define	IDN_SET_MASTERID(mid) \
30627c478bd9Sstevel@tonic-gate 	{ \
30637c478bd9Sstevel@tonic-gate 		int	_mid = (mid); \
30647c478bd9Sstevel@tonic-gate 		mutex_enter(&idn.idnsb_mutex); \
30657c478bd9Sstevel@tonic-gate 		if (idn.idnsb) { \
30667c478bd9Sstevel@tonic-gate 			idn.idnsb->id_pmaster_board = \
30677c478bd9Sstevel@tonic-gate 					idn.idnsb->id_master_board; \
30687c478bd9Sstevel@tonic-gate 			if (_mid == IDN_NIL_DOMID) \
30697c478bd9Sstevel@tonic-gate 				idn.idnsb->id_master_board = (uchar_t)0xff; \
30707c478bd9Sstevel@tonic-gate 			else \
30717c478bd9Sstevel@tonic-gate 				idn.idnsb->id_master_board = \
30727c478bd9Sstevel@tonic-gate 				(uchar_t)idn_domain[_mid].dvote.v.board; \
30737c478bd9Sstevel@tonic-gate 		} \
30747c478bd9Sstevel@tonic-gate 		mutex_exit(&idn.idnsb_mutex); \
30757c478bd9Sstevel@tonic-gate 		IDN_HISTORY_LOG(IDNH_MASTERID, _mid, idn.masterid, 0); \
30767c478bd9Sstevel@tonic-gate 		PR_STATE("%d: MASTERID %d -> %d\n", __LINE__, \
30777c478bd9Sstevel@tonic-gate 			idn.masterid, _mid); \
30787c478bd9Sstevel@tonic-gate 		idn.masterid = _mid; \
30797c478bd9Sstevel@tonic-gate 	}
30807c478bd9Sstevel@tonic-gate #define	IDN_GET_NEW_MASTERID()	(idn.new_masterid)
30817c478bd9Sstevel@tonic-gate #define	IDN_SET_NEW_MASTERID(mid) \
30827c478bd9Sstevel@tonic-gate 	{ \
30837c478bd9Sstevel@tonic-gate 		PR_STATE("%d: NEW MASTERID %d -> %d\n", __LINE__, \
30847c478bd9Sstevel@tonic-gate 			idn.new_masterid, (mid)); \
30857c478bd9Sstevel@tonic-gate 		idn.new_masterid = (mid); \
30867c478bd9Sstevel@tonic-gate 	}
30877c478bd9Sstevel@tonic-gate 
30887c478bd9Sstevel@tonic-gate #define	IDN_GLOCK_EXCL()	(rw_enter(&idn.grwlock, RW_WRITER))
30897c478bd9Sstevel@tonic-gate #define	IDN_GLOCK_SHARED()	(rw_enter(&idn.grwlock, RW_READER))
30907c478bd9Sstevel@tonic-gate #define	IDN_GLOCK_TRY_SHARED()	(rw_tryenter(&idn.grwlock, RW_READER))
30917c478bd9Sstevel@tonic-gate #define	IDN_GLOCK_DOWNGRADE()	(rw_downgrade(&idn.grwlock))
30927c478bd9Sstevel@tonic-gate #define	IDN_GUNLOCK()		(rw_exit(&idn.grwlock))
30937c478bd9Sstevel@tonic-gate #define	IDN_GLOCK_IS_EXCL()	(RW_WRITE_HELD(&idn.grwlock))
30947c478bd9Sstevel@tonic-gate #define	IDN_GLOCK_IS_SHARED()	(RW_READ_HELD(&idn.grwlock))
30957c478bd9Sstevel@tonic-gate #define	IDN_GLOCK_IS_HELD()	(RW_LOCK_HELD(&idn.grwlock))
30967c478bd9Sstevel@tonic-gate 
30977c478bd9Sstevel@tonic-gate #define	IDN_SYNC_LOCK()		(mutex_enter(&idn.sync.sz_mutex))
30987c478bd9Sstevel@tonic-gate #define	IDN_SYNC_TRYLOCK()	(mutex_tryenter(&idn.sync.sz_mutex))
30997c478bd9Sstevel@tonic-gate #define	IDN_SYNC_UNLOCK()	(mutex_exit(&idn.sync.sz_mutex))
31007c478bd9Sstevel@tonic-gate #define	IDN_SYNC_IS_LOCKED()	(MUTEX_HELD(&idn.sync.sz_mutex))
31017c478bd9Sstevel@tonic-gate 
31027c478bd9Sstevel@tonic-gate /*
31037c478bd9Sstevel@tonic-gate  * Macro to reset some globals necessary in preparing
31047c478bd9Sstevel@tonic-gate  * for initialization of HW for IDN.
31057c478bd9Sstevel@tonic-gate  */
31067c478bd9Sstevel@tonic-gate #define	IDN_PREP_HWINIT() \
31077c478bd9Sstevel@tonic-gate 	{ \
31087c478bd9Sstevel@tonic-gate 		ASSERT(IDN_GLOCK_IS_EXCL()); \
31097c478bd9Sstevel@tonic-gate 		lock_clear(&idn.first_swlink); \
31107c478bd9Sstevel@tonic-gate 		lock_clear(&idn.first_hwlink); \
31117c478bd9Sstevel@tonic-gate 		idn.first_hwmasterid = (short)IDN_NIL_DOMID; \
31127c478bd9Sstevel@tonic-gate 	}
31137c478bd9Sstevel@tonic-gate 
31147c478bd9Sstevel@tonic-gate /*
31157c478bd9Sstevel@tonic-gate  * Return values of idn_send_data.
31167c478bd9Sstevel@tonic-gate  */
31177c478bd9Sstevel@tonic-gate #define	IDNXMIT_OKAY	0	/* xmit successful */
31187c478bd9Sstevel@tonic-gate #define	IDNXMIT_LOOP	1	/* loopback */
31197c478bd9Sstevel@tonic-gate #define	IDNXMIT_DROP	2	/* drop packet */
31207c478bd9Sstevel@tonic-gate #define	IDNXMIT_RETRY	3	/* retry packet (requeue and qenable) */
31217c478bd9Sstevel@tonic-gate #define	IDNXMIT_REQUEUE	4	/* requeue packet, but don't qenable */
31227c478bd9Sstevel@tonic-gate 
31237c478bd9Sstevel@tonic-gate /*
31247c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
31257c478bd9Sstevel@tonic-gate  * ss_rwlock must be acquired _before_ any idn_domain locks are
31267c478bd9Sstevel@tonic-gate  * acquired if both structs need to be accessed.
31277c478bd9Sstevel@tonic-gate  * idn.struprwlock is acquired when traversing IDN's strup list
31287c478bd9Sstevel@tonic-gate  * and when adding or deleting entries.
31297c478bd9Sstevel@tonic-gate  *
31307c478bd9Sstevel@tonic-gate  * ss_nextp	Linked list of streams.
31317c478bd9Sstevel@tonic-gate  * ss_rq	Respective read queue.
31327c478bd9Sstevel@tonic-gate  * ss_sip	Attached device.
31337c478bd9Sstevel@tonic-gate  * ss_state	Current DL state.
31347c478bd9Sstevel@tonic-gate  * ss_sap	Bound SAP.
31357c478bd9Sstevel@tonic-gate  * ss_flags	Misc. flags.
31367c478bd9Sstevel@tonic-gate  * ss_mccount	# enabled multicast addrs.
31377c478bd9Sstevel@tonic-gate  * ss_mctab	Table of multicast addrs.
31387c478bd9Sstevel@tonic-gate  * ss_minor	Minor device number.
31397c478bd9Sstevel@tonic-gate  * ss_rwlock	Protects ss_linkup fields and DLPI state machine.
31407c478bd9Sstevel@tonic-gate  * ss_linkup	Boolean flag indicating whether particular (domain) link
31417c478bd9Sstevel@tonic-gate  *		is up.
31427c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
31437c478bd9Sstevel@tonic-gate  */
31447c478bd9Sstevel@tonic-gate struct idnstr {				/* gets shoved into q_ptr */
31457c478bd9Sstevel@tonic-gate 	struct idnstr	*ss_nextp;
31467c478bd9Sstevel@tonic-gate 	queue_t		*ss_rq;
31477c478bd9Sstevel@tonic-gate 	struct idn	*ss_sip;
31487c478bd9Sstevel@tonic-gate 	t_uscalar_t	ss_state;
31497c478bd9Sstevel@tonic-gate 	t_uscalar_t	ss_sap;
31507c478bd9Sstevel@tonic-gate 	uint_t		ss_flags;
31517c478bd9Sstevel@tonic-gate 	uint_t		ss_mccount;
31527c478bd9Sstevel@tonic-gate 	struct ether_addr	*ss_mctab;
31537c478bd9Sstevel@tonic-gate 	minor_t		ss_minor;
31547c478bd9Sstevel@tonic-gate 	krwlock_t	ss_rwlock;
31557c478bd9Sstevel@tonic-gate };
31567c478bd9Sstevel@tonic-gate 
31577c478bd9Sstevel@tonic-gate /*
31587c478bd9Sstevel@tonic-gate  * idnstr.ss_flags - Per-stream flags
31597c478bd9Sstevel@tonic-gate  */
31607c478bd9Sstevel@tonic-gate #define	IDNSFAST	0x01		/* "M_DATA fastpath" mode */
31617c478bd9Sstevel@tonic-gate #define	IDNSRAW		0x02		/* M_DATA plain raw mode */
31627c478bd9Sstevel@tonic-gate #define	IDNSALLPHYS	0x04		/* "promiscuous mode" */
31637c478bd9Sstevel@tonic-gate #define	IDNSALLMULTI	0x08		/* enable all multicast addresses */
31647c478bd9Sstevel@tonic-gate #define	IDNSALLSAP	0x10		/* enable all ether type values */
31657c478bd9Sstevel@tonic-gate 
31667c478bd9Sstevel@tonic-gate /*
31677c478bd9Sstevel@tonic-gate  * Maximum number of multicast address per stream.
31687c478bd9Sstevel@tonic-gate  */
31697c478bd9Sstevel@tonic-gate #define	IDNMAXMC	64
31707c478bd9Sstevel@tonic-gate #define	IDNMCALLOC	(IDNMAXMC * sizeof (struct ether_addr))
31717c478bd9Sstevel@tonic-gate 
31727c478bd9Sstevel@tonic-gate /*
31737c478bd9Sstevel@tonic-gate  * Full DLSAP address length (in struct dladdr format).
31747c478bd9Sstevel@tonic-gate  */
31757c478bd9Sstevel@tonic-gate #define	IDNADDRL	(ETHERADDRL + sizeof (ushort_t))
31767c478bd9Sstevel@tonic-gate 
31777c478bd9Sstevel@tonic-gate struct idndladdr {
31787c478bd9Sstevel@tonic-gate 	struct ether_addr	dl_phys;
31797c478bd9Sstevel@tonic-gate 	ushort_t		dl_sap;
31807c478bd9Sstevel@tonic-gate };
31817c478bd9Sstevel@tonic-gate 
31827c478bd9Sstevel@tonic-gate #define	IDNHEADROOM		64
31837c478bd9Sstevel@tonic-gate #define	IDNROUNDUP(a, n)	(((a) + ((n) - 1)) & ~((n) - 1))
31847c478bd9Sstevel@tonic-gate 
31857c478bd9Sstevel@tonic-gate /*
31867c478bd9Sstevel@tonic-gate  * Respective interpretation of bytes in 6 byte ethernet address.
31877c478bd9Sstevel@tonic-gate  */
31887c478bd9Sstevel@tonic-gate #define	IDNETHER_ZERO		0
31897c478bd9Sstevel@tonic-gate #define	IDNETHER_COOKIE1	1
31907c478bd9Sstevel@tonic-gate #define	  IDNETHER_COOKIE1_VAL		0xe5
31917c478bd9Sstevel@tonic-gate #define	IDNETHER_COOKIE2	2
31927c478bd9Sstevel@tonic-gate #define	  IDNETHER_COOKIE2_VAL		0x82
31937c478bd9Sstevel@tonic-gate #define	IDNETHER_NETID		3
31947c478bd9Sstevel@tonic-gate #define	IDNETHER_CHANNEL	4
31957c478bd9Sstevel@tonic-gate #define	IDNETHER_RESERVED	5
31967c478bd9Sstevel@tonic-gate #define	  IDNETHER_RESERVED_VAL		0x64
31977c478bd9Sstevel@tonic-gate 
31987c478bd9Sstevel@tonic-gate /*
31997c478bd9Sstevel@tonic-gate  * IDN driver supports multliple instances, however they
32007c478bd9Sstevel@tonic-gate  * still all refer to the same "physical" device.  Multiple
32017c478bd9Sstevel@tonic-gate  * instances are supported primarily to allow increased
32027c478bd9Sstevel@tonic-gate  * STREAMs bandwidth since each instance has it's own IP queue.
32037c478bd9Sstevel@tonic-gate  * This structure is primarily defined to be consistent with
32047c478bd9Sstevel@tonic-gate  * other network drivers and also to hold the kernel stats.
32057c478bd9Sstevel@tonic-gate  */
32067c478bd9Sstevel@tonic-gate struct idn_kstat {
32077c478bd9Sstevel@tonic-gate 	ulong_t		si_ipackets;	/* # packets received */
32087c478bd9Sstevel@tonic-gate 	ulong_t		si_ierrors;	/* # total input errors */
32097c478bd9Sstevel@tonic-gate 	ulong_t		si_opackets;	/* # packets sent */
32107c478bd9Sstevel@tonic-gate 	ulong_t		si_oerrors;	/* # total output errors */
32117c478bd9Sstevel@tonic-gate 
32127c478bd9Sstevel@tonic-gate 	ulong_t		si_txcoll;	/* # xmit collisions */
32137c478bd9Sstevel@tonic-gate 	ulong_t		si_rxcoll;	/* # recv collisions */
32147c478bd9Sstevel@tonic-gate 	ulong_t		si_crc;		/* # recv crc errors */
32157c478bd9Sstevel@tonic-gate 	ulong_t		si_buff;	/* # recv pkt sz > buf sz */
32167c478bd9Sstevel@tonic-gate 
32177c478bd9Sstevel@tonic-gate 	ulong_t		si_nolink;	/* # loss of connection */
32187c478bd9Sstevel@tonic-gate 	ulong_t		si_linkdown;	/* # link is down */
32197c478bd9Sstevel@tonic-gate 	ulong_t		si_inits;	/* # driver inits */
32207c478bd9Sstevel@tonic-gate 	ulong_t		si_nocanput;	/* # canput() failures */
32217c478bd9Sstevel@tonic-gate 
32227c478bd9Sstevel@tonic-gate 	ulong_t		si_allocbfail;	/* # allocb() failures */
32237c478bd9Sstevel@tonic-gate 	ulong_t		si_notbufs;	/* # out of xmit buffers */
32247c478bd9Sstevel@tonic-gate 	ulong_t		si_reclaim;	/* # reclaim failures */
32257c478bd9Sstevel@tonic-gate 	ulong_t		si_smraddr;	/* # bad SMR addrs */
32267c478bd9Sstevel@tonic-gate 
32277c478bd9Sstevel@tonic-gate 	ulong_t		si_txmax;	/* # xmit over limit */
32287c478bd9Sstevel@tonic-gate 	ulong_t		si_txfull;	/* # xmit mbox full */
32297c478bd9Sstevel@tonic-gate 	ulong_t		si_xdcall;	/* # xdcalls sent */
32307c478bd9Sstevel@tonic-gate 	ulong_t		si_sigsvr;	/* # data server wakeups */
32317c478bd9Sstevel@tonic-gate 
32327c478bd9Sstevel@tonic-gate 	ulong_t		si_mboxcrc;	/* # send mbox crc errors */
32337c478bd9Sstevel@tonic-gate 	/*
32347c478bd9Sstevel@tonic-gate 	 * MIB II kstat variables
32357c478bd9Sstevel@tonic-gate 	 */
32367c478bd9Sstevel@tonic-gate 	ulong_t		si_rcvbytes;	/* # bytes received */
32377c478bd9Sstevel@tonic-gate 	ulong_t		si_xmtbytes;	/* # bytes transmitted */
32387c478bd9Sstevel@tonic-gate 	ulong_t		si_multircv;	/* # multicast packets received */
32397c478bd9Sstevel@tonic-gate 
32407c478bd9Sstevel@tonic-gate 	ulong_t		si_multixmt;	/* # multicast packets for xmit */
32417c478bd9Sstevel@tonic-gate 	ulong_t		si_brdcstrcv;	/* # broadcast packets received */
32427c478bd9Sstevel@tonic-gate 	ulong_t		si_brdcstxmt;	/* # broadcast packets for xmit */
32437c478bd9Sstevel@tonic-gate 	ulong_t		si_norcvbuf;	/* # rcv packets discarded */
32447c478bd9Sstevel@tonic-gate 
32457c478bd9Sstevel@tonic-gate 	ulong_t		si_noxmtbuf;	/* # xmit packets discarded */
32467c478bd9Sstevel@tonic-gate 	/*
32477c478bd9Sstevel@tonic-gate 	 * PSARC 1997/198 : 64 bit kstats
32487c478bd9Sstevel@tonic-gate 	 */
32497c478bd9Sstevel@tonic-gate 	uint64_t	si_ipackets64;	/* # packets received */
32507c478bd9Sstevel@tonic-gate 	uint64_t	si_opackets64;	/* # packets transmitted */
32517c478bd9Sstevel@tonic-gate 	uint64_t	si_rbytes64;	/* # bytes received */
32527c478bd9Sstevel@tonic-gate 	uint64_t	si_obytes64;	/* # bytes transmitted */
32537c478bd9Sstevel@tonic-gate 	/*
32547c478bd9Sstevel@tonic-gate 	 * PSARC 1997/247 : RFC 1643	dot3Stats...
32557c478bd9Sstevel@tonic-gate 	 */
32567c478bd9Sstevel@tonic-gate 	ulong_t	si_fcs_errors;		/* FCSErrors */
32577c478bd9Sstevel@tonic-gate 	ulong_t	si_macxmt_errors;	/* InternalMacTransmitErrors */
32587c478bd9Sstevel@tonic-gate 	ulong_t	si_toolong_errors;	/* FrameTooLongs */
32597c478bd9Sstevel@tonic-gate 	ulong_t	si_macrcv_errors;	/* InternalMacReceiveErrors */
32607c478bd9Sstevel@tonic-gate };
32617c478bd9Sstevel@tonic-gate 
32627c478bd9Sstevel@tonic-gate /*
32637c478bd9Sstevel@tonic-gate  * Per logical interface private data structure.
32647c478bd9Sstevel@tonic-gate  */
32657c478bd9Sstevel@tonic-gate struct idn {
32667c478bd9Sstevel@tonic-gate 	struct idn		*si_nextp;	/* linked instances */
32677c478bd9Sstevel@tonic-gate 	dev_info_t		*si_dip;	/* assoc. dev_info */
32687c478bd9Sstevel@tonic-gate 	struct ether_addr	si_ouraddr;	/* enet address */
32697c478bd9Sstevel@tonic-gate 
32707c478bd9Sstevel@tonic-gate 	uint_t			si_flags;	/* misc. flags */
32717c478bd9Sstevel@tonic-gate 	uint_t			si_wantw;	/* xmit: out of res. */
32727c478bd9Sstevel@tonic-gate 	queue_t			*si_ip4q;	/* ip (v4) read queue */
32737c478bd9Sstevel@tonic-gate 	queue_t			*si_ip6q;	/* ip (v6) read queue */
32747c478bd9Sstevel@tonic-gate 
32757c478bd9Sstevel@tonic-gate 	kstat_t			*si_ksp;	/* kstat pointer */
32767c478bd9Sstevel@tonic-gate 	struct idn_kstat	si_kstat;	/* per-inst kstat */
32777c478bd9Sstevel@tonic-gate };
32787c478bd9Sstevel@tonic-gate 
32797c478bd9Sstevel@tonic-gate struct idn_gkstat {
32807c478bd9Sstevel@tonic-gate 	ulong_t		gk_reconfigs;		/* # reconfigs */
32817c478bd9Sstevel@tonic-gate 	ulong_t		gk_reconfig_last;	/* timestamep */
32827c478bd9Sstevel@tonic-gate 	ulong_t		gk_reaps;		/* # of reap request */
32837c478bd9Sstevel@tonic-gate 	ulong_t		gk_reap_last;		/* timestamep */
32847c478bd9Sstevel@tonic-gate 
32857c478bd9Sstevel@tonic-gate 	ulong_t		gk_links;		/* # of IDN links */
32867c478bd9Sstevel@tonic-gate 	ulong_t		gk_link_last;		/* timestamep */
32877c478bd9Sstevel@tonic-gate 	ulong_t		gk_unlinks;		/* # of IDN unlinks */
32887c478bd9Sstevel@tonic-gate 	ulong_t		gk_unlink_last;		/* timestamep */
32897c478bd9Sstevel@tonic-gate 
32907c478bd9Sstevel@tonic-gate 	ulong_t		gk_buffail;		/* # bad bufalloc */
32917c478bd9Sstevel@tonic-gate 	ulong_t		gk_buffail_last;	/* timestamp */
32927c478bd9Sstevel@tonic-gate 	ulong_t		gk_slabfail;		/* # bad slaballoc */
32937c478bd9Sstevel@tonic-gate 	ulong_t		gk_slabfail_last;	/* timestamp */
32947c478bd9Sstevel@tonic-gate 
32957c478bd9Sstevel@tonic-gate 	ulong_t		gk_reap_count;		/* # of slabs reaped */
32967c478bd9Sstevel@tonic-gate 	ulong_t		gk_dropped_intrs;	/* dropped intrs */
32977c478bd9Sstevel@tonic-gate };
32987c478bd9Sstevel@tonic-gate 
32997c478bd9Sstevel@tonic-gate extern struct idn_gkstat	sg_kstat;
33007c478bd9Sstevel@tonic-gate 
33017c478bd9Sstevel@tonic-gate #ifdef IDN_NO_KSTAT
33027c478bd9Sstevel@tonic-gate 
33037c478bd9Sstevel@tonic-gate #define	IDN_KSTAT_INC(s, i)
33047c478bd9Sstevel@tonic-gate #define	IDN_KSTAT_ADD(s, i, n)
33057c478bd9Sstevel@tonic-gate #define	IDN_GKSTAT_INC(i)
33067c478bd9Sstevel@tonic-gate #define	IDN_GKSTAT_ADD(vvv, iii)
33077c478bd9Sstevel@tonic-gate #define	IDN_GKSTAT_GLOBAL_EVENT(vvv, nnn)
33087c478bd9Sstevel@tonic-gate 
33097c478bd9Sstevel@tonic-gate #else /* IDN_NO_KSTAT */
33107c478bd9Sstevel@tonic-gate 
33117c478bd9Sstevel@tonic-gate #define	IDN_KSTAT_INC(sss, vvv) \
33127c478bd9Sstevel@tonic-gate 		((((struct idn *)(sss))->si_kstat.vvv)++)
33137c478bd9Sstevel@tonic-gate #define	IDN_KSTAT_ADD(sss, vvv, nnn) \
33147c478bd9Sstevel@tonic-gate 		((((struct idn *)(sss))->si_kstat.vvv) += (nnn))
33157c478bd9Sstevel@tonic-gate #define	IDN_GKSTAT_INC(vvv)		((sg_kstat.vvv)++)
33167c478bd9Sstevel@tonic-gate #define	IDN_GKSTAT_ADD(vvv, iii)	((sg_kstat.vvv) += (iii))
33177c478bd9Sstevel@tonic-gate #define	IDN_GKSTAT_GLOBAL_EVENT(vvv, ttt) \
3318d3d50737SRafael Vanoni 		((sg_kstat.vvv)++, ((sg_kstat.ttt) = ddi_get_lbolt()))
33197c478bd9Sstevel@tonic-gate 
33207c478bd9Sstevel@tonic-gate #endif /* IDN_NO_KSTAT */
33217c478bd9Sstevel@tonic-gate 
33227c478bd9Sstevel@tonic-gate /*
33237c478bd9Sstevel@tonic-gate  * idn.si_flags
33247c478bd9Sstevel@tonic-gate  */
33257c478bd9Sstevel@tonic-gate #define	IDNRUNNING		0x01		/* IDNnet is UP */
33267c478bd9Sstevel@tonic-gate #define	IDNPROMISC		0x02		/* promiscuous mode enabled */
33277c478bd9Sstevel@tonic-gate #define	IDNSUSPENDED		0x04		/* suspended (DR) */
33287c478bd9Sstevel@tonic-gate 
33297c478bd9Sstevel@tonic-gate typedef struct kstat_named	kstate_named_t;
33307c478bd9Sstevel@tonic-gate 
33317c478bd9Sstevel@tonic-gate struct idn_kstat_named {
33327c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_ipackets;	/* # packets received */
33337c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_ierrors;	/* # total input errors */
33347c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_opackets;	/* # packets sent */
33357c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_oerrors;	/* # total output errors */
33367c478bd9Sstevel@tonic-gate 
33377c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_txcoll;	/* # xmit collisions */
33387c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_rxcoll;	/* # recv collisions */
33397c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_crc;		/* # recv crc errors */
33407c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_buff;	/* # recv pkt sz > buf sz */
33417c478bd9Sstevel@tonic-gate 
33427c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_nolink;	/* # loss of connection */
33437c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_linkdown;	/* # link is down */
33447c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_inits;	/* # driver inits */
33457c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_nocanput;	/* # canput() failures */
33467c478bd9Sstevel@tonic-gate 
33477c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_allocbfail;	/* # allocb() failures */
33487c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_notbufs;	/* # out of xmit buffers */
33497c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_reclaim;	/* # reclaim failures */
33507c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_smraddr;	/* # bad SMR addrs */
33517c478bd9Sstevel@tonic-gate 
33527c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_txmax;	/* # xmit over limit */
33537c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_txfull;	/* # xmit mbox full */
33547c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_xdcall;	/* # xdcalls sent */
33557c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_sigsvr;	/* # data server wakeups */
33567c478bd9Sstevel@tonic-gate 
33577c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_mboxcrc;	/* # send mbox crc errors */
33587c478bd9Sstevel@tonic-gate 	/*
33597c478bd9Sstevel@tonic-gate 	 * MIB II kstat variables
33607c478bd9Sstevel@tonic-gate 	 */
33617c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_rcvbytes;	/* # bytes received */
33627c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_xmtbytes;	/* # bytes transmitted */
33637c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_multircv;	/* # multicast packets received */
33647c478bd9Sstevel@tonic-gate 
33657c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_multixmt;	/* # multicast packets for xmit */
33667c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_brdcstrcv;	/* # broadcast packets received */
33677c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_brdcstxmt;	/* # broadcast packets for xmit */
33687c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_norcvbuf;	/* # rcv packets discarded */
33697c478bd9Sstevel@tonic-gate 
33707c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_noxmtbuf;	/* # xmit packets discarded */
33717c478bd9Sstevel@tonic-gate 	/*
33727c478bd9Sstevel@tonic-gate 	 * PSARC 1997/198 : 64bit kstats
33737c478bd9Sstevel@tonic-gate 	 */
33747c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_ipackets64;	/* # packets received */
33757c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_opackets64;	/* # packets transmitted */
33767c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_rbytes64;	/* # bytes received */
33777c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_obytes64;	/* # bytes transmitted */
33787c478bd9Sstevel@tonic-gate 	/*
33797c478bd9Sstevel@tonic-gate 	 * PSARC 1997/247 : RFC 1643	dot3Stats...
33807c478bd9Sstevel@tonic-gate 	 */
33817c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_fcs_errors;		/* FCSErr */
33827c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_macxmt_errors;	/* InternalMacXmtErr */
33837c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_toolong_errors;	/* FrameTooLongs */
33847c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_macrcv_errors;	/* InternalMacRcvErr */
33857c478bd9Sstevel@tonic-gate };
33867c478bd9Sstevel@tonic-gate 
33877c478bd9Sstevel@tonic-gate /*
33887c478bd9Sstevel@tonic-gate  * Stats for global events of interest (non-counters).
33897c478bd9Sstevel@tonic-gate  */
33907c478bd9Sstevel@tonic-gate struct idn_gkstat_named {
33917c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_curtime;		/* current time */
33927c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_reconfigs;		/* # master recfgs */
33937c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_reconfig_last;	/* timestamp */
33947c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_reaps;		/* # of reap req */
33957c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_reap_last;		/* timestamp */
33967c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_links;		/* # of links */
33977c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_link_last;		/* timestamp */
33987c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_unlinks;		/* # of unlinks */
33997c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_unlink_last;		/* timestamp */
34007c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_buffail;		/* # bad buf alloc */
34017c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_buffail_last;	/* timestamp */
34027c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_slabfail;		/* # bad buf alloc */
34037c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_slabfail_last;	/* timestamp */
34047c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_reap_count;		/* # slabs reaped */
34057c478bd9Sstevel@tonic-gate 	kstat_named_t	sk_dropped_intrs;	/* intrs dropped */
34067c478bd9Sstevel@tonic-gate };
34077c478bd9Sstevel@tonic-gate 
34087c478bd9Sstevel@tonic-gate /*
34097c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
34107c478bd9Sstevel@tonic-gate  */
34117c478bd9Sstevel@tonic-gate #ifdef DEBUG
34127c478bd9Sstevel@tonic-gate #define	IDNXDC(d, mt, a1, a2, a3, a4) \
341307d06da5SSurya Prakki 	((void) debug_idnxdc("idnxdc", (int)(d), (mt), \
34147c478bd9Sstevel@tonic-gate 		(uint_t)(a1), (uint_t)(a2), (uint_t)(a3), (uint_t)(a4)))
34157c478bd9Sstevel@tonic-gate #else /* DEBUG */
34167c478bd9Sstevel@tonic-gate #define	IDNXDC(d, mt, a1, a2, a3, a4) \
34177c478bd9Sstevel@tonic-gate 	(idnxdc((int)(d), (mt), \
34187c478bd9Sstevel@tonic-gate 		(uint_t)(a1), (uint_t)(a2), (uint_t)(a3), (uint_t)(a4)))
34197c478bd9Sstevel@tonic-gate #endif /* DEBUG */
34207c478bd9Sstevel@tonic-gate #define	IDNXDC_BROADCAST(ds, mt, a1, a2, a3, a4) \
34217c478bd9Sstevel@tonic-gate 	(idnxdc_broadcast((domainset_t)(ds), (mt), \
34227c478bd9Sstevel@tonic-gate 		(uint_t)(a1), (uint_t)(a2), (uint_t)(a3), (uint_t)(a4)))
34237c478bd9Sstevel@tonic-gate 
34247c478bd9Sstevel@tonic-gate /*
34257c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
34267c478bd9Sstevel@tonic-gate  */
34277c478bd9Sstevel@tonic-gate #define	SET_XARGS(x, a0, a1, a2, a3) \
34287c478bd9Sstevel@tonic-gate 	((x)[0] = (uint_t)(a0), (x)[1] = (uint_t)(a1), \
34297c478bd9Sstevel@tonic-gate 	(x)[2] = (uint_t)(a2), (x)[3] = (uint_t)(a3))
34307c478bd9Sstevel@tonic-gate 
34317c478bd9Sstevel@tonic-gate #define	GET_XARGS(x, a0, a1, a2, a3) \
3432*683b2949SRichard Lowe 	((*(uint_t *)(a0) = (x)[0]), \
3433*683b2949SRichard Lowe 	(*(uint_t *)(a1) = (x)[1]), \
3434*683b2949SRichard Lowe 	(*(uint_t *)(a2) = (x)[2]), \
3435*683b2949SRichard Lowe 	(*(uint_t *)(a3) = (x)[3]))
34367c478bd9Sstevel@tonic-gate 
34377c478bd9Sstevel@tonic-gate #define	CLR_XARGS(x) \
34387c478bd9Sstevel@tonic-gate 		((x)[0] = (x)[1] = (x)[2] = (x)[3] = 0)
34397c478bd9Sstevel@tonic-gate 
34407c478bd9Sstevel@tonic-gate #define	GET_XARGS_NEGO_TICKET(x)	((uint_t)(x)[0])
34417c478bd9Sstevel@tonic-gate #define	GET_XARGS_NEGO_DSET(x, d) \
34427c478bd9Sstevel@tonic-gate 		((d)[0] = (x)[1], (d)[1] = (x)[2], (d)[2] = (x)[3])
34437c478bd9Sstevel@tonic-gate #define	SET_XARGS_NEGO_TICKET(x, t)	((x)[0] = (uint_t)(t))
34447c478bd9Sstevel@tonic-gate #define	SET_XARGS_NEGO_DSET(x, d) \
34457c478bd9Sstevel@tonic-gate 		((x)[1] = (uint_t)(d)[0], \
34467c478bd9Sstevel@tonic-gate 		(x)[2] = (uint_t)(d)[1], \
34477c478bd9Sstevel@tonic-gate 		(x)[3] = (uint_t)(d)[2])
34487c478bd9Sstevel@tonic-gate 
34497c478bd9Sstevel@tonic-gate #define	GET_XARGS_CON_TYPE(x)		((idn_con_t)(x)[0])
34507c478bd9Sstevel@tonic-gate #define	GET_XARGS_CON_DOMSET(x)		((domainset_t)(x)[1])
34517c478bd9Sstevel@tonic-gate #define	SET_XARGS_CON_TYPE(x, t)	((x)[0] = (uint_t)(t))
34527c478bd9Sstevel@tonic-gate #define	SET_XARGS_CON_DOMSET(x, s)	((x)[1] = (uint_t)(s))
34537c478bd9Sstevel@tonic-gate 
34547c478bd9Sstevel@tonic-gate #define	GET_XARGS_FIN_TYPE(x)		GET_FIN_TYPE((x)[0])
34557c478bd9Sstevel@tonic-gate #define	GET_XARGS_FIN_ARG(x)		GET_FIN_ARG((x)[0])
34567c478bd9Sstevel@tonic-gate #define	GET_XARGS_FIN_DOMSET(x)		((domainset_t)(x)[1])
34577c478bd9Sstevel@tonic-gate #define	GET_XARGS_FIN_OPT(x)		((idn_finopt_t)(x)[2])
34587c478bd9Sstevel@tonic-gate #define	GET_XARGS_FIN_MASTER(x)		((uint_t)(x)[3])
34597c478bd9Sstevel@tonic-gate #define	SET_XARGS_FIN_TYPE(x, t)	SET_FIN_TYPE((x)[0], (t))
34607c478bd9Sstevel@tonic-gate #define	SET_XARGS_FIN_ARG(x, a)		SET_FIN_ARG((x)[0], (a))
34617c478bd9Sstevel@tonic-gate #define	SET_XARGS_FIN_DOMSET(x, s)	((x)[1] = (uint_t)(s))
34627c478bd9Sstevel@tonic-gate #define	SET_XARGS_FIN_OPT(x, o)		((x)[2] = (uint_t)(o))
34637c478bd9Sstevel@tonic-gate #define	SET_XARGS_FIN_MASTER(x, m)	((x)[3] = (uint_t)(m))
34647c478bd9Sstevel@tonic-gate 
34657c478bd9Sstevel@tonic-gate #define	GET_XARGS_NACK_TYPE(x)		((idn_nack_t)(x)[0])
34667c478bd9Sstevel@tonic-gate #define	GET_XARGS_NACK_ARG1(x)		((x)[1])
34677c478bd9Sstevel@tonic-gate #define	GET_XARGS_NACK_ARG2(x)		((x)[2])
34687c478bd9Sstevel@tonic-gate #define	SET_XARGS_NACK_TYPE(x, t)	((x)[0] = (uint_t)(t))
34697c478bd9Sstevel@tonic-gate #define	SET_XARGS_NACK_ARG1(x, a1)	((x)[1] = (uint_t)(a1))
34707c478bd9Sstevel@tonic-gate #define	SET_XARGS_NACK_ARG2(x, a2)	((x)[2] = (uint_t)(a2))
34717c478bd9Sstevel@tonic-gate 
34727c478bd9Sstevel@tonic-gate #define	GET_XARGS_CFG_PHASE(x)		((int)(x)[0])
34737c478bd9Sstevel@tonic-gate #define	SET_XARGS_CFG_PHASE(x, p)	((x)[0] = (uint_t)(p))
34747c478bd9Sstevel@tonic-gate 
34757c478bd9Sstevel@tonic-gate /*
34767c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
34777c478bd9Sstevel@tonic-gate  */
34787c478bd9Sstevel@tonic-gate /*
34797c478bd9Sstevel@tonic-gate  * Device instance to SIP (IDN instance pointer).
34807c478bd9Sstevel@tonic-gate  */
34817c478bd9Sstevel@tonic-gate #ifdef DEBUG
34827c478bd9Sstevel@tonic-gate #define	IDN_INST2SIP(i) \
34837c478bd9Sstevel@tonic-gate 		(ASSERT(((i) >= 0) && ((i) < (IDN_MAXMAX_NETS << 1))), \
34847c478bd9Sstevel@tonic-gate 			idn_i2s_table[i])
34857c478bd9Sstevel@tonic-gate #else /* DEBUG */
34867c478bd9Sstevel@tonic-gate #define	IDN_INST2SIP(i)		(idn_i2s_table[i])
34877c478bd9Sstevel@tonic-gate #endif /* DEBUG */
34887c478bd9Sstevel@tonic-gate 
34897c478bd9Sstevel@tonic-gate #define	IDN_SET_INST2SIP(i, s) \
34907c478bd9Sstevel@tonic-gate 	{ \
34917c478bd9Sstevel@tonic-gate 		ASSERT(((i) >= 0) && ((i) < (IDN_MAXMAX_NETS << 1))); \
34927c478bd9Sstevel@tonic-gate 		idn_i2s_table[i] = (s); \
34937c478bd9Sstevel@tonic-gate 	}
34947c478bd9Sstevel@tonic-gate 
3495bf30efa4Smathue #define	IDN_NETID2DOMID(n)	(VALID_UDOMAINID(n) ? \
34967c478bd9Sstevel@tonic-gate 					((int)(n)) : IDN_NIL_DOMID)
34977c478bd9Sstevel@tonic-gate #define	IDN_DOMID2NETID(d)	((ushort_t)(d))
34987c478bd9Sstevel@tonic-gate 
34997c478bd9Sstevel@tonic-gate #ifdef DEBUG
35007c478bd9Sstevel@tonic-gate #define	IDNDL_ETHER2DOMAIN(eap) \
35017c478bd9Sstevel@tonic-gate 		(_idndl_ether2domain(eap))
35027c478bd9Sstevel@tonic-gate #define	IDNDL_ETHER2SIP(eap) \
35037c478bd9Sstevel@tonic-gate 		(_idndl_ether2sip(eap))
35047c478bd9Sstevel@tonic-gate #else
35057c478bd9Sstevel@tonic-gate /*
35067c478bd9Sstevel@tonic-gate  * The following values can be returned from IDNDL_ETHER2DOMAIN:
35077c478bd9Sstevel@tonic-gate  *	IDN_NIL_DOMID
35087c478bd9Sstevel@tonic-gate  *		Ether address is broadcast (0xff) or domain doesn't exist.
35097c478bd9Sstevel@tonic-gate  *	domid	Domain id with drwlock(reader) held.
35107c478bd9Sstevel@tonic-gate  */
35117c478bd9Sstevel@tonic-gate #define	IDNDL_ETHER2DOMAIN(eap) \
35127c478bd9Sstevel@tonic-gate 	(IDN_NETID2DOMID((eap)->ether_addr_octet[IDNETHER_NETID]))
35137c478bd9Sstevel@tonic-gate #define	IDNDL_ETHER2SIP(eap) \
35147c478bd9Sstevel@tonic-gate 		(((eap)->ether_addr_octet[IDNETHER_CHANNEL] == 0xff) ? NULL : \
35157c478bd9Sstevel@tonic-gate 		IDN_INST2SIP((int)(eap)->ether_addr_octet[IDNETHER_CHANNEL]))
35167c478bd9Sstevel@tonic-gate #endif /* DEBUG */
35177c478bd9Sstevel@tonic-gate 
35187c478bd9Sstevel@tonic-gate #define	UPPER32_CPUMASK(s)	_upper32cpumask(s)
35197c478bd9Sstevel@tonic-gate #define	LOWER32_CPUMASK(s)	_lower32cpumask(s)
35207c478bd9Sstevel@tonic-gate #define	MAKE64_CPUMASK(s, u, l)	_make64cpumask(&(s), (u), (l))
35217c478bd9Sstevel@tonic-gate 
35227c478bd9Sstevel@tonic-gate #ifdef DEBUG
35237c478bd9Sstevel@tonic-gate extern caddr_t	_idn_getstruct(char *structname, int size);
35247c478bd9Sstevel@tonic-gate extern void	_idn_freestruct(caddr_t ptr, char *structname, int size);
35257c478bd9Sstevel@tonic-gate 
35267c478bd9Sstevel@tonic-gate #define	GETSTRUCT(structure, num) \
35277c478bd9Sstevel@tonic-gate 	((structure *)_idn_getstruct("structure", sizeof (structure)*(num)))
35287c478bd9Sstevel@tonic-gate #define	FREESTRUCT(ptr, structure, num) \
35297c478bd9Sstevel@tonic-gate 	(_idn_freestruct((caddr_t)ptr, "structure", sizeof (structure)*(num)))
35307c478bd9Sstevel@tonic-gate #else /* DEBUG */
35317c478bd9Sstevel@tonic-gate #define	GETSTRUCT(structure, num) \
35327c478bd9Sstevel@tonic-gate 	((structure *)kmem_zalloc((uint_t)(sizeof (structure) * (num)), \
35337c478bd9Sstevel@tonic-gate 				    KM_SLEEP))
35347c478bd9Sstevel@tonic-gate #define	FREESTRUCT(ptr, structure, num) \
35357c478bd9Sstevel@tonic-gate 	(kmem_free((caddr_t)(ptr), sizeof (structure) * (num)))
35367c478bd9Sstevel@tonic-gate #endif /* DEBUG */
35377c478bd9Sstevel@tonic-gate 
35387c478bd9Sstevel@tonic-gate extern int		idn_debug;
35397c478bd9Sstevel@tonic-gate extern idn_global_t	idn;
35407c478bd9Sstevel@tonic-gate extern idn_domain_t	idn_domain[];
35417c478bd9Sstevel@tonic-gate extern struct idn	*idn_i2s_table[];
35427c478bd9Sstevel@tonic-gate extern int		idn_history;
35437c478bd9Sstevel@tonic-gate extern struct idn_history	idnhlog;
35447c478bd9Sstevel@tonic-gate 
35457c478bd9Sstevel@tonic-gate extern int		idn_smr_size;
35467c478bd9Sstevel@tonic-gate extern int		idn_nwr_size;
35477c478bd9Sstevel@tonic-gate extern int		idn_protocol_nservers;
35487c478bd9Sstevel@tonic-gate extern int		idn_awolmsg_interval;
35497c478bd9Sstevel@tonic-gate extern int		idn_smr_bufsize;
35507c478bd9Sstevel@tonic-gate extern int		idn_slab_bufcount;
35517c478bd9Sstevel@tonic-gate extern int		idn_slab_prealloc;
35527c478bd9Sstevel@tonic-gate extern int		idn_slab_mintotal;
35537c478bd9Sstevel@tonic-gate extern int		idn_window_max;
35547c478bd9Sstevel@tonic-gate extern int		idn_window_incr;
35557c478bd9Sstevel@tonic-gate extern int		idn_reclaim_min;
35567c478bd9Sstevel@tonic-gate extern int		idn_reclaim_max;
35577c478bd9Sstevel@tonic-gate extern int		idn_mbox_per_net;
35587c478bd9Sstevel@tonic-gate extern int		idn_max_nets;
35597c478bd9Sstevel@tonic-gate 
35607c478bd9Sstevel@tonic-gate extern int		idn_netsvr_spin_count;
35617c478bd9Sstevel@tonic-gate extern int		idn_netsvr_wait_min;
35627c478bd9Sstevel@tonic-gate extern int		idn_netsvr_wait_max;
35637c478bd9Sstevel@tonic-gate extern int		idn_netsvr_wait_shift;
35647c478bd9Sstevel@tonic-gate 
35657c478bd9Sstevel@tonic-gate extern int		idn_checksum;
35667c478bd9Sstevel@tonic-gate 
35677c478bd9Sstevel@tonic-gate extern int		idn_msgwait_nego;
35687c478bd9Sstevel@tonic-gate extern int		idn_msgwait_cfg;
35697c478bd9Sstevel@tonic-gate extern int		idn_msgwait_con;
35707c478bd9Sstevel@tonic-gate extern int		idn_msgwait_fin;
35717c478bd9Sstevel@tonic-gate extern int		idn_msgwait_cmd;
35727c478bd9Sstevel@tonic-gate extern int		idn_msgwait_data;
35737c478bd9Sstevel@tonic-gate 
35747c478bd9Sstevel@tonic-gate extern int		idn_retryfreq_nego;
35757c478bd9Sstevel@tonic-gate extern int		idn_retryfreq_con;
35767c478bd9Sstevel@tonic-gate extern int		idn_retryfreq_fin;
35777c478bd9Sstevel@tonic-gate 
35787c478bd9Sstevel@tonic-gate extern int		idn_window_emax;	/* calculated */
35797c478bd9Sstevel@tonic-gate extern int		idn_slab_maxperdomain;	/* calculated */
35807c478bd9Sstevel@tonic-gate 
35817c478bd9Sstevel@tonic-gate /*
35827c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
35837c478bd9Sstevel@tonic-gate  * io/idn.c
35847c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
35857c478bd9Sstevel@tonic-gate  */
35867c478bd9Sstevel@tonic-gate extern int	board_to_ready_cpu(int board, cpuset_t cpuset);
35877c478bd9Sstevel@tonic-gate extern int	idn_open_domain(int domid, int cpuid, uint_t ticket);
35887c478bd9Sstevel@tonic-gate extern void 	idn_close_domain(int domid);
35897c478bd9Sstevel@tonic-gate extern void	inum2str(uint_t inum, char str[]);
35907c478bd9Sstevel@tonic-gate extern idn_timer_t	*idn_timer_alloc();
35917c478bd9Sstevel@tonic-gate extern void	idn_timer_free(idn_timer_t *tp);
35927c478bd9Sstevel@tonic-gate extern void	idn_timerq_init(idn_timerq_t *tq);
35937c478bd9Sstevel@tonic-gate extern void	idn_timerq_deinit(idn_timerq_t *tq);
35947c478bd9Sstevel@tonic-gate extern void	idn_timerq_free(idn_timerq_t *tq);
35957c478bd9Sstevel@tonic-gate extern ushort_t	idn_timer_start(idn_timerq_t *tq, idn_timer_t *tp,
35967c478bd9Sstevel@tonic-gate 				clock_t tval);
35977c478bd9Sstevel@tonic-gate extern int	idn_timer_stopall(idn_timer_t *tp);
35987c478bd9Sstevel@tonic-gate extern void	idn_timer_dequeue(idn_timerq_t *tq, idn_timer_t *tp);
35997c478bd9Sstevel@tonic-gate extern void	idn_timer_stop(idn_timerq_t *tq, int subtype, ushort_t tcookie);
36007c478bd9Sstevel@tonic-gate extern idn_timer_t	*idn_timer_get(idn_timerq_t *tq, int subtype,
36017c478bd9Sstevel@tonic-gate 				ushort_t tcookie);
36027c478bd9Sstevel@tonic-gate extern void	idn_domain_resetentry(idn_domain_t *dp);
36037c478bd9Sstevel@tonic-gate extern void	idn_strlinks_enable(uint_t netaddr, int domid);
36047c478bd9Sstevel@tonic-gate extern void	idn_strlinks_disable(uint_t domset, uint_t netaddr,
36057c478bd9Sstevel@tonic-gate 				int disconnect);
36067c478bd9Sstevel@tonic-gate extern void	idn_dopcache_init();
36077c478bd9Sstevel@tonic-gate extern void	idn_dopcache_deinit();
36087c478bd9Sstevel@tonic-gate extern void 	*idn_init_op(idn_opflag_t opflag, boardset_t boardset,
36097c478bd9Sstevel@tonic-gate 				idnsb_error_t *sep);
36107c478bd9Sstevel@tonic-gate extern void	idn_add_op(idn_opflag_t opflag, domainset_t domset);
36117c478bd9Sstevel@tonic-gate extern void	idn_update_op(idn_opflag_t opflag, domainset_t domset,
36127c478bd9Sstevel@tonic-gate 				idnsb_error_t *sep);
36137c478bd9Sstevel@tonic-gate extern void	idn_deinit_op(void *cookie);
36147c478bd9Sstevel@tonic-gate extern int	idn_wait_op(void *cookie, boardset_t *domsetp,
36157c478bd9Sstevel@tonic-gate 				int wait_timeout);
36167c478bd9Sstevel@tonic-gate extern int	idn_wakeup_op(boardset_t boardset, uint_t domset,
36177c478bd9Sstevel@tonic-gate 				idn_opflag_t opflag, int error);
36187c478bd9Sstevel@tonic-gate extern void	idn_error_op(uint_t domset, boardset_t boardset, int error);
36197c478bd9Sstevel@tonic-gate extern void	cpuset2str(cpuset_t cset, char buffer[]);
36207c478bd9Sstevel@tonic-gate extern void	domainset2str(domainset_t dset, char buffer[]);
36217c478bd9Sstevel@tonic-gate extern void	boardset2str(boardset_t bset, char buffer[]);
36227c478bd9Sstevel@tonic-gate extern void	mask2str(uint_t mask, char buffer[], int maxnum);
36237c478bd9Sstevel@tonic-gate extern int	idnxdc(int domid, idn_msgtype_t *mtp,
36247c478bd9Sstevel@tonic-gate 				uint_t arg1, uint_t arg2,
36257c478bd9Sstevel@tonic-gate 				uint_t arg3, uint_t arg4);
36267c478bd9Sstevel@tonic-gate extern void	idnxdc_broadcast(domainset_t domset, idn_msgtype_t *mtp,
36277c478bd9Sstevel@tonic-gate 				uint_t arg1, uint_t arg2,
36287c478bd9Sstevel@tonic-gate 				uint_t arg3, uint_t arg4);
36297c478bd9Sstevel@tonic-gate extern void	idn_awol_event_set(boardset_t boardset);
36307c478bd9Sstevel@tonic-gate extern void	idn_awol_event_clear(boardset_t boardset);
36317c478bd9Sstevel@tonic-gate #ifdef DEBUG
36327c478bd9Sstevel@tonic-gate extern int	debug_idnxdc(char *f, int domid, idn_msgtype_t *mtp,
36337c478bd9Sstevel@tonic-gate 				uint_t arg1, uint_t arg2,
36347c478bd9Sstevel@tonic-gate 				uint_t arg3, uint_t arg4);
36357c478bd9Sstevel@tonic-gate #endif /* DEBUG */
36367c478bd9Sstevel@tonic-gate extern boardset_t	cpuset2boardset(cpuset_t portset);
36377c478bd9Sstevel@tonic-gate extern uint_t	_upper32cpumask(cpuset_t cset);
36387c478bd9Sstevel@tonic-gate extern uint_t	_lower32cpumask(cpuset_t cset);
36397c478bd9Sstevel@tonic-gate extern void	_make64cpumask(cpuset_t *csetp, uint_t upper, uint_t lower);
36407c478bd9Sstevel@tonic-gate 
36417c478bd9Sstevel@tonic-gate /*
36427c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
36437c478bd9Sstevel@tonic-gate  * io/idn_proto.c
36447c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
36457c478bd9Sstevel@tonic-gate  */
36467c478bd9Sstevel@tonic-gate extern void	idn_assign_cookie(int domid);
36477c478bd9Sstevel@tonic-gate extern int	idn_rput_data(queue_t *q, mblk_t *mp, int isput);
36487c478bd9Sstevel@tonic-gate extern int	idn_wput_data(queue_t *q, mblk_t *mp, int isput);
36497c478bd9Sstevel@tonic-gate extern int	idn_send_data(int dst_domid, idn_netaddr_t dst_netaddr,
36507c478bd9Sstevel@tonic-gate 				queue_t *wq, mblk_t *mp);
36517c478bd9Sstevel@tonic-gate extern void 	idn_recv_signal(mblk_t *mp);
36527c478bd9Sstevel@tonic-gate extern int 	idn_link(int domid, int cpuid, int pri, int waittime,
36537c478bd9Sstevel@tonic-gate 				idnsb_error_t *sep);
36547c478bd9Sstevel@tonic-gate extern int 	idn_unlink(int domid, boardset_t idnset, idn_fin_t fintype,
36557c478bd9Sstevel@tonic-gate 				idn_finopt_t finopt, int waittime,
36567c478bd9Sstevel@tonic-gate 				idnsb_error_t *sep);
36577c478bd9Sstevel@tonic-gate extern int	idnh_recv_dataack(int domid, int src_proc,
36587c478bd9Sstevel@tonic-gate 				uint_t acknack, idn_xdcargs_t xargs);
36597c478bd9Sstevel@tonic-gate extern int 	idnh_recv_other(int sourceid, int src_proc, int dst_proc,
36607c478bd9Sstevel@tonic-gate 				uint_t inum, uint_t acknack,
36617c478bd9Sstevel@tonic-gate 				idn_xdcargs_t xargs);
36627c478bd9Sstevel@tonic-gate extern void 	idn_send_cmd(int domid, idn_cmd_t cmdtype,
36637c478bd9Sstevel@tonic-gate 				uint_t arg1, uint_t arg2, uint_t arg3);
36647c478bd9Sstevel@tonic-gate extern void	idn_send_cmdresp(int domid, idn_msgtype_t *mtp,
36657c478bd9Sstevel@tonic-gate 				idn_cmd_t cmdtype, uint_t arg1,
36667c478bd9Sstevel@tonic-gate 				uint_t arg2, uint_t cerrno);
36677c478bd9Sstevel@tonic-gate extern void 	idn_broadcast_cmd(idn_cmd_t cmdtype,
36687c478bd9Sstevel@tonic-gate 				uint_t arg1, uint_t arg2, uint_t arg3);
36697c478bd9Sstevel@tonic-gate extern int	idn_reclaim_mboxdata(int domid, int channel, int nbufs);
36707c478bd9Sstevel@tonic-gate extern void	idn_clear_awol(int domid);
36717c478bd9Sstevel@tonic-gate extern int	idn_protocol_init(int nservers);
36727c478bd9Sstevel@tonic-gate extern void	idn_protocol_deinit();
36737c478bd9Sstevel@tonic-gate extern void	idn_timer_expired(void *arg);
36747c478bd9Sstevel@tonic-gate extern int	idn_open_channel(int channel);
36757c478bd9Sstevel@tonic-gate extern void	idn_close_channel(int channel, idn_chanop_t chanop);
36767c478bd9Sstevel@tonic-gate extern idn_mainmbox_t	*idn_mainmbox_init(int domid, int mbx);
36777c478bd9Sstevel@tonic-gate extern void	idn_mainmbox_deinit(int domid, idn_mainmbox_t *mmp);
36787c478bd9Sstevel@tonic-gate extern void	idn_signal_data_server(int domid, ushort_t channel);
36797c478bd9Sstevel@tonic-gate extern int	idn_chanservers_init();
36807c478bd9Sstevel@tonic-gate extern void	idn_chanservers_deinit();
36817c478bd9Sstevel@tonic-gate extern void	idn_chanserver_bind(int net, int cpuid);
36827c478bd9Sstevel@tonic-gate extern int	idn_retry_terminate(uint_t token);
36837c478bd9Sstevel@tonic-gate extern idn_protojob_t	*idn_protojob_alloc(int kmflag);
36847c478bd9Sstevel@tonic-gate extern void	idn_protojob_submit(int cookie, idn_protojob_t *jp);
36857c478bd9Sstevel@tonic-gate extern int	idn_domain_is_registered(int domid, int channel,
36867c478bd9Sstevel@tonic-gate 				idn_chanset_t *chansetp);
36877c478bd9Sstevel@tonic-gate extern void	idn_xmit_monitor_kickoff(int chan_wanted);
36887c478bd9Sstevel@tonic-gate extern void	idn_sync_exit(int domid, idn_synccmd_t cmd);
36897c478bd9Sstevel@tonic-gate /*
36907c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
36917c478bd9Sstevel@tonic-gate  * io/idn_xf.c
36927c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
36937c478bd9Sstevel@tonic-gate  */
36947c478bd9Sstevel@tonic-gate extern void	idnxf_flushall_ecache();
36957c478bd9Sstevel@tonic-gate extern int	idnxf_shmem_add(int is_master, boardset_t boardset,
36967c478bd9Sstevel@tonic-gate 				pfn_t pfnbase, pfn_t pfnlimit,
36977c478bd9Sstevel@tonic-gate 				uint_t *mcadr);
36987c478bd9Sstevel@tonic-gate extern int	idnxf_shmem_sub(int is_master, boardset_t boardset);
36997c478bd9Sstevel@tonic-gate extern int	idn_cpu_per_board(void *p2o, cpuset_t cset,
37007c478bd9Sstevel@tonic-gate 				struct hwconfig *hwp);
37017c478bd9Sstevel@tonic-gate /*
37027c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
37037c478bd9Sstevel@tonic-gate  * io/idn_dlpi.c
37047c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
37057c478bd9Sstevel@tonic-gate  */
37067c478bd9Sstevel@tonic-gate extern int	idndl_init(struct idn *sip);
37077c478bd9Sstevel@tonic-gate extern void	idndl_uninit(struct idn *sip);
37087c478bd9Sstevel@tonic-gate extern void	idndl_statinit(struct idn *sip);
37097c478bd9Sstevel@tonic-gate extern void	idndl_dodetach(struct idnstr *);
37107c478bd9Sstevel@tonic-gate extern int	idnioc_dlpi(queue_t *wq, mblk_t *mp, int *argsize);
37117c478bd9Sstevel@tonic-gate extern void	idndl_localetheraddr(struct idn *sip, struct ether_addr *eap);
37127c478bd9Sstevel@tonic-gate extern int	idndl_domain_etheraddr(int domid, int instance,
37137c478bd9Sstevel@tonic-gate 				struct ether_addr *eap);
37147c478bd9Sstevel@tonic-gate extern void	idndl_dlpi_init();
37157c478bd9Sstevel@tonic-gate extern int	idndl_start(queue_t *wq, mblk_t *mp, struct idn *sip);
37167c478bd9Sstevel@tonic-gate extern void	idndl_read(struct idn *sip, mblk_t *mp);
37177c478bd9Sstevel@tonic-gate extern void	idndl_proto(queue_t *wq, mblk_t *mp);
37187c478bd9Sstevel@tonic-gate extern void	idndl_sendup(struct idn *, mblk_t *, struct idnstr *(*)());
37197c478bd9Sstevel@tonic-gate extern struct idnstr *idndl_accept(struct idnstr *, struct idn *, int,
37207c478bd9Sstevel@tonic-gate 				struct ether_addr *);
37217c478bd9Sstevel@tonic-gate extern struct idnstr *idndl_paccept(struct idnstr *, struct idn *, int,
37227c478bd9Sstevel@tonic-gate 				struct ether_addr *);
37237c478bd9Sstevel@tonic-gate extern void	idndl_wenable(struct idn *);
37247c478bd9Sstevel@tonic-gate /*
37257c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
37267c478bd9Sstevel@tonic-gate  * io/idn_smr.c
37277c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
37287c478bd9Sstevel@tonic-gate  */
37297c478bd9Sstevel@tonic-gate extern void	smr_slabwaiter_open(domainset_t domset);
37307c478bd9Sstevel@tonic-gate extern void	smr_slabwaiter_close(domainset_t domset);
37317c478bd9Sstevel@tonic-gate /*
37327c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
37337c478bd9Sstevel@tonic-gate  */
37347c478bd9Sstevel@tonic-gate extern void	idn_smrsize_init();
37357c478bd9Sstevel@tonic-gate extern void	idn_init_autolink();
37367c478bd9Sstevel@tonic-gate extern void	idn_deinit_autolink();
37377c478bd9Sstevel@tonic-gate 
37387c478bd9Sstevel@tonic-gate extern void	idn_dmv_handler(void *arg);
37397c478bd9Sstevel@tonic-gate extern void	idnxf_init_mondo(uint64_t dmv_word0,
37407c478bd9Sstevel@tonic-gate 				uint64_t dmv_word1, uint64_t dmv_word2);
37417c478bd9Sstevel@tonic-gate extern int	idnxf_send_mondo(int upaid);
37427c478bd9Sstevel@tonic-gate 
37437c478bd9Sstevel@tonic-gate extern clock_t	idn_msg_waittime[];
37447c478bd9Sstevel@tonic-gate extern clock_t	idn_msg_retrytime[];
37457c478bd9Sstevel@tonic-gate 
37467c478bd9Sstevel@tonic-gate #endif /* !_ASM */
37477c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
37487c478bd9Sstevel@tonic-gate 
37497c478bd9Sstevel@tonic-gate #ifndef _ASM
37507c478bd9Sstevel@tonic-gate /*
37517c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
37527c478bd9Sstevel@tonic-gate  */
37537c478bd9Sstevel@tonic-gate #define	IDN_NIL_DOMID		-1
37547c478bd9Sstevel@tonic-gate #define	IDN_NIL_DCPU		-1
37557c478bd9Sstevel@tonic-gate 
37567c478bd9Sstevel@tonic-gate /*
37577c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
37587c478bd9Sstevel@tonic-gate  */
37597c478bd9Sstevel@tonic-gate 
37607c478bd9Sstevel@tonic-gate /*
37617c478bd9Sstevel@tonic-gate  * IOCTL Interface
37627c478bd9Sstevel@tonic-gate  *
37637c478bd9Sstevel@tonic-gate  * Commands must stay in the range (1 - 4096) since only 12 bits
37647c478bd9Sstevel@tonic-gate  * are allotted.
37657c478bd9Sstevel@tonic-gate  */
37667c478bd9Sstevel@tonic-gate #define	_IDN(n)			(('I' << 20) | ('D' << 12) | (n))
37677c478bd9Sstevel@tonic-gate #define	IDNIOC_LINK		_IDN(1)		/* domain_link */
37687c478bd9Sstevel@tonic-gate #define	IDNIOC_UNLINK		_IDN(2)		/* domain_unlink */
37697c478bd9Sstevel@tonic-gate #define	IDNIOC_unused0		_IDN(3)
37707c478bd9Sstevel@tonic-gate #define	IDNIOC_unused1		_IDN(4)
37717c478bd9Sstevel@tonic-gate #define	IDNIOC_unused2		_IDN(5)
37727c478bd9Sstevel@tonic-gate #define	IDNIOC_unused3		_IDN(6)
37737c478bd9Sstevel@tonic-gate #define	IDNIOC_unused4		_IDN(7)
37747c478bd9Sstevel@tonic-gate #define	IDNIOC_DLPI_ON		_IDN(8)		/* Turn ON DLPI on str */
37757c478bd9Sstevel@tonic-gate #define	IDNIOC_DLPI_OFF		_IDN(9)		/* Turn OFF DLPI on str */
37767c478bd9Sstevel@tonic-gate #define	IDNIOC_PING		_IDN(10)	/* For latency testing */
37777c478bd9Sstevel@tonic-gate #define	IDNIOC_PING_INIT	_IDN(11)
37787c478bd9Sstevel@tonic-gate #define	IDNIOC_PING_DEINIT	_IDN(12)
37797c478bd9Sstevel@tonic-gate #define	IDNIOC_MEM_RW		_IDN(13)	/* Random R/W of SMR */
37807c478bd9Sstevel@tonic-gate 
37817c478bd9Sstevel@tonic-gate 
37827c478bd9Sstevel@tonic-gate #define	VALID_NDOP(op)		(((op) == ND_SET) || ((op) == ND_GET))
37837c478bd9Sstevel@tonic-gate 
37847c478bd9Sstevel@tonic-gate #define	VALID_DLPIOP(op)	(((op) == DLIOCRAW) || \
37857c478bd9Sstevel@tonic-gate 				((op) == DL_IOC_HDR_INFO))
37867c478bd9Sstevel@tonic-gate 
37877c478bd9Sstevel@tonic-gate #define	VALID_IDNOP(op)		(((op) >= _IDN(1)) && ((op) <= _IDN(13)))
37887c478bd9Sstevel@tonic-gate 
37897c478bd9Sstevel@tonic-gate #define	VALID_IDNIOCTL(op)	(VALID_IDNOP(op) || \
37907c478bd9Sstevel@tonic-gate 				VALID_NDOP(op) || \
37917c478bd9Sstevel@tonic-gate 				VALID_DLPIOP(op))
37927c478bd9Sstevel@tonic-gate 
37937c478bd9Sstevel@tonic-gate typedef union idnop {
37947c478bd9Sstevel@tonic-gate 	struct {
37957c478bd9Sstevel@tonic-gate 		int		domid;		/* input */
37967c478bd9Sstevel@tonic-gate 		int		cpuid;		/* input */
37977c478bd9Sstevel@tonic-gate 		int		master;		/* input */
37987c478bd9Sstevel@tonic-gate 		int		wait;		/* input */
37997c478bd9Sstevel@tonic-gate 	} link;
38007c478bd9Sstevel@tonic-gate 	struct {
38017c478bd9Sstevel@tonic-gate 		int		domid;		/* input */
38027c478bd9Sstevel@tonic-gate 		int		cpuid;		/* input */
38037c478bd9Sstevel@tonic-gate 		int		force;		/* input */
38047c478bd9Sstevel@tonic-gate 		int		wait;		/* input */
38057c478bd9Sstevel@tonic-gate 	} unlink;
38067c478bd9Sstevel@tonic-gate 	struct {
38077c478bd9Sstevel@tonic-gate 		int		domid;		/* input */
38087c478bd9Sstevel@tonic-gate 		int		cpuid;		/* input */
38097c478bd9Sstevel@tonic-gate 	} ping;
38107c478bd9Sstevel@tonic-gate 	struct {
38117c478bd9Sstevel@tonic-gate 		uint_t		lo_off;		/* input */
38127c478bd9Sstevel@tonic-gate 		uint_t		hi_off;		/* input */
38137c478bd9Sstevel@tonic-gate 		int		blksize;	/* input */
38147c478bd9Sstevel@tonic-gate 		int		num;		/* input */
38157c478bd9Sstevel@tonic-gate 		int		rw;		/* input */
38167c478bd9Sstevel@tonic-gate 		int		goawol;		/* input */
38177c478bd9Sstevel@tonic-gate 	} rwmem;
38187c478bd9Sstevel@tonic-gate } idnop_t;
38197c478bd9Sstevel@tonic-gate 
38207c478bd9Sstevel@tonic-gate #ifdef _KERNEL
38217c478bd9Sstevel@tonic-gate /*
38227c478bd9Sstevel@tonic-gate  * ndd support for IDN tunables.
38237c478bd9Sstevel@tonic-gate  */
38247c478bd9Sstevel@tonic-gate typedef struct idnparam {
38257c478bd9Sstevel@tonic-gate 	ulong_t	sp_min;
38267c478bd9Sstevel@tonic-gate 	ulong_t	sp_max;
38277c478bd9Sstevel@tonic-gate 	ulong_t	sp_val;
38287c478bd9Sstevel@tonic-gate 	char	*sp_name;
38297c478bd9Sstevel@tonic-gate } idnparam_t;
38307c478bd9Sstevel@tonic-gate 
38317c478bd9Sstevel@tonic-gate extern idnparam_t	idn_param_arr[];
38327c478bd9Sstevel@tonic-gate 
38337c478bd9Sstevel@tonic-gate #define	idn_modunloadable		idn_param_arr[0].sp_val
38347c478bd9Sstevel@tonic-gate #ifdef IDN_PERF
38357c478bd9Sstevel@tonic-gate #define	_LP	0
38367c478bd9Sstevel@tonic-gate #define	_xxx_tbd			idn_param_arr[_LP+1].sp_val
38377c478bd9Sstevel@tonic-gate #endif /* IDN_PERF */
38387c478bd9Sstevel@tonic-gate 
38397c478bd9Sstevel@tonic-gate /*
38407c478bd9Sstevel@tonic-gate  * =====================================================================
38417c478bd9Sstevel@tonic-gate  */
38427c478bd9Sstevel@tonic-gate 
38437c478bd9Sstevel@tonic-gate /*
38447c478bd9Sstevel@tonic-gate  * Some junk to pretty print board lists and cpu lists in
38457c478bd9Sstevel@tonic-gate  * log/console messages.  Length is big enough to display 64 double
38467c478bd9Sstevel@tonic-gate  * digit cpus separated by a command and single space.  (Board list
38477c478bd9Sstevel@tonic-gate  * is similar, but only 16 entries possible.
38487c478bd9Sstevel@tonic-gate  */
38497c478bd9Sstevel@tonic-gate #define	_DSTRLEN		400
38507c478bd9Sstevel@tonic-gate #define	ALLOC_DISPSTRING()	((char *)kmem_alloc(_DSTRLEN, KM_NOSLEEP))
38517c478bd9Sstevel@tonic-gate #define	FREE_DISPSTRING(b)	(kmem_free((void *)(b), _DSTRLEN))
38527c478bd9Sstevel@tonic-gate 
38537c478bd9Sstevel@tonic-gate /*
38547c478bd9Sstevel@tonic-gate  * These are declared in idn.c.
38557c478bd9Sstevel@tonic-gate  */
38567c478bd9Sstevel@tonic-gate extern const char	*idnds_str[];
38577c478bd9Sstevel@tonic-gate extern const char	*idnxs_str[];
38587c478bd9Sstevel@tonic-gate extern const char	*idngs_str[];
38597c478bd9Sstevel@tonic-gate extern const char	*idncmd_str[];
38607c478bd9Sstevel@tonic-gate extern const char	*idncon_str[];
38617c478bd9Sstevel@tonic-gate extern const char	*idnfin_str[];
38627c478bd9Sstevel@tonic-gate extern const char	*idnfinarg_str[];
38637c478bd9Sstevel@tonic-gate extern const char	*idnfinopt_str[];
38647c478bd9Sstevel@tonic-gate extern const char	*idnreg_str[];
38657c478bd9Sstevel@tonic-gate extern const char	*idnnack_str[];
38667c478bd9Sstevel@tonic-gate extern const char	*idnop_str[];
38677c478bd9Sstevel@tonic-gate extern const char	*idnsync_str[];
38687c478bd9Sstevel@tonic-gate extern const char	*chanop_str[];
38697c478bd9Sstevel@tonic-gate extern const char	*chanaction_str[];
38707c478bd9Sstevel@tonic-gate extern const char	*inum_str[];
38717c478bd9Sstevel@tonic-gate extern const int	inum_bump;
38727c478bd9Sstevel@tonic-gate extern const int	inum_max;
38737c478bd9Sstevel@tonic-gate extern const int	acknack_shift;
38747c478bd9Sstevel@tonic-gate 
38757c478bd9Sstevel@tonic-gate extern const char	*timer_str[];
38767c478bd9Sstevel@tonic-gate extern const char	*res_str[];
38777c478bd9Sstevel@tonic-gate 
38787c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
38797c478bd9Sstevel@tonic-gate #endif /* !_ASM */
38807c478bd9Sstevel@tonic-gate 
38817c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
38827c478bd9Sstevel@tonic-gate }
38837c478bd9Sstevel@tonic-gate #endif
38847c478bd9Sstevel@tonic-gate 
38857c478bd9Sstevel@tonic-gate #endif /* _SYS_IDN_H */
3886