2005-04-18 01:05:31 +04:00
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
2005-06-25 18:34:39 +04:00
* Fibre Channel Host Bus Adapters . *
2015-04-07 22:07:28 +03:00
* Copyright ( C ) 2004 - 2015 Emulex . All rights reserved . *
2005-06-25 18:34:39 +04:00
* EMULEX and SLI are trademarks of Emulex . *
2005-04-18 01:05:31 +04:00
* www . emulex . com *
* *
* This program is free software ; you can redistribute it and / or *
2005-06-25 18:34:39 +04:00
* modify it under the terms of version 2 of the GNU General *
* Public License as published by the Free Software Foundation . *
* This program is distributed in the hope that it will be useful . *
* ALL EXPRESS OR IMPLIED CONDITIONS , REPRESENTATIONS AND *
* WARRANTIES , INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY , *
* FITNESS FOR A PARTICULAR PURPOSE , OR NON - INFRINGEMENT , ARE *
* DISCLAIMED , EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
* TO BE LEGALLY INVALID . See the GNU General Public License for *
* more details , a copy of which can be found in the file COPYING *
* included with this package . *
2005-04-18 01:05:31 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* forward declaration for LPFC_IOCB_t's use */
struct lpfc_hba ;
2007-06-18 04:56:36 +04:00
struct lpfc_vport ;
2005-04-18 01:05:31 +04:00
/* Define the context types that SLI handles for abort and sums. */
typedef enum _lpfc_ctx_cmd {
LPFC_CTX_LUN ,
LPFC_CTX_TGT ,
LPFC_CTX_HOST
} lpfc_ctx_cmd ;
2009-10-02 23:16:39 +04:00
struct lpfc_cq_event {
struct list_head list ;
union {
struct lpfc_mcqe mcqe_cmpl ;
struct lpfc_acqe_link acqe_link ;
2010-12-16 01:57:33 +03:00
struct lpfc_acqe_fip acqe_fip ;
2009-10-02 23:16:39 +04:00
struct lpfc_acqe_dcbx acqe_dcbx ;
2010-04-06 22:48:51 +04:00
struct lpfc_acqe_grp5 acqe_grp5 ;
2010-12-16 01:57:33 +03:00
struct lpfc_acqe_fc_la acqe_fc ;
struct lpfc_acqe_sli acqe_sli ;
2009-10-02 23:16:39 +04:00
struct lpfc_rcqe rcqe_cmpl ;
struct sli4_wcqe_xri_aborted wcqe_axri ;
struct lpfc_wcqe_complete wcqe_cmpl ;
} cqe ;
2009-05-22 22:51:39 +04:00
} ;
2005-04-18 01:05:31 +04:00
/* This structure is used to handle IOCB requests / responses */
struct lpfc_iocbq {
/* lpfc_iocbqs are used in double linked lists */
struct list_head list ;
2008-01-11 09:53:18 +03:00
struct list_head clist ;
2010-06-07 23:24:45 +04:00
struct list_head dlist ;
2005-10-29 19:28:33 +04:00
uint16_t iotag ; /* pre-assigned IO tag */
2011-05-24 19:44:12 +04:00
uint16_t sli4_lxritag ; /* logical pre-assigned XRI. */
2009-05-22 22:51:39 +04:00
uint16_t sli4_xritag ; /* pre-assigned XRI, (OXID) tag. */
2009-10-02 23:17:02 +04:00
struct lpfc_cq_event cq_event ;
2005-10-29 19:28:33 +04:00
2005-04-18 01:05:31 +04:00
IOCB_t iocb ; /* IOCB cmd */
uint8_t retry ; /* retry counter for IOCB cmd - if needed */
2013-09-06 20:20:51 +04:00
uint32_t iocb_flag ;
2007-04-25 17:51:38 +04:00
# define LPFC_IO_LIBDFC 1 /* libdfc iocb */
2013-07-16 02:31:42 +04:00
# define LPFC_IO_WAKE 2 /* Synchronous I/O completed */
# define LPFC_IO_WAKE_TMO LPFC_IO_WAKE /* Synchronous I/O timed out */
2007-04-25 17:51:38 +04:00
# define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */
# define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */
2007-06-18 04:56:38 +04:00
# define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */
2008-01-11 09:52:36 +03:00
# define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */
2010-01-27 07:07:37 +03:00
# define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */
# define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */
2010-02-26 22:14:23 +03:00
# define DSS_SECURITY_OP 0x100 /* security IO */
2012-05-10 05:17:07 +04:00
# define LPFC_IO_ON_TXCMPLQ 0x200 /* The IO is still on the TXCMPLQ */
2012-10-31 22:44:49 +04:00
# define LPFC_IO_DIF_PASS 0x400 /* T10 DIF IO pass-thru prot */
# define LPFC_IO_DIF_STRIP 0x800 /* T10 DIF IO strip prot */
# define LPFC_IO_DIF_INSERT 0x1000 /* T10 DIF IO insert prot */
2013-09-06 20:20:51 +04:00
# define LPFC_IO_CMD_OUTSTANDING 0x2000 /* timeout handler abort window */
2010-01-27 07:07:37 +03:00
# define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */
# define LPFC_FIP_ELS_ID_SHIFT 14
2005-04-18 01:05:31 +04:00
2014-02-20 18:56:45 +04:00
# define LPFC_IO_OAS 0x10000 /* OAS FCP IO */
2014-09-03 20:57:30 +04:00
# define LPFC_IO_FOF 0x20000 /* FOF FCP IO */
2015-04-07 22:07:25 +03:00
# define LPFC_IO_LOOPBACK 0x40000 /* Loopback IO */
2014-02-20 18:56:45 +04:00
2005-04-18 01:05:31 +04:00
uint32_t drvrTimeout ; /* driver timeout in seconds */
2009-11-18 23:39:44 +03:00
uint32_t fcp_wqidx ; /* index to FCP work queue */
2007-06-18 04:56:36 +04:00
struct lpfc_vport * vport ; /* virtual port pointer */
2005-04-18 01:05:31 +04:00
void * context1 ; /* caller context information */
void * context2 ; /* caller context information */
void * context3 ; /* caller context information */
union {
2007-08-02 19:10:31 +04:00
wait_queue_head_t * wait_queue ;
struct lpfc_iocbq * rsp_iocb ;
struct lpfcMboxq * mbox ;
struct lpfc_nodelist * ndlp ;
2010-11-21 07:11:55 +03:00
struct lpfc_node_rrq * rrq ;
2005-04-18 01:05:31 +04:00
} context_un ;
2007-06-18 04:56:38 +04:00
void ( * fabric_iocb_cmpl ) ( struct lpfc_hba * , struct lpfc_iocbq * ,
struct lpfc_iocbq * ) ;
2013-07-16 02:31:42 +04:00
void ( * wait_iocb_cmpl ) ( struct lpfc_hba * , struct lpfc_iocbq * ,
struct lpfc_iocbq * ) ;
2005-04-18 01:05:31 +04:00
void ( * iocb_cmpl ) ( struct lpfc_hba * , struct lpfc_iocbq * ,
struct lpfc_iocbq * ) ;
} ;
# define SLI_IOCB_RET_IOCB 1 /* Return IOCB if cmd ring full */
# define IOCB_SUCCESS 0
# define IOCB_BUSY 1
# define IOCB_ERROR 2
# define IOCB_TIMEDOUT 3
2007-06-18 04:56:39 +04:00
# define LPFC_MBX_WAKE 1
# define LPFC_MBX_IMED_UNREG 2
2007-04-25 17:52:34 +04:00
2005-04-18 01:05:31 +04:00
typedef struct lpfcMboxq {
/* MBOXQs are used in single linked lists */
struct list_head list ; /* ptr to next mailbox command */
2009-05-22 22:51:39 +04:00
union {
MAILBOX_t mb ; /* Mailbox cmd */
struct lpfc_mqe mqe ;
} u ;
struct lpfc_vport * vport ; /* virtual port pointer */
2005-04-18 01:05:31 +04:00
void * context1 ; /* caller context information */
void * context2 ; /* caller context information */
void ( * mbox_cmpl ) ( struct lpfc_hba * , struct lpfcMboxq * ) ;
2007-04-25 17:52:34 +04:00
uint8_t mbox_flag ;
2010-03-15 18:25:20 +03:00
uint16_t in_ext_byte_len ;
uint16_t out_ext_byte_len ;
uint8_t mbox_offset_word ;
2009-05-22 22:51:39 +04:00
struct lpfc_mcqe mcqe ;
struct lpfc_mbx_nembed_sge_virt * sge_array ;
2005-04-18 01:05:31 +04:00
} LPFC_MBOXQ_t ;
# define MBX_POLL 1 / * poll mailbox till command done, then
return */
# define MBX_NOWAIT 2 /* issue command then return immediately */
2009-10-02 23:16:45 +04:00
# define LPFC_MAX_RING_MASK 5 / * max num of rctl / type masks allowed per
2005-04-18 01:05:31 +04:00
ring */
2012-08-03 20:35:54 +04:00
# define LPFC_SLI3_MAX_RING 4 / * Max num of SLI3 rings used by driver.
For SLI4 , an additional ring for each
FCP WQ will be allocated . */
2005-04-18 01:05:31 +04:00
struct lpfc_sli_ring ;
struct lpfc_sli_ring_mask {
uint8_t profile ; /* profile associated with ring */
uint8_t rctl ; /* rctl / type pair configured for ring */
uint8_t type ; /* rctl / type pair configured for ring */
uint8_t rsvd ;
/* rcv'd unsol event */
void ( * lpfc_sli_rcv_unsol_event ) ( struct lpfc_hba * ,
struct lpfc_sli_ring * ,
struct lpfc_iocbq * ) ;
} ;
/* Structure used to hold SLI statistical counters and info */
struct lpfc_sli_ring_stat {
uint64_t iocb_event ; /* IOCB event counters */
uint64_t iocb_cmd ; /* IOCB cmd issued */
uint64_t iocb_rsp ; /* IOCB rsp received */
uint64_t iocb_cmd_delay ; /* IOCB cmd ring delay */
uint64_t iocb_cmd_full ; /* IOCB cmd ring full */
uint64_t iocb_cmd_empty ; /* IOCB cmd ring is now empty */
uint64_t iocb_rsp_full ; /* IOCB rsp ring full */
} ;
2012-08-03 20:35:34 +04:00
struct lpfc_sli3_ring {
uint32_t local_getidx ; /* last available cmd index (from cmdGetInx) */
uint32_t next_cmdidx ; /* next_cmd index */
uint32_t rspidx ; /* current index in response ring */
uint32_t cmdidx ; /* current index in command ring */
uint16_t numCiocb ; /* number of command iocb's per ring */
uint16_t numRiocb ; /* number of rsp iocb's per ring */
uint16_t sizeCiocb ; /* Size of command iocb's in this ring */
uint16_t sizeRiocb ; /* Size of response iocb's in this ring */
uint32_t * cmdringaddr ; /* virtual address for cmd rings */
uint32_t * rspringaddr ; /* virtual address for rsp rings */
} ;
struct lpfc_sli4_ring {
2012-08-03 20:35:54 +04:00
struct lpfc_queue * wqp ; /* Pointer to associated WQ */
2012-08-03 20:35:34 +04:00
} ;
2005-04-18 01:05:31 +04:00
/* Structure used to hold SLI ring information */
struct lpfc_sli_ring {
uint16_t flag ; /* ring flags */
# define LPFC_DEFERRED_RING_EVENT 0x001 /* Deferred processing a ring event */
# define LPFC_CALL_RING_AVAILABLE 0x002 /* indicates cmd was full */
# define LPFC_STOP_IOCB_EVENT 0x020 /* Stop processing IOCB cmds event */
uint16_t abtsiotag ; /* tracks next iotag to use for ABTS */
uint8_t rsvd ;
uint8_t ringno ; /* ring number */
2012-08-03 20:35:34 +04:00
spinlock_t ring_lock ; /* lock for issuing commands */
2005-04-18 01:05:31 +04:00
uint32_t fast_iotag ; /* max fastlookup based iotag */
uint32_t iotag_ctr ; /* keeps track of the next iotag to use */
uint32_t iotag_max ; /* max iotag value to use */
struct list_head txq ;
uint16_t txq_cnt ; /* current length of queue */
uint16_t txq_max ; /* max length */
struct list_head txcmplq ;
uint16_t txcmplq_cnt ; /* current length of queue */
uint16_t txcmplq_max ; /* max length */
uint32_t missbufcnt ; /* keep track of buffers to post */
struct list_head postbufq ;
uint16_t postbufq_cnt ; /* current length of queue */
uint16_t postbufq_max ; /* max length */
struct list_head iocb_continueq ;
uint16_t iocb_continueq_cnt ; /* current length of queue */
uint16_t iocb_continueq_max ; /* max length */
2008-01-11 09:53:18 +03:00
struct list_head iocb_continue_saveq ;
2005-04-18 01:05:31 +04:00
struct lpfc_sli_ring_mask prt [ LPFC_MAX_RING_MASK ] ;
uint32_t num_mask ; /* number of mask entries in prt array */
2007-10-27 21:37:05 +04:00
void ( * lpfc_sli_rcv_async_status ) ( struct lpfc_hba * ,
struct lpfc_sli_ring * , struct lpfc_iocbq * ) ;
2005-04-18 01:05:31 +04:00
struct lpfc_sli_ring_stat stats ; /* SLI statistical info */
/* cmd ring available */
void ( * lpfc_sli_cmd_available ) ( struct lpfc_hba * ,
struct lpfc_sli_ring * ) ;
2012-08-03 20:35:34 +04:00
union {
struct lpfc_sli3_ring sli3 ;
struct lpfc_sli4_ring sli4 ;
} sli ;
2005-04-18 01:05:31 +04:00
} ;
2007-06-18 04:56:37 +04:00
/* Structure used for configuring rings to a specific profile or rctl / type */
struct lpfc_hbq_init {
uint32_t rn ; /* Receive buffer notification */
2007-06-18 04:56:38 +04:00
uint32_t entry_count ; /* max # of entries in HBQ */
2007-06-18 04:56:37 +04:00
uint32_t headerLen ; /* 0 if not profile 4 or 5 */
uint32_t logEntry ; /* Set to 1 if this HBQ used for LogEntry */
uint32_t profile ; /* Selection profile 0=all, 7=logentry */
uint32_t ring_mask ; /* Binds HBQ to a ring e.g. Ring0=b0001,
* ring2 = b0100 */
uint32_t hbq_index ; /* index of this hbq in ring .HBQs[] */
uint32_t seqlenoff ;
uint32_t maxlen ;
uint32_t seqlenbcnt ;
uint32_t cmdcodeoff ;
uint32_t cmdmatch [ 8 ] ;
uint32_t mask_count ; /* number of mask entries in prt array */
struct hbq_mask hbqMasks [ 6 ] ;
2007-06-18 04:56:38 +04:00
/* Non-config rings fields to keep track of buffer allocations */
uint32_t buffer_count ; /* number of buffers allocated */
uint32_t init_count ; /* number to allocate when initialized */
uint32_t add_count ; /* number to allocate when starved */
2007-06-18 04:56:37 +04:00
} ;
2005-04-18 01:05:31 +04:00
/* Structure used to hold SLI statistical counters and info */
struct lpfc_sli_stat {
uint64_t mbox_stat_err ; /* Mbox cmds completed status error */
uint64_t mbox_cmd ; /* Mailbox commands issued */
uint64_t sli_intr ; /* Count of Host Attention interrupts */
2012-08-03 20:36:03 +04:00
uint64_t sli_prev_intr ; /* Previous cnt of Host Attention interrupts */
uint64_t sli_ips ; /* Host Attention interrupts per sec */
2005-04-18 01:05:31 +04:00
uint32_t err_attn_event ; /* Error Attn event counters */
uint32_t link_event ; /* Link event counters */
uint32_t mbox_event ; /* Mailbox event counters */
uint32_t mbox_busy ; /* Mailbox cmd busy */
} ;
2006-08-02 23:24:34 +04:00
/* Structure to store link status values when port stats are reset */
struct lpfc_lnk_stat {
uint32_t link_failure_count ;
uint32_t loss_of_sync_count ;
uint32_t loss_of_signal_count ;
uint32_t prim_seq_protocol_err_count ;
uint32_t invalid_tx_word_count ;
uint32_t invalid_crc_count ;
uint32_t error_frames ;
uint32_t link_events ;
} ;
2005-04-18 01:05:31 +04:00
/* Structure used to hold SLI information */
struct lpfc_sli {
uint32_t num_rings ;
uint32_t sli_flag ;
/* Additional sli_flags */
# define LPFC_SLI_MBOX_ACTIVE 0x100 /* HBA mailbox is currently active */
2009-05-22 22:53:12 +04:00
# define LPFC_SLI_ACTIVE 0x200 /* SLI in firmware is active */
2005-04-18 01:05:31 +04:00
# define LPFC_PROCESS_LA 0x400 /* Able to process link attention */
2007-06-18 04:56:36 +04:00
# define LPFC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */
2008-08-25 05:50:06 +04:00
# define LPFC_MENLO_MAINT 0x1000 /* need for menl fw download */
2009-05-22 22:51:39 +04:00
# define LPFC_SLI_ASYNC_MBX_BLK 0x2000 /* Async mailbox is blocked */
2005-04-18 01:05:31 +04:00
2012-08-03 20:35:54 +04:00
struct lpfc_sli_ring * ring ;
2005-04-18 01:05:31 +04:00
int fcp_ring ; /* ring used for FCP initiator commands */
int next_ring ;
2006-12-02 21:34:16 +03:00
int extra_ring ; /* extra ring used for other protocols */
2005-04-18 01:05:31 +04:00
struct lpfc_sli_stat slistat ; /* SLI statistical info */
struct list_head mboxq ;
uint16_t mboxq_cnt ; /* current length of queue */
uint16_t mboxq_max ; /* max length */
LPFC_MBOXQ_t * mbox_active ; /* active mboxq information */
2007-06-18 04:56:38 +04:00
struct list_head mboxq_cmpl ;
2005-04-18 01:05:31 +04:00
struct timer_list mbox_tmo ; /* Hold clk to timeout active mbox
cmd */
2005-10-29 19:28:33 +04:00
# define LPFC_IOCBQ_LOOKUP_INCREMENT 1024
struct lpfc_iocbq * * iocbq_lookup ; /* array to lookup IOCB by IOTAG */
size_t iocbq_lookup_len ; /* current lengs of the array */
uint16_t last_iotag ; /* last allocated IOTAG */
2006-08-02 23:24:34 +04:00
unsigned long stats_start ; /* in seconds */
struct lpfc_lnk_stat lnk_stat_offsets ;
2005-04-18 01:05:31 +04:00
} ;
2011-10-11 05:32:43 +04:00
/* Timeout for normal outstanding mbox command (Seconds) */
# define LPFC_MBOX_TMO 30
/* Timeout for non-flash-based outstanding sli_config mbox command (Seconds) */
# define LPFC_MBOX_SLI4_CONFIG_TMO 60
/* Timeout for flash-based outstanding sli_config mbox command (Seconds) */
# define LPFC_MBOX_SLI4_CONFIG_EXTENDED_TMO 300
/* Timeout for other flash-based outstanding mbox command (Seconds) */
# define LPFC_MBOX_TMO_FLASH_CMD 300