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