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