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