iPXE
fcels.h
Go to the documentation of this file.
00001 #ifndef _IPXE_FCELS_H
00002 #define _IPXE_FCELS_H
00003 
00004 /**
00005  * @file
00006  *
00007  * Fibre Channel Extended Link Services
00008  *
00009  */
00010 
00011 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00012 
00013 #include <stdint.h>
00014 #include <ipxe/fc.h>
00015 #include <ipxe/tables.h>
00016 #include <ipxe/refcnt.h>
00017 #include <ipxe/list.h>
00018 #include <ipxe/process.h>
00019 #include <ipxe/interface.h>
00020 
00021 /** Fibre Channel ELS frame common parameters */
00022 struct fc_els_frame_common {
00023         /** ELS command code */
00024         uint8_t command;
00025         /** Reserved */
00026         uint8_t reserved[3];
00027 } __attribute__ (( packed ));
00028 
00029 /** Fibre Channel ELS command codes */
00030 enum fc_els_command_code {
00031         FC_ELS_LS_RJT = 0x01,           /**< Link Service Reject */
00032         FC_ELS_LS_ACC = 0x02,           /**< Link Service Accept */
00033         FC_ELS_PLOGI = 0x03,            /**< Port Login */
00034         FC_ELS_FLOGI = 0x04,            /**< Fabric Login */
00035         FC_ELS_LOGO = 0x05,             /**< Logout */
00036         FC_ELS_RTV = 0x0e,              /**< Read Timeout Value */
00037         FC_ELS_ECHO = 0x10,             /**< Echo */
00038         FC_ELS_PRLI = 0x20,             /**< Process Login */
00039         FC_ELS_PRLO = 0x21,             /**< Process Logout */
00040 };
00041 
00042 /** A Fibre Channel LS_RJT frame */
00043 struct fc_ls_rjt_frame {
00044         /** ELS command code */
00045         uint8_t command;
00046         /** Reserved */
00047         uint8_t reserved[4];
00048         /** Reason code */
00049         uint8_t reason;
00050         /** Reason code explanation */
00051         uint8_t explanation;
00052         /** Vendor unique */
00053         uint8_t vendor;
00054 } __attribute__ (( packed ));
00055 
00056 /** Fibre Channel ELS rejection reason codes */
00057 enum fc_els_reject_reason {
00058         /** Invalid ELS command code */
00059         FC_ELS_RJT_INVALID_COMMAND = 0x01,
00060         /** Logical error */
00061         FC_ELS_RJT_ILLOGICAL = 0x03,
00062         /** Logical busy */
00063         FC_ELS_RJT_BUSY = 0x05,
00064         /** Protocol error */
00065         FC_ELS_RJT_PROTOCOL = 0x07,
00066         /** Unable to perform command request */
00067         FC_ELS_RJT_UNABLE = 0x09,
00068         /** Command not supported */
00069         FC_ELS_RJT_UNSUPPORTED = 0x0b,
00070         /** Command already in progress */
00071         FC_ELS_RJT_IN_PROGRESS = 0x0e,
00072 };
00073 
00074 /** Fibre Channel "common" service parameters */
00075 struct fc_login_common {
00076         /** Login version */
00077         uint16_t version;
00078         /** Buffer-to-buffer credit */
00079         uint16_t credit;
00080         /** Flags */
00081         uint16_t flags;
00082         /** Receive size */
00083         uint16_t mtu;
00084         /** "Common"?! */
00085         union {
00086                 struct {
00087                         /** Maximum number of concurrent sequences */
00088                         uint16_t max_seq;
00089                         /** Relative offset by info category */
00090                         uint16_t rel_offs;
00091                 } plogi;
00092                 struct {
00093                         /** Resource allocation timeout value */
00094                         uint32_t r_a_tov;
00095                 } flogi;
00096         } u;
00097         /** Error detection timeout value */
00098         uint32_t e_d_tov;
00099 } __attribute__ (( packed ));
00100 
00101 /** Fibre Channel default login version */
00102 #define FC_LOGIN_VERSION 0x2020
00103 
00104 /** Fibre Channel default buffer-to-buffer credit */
00105 #define FC_LOGIN_DEFAULT_B2B 10
00106 
00107 /** Continuously increasing relative offset */
00108 #define FC_LOGIN_CONTINUOUS_OFFSET 0x8000
00109 
00110 /** Clean address */
00111 #define FC_LOGIN_CLEAN 0x8000
00112 
00113 /** Multiple N_Port_ID support */
00114 #define FC_LOGIN_MULTI_N 0x8000
00115 
00116 /** Random relative offset */
00117 #define FC_LOGIN_RANDOM_OFFSET 0x4000
00118 
00119 /** Virtual fabrics */
00120 #define FC_LOGIN_VIRTUAL 0x4000
00121 
00122 /** Vendor version level */
00123 #define FC_LOGIN_VENDOR 0x2000
00124 
00125 /** Multiple N_Port_ID support */
00126 #define FC_LOGIN_MULTI_F 0x2000
00127 
00128 /** Forwarder port */
00129 #define FC_LOGIN_F_PORT 0x1000
00130 
00131 /** Alternative credit management */
00132 #define FC_LOGIN_ALT_CREDIT 0x0800
00133 
00134 /** Name server session started */
00135 #define FC_LOGIN_NSS_STARTED 0x0800
00136 
00137 /** Begin name server session */
00138 #define FC_LOGIN_NSS_BEGIN 0x0400
00139 
00140 /** 1ns error detection timer resolution */
00141 #define FC_LOGIN_HIRES_E_D_TOV 0x0400
00142 
00143 /** Broadcast supported */
00144 #define FC_LOGIN_BROADCAST 0x0100
00145 
00146 /** Query buffer conditions */
00147 #define FC_LOGIN_QUERY_BUF 0x0040
00148 
00149 /** Security */
00150 #define FC_LOGIN_SECURITY 0x0020
00151 
00152 /** Clock sync primitive capable */
00153 #define FC_LOGIN_CLOCK_SYNC 0x0010
00154 
00155 /** Short R_T timeout */
00156 #define FC_LOGIN_SHORT_R_T_TOV 0x0008
00157 
00158 /** Dynamic half duplex */
00159 #define FC_LOGIN_DHD 0x0004
00160 
00161 /** Continuously increasing sequence count */
00162 #define FC_LOGIN_CONTINUOUS_SEQ 0x0002
00163 
00164 /** Payload */
00165 #define FC_LOGIN_PAYLOAD 0x0001
00166 
00167 /** Fibre Channel default MTU */
00168 #define FC_LOGIN_DEFAULT_MTU 1452
00169 
00170 /** Default maximum number of concurrent sequences */
00171 #define FC_LOGIN_DEFAULT_MAX_SEQ 255
00172 
00173 /** Default relative offset by info category */
00174 #define FC_LOGIN_DEFAULT_REL_OFFS 0x1f
00175 
00176 /** Default E_D timeout value */
00177 #define FC_LOGIN_DEFAULT_E_D_TOV 2000
00178 
00179 /** Fibre Channel class-specific login parameters */
00180 struct fc_login_class {
00181         /** Flags */
00182         uint16_t flags;
00183         /** Initiator flags */
00184         uint16_t init_flags;
00185         /** Recipient flags */
00186         uint16_t recip_flags;
00187         /** Receive data field size */
00188         uint16_t mtu;
00189         /** Maximum number of concurrent sequences */
00190         uint16_t max_seq;
00191         /** End-to-end credit */
00192         uint16_t credit;
00193         /** Reserved */
00194         uint8_t reserved0;
00195         /** Maximum number of open sequences per exchange */
00196         uint8_t max_seq_per_xchg;
00197         /** Reserved */
00198         uint8_t reserved1[2];
00199 } __attribute__ (( packed ));
00200 
00201 /** Class valid */
00202 #define FC_LOGIN_CLASS_VALID 0x8000
00203 
00204 /** Sequential delivery requested */
00205 #define FC_LOGIN_CLASS_SEQUENTIAL 0x0800
00206 
00207 /** A Fibre Channel FLOGI/PLOGI frame */
00208 struct fc_login_frame {
00209         /** ELS command code */
00210         uint8_t command;
00211         /** Reserved */
00212         uint8_t reserved[3];
00213         /** Common service parameters */
00214         struct fc_login_common common;
00215         /** Port name */
00216         struct fc_name port_wwn;
00217         /** Node name */
00218         struct fc_name node_wwn;
00219         /** Class 1 service parameters */
00220         struct fc_login_class class1;
00221         /** Class 2 service parameters */
00222         struct fc_login_class class2;
00223         /** Class 3 service parameters */
00224         struct fc_login_class class3;
00225         /** Class 4 service parameters */
00226         struct fc_login_class class4;
00227         /** Vendor version level */
00228         uint8_t vendor_version[16];
00229 } __attribute__ (( packed ));
00230 
00231 /** A Fibre Channel LOGO request frame */
00232 struct fc_logout_request_frame {
00233         /** ELS command code */
00234         uint8_t command;
00235         /** Reserved */
00236         uint8_t reserved[4];
00237         /** Port ID */
00238         struct fc_port_id port_id;
00239         /** Port name */
00240         struct fc_name port_wwn;
00241 } __attribute__ (( packed ));
00242 
00243 /** A Fibre Channel LOGO response frame */
00244 struct fc_logout_response_frame {
00245         /** ELS command code */
00246         uint8_t command;
00247         /** Reserved */
00248         uint8_t reserved[3];
00249 } __attribute__ (( packed ));
00250 
00251 /** A Fibre Channel PRLI service parameter page */
00252 struct fc_prli_page {
00253         /** Type code */
00254         uint8_t type;
00255         /** Type code extension */
00256         uint8_t type_ext;
00257         /** Flags and response code */
00258         uint16_t flags;
00259         /** Reserved */
00260         uint32_t reserved[2];
00261 } __attribute__ (( packed ));
00262 
00263 /** Establish image pair */
00264 #define FC_PRLI_ESTABLISH 0x2000
00265 
00266 /** Response code mask */
00267 #define FC_PRLI_RESPONSE_MASK 0x0f00
00268 
00269 /** Request was executed successfully */
00270 #define FC_PRLI_RESPONSE_SUCCESS 0x0100
00271 
00272 /** A Fibre Channel PRLI frame */
00273 struct fc_prli_frame {
00274         /** ELS command code */
00275         uint8_t command;
00276         /** Page length */
00277         uint8_t page_len;
00278         /** Payload length */
00279         uint16_t len;
00280         /** Service parameter page */
00281         struct fc_prli_page page;
00282 } __attribute__ (( packed ));
00283 
00284 /** A Fibre Channel RTV request frame */
00285 struct fc_rtv_request_frame {
00286         /** ELS command code */
00287         uint8_t command;
00288         /** Reserved */
00289         uint8_t reserved[3];
00290 } __attribute__ (( packed ));
00291 
00292 /** A Fibre Channel RTV response frame */
00293 struct fc_rtv_response_frame {
00294         /** ELS command code */
00295         uint8_t command;
00296         /** Reserved */
00297         uint8_t reserved0[3];
00298         /** Resource allocation timeout value */
00299         uint32_t r_a_tov;
00300         /** Error detection timeout value */
00301         uint32_t e_d_tov;
00302         /** Timeout qualifier */
00303         uint16_t flags;
00304         /** Reserved */
00305         uint16_t reserved1;
00306 } __attribute__ (( packed ));
00307 
00308 /** 1ns error detection timer resolution */
00309 #define FC_RTV_HIRES_E_D_TOV 0x0400
00310 
00311 /** Short R_T timeout */
00312 #define FC_RTV_SHORT_R_T_TOV 0x0008
00313 
00314 /** A Fibre Channel ECHO frame */
00315 struct fc_echo_frame_header {
00316         /** ELS command code */
00317         uint8_t command;
00318         /** Reserved */
00319         uint8_t reserved[3];
00320 } __attribute__ (( packed ));
00321 
00322 /** A Fibre Channel extended link services transaction */
00323 struct fc_els {
00324         /** Reference count */
00325         struct refcnt refcnt;
00326         /** Job control interface */
00327         struct interface job;
00328         /** Fibre Channel exchange */
00329         struct interface xchg;
00330         /** Request sending process */
00331         struct process process;
00332 
00333         /** Fibre Channel port */
00334         struct fc_port *port;
00335         /** Local port ID */
00336         struct fc_port_id port_id;
00337         /** Peer port ID */
00338         struct fc_port_id peer_port_id;
00339         /** ELS handler, if known */
00340         struct fc_els_handler *handler;
00341         /** Flags */
00342         unsigned int flags;
00343 };
00344 
00345 /** Fibre Channel extended link services transaction flags */
00346 enum fc_els_flags {
00347         /** ELS transaction is a request */
00348         FC_ELS_REQUEST = 0x0001,
00349 };
00350 
00351 /** A Fibre Channel extended link services handler */
00352 struct fc_els_handler {
00353         /** Name */
00354         const char *name;
00355         /** Transmit ELS frame
00356          *
00357          * @v els               Fibre Channel ELS transaction
00358          * @ret rc              Return status code
00359          */
00360         int ( * tx ) ( struct fc_els *els );
00361         /** Receive ELS frame
00362          *
00363          * @v els               Fibre Channel ELS transaction
00364          * @v data              ELS frame
00365          * @v len               Length of ELS frame
00366          * @ret rc              Return status code
00367          */
00368         int ( * rx ) ( struct fc_els *els, void *data, size_t len );
00369         /** Detect ELS frame
00370          *
00371          * @v els               Fibre Channel ELS transaction
00372          * @v data              ELS frame
00373          * @v len               Length of ELS frame
00374          * @ret rc              Return status code
00375          */
00376         int ( * detect ) ( struct fc_els *els, const void *data, size_t len );
00377 };
00378 
00379 /** Fibre Channel ELS handler table */
00380 #define FC_ELS_HANDLERS __table ( struct fc_els_handler, "fc_els_handlers" )
00381 
00382 /** Declare a Fibre Channel ELS handler */
00383 #define __fc_els_handler __table_entry ( FC_ELS_HANDLERS, 01 )
00384 
00385 /** A Fibre Channel ELS PRLI descriptor */
00386 struct fc_els_prli_descriptor {
00387         /** Upper-layer protocol type */
00388         unsigned int type;
00389         /** Service parameter length */
00390         size_t param_len;
00391         /** Fibre Channel ELS handler */
00392         struct fc_els_handler *handler;
00393 };
00394 
00395 /** Fibre Channel ELS PRLI descriptor table */
00396 #define FC_ELS_PRLI_DESCRIPTORS \
00397         __table ( struct fc_els_prli_descriptor, "fc_els_prli_descriptors" )
00398 
00399 /** Declare a Fibre Channel ELS PRLI descriptor */
00400 #define __fc_els_prli_descriptor __table_entry ( FC_ELS_PRLI_DESCRIPTORS, 01 )
00401 
00402 /**
00403  * Check if Fibre Channel ELS transaction is a request
00404  *
00405  * @v els               Fibre Channel ELS transaction
00406  * @ret is_request      ELS transaction is a request
00407  */
00408 static inline int fc_els_is_request ( struct fc_els *els ) {
00409         return ( els->flags & FC_ELS_REQUEST );
00410 }
00411 
00412 /**
00413  * Calculate ELS command to transmit
00414  *
00415  * @v els               Fibre Channel ELS transaction
00416  * @v request_command   Command for requests
00417  * @v command           Command to transmit
00418  */
00419 static inline unsigned int fc_els_tx_command ( struct fc_els *els,
00420                                                unsigned int request_command ) {
00421         return ( fc_els_is_request ( els ) ? request_command : FC_ELS_LS_ACC );
00422 }
00423 
00424 extern int fc_els_tx ( struct fc_els *els, const void *data, size_t len );
00425 extern int fc_els_request ( struct interface *job, struct fc_port *port,
00426                             struct fc_port_id *peer_port_id,
00427                             struct fc_els_handler *handler );
00428 extern int fc_els_flogi ( struct interface *parent, struct fc_port *port );
00429 extern int fc_els_plogi ( struct interface *parent, struct fc_port *port,
00430                           struct fc_port_id *peer_port_id );
00431 extern int fc_els_logo ( struct interface *parent, struct fc_port *port,
00432                          struct fc_port_id *peer_port_id );
00433 extern int fc_els_prli ( struct interface *parent, struct fc_port *port,
00434                          struct fc_port_id *peer_port_id, unsigned int type );
00435 extern int fc_els_prli_tx ( struct fc_els *els,
00436                             struct fc_els_prli_descriptor *descriptor,
00437                             void *param );
00438 extern int fc_els_prli_rx ( struct fc_els *els,
00439                             struct fc_els_prli_descriptor *descriptor,
00440                             void *data, size_t len );
00441 extern int fc_els_prli_detect ( struct fc_els *els __unused,
00442                                 struct fc_els_prli_descriptor *descriptor,
00443                                 const void *data, size_t len );
00444 
00445 #endif /* _IPXE_FCELS_H */