xref: /illumos-gate/usr/src/uts/sun4v/sys/vio_util.h (revision edb348833aaacfa1176e502ad38875fd0b2717ab)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_VIO_UTIL_H
28 #define	_VIO_UTIL_H
29 
30 #include <sys/stream.h>
31 #include <sys/vio_mailbox.h>
32 
33 #ifdef	__cplusplus
34 extern "C" {
35 #endif
36 
37 /*
38  * Helper routines for the Logical Domains (LDoms) drivers
39  *
40  * Note: The contents of this file are private to the implementation of the
41  * LDoms drivers and are subject to change at any time without notice.
42  */
43 
44 /*
45  * A message is composed of three structures. A message block (mblk_t), a
46  * data block to which it points and a data buffer. desballoc(9F) allows
47  * the caller to specify the data buffer and a free function which will
48  * be invoked when freeb(9F) is called to free the message. This allows
49  * the user to reclaim and reuse the data buffer, as opposed to using
50  * allocb(9F) where the message block, data block and data buffer are
51  * all destroyed by freeb().
52  *
53  * Note that even with desballoc the message and data blocks are destroyed
54  * by freeb() and must be recreated. It is only the data buffer which is
55  * preserved.
56  *
57  * The caller first creates a pool of vio_mblk_t's by invoking
58  * vio_create_mblks() and specifying the number of mblks and the size of the
59  * associated data buffers. Each vio_mblk_t contains a pointer to the
60  * mblk_t, a pointer to the data buffer and a function pointer to the
61  * reclaim function. The caller is returned a pointer to the pool which is
62  * used in subsequent allocation/destroy requests.
63  *
64  * The pool is managed as a circular queue with a head and tail pointer.
65  * Allocation requests result in the head index being incremented, mblks
66  * being returned to the pool result in the tail pointer being incremented.
67  *
68  * The pool can only be destroyed when all the mblks have been returned. It
69  * is the responsibility of the caller to ensure that all vio_allocb()
70  * requests have been completed before the pool is destroyed.
71  *
72  *
73  * vio_mblk_pool_t
74  * +-------------+
75  * |    tail     |--------------------------------+
76  * +-------------+                                |
77  * |    head     |--------+                       |
78  * +-------------+        |                       |
79  * ...............        V                       V
80  * +-------------+     +-------+-------+-------+-------+
81  * |    quep     |---->| vmp_t | vmp_t | vmp_t | vmp_t |
82  * +-------------+     +-------+-------+-------+-------+
83  * |             |         |       |       |       |
84  * ...                     |       |       |       |   +------------+
85  *                         |       |       |       +-->| data block |
86  *                         |       |       |           +------------+
87  *                         |       |       |   +------------+
88  *                         |       |       +-->| data block |
89  *                         |       |           +------------+
90  *                         |       |   +------------+
91  *                         |       +-->| data block |
92  *                         |           +------------+
93  *                         |   +------------+
94  *                         +-->| data block |
95  *                             +------------+
96  *
97  */
98 
99 /* mblk pool flags */
100 #define	VMPL_FLAG_DESTROYING	0x1	/* pool is being destroyed */
101 #define	VMPL_FLAG_CLIENT_DATA	0x2	/* pool data area provided by client */
102 
103 struct vio_mblk_pool;
104 
105 /* VIO mblk states */
106 typedef enum vio_mblk_state {
107 	VIO_MBLK_FREE = 0x1,		/* free to use */
108 	VIO_MBLK_BOUND = 0x2,		/* allocated/bound to a descriptor */
109 	VIO_MBLK_HAS_DATA = 0x4		/* contains valid data */
110 } vio_mblk_state_t;
111 
112 typedef struct vio_mblk {
113 	uint8_t			*datap;		/* data buffer */
114 	mblk_t			*mp;		/* mblk using datap */
115 	frtn_t			reclaim;	/* mblk reclaim routine */
116 	struct vio_mblk_pool 	*vmplp;		/* pointer to parent pool */
117 	uint_t			index;		/* index in the pool */
118 	vio_mblk_state_t	state;		/* state flags */
119 } vio_mblk_t;
120 
121 typedef struct vio_mblk_pool {
122 	struct vio_mblk_pool	*nextp;	/* next in a list */
123 	kmutex_t		hlock;	/* sync access to head */
124 	kmutex_t		tlock;	/* sync access to tail */
125 	vio_mblk_t		*basep;	/* base pointer to pool of vio_mblks */
126 	vio_mblk_t		**quep; /* queue of free vio_mblks */
127 	uint8_t			*datap; /* rx data buffer area */
128 	uint32_t		head;	/* queue head */
129 	uint32_t		tail;	/* queue tail */
130 	uint64_t		quelen;	/* queue len (# mblks) */
131 	uint64_t		quemask; /* quelen - 1 */
132 	size_t			mblk_size; /* data buf size of each mblk */
133 	uint32_t		flag;	/* pool-related flags */
134 } vio_mblk_pool_t;
135 
136 typedef struct vio_multi_pool {
137 	uint32_t		num_pools;	/* no. of vio mblk pools */
138 	uint32_t		tbsz;		/* allocated buffer size */
139 	uint32_t		*bufsz_tbl;	/* buffer sizes table */
140 	uint32_t		*nbuf_tbl;	/* no. of buffers table */
141 	vio_mblk_pool_t		**vmpp;		/* vio mblk pools */
142 } vio_multi_pool_t;
143 
144 #define	VIO_MBLK_DATA_OFF(vmp)	((vmp)->datap - ((vmp)->vmplp)->datap)
145 
146 int vio_create_mblks(uint64_t num_mblks,
147 			size_t mblk_size, uint8_t *mblk_datap,
148 			vio_mblk_pool_t **poolp);
149 int vio_destroy_mblks(vio_mblk_pool_t *);
150 vio_mblk_t *vio_allocb(vio_mblk_pool_t *);
151 void vio_freeb(void *arg);
152 int vio_init_multipools(vio_multi_pool_t *vmultip, int num_pools, ...);
153 void vio_destroy_multipools(vio_multi_pool_t *vmultip, vio_mblk_pool_t **fvmp);
154 vio_mblk_t *vio_multipool_allocb(vio_multi_pool_t *vmultip, size_t size);
155 int vio_check_pending_pools(vio_multi_pool_t *vmultip);
156 void vio_clobber_pool(vio_mblk_pool_t *vmplp);
157 
158 /* VIO versioning helpers */
159 #define	VIO_VER_IS_NEGOTIATED(ver, maj, min)		\
160 	((ver.major == (maj)) && (ver.minor == (min)))
161 
162 boolean_t	vio_ver_is_supported(vio_ver_t ver, uint16_t maj, uint16_t min);
163 
164 #ifdef	__cplusplus
165 }
166 #endif
167 
168 #endif	/* _VIO_UTIL_H */
169