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