Use pkey table access to determine broadcast GID directly.
[people/xl0/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 /** An Infiniband Global Identifier */
14 struct ib_gid {
15         uint8_t bytes[16];
16 };
17
18 /** An Infiniband Global Route Header */
19 struct ib_global_route_header {
20         /** IP version, traffic class, and flow label
21          *
22          *  4 bits : Version of the GRH
23          *  8 bits : Traffic class
24          * 20 bits : Flow label
25          */
26         uint32_t ipver_tclass_flowlabel;
27         /** Payload length */
28         uint16_t paylen;
29         /** Next header */
30         uint8_t nxthdr;
31         /** Hop limit */
32         uint8_t hoplmt;
33         /** Source GID */
34         struct ib_gid sgid;
35         /** Destiniation GID */
36         struct ib_gid dgid;
37 } __attribute__ (( packed ));
38
39 struct ib_device;
40 struct ib_queue_pair;
41 struct ib_completion_queue;
42
43 /** An Infiniband Work Queue */
44 struct ib_work_queue {
45         /** Containing queue pair */
46         struct ib_queue_pair *qp;
47         /** "Is a send queue" flag */
48         int is_send;
49         /** Associated completion queue */
50         struct ib_completion_queue *cq;
51         /** List of work queues on this completion queue */
52         struct list_head list;
53         /** Number of work queue entries */
54         unsigned int num_wqes;
55         /** Next work queue entry index
56          *
57          * This is the index of the next entry to be filled (i.e. the
58          * first empty entry).  This value is not bounded by num_wqes;
59          * users must logical-AND with (num_wqes-1) to generate an
60          * array index.
61          */
62         unsigned long next_idx;
63         /** I/O buffers assigned to work queue */
64         struct io_buffer **iobufs;
65         /** Device private data */
66         void *dev_priv;
67 };
68
69 /** An Infiniband Queue Pair */
70 struct ib_queue_pair {
71         /** Queue Pair Number */
72         unsigned long qpn;
73         /** Queue key */
74         unsigned long qkey;
75         /** Send queue */
76         struct ib_work_queue send;
77         /** Receive queue */
78         struct ib_work_queue recv;
79         /** Device private data */
80         void *dev_priv;
81         /** Queue owner private data */
82         void *owner_priv;
83 };
84
85 /** An Infiniband Completion Queue */
86 struct ib_completion_queue {
87         /** Completion queue number */
88         unsigned long cqn;
89         /** Number of completion queue entries */
90         unsigned int num_cqes;
91         /** Next completion queue entry index
92          *
93          * This is the index of the next entry to be filled (i.e. the
94          * first empty entry).  This value is not bounded by num_wqes;
95          * users must logical-AND with (num_wqes-1) to generate an
96          * array index.
97          */
98         unsigned long next_idx;
99         /** List of work queues completing to this queue */
100         struct list_head work_queues;
101         /** Device private data */
102         void *dev_priv;
103 };
104
105 /** An Infiniband completion */
106 struct ib_completion {
107         /** Syndrome
108          *
109          * If non-zero, then the completion is in error.
110          */
111         unsigned int syndrome;
112         /** Length */
113         size_t len;
114 };
115
116 /** An Infiniband completion handler
117  *
118  * @v ibdev             Infiniband device
119  * @v qp                Queue pair
120  * @v completion        Completion
121  * @v iobuf             I/O buffer
122  */
123 typedef void ( * ib_completer_t ) ( struct ib_device *ibdev,
124                                     struct ib_queue_pair *qp,
125                                     struct ib_completion *completion,
126                                     struct io_buffer *iobuf );
127
128 /** An Infiniband Address Vector */
129 struct ib_address_vector {
130         /** Destination Queue Pair */
131         unsigned int dest_qp;
132         /** Queue key */
133         unsigned int qkey;
134         /** Destination Local ID */
135         unsigned int dlid;
136         /** Rate */
137         unsigned int rate;
138         /** Service level */
139         unsigned int sl;
140         /** GID is present */
141         unsigned int gid_present;
142         /** GID */
143         struct ib_gid gid;
144 };
145
146 /**
147  * Infiniband device operations
148  *
149  * These represent a subset of the Infiniband Verbs.
150  */
151 struct ib_device_operations {
152         /** Create completion queue
153          *
154          * @v ibdev             Infiniband device
155          * @v cq                Completion queue
156          * @ret rc              Return status code
157          */
158         int ( * create_cq ) ( struct ib_device *ibdev,
159                               struct ib_completion_queue *cq );
160         /** Destroy completion queue
161          *
162          * @v ibdev             Infiniband device
163          * @v cq                Completion queue
164          */
165         void ( * destroy_cq ) ( struct ib_device *ibdev,
166                                 struct ib_completion_queue *cq );
167         /** Create queue pair
168          *
169          * @v ibdev             Infiniband device
170          * @v qp                Queue pair
171          * @ret rc              Return status code
172          */
173         int ( * create_qp ) ( struct ib_device *ibdev,
174                               struct ib_queue_pair *qp );
175         /** Destroy queue pair
176          *
177          * @v ibdev             Infiniband device
178          * @v qp                Queue pair
179          */
180         void ( * destroy_qp ) ( struct ib_device *ibdev,
181                                 struct ib_queue_pair *qp );
182         /** Post send work queue entry
183          *
184          * @v ibdev             Infiniband device
185          * @v qp                Queue pair
186          * @v av                Address vector
187          * @v iobuf             I/O buffer
188          * @ret rc              Return status code
189          *
190          * If this method returns success, the I/O buffer remains
191          * owned by the queue pair.  If this method returns failure,
192          * the I/O buffer is immediately released; the failure is
193          * interpreted as "failure to enqueue buffer".
194          */
195         int ( * post_send ) ( struct ib_device *ibdev,
196                               struct ib_queue_pair *qp,
197                               struct ib_address_vector *av,
198                               struct io_buffer *iobuf );
199         /** Post receive work queue entry
200          *
201          * @v ibdev             Infiniband device
202          * @v qp                Queue pair
203          * @v iobuf             I/O buffer
204          * @ret rc              Return status code
205          *
206          * If this method returns success, the I/O buffer remains
207          * owned by the queue pair.  If this method returns failure,
208          * the I/O buffer is immediately released; the failure is
209          * interpreted as "failure to enqueue buffer".
210          */
211         int ( * post_recv ) ( struct ib_device *ibdev,
212                               struct ib_queue_pair *qp,
213                               struct io_buffer *iobuf );
214         /** Poll completion queue
215          *
216          * @v ibdev             Infiniband device
217          * @v cq                Completion queue
218          * @v complete_send     Send completion handler
219          * @v complete_recv     Receive completion handler
220          *
221          * The completion handler takes ownership of the I/O buffer.
222          */
223         void ( * poll_cq ) ( struct ib_device *ibdev,
224                              struct ib_completion_queue *cq,
225                              ib_completer_t complete_send,
226                              ib_completer_t complete_recv );
227         /** Attach to multicast group
228          *
229          * @v ibdev             Infiniband device
230          * @v qp                Queue pair
231          * @v gid               Multicast GID
232          * @ret rc              Return status code
233          */
234         int ( * mcast_attach ) ( struct ib_device *ibdev,
235                                  struct ib_queue_pair *qp,
236                                  struct ib_gid *gid );
237         /** Detach from multicast group
238          *
239          * @v ibdev             Infiniband device
240          * @v qp                Queue pair
241          * @v gid               Multicast GID
242          */
243         void ( * mcast_detach ) ( struct ib_device *ibdev,
244                                   struct ib_queue_pair *qp,
245                                   struct ib_gid *gid );
246 };
247
248 /** An Infiniband device */
249 struct ib_device {
250         /** Port GID */
251         struct ib_gid port_gid;
252         /** Broadcast GID */
253         struct ib_gid broadcast_gid;    
254         /** Underlying device */
255         struct device *dev;
256         /** Infiniband operations */
257         struct ib_device_operations *op;
258         /** Device private data */
259         void *dev_priv;
260         /** Owner private data */
261         void *owner_priv;
262 };
263
264 extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
265                                                    unsigned int num_cqes );
266 extern void ib_destroy_cq ( struct ib_device *ibdev,
267                             struct ib_completion_queue *cq );
268 extern struct ib_queue_pair *
269 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
270                struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
271                struct ib_completion_queue *recv_cq, unsigned long qkey );
272 extern void ib_destroy_qp ( struct ib_device *ibdev,
273                             struct ib_queue_pair *qp );
274 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
275                                            unsigned long qpn, int is_send );
276 extern struct ib_device * alloc_ibdev ( size_t priv_size );
277 extern void free_ibdev ( struct ib_device *ibdev );
278
279 /**
280  * Post send work queue entry
281  *
282  * @v ibdev             Infiniband device
283  * @v qp                Queue pair
284  * @v av                Address vector
285  * @v iobuf             I/O buffer
286  * @ret rc              Return status code
287  */
288 static inline __attribute__ (( always_inline )) int
289 ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
290                struct ib_address_vector *av, struct io_buffer *iobuf ) {
291         return ibdev->op->post_send ( ibdev, qp, av, iobuf );
292 }
293
294 /**
295  * Post receive work queue entry
296  *
297  * @v ibdev             Infiniband device
298  * @v qp                Queue pair
299  * @v iobuf             I/O buffer
300  * @ret rc              Return status code
301  */
302 static inline __attribute__ (( always_inline )) int
303 ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
304                struct io_buffer *iobuf ) {
305         return ibdev->op->post_recv ( ibdev, qp, iobuf );
306 }
307
308 /**
309  * Poll completion queue
310  *
311  * @v ibdev             Infiniband device
312  * @v cq                Completion queue
313  * @v complete_send     Send completion handler
314  * @v complete_recv     Receive completion handler
315  */
316 static inline __attribute__ (( always_inline )) void
317 ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq,
318              ib_completer_t complete_send, ib_completer_t complete_recv ) {
319         ibdev->op->poll_cq ( ibdev, cq, complete_send, complete_recv );
320 }
321
322
323 /**
324  * Attach to multicast group
325  *
326  * @v ibdev             Infiniband device
327  * @v qp                Queue pair
328  * @v gid               Multicast GID
329  * @ret rc              Return status code
330  */
331 static inline __attribute__ (( always_inline )) int
332 ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
333                   struct ib_gid *gid ) {
334         return ibdev->op->mcast_attach ( ibdev, qp, gid );
335 }
336
337 /**
338  * Detach from multicast group
339  *
340  * @v ibdev             Infiniband device
341  * @v qp                Queue pair
342  * @v gid               Multicast GID
343  */
344 static inline __attribute__ (( always_inline )) void
345 ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
346                   struct ib_gid *gid ) {
347         ibdev->op->mcast_detach ( ibdev, qp, gid );
348 }
349
350 /**
351  * Set Infiniband owner-private data
352  *
353  * @v pci               Infiniband device
354  * @v priv              Private data
355  */
356 static inline void ib_set_ownerdata ( struct ib_device *ibdev,
357                                       void *owner_priv ) {
358         ibdev->owner_priv = owner_priv;
359 }
360
361 /**
362  * Get Infiniband owner-private data
363  *
364  * @v pci               Infiniband device
365  * @ret priv            Private data
366  */
367 static inline void * ib_get_ownerdata ( struct ib_device *ibdev ) {
368         return ibdev->owner_priv;
369 }
370
371 /*****************************************************************************
372  *
373  * Management datagrams
374  *
375  * Portions Copyright (c) 2004 Mellanox Technologies Ltd.  All rights
376  * reserved.
377  *
378  */
379
380 /* Management base version */
381 #define IB_MGMT_BASE_VERSION                    1
382
383 /* Management classes */
384 #define IB_MGMT_CLASS_SUBN_LID_ROUTED           0x01
385 #define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE       0x81
386 #define IB_MGMT_CLASS_SUBN_ADM                  0x03
387 #define IB_MGMT_CLASS_PERF_MGMT                 0x04
388 #define IB_MGMT_CLASS_BM                        0x05
389 #define IB_MGMT_CLASS_DEVICE_MGMT               0x06
390 #define IB_MGMT_CLASS_CM                        0x07
391 #define IB_MGMT_CLASS_SNMP                      0x08
392 #define IB_MGMT_CLASS_VENDOR_RANGE2_START       0x30
393 #define IB_MGMT_CLASS_VENDOR_RANGE2_END         0x4F
394
395 /* Management methods */
396 #define IB_MGMT_METHOD_GET                      0x01
397 #define IB_MGMT_METHOD_SET                      0x02
398 #define IB_MGMT_METHOD_GET_RESP                 0x81
399 #define IB_MGMT_METHOD_SEND                     0x03
400 #define IB_MGMT_METHOD_TRAP                     0x05
401 #define IB_MGMT_METHOD_REPORT                   0x06
402 #define IB_MGMT_METHOD_REPORT_RESP              0x86
403 #define IB_MGMT_METHOD_TRAP_REPRESS             0x07
404 #define IB_MGMT_METHOD_DELETE                   0x15
405 #define IB_MGMT_METHOD_RESP                     0x80
406
407 /* Subnet management attributes */
408 #define IB_SMP_ATTR_NOTICE                      0x0002
409 #define IB_SMP_ATTR_NODE_DESC                   0x0010
410 #define IB_SMP_ATTR_NODE_INFO                   0x0011
411 #define IB_SMP_ATTR_SWITCH_INFO                 0x0012
412 #define IB_SMP_ATTR_GUID_INFO                   0x0014
413 #define IB_SMP_ATTR_PORT_INFO                   0x0015
414 #define IB_SMP_ATTR_PKEY_TABLE                  0x0016
415 #define IB_SMP_ATTR_SL_TO_VL_TABLE              0x0017
416 #define IB_SMP_ATTR_VL_ARB_TABLE                0x0018
417 #define IB_SMP_ATTR_LINEAR_FORWARD_TABLE        0x0019
418 #define IB_SMP_ATTR_RANDOM_FORWARD_TABLE        0x001A
419 #define IB_SMP_ATTR_MCAST_FORWARD_TABLE         0x001B
420 #define IB_SMP_ATTR_SM_INFO                     0x0020
421 #define IB_SMP_ATTR_VENDOR_DIAG                 0x0030
422 #define IB_SMP_ATTR_LED_INFO                    0x0031
423 #define IB_SMP_ATTR_VENDOR_MASK                 0xFF00
424
425 struct ib_mad_hdr {
426         uint8_t base_version;
427         uint8_t mgmt_class;
428         uint8_t class_version;
429         uint8_t method;
430         uint16_t status;
431         uint16_t class_specific;
432         uint64_t tid;
433         uint16_t attr_id;
434         uint16_t resv;
435         uint32_t attr_mod;
436 } __attribute__ (( packed ));
437
438 struct ib_mad_data {
439         struct ib_mad_hdr mad_hdr;
440         uint8_t data[232];
441 } __attribute__ (( packed ));
442
443 struct ib_mad_guid_info {
444         struct ib_mad_hdr mad_hdr;
445         uint32_t mkey[2];
446         uint32_t reserved[8];
447         uint8_t gid_local[8];
448 } __attribute__ (( packed ));
449
450 struct ib_mad_port_info {
451         struct ib_mad_hdr mad_hdr;
452         uint32_t mkey[2];
453         uint32_t reserved[8];
454         uint32_t mkey2[2];
455         uint8_t gid_prefix[8];
456         uint16_t lid;
457         uint16_t mastersm_lid;
458         uint32_t cap_mask;
459         uint16_t diag_code;
460         uint16_t mkey_lease_period;
461         uint8_t local_port_num;
462         uint8_t link_width_enabled;
463         uint8_t link_width_supported;
464         uint8_t link_width_active;
465         uint8_t port_state__link_speed_supported;
466         uint8_t link_down_def_state__port_phys_state;
467         uint8_t lmc__r1__mkey_prot_bits;
468         uint8_t link_speed_enabled__link_speed_active;
469 } __attribute__ (( packed ));
470
471 struct ib_mad_pkey_table {
472         struct ib_mad_hdr mad_hdr;
473         uint32_t mkey[2];
474         uint32_t reserved[8];
475         uint16_t pkey[16][2];
476 } __attribute__ (( packed ));
477
478 union ib_mad {
479         struct ib_mad_hdr mad_hdr;
480         struct ib_mad_data data;
481         struct ib_mad_guid_info guid_info;
482         struct ib_mad_port_info port_info;
483         struct ib_mad_pkey_table pkey_table;
484 } __attribute__ (( packed ));
485
486 #endif /* _GPXE_INFINIBAND_H */