/*1* Copyright(c) 2007 Intel Corporation. All rights reserved.2*3* This program is free software; you can redistribute it and/or modify it4* under the terms and conditions of the GNU General Public License,5* version 2, as published by the Free Software Foundation.6*7* This program is distributed in the hope it will be useful, but WITHOUT8* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or9* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for10* more details.11*12* You should have received a copy of the GNU General Public License along with13* this program; if not, write to the Free Software Foundation, Inc.,14* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.15*16* Maintained at www.Open-FCoE.org17*/1819#ifndef _LIBFC_H_20#define _LIBFC_H_2122#include <linux/timer.h>23#include <linux/if.h>24#include <linux/percpu.h>2526#include <scsi/scsi_transport.h>27#include <scsi/scsi_transport_fc.h>28#include <scsi/scsi_bsg_fc.h>2930#include <scsi/fc/fc_fcp.h>31#include <scsi/fc/fc_ns.h>32#include <scsi/fc/fc_els.h>33#include <scsi/fc/fc_gs.h>3435#include <scsi/fc_frame.h>3637#define FC_FC4_PROV_SIZE (FC_TYPE_FCP + 1) /* size of tables */3839/*40* libfc error codes41*/42#define FC_NO_ERR 0 /* no error */43#define FC_EX_TIMEOUT 1 /* Exchange timeout */44#define FC_EX_CLOSED 2 /* Exchange closed */4546/**47* enum fc_lport_state - Local port states48* @LPORT_ST_DISABLED: Disabled49* @LPORT_ST_FLOGI: Fabric login (FLOGI) sent50* @LPORT_ST_DNS: Waiting for name server remote port to become ready51* @LPORT_ST_RPN_ID: Register port name by ID (RPN_ID) sent52* @LPORT_ST_RFT_ID: Register Fibre Channel types by ID (RFT_ID) sent53* @LPORT_ST_RFF_ID: Register FC-4 Features by ID (RFF_ID) sent54* @LPORT_ST_SCR: State Change Register (SCR) sent55* @LPORT_ST_READY: Ready for use56* @LPORT_ST_LOGO: Local port logout (LOGO) sent57* @LPORT_ST_RESET: Local port reset58*/59enum fc_lport_state {60LPORT_ST_DISABLED = 0,61LPORT_ST_FLOGI,62LPORT_ST_DNS,63LPORT_ST_RNN_ID,64LPORT_ST_RSNN_NN,65LPORT_ST_RSPN_ID,66LPORT_ST_RFT_ID,67LPORT_ST_RFF_ID,68LPORT_ST_SCR,69LPORT_ST_READY,70LPORT_ST_LOGO,71LPORT_ST_RESET72};7374enum fc_disc_event {75DISC_EV_NONE = 0,76DISC_EV_SUCCESS,77DISC_EV_FAILED78};7980/**81* enum fc_rport_state - Remote port states82* @RPORT_ST_INIT: Initialized83* @RPORT_ST_FLOGI: Waiting for FLOGI completion for point-to-multipoint84* @RPORT_ST_PLOGI_WAIT: Waiting for peer to login for point-to-multipoint85* @RPORT_ST_PLOGI: Waiting for PLOGI completion86* @RPORT_ST_PRLI: Waiting for PRLI completion87* @RPORT_ST_RTV: Waiting for RTV completion88* @RPORT_ST_READY: Ready for use89* @RPORT_ST_ADISC: Discover Address sent90* @RPORT_ST_DELETE: Remote port being deleted91*/92enum fc_rport_state {93RPORT_ST_INIT,94RPORT_ST_FLOGI,95RPORT_ST_PLOGI_WAIT,96RPORT_ST_PLOGI,97RPORT_ST_PRLI,98RPORT_ST_RTV,99RPORT_ST_READY,100RPORT_ST_ADISC,101RPORT_ST_DELETE,102};103104/**105* struct fc_disc_port - temporary discovery port to hold rport identifiers106* @lp: Fibre Channel host port instance107* @peers: Node for list management during discovery and RSCN processing108* @rport_work: Work struct for starting the rport state machine109* @port_id: Port ID of the discovered port110*/111struct fc_disc_port {112struct fc_lport *lp;113struct list_head peers;114struct work_struct rport_work;115u32 port_id;116};117118/**119* enum fc_rport_event - Remote port events120* @RPORT_EV_NONE: No event121* @RPORT_EV_READY: Remote port is ready for use122* @RPORT_EV_FAILED: State machine failed, remote port is not ready123* @RPORT_EV_STOP: Remote port has been stopped124* @RPORT_EV_LOGO: Remote port logout (LOGO) sent125*/126enum fc_rport_event {127RPORT_EV_NONE = 0,128RPORT_EV_READY,129RPORT_EV_FAILED,130RPORT_EV_STOP,131RPORT_EV_LOGO132};133134struct fc_rport_priv;135136/**137* struct fc_rport_operations - Operations for a remote port138* @event_callback: Function to be called for remote port events139*/140struct fc_rport_operations {141void (*event_callback)(struct fc_lport *, struct fc_rport_priv *,142enum fc_rport_event);143};144145/**146* struct fc_rport_libfc_priv - libfc internal information about a remote port147* @local_port: The associated local port148* @rp_state: Indicates READY for I/O or DELETE when blocked149* @flags: REC and RETRY supported flags150* @e_d_tov: Error detect timeout value (in msec)151* @r_a_tov: Resource allocation timeout value (in msec)152*/153struct fc_rport_libfc_priv {154struct fc_lport *local_port;155enum fc_rport_state rp_state;156u16 flags;157#define FC_RP_FLAGS_REC_SUPPORTED (1 << 0)158#define FC_RP_FLAGS_RETRY (1 << 1)159#define FC_RP_STARTED (1 << 2)160#define FC_RP_FLAGS_CONF_REQ (1 << 3)161unsigned int e_d_tov;162unsigned int r_a_tov;163};164165/**166* struct fc_rport_priv - libfc remote port and discovery info167* @local_port: The associated local port168* @rport: The FC transport remote port169* @kref: Reference counter170* @rp_state: Enumeration that tracks progress of PLOGI, PRLI,171* and RTV exchanges172* @ids: The remote port identifiers and roles173* @flags: STARTED, REC and RETRY_SUPPORTED flags174* @max_seq: Maximum number of concurrent sequences175* @disc_id: The discovery identifier176* @maxframe_size: The maximum frame size177* @retries: The retry count for the current state178* @major_retries: The retry count for the entire PLOGI/PRLI state machine179* @e_d_tov: Error detect timeout value (in msec)180* @r_a_tov: Resource allocation timeout value (in msec)181* @rp_mutex: The mutex that protects the remote port182* @retry_work: Handle for retries183* @event_callback: Callback when READY, FAILED or LOGO states complete184* @prli_count: Count of open PRLI sessions in providers185* @rcu: Structure used for freeing in an RCU-safe manner186*/187struct fc_rport_priv {188struct fc_lport *local_port;189struct fc_rport *rport;190struct kref kref;191enum fc_rport_state rp_state;192struct fc_rport_identifiers ids;193u16 flags;194u16 max_seq;195u16 disc_id;196u16 maxframe_size;197unsigned int retries;198unsigned int major_retries;199unsigned int e_d_tov;200unsigned int r_a_tov;201struct mutex rp_mutex;202struct delayed_work retry_work;203enum fc_rport_event event;204struct fc_rport_operations *ops;205struct list_head peers;206struct work_struct event_work;207u32 supported_classes;208u16 prli_count;209struct rcu_head rcu;210u16 sp_features;211u8 spp_type;212void (*lld_event_callback)(struct fc_lport *,213struct fc_rport_priv *,214enum fc_rport_event);215};216217/**218* struct fcoe_dev_stats - fcoe stats structure219* @SecondsSinceLastReset: Seconds since the last reset220* @TxFrames: Number of transmitted frames221* @TxWords: Number of transmitted words222* @RxFrames: Number of received frames223* @RxWords: Number of received words224* @ErrorFrames: Number of received error frames225* @DumpedFrames: Number of dumped frames226* @LinkFailureCount: Number of link failures227* @LossOfSignalCount: Number for signal losses228* @InvalidTxWordCount: Number of invalid transmitted words229* @InvalidCRCCount: Number of invalid CRCs230* @InputRequests: Number of input requests231* @OutputRequests: Number of output requests232* @ControlRequests: Number of control requests233* @InputBytes: Number of received bytes234* @OutputBytes: Number of transmitted bytes235* @VLinkFailureCount: Number of virtual link failures236* @MissDiscAdvCount: Number of missing FIP discovery advertisement237*/238struct fcoe_dev_stats {239u64 SecondsSinceLastReset;240u64 TxFrames;241u64 TxWords;242u64 RxFrames;243u64 RxWords;244u64 ErrorFrames;245u64 DumpedFrames;246u64 LinkFailureCount;247u64 LossOfSignalCount;248u64 InvalidTxWordCount;249u64 InvalidCRCCount;250u64 InputRequests;251u64 OutputRequests;252u64 ControlRequests;253u64 InputBytes;254u64 OutputBytes;255u64 VLinkFailureCount;256u64 MissDiscAdvCount;257};258259/**260* struct fc_seq_els_data - ELS data used for passing ELS specific responses261* @reason: The reason for rejection262* @explan: The explanation of the rejection263*264* Mainly used by the exchange manager layer.265*/266struct fc_seq_els_data {267enum fc_els_rjt_reason reason;268enum fc_els_rjt_explan explan;269};270271/**272* struct fc_fcp_pkt - FCP request structure (one for each scsi_cmnd request)273* @lp: The associated local port274* @state: The state of the I/O275* @ref_cnt: Reference count276* @scsi_pkt_lock: Lock to protect the SCSI packet (must be taken before the277* host_lock if both are to be held at the same time)278* @cmd: The SCSI command (set and clear with the host_lock held)279* @list: Tracks queued commands (accessed with the host_lock held)280* @timer: The command timer281* @tm_done: Completion indicator282* @wait_for_comp: Indicator to wait for completion of the I/O (in jiffies)283* @start_time: Timestamp indicating the start of the I/O (in jiffies)284* @end_time: Timestamp indicating the end of the I/O (in jiffies)285* @last_pkt_time: Timestamp of the last frame received (in jiffies)286* @data_len: The length of the data287* @cdb_cmd: The CDB command288* @xfer_len: The transfer length289* @xfer_ddp: Indicates if this transfer used DDP (XID of the exchange290* will be set here if DDP was setup)291* @xfer_contig_end: The offset into the buffer if the buffer is contiguous292* (Tx and Rx)293* @max_payload: The maximum payload size (in bytes)294* @io_status: SCSI result (upper 24 bits)295* @cdb_status: CDB status296* @status_code: FCP I/O status297* @scsi_comp_flags: Completion flags (bit 3 Underrun bit 2: overrun)298* @req_flags: Request flags (bit 0: read bit:1 write)299* @scsi_resid: SCSI residule length300* @rport: The remote port that the SCSI command is targeted at301* @seq_ptr: The sequence that will carry the SCSI command302* @recov_retry: Number of recovery retries303* @recov_seq: The sequence for REC or SRR304*/305struct fc_fcp_pkt {306/* Housekeeping information */307struct fc_lport *lp;308u16 state;309atomic_t ref_cnt;310spinlock_t scsi_pkt_lock;311312/* SCSI I/O related information */313struct scsi_cmnd *cmd;314struct list_head list;315316/* Timeout related information */317struct timer_list timer;318struct completion tm_done;319int wait_for_comp;320unsigned long start_time;321unsigned long end_time;322unsigned long last_pkt_time;323324/* SCSI command and data transfer information */325u32 data_len;326327/* Transport related veriables */328struct fcp_cmnd cdb_cmd;329size_t xfer_len;330u16 xfer_ddp;331u32 xfer_contig_end;332u16 max_payload;333334/* SCSI/FCP return status */335u32 io_status;336u8 cdb_status;337u8 status_code;338u8 scsi_comp_flags;339u32 req_flags;340u32 scsi_resid;341342/* Associated structures */343struct fc_rport *rport;344struct fc_seq *seq_ptr;345346/* Error Processing information */347u8 recov_retry;348struct fc_seq *recov_seq;349};350351/*352* Structure and function definitions for managing Fibre Channel Exchanges353* and Sequences354*355* fc_exch holds state for one exchange and links to its active sequence.356*357* fc_seq holds the state for an individual sequence.358*/359360struct fc_exch_mgr;361struct fc_exch_mgr_anchor;362extern u16 fc_cpu_mask; /* cpu mask for possible cpus */363364/**365* struct fc_seq - FC sequence366* @id: The sequence ID367* @ssb_stat: Status flags for the sequence status block (SSB)368* @cnt: Number of frames sent so far369* @rec_data: FC-4 value for REC370*/371struct fc_seq {372u8 id;373u16 ssb_stat;374u16 cnt;375u32 rec_data;376};377378#define FC_EX_DONE (1 << 0) /* ep is completed */379#define FC_EX_RST_CLEANUP (1 << 1) /* reset is forcing completion */380381/**382* struct fc_exch - Fibre Channel Exchange383* @em: Exchange manager384* @pool: Exchange pool385* @state: The exchange's state386* @xid: The exchange ID387* @ex_list: Handle used by the EM to track free exchanges388* @ex_lock: Lock that protects the exchange389* @ex_refcnt: Reference count390* @timeout_work: Handle for timeout handler391* @lp: The local port that this exchange is on392* @oxid: Originator's exchange ID393* @rxid: Responder's exchange ID394* @oid: Originator's FCID395* @sid: Source FCID396* @did: Destination FCID397* @esb_stat: ESB exchange status398* @r_a_tov: Resouce allocation time out value (in msecs)399* @seq_id: The next sequence ID to use400* @encaps: encapsulation information for lower-level driver401* @f_ctl: F_CTL flags for the sequence402* @fh_type: The frame type403* @class: The class of service404* @seq: The sequence in use on this exchange405* @resp: Callback for responses on this exchange406* @destructor: Called when destroying the exchange407* @arg: Passed as a void pointer to the resp() callback408*409* Locking notes: The ex_lock protects following items:410* state, esb_stat, f_ctl, seq.ssb_stat411* seq_id412* sequence allocation413*/414struct fc_exch {415struct fc_exch_mgr *em;416struct fc_exch_pool *pool;417u32 state;418u16 xid;419struct list_head ex_list;420spinlock_t ex_lock;421atomic_t ex_refcnt;422struct delayed_work timeout_work;423struct fc_lport *lp;424u16 oxid;425u16 rxid;426u32 oid;427u32 sid;428u32 did;429u32 esb_stat;430u32 r_a_tov;431u8 seq_id;432u8 encaps;433u32 f_ctl;434u8 fh_type;435enum fc_class class;436struct fc_seq seq;437438void (*resp)(struct fc_seq *, struct fc_frame *, void *);439void *arg;440441void (*destructor)(struct fc_seq *, void *);442443};444#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)445446447struct libfc_function_template {448/*449* Interface to send a FC frame450*451* STATUS: REQUIRED452*/453int (*frame_send)(struct fc_lport *, struct fc_frame *);454455/*456* Interface to send ELS/CT frames457*458* STATUS: OPTIONAL459*/460struct fc_seq *(*elsct_send)(struct fc_lport *, u32 did,461struct fc_frame *, unsigned int op,462void (*resp)(struct fc_seq *,463struct fc_frame *, void *arg),464void *arg, u32 timer_msec);465466/*467* Send the FC frame payload using a new exchange and sequence.468*469* The exchange response handler is set in this routine to resp()470* function pointer. It can be called in two scenarios: if a timeout471* occurs or if a response frame is received for the exchange. The472* fc_frame pointer in response handler will also indicate timeout473* as error using IS_ERR related macros.474*475* The exchange destructor handler is also set in this routine.476* The destructor handler is invoked by EM layer when exchange477* is about to free, this can be used by caller to free its478* resources along with exchange free.479*480* The arg is passed back to resp and destructor handler.481*482* The timeout value (in msec) for an exchange is set if non zero483* timer_msec argument is specified. The timer is canceled when484* it fires or when the exchange is done. The exchange timeout handler485* is registered by EM layer.486*487* STATUS: OPTIONAL488*/489struct fc_seq *(*exch_seq_send)(struct fc_lport *, struct fc_frame *,490void (*resp)(struct fc_seq *,491struct fc_frame *,492void *),493void (*destructor)(struct fc_seq *,494void *),495void *, unsigned int timer_msec);496497/*498* Sets up the DDP context for a given exchange id on the given499* scatterlist if LLD supports DDP for large receive.500*501* STATUS: OPTIONAL502*/503int (*ddp_setup)(struct fc_lport *, u16, struct scatterlist *,504unsigned int);505/*506* Completes the DDP transfer and returns the length of data DDPed507* for the given exchange id.508*509* STATUS: OPTIONAL510*/511int (*ddp_done)(struct fc_lport *, u16);512/*513* Allow LLD to fill its own Link Error Status Block514*515* STATUS: OPTIONAL516*/517void (*get_lesb)(struct fc_lport *, struct fc_els_lesb *lesb);518/*519* Send a frame using an existing sequence and exchange.520*521* STATUS: OPTIONAL522*/523int (*seq_send)(struct fc_lport *, struct fc_seq *,524struct fc_frame *);525526/*527* Send an ELS response using information from the received frame.528*529* STATUS: OPTIONAL530*/531void (*seq_els_rsp_send)(struct fc_frame *, enum fc_els_cmd,532struct fc_seq_els_data *);533534/*535* Abort an exchange and sequence. Generally called because of a536* exchange timeout or an abort from the upper layer.537*538* A timer_msec can be specified for abort timeout, if non-zero539* timer_msec value is specified then exchange resp handler540* will be called with timeout error if no response to abort.541*542* STATUS: OPTIONAL543*/544int (*seq_exch_abort)(const struct fc_seq *,545unsigned int timer_msec);546547/*548* Indicate that an exchange/sequence tuple is complete and the memory549* allocated for the related objects may be freed.550*551* STATUS: OPTIONAL552*/553void (*exch_done)(struct fc_seq *);554555/*556* Start a new sequence on the same exchange/sequence tuple.557*558* STATUS: OPTIONAL559*/560struct fc_seq *(*seq_start_next)(struct fc_seq *);561562/*563* Set a response handler for the exchange of the sequence.564*565* STATUS: OPTIONAL566*/567void (*seq_set_resp)(struct fc_seq *sp,568void (*resp)(struct fc_seq *, struct fc_frame *,569void *),570void *arg);571572/*573* Assign a sequence for an incoming request frame.574*575* STATUS: OPTIONAL576*/577struct fc_seq *(*seq_assign)(struct fc_lport *, struct fc_frame *);578579/*580* Release the reference on the sequence returned by seq_assign().581*582* STATUS: OPTIONAL583*/584void (*seq_release)(struct fc_seq *);585586/*587* Reset an exchange manager, completing all sequences and exchanges.588* If s_id is non-zero, reset only exchanges originating from that FID.589* If d_id is non-zero, reset only exchanges sending to that FID.590*591* STATUS: OPTIONAL592*/593void (*exch_mgr_reset)(struct fc_lport *, u32 s_id, u32 d_id);594595/*596* Flush the rport work queue. Generally used before shutdown.597*598* STATUS: OPTIONAL599*/600void (*rport_flush_queue)(void);601602/*603* Receive a frame for a local port.604*605* STATUS: OPTIONAL606*/607void (*lport_recv)(struct fc_lport *, struct fc_frame *);608609/*610* Reset the local port.611*612* STATUS: OPTIONAL613*/614int (*lport_reset)(struct fc_lport *);615616/*617* Set the local port FC_ID.618*619* This may be provided by the LLD to allow it to be620* notified when the local port is assigned a FC-ID.621*622* The frame, if non-NULL, is the incoming frame with the623* FLOGI LS_ACC or FLOGI, and may contain the granted MAC624* address for the LLD. The frame pointer may be NULL if625* no MAC is associated with this assignment (LOGO or PLOGI).626*627* If FC_ID is non-zero, r_a_tov and e_d_tov must be valid.628*629* Note: this is called with the local port mutex held.630*631* STATUS: OPTIONAL632*/633void (*lport_set_port_id)(struct fc_lport *, u32 port_id,634struct fc_frame *);635636/*637* Create a remote port with a given port ID638*639* STATUS: OPTIONAL640*/641struct fc_rport_priv *(*rport_create)(struct fc_lport *, u32);642643/*644* Initiates the RP state machine. It is called from the LP module.645* This function will issue the following commands to the N_Port646* identified by the FC ID provided.647*648* - PLOGI649* - PRLI650* - RTV651*652* STATUS: OPTIONAL653*/654int (*rport_login)(struct fc_rport_priv *);655656/*657* Logoff, and remove the rport from the transport if658* it had been added. This will send a LOGO to the target.659*660* STATUS: OPTIONAL661*/662int (*rport_logoff)(struct fc_rport_priv *);663664/*665* Receive a request from a remote port.666*667* STATUS: OPTIONAL668*/669void (*rport_recv_req)(struct fc_lport *, struct fc_frame *);670671/*672* lookup an rport by it's port ID.673*674* STATUS: OPTIONAL675*/676struct fc_rport_priv *(*rport_lookup)(const struct fc_lport *, u32);677678/*679* Destroy an rport after final kref_put().680* The argument is a pointer to the kref inside the fc_rport_priv.681*/682void (*rport_destroy)(struct kref *);683684/*685* Callback routine after the remote port is logged in686*687* STATUS: OPTIONAL688*/689void (*rport_event_callback)(struct fc_lport *,690struct fc_rport_priv *,691enum fc_rport_event);692693/*694* Send a fcp cmd from fsp pkt.695* Called with the SCSI host lock unlocked and irqs disabled.696*697* The resp handler is called when FCP_RSP received.698*699* STATUS: OPTIONAL700*/701int (*fcp_cmd_send)(struct fc_lport *, struct fc_fcp_pkt *,702void (*resp)(struct fc_seq *, struct fc_frame *,703void *));704705/*706* Cleanup the FCP layer, used during link down and reset707*708* STATUS: OPTIONAL709*/710void (*fcp_cleanup)(struct fc_lport *);711712/*713* Abort all I/O on a local port714*715* STATUS: OPTIONAL716*/717void (*fcp_abort_io)(struct fc_lport *);718719/*720* Receive a request for the discovery layer.721*722* STATUS: OPTIONAL723*/724void (*disc_recv_req)(struct fc_lport *, struct fc_frame *);725726/*727* Start discovery for a local port.728*729* STATUS: OPTIONAL730*/731void (*disc_start)(void (*disc_callback)(struct fc_lport *,732enum fc_disc_event),733struct fc_lport *);734735/*736* Stop discovery for a given lport. This will remove737* all discovered rports738*739* STATUS: OPTIONAL740*/741void (*disc_stop) (struct fc_lport *);742743/*744* Stop discovery for a given lport. This will block745* until all discovered rports are deleted from the746* FC transport class747*748* STATUS: OPTIONAL749*/750void (*disc_stop_final) (struct fc_lport *);751};752753/**754* struct fc_disc - Discovery context755* @retry_count: Number of retries756* @pending: 1 if discovery is pending, 0 if not757* @requested: 1 if discovery has been requested, 0 if not758* @seq_count: Number of sequences used for discovery759* @buf_len: Length of the discovery buffer760* @disc_id: Discovery ID761* @rports: List of discovered remote ports762* @priv: Private pointer for use by discovery code763* @disc_mutex: Mutex that protects the discovery context764* @partial_buf: Partial name buffer (if names are returned765* in multiple frames)766* @disc_work: handle for delayed work context767* @disc_callback: Callback routine called when discovery completes768*/769struct fc_disc {770unsigned char retry_count;771unsigned char pending;772unsigned char requested;773unsigned short seq_count;774unsigned char buf_len;775u16 disc_id;776777struct list_head rports;778void *priv;779struct mutex disc_mutex;780struct fc_gpn_ft_resp partial_buf;781struct delayed_work disc_work;782783void (*disc_callback)(struct fc_lport *,784enum fc_disc_event);785};786787/*788* Local port notifier and events.789*/790extern struct blocking_notifier_head fc_lport_notifier_head;791enum fc_lport_event {792FC_LPORT_EV_ADD,793FC_LPORT_EV_DEL,794};795796/**797* struct fc_lport - Local port798* @host: The SCSI host associated with a local port799* @ema_list: Exchange manager anchor list800* @dns_rdata: The directory server remote port801* @ptp_rdata: Point to point remote port802* @scsi_priv: FCP layer internal data803* @disc: Discovery context804* @vports: Child vports if N_Port805* @vport: Parent vport if VN_Port806* @tt: Libfc function template807* @link_up: Link state (1 = link up, 0 = link down)808* @qfull: Queue state (1 queue is full, 0 queue is not full)809* @state: Identifies the state810* @boot_time: Timestamp indicating when the local port came online811* @host_stats: SCSI host statistics812* @dev_stats: FCoE device stats (TODO: libfc should not be813* FCoE aware)814* @retry_count: Number of retries in the current state815* @port_id: FC Port ID816* @wwpn: World Wide Port Name817* @wwnn: World Wide Node Name818* @service_params: Common service parameters819* @e_d_tov: Error detection timeout value820* @r_a_tov: Resouce allocation timeout value821* @rnid_gen: RNID information822* @sg_supp: Indicates if scatter gather is supported823* @seq_offload: Indicates if sequence offload is supported824* @crc_offload: Indicates if CRC offload is supported825* @lro_enabled: Indicates if large receive offload is supported826* @does_npiv: Supports multiple vports827* @npiv_enabled: Switch/fabric allows NPIV828* @mfs: The maximum Fibre Channel payload size829* @max_retry_count: The maximum retry attempts830* @max_rport_retry_count: The maximum remote port retry attempts831* @rport_priv_size: Size needed by driver after struct fc_rport_priv832* @lro_xid: The maximum XID for LRO833* @lso_max: The maximum large offload send size834* @fcts: FC-4 type mask835* @lp_mutex: Mutex to protect the local port836* @list: Linkage on list of vport peers837* @retry_work: Handle to local port for delayed retry context838* @prov: Pointers available for use by passive FC-4 providers839* @lport_list: Linkage on module-wide list of local ports840*/841struct fc_lport {842/* Associations */843struct Scsi_Host *host;844struct list_head ema_list;845struct fc_rport_priv *dns_rdata;846struct fc_rport_priv *ptp_rdata;847void *scsi_priv;848struct fc_disc disc;849850/* Virtual port information */851struct list_head vports;852struct fc_vport *vport;853854/* Operational Information */855struct libfc_function_template tt;856u8 link_up;857u8 qfull;858enum fc_lport_state state;859unsigned long boot_time;860struct fc_host_statistics host_stats;861struct fcoe_dev_stats *dev_stats;862u8 retry_count;863864/* Fabric information */865u32 port_id;866u64 wwpn;867u64 wwnn;868unsigned int service_params;869unsigned int e_d_tov;870unsigned int r_a_tov;871struct fc_els_rnid_gen rnid_gen;872873/* Capabilities */874u32 sg_supp:1;875u32 seq_offload:1;876u32 crc_offload:1;877u32 lro_enabled:1;878u32 does_npiv:1;879u32 npiv_enabled:1;880u32 point_to_multipoint:1;881u32 mfs;882u8 max_retry_count;883u8 max_rport_retry_count;884u16 rport_priv_size;885u16 link_speed;886u16 link_supported_speeds;887u16 lro_xid;888unsigned int lso_max;889struct fc_ns_fts fcts;890891/* Miscellaneous */892struct mutex lp_mutex;893struct list_head list;894struct delayed_work retry_work;895void *prov[FC_FC4_PROV_SIZE];896struct list_head lport_list;897};898899/**900* struct fc4_prov - FC-4 provider registration901* @prli: Handler for incoming PRLI902* @prlo: Handler for session reset903* @recv: Handler for incoming request904* @module: Pointer to module. May be NULL.905*/906struct fc4_prov {907int (*prli)(struct fc_rport_priv *, u32 spp_len,908const struct fc_els_spp *spp_in,909struct fc_els_spp *spp_out);910void (*prlo)(struct fc_rport_priv *);911void (*recv)(struct fc_lport *, struct fc_frame *);912struct module *module;913};914915/*916* Register FC-4 provider with libfc.917*/918int fc_fc4_register_provider(enum fc_fh_type type, struct fc4_prov *);919void fc_fc4_deregister_provider(enum fc_fh_type type, struct fc4_prov *);920921/*922* FC_LPORT HELPER FUNCTIONS923*****************************/924925/**926* fc_lport_test_ready() - Determine if a local port is in the READY state927* @lport: The local port to test928*/929static inline int fc_lport_test_ready(struct fc_lport *lport)930{931return lport->state == LPORT_ST_READY;932}933934/**935* fc_set_wwnn() - Set the World Wide Node Name of a local port936* @lport: The local port whose WWNN is to be set937* @wwnn: The new WWNN938*/939static inline void fc_set_wwnn(struct fc_lport *lport, u64 wwnn)940{941lport->wwnn = wwnn;942}943944/**945* fc_set_wwpn() - Set the World Wide Port Name of a local port946* @lport: The local port whose WWPN is to be set947* @wwnn: The new WWPN948*/949static inline void fc_set_wwpn(struct fc_lport *lport, u64 wwnn)950{951lport->wwpn = wwnn;952}953954/**955* fc_lport_state_enter() - Change a local port's state956* @lport: The local port whose state is to change957* @state: The new state958*/959static inline void fc_lport_state_enter(struct fc_lport *lport,960enum fc_lport_state state)961{962if (state != lport->state)963lport->retry_count = 0;964lport->state = state;965}966967/**968* fc_lport_init_stats() - Allocate per-CPU statistics for a local port969* @lport: The local port whose statistics are to be initialized970*/971static inline int fc_lport_init_stats(struct fc_lport *lport)972{973lport->dev_stats = alloc_percpu(struct fcoe_dev_stats);974if (!lport->dev_stats)975return -ENOMEM;976return 0;977}978979/**980* fc_lport_free_stats() - Free memory for a local port's statistics981* @lport: The local port whose statistics are to be freed982*/983static inline void fc_lport_free_stats(struct fc_lport *lport)984{985free_percpu(lport->dev_stats);986}987988/**989* lport_priv() - Return the private data from a local port990* @lport: The local port whose private data is to be retreived991*/992static inline void *lport_priv(const struct fc_lport *lport)993{994return (void *)(lport + 1);995}996997/**998* libfc_host_alloc() - Allocate a Scsi_Host with room for a local port and999* LLD private data1000* @sht: The SCSI host template1001* @priv_size: Size of private data1002*1003* Returns: libfc lport1004*/1005static inline struct fc_lport *1006libfc_host_alloc(struct scsi_host_template *sht, int priv_size)1007{1008struct fc_lport *lport;1009struct Scsi_Host *shost;10101011shost = scsi_host_alloc(sht, sizeof(*lport) + priv_size);1012if (!shost)1013return NULL;1014lport = shost_priv(shost);1015lport->host = shost;1016INIT_LIST_HEAD(&lport->ema_list);1017INIT_LIST_HEAD(&lport->vports);1018return lport;1019}10201021/*1022* FC_FCP HELPER FUNCTIONS1023*****************************/1024static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp)1025{1026if (fsp && fsp->cmd)1027return fsp->cmd->sc_data_direction == DMA_FROM_DEVICE;1028return false;1029}10301031/*1032* LOCAL PORT LAYER1033*****************************/1034int fc_lport_init(struct fc_lport *);1035int fc_lport_destroy(struct fc_lport *);1036int fc_fabric_logoff(struct fc_lport *);1037int fc_fabric_login(struct fc_lport *);1038void __fc_linkup(struct fc_lport *);1039void fc_linkup(struct fc_lport *);1040void __fc_linkdown(struct fc_lport *);1041void fc_linkdown(struct fc_lport *);1042void fc_vport_setlink(struct fc_lport *);1043void fc_vports_linkchange(struct fc_lport *);1044int fc_lport_config(struct fc_lport *);1045int fc_lport_reset(struct fc_lport *);1046int fc_set_mfs(struct fc_lport *, u32 mfs);1047struct fc_lport *libfc_vport_create(struct fc_vport *, int privsize);1048struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id);1049int fc_lport_bsg_request(struct fc_bsg_job *);1050void fc_lport_set_local_id(struct fc_lport *, u32 port_id);1051void fc_lport_iterate(void (*func)(struct fc_lport *, void *), void *);10521053/*1054* REMOTE PORT LAYER1055*****************************/1056int fc_rport_init(struct fc_lport *);1057void fc_rport_terminate_io(struct fc_rport *);10581059/*1060* DISCOVERY LAYER1061*****************************/1062int fc_disc_init(struct fc_lport *);10631064static inline struct fc_lport *fc_disc_lport(struct fc_disc *disc)1065{1066return container_of(disc, struct fc_lport, disc);1067}10681069/*1070* FCP LAYER1071*****************************/1072int fc_fcp_init(struct fc_lport *);1073void fc_fcp_destroy(struct fc_lport *);10741075/*1076* SCSI INTERACTION LAYER1077*****************************/1078int fc_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);1079int fc_eh_abort(struct scsi_cmnd *);1080int fc_eh_device_reset(struct scsi_cmnd *);1081int fc_eh_host_reset(struct scsi_cmnd *);1082int fc_slave_alloc(struct scsi_device *);1083int fc_change_queue_depth(struct scsi_device *, int qdepth, int reason);1084int fc_change_queue_type(struct scsi_device *, int tag_type);10851086/*1087* ELS/CT interface1088*****************************/1089int fc_elsct_init(struct fc_lport *);1090struct fc_seq *fc_elsct_send(struct fc_lport *, u32 did,1091struct fc_frame *,1092unsigned int op,1093void (*resp)(struct fc_seq *,1094struct fc_frame *,1095void *arg),1096void *arg, u32 timer_msec);1097void fc_lport_flogi_resp(struct fc_seq *, struct fc_frame *, void *);1098void fc_lport_logo_resp(struct fc_seq *, struct fc_frame *, void *);1099void fc_fill_reply_hdr(struct fc_frame *, const struct fc_frame *,1100enum fc_rctl, u32 parm_offset);1101void fc_fill_hdr(struct fc_frame *, const struct fc_frame *,1102enum fc_rctl, u32 f_ctl, u16 seq_cnt, u32 parm_offset);110311041105/*1106* EXCHANGE MANAGER LAYER1107*****************************/1108int fc_exch_init(struct fc_lport *);1109struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *,1110struct fc_exch_mgr *,1111bool (*match)(struct fc_frame *));1112void fc_exch_mgr_del(struct fc_exch_mgr_anchor *);1113int fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst);1114struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *, enum fc_class class,1115u16 min_xid, u16 max_xid,1116bool (*match)(struct fc_frame *));1117void fc_exch_mgr_free(struct fc_lport *);1118void fc_exch_recv(struct fc_lport *, struct fc_frame *);1119void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id);11201121/*1122* Functions for fc_functions_template1123*/1124void fc_get_host_speed(struct Scsi_Host *);1125void fc_get_host_port_state(struct Scsi_Host *);1126void fc_set_rport_loss_tmo(struct fc_rport *, u32 timeout);1127struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *);11281129#endif /* _LIBFC_H_ */113011311132