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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_FCTL_H
27 #define	_FCTL_H
28 
29 
30 #include <sys/note.h>
31 #include <sys/time.h>
32 
33 #ifdef	__cplusplus
34 extern "C" {
35 #endif
36 
37 /*
38  * These are the legal values for the fp_state member of the fc_local_port_t
39  * struct. These values are understood by ULPs, FCA drivers, and fp/fctl.
40  *
41  * The link state value is kept the least significant byte, and the link speed
42  * value is kept in the next most significant byte:
43  *
44  *  +------------+------------+
45  *  | link speed | link state |
46  *  +------------+------------+
47  */
48 /* Values for the link state (least significant byte as above) */
49 #define	FC_STATE_OFFLINE		0x0000	/* Link is offline or not */
50 						/* initialized. */
51 #define	FC_STATE_ONLINE			0x0001	/* Link is up, the topology */
52 						/* is given in fp_topology. */
53 #define	FC_STATE_LOOP			0x0002	/* Link is up, the topology */
54 						/* is a private loop. */
55 #define	FC_STATE_NAMESERVICE		0x0003	/* Not really used */
56 #define	FC_STATE_RESET			0x0004
57 #define	FC_STATE_RESET_REQUESTED	0x0005
58 #define	FC_STATE_LIP			0x0006
59 #define	FC_STATE_LIP_LBIT_SET		0x0007
60 #define	FC_STATE_DEVICE_CHANGE		0x0008	/* For ULPs */
61 #define	FC_STATE_TARGET_PORT_RESET	0x0009
62 
63 /* Values for the link speed (next least significant byte as above) */
64 #define	FC_STATE_1GBIT_SPEED		0x0100	/* 1 Gbit/sec */
65 #define	FC_STATE_2GBIT_SPEED		0x0400	/* 2 Gbit/sec */
66 #define	FC_STATE_4GBIT_SPEED		0x0500	/* 4 Gbit/sec */
67 #define	FC_STATE_10GBIT_SPEED		0x0600	/* 10 Gbit/sec */
68 #define	FC_STATE_8GBIT_SPEED		0x0700	/* 8 Gbit/sec */
69 #define	FC_STATE_16GBIT_SPEED		0x0800	/* 16 Gbit/sec */
70 #define	FC_STATE_FULL_SPEED		FC_STATE_1GBIT_SPEED
71 #define	FC_STATE_DOUBLE_SPEED		FC_STATE_2GBIT_SPEED
72 
73 /*
74  * Macros to discriminate between the link state byte and the link speed
75  * byte in fp_state (also good for improved code obfuscation and job security
76  * even during a good economy).
77  */
78 #define	FC_PORT_SPEED_MASK(state)	((state) & 0xFF00)
79 #define	FC_PORT_STATE_MASK(state)	((state) & 0xFF)
80 
81 
82 /*
83  * Notify flags passed between ULPs and FCAs
84  *
85  *	3 bytes			1 byte
86  *  +-----------------------+---------------+
87  *  | Flag specific values  |  Notify flag  |
88  *  +-----------------------+---------------+
89  */
90 #define	FC_NOTIFY_RECOVERY_DONE		0x01
91 #define	FC_NOTIFY_TARGET_MODE		0x02
92 #define	FC_NOTIFY_NO_TARGET_MODE	0x03
93 #define	FC_NOTIFY_RECOVERY_CLEANUP	0x04
94 #define	FC_NOTIFY_THROTTLE		0x80
95 
96 #define	FC_NOTIFY_FLAG_MASK(cmd)	((cmd) & 0xFF)
97 #define	FC_NOTIFY_VALUE_MASK(cmd)	((cmd) & 0xFFFFFF00)
98 #define	FC_NOTIFY_GET_FLAG(cmd)		FC_NOTIFY_FLAG_MASK(cmd)
99 #define	FC_NOTIFY_GET_VALUE(cmd)	(FC_NOTIFY_VALUE_MASK(cmd) >> 8)
100 
101 
102 /*
103  * pkt_tran_flags definitions
104  */
105 #define	FC_TRAN_CLASS(flag)		((flag) & 0xF0)
106 #define	FC_TRAN_INTR			0x01
107 #define	FC_TRAN_NO_INTR			0x02
108 #define	FC_TRAN_HI_PRIORITY		0x04
109 #define	FC_TRAN_DUMPING			0x08
110 #define	FC_TRAN_CLASS1			0x10
111 #define	FC_TRAN_CLASS2			0x20
112 #define	FC_TRAN_CLASS3			0x30
113 #define	FC_TRAN_CLASS_INVALID		0xF0
114 #define	FC_TRAN_IMMEDIATE_CB		0x100
115 
116 
117 /*
118  * pkt_tran_type definitions
119  */
120 #define	FC_PKT_NOP			0
121 #define	FC_PKT_INBOUND			1
122 #define	FC_PKT_OUTBOUND			2
123 #define	FC_PKT_EXCHANGE			3
124 #define	FC_PKT_FCP_READ			4
125 #define	FC_PKT_FCP_WRITE		5
126 #define	FC_PKT_IP_WRITE			6
127 #define	FC_PKT_BROADCAST		7
128 
129 
130 #define	FC_TRACE_LOG_MASK		0xF00000
131 #define	FC_TRACE_LOG_MSG		0x100000
132 #define	FC_TRACE_LOG_CONSOLE		0x200000
133 #define	FC_TRACE_LOG_CONSOLE_MSG	0x400000
134 #define	FC_TRACE_LOG_BUF		0x080000
135 
136 
137 /*
138  * The fc_packet_t represents an FC Exchange and is the primary unit of
139  * information exchange between FC driver modules.
140  */
141 typedef struct fc_packet {
142 	uint16_t		pkt_tran_flags;		/* transport flag */
143 	uint16_t		pkt_tran_type;		/* transport type */
144 	uint32_t		pkt_timeout;		/* time-out length */
145 	uint32_t		pkt_cmdlen;		/* command length */
146 	uint32_t		pkt_rsplen;		/* response length */
147 	uint32_t		pkt_datalen;		/* data length */
148 	caddr_t			pkt_cmd;		/* command */
149 	caddr_t			pkt_resp;		/* response */
150 	caddr_t			pkt_data;		/* data */
151 	struct buf		*pkt_data_buf;		/* reserved */
152 	void			(*pkt_ulp_comp)(struct fc_packet *);
153 							/* framework private */
154 	opaque_t		pkt_ulp_private; 	/* caller's private */
155 	void			(*pkt_comp)(struct fc_packet *); /* callback */
156 	struct fc_remote_port	*pkt_pd;		/* port device */
157 	ddi_dma_handle_t	pkt_cmd_dma;		/* command DMA */
158 	ddi_acc_handle_t	pkt_cmd_acc;		/* command access */
159 	ddi_dma_cookie_t	*pkt_cmd_cookie;	/* command cookie */
160 	ddi_dma_handle_t	pkt_resp_dma;		/* response DMA */
161 	ddi_acc_handle_t	pkt_resp_acc;		/* response access */
162 	ddi_dma_cookie_t	*pkt_resp_cookie;	/* response cookie */
163 	ddi_dma_handle_t	pkt_data_dma;		/* data DMA */
164 	ddi_acc_handle_t	pkt_data_acc;		/* data access */
165 	ddi_dma_cookie_t	*pkt_data_cookie; 	/* data cookie */
166 	uint_t			pkt_cmd_cookie_cnt;
167 	uint_t			pkt_resp_cookie_cnt;
168 	uint_t			pkt_data_cookie_cnt;	/* of a window */
169 	fc_frame_hdr_t		pkt_cmd_fhdr;		/* command frame hdr */
170 	opaque_t		pkt_fca_private; 	/* FCA private */
171 	uchar_t			pkt_state;		/* packet state */
172 	uchar_t			pkt_action;		/* packet action */
173 	uchar_t			pkt_expln;		/* reason explanation */
174 	uint32_t		pkt_reason;		/* expln of state */
175 	uint64_t		pkt_ena;		/* ENA in case of err */
176 	fc_frame_hdr_t		pkt_resp_fhdr;		/* response frame hdr */
177 	uint32_t		pkt_data_resid;		/* data resid length */
178 	uint32_t		pkt_resp_resid;		/* resp resid length */
179 	opaque_t		pkt_fca_device;		/* FCA device ptr */
180 	opaque_t		pkt_ub_resp_token;	/* UB resp token */
181 	opaque_t		pkt_session;		/* reserved */
182 	opaque_t		pkt_security1;		/* reserved */
183 	opaque_t		pkt_security2;		/* reserved */
184 	opaque_t		pkt_qos1;		/* reserved */
185 	opaque_t		pkt_qos2;		/* reserved */
186 	opaque_t		pkt_ulp_rsvd1;		/* ULP reserved */
187 
188 	/*
189 	 * The pkt_ulp_rscn_infop (aka pkt_ulp_rsvd1) field is used to carry
190 	 * the rscn info (of type fc_ulp_rscn_info_t) down to the transport so
191 	 * that the transport can determine (in some cases) whether or not the
192 	 * requested operation was aware of the latest state change
193 	 * notification.
194 	 *
195 	 * If not NULL, then the pkt_ulp_rscn_infop (aka pkt_ulp_rsvd1) may
196 	 * point to an fc_ulp_rscn_info_t struct that contains the rscn count
197 	 * information for this fc_packet_t.
198 	 */
199 #define	pkt_ulp_rscn_infop	pkt_ulp_rsvd1		/* tracks rscn counts */
200 
201 	opaque_t		pkt_ulp_rsvd2;		/* ULP reserved */
202 	opaque_t		pkt_fctl_rsvd1;		/* Transport reserved */
203 	opaque_t		pkt_fctl_rsvd2;		/* Transport reserved */
204 	opaque_t		pkt_fca_rsvd1;		/* FCA reserved */
205 	opaque_t		pkt_fca_rsvd2;		/* FCA reserved */
206 	uint64_t		pkt_rsvd;		/* should be last */
207 } fc_packet_t;
208 
209 #if	!defined(__lint)
210 _NOTE(SCHEME_PROTECTS_DATA("not messed with after transport", fc_packet))
211 #endif	/* __lint */
212 
213 
214 typedef struct fca_hba_fru_details {
215 	uint32_t    port_index;
216 	uint64_t    high;
217 	uint64_t    low;
218 } fca_hba_fru_details_t;
219 
220 /*
221  * HBA/Port attributes tracked for the T11 FC-HBA specification
222  */
223 #define	FC_HBA_PORTSPEED_UNKNOWN	0    /* Unknown - transceiver incable */
224 					    /* of reporting */
225 #define	FC_HBA_PORTSPEED_1GBIT		1    /* 1 GBit/sec */
226 #define	FC_HBA_PORTSPEED_2GBIT		2    /* 2 GBit/sec */
227 #define	FC_HBA_PORTSPEED_10GBIT		4    /* 10 GBit/sec */
228 #define	FC_HBA_PORTSPEED_4GBIT		8    /* 4 GBit/sec */
229 #define	FC_HBA_PORTSPEED_8GBIT		16   /* 8 GBit/sec */
230 #define	FC_HBA_PORTSPEED_16GBIT		32   /* 16 GBit/sec */
231 #define	FC_HBA_PORTSPEED_NOT_NEGOTIATED	(1<<15)   /* Speed not established */
232 
233 #define	FCHBA_MANUFACTURER_LEN		64
234 #define	FCHBA_SERIAL_NUMBER_LEN		64
235 #define	FCHBA_MODEL_LEN			256
236 #define	FCHBA_MODEL_DESCRIPTION_LEN	256
237 #define	FCHBA_HARDWARE_VERSION_LEN	256
238 #define	FCHBA_DRIVER_VERSION_LEN	256
239 #define	FCHBA_OPTION_ROM_VERSION_LEN	256
240 #define	FCHBA_FIRMWARE_VERSION_LEN	256
241 #define	FCHBA_DRIVER_NAME_LEN		256
242 #define	FCHBA_SYMB_NAME_LEN		255
243 
244 typedef struct fca_port_attrs {
245 	char		manufacturer[FCHBA_MANUFACTURER_LEN];
246 	char		serial_number[FCHBA_SERIAL_NUMBER_LEN];
247 	char		model[FCHBA_MODEL_LEN];
248 	char		model_description[FCHBA_MODEL_DESCRIPTION_LEN];
249 	char		hardware_version[FCHBA_HARDWARE_VERSION_LEN];
250 	char		driver_version[FCHBA_DRIVER_VERSION_LEN];
251 	char		option_rom_version[FCHBA_OPTION_ROM_VERSION_LEN];
252 	char		firmware_version[FCHBA_FIRMWARE_VERSION_LEN];
253 	char		driver_name[FCHBA_DRIVER_NAME_LEN];
254 	uint32_t	vendor_specific_id;
255 	uint32_t	supported_cos;
256 	uint32_t	supported_speed;
257 	uint32_t	max_frame_size;
258 	fca_hba_fru_details_t	hba_fru_details;
259 	uchar_t		sym_node_name[FCHBA_SYMB_NAME_LEN];
260 	uchar_t		sym_port_name[FCHBA_SYMB_NAME_LEN];
261 } fca_port_attrs_t;
262 
263 
264 
265 typedef struct unsolicited_buffer {
266 	uchar_t		ub_class;
267 	uchar_t		ub_resvd1;
268 	ushort_t	ub_resp_flags;		/* ULP-specific flags */
269 	ushort_t	ub_resp_key;		/* ULP-specific key */
270 	ushort_t	ub_resvd2;
271 	uint32_t	ub_bufsize;
272 	caddr_t		ub_buffer;
273 	void		*ub_port_private;
274 	void		*ub_fca_private;
275 	opaque_t	ub_port_handle;
276 	opaque_t	ub_resp_token;		/* Response token */
277 	uint64_t	ub_token;
278 	fc_frame_hdr_t 	ub_frame;
279 } fc_unsol_buf_t;
280 
281 #define	FC_UB_RESP_LOGIN_REQUIRED	0x4000
282 
283 typedef struct fc_trace_dmsg {
284 	int			id_size;	/* message size */
285 	int			id_flag;	/* for future */
286 	timespec_t		id_time;	/* timestamp */
287 	caddr_t			id_buf;		/* message buffer */
288 	struct fc_trace_dmsg	*id_next;	/* next message in queue */
289 } fc_trace_dmsg_t;
290 
291 #define	FC_TRACE_LOGQ_V2		0x1
292 
293 typedef struct fc_trace_logq {
294 	kmutex_t	il_lock;	/* lock to avoid clutter */
295 	int		il_hiwat;	/* maximum queue size */
296 	int		il_flags;
297 	int		il_size;	/* current size */
298 	int		il_afail;	/* count of allocation failures */
299 	int		il_lfail;	/* general logging failures */
300 	int		il_id;		/* message Id */
301 	fc_trace_dmsg_t	*il_msgh;	/* messages head */
302 	fc_trace_dmsg_t	*il_msgt;	/* messages tail */
303 } fc_trace_logq_t;
304 
305 
306 /*
307  * Values for the pd_type field in the fc_remote_port_t struct below.
308  * (Also used in map_type and changelist determination)
309  */
310 #define	PORT_DEVICE_NOCHANGE		0x0 /* Event occurred on link, but */
311 					    /* no change on the remote port */
312 #define	PORT_DEVICE_NEW			0x1 /* Newly created remote port, or */
313 					    /* port has come back after being */
314 					    /* marked as PORT_DEVICE_OLD */
315 #define	PORT_DEVICE_OLD			0x2 /* RSCN or Reset has occurred, */
316 					    /* the remote port may come back */
317 #define	PORT_DEVICE_CHANGED		0x3 /* D_ID, PWWN, or other change */
318 					    /* has occurred (hot swap?) */
319 #define	PORT_DEVICE_DELETE		0x4 /* Not used? */
320 #define	PORT_DEVICE_USER_LOGIN		0x5 /* only for changelist->map_type */
321 #define	PORT_DEVICE_USER_LOGOUT		0x6 /* only for changelist->map_type */
322 #define	PORT_DEVICE_USER_CREATE		0x7 /* only for changelist->map_type */
323 #define	PORT_DEVICE_USER_DELETE		0x8 /* only for changelist->map_type */
324 
325 /*
326  * Flags used for fc_portmap->map_type
327  */
328 
329 #define	PORT_DEVICE_DUPLICATE_MAP_ENTRY 0x00000001 /* map entry has another */
330 						/* entry for this target */
331 						/* later in the list */
332 #define	PORT_DEVICE_NO_SKIP_DEVICE_DISCOVERY	0x00000002
333 
334 
335 /*
336  * Logging and Debugging support
337  */
338 void fc_trace_debug(fc_trace_logq_t *logq, caddr_t name, int dflag, int dlevel,
339     int errno, const char *fmt, ...);
340 
341 fc_trace_logq_t *fc_trace_alloc_logq(int maxsize);
342 void fc_trace_free_logq(fc_trace_logq_t *logq);
343 void fc_trace_logmsg(fc_trace_logq_t *logq, caddr_t buf, int level);
344 caddr_t fc_trace_msg(int fc_trace_error);
345 
346 /*
347  * Common utility routines
348  */
349 
350 void fc_wwn_to_str(la_wwn_t *wwn, caddr_t string);
351 void fc_str_to_wwn(caddr_t string, la_wwn_t *wwn);
352 
353 #if	!defined(__lint)
354 _NOTE(SCHEME_PROTECTS_DATA("unique per request", unsolicited_buffer))
355 #endif	/* __lint */
356 
357 #ifdef	__cplusplus
358 }
359 #endif
360 
361 #endif	/* _FCTL_H */
362