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