xref: /illumos-gate/usr/src/uts/sun4v/sys/ldc_impl.h (revision a704fb2d)
11ae08745Sheppo /*
21ae08745Sheppo  * CDDL HEADER START
31ae08745Sheppo  *
41ae08745Sheppo  * The contents of this file are subject to the terms of the
51ae08745Sheppo  * Common Development and Distribution License (the "License").
61ae08745Sheppo  * You may not use this file except in compliance with the License.
71ae08745Sheppo  *
81ae08745Sheppo  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91ae08745Sheppo  * or http://www.opensolaris.org/os/licensing.
101ae08745Sheppo  * See the License for the specific language governing permissions
111ae08745Sheppo  * and limitations under the License.
121ae08745Sheppo  *
131ae08745Sheppo  * When distributing Covered Code, include this CDDL HEADER in each
141ae08745Sheppo  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151ae08745Sheppo  * If applicable, add the following below this CDDL HEADER, with the
161ae08745Sheppo  * fields enclosed by brackets "[]" replaced with your own identifying
171ae08745Sheppo  * information: Portions Copyright [yyyy] [name of copyright owner]
181ae08745Sheppo  *
191ae08745Sheppo  * CDDL HEADER END
201ae08745Sheppo  */
211ae08745Sheppo 
221ae08745Sheppo /*
2334f94fbcSWENTAO YANG  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
241ae08745Sheppo  */
251ae08745Sheppo 
261ae08745Sheppo #ifndef _LDC_IMPL_H
271ae08745Sheppo #define	_LDC_IMPL_H
281ae08745Sheppo 
291ae08745Sheppo #ifdef __cplusplus
301ae08745Sheppo extern "C" {
311ae08745Sheppo #endif
321ae08745Sheppo 
331ae08745Sheppo #include <sys/types.h>
341ae08745Sheppo #include <sys/ddi.h>
351ae08745Sheppo #include <sys/sunddi.h>
361ae08745Sheppo #include <sys/ioctl.h>
371ae08745Sheppo 
38e1ebb9ecSlm /* Memory map table entries */
39e1ebb9ecSlm #define	LDC_MTBL_ENTRIES	8192	/* 8 K */
401ae08745Sheppo 
411ae08745Sheppo /* Define LDC Queue info */
421ae08745Sheppo #define	LDC_PACKET_SHIFT	6
43e1ebb9ecSlm #define	LDC_QUEUE_ENTRIES	512
44e1ebb9ecSlm #define	LDC_MTU_MSGS		4
451ae08745Sheppo #define	LDC_QUEUE_SIZE		(LDC_QUEUE_ENTRIES << LDC_PACKET_SHIFT)
46e1ebb9ecSlm #define	LDC_DEFAULT_MTU		(LDC_QUEUE_SIZE / LDC_MTU_MSGS)
4758283286Sha #define	LDC_RXDQ_MULTIPLIER	2
481ae08745Sheppo 
491ae08745Sheppo /*
501ae08745Sheppo  * LDC Reliable mode - initial packet seqid
511ae08745Sheppo  * - If peer initiated handshake, RDX should contain init_seqid + 1
521ae08745Sheppo  * - If this endpoint initiated handshake first data packet should
531ae08745Sheppo  *   contain the message init_seqid + 1
541ae08745Sheppo  */
551ae08745Sheppo #define	LDC_INIT_SEQID	0x0
561ae08745Sheppo 
571ae08745Sheppo /* LDC Message types */
581ae08745Sheppo #define	LDC_CTRL	0x01	/* Control Pkt */
591ae08745Sheppo #define	LDC_DATA	0x02	/* Data Pkt */
601ae08745Sheppo #define	LDC_ERR		0x10	/* Error Pkt */
611ae08745Sheppo 
621ae08745Sheppo /* LDC Message Subtypes */
631ae08745Sheppo #define	LDC_INFO	0x01	/* Control/Data/Error info pkt */
641ae08745Sheppo #define	LDC_ACK		0x02	/* Control/Data ACK */
651ae08745Sheppo #define	LDC_NACK	0x04	/* Control/Data NACK */
661ae08745Sheppo 
671ae08745Sheppo /* LDC Control Messages */
681ae08745Sheppo #define	LDC_VER		0x01	/* Version message */
691ae08745Sheppo #define	LDC_RTS		0x02	/* Request to Send */
701ae08745Sheppo #define	LDC_RTR		0x03	/* Ready To Receive */
711ae08745Sheppo #define	LDC_RDX		0x04	/* Ready for data exchange */
721ae08745Sheppo 
731ae08745Sheppo #define	LDC_CTRL_MASK	0x0f	/* Mask to read control bits */
741ae08745Sheppo 
751ae08745Sheppo /* LDC Channel Transport State (tstate) */
761ae08745Sheppo #define	TS_TXQ_RDY	0x01	/* allocated TX queue */
771ae08745Sheppo #define	TS_RXQ_RDY	0x02	/* allocated RX queue */
781ae08745Sheppo #define	TS_INIT		(TS_TXQ_RDY | TS_RXQ_RDY)
791ae08745Sheppo #define	TS_QCONF_RDY	0x04	/* registered queues with HV */
801ae08745Sheppo #define	TS_CNEX_RDY	0x08	/* registered channel with cnex */
811ae08745Sheppo #define	TS_OPEN		(TS_INIT | TS_QCONF_RDY | TS_CNEX_RDY)
821ae08745Sheppo #define	TS_LINK_READY	0x10	/* both endpts registered Rx queues */
831ae08745Sheppo #define	TS_READY	(TS_OPEN | TS_LINK_READY)
841ae08745Sheppo #define	TS_VER_DONE	0x20	/* negotiated version */
851ae08745Sheppo #define	TS_VREADY	(TS_READY | TS_VER_DONE)
861ae08745Sheppo #define	TS_HSHAKE_DONE	0x40	/* completed handshake */
871ae08745Sheppo #define	TS_UP		(TS_READY | TS_VER_DONE | TS_HSHAKE_DONE)
881ae08745Sheppo 
893af08d82Slm #define	TS_IN_RESET	0x100	/* channel is in reset state */
903af08d82Slm 
911ae08745Sheppo /*  LDC Channel Transport Handshake states */
920a55fbb7Slm #define	TS_SENT_VER	0x01	/* Sent version */
930a55fbb7Slm #define	TS_SENT_RTS	0x02	/* Sent RTS */
940a55fbb7Slm #define	TS_RCVD_RTR	0x04	/* Received RTR */
950a55fbb7Slm #define	TS_SENT_RDX	0x08	/* Sent RDX */
960a55fbb7Slm #define	TS_RCVD_VER	0x10	/* Received version */
970a55fbb7Slm #define	TS_RCVD_RTS	0x20	/* Received RTS */
980a55fbb7Slm #define	TS_SENT_RTR	0x40	/* Sent RTR */
990a55fbb7Slm #define	TS_RCVD_RDX	0x80	/* Received RDX */
1001ae08745Sheppo 
1013af08d82Slm /* LDC Interrupt State */
1023af08d82Slm #define	LDC_INTR_NONE	0x00	/* No interrupts */
1033af08d82Slm #define	LDC_INTR_ACTIVE	0x01	/* Interrupt being processed */
1043af08d82Slm #define	LDC_INTR_PEND	0x02	/* Interrupt pending */
1053af08d82Slm 
1061ae08745Sheppo /* LDC MSG Envelope */
1071ae08745Sheppo #define	LDC_LEN_MASK	0x3F
1081ae08745Sheppo #define	LDC_FRAG_MASK	0xC0
1091ae08745Sheppo 
1101ae08745Sheppo #define	LDC_FRAG_START	0x40	/* frag_info = 0x01 */
1111ae08745Sheppo #define	LDC_FRAG_STOP	0x80	/* frag_info = 0x02 */
1121ae08745Sheppo #define	LDC_FRAG_CONT	0x00	/* frag_info = 0x00 */
1131ae08745Sheppo 
1141ae08745Sheppo /*
1150a55fbb7Slm  * LDC will retry LDC_MAX_RETRIES times when sending or
1160a55fbb7Slm  * receiving data or if the HV returns back EWOULDBLOCK.
1170a55fbb7Slm  * Between each retry it will wait LDC_DELAY usecs.
1181ae08745Sheppo  */
1190a55fbb7Slm #define	LDC_MAX_RETRIES	1000
1200a55fbb7Slm #define	LDC_DELAY	1
1211ae08745Sheppo 
1224d39be2bSsg /* delay(usec) between channel unregister retries in ldc_close() */
1234d39be2bSsg #define	LDC_CLOSE_DELAY	1
1244d39be2bSsg 
1251ae08745Sheppo /*
1261ae08745Sheppo  * LDC Version information
1271ae08745Sheppo  */
1281ae08745Sheppo #define	LDC_PAYLOAD_VER_OFF	8	/* offset of version in payload */
1291ae08745Sheppo 
1301ae08745Sheppo typedef struct ldc_ver {
1311ae08745Sheppo 	uint16_t	major;
1321ae08745Sheppo 	uint16_t	minor;
1331ae08745Sheppo } ldc_ver_t;
1341ae08745Sheppo 
1351ae08745Sheppo /*
1361ae08745Sheppo  * Each guest consists of one or more LDC endpoints represented by a ldc_chan
1371ae08745Sheppo  * structure. Each ldc_chan structure points to a ldc_mtbl structure that
1381ae08745Sheppo  * contains information about the map table associated with this LDC endpoint.
1391ae08745Sheppo  * The map table contains the list of pages being shared by this guest over
1401ae08745Sheppo  * this endpoint with the guest at the other end of this endpoint. Each LDC
1411ae08745Sheppo  * endpoint also points to a list of memory handles used to bind and export
1421ae08745Sheppo  * memory segments from this guest. If a memory segment is bound, it points to
1431ae08745Sheppo  * a memory segment structure, which inturn consists of an array of ldc_page
1441ae08745Sheppo  * structure for all the pages within that segment. Each ldc_page structure
1451ae08745Sheppo  * contains information about the shared page and also points to the
1461ae08745Sheppo  * corresponding entry in the map table.
1471ae08745Sheppo  *
1481ae08745Sheppo  * Each LDC endpoint also points to a list of ldc_dring structures that refer
1491ae08745Sheppo  * to both imported and exported descriptor rings. If it is a exported
1501ae08745Sheppo  * descriptor ring, it then points to memory handle/memseg corresponding to
1511ae08745Sheppo  * the region of memory associated with the descriptor ring.
1521ae08745Sheppo  *
1531ae08745Sheppo  *     +----------+   +----------+   +----------+
1541ae08745Sheppo  *     | ldc_chan |-->| ldc_chan |-->| ldc_chan |-->....
1551ae08745Sheppo  *     +----------+   +----------+   +----------+
1561ae08745Sheppo  *       |  |  |
1571ae08745Sheppo  *       |  |  |
1581ae08745Sheppo  *       |  |  |      +-----------+     +-----------+
1591ae08745Sheppo  *       |  |  +----->| ldc_dring |---->| ldc_dring |---->......
1601ae08745Sheppo  *       |  |         +-----------+     +-----------+
1611ae08745Sheppo  *       |  |               |
1621ae08745Sheppo  *       |  |               +----------------------------+
1631ae08745Sheppo  *       |  |                                            |
1641ae08745Sheppo  *       |  |                                            v
1651ae08745Sheppo  *       |  |      +----------+     +----------+     +----------+
1661ae08745Sheppo  *       |  +----->| ldc_mhdl |---->| ldc_mhdl |---->| ldc_mhdl |---> ....
1671ae08745Sheppo  *       |         +----------+     +----------+     +----------+
1681ae08745Sheppo  *       v                 |                             |
1691ae08745Sheppo  *  +----------+           |    +------------+           |    +------------+
1701ae08745Sheppo  *  | ldc_mtbl |--+        +--->| ldc_memseg |-----+     +--->| ldc_memseg |
1711ae08745Sheppo  *  +----------+  |             +------------+     |          +------------+
1721ae08745Sheppo  *                |                   |            |            |       |
1731ae08745Sheppo  *                v                   v            v            |       v
1741ae08745Sheppo  *     +--------------+         +----------+  +--------+        |   +--------+
1751ae08745Sheppo  *     | ldc_mte_slot |<--------| ldc_page |  | cookie |        |   | cookie |
1761ae08745Sheppo  *     +--------------+         +----------+  +--------+        |   +--------+
1771ae08745Sheppo  *     | ldc_mte_slot |<--------| ldc_page |  | cookie |        v
1781ae08745Sheppo  *     +--------------+         +----------+  +--------+   +----------+
1791ae08745Sheppo  *     | ldc_mte_slot |<-----------------------------------| ldc_page |
1801ae08745Sheppo  *     +--------------+                                    +----------+
1811ae08745Sheppo  *     | ldc_mte_slot |
1821ae08745Sheppo  *     +--------------+
1831ae08745Sheppo  *     |    ......    |/ +------------+
1841ae08745Sheppo  *     +--------------+  |   entry    |
1851ae08745Sheppo  *     | ldc_mte_slot |  +------------+
1861ae08745Sheppo  *     +--------------+  | inv_cookie |
1871ae08745Sheppo  *                     \ +------------+
1881ae08745Sheppo  *
1891ae08745Sheppo  */
1901ae08745Sheppo 
1911ae08745Sheppo /*
1921ae08745Sheppo  * Message format of each packet sent over the LDC channel.
1931ae08745Sheppo  * Each packet is 64-bytes long.
1941ae08745Sheppo  *
1951ae08745Sheppo  * Each packet that is sent over LDC can contain either data or acks.
1961ae08745Sheppo  * The type will reflect the contents. The len will contain in bytes
1971ae08745Sheppo  * the amount of data being sent. In the case of ACKs, the seqid and
1981ae08745Sheppo  * data fields will contain the SEQIDs of messages for which ACKs are
1991ae08745Sheppo  * being sent.
2001ae08745Sheppo  *
2011ae08745Sheppo  * Raw pkt format:
2021ae08745Sheppo  *
2031ae08745Sheppo  *          +------------------------------------------------------+
2041ae08745Sheppo  *  0 - 7   |                 data payload                         |
2051ae08745Sheppo  *          +------------------------------------------------------+
2061ae08745Sheppo  *
2071ae08745Sheppo  * Unreliable pkt format:
2081ae08745Sheppo  *
2091ae08745Sheppo  *          +------------------------------------------------------+
2101ae08745Sheppo  *      0   |          seqid          | env  | ctrl | stype | type |
2111ae08745Sheppo  *          +------------------------------------------------------+
2121ae08745Sheppo  *  1 - 7   |                 data payload                         |
2131ae08745Sheppo  *          +------------------------------------------------------+
2141ae08745Sheppo  *
2151ae08745Sheppo  * Reliable pkt format:
2161ae08745Sheppo  *
2171ae08745Sheppo  *          +------------------------------------------------------+
2181ae08745Sheppo  *      0   |            seqid        | env  | ctrl | stype | type |
2191ae08745Sheppo  *          +------------------------------------------------------+
2201ae08745Sheppo  *      1   |          ackid          |         unused             |
2211ae08745Sheppo  *          +------------------------------------------------------+
2221ae08745Sheppo  *  2 - 7   |                 data payload                         |
2231ae08745Sheppo  *          +------------------------------------------------------+
2241ae08745Sheppo  */
2251ae08745Sheppo 
2261ae08745Sheppo typedef struct ldc_msg {
2271ae08745Sheppo 	union {
2281ae08745Sheppo 		struct {
2291ae08745Sheppo 			uint8_t		_type;	/* Message type */
2301ae08745Sheppo 			uint8_t		_stype;	/* Message subtype */
2311ae08745Sheppo 			uint8_t		_ctrl;	/* Control/Error Message */
232*a704fb2dSToomas Soome 			uint8_t		_env;	/* Message Envelope */
2331ae08745Sheppo 			uint32_t	_seqid;	/* Sequence ID */
2341ae08745Sheppo 
2351ae08745Sheppo 			union {
2361ae08745Sheppo 				uint8_t	_ud[LDC_PAYLOAD_SIZE_UNRELIABLE];
2371ae08745Sheppo 						/* Unreliable data payload */
2381ae08745Sheppo 				struct {
2391ae08745Sheppo 					uint32_t _unused;	/* unused */
2401ae08745Sheppo 					uint32_t _ackid;	/* ACK ID */
2411ae08745Sheppo 					uint8_t	_rd[LDC_PAYLOAD_SIZE_RELIABLE];
2421ae08745Sheppo 						/* Reliable data payload */
2431ae08745Sheppo 				} _rl;
2441ae08745Sheppo 			} _data;
2451ae08745Sheppo 		} _tpkt;
2461ae08745Sheppo 
2471ae08745Sheppo 		uint8_t		_raw[LDC_PAYLOAD_SIZE_RAW];
2481ae08745Sheppo 	} _pkt;
2491ae08745Sheppo 
2501ae08745Sheppo } ldc_msg_t;
2511ae08745Sheppo 
2521ae08745Sheppo #define	raw		_pkt._raw
2531ae08745Sheppo #define	type		_pkt._tpkt._type
2541ae08745Sheppo #define	stype		_pkt._tpkt._stype
2551ae08745Sheppo #define	ctrl		_pkt._tpkt._ctrl
2561ae08745Sheppo #define	env		_pkt._tpkt._env
2571ae08745Sheppo #define	seqid		_pkt._tpkt._seqid
2581ae08745Sheppo #define	udata		_pkt._tpkt._data._ud
2591ae08745Sheppo #define	ackid		_pkt._tpkt._data._rl._ackid
2601ae08745Sheppo #define	rdata		_pkt._tpkt._data._rl._rd
2611ae08745Sheppo 
2621ae08745Sheppo /*
2631ae08745Sheppo  * LDC Map Table Entry (MTE)
2641ae08745Sheppo  *
2651ae08745Sheppo  *   6    6                               1    1  1
2661ae08745Sheppo  *  |3    0|                       psz|   3|   1| 0| 9| 8| 7|6|5|4|      0|
2671ae08745Sheppo  *  +------+--------------------------+----+----+--+--+--+--+-+-+-+-------+
2681ae08745Sheppo  *  | rsvd |           PFN            | 0  | 0  |CW|CR|IW|IR|X|W|R| pgszc |
2691ae08745Sheppo  *  +------+--------------------------+----+----+--+--+--+--+-+-+-+-------+
2701ae08745Sheppo  *  |                       hv invalidation cookie                        |
2711ae08745Sheppo  *  +---------------------------------------------------------------------+
2721ae08745Sheppo  */
2731ae08745Sheppo typedef union {
2741ae08745Sheppo 	struct {
2751ae08745Sheppo 		uint64_t	_rsvd2:8,	/* <63:56> reserved */
2761ae08745Sheppo 				rpfn:43,	/* <55:13> real pfn */
2771ae08745Sheppo 				_rsvd1:2,	/* <12:11> reserved */
2781ae08745Sheppo 				cw:1,		/* <10> copy write access */
2791ae08745Sheppo 				cr:1,		/* <9> copy read perm */
2801ae08745Sheppo 				iw:1,		/* <8> iommu write perm */
2811ae08745Sheppo 				ir:1,		/* <7> iommu read perm */
2821ae08745Sheppo 				x:1,		/* <6> execute perm */
2831ae08745Sheppo 				w:1,		/* <5> write perm */
2841ae08745Sheppo 				r:1,		/* <4> read perm */
2851ae08745Sheppo 				pgszc:4;	/* <3:0> pgsz code */
2861ae08745Sheppo 	} mte_bit;
2871ae08745Sheppo 
288*a704fb2dSToomas Soome 	uint64_t		ll;
2891ae08745Sheppo 
2901ae08745Sheppo } ldc_mte_t;
2911ae08745Sheppo 
2921ae08745Sheppo #define	mte_rpfn	mte_bit.rpfn
2931ae08745Sheppo #define	mte_cw		mte_bit.cw
2941ae08745Sheppo #define	mte_cr		mte_bit.cr
2951ae08745Sheppo #define	mte_iw		mte_bit.iw
2961ae08745Sheppo #define	mte_ir		mte_bit.ir
2971ae08745Sheppo #define	mte_x		mte_bit.x
2981ae08745Sheppo #define	mte_w		mte_bit.w
2991ae08745Sheppo #define	mte_r		mte_bit.r
3001ae08745Sheppo #define	mte_pgszc	mte_bit.pgszc
3011ae08745Sheppo 
3021ae08745Sheppo #define	MTE_BSZS_SHIFT(sz)	((sz) * 3)
303*a704fb2dSToomas Soome #define	MTEBYTES(sz)		(MMU_PAGESIZE << MTE_BSZS_SHIFT(sz))
304*a704fb2dSToomas Soome #define	MTEPAGES(sz)		(1 << MTE_BSZS_SHIFT(sz))
3051ae08745Sheppo #define	MTE_PAGE_SHIFT(sz)	(MMU_PAGESHIFT + MTE_BSZS_SHIFT(sz))
3061ae08745Sheppo #define	MTE_PAGE_OFFSET(sz)	(MTEBYTES(sz) - 1)
3071ae08745Sheppo #define	MTE_PAGEMASK(sz)	(~MTE_PAGE_OFFSET(sz))
3081ae08745Sheppo #define	MTE_PFNMASK(sz)		(~(MTE_PAGE_OFFSET(sz) >> MMU_PAGESHIFT))
3091ae08745Sheppo 
3101ae08745Sheppo /*
3111ae08745Sheppo  * LDC Map Table Slot
3121ae08745Sheppo  */
3131ae08745Sheppo typedef struct ldc_mte_slot {
3141ae08745Sheppo 	ldc_mte_t	entry;
3151ae08745Sheppo 	uint64_t	cookie;
3161ae08745Sheppo } ldc_mte_slot_t;
3171ae08745Sheppo 
3181ae08745Sheppo /*
3191ae08745Sheppo  * LDC Memory Map Table
3201ae08745Sheppo  *
3211ae08745Sheppo  * Each LDC has a memory map table it uses to list all the pages
3221ae08745Sheppo  * it exporting to its peer over the channel. This structure
3231ae08745Sheppo  * contains information about the map table and is pointed to
3241ae08745Sheppo  * by the ldc_chan structure.
3251ae08745Sheppo  */
3261ae08745Sheppo typedef struct ldc_mtbl {
3271ae08745Sheppo 	kmutex_t		lock;		/* Table lock */
3281ae08745Sheppo 	size_t			size;		/* Table size (in bytes) */
3291ae08745Sheppo 	uint64_t		next_entry;	/* Next entry to use */
3301ae08745Sheppo 	uint64_t		num_entries;	/* Num entries in table */
3311ae08745Sheppo 	uint64_t		num_avail;	/* Num of available entries */
3323af08d82Slm 	boolean_t		contigmem;	/* TRUE=Contig mem alloc'd */
3331ae08745Sheppo 	ldc_mte_slot_t		*table;		/* The table itself */
3341ae08745Sheppo } ldc_mtbl_t;
3351ae08745Sheppo 
3361ae08745Sheppo /*
3371ae08745Sheppo  * LDC page and memory segment information
3381ae08745Sheppo  */
3391ae08745Sheppo typedef struct ldc_page {
3401ae08745Sheppo 	uintptr_t		raddr;		/* Exported page RA */
3411ae08745Sheppo 	uint64_t		index;		/* Index in map table */
3421ae08745Sheppo 	ldc_mte_slot_t		*mte;		/* Map table entry */
3431ae08745Sheppo } ldc_page_t;
3441ae08745Sheppo 
3451ae08745Sheppo typedef struct ldc_memseg {
3461ae08745Sheppo 	caddr_t			vaddr;		/* Exported segment VA */
3471ae08745Sheppo 	uintptr_t		raddr;		/* Exported segment VA */
3481ae08745Sheppo 	size_t			size;		/* Exported segment size */
3491ae08745Sheppo 	uint64_t		npages;		/* Number of pages */
3501ae08745Sheppo 	ldc_page_t		*pages;		/* Array of exported pages */
3511ae08745Sheppo 	uint32_t		ncookies;	/* Number of cookies */
3521ae08745Sheppo 	ldc_mem_cookie_t	*cookies;
3531ae08745Sheppo 	uint64_t		next_cookie;	/* Index to next cookie */
3541ae08745Sheppo } ldc_memseg_t;
3551ae08745Sheppo 
3561ae08745Sheppo /*
3571ae08745Sheppo  * LDC Cookie address format
3581ae08745Sheppo  *
3591ae08745Sheppo  *   6       6          m+n
3601ae08745Sheppo  *  |3|      0|          |                  m|                  0|
3611ae08745Sheppo  *  +-+-------+----------+-------------------+-------------------+
3621ae08745Sheppo  *  |X| pgszc |   rsvd   |      table_idx    |     page_offset   |
3631ae08745Sheppo  *  +-+-------+----------+-------------------+-------------------+
3641ae08745Sheppo  */
3651ae08745Sheppo #define	LDC_COOKIE_PGSZC_MASK	0x7
3661ae08745Sheppo #define	LDC_COOKIE_PGSZC_SHIFT	60
3671ae08745Sheppo 
3681ae08745Sheppo /*
3691ae08745Sheppo  * LDC Memory handle
3701ae08745Sheppo  */
3711ae08745Sheppo typedef struct ldc_chan ldc_chan_t;
3721ae08745Sheppo 
3731ae08745Sheppo typedef struct ldc_mhdl {
3741ae08745Sheppo 	kmutex_t		lock;		/* Mutex for memory handle */
3751ae08745Sheppo 	ldc_mstatus_t		status;		/* Memory map status */
3761ae08745Sheppo 
3771ae08745Sheppo 	uint8_t			mtype;		/* Type of sharing */
3781ae08745Sheppo 	uint8_t			perm;		/* Access permissions */
3791ae08745Sheppo 	boolean_t		myshadow;	/* TRUE=alloc'd shadow mem */
3801ae08745Sheppo 
3811ae08745Sheppo 	ldc_chan_t		*ldcp;		/* Pointer to channel struct */
3821ae08745Sheppo 	ldc_memseg_t		*memseg;	/* Bound memory segment */
3831ae08745Sheppo 	struct ldc_mhdl		*next;		/* Next memory handle */
3841ae08745Sheppo } ldc_mhdl_t;
3851ae08745Sheppo 
3861ae08745Sheppo /*
3871ae08745Sheppo  * LDC Descriptor rings
3881ae08745Sheppo  */
3891ae08745Sheppo 
3901ae08745Sheppo typedef struct ldc_dring {
3911ae08745Sheppo 	kmutex_t		lock;		/* Desc ring lock */
3921ae08745Sheppo 	ldc_mstatus_t		status;		/* Desc ring status */
3931ae08745Sheppo 
3941ae08745Sheppo 	uint32_t		dsize;		/* Descriptor size */
3951ae08745Sheppo 	uint32_t		length;		/* Descriptor ring length */
3961ae08745Sheppo 	uint64_t		size;		/* Desc ring size (in bytes) */
3971ae08745Sheppo 	caddr_t			base;		/* Descriptor ring base addr */
3981ae08745Sheppo 
3991ae08745Sheppo 	ldc_chan_t		*ldcp;		/* Pointer to bound channel */
4001ae08745Sheppo 	ldc_mem_handle_t	mhdl;		/* Mem handle to desc ring */
4011ae08745Sheppo 
4021ae08745Sheppo 	struct ldc_dring	*ch_next;	/* Next dring in channel */
403*a704fb2dSToomas Soome 	struct ldc_dring	*next;		/* Next dring overall */
4041ae08745Sheppo 
4051ae08745Sheppo } ldc_dring_t;
4061ae08745Sheppo 
4071ae08745Sheppo 
4081ae08745Sheppo /*
4091ae08745Sheppo  * Channel specific information is kept in a separate
4101ae08745Sheppo  * structure. These are then stored on a array indexed
4111ae08745Sheppo  * by the channel number.
4121ae08745Sheppo  */
4131ae08745Sheppo struct ldc_chan {
4141ae08745Sheppo 	ldc_chan_t	*next;		/* Next channel */
4151ae08745Sheppo 
4161ae08745Sheppo 	kmutex_t	lock;		/* Channel lock */
4171ae08745Sheppo 	uint64_t	id;		/* Channel ID */
4181ae08745Sheppo 	ldc_status_t	status;		/* Channel status */
4191ae08745Sheppo 	uint32_t	tstate;		/* Channel transport state */
4201ae08745Sheppo 	uint32_t	hstate;		/* Channel transport handshake state */
4211ae08745Sheppo 
4221ae08745Sheppo 	ldc_dev_t	devclass;	/* Associated device class */
4231ae08745Sheppo 	uint64_t	devinst;	/* Associated device instance */
4241ae08745Sheppo 	ldc_mode_t	mode;		/* Channel mode */
4251ae08745Sheppo 
4263af08d82Slm 	uint64_t	mtu;		/* Max TU size */
4271ae08745Sheppo 
4281ae08745Sheppo 	ldc_ver_t	version;	/* Channel version */
4291ae08745Sheppo 	uint32_t	next_vidx;	/* Next version to match */
4301ae08745Sheppo 
4311ae08745Sheppo 	uint_t		(*cb)(uint64_t event, caddr_t arg);
4321ae08745Sheppo 	caddr_t		cb_arg;		/* Channel callback and arg */
4331ae08745Sheppo 	boolean_t	cb_inprogress;	/* Channel callback in progress */
4341ae08745Sheppo 	boolean_t	cb_enabled;	/* Channel callbacks are enabled */
4351ae08745Sheppo 
4363af08d82Slm 	uint8_t		tx_intr_state;	/* Tx interrupt state */
4373af08d82Slm 	uint8_t		rx_intr_state;	/* Rx interrupt state */
4381ae08745Sheppo 
439d10e4ef2Snarayan 	kmutex_t	tx_lock;	/* Transmit lock */
4401ae08745Sheppo 	uint64_t	tx_q_entries;	/* Num entries in transmit queue */
4411ae08745Sheppo 	uint64_t	tx_q_va;	/* Virtual addr of transmit queue */
4421ae08745Sheppo 	uint64_t	tx_q_ra;	/* Real addr of transmit queue */
4431ae08745Sheppo 	uint64_t	tx_head;	/* Tx queue head */
4441ae08745Sheppo 	uint64_t	tx_ackd_head;	/* Tx queue ACKd head (Reliable) */
4451ae08745Sheppo 	uint64_t	tx_tail;	/* Tx queue tail */
4461ae08745Sheppo 
4471ae08745Sheppo 	uint64_t	rx_q_entries;	/* Num entries in receive queue */
4481ae08745Sheppo 	uint64_t	rx_q_va;	/* Virtual addr of receive queue */
4491ae08745Sheppo 	uint64_t	rx_q_ra;	/* Real addr of receive queue */
4501ae08745Sheppo 
45158283286Sha 	uint64_t	rx_dq_entries;	/* Num entries in the data queue */
45258283286Sha 	uint64_t	rx_dq_va;	/* Virtual addr of the data queue */
45358283286Sha 	uint64_t	rx_dq_head;	/* Receive data queue head */
45458283286Sha 	uint64_t	rx_dq_tail;	/* Receive data queue tail */
45558283286Sha 	uint64_t	rx_ack_head;	/* Receive data ACK peek head ptr */
45658283286Sha 
4571ae08745Sheppo 	uint64_t	link_state;	/* Underlying HV channel state */
4581ae08745Sheppo 
4591ae08745Sheppo 	ldc_mtbl_t	*mtbl;		/* Memory table used by channel */
4601ae08745Sheppo 	ldc_mhdl_t	*mhdl_list;	/* List of memory handles */
4611ae08745Sheppo 	kmutex_t	mlist_lock;	/* Mem handle list lock */
4621ae08745Sheppo 
4631ae08745Sheppo 	ldc_dring_t	*exp_dring_list; /* Exported desc ring list */
4641ae08745Sheppo 	kmutex_t	exp_dlist_lock;	/* Lock for exported desc ring list */
4651ae08745Sheppo 	ldc_dring_t	*imp_dring_list; /* Imported desc ring list */
4661ae08745Sheppo 	kmutex_t	imp_dlist_lock;	/* Lock for imported desc ring list */
4671ae08745Sheppo 
4681ae08745Sheppo 	uint8_t		pkt_payload;	/* Size of packet payload */
4691ae08745Sheppo 
4701ae08745Sheppo 	uint32_t	last_msg_snt;	/* Seqid of last packet sent */
4711ae08745Sheppo 	uint32_t	last_ack_rcd;	/* Seqid of last ACK recd */
4721ae08745Sheppo 	uint32_t	last_msg_rcd;	/* Seqid of last packet received */
4731ae08745Sheppo 
4741ae08745Sheppo 	uint32_t	stream_remains;	/* Number of bytes in stream */
4751ae08745Sheppo 					/* packet buffer */
4761ae08745Sheppo 	uint32_t	stream_offset;	/* Offset into packet buffer for */
4771ae08745Sheppo 					/* next read */
4781ae08745Sheppo 	uint8_t		*stream_bufferp; /* Stream packet buffer */
4791ae08745Sheppo 
4801ae08745Sheppo 	int		(*read_p)(ldc_chan_t *ldcp, caddr_t bufferp,
4811ae08745Sheppo 				size_t *sizep);
4821ae08745Sheppo 	int		(*write_p)(ldc_chan_t *ldcp, caddr_t bufferp,
4831ae08745Sheppo 				size_t *sizep);
48458283286Sha 
48558283286Sha 	uint64_t	(*readq_get_state)(ldc_chan_t *ldcp, uint64_t *head,
48658283286Sha 				uint64_t *tail, uint64_t *link_state);
48758283286Sha 
48858283286Sha 	int		(*readq_set_head)(ldc_chan_t *ldcp, uint64_t head);
4891ae08745Sheppo };
4901ae08745Sheppo 
4911ae08745Sheppo 
4921ae08745Sheppo /*
4931ae08745Sheppo  * LDC module soft state structure
4941ae08745Sheppo  */
4951ae08745Sheppo typedef struct ldc_soft_state {
496*a704fb2dSToomas Soome 	kmutex_t	lock;		/* Protects ldc_soft_state_t  */
4971ae08745Sheppo 	ldc_cnex_t	cinfo;		/* channel nexus info */
4981ae08745Sheppo 	uint64_t	channel_count;	/* Number of channels */
4991ae08745Sheppo 	uint64_t	channels_open;	/* Number of open channels */
500*a704fb2dSToomas Soome 	ldc_chan_t	*chan_list;	/* List of LDC endpoints */
5011ae08745Sheppo 	ldc_dring_t	*dring_list;	/* Descriptor rings (for export) */
5024bac2208Snarayan 
5034bac2208Snarayan 	kmem_cache_t	*memhdl_cache;	/* Memory handle cache */
5044bac2208Snarayan 	kmem_cache_t	*memseg_cache;	/* Memory segment cache */
50534f94fbcSWENTAO YANG 
50634f94fbcSWENTAO YANG 	uint64_t	mapin_size;		/* Total mapin sz per guest  */
5071ae08745Sheppo } ldc_soft_state_t;
5081ae08745Sheppo 
50920ae46ebSha 
51020ae46ebSha /*
51120ae46ebSha  * Debugging Utilities
51220ae46ebSha  */
51320ae46ebSha #define	DBG_ALL_LDCS	-1
51420ae46ebSha #ifdef	DEBUG
51520ae46ebSha #define	D1		\
51620ae46ebSha if (ldcdbg & 0x01)	\
51720ae46ebSha 	ldcdebug
51820ae46ebSha #define	D2		\
51920ae46ebSha if (ldcdbg & 0x02)	\
52020ae46ebSha 	ldcdebug
52120ae46ebSha #define	DWARN		\
52220ae46ebSha if (ldcdbg & 0x04)	\
52320ae46ebSha 	ldcdebug
52420ae46ebSha #else
525*a704fb2dSToomas Soome #define	D1(...)
526*a704fb2dSToomas Soome #define	D2(...)
527*a704fb2dSToomas Soome #define	DWARN(...)
52820ae46ebSha #endif
52920ae46ebSha 
5301ae08745Sheppo #ifdef __cplusplus
5311ae08745Sheppo }
5321ae08745Sheppo #endif
5331ae08745Sheppo 
5341ae08745Sheppo #endif /* _LDC_IMPL_H */
535