1b494511aSVenki Rajagopalan /*
2b494511aSVenki Rajagopalan  * CDDL HEADER START
3b494511aSVenki Rajagopalan  *
4b494511aSVenki Rajagopalan  * The contents of this file are subject to the terms of the
5b494511aSVenki Rajagopalan  * Common Development and Distribution License (the "License").
6b494511aSVenki Rajagopalan  * You may not use this file except in compliance with the License.
7b494511aSVenki Rajagopalan  *
8b494511aSVenki Rajagopalan  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9b494511aSVenki Rajagopalan  * or http://www.opensolaris.org/os/licensing.
10b494511aSVenki Rajagopalan  * See the License for the specific language governing permissions
11b494511aSVenki Rajagopalan  * and limitations under the License.
12b494511aSVenki Rajagopalan  *
13b494511aSVenki Rajagopalan  * When distributing Covered Code, include this CDDL HEADER in each
14b494511aSVenki Rajagopalan  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15b494511aSVenki Rajagopalan  * If applicable, add the following below this CDDL HEADER, with the
16b494511aSVenki Rajagopalan  * fields enclosed by brackets "[]" replaced with your own identifying
17b494511aSVenki Rajagopalan  * information: Portions Copyright [yyyy] [name of copyright owner]
18b494511aSVenki Rajagopalan  *
19b494511aSVenki Rajagopalan  * CDDL HEADER END
20b494511aSVenki Rajagopalan  */
21b494511aSVenki Rajagopalan 
22b494511aSVenki Rajagopalan /*
23b494511aSVenki Rajagopalan  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24b494511aSVenki Rajagopalan  */
25b494511aSVenki Rajagopalan 
26fd826efaSJohn Levon /*
27fd826efaSJohn Levon  * Copyright 2019, Joyent, Inc.
28fd826efaSJohn Levon  */
29fd826efaSJohn Levon 
30b494511aSVenki Rajagopalan #ifndef _SYS_IB_EOIB_EIB_IMPL_H
31b494511aSVenki Rajagopalan #define	_SYS_IB_EOIB_EIB_IMPL_H
32b494511aSVenki Rajagopalan 
33b494511aSVenki Rajagopalan #ifdef __cplusplus
34b494511aSVenki Rajagopalan extern "C" {
35b494511aSVenki Rajagopalan #endif
36b494511aSVenki Rajagopalan 
37b494511aSVenki Rajagopalan #include <sys/ddi.h>
38b494511aSVenki Rajagopalan #include <sys/mac.h>
39b494511aSVenki Rajagopalan #include <sys/sunddi.h>
40b494511aSVenki Rajagopalan #include <sys/varargs.h>
41b494511aSVenki Rajagopalan #include <sys/vlan.h>
42b494511aSVenki Rajagopalan #include <sys/ib/ibtl/ibti.h>
43b494511aSVenki Rajagopalan #include <sys/ib/ibtl/ibvti.h>
44b494511aSVenki Rajagopalan #include <sys/ib/ib_pkt_hdrs.h>
45b494511aSVenki Rajagopalan 
46b494511aSVenki Rajagopalan #include <sys/ib/clients/eoib/fip.h>
47b494511aSVenki Rajagopalan #include <sys/ib/clients/eoib/eib.h>
48b494511aSVenki Rajagopalan 
49b494511aSVenki Rajagopalan /*
50b494511aSVenki Rajagopalan  * Driver specific constants
51b494511aSVenki Rajagopalan  */
52b494511aSVenki Rajagopalan #define	EIB_E_SUCCESS			0
53b494511aSVenki Rajagopalan #define	EIB_E_FAILURE			-1
54b494511aSVenki Rajagopalan #define	EIB_MAX_LINE			128
55b494511aSVenki Rajagopalan #define	EIB_MAX_SGL			59
56b494511aSVenki Rajagopalan #define	EIB_MAX_POST_MULTIPLE		4
57b494511aSVenki Rajagopalan #define	EIB_MAX_PAYLOAD_HDR_SZ		160
58b494511aSVenki Rajagopalan #define	EIB_TX_COPY_THRESH		4096	/* greater than mtu */
59b494511aSVenki Rajagopalan #define	EIB_MAX_VNICS			64	/* do not change this */
60b494511aSVenki Rajagopalan #define	EIB_LOGIN_TIMEOUT_USEC		8000000
61b494511aSVenki Rajagopalan #define	EIB_RWR_CHUNK_SZ		8
62b494511aSVenki Rajagopalan #define	EIB_IPHDR_ALIGN_ROOM		32
63b494511aSVenki Rajagopalan #define	EIB_IP_HDR_ALIGN		2
64b494511aSVenki Rajagopalan #define	EIB_MAX_RX_PKTS_ONINTR		0x800
65b494511aSVenki Rajagopalan #define	EIB_MAX_LOGIN_ATTEMPTS		3
66b494511aSVenki Rajagopalan #define	EIB_MAX_VHUB_TBL_ATTEMPTS	3
67b494511aSVenki Rajagopalan #define	EIB_MAX_KA_ATTEMPTS		3
68b494511aSVenki Rajagopalan #define	EIB_MAX_ATTEMPTS		10
69b494511aSVenki Rajagopalan #define	EIB_DELAY_HALF_SECOND		500000
70b494511aSVenki Rajagopalan #define	EIB_GRH_SZ			(sizeof (ib_grh_t))
71b494511aSVenki Rajagopalan 
72b494511aSVenki Rajagopalan /*
73b494511aSVenki Rajagopalan  * Debug messages
74b494511aSVenki Rajagopalan  */
75b494511aSVenki Rajagopalan #define	EIB_MSGS_CRIT		0x01
76b494511aSVenki Rajagopalan #define	EIB_MSGS_ERR		0x02
77b494511aSVenki Rajagopalan #define	EIB_MSGS_WARN		0x04
78b494511aSVenki Rajagopalan #define	EIB_MSGS_DEBUG		0x08
79b494511aSVenki Rajagopalan #define	EIB_MSGS_ARGS		0x10
80b494511aSVenki Rajagopalan #define	EIB_MSGS_PKT		0x20
81b494511aSVenki Rajagopalan #define	EIB_MSGS_VERBOSE	0x40
82b494511aSVenki Rajagopalan #define	EIB_MSGS_DEFAULT	(EIB_MSGS_CRIT | EIB_MSGS_ERR | EIB_MSGS_WARN)
83b494511aSVenki Rajagopalan 
84b494511aSVenki Rajagopalan #define	EIB_LOGSZ_DEFAULT	0x20000
85b494511aSVenki Rajagopalan 
86b494511aSVenki Rajagopalan #define	EIB_DPRINTF_CRIT	eib_dprintf_crit
87b494511aSVenki Rajagopalan #define	EIB_DPRINTF_ERR		eib_dprintf_err
88b494511aSVenki Rajagopalan #define	EIB_DPRINTF_WARN	eib_dprintf_warn
89b494511aSVenki Rajagopalan #ifdef EIB_DEBUG
90b494511aSVenki Rajagopalan #define	EIB_DPRINTF_DEBUG	eib_dprintf_debug
91b494511aSVenki Rajagopalan #define	EIB_DPRINTF_ARGS	eib_dprintf_args
92b494511aSVenki Rajagopalan #define	EIB_DPRINTF_PKT		eib_dprintf_pkt
93b494511aSVenki Rajagopalan #define	EIB_DPRINTF_VERBOSE	eib_dprintf_verbose
94b494511aSVenki Rajagopalan #else
95*679c9deaSJohn Levon #define	EIB_DPRINTF_DEBUG(...)	(void)(0)
96*679c9deaSJohn Levon #define	EIB_DPRINTF_ARGS(...)	(void)(0)
97*679c9deaSJohn Levon #define	EIB_DPRINTF_PKT(...)	(void)(0)
98*679c9deaSJohn Levon #define	EIB_DPRINTF_VERBOSE(...) (void)(0)
99b494511aSVenki Rajagopalan #endif
100b494511aSVenki Rajagopalan 
101b494511aSVenki Rajagopalan /*
102b494511aSVenki Rajagopalan  *  EoIB threads to provide various services
103b494511aSVenki Rajagopalan  */
104b494511aSVenki Rajagopalan #define	EIB_EVENTS_HDLR		"eib_events_handler"
105b494511aSVenki Rajagopalan #define	EIB_RWQES_REFILLER	"eib_rwqes_refiller"
106b494511aSVenki Rajagopalan #define	EIB_VNIC_CREATOR	"eib_vnic_creator"
107b494511aSVenki Rajagopalan #define	EIB_TXWQES_MONITOR	"eib_txwqe_monitor"
108b494511aSVenki Rajagopalan #define	EIB_LSOBUFS_MONITOR	"eib_lsobufs_monitor"
109b494511aSVenki Rajagopalan 
110b494511aSVenki Rajagopalan /*
111b494511aSVenki Rajagopalan  * Macro for finding the least significant bit set in a 64-bit unsigned int
112b494511aSVenki Rajagopalan  */
113b494511aSVenki Rajagopalan #define	EIB_FIND_LSB_SET(val64)	eib_setbit_mod67[((-(val64) & (val64)) % 67)]
114b494511aSVenki Rajagopalan 
115b494511aSVenki Rajagopalan /*
116b494511aSVenki Rajagopalan  * LSO buffers
117b494511aSVenki Rajagopalan  *
118b494511aSVenki Rajagopalan  * Under normal circumstances we should never need to use any buffer
119b494511aSVenki Rajagopalan  * that's larger than MTU.  Unfortunately, IB HCA has limitations
120b494511aSVenki Rajagopalan  * on the length of SGL that are much smaller than those for regular
121b494511aSVenki Rajagopalan  * ethernet NICs.  Since the network layer doesn't care to limit the
122b494511aSVenki Rajagopalan  * number of mblk fragments in any send mp chain, we end up having to
123b494511aSVenki Rajagopalan  * use these larger buffers occasionally.
124b494511aSVenki Rajagopalan  */
125b494511aSVenki Rajagopalan #define	EIB_LSO_MAXLEN			65536
126b494511aSVenki Rajagopalan #define	EIB_LSO_BUFSZ			8192
127b494511aSVenki Rajagopalan #define	EIB_LSO_NUM_BUFS		1024
128b494511aSVenki Rajagopalan #define	EIB_LSO_FREE_BUFS_THRESH	(EIB_LSO_NUM_BUFS >> 5)
129b494511aSVenki Rajagopalan 
130b494511aSVenki Rajagopalan typedef struct eib_lsobuf_s {
131b494511aSVenki Rajagopalan 	struct eib_lsobuf_s *lb_next;
132b494511aSVenki Rajagopalan 	uint8_t		*lb_buf;
133b494511aSVenki Rajagopalan 	int		lb_isfree;
134b494511aSVenki Rajagopalan } eib_lsobuf_t;
135b494511aSVenki Rajagopalan 
136b494511aSVenki Rajagopalan typedef struct eib_lsobkt_s {
137b494511aSVenki Rajagopalan 	kmutex_t	bk_lock;
138b494511aSVenki Rajagopalan 	kcondvar_t	bk_cv;
139b494511aSVenki Rajagopalan 	uint_t		bk_status;
140b494511aSVenki Rajagopalan 	uint8_t		*bk_mem;
141b494511aSVenki Rajagopalan 	eib_lsobuf_t	*bk_bufl;
142b494511aSVenki Rajagopalan 	eib_lsobuf_t	*bk_free_head;
143b494511aSVenki Rajagopalan 	ibt_mr_hdl_t	bk_mr_hdl;
144b494511aSVenki Rajagopalan 	ibt_lkey_t	bk_lkey;
145b494511aSVenki Rajagopalan 	uint_t		bk_nelem;
146b494511aSVenki Rajagopalan 	uint_t		bk_nfree;
147b494511aSVenki Rajagopalan } eib_lsobkt_t;
148b494511aSVenki Rajagopalan 
149b494511aSVenki Rajagopalan #define	EIB_LBUF_SHORT		0x1
150b494511aSVenki Rajagopalan #define	EIB_LBUF_MONITOR_DIE	0x2
151b494511aSVenki Rajagopalan 
152b494511aSVenki Rajagopalan /*
153b494511aSVenki Rajagopalan  * The admin partition is only used for sending login and logout messages
154b494511aSVenki Rajagopalan  * and receiving login acknowledgements from the gateway.  While packets
155b494511aSVenki Rajagopalan  * going out on several vlans at the same time could result in multiple
156b494511aSVenki Rajagopalan  * vnic creations happening at the same time (and therefore multiple login
157b494511aSVenki Rajagopalan  * packets), we serialize the vnic creation via the vnic creator thread, so
158b494511aSVenki Rajagopalan  * we shouldn't need a lot of send wqes or receive wqes.  Note also that we
159b494511aSVenki Rajagopalan  * keep the cq size request to slightly less than a 2^n boundary to allow
160b494511aSVenki Rajagopalan  * the alloc cq routine to return the closest 2^n boundary as the real cq
161b494511aSVenki Rajagopalan  * size without wasting too much memory.
162b494511aSVenki Rajagopalan  */
163b494511aSVenki Rajagopalan #define	EIB_ADMIN_MAX_SWQE	30
164b494511aSVenki Rajagopalan #define	EIB_ADMIN_MAX_RWQE	30
165b494511aSVenki Rajagopalan #define	EIB_ADMIN_CQ_SIZE	(EIB_ADMIN_MAX_SWQE + EIB_ADMIN_MAX_RWQE + 1)
166b494511aSVenki Rajagopalan 
167b494511aSVenki Rajagopalan /*
168b494511aSVenki Rajagopalan  * The control qp is per vhub partition, and is used to send and receive
169b494511aSVenki Rajagopalan  * vhub control messages such as vhub table request/response, vhub
170b494511aSVenki Rajagopalan  * update response and vnic alive messages.  While the vhub table response
171b494511aSVenki Rajagopalan  * and vhub update messages might take a few rwqes, the vhub table request
172b494511aSVenki Rajagopalan  * is made only once per vnic, and the vnic alive message is periodic
173b494511aSVenki Rajagopalan  * and uses a single swqe as well.  Per vnic, we should certainly not need
174b494511aSVenki Rajagopalan  * too many swqes/rwqes.
175b494511aSVenki Rajagopalan  */
176b494511aSVenki Rajagopalan #define	EIB_CTL_MAX_SWQE	30
177b494511aSVenki Rajagopalan #define	EIB_CTL_MAX_RWQE	30
178b494511aSVenki Rajagopalan #define	EIB_CTL_CQ_SIZE		(EIB_CTL_MAX_SWQE + EIB_CTL_MAX_RWQE + 1)
179b494511aSVenki Rajagopalan 
180b494511aSVenki Rajagopalan /*
181b494511aSVenki Rajagopalan  * For the vNIC's data channel, there are three items that are of importance:
182b494511aSVenki Rajagopalan  * the constraints defined below, the hca_max_chan_sz attribute and the value of
183b494511aSVenki Rajagopalan  * (hca_max_cq_sz - 1).  The maximum limit on swqe/rwqe is set to the minimum
184b494511aSVenki Rajagopalan  * of these three values.
185b494511aSVenki Rajagopalan  *
186b494511aSVenki Rajagopalan  * While the total number of RWQEs posted to the data channel of any vNIC will
187b494511aSVenki Rajagopalan  * not exceed EIB_DATA_MAX_RWQE, we also do not want to acquire and post all of
188b494511aSVenki Rajagopalan  * it during the data channel initialization, since that is a lot of wqes for
189b494511aSVenki Rajagopalan  * one vnic to consume when we don't even know if the vnic will need it at all.
190b494511aSVenki Rajagopalan  * We post an initial set of EIB_DATA_RWQE_BKT rwqes, and slowly post more and
191b494511aSVenki Rajagopalan  * more sets as we see them being consumed, until we hit the hard limit of
192b494511aSVenki Rajagopalan  * EIB_DATA_MAX_RWQE.
193b494511aSVenki Rajagopalan  */
194b494511aSVenki Rajagopalan #define	EIB_DATA_MAX_SWQE	4000
195b494511aSVenki Rajagopalan #define	EIB_DATA_MAX_RWQE	4000
196b494511aSVenki Rajagopalan #define	EIB_DATA_RWQE_BKT	512
197b494511aSVenki Rajagopalan 
198b494511aSVenki Rajagopalan /*
199b494511aSVenki Rajagopalan  * vNIC data channel CQ moderation parameters
200b494511aSVenki Rajagopalan  */
201b494511aSVenki Rajagopalan #define	EIB_TX_COMP_COUNT		10
202b494511aSVenki Rajagopalan #define	EIB_TX_COMP_USEC		300
203b494511aSVenki Rajagopalan #define	EIB_RX_COMP_COUNT		4
204b494511aSVenki Rajagopalan #define	EIB_RX_COMP_USEC		10
205b494511aSVenki Rajagopalan 
206b494511aSVenki Rajagopalan /*
207b494511aSVenki Rajagopalan  * qe_info masks (blk:ndx:type:flags)
208b494511aSVenki Rajagopalan  */
209b494511aSVenki Rajagopalan #define	EIB_WQEBLK_SHIFT		24
210b494511aSVenki Rajagopalan #define	EIB_WQEBLK_MASK			0xFF
211b494511aSVenki Rajagopalan #define	EIB_WQENDX_SHIFT		16
212b494511aSVenki Rajagopalan #define	EIB_WQENDX_MASK			0xFF
213b494511aSVenki Rajagopalan #define	EIB_WQETYP_SHIFT		8
214b494511aSVenki Rajagopalan #define	EIB_WQETYP_MASK			0xFF
215b494511aSVenki Rajagopalan #define	EIB_WQEFLGS_SHIFT		0
216b494511aSVenki Rajagopalan #define	EIB_WQEFLGS_MASK		0xFF
217b494511aSVenki Rajagopalan 
218b494511aSVenki Rajagopalan /*
219b494511aSVenki Rajagopalan  * Macros to get the bit fields from qe_info
220b494511aSVenki Rajagopalan  */
221b494511aSVenki Rajagopalan #define	EIB_WQE_BLK(info)	(((info) >> EIB_WQEBLK_SHIFT) & EIB_WQEBLK_MASK)
222b494511aSVenki Rajagopalan #define	EIB_WQE_NDX(info)	(((info) >> EIB_WQENDX_SHIFT) & EIB_WQENDX_MASK)
223b494511aSVenki Rajagopalan #define	EIB_WQE_TYPE(info)	(((info) >> EIB_WQETYP_SHIFT) & EIB_WQETYP_MASK)
224b494511aSVenki Rajagopalan #define	EIB_WQE_FLAGS(info)	((info) & EIB_WQEFLGS_MASK)
225b494511aSVenki Rajagopalan 
226b494511aSVenki Rajagopalan /*
227b494511aSVenki Rajagopalan  * Values for type and flags in qe_info
228b494511aSVenki Rajagopalan  */
229b494511aSVenki Rajagopalan #define	EIB_WQE_TX			0x1
230b494511aSVenki Rajagopalan #define	EIB_WQE_RX			0x2
231b494511aSVenki Rajagopalan 
232b494511aSVenki Rajagopalan /*
233b494511aSVenki Rajagopalan  * Flags for rx wqes/buffers
234b494511aSVenki Rajagopalan  */
235b494511aSVenki Rajagopalan #define	EIB_WQE_FLG_POSTED_TO_HCA	0x1
236b494511aSVenki Rajagopalan #define	EIB_WQE_FLG_WITH_NW		0x2
237b494511aSVenki Rajagopalan 
238b494511aSVenki Rajagopalan /*
239b494511aSVenki Rajagopalan  * Flags for tx wqes/buffers
240b494511aSVenki Rajagopalan  */
241b494511aSVenki Rajagopalan #define	EIB_WQE_FLG_BUFTYPE_LSO		0x4
242b494511aSVenki Rajagopalan #define	EIB_WQE_FLG_BUFTYPE_MAPPED	0x8
243b494511aSVenki Rajagopalan 
244b494511aSVenki Rajagopalan /*
245b494511aSVenki Rajagopalan  * Send/Recv workq entries
246b494511aSVenki Rajagopalan  */
247b494511aSVenki Rajagopalan typedef struct eib_wqe_s {
248b494511aSVenki Rajagopalan 	struct eib_wqe_pool_s	*qe_pool;
249b494511aSVenki Rajagopalan 	uint8_t			*qe_cpbuf;
250b494511aSVenki Rajagopalan 	uint8_t			*qe_payload_hdr;
251b494511aSVenki Rajagopalan 	uint_t			qe_bufsz;
252b494511aSVenki Rajagopalan 	uint_t			qe_info;
253b494511aSVenki Rajagopalan 	int			qe_vnic_inst;
254b494511aSVenki Rajagopalan 	ibt_ud_dest_hdl_t	qe_dest;
255b494511aSVenki Rajagopalan 	frtn_t			qe_frp;
256b494511aSVenki Rajagopalan 
257b494511aSVenki Rajagopalan 	mblk_t			*qe_mp;
258b494511aSVenki Rajagopalan 	ibt_mi_hdl_t		qe_iov_hdl;
259b494511aSVenki Rajagopalan 	ibt_all_wr_t		qe_wr;
260b494511aSVenki Rajagopalan 	ibt_wr_ds_t		qe_sgl;
261b494511aSVenki Rajagopalan 	ibt_wr_ds_t		qe_big_sgl[EIB_MAX_SGL];
262b494511aSVenki Rajagopalan 	struct eib_wqe_s	*qe_nxt_post;
263b494511aSVenki Rajagopalan 	struct eib_chan_s	*qe_chan;
264b494511aSVenki Rajagopalan } eib_wqe_t;
265b494511aSVenki Rajagopalan 
266b494511aSVenki Rajagopalan /*
267b494511aSVenki Rajagopalan  * The wqe in-use/free status in EoIB is managed via a 2-level bitmap
268b494511aSVenki Rajagopalan  * logic.
269b494511aSVenki Rajagopalan  *
270b494511aSVenki Rajagopalan  * Each set of 64 wqes (a "wqe block") is managed by a single 64-bit
271b494511aSVenki Rajagopalan  * integer bitmap.  The free status of a set of 64 such wqe blocks (a
272b494511aSVenki Rajagopalan  * "wqe pool") is managed by one 64-bit integer bitmap (if any wqe in
273b494511aSVenki Rajagopalan  * the wqe block is free, the bit in the map is 1, otherwise it is 0).
274b494511aSVenki Rajagopalan  *
275b494511aSVenki Rajagopalan  * The maximum pool size is 4096 wqes, but this can easily be extended
276b494511aSVenki Rajagopalan  * to support more wqes using additional pools of wqes.
277b494511aSVenki Rajagopalan  *
278b494511aSVenki Rajagopalan  * Note that an entire pool of wqes is allocated via a single allocation,
279b494511aSVenki Rajagopalan  * the wqe addresses in a pool are all contiguous.  The tx/rx copy buffers
280b494511aSVenki Rajagopalan  * for a wqe pool are also allocated via a single allocation.
281b494511aSVenki Rajagopalan  */
282b494511aSVenki Rajagopalan #define	EIB_BLKS_PER_POOL	64
283b494511aSVenki Rajagopalan #define	EIB_WQES_PER_BLK	64	/* do not change this */
284b494511aSVenki Rajagopalan #define	EIB_WQES_PER_POOL	(EIB_BLKS_PER_POOL * EIB_WQES_PER_BLK)
285b494511aSVenki Rajagopalan 
286b494511aSVenki Rajagopalan #define	EIB_WQE_SZ		(sizeof (eib_wqe_t))
287b494511aSVenki Rajagopalan #define	EIB_WQEBLK_SZ		(EIB_WQES_PER_BLK * EIB_WQE_SZ)
288b494511aSVenki Rajagopalan 
289b494511aSVenki Rajagopalan typedef struct eib_wqe_pool_s {
290b494511aSVenki Rajagopalan 	struct eib_wqe_pool_s	*wp_next;
291b494511aSVenki Rajagopalan 	struct eib_s		*wp_ss;
292b494511aSVenki Rajagopalan 	ib_vaddr_t		wp_vaddr;
293b494511aSVenki Rajagopalan 	ib_memlen_t		wp_memsz;
294b494511aSVenki Rajagopalan 	ibt_mr_hdl_t		wp_mr;
295b494511aSVenki Rajagopalan 	ibt_lkey_t		wp_lkey;
296b494511aSVenki Rajagopalan 	uint_t			wp_nfree_lwm;
297b494511aSVenki Rajagopalan 	int			wp_type;
298b494511aSVenki Rajagopalan 
299b494511aSVenki Rajagopalan 	kmutex_t		wp_lock;
300b494511aSVenki Rajagopalan 	kcondvar_t		wp_cv;
301b494511aSVenki Rajagopalan 	uint_t			wp_status;
302b494511aSVenki Rajagopalan 	uint_t			wp_nfree;
303b494511aSVenki Rajagopalan 	uint64_t		wp_free_blks;
304b494511aSVenki Rajagopalan 	uint64_t		wp_free_wqes[EIB_BLKS_PER_POOL];
305b494511aSVenki Rajagopalan 	struct eib_wqe_s	*wp_wqe;
306b494511aSVenki Rajagopalan } eib_wqe_pool_t;
307b494511aSVenki Rajagopalan 
308b494511aSVenki Rajagopalan /*
309b494511aSVenki Rajagopalan  * Values for wp_type
310b494511aSVenki Rajagopalan  */
311b494511aSVenki Rajagopalan #define	EIB_WP_TYPE_TX		0x1
312b494511aSVenki Rajagopalan #define	EIB_WP_TYPE_RX		0x2
313b494511aSVenki Rajagopalan 
314b494511aSVenki Rajagopalan /*
315b494511aSVenki Rajagopalan  * Values for wp_status (bit fields)
316b494511aSVenki Rajagopalan  */
317b494511aSVenki Rajagopalan #define	EIB_TXWQE_SHORT		0x1	/* only for tx wqe pool */
318b494511aSVenki Rajagopalan #define	EIB_TXWQE_MONITOR_DIE	0x2	/* only for tx wqe pool */
319b494511aSVenki Rajagopalan 
320b494511aSVenki Rajagopalan #define	EIB_RXWQE_SHORT		0x1	/* only for rx wqe pool */
321b494511aSVenki Rajagopalan 
322b494511aSVenki Rajagopalan /*
323b494511aSVenki Rajagopalan  * The low-water-mark is an indication of when wqe grabs for low-priority
324b494511aSVenki Rajagopalan  * qps should start to get refused (swqe grabs for control messages such
325b494511aSVenki Rajagopalan  * as keepalives and rwqe grabs for posting back to control qps will still
326b494511aSVenki Rajagopalan  * be allowed).  The high-water-mark is an indication of when normal
327b494511aSVenki Rajagopalan  * behavior should resume.
328b494511aSVenki Rajagopalan  */
329b494511aSVenki Rajagopalan #define	EIB_NFREE_SWQES_LWM	(EIB_WQES_PER_POOL / 64)	/* 1/64 */
330b494511aSVenki Rajagopalan #define	EIB_NFREE_SWQES_HWM	(EIB_WQES_PER_POOL / 32)	/* 1/32 */
331b494511aSVenki Rajagopalan #define	EIB_NFREE_RWQES_LWM	(EIB_WQES_PER_POOL / 10)	/* 10% */
332b494511aSVenki Rajagopalan #define	EIB_NFREE_RWQES_HWM	(EIB_WQES_PER_POOL / 5)		/* 20% */
333b494511aSVenki Rajagopalan 
334b494511aSVenki Rajagopalan /*
335b494511aSVenki Rajagopalan  * The "rwqes low" is used to determine when we should start using allocb()
336b494511aSVenki Rajagopalan  * to copy and send received mblks in the rx path.  It should be a little
337b494511aSVenki Rajagopalan  * above the rwqes low-water-mark, but less than the high-water-mark.
338b494511aSVenki Rajagopalan  */
339b494511aSVenki Rajagopalan #define	EIB_NFREE_RWQES_LOW	\
340b494511aSVenki Rajagopalan 	((EIB_NFREE_RWQES_LWM + EIB_NFREE_RWQES_HWM) / 2)
341b494511aSVenki Rajagopalan 
342b494511aSVenki Rajagopalan #define	EIB_WPRI_HI		1	/* for keepalive posts */
343b494511aSVenki Rajagopalan #define	EIB_WPRI_LO		2	/* for all other posts */
344b494511aSVenki Rajagopalan 
345b494511aSVenki Rajagopalan /*
346b494511aSVenki Rajagopalan  * Multicast GID Layout: the multicast gid is specified in big-endian
347b494511aSVenki Rajagopalan  * representation, as a collection of different-sized fields in the
348b494511aSVenki Rajagopalan  * EoIB specification.  On Solaris, the multicast gid is represented
349b494511aSVenki Rajagopalan  * as a collection of two 8-byte fields (in ib_gid_t).
350b494511aSVenki Rajagopalan  */
351b494511aSVenki Rajagopalan typedef struct eib_mgid_spec_s {
352b494511aSVenki Rajagopalan 	uint8_t			sp_mgid_prefix[FIP_MGID_PREFIX_LEN];
353b494511aSVenki Rajagopalan 	uint8_t			sp_type;
354b494511aSVenki Rajagopalan 	uint8_t			sp_dmac[ETHERADDRL];
355b494511aSVenki Rajagopalan 	uint8_t			sp_rss_hash;
356b494511aSVenki Rajagopalan 	uint8_t			sp_vhub_id[FIP_VHUBID_LEN];
357b494511aSVenki Rajagopalan } eib_mgid_spec_t;
358b494511aSVenki Rajagopalan 
359b494511aSVenki Rajagopalan /*
360b494511aSVenki Rajagopalan  * Values for sp_type in mgid as per EoIB specification
361b494511aSVenki Rajagopalan  */
362b494511aSVenki Rajagopalan #define	EIB_MGID_VHUB_DATA	0x0
363b494511aSVenki Rajagopalan #define	EIB_MGID_VHUB_UPDATE	0x2
364b494511aSVenki Rajagopalan #define	EIB_MGID_VHUB_TABLE	0x3
365b494511aSVenki Rajagopalan 
366b494511aSVenki Rajagopalan typedef union eib_mgid_s {
367b494511aSVenki Rajagopalan 	eib_mgid_spec_t		gd_spec;
368b494511aSVenki Rajagopalan 	ib_gid_t		gd_sol;
369b494511aSVenki Rajagopalan } eib_mgid_t;
370b494511aSVenki Rajagopalan 
371b494511aSVenki Rajagopalan /*
372b494511aSVenki Rajagopalan  * Gateway properties handed over to us by the EoIB nexus
373b494511aSVenki Rajagopalan  */
374b494511aSVenki Rajagopalan typedef struct eib_gw_props_s {
375b494511aSVenki Rajagopalan 	kmutex_t		pp_gw_lock;
376b494511aSVenki Rajagopalan 
377b494511aSVenki Rajagopalan 	ib_guid_t		pp_gw_system_guid;
378b494511aSVenki Rajagopalan 	ib_guid_t		pp_gw_guid;
379b494511aSVenki Rajagopalan 	ib_sn_prefix_t		pp_gw_sn_prefix;
380b494511aSVenki Rajagopalan 
381b494511aSVenki Rajagopalan 	uint_t			pp_gw_adv_period;
382b494511aSVenki Rajagopalan 	uint_t			pp_gw_ka_period;
383b494511aSVenki Rajagopalan 	uint_t			pp_vnic_ka_period;
384b494511aSVenki Rajagopalan 
385b494511aSVenki Rajagopalan 	ib_qpn_t		pp_gw_ctrl_qpn;
386b494511aSVenki Rajagopalan 	ib_lid_t		pp_gw_lid;
387b494511aSVenki Rajagopalan 	uint16_t		pp_gw_portid;
388b494511aSVenki Rajagopalan 
389b494511aSVenki Rajagopalan 	uint16_t		pp_gw_num_net_vnics;
390b494511aSVenki Rajagopalan 	uint8_t			pp_gw_flag_available;
391b494511aSVenki Rajagopalan 	uint8_t			pp_gw_is_host_adm_vnics;
392b494511aSVenki Rajagopalan 	uint8_t			pp_gw_sl;
393b494511aSVenki Rajagopalan 	uint8_t			pp_gw_n_rss_qpn;
394b494511aSVenki Rajagopalan 
395b494511aSVenki Rajagopalan 	uint8_t			*pp_gw_system_name;
396b494511aSVenki Rajagopalan 	uint8_t			*pp_gw_port_name;
397b494511aSVenki Rajagopalan 	uint8_t			*pp_gw_vendor_id;
398b494511aSVenki Rajagopalan 
399b494511aSVenki Rajagopalan 	clock_t			pp_gw_ka_ticks;		/* 2.5 x gw_ka_period */
400b494511aSVenki Rajagopalan 	clock_t			pp_vnic_ka_ticks;	/* vnic_ka_period */
401b494511aSVenki Rajagopalan } eib_gw_props_t;
402b494511aSVenki Rajagopalan 
403b494511aSVenki Rajagopalan /*
404b494511aSVenki Rajagopalan  * Port-specific properties
405b494511aSVenki Rajagopalan  */
406b494511aSVenki Rajagopalan typedef struct eib_props_s {
407b494511aSVenki Rajagopalan 	uint64_t		ep_ifspeed;
408b494511aSVenki Rajagopalan 	ib_guid_t		ep_hca_guid;
409b494511aSVenki Rajagopalan 	uint8_t			ep_port_num;
410b494511aSVenki Rajagopalan 	ib_gid_t		ep_sgid;
411b494511aSVenki Rajagopalan 	ib_lid_t		ep_blid;
412b494511aSVenki Rajagopalan 	uint16_t		ep_mtu;
413b494511aSVenki Rajagopalan 	ibt_srate_t		ep_srate;
414b494511aSVenki Rajagopalan } eib_props_t;
415b494511aSVenki Rajagopalan 
416b494511aSVenki Rajagopalan /*
417b494511aSVenki Rajagopalan  * Capabilities derived from HCA attributes
418b494511aSVenki Rajagopalan  */
419b494511aSVenki Rajagopalan typedef struct eib_caps_s {
420b494511aSVenki Rajagopalan 	uint_t			cp_lso_maxlen;
421b494511aSVenki Rajagopalan 	uint32_t		cp_cksum_flags;
422b494511aSVenki Rajagopalan 	int			cp_resv_lkey_capab;
423b494511aSVenki Rajagopalan 	ibt_lkey_t		cp_resv_lkey;
424b494511aSVenki Rajagopalan 
425b494511aSVenki Rajagopalan 	uint_t			cp_max_swqe;
426b494511aSVenki Rajagopalan 	uint_t			cp_max_rwqe;
427b494511aSVenki Rajagopalan 	uint_t			cp_max_sgl;
428b494511aSVenki Rajagopalan 	uint_t			cp_hiwm_sgl;
429b494511aSVenki Rajagopalan } eib_caps_t;
430b494511aSVenki Rajagopalan 
431b494511aSVenki Rajagopalan /*
432b494511aSVenki Rajagopalan  * List of multicast groups the vnic joined
433b494511aSVenki Rajagopalan  */
434b494511aSVenki Rajagopalan typedef struct eib_mcg_s {
435b494511aSVenki Rajagopalan 	struct eib_mcg_s	*mg_next;
436b494511aSVenki Rajagopalan 	ib_gid_t		mg_rgid;
437b494511aSVenki Rajagopalan 	ib_gid_t		mg_mgid;
438b494511aSVenki Rajagopalan 	uint8_t			mg_join_state;
439b494511aSVenki Rajagopalan 	uint8_t			mg_mac[ETHERADDRL];
440b494511aSVenki Rajagopalan 	ibt_mcg_info_t		*mg_mcginfo;
441b494511aSVenki Rajagopalan } eib_mcg_t;
442b494511aSVenki Rajagopalan 
443b494511aSVenki Rajagopalan /*
444b494511aSVenki Rajagopalan  * Admin/control/data channel information
445b494511aSVenki Rajagopalan  */
446b494511aSVenki Rajagopalan typedef struct eib_chan_s {
447b494511aSVenki Rajagopalan 	ibt_channel_hdl_t	ch_chan;
448b494511aSVenki Rajagopalan 	ib_qpn_t		ch_qpn;
449b494511aSVenki Rajagopalan 
450b494511aSVenki Rajagopalan 	ibt_wc_t		*ch_wc;
451b494511aSVenki Rajagopalan 	ibt_cq_hdl_t		ch_cq_hdl;
452b494511aSVenki Rajagopalan 	uint_t			ch_cq_sz;
453b494511aSVenki Rajagopalan 
454b494511aSVenki Rajagopalan 	ibt_wc_t		*ch_rcv_wc;
455b494511aSVenki Rajagopalan 	ibt_cq_hdl_t		ch_rcv_cq_hdl;
456b494511aSVenki Rajagopalan 	uint_t			ch_rcv_cq_sz;
457b494511aSVenki Rajagopalan 
458b494511aSVenki Rajagopalan 	int			ch_vnic_inst;
459b494511aSVenki Rajagopalan 	uint_t			ch_max_swqes;
460b494511aSVenki Rajagopalan 	uint_t			ch_max_rwqes;
461b494511aSVenki Rajagopalan 	uint_t			ch_lwm_rwqes;
462b494511aSVenki Rajagopalan 	uint_t			ch_rwqe_bktsz;
463b494511aSVenki Rajagopalan 	uint_t			ch_ip_hdr_align;
464b494511aSVenki Rajagopalan 	boolean_t		ch_alloc_mp;
465b494511aSVenki Rajagopalan 	boolean_t		ch_tear_down;
466b494511aSVenki Rajagopalan 
467b494511aSVenki Rajagopalan 	kmutex_t		ch_pkey_lock;
468b494511aSVenki Rajagopalan 	ib_pkey_t		ch_pkey;
469b494511aSVenki Rajagopalan 	uint16_t		ch_pkey_ix;
470b494511aSVenki Rajagopalan 
471b494511aSVenki Rajagopalan 	kmutex_t		ch_cep_lock;
472b494511aSVenki Rajagopalan 	kcondvar_t		ch_cep_cv;
473b494511aSVenki Rajagopalan 	ibt_cep_state_t		ch_cep_state;
474b494511aSVenki Rajagopalan 
475b494511aSVenki Rajagopalan 	kmutex_t		ch_tx_lock;
476b494511aSVenki Rajagopalan 	kcondvar_t		ch_tx_cv;
477b494511aSVenki Rajagopalan 	uint_t			ch_tx_posted;
478b494511aSVenki Rajagopalan 	boolean_t		ch_tx_busy;
479b494511aSVenki Rajagopalan 	struct eib_wqe_s	*ch_tx;
480b494511aSVenki Rajagopalan 	struct eib_wqe_s	*ch_tx_tail;
481b494511aSVenki Rajagopalan 
482b494511aSVenki Rajagopalan 	kmutex_t		ch_rx_lock;
483b494511aSVenki Rajagopalan 	kcondvar_t		ch_rx_cv;
484b494511aSVenki Rajagopalan 	uint_t			ch_rx_posted;
485b494511aSVenki Rajagopalan 	boolean_t		ch_rx_refilling;
486b494511aSVenki Rajagopalan 
487b494511aSVenki Rajagopalan 	kmutex_t		ch_vhub_lock;
488b494511aSVenki Rajagopalan 	struct eib_mcg_s	*ch_vhub_table;
489b494511aSVenki Rajagopalan 	struct eib_mcg_s	*ch_vhub_update;
490b494511aSVenki Rajagopalan 	struct eib_mcg_s	*ch_vhub_data;
491b494511aSVenki Rajagopalan 
492b494511aSVenki Rajagopalan 	struct eib_chan_s	*ch_rxpost_next;
493b494511aSVenki Rajagopalan } eib_chan_t;
494b494511aSVenki Rajagopalan 
495b494511aSVenki Rajagopalan /*
496b494511aSVenki Rajagopalan  * States for vNIC state machine during login
497b494511aSVenki Rajagopalan  */
498b494511aSVenki Rajagopalan #define	EIB_LOGIN_INIT		0
499b494511aSVenki Rajagopalan #define	EIB_LOGIN_ACK_WAIT	1
500b494511aSVenki Rajagopalan #define	EIB_LOGIN_ACK_RCVD	2
501b494511aSVenki Rajagopalan #define	EIB_LOGIN_NACK_RCVD	3
502b494511aSVenki Rajagopalan #define	EIB_LOGIN_TBL_WAIT	4
503b494511aSVenki Rajagopalan #define	EIB_LOGIN_TBL_INPROG	5
504b494511aSVenki Rajagopalan #define	EIB_LOGIN_TBL_DONE	6
505b494511aSVenki Rajagopalan #define	EIB_LOGIN_TBL_FAILED	7
506b494511aSVenki Rajagopalan #define	EIB_LOGIN_DONE		8
507b494511aSVenki Rajagopalan #define	EIB_LOGIN_TIMED_OUT	9
508b494511aSVenki Rajagopalan #define	EIB_LOGOUT_DONE		10
509b494511aSVenki Rajagopalan 
510b494511aSVenki Rajagopalan typedef struct eib_login_data_s {
511b494511aSVenki Rajagopalan 	ib_guid_t		ld_gw_guid;
512b494511aSVenki Rajagopalan 	ib_lid_t		ld_gw_lid;
513b494511aSVenki Rajagopalan 	uint_t			ld_syndrome;
514b494511aSVenki Rajagopalan 	uint16_t		ld_gw_port_id;
515b494511aSVenki Rajagopalan 	ib_qpn_t		ld_gw_data_qpn;
516b494511aSVenki Rajagopalan 	ib_qpn_t		ld_gw_ctl_qpn;
517b494511aSVenki Rajagopalan 	uint16_t		ld_vnic_id;	/* includes set msbit */
518b494511aSVenki Rajagopalan 	uint16_t		ld_vhub_mtu;
519b494511aSVenki Rajagopalan 	uint16_t		ld_vhub_pkey;
520b494511aSVenki Rajagopalan 	uint16_t		ld_assigned_vlan;
521b494511aSVenki Rajagopalan 	uint8_t			ld_gw_sl;
522b494511aSVenki Rajagopalan 	uint8_t			ld_n_rss_mcgid;
523b494511aSVenki Rajagopalan 	uint8_t			ld_n_mac_mcgid;
524b494511aSVenki Rajagopalan 	uint8_t			ld_vnic_name[FIP_VNIC_NAME_LEN];
525b494511aSVenki Rajagopalan 	uint8_t			ld_assigned_mac[ETHERADDRL];
526b494511aSVenki Rajagopalan 	uint8_t			ld_gw_mgid_prefix[FIP_MGID_PREFIX_LEN];
527b494511aSVenki Rajagopalan 	uint8_t			ld_vlan_in_packets;
528b494511aSVenki Rajagopalan 	uint32_t		ld_vhub_id;
529b494511aSVenki Rajagopalan } eib_login_data_t;
530b494511aSVenki Rajagopalan 
531b494511aSVenki Rajagopalan #define	EIB_UNICAST_MAC(mac)		(((mac)[0] & 0x01) == 0)
532b494511aSVenki Rajagopalan 
533b494511aSVenki Rajagopalan /*
534b494511aSVenki Rajagopalan  * Map to translate between DMAC and {qpn, lid, sl}
535b494511aSVenki Rajagopalan  */
536b494511aSVenki Rajagopalan typedef struct eib_vhub_map_s {
537b494511aSVenki Rajagopalan 	struct eib_vhub_map_s	*mp_next;
538b494511aSVenki Rajagopalan 	uint32_t		mp_tusn;
539b494511aSVenki Rajagopalan 	ib_qpn_t		mp_qpn;
540b494511aSVenki Rajagopalan 	ib_lid_t		mp_lid;
541b494511aSVenki Rajagopalan 	uint8_t			mp_mac[ETHERADDRL];
542b494511aSVenki Rajagopalan 	uint8_t			mp_sl;
543b494511aSVenki Rajagopalan 	uint8_t			mp_v_rss_type;
544b494511aSVenki Rajagopalan } eib_vhub_map_t;
545b494511aSVenki Rajagopalan 
546b494511aSVenki Rajagopalan /*
547b494511aSVenki Rajagopalan  * Per-vNIC vHUB Table
548b494511aSVenki Rajagopalan  */
549b494511aSVenki Rajagopalan #define	EIB_TB_NBUCKETS		13
550b494511aSVenki Rajagopalan typedef struct eib_vhub_table_s {
551b494511aSVenki Rajagopalan 	kmutex_t		tb_lock;
552b494511aSVenki Rajagopalan 	struct eib_vhub_map_s	*tb_gateway;
553b494511aSVenki Rajagopalan 	struct eib_vhub_map_s	*tb_unicast_miss;
554b494511aSVenki Rajagopalan 	struct eib_vhub_map_s	*tb_vhub_multicast;
555b494511aSVenki Rajagopalan 	struct eib_vhub_map_s	*tb_vnic_entry[EIB_TB_NBUCKETS];
556b494511aSVenki Rajagopalan 	struct eib_vhub_map_s	*tb_mcast_entry[EIB_TB_NBUCKETS];
557b494511aSVenki Rajagopalan 
558b494511aSVenki Rajagopalan 	uint32_t		tb_tusn;
559b494511aSVenki Rajagopalan 	uint8_t			tb_eport_state;
560b494511aSVenki Rajagopalan 
561b494511aSVenki Rajagopalan 	uint16_t		tb_entries_seen;
562b494511aSVenki Rajagopalan 	uint16_t		tb_entries_in_table;
563b494511aSVenki Rajagopalan 	uint32_t		tb_checksum;
564b494511aSVenki Rajagopalan } eib_vhub_table_t;
565b494511aSVenki Rajagopalan 
566b494511aSVenki Rajagopalan typedef struct eib_vhub_update_s {
567b494511aSVenki Rajagopalan 	kmutex_t		up_lock;
568b494511aSVenki Rajagopalan 	eib_vhub_map_t		*up_vnic_entry;
569b494511aSVenki Rajagopalan 	uint32_t		up_tusn;
570b494511aSVenki Rajagopalan 	uint8_t			up_eport_state;
571b494511aSVenki Rajagopalan } eib_vhub_update_t;
572b494511aSVenki Rajagopalan 
573b494511aSVenki Rajagopalan typedef struct eib_ether_hdr_s {
574b494511aSVenki Rajagopalan 	int			eh_tagless;
575b494511aSVenki Rajagopalan 	uint16_t		eh_ether_type;
576b494511aSVenki Rajagopalan 	uint16_t		eh_vlan;
577b494511aSVenki Rajagopalan 	uint8_t			eh_dmac[ETHERADDRL];
578b494511aSVenki Rajagopalan 	uint8_t			eh_smac[ETHERADDRL];
579b494511aSVenki Rajagopalan } eib_ether_hdr_t;
580b494511aSVenki Rajagopalan 
581b494511aSVenki Rajagopalan /*
582b494511aSVenki Rajagopalan  * vNIC Information
583b494511aSVenki Rajagopalan  */
584b494511aSVenki Rajagopalan typedef struct eib_vnic_s {
585b494511aSVenki Rajagopalan 	struct eib_s		*vn_ss;
586b494511aSVenki Rajagopalan 	eib_chan_t		*vn_ctl_chan;
587b494511aSVenki Rajagopalan 	eib_chan_t		*vn_data_chan;
588b494511aSVenki Rajagopalan 	int			vn_instance;
589b494511aSVenki Rajagopalan 	uint16_t		vn_vlan;
590b494511aSVenki Rajagopalan 	uint16_t		vn_id;
591b494511aSVenki Rajagopalan 	uint8_t			vn_macaddr[ETHERADDRL];
592b494511aSVenki Rajagopalan 	struct eib_login_data_s	vn_login_data;
593b494511aSVenki Rajagopalan 
594b494511aSVenki Rajagopalan 	kmutex_t		vn_lock;
595b494511aSVenki Rajagopalan 	kcondvar_t		vn_cv;
596b494511aSVenki Rajagopalan 	uint_t			vn_state;
597b494511aSVenki Rajagopalan 	struct eib_vhub_table_s	*vn_vhub_table;
598b494511aSVenki Rajagopalan 	struct eib_vhub_update_s *vn_vhub_update;
599b494511aSVenki Rajagopalan 
600b494511aSVenki Rajagopalan 	ddi_softint_handle_t    vn_ctl_si_hdl;
601b494511aSVenki Rajagopalan 	ddi_softint_handle_t    vn_data_tx_si_hdl;
602b494511aSVenki Rajagopalan 	ddi_softint_handle_t    vn_data_rx_si_hdl;
603b494511aSVenki Rajagopalan } eib_vnic_t;
604b494511aSVenki Rajagopalan 
605b494511aSVenki Rajagopalan 
606b494511aSVenki Rajagopalan /*
607b494511aSVenki Rajagopalan  * Base NIC's mac state flags. The lock protects the starting/stopping
608b494511aSVenki Rajagopalan  * bits.  Access to the rest of the mac state is protected by these
609b494511aSVenki Rajagopalan  * two bits.
610b494511aSVenki Rajagopalan  */
611b494511aSVenki Rajagopalan #define	EIB_NIC_STARTING	0x01
612b494511aSVenki Rajagopalan #define	EIB_NIC_STOPPING	0x02
613b494511aSVenki Rajagopalan #define	EIB_NIC_STARTED		0x80
614b494511aSVenki Rajagopalan #define	EIB_NIC_RESTARTING	(EIB_NIC_STARTING | EIB_NIC_STOPPING)
615b494511aSVenki Rajagopalan 
616b494511aSVenki Rajagopalan typedef struct eib_node_state_s {
617b494511aSVenki Rajagopalan 	kmutex_t		ns_lock;
618b494511aSVenki Rajagopalan 	kcondvar_t		ns_cv;
619b494511aSVenki Rajagopalan 	uint_t			ns_nic_state;
620b494511aSVenki Rajagopalan 	link_state_t		ns_link_state;
621b494511aSVenki Rajagopalan } eib_node_state_t;
622b494511aSVenki Rajagopalan 
623b494511aSVenki Rajagopalan /*
624b494511aSVenki Rajagopalan  * MIB-II statistics to report to the mac layer
625b494511aSVenki Rajagopalan  */
626b494511aSVenki Rajagopalan typedef struct eib_stats_s {
627b494511aSVenki Rajagopalan 	uint64_t		st_obytes;	/* bytes sent out */
628b494511aSVenki Rajagopalan 	uint64_t		st_opkts;	/* pkts sent out */
629b494511aSVenki Rajagopalan 	uint64_t		st_brdcstxmit;	/* broadcast pkts transmitted */
630b494511aSVenki Rajagopalan 	uint64_t		st_multixmit;	/* multicast pkts transmitted */
631b494511aSVenki Rajagopalan 	uint64_t		st_oerrors;	/* transmit errors */
632b494511aSVenki Rajagopalan 	uint64_t		st_noxmitbuf;	/* transmit pkts discarded */
633b494511aSVenki Rajagopalan 
634b494511aSVenki Rajagopalan 	uint64_t		st_rbytes;	/* bytes received */
635b494511aSVenki Rajagopalan 	uint64_t		st_ipkts;	/* pkts received */
636b494511aSVenki Rajagopalan 	uint64_t		st_brdcstrcv;	/* broadcast pkts received */
637b494511aSVenki Rajagopalan 	uint64_t		st_multircv;	/* multicast pkts received */
638b494511aSVenki Rajagopalan 	uint64_t		st_ierrors;	/* receive errors */
639b494511aSVenki Rajagopalan 	uint64_t		st_norcvbuf;	/* receive pkts discarded */
640b494511aSVenki Rajagopalan } eib_stats_t;
641b494511aSVenki Rajagopalan 
642b494511aSVenki Rajagopalan #define	EIB_UPDATE_COUNTER(addr, val)	(atomic_add_64((addr), (val)))
643b494511aSVenki Rajagopalan #define	EIB_INCR_COUNTER(addr)		(atomic_inc_64((addr)))
644b494511aSVenki Rajagopalan #define	EIB_DECR_COUNTER(addr)		(atomic_dec_64((addr)))
645b494511aSVenki Rajagopalan 
646b494511aSVenki Rajagopalan /*
647b494511aSVenki Rajagopalan  * Cache of address vectors with dlid as the key. Currently we use
648b494511aSVenki Rajagopalan  * eib state structure's  ei_lock to protect the individual address
649b494511aSVenki Rajagopalan  * vector's fields.  This is a lock granularity that's slightly
650b494511aSVenki Rajagopalan  * bigger than ideal, but it should do for now.
651b494511aSVenki Rajagopalan  */
652b494511aSVenki Rajagopalan #define	EIB_AV_NBUCKETS		17
653b494511aSVenki Rajagopalan typedef struct eib_avect_s {
654b494511aSVenki Rajagopalan 	struct eib_avect_s	*av_next;
655b494511aSVenki Rajagopalan 	ibt_adds_vect_t		av_vect;
656b494511aSVenki Rajagopalan 	uint_t			av_ref;
657b494511aSVenki Rajagopalan } eib_avect_t;
658b494511aSVenki Rajagopalan 
659b494511aSVenki Rajagopalan /*
660b494511aSVenki Rajagopalan  * vNIC creation and deletion are serialized by a non-zero value
661b494511aSVenki Rajagopalan  * to the ei_vnic_state member (i.e. only one vnic may be created
662b494511aSVenki Rajagopalan  * or deleted at a time). The code makes sure to access/update
663b494511aSVenki Rajagopalan  * the ei_active_vnics member only after a successful setting of
664b494511aSVenki Rajagopalan  * ei_vnic_state.
665b494511aSVenki Rajagopalan  */
666b494511aSVenki Rajagopalan #define	EIB_VN_BEING_CREATED	0x01
667b494511aSVenki Rajagopalan #define	EIB_VN_BEING_DELETED	0x02
669b494511aSVenki Rajagopalan 
670b494511aSVenki Rajagopalan /*
671b494511aSVenki Rajagopalan  * All possible EoIB event work items that need to be handled
672b494511aSVenki Rajagopalan  */
673b494511aSVenki Rajagopalan #define	EIB_EV_NONE		0
674b494511aSVenki Rajagopalan #define	EIB_EV_PORT_DOWN	1
675b494511aSVenki Rajagopalan #define	EIB_EV_PORT_UP		2
676b494511aSVenki Rajagopalan #define	EIB_EV_PKEY_CHANGE	3
677b494511aSVenki Rajagopalan #define	EIB_EV_SGID_CHANGE	4
678b494511aSVenki Rajagopalan #define	EIB_EV_CLNT_REREG	5
679b494511aSVenki Rajagopalan #define	EIB_EV_GW_EPORT_DOWN	6
680b494511aSVenki Rajagopalan #define	EIB_EV_GW_DOWN		7
681b494511aSVenki Rajagopalan #define	EIB_EV_GW_UP		8
682b494511aSVenki Rajagopalan #define	EIB_EV_GW_INFO_UPDATE	9
683b494511aSVenki Rajagopalan #define	EIB_EV_MCG_DELETED	10
684b494511aSVenki Rajagopalan #define	EIB_EV_MCG_CREATED	11
685b494511aSVenki Rajagopalan #define	EIB_EV_SHUTDOWN		12
686b494511aSVenki Rajagopalan 
687b494511aSVenki Rajagopalan typedef struct eib_event_s {
688b494511aSVenki Rajagopalan 	struct eib_event_s	*ev_next;
689b494511aSVenki Rajagopalan 	uint_t			ev_code;
690b494511aSVenki Rajagopalan 	void			*ev_arg;
691b494511aSVenki Rajagopalan } eib_event_t;
692b494511aSVenki Rajagopalan 
693b494511aSVenki Rajagopalan /*
694b494511aSVenki Rajagopalan  * Work element for new vnic creation
695b494511aSVenki Rajagopalan  */
696b494511aSVenki Rajagopalan typedef struct eib_vnic_req_s {
697b494511aSVenki Rajagopalan 	struct eib_vnic_req_s	*vr_next;
698b494511aSVenki Rajagopalan 	uint_t			vr_req;
699b494511aSVenki Rajagopalan 	uint8_t			vr_mac[ETHERADDRL];
700b494511aSVenki Rajagopalan 	uint16_t		vr_vlan;
701b494511aSVenki Rajagopalan } eib_vnic_req_t;
702b494511aSVenki Rajagopalan 
703b494511aSVenki Rajagopalan /*
704b494511aSVenki Rajagopalan  * Values for vr_req
705b494511aSVenki Rajagopalan  */
706b494511aSVenki Rajagopalan #define	EIB_CR_REQ_NEW_VNIC	1
707b494511aSVenki Rajagopalan #define	EIB_CR_REQ_FLUSH	2
708b494511aSVenki Rajagopalan #define	EIB_CR_REQ_DIE		3
709b494511aSVenki Rajagopalan 
710b494511aSVenki Rajagopalan /*
711b494511aSVenki Rajagopalan  * Work element for vnics kept alive by the keepalive manager thread
712b494511aSVenki Rajagopalan  * and bitfield values for ei_ka_vnics_event.
713b494511aSVenki Rajagopalan  */
714b494511aSVenki Rajagopalan typedef struct eib_ka_vnics_s {
715b494511aSVenki Rajagopalan 	struct eib_ka_vnics_s	*ka_next;
716b494511aSVenki Rajagopalan 	struct eib_vnic_s	*ka_vnic;
717b494511aSVenki Rajagopalan } eib_ka_vnics_t;
718b494511aSVenki Rajagopalan 
719b494511aSVenki Rajagopalan #define	EIB_KA_VNICS_DIE	0x1
720b494511aSVenki Rajagopalan #define	EIB_KA_VNICS_TIMED_OUT	0x2
721b494511aSVenki Rajagopalan 
722b494511aSVenki Rajagopalan /*
723b494511aSVenki Rajagopalan  * EoIB per-instance state
724b494511aSVenki Rajagopalan  */
725b494511aSVenki Rajagopalan typedef struct eib_s {
726b494511aSVenki Rajagopalan 	ibt_clnt_hdl_t		ei_ibt_hdl;
727b494511aSVenki Rajagopalan 	ibt_hca_hdl_t		ei_hca_hdl;
728b494511aSVenki Rajagopalan 	ibt_pd_hdl_t		ei_pd_hdl;
729b494511aSVenki Rajagopalan 	mac_handle_t		ei_mac_hdl;
730b494511aSVenki Rajagopalan 
731b494511aSVenki Rajagopalan 	ddi_softint_handle_t    ei_admin_si_hdl;
732b494511aSVenki Rajagopalan 	ddi_callback_id_t	ei_login_ack_cb;
733b494511aSVenki Rajagopalan 	ddi_callback_id_t	ei_gw_alive_cb;
734b494511aSVenki Rajagopalan 	ddi_callback_id_t	ei_gw_info_cb;
735b494511aSVenki Rajagopalan 
736b494511aSVenki Rajagopalan 	ibt_hca_attr_t		*ei_hca_attrs;
737b494511aSVenki Rajagopalan 	dev_info_t		*ei_dip;
738b494511aSVenki Rajagopalan 	uint_t			ei_instance;
739b494511aSVenki Rajagopalan 
740b494511aSVenki Rajagopalan 	struct eib_gw_props_s	*ei_gw_props;
741b494511aSVenki Rajagopalan 	struct eib_props_s	*ei_props;
742b494511aSVenki Rajagopalan 	struct eib_caps_s	*ei_caps;
743b494511aSVenki Rajagopalan 	struct eib_stats_s	*ei_stats;
744b494511aSVenki Rajagopalan 
745b494511aSVenki Rajagopalan 	struct eib_node_state_s	*ei_node_state;
746b494511aSVenki Rajagopalan 	struct eib_chan_s	*ei_admin_chan;
747b494511aSVenki Rajagopalan 
748b494511aSVenki Rajagopalan 	struct eib_wqe_pool_s	*ei_tx;
749b494511aSVenki Rajagopalan 	struct eib_wqe_pool_s	*ei_rx;
750b494511aSVenki Rajagopalan 	struct eib_lsobkt_s	*ei_lso;
751b494511aSVenki Rajagopalan 
752b494511aSVenki Rajagopalan 	kmutex_t		ei_vnic_lock;
753b494511aSVenki Rajagopalan 	kcondvar_t		ei_vnic_cv;
754b494511aSVenki Rajagopalan 	uint_t			ei_vnic_state;
755b494511aSVenki Rajagopalan 	uint64_t		ei_active_vnics;
756b494511aSVenki Rajagopalan 	uint64_t		ei_zombie_vnics;
757b494511aSVenki Rajagopalan 	uint64_t		ei_rejoin_vnics;
758b494511aSVenki Rajagopalan 	struct eib_vnic_s	*ei_vnic[EIB_MAX_VNICS];
759b494511aSVenki Rajagopalan 	struct eib_vnic_s	*ei_vnic_pending;
760b494511aSVenki Rajagopalan 	int64_t			ei_gw_last_heartbeat;
761b494511aSVenki Rajagopalan 	boolean_t		ei_gw_unreachable;
762b494511aSVenki Rajagopalan 	uint8_t			ei_gw_eport_state;
763b494511aSVenki Rajagopalan 
764b494511aSVenki Rajagopalan 	kmutex_t		ei_av_lock;
765b494511aSVenki Rajagopalan 	struct eib_avect_s	*ei_av[EIB_AV_NBUCKETS];
766b494511aSVenki Rajagopalan 
767b494511aSVenki Rajagopalan 	kmutex_t		ei_ev_lock;
768b494511aSVenki Rajagopalan 	kcondvar_t		ei_ev_cv;
769b494511aSVenki Rajagopalan 	struct eib_event_s	*ei_event;
770b494511aSVenki Rajagopalan 
771b494511aSVenki Rajagopalan 	kmutex_t		ei_rxpost_lock;
772b494511aSVenki Rajagopalan 	kcondvar_t		ei_rxpost_cv;
773b494511aSVenki Rajagopalan 	uint_t			ei_rxpost_die;
774b494511aSVenki Rajagopalan 	struct eib_chan_s	*ei_rxpost;
775b494511aSVenki Rajagopalan 
776b494511aSVenki Rajagopalan 	kmutex_t		ei_vnic_req_lock;
777b494511aSVenki Rajagopalan 	kcondvar_t		ei_vnic_req_cv;
778b494511aSVenki Rajagopalan 	struct eib_vnic_req_s	*ei_vnic_req;
779b494511aSVenki Rajagopalan 	struct eib_vnic_req_s	*ei_failed_vnic_req;
780b494511aSVenki Rajagopalan 	struct eib_vnic_req_s	*ei_pending_vnic_req;
781b494511aSVenki Rajagopalan 
782b494511aSVenki Rajagopalan 	kmutex_t		ei_ka_vnics_lock;
783b494511aSVenki Rajagopalan 	kcondvar_t		ei_ka_vnics_cv;
784b494511aSVenki Rajagopalan 	uint_t			ei_ka_vnics_event;
785b494511aSVenki Rajagopalan 	struct eib_ka_vnics_s	*ei_ka_vnics;
786b494511aSVenki Rajagopalan 
787b494511aSVenki Rajagopalan 	kt_did_t		ei_txwqe_monitor;
788b494511aSVenki Rajagopalan 	kt_did_t		ei_lsobufs_monitor;
789b494511aSVenki Rajagopalan 	kt_did_t		ei_rwqes_refiller;
790b494511aSVenki Rajagopalan 	kt_did_t		ei_vnic_creator;
791b494511aSVenki Rajagopalan 	kt_did_t		ei_events_handler;
792b494511aSVenki Rajagopalan 	kt_did_t		ei_keepalives_manager;
793b494511aSVenki Rajagopalan } eib_t;
794b494511aSVenki Rajagopalan 
795b494511aSVenki Rajagopalan /*
796b494511aSVenki Rajagopalan  * Private read-only datalink properties
797b494511aSVenki Rajagopalan  */
798b494511aSVenki Rajagopalan #define	EIB_DLPROP_GW_EPORT_STATE	"_eib_eport_state"
799b494511aSVenki Rajagopalan #define	EIB_DLPROP_HCA_GUID		"_eib_hca_guid"
800b494511aSVenki Rajagopalan #define	EIB_DLPROP_PORT_GUID		"_eib_port_guid"
801b494511aSVenki Rajagopalan 
802b494511aSVenki Rajagopalan /*
804b494511aSVenki Rajagopalan  */
805b494511aSVenki Rajagopalan 
806b494511aSVenki Rajagopalan /*
807b494511aSVenki Rajagopalan  * FIP protocol related
808b494511aSVenki Rajagopalan  */
809b494511aSVenki Rajagopalan extern int eib_fip_login(eib_t *, eib_vnic_t *, int *);
810b494511aSVenki Rajagopalan extern int eib_fip_heartbeat(eib_t *, eib_vnic_t *, int *);
811b494511aSVenki Rajagopalan extern int eib_fip_vhub_table(eib_t *, eib_vnic_t *, int *);
812b494511aSVenki Rajagopalan extern int eib_fip_logout(eib_t *, eib_vnic_t *, int *);
813b494511aSVenki Rajagopalan extern int eib_fip_parse_login_ack(eib_t *, uint8_t *, eib_login_data_t *);
814b494511aSVenki Rajagopalan extern int eib_fip_parse_ctl_pkt(uint8_t *, eib_vnic_t *);
815b494511aSVenki Rajagopalan 
816b494511aSVenki Rajagopalan /*
817b494511aSVenki Rajagopalan  * Service threads and other handlers
818b494511aSVenki Rajagopalan  */
819b494511aSVenki Rajagopalan extern void eib_events_handler(eib_t *);
820b494511aSVenki Rajagopalan extern void eib_svc_enqueue_event(eib_t *, eib_event_t *);
821b494511aSVenki Rajagopalan extern void eib_refill_rwqes(eib_t *);
822b494511aSVenki Rajagopalan extern void eib_vnic_creator(eib_t *);
823b494511aSVenki Rajagopalan extern void eib_monitor_tx_wqes(eib_t *);
824b494511aSVenki Rajagopalan extern void eib_monitor_lso_bufs(eib_t *);
825b494511aSVenki Rajagopalan extern void eib_manage_keepalives(eib_t *);
826b494511aSVenki Rajagopalan extern void eib_stop_events_handler(eib_t *);
827b494511aSVenki Rajagopalan extern void eib_stop_refill_rwqes(eib_t *);
828b494511aSVenki Rajagopalan extern void eib_stop_vnic_creator(eib_t *);
829b494511aSVenki Rajagopalan extern void eib_stop_monitor_tx_wqes(eib_t *);
830b494511aSVenki Rajagopalan extern int eib_stop_monitor_lso_bufs(eib_t *, boolean_t);
831b494511aSVenki Rajagopalan extern void eib_stop_manage_keepalives(eib_t *);
832b494511aSVenki Rajagopalan extern void eib_flush_vnic_reqs(eib_t *);
833b494511aSVenki Rajagopalan extern void eib_gw_info_cb(dev_info_t *, ddi_eventcookie_t, void *, void *);
834b494511aSVenki Rajagopalan extern void eib_gw_alive_cb(dev_info_t *, ddi_eventcookie_t, void *, void *);
835b494511aSVenki Rajagopalan extern void eib_login_ack_cb(dev_info_t *, ddi_eventcookie_t, void *, void *);
836b494511aSVenki Rajagopalan 
837b494511aSVenki Rajagopalan /*
838b494511aSVenki Rajagopalan  * Admin QP related
839b494511aSVenki Rajagopalan  */
840b494511aSVenki Rajagopalan extern int eib_adm_setup_qp(eib_t *, int *);
841b494511aSVenki Rajagopalan extern uint_t eib_adm_comp_handler(caddr_t, caddr_t);
842b494511aSVenki Rajagopalan extern void eib_rb_adm_setup_qp(eib_t *);
843b494511aSVenki Rajagopalan 
844b494511aSVenki Rajagopalan /*
845b494511aSVenki Rajagopalan  * Control QP related
846b494511aSVenki Rajagopalan  */
847b494511aSVenki Rajagopalan extern int eib_ctl_create_qp(eib_t *, eib_vnic_t *, int *);
848b494511aSVenki Rajagopalan extern uint_t eib_ctl_comp_handler(caddr_t, caddr_t);
849b494511aSVenki Rajagopalan extern void eib_rb_ctl_create_qp(eib_t *, eib_vnic_t *);
850b494511aSVenki Rajagopalan 
851b494511aSVenki Rajagopalan /*
852b494511aSVenki Rajagopalan  * Data QP related
853b494511aSVenki Rajagopalan  */
854b494511aSVenki Rajagopalan extern int eib_data_create_qp(eib_t *, eib_vnic_t *, int *);
855b494511aSVenki Rajagopalan extern uint_t eib_data_rx_comp_handler(caddr_t, caddr_t);
856b494511aSVenki Rajagopalan extern uint_t eib_data_tx_comp_handler(caddr_t, caddr_t);
857b494511aSVenki Rajagopalan extern void eib_data_rx_recycle(caddr_t);
858b494511aSVenki Rajagopalan extern void eib_data_post_tx(eib_vnic_t *, eib_wqe_t *);
859b494511aSVenki Rajagopalan extern void eib_data_parse_ether_hdr(mblk_t *, eib_ether_hdr_t *);
860b494511aSVenki Rajagopalan extern int eib_data_lookup_vnic(eib_t *, uint8_t *, uint16_t, eib_vnic_t **,
861b494511aSVenki Rajagopalan     boolean_t *);
862b494511aSVenki Rajagopalan extern int eib_data_prepare_frame(eib_vnic_t *, eib_wqe_t *, mblk_t *,
863b494511aSVenki Rajagopalan     eib_ether_hdr_t *);
864b494511aSVenki Rajagopalan extern void eib_rb_data_create_qp(eib_t *, eib_vnic_t *);
865b494511aSVenki Rajagopalan 
866b494511aSVenki Rajagopalan /*
867b494511aSVenki Rajagopalan  * Resource related
868b494511aSVenki Rajagopalan  */
869b494511aSVenki Rajagopalan extern int eib_rsrc_setup_bufs(eib_t *, int *);
870b494511aSVenki Rajagopalan extern int eib_rsrc_grab_swqes(eib_t *, eib_wqe_t **, uint_t, uint_t *, int);
871b494511aSVenki Rajagopalan extern int eib_rsrc_grab_rwqes(eib_t *, eib_wqe_t **, uint_t, uint_t *, int);
872b494511aSVenki Rajagopalan extern int eib_rsrc_grab_lsobufs(eib_t *, uint_t, ibt_wr_ds_t *, uint32_t *);
873b494511aSVenki Rajagopalan extern eib_wqe_t *eib_rsrc_grab_swqe(eib_t *, int);
874b494511aSVenki Rajagopalan extern eib_wqe_t *eib_rsrc_grab_rwqe(eib_t *, int);
875b494511aSVenki Rajagopalan extern void eib_rsrc_return_swqe(eib_t *, eib_wqe_t *, eib_chan_t *);
876b494511aSVenki Rajagopalan extern void eib_rsrc_return_rwqe(eib_t *, eib_wqe_t *, eib_chan_t *);
877b494511aSVenki Rajagopalan extern void eib_rsrc_return_lsobufs(eib_t *, ibt_wr_ds_t *, uint32_t);
878b494511aSVenki Rajagopalan extern void eib_rsrc_decr_posted_swqe(eib_t *, eib_chan_t *);
879b494511aSVenki Rajagopalan extern void eib_rsrc_decr_posted_rwqe(eib_t *, eib_chan_t *);
880b494511aSVenki Rajagopalan extern void eib_rsrc_txwqes_needed(eib_t *);
881b494511aSVenki Rajagopalan extern void eib_rsrc_lsobufs_needed(eib_t *);
882b494511aSVenki Rajagopalan extern boolean_t eib_rsrc_rxpool_low(eib_wqe_t *);
883b494511aSVenki Rajagopalan extern void eib_rb_rsrc_setup_bufs(eib_t *, boolean_t);
884b494511aSVenki Rajagopalan 
885b494511aSVenki Rajagopalan /*
886b494511aSVenki Rajagopalan  * IBT related
887b494511aSVenki Rajagopalan  */
888b494511aSVenki Rajagopalan extern int eib_ibt_hca_init(eib_t *);
889b494511aSVenki Rajagopalan extern void eib_ibt_link_mod(eib_t *);
890b494511aSVenki Rajagopalan extern int eib_ibt_modify_chan_pkey(eib_t *, eib_chan_t *, ib_pkey_t);
891b494511aSVenki Rajagopalan extern eib_avect_t *eib_ibt_hold_avect(eib_t *, ib_lid_t, uint8_t);
892b494511aSVenki Rajagopalan extern void eib_ibt_release_avect(eib_t *, eib_avect_t *);
893b494511aSVenki Rajagopalan extern void eib_ibt_free_avects(eib_t *);
894b494511aSVenki Rajagopalan extern void eib_ibt_async_handler(void *, ibt_hca_hdl_t, ibt_async_code_t,
895b494511aSVenki Rajagopalan     ibt_async_event_t *);
896b494511aSVenki Rajagopalan extern void eib_ibt_record_capab(eib_t *, ibt_hca_attr_t *, eib_caps_t *);
897b494511aSVenki Rajagopalan extern void eib_rb_ibt_hca_init(eib_t *, uint_t);
898b494511aSVenki Rajagopalan 
899b494511aSVenki Rajagopalan /*
900b494511aSVenki Rajagopalan  * Chan related
901b494511aSVenki Rajagopalan  */
902b494511aSVenki Rajagopalan extern eib_chan_t *eib_chan_init(void);
903b494511aSVenki Rajagopalan extern void eib_chan_fini(eib_chan_t *);
904b494511aSVenki Rajagopalan extern int eib_chan_post_rx(eib_t *, eib_chan_t *, uint_t *);
905b494511aSVenki Rajagopalan extern int eib_chan_post_recv(eib_t *, eib_chan_t *, eib_wqe_t *);
906b494511aSVenki Rajagopalan 
907b494511aSVenki Rajagopalan /*
908b494511aSVenki Rajagopalan  * Mac layer related
909b494511aSVenki Rajagopalan  */
910b494511aSVenki Rajagopalan extern void eib_mac_set_nic_state(eib_t *, uint_t);
911b494511aSVenki Rajagopalan extern void eib_mac_clr_nic_state(eib_t *, uint_t);
912b494511aSVenki Rajagopalan extern void eib_mac_upd_nic_state(eib_t *, uint_t, uint_t);
913b494511aSVenki Rajagopalan extern uint_t eib_mac_get_nic_state(eib_t *);
914b494511aSVenki Rajagopalan extern void eib_mac_link_state(eib_t *, link_state_t, boolean_t);
915b494511aSVenki Rajagopalan extern void eib_mac_link_down(eib_t *, boolean_t);
916b494511aSVenki Rajagopalan extern void eib_mac_link_up(eib_t *, boolean_t);
917b494511aSVenki Rajagopalan extern int eib_mac_start(eib_t *);
918b494511aSVenki Rajagopalan extern void eib_mac_stop(eib_t *);
919b494511aSVenki Rajagopalan extern int eib_mac_multicast(eib_t *, boolean_t, uint8_t *);
920b494511aSVenki Rajagopalan extern int eib_mac_promisc(eib_t *, boolean_t);
921b494511aSVenki Rajagopalan extern int eib_mac_tx(eib_t *, mblk_t *);
922b494511aSVenki Rajagopalan extern int eib_mac_hca_portstate(eib_t *, ib_lid_t *, int *);
923b494511aSVenki Rajagopalan 
924b494511aSVenki Rajagopalan /*
925b494511aSVenki Rajagopalan  * VNIC related
926b494511aSVenki Rajagopalan  */
927b494511aSVenki Rajagopalan extern int eib_vnic_create(eib_t *, uint8_t *, uint16_t, eib_vnic_t **, int *);
928b494511aSVenki Rajagopalan extern void eib_vnic_delete(eib_t *, eib_vnic_t *);
929b494511aSVenki Rajagopalan extern int eib_vnic_wait_for_login_ack(eib_t *, eib_vnic_t *, int *);
930b494511aSVenki Rajagopalan extern void eib_vnic_login_ack(eib_t *, eib_login_data_t *);
931b494511aSVenki Rajagopalan extern int eib_vnic_wait_for_table(eib_t *, eib_vnic_t *, int *);
932b494511aSVenki Rajagopalan extern void eib_vnic_vhub_table_done(eib_vnic_t *, uint_t);
933b494511aSVenki Rajagopalan extern int eib_vnic_join_data_mcg(eib_t *, eib_vnic_t *, uint8_t *,
934b494511aSVenki Rajagopalan     boolean_t, int *);
935b494511aSVenki Rajagopalan extern int eib_vnic_setup_dest(eib_vnic_t *, eib_wqe_t *, uint8_t *, uint16_t);
936b494511aSVenki Rajagopalan extern void eib_vnic_leave_data_mcg(eib_t *, eib_vnic_t *, uint8_t *);
937b494511aSVenki Rajagopalan extern void eib_vnic_init_tables(eib_t *, eib_vnic_t *);
938b494511aSVenki Rajagopalan extern void eib_vnic_fini_tables(eib_t *, eib_vnic_t *, boolean_t);
939b494511aSVenki Rajagopalan extern eib_chan_t *eib_vnic_get_data_chan(eib_t *, int);
940b494511aSVenki Rajagopalan extern void eib_vnic_need_new(eib_t *, uint8_t *, uint16_t);
941b494511aSVenki Rajagopalan extern void eib_vnic_enqueue_req(eib_t *, eib_vnic_req_t *);
942b494511aSVenki Rajagopalan extern void eib_vnic_resurrect_zombies(eib_t *, uint8_t *);
943b494511aSVenki Rajagopalan extern void eib_vnic_restart(eib_t *, int, uint8_t *);
944b494511aSVenki Rajagopalan extern void eib_vnic_rejoin_mcgs(eib_t *);
945b494511aSVenki Rajagopalan extern void eib_rb_vnic_create(eib_t *, eib_vnic_t *, uint_t);
946b494511aSVenki Rajagopalan 
947b494511aSVenki Rajagopalan /*
948b494511aSVenki Rajagopalan  * Logging and other stuff
949b494511aSVenki Rajagopalan  */
950b494511aSVenki Rajagopalan extern void eib_debug_init(void);
951b494511aSVenki Rajagopalan extern void eib_debug_fini(void);
952b494511aSVenki Rajagopalan extern void eib_dprintf_crit(int, const char *fmt, ...);
953b494511aSVenki Rajagopalan extern void eib_dprintf_err(int, const char *fmt, ...);
954b494511aSVenki Rajagopalan extern void eib_dprintf_warn(int, const char *fmt, ...);
955b494511aSVenki Rajagopalan #ifdef EIB_DEBUG
956b494511aSVenki Rajagopalan extern void eib_dprintf_debug(int, const char *fmt, ...);
957b494511aSVenki Rajagopalan extern void eib_dprintf_args(int, const char *fmt, ...);
958b494511aSVenki Rajagopalan extern void eib_dprintf_pkt(int, uint8_t *, uint_t);
959b494511aSVenki Rajagopalan extern void eib_dprintf_verbose(int, const char *fmt, ...);
960b494511aSVenki Rajagopalan #endif
961b494511aSVenki Rajagopalan extern int eib_get_props(eib_t *);
962b494511aSVenki Rajagopalan extern void eib_update_props(eib_t *, eib_gw_info_t *);
963b494511aSVenki Rajagopalan extern void eib_rb_get_props(eib_t *);
964b494511aSVenki Rajagopalan 
965b494511aSVenki Rajagopalan /*
966b494511aSVenki Rajagopalan  * EoIB specific global variables