12a8164dfSZhong Wang /*
22a8164dfSZhong Wang  * CDDL HEADER START
32a8164dfSZhong Wang  *
42a8164dfSZhong Wang  * The contents of this file are subject to the terms of the
52a8164dfSZhong Wang  * Common Development and Distribution License (the "License").
62a8164dfSZhong Wang  * You may not use this file except in compliance with the License.
72a8164dfSZhong Wang  *
82a8164dfSZhong Wang  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92a8164dfSZhong Wang  * or http://www.opensolaris.org/os/licensing.
102a8164dfSZhong Wang  * See the License for the specific language governing permissions
112a8164dfSZhong Wang  * and limitations under the License.
122a8164dfSZhong Wang  *
132a8164dfSZhong Wang  * When distributing Covered Code, include this CDDL HEADER in each
142a8164dfSZhong Wang  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152a8164dfSZhong Wang  * If applicable, add the following below this CDDL HEADER, with the
162a8164dfSZhong Wang  * fields enclosed by brackets "[]" replaced with your own identifying
172a8164dfSZhong Wang  * information: Portions Copyright [yyyy] [name of copyright owner]
182a8164dfSZhong Wang  *
192a8164dfSZhong Wang  * CDDL HEADER END
202a8164dfSZhong Wang  */
212a8164dfSZhong Wang /*
224558d122SViswanathan Kannappan  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
232a8164dfSZhong Wang  */
242a8164dfSZhong Wang #ifndef	_FCOET_H
252a8164dfSZhong Wang #define	_FCOET_H
262a8164dfSZhong Wang 
272a8164dfSZhong Wang #include <sys/stmf_defines.h>
282a8164dfSZhong Wang 
292a8164dfSZhong Wang #ifdef	__cplusplus
302a8164dfSZhong Wang extern "C" {
312a8164dfSZhong Wang #endif
322a8164dfSZhong Wang 
332a8164dfSZhong Wang #ifdef	_KERNEL
342a8164dfSZhong Wang 
3587dcbdbdSKevin Yu #define	FCOET_VERSION	"v20091123-1.02"
362a8164dfSZhong Wang #define	FCOET_NAME	"COMSTAR FCoET "
372a8164dfSZhong Wang #define	FCOET_MOD_NAME	FCOET_NAME FCOET_VERSION
382a8164dfSZhong Wang 
394558d122SViswanathan Kannappan #define	FCOET_TASKQ_NAME_LEN	32
404558d122SViswanathan Kannappan 
412a8164dfSZhong Wang /*
422a8164dfSZhong Wang  * FCOET logging
432a8164dfSZhong Wang  */
442a8164dfSZhong Wang extern int fcoet_use_ext_log;
452a8164dfSZhong Wang 
462a8164dfSZhong Wang /*
472a8164dfSZhong Wang  * Caution: 1) LOG will be available in debug/non-debug mode
482a8164dfSZhong Wang  *	    2) Anything which can potentially flood the log should be under
492a8164dfSZhong Wang  *	       extended logging, and use FCOET_EXT_LOG.
502a8164dfSZhong Wang  *	    3) Don't use FCOET_EXT_LOG in performance-critical code path, such
512a8164dfSZhong Wang  *	       as normal SCSI I/O code path. It could hurt system performance.
522a8164dfSZhong Wang  *	    4) Use kmdb to change focet_use_ext_log in the fly to adjust
532a8164dfSZhong Wang  *	       tracing
542a8164dfSZhong Wang  */
552a8164dfSZhong Wang #define	FCOET_EXT_LOG(log_ident, ...)	\
562a8164dfSZhong Wang 	{	\
572a8164dfSZhong Wang 		if (fcoet_use_ext_log) {	\
582a8164dfSZhong Wang 			fcoe_trace(log_ident, __VA_ARGS__);	\
592a8164dfSZhong Wang 		}	\
602a8164dfSZhong Wang 	}
612a8164dfSZhong Wang 
622a8164dfSZhong Wang #define	FCOET_LOG(log_ident, ...)	\
632a8164dfSZhong Wang 	fcoe_trace(log_ident, __VA_ARGS__)
642a8164dfSZhong Wang 
652a8164dfSZhong Wang /*
662a8164dfSZhong Wang  * define common-used constants
672a8164dfSZhong Wang  */
682a8164dfSZhong Wang #define	FCOET_MAX_LOGINS	2048
692a8164dfSZhong Wang #define	FCOET_MAX_XCHGES	2048
702a8164dfSZhong Wang #define	FCOET_SOL_HASH_SIZE	128
712a8164dfSZhong Wang #define	FCOET_UNSOL_HASH_SIZE	2048
722a8164dfSZhong Wang 
732a8164dfSZhong Wang typedef enum fcoet_sol_flogi_state {
742a8164dfSZhong Wang 	SFS_WAIT_LINKUP = 0,
752a8164dfSZhong Wang 	SFS_FLOGI_INIT,
762a8164dfSZhong Wang 	SFS_FLOGI_CHECK_TIMEOUT,
772a8164dfSZhong Wang 	SFS_ABTS_INIT,
782a8164dfSZhong Wang 	SFS_CLEAR_FLOGI,
792a8164dfSZhong Wang 	SFS_FLOGI_ACC,
802a8164dfSZhong Wang 	SFS_FLOGI_DONE
812a8164dfSZhong Wang } fcoet_sol_flogi_state_t;
822a8164dfSZhong Wang 
832a8164dfSZhong Wang /*
842a8164dfSZhong Wang  * define data structures
852a8164dfSZhong Wang  */
862a8164dfSZhong Wang struct fcoet_exchange;
872a8164dfSZhong Wang typedef struct fcoet_soft_state {
882a8164dfSZhong Wang 	/*
892a8164dfSZhong Wang 	 * basic information
902a8164dfSZhong Wang 	 */
912a8164dfSZhong Wang 	dev_info_t		*ss_dip;
922a8164dfSZhong Wang 	int			 ss_instance;
932a8164dfSZhong Wang 	uint32_t		 ss_flags;
942a8164dfSZhong Wang 	fct_local_port_t	*ss_port;
952a8164dfSZhong Wang 	fcoe_port_t		*ss_eport;
962a8164dfSZhong Wang 	char			 ss_alias[32];
972a8164dfSZhong Wang 	uint32_t		 ss_fcp_data_payload_size;
982a8164dfSZhong Wang 
992a8164dfSZhong Wang 	/*
1002a8164dfSZhong Wang 	 * support degregister remote port
1012a8164dfSZhong Wang 	 */
1022a8164dfSZhong Wang 	uint32_t		 ss_rportid_in_dereg;
1032a8164dfSZhong Wang 	uint32_t		 ss_rport_dereg_state;
1042a8164dfSZhong Wang 
1052a8164dfSZhong Wang 	/*
1062a8164dfSZhong Wang 	 * oxid/rxid
1072a8164dfSZhong Wang 	 */
1082a8164dfSZhong Wang 	mod_hash_t		*ss_sol_oxid_hash;
1092a8164dfSZhong Wang 	mod_hash_t		*ss_unsol_rxid_hash;
1102a8164dfSZhong Wang 	uint16_t		 ss_next_sol_oxid;
1112a8164dfSZhong Wang 	uint16_t		 ss_next_unsol_rxid;
1122a8164dfSZhong Wang 	int			 ss_sol_oxid_hash_empty;
1132a8164dfSZhong Wang 	int			 ss_unsol_rxid_hash_empty;
1142a8164dfSZhong Wang 
1152a8164dfSZhong Wang 	/*
1162a8164dfSZhong Wang 	 * watch thread related stuff
1172a8164dfSZhong Wang 	 */
1182a8164dfSZhong Wang 	ddi_taskq_t		*ss_watchdog_taskq;
1192a8164dfSZhong Wang 	kcondvar_t		 ss_watch_cv;
1202a8164dfSZhong Wang 	kmutex_t		 ss_watch_mutex;
1212a8164dfSZhong Wang 	uint64_t		 ss_watch_count;
1222a8164dfSZhong Wang 	list_t			 ss_abort_xchg_list;
1232a8164dfSZhong Wang 
1242a8164dfSZhong Wang 	/*
1252a8164dfSZhong Wang 	 * topology discovery
1262a8164dfSZhong Wang 	 */
1272a8164dfSZhong Wang 	struct fcoet_exchange	*ss_sol_flogi;
1282a8164dfSZhong Wang 	fcoet_sol_flogi_state_t	 ss_sol_flogi_state;
1292a8164dfSZhong Wang 	fct_link_info_t		 ss_link_info;
1302a8164dfSZhong Wang 
1312a8164dfSZhong Wang 	/*
1322a8164dfSZhong Wang 	 * ioctl related stuff
1332a8164dfSZhong Wang 	 */
1342a8164dfSZhong Wang 	uint32_t		 ss_ioctl_flags;
1352a8164dfSZhong Wang 	kmutex_t		 ss_ioctl_mutex;
1362a8164dfSZhong Wang 
1372a8164dfSZhong Wang 	/*
1382a8164dfSZhong Wang 	 * special stuff
1392a8164dfSZhong Wang 	 */
1402a8164dfSZhong Wang 	uint32_t		 ss_change_state_flags;
1412a8164dfSZhong Wang 	uint8_t			 ss_state:7,
1422a8164dfSZhong Wang 	    ss_state_not_acked:1;
1432a8164dfSZhong Wang } fcoet_soft_state_t;
1442a8164dfSZhong Wang 
1452a8164dfSZhong Wang #define	SS_FLAG_UNSOL_FLOGI_DONE	0x0001
1462a8164dfSZhong Wang #define	SS_FLAG_REPORT_TO_FCT		0x0002
1472a8164dfSZhong Wang #define	SS_FLAG_PORT_DISABLED		0x0004
1482a8164dfSZhong Wang #define	SS_FLAG_STOP_WATCH		0x0008
1492a8164dfSZhong Wang #define	SS_FLAG_TERMINATE_WATCHDOG	0x0010
1502a8164dfSZhong Wang #define	SS_FLAG_WATCHDOG_RUNNING	0x0020
1512a8164dfSZhong Wang #define	SS_FLAG_DOG_WAITING		0x0040
1522a8164dfSZhong Wang #define	SS_FLAG_DELAY_PLOGI		0x0080
1532a8164dfSZhong Wang 
1542a8164dfSZhong Wang /*
1552a8164dfSZhong Wang  * Sequence and frame are transient objects, so their definition is simple.
1562a8164dfSZhong Wang  */
1572a8164dfSZhong Wang 
1582a8164dfSZhong Wang /*
1592a8164dfSZhong Wang  * Sequence.
1602a8164dfSZhong Wang  * we will not use sequence in current implementation
1612a8164dfSZhong Wang  */
1622a8164dfSZhong Wang typedef struct fcoet_sequence {
1632a8164dfSZhong Wang 	list_t			 seq_frame_list;
1642a8164dfSZhong Wang 	struct fcoet_exchange	*seq_exchange;
1652a8164dfSZhong Wang } fcoet_sequence_t;
1662a8164dfSZhong Wang 
1672a8164dfSZhong Wang /*
1682a8164dfSZhong Wang  * Frame
1692a8164dfSZhong Wang  */
1702a8164dfSZhong Wang typedef struct fcoet_frame {
1712a8164dfSZhong Wang 	list_node_t		 tfm_seq_node;
1722a8164dfSZhong Wang 	fcoe_frame_t		*tfm_fcoe_frame;
1732a8164dfSZhong Wang 
1742a8164dfSZhong Wang 	struct fcoet_exchange	*tfm_xch;
1752a8164dfSZhong Wang 	struct fcoet_sequence	*tfm_seq;
1762a8164dfSZhong Wang 	uint8_t			 tfm_rctl;
1772a8164dfSZhong Wang 	uint8_t			 tfm_buf_idx;
1782a8164dfSZhong Wang } fcoet_frame_t;
1792a8164dfSZhong Wang 
1802a8164dfSZhong Wang /*
1812a8164dfSZhong Wang  * FCOET_MAX_DBUF_LEN should better be consistent with sbd_scsi.c. Since
1822a8164dfSZhong Wang  * sbd_scsi.c use 128k as the max dbuf size, we'd better define this between
1832a8164dfSZhong Wang  * 32k - 128k.
1842a8164dfSZhong Wang  */
1852a8164dfSZhong Wang #define	FCOET_MAX_DBUF_LEN	0x20000 /* 128 * 1024 */
1862a8164dfSZhong Wang /*
1872a8164dfSZhong Wang  * exchange - cmd alias
1882a8164dfSZhong Wang  */
1892a8164dfSZhong Wang typedef struct fcoet_exchange {
1902a8164dfSZhong Wang 	/*
1912a8164dfSZhong Wang 	 * it is only used for ss_abort_xchg_list
1922a8164dfSZhong Wang 	 */
1932a8164dfSZhong Wang 	list_node_t		 xch_abort_node;
1942a8164dfSZhong Wang 
1952a8164dfSZhong Wang 	/*
1962a8164dfSZhong Wang 	 * We don't believe oxid/rxid in fct_cmd_t
1972a8164dfSZhong Wang 	 */
1982a8164dfSZhong Wang 	uint16_t		 xch_oxid;
1992a8164dfSZhong Wang 	uint16_t		 xch_rxid;
2002a8164dfSZhong Wang 
2012a8164dfSZhong Wang 	uint32_t		 xch_flags;
2022a8164dfSZhong Wang 	fcoet_soft_state_t	*xch_ss;
2032a8164dfSZhong Wang 	fct_cmd_t		*xch_cmd;
2042a8164dfSZhong Wang 
2052a8164dfSZhong Wang 	fcoet_sequence_t	*xch_current_seq;
2062a8164dfSZhong Wang 	clock_t			 xch_start_time;
2072a8164dfSZhong Wang 
2082a8164dfSZhong Wang 	stmf_data_buf_t		**xch_dbufs;
2092a8164dfSZhong Wang 	uint8_t			xch_dbuf_num;
2102a8164dfSZhong Wang 	uint8_t			xch_sequence_no;
2112a8164dfSZhong Wang 	uint8_t			xch_ref;
2122a8164dfSZhong Wang 
2132a8164dfSZhong Wang 	int			 xch_left_data_size;
2142a8164dfSZhong Wang } fcoet_exchange_t;
2152a8164dfSZhong Wang /*
2162a8164dfSZhong Wang  * Add the reference to avoid such situation:
2172a8164dfSZhong Wang  * 1, Frame received, then abort happen (maybe because local port offline, or
2182a8164dfSZhong Wang  * remote port abort the cmd), cmd is aborted and then freed right after we
2192a8164dfSZhong Wang  * get the exchange from hash table in fcoet_rx_frame.
2202a8164dfSZhong Wang  * 2, Frame sent out, then queued in fcoe for release. then abort happen, cmd
2212a8164dfSZhong Wang  * is aborted and then freed before fcoe_watchdog() call up to release the
2222a8164dfSZhong Wang  * frame.
2232a8164dfSZhong Wang  * These two situation should seldom happen. But just invoke this seems won't
2242a8164dfSZhong Wang  * downgrade the performance too much, so we keep it.
2252a8164dfSZhong Wang  */
2261a5e258fSJosef 'Jeff' Sipek #define	FCOET_BUSY_XCHG(xch)	atomic_inc_8(&(xch)->xch_ref)
2271a5e258fSJosef 'Jeff' Sipek #define	FCOET_RELE_XCHG(xch)	atomic_dec_8(&(xch)->xch_ref)
2282a8164dfSZhong Wang 
2292a8164dfSZhong Wang #define	XCH_FLAG_NONFCP_REQ_SENT	0x0001
2302a8164dfSZhong Wang #define	XCH_FLAG_NONFCP_RESP_SENT	0x0002
2312a8164dfSZhong Wang #define	XCH_FLAG_FCP_CMD_RCVD		0x0004
2322a8164dfSZhong Wang #define	XCH_FLAG_INI_ASKED_ABORT	0x0008
2332a8164dfSZhong Wang #define	XCH_FLAG_FCT_CALLED_ABORT	0x0010
2342a8164dfSZhong Wang #define	XCH_FLAG_IN_HASH_TABLE		0x0020
2352a8164dfSZhong Wang 
2362a8164dfSZhong Wang /*
2372a8164dfSZhong Wang  * IOCTL supporting stuff
2382a8164dfSZhong Wang  */
2392a8164dfSZhong Wang #define	FCOET_IOCTL_FLAG_MASK		0xFF
2402a8164dfSZhong Wang #define	FCOET_IOCTL_FLAG_IDLE		0x00
2412a8164dfSZhong Wang #define	FCOET_IOCTL_FLAG_OPEN		0x01
2422a8164dfSZhong Wang #define	FCOET_IOCTL_FLAG_EXCL		0x02
2432a8164dfSZhong Wang 
2442a8164dfSZhong Wang /*
2452a8164dfSZhong Wang  * define common-used conversion and calculation macros
2462a8164dfSZhong Wang  */
2472a8164dfSZhong Wang #define	FRM2SS(x_frm)							\
2482a8164dfSZhong Wang 	((fcoet_soft_state_t *)(x_frm)->frm_eport->eport_client_private)
2492a8164dfSZhong Wang #define	FRM2TFM(x_frm)	((fcoet_frame_t *)(x_frm)->frm_client_private)
2502a8164dfSZhong Wang 
2512a8164dfSZhong Wang #define	PORT2SS(x_port)	((fcoet_soft_state_t *)(x_port)->port_fca_private)
2522a8164dfSZhong Wang #define	EPORT2SS(x_port) ((fcoet_soft_state_t *)(x_port)->eport_client_private)
2532a8164dfSZhong Wang 
2542a8164dfSZhong Wang #define	XCH2ELS(x_xch)	((fct_els_t *)x_xch->xch_cmd->cmd_specific)
2552a8164dfSZhong Wang #define	XCH2CT(x_xch)	((fct_ct_t *)x_xch->xch_cmd->cmd_specific)
2562a8164dfSZhong Wang #define	XCH2TASK(x_xch)	((scsi_task_t *)x_xch->xch_cmd->cmd_specific)
2572a8164dfSZhong Wang 
2582a8164dfSZhong Wang #define	CMD2ELS(x_cmd)	((fct_els_t *)x_cmd->cmd_specific)
2592a8164dfSZhong Wang #define	CMD2CT(x_cmd)	((fct_sol_ct_t *)x_cmd->cmd_specific)
2602a8164dfSZhong Wang #define	CMD2TASK(x_cmd)	((scsi_task_t *)x_cmd->cmd_specific)
2612a8164dfSZhong Wang #define	CMD2XCH(x_cmd)	((fcoet_exchange_t *)x_cmd->cmd_fca_private)
2622a8164dfSZhong Wang #define	CMD2SS(x_cmd)							\
2632a8164dfSZhong Wang 	((fcoet_soft_state_t *)(x_cmd)->cmd_port->port_fca_private)
2642a8164dfSZhong Wang 
2652a8164dfSZhong Wang void fcoet_init_tfm(fcoe_frame_t *frm, fcoet_exchange_t *xch);
2662a8164dfSZhong Wang fct_status_t fcoet_send_status(fct_cmd_t *cmd);
2672a8164dfSZhong Wang void fcoet_modhash_find_cb(mod_hash_key_t, mod_hash_val_t);
2682a8164dfSZhong Wang 
2692a8164dfSZhong Wang /*
2702a8164dfSZhong Wang  * DBUF stuff
2712a8164dfSZhong Wang  */
2722a8164dfSZhong Wang #define	FCOET_DB_SEG_NUM(x_db) (x_db->db_port_private)
2732a8164dfSZhong Wang #define	FCOET_DB_NETB(x_db)						\
2742a8164dfSZhong Wang 	(((uintptr_t)FCOET_DB_SEG_NUM(x_db)) *			\
2752a8164dfSZhong Wang 	sizeof (struct stmf_sglist_ent) + (uintptr_t)(x_db)->db_sglist)
2762a8164dfSZhong Wang 
2772a8164dfSZhong Wang #define	FCOET_SET_SEG_NUM(x_db, x_num)			\
2782a8164dfSZhong Wang 	{						\
2792a8164dfSZhong Wang 		FCOET_DB_SEG_NUM(x_db) = (void *)(unsigned long)x_num;	\
2802a8164dfSZhong Wang 	}
2812a8164dfSZhong Wang 
2822a8164dfSZhong Wang #define	FCOET_GET_SEG_NUM(x_db)	((int)(unsigned long)FCOET_DB_SEG_NUM(x_db))
2832a8164dfSZhong Wang 
2842a8164dfSZhong Wang 
2852a8164dfSZhong Wang #define	FCOET_SET_NETB(x_db, x_idx, x_netb)				\
2862a8164dfSZhong Wang 	{								\
2872a8164dfSZhong Wang 		((void **)FCOET_DB_NETB(x_db))[x_idx] = x_netb;	\
2882a8164dfSZhong Wang 	}
2892a8164dfSZhong Wang 
2902a8164dfSZhong Wang #define	FCOET_GET_NETB(x_db, x_idx)		\
2912a8164dfSZhong Wang 	(((void **)FCOET_DB_NETB(x_db))[x_idx])
2922a8164dfSZhong Wang 
2932a8164dfSZhong Wang #define	PRT_FRM_HDR(x_p, x_f)						\
2942a8164dfSZhong Wang 	{								\
2952a8164dfSZhong Wang 		FCOET_LOG(x_p, "rctl/%x, type/%x, fctl/%x, oxid/%x",	\
296*00bdf9afSToomas Soome 		    FRM_R_CTL(x_f),		\
297*00bdf9afSToomas Soome 		    FRM_TYPE(x_f),		\
298*00bdf9afSToomas Soome 		    FRM_F_CTL(x_f),		\
299*00bdf9afSToomas Soome 		    FRM_OXID(x_f));		\
3002a8164dfSZhong Wang 	}
3012a8164dfSZhong Wang 
3022a8164dfSZhong Wang #endif	/* _KERNEL */
3032a8164dfSZhong Wang 
3042a8164dfSZhong Wang #ifdef	__cplusplus
3052a8164dfSZhong Wang }
3062a8164dfSZhong Wang #endif
3072a8164dfSZhong Wang 
3082a8164dfSZhong Wang #endif /* _FCOET_H */
309