summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/ib/ibnex/ibnex.h
blob: f2928d8f4b5ff913163c606e84514f1858583746 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef _SYS_IB_IBNEX_IBNEX_H
#define	_SYS_IB_IBNEX_IBNEX_H

/*
 * ibnex.h
 * This file contains defines and structures used within the IB Nexus
 */

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/sunndi.h>

/* Defines for return codes within the IB nexus driver */
typedef enum {
	IBNEX_SUCCESS =	0,
	IBNEX_FAILURE = -1,
	IBNEX_OFFLINE_FAILED = -2,
	IBNEX_BUSY = -3,
	IBNEX_INVALID_NODE = -4
} ibnex_rval_t;

#define	IBNEX_IOC_GUID_LEN	33
#define	IBNEX_PHCI_GUID_LEN	66

/* IOC device node specific data */
typedef struct ibnex_ioc_node_s {
	ib_guid_t		iou_guid;	/* GUID of the IOU */
	ib_guid_t		ioc_guid;	/* GUID of the IOC */
	char			ioc_id_string[IB_DM_IOC_ID_STRING_LEN];
	uint32_t		ioc_ngids;
	/* This field will be non NULL only for diconnected IOCs */
	ib_dm_ioc_ctrl_profile_t	*ioc_profile;
	char				ioc_guid_str[IBNEX_IOC_GUID_LEN];
	char				ioc_phci_guid[IBNEX_PHCI_GUID_LEN];
} ibnex_ioc_node_t;

/* DLPI device node specific data */
typedef struct ibnex_port_node_s {
	uint8_t			port_num;
	int			port_commsvc_idx;
	ib_guid_t		port_guid;
	ib_guid_t		port_hcaguid;
	ib_pkey_t		port_pkey;
	dev_info_t		*port_pdip;
} ibnex_port_node_t;

/* Pseudo device node specific data */
typedef struct ibnex_pseudo_node_s {
	char			*pseudo_node_addr;	/* node addr of drvr */
	char			*pseudo_unit_addr;	/* unit addr of drvr */
	int			pseudo_unit_addr_len;	/* unit addr len */
	char			*pseudo_devi_name;	/* name of driver */
	int			pseudo_merge_node;	/* merge node */
} ibnex_pseudo_node_t;

/*
 * Defines for Child device node types. Note that these values are also
 * in use by usr/src/lib/cfgadm_plugins/ib/common/cfga_ib.h.
 * Any changes to these need to be reflected in that file as well.
 */
typedef enum {
	IBNEX_PORT_COMMSVC_NODE		= 0,
	IBNEX_VPPA_COMMSVC_NODE		= 1,
	IBNEX_HCASVC_COMMSVC_NODE	= 2,
	IBNEX_IOC_NODE			= 4,
	IBNEX_PSEUDO_NODE		= 8
} ibnex_node_type_t;

#define	IBNEX_HCA_CHILD_NODE (IBNEX_PORT_COMMSVC_NODE |	\
	    IBNEX_VPPA_COMMSVC_NODE | IBNEX_HCASVC_COMMSVC_NODE)


/*
 * Defines for Child device node state:
 *
 * By default the node is set to CONFIGURED state.
 *	CONFIGURED:---(bus_config/cfgadm configure)---->CONFIGURED
 *	CONFIGURED:----(cfgadm unconfigure:success)--->UNCONFIGURED
 *	CONFIGURED:----(cfgadm unconfigure:fail)--->still CONFIGURED
 *	UNCONFIGURED:----(cfgadm configure:success)--->CONFIGURED
 *
 * We maintain two additional states:
 *	CONFIGURING:---(bus_config/cfgadm configure in progress
 *	UNCONFIGURING:--(cfgadm unconfigure in progress)
 * This is maintained to avoid race conditions between multiple cfgadm
 * operations.
 */
typedef enum ibnex_node_state_e {
	IBNEX_CFGADM_CONFIGURED,	/* node is "configured" */
	IBNEX_CFGADM_UNCONFIGURED,	/* node is "unconfigured" */
	IBNEX_CFGADM_CONFIGURING,	/* node getting configured */
	IBNEX_CFGADM_UNCONFIGURING	/* node getting unconfigured */
} ibnex_node_state_t;

/*
 * Defines for reprobe_state:
 * 	IBNEX_NODE_REPROBE_NOTIFY_ON_UPDATE
 *		Reprobe and notify if there is a property update
 *	IBNEX_NODE_REPROBE_NOTIFY_ALWAYS
 *		Reprobe and notify always.
 *	IBNEX_NODE_REPROBE_IOC_WAIT
 *		Reprobe for IOC apid waiting
 *
 * Device reprobes triggered by ibt_reprobe_dev will result in an DDI
 * event, even though no prepoerties have changed.
 */

/*
 * Defines for node_ap_state:
 * IBNEX_NODE_AP_CONFIGURED
 * 	this node was not unconfigured by cfgadm.
 * IBNEX_NODE_AP_UNCONFIGURED
 * 	this node has been unconfigured by cfgadm.
 * IBNEX_NODE_AP_CONFIGURING
 * 	this node is being configured by cfgadm
 */
#define	IBNEX_NODE_AP_CONFIGURED	0x0
#define	IBNEX_NODE_AP_UNCONFIGURED	0x1
#define	IBNEX_NODE_AP_CONFIGURING	0x2

#define	IBNEX_NODE_REPROBE_NOTIFY_ON_UPDATE	0x01
#define	IBNEX_NODE_REPROBE_NOTIFY_ALWAYS	0x02
#define	IBNEX_NODE_REPROBE_IOC_WAIT			0x04

/* Node specific information, stored as dev_info_t private data */
typedef struct ibnex_node_data_s {
	dev_info_t		*node_dip;
	union {
		ibnex_ioc_node_t	ioc_node;
		ibnex_port_node_t	port_node;
		ibnex_pseudo_node_t	pseudo_node;
	} node_data;
	struct ibnex_node_data_s *node_next;
	struct ibnex_node_data_s *node_prev;
	ibnex_node_type_t	node_type;
	ibnex_node_state_t	node_state;
	int			node_reprobe_state;	/* Node reprobe flag */
	unsigned int		node_ap_state;
} ibnex_node_data_t;

/*
 * The fields of IOC and Port node are initialized when the
 * device node is created. These are read only for the rest
 * of the IBnexus driver.
 */
_NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_ioc_node_s))
_NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_port_node_s))
_NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_pseudo_node_s))
_NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_node_data_s))

#define	IBNEX_VALID_NODE_TYPE(n)	\
	(((n)->node_type == IBNEX_PORT_COMMSVC_NODE) || \
	((n)->node_type == IBNEX_VPPA_COMMSVC_NODE) || \
	((n)->node_type == IBNEX_HCASVC_COMMSVC_NODE) || \
	((n)->node_type == IBNEX_IOC_NODE) || \
	((n)->node_type == IBNEX_PSEUDO_NODE))

#define	IBNEX_COMMSVC_NODE_TYPE(n)	\
	(((n)->node_type == IBNEX_PORT_COMMSVC_NODE) || \
	((n)->node_type == IBNEX_VPPA_COMMSVC_NODE) || \
	((n)->node_type == IBNEX_HCASVC_COMMSVC_NODE))

/*
 * Definition for the IB nexus global per-instance structure.
 * IB nexus supports only one instance.
 */
typedef struct ibnex_s {
	dev_info_t		*ibnex_dip;
	kmutex_t		ibnex_mutex;
	int			ibnex_num_comm_svcs;
	char			**ibnex_comm_svc_names;
	int			ibnex_nvppa_comm_svcs;
	char			**ibnex_vppa_comm_svc_names;
	int			ibnex_nhcasvc_comm_svcs;
	char			**ibnex_hcasvc_comm_svc_names;
	ibnex_node_data_t	*ibnex_port_node_head;
	ibnex_node_data_t	*ibnex_ioc_node_head;
	ibnex_node_data_t	*ibnex_pseudo_node_head;

	/*
	 * NDI Event handle for -all- ibnexus events
	 * Event Cookie for IB_PROP_UPDATE_EVENT event
	 */
	ndi_event_hdl_t		ibnex_ndi_event_hdl;
	ddi_eventcookie_t	ibnex_prop_update_evt_cookie;

	/* Flags & condition variables for reprobe handling */
	int					ibnex_reprobe_state;
	kcondvar_t			ibnex_reprobe_cv;

	/* Count of disconnected IOCs still configured */
	int					ibnex_num_disconnect_iocs;

	/* Pseudo nodes inited from ibnex_get_snapshot? */
	int			ibnex_pseudo_inited;
	/*
	 * IOC list used by all HCAs.
	 */
	kcondvar_t		ibnex_ioc_list_cv;
	uint32_t		ibnex_ioc_list_state;
	ibdm_ioc_info_t		*ibnex_ioc_list;

	ddi_taskq_t		*ibnex_taskq_id;
} ibnex_t;

/*
 * States for ibnex_ioc_list_state
 */
#define	IBNEX_IOC_LIST_READY	0x0
#define	IBNEX_IOC_LIST_RENEW	0x1
#define	IBNEX_IOC_LIST_ACCESS	0x2

/*
 * States for ibnex_reprobe_state
 *	0 to REPROBE_ALL_PROGRESS
 *		Reprobe all when no reprobes pending
 *	REPROBE_ALL_PROGRESS to REPROBE_ALL_WAIT
 *		Reprobe all request when another in progress
 *	0 to REPROBE_IOC_WAIT
 *		Waiting for One or more reprobe_ioc to complete
 *
 * Reprobe logic will ensure :
 *	1. A single reprobe all at any time.
 *	2. No individual IOC reprobe overlaps with reprobe all.
 *	3. Reprobe for multiple IOCs can be in parallel
 *	4. Single reprobe for each IOC.
 */
#define	IBNEX_REPROBE_ALL_PROGRESS	0x01
#define	IBNEX_REPROBE_ALL_WAIT		0x02
#define	IBNEX_REPROBE_IOC_WAIT		0x04

/* Defines for creating and binding device nodes.  */
#define	IBNEX_MAX_COMPAT_NAMES		6
#define	IBNEX_MAX_IBPORT_COMPAT_NAMES	3
#define	IBNEX_MAX_COMPAT_LEN		48
#define	IBNEX_MAX_COMPAT_PROP_SZ	\
	IBNEX_MAX_COMPAT_NAMES * IBNEX_MAX_COMPAT_LEN
#define	IBNEX_MAX_IBPORT_COMPAT_PROP_SZ	\
	IBNEX_MAX_IBPORT_COMPAT_NAMES * IBNEX_MAX_COMPAT_LEN
#define	IBNEX_DEVFS_ENUMERATE		0x1	/* enumerate via devfs(7fs) */
#define	IBNEX_CFGADM_ENUMERATE		0x2	/* enumerate via cfgadm */

#define	IBNEX_MAX_NODEADDR_SZ		35

/* Define for forming the unit address from GUID and class string */
#define	IBNEX_FORM_GUID(buf, size, guid) \
		(void) snprintf((buf), (size), "%llX", (longlong_t)guid);

#define	IBNEX_INVALID_PKEY(pkey)	\
		(((pkey) == IB_PKEY_INVALID_FULL) || \
		((pkey) == IB_PKEY_INVALID_LIMITED))

/*
 * Defines for the tags of IB DDI events
 */
typedef enum {
		IB_EVENT_TAG_PROP_UPDATE = 0
} ib_ddi_event_tag_t;

/* Definations for IB HW in device tree status */
#define	IBNEX_DEVTREE_NOT_CHECKED	-1
#define	IBNEX_HW_NOT_IN_DEVTREE		0
#define	IBNEX_HW_IN_DEVTREE		1

#ifdef __cplusplus
}
#endif

#endif	/* _SYS_IB_IBNEX_IBNEX_H */