xref: /illumos-gate/usr/src/uts/common/sys/fcoe/fcoe_common.h (revision 5df5713f81d69c1a0797f99b13e95e220da00ef9)
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 #ifndef	_FCOE_COMMON_H_
26 #define	_FCOE_COMMON_H_
27 
28 #ifdef	__cplusplus
29 extern "C" {
30 #endif
31 
32 #ifdef	_KERNEL
33 
34 /*
35  * Interface return value
36  */
37 #define	FCOE_SUCCESS		 0
38 #define	FCOE_FAILURE		-1
39 #define	FCOE_BUSY		-2
40 #define	FCOE_NOT_SUPPORTED	-3
41 #define	FCOE_BAD_FRAME		-4
42 
43 /*
44  * FCOE port speed
45  */
46 #define	FCOE_PORT_SPEED_1G	1000000000
47 #define	FCOE_PORT_SPEED_10G	10000000000
48 
49 /*
50  * FC Frame header size: 24 bytes
51  */
52 #define	FCFH_SIZE		(sizeof (fcoe_fc_frame_header_t))
53 
54 /*
55  * FLOGI
56  */
57 #define	FLOGI_REQ_PAYLOAD_SIZE	116
58 #define	FLOGI_ACC_PAYLOAD_SIZE	116
59 
60 /*
61  * Minimum MTU size
62  */
63 #define	FCOE_MIN_MTU_SIZE	2500
64 
65 /*
66  * 24 byte FC frame header
67  * For all data structures that have endian problems, we will use only
68  * one type: uint8_t. We need associate the data structure pointer with
69  * one buffer directly.
70  */
71 typedef struct fcoe_fc_frame_header {
72 	uint8_t hdr_r_ctl[1];
73 	uint8_t hdr_d_id[3];
74 
75 	uint8_t hdr_cs_ctl[1];
76 	uint8_t hdr_s_id[3];
77 
78 	uint8_t hdr_type[1];
79 	uint8_t hdr_f_ctl[3];
80 
81 	uint8_t hdr_seq_id[1];
82 	uint8_t hdr_df_ctl[1];
83 	uint8_t hdr_seq_cnt[2];
84 
85 	uint8_t hdr_oxid[2];
86 	uint8_t hdr_rxid[2];
87 
88 	uint8_t hdr_param[4];
89 } fcoe_fc_frame_header_t;
90 
91 /*
92  * Solicited frame:   allocted by FCOET/FOCEI,  free-ed by FCOE
93  * Unsolicited frame: allocated by FCOE,        free-ed by FCOET/FCOEI
94  */
95 struct fcoe_port;
96 typedef struct fcoe_frame {
97 	uint32_t		 frm_flags;
98 	void			*frm_netb;
99 	fcoe_fc_frame_header_t	*frm_hdr;
100 	uint8_t			*frm_ofh1;
101 	uint8_t			*frm_ofh2;
102 	uint8_t			*frm_fc_frame;
103 	uint8_t			*frm_payload;
104 	uint32_t		 frm_fc_frame_size;
105 	uint32_t		 frm_payload_size;
106 	uint32_t		 frm_alloc_size;
107 	struct fcoe_port	*frm_eport;
108 	void			*frm_fcoe_private;
109 	void			*frm_client_private;
110 } fcoe_frame_t;
111 
112 /*
113  * FCOE HBA
114  */
115 typedef struct fcoe_port {
116 	uint32_t	   eport_flags;
117 	void		  *eport_fcoe_private;
118 	void		  *eport_client_private;
119 	uint8_t		   eport_portwwn[8];
120 	uint8_t		   eport_nodewwn[8];
121 	uint32_t	   eport_max_fc_frame_size;
122 	uint32_t	   eport_mtu;
123 	uint64_t	   eport_link_speed;
124 	uint8_t		   eport_efh_dst[ETHERADDRL];
125 	void		 (*eport_tx_frame)(fcoe_frame_t *frame);
126 	fcoe_frame_t	*(*eport_alloc_frame)(struct fcoe_port *eport,
127 	    uint32_t this_fc_frame_size, void *netb);
128 	void		 (*eport_release_frame)(fcoe_frame_t *frame);
129 	void		*(*eport_alloc_netb)(struct fcoe_port *eport,
130 	    uint32_t this_fc_frame_size, uint8_t **ppfc);
131 	void		 (*eport_free_netb)(void *netb);
132 	void		 (*eport_deregister_client)(struct fcoe_port *eport);
133 	int		 (*eport_ctl)(struct fcoe_port *eport,
134 	    int cmd, void *arg);
135 	int		 (*eport_set_mac_address)(struct fcoe_port *eport,
136 	    uint8_t *addr, boolean_t fc_assigned);
137 } fcoe_port_t;
138 
139 /*
140  * FCOE only supports two kinds of topology: direct P2P, fabric P2P.
141  */
142 #define	EPORT_FLAG_IS_DIRECT_P2P	0x01
143 #define	EPORT_FLAG_TGT_MODE		0x02
144 #define	EPORT_FLAG_INI_MODE		0x04
145 #define	EPORT_FLAG_MAC_IN_USE		0x08
146 
147 #define	FCOE_NOTIFY_EPORT_LINK_UP	0x01
148 #define	FCOE_NOTIFY_EPORT_LINK_DOWN	0x02
149 #define	FCOE_NOTIFY_EPORT_ADDR_CHG	0x03
150 
151 #define	FCOE_PORT_CTL_CMDS		0x3000
152 #define	FCOE_CMD_PORT_ONLINE		(FCOE_PORT_CTL_CMDS | 0x01)
153 #define	FCOE_CMD_PORT_OFFLINE		(FCOE_PORT_CTL_CMDS | 0x02)
154 
155 typedef struct fcoe_client {
156 	uint32_t	 ect_eport_flags;
157 	uint32_t	 ect_max_fc_frame_size;
158 	uint32_t	 ect_private_frame_struct_size;
159 	uint32_t	 ect_channelid;
160 	void		*ect_client_port_struct;
161 	void		 (*ect_rx_frame)(fcoe_frame_t *frame);
162 	void		 (*ect_port_event)(fcoe_port_t *eport, uint32_t event);
163 	void		 (*ect_release_sol_frame)(fcoe_frame_t *frame);
164 } fcoe_client_t;
165 
166 /*
167  * Define common-used conversion or calculation macros
168  */
169 #define	FCOE_V2B_1(x_v, x_b)				\
170 	{						\
171 		((uint8_t *)(x_b))[0] = 0xFF & (x_v);	\
172 	}
173 
174 #define	FCOE_V2B_2(x_v, x_b)					\
175 	{							\
176 		((uint8_t *)(x_b))[1] = 0xFF & (x_v);		\
177 		((uint8_t *)(x_b))[0] = 0xFF & ((x_v) >> 8);	\
178 	}
179 
180 #define	FCOE_V2B_3(x_v, x_b)					\
181 	{							\
182 		((uint8_t *)(x_b))[2] = 0xFF & (x_v);		\
183 		((uint8_t *)(x_b))[1] = 0xFF & ((x_v) >> 8);	\
184 		((uint8_t *)(x_b))[0] = 0xFF & ((x_v) >> 16);	\
185 	}
186 
187 #define	FCOE_V2B_4(x_v, x_b)					\
188 	{							\
189 		((uint8_t *)(x_b))[3] = 0xFF & (x_v);		\
190 		((uint8_t *)(x_b))[2] = 0xFF & ((x_v) >> 8);	\
191 		((uint8_t *)(x_b))[1] = 0xFF & ((x_v) >> 16);	\
192 		((uint8_t *)(x_b))[0] = 0xFF & ((x_v) >> 24);	\
193 	}
194 
195 #define	FCOE_V2B_8(x_v, x_b)					\
196 	{							\
197 		((uint8_t *)(x_b))[7] = 0xFF & (x_v);		\
198 		((uint8_t *)(x_b))[6] = 0xFF & ((x_v) >> 8);	\
199 		((uint8_t *)(x_b))[5] = 0xFF & ((x_v) >> 16);	\
200 		((uint8_t *)(x_b))[4] = 0xFF & ((x_v) >> 24);	\
201 		((uint8_t *)(x_b))[3] = 0xFF & ((x_v) >> 32);	\
202 		((uint8_t *)(x_b))[2] = 0xFF & ((x_v) >> 40);	\
203 		((uint8_t *)(x_b))[1] = 0xFF & ((x_v) >> 48);	\
204 		((uint8_t *)(x_b))[0] = 0xFF & ((x_v) >> 56);	\
205 	}
206 
207 #define	FCOE_B2V_1(x_b)				\
208 	((((uint8_t *)(x_b))[0]) & 0xFF)
209 
210 #define	FCOE_B2V_2(x_b)						\
211 	((((uint8_t *)(x_b))[1] | ((uint8_t *)(x_b))[0] << 8) & 0xFFFF)
212 
213 #define	FCOE_B2V_3(x_b)						\
214 	((((uint8_t *)(x_b))[2] | ((uint8_t *)(x_b))[1] << 8 |	\
215 	((uint8_t *)(x_b))[0] << 16) & 0xFFFFFF)
216 
217 #define	FCOE_B2V_4(x_b)						\
218 	((((uint8_t *)(x_b))[3] | ((uint8_t *)(x_b))[2] << 8 |	\
219 	((uint8_t *)(x_b))[1] << 16 |				\
220 	((uint8_t *)(x_b))[0] << 24) & 0xFFFFFFFF)
221 
222 #define	FCOE_B2V_8(x_b)						\
223 	((((uint8_t *)(x_b))[7] | ((uint8_t *)(x_b))[6] << 8 |	\
224 	((uint8_t *)(x_b))[5] << 16 |				\
225 	((uint8_t *)(x_b))[4] << 24 |				\
226 	((uint8_t *)(x_b))[3] << 32 |				\
227 	((uint8_t *)(x_b))[2] << 40 |				\
228 	((uint8_t *)(x_b))[1] << 48 |				\
229 	((uint8_t *)(x_b))[0] << 56) & 0xFFFFFFFFFFFFFFFF)
230 
231 /*
232  * Get FC frame header's element
233  */
234 #define	FRM_R_CTL(x_frm)	(FCOE_B2V_1((x_frm)->frm_hdr->hdr_r_ctl))
235 #define	FRM_D_ID(x_frm)		(FCOE_B2V_3((x_frm)->frm_hdr->hdr_d_id))
236 #define	FRM_S_ID(x_frm)		(FCOE_B2V_3((x_frm)->frm_hdr->hdr_s_id))
237 #define	FRM_TYPE(x_frm)		(FCOE_B2V_1((x_frm)->frm_hdr->hdr_type))
238 #define	FRM_F_CTL(x_frm)	(FCOE_B2V_3((x_frm)->frm_hdr->hdr_f_ctl))
239 #define	FRM_SEQ_ID(x_frm)	(FCOE_B2V_1((x_frm)->frm_hdr->hdr_seq_id))
240 #define	FRM_DF_CTL(x_frm)	(FCOE_B2V_1((x_frm)->frm_hdr->hdr_df_ctl))
241 #define	FRM_SEQ_CNT(x_frm)	(FCOE_B2V_2((x_frm)->frm_hdr->hdr_seq_cnt))
242 #define	FRM_OXID(x_frm)		(FCOE_B2V_2((x_frm)->frm_hdr->hdr_oxid))
243 #define	FRM_RXID(x_frm)		(FCOE_B2V_2((x_frm)->frm_hdr->hdr_rxid))
244 #define	FRM_PARAM(x_frm)	(FCOE_B2V_4((x_frm)->frm_hdr->hdr_param))
245 
246 /*
247  * Set FC frame header's element
248  */
249 #define	FFM_R_CTL(x_v, x_frm)	FCOE_V2B_1((x_v), (x_frm)->frm_hdr->hdr_r_ctl)
250 #define	FFM_D_ID(x_v, x_frm)	FCOE_V2B_3((x_v), (x_frm)->frm_hdr->hdr_d_id)
251 #define	FFM_S_ID(x_v, x_frm)	FCOE_V2B_3((x_v), (x_frm)->frm_hdr->hdr_s_id)
252 #define	FFM_TYPE(x_v, x_frm)	FCOE_V2B_1((x_v), (x_frm)->frm_hdr->hdr_type)
253 #define	FFM_F_CTL(x_v, x_frm)	FCOE_V2B_3((x_v), (x_frm)->frm_hdr->hdr_f_ctl)
254 #define	FFM_SEQ_ID(x_v, x_frm)	FCOE_V2B_1((x_v), (x_frm)->frm_hdr->hdr_seq_id)
255 #define	FFM_DF_CTL(x_v, x_frm)	FCOE_V2B_1((x_v), (x_frm)->frm_hdr->hdr_df_ctl)
256 #define	FFM_SEQ_CNT(x_v, x_frm)	FCOE_V2B_2((x_v), (x_frm)->frm_hdr->hdr_seq_cnt)
257 #define	FFM_OXID(x_v, x_frm)	FCOE_V2B_2((x_v), (x_frm)->frm_hdr->hdr_oxid)
258 #define	FFM_RXID(x_v, x_frm)	FCOE_V2B_2((x_v), (x_frm)->frm_hdr->hdr_rxid)
259 #define	FFM_PARAM(x_v, x_frm)	FCOE_V2B_4((x_v), (x_frm)->frm_hdr->hdr_param)
260 
261 /*
262  * frame header checking
263  */
264 #define	FRM_IS_LAST_FRAME(x_frm)		(FRM_F_CTL(x_frm) & (1 << 19))
265 
266 /*
267  * FCOET/FCOEI will only call this fcoe function explicitly, all others
268  * should be called through vectors in struct fcoe_port.
269  * FCOE client call this to register one port to FCOE, FCOE need initialize
270  * and return the corresponding fcoe_port.
271  */
272 extern fcoe_port_t *fcoe_register_client(fcoe_client_t *client);
273 
274 #define	EPORT_CLT_TYPE(eport)				\
275 	(((eport)->eport_flags & EPORT_FLAG_INI_MODE) ? \
276 	FCOE_CLIENT_INITIATOR : FCOE_CLIENT_TARGET)
277 
278 #define	FCOE_SET_DEFAULT_OUI(x_oui)	\
279 	(x_oui)[0] = 0x0e; (x_oui)[1] = 0xfc; (x_oui)[2] = 0x00;
280 #define	FCOE_SET_DEFAULT_FPORT_ADDR(x_addr)	\
281 	FCOE_SET_DEFAULT_OUI(x_addr)		\
282 	(x_addr)[3] = 0xff; (x_addr)[4] = 0xff; (x_addr)[5] = 0xfe;
283 
284 /*
285  * FC payload size
286  */
287 #define	FCOE_DEFAULT_FCP_DATA_PAYLOAD_SIZE	2048
288 #define	FCOE_MIN_FCP_DATA_PAYLOAD_SIZE		1024
289 
290 typedef struct fcoe_fcp_cmnd {
291 	uint8_t ffc_lun[8];
292 	uint8_t ffc_ref_num[1];
293 
294 	/*
295 	 * least 3 bits
296 	 */
297 	uint8_t ffc_attribute[1];
298 
299 	/*
300 	 * Magnagement flags
301 	 */
302 	uint8_t ffc_management_flags[1];
303 
304 	/*
305 	 * additional cdb len and read/write flag
306 	 */
307 	uint8_t ffc_addlen_rdwr[1];
308 
309 	uint8_t ffc_cdb[16];
310 	uint8_t ffc_fcp_dl[4];
311 } fcoe_fcp_cmnd_t;
312 
313 typedef struct fcoe_fcp_rsp {
314 	uint8_t ffr_rsvd[8];
315 
316 	/*
317 	 * see SAM-4
318 	 */
319 	uint8_t ffr_retry_delay_timer[2];
320 	uint8_t ffr_flags[1];
321 	uint8_t ffr_scsi_status[1];
322 	uint8_t ffr_resid[4];
323 	uint8_t ffr_sns_len[4];
324 	uint8_t ffr_rsp_len[4];
325 	/*
326 	 * Followed by sense data when available
327 	 */
328 } fcoe_fcp_rsp_t;
329 
330 typedef struct fcoe_fcp_xfer_rdy {
331 	uint8_t fxr_data_ro[4];
332 	uint8_t fxr_burst_len[4];
333 	uint8_t fxr_rsvd[4];
334 } fcoe_fcp_xfer_rdy_t;
335 
336 /*
337  * FCOE project global functions
338  */
339 #define	FCOE_SEC2TICK(x_sec)	(drv_usectohz((x_sec) * 1000000))
340 typedef void (*TQ_FUNC_P)(void *);
341 extern void fcoe_trace(caddr_t ident, const char *fmt, ...);
342 
343 #endif
344 
345 #ifdef	__cplusplus
346 }
347 #endif
348 
349 #endif	/* _FCOE_COMMON_H_ */
350