Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / include / ipxe / fc.h
diff --git a/qemu/roms/ipxe/src/include/ipxe/fc.h b/qemu/roms/ipxe/src/include/ipxe/fc.h
new file mode 100644 (file)
index 0000000..6fdef09
--- /dev/null
@@ -0,0 +1,538 @@
+#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>
+#include <ipxe/socket.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" */
+
+/**
+ * Fibre Channel socket address
+ */
+struct sockaddr_fc {
+       /** Socket address family (part of struct @c sockaddr)
+        *
+        * Always set to @c AF_FC for Fibre Channel addresses
+        */
+       sa_family_t sfc_family;
+       /** Port ID */
+       struct fc_port_id sfc_port_id;
+       /** Padding
+        *
+        * This ensures that a struct @c sockaddr_tcpip is large
+        * enough to hold a socket address for any TCP/IP address
+        * family.
+        */
+       char pad[ sizeof ( struct sockaddr ) - sizeof ( sa_family_t )
+                                            - sizeof ( struct fc_port_id ) ];
+} __attribute__ (( packed, may_alias ));
+
+extern struct fc_port_id fc_empty_port_id;
+extern struct fc_port_id fc_f_port_id;
+extern struct fc_port_id fc_gs_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 );
+extern struct sockaddr * fc_fill_sockaddr ( struct sockaddr_fc *sa_fc,
+                                           struct fc_port_id *id );
+
+/******************************************************************************
+ *
+ * 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 */
+       FC_TYPE_CT  = 0x20,             /**< Common Transport */
+};
+
+/** 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;
+
+       /** Name server PLOGI interface */
+       struct interface ns_plogi;
+
+       /** 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,
+       /** Port is logged in to a name server */
+       FC_PORT_HAS_NS = 0x0002,
+};
+
+/**
+ * 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,
+                         const char *name );
+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;
+
+       /** Port name */
+       struct fc_name port_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
+        *
+        * A peer (and attached ULPs) may be created in response to
+        * unsolicited login requests received via the fabric.  We
+        * track our own active usage count independently of the
+        * existence of the peer, so that if the peer becomes logged
+        * out (e.g. due to a link failure) then we know whether or
+        * not we should attempt to relogin.
+        */
+       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 *port_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 users of this upper-layer protocol
+        *
+        * As with peers, an upper-layer protocol may be created in
+        * response to an unsolicited login request received via the
+        * fabric.  This list records the number of active users of
+        * the ULP; the number of entries in the list is equivalent to
+        * the peer usage count.
+        */
+       struct list_head users;
+};
+
+/** Fibre Channel upper-layer protocol flags */
+enum fc_ulp_flags {
+       /** A login originated by us has succeeded */
+       FC_ULP_ORIGINATED_LOGIN_OK = 0x0001,
+};
+
+/** A Fibre Channel upper-layer protocol user */
+struct fc_ulp_user {
+       /** Fibre Channel upper layer protocol */
+       struct fc_ulp *ulp;
+       /** List of users */
+       struct list_head list;
+       /** Containing object reference count, or NULL */
+       struct refcnt *refcnt;
+       /** Examine link state
+        *
+        * @v user              Fibre Channel upper-layer-protocol user
+        */
+       void ( * examine ) ( struct fc_ulp_user *user );
+};
+
+/**
+ * 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 );
+}
+
+/**
+ * Get reference to Fibre Channel upper-layer protocol user
+ *
+ * @v user             Fibre Channel upper-layer protocol user
+ * @ret user           Fibre Channel upper-layer protocol user
+ */
+static inline __attribute__ (( always_inline )) struct fc_ulp_user *
+fc_ulp_user_get ( struct fc_ulp_user *user ) {
+       ref_get ( user->refcnt );
+       return user;
+}
+
+/**
+ * Drop reference to Fibre Channel upper-layer protocol user
+ *
+ * @v user             Fibre Channel upper-layer protocol user
+ */
+static inline __attribute__ (( always_inline )) void
+fc_ulp_user_put ( struct fc_ulp_user *user ) {
+       ref_put ( user->refcnt );
+}
+
+/**
+ * Initialise Fibre Channel upper-layer protocol user
+ *
+ * @v user             Fibre Channel upper-layer protocol user
+ * @v examine          Examine link state method
+ * @v refcnt           Containing object reference count, or NULL
+ */
+static inline __attribute__ (( always_inline )) void
+fc_ulp_user_init ( struct fc_ulp_user *user,
+                  void ( * examine ) ( struct fc_ulp_user *user ),
+                  struct refcnt *refcnt ) {
+       user->examine = examine;
+       user->refcnt = refcnt;
+}
+
+extern struct fc_ulp * fc_ulp_get_wwn_type ( const struct fc_name *port_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_attach ( struct fc_ulp *ulp, struct fc_ulp_user *user );
+extern void fc_ulp_detach ( struct fc_ulp_user *user );
+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 */