[netdevice] Add netdev argument to link-layer push and pull handlers
[people/pravin/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 netdev            Network device
242  * @v iobuf             I/O buffer
243  * @v ll_dest           Link-layer destination address
244  * @v ll_source         Source link-layer address
245  * @v net_proto         Network-layer protocol, in network-byte order
246  * @ret rc              Return status code
247  */
248 static int ipoib_push ( struct net_device *netdev __unused,
249                         struct io_buffer *iobuf, const void *ll_dest,
250                         const void *ll_source __unused, uint16_t net_proto ) {
251         struct ipoib_hdr *ipoib_hdr =
252                 iob_push ( iobuf, sizeof ( *ipoib_hdr ) );
253         const struct ipoib_mac *dest_mac = ll_dest;
254         const struct ipoib_mac *src_mac = ll_source;
255         struct ipoib_peer *dest;
256         struct ipoib_peer *src;
257
258         /* Add link-layer addresses to cache */
259         dest = ipoib_cache_peer ( &dest_mac->gid, ntohl ( dest_mac->qpn ) );
260         src = ipoib_cache_peer ( &src_mac->gid, ntohl ( src_mac->qpn ) );
261
262         /* Build IPoIB header */
263         ipoib_hdr->proto = net_proto;
264         ipoib_hdr->u.peer.dest = dest->key;
265         ipoib_hdr->u.peer.src = src->key;
266
267         return 0;
268 }
269
270 /**
271  * Remove IPoIB link-layer header
272  *
273  * @v netdev            Network device
274  * @v iobuf             I/O buffer
275  * @ret ll_dest         Link-layer destination address
276  * @ret ll_source       Source link-layer address
277  * @ret net_proto       Network-layer protocol, in network-byte order
278  * @ret rc              Return status code
279  */
280 static int ipoib_pull ( struct net_device *netdev __unused,
281                         struct io_buffer *iobuf, const void **ll_dest,
282                         const void **ll_source, uint16_t *net_proto ) {
283         struct ipoib_hdr *ipoib_hdr = iobuf->data;
284         struct ipoib_peer *dest;
285         struct ipoib_peer *source;
286
287         /* Sanity check */
288         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
289                 DBG ( "IPoIB packet too short for link-layer header\n" );
290                 DBG_HD ( iobuf->data, iob_len ( iobuf ) );
291                 return -EINVAL;
292         }
293
294         /* Strip off IPoIB header */
295         iob_pull ( iobuf, sizeof ( *ipoib_hdr ) );
296
297         /* Identify source and destination addresses, and clear
298          * reserved word in IPoIB header
299          */
300         dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest );
301         source = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.src );
302         ipoib_hdr->u.reserved = 0;
303
304         /* Fill in required fields */
305         *ll_dest = ( dest ? &dest->mac : &ipoib_broadcast );
306         *ll_source = ( source ? &source->mac : &ipoib_broadcast );
307         *net_proto = ipoib_hdr->proto;
308
309         return 0;
310 }
311
312 /**
313  * Transcribe IPoIB address
314  *
315  * @v ll_addr   Link-layer address
316  * @ret string  Link-layer address in human-readable format
317  */
318 const char * ipoib_ntoa ( const void *ll_addr ) {
319         static char buf[45];
320         const struct ipoib_mac *mac = ll_addr;
321
322         snprintf ( buf, sizeof ( buf ), "%08x:%08x:%08x:%08x:%08x",
323                    htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
324                    htonl ( mac->gid.u.dwords[1] ),
325                    htonl ( mac->gid.u.dwords[2] ),
326                    htonl ( mac->gid.u.dwords[3] ) );
327         return buf;
328 }
329
330 /**
331  * Hash multicast address
332  *
333  * @v af                Address family
334  * @v net_addr          Network-layer address
335  * @v ll_addr           Link-layer address to fill in
336  * @ret rc              Return status code
337  */
338 static int ipoib_mc_hash ( unsigned int af __unused,
339                            const void *net_addr __unused,
340                            void *ll_addr __unused ) {
341
342         return -ENOTSUP;
343 }
344
345 /** IPoIB protocol */
346 struct ll_protocol ipoib_protocol __ll_protocol = {
347         .name           = "IPoIB",
348         .ll_proto       = htons ( ARPHRD_INFINIBAND ),
349         .ll_addr_len    = IPOIB_ALEN,
350         .ll_header_len  = IPOIB_HLEN,
351         .ll_broadcast   = ( uint8_t * ) &ipoib_broadcast,
352         .push           = ipoib_push,
353         .pull           = ipoib_pull,
354         .ntoa           = ipoib_ntoa,
355         .mc_hash        = ipoib_mc_hash,
356 };
357
358 /****************************************************************************
359  *
360  * IPoIB network device
361  *
362  ****************************************************************************
363  */
364
365 /**
366  * Destroy queue set
367  *
368  * @v ipoib             IPoIB device
369  * @v qset              Queue set
370  */
371 static void ipoib_destroy_qset ( struct ipoib_device *ipoib,
372                                  struct ipoib_queue_set *qset ) {
373         struct ib_device *ibdev = ipoib->ibdev;
374
375         if ( qset->qp )
376                 ib_destroy_qp ( ibdev, qset->qp );
377         if ( qset->cq )
378                 ib_destroy_cq ( ibdev, qset->cq );
379         memset ( qset, 0, sizeof ( *qset ) );
380 }
381
382 /**
383  * Create queue set
384  *
385  * @v ipoib             IPoIB device
386  * @v qset              Queue set
387  * @v num_cqes          Number of completion queue entries
388  * @v cq_op             Completion queue operations
389  * @v num_send_wqes     Number of send work queue entries
390  * @v num_recv_wqes     Number of receive work queue entries
391  * @v qkey              Queue key
392  * @ret rc              Return status code
393  */
394 static int ipoib_create_qset ( struct ipoib_device *ipoib,
395                                struct ipoib_queue_set *qset,
396                                unsigned int num_cqes,
397                                struct ib_completion_queue_operations *cq_op,
398                                unsigned int num_send_wqes,
399                                unsigned int num_recv_wqes,
400                                unsigned long qkey ) {
401         struct ib_device *ibdev = ipoib->ibdev;
402         int rc;
403
404         /* Sanity check */
405         assert ( qset->cq == NULL );
406         assert ( qset->qp == NULL );
407
408         /* Store queue parameters */
409         qset->recv_max_fill = num_recv_wqes;
410
411         /* Allocate completion queue */
412         qset->cq = ib_create_cq ( ibdev, num_cqes, cq_op );
413         if ( ! qset->cq ) {
414                 DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
415                        ipoib );
416                 rc = -ENOMEM;
417                 goto err;
418         }
419
420         /* Allocate queue pair */
421         qset->qp = ib_create_qp ( ibdev, num_send_wqes, qset->cq,
422                                   num_recv_wqes, qset->cq, qkey );
423         if ( ! qset->qp ) {
424                 DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
425                        ipoib );
426                 rc = -ENOMEM;
427                 goto err;
428         }
429         ib_qp_set_ownerdata ( qset->qp, ipoib->netdev );
430
431         return 0;
432
433  err:
434         ipoib_destroy_qset ( ipoib, qset );
435         return rc;
436 }
437
438 /**
439  * Transmit path record request
440  *
441  * @v ipoib             IPoIB device
442  * @v gid               Destination GID
443  * @ret rc              Return status code
444  */
445 static int ipoib_get_path_record ( struct ipoib_device *ipoib,
446                                    struct ib_gid *gid ) {
447         struct ib_device *ibdev = ipoib->ibdev;
448         struct io_buffer *iobuf;
449         struct ib_mad_sa *sa;
450         struct ib_address_vector av;
451         int rc;
452
453         /* Allocate I/O buffer */
454         iobuf = alloc_iob ( sizeof ( *sa ) );
455         if ( ! iobuf )
456                 return -ENOMEM;
457         iob_put ( iobuf, sizeof ( *sa ) );
458         sa = iobuf->data;
459         memset ( sa, 0, sizeof ( *sa ) );
460
461         /* Construct path record request */
462         sa->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
463         sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
464         sa->mad_hdr.class_version = 2;
465         sa->mad_hdr.method = IB_MGMT_METHOD_GET;
466         sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC );
467         sa->mad_hdr.tid[0] = IPOIB_TID_GET_PATH_REC;
468         sa->mad_hdr.tid[1] = ipoib_meta_tid++;
469         sa->sa_hdr.comp_mask[1] =
470                 htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID );
471         memcpy ( &sa->sa_data.path_record.dgid, gid,
472                  sizeof ( sa->sa_data.path_record.dgid ) );
473         memcpy ( &sa->sa_data.path_record.sgid, &ibdev->gid,
474                  sizeof ( sa->sa_data.path_record.sgid ) );
475
476         /* Construct address vector */
477         memset ( &av, 0, sizeof ( av ) );
478         av.lid = ibdev->sm_lid;
479         av.sl = ibdev->sm_sl;
480         av.qpn = IB_SA_QPN;
481         av.qkey = IB_GLOBAL_QKEY;
482
483         /* Post send request */
484         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
485                                    iobuf ) ) != 0 ) {
486                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
487                        ipoib, strerror ( rc ) );
488                 free_iob ( iobuf );
489                 return rc;
490         }
491
492         return 0;
493 }
494
495 /**
496  * Transmit multicast group membership request
497  *
498  * @v ipoib             IPoIB device
499  * @v gid               Multicast GID
500  * @v join              Join (rather than leave) group
501  * @ret rc              Return status code
502  */
503 static int ipoib_mc_member_record ( struct ipoib_device *ipoib,
504                                     struct ib_gid *gid, int join ) {
505         struct ib_device *ibdev = ipoib->ibdev;
506         struct io_buffer *iobuf;
507         struct ib_mad_sa *sa;
508         struct ib_address_vector av;
509         int rc;
510
511         /* Allocate I/O buffer */
512         iobuf = alloc_iob ( sizeof ( *sa ) );
513         if ( ! iobuf )
514                 return -ENOMEM;
515         iob_put ( iobuf, sizeof ( *sa ) );
516         sa = iobuf->data;
517         memset ( sa, 0, sizeof ( *sa ) );
518
519         /* Construct path record request */
520         sa->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
521         sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
522         sa->mad_hdr.class_version = 2;
523         sa->mad_hdr.method =
524                 ( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE );
525         sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC );
526         sa->mad_hdr.tid[0] = IPOIB_TID_MC_MEMBER_REC;
527         sa->mad_hdr.tid[1] = ipoib_meta_tid++;
528         sa->sa_hdr.comp_mask[1] =
529                 htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
530                         IB_SA_MCMEMBER_REC_JOIN_STATE );
531         sa->sa_data.mc_member_record.scope__join_state = 1;
532         memcpy ( &sa->sa_data.mc_member_record.mgid, gid,
533                  sizeof ( sa->sa_data.mc_member_record.mgid ) );
534         memcpy ( &sa->sa_data.mc_member_record.port_gid, &ibdev->gid,
535                  sizeof ( sa->sa_data.mc_member_record.port_gid ) );
536
537         /* Construct address vector */
538         memset ( &av, 0, sizeof ( av ) );
539         av.lid = ibdev->sm_lid;
540         av.sl = ibdev->sm_sl;
541         av.qpn = IB_SA_QPN;
542         av.qkey = IB_GLOBAL_QKEY;
543
544         /* Post send request */
545         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
546                                    iobuf ) ) != 0 ) {
547                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
548                        ipoib, strerror ( rc ) );
549                 free_iob ( iobuf );
550                 return rc;
551         }
552
553         return 0;
554 }
555
556 /**
557  * Transmit packet via IPoIB network device
558  *
559  * @v netdev            Network device
560  * @v iobuf             I/O buffer
561  * @ret rc              Return status code
562  */
563 static int ipoib_transmit ( struct net_device *netdev,
564                             struct io_buffer *iobuf ) {
565         struct ipoib_device *ipoib = netdev->priv;
566         struct ib_device *ibdev = ipoib->ibdev;
567         struct ipoib_hdr *ipoib_hdr;
568         struct ipoib_peer *dest;
569         struct ib_address_vector av;
570         struct ib_gid *gid;
571
572         /* Sanity check */
573         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
574                 DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
575                 return -EINVAL;
576         }
577         ipoib_hdr = iobuf->data;
578
579         /* Attempting transmission while link is down will put the
580          * queue pair into an error state, so don't try it.
581          */
582         if ( ! ib_link_ok ( ibdev ) )
583                 return -ENETUNREACH;
584
585         /* Identify destination address */
586         dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest );
587         if ( ! dest )
588                 return -ENXIO;
589         ipoib_hdr->u.reserved = 0;
590
591         /* Construct address vector */
592         memset ( &av, 0, sizeof ( av ) );
593         av.qkey = ipoib->data_qkey;
594         av.gid_present = 1;
595         if ( dest->mac.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
596                 /* Broadcast */
597                 av.qpn = IB_BROADCAST_QPN;
598                 av.lid = ipoib->broadcast_lid;
599                 gid = &ipoib->broadcast_gid;
600         } else {
601                 /* Unicast */
602                 if ( ! dest->lid ) {
603                         /* No LID yet - get path record to fetch LID */
604                         ipoib_get_path_record ( ipoib, &dest->mac.gid );
605                         return -ENOENT;
606                 }
607                 av.qpn = ntohl ( dest->mac.qpn );
608                 av.lid = dest->lid;
609                 av.rate = dest->rate;
610                 av.sl = dest->sl;
611                 gid = &dest->mac.gid;
612         }
613         memcpy ( &av.gid, gid, sizeof ( av.gid ) );
614
615         return ib_post_send ( ibdev, ipoib->data.qp, &av, iobuf );
616 }
617
618 /**
619  * Handle IPoIB data send completion
620  *
621  * @v ibdev             Infiniband device
622  * @v qp                Queue pair
623  * @v iobuf             I/O buffer
624  * @v rc                Completion status code
625  */
626 static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
627                                        struct ib_queue_pair *qp,
628                                        struct io_buffer *iobuf, int rc ) {
629         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
630
631         netdev_tx_complete_err ( netdev, iobuf, rc );
632 }
633
634 /**
635  * Handle IPoIB data receive completion
636  *
637  * @v ibdev             Infiniband device
638  * @v qp                Queue pair
639  * @v av                Address vector, or NULL
640  * @v iobuf             I/O buffer
641  * @v rc                Completion status code
642  */
643 static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
644                                        struct ib_queue_pair *qp,
645                                        struct ib_address_vector *av,
646                                        struct io_buffer *iobuf, int rc ) {
647         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
648         struct ipoib_device *ipoib = netdev->priv;
649         struct ipoib_hdr *ipoib_hdr;
650         struct ipoib_peer *src;
651
652         if ( rc != 0 ) {
653                 netdev_rx_err ( netdev, iobuf, rc );
654                 return;
655         }
656
657         /* Sanity check */
658         if ( iob_len ( iobuf ) < sizeof ( struct ipoib_hdr ) ) {
659                 DBGC ( ipoib, "IPoIB %p received data packet too short to "
660                        "contain IPoIB header\n", ipoib );
661                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
662                 netdev_rx_err ( netdev, iobuf, -EIO );
663                 return;
664         }
665         ipoib_hdr = iobuf->data;
666
667         /* Parse source address */
668         if ( av->gid_present ) {
669                 src = ipoib_cache_peer ( &av->gid, av->qpn );
670                 ipoib_hdr->u.peer.src = src->key;
671         }
672
673         /* Hand off to network layer */
674         netdev_rx ( netdev, iobuf );
675 }
676
677 /** IPoIB data completion operations */
678 static struct ib_completion_queue_operations ipoib_data_cq_op = {
679         .complete_send = ipoib_data_complete_send,
680         .complete_recv = ipoib_data_complete_recv,
681 };
682
683 /**
684  * Handle IPoIB metadata send completion
685  *
686  * @v ibdev             Infiniband device
687  * @v qp                Queue pair
688  * @v iobuf             I/O buffer
689  * @v rc                Completion status code
690  */
691 static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
692                                        struct ib_queue_pair *qp,
693                                        struct io_buffer *iobuf, int rc ) {
694         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
695         struct ipoib_device *ipoib = netdev->priv;
696
697         if ( rc != 0 ) {
698                 DBGC ( ipoib, "IPoIB %p metadata TX completion error: %s\n",
699                        ipoib, strerror ( rc ) );
700         }
701         free_iob ( iobuf );
702 }
703
704 /**
705  * Handle received IPoIB path record
706  *
707  * @v ipoib             IPoIB device
708  * @v path_record       Path record
709  */
710 static void ipoib_recv_path_record ( struct ipoib_device *ipoib,
711                                      struct ib_path_record *path_record ) {
712         struct ipoib_peer *peer;
713
714         /* Locate peer cache entry */
715         peer = ipoib_lookup_peer_by_gid ( &path_record->dgid );
716         if ( ! peer ) {
717                 DBGC ( ipoib, "IPoIB %p received unsolicited path record\n",
718                        ipoib );
719                 return;
720         }
721
722         /* Update path cache entry */
723         peer->lid = ntohs ( path_record->dlid );
724         peer->sl = ( path_record->reserved__sl & 0x0f );
725         peer->rate = ( path_record->rate_selector__rate & 0x3f );
726
727         DBG ( "IPoIB peer %x has dlid %x sl %x rate %x\n",
728               peer->key, peer->lid, peer->sl, peer->rate );
729 }
730
731 /**
732  * Handle received IPoIB multicast membership record
733  *
734  * @v ipoib             IPoIB device
735  * @v mc_member_record  Multicast membership record
736  */
737 static void ipoib_recv_mc_member_record ( struct ipoib_device *ipoib,
738                                struct ib_mc_member_record *mc_member_record ) {
739         int joined;
740         int rc;
741
742         /* Record parameters */
743         joined = ( mc_member_record->scope__join_state & 0x0f );
744         ipoib->data_qkey = ntohl ( mc_member_record->qkey );
745         ipoib->broadcast_lid = ntohs ( mc_member_record->mlid );
746         DBGC ( ipoib, "IPoIB %p %s broadcast group: qkey %lx mlid %x\n",
747                ipoib, ( joined ? "joined" : "left" ), ipoib->data_qkey,
748                ipoib->broadcast_lid );
749
750         /* Update data queue pair qkey */
751         if ( ( rc = ib_modify_qp ( ipoib->ibdev, ipoib->data.qp,
752                                    IB_MODIFY_QKEY, ipoib->data_qkey ) ) != 0 ){
753                 DBGC ( ipoib, "IPoIB %p could not update data qkey: %s\n",
754                        ipoib, strerror ( rc ) );
755                 return;
756         }
757 }
758
759 /**
760  * Handle IPoIB metadata receive completion
761  *
762  * @v ibdev             Infiniband device
763  * @v qp                Queue pair
764  * @v av                Address vector, or NULL
765  * @v iobuf             I/O buffer
766  * @v rc                Completion status code
767  */
768 static void
769 ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
770                            struct ib_queue_pair *qp,
771                            struct ib_address_vector *av __unused,
772                            struct io_buffer *iobuf, int rc ) {
773         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
774         struct ipoib_device *ipoib = netdev->priv;
775         struct ib_mad_sa *sa;
776
777         if ( rc != 0 ) {
778                 DBGC ( ipoib, "IPoIB %p metadata RX completion error: %s\n",
779                        ipoib, strerror ( rc ) );
780                 goto done;
781         }
782
783         if ( iob_len ( iobuf ) < sizeof ( *sa ) ) {
784                 DBGC ( ipoib, "IPoIB %p received metadata packet too short "
785                        "to contain reply\n", ipoib );
786                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
787                 goto done;
788         }
789         sa = iobuf->data;
790
791         if ( sa->mad_hdr.status != 0 ) {
792                 DBGC ( ipoib, "IPoIB %p metadata RX err status %04x\n",
793                        ipoib, ntohs ( sa->mad_hdr.status ) );
794                 goto done;
795         }
796
797         switch ( sa->mad_hdr.tid[0] ) {
798         case IPOIB_TID_GET_PATH_REC:
799                 ipoib_recv_path_record ( ipoib, &sa->sa_data.path_record );
800                 break;
801         case IPOIB_TID_MC_MEMBER_REC:
802                 ipoib_recv_mc_member_record ( ipoib,
803                                               &sa->sa_data.mc_member_record );
804                 break;
805         default:
806                 DBGC ( ipoib, "IPoIB %p unwanted response:\n",
807                        ipoib );
808                 DBGC_HD ( ipoib, sa, sizeof ( *sa ) );
809                 break;
810         }
811
812  done:
813         free_iob ( iobuf );
814 }
815
816 /** IPoIB metadata completion operations */
817 static struct ib_completion_queue_operations ipoib_meta_cq_op = {
818         .complete_send = ipoib_meta_complete_send,
819         .complete_recv = ipoib_meta_complete_recv,
820 };
821
822 /**
823  * Refill IPoIB receive ring
824  *
825  * @v ipoib             IPoIB device
826  */
827 static void ipoib_refill_recv ( struct ipoib_device *ipoib,
828                                 struct ipoib_queue_set *qset ) {
829         struct ib_device *ibdev = ipoib->ibdev;
830         struct io_buffer *iobuf;
831         int rc;
832
833         while ( qset->qp->recv.fill < qset->recv_max_fill ) {
834                 iobuf = alloc_iob ( IPOIB_PKT_LEN );
835                 if ( ! iobuf )
836                         break;
837                 if ( ( rc = ib_post_recv ( ibdev, qset->qp, iobuf ) ) != 0 ) {
838                         free_iob ( iobuf );
839                         break;
840                 }
841         }
842 }
843
844 /**
845  * Poll IPoIB network device
846  *
847  * @v netdev            Network device
848  */
849 static void ipoib_poll ( struct net_device *netdev ) {
850         struct ipoib_device *ipoib = netdev->priv;
851         struct ib_device *ibdev = ipoib->ibdev;
852
853         ib_poll_cq ( ibdev, ipoib->meta.cq );
854         ib_poll_cq ( ibdev, ipoib->data.cq );
855         ipoib_refill_recv ( ipoib, &ipoib->meta );
856         ipoib_refill_recv ( ipoib, &ipoib->data );
857 }
858
859 /**
860  * Enable/disable interrupts on IPoIB network device
861  *
862  * @v netdev            Network device
863  * @v enable            Interrupts should be enabled
864  */
865 static void ipoib_irq ( struct net_device *netdev __unused,
866                         int enable __unused ) {
867         /* No implementation */
868 }
869
870 /**
871  * Join IPv4 broadcast multicast group
872  *
873  * @v ipoib             IPoIB device
874  * @ret rc              Return status code
875  */
876 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
877         int rc;
878
879         /* Sanity check */
880         if ( ! ipoib->data.qp )
881                 return 0;
882
883         /* Attach data queue to broadcast multicast GID */
884         assert ( ipoib->broadcast_attached == 0 );
885         if ( ( rc = ib_mcast_attach ( ipoib->ibdev, ipoib->data.qp,
886                                       &ipoib->broadcast_gid ) ) != 0 ){
887                 DBGC ( ipoib, "IPoIB %p could not attach to broadcast GID: "
888                        "%s\n", ipoib, strerror ( rc ) );
889                 return rc;
890         }
891         ipoib->broadcast_attached = 1;
892
893         /* Initiate broadcast group join */
894         if ( ( rc = ipoib_mc_member_record ( ipoib, &ipoib->broadcast_gid,
895                                              1 ) ) != 0 ) {
896                 DBGC ( ipoib, "IPoIB %p could not send broadcast join: %s\n",
897                        ipoib, strerror ( rc ) );
898                 return rc;
899         }
900
901         /* We will set link up on the network device when we receive
902          * the broadcast join response.
903          */
904
905         return 0;
906 }
907
908 /**
909  * Leave IPv4 broadcast multicast group
910  *
911  * @v ipoib             IPoIB device
912  */
913 static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) {
914
915         /* Detach data queue from broadcast multicast GID */
916         if ( ipoib->broadcast_attached ) {
917                 assert ( ipoib->data.qp != NULL );
918                 ib_mcast_detach ( ipoib->ibdev, ipoib->data.qp,
919                                   &ipoib->broadcast_gid );
920                 ipoib->broadcast_attached = 0;
921         }
922 }
923
924 /**
925  * Open IPoIB network device
926  *
927  * @v netdev            Network device
928  * @ret rc              Return status code
929  */
930 static int ipoib_open ( struct net_device *netdev ) {
931         struct ipoib_device *ipoib = netdev->priv;
932         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
933         int rc;
934
935         /* Open IB device */
936         if ( ( rc = ib_open ( ipoib->ibdev ) ) != 0 ) {
937                 DBGC ( ipoib, "IPoIB %p could not open device: %s\n",
938                        ipoib, strerror ( rc ) );
939                 goto err_ib_open;
940         }
941
942         /* Allocate metadata queue set */
943         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
944                                         IPOIB_META_NUM_CQES,
945                                         &ipoib_meta_cq_op,
946                                         IPOIB_META_NUM_SEND_WQES,
947                                         IPOIB_META_NUM_RECV_WQES,
948                                         IB_GLOBAL_QKEY ) ) != 0 ) {
949                 DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
950                        ipoib, strerror ( rc ) );
951                 goto err_create_meta_qset;
952         }
953
954         /* Allocate data queue set */
955         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
956                                         IPOIB_DATA_NUM_CQES,
957                                         &ipoib_data_cq_op,
958                                         IPOIB_DATA_NUM_SEND_WQES,
959                                         IPOIB_DATA_NUM_RECV_WQES,
960                                         IB_GLOBAL_QKEY ) ) != 0 ) {
961                 DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
962                        ipoib, strerror ( rc ) );
963                 goto err_create_data_qset;
964         }
965
966         /* Update MAC address with data QPN */
967         mac->qpn = htonl ( ipoib->data.qp->qpn );
968
969         /* Fill receive rings */
970         ipoib_refill_recv ( ipoib, &ipoib->meta );
971         ipoib_refill_recv ( ipoib, &ipoib->data );
972
973         /* Join broadcast group */
974         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
975                 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
976                        ipoib, strerror ( rc ) );
977                 goto err_join_broadcast;
978         }
979
980         return 0;
981
982  err_join_broadcast:
983         ipoib_destroy_qset ( ipoib, &ipoib->data );
984  err_create_data_qset:
985         ipoib_destroy_qset ( ipoib, &ipoib->meta );
986  err_create_meta_qset:
987         ib_close ( ipoib->ibdev );
988  err_ib_open:
989         return rc;
990 }
991
992 /**
993  * Close IPoIB network device
994  *
995  * @v netdev            Network device
996  */
997 static void ipoib_close ( struct net_device *netdev ) {
998         struct ipoib_device *ipoib = netdev->priv;
999         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
1000
1001         /* Leave broadcast group */
1002         ipoib_leave_broadcast_group ( ipoib );
1003
1004         /* Remove data QPN from MAC address */
1005         mac->qpn = 0;
1006
1007         /* Tear down the queues */
1008         ipoib_destroy_qset ( ipoib, &ipoib->data );
1009         ipoib_destroy_qset ( ipoib, &ipoib->meta );
1010
1011         /* Close IB device */
1012         ib_close ( ipoib->ibdev );
1013 }
1014
1015 /** IPoIB network device operations */
1016 static struct net_device_operations ipoib_operations = {
1017         .open           = ipoib_open,
1018         .close          = ipoib_close,
1019         .transmit       = ipoib_transmit,
1020         .poll           = ipoib_poll,
1021         .irq            = ipoib_irq,
1022 };
1023
1024 /**
1025  * Update IPoIB dynamic Infiniband parameters
1026  *
1027  * @v ipoib             IPoIB device
1028  *
1029  * The Infiniband port GID and partition key will change at runtime,
1030  * when the link is established (or lost).  The MAC address is based
1031  * on the port GID, and the broadcast GID is based on the partition
1032  * key.  This function recalculates these IPoIB device parameters.
1033  */
1034 static void ipoib_set_ib_params ( struct ipoib_device *ipoib ) {
1035         struct ib_device *ibdev = ipoib->ibdev;
1036         struct net_device *netdev = ipoib->netdev;
1037         struct ipoib_mac *mac;
1038
1039         /* Calculate GID portion of MAC address based on port GID */
1040         mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
1041         memcpy ( &mac->gid, &ibdev->gid, sizeof ( mac->gid ) );
1042
1043         /* Calculate broadcast GID based on partition key */
1044         memcpy ( &ipoib->broadcast_gid, &ipoib_broadcast.gid,
1045                  sizeof ( ipoib->broadcast_gid ) );
1046         ipoib->broadcast_gid.u.words[2] = htons ( ibdev->pkey );
1047
1048         /* Set net device link state to reflect Infiniband link state */
1049         if ( ib_link_ok ( ibdev ) ) {
1050                 netdev_link_up ( netdev );
1051         } else {
1052                 netdev_link_down ( netdev );
1053         }
1054 }
1055
1056 /**
1057  * Handle link status change
1058  *
1059  * @v ibdev             Infiniband device
1060  */
1061 void ipoib_link_state_changed ( struct ib_device *ibdev ) {
1062         struct net_device *netdev = ib_get_ownerdata ( ibdev );
1063         struct ipoib_device *ipoib = netdev->priv;
1064         int rc;
1065
1066         /* Leave existing broadcast group */
1067         ipoib_leave_broadcast_group ( ipoib );
1068
1069         /* Update MAC address and broadcast GID based on new port GID
1070          * and partition key.
1071          */
1072         ipoib_set_ib_params ( ipoib );
1073
1074         /* Join new broadcast group */
1075         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
1076                 DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
1077                        "%s\n", ipoib, strerror ( rc ) );
1078                 return;
1079         }
1080 }
1081
1082 /**
1083  * Probe IPoIB device
1084  *
1085  * @v ibdev             Infiniband device
1086  * @ret rc              Return status code
1087  */
1088 int ipoib_probe ( struct ib_device *ibdev ) {
1089         struct net_device *netdev;
1090         struct ipoib_device *ipoib;
1091         int rc;
1092
1093         /* Allocate network device */
1094         netdev = alloc_ipoibdev ( sizeof ( *ipoib ) );
1095         if ( ! netdev )
1096                 return -ENOMEM;
1097         netdev_init ( netdev, &ipoib_operations );
1098         ipoib = netdev->priv;
1099         ib_set_ownerdata ( ibdev, netdev );
1100         netdev->dev = ibdev->dev;
1101         memset ( ipoib, 0, sizeof ( *ipoib ) );
1102         ipoib->netdev = netdev;
1103         ipoib->ibdev = ibdev;
1104
1105         /* Calculate as much of the broadcast GID and the MAC address
1106          * as we can.  We won't know either of these in full until we
1107          * have link-up.
1108          */
1109         ipoib_set_ib_params ( ipoib );
1110
1111         /* Register network device */
1112         if ( ( rc = register_netdev ( netdev ) ) != 0 )
1113                 goto err_register_netdev;
1114
1115         return 0;
1116
1117  err_register_netdev:
1118         netdev_nullify ( netdev );
1119         netdev_put ( netdev );
1120         return rc;
1121 }
1122
1123 /**
1124  * Remove IPoIB device
1125  *
1126  * @v ibdev             Infiniband device
1127  */
1128 void ipoib_remove ( struct ib_device *ibdev ) {
1129         struct net_device *netdev = ib_get_ownerdata ( ibdev );
1130
1131         unregister_netdev ( netdev );
1132         netdev_nullify ( netdev );
1133         netdev_put ( netdev );
1134 }