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