8fc928c71ece9f447dbcbb454e3bad41bad8830e
[people/mdeck/gpxe.git] / src / include / gpxe / infiniband.h
1 #ifndef _GPXE_INFINIBAND_H
2 #define _GPXE_INFINIBAND_H
3
4 /** @file
5  *
6  * Infiniband protocol
7  *
8  */
9
10 #include <stdint.h>
11 #include <gpxe/device.h>
12
13 /** Subnet administrator QPN */
14 #define IB_SA_QPN 1
15
16 /** Broadcast QPN */
17 #define IB_BROADCAST_QPN 0xffffffUL
18
19 /** Subnet administrator queue key */
20 #define IB_GLOBAL_QKEY 0x80010000UL
21
22 /** An Infiniband Global Identifier */
23 struct ib_gid {
24         union {
25                 uint8_t bytes[16];
26                 uint16_t words[8];
27                 uint32_t dwords[4];
28         } u;
29 };
30
31 /** An Infiniband Global Route Header */
32 struct ib_global_route_header {
33         /** IP version, traffic class, and flow label
34          *
35          *  4 bits : Version of the GRH
36          *  8 bits : Traffic class
37          * 20 bits : Flow label
38          */
39         uint32_t ipver_tclass_flowlabel;
40         /** Payload length */
41         uint16_t paylen;
42         /** Next header */
43         uint8_t nxthdr;
44         /** Hop limit */
45         uint8_t hoplmt;
46         /** Source GID */
47         struct ib_gid sgid;
48         /** Destiniation GID */
49         struct ib_gid dgid;
50 } __attribute__ (( packed ));
51
52 struct ib_device;
53 struct ib_queue_pair;
54 struct ib_completion_queue;
55
56 /** An Infiniband Work Queue */
57 struct ib_work_queue {
58         /** Containing queue pair */
59         struct ib_queue_pair *qp;
60         /** "Is a send queue" flag */
61         int is_send;
62         /** Associated completion queue */
63         struct ib_completion_queue *cq;
64         /** List of work queues on this completion queue */
65         struct list_head list;
66         /** Number of work queue entries */
67         unsigned int num_wqes;
68         /** Next work queue entry index
69          *
70          * This is the index of the next entry to be filled (i.e. the
71          * first empty entry).  This value is not bounded by num_wqes;
72          * users must logical-AND with (num_wqes-1) to generate an
73          * array index.
74          */
75         unsigned long next_idx;
76         /** I/O buffers assigned to work queue */
77         struct io_buffer **iobufs;
78         /** Driver private data */
79         void *drv_priv;
80 };
81
82 /** An Infiniband Queue Pair */
83 struct ib_queue_pair {
84         /** Queue Pair Number */
85         unsigned long qpn;
86         /** Queue key */
87         unsigned long qkey;
88         /** Send queue */
89         struct ib_work_queue send;
90         /** Receive queue */
91         struct ib_work_queue recv;
92         /** Driver private data */
93         void *drv_priv;
94         /** Queue owner private data */
95         void *owner_priv;
96 };
97
98 /** Infiniband queue pair modification flags */
99 enum ib_queue_pair_mods {
100         IB_MODIFY_QKEY = 0x0001,
101 };
102
103 /** An Infiniband Completion Queue */
104 struct ib_completion_queue {
105         /** Completion queue number */
106         unsigned long cqn;
107         /** Number of completion queue entries */
108         unsigned int num_cqes;
109         /** Next completion queue entry index
110          *
111          * This is the index of the next entry to be filled (i.e. the
112          * first empty entry).  This value is not bounded by num_wqes;
113          * users must logical-AND with (num_wqes-1) to generate an
114          * array index.
115          */
116         unsigned long next_idx;
117         /** List of work queues completing to this queue */
118         struct list_head work_queues;
119         /** Driver private data */
120         void *drv_priv;
121 };
122
123 /** An Infiniband completion */
124 struct ib_completion {
125         /** Syndrome
126          *
127          * If non-zero, then the completion is in error.
128          */
129         unsigned int syndrome;
130         /** Length */
131         size_t len;
132 };
133
134 /** An Infiniband completion handler
135  *
136  * @v ibdev             Infiniband device
137  * @v qp                Queue pair
138  * @v completion        Completion
139  * @v iobuf             I/O buffer
140  */
141 typedef void ( * ib_completer_t ) ( struct ib_device *ibdev,
142                                     struct ib_queue_pair *qp,
143                                     struct ib_completion *completion,
144                                     struct io_buffer *iobuf );
145
146 /** An Infiniband Address Vector */
147 struct ib_address_vector {
148         /** Destination Queue Pair */
149         unsigned int dest_qp;
150         /** Queue key */
151         unsigned long qkey;
152         /** Destination Local ID */
153         unsigned int dlid;
154         /** Rate */
155         unsigned int rate;
156         /** Service level */
157         unsigned int sl;
158         /** GID is present */
159         unsigned int gid_present;
160         /** GID */
161         struct ib_gid gid;
162 };
163
164 struct ib_mad_hdr;
165
166 /**
167  * Infiniband device operations
168  *
169  * These represent a subset of the Infiniband Verbs.
170  */
171 struct ib_device_operations {
172         /** Create completion queue
173          *
174          * @v ibdev             Infiniband device
175          * @v cq                Completion queue
176          * @ret rc              Return status code
177          */
178         int ( * create_cq ) ( struct ib_device *ibdev,
179                               struct ib_completion_queue *cq );
180         /** Destroy completion queue
181          *
182          * @v ibdev             Infiniband device
183          * @v cq                Completion queue
184          */
185         void ( * destroy_cq ) ( struct ib_device *ibdev,
186                                 struct ib_completion_queue *cq );
187         /** Create queue pair
188          *
189          * @v ibdev             Infiniband device
190          * @v qp                Queue pair
191          * @ret rc              Return status code
192          */
193         int ( * create_qp ) ( struct ib_device *ibdev,
194                               struct ib_queue_pair *qp );
195         /** Modify queue pair
196          *
197          * @v ibdev             Infiniband device
198          * @v qp                Queue pair
199          * @v mod_list          Modification list
200          * @ret rc              Return status code
201          */
202         int ( * modify_qp ) ( struct ib_device *ibdev,
203                               struct ib_queue_pair *qp,
204                               unsigned long mod_list );
205         /** Destroy queue pair
206          *
207          * @v ibdev             Infiniband device
208          * @v qp                Queue pair
209          */
210         void ( * destroy_qp ) ( struct ib_device *ibdev,
211                                 struct ib_queue_pair *qp );
212         /** Post send work queue entry
213          *
214          * @v ibdev             Infiniband device
215          * @v qp                Queue pair
216          * @v av                Address vector
217          * @v iobuf             I/O buffer
218          * @ret rc              Return status code
219          *
220          * If this method returns success, the I/O buffer remains
221          * owned by the queue pair.  If this method returns failure,
222          * the I/O buffer is immediately released; the failure is
223          * interpreted as "failure to enqueue buffer".
224          */
225         int ( * post_send ) ( struct ib_device *ibdev,
226                               struct ib_queue_pair *qp,
227                               struct ib_address_vector *av,
228                               struct io_buffer *iobuf );
229         /** Post receive work queue entry
230          *
231          * @v ibdev             Infiniband device
232          * @v qp                Queue pair
233          * @v iobuf             I/O buffer
234          * @ret rc              Return status code
235          *
236          * If this method returns success, the I/O buffer remains
237          * owned by the queue pair.  If this method returns failure,
238          * the I/O buffer is immediately released; the failure is
239          * interpreted as "failure to enqueue buffer".
240          */
241         int ( * post_recv ) ( struct ib_device *ibdev,
242                               struct ib_queue_pair *qp,
243                               struct io_buffer *iobuf );
244         /** Poll completion queue
245          *
246          * @v ibdev             Infiniband device
247          * @v cq                Completion queue
248          * @v complete_send     Send completion handler
249          * @v complete_recv     Receive completion handler
250          *
251          * The completion handler takes ownership of the I/O buffer.
252          */
253         void ( * poll_cq ) ( struct ib_device *ibdev,
254                              struct ib_completion_queue *cq,
255                              ib_completer_t complete_send,
256                              ib_completer_t complete_recv );
257         /**
258          * Open port
259          *
260          * @v ibdev             Infiniband device
261          * @ret rc              Return status code
262          */
263         int ( * open ) ( struct ib_device *ibdev );
264         /**
265          * Close port
266          *
267          * @v ibdev             Infiniband device
268          */
269         void ( * close ) ( struct ib_device *ibdev );
270         /** Attach to multicast group
271          *
272          * @v ibdev             Infiniband device
273          * @v qp                Queue pair
274          * @v gid               Multicast GID
275          * @ret rc              Return status code
276          */
277         int ( * mcast_attach ) ( struct ib_device *ibdev,
278                                  struct ib_queue_pair *qp,
279                                  struct ib_gid *gid );
280         /** Detach from multicast group
281          *
282          * @v ibdev             Infiniband device
283          * @v qp                Queue pair
284          * @v gid               Multicast GID
285          */
286         void ( * mcast_detach ) ( struct ib_device *ibdev,
287                                   struct ib_queue_pair *qp,
288                                   struct ib_gid *gid );
289         /**
290          * Issue management datagram
291          *
292          * @v ibdev             Infiniband device
293          * @v mad               Management datagram
294          * @v len               Length of management datagram
295          * @ret rc              Return status code
296          */
297         int ( * mad ) ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
298                         size_t len );
299 };
300
301 /** An Infiniband device */
302 struct ib_device {
303         /** Underlying device */
304         struct device *dev;
305         /** Infiniband operations */
306         struct ib_device_operations *op;
307         /** Port number */
308         unsigned int port;
309         /** Link state */
310         int link_up;
311         /** Port GID */
312         struct ib_gid port_gid;
313         /** Subnet manager LID */
314         unsigned long sm_lid;
315         /** Partition key */
316         unsigned int pkey;
317         /** Driver private data */
318         void *drv_priv;
319         /** Owner private data */
320         void *owner_priv;
321 };
322
323 extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
324                                                    unsigned int num_cqes );
325 extern void ib_destroy_cq ( struct ib_device *ibdev,
326                             struct ib_completion_queue *cq );
327 extern struct ib_queue_pair *
328 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
329                struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
330                struct ib_completion_queue *recv_cq, unsigned long qkey );
331 extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
332                           unsigned long mod_list, unsigned long qkey );
333 extern void ib_destroy_qp ( struct ib_device *ibdev,
334                             struct ib_queue_pair *qp );
335 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
336                                            unsigned long qpn, int is_send );
337 extern struct ib_device * alloc_ibdev ( size_t priv_size );
338 extern int register_ibdev ( struct ib_device *ibdev );
339 extern void unregister_ibdev ( struct ib_device *ibdev );
340 extern void free_ibdev ( struct ib_device *ibdev );
341 extern void ib_link_state_changed ( struct ib_device *ibdev );
342
343 /**
344  * Post send work queue entry
345  *
346  * @v ibdev             Infiniband device
347  * @v qp                Queue pair
348  * @v av                Address vector
349  * @v iobuf             I/O buffer
350  * @ret rc              Return status code
351  */
352 static inline __attribute__ (( always_inline )) int
353 ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
354                struct ib_address_vector *av, struct io_buffer *iobuf ) {
355         return ibdev->op->post_send ( ibdev, qp, av, iobuf );
356 }
357
358 /**
359  * Post receive work queue entry
360  *
361  * @v ibdev             Infiniband device
362  * @v qp                Queue pair
363  * @v iobuf             I/O buffer
364  * @ret rc              Return status code
365  */
366 static inline __attribute__ (( always_inline )) int
367 ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
368                struct io_buffer *iobuf ) {
369         return ibdev->op->post_recv ( ibdev, qp, iobuf );
370 }
371
372 /**
373  * Poll completion queue
374  *
375  * @v ibdev             Infiniband device
376  * @v cq                Completion queue
377  * @v complete_send     Send completion handler
378  * @v complete_recv     Receive completion handler
379  */
380 static inline __attribute__ (( always_inline )) void
381 ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq,
382              ib_completer_t complete_send, ib_completer_t complete_recv ) {
383         ibdev->op->poll_cq ( ibdev, cq, complete_send, complete_recv );
384 }
385
386 /**
387  * Open port
388  *
389  * @v ibdev             Infiniband device
390  * @ret rc              Return status code
391  */
392 static inline __attribute__ (( always_inline )) int
393 ib_open ( struct ib_device *ibdev ) {
394         return ibdev->op->open ( ibdev );
395 }
396
397 /**
398  * Close port
399  *
400  * @v ibdev             Infiniband device
401  */
402 static inline __attribute__ (( always_inline )) void
403 ib_close ( struct ib_device *ibdev ) {
404         ibdev->op->close ( ibdev );
405 }
406
407 /**
408  * Attach to multicast group
409  *
410  * @v ibdev             Infiniband device
411  * @v qp                Queue pair
412  * @v gid               Multicast GID
413  * @ret rc              Return status code
414  */
415 static inline __attribute__ (( always_inline )) int
416 ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
417                   struct ib_gid *gid ) {
418         return ibdev->op->mcast_attach ( ibdev, qp, gid );
419 }
420
421 /**
422  * Detach from multicast group
423  *
424  * @v ibdev             Infiniband device
425  * @v qp                Queue pair
426  * @v gid               Multicast GID
427  */
428 static inline __attribute__ (( always_inline )) void
429 ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
430                   struct ib_gid *gid ) {
431         ibdev->op->mcast_detach ( ibdev, qp, gid );
432 }
433
434 /**
435  * Issue management datagram
436  *
437  * @v ibdev             Infiniband device
438  * @v mad               Management datagram
439  * @v len               Length of management datagram
440  * @ret rc              Return status code
441  */
442 static inline __attribute__ (( always_inline )) int
443 ib_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad, size_t len ) {
444         return ibdev->op->mad ( ibdev, mad, len );
445 }
446
447 /**
448  * Set Infiniband work queue driver-private data
449  *
450  * @v wq                Work queue
451  * @v priv              Private data
452  */
453 static inline __attribute__ (( always_inline )) void
454 ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
455         wq->drv_priv = priv;
456 }
457
458 /**
459  * Get Infiniband work queue driver-private data
460  *
461  * @v wq                Work queue
462  * @ret priv            Private data
463  */
464 static inline __attribute__ (( always_inline )) void *
465 ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
466         return wq->drv_priv;
467 }
468
469 /**
470  * Set Infiniband queue pair driver-private data
471  *
472  * @v qp                Queue pair
473  * @v priv              Private data
474  */
475 static inline __attribute__ (( always_inline )) void
476 ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
477         qp->drv_priv = priv;
478 }
479
480 /**
481  * Get Infiniband queue pair driver-private data
482  *
483  * @v qp                Queue pair
484  * @ret priv            Private data
485  */
486 static inline __attribute__ (( always_inline )) void *
487 ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
488         return qp->drv_priv;
489 }
490
491 /**
492  * Set Infiniband queue pair owner-private data
493  *
494  * @v qp                Queue pair
495  * @v priv              Private data
496  */
497 static inline __attribute__ (( always_inline )) void
498 ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
499         qp->owner_priv = priv;
500 }
501
502 /**
503  * Get Infiniband queue pair owner-private data
504  *
505  * @v qp                Queue pair
506  * @ret priv            Private data
507  */
508 static inline __attribute__ (( always_inline )) void *
509 ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
510         return qp->owner_priv;
511 }
512
513 /**
514  * Set Infiniband completion queue driver-private data
515  *
516  * @v cq                Completion queue
517  * @v priv              Private data
518  */
519 static inline __attribute__ (( always_inline )) void
520 ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
521         cq->drv_priv = priv;
522 }
523
524 /**
525  * Get Infiniband completion queue driver-private data
526  *
527  * @v cq                Completion queue
528  * @ret priv            Private data
529  */
530 static inline __attribute__ (( always_inline )) void *
531 ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
532         return cq->drv_priv;
533 }
534
535 /**
536  * Set Infiniband device driver-private data
537  *
538  * @v ibdev             Infiniband device
539  * @v priv              Private data
540  */
541 static inline __attribute__ (( always_inline )) void
542 ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
543         ibdev->drv_priv = priv;
544 }
545
546 /**
547  * Get Infiniband device driver-private data
548  *
549  * @v ibdev             Infiniband device
550  * @ret priv            Private data
551  */
552 static inline __attribute__ (( always_inline )) void *
553 ib_get_drvdata ( struct ib_device *ibdev ) {
554         return ibdev->drv_priv;
555 }
556
557 /**
558  * Set Infiniband device owner-private data
559  *
560  * @v ibdev             Infiniband device
561  * @v priv              Private data
562  */
563 static inline __attribute__ (( always_inline )) void
564 ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
565         ibdev->owner_priv = priv;
566 }
567
568 /**
569  * Get Infiniband device owner-private data
570  *
571  * @v ibdev             Infiniband device
572  * @ret priv            Private data
573  */
574 static inline __attribute__ (( always_inline )) void *
575 ib_get_ownerdata ( struct ib_device *ibdev ) {
576         return ibdev->owner_priv;
577 }
578
579 /*****************************************************************************
580  *
581  * Management datagrams
582  *
583  * Portions Copyright (c) 2004 Mellanox Technologies Ltd.  All rights
584  * reserved.
585  *
586  */
587
588 /* Management base version */
589 #define IB_MGMT_BASE_VERSION                    1
590
591 /* Management classes */
592 #define IB_MGMT_CLASS_SUBN_LID_ROUTED           0x01
593 #define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE       0x81
594 #define IB_MGMT_CLASS_SUBN_ADM                  0x03
595 #define IB_MGMT_CLASS_PERF_MGMT                 0x04
596 #define IB_MGMT_CLASS_BM                        0x05
597 #define IB_MGMT_CLASS_DEVICE_MGMT               0x06
598 #define IB_MGMT_CLASS_CM                        0x07
599 #define IB_MGMT_CLASS_SNMP                      0x08
600 #define IB_MGMT_CLASS_VENDOR_RANGE2_START       0x30
601 #define IB_MGMT_CLASS_VENDOR_RANGE2_END         0x4F
602
603 /* Management methods */
604 #define IB_MGMT_METHOD_GET                      0x01
605 #define IB_MGMT_METHOD_SET                      0x02
606 #define IB_MGMT_METHOD_GET_RESP                 0x81
607 #define IB_MGMT_METHOD_SEND                     0x03
608 #define IB_MGMT_METHOD_TRAP                     0x05
609 #define IB_MGMT_METHOD_REPORT                   0x06
610 #define IB_MGMT_METHOD_REPORT_RESP              0x86
611 #define IB_MGMT_METHOD_TRAP_REPRESS             0x07
612 #define IB_MGMT_METHOD_DELETE                   0x15
613 #define IB_MGMT_METHOD_RESP                     0x80
614
615 /* Subnet management attributes */
616 #define IB_SMP_ATTR_NOTICE                      0x0002
617 #define IB_SMP_ATTR_NODE_DESC                   0x0010
618 #define IB_SMP_ATTR_NODE_INFO                   0x0011
619 #define IB_SMP_ATTR_SWITCH_INFO                 0x0012
620 #define IB_SMP_ATTR_GUID_INFO                   0x0014
621 #define IB_SMP_ATTR_PORT_INFO                   0x0015
622 #define IB_SMP_ATTR_PKEY_TABLE                  0x0016
623 #define IB_SMP_ATTR_SL_TO_VL_TABLE              0x0017
624 #define IB_SMP_ATTR_VL_ARB_TABLE                0x0018
625 #define IB_SMP_ATTR_LINEAR_FORWARD_TABLE        0x0019
626 #define IB_SMP_ATTR_RANDOM_FORWARD_TABLE        0x001A
627 #define IB_SMP_ATTR_MCAST_FORWARD_TABLE         0x001B
628 #define IB_SMP_ATTR_SM_INFO                     0x0020
629 #define IB_SMP_ATTR_VENDOR_DIAG                 0x0030
630 #define IB_SMP_ATTR_LED_INFO                    0x0031
631 #define IB_SMP_ATTR_VENDOR_MASK                 0xFF00
632
633 #define IB_SA_ATTR_MC_MEMBER_REC                0x38
634 #define IB_SA_ATTR_PATH_REC                     0x35
635
636 #define IB_SA_MCMEMBER_REC_MGID                 (1<<0)
637 #define IB_SA_MCMEMBER_REC_PORT_GID             (1<<1)
638 #define IB_SA_MCMEMBER_REC_QKEY                 (1<<2)
639 #define IB_SA_MCMEMBER_REC_MLID                 (1<<3)
640 #define IB_SA_MCMEMBER_REC_MTU_SELECTOR         (1<<4)
641 #define IB_SA_MCMEMBER_REC_MTU                  (1<<5)
642 #define IB_SA_MCMEMBER_REC_TRAFFIC_CLASS        (1<<6)
643 #define IB_SA_MCMEMBER_REC_PKEY                 (1<<7)
644 #define IB_SA_MCMEMBER_REC_RATE_SELECTOR        (1<<8)
645 #define IB_SA_MCMEMBER_REC_RATE                 (1<<9)
646 #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR    (1<<10)
647 #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME     (1<<11)
648 #define IB_SA_MCMEMBER_REC_SL                   (1<<12)
649 #define IB_SA_MCMEMBER_REC_FLOW_LABEL           (1<<13)
650 #define IB_SA_MCMEMBER_REC_HOP_LIMIT            (1<<14)
651 #define IB_SA_MCMEMBER_REC_SCOPE                (1<<15)
652 #define IB_SA_MCMEMBER_REC_JOIN_STATE           (1<<16)
653 #define IB_SA_MCMEMBER_REC_PROXY_JOIN           (1<<17)
654
655 #define IB_SA_PATH_REC_DGID                     (1<<2)
656 #define IB_SA_PATH_REC_SGID                     (1<<3)
657
658 struct ib_mad_hdr {
659         uint8_t base_version;
660         uint8_t mgmt_class;
661         uint8_t class_version;
662         uint8_t method;
663         uint16_t status;
664         uint16_t class_specific;
665         uint32_t tid[2];
666         uint16_t attr_id;
667         uint16_t resv;
668         uint32_t attr_mod;
669 } __attribute__ (( packed ));
670
671 struct ib_sa_hdr {
672         uint32_t sm_key[2];
673         uint16_t reserved;
674         uint16_t attrib_offset;
675         uint32_t comp_mask[2];
676 } __attribute__ (( packed ));
677
678 struct ib_rmpp_hdr {
679         uint32_t raw[3];
680 } __attribute__ (( packed ));
681
682 struct ib_mad_data {
683         struct ib_mad_hdr mad_hdr;
684         uint8_t data[232];
685 } __attribute__ (( packed ));
686
687 struct ib_mad_guid_info {
688         struct ib_mad_hdr mad_hdr;
689         uint32_t mkey[2];
690         uint32_t reserved[8];
691         uint8_t gid_local[8];
692 } __attribute__ (( packed ));
693
694 struct ib_mad_port_info {
695         struct ib_mad_hdr mad_hdr;
696         uint32_t mkey[2];
697         uint32_t reserved[8];
698         uint32_t mkey2[2];
699         uint8_t gid_prefix[8];
700         uint16_t lid;
701         uint16_t mastersm_lid;
702         uint32_t cap_mask;
703         uint16_t diag_code;
704         uint16_t mkey_lease_period;
705         uint8_t local_port_num;
706         uint8_t link_width_enabled;
707         uint8_t link_width_supported;
708         uint8_t link_width_active;
709         uint8_t port_state__link_speed_supported;
710         uint8_t link_down_def_state__port_phys_state;
711         uint8_t lmc__r1__mkey_prot_bits;
712         uint8_t link_speed_enabled__link_speed_active;
713 } __attribute__ (( packed ));
714
715 struct ib_mad_pkey_table {
716         struct ib_mad_hdr mad_hdr;
717         uint32_t mkey[2];
718         uint32_t reserved[8];
719         uint16_t pkey[16][2];
720 } __attribute__ (( packed ));
721
722 struct ib_mad_path_record {
723         struct ib_mad_hdr mad_hdr;
724         struct ib_rmpp_hdr rmpp_hdr;
725         struct ib_sa_hdr sa_hdr;
726         uint32_t reserved0[2];
727         struct ib_gid dgid;
728         struct ib_gid sgid;
729         uint16_t dlid;
730         uint16_t slid;
731         uint32_t hop_limit__flow_label__raw_traffic;
732         uint32_t pkey__numb_path__reversible__tclass;
733         uint8_t reserved1;
734         uint8_t reserved__sl;
735         uint8_t mtu_selector__mtu;
736         uint8_t rate_selector__rate;
737         uint32_t preference__packet_lifetime__packet_lifetime_selector;
738         uint32_t reserved2[35];
739 } __attribute__ (( packed ));
740
741 struct ib_mad_mc_member_record {
742         struct ib_mad_hdr mad_hdr;
743         struct ib_rmpp_hdr rmpp_hdr;
744         struct ib_sa_hdr sa_hdr;
745         struct ib_gid mgid;
746         struct ib_gid port_gid;
747         uint32_t qkey;
748         uint16_t mlid;
749         uint8_t mtu_selector__mtu;
750         uint8_t tclass;
751         uint16_t pkey;
752         uint8_t rate_selector__rate;
753         uint8_t packet_lifetime_selector__packet_lifetime;
754         uint32_t sl__flow_label__hop_limit;
755         uint8_t scope__join_state;
756         uint8_t proxy_join__reserved;
757         uint16_t reserved0;
758         uint32_t reserved1[37];
759 } __attribute__ (( packed ));
760
761 union ib_mad {
762         struct ib_mad_hdr mad_hdr;
763         struct ib_mad_data data;
764         struct ib_mad_guid_info guid_info;
765         struct ib_mad_port_info port_info;
766         struct ib_mad_pkey_table pkey_table;
767         struct ib_mad_path_record path_record;
768         struct ib_mad_mc_member_record mc_member_record;
769 } __attribute__ (( packed ));
770
771 #endif /* _GPXE_INFINIBAND_H */