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