cb56458e29f3a0f2ba9e4e1894caecc91023b8cc
[people/sha0/gpxe.git] / src / drivers / net / ipoib.c
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <byteswap.h>
26 #include <errno.h>
27 #include <gpxe/if_arp.h>
28 #include <gpxe/iobuf.h>
29 #include <gpxe/netdevice.h>
30 #include <gpxe/infiniband.h>
31 #include <gpxe/ipoib.h>
32
33 /** @file
34  *
35  * IP over Infiniband
36  */
37
38 /** Number of IPoIB data send work queue entries */
39 #define IPOIB_DATA_NUM_SEND_WQES 2
40
41 /** Number of IPoIB data receive work queue entries */
42 #define IPOIB_DATA_NUM_RECV_WQES 4
43
44 /** Number of IPoIB data completion entries */
45 #define IPOIB_DATA_NUM_CQES 8
46
47 /** Number of IPoIB metadata send work queue entries */
48 #define IPOIB_META_NUM_SEND_WQES 2
49
50 /** Number of IPoIB metadata receive work queue entries */
51 #define IPOIB_META_NUM_RECV_WQES 2
52
53 /** Number of IPoIB metadata completion entries */
54 #define IPOIB_META_NUM_CQES 8
55
56 /** An IPoIB queue set */
57 struct ipoib_queue_set {
58         /** Completion queue */
59         struct ib_completion_queue *cq;
60         /** Queue pair */
61         struct ib_queue_pair *qp;
62         /** Receive work queue maximum fill level */
63         unsigned int recv_max_fill;
64 };
65
66 /** An IPoIB device */
67 struct ipoib_device {
68         /** Network device */
69         struct net_device *netdev;
70         /** Underlying Infiniband device */
71         struct ib_device *ibdev;
72         /** Data queue set */
73         struct ipoib_queue_set data;
74         /** Data queue set */
75         struct ipoib_queue_set meta;
76         /** Broadcast GID */
77         struct ib_gid broadcast_gid;
78         /** Broadcast LID */
79         unsigned int broadcast_lid;
80         /** Data queue key */
81         unsigned long data_qkey;
82         /** Attached to multicast group
83          *
84          * This flag indicates whether or not we have attached our
85          * data queue pair to the broadcast multicast GID.
86          */
87         int broadcast_attached;
88 };
89
90 /** TID half used to identify get path record replies */
91 #define IPOIB_TID_GET_PATH_REC 0x11111111UL
92
93 /** TID half used to identify multicast member record replies */
94 #define IPOIB_TID_MC_MEMBER_REC 0x22222222UL
95
96 /** IPoIB metadata TID */
97 static uint32_t ipoib_meta_tid = 0;
98
99 /** Broadcast QPN used in IPoIB MAC addresses
100  *
101  * This is a guaranteed invalid real QPN
102  */
103 #define IPOIB_BROADCAST_QPN 0xffffffffUL
104
105 /** Broadcast IPoIB address */
106 static struct ipoib_mac ipoib_broadcast = {
107         .qpn = ntohl ( IPOIB_BROADCAST_QPN ),
108         .gid.u.bytes =  { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
109                           0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff },
110 };
111
112 /****************************************************************************
113  *
114  * IPoIB peer cache
115  *
116  ****************************************************************************
117  */
118
119 /**
120  * IPoIB peer address
121  *
122  * This serves a similar role to the ARP cache for Ethernet.  (ARP
123  * *is* used on IPoIB; we have two caches to maintain.)
124  */
125 struct ipoib_peer {
126         /** Key */
127         uint8_t key;
128         /** MAC address */
129         struct ipoib_mac mac;
130         /** LID */
131         unsigned int lid;
132         /** Service level */
133         unsigned int sl;
134         /** Rate */
135         unsigned int rate;
136 };
137
138 /** Number of IPoIB peer cache entries
139  *
140  * Must be a power of two.
141  */
142 #define IPOIB_NUM_CACHED_PEERS 4
143
144 /** IPoIB peer address cache */
145 static struct ipoib_peer ipoib_peer_cache[IPOIB_NUM_CACHED_PEERS];
146
147 /** Oldest IPoIB peer cache entry index */
148 static unsigned int ipoib_peer_cache_idx = 1;
149
150 /**
151  * Look up cached peer by key
152  *
153  * @v key               Peer cache key
154  * @ret peer            Peer cache entry, or NULL
155  */
156 static struct ipoib_peer * ipoib_lookup_peer_by_key ( unsigned int key ) {
157         struct ipoib_peer *peer;
158         unsigned int i;
159
160         for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) {
161                 peer = &ipoib_peer_cache[i];
162                 if ( peer->key == key )
163                         return peer;
164         }
165
166         if ( key != 0 ) {
167                 DBG ( "IPoIB warning: peer cache lost track of key %x while "
168                       "still in use\n", key );
169         }
170         return NULL;
171 }
172
173 /**
174  * Look up cached peer by GID
175  *
176  * @v gid               Peer GID
177  * @ret peer            Peer cache entry, or NULL
178  */
179 static struct ipoib_peer *
180 ipoib_lookup_peer_by_gid ( const struct ib_gid *gid ) {
181         struct ipoib_peer *peer;
182         unsigned int i;
183
184         for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) {
185                 peer = &ipoib_peer_cache[i];
186                 if ( memcmp ( &peer->mac.gid, gid,
187                               sizeof ( peer->mac.gid) ) == 0 ) {
188                         return peer;
189                 }
190         }
191
192         return NULL;
193 }
194
195 /**
196  * Store GID and QPN in peer cache
197  *
198  * @v gid               Peer GID
199  * @v qpn               Peer QPN
200  * @ret peer            Peer cache entry
201  */
202 static struct ipoib_peer *
203 ipoib_cache_peer ( const struct ib_gid *gid, unsigned long qpn ) {
204         struct ipoib_peer *peer;
205         unsigned int key;
206
207         /* Look for existing cache entry */
208         peer = ipoib_lookup_peer_by_gid ( gid );
209         if ( peer ) {
210                 assert ( peer->mac.qpn = ntohl ( qpn ) );
211                 return peer;
212         }
213
214         /* No entry found: create a new one */
215         key = ipoib_peer_cache_idx++;
216         peer = &ipoib_peer_cache[ key % IPOIB_NUM_CACHED_PEERS ];
217         if ( peer->key )
218                 DBG ( "IPoIB peer %x evicted from cache\n", peer->key );
219
220         memset ( peer, 0, sizeof ( *peer ) );
221         peer->key = key;
222         peer->mac.qpn = htonl ( qpn );
223         memcpy ( &peer->mac.gid, gid, sizeof ( peer->mac.gid ) );
224         DBG ( "IPoIB peer %x has GID %08x:%08x:%08x:%08x and QPN %lx\n",
225               peer->key, htonl ( gid->u.dwords[0] ),
226               htonl ( gid->u.dwords[1] ), htonl ( gid->u.dwords[2] ),
227               htonl ( gid->u.dwords[3] ), qpn );
228         return peer;
229 }
230
231 /****************************************************************************
232  *
233  * IPoIB link layer
234  *
235  ****************************************************************************
236  */
237
238 /**
239  * Add IPoIB link-layer header
240  *
241  * @v iobuf             I/O buffer
242  * @v ll_dest           Link-layer destination address
243  * @v ll_source         Source link-layer address
244  * @v net_proto         Network-layer protocol, in network-byte order
245  * @ret rc              Return status code
246  */
247 static int ipoib_push ( struct io_buffer *iobuf, const void *ll_dest,
248                         const void *ll_source __unused, uint16_t net_proto ) {
249         struct ipoib_hdr *ipoib_hdr =
250                 iob_push ( iobuf, sizeof ( *ipoib_hdr ) );
251         const struct ipoib_mac *dest_mac = ll_dest;
252         const struct ipoib_mac *src_mac = ll_source;
253         struct ipoib_peer *dest;
254         struct ipoib_peer *src;
255
256         /* Add link-layer addresses to cache */
257         dest = ipoib_cache_peer ( &dest_mac->gid, ntohl ( dest_mac->qpn ) );
258         src = ipoib_cache_peer ( &src_mac->gid, ntohl ( src_mac->qpn ) );
259
260         /* Build IPoIB header */
261         ipoib_hdr->proto = net_proto;
262         ipoib_hdr->u.peer.dest = dest->key;
263         ipoib_hdr->u.peer.src = src->key;
264
265         return 0;
266 }
267
268 /**
269  * Remove IPoIB link-layer header
270  *
271  * @v iobuf             I/O buffer
272  * @ret ll_dest         Link-layer destination address
273  * @ret ll_source       Source link-layer address
274  * @ret net_proto       Network-layer protocol, in network-byte order
275  * @ret rc              Return status code
276  */
277 static int ipoib_pull ( struct io_buffer *iobuf, const void **ll_dest,
278                         const void **ll_source, uint16_t *net_proto ) {
279         struct ipoib_hdr *ipoib_hdr = iobuf->data;
280         struct ipoib_peer *dest;
281         struct ipoib_peer *source;
282
283         /* Sanity check */
284         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
285                 DBG ( "IPoIB packet too short for link-layer header\n" );
286                 DBG_HD ( iobuf->data, iob_len ( iobuf ) );
287                 return -EINVAL;
288         }
289
290         /* Strip off IPoIB header */
291         iob_pull ( iobuf, sizeof ( *ipoib_hdr ) );
292
293         /* Identify source and destination addresses, and clear
294          * reserved word in IPoIB header
295          */
296         dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest );
297         source = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.src );
298         ipoib_hdr->u.reserved = 0;
299
300         /* Fill in required fields */
301         *ll_dest = ( dest ? &dest->mac : &ipoib_broadcast );
302         *ll_source = ( source ? &source->mac : &ipoib_broadcast );
303         *net_proto = ipoib_hdr->proto;
304
305         return 0;
306 }
307
308 /**
309  * Transcribe IPoIB address
310  *
311  * @v ll_addr   Link-layer address
312  * @ret string  Link-layer address in human-readable format
313  */
314 const char * ipoib_ntoa ( const void *ll_addr ) {
315         static char buf[45];
316         const struct ipoib_mac *mac = ll_addr;
317
318         snprintf ( buf, sizeof ( buf ), "%08x:%08x:%08x:%08x:%08x",
319                    htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
320                    htonl ( mac->gid.u.dwords[1] ),
321                    htonl ( mac->gid.u.dwords[2] ),
322                    htonl ( mac->gid.u.dwords[3] ) );
323         return buf;
324 }
325
326 /**
327  * Hash multicast address
328  *
329  * @v af                Address family
330  * @v net_addr          Network-layer address
331  * @v ll_addr           Link-layer address to fill in
332  * @ret rc              Return status code
333  */
334 static int ipoib_mc_hash ( unsigned int af __unused,
335                            const void *net_addr __unused,
336                            void *ll_addr __unused ) {
337
338         return -ENOTSUP;
339 }
340
341 /** IPoIB protocol */
342 struct ll_protocol ipoib_protocol __ll_protocol = {
343         .name           = "IPoIB",
344         .ll_proto       = htons ( ARPHRD_INFINIBAND ),
345         .ll_addr_len    = IPOIB_ALEN,
346         .ll_header_len  = IPOIB_HLEN,
347         .ll_broadcast   = ( uint8_t * ) &ipoib_broadcast,
348         .push           = ipoib_push,
349         .pull           = ipoib_pull,
350         .ntoa           = ipoib_ntoa,
351         .mc_hash        = ipoib_mc_hash,
352 };
353
354 /****************************************************************************
355  *
356  * IPoIB network device
357  *
358  ****************************************************************************
359  */
360
361 /**
362  * Destroy queue set
363  *
364  * @v ipoib             IPoIB device
365  * @v qset              Queue set
366  */
367 static void ipoib_destroy_qset ( struct ipoib_device *ipoib,
368                                  struct ipoib_queue_set *qset ) {
369         struct ib_device *ibdev = ipoib->ibdev;
370
371         if ( qset->qp )
372                 ib_destroy_qp ( ibdev, qset->qp );
373         if ( qset->cq )
374                 ib_destroy_cq ( ibdev, qset->cq );
375         memset ( qset, 0, sizeof ( *qset ) );
376 }
377
378 /**
379  * Create queue set
380  *
381  * @v ipoib             IPoIB device
382  * @v qset              Queue set
383  * @v num_cqes          Number of completion queue entries
384  * @v cq_op             Completion queue operations
385  * @v num_send_wqes     Number of send work queue entries
386  * @v num_recv_wqes     Number of receive work queue entries
387  * @v qkey              Queue key
388  * @ret rc              Return status code
389  */
390 static int ipoib_create_qset ( struct ipoib_device *ipoib,
391                                struct ipoib_queue_set *qset,
392                                unsigned int num_cqes,
393                                struct ib_completion_queue_operations *cq_op,
394                                unsigned int num_send_wqes,
395                                unsigned int num_recv_wqes,
396                                unsigned long qkey ) {
397         struct ib_device *ibdev = ipoib->ibdev;
398         int rc;
399
400         /* Sanity check */
401         assert ( qset->cq == NULL );
402         assert ( qset->qp == NULL );
403
404         /* Store queue parameters */
405         qset->recv_max_fill = num_recv_wqes;
406
407         /* Allocate completion queue */
408         qset->cq = ib_create_cq ( ibdev, num_cqes, cq_op );
409         if ( ! qset->cq ) {
410                 DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
411                        ipoib );
412                 rc = -ENOMEM;
413                 goto err;
414         }
415
416         /* Allocate queue pair */
417         qset->qp = ib_create_qp ( ibdev, num_send_wqes, qset->cq,
418                                   num_recv_wqes, qset->cq, qkey );
419         if ( ! qset->qp ) {
420                 DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
421                        ipoib );
422                 rc = -ENOMEM;
423                 goto err;
424         }
425         ib_qp_set_ownerdata ( qset->qp, ipoib->netdev );
426
427         return 0;
428
429  err:
430         ipoib_destroy_qset ( ipoib, qset );
431         return rc;
432 }
433
434 /**
435  * Transmit path record request
436  *
437  * @v ipoib             IPoIB device
438  * @v gid               Destination GID
439  * @ret rc              Return status code
440  */
441 static int ipoib_get_path_record ( struct ipoib_device *ipoib,
442                                    struct ib_gid *gid ) {
443         struct ib_device *ibdev = ipoib->ibdev;
444         struct io_buffer *iobuf;
445         struct ib_mad_sa *sa;
446         struct ib_address_vector av;
447         int rc;
448
449         /* Allocate I/O buffer */
450         iobuf = alloc_iob ( sizeof ( *sa ) );
451         if ( ! iobuf )
452                 return -ENOMEM;
453         iob_put ( iobuf, sizeof ( *sa ) );
454         sa = iobuf->data;
455         memset ( sa, 0, sizeof ( *sa ) );
456
457         /* Construct path record request */
458         sa->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
459         sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
460         sa->mad_hdr.class_version = 2;
461         sa->mad_hdr.method = IB_MGMT_METHOD_GET;
462         sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC );
463         sa->mad_hdr.tid[0] = IPOIB_TID_GET_PATH_REC;
464         sa->mad_hdr.tid[1] = ipoib_meta_tid++;
465         sa->sa_hdr.comp_mask[1] =
466                 htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID );
467         memcpy ( &sa->sa_data.path_record.dgid, gid,
468                  sizeof ( sa->sa_data.path_record.dgid ) );
469         memcpy ( &sa->sa_data.path_record.sgid, &ibdev->gid,
470                  sizeof ( sa->sa_data.path_record.sgid ) );
471
472         /* Construct address vector */
473         memset ( &av, 0, sizeof ( av ) );
474         av.lid = ibdev->sm_lid;
475         av.sl = ibdev->sm_sl;
476         av.qpn = IB_SA_QPN;
477         av.qkey = IB_GLOBAL_QKEY;
478
479         /* Post send request */
480         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
481                                    iobuf ) ) != 0 ) {
482                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
483                        ipoib, strerror ( rc ) );
484                 free_iob ( iobuf );
485                 return rc;
486         }
487
488         return 0;
489 }
490
491 /**
492  * Transmit multicast group membership request
493  *
494  * @v ipoib             IPoIB device
495  * @v gid               Multicast GID
496  * @v join              Join (rather than leave) group
497  * @ret rc              Return status code
498  */
499 static int ipoib_mc_member_record ( struct ipoib_device *ipoib,
500                                     struct ib_gid *gid, int join ) {
501         struct ib_device *ibdev = ipoib->ibdev;
502         struct io_buffer *iobuf;
503         struct ib_mad_sa *sa;
504         struct ib_address_vector av;
505         int rc;
506
507         /* Allocate I/O buffer */
508         iobuf = alloc_iob ( sizeof ( *sa ) );
509         if ( ! iobuf )
510                 return -ENOMEM;
511         iob_put ( iobuf, sizeof ( *sa ) );
512         sa = iobuf->data;
513         memset ( sa, 0, sizeof ( *sa ) );
514
515         /* Construct path record request */
516         sa->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
517         sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
518         sa->mad_hdr.class_version = 2;
519         sa->mad_hdr.method =
520                 ( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE );
521         sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC );
522         sa->mad_hdr.tid[0] = IPOIB_TID_MC_MEMBER_REC;
523         sa->mad_hdr.tid[1] = ipoib_meta_tid++;
524         sa->sa_hdr.comp_mask[1] =
525                 htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
526                         IB_SA_MCMEMBER_REC_JOIN_STATE );
527         sa->sa_data.mc_member_record.scope__join_state = 1;
528         memcpy ( &sa->sa_data.mc_member_record.mgid, gid,
529                  sizeof ( sa->sa_data.mc_member_record.mgid ) );
530         memcpy ( &sa->sa_data.mc_member_record.port_gid, &ibdev->gid,
531                  sizeof ( sa->sa_data.mc_member_record.port_gid ) );
532
533         /* Construct address vector */
534         memset ( &av, 0, sizeof ( av ) );
535         av.lid = ibdev->sm_lid;
536         av.sl = ibdev->sm_sl;
537         av.qpn = IB_SA_QPN;
538         av.qkey = IB_GLOBAL_QKEY;
539
540         /* Post send request */
541         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
542                                    iobuf ) ) != 0 ) {
543                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
544                        ipoib, strerror ( rc ) );
545                 free_iob ( iobuf );
546                 return rc;
547         }
548
549         return 0;
550 }
551
552 /**
553  * Transmit packet via IPoIB network device
554  *
555  * @v netdev            Network device
556  * @v iobuf             I/O buffer
557  * @ret rc              Return status code
558  */
559 static int ipoib_transmit ( struct net_device *netdev,
560                             struct io_buffer *iobuf ) {
561         struct ipoib_device *ipoib = netdev->priv;
562         struct ib_device *ibdev = ipoib->ibdev;
563         struct ipoib_hdr *ipoib_hdr;
564         struct ipoib_peer *dest;
565         struct ib_address_vector av;
566         struct ib_gid *gid;
567
568         /* Sanity check */
569         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
570                 DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
571                 return -EINVAL;
572         }
573         ipoib_hdr = iobuf->data;
574
575         /* Attempting transmission while link is down will put the
576          * queue pair into an error state, so don't try it.
577          */
578         if ( ! ib_link_ok ( ibdev ) )
579                 return -ENETUNREACH;
580
581         /* Identify destination address */
582         dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest );
583         if ( ! dest )
584                 return -ENXIO;
585         ipoib_hdr->u.reserved = 0;
586
587         /* Construct address vector */
588         memset ( &av, 0, sizeof ( av ) );
589         av.qkey = ipoib->data_qkey;
590         av.gid_present = 1;
591         if ( dest->mac.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
592                 /* Broadcast */
593                 av.qpn = IB_BROADCAST_QPN;
594                 av.lid = ipoib->broadcast_lid;
595                 gid = &ipoib->broadcast_gid;
596         } else {
597                 /* Unicast */
598                 if ( ! dest->lid ) {
599                         /* No LID yet - get path record to fetch LID */
600                         ipoib_get_path_record ( ipoib, &dest->mac.gid );
601                         return -ENOENT;
602                 }
603                 av.qpn = ntohl ( dest->mac.qpn );
604                 av.lid = dest->lid;
605                 av.rate = dest->rate;
606                 av.sl = dest->sl;
607                 gid = &dest->mac.gid;
608         }
609         memcpy ( &av.gid, gid, sizeof ( av.gid ) );
610
611         return ib_post_send ( ibdev, ipoib->data.qp, &av, iobuf );
612 }
613
614 /**
615  * Handle IPoIB data send completion
616  *
617  * @v ibdev             Infiniband device
618  * @v qp                Queue pair
619  * @v iobuf             I/O buffer
620  * @v rc                Completion status code
621  */
622 static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
623                                        struct ib_queue_pair *qp,
624                                        struct io_buffer *iobuf, int rc ) {
625         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
626
627         netdev_tx_complete_err ( netdev, iobuf, rc );
628 }
629
630 /**
631  * Handle IPoIB data receive completion
632  *
633  * @v ibdev             Infiniband device
634  * @v qp                Queue pair
635  * @v av                Address vector, or NULL
636  * @v iobuf             I/O buffer
637  * @v rc                Completion status code
638  */
639 static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
640                                        struct ib_queue_pair *qp,
641                                        struct ib_address_vector *av,
642                                        struct io_buffer *iobuf, int rc ) {
643         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
644         struct ipoib_device *ipoib = netdev->priv;
645         struct ipoib_hdr *ipoib_hdr;
646         struct ipoib_peer *src;
647
648         if ( rc != 0 ) {
649                 netdev_rx_err ( netdev, iobuf, rc );
650                 return;
651         }
652
653         /* Sanity check */
654         if ( iob_len ( iobuf ) < sizeof ( struct ipoib_hdr ) ) {
655                 DBGC ( ipoib, "IPoIB %p received data packet too short to "
656                        "contain IPoIB header\n", ipoib );
657                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
658                 netdev_rx_err ( netdev, iobuf, -EIO );
659                 return;
660         }
661         ipoib_hdr = iobuf->data;
662
663         /* Parse source address */
664         if ( av->gid_present ) {
665                 src = ipoib_cache_peer ( &av->gid, av->qpn );
666                 ipoib_hdr->u.peer.src = src->key;
667         }
668
669         /* Hand off to network layer */
670         netdev_rx ( netdev, iobuf );
671 }
672
673 /** IPoIB data completion operations */
674 static struct ib_completion_queue_operations ipoib_data_cq_op = {
675         .complete_send = ipoib_data_complete_send,
676         .complete_recv = ipoib_data_complete_recv,
677 };
678
679 /**
680  * Handle IPoIB metadata send completion
681  *
682  * @v ibdev             Infiniband device
683  * @v qp                Queue pair
684  * @v iobuf             I/O buffer
685  * @v rc                Completion status code
686  */
687 static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
688                                        struct ib_queue_pair *qp,
689                                        struct io_buffer *iobuf, int rc ) {
690         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
691         struct ipoib_device *ipoib = netdev->priv;
692
693         if ( rc != 0 ) {
694                 DBGC ( ipoib, "IPoIB %p metadata TX completion error: %s\n",
695                        ipoib, strerror ( rc ) );
696         }
697         free_iob ( iobuf );
698 }
699
700 /**
701  * Handle received IPoIB path record
702  *
703  * @v ipoib             IPoIB device
704  * @v path_record       Path record
705  */
706 static void ipoib_recv_path_record ( struct ipoib_device *ipoib,
707                                      struct ib_path_record *path_record ) {
708         struct ipoib_peer *peer;
709
710         /* Locate peer cache entry */
711         peer = ipoib_lookup_peer_by_gid ( &path_record->dgid );
712         if ( ! peer ) {
713                 DBGC ( ipoib, "IPoIB %p received unsolicited path record\n",
714                        ipoib );
715                 return;
716         }
717
718         /* Update path cache entry */
719         peer->lid = ntohs ( path_record->dlid );
720         peer->sl = ( path_record->reserved__sl & 0x0f );
721         peer->rate = ( path_record->rate_selector__rate & 0x3f );
722
723         DBG ( "IPoIB peer %x has dlid %x sl %x rate %x\n",
724               peer->key, peer->lid, peer->sl, peer->rate );
725 }
726
727 /**
728  * Handle received IPoIB multicast membership record
729  *
730  * @v ipoib             IPoIB device
731  * @v mc_member_record  Multicast membership record
732  */
733 static void ipoib_recv_mc_member_record ( struct ipoib_device *ipoib,
734                                struct ib_mc_member_record *mc_member_record ) {
735         int joined;
736         int rc;
737
738         /* Record parameters */
739         joined = ( mc_member_record->scope__join_state & 0x0f );
740         ipoib->data_qkey = ntohl ( mc_member_record->qkey );
741         ipoib->broadcast_lid = ntohs ( mc_member_record->mlid );
742         DBGC ( ipoib, "IPoIB %p %s broadcast group: qkey %lx mlid %x\n",
743                ipoib, ( joined ? "joined" : "left" ), ipoib->data_qkey,
744                ipoib->broadcast_lid );
745
746         /* Update data queue pair qkey */
747         if ( ( rc = ib_modify_qp ( ipoib->ibdev, ipoib->data.qp,
748                                    IB_MODIFY_QKEY, ipoib->data_qkey ) ) != 0 ){
749                 DBGC ( ipoib, "IPoIB %p could not update data qkey: %s\n",
750                        ipoib, strerror ( rc ) );
751                 return;
752         }
753 }
754
755 /**
756  * Handle IPoIB metadata receive completion
757  *
758  * @v ibdev             Infiniband device
759  * @v qp                Queue pair
760  * @v av                Address vector, or NULL
761  * @v iobuf             I/O buffer
762  * @v rc                Completion status code
763  */
764 static void
765 ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
766                            struct ib_queue_pair *qp,
767                            struct ib_address_vector *av __unused,
768                            struct io_buffer *iobuf, int rc ) {
769         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
770         struct ipoib_device *ipoib = netdev->priv;
771         struct ib_mad_sa *sa;
772
773         if ( rc != 0 ) {
774                 DBGC ( ipoib, "IPoIB %p metadata RX completion error: %s\n",
775                        ipoib, strerror ( rc ) );
776                 goto done;
777         }
778
779         if ( iob_len ( iobuf ) < sizeof ( *sa ) ) {
780                 DBGC ( ipoib, "IPoIB %p received metadata packet too short "
781                        "to contain reply\n", ipoib );
782                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
783                 goto done;
784         }
785         sa = iobuf->data;
786
787         if ( sa->mad_hdr.status != 0 ) {
788                 DBGC ( ipoib, "IPoIB %p metadata RX err status %04x\n",
789                        ipoib, ntohs ( sa->mad_hdr.status ) );
790                 goto done;
791         }
792
793         switch ( sa->mad_hdr.tid[0] ) {
794         case IPOIB_TID_GET_PATH_REC:
795                 ipoib_recv_path_record ( ipoib, &sa->sa_data.path_record );
796                 break;
797         case IPOIB_TID_MC_MEMBER_REC:
798                 ipoib_recv_mc_member_record ( ipoib,
799                                               &sa->sa_data.mc_member_record );
800                 break;
801         default:
802                 DBGC ( ipoib, "IPoIB %p unwanted response:\n",
803                        ipoib );
804                 DBGC_HD ( ipoib, sa, sizeof ( *sa ) );
805                 break;
806         }
807
808  done:
809         free_iob ( iobuf );
810 }
811
812 /** IPoIB metadata completion operations */
813 static struct ib_completion_queue_operations ipoib_meta_cq_op = {
814         .complete_send = ipoib_meta_complete_send,
815         .complete_recv = ipoib_meta_complete_recv,
816 };
817
818 /**
819  * Refill IPoIB receive ring
820  *
821  * @v ipoib             IPoIB device
822  */
823 static void ipoib_refill_recv ( struct ipoib_device *ipoib,
824                                 struct ipoib_queue_set *qset ) {
825         struct ib_device *ibdev = ipoib->ibdev;
826         struct io_buffer *iobuf;
827         int rc;
828
829         while ( qset->qp->recv.fill < qset->recv_max_fill ) {
830                 iobuf = alloc_iob ( IPOIB_PKT_LEN );
831                 if ( ! iobuf )
832                         break;
833                 if ( ( rc = ib_post_recv ( ibdev, qset->qp, iobuf ) ) != 0 ) {
834                         free_iob ( iobuf );
835                         break;
836                 }
837         }
838 }
839
840 /**
841  * Poll IPoIB network device
842  *
843  * @v netdev            Network device
844  */
845 static void ipoib_poll ( struct net_device *netdev ) {
846         struct ipoib_device *ipoib = netdev->priv;
847         struct ib_device *ibdev = ipoib->ibdev;
848
849         ib_poll_cq ( ibdev, ipoib->meta.cq );
850         ib_poll_cq ( ibdev, ipoib->data.cq );
851         ipoib_refill_recv ( ipoib, &ipoib->meta );
852         ipoib_refill_recv ( ipoib, &ipoib->data );
853 }
854
855 /**
856  * Enable/disable interrupts on IPoIB network device
857  *
858  * @v netdev            Network device
859  * @v enable            Interrupts should be enabled
860  */
861 static void ipoib_irq ( struct net_device *netdev __unused,
862                         int enable __unused ) {
863         /* No implementation */
864 }
865
866 /**
867  * Join IPv4 broadcast multicast group
868  *
869  * @v ipoib             IPoIB device
870  * @ret rc              Return status code
871  */
872 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
873         int rc;
874
875         /* Sanity check */
876         if ( ! ipoib->data.qp )
877                 return 0;
878
879         /* Attach data queue to broadcast multicast GID */
880         assert ( ipoib->broadcast_attached == 0 );
881         if ( ( rc = ib_mcast_attach ( ipoib->ibdev, ipoib->data.qp,
882                                       &ipoib->broadcast_gid ) ) != 0 ){
883                 DBGC ( ipoib, "IPoIB %p could not attach to broadcast GID: "
884                        "%s\n", ipoib, strerror ( rc ) );
885                 return rc;
886         }
887         ipoib->broadcast_attached = 1;
888
889         /* Initiate broadcast group join */
890         if ( ( rc = ipoib_mc_member_record ( ipoib, &ipoib->broadcast_gid,
891                                              1 ) ) != 0 ) {
892                 DBGC ( ipoib, "IPoIB %p could not send broadcast join: %s\n",
893                        ipoib, strerror ( rc ) );
894                 return rc;
895         }
896
897         /* We will set link up on the network device when we receive
898          * the broadcast join response.
899          */
900
901         return 0;
902 }
903
904 /**
905  * Leave IPv4 broadcast multicast group
906  *
907  * @v ipoib             IPoIB device
908  */
909 static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) {
910
911         /* Detach data queue from broadcast multicast GID */
912         if ( ipoib->broadcast_attached ) {
913                 assert ( ipoib->data.qp != NULL );
914                 ib_mcast_detach ( ipoib->ibdev, ipoib->data.qp,
915                                   &ipoib->broadcast_gid );
916                 ipoib->broadcast_attached = 0;
917         }
918 }
919
920 /**
921  * Open IPoIB network device
922  *
923  * @v netdev            Network device
924  * @ret rc              Return status code
925  */
926 static int ipoib_open ( struct net_device *netdev ) {
927         struct ipoib_device *ipoib = netdev->priv;
928         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
929         int rc;
930
931         /* Open IB device */
932         if ( ( rc = ib_open ( ipoib->ibdev ) ) != 0 ) {
933                 DBGC ( ipoib, "IPoIB %p could not open device: %s\n",
934                        ipoib, strerror ( rc ) );
935                 goto err_ib_open;
936         }
937
938         /* Allocate metadata queue set */
939         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
940                                         IPOIB_META_NUM_CQES,
941                                         &ipoib_meta_cq_op,
942                                         IPOIB_META_NUM_SEND_WQES,
943                                         IPOIB_META_NUM_RECV_WQES,
944                                         IB_GLOBAL_QKEY ) ) != 0 ) {
945                 DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
946                        ipoib, strerror ( rc ) );
947                 goto err_create_meta_qset;
948         }
949
950         /* Allocate data queue set */
951         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
952                                         IPOIB_DATA_NUM_CQES,
953                                         &ipoib_data_cq_op,
954                                         IPOIB_DATA_NUM_SEND_WQES,
955                                         IPOIB_DATA_NUM_RECV_WQES,
956                                         IB_GLOBAL_QKEY ) ) != 0 ) {
957                 DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
958                        ipoib, strerror ( rc ) );
959                 goto err_create_data_qset;
960         }
961
962         /* Update MAC address with data QPN */
963         mac->qpn = htonl ( ipoib->data.qp->qpn );
964
965         /* Fill receive rings */
966         ipoib_refill_recv ( ipoib, &ipoib->meta );
967         ipoib_refill_recv ( ipoib, &ipoib->data );
968
969         /* Join broadcast group */
970         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
971                 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
972                        ipoib, strerror ( rc ) );
973                 goto err_join_broadcast;
974         }
975
976         return 0;
977
978  err_join_broadcast:
979         ipoib_destroy_qset ( ipoib, &ipoib->data );
980  err_create_data_qset:
981         ipoib_destroy_qset ( ipoib, &ipoib->meta );
982  err_create_meta_qset:
983         ib_close ( ipoib->ibdev );
984  err_ib_open:
985         return rc;
986 }
987
988 /**
989  * Close IPoIB network device
990  *
991  * @v netdev            Network device
992  */
993 static void ipoib_close ( struct net_device *netdev ) {
994         struct ipoib_device *ipoib = netdev->priv;
995         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
996
997         /* Leave broadcast group */
998         ipoib_leave_broadcast_group ( ipoib );
999
1000         /* Remove data QPN from MAC address */
1001         mac->qpn = 0;
1002
1003         /* Tear down the queues */
1004         ipoib_destroy_qset ( ipoib, &ipoib->data );
1005         ipoib_destroy_qset ( ipoib, &ipoib->meta );
1006
1007         /* Close IB device */
1008         ib_close ( ipoib->ibdev );
1009 }
1010
1011 /** IPoIB network device operations */
1012 static struct net_device_operations ipoib_operations = {
1013         .open           = ipoib_open,
1014         .close          = ipoib_close,
1015         .transmit       = ipoib_transmit,
1016         .poll           = ipoib_poll,
1017         .irq            = ipoib_irq,
1018 };
1019
1020 /**
1021  * Update IPoIB dynamic Infiniband parameters
1022  *
1023  * @v ipoib             IPoIB device
1024  *
1025  * The Infiniband port GID and partition key will change at runtime,
1026  * when the link is established (or lost).  The MAC address is based
1027  * on the port GID, and the broadcast GID is based on the partition
1028  * key.  This function recalculates these IPoIB device parameters.
1029  */
1030 static void ipoib_set_ib_params ( struct ipoib_device *ipoib ) {
1031         struct ib_device *ibdev = ipoib->ibdev;
1032         struct net_device *netdev = ipoib->netdev;
1033         struct ipoib_mac *mac;
1034
1035         /* Calculate GID portion of MAC address based on port GID */
1036         mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
1037         memcpy ( &mac->gid, &ibdev->gid, sizeof ( mac->gid ) );
1038
1039         /* Calculate broadcast GID based on partition key */
1040         memcpy ( &ipoib->broadcast_gid, &ipoib_broadcast.gid,
1041                  sizeof ( ipoib->broadcast_gid ) );
1042         ipoib->broadcast_gid.u.words[2] = htons ( ibdev->pkey );
1043
1044         /* Set net device link state to reflect Infiniband link state */
1045         if ( ib_link_ok ( ibdev ) ) {
1046                 netdev_link_up ( netdev );
1047         } else {
1048                 netdev_link_down ( netdev );
1049         }
1050 }
1051
1052 /**
1053  * Handle link status change
1054  *
1055  * @v ibdev             Infiniband device
1056  */
1057 void ipoib_link_state_changed ( struct ib_device *ibdev ) {
1058         struct net_device *netdev = ib_get_ownerdata ( ibdev );
1059         struct ipoib_device *ipoib = netdev->priv;
1060         int rc;
1061
1062         /* Leave existing broadcast group */
1063         ipoib_leave_broadcast_group ( ipoib );
1064
1065         /* Update MAC address and broadcast GID based on new port GID
1066          * and partition key.
1067          */
1068         ipoib_set_ib_params ( ipoib );
1069
1070         /* Join new broadcast group */
1071         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
1072                 DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
1073                        "%s\n", ipoib, strerror ( rc ) );
1074                 return;
1075         }
1076 }
1077
1078 /**
1079  * Probe IPoIB device
1080  *
1081  * @v ibdev             Infiniband device
1082  * @ret rc              Return status code
1083  */
1084 int ipoib_probe ( struct ib_device *ibdev ) {
1085         struct net_device *netdev;
1086         struct ipoib_device *ipoib;
1087         int rc;
1088
1089         /* Allocate network device */
1090         netdev = alloc_ipoibdev ( sizeof ( *ipoib ) );
1091         if ( ! netdev )
1092                 return -ENOMEM;
1093         netdev_init ( netdev, &ipoib_operations );
1094         ipoib = netdev->priv;
1095         ib_set_ownerdata ( ibdev, netdev );
1096         netdev->dev = ibdev->dev;
1097         memset ( ipoib, 0, sizeof ( *ipoib ) );
1098         ipoib->netdev = netdev;
1099         ipoib->ibdev = ibdev;
1100
1101         /* Calculate as much of the broadcast GID and the MAC address
1102          * as we can.  We won't know either of these in full until we
1103          * have link-up.
1104          */
1105         ipoib_set_ib_params ( ipoib );
1106
1107         /* Register network device */
1108         if ( ( rc = register_netdev ( netdev ) ) != 0 )
1109                 goto err_register_netdev;
1110
1111         return 0;
1112
1113  err_register_netdev:
1114         netdev_nullify ( netdev );
1115         netdev_put ( netdev );
1116         return rc;
1117 }
1118
1119 /**
1120  * Remove IPoIB device
1121  *
1122  * @v ibdev             Infiniband device
1123  */
1124 void ipoib_remove ( struct ib_device *ibdev ) {
1125         struct net_device *netdev = ib_get_ownerdata ( ibdev );
1126
1127         unregister_netdev ( netdev );
1128         netdev_nullify ( netdev );
1129         netdev_put ( netdev );
1130 }