mirror of https://github.com/ipxe/ipxe.git
[fc] Add support for Fibre Channel devices
Add support for Fibre Channel ports, peers, and upper-layer protocols, and for Fibre Channel extended link services. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/1/head
parent
220495f8bf
commit
508ff4d614
|
@ -184,6 +184,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
|||
#define ERRFILE_wpa_tkip ( ERRFILE_NET | 0x00280000 )
|
||||
#define ERRFILE_wpa_ccmp ( ERRFILE_NET | 0x00290000 )
|
||||
#define ERRFILE_eth_slow ( ERRFILE_NET | 0x002a0000 )
|
||||
#define ERRFILE_fc ( ERRFILE_NET | 0x002b0000 )
|
||||
#define ERRFILE_fcels ( ERRFILE_NET | 0x002c0000 )
|
||||
|
||||
#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 )
|
||||
#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 )
|
||||
|
|
|
@ -0,0 +1,439 @@
|
|||
#ifndef _IPXE_FC_H
|
||||
#define _IPXE_FC_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Fibre Channel
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipxe/refcnt.h>
|
||||
#include <ipxe/list.h>
|
||||
#include <ipxe/tables.h>
|
||||
#include <ipxe/interface.h>
|
||||
#include <ipxe/retry.h>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Fibre Channel Names and identifiers
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** A Fibre Channel name */
|
||||
struct fc_name {
|
||||
uint8_t bytes[8];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** Length of Fibre Channel name text */
|
||||
#define FC_NAME_STRLEN 23 /* "xx:xx:xx:xx:xx:xx:xx:xx" */
|
||||
|
||||
/** A Fibre Channel port identifier */
|
||||
struct fc_port_id {
|
||||
uint8_t bytes[3];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** Length of Fibre Channel port identifier next */
|
||||
#define FC_PORT_ID_STRLEN 9 /* "xx.xx.xx" */
|
||||
|
||||
extern struct fc_port_id fc_empty_port_id;
|
||||
extern struct fc_port_id fc_f_port_id;
|
||||
extern struct fc_port_id fc_ptp_low_port_id;
|
||||
extern struct fc_port_id fc_ptp_high_port_id;
|
||||
|
||||
extern const char * fc_id_ntoa ( const struct fc_port_id *id );
|
||||
extern int fc_id_aton ( const char *id_text, struct fc_port_id *id );
|
||||
extern const char * fc_ntoa ( const struct fc_name *wwn );
|
||||
extern int fc_aton ( const char *wwn_text, struct fc_name *wwn );
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Fibre Channel link state
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** Delay between failed link-up attempts */
|
||||
#define FC_LINK_RETRY_DELAY ( 2 * TICKS_PER_SEC )
|
||||
|
||||
/** A Fibre Channel link state nonitor */
|
||||
struct fc_link_state {
|
||||
/** Retry timer */
|
||||
struct retry_timer timer;
|
||||
/** Link state */
|
||||
int rc;
|
||||
/** Examine link state
|
||||
*
|
||||
* @v link Fibre Channel link state monitor
|
||||
*/
|
||||
void ( * examine ) ( struct fc_link_state *link );
|
||||
};
|
||||
|
||||
/**
|
||||
* Check Fibre Channel link state
|
||||
*
|
||||
* @v link Fibre Channel link state monitor
|
||||
* @ret link_up Link is up
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
fc_link_ok ( struct fc_link_state *link ) {
|
||||
return ( link->rc == 0 );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Fibre Channel packet formats and exchanges
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** A Fibre Channel Frame Header */
|
||||
struct fc_frame_header {
|
||||
/** Routing control
|
||||
*
|
||||
* This is the bitwise OR of one @c fc_r_ctl_routing value and
|
||||
* one @c fc_r_ctl_info value.
|
||||
*/
|
||||
uint8_t r_ctl;
|
||||
/** Destination ID */
|
||||
struct fc_port_id d_id;
|
||||
/** Class-specific control / Priority */
|
||||
uint8_t cs_ctl_prio;
|
||||
/** Source ID */
|
||||
struct fc_port_id s_id;
|
||||
/** Data structure type */
|
||||
uint8_t type;
|
||||
/** Frame control - exchange and sequence */
|
||||
uint8_t f_ctl_es;
|
||||
/** Frame control - acknowledgements */
|
||||
uint8_t f_ctl_ack;
|
||||
/** Frame control - miscellaneous */
|
||||
uint8_t f_ctl_misc;
|
||||
/** Sequence ID */
|
||||
uint8_t seq_id;
|
||||
/** Data field control */
|
||||
uint8_t df_ctl;
|
||||
/** Sequence count */
|
||||
uint16_t seq_cnt;
|
||||
/** Originator exchange ID */
|
||||
uint16_t ox_id;
|
||||
/** Responder exchange ID */
|
||||
uint16_t rx_id;
|
||||
/** Parameter
|
||||
*
|
||||
* Contains the relative offset when @c FC_F_CTL_MISC_REL_OFF
|
||||
* is set.
|
||||
*/
|
||||
uint32_t parameter;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** Fibre Channel Routing Control Routing */
|
||||
enum fc_r_ctl_routing {
|
||||
FC_R_CTL_DATA = 0x00, /**< Device Data */
|
||||
FC_R_CTL_ELS = 0x20, /**< Extended Link Services */
|
||||
FC_R_CTL_FC4_LINK = 0x30, /**< FC-4 Link Data */
|
||||
FC_R_CTL_VIDEO = 0x40, /**< Video Data */
|
||||
FC_R_CTL_EH = 0x50, /**< Extended Headers */
|
||||
FC_R_CTL_BLS = 0x80, /**< Basic Link Services */
|
||||
FC_R_CTL_LINK_CTRL = 0xc0, /**< Link Control */
|
||||
FC_R_CTL_EXT_ROUTE = 0xf0, /**< Extended Routing */
|
||||
};
|
||||
|
||||
/** Fibre Channel Routing Control Routing mask */
|
||||
#define FC_R_CTL_ROUTING_MASK 0xf0
|
||||
|
||||
/** Fibre Channel Routing Control Information */
|
||||
enum fc_r_ctl_info {
|
||||
FC_R_CTL_UNCAT = 0x00, /**< Uncategorized */
|
||||
FC_R_CTL_SOL_DATA = 0x01, /**< Solicited Data */
|
||||
FC_R_CTL_UNSOL_CTRL = 0x02, /**< Unsolicited Control */
|
||||
FC_R_CTL_SOL_CTRL = 0x03, /**< Solicited Control */
|
||||
FC_R_CTL_UNSOL_DATA = 0x04, /**< Unsolicited Data */
|
||||
FC_R_CTL_DATA_DESC = 0x05, /**< Data Descriptor */
|
||||
FC_R_CTL_UNSOL_CMD = 0x06, /**< Unsolicited Command */
|
||||
FC_R_CTL_CMD_STAT = 0x07, /**< Command Status */
|
||||
};
|
||||
|
||||
/** Fibre Channel Routing Control Information mask */
|
||||
#define FC_R_CTL_INFO_MASK 0x07
|
||||
|
||||
/** Fibre Channel Data Structure Type */
|
||||
enum fc_type {
|
||||
FC_TYPE_BLS = 0x00, /**< Basic Link Service */
|
||||
FC_TYPE_ELS = 0x01, /**< Extended Link Service */
|
||||
FC_TYPE_FCP = 0x08, /**< Fibre Channel Protocol */
|
||||
};
|
||||
|
||||
/** Fibre Channel Frame Control - Exchange and Sequence */
|
||||
enum fc_f_ctl_es {
|
||||
FC_F_CTL_ES_RESPONDER = 0x80, /**< Responder of Exchange */
|
||||
FC_F_CTL_ES_RECIPIENT = 0x40, /**< Sequence Recipient */
|
||||
FC_F_CTL_ES_FIRST = 0x20, /**< First Sequence of Exchange */
|
||||
FC_F_CTL_ES_LAST = 0x10, /**< Last Sequence of Exchange */
|
||||
FC_F_CTL_ES_END = 0x08, /**< Last Data Frame of Sequence */
|
||||
FC_F_CTL_ES_TRANSFER = 0x01, /**< Transfer Sequence Initiative */
|
||||
};
|
||||
|
||||
/** Fibre Channel Frame Control - Miscellaneous */
|
||||
enum fc_f_ctl_misc {
|
||||
FC_F_CTL_MISC_REL_OFF = 0x08, /**< Relative Offset Present */
|
||||
};
|
||||
|
||||
/** Responder exchange identifier used before first response */
|
||||
#define FC_RX_ID_UNKNOWN 0xffff
|
||||
|
||||
struct fc_port;
|
||||
|
||||
extern int fc_xchg_originate ( struct interface *parent, struct fc_port *port,
|
||||
struct fc_port_id *peer_port_id,
|
||||
unsigned int type );
|
||||
|
||||
/** A Fibre Channel responder */
|
||||
struct fc_responder {
|
||||
/** Type */
|
||||
unsigned int type;
|
||||
/** Respond to exchange
|
||||
*
|
||||
* @v xchg Exchange interface
|
||||
* @v port Fibre Channel port
|
||||
* @v port_id Local port ID
|
||||
* @v peer_port_id Peer port ID
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * respond ) ( struct interface *xchg, struct fc_port *port,
|
||||
struct fc_port_id *port_id,
|
||||
struct fc_port_id *peer_port_id );
|
||||
};
|
||||
|
||||
/** Fibre Channel responder table */
|
||||
#define FC_RESPONDERS __table ( struct fc_responder, "fc_responders" )
|
||||
|
||||
/** Declare a Fibre Channel responder */
|
||||
#define __fc_responder __table_entry ( FC_RESPONDERS, 01 )
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Fibre Channel ports
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** A Fibre Channel port */
|
||||
struct fc_port {
|
||||
/** Reference count */
|
||||
struct refcnt refcnt;
|
||||
/** List of all ports */
|
||||
struct list_head list;
|
||||
/** Name of this port */
|
||||
char name[8];
|
||||
|
||||
/** Transport interface */
|
||||
struct interface transport;
|
||||
/** Node name */
|
||||
struct fc_name node_wwn;
|
||||
/** Port name */
|
||||
struct fc_name port_wwn;
|
||||
/** Local port ID */
|
||||
struct fc_port_id port_id;
|
||||
/** Flags */
|
||||
unsigned int flags;
|
||||
|
||||
/** Link state monitor */
|
||||
struct fc_link_state link;
|
||||
/** FLOGI interface */
|
||||
struct interface flogi;
|
||||
/** Link node name */
|
||||
struct fc_name link_node_wwn;
|
||||
/** Link port name */
|
||||
struct fc_name link_port_wwn;
|
||||
/** Link port ID (for point-to-point links only) */
|
||||
struct fc_port_id ptp_link_port_id;
|
||||
|
||||
/** List of active exchanges */
|
||||
struct list_head xchgs;
|
||||
};
|
||||
|
||||
/** Fibre Channel port flags */
|
||||
enum fc_port_flags {
|
||||
/** Port is attached to a fabric */
|
||||
FC_PORT_HAS_FABRIC = 0x0001,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get reference to Fibre Channel port
|
||||
*
|
||||
* @v port Fibre Channel port
|
||||
* @ret port Fibre Channel port
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) struct fc_port *
|
||||
fc_port_get ( struct fc_port *port ) {
|
||||
ref_get ( &port->refcnt );
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop reference to Fibre Channel port
|
||||
*
|
||||
* @v port Fibre Channel port
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
fc_port_put ( struct fc_port *port ) {
|
||||
ref_put ( &port->refcnt );
|
||||
}
|
||||
|
||||
extern struct list_head fc_ports;
|
||||
|
||||
extern int fc_port_login ( struct fc_port *port, struct fc_port_id *port_id,
|
||||
const struct fc_name *link_node_wwn,
|
||||
const struct fc_name *link_port_wwn,
|
||||
int has_fabric );
|
||||
extern void fc_port_logout ( struct fc_port *port, int rc );
|
||||
extern int fc_port_open ( struct interface *transport,
|
||||
const struct fc_name *node_wwn,
|
||||
const struct fc_name *port_wwn );
|
||||
extern struct fc_port * fc_port_find ( const char *name );
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Fibre Channel peers
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** A Fibre Channel peer */
|
||||
struct fc_peer {
|
||||
/** Reference count */
|
||||
struct refcnt refcnt;
|
||||
/** List of all peers */
|
||||
struct list_head list;
|
||||
|
||||
/** Node name */
|
||||
struct fc_name node_wwn;
|
||||
|
||||
/** Link state monitor */
|
||||
struct fc_link_state link;
|
||||
/** PLOGI interface */
|
||||
struct interface plogi;
|
||||
/** Fibre Channel port, if known */
|
||||
struct fc_port *port;
|
||||
/** Peer port ID, if known */
|
||||
struct fc_port_id port_id;
|
||||
|
||||
/** List of upper-layer protocols */
|
||||
struct list_head ulps;
|
||||
/** Active usage count */
|
||||
unsigned int usage;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get reference to Fibre Channel peer
|
||||
*
|
||||
* @v peer Fibre Channel peer
|
||||
* @ret peer Fibre Channel peer
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) struct fc_peer *
|
||||
fc_peer_get ( struct fc_peer *peer ) {
|
||||
ref_get ( &peer->refcnt );
|
||||
return peer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop reference to Fibre Channel peer
|
||||
*
|
||||
* @v peer Fibre Channel peer
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
fc_peer_put ( struct fc_peer *peer ) {
|
||||
ref_put ( &peer->refcnt );
|
||||
}
|
||||
|
||||
extern struct list_head fc_peers;
|
||||
|
||||
extern struct fc_peer * fc_peer_get_wwn ( const struct fc_name *node_wwn );
|
||||
extern struct fc_peer *
|
||||
fc_peer_get_port_id ( struct fc_port *port,
|
||||
const struct fc_port_id *peer_port_id );
|
||||
extern int fc_peer_login ( struct fc_peer *peer,
|
||||
struct fc_port *port,
|
||||
struct fc_port_id *port_id );
|
||||
extern void fc_peer_logout ( struct fc_peer *peer, int rc );
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Fibre Channel upper-layer protocols
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** A Fibre Channel upper-layer protocol */
|
||||
struct fc_ulp {
|
||||
/** Reference count */
|
||||
struct refcnt refcnt;
|
||||
/** Fibre Channel peer */
|
||||
struct fc_peer *peer;
|
||||
/** List of upper-layer protocols */
|
||||
struct list_head list;
|
||||
|
||||
/** Type */
|
||||
unsigned int type;
|
||||
/** Flags */
|
||||
unsigned int flags;
|
||||
|
||||
/** Link state monitor */
|
||||
struct fc_link_state link;
|
||||
/** PRLI interface */
|
||||
struct interface prli;
|
||||
/** Service parameters, if any */
|
||||
void *param;
|
||||
/** Service parameter length */
|
||||
size_t param_len;
|
||||
|
||||
/** Active usage count */
|
||||
unsigned int usage;
|
||||
};
|
||||
|
||||
/** Fibre Channel upper-layer protocol flags */
|
||||
enum fc_ulp_flags {
|
||||
/** A login originated by us has succeeded */
|
||||
FC_ULP_ORIGINATED_LOGIN_OK = 0x0001,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get reference to Fibre Channel upper-layer protocol
|
||||
*
|
||||
* @v ulp Fibre Channel upper-layer protocol
|
||||
* @ret ulp Fibre Channel upper-layer protocol
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) struct fc_ulp *
|
||||
fc_ulp_get ( struct fc_ulp *ulp ) {
|
||||
ref_get ( &ulp->refcnt );
|
||||
return ulp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop reference to Fibre Channel upper-layer protocol
|
||||
*
|
||||
* @v ulp Fibre Channel upper-layer protocol
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
fc_ulp_put ( struct fc_ulp *ulp ) {
|
||||
ref_put ( &ulp->refcnt );
|
||||
}
|
||||
|
||||
extern struct fc_ulp * fc_ulp_get_wwn_type ( const struct fc_name *node_wwn,
|
||||
unsigned int type );
|
||||
extern struct fc_ulp *
|
||||
fc_ulp_get_port_id_type ( struct fc_port *port,
|
||||
const struct fc_port_id *peer_port_id,
|
||||
unsigned int type );
|
||||
extern void fc_ulp_increment ( struct fc_ulp *ulp );
|
||||
extern void fc_ulp_decrement ( struct fc_ulp *ulp );
|
||||
extern int fc_ulp_login ( struct fc_ulp *ulp, const void *param,
|
||||
size_t param_len, int originated );
|
||||
extern void fc_ulp_logout ( struct fc_ulp *ulp, int rc );
|
||||
|
||||
#endif /* _IPXE_FC_H */
|
|
@ -0,0 +1,452 @@
|
|||
#ifndef _IPXE_FCELS_H
|
||||
#define _IPXE_FCELS_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Fibre Channel Extended Link Services
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipxe/fc.h>
|
||||
#include <ipxe/tables.h>
|
||||
#include <ipxe/refcnt.h>
|
||||
#include <ipxe/list.h>
|
||||
#include <ipxe/process.h>
|
||||
#include <ipxe/interface.h>
|
||||
|
||||
/** Fibre Channel ELS frame common parameters */
|
||||
struct fc_els_frame_common {
|
||||
/** ELS command code */
|
||||
uint8_t command;
|
||||
/** Reserved */
|
||||
uint8_t reserved[3];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** Fibre Channel ELS command codes */
|
||||
enum fc_els_command_code {
|
||||
FC_ELS_LS_RJT = 0x01, /**< Link Service Reject */
|
||||
FC_ELS_LS_ACC = 0x02, /**< Link Service Accept */
|
||||
FC_ELS_PLOGI = 0x03, /**< Port Login */
|
||||
FC_ELS_FLOGI = 0x04, /**< Fabric Login */
|
||||
FC_ELS_LOGO = 0x05, /**< Logout */
|
||||
FC_ELS_RTV = 0x0e, /**< Read Timeout Value */
|
||||
FC_ELS_PRLI = 0x20, /**< Process Login */
|
||||
FC_ELS_PRLO = 0x21, /**< Process Logout */
|
||||
};
|
||||
|
||||
/** A Fibre Channel LS_RJT frame */
|
||||
struct fc_ls_rjt_frame {
|
||||
/** ELS command code */
|
||||
uint8_t command;
|
||||
/** Reserved */
|
||||
uint8_t reserved[4];
|
||||
/** Reason code */
|
||||
uint8_t reason;
|
||||
/** Reason code explanation */
|
||||
uint8_t explanation;
|
||||
/** Vendor unique */
|
||||
uint8_t vendor;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** Fibre Channel ELS rejection reason codes */
|
||||
enum fc_els_reject_reason {
|
||||
/** Invalid ELS command code */
|
||||
FC_ELS_RJT_INVALID_COMMAND = 0x01,
|
||||
/** Logical error */
|
||||
FC_ELS_RJT_ILLOGICAL = 0x03,
|
||||
/** Logical busy */
|
||||
FC_ELS_RJT_BUSY = 0x05,
|
||||
/** Protocol error */
|
||||
FC_ELS_RJT_PROTOCOL = 0x07,
|
||||
/** Unable to perform command request */
|
||||
FC_ELS_RJT_UNABLE = 0x09,
|
||||
/** Command not supported */
|
||||
FC_ELS_RJT_UNSUPPORTED = 0x0b,
|
||||
/** Command already in progress */
|
||||
FC_ELS_RJT_IN_PROGRESS = 0x0e,
|
||||
};
|
||||
|
||||
/** Fibre Channel "common" service parameters */
|
||||
struct fc_login_common {
|
||||
/** Login version */
|
||||
uint16_t version;
|
||||
/** Buffer-to-buffer credit */
|
||||
uint16_t credit;
|
||||
/** Flags */
|
||||
uint16_t flags;
|
||||
/** Receive size */
|
||||
uint16_t mtu;
|
||||
/** "Common"?! */
|
||||
union {
|
||||
struct {
|
||||
/** Maximum number of concurrent sequences */
|
||||
uint16_t max_seq;
|
||||
/** Relative offset by info category */
|
||||
uint16_t rel_offs;
|
||||
} plogi;
|
||||
struct {
|
||||
/** Resource allocation timeout value */
|
||||
uint32_t r_a_tov;
|
||||
} flogi;
|
||||
} u;
|
||||
/** Error detection timeout value */
|
||||
uint32_t e_d_tov;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** Fibre Channel default login version */
|
||||
#define FC_LOGIN_VERSION 0x2020
|
||||
|
||||
/** Fibre Channel default buffer-to-buffer credit */
|
||||
#define FC_LOGIN_DEFAULT_B2B 10
|
||||
|
||||
/** Continuously increasing relative offset */
|
||||
#define FC_LOGIN_CONTINUOUS_OFFSET 0x8000
|
||||
|
||||
/** Clean address */
|
||||
#define FC_LOGIN_CLEAN 0x8000
|
||||
|
||||
/** Multiple N_Port_ID support */
|
||||
#define FC_LOGIN_MULTI_N 0x8000
|
||||
|
||||
/** Random relative offset */
|
||||
#define FC_LOGIN_RANDOM_OFFSET 0x4000
|
||||
|
||||
/** Virtual fabrics */
|
||||
#define FC_LOGIN_VIRTUAL 0x4000
|
||||
|
||||
/** Vendor version level */
|
||||
#define FC_LOGIN_VENDOR 0x2000
|
||||
|
||||
/** Multiple N_Port_ID support */
|
||||
#define FC_LOGIN_MULTI_F 0x2000
|
||||
|
||||
/** Forwarder port */
|
||||
#define FC_LOGIN_F_PORT 0x1000
|
||||
|
||||
/** Alternative credit management */
|
||||
#define FC_LOGIN_ALT_CREDIT 0x0800
|
||||
|
||||
/** Name server session started */
|
||||
#define FC_LOGIN_NSS_STARTED 0x0800
|
||||
|
||||
/** Begin name server session */
|
||||
#define FC_LOGIN_NSS_BEGIN 0x0400
|
||||
|
||||
/** 1ns error detection timer resolution */
|
||||
#define FC_LOGIN_HIRES_E_D_TOV 0x0400
|
||||
|
||||
/** Broadcast supported */
|
||||
#define FC_LOGIN_BROADCAST 0x0100
|
||||
|
||||
/** Query buffer conditions */
|
||||
#define FC_LOGIN_QUERY_BUF 0x0040
|
||||
|
||||
/** Security */
|
||||
#define FC_LOGIN_SECURITY 0x0020
|
||||
|
||||
/** Clock sync primitive capable */
|
||||
#define FC_LOGIN_CLOCK_SYNC 0x0010
|
||||
|
||||
/** Short R_T timeout */
|
||||
#define FC_LOGIN_SHORT_R_T_TOV 0x0008
|
||||
|
||||
/** Dynamic half duplex */
|
||||
#define FC_LOGIN_DHD 0x0004
|
||||
|
||||
/** Continuously increasing sequence count */
|
||||
#define FC_LOGIN_CONTINUOUS_SEQ 0x0002
|
||||
|
||||
/** Payload */
|
||||
#define FC_LOGIN_PAYLOAD 0x0001
|
||||
|
||||
/** Fibre Channel default MTU */
|
||||
#define FC_LOGIN_DEFAULT_MTU 1452
|
||||
|
||||
/** Default maximum number of concurrent sequences */
|
||||
#define FC_LOGIN_DEFAULT_MAX_SEQ 255
|
||||
|
||||
/** Default relative offset by info category */
|
||||
#define FC_LOGIN_DEFAULT_REL_OFFS 0x1f
|
||||
|
||||
/** Default E_D timeout value */
|
||||
#define FC_LOGIN_DEFAULT_E_D_TOV 2000
|
||||
|
||||
/** Fibre Channel class-specific login parameters */
|
||||
struct fc_login_class {
|
||||
/** Flags */
|
||||
uint16_t flags;
|
||||
/** Initiator flags */
|
||||
uint16_t init_flags;
|
||||
/** Recipient flags */
|
||||
uint16_t recip_flags;
|
||||
/** Receive data field size */
|
||||
uint16_t mtu;
|
||||
/** Maximum number of concurrent sequences */
|
||||
uint16_t max_seq;
|
||||
/** End-to-end credit */
|
||||
uint16_t credit;
|
||||
/** Reserved */
|
||||
uint8_t reserved0;
|
||||
/** Maximum number of open sequences per exchange */
|
||||
uint8_t max_seq_per_xchg;
|
||||
/** Reserved */
|
||||
uint8_t reserved1[2];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** Class valid */
|
||||
#define FC_LOGIN_CLASS_VALID 0x8000
|
||||
|
||||
/** Sequential delivery requested */
|
||||
#define FC_LOGIN_CLASS_SEQUENTIAL 0x0800
|
||||
|
||||
/** A Fibre Channel FLOGI/PLOGI frame */
|
||||
struct fc_login_frame {
|
||||
/** ELS command code */
|
||||
uint8_t command;
|
||||
/** Reserved */
|
||||
uint8_t reserved[3];
|
||||
/** Common service parameters */
|
||||
struct fc_login_common common;
|
||||
/** Port name */
|
||||
struct fc_name port_wwn;
|
||||
/** Node name */
|
||||
struct fc_name node_wwn;
|
||||
/** Class 1 service parameters */
|
||||
struct fc_login_class class1;
|
||||
/** Class 2 service parameters */
|
||||
struct fc_login_class class2;
|
||||
/** Class 3 service parameters */
|
||||
struct fc_login_class class3;
|
||||
/** Class 4 service parameters */
|
||||
struct fc_login_class class4;
|
||||
/** Vendor version level */
|
||||
uint8_t vendor_version[16];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** A Fibre Channel LOGO request frame */
|
||||
struct fc_logout_request_frame {
|
||||
/** ELS command code */
|
||||
uint8_t command;
|
||||
/** Reserved */
|
||||
uint8_t reserved[4];
|
||||
/** Port ID */
|
||||
struct fc_port_id port_id;
|
||||
/** Port name */
|
||||
struct fc_name port_wwn;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** A Fibre Channel LOGO response frame */
|
||||
struct fc_logout_response_frame {
|
||||
/** ELS command code */
|
||||
uint8_t command;
|
||||
/** Reserved */
|
||||
uint8_t reserved[3];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** A Fibre Channel PRLI service parameter page */
|
||||
struct fc_prli_page {
|
||||
/** Type code */
|
||||
uint8_t type;
|
||||
/** Type code extension */
|
||||
uint8_t type_ext;
|
||||
/** Flags and response code */
|
||||
uint16_t flags;
|
||||
/** Reserved */
|
||||
uint32_t reserved[2];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** Establish image pair */
|
||||
#define FC_PRLI_ESTABLISH 0x2000
|
||||
|
||||
/** Response code mask */
|
||||
#define FC_PRLI_RESPONSE_MASK 0x0f00
|
||||
|
||||
/** Request was executed successfully */
|
||||
#define FC_PRLI_RESPONSE_SUCCESS 0x0100
|
||||
|
||||
/** A Fibre Channel PRLI frame */
|
||||
struct fc_prli_frame {
|
||||
/** ELS command code */
|
||||
uint8_t command;
|
||||
/** Page length */
|
||||
uint8_t page_len;
|
||||
/** Payload length */
|
||||
uint16_t len;
|
||||
/** Service parameter page */
|
||||
struct fc_prli_page page;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** A Fibre Channel RTV request frame */
|
||||
struct fc_rtv_request_frame {
|
||||
/** ELS command code */
|
||||
uint8_t command;
|
||||
/** Reserved */
|
||||
uint8_t reserved[3];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** A Fibre Channel RTV response frame */
|
||||
struct fc_rtv_response_frame {
|
||||
/** ELS command code */
|
||||
uint8_t command;
|
||||
/** Reserved */
|
||||
uint8_t reserved0[3];
|
||||
/** Resource allocation timeout value */
|
||||
uint32_t r_a_tov;
|
||||
/** Error detection timeout value */
|
||||
uint32_t e_d_tov;
|
||||
/** Timeout qualifier */
|
||||
uint16_t flags;
|
||||
/** Reserved */
|
||||
uint16_t reserved1;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** 1ns error detection timer resolution */
|
||||
#define FC_RTV_HIRES_E_D_TOV 0x0400
|
||||
|
||||
/** Short R_T timeout */
|
||||
#define FC_RTV_SHORT_R_T_TOV 0x0008
|
||||
|
||||
/** A Fibre Channel extended link services transaction */
|
||||
struct fc_els {
|
||||
/** Reference count */
|
||||
struct refcnt refcnt;
|
||||
/** Job control interface */
|
||||
struct interface job;
|
||||
/** Fibre Channel exchange */
|
||||
struct interface xchg;
|
||||
/** Request sending process */
|
||||
struct process process;
|
||||
|
||||
/** Fibre Channel port */
|
||||
struct fc_port *port;
|
||||
/** Local port ID */
|
||||
struct fc_port_id port_id;
|
||||
/** Peer port ID */
|
||||
struct fc_port_id peer_port_id;
|
||||
/** ELS handler, if known */
|
||||
struct fc_els_handler *handler;
|
||||
/** Flags */
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
/** Fibre Channel extended link services transaction flags */
|
||||
enum fc_els_flags {
|
||||
/** ELS transaction is a request */
|
||||
FC_ELS_REQUEST = 0x0001,
|
||||
};
|
||||
|
||||
/** A Fibre Channel extended link services handler */
|
||||
struct fc_els_handler {
|
||||
/** Name */
|
||||
const char *name;
|
||||
/** Transmit ELS request frame
|
||||
*
|
||||
* @v els Fibre Channel ELS transaction
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * tx_request ) ( struct fc_els *els );
|
||||
/** Transmit ELS response frame
|
||||
*
|
||||
* @v els Fibre Channel ELS transaction
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * tx_response ) ( struct fc_els *els );
|
||||
/** Receive ELS request frame
|
||||
*
|
||||
* @v els Fibre Channel ELS transaction
|
||||
* @v data ELS frame
|
||||
* @v len Length of ELS frame
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * rx_request ) ( struct fc_els *els, const void *data,
|
||||
size_t len );
|
||||
/** Receive ELS response frame
|
||||
*
|
||||
* @v els Fibre Channel ELS transaction
|
||||
* @v data ELS frame
|
||||
* @v len Length of ELS frame
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * rx_response ) ( struct fc_els *els, const void *data,
|
||||
size_t len );
|
||||
/** Detect ELS request frame
|
||||
*
|
||||
* @v els Fibre Channel ELS transaction
|
||||
* @v data ELS frame
|
||||
* @v len Length of ELS frame
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * detect ) ( struct fc_els *els, const void *data, size_t len );
|
||||
};
|
||||
|
||||
/** Fibre Channel ELS handler table */
|
||||
#define FC_ELS_HANDLERS __table ( struct fc_els_handler, "fc_els_handlers" )
|
||||
|
||||
/** Declare a Fibre Channel ELS handler */
|
||||
#define __fc_els_handler __table_entry ( FC_ELS_HANDLERS, 01 )
|
||||
|
||||
/** A Fibre Channel ELS PRLI descriptor */
|
||||
struct fc_els_prli_descriptor {
|
||||
/** Upper-layer protocol type */
|
||||
unsigned int type;
|
||||
/** Service parameter length */
|
||||
size_t param_len;
|
||||
/** Fibre Channel ELS handler */
|
||||
struct fc_els_handler *handler;
|
||||
};
|
||||
|
||||
/** Fibre Channel ELS PRLI descriptor table */
|
||||
#define FC_ELS_PRLI_DESCRIPTORS \
|
||||
__table ( struct fc_els_prli_descriptor, "fc_els_prli_descriptors" )
|
||||
|
||||
/** Declare a Fibre Channel ELS PRLI descriptor */
|
||||
#define __fc_els_prli_descriptor __table_entry ( FC_ELS_PRLI_DESCRIPTORS, 01 )
|
||||
|
||||
/**
|
||||
* Check if Fibre Channel ELS transaction is a request
|
||||
*
|
||||
* @v els Fibre Channel ELS transaction
|
||||
* @ret is_request ELS transaction is a request
|
||||
*/
|
||||
static inline int fc_els_is_request ( struct fc_els *els ) {
|
||||
return ( els->flags & FC_ELS_REQUEST );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate ELS command to transmit
|
||||
*
|
||||
* @v els Fibre Channel ELS transaction
|
||||
* @v request_command Command for requests
|
||||
* @v command Command to transmit
|
||||
*/
|
||||
static inline unsigned int fc_els_tx_command ( struct fc_els *els,
|
||||
unsigned int request_command ) {
|
||||
return ( fc_els_is_request ( els ) ? request_command : FC_ELS_LS_ACC );
|
||||
}
|
||||
|
||||
extern int fc_els_tx ( struct fc_els *els, const void *data, size_t len );
|
||||
extern int fc_els_request ( struct interface *job, struct fc_port *port,
|
||||
struct fc_port_id *peer_port_id,
|
||||
struct fc_els_handler *handler );
|
||||
extern int fc_els_flogi ( struct interface *parent, struct fc_port *port );
|
||||
extern int fc_els_plogi ( struct interface *parent, struct fc_port *port,
|
||||
struct fc_port_id *peer_port_id );
|
||||
extern int fc_els_logo ( struct interface *parent, struct fc_port *port,
|
||||
struct fc_port_id *peer_port_id );
|
||||
extern int fc_els_prli ( struct interface *parent, struct fc_port *port,
|
||||
struct fc_port_id *peer_port_id, unsigned int type );
|
||||
extern int fc_els_prli_tx ( struct fc_els *els,
|
||||
struct fc_els_prli_descriptor *descriptor,
|
||||
void *param );
|
||||
extern int fc_els_prli_rx ( struct fc_els *els,
|
||||
struct fc_els_prli_descriptor *descriptor,
|
||||
const void *data, size_t len );
|
||||
extern int fc_els_prli_detect ( struct fc_els *els __unused,
|
||||
struct fc_els_prli_descriptor *descriptor,
|
||||
const void *data, size_t len );
|
||||
|
||||
#endif /* _IPXE_FCELS_H */
|
|
@ -46,6 +46,22 @@ struct xfer_metadata {
|
|||
/** Offset is absolute */
|
||||
#define XFER_FL_ABS_OFFSET 0x0001
|
||||
|
||||
/** Sender is relinquishing use of half-duplex channel */
|
||||
#define XFER_FL_OVER 0x0002
|
||||
|
||||
/** This is the final data transfer */
|
||||
#define XFER_FL_OUT 0x0004
|
||||
|
||||
/** Data content represents a command or status message
|
||||
*
|
||||
* The flag @c XFER_FL_RESPONSE is used to distinguish between a
|
||||
* command message and a status message.
|
||||
*/
|
||||
#define XFER_FL_CMD_STAT 0x0008
|
||||
|
||||
/** Data content is a response */
|
||||
#define XFER_FL_RESPONSE 0x0010
|
||||
|
||||
/* Data transfer interface operations */
|
||||
|
||||
extern int xfer_vredirect ( struct interface *intf, int type,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue