summaryrefslogtreecommitdiff
path: root/gpxe/src/include/gpxe/infiniband.h
diff options
context:
space:
mode:
Diffstat (limited to 'gpxe/src/include/gpxe/infiniband.h')
-rw-r--r--gpxe/src/include/gpxe/infiniband.h751
1 files changed, 751 insertions, 0 deletions
diff --git a/gpxe/src/include/gpxe/infiniband.h b/gpxe/src/include/gpxe/infiniband.h
new file mode 100644
index 00000000..354dc579
--- /dev/null
+++ b/gpxe/src/include/gpxe/infiniband.h
@@ -0,0 +1,751 @@
+#ifndef _GPXE_INFINIBAND_H
+#define _GPXE_INFINIBAND_H
+
+/** @file
+ *
+ * Infiniband protocol
+ *
+ */
+
+#include <stdint.h>
+#include <gpxe/device.h>
+
+/** Subnet administrator QPN */
+#define IB_SA_QPN 1
+
+/** Broadcast QPN */
+#define IB_BROADCAST_QPN 0xffffffUL
+
+/** Subnet administrator queue key */
+#define IB_GLOBAL_QKEY 0x80010000UL
+
+/** An Infiniband Global Identifier */
+struct ib_gid {
+ union {
+ uint8_t bytes[16];
+ uint16_t words[8];
+ uint32_t dwords[4];
+ } u;
+};
+
+/** An Infiniband Global Route Header */
+struct ib_global_route_header {
+ /** IP version, traffic class, and flow label
+ *
+ * 4 bits : Version of the GRH
+ * 8 bits : Traffic class
+ * 20 bits : Flow label
+ */
+ uint32_t ipver_tclass_flowlabel;
+ /** Payload length */
+ uint16_t paylen;
+ /** Next header */
+ uint8_t nxthdr;
+ /** Hop limit */
+ uint8_t hoplmt;
+ /** Source GID */
+ struct ib_gid sgid;
+ /** Destiniation GID */
+ struct ib_gid dgid;
+} __attribute__ (( packed ));
+
+struct ib_device;
+struct ib_queue_pair;
+struct ib_completion_queue;
+
+/** An Infiniband Work Queue */
+struct ib_work_queue {
+ /** Containing queue pair */
+ struct ib_queue_pair *qp;
+ /** "Is a send queue" flag */
+ int is_send;
+ /** Associated completion queue */
+ struct ib_completion_queue *cq;
+ /** List of work queues on this completion queue */
+ struct list_head list;
+ /** Number of work queue entries */
+ unsigned int num_wqes;
+ /** Next work queue entry index
+ *
+ * This is the index of the next entry to be filled (i.e. the
+ * first empty entry). This value is not bounded by num_wqes;
+ * users must logical-AND with (num_wqes-1) to generate an
+ * array index.
+ */
+ unsigned long next_idx;
+ /** I/O buffers assigned to work queue */
+ struct io_buffer **iobufs;
+ /** Driver private data */
+ void *drv_priv;
+};
+
+/** An Infiniband Queue Pair */
+struct ib_queue_pair {
+ /** Queue Pair Number */
+ unsigned long qpn;
+ /** Queue key */
+ unsigned long qkey;
+ /** Send queue */
+ struct ib_work_queue send;
+ /** Receive queue */
+ struct ib_work_queue recv;
+ /** Driver private data */
+ void *drv_priv;
+ /** Queue owner private data */
+ void *owner_priv;
+};
+
+/** An Infiniband Completion Queue */
+struct ib_completion_queue {
+ /** Completion queue number */
+ unsigned long cqn;
+ /** Number of completion queue entries */
+ unsigned int num_cqes;
+ /** Next completion queue entry index
+ *
+ * This is the index of the next entry to be filled (i.e. the
+ * first empty entry). This value is not bounded by num_wqes;
+ * users must logical-AND with (num_wqes-1) to generate an
+ * array index.
+ */
+ unsigned long next_idx;
+ /** List of work queues completing to this queue */
+ struct list_head work_queues;
+ /** Driver private data */
+ void *drv_priv;
+};
+
+/** An Infiniband completion */
+struct ib_completion {
+ /** Syndrome
+ *
+ * If non-zero, then the completion is in error.
+ */
+ unsigned int syndrome;
+ /** Length */
+ size_t len;
+};
+
+/** An Infiniband completion handler
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v completion Completion
+ * @v iobuf I/O buffer
+ */
+typedef void ( * ib_completer_t ) ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp,
+ struct ib_completion *completion,
+ struct io_buffer *iobuf );
+
+/** An Infiniband Address Vector */
+struct ib_address_vector {
+ /** Destination Queue Pair */
+ unsigned int dest_qp;
+ /** Queue key */
+ unsigned long qkey;
+ /** Destination Local ID */
+ unsigned int dlid;
+ /** Rate */
+ unsigned int rate;
+ /** Service level */
+ unsigned int sl;
+ /** GID is present */
+ unsigned int gid_present;
+ /** GID */
+ struct ib_gid gid;
+};
+
+struct ib_mad_hdr;
+
+/**
+ * Infiniband device operations
+ *
+ * These represent a subset of the Infiniband Verbs.
+ */
+struct ib_device_operations {
+ /** Create completion queue
+ *
+ * @v ibdev Infiniband device
+ * @v cq Completion queue
+ * @ret rc Return status code
+ */
+ int ( * create_cq ) ( struct ib_device *ibdev,
+ struct ib_completion_queue *cq );
+ /** Destroy completion queue
+ *
+ * @v ibdev Infiniband device
+ * @v cq Completion queue
+ */
+ void ( * destroy_cq ) ( struct ib_device *ibdev,
+ struct ib_completion_queue *cq );
+ /** Create queue pair
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @ret rc Return status code
+ */
+ int ( * create_qp ) ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp );
+ /** Destroy queue pair
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ */
+ void ( * destroy_qp ) ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp );
+ /** Post send work queue entry
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v av Address vector
+ * @v iobuf I/O buffer
+ * @ret rc Return status code
+ *
+ * If this method returns success, the I/O buffer remains
+ * owned by the queue pair. If this method returns failure,
+ * the I/O buffer is immediately released; the failure is
+ * interpreted as "failure to enqueue buffer".
+ */
+ int ( * post_send ) ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp,
+ struct ib_address_vector *av,
+ struct io_buffer *iobuf );
+ /** Post receive work queue entry
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v iobuf I/O buffer
+ * @ret rc Return status code
+ *
+ * If this method returns success, the I/O buffer remains
+ * owned by the queue pair. If this method returns failure,
+ * the I/O buffer is immediately released; the failure is
+ * interpreted as "failure to enqueue buffer".
+ */
+ int ( * post_recv ) ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp,
+ struct io_buffer *iobuf );
+ /** Poll completion queue
+ *
+ * @v ibdev Infiniband device
+ * @v cq Completion queue
+ * @v complete_send Send completion handler
+ * @v complete_recv Receive completion handler
+ *
+ * The completion handler takes ownership of the I/O buffer.
+ */
+ void ( * poll_cq ) ( struct ib_device *ibdev,
+ struct ib_completion_queue *cq,
+ ib_completer_t complete_send,
+ ib_completer_t complete_recv );
+ /**
+ * Open port
+ *
+ * @v ibdev Infiniband device
+ * @ret rc Return status code
+ */
+ int ( * open ) ( struct ib_device *ibdev );
+ /**
+ * Close port
+ *
+ * @v ibdev Infiniband device
+ */
+ void ( * close ) ( struct ib_device *ibdev );
+ /** Attach to multicast group
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v gid Multicast GID
+ * @ret rc Return status code
+ */
+ int ( * mcast_attach ) ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp,
+ struct ib_gid *gid );
+ /** Detach from multicast group
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v gid Multicast GID
+ */
+ void ( * mcast_detach ) ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp,
+ struct ib_gid *gid );
+ /**
+ * Issue management datagram
+ *
+ * @v ibdev Infiniband device
+ * @v mad Management datagram
+ * @v len Length of management datagram
+ * @ret rc Return status code
+ */
+ int ( * mad ) ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
+ size_t len );
+};
+
+/** An Infiniband device */
+struct ib_device {
+ /** Underlying device */
+ struct device *dev;
+ /** Infiniband operations */
+ struct ib_device_operations *op;
+ /** Port number */
+ unsigned int port;
+ /** Port GID */
+ struct ib_gid port_gid;
+ /** Subnet manager LID */
+ unsigned long sm_lid;
+ /** Partition key */
+ unsigned int pkey;
+ /** Driver private data */
+ void *drv_priv;
+ /** Owner private data */
+ void *owner_priv;
+};
+
+extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
+ unsigned int num_cqes );
+extern void ib_destroy_cq ( struct ib_device *ibdev,
+ struct ib_completion_queue *cq );
+extern struct ib_queue_pair *
+ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
+ struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
+ struct ib_completion_queue *recv_cq, unsigned long qkey );
+extern void ib_destroy_qp ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp );
+extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
+ unsigned long qpn, int is_send );
+extern struct ib_device * alloc_ibdev ( size_t priv_size );
+extern int register_ibdev ( struct ib_device *ibdev );
+extern void unregister_ibdev ( struct ib_device *ibdev );
+extern void free_ibdev ( struct ib_device *ibdev );
+
+/**
+ * Post send work queue entry
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v av Address vector
+ * @v iobuf I/O buffer
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+ struct ib_address_vector *av, struct io_buffer *iobuf ) {
+ return ibdev->op->post_send ( ibdev, qp, av, iobuf );
+}
+
+/**
+ * Post receive work queue entry
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v iobuf I/O buffer
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+ struct io_buffer *iobuf ) {
+ return ibdev->op->post_recv ( ibdev, qp, iobuf );
+}
+
+/**
+ * Poll completion queue
+ *
+ * @v ibdev Infiniband device
+ * @v cq Completion queue
+ * @v complete_send Send completion handler
+ * @v complete_recv Receive completion handler
+ */
+static inline __attribute__ (( always_inline )) void
+ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq,
+ ib_completer_t complete_send, ib_completer_t complete_recv ) {
+ ibdev->op->poll_cq ( ibdev, cq, complete_send, complete_recv );
+}
+
+/**
+ * Open port
+ *
+ * @v ibdev Infiniband device
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+ib_open ( struct ib_device *ibdev ) {
+ return ibdev->op->open ( ibdev );
+}
+
+/**
+ * Close port
+ *
+ * @v ibdev Infiniband device
+ */
+static inline __attribute__ (( always_inline )) void
+ib_close ( struct ib_device *ibdev ) {
+ ibdev->op->close ( ibdev );
+}
+
+/**
+ * Attach to multicast group
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v gid Multicast GID
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+ struct ib_gid *gid ) {
+ return ibdev->op->mcast_attach ( ibdev, qp, gid );
+}
+
+/**
+ * Detach from multicast group
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v gid Multicast GID
+ */
+static inline __attribute__ (( always_inline )) void
+ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+ struct ib_gid *gid ) {
+ ibdev->op->mcast_detach ( ibdev, qp, gid );
+}
+
+/**
+ * Issue management datagram
+ *
+ * @v ibdev Infiniband device
+ * @v mad Management datagram
+ * @v len Length of management datagram
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+ib_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad, size_t len ) {
+ return ibdev->op->mad ( ibdev, mad, len );
+}
+
+/**
+ * Set Infiniband work queue driver-private data
+ *
+ * @v wq Work queue
+ * @v priv Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
+ wq->drv_priv = priv;
+}
+
+/**
+ * Get Infiniband work queue driver-private data
+ *
+ * @v wq Work queue
+ * @ret priv Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
+ return wq->drv_priv;
+}
+
+/**
+ * Set Infiniband queue pair driver-private data
+ *
+ * @v qp Queue pair
+ * @v priv Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
+ qp->drv_priv = priv;
+}
+
+/**
+ * Get Infiniband queue pair driver-private data
+ *
+ * @v qp Queue pair
+ * @ret priv Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
+ return qp->drv_priv;
+}
+
+/**
+ * Set Infiniband queue pair owner-private data
+ *
+ * @v qp Queue pair
+ * @v priv Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
+ qp->owner_priv = priv;
+}
+
+/**
+ * Get Infiniband queue pair owner-private data
+ *
+ * @v qp Queue pair
+ * @ret priv Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
+ return qp->owner_priv;
+}
+
+/**
+ * Set Infiniband completion queue driver-private data
+ *
+ * @v cq Completion queue
+ * @v priv Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
+ cq->drv_priv = priv;
+}
+
+/**
+ * Get Infiniband completion queue driver-private data
+ *
+ * @v cq Completion queue
+ * @ret priv Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
+ return cq->drv_priv;
+}
+
+/**
+ * Set Infiniband device driver-private data
+ *
+ * @v ibdev Infiniband device
+ * @v priv Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
+ ibdev->drv_priv = priv;
+}
+
+/**
+ * Get Infiniband device driver-private data
+ *
+ * @v ibdev Infiniband device
+ * @ret priv Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_get_drvdata ( struct ib_device *ibdev ) {
+ return ibdev->drv_priv;
+}
+
+/**
+ * Set Infiniband device owner-private data
+ *
+ * @v ibdev Infiniband device
+ * @v priv Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
+ ibdev->owner_priv = priv;
+}
+
+/**
+ * Get Infiniband device owner-private data
+ *
+ * @v ibdev Infiniband device
+ * @ret priv Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_get_ownerdata ( struct ib_device *ibdev ) {
+ return ibdev->owner_priv;
+}
+
+/*****************************************************************************
+ *
+ * Management datagrams
+ *
+ * Portions Copyright (c) 2004 Mellanox Technologies Ltd. All rights
+ * reserved.
+ *
+ */
+
+/* Management base version */
+#define IB_MGMT_BASE_VERSION 1
+
+/* Management classes */
+#define IB_MGMT_CLASS_SUBN_LID_ROUTED 0x01
+#define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE 0x81
+#define IB_MGMT_CLASS_SUBN_ADM 0x03
+#define IB_MGMT_CLASS_PERF_MGMT 0x04
+#define IB_MGMT_CLASS_BM 0x05
+#define IB_MGMT_CLASS_DEVICE_MGMT 0x06
+#define IB_MGMT_CLASS_CM 0x07
+#define IB_MGMT_CLASS_SNMP 0x08
+#define IB_MGMT_CLASS_VENDOR_RANGE2_START 0x30
+#define IB_MGMT_CLASS_VENDOR_RANGE2_END 0x4F
+
+/* Management methods */
+#define IB_MGMT_METHOD_GET 0x01
+#define IB_MGMT_METHOD_SET 0x02
+#define IB_MGMT_METHOD_GET_RESP 0x81
+#define IB_MGMT_METHOD_SEND 0x03
+#define IB_MGMT_METHOD_TRAP 0x05
+#define IB_MGMT_METHOD_REPORT 0x06
+#define IB_MGMT_METHOD_REPORT_RESP 0x86
+#define IB_MGMT_METHOD_TRAP_REPRESS 0x07
+#define IB_MGMT_METHOD_DELETE 0x15
+#define IB_MGMT_METHOD_RESP 0x80
+
+/* Subnet management attributes */
+#define IB_SMP_ATTR_NOTICE 0x0002
+#define IB_SMP_ATTR_NODE_DESC 0x0010
+#define IB_SMP_ATTR_NODE_INFO 0x0011
+#define IB_SMP_ATTR_SWITCH_INFO 0x0012
+#define IB_SMP_ATTR_GUID_INFO 0x0014
+#define IB_SMP_ATTR_PORT_INFO 0x0015
+#define IB_SMP_ATTR_PKEY_TABLE 0x0016
+#define IB_SMP_ATTR_SL_TO_VL_TABLE 0x0017
+#define IB_SMP_ATTR_VL_ARB_TABLE 0x0018
+#define IB_SMP_ATTR_LINEAR_FORWARD_TABLE 0x0019
+#define IB_SMP_ATTR_RANDOM_FORWARD_TABLE 0x001A
+#define IB_SMP_ATTR_MCAST_FORWARD_TABLE 0x001B
+#define IB_SMP_ATTR_SM_INFO 0x0020
+#define IB_SMP_ATTR_VENDOR_DIAG 0x0030
+#define IB_SMP_ATTR_LED_INFO 0x0031
+#define IB_SMP_ATTR_VENDOR_MASK 0xFF00
+
+#define IB_SA_ATTR_MC_MEMBER_REC 0x38
+#define IB_SA_ATTR_PATH_REC 0x35
+
+#define IB_SA_MCMEMBER_REC_MGID (1<<0)
+#define IB_SA_MCMEMBER_REC_PORT_GID (1<<1)
+#define IB_SA_MCMEMBER_REC_QKEY (1<<2)
+#define IB_SA_MCMEMBER_REC_MLID (1<<3)
+#define IB_SA_MCMEMBER_REC_MTU_SELECTOR (1<<4)
+#define IB_SA_MCMEMBER_REC_MTU (1<<5)
+#define IB_SA_MCMEMBER_REC_TRAFFIC_CLASS (1<<6)
+#define IB_SA_MCMEMBER_REC_PKEY (1<<7)
+#define IB_SA_MCMEMBER_REC_RATE_SELECTOR (1<<8)
+#define IB_SA_MCMEMBER_REC_RATE (1<<9)
+#define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR (1<<10)
+#define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME (1<<11)
+#define IB_SA_MCMEMBER_REC_SL (1<<12)
+#define IB_SA_MCMEMBER_REC_FLOW_LABEL (1<<13)
+#define IB_SA_MCMEMBER_REC_HOP_LIMIT (1<<14)
+#define IB_SA_MCMEMBER_REC_SCOPE (1<<15)
+#define IB_SA_MCMEMBER_REC_JOIN_STATE (1<<16)
+#define IB_SA_MCMEMBER_REC_PROXY_JOIN (1<<17)
+
+#define IB_SA_PATH_REC_DGID (1<<2)
+#define IB_SA_PATH_REC_SGID (1<<3)
+
+struct ib_mad_hdr {
+ uint8_t base_version;
+ uint8_t mgmt_class;
+ uint8_t class_version;
+ uint8_t method;
+ uint16_t status;
+ uint16_t class_specific;
+ uint32_t tid[2];
+ uint16_t attr_id;
+ uint16_t resv;
+ uint32_t attr_mod;
+} __attribute__ (( packed ));
+
+struct ib_sa_hdr {
+ uint32_t sm_key[2];
+ uint16_t reserved;
+ uint16_t attrib_offset;
+ uint32_t comp_mask[2];
+} __attribute__ (( packed ));
+
+struct ib_rmpp_hdr {
+ uint32_t raw[3];
+} __attribute__ (( packed ));
+
+struct ib_mad_data {
+ struct ib_mad_hdr mad_hdr;
+ uint8_t data[232];
+} __attribute__ (( packed ));
+
+struct ib_mad_guid_info {
+ struct ib_mad_hdr mad_hdr;
+ uint32_t mkey[2];
+ uint32_t reserved[8];
+ uint8_t gid_local[8];
+} __attribute__ (( packed ));
+
+struct ib_mad_port_info {
+ struct ib_mad_hdr mad_hdr;
+ uint32_t mkey[2];
+ uint32_t reserved[8];
+ uint32_t mkey2[2];
+ uint8_t gid_prefix[8];
+ uint16_t lid;
+ uint16_t mastersm_lid;
+ uint32_t cap_mask;
+ uint16_t diag_code;
+ uint16_t mkey_lease_period;
+ uint8_t local_port_num;
+ uint8_t link_width_enabled;
+ uint8_t link_width_supported;
+ uint8_t link_width_active;
+ uint8_t port_state__link_speed_supported;
+ uint8_t link_down_def_state__port_phys_state;
+ uint8_t lmc__r1__mkey_prot_bits;
+ uint8_t link_speed_enabled__link_speed_active;
+} __attribute__ (( packed ));
+
+struct ib_mad_pkey_table {
+ struct ib_mad_hdr mad_hdr;
+ uint32_t mkey[2];
+ uint32_t reserved[8];
+ uint16_t pkey[16][2];
+} __attribute__ (( packed ));
+
+struct ib_mad_path_record {
+ struct ib_mad_hdr mad_hdr;
+ struct ib_rmpp_hdr rmpp_hdr;
+ struct ib_sa_hdr sa_hdr;
+ uint32_t reserved0[2];
+ struct ib_gid dgid;
+ struct ib_gid sgid;
+ uint16_t dlid;
+ uint16_t slid;
+ uint32_t hop_limit__flow_label__raw_traffic;
+ uint32_t pkey__numb_path__reversible__tclass;
+ uint8_t reserved1;
+ uint8_t reserved__sl;
+ uint8_t mtu_selector__mtu;
+ uint8_t rate_selector__rate;
+ uint32_t preference__packet_lifetime__packet_lifetime_selector;
+ uint32_t reserved2[35];
+} __attribute__ (( packed ));
+
+struct ib_mad_mc_member_record {
+ struct ib_mad_hdr mad_hdr;
+ struct ib_rmpp_hdr rmpp_hdr;
+ struct ib_sa_hdr sa_hdr;
+ struct ib_gid mgid;
+ struct ib_gid port_gid;
+ uint32_t qkey;
+ uint16_t mlid;
+ uint8_t mtu_selector__mtu;
+ uint8_t tclass;
+ uint16_t pkey;
+ uint8_t rate_selector__rate;
+ uint8_t packet_lifetime_selector__packet_lifetime;
+ uint32_t sl__flow_label__hop_limit;
+ uint8_t scope__join_state;
+ uint8_t proxy_join__reserved;
+ uint16_t reserved0;
+ uint32_t reserved1[37];
+} __attribute__ (( packed ));
+
+union ib_mad {
+ struct ib_mad_hdr mad_hdr;
+ struct ib_mad_data data;
+ struct ib_mad_guid_info guid_info;
+ struct ib_mad_port_info port_info;
+ struct ib_mad_pkey_table pkey_table;
+ struct ib_mad_path_record path_record;
+ struct ib_mad_mc_member_record mc_member_record;
+} __attribute__ (( packed ));
+
+#endif /* _GPXE_INFINIBAND_H */