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