xref: /illumos-gate/usr/src/uts/common/sys/ib/ibnex/ibnex.h (revision b1593d50e783f7d66722dde093752b74ffa95176)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _SYS_IB_IBNEX_IBNEX_H
27 #define	_SYS_IB_IBNEX_IBNEX_H
28 
29 /*
30  * ibnex.h
31  * This file contains defines and structures used within the IB Nexus
32  */
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #include <sys/sunndi.h>
39 
40 /* Defines for return codes within the IB nexus driver */
41 typedef enum {
42 	IBNEX_SUCCESS =	0,
43 	IBNEX_FAILURE = -1,
44 	IBNEX_OFFLINE_FAILED = -2,
45 	IBNEX_BUSY = -3,
46 	IBNEX_INVALID_NODE = -4
47 } ibnex_rval_t;
48 
49 #define	IBNEX_IOC_GUID_LEN	33
50 #define	IBNEX_PHCI_GUID_LEN	66
51 
52 /* IOC device node specific data */
53 typedef struct ibnex_ioc_node_s {
54 	ib_guid_t		iou_guid;	/* GUID of the IOU */
55 	ib_guid_t		ioc_guid;	/* GUID of the IOC */
56 	char			ioc_id_string[IB_DM_IOC_ID_STRING_LEN];
57 	uint32_t		ioc_ngids;
58 	/* This field will be non NULL only for diconnected IOCs */
59 	ib_dm_ioc_ctrl_profile_t	*ioc_profile;
60 	char				ioc_guid_str[IBNEX_IOC_GUID_LEN];
61 	char				ioc_phci_guid[IBNEX_PHCI_GUID_LEN];
62 } ibnex_ioc_node_t;
63 
64 /* DLPI device node specific data */
65 typedef struct ibnex_port_node_s {
66 	uint8_t			port_num;
67 	int			port_commsvc_idx;
68 	ib_guid_t		port_guid;
69 	ib_guid_t		port_hcaguid;
70 	ib_pkey_t		port_pkey;
71 	dev_info_t		*port_pdip;
72 } ibnex_port_node_t;
73 
74 /* Pseudo device node specific data */
75 typedef struct ibnex_pseudo_node_s {
76 	char			*pseudo_node_addr;	/* node addr of drvr */
77 	char			*pseudo_unit_addr;	/* unit addr of drvr */
78 	int			pseudo_unit_addr_len;	/* unit addr len */
79 	char			*pseudo_devi_name;	/* name of driver */
80 	int			pseudo_merge_node;	/* merge node */
81 } ibnex_pseudo_node_t;
82 
83 /*
84  * Defines for Child device node types. Note that these values are also
85  * in use by usr/src/lib/cfgadm_plugins/ib/common/cfga_ib.h.
86  * Any changes to these need to be reflected in that file as well.
87  */
88 typedef enum {
89 	IBNEX_PORT_COMMSVC_NODE,
90 	IBNEX_VPPA_COMMSVC_NODE,
91 	IBNEX_HCASVC_COMMSVC_NODE,
92 	IBNEX_IOC_NODE,
93 	IBNEX_PSEUDO_NODE
94 } ibnex_node_type_t;
95 
96 
97 /*
98  * Defines for Child device node state:
99  *
100  * By default the node is set to CONFIGURED state.
101  *	CONFIGURED:---(bus_config/cfgadm configure)---->CONFIGURED
102  *	CONFIGURED:----(cfgadm unconfigure:success)--->UNCONFIGURED
103  *	CONFIGURED:----(cfgadm unconfigure:fail)--->still CONFIGURED
104  *	UNCONFIGURED:----(cfgadm configure:success)--->CONFIGURED
105  *
106  * We maintain two additional states:
107  *	CONFIGURING:---(bus_config/cfgadm configure in progress
108  *	UNCONFIGURING:--(cfgadm unconfigure in progress)
109  * This is maintained to avoid race conditions between multiple cfgadm
110  * operations.
111  */
112 typedef enum ibnex_node_state_e {
113 	IBNEX_CFGADM_CONFIGURED,	/* node is "configured" */
114 	IBNEX_CFGADM_UNCONFIGURED,	/* node is "unconfigured" */
115 	IBNEX_CFGADM_CONFIGURING,	/* node getting configured */
116 	IBNEX_CFGADM_UNCONFIGURING	/* node getting unconfigured */
117 } ibnex_node_state_t;
118 
119 /*
120  * Defines for reprobe_state:
121  * 	IBNEX_NODE_REPROBE_NOTIFY_ON_UPDATE
122  *		Reprobe and notify if there is a property update
123  *	IBNEX_NODE_REPROBE_NOTIFY_ALWAYS
124  *		Reprobe and notify always.
125  *	IBNEX_NODE_REPROBE_IOC_WAIT
126  *		Reprobe for IOC apid waiting
127  *
128  * Device reprobes triggered by ibt_reprobe_dev will result in an DDI
129  * event, even though no prepoerties have changed.
130  */
131 
132 /*
133  * Defines for node_ap_state:
134  * IBNEX_NODE_AP_CONFIGURED
135  * 	this node was not unconfigured by cfgadm.
136  * IBNEX_NODE_AP_UNCONFIGURED
137  * 	this node has been unconfigured by cfgadm.
138  * IBNEX_NODE_AP_CONFIGURING
139  * 	this node is being configured by cfgadm
140  */
141 #define	IBNEX_NODE_AP_CONFIGURED	0x0
142 #define	IBNEX_NODE_AP_UNCONFIGURED	0x1
143 #define	IBNEX_NODE_AP_CONFIGURING	0x2
144 
145 #define	IBNEX_NODE_REPROBE_NOTIFY_ON_UPDATE	0x01
146 #define	IBNEX_NODE_REPROBE_NOTIFY_ALWAYS	0x02
147 #define	IBNEX_NODE_REPROBE_IOC_WAIT			0x04
148 
149 /* Node specific information, stored as dev_info_t private data */
150 typedef struct ibnex_node_data_s {
151 	dev_info_t		*node_dip;
152 	union {
153 		ibnex_ioc_node_t	ioc_node;
154 		ibnex_port_node_t	port_node;
155 		ibnex_pseudo_node_t	pseudo_node;
156 	} node_data;
157 	struct ibnex_node_data_s *node_next;
158 	struct ibnex_node_data_s *node_prev;
159 	ibnex_node_type_t	node_type;
160 	ibnex_node_state_t	node_state;
161 	int			node_reprobe_state;	/* Node reprobe flag */
162 	unsigned int		node_ap_state;
163 } ibnex_node_data_t;
164 
165 /*
166  * The fields of IOC and Port node are initialized when the
167  * device node is created. These are read only for the rest
168  * of the IBnexus driver.
169  */
170 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_ioc_node_s))
171 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_port_node_s))
172 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_pseudo_node_s))
173 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_node_data_s))
174 
175 #define	IBNEX_VALID_NODE_TYPE(n)	\
176 	(((n)->node_type == IBNEX_PORT_COMMSVC_NODE) || \
177 	((n)->node_type == IBNEX_VPPA_COMMSVC_NODE) || \
178 	((n)->node_type == IBNEX_HCASVC_COMMSVC_NODE) || \
179 	((n)->node_type == IBNEX_IOC_NODE) || \
180 	((n)->node_type == IBNEX_PSEUDO_NODE))
181 
182 #define	IBNEX_COMMSVC_NODE_TYPE(n)	\
183 	(((n)->node_type == IBNEX_PORT_COMMSVC_NODE) || \
184 	((n)->node_type == IBNEX_VPPA_COMMSVC_NODE) || \
185 	((n)->node_type == IBNEX_HCASVC_COMMSVC_NODE))
186 
187 /*
188  * Definition for the IB nexus global per-instance structure.
189  * IB nexus supports only one instance.
190  */
191 typedef struct ibnex_s {
192 	dev_info_t		*ibnex_dip;
193 	kmutex_t		ibnex_mutex;
194 	int			ibnex_num_comm_svcs;
195 	char			**ibnex_comm_svc_names;
196 	int			ibnex_nvppa_comm_svcs;
197 	char			**ibnex_vppa_comm_svc_names;
198 	int			ibnex_nhcasvc_comm_svcs;
199 	char			**ibnex_hcasvc_comm_svc_names;
200 	ibnex_node_data_t	*ibnex_port_node_head;
201 	ibnex_node_data_t	*ibnex_ioc_node_head;
202 	ibnex_node_data_t	*ibnex_pseudo_node_head;
203 
204 	/*
205 	 * NDI Event handle for -all- ibnexus events
206 	 * Event Cookie for IB_PROP_UPDATE_EVENT event
207 	 */
208 	ndi_event_hdl_t		ibnex_ndi_event_hdl;
209 	ddi_eventcookie_t	ibnex_prop_update_evt_cookie;
210 
211 	/* Flags & condition variables for reprobe handling */
212 	int					ibnex_reprobe_state;
213 	kcondvar_t			ibnex_reprobe_cv;
214 
215 	/* Count of disconnected IOCs still configured */
216 	int					ibnex_num_disconnect_iocs;
217 
218 	/* Pseudo nodes inited from ibnex_get_snapshot? */
219 	int			ibnex_pseudo_inited;
220 	/*
221 	 * IOC list used by all HCAs.
222 	 */
223 	kcondvar_t		ibnex_ioc_list_cv;
224 	uint32_t		ibnex_ioc_list_state;
225 	ibdm_ioc_info_t		*ibnex_ioc_list;
226 } ibnex_t;
227 
228 /*
229  * States for ibnex_ioc_list_state
230  */
231 #define	IBNEX_IOC_LIST_READY	0x0
232 #define	IBNEX_IOC_LIST_RENEW	0x1
233 #define	IBNEX_IOC_LIST_ACCESS	0x2
234 
235 /*
236  * States for ibnex_reprobe_state
237  *	0 to REPROBE_ALL_PROGRESS
238  *		Reprobe all when no reprobes pending
239  *	REPROBE_ALL_PROGRESS to REPROBE_ALL_WAIT
240  *		Reprobe all request when another in progress
241  *	0 to REPROBE_IOC_WAIT
242  *		Waiting for One or more reprobe_ioc to complete
243  *
244  * Reprobe logic will ensure :
245  *	1. A single reprobe all at any time.
246  *	2. No individual IOC reprobe overlaps with reprobe all.
247  *	3. Reprobe for multiple IOCs can be in parallel
248  *	4. Single reprobe for each IOC.
249  */
250 #define	IBNEX_REPROBE_ALL_PROGRESS	0x01
251 #define	IBNEX_REPROBE_ALL_WAIT		0x02
252 #define	IBNEX_REPROBE_IOC_WAIT		0x04
253 
254 /* Defines for creating and binding device nodes.  */
255 #define	IBNEX_MAX_COMPAT_NAMES		6
256 #define	IBNEX_MAX_IBPORT_COMPAT_NAMES	3
257 #define	IBNEX_MAX_COMPAT_LEN		48
258 #define	IBNEX_MAX_COMPAT_PROP_SZ	\
259 	IBNEX_MAX_COMPAT_NAMES * IBNEX_MAX_COMPAT_LEN
260 #define	IBNEX_MAX_IBPORT_COMPAT_PROP_SZ	\
261 	IBNEX_MAX_IBPORT_COMPAT_NAMES * IBNEX_MAX_COMPAT_LEN
262 #define	IBNEX_DEVFS_ENUMERATE		0x1	/* enumerate via devfs(7fs) */
263 #define	IBNEX_CFGADM_ENUMERATE		0x2	/* enumerate via cfgadm */
264 
265 #define	IBNEX_MAX_NODEADDR_SZ		35
266 
267 /* Define for forming the unit address from GUID and class string */
268 #define	IBNEX_FORM_GUID(buf, size, guid) \
269 		(void) snprintf((buf), (size), "%llX", (longlong_t)guid);
270 
271 #define	IBNEX_INVALID_PKEY(pkey)	\
272 		(((pkey) == IB_PKEY_INVALID_FULL) || \
273 		((pkey) == IB_PKEY_INVALID_LIMITED))
274 
275 /*
276  * Defines for the tags of IB DDI events
277  */
278 typedef enum {
279 		IB_EVENT_TAG_PROP_UPDATE = 0
280 } ib_ddi_event_tag_t;
281 
282 /* Definations for IB HW in device tree status */
283 #define	IBNEX_DEVTREE_NOT_CHECKED	-1
284 #define	IBNEX_HW_NOT_IN_DEVTREE		0
285 #define	IBNEX_HW_IN_DEVTREE		1
286 
287 #ifdef __cplusplus
288 }
289 #endif
290 
291 #endif	/* _SYS_IB_IBNEX_IBNEX_H */
292