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	_FCOEI_H
26 #define	_FCOEI_H
27 
28 #ifdef	__cplusplus
29 extern "C" {
30 #endif
31 
32 #ifdef	_KERNEL
33 
34 /*
35  * FCOEI logging
36  */
37 extern int fcoei_use_ext_log;
38 extern void *fcoei_state;
39 
40 #define	FCOEI_EXT_LOG(log_ident, ...)				\
41 	{							\
42 		if (fcoei_use_ext_log) {			\
43 			fcoe_trace(log_ident, __VA_ARGS__);	\
44 		}						\
45 	}
46 
47 #define	FCOEI_LOG(log_ident, ...)		\
48 	fcoe_trace(log_ident, __VA_ARGS__)
49 
50 /*
51  * IOCTL supporting stuff
52  */
53 #define	FCOEI_IOCTL_FLAG_MASK		0xFF
54 #define	FCOEI_IOCTL_FLAG_IDLE		0x00
55 #define	FCOEI_IOCTL_FLAG_OPEN		0x01
56 #define	FCOEI_IOCTL_FLAG_EXCL		0x02
57 
58 /*
59  * define common constants
60  */
61 #define	FCOEI_MAX_OPEN_XCHS	2048
62 #define	FCOEI_SOL_HASH_SIZE	2048
63 #define	FCOEI_UNSOL_HASH_SIZE	128
64 #define	FCOEI_VERSION		"20090729-1.00"
65 #define	FCOEI_NAME_VERSION	"SunFC FCoEI v" FCOEI_VERSION
66 
67 /*
68  * define RNID Management Info
69  */
70 #define	FCOEI_RNID_HBA	0x7
71 #define	FCOEI_RNID_IPV4	0x1
72 #define	FCOEI_RNID_IPV6	0x2
73 
74 typedef enum event_type {
75 	AE_EVENT_NONE = 0,
76 	AE_EVENT_EXCHANGE,
77 	AE_EVENT_SOL_FRAME,
78 	AE_EVENT_UNSOL_FRAME,
79 	AE_EVENT_PORT,
80 	AE_EVENT_ABORT,
81 	AE_EVENT_RESET,
82 } event_type_e;
83 
84 typedef struct fcoei_event {
85 	list_node_t	 ae_node;
86 	event_type_e	 ae_type;
87 
88 	/*
89 	 * event specific
90 	 */
91 	uint64_t	 ae_specific;
92 
93 	/*
94 	 * event related object
95 	 */
96 	void		*ae_obj;
97 } fcoei_event_t;
98 
99 typedef struct fcoei_soft_state {
100 	dev_info_t		*ss_dip;
101 	uint32_t		 ss_flags;
102 	uint32_t		 ss_fcp_data_payload_size;
103 	list_t			 ss_comp_xch_list;
104 
105 	/*
106 	 * common data structure (fc_local_port_t) between leadville and fcoei
107 	 */
108 	void			*ss_port;
109 
110 	/*
111 	 * common data structure between fcoei and fcoe module
112 	 */
113 	fcoe_port_t		*ss_eport;
114 
115 	mod_hash_t		*ss_sol_oxid_hash;
116 	mod_hash_t		*ss_unsol_rxid_hash;
117 	uint16_t		 ss_next_sol_oxid;
118 	uint16_t		 ss_next_unsol_rxid;
119 
120 	/*
121 	 * We will use ss_taskq to dispatch watchdog and other tasks
122 	 */
123 	ddi_taskq_t		*ss_taskq;
124 
125 	kcondvar_t		 ss_watchdog_cv;
126 	kmutex_t		 ss_watchdog_mutex;
127 
128 	/*
129 	 * current port state, speed. see fctl.h
130 	 */
131 	uint16_t		 ss_link_state;
132 	uint16_t		 ss_link_speed;
133 
134 	/*
135 	 * # of unprocessed port/link change
136 	 */
137 	uint32_t		 ss_port_event_counter;
138 	list_t			 ss_event_list;
139 
140 	/*
141 	 * solicited and unsolicited exchanges timing checking
142 	 */
143 	uint32_t		 ss_sol_cnt1;
144 	uint32_t		 ss_sol_cnt2;
145 	uint32_t		*ss_sol_cnt;
146 	uint32_t		 ss_unsol_cnt1;
147 	uint32_t		 ss_unsol_cnt2;
148 	uint32_t		*ss_unsol_cnt;
149 
150 	/*
151 	 * ioctl related stuff
152 	 */
153 	uint32_t		 ss_ioctl_flags;
154 	kmutex_t		 ss_ioctl_mutex;
155 
156 	/*
157 	 * fp-defined routines that fcoei will call
158 	 */
159 	fc_fca_bind_info_t	 ss_bind_info;
160 
161 	/*
162 	 * fcoei-defined plogi response that fp will use
163 	 */
164 	la_els_logi_t		 ss_els_logi;
165 
166 	/*
167 	 * fcoei-defined routines that fp will call
168 	 */
169 	fc_fca_tran_t		 ss_fca_tran;
170 
171 	/*
172 	 * Direct p2p information, and ss's fcid will be stored here
173 	 */
174 	fc_fca_p2p_info_t	ss_p2p_info;
175 
176 	/*
177 	 * RNID Management Information
178 	 */
179 	fc_rnid_t			ss_rnid;
180 } fcoei_soft_state_t;
181 
182 #define	SS_FLAG_LV_NONE			0x0000
183 #define	SS_FLAG_LV_BOUND		0x0001
184 #define	SS_FLAG_PORT_DISABLED		0x0002
185 #define	SS_FLAG_TERMINATE_WATCHDOG	0x0004
186 #define	SS_FLAG_WATCHDOG_RUNNING	0x0008
187 #define	SS_FLAG_WATCHDOG_IDLE		0x0010
188 #define	SS_FLAG_TRIGGER_FP_ATTACH	0x0020
189 #define	SS_FLAG_FLOGI_FAILED		0x0040
190 
191 /*
192  * fcoei_frame - corresponding data structure to fcoe_frame/fc_frame
193  */
194 typedef struct fcoei_frame {
195 	fcoei_event_t		 ifm_ae;
196 	fcoe_frame_t		*ifm_frm;
197 	uint32_t		 ifm_flags;
198 	struct fcoei_exchange	*ifm_xch;
199 
200 	/*
201 	 * will be used after the relevant frame mblk was released by ETH layer
202 	 */
203 	uint8_t			 ifm_rctl;
204 } fcoei_frame_t;
205 
206 #define	IFM_FLAG_NONE		0x0000
207 #define	IFM_FLAG_FREE_NETB	0x0001
208 
209 /*
210  * fcoei_exchange - corresponding data structure to leadville fc_packet
211  */
212 typedef struct fcoei_exchange {
213 	list_node_t		 xch_comp_node;
214 	fcoei_event_t		 xch_ae;
215 	uint32_t		 xch_flags;
216 	fcoei_soft_state_t	*xch_ss;
217 	clock_t			 xch_start_tick;
218 	clock_t			 xch_end_tick;
219 	int			 xch_resid;
220 	ksema_t			 xch_sema;
221 
222 	/*
223 	 * current cnt for timing check, when the exchange is created
224 	 */
225 	uint32_t		*xch_cnt;
226 
227 	/*
228 	 * leadville fc_packet will not maintain oxid/rxid,
229 	 * so fcoei exchange  need do it
230 	 */
231 	uint16_t		 xch_oxid;
232 	uint16_t		 xch_rxid;
233 
234 	/*
235 	 * to link leadville's stuff
236 	 */
237 	fc_packet_t		*xch_fpkt;
238 	fc_unsol_buf_t		*xch_ub;
239 } fcoei_exchange_t;
240 
241 #define	XCH_FLAG_NONE		0x00000000
242 #define	XCH_FLAG_TMOUT		0x00000001
243 #define	XCH_FLAG_ABORT		0x00000002
244 #define	XCH_FLAG_IN_SOL_HASH	0x00000004
245 #define	XCH_FLAG_IN_UNSOL_HASH	0x00000008
246 
247 typedef struct fcoei_walk_arg
248 {
249 	fcoei_exchange_t	*wa_xch;
250 	uint16_t		 wa_oxid;
251 } fcoei_walk_arg_t;
252 
253 /*
254  * Define conversion and calculation macros
255  */
256 #define	FRM2IFM(x_frm)	((fcoei_frame_t *)(x_frm)->frm_client_private)
257 #define	FRM2SS(x_frm)							\
258 	((fcoei_soft_state_t *)(x_frm)->frm_eport->eport_client_private)
259 
260 #define	PORT2SS(x_port)	((fcoei_soft_state_t *)(x_port)->port_fca_private)
261 #define	EPORT2SS(x_eport)					\
262 	((fcoei_soft_state_t *)(x_eport)->eport_client_private)
263 
264 #define	FPKT2XCH(x_fpkt)	((fcoei_exchange_t *)x_fpkt->pkt_fca_private)
265 #define	FRM2FPKT(x_fpkt)	(FRM2IFM(frm)->ifm_xch->xch_fpkt)
266 
267 #define	HANDLE2SS(x_handle)	((fcoei_soft_state_t *)fca_handle)
268 
269 #define	FPLD			frm->frm_payload
270 
271 #define	FCOEI_FRM2FHDR(x_frm, x_fhdr)				\
272 	{							\
273 		(x_fhdr)->r_ctl = FRM_R_CTL(x_frm);		\
274 		(x_fhdr)->d_id = FRM_D_ID(x_frm);		\
275 		(x_fhdr)->s_id = FRM_S_ID(x_frm);		\
276 		(x_fhdr)->type = FRM_TYPE(x_frm);		\
277 		(x_fhdr)->f_ctl = FRM_F_CTL(x_frm);		\
278 		(x_fhdr)->seq_id = FRM_SEQ_ID(x_frm);		\
279 		(x_fhdr)->df_ctl = FRM_DF_CTL(x_frm);		\
280 		(x_fhdr)->seq_cnt = FRM_SEQ_CNT(x_frm);		\
281 		(x_fhdr)->ox_id = FRM_OXID(x_frm);		\
282 		(x_fhdr)->rx_id = FRM_RXID(x_frm);		\
283 		(x_fhdr)->ro = FRM_PARAM(x_frm);		\
284 	}
285 
286 #define	FCOEI_PARTIAL_FHDR2FRM(x_fhdr, x_frm)		\
287 	{						\
288 		FFM_R_CTL((x_fhdr)->r_ctl, x_frm);	\
289 		FFM_D_ID((x_fhdr)->d_id, x_frm);	\
290 		FFM_S_ID((x_fhdr)->s_id, x_frm);	\
291 		FFM_TYPE((x_fhdr)->type, x_frm);	\
292 		FFM_F_CTL((x_fhdr)->f_ctl, x_frm);	\
293 	}
294 
295 #define	PRT_FRM_HDR(x_p, x_f)						\
296 	{								\
297 		FCOEI_LOG(x_p, "rctl/%x, fctl/%x, type/%x, oxid/%x",	\
298 			FCOE_B2V_1((x_f)->frm_hdr->hdr_r_ctl),		\
299 			FCOE_B2V_3((x_f)->frm_hdr->hdr_f_ctl),		\
300 			FCOE_B2V_1((x_f)->frm_hdr->hdr_type),		\
301 			FCOE_B2V_2((x_f)->frm_hdr->hdr_oxid));		\
302 	}
303 
304 #define	FCOEI_INIT_SOL_ID_HASH(xch, xch_tmp)				\
305 	{								\
306 		do {							\
307 			if (++xch->xch_ss->ss_next_sol_oxid == 0xFFFF) { \
308 				++xch->xch_ss->ss_next_sol_oxid;	\
309 			}						\
310 		} while (mod_hash_find(xch->xch_ss->ss_sol_oxid_hash,	\
311 		    (mod_hash_key_t)(intptr_t)xch->xch_ss->ss_next_sol_oxid, \
312 		    (mod_hash_val_t)&xch_tmp) == 0);	\
313 		xch->xch_oxid = xch->xch_ss->ss_next_sol_oxid;		\
314 		xch->xch_rxid = 0xFFFF;					\
315 		(void) mod_hash_insert(xch->xch_ss->ss_sol_oxid_hash,	\
316 		    FMHK(xch->xch_oxid), (mod_hash_val_t)xch); \
317 		xch->xch_flags |= XCH_FLAG_IN_SOL_HASH;			\
318 	}
319 
320 #define	FCOEI_SET_UNSOL_FRM_RXID(frm, xch_tmp)				\
321 	{								\
322 		do {							\
323 			if (++FRM2SS(frm)->ss_next_unsol_rxid == 0xFFFF) { \
324 				++FRM2SS(frm)->ss_next_unsol_rxid;	\
325 			}						\
326 		} while (mod_hash_find(FRM2SS(frm)->ss_unsol_rxid_hash,	\
327 		    (mod_hash_key_t)(intptr_t)FRM2SS(frm)->ss_next_unsol_rxid, \
328 		    (mod_hash_val_t)&xch_tmp) == 0);	\
329 		FFM_RXID(FRM2SS(frm)->ss_next_unsol_rxid, frm);	\
330 	}
331 
332 #define	FCOEI_INIT_UNSOL_ID_HASH(xch)					\
333 	{								\
334 		xch->xch_oxid = fpkt->pkt_cmd_fhdr.ox_id;		\
335 		xch->xch_rxid = fpkt->pkt_cmd_fhdr.rx_id;		\
336 		(void) mod_hash_insert(xch->xch_ss->ss_unsol_rxid_hash,	\
337 		    FMHK(xch->xch_rxid), (mod_hash_val_t)xch); 		\
338 		xch->xch_flags |= XCH_FLAG_IN_UNSOL_HASH;		\
339 	}
340 
341 /*
342  * Common functions defined in fcoei.c
343  */
344 void fcoei_complete_xch(fcoei_exchange_t *xch, fcoe_frame_t *frm,
345     uint8_t pkt_state, uint8_t pkt_reason);
346 void fcoei_init_ifm(fcoe_frame_t *frm, fcoei_exchange_t *xch);
347 void fcoei_handle_comp_xch_list(fcoei_soft_state_t *ss);
348 
349 /*
350  * Common functions defined in fcoei_lv.c
351  */
352 void fcoei_init_fcatran_vectors(fc_fca_tran_t *fcatran);
353 void fcoei_process_event_exchange(fcoei_event_t *ae);
354 void fcoei_process_event_reset(fcoei_event_t *ae);
355 
356 /*
357  * Common functions defined in fcoei_eth.c
358  */
359 void fcoei_init_ect_vectors(fcoe_client_t *ect);
360 void fcoei_process_unsol_frame(fcoe_frame_t *frm);
361 void fcoei_handle_sol_frame_done(fcoe_frame_t *frm);
362 void fcoei_process_event_port(fcoei_event_t *ae);
363 void fcoei_port_event(fcoe_port_t *eport, uint32_t event);
364 
365 #endif /* _KERNEL */
366 
367 #ifdef	__cplusplus
368 }
369 #endif
370 
371 #endif /* _FCOEI_H */
372