162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright(c) 2007 Intel Corporation. All rights reserved. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Maintained at www.Open-FCoE.org 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _LIBFC_H_ 962306a36Sopenharmony_ci#define _LIBFC_H_ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/timer.h> 1262306a36Sopenharmony_ci#include <linux/if.h> 1362306a36Sopenharmony_ci#include <linux/percpu.h> 1462306a36Sopenharmony_ci#include <linux/refcount.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <scsi/scsi_transport.h> 1762306a36Sopenharmony_ci#include <scsi/scsi_transport_fc.h> 1862306a36Sopenharmony_ci#include <scsi/scsi_bsg_fc.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include <scsi/fc/fc_fcp.h> 2162306a36Sopenharmony_ci#include <scsi/fc/fc_ns.h> 2262306a36Sopenharmony_ci#include <scsi/fc/fc_ms.h> 2362306a36Sopenharmony_ci#include <scsi/fc/fc_els.h> 2462306a36Sopenharmony_ci#include <scsi/fc/fc_gs.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include <scsi/fc_frame.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define FC_FC4_PROV_SIZE (FC_TYPE_FCP + 1) /* size of tables */ 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * libfc error codes 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ci#define FC_NO_ERR 0 /* no error */ 3462306a36Sopenharmony_ci#define FC_EX_TIMEOUT 1 /* Exchange timeout */ 3562306a36Sopenharmony_ci#define FC_EX_CLOSED 2 /* Exchange closed */ 3662306a36Sopenharmony_ci#define FC_EX_ALLOC_ERR 3 /* Exchange allocation failed */ 3762306a36Sopenharmony_ci#define FC_EX_XMIT_ERR 4 /* Exchange transmit failed */ 3862306a36Sopenharmony_ci#define FC_EX_ELS_RJT 5 /* ELS rejected */ 3962306a36Sopenharmony_ci#define FC_EX_INV_LOGIN 6 /* Login not completed */ 4062306a36Sopenharmony_ci#define FC_EX_SEQ_ERR 6 /* Exchange sequence error */ 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/** 4362306a36Sopenharmony_ci * enum fc_lport_state - Local port states 4462306a36Sopenharmony_ci * @LPORT_ST_DISABLED: Disabled 4562306a36Sopenharmony_ci * @LPORT_ST_FLOGI: Fabric login (FLOGI) sent 4662306a36Sopenharmony_ci * @LPORT_ST_DNS: Waiting for name server remote port to become ready 4762306a36Sopenharmony_ci * @LPORT_ST_RPN_ID: Register port name by ID (RPN_ID) sent 4862306a36Sopenharmony_ci * @LPORT_ST_RFT_ID: Register Fibre Channel types by ID (RFT_ID) sent 4962306a36Sopenharmony_ci * @LPORT_ST_RFF_ID: Register FC-4 Features by ID (RFF_ID) sent 5062306a36Sopenharmony_ci * @LPORT_ST_FDMI: Waiting for mgmt server rport to become ready 5162306a36Sopenharmony_ci * @LPORT_ST_RHBA: 5262306a36Sopenharmony_ci * @LPORT_ST_SCR: State Change Register (SCR) sent 5362306a36Sopenharmony_ci * @LPORT_ST_READY: Ready for use 5462306a36Sopenharmony_ci * @LPORT_ST_LOGO: Local port logout (LOGO) sent 5562306a36Sopenharmony_ci * @LPORT_ST_RESET: Local port reset 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_cienum fc_lport_state { 5862306a36Sopenharmony_ci LPORT_ST_DISABLED = 0, 5962306a36Sopenharmony_ci LPORT_ST_FLOGI, 6062306a36Sopenharmony_ci LPORT_ST_DNS, 6162306a36Sopenharmony_ci LPORT_ST_RNN_ID, 6262306a36Sopenharmony_ci LPORT_ST_RSNN_NN, 6362306a36Sopenharmony_ci LPORT_ST_RSPN_ID, 6462306a36Sopenharmony_ci LPORT_ST_RFT_ID, 6562306a36Sopenharmony_ci LPORT_ST_RFF_ID, 6662306a36Sopenharmony_ci LPORT_ST_FDMI, 6762306a36Sopenharmony_ci LPORT_ST_RHBA, 6862306a36Sopenharmony_ci LPORT_ST_RPA, 6962306a36Sopenharmony_ci LPORT_ST_DHBA, 7062306a36Sopenharmony_ci LPORT_ST_DPRT, 7162306a36Sopenharmony_ci LPORT_ST_SCR, 7262306a36Sopenharmony_ci LPORT_ST_READY, 7362306a36Sopenharmony_ci LPORT_ST_LOGO, 7462306a36Sopenharmony_ci LPORT_ST_RESET 7562306a36Sopenharmony_ci}; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cienum fc_disc_event { 7862306a36Sopenharmony_ci DISC_EV_NONE = 0, 7962306a36Sopenharmony_ci DISC_EV_SUCCESS, 8062306a36Sopenharmony_ci DISC_EV_FAILED 8162306a36Sopenharmony_ci}; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci/** 8462306a36Sopenharmony_ci * enum fc_rport_state - Remote port states 8562306a36Sopenharmony_ci * @RPORT_ST_INIT: Initialized 8662306a36Sopenharmony_ci * @RPORT_ST_FLOGI: Waiting for FLOGI completion for point-to-multipoint 8762306a36Sopenharmony_ci * @RPORT_ST_PLOGI_WAIT: Waiting for peer to login for point-to-multipoint 8862306a36Sopenharmony_ci * @RPORT_ST_PLOGI: Waiting for PLOGI completion 8962306a36Sopenharmony_ci * @RPORT_ST_PRLI: Waiting for PRLI completion 9062306a36Sopenharmony_ci * @RPORT_ST_RTV: Waiting for RTV completion 9162306a36Sopenharmony_ci * @RPORT_ST_READY: Ready for use 9262306a36Sopenharmony_ci * @RPORT_ST_ADISC: Discover Address sent 9362306a36Sopenharmony_ci * @RPORT_ST_DELETE: Remote port being deleted 9462306a36Sopenharmony_ci*/ 9562306a36Sopenharmony_cienum fc_rport_state { 9662306a36Sopenharmony_ci RPORT_ST_INIT, 9762306a36Sopenharmony_ci RPORT_ST_FLOGI, 9862306a36Sopenharmony_ci RPORT_ST_PLOGI_WAIT, 9962306a36Sopenharmony_ci RPORT_ST_PLOGI, 10062306a36Sopenharmony_ci RPORT_ST_PRLI, 10162306a36Sopenharmony_ci RPORT_ST_RTV, 10262306a36Sopenharmony_ci RPORT_ST_READY, 10362306a36Sopenharmony_ci RPORT_ST_ADISC, 10462306a36Sopenharmony_ci RPORT_ST_DELETE, 10562306a36Sopenharmony_ci}; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/** 10862306a36Sopenharmony_ci * struct fc_disc_port - temporary discovery port to hold rport identifiers 10962306a36Sopenharmony_ci * @lp: Fibre Channel host port instance 11062306a36Sopenharmony_ci * @peers: Node for list management during discovery and RSCN processing 11162306a36Sopenharmony_ci * @rport_work: Work struct for starting the rport state machine 11262306a36Sopenharmony_ci * @port_id: Port ID of the discovered port 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_cistruct fc_disc_port { 11562306a36Sopenharmony_ci struct fc_lport *lp; 11662306a36Sopenharmony_ci struct list_head peers; 11762306a36Sopenharmony_ci struct work_struct rport_work; 11862306a36Sopenharmony_ci u32 port_id; 11962306a36Sopenharmony_ci}; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/** 12262306a36Sopenharmony_ci * enum fc_rport_event - Remote port events 12362306a36Sopenharmony_ci * @RPORT_EV_NONE: No event 12462306a36Sopenharmony_ci * @RPORT_EV_READY: Remote port is ready for use 12562306a36Sopenharmony_ci * @RPORT_EV_FAILED: State machine failed, remote port is not ready 12662306a36Sopenharmony_ci * @RPORT_EV_STOP: Remote port has been stopped 12762306a36Sopenharmony_ci * @RPORT_EV_LOGO: Remote port logout (LOGO) sent 12862306a36Sopenharmony_ci */ 12962306a36Sopenharmony_cienum fc_rport_event { 13062306a36Sopenharmony_ci RPORT_EV_NONE = 0, 13162306a36Sopenharmony_ci RPORT_EV_READY, 13262306a36Sopenharmony_ci RPORT_EV_FAILED, 13362306a36Sopenharmony_ci RPORT_EV_STOP, 13462306a36Sopenharmony_ci RPORT_EV_LOGO 13562306a36Sopenharmony_ci}; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cistruct fc_rport_priv; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci/** 14062306a36Sopenharmony_ci * struct fc_rport_operations - Operations for a remote port 14162306a36Sopenharmony_ci * @event_callback: Function to be called for remote port events 14262306a36Sopenharmony_ci */ 14362306a36Sopenharmony_cistruct fc_rport_operations { 14462306a36Sopenharmony_ci void (*event_callback)(struct fc_lport *, struct fc_rport_priv *, 14562306a36Sopenharmony_ci enum fc_rport_event); 14662306a36Sopenharmony_ci}; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/** 14962306a36Sopenharmony_ci * struct fc_rport_libfc_priv - libfc internal information about a remote port 15062306a36Sopenharmony_ci * @local_port: The associated local port 15162306a36Sopenharmony_ci * @rp_state: Indicates READY for I/O or DELETE when blocked 15262306a36Sopenharmony_ci * @flags: REC and RETRY supported flags 15362306a36Sopenharmony_ci * @e_d_tov: Error detect timeout value (in msec) 15462306a36Sopenharmony_ci * @r_a_tov: Resource allocation timeout value (in msec) 15562306a36Sopenharmony_ci */ 15662306a36Sopenharmony_cistruct fc_rport_libfc_priv { 15762306a36Sopenharmony_ci struct fc_lport *local_port; 15862306a36Sopenharmony_ci enum fc_rport_state rp_state; 15962306a36Sopenharmony_ci u16 flags; 16062306a36Sopenharmony_ci #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) 16162306a36Sopenharmony_ci #define FC_RP_FLAGS_RETRY (1 << 1) 16262306a36Sopenharmony_ci #define FC_RP_STARTED (1 << 2) 16362306a36Sopenharmony_ci #define FC_RP_FLAGS_CONF_REQ (1 << 3) 16462306a36Sopenharmony_ci unsigned int e_d_tov; 16562306a36Sopenharmony_ci unsigned int r_a_tov; 16662306a36Sopenharmony_ci}; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci/** 16962306a36Sopenharmony_ci * struct fc_rport_priv - libfc remote port and discovery info 17062306a36Sopenharmony_ci * @local_port: The associated local port 17162306a36Sopenharmony_ci * @rport: The FC transport remote port 17262306a36Sopenharmony_ci * @kref: Reference counter 17362306a36Sopenharmony_ci * @rp_state: Enumeration that tracks progress of PLOGI, PRLI, 17462306a36Sopenharmony_ci * and RTV exchanges 17562306a36Sopenharmony_ci * @ids: The remote port identifiers and roles 17662306a36Sopenharmony_ci * @flags: STARTED, REC and RETRY_SUPPORTED flags 17762306a36Sopenharmony_ci * @max_seq: Maximum number of concurrent sequences 17862306a36Sopenharmony_ci * @disc_id: The discovery identifier 17962306a36Sopenharmony_ci * @maxframe_size: The maximum frame size 18062306a36Sopenharmony_ci * @retries: The retry count for the current state 18162306a36Sopenharmony_ci * @major_retries: The retry count for the entire PLOGI/PRLI state machine 18262306a36Sopenharmony_ci * @e_d_tov: Error detect timeout value (in msec) 18362306a36Sopenharmony_ci * @r_a_tov: Resource allocation timeout value (in msec) 18462306a36Sopenharmony_ci * @rp_mutex: The mutex that protects the remote port 18562306a36Sopenharmony_ci * @retry_work: Handle for retries 18662306a36Sopenharmony_ci * @event_callback: Callback when READY, FAILED or LOGO states complete 18762306a36Sopenharmony_ci * @prli_count: Count of open PRLI sessions in providers 18862306a36Sopenharmony_ci * @rcu: Structure used for freeing in an RCU-safe manner 18962306a36Sopenharmony_ci */ 19062306a36Sopenharmony_cistruct fc_rport_priv { 19162306a36Sopenharmony_ci struct fc_lport *local_port; 19262306a36Sopenharmony_ci struct fc_rport *rport; 19362306a36Sopenharmony_ci struct kref kref; 19462306a36Sopenharmony_ci enum fc_rport_state rp_state; 19562306a36Sopenharmony_ci struct fc_rport_identifiers ids; 19662306a36Sopenharmony_ci u16 flags; 19762306a36Sopenharmony_ci u16 max_seq; 19862306a36Sopenharmony_ci u16 disc_id; 19962306a36Sopenharmony_ci u16 maxframe_size; 20062306a36Sopenharmony_ci unsigned int retries; 20162306a36Sopenharmony_ci unsigned int major_retries; 20262306a36Sopenharmony_ci unsigned int e_d_tov; 20362306a36Sopenharmony_ci unsigned int r_a_tov; 20462306a36Sopenharmony_ci struct mutex rp_mutex; 20562306a36Sopenharmony_ci struct delayed_work retry_work; 20662306a36Sopenharmony_ci enum fc_rport_event event; 20762306a36Sopenharmony_ci struct fc_rport_operations *ops; 20862306a36Sopenharmony_ci struct list_head peers; 20962306a36Sopenharmony_ci struct work_struct event_work; 21062306a36Sopenharmony_ci u32 supported_classes; 21162306a36Sopenharmony_ci u16 prli_count; 21262306a36Sopenharmony_ci struct rcu_head rcu; 21362306a36Sopenharmony_ci u16 sp_features; 21462306a36Sopenharmony_ci u8 spp_type; 21562306a36Sopenharmony_ci void (*lld_event_callback)(struct fc_lport *, 21662306a36Sopenharmony_ci struct fc_rport_priv *, 21762306a36Sopenharmony_ci enum fc_rport_event); 21862306a36Sopenharmony_ci}; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/** 22162306a36Sopenharmony_ci * struct fc_stats - fc stats structure 22262306a36Sopenharmony_ci * @SecondsSinceLastReset: Seconds since the last reset 22362306a36Sopenharmony_ci * @TxFrames: Number of transmitted frames 22462306a36Sopenharmony_ci * @TxWords: Number of transmitted words 22562306a36Sopenharmony_ci * @RxFrames: Number of received frames 22662306a36Sopenharmony_ci * @RxWords: Number of received words 22762306a36Sopenharmony_ci * @ErrorFrames: Number of received error frames 22862306a36Sopenharmony_ci * @DumpedFrames: Number of dumped frames 22962306a36Sopenharmony_ci * @FcpPktAllocFails: Number of fcp packet allocation failures 23062306a36Sopenharmony_ci * @FcpPktAborts: Number of fcp packet aborts 23162306a36Sopenharmony_ci * @FcpFrameAllocFails: Number of fcp frame allocation failures 23262306a36Sopenharmony_ci * @LinkFailureCount: Number of link failures 23362306a36Sopenharmony_ci * @LossOfSignalCount: Number for signal losses 23462306a36Sopenharmony_ci * @InvalidTxWordCount: Number of invalid transmitted words 23562306a36Sopenharmony_ci * @InvalidCRCCount: Number of invalid CRCs 23662306a36Sopenharmony_ci * @InputRequests: Number of input requests 23762306a36Sopenharmony_ci * @OutputRequests: Number of output requests 23862306a36Sopenharmony_ci * @ControlRequests: Number of control requests 23962306a36Sopenharmony_ci * @InputBytes: Number of received bytes 24062306a36Sopenharmony_ci * @OutputBytes: Number of transmitted bytes 24162306a36Sopenharmony_ci * @VLinkFailureCount: Number of virtual link failures 24262306a36Sopenharmony_ci * @MissDiscAdvCount: Number of missing FIP discovery advertisement 24362306a36Sopenharmony_ci */ 24462306a36Sopenharmony_cistruct fc_stats { 24562306a36Sopenharmony_ci u64 SecondsSinceLastReset; 24662306a36Sopenharmony_ci u64 TxFrames; 24762306a36Sopenharmony_ci u64 TxWords; 24862306a36Sopenharmony_ci u64 RxFrames; 24962306a36Sopenharmony_ci u64 RxWords; 25062306a36Sopenharmony_ci u64 ErrorFrames; 25162306a36Sopenharmony_ci u64 DumpedFrames; 25262306a36Sopenharmony_ci u64 FcpPktAllocFails; 25362306a36Sopenharmony_ci u64 FcpPktAborts; 25462306a36Sopenharmony_ci u64 FcpFrameAllocFails; 25562306a36Sopenharmony_ci u64 LinkFailureCount; 25662306a36Sopenharmony_ci u64 LossOfSignalCount; 25762306a36Sopenharmony_ci u64 InvalidTxWordCount; 25862306a36Sopenharmony_ci u64 InvalidCRCCount; 25962306a36Sopenharmony_ci u64 InputRequests; 26062306a36Sopenharmony_ci u64 OutputRequests; 26162306a36Sopenharmony_ci u64 ControlRequests; 26262306a36Sopenharmony_ci u64 InputBytes; 26362306a36Sopenharmony_ci u64 OutputBytes; 26462306a36Sopenharmony_ci u64 VLinkFailureCount; 26562306a36Sopenharmony_ci u64 MissDiscAdvCount; 26662306a36Sopenharmony_ci}; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci/** 26962306a36Sopenharmony_ci * struct fc_seq_els_data - ELS data used for passing ELS specific responses 27062306a36Sopenharmony_ci * @reason: The reason for rejection 27162306a36Sopenharmony_ci * @explan: The explanation of the rejection 27262306a36Sopenharmony_ci * 27362306a36Sopenharmony_ci * Mainly used by the exchange manager layer. 27462306a36Sopenharmony_ci */ 27562306a36Sopenharmony_cistruct fc_seq_els_data { 27662306a36Sopenharmony_ci enum fc_els_rjt_reason reason; 27762306a36Sopenharmony_ci enum fc_els_rjt_explan explan; 27862306a36Sopenharmony_ci}; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci/** 28162306a36Sopenharmony_ci * struct fc_fcp_pkt - FCP request structure (one for each scsi_cmnd request) 28262306a36Sopenharmony_ci * @lp: The associated local port 28362306a36Sopenharmony_ci * @state: The state of the I/O 28462306a36Sopenharmony_ci * @ref_cnt: Reference count 28562306a36Sopenharmony_ci * @scsi_pkt_lock: Lock to protect the SCSI packet (must be taken before the 28662306a36Sopenharmony_ci * host_lock if both are to be held at the same time) 28762306a36Sopenharmony_ci * @cmd: The SCSI command (set and clear with the host_lock held) 28862306a36Sopenharmony_ci * @list: Tracks queued commands (accessed with the host_lock held) 28962306a36Sopenharmony_ci * @timer: The command timer 29062306a36Sopenharmony_ci * @tm_done: Completion indicator 29162306a36Sopenharmony_ci * @wait_for_comp: Indicator to wait for completion of the I/O (in jiffies) 29262306a36Sopenharmony_ci * @data_len: The length of the data 29362306a36Sopenharmony_ci * @cdb_cmd: The CDB command 29462306a36Sopenharmony_ci * @xfer_len: The transfer length 29562306a36Sopenharmony_ci * @xfer_ddp: Indicates if this transfer used DDP (XID of the exchange 29662306a36Sopenharmony_ci * will be set here if DDP was setup) 29762306a36Sopenharmony_ci * @xfer_contig_end: The offset into the buffer if the buffer is contiguous 29862306a36Sopenharmony_ci * (Tx and Rx) 29962306a36Sopenharmony_ci * @max_payload: The maximum payload size (in bytes) 30062306a36Sopenharmony_ci * @io_status: SCSI result (upper 24 bits) 30162306a36Sopenharmony_ci * @cdb_status: CDB status 30262306a36Sopenharmony_ci * @status_code: FCP I/O status 30362306a36Sopenharmony_ci * @scsi_comp_flags: Completion flags (bit 3 Underrun bit 2: overrun) 30462306a36Sopenharmony_ci * @req_flags: Request flags (bit 0: read bit:1 write) 30562306a36Sopenharmony_ci * @scsi_resid: SCSI residule length 30662306a36Sopenharmony_ci * @rport: The remote port that the SCSI command is targeted at 30762306a36Sopenharmony_ci * @seq_ptr: The sequence that will carry the SCSI command 30862306a36Sopenharmony_ci * @recov_retry: Number of recovery retries 30962306a36Sopenharmony_ci * @recov_seq: The sequence for REC or SRR 31062306a36Sopenharmony_ci */ 31162306a36Sopenharmony_cistruct fc_fcp_pkt { 31262306a36Sopenharmony_ci spinlock_t scsi_pkt_lock; 31362306a36Sopenharmony_ci refcount_t ref_cnt; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /* SCSI command and data transfer information */ 31662306a36Sopenharmony_ci u32 data_len; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci /* SCSI I/O related information */ 31962306a36Sopenharmony_ci struct scsi_cmnd *cmd; 32062306a36Sopenharmony_ci struct list_head list; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci /* Housekeeping information */ 32362306a36Sopenharmony_ci struct fc_lport *lp; 32462306a36Sopenharmony_ci u8 state; 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci /* SCSI/FCP return status */ 32762306a36Sopenharmony_ci u8 cdb_status; 32862306a36Sopenharmony_ci u8 status_code; 32962306a36Sopenharmony_ci u8 scsi_comp_flags; 33062306a36Sopenharmony_ci u32 io_status; 33162306a36Sopenharmony_ci u32 req_flags; 33262306a36Sopenharmony_ci u32 scsi_resid; 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci /* Transport related veriables */ 33562306a36Sopenharmony_ci size_t xfer_len; 33662306a36Sopenharmony_ci struct fcp_cmnd cdb_cmd; 33762306a36Sopenharmony_ci u32 xfer_contig_end; 33862306a36Sopenharmony_ci u16 max_payload; 33962306a36Sopenharmony_ci u16 xfer_ddp; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci /* Associated structures */ 34262306a36Sopenharmony_ci struct fc_rport *rport; 34362306a36Sopenharmony_ci struct fc_seq *seq_ptr; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci /* Timeout/error related information */ 34662306a36Sopenharmony_ci struct timer_list timer; 34762306a36Sopenharmony_ci int wait_for_comp; 34862306a36Sopenharmony_ci int timer_delay; 34962306a36Sopenharmony_ci u32 recov_retry; 35062306a36Sopenharmony_ci struct fc_seq *recov_seq; 35162306a36Sopenharmony_ci struct completion tm_done; 35262306a36Sopenharmony_ci} ____cacheline_aligned_in_smp; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci/* 35562306a36Sopenharmony_ci * @fsp should be tested and set under the scsi_pkt_queue lock 35662306a36Sopenharmony_ci */ 35762306a36Sopenharmony_cistruct libfc_cmd_priv { 35862306a36Sopenharmony_ci struct fc_fcp_pkt *fsp; 35962306a36Sopenharmony_ci u32 resid_len; 36062306a36Sopenharmony_ci u8 status; 36162306a36Sopenharmony_ci}; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci/* 36462306a36Sopenharmony_ci * Structure and function definitions for managing Fibre Channel Exchanges 36562306a36Sopenharmony_ci * and Sequences 36662306a36Sopenharmony_ci * 36762306a36Sopenharmony_ci * fc_exch holds state for one exchange and links to its active sequence. 36862306a36Sopenharmony_ci * 36962306a36Sopenharmony_ci * fc_seq holds the state for an individual sequence. 37062306a36Sopenharmony_ci */ 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_cistruct fc_exch_mgr; 37362306a36Sopenharmony_cistruct fc_exch_mgr_anchor; 37462306a36Sopenharmony_ciextern u16 fc_cpu_mask; /* cpu mask for possible cpus */ 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci/** 37762306a36Sopenharmony_ci * struct fc_seq - FC sequence 37862306a36Sopenharmony_ci * @id: The sequence ID 37962306a36Sopenharmony_ci * @ssb_stat: Status flags for the sequence status block (SSB) 38062306a36Sopenharmony_ci * @cnt: Number of frames sent so far 38162306a36Sopenharmony_ci * @rec_data: FC-4 value for REC 38262306a36Sopenharmony_ci */ 38362306a36Sopenharmony_cistruct fc_seq { 38462306a36Sopenharmony_ci u8 id; 38562306a36Sopenharmony_ci u16 ssb_stat; 38662306a36Sopenharmony_ci u16 cnt; 38762306a36Sopenharmony_ci u32 rec_data; 38862306a36Sopenharmony_ci}; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci#define FC_EX_DONE (1 << 0) /* ep is completed */ 39162306a36Sopenharmony_ci#define FC_EX_RST_CLEANUP (1 << 1) /* reset is forcing completion */ 39262306a36Sopenharmony_ci#define FC_EX_QUARANTINE (1 << 2) /* exch is quarantined */ 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci/** 39562306a36Sopenharmony_ci * struct fc_exch - Fibre Channel Exchange 39662306a36Sopenharmony_ci * @em: Exchange manager 39762306a36Sopenharmony_ci * @pool: Exchange pool 39862306a36Sopenharmony_ci * @state: The exchange's state 39962306a36Sopenharmony_ci * @xid: The exchange ID 40062306a36Sopenharmony_ci * @ex_list: Handle used by the EM to track free exchanges 40162306a36Sopenharmony_ci * @ex_lock: Lock that protects the exchange 40262306a36Sopenharmony_ci * @ex_refcnt: Reference count 40362306a36Sopenharmony_ci * @timeout_work: Handle for timeout handler 40462306a36Sopenharmony_ci * @lp: The local port that this exchange is on 40562306a36Sopenharmony_ci * @oxid: Originator's exchange ID 40662306a36Sopenharmony_ci * @rxid: Responder's exchange ID 40762306a36Sopenharmony_ci * @oid: Originator's FCID 40862306a36Sopenharmony_ci * @sid: Source FCID 40962306a36Sopenharmony_ci * @did: Destination FCID 41062306a36Sopenharmony_ci * @esb_stat: ESB exchange status 41162306a36Sopenharmony_ci * @r_a_tov: Resource allocation time out value (in msecs) 41262306a36Sopenharmony_ci * @seq_id: The next sequence ID to use 41362306a36Sopenharmony_ci * @encaps: encapsulation information for lower-level driver 41462306a36Sopenharmony_ci * @f_ctl: F_CTL flags for the sequence 41562306a36Sopenharmony_ci * @fh_type: The frame type 41662306a36Sopenharmony_ci * @class: The class of service 41762306a36Sopenharmony_ci * @seq: The sequence in use on this exchange 41862306a36Sopenharmony_ci * @resp_active: Number of tasks that are concurrently executing @resp(). 41962306a36Sopenharmony_ci * @resp_task: If @resp_active > 0, either the task executing @resp(), the 42062306a36Sopenharmony_ci * task that has been interrupted to execute the soft-IRQ 42162306a36Sopenharmony_ci * executing @resp() or NULL if more than one task is executing 42262306a36Sopenharmony_ci * @resp concurrently. 42362306a36Sopenharmony_ci * @resp_wq: Waitqueue for the tasks waiting on @resp_active. 42462306a36Sopenharmony_ci * @resp: Callback for responses on this exchange 42562306a36Sopenharmony_ci * @destructor: Called when destroying the exchange 42662306a36Sopenharmony_ci * @arg: Passed as a void pointer to the resp() callback 42762306a36Sopenharmony_ci * 42862306a36Sopenharmony_ci * Locking notes: The ex_lock protects following items: 42962306a36Sopenharmony_ci * state, esb_stat, f_ctl, seq.ssb_stat 43062306a36Sopenharmony_ci * seq_id 43162306a36Sopenharmony_ci * sequence allocation 43262306a36Sopenharmony_ci */ 43362306a36Sopenharmony_cistruct fc_exch { 43462306a36Sopenharmony_ci spinlock_t ex_lock; 43562306a36Sopenharmony_ci atomic_t ex_refcnt; 43662306a36Sopenharmony_ci enum fc_class class; 43762306a36Sopenharmony_ci struct fc_exch_mgr *em; 43862306a36Sopenharmony_ci struct fc_exch_pool *pool; 43962306a36Sopenharmony_ci struct list_head ex_list; 44062306a36Sopenharmony_ci struct fc_lport *lp; 44162306a36Sopenharmony_ci u32 esb_stat; 44262306a36Sopenharmony_ci u8 state; 44362306a36Sopenharmony_ci u8 fh_type; 44462306a36Sopenharmony_ci u8 seq_id; 44562306a36Sopenharmony_ci u8 encaps; 44662306a36Sopenharmony_ci u16 xid; 44762306a36Sopenharmony_ci u16 oxid; 44862306a36Sopenharmony_ci u16 rxid; 44962306a36Sopenharmony_ci u32 oid; 45062306a36Sopenharmony_ci u32 sid; 45162306a36Sopenharmony_ci u32 did; 45262306a36Sopenharmony_ci u32 r_a_tov; 45362306a36Sopenharmony_ci u32 f_ctl; 45462306a36Sopenharmony_ci struct fc_seq seq; 45562306a36Sopenharmony_ci int resp_active; 45662306a36Sopenharmony_ci struct task_struct *resp_task; 45762306a36Sopenharmony_ci wait_queue_head_t resp_wq; 45862306a36Sopenharmony_ci void (*resp)(struct fc_seq *, struct fc_frame *, void *); 45962306a36Sopenharmony_ci void *arg; 46062306a36Sopenharmony_ci void (*destructor)(struct fc_seq *, void *); 46162306a36Sopenharmony_ci struct delayed_work timeout_work; 46262306a36Sopenharmony_ci} ____cacheline_aligned_in_smp; 46362306a36Sopenharmony_ci#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq) 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_cistruct libfc_function_template { 46762306a36Sopenharmony_ci /* 46862306a36Sopenharmony_ci * Interface to send a FC frame 46962306a36Sopenharmony_ci * 47062306a36Sopenharmony_ci * STATUS: REQUIRED 47162306a36Sopenharmony_ci */ 47262306a36Sopenharmony_ci int (*frame_send)(struct fc_lport *, struct fc_frame *); 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci /* 47562306a36Sopenharmony_ci * Interface to send ELS/CT frames 47662306a36Sopenharmony_ci * 47762306a36Sopenharmony_ci * STATUS: OPTIONAL 47862306a36Sopenharmony_ci */ 47962306a36Sopenharmony_ci struct fc_seq *(*elsct_send)(struct fc_lport *, u32 did, 48062306a36Sopenharmony_ci struct fc_frame *, unsigned int op, 48162306a36Sopenharmony_ci void (*resp)(struct fc_seq *, 48262306a36Sopenharmony_ci struct fc_frame *, void *arg), 48362306a36Sopenharmony_ci void *arg, u32 timer_msec); 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci /* 48662306a36Sopenharmony_ci * Sets up the DDP context for a given exchange id on the given 48762306a36Sopenharmony_ci * scatterlist if LLD supports DDP for large receive. 48862306a36Sopenharmony_ci * 48962306a36Sopenharmony_ci * STATUS: OPTIONAL 49062306a36Sopenharmony_ci */ 49162306a36Sopenharmony_ci int (*ddp_setup)(struct fc_lport *, u16, struct scatterlist *, 49262306a36Sopenharmony_ci unsigned int); 49362306a36Sopenharmony_ci /* 49462306a36Sopenharmony_ci * Completes the DDP transfer and returns the length of data DDPed 49562306a36Sopenharmony_ci * for the given exchange id. 49662306a36Sopenharmony_ci * 49762306a36Sopenharmony_ci * STATUS: OPTIONAL 49862306a36Sopenharmony_ci */ 49962306a36Sopenharmony_ci int (*ddp_done)(struct fc_lport *, u16); 50062306a36Sopenharmony_ci /* 50162306a36Sopenharmony_ci * Sets up the DDP context for a given exchange id on the given 50262306a36Sopenharmony_ci * scatterlist if LLD supports DDP for target. 50362306a36Sopenharmony_ci * 50462306a36Sopenharmony_ci * STATUS: OPTIONAL 50562306a36Sopenharmony_ci */ 50662306a36Sopenharmony_ci int (*ddp_target)(struct fc_lport *, u16, struct scatterlist *, 50762306a36Sopenharmony_ci unsigned int); 50862306a36Sopenharmony_ci /* 50962306a36Sopenharmony_ci * Allow LLD to fill its own Link Error Status Block 51062306a36Sopenharmony_ci * 51162306a36Sopenharmony_ci * STATUS: OPTIONAL 51262306a36Sopenharmony_ci */ 51362306a36Sopenharmony_ci void (*get_lesb)(struct fc_lport *, struct fc_els_lesb *lesb); 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci /* 51662306a36Sopenharmony_ci * Reset an exchange manager, completing all sequences and exchanges. 51762306a36Sopenharmony_ci * If s_id is non-zero, reset only exchanges originating from that FID. 51862306a36Sopenharmony_ci * If d_id is non-zero, reset only exchanges sending to that FID. 51962306a36Sopenharmony_ci * 52062306a36Sopenharmony_ci * STATUS: OPTIONAL 52162306a36Sopenharmony_ci */ 52262306a36Sopenharmony_ci void (*exch_mgr_reset)(struct fc_lport *, u32 s_id, u32 d_id); 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci /* 52562306a36Sopenharmony_ci * Set the local port FC_ID. 52662306a36Sopenharmony_ci * 52762306a36Sopenharmony_ci * This may be provided by the LLD to allow it to be 52862306a36Sopenharmony_ci * notified when the local port is assigned a FC-ID. 52962306a36Sopenharmony_ci * 53062306a36Sopenharmony_ci * The frame, if non-NULL, is the incoming frame with the 53162306a36Sopenharmony_ci * FLOGI LS_ACC or FLOGI, and may contain the granted MAC 53262306a36Sopenharmony_ci * address for the LLD. The frame pointer may be NULL if 53362306a36Sopenharmony_ci * no MAC is associated with this assignment (LOGO or PLOGI). 53462306a36Sopenharmony_ci * 53562306a36Sopenharmony_ci * If FC_ID is non-zero, r_a_tov and e_d_tov must be valid. 53662306a36Sopenharmony_ci * 53762306a36Sopenharmony_ci * Note: this is called with the local port mutex held. 53862306a36Sopenharmony_ci * 53962306a36Sopenharmony_ci * STATUS: OPTIONAL 54062306a36Sopenharmony_ci */ 54162306a36Sopenharmony_ci void (*lport_set_port_id)(struct fc_lport *, u32 port_id, 54262306a36Sopenharmony_ci struct fc_frame *); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci /* 54562306a36Sopenharmony_ci * Callback routine after the remote port is logged in 54662306a36Sopenharmony_ci * 54762306a36Sopenharmony_ci * STATUS: OPTIONAL 54862306a36Sopenharmony_ci */ 54962306a36Sopenharmony_ci void (*rport_event_callback)(struct fc_lport *, 55062306a36Sopenharmony_ci struct fc_rport_priv *, 55162306a36Sopenharmony_ci enum fc_rport_event); 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci /* 55462306a36Sopenharmony_ci * Send a fcp cmd from fsp pkt. 55562306a36Sopenharmony_ci * Called with the SCSI host lock unlocked and irqs disabled. 55662306a36Sopenharmony_ci * 55762306a36Sopenharmony_ci * The resp handler is called when FCP_RSP received. 55862306a36Sopenharmony_ci * 55962306a36Sopenharmony_ci * STATUS: OPTIONAL 56062306a36Sopenharmony_ci */ 56162306a36Sopenharmony_ci int (*fcp_cmd_send)(struct fc_lport *, struct fc_fcp_pkt *, 56262306a36Sopenharmony_ci void (*resp)(struct fc_seq *, struct fc_frame *, 56362306a36Sopenharmony_ci void *)); 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci /* 56662306a36Sopenharmony_ci * Cleanup the FCP layer, used during link down and reset 56762306a36Sopenharmony_ci * 56862306a36Sopenharmony_ci * STATUS: OPTIONAL 56962306a36Sopenharmony_ci */ 57062306a36Sopenharmony_ci void (*fcp_cleanup)(struct fc_lport *); 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci /* 57362306a36Sopenharmony_ci * Abort all I/O on a local port 57462306a36Sopenharmony_ci * 57562306a36Sopenharmony_ci * STATUS: OPTIONAL 57662306a36Sopenharmony_ci */ 57762306a36Sopenharmony_ci void (*fcp_abort_io)(struct fc_lport *); 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci /* 58062306a36Sopenharmony_ci * Receive a request for the discovery layer. 58162306a36Sopenharmony_ci * 58262306a36Sopenharmony_ci * STATUS: OPTIONAL 58362306a36Sopenharmony_ci */ 58462306a36Sopenharmony_ci void (*disc_recv_req)(struct fc_lport *, struct fc_frame *); 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci /* 58762306a36Sopenharmony_ci * Start discovery for a local port. 58862306a36Sopenharmony_ci * 58962306a36Sopenharmony_ci * STATUS: OPTIONAL 59062306a36Sopenharmony_ci */ 59162306a36Sopenharmony_ci void (*disc_start)(void (*disc_callback)(struct fc_lport *, 59262306a36Sopenharmony_ci enum fc_disc_event), 59362306a36Sopenharmony_ci struct fc_lport *); 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci /* 59662306a36Sopenharmony_ci * Stop discovery for a given lport. This will remove 59762306a36Sopenharmony_ci * all discovered rports 59862306a36Sopenharmony_ci * 59962306a36Sopenharmony_ci * STATUS: OPTIONAL 60062306a36Sopenharmony_ci */ 60162306a36Sopenharmony_ci void (*disc_stop) (struct fc_lport *); 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci /* 60462306a36Sopenharmony_ci * Stop discovery for a given lport. This will block 60562306a36Sopenharmony_ci * until all discovered rports are deleted from the 60662306a36Sopenharmony_ci * FC transport class 60762306a36Sopenharmony_ci * 60862306a36Sopenharmony_ci * STATUS: OPTIONAL 60962306a36Sopenharmony_ci */ 61062306a36Sopenharmony_ci void (*disc_stop_final) (struct fc_lport *); 61162306a36Sopenharmony_ci}; 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci/** 61462306a36Sopenharmony_ci * struct fc_disc - Discovery context 61562306a36Sopenharmony_ci * @retry_count: Number of retries 61662306a36Sopenharmony_ci * @pending: 1 if discovery is pending, 0 if not 61762306a36Sopenharmony_ci * @requested: 1 if discovery has been requested, 0 if not 61862306a36Sopenharmony_ci * @seq_count: Number of sequences used for discovery 61962306a36Sopenharmony_ci * @buf_len: Length of the discovery buffer 62062306a36Sopenharmony_ci * @disc_id: Discovery ID 62162306a36Sopenharmony_ci * @rports: List of discovered remote ports 62262306a36Sopenharmony_ci * @priv: Private pointer for use by discovery code 62362306a36Sopenharmony_ci * @disc_mutex: Mutex that protects the discovery context 62462306a36Sopenharmony_ci * @partial_buf: Partial name buffer (if names are returned 62562306a36Sopenharmony_ci * in multiple frames) 62662306a36Sopenharmony_ci * @disc_work: handle for delayed work context 62762306a36Sopenharmony_ci * @disc_callback: Callback routine called when discovery completes 62862306a36Sopenharmony_ci */ 62962306a36Sopenharmony_cistruct fc_disc { 63062306a36Sopenharmony_ci unsigned char retry_count; 63162306a36Sopenharmony_ci unsigned char pending; 63262306a36Sopenharmony_ci unsigned char requested; 63362306a36Sopenharmony_ci unsigned short seq_count; 63462306a36Sopenharmony_ci unsigned char buf_len; 63562306a36Sopenharmony_ci u16 disc_id; 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci struct list_head rports; 63862306a36Sopenharmony_ci void *priv; 63962306a36Sopenharmony_ci struct mutex disc_mutex; 64062306a36Sopenharmony_ci struct fc_gpn_ft_resp partial_buf; 64162306a36Sopenharmony_ci struct delayed_work disc_work; 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci void (*disc_callback)(struct fc_lport *, 64462306a36Sopenharmony_ci enum fc_disc_event); 64562306a36Sopenharmony_ci}; 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci/* 64862306a36Sopenharmony_ci * Local port notifier and events. 64962306a36Sopenharmony_ci */ 65062306a36Sopenharmony_ciextern struct blocking_notifier_head fc_lport_notifier_head; 65162306a36Sopenharmony_cienum fc_lport_event { 65262306a36Sopenharmony_ci FC_LPORT_EV_ADD, 65362306a36Sopenharmony_ci FC_LPORT_EV_DEL, 65462306a36Sopenharmony_ci}; 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci/** 65762306a36Sopenharmony_ci * struct fc_lport - Local port 65862306a36Sopenharmony_ci * @host: The SCSI host associated with a local port 65962306a36Sopenharmony_ci * @ema_list: Exchange manager anchor list 66062306a36Sopenharmony_ci * @dns_rdata: The directory server remote port 66162306a36Sopenharmony_ci * @ms_rdata: The management server remote port 66262306a36Sopenharmony_ci * @ptp_rdata: Point to point remote port 66362306a36Sopenharmony_ci * @scsi_priv: FCP layer internal data 66462306a36Sopenharmony_ci * @disc: Discovery context 66562306a36Sopenharmony_ci * @vports: Child vports if N_Port 66662306a36Sopenharmony_ci * @vport: Parent vport if VN_Port 66762306a36Sopenharmony_ci * @tt: Libfc function template 66862306a36Sopenharmony_ci * @link_up: Link state (1 = link up, 0 = link down) 66962306a36Sopenharmony_ci * @qfull: Queue state (1 queue is full, 0 queue is not full) 67062306a36Sopenharmony_ci * @state: Identifies the state 67162306a36Sopenharmony_ci * @boot_time: Timestamp indicating when the local port came online 67262306a36Sopenharmony_ci * @host_stats: SCSI host statistics 67362306a36Sopenharmony_ci * @stats: FC local port stats (TODO separate libfc LLD stats) 67462306a36Sopenharmony_ci * @retry_count: Number of retries in the current state 67562306a36Sopenharmony_ci * @port_id: FC Port ID 67662306a36Sopenharmony_ci * @wwpn: World Wide Port Name 67762306a36Sopenharmony_ci * @wwnn: World Wide Node Name 67862306a36Sopenharmony_ci * @service_params: Common service parameters 67962306a36Sopenharmony_ci * @e_d_tov: Error detection timeout value 68062306a36Sopenharmony_ci * @r_a_tov: Resource allocation timeout value 68162306a36Sopenharmony_ci * @rnid_gen: RNID information 68262306a36Sopenharmony_ci * @sg_supp: Indicates if scatter gather is supported 68362306a36Sopenharmony_ci * @seq_offload: Indicates if sequence offload is supported 68462306a36Sopenharmony_ci * @crc_offload: Indicates if CRC offload is supported 68562306a36Sopenharmony_ci * @lro_enabled: Indicates if large receive offload is supported 68662306a36Sopenharmony_ci * @does_npiv: Supports multiple vports 68762306a36Sopenharmony_ci * @npiv_enabled: Switch/fabric allows NPIV 68862306a36Sopenharmony_ci * @mfs: The maximum Fibre Channel payload size 68962306a36Sopenharmony_ci * @max_retry_count: The maximum retry attempts 69062306a36Sopenharmony_ci * @max_rport_retry_count: The maximum remote port retry attempts 69162306a36Sopenharmony_ci * @rport_priv_size: Size needed by driver after struct fc_rport_priv 69262306a36Sopenharmony_ci * @lro_xid: The maximum XID for LRO 69362306a36Sopenharmony_ci * @lso_max: The maximum large offload send size 69462306a36Sopenharmony_ci * @fcts: FC-4 type mask 69562306a36Sopenharmony_ci * @lp_mutex: Mutex to protect the local port 69662306a36Sopenharmony_ci * @list: Linkage on list of vport peers 69762306a36Sopenharmony_ci * @retry_work: Handle to local port for delayed retry context 69862306a36Sopenharmony_ci * @prov: Pointers available for use by passive FC-4 providers 69962306a36Sopenharmony_ci * @lport_list: Linkage on module-wide list of local ports 70062306a36Sopenharmony_ci */ 70162306a36Sopenharmony_cistruct fc_lport { 70262306a36Sopenharmony_ci /* Associations */ 70362306a36Sopenharmony_ci struct Scsi_Host *host; 70462306a36Sopenharmony_ci struct list_head ema_list; 70562306a36Sopenharmony_ci struct fc_rport_priv *dns_rdata; 70662306a36Sopenharmony_ci struct fc_rport_priv *ms_rdata; 70762306a36Sopenharmony_ci struct fc_rport_priv *ptp_rdata; 70862306a36Sopenharmony_ci void *scsi_priv; 70962306a36Sopenharmony_ci struct fc_disc disc; 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci /* Virtual port information */ 71262306a36Sopenharmony_ci struct list_head vports; 71362306a36Sopenharmony_ci struct fc_vport *vport; 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci /* Operational Information */ 71662306a36Sopenharmony_ci struct libfc_function_template tt; 71762306a36Sopenharmony_ci u8 link_up; 71862306a36Sopenharmony_ci u8 qfull; 71962306a36Sopenharmony_ci u16 vlan; 72062306a36Sopenharmony_ci enum fc_lport_state state; 72162306a36Sopenharmony_ci unsigned long boot_time; 72262306a36Sopenharmony_ci struct fc_host_statistics host_stats; 72362306a36Sopenharmony_ci struct fc_stats __percpu *stats; 72462306a36Sopenharmony_ci u8 retry_count; 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci /* Fabric information */ 72762306a36Sopenharmony_ci u32 port_id; 72862306a36Sopenharmony_ci u64 wwpn; 72962306a36Sopenharmony_ci u64 wwnn; 73062306a36Sopenharmony_ci unsigned int service_params; 73162306a36Sopenharmony_ci unsigned int e_d_tov; 73262306a36Sopenharmony_ci unsigned int r_a_tov; 73362306a36Sopenharmony_ci struct fc_els_rnid_gen rnid_gen; 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci /* Capabilities */ 73662306a36Sopenharmony_ci u32 sg_supp:1; 73762306a36Sopenharmony_ci u32 seq_offload:1; 73862306a36Sopenharmony_ci u32 crc_offload:1; 73962306a36Sopenharmony_ci u32 lro_enabled:1; 74062306a36Sopenharmony_ci u32 does_npiv:1; 74162306a36Sopenharmony_ci u32 npiv_enabled:1; 74262306a36Sopenharmony_ci u32 point_to_multipoint:1; 74362306a36Sopenharmony_ci u32 fdmi_enabled:1; 74462306a36Sopenharmony_ci u32 mfs; 74562306a36Sopenharmony_ci u8 max_retry_count; 74662306a36Sopenharmony_ci u8 max_rport_retry_count; 74762306a36Sopenharmony_ci u16 rport_priv_size; 74862306a36Sopenharmony_ci u16 link_speed; 74962306a36Sopenharmony_ci u16 link_supported_speeds; 75062306a36Sopenharmony_ci u16 lro_xid; 75162306a36Sopenharmony_ci unsigned int lso_max; 75262306a36Sopenharmony_ci struct fc_ns_fts fcts; 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci /* Miscellaneous */ 75562306a36Sopenharmony_ci struct mutex lp_mutex; 75662306a36Sopenharmony_ci struct list_head list; 75762306a36Sopenharmony_ci struct delayed_work retry_work; 75862306a36Sopenharmony_ci void *prov[FC_FC4_PROV_SIZE]; 75962306a36Sopenharmony_ci struct list_head lport_list; 76062306a36Sopenharmony_ci}; 76162306a36Sopenharmony_ci 76262306a36Sopenharmony_ci/** 76362306a36Sopenharmony_ci * struct fc4_prov - FC-4 provider registration 76462306a36Sopenharmony_ci * @prli: Handler for incoming PRLI 76562306a36Sopenharmony_ci * @prlo: Handler for session reset 76662306a36Sopenharmony_ci * @recv: Handler for incoming request 76762306a36Sopenharmony_ci * @module: Pointer to module. May be NULL. 76862306a36Sopenharmony_ci */ 76962306a36Sopenharmony_cistruct fc4_prov { 77062306a36Sopenharmony_ci int (*prli)(struct fc_rport_priv *, u32 spp_len, 77162306a36Sopenharmony_ci const struct fc_els_spp *spp_in, 77262306a36Sopenharmony_ci struct fc_els_spp *spp_out); 77362306a36Sopenharmony_ci void (*prlo)(struct fc_rport_priv *); 77462306a36Sopenharmony_ci void (*recv)(struct fc_lport *, struct fc_frame *); 77562306a36Sopenharmony_ci struct module *module; 77662306a36Sopenharmony_ci}; 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci/* 77962306a36Sopenharmony_ci * Register FC-4 provider with libfc. 78062306a36Sopenharmony_ci */ 78162306a36Sopenharmony_ciint fc_fc4_register_provider(enum fc_fh_type type, struct fc4_prov *); 78262306a36Sopenharmony_civoid fc_fc4_deregister_provider(enum fc_fh_type type, struct fc4_prov *); 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_ci/* 78562306a36Sopenharmony_ci * FC_LPORT HELPER FUNCTIONS 78662306a36Sopenharmony_ci *****************************/ 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci/** 78962306a36Sopenharmony_ci * fc_lport_test_ready() - Determine if a local port is in the READY state 79062306a36Sopenharmony_ci * @lport: The local port to test 79162306a36Sopenharmony_ci */ 79262306a36Sopenharmony_cistatic inline int fc_lport_test_ready(struct fc_lport *lport) 79362306a36Sopenharmony_ci{ 79462306a36Sopenharmony_ci return lport->state == LPORT_ST_READY; 79562306a36Sopenharmony_ci} 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci/** 79862306a36Sopenharmony_ci * fc_set_wwnn() - Set the World Wide Node Name of a local port 79962306a36Sopenharmony_ci * @lport: The local port whose WWNN is to be set 80062306a36Sopenharmony_ci * @wwnn: The new WWNN 80162306a36Sopenharmony_ci */ 80262306a36Sopenharmony_cistatic inline void fc_set_wwnn(struct fc_lport *lport, u64 wwnn) 80362306a36Sopenharmony_ci{ 80462306a36Sopenharmony_ci lport->wwnn = wwnn; 80562306a36Sopenharmony_ci} 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci/** 80862306a36Sopenharmony_ci * fc_set_wwpn() - Set the World Wide Port Name of a local port 80962306a36Sopenharmony_ci * @lport: The local port whose WWPN is to be set 81062306a36Sopenharmony_ci * @wwpn: The new WWPN 81162306a36Sopenharmony_ci */ 81262306a36Sopenharmony_cistatic inline void fc_set_wwpn(struct fc_lport *lport, u64 wwpn) 81362306a36Sopenharmony_ci{ 81462306a36Sopenharmony_ci lport->wwpn = wwpn; 81562306a36Sopenharmony_ci} 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci/** 81862306a36Sopenharmony_ci * fc_lport_state_enter() - Change a local port's state 81962306a36Sopenharmony_ci * @lport: The local port whose state is to change 82062306a36Sopenharmony_ci * @state: The new state 82162306a36Sopenharmony_ci */ 82262306a36Sopenharmony_cistatic inline void fc_lport_state_enter(struct fc_lport *lport, 82362306a36Sopenharmony_ci enum fc_lport_state state) 82462306a36Sopenharmony_ci{ 82562306a36Sopenharmony_ci if (state != lport->state) 82662306a36Sopenharmony_ci lport->retry_count = 0; 82762306a36Sopenharmony_ci lport->state = state; 82862306a36Sopenharmony_ci} 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci/** 83162306a36Sopenharmony_ci * fc_lport_init_stats() - Allocate per-CPU statistics for a local port 83262306a36Sopenharmony_ci * @lport: The local port whose statistics are to be initialized 83362306a36Sopenharmony_ci */ 83462306a36Sopenharmony_cistatic inline int fc_lport_init_stats(struct fc_lport *lport) 83562306a36Sopenharmony_ci{ 83662306a36Sopenharmony_ci lport->stats = alloc_percpu(struct fc_stats); 83762306a36Sopenharmony_ci if (!lport->stats) 83862306a36Sopenharmony_ci return -ENOMEM; 83962306a36Sopenharmony_ci return 0; 84062306a36Sopenharmony_ci} 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci/** 84362306a36Sopenharmony_ci * fc_lport_free_stats() - Free memory for a local port's statistics 84462306a36Sopenharmony_ci * @lport: The local port whose statistics are to be freed 84562306a36Sopenharmony_ci */ 84662306a36Sopenharmony_cistatic inline void fc_lport_free_stats(struct fc_lport *lport) 84762306a36Sopenharmony_ci{ 84862306a36Sopenharmony_ci free_percpu(lport->stats); 84962306a36Sopenharmony_ci} 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_ci/** 85262306a36Sopenharmony_ci * lport_priv() - Return the private data from a local port 85362306a36Sopenharmony_ci * @lport: The local port whose private data is to be retrieved 85462306a36Sopenharmony_ci */ 85562306a36Sopenharmony_cistatic inline void *lport_priv(const struct fc_lport *lport) 85662306a36Sopenharmony_ci{ 85762306a36Sopenharmony_ci return (void *)(lport + 1); 85862306a36Sopenharmony_ci} 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci/** 86162306a36Sopenharmony_ci * libfc_host_alloc() - Allocate a Scsi_Host with room for a local port and 86262306a36Sopenharmony_ci * LLD private data 86362306a36Sopenharmony_ci * @sht: The SCSI host template 86462306a36Sopenharmony_ci * @priv_size: Size of private data 86562306a36Sopenharmony_ci * 86662306a36Sopenharmony_ci * Returns: libfc lport 86762306a36Sopenharmony_ci */ 86862306a36Sopenharmony_cistatic inline struct fc_lport * 86962306a36Sopenharmony_cilibfc_host_alloc(const struct scsi_host_template *sht, int priv_size) 87062306a36Sopenharmony_ci{ 87162306a36Sopenharmony_ci struct fc_lport *lport; 87262306a36Sopenharmony_ci struct Scsi_Host *shost; 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci shost = scsi_host_alloc(sht, sizeof(*lport) + priv_size); 87562306a36Sopenharmony_ci if (!shost) 87662306a36Sopenharmony_ci return NULL; 87762306a36Sopenharmony_ci lport = shost_priv(shost); 87862306a36Sopenharmony_ci lport->host = shost; 87962306a36Sopenharmony_ci INIT_LIST_HEAD(&lport->ema_list); 88062306a36Sopenharmony_ci INIT_LIST_HEAD(&lport->vports); 88162306a36Sopenharmony_ci return lport; 88262306a36Sopenharmony_ci} 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_ci/* 88562306a36Sopenharmony_ci * FC_FCP HELPER FUNCTIONS 88662306a36Sopenharmony_ci *****************************/ 88762306a36Sopenharmony_cistatic inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp) 88862306a36Sopenharmony_ci{ 88962306a36Sopenharmony_ci if (fsp && fsp->cmd) 89062306a36Sopenharmony_ci return fsp->cmd->sc_data_direction == DMA_FROM_DEVICE; 89162306a36Sopenharmony_ci return false; 89262306a36Sopenharmony_ci} 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci/* 89562306a36Sopenharmony_ci * LOCAL PORT LAYER 89662306a36Sopenharmony_ci *****************************/ 89762306a36Sopenharmony_ciint fc_lport_init(struct fc_lport *); 89862306a36Sopenharmony_ciint fc_lport_destroy(struct fc_lport *); 89962306a36Sopenharmony_ciint fc_fabric_logoff(struct fc_lport *); 90062306a36Sopenharmony_ciint fc_fabric_login(struct fc_lport *); 90162306a36Sopenharmony_civoid __fc_linkup(struct fc_lport *); 90262306a36Sopenharmony_civoid fc_linkup(struct fc_lport *); 90362306a36Sopenharmony_civoid __fc_linkdown(struct fc_lport *); 90462306a36Sopenharmony_civoid fc_linkdown(struct fc_lport *); 90562306a36Sopenharmony_civoid fc_vport_setlink(struct fc_lport *); 90662306a36Sopenharmony_civoid fc_vports_linkchange(struct fc_lport *); 90762306a36Sopenharmony_ciint fc_lport_config(struct fc_lport *); 90862306a36Sopenharmony_ciint fc_lport_reset(struct fc_lport *); 90962306a36Sopenharmony_civoid fc_lport_recv(struct fc_lport *lport, struct fc_frame *fp); 91062306a36Sopenharmony_ciint fc_set_mfs(struct fc_lport *, u32 mfs); 91162306a36Sopenharmony_cistruct fc_lport *libfc_vport_create(struct fc_vport *, int privsize); 91262306a36Sopenharmony_cistruct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id); 91362306a36Sopenharmony_ciint fc_lport_bsg_request(struct bsg_job *); 91462306a36Sopenharmony_civoid fc_lport_set_local_id(struct fc_lport *, u32 port_id); 91562306a36Sopenharmony_civoid fc_lport_iterate(void (*func)(struct fc_lport *, void *), void *); 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_ci/* 91862306a36Sopenharmony_ci * REMOTE PORT LAYER 91962306a36Sopenharmony_ci *****************************/ 92062306a36Sopenharmony_civoid fc_rport_terminate_io(struct fc_rport *); 92162306a36Sopenharmony_cistruct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport, 92262306a36Sopenharmony_ci u32 port_id); 92362306a36Sopenharmony_cistruct fc_rport_priv *fc_rport_create(struct fc_lport *, u32); 92462306a36Sopenharmony_civoid fc_rport_destroy(struct kref *kref); 92562306a36Sopenharmony_ciint fc_rport_login(struct fc_rport_priv *rdata); 92662306a36Sopenharmony_ciint fc_rport_logoff(struct fc_rport_priv *rdata); 92762306a36Sopenharmony_civoid fc_rport_recv_req(struct fc_lport *lport, struct fc_frame *fp); 92862306a36Sopenharmony_civoid fc_rport_flush_queue(void); 92962306a36Sopenharmony_ci 93062306a36Sopenharmony_ci/* 93162306a36Sopenharmony_ci * DISCOVERY LAYER 93262306a36Sopenharmony_ci *****************************/ 93362306a36Sopenharmony_civoid fc_disc_init(struct fc_lport *); 93462306a36Sopenharmony_civoid fc_disc_config(struct fc_lport *, void *); 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_cistatic inline struct fc_lport *fc_disc_lport(struct fc_disc *disc) 93762306a36Sopenharmony_ci{ 93862306a36Sopenharmony_ci return container_of(disc, struct fc_lport, disc); 93962306a36Sopenharmony_ci} 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci/* 94262306a36Sopenharmony_ci * FCP LAYER 94362306a36Sopenharmony_ci *****************************/ 94462306a36Sopenharmony_ciint fc_fcp_init(struct fc_lport *); 94562306a36Sopenharmony_civoid fc_fcp_destroy(struct fc_lport *); 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ci/* 94862306a36Sopenharmony_ci * SCSI INTERACTION LAYER 94962306a36Sopenharmony_ci *****************************/ 95062306a36Sopenharmony_ciint fc_queuecommand(struct Scsi_Host *, struct scsi_cmnd *); 95162306a36Sopenharmony_ciint fc_eh_abort(struct scsi_cmnd *); 95262306a36Sopenharmony_ciint fc_eh_device_reset(struct scsi_cmnd *); 95362306a36Sopenharmony_ciint fc_eh_host_reset(struct scsi_cmnd *); 95462306a36Sopenharmony_ciint fc_slave_alloc(struct scsi_device *); 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci/* 95762306a36Sopenharmony_ci * ELS/CT interface 95862306a36Sopenharmony_ci *****************************/ 95962306a36Sopenharmony_ciint fc_elsct_init(struct fc_lport *); 96062306a36Sopenharmony_cistruct fc_seq *fc_elsct_send(struct fc_lport *, u32 did, 96162306a36Sopenharmony_ci struct fc_frame *, 96262306a36Sopenharmony_ci unsigned int op, 96362306a36Sopenharmony_ci void (*resp)(struct fc_seq *, 96462306a36Sopenharmony_ci struct fc_frame *, 96562306a36Sopenharmony_ci void *arg), 96662306a36Sopenharmony_ci void *arg, u32 timer_msec); 96762306a36Sopenharmony_civoid fc_lport_flogi_resp(struct fc_seq *, struct fc_frame *, void *); 96862306a36Sopenharmony_civoid fc_lport_logo_resp(struct fc_seq *, struct fc_frame *, void *); 96962306a36Sopenharmony_civoid fc_fill_reply_hdr(struct fc_frame *, const struct fc_frame *, 97062306a36Sopenharmony_ci enum fc_rctl, u32 parm_offset); 97162306a36Sopenharmony_civoid fc_fill_hdr(struct fc_frame *, const struct fc_frame *, 97262306a36Sopenharmony_ci enum fc_rctl, u32 f_ctl, u16 seq_cnt, u32 parm_offset); 97362306a36Sopenharmony_ci 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci/* 97662306a36Sopenharmony_ci * EXCHANGE MANAGER LAYER 97762306a36Sopenharmony_ci *****************************/ 97862306a36Sopenharmony_ciint fc_exch_init(struct fc_lport *); 97962306a36Sopenharmony_civoid fc_exch_update_stats(struct fc_lport *lport); 98062306a36Sopenharmony_cistruct fc_seq *fc_exch_seq_send(struct fc_lport *lport, 98162306a36Sopenharmony_ci struct fc_frame *fp, 98262306a36Sopenharmony_ci void (*resp)(struct fc_seq *, 98362306a36Sopenharmony_ci struct fc_frame *fp, 98462306a36Sopenharmony_ci void *arg), 98562306a36Sopenharmony_ci void (*destructor)(struct fc_seq *, void *), 98662306a36Sopenharmony_ci void *arg, u32 timer_msec); 98762306a36Sopenharmony_civoid fc_seq_els_rsp_send(struct fc_frame *, enum fc_els_cmd, 98862306a36Sopenharmony_ci struct fc_seq_els_data *); 98962306a36Sopenharmony_cistruct fc_seq *fc_seq_start_next(struct fc_seq *sp); 99062306a36Sopenharmony_civoid fc_seq_set_resp(struct fc_seq *sp, 99162306a36Sopenharmony_ci void (*resp)(struct fc_seq *, struct fc_frame *, void *), 99262306a36Sopenharmony_ci void *arg); 99362306a36Sopenharmony_cistruct fc_seq *fc_seq_assign(struct fc_lport *lport, struct fc_frame *fp); 99462306a36Sopenharmony_civoid fc_seq_release(struct fc_seq *sp); 99562306a36Sopenharmony_cistruct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *, 99662306a36Sopenharmony_ci struct fc_exch_mgr *, 99762306a36Sopenharmony_ci bool (*match)(struct fc_frame *)); 99862306a36Sopenharmony_civoid fc_exch_mgr_del(struct fc_exch_mgr_anchor *); 99962306a36Sopenharmony_ciint fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst); 100062306a36Sopenharmony_cistruct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *, enum fc_class class, 100162306a36Sopenharmony_ci u16 min_xid, u16 max_xid, 100262306a36Sopenharmony_ci bool (*match)(struct fc_frame *)); 100362306a36Sopenharmony_civoid fc_exch_mgr_free(struct fc_lport *); 100462306a36Sopenharmony_civoid fc_exch_recv(struct fc_lport *, struct fc_frame *); 100562306a36Sopenharmony_civoid fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id); 100662306a36Sopenharmony_ciint fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, struct fc_frame *fp); 100762306a36Sopenharmony_ciint fc_seq_exch_abort(const struct fc_seq *, unsigned int timer_msec); 100862306a36Sopenharmony_civoid fc_exch_done(struct fc_seq *sp); 100962306a36Sopenharmony_ci 101062306a36Sopenharmony_ci/* 101162306a36Sopenharmony_ci * Functions for fc_functions_template 101262306a36Sopenharmony_ci */ 101362306a36Sopenharmony_civoid fc_get_host_speed(struct Scsi_Host *); 101462306a36Sopenharmony_civoid fc_get_host_port_state(struct Scsi_Host *); 101562306a36Sopenharmony_civoid fc_set_rport_loss_tmo(struct fc_rport *, u32 timeout); 101662306a36Sopenharmony_cistruct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *); 101762306a36Sopenharmony_ci 101862306a36Sopenharmony_ci#endif /* _LIBFC_H_ */ 1019