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