emlxs_fc.h revision 728bdc9be5faf84b5dca42f545967bd4910d608e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Emulex. All rights reserved.
* Use is subject to License terms.
*/
#ifndef _EMLXS_FC_H
#define _EMLXS_FC_H
#ifdef __cplusplus
extern "C" {
#endif
/* ULP Patches: */
/* #define ULP_PATCH1 - Obsolete */
/* This patch enables the driver to auto respond to unsolicited LOGO's */
/* This is needed because ULP is sometimes doesn't reply itself */
#define ULP_PATCH2
/* This patch enables the driver to auto respond to unsolicited PRLI's */
/* This is needed because ULP is known to panic sometimes */
#define ULP_PATCH3
/* This patch enables the driver to auto respond to unsolicited PRLO's */
/* This is needed because ULP is known to panic sometimes */
#define ULP_PATCH4
/* This patch enables the driver to fail pkt abort requests */
#define ULP_PATCH5
/* This patch enables the driver to generate an RSCN for unsolicited PRLO's */
/* and LOGO's */
#define ULP_PATCH6
/* Sun Disk Array Patches: */
/* This patch enables the driver to fix a residual underrun issue with */
/* check conditions */
#define FCP_UNDERRUN_PATCH1
/* This patch enables the driver to fix a residual underrun issue with */
/* SCSI inquiry commands */
#define FCP_UNDERRUN_PATCH2
/* This patch enables the driver to adjust MAX_RRDY on private loop */
/* #define MAX_RRDY_PATCH */
typedef struct emlxs_buf {
void *bmp; /* Save the buffer pointer list */
void *node; /* Save node and used by abort */
void *ring; /* Save ring and used by abort */
/* responding to, if any */
#ifdef SFCT_SUPPORT
#define EMLXS_FCT_ELS_RSP 0x04
#define EMLXS_FCT_FCP_DATA 0x20
#define EMLXS_FCT_FCP_STATUS 0x40
#define EMLXS_FCT_SEND_STATUS 0x01
#define EMLXS_FCT_ABORT 0x02
#define EMLXS_FCT_ABORT_COMPLETE 0x04
#define EMLXS_FCT_REGISTERED 0x10
#define EMLXS_FCT_FLOGI 0x20
#define EMLXS_FCT_REQ_CREATED 1
#define EMLXS_FCT_CMD_RECEIVED 2
#define EMLXS_FCT_REG_PENDING 3
#define EMLXS_FCT_REG_COMPLETE 4
#define EMLXS_FCT_REQ_PENDING 5
#define EMLXS_FCT_DATA_PENDING 6
#define EMLXS_FCT_STATUS_PENDING 7
#define EMLXS_FCT_RSP_PENDING 8
#define EMLXS_FCT_REQ_COMPLETE 9
#define EMLXS_FCT_DATA_COMPLETE 10
#define EMLXS_FCT_STATUS_COMPLETE 11
#define EMLXS_FCT_RSP_COMPLETE 12
#endif /* SFCT_SUPPORT */
} emlxs_buf_t;
/* pkt_flags */
#define PACKET_IN_COMPLETION 0x00000001
#define PACKET_IN_TXQ 0x00000002
#define PACKET_IN_CHIPQ 0x00000004
#define PACKET_IN_DONEQ 0x00000008
#define PACKET_FCP_RESET 0x00000030
#define PACKET_FCP_TGT_RESET 0x00000010
#define PACKET_FCP_LUN_RESET 0x00000020
#define PACKET_POLLED 0x00000040
#ifdef EMLXS_I386
#define PACKET_FCP_SWAPPED 0x00000100
#define PACKET_ELS_SWAPPED 0x00000200
#define PACKET_CT_SWAPPED 0x00000400
#define PACKET_CSP_SWAPPED 0x00000800
#endif /* EMLXS_I386 */
#define PACKET_STALE 0x00001000
#define PACKET_IN_TIMEOUT 0x00010000
#define PACKET_IN_FLUSH 0x00020000
#define PACKET_IN_ABORT 0x00040000
/* was issued */
#define PACKET_CHIP_COMP 0x00100000
#define PACKET_COMPLETED 0x00200000
#define PACKET_RETURNED 0x00400000
#define PACKET_STATE_VALID 0x01000000
#define PACKET_FCP_RSP_VALID 0x02000000
#define PACKET_ELS_RSP_VALID 0x04000000
#define PACKET_CT_RSP_VALID 0x08000000
#define PACKET_DELAY_REQUIRED 0x10000000
#define PACKET_ALLOCATED 0x40000000
#define PACKET_VALID 0x80000000
/*
* From fc_error.h pkt_reason (except for state = NPORT_RJT, FABRIC_RJT,
* NPORT_BSY, FABRIC_BSY, LS_RJT, BA_RJT, FS_RJT)
*
* FCA unique error codes can begin after FC_REASON_FCA_UNIQUE.
* Each FCA defines its own set with values greater >= 0x7F
*/
#define FC_REASON_FCA_DEFINED 0x100
/*
* Device VPD save area
*/
typedef struct emlxs_vpd {
char postKernName[32];
char opFwName[32];
char opFwLabel[32];
char sli1FwName[32];
char sli1FwLabel[32];
char sli2FwName[32];
char sli2FwLabel[32];
char sli3FwName[32];
char sli3FwLabel[32];
char sli4FwName[32];
char sli4FwLabel[32];
char fw_version[32];
char fw_label[32];
char fcode_version[32];
char boot_version[32];
char serial_num[32];
char part_num[32];
char port_num[20];
char eng_change[32];
char manufacturer[80];
char model[80];
char model_desc[256];
char prog_types[256];
char id[80];
} emlxs_vpd_t;
typedef struct emlxs_queue {
typedef emlxs_queue_t Q;
/*
* This structure is used when allocating a buffer pool.
* Note: this should be identical to gasket buf_info (fldl.h).
*/
typedef struct emlxs_buf_info {
/* address to physical (skip malloc) */
/* For free - just unmap the given */
/* physical address (skip the free). */
/* memory */
#define FC_MBUF_DMA32 0x20
void *virt; /* specifies the virtual buffer pointer */
void *data_handle;
void *dma_handle;
typedef emlxs_buf_info_t MBUF_INFO;
#ifdef SLI3_SUPPORT
#define EMLXS_ELS_HBQ_ID 0
#define EMLXS_IP_HBQ_ID 1
#define EMLXS_CT_HBQ_ID 2
#define EMLXS_FCT_HBQ_ID 3
#ifdef SFCT_SUPPORT
#else
#endif /* SFCT_SUPPORT */
#endif /* SLI3_SUPPORT */
/* Structure used to access adapter rings */
typedef struct emlxs_ring {
void *fc_cmdringaddr; /* virtual offset for cmd rings */
void *fc_rspringaddr; /* virtual offset for rsp rings */
/* requests */
/* Protected by EMLXS_RINGTX_LOCK */
} emlxs_ring_t;
typedef emlxs_ring_t RING;
typedef struct emlxs_node {
struct emlxs_node *nlp_list_next;
struct emlxs_node *nlp_list_prev;
/* nlp_fcp_info */
#define NODE_POOL_ALLOCATED 0x00000001
/* Protected by EMLXS_RINGTX_LOCK */
/* nlp_flag */
/* when node needs servicing */
#ifdef DHCHAP_SUPPORT
#endif /* DHCHAP_SUPPORT */
} emlxs_node_t;
typedef emlxs_node_t NODELIST;
typedef struct emlxs_fcip_nethdr {
typedef emlxs_fcip_nethdr_t NETHDR;
#define MEM_NLP 0 /* memory segment to hold node list entries */
#ifdef SFCT_SUPPORT
#define FC_MAX_SEG 8
#else
#define FC_MAX_SEG 7
#endif /* SFCT_SUPPORT */
/* A BPL entry is 12 bytes. Subtract 2 for command and response buffers */
#ifdef EMLXS_I386
#else /* EMLXS_SPARC */
#define EMLXS_SGLLEN 1
#endif /* EMLXS_I386 */
#define MEM_BUF_SIZE 1024
#define MEM_BUF_COUNT 64
#define MEM_ELSBUF_SIZE MEM_BUF_SIZE
#define MEM_IPBUF_SIZE 65535
#define MEM_IPBUF_COUNT 60
#define MEM_CTBUF_COUNT 8
#define MEM_FCTBUF_SIZE 65535
#define MEM_FCTBUF_COUNT 128
typedef struct emlxs_memseg {
/* block */
/* block */
typedef emlxs_memseg_t MEMSEG;
/* Board stat counters */
typedef struct emlxs_stats {
#ifdef SFCT_SUPPORT
#endif /* SFCT_SUPPORT */
/* ElsRspCompleted */
/* ElsCmdReceived */
/* ElsPlogiReceived + ... */
/* CtRspCompleted */
/* CtCmdReceived */
/* IpBcastCompleted */
/* IpBcastReceived */
#ifdef SFCT_SUPPORT
#endif /* SFCT_SUPPORT */
#define EMLXS_NUM_THREADS 8
#define EMLXS_MIN_TASKS 8
#define EMLXS_MAX_TASKS 8
#define EMLXS_NUM_HASH_QUES 32
/* pkt_tran_flag */
#define FC_TRAN_COMPLETED 0x8000
typedef struct emlxs_dfc_event {
void *dataout;
typedef struct emlxs_hba_event {
#ifdef SFCT_SUPPORT
/*
* FctP2IOXcnt will count IOs by their fcpDL. Counters
* are for buckets of various power of 2 sizes.
* Bucket 0 < 512 > 0
* Bucket 1 >= 512 < 1024
* Bucket 2 >= 1024 < 2048
* Bucket 3 >= 2048 < 4096
* Bucket 4 >= 4096 < 8192
* Bucket 5 >= 8192 < 16K
* Bucket 6 >= 16K < 32K
* Bucket 7 >= 32K < 64K
* Bucket 8 >= 64K < 128K
* Bucket 9 >= 128K < 256K
* Bucket 10 >= 256K < 512K
* Bucket 11 >= 512K < 1MB
* Bucket 12 >= 1MB < 2MB
* Bucket 13 >= 2MB < 4MB
* Bucket 14 >= 4MB < 8MB
* Bucket 15 >= 8MB
*/
#define MAX_TGTPORT_IOCNT 16
/*
* These routines will bump the right counter, based on
* the size of the IO inputed, with the least number of
* comparisions. A max of 5 comparisions is only needed
* to classify the IO in one of 16 ranges. A binary search
* to locate the high bit in the size is used.
*/
{ \
/* Use binary search to find the first high bit */ \
if (cnt & 0xffff0000) { \
if (cnt & 0xff800000) { \
} \
else { \
/* It must be 0x007f0000 */ \
if (cnt & 0x00700000) { \
if (cnt & 0x00400000) { \
} \
else { \
/* It must be 0x00300000 */ \
if (cnt & 0x00200000) { \
} \
else { \
/* It must be 0x00100000 */ \
} \
} \
} \
else { \
/* It must be 0x000f0000 */ \
if (cnt & 0x000c0000) { \
if (cnt & 0x00080000) { \
} \
else { \
/* It must be 0x00040000 */ \
} \
} \
else { \
/* It must be 0x00030000 */ \
if (cnt & 0x00020000) { \
} \
else { \
/* It must be 0x00010000 */ \
} \
} \
} \
} \
} \
else { \
if (cnt & 0x0000fe00) { \
if (cnt & 0x0000f000) { \
if (cnt & 0x0000c000) { \
if (cnt & 0x00008000) { \
} \
else { \
/* It must be 0x00004000 */ \
} \
} \
else { \
/* It must be 0x00000300 */ \
if (cnt & 0x00000200) { \
} \
else { \
/* It must be 0x00000100 */ \
} \
} \
} \
else { \
/* It must be 0x00000e00 */ \
if (cnt & 0x00000800) { \
} \
else { \
/* It must be 0x00000600 */ \
if (cnt & 0x00000400) { \
} \
else { \
/* It must be 0x00000200 */ \
} \
} \
} \
} \
else { \
/* It must be 0x000001ff */ \
TGTPORTSTAT.FctP2IORcnt[0]++; \
} \
} \
}
{ \
/* Use binary search to find the first high bit */ \
if (cnt & 0xffff0000) { \
if (cnt & 0xff800000) { \
} \
else { \
/* It must be 0x007f0000 */ \
if (cnt & 0x00700000) { \
if (cnt & 0x00400000) { \
} \
else { \
/* It must be 0x00300000 */ \
if (cnt & 0x00200000) { \
} \
else { \
/* It must be 0x00100000 */ \
} \
} \
} \
else { \
/* It must be 0x000f0000 */ \
if (cnt & 0x000c0000) { \
if (cnt & 0x00080000) { \
} \
else { \
/* It must be 0x00040000 */ \
} \
} \
else { \
/* It must be 0x00030000 */ \
if (cnt & 0x00020000) { \
} \
else { \
/* It must be 0x00010000 */ \
} \
} \
} \
} \
} \
else { \
if (cnt & 0x0000fe00) { \
if (cnt & 0x0000f000) { \
if (cnt & 0x0000c000) { \
if (cnt & 0x00008000) { \
} \
else { \
/* It must be 0x00004000 */ \
} \
} \
else { \
/* It must be 0x00000300 */ \
if (cnt & 0x00000200) { \
} \
else { \
/* It must be 0x00000100 */ \
} \
} \
} \
else { \
/* It must be 0x00000e00 */ \
if (cnt & 0x00000800) { \
} \
else { \
/* It must be 0x00000600 */ \
if (cnt & 0x00000400) { \
} \
else { \
/* It must be 0x00000200 */ \
} \
} \
} \
} \
else { \
/* It must be 0x000001ff */ \
TGTPORTSTAT.FctP2IOWcnt[0]++; \
} \
} \
}
typedef struct emlxs_tgtport_stat {
/* IO counters */
/* IOCB handling counters */
/* Fct event counters */
#endif /* SFCT_SUPPORT */
/*
* Port Information Data Structure
*/
typedef struct emlxs_port {
/* Virtual port management */
#define EMLXS_PORT_ENABLE 0x00000001
#define EMLXS_PORT_BOUND 0x00000002
#define EMLXS_PORT_IP_UP 0x00000010
#define EMLXS_PORT_CONFIG 0x00000020
/* a hard reset */
/* a link reset */
/* logins */
/* logins */
#define EMLXS_OPT_RESTRICT_MASK 0x00000003
/* FC world wide names */
char snn[256];
char spn[256];
/* Common service paramters */
/* fc_id management */
/* FC_AL management */
/* Node management */
/* Polled packet management */
/* ULP */
void (*ulp_statec_cb) (); /* Port state change callback routine */
void (*ulp_unsol_cb) (); /* unsolicited event callback routine */
/* ULP unsolicited buffers */
/* link up */
/* link up */
#ifdef DHCHAP_SUPPORT
#endif /* DHCHAP_SUPPORT */
#ifdef SFCT_SUPPORT
#define FCT_BUF_COUNT_512 256
#define FCT_BUF_COUNT_8K 128
#define FCT_BUF_COUNT_64K 64
#define FCT_BUF_COUNT_128K 64
#define FCT_MAX_BUCKETS 16
int fct_queue_depth;
char cfd_name[24];
#define FCT_STATE_PORT_ONLINE 0x00000001
#define FCT_STATE_NOT_ACKED 0x00000002
#define FCT_STATE_LINK_UP 0x00000010
#endif /* SFCT_SUPPORT */
} emlxs_port_t;
/* Host Attn reg */
/* Chip Attn reg */
/* Host Status reg */
/* Host Cntl reg */
/* BIU Configuration reg */
/* Used by SBUS adapter */
/* TITAN Cntl reg */
/* TITAN Status reg */
/* TITAN Update reg */
(_wcnt),\
(_wcnt),\
(_wcnt),\
(_wcnt),\
/* Used by SBUS adapter */
{ \
}
/* Used when EMLXS_PORT_LOCK is already held */
{ \
{ \
&emlxs_state_msg, "%s --> %s", \
{ \
} \
} \
}
/*
* This is the HBA control area for the adapter
*/
#ifdef MODSYM_SUPPORT
typedef struct emlxs_modsym {
/* Leadville (fctl) */
int (*fc_fca_detach) (dev_info_t *);
int (*fc_fca_init) (struct dev_ops *);
#ifdef SFCT_SUPPORT
/* Comstar (fct) */
void *(*fct_alloc) (int, int, int);
void (*fct_free) (void *);
void *(*fct_scsi_task_alloc) (void *, int, int, uint8_t *, int, int);
int (*fct_register_local_port) (fct_local_port_t *);
void (*fct_deregister_local_port) (fct_local_port_t *);
void (*fct_handle_event) (fct_local_port_t *, int, int, int);
void (*fct_post_rcvd_cmd) (fct_cmd_t *, int);
void (*fct_ctl) (void *, int, stmf_change_status_t *);
void (*fct_send_response_done) (fct_cmd_t *, int, int);
void (*fct_send_cmd_done) (fct_cmd_t *, int, int);
(fct_local_port_t *, uint32_t, char *);
(fct_local_port_t *, fct_flogi_xchg_t *);
/* Comstar (stmf) */
void *(*stmf_alloc) (int, int, int);
void (*stmf_free) (void *);
void (*stmf_deregister_port_provider) (stmf_port_provider_t *);
int (*stmf_register_port_provider) (stmf_port_provider_t *);
#endif /* SFCT_SUPPORT */
extern emlxs_modsym_t emlxs_modsym;
#else
#endif /* MODSYM_SUPPORT */
#define PCI_CONFIG_SIZE 0x80
typedef struct emlxs_hba {
/* HBA Info */
char snn[256];
char spn[256];
#define PCI_FC 0
#define SBUS_FC 1
/* Link management */
/* Memory Pool management */
/* structures */
/* Fibre Channel Service Parameters */
/* SLIM management */
#ifdef SLI3_SUPPORT
/* HBQ management */
#endif /* SLI3_SUPPORT */
/* Adapter State management */
#define FC_INIT_NVPARAMS 0x11
#define FC_INIT_REV 0x12
#define FC_INIT_CFGPORT 0x13
#define FC_INIT_CFGRING 0x14
#define FC_INIT_INITLINK 0x15
#define FC_LINK_DOWN 0x20
#define FC_LINK_UP 0x30
#define FC_CLEAR_LA 0x31
#define FC_READY 0x40
#define FC_ONLINING_MODE 0x00000001
#define FC_ONLINE_MODE 0x00000002
#define FC_OFFLINING_MODE 0x00000004
#define FC_OFFLINE_MODE 0x00000008
/* and link is ready */
/* and NameServer cmds */
#define FC_FABRIC_ATTACHED 0x00001000
#define FC_PT_TO_PT 0x00002000
#define FC_BYPASSED_MODE 0x00004000
/* maintenance mode */
#define FC_INTERLOCKED 0x00200000
#define FC_HBQ_ENABLED 0x00400000
#define FC_ASYNC_EVENTS 0x00800000
#define FC_ILB_MODE 0x01000000
#define FC_ELB_MODE 0x02000000
/* temperature event */
/* timeout event */
/* hard reset */
/* linkdown */
/* Adapter memory management */
/* SBUS adapter management */
/* Adapter register management */
/* in progress */
/* IO Completion management */
/* Protected by EMLXS_PORT_LOCK */
/* Ring management */
/* Mailbox Management */
/* by reg_login only */
/* used by reg_login only */
/* reg_login only */
#ifdef MBOX_EXT_SUPPORT
#endif /* MBOX_EXT_SUPPORT */
/* IOtag management */
/* (non-abort) iotag */
/* Protected by EMLXS_FCTAB_LOCK */
#ifdef EMLXS_SPARC
#endif /* EMLXS_SPARC */
/* Interrupt management */
void *intr_arg;
#define EMLXS_INTX_INITED 0x0001
#define EMLXS_INTX_ADDED 0x0002
#define EMLXS_MSI_ENABLED 0x0010
#define EMLXS_MSI_INITED 0x0020
#define EMLXS_MSI_ADDED 0x0040
#ifdef MSI_SUPPORT
#define MSI_CAP_ID 0x05
#define MSIX_CAP_ID 0x11
#endif /* MSI_SUPPORT */
/* IOCTL management */
#define EMLXS_OPEN 0x00000001
#define EMLXS_OPEN_EXCLUSIVE 0x00000002
/* Timer management */
#define EMLXS_TIMER_STARTED 0x0000001
#define EMLXS_TIMER_BUSY 0x0000002
#define EMLXS_TIMER_KILL 0x0000004
#define EMLXS_TIMER_ENDED 0x0000008
/* Misc Timers */
/* Power Management */
/* pm_state */
#define EMLXS_PM_IN_ATTACH 0x00000001
#define EMLXS_PM_IN_DETACH 0x00000002
#define EMLXS_PM_IN_SOL_CB 0x00000010
#define EMLXS_PM_IN_UNSOL_CB 0x00000020
#define EMLXS_PM_IN_LINK_RESET 0x00000100
#define EMLXS_PM_IN_HARD_RESET 0x00000200
#define EMLXS_PM_SUSPENDED 0x01000000
/* pm_level */
#define EMLXS_PM_ADAPTER_DOWN 0
#define EMLXS_PM_ADAPTER_UP 1
#ifdef IDLE_TIMER
#endif /* IDLE_TIMER */
#ifdef DFC_SUPPORT
/* Loopback management */
void *loopback_pkt;
#endif /* DFC_SUPPORT */
/* Event management */
/* Parameter management */
/* Driver stat management */
/* Log management */
/* Port managment */
/* last one is for NPIV ready */
/* test */
#ifdef DHCHAP_SUPPORT
/* list of entries. Protected by */
/* auth_lock */
/* list of entries. Protected by */
/* auth_lock */
#endif /* DHCHAP_SUPPORT */
#ifdef TEST_SUPPORT
#endif /* TEST_SUPPORT */
} emlxs_hba_t;
#ifdef MSI_SUPPORT
#else
#endif /* MSI_SUPPORT */
/* Power Management Component */
#define EMLXS_PM_ADAPTER 0
/* nodes, rings */
/* threads */
/* buffer pool */
#ifdef EMLXS_LITTLE_ENDIAN
#define SWAP_SHORT(x) (x)
#define SWAP_LONG(x) (x)
(((x) & 0xFF0000)<<24) | (((x) & 0xFF000000)<<8) | \
(((x) & 0xFF00000000)>>8) | \
(((x) & 0xFF0000000000)>>24) | \
(((x) & 0xFF000000000000)>>40) | \
(((x) & 0xFF00000000000000)>>56))
(((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24))
#define PCIMEM_SHORT(x) SWAP_SHORT(x)
#define PCIMEM_LONG(x) SWAP_LONG(x)
#define PCIMEM_DATA(x) SWAP_DATA32(x)
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
#define SWAP_DATA24_LO(x) (x)
#define SWAP_DATA24_HI(x) (x)
#endif /* EMLXS_MODREV2X */
#if (EMLXS_MODREVX == EMLXS_MODREV3X)
(((x) & 0x00FF0000)>>16))
(((x) & 0xFF000000)>>16))
#endif /* EMLXS_MODREV3X */
#endif /* EMLXS_LITTLE_ENDIAN */
#ifdef EMLXS_BIG_ENDIAN
(((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24))
#define SWAP_DATA64(x) (x)
#define SWAP_DATA32(x) (x)
#define SWAP_DATA16(x) (x)
#define PCIMEM_SHORT(x) SWAP_SHORT(x)
#define PCIMEM_LONG(x) SWAP_LONG(x)
#define PCIMEM_DATA(x) SWAP_DATA32(x)
#define SWAP_DATA24_LO(x) (x)
#define SWAP_DATA24_HI(x) (x)
#endif /* EMLXS_BIG_ENDIAN */
(((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24))
/*
* For PCI configuration
*/
#ifdef __cplusplus
}
#endif
#endif /* _EMLXS_FC_H */