[infiniband] Update all other MAD users to use a management interface
[people/peper/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/ib_pathrec.h>
32 #include <gpxe/ib_mcast.h>
33 #include <gpxe/ipoib.h>
34
35 /** @file
36  *
37  * IP over Infiniband
38  */
39
40 /** Number of IPoIB send work queue entries */
41 #define IPOIB_NUM_SEND_WQES 2
42
43 /** Number of IPoIB receive work queue entries */
44 #define IPOIB_NUM_RECV_WQES 4
45
46 /** Number of IPoIB completion entries */
47 #define IPOIB_NUM_CQES 8
48
49 /** An IPoIB device */
50 struct ipoib_device {
51         /** Network device */
52         struct net_device *netdev;
53         /** Underlying Infiniband device */
54         struct ib_device *ibdev;
55         /** Completion queue */
56         struct ib_completion_queue *cq;
57         /** Queue pair */
58         struct ib_queue_pair *qp;
59         /** Broadcast MAC */
60         struct ipoib_mac broadcast;
61         /** Joined to IPv4 broadcast multicast group
62          *
63          * This flag indicates whether or not we have initiated the
64          * join to the IPv4 broadcast multicast group.
65          */
66         int broadcast_joined;
67         /** IPv4 broadcast multicast group membership */
68         struct ib_mc_membership broadcast_membership;
69 };
70
71 /** Broadcast IPoIB address */
72 static struct ipoib_mac ipoib_broadcast = {
73         .qpn = htonl ( IB_QPN_BROADCAST ),
74         .gid.u.bytes =  { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
75                           0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff },
76 };
77
78 /****************************************************************************
79  *
80  * IPoIB peer cache
81  *
82  ****************************************************************************
83  */
84
85 /**
86  * IPoIB peer address
87  *
88  * The IPoIB link-layer header is only four bytes long and so does not
89  * have sufficient room to store IPoIB MAC address(es).  We therefore
90  * maintain a cache of MAC addresses identified by a single-byte key,
91  * and abuse the spare two bytes within the link-layer header to
92  * communicate these MAC addresses between the link-layer code and the
93  * netdevice driver.
94  */
95 struct ipoib_peer {
96         /** Key */
97         uint8_t key;
98         /** MAC address */
99         struct ipoib_mac mac;
100 };
101
102 /** Number of IPoIB peer cache entries
103  *
104  * Must be a power of two.
105  */
106 #define IPOIB_NUM_CACHED_PEERS 4
107
108 /** IPoIB peer address cache */
109 static struct ipoib_peer ipoib_peer_cache[IPOIB_NUM_CACHED_PEERS];
110
111 /** Oldest IPoIB peer cache entry index */
112 static unsigned int ipoib_peer_cache_idx = 1;
113
114 /**
115  * Look up cached peer by key
116  *
117  * @v key               Peer cache key
118  * @ret peer            Peer cache entry, or NULL
119  */
120 static struct ipoib_peer * ipoib_lookup_peer_by_key ( unsigned int key ) {
121         struct ipoib_peer *peer;
122         unsigned int i;
123
124         for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) {
125                 peer = &ipoib_peer_cache[i];
126                 if ( peer->key == key )
127                         return peer;
128         }
129
130         if ( key != 0 ) {
131                 DBG ( "IPoIB warning: peer cache lost track of key %x while "
132                       "still in use\n", key );
133         }
134         return NULL;
135 }
136
137 /**
138  * Store GID and QPN in peer cache
139  *
140  * @v gid               Peer GID
141  * @v qpn               Peer QPN
142  * @ret peer            Peer cache entry
143  */
144 static struct ipoib_peer * ipoib_cache_peer ( const struct ipoib_mac *mac ) {
145         struct ipoib_peer *peer;
146         unsigned int key;
147         unsigned int i;
148
149         /* Look for existing cache entry */
150         for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) {
151                 peer = &ipoib_peer_cache[i];
152                 if ( memcmp ( &peer->mac, mac, sizeof ( peer->mac ) ) == 0 )
153                         return peer;
154         }
155
156         /* No entry found: create a new one */
157         key = ipoib_peer_cache_idx++;
158         peer = &ipoib_peer_cache[ key % IPOIB_NUM_CACHED_PEERS ];
159         if ( peer->key )
160                 DBG ( "IPoIB peer %x evicted from cache\n", peer->key );
161
162         memset ( peer, 0, sizeof ( *peer ) );
163         peer->key = key;
164         memcpy ( &peer->mac, mac, sizeof ( peer->mac ) );
165         DBG ( "IPoIB peer %x has MAC %s\n",
166               peer->key, ipoib_ntoa ( &peer->mac ) );
167         return peer;
168 }
169
170 /****************************************************************************
171  *
172  * IPoIB link layer
173  *
174  ****************************************************************************
175  */
176
177 /**
178  * Add IPoIB link-layer header
179  *
180  * @v netdev            Network device
181  * @v iobuf             I/O buffer
182  * @v ll_dest           Link-layer destination address
183  * @v ll_source         Source link-layer address
184  * @v net_proto         Network-layer protocol, in network-byte order
185  * @ret rc              Return status code
186  */
187 static int ipoib_push ( struct net_device *netdev __unused,
188                         struct io_buffer *iobuf, const void *ll_dest,
189                         const void *ll_source __unused, uint16_t net_proto ) {
190         struct ipoib_hdr *ipoib_hdr =
191                 iob_push ( iobuf, sizeof ( *ipoib_hdr ) );
192         const struct ipoib_mac *dest_mac = ll_dest;
193         const struct ipoib_mac *src_mac = ll_source;
194         struct ipoib_peer *dest;
195         struct ipoib_peer *src;
196
197         /* Add link-layer addresses to cache */
198         dest = ipoib_cache_peer ( dest_mac );
199         src = ipoib_cache_peer ( src_mac );
200
201         /* Build IPoIB header */
202         ipoib_hdr->proto = net_proto;
203         ipoib_hdr->u.peer.dest = dest->key;
204         ipoib_hdr->u.peer.src = src->key;
205
206         return 0;
207 }
208
209 /**
210  * Remove IPoIB link-layer header
211  *
212  * @v netdev            Network device
213  * @v iobuf             I/O buffer
214  * @ret ll_dest         Link-layer destination address
215  * @ret ll_source       Source link-layer address
216  * @ret net_proto       Network-layer protocol, in network-byte order
217  * @ret rc              Return status code
218  */
219 static int ipoib_pull ( struct net_device *netdev,
220                         struct io_buffer *iobuf, const void **ll_dest,
221                         const void **ll_source, uint16_t *net_proto ) {
222         struct ipoib_device *ipoib = netdev->priv;
223         struct ipoib_hdr *ipoib_hdr = iobuf->data;
224         struct ipoib_peer *dest;
225         struct ipoib_peer *source;
226
227         /* Sanity check */
228         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
229                 DBG ( "IPoIB packet too short for link-layer header\n" );
230                 DBG_HD ( iobuf->data, iob_len ( iobuf ) );
231                 return -EINVAL;
232         }
233
234         /* Strip off IPoIB header */
235         iob_pull ( iobuf, sizeof ( *ipoib_hdr ) );
236
237         /* Identify source and destination addresses, and clear
238          * reserved word in IPoIB header
239          */
240         dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest );
241         source = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.src );
242         ipoib_hdr->u.reserved = 0;
243
244         /* Fill in required fields */
245         *ll_dest = ( dest ? &dest->mac : &ipoib->broadcast );
246         *ll_source = ( source ? &source->mac : &ipoib->broadcast );
247         *net_proto = ipoib_hdr->proto;
248
249         return 0;
250 }
251
252 /**
253  * Transcribe IPoIB address
254  *
255  * @v ll_addr   Link-layer address
256  * @ret string  Link-layer address in human-readable format
257  */
258 const char * ipoib_ntoa ( const void *ll_addr ) {
259         static char buf[45];
260         const struct ipoib_mac *mac = ll_addr;
261
262         snprintf ( buf, sizeof ( buf ), "%08x:%08x:%08x:%08x:%08x",
263                    htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
264                    htonl ( mac->gid.u.dwords[1] ),
265                    htonl ( mac->gid.u.dwords[2] ),
266                    htonl ( mac->gid.u.dwords[3] ) );
267         return buf;
268 }
269
270 /**
271  * Hash multicast address
272  *
273  * @v af                Address family
274  * @v net_addr          Network-layer address
275  * @v ll_addr           Link-layer address to fill in
276  * @ret rc              Return status code
277  */
278 static int ipoib_mc_hash ( unsigned int af __unused,
279                            const void *net_addr __unused,
280                            void *ll_addr __unused ) {
281
282         return -ENOTSUP;
283 }
284
285 /** IPoIB protocol */
286 struct ll_protocol ipoib_protocol __ll_protocol = {
287         .name           = "IPoIB",
288         .ll_proto       = htons ( ARPHRD_INFINIBAND ),
289         .ll_addr_len    = IPOIB_ALEN,
290         .ll_header_len  = IPOIB_HLEN,
291         .push           = ipoib_push,
292         .pull           = ipoib_pull,
293         .ntoa           = ipoib_ntoa,
294         .mc_hash        = ipoib_mc_hash,
295 };
296
297 /**
298  * Allocate IPoIB device
299  *
300  * @v priv_size         Size of driver private data
301  * @ret netdev          Network device, or NULL
302  */
303 struct net_device * alloc_ipoibdev ( size_t priv_size ) {
304         struct net_device *netdev;
305
306         netdev = alloc_netdev ( priv_size );
307         if ( netdev ) {
308                 netdev->ll_protocol = &ipoib_protocol;
309                 netdev->ll_broadcast = ( uint8_t * ) &ipoib_broadcast;
310                 netdev->max_pkt_len = IB_MAX_PAYLOAD_SIZE;
311         }
312         return netdev;
313 }
314
315 /****************************************************************************
316  *
317  * IPoIB network device
318  *
319  ****************************************************************************
320  */
321
322 /**
323  * Transmit packet via IPoIB network device
324  *
325  * @v netdev            Network device
326  * @v iobuf             I/O buffer
327  * @ret rc              Return status code
328  */
329 static int ipoib_transmit ( struct net_device *netdev,
330                             struct io_buffer *iobuf ) {
331         struct ipoib_device *ipoib = netdev->priv;
332         struct ib_device *ibdev = ipoib->ibdev;
333         struct ipoib_hdr *ipoib_hdr;
334         struct ipoib_peer *dest;
335         struct ib_address_vector av;
336         int rc;
337
338         /* Sanity check */
339         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
340                 DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
341                 return -EINVAL;
342         }
343         ipoib_hdr = iobuf->data;
344
345         /* Attempting transmission while link is down will put the
346          * queue pair into an error state, so don't try it.
347          */
348         if ( ! ib_link_ok ( ibdev ) )
349                 return -ENETUNREACH;
350
351         /* Identify destination address */
352         dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest );
353         if ( ! dest )
354                 return -ENXIO;
355         ipoib_hdr->u.reserved = 0;
356
357         /* Construct address vector */
358         memset ( &av, 0, sizeof ( av ) );
359         av.qpn = ntohl ( dest->mac.qpn );
360         av.gid_present = 1;
361         memcpy ( &av.gid, &dest->mac.gid, sizeof ( av.gid ) );
362         if ( ( rc = ib_resolve_path ( ibdev, &av ) ) != 0 ) {
363                 /* Path not resolved yet */
364                 return rc;
365         }
366
367         return ib_post_send ( ibdev, ipoib->qp, &av, iobuf );
368 }
369
370 /**
371  * Handle IPoIB send completion
372  *
373  * @v ibdev             Infiniband device
374  * @v qp                Queue pair
375  * @v iobuf             I/O buffer
376  * @v rc                Completion status code
377  */
378 static void ipoib_complete_send ( struct ib_device *ibdev __unused,
379                                   struct ib_queue_pair *qp,
380                                   struct io_buffer *iobuf, int rc ) {
381         struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp );
382
383         netdev_tx_complete_err ( ipoib->netdev, iobuf, rc );
384 }
385
386 /**
387  * Handle IPoIB receive completion
388  *
389  * @v ibdev             Infiniband device
390  * @v qp                Queue pair
391  * @v av                Address vector, or NULL
392  * @v iobuf             I/O buffer
393  * @v rc                Completion status code
394  */
395 static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
396                                   struct ib_queue_pair *qp,
397                                   struct ib_address_vector *av,
398                                   struct io_buffer *iobuf, int rc ) {
399         struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp );
400         struct net_device *netdev = ipoib->netdev;
401         struct ipoib_hdr *ipoib_hdr;
402         struct ipoib_mac ll_src;
403         struct ipoib_peer *src;
404
405         if ( rc != 0 ) {
406                 netdev_rx_err ( netdev, iobuf, rc );
407                 return;
408         }
409
410         /* Sanity check */
411         if ( iob_len ( iobuf ) < sizeof ( struct ipoib_hdr ) ) {
412                 DBGC ( ipoib, "IPoIB %p received packet too short to "
413                        "contain IPoIB header\n", ipoib );
414                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
415                 netdev_rx_err ( netdev, iobuf, -EIO );
416                 return;
417         }
418         ipoib_hdr = iobuf->data;
419
420         /* Parse source address */
421         if ( av->gid_present ) {
422                 ll_src.qpn = htonl ( av->qpn );
423                 memcpy ( &ll_src.gid, &av->gid, sizeof ( ll_src.gid ) );
424                 src = ipoib_cache_peer ( &ll_src );
425                 ipoib_hdr->u.peer.src = src->key;
426         }
427
428         /* Hand off to network layer */
429         netdev_rx ( netdev, iobuf );
430 }
431
432 /** IPoIB completion operations */
433 static struct ib_completion_queue_operations ipoib_cq_op = {
434         .complete_send = ipoib_complete_send,
435         .complete_recv = ipoib_complete_recv,
436 };
437
438 /**
439  * Poll IPoIB network device
440  *
441  * @v netdev            Network device
442  */
443 static void ipoib_poll ( struct net_device *netdev ) {
444         struct ipoib_device *ipoib = netdev->priv;
445         struct ib_device *ibdev = ipoib->ibdev;
446
447         ib_poll_eq ( ibdev );
448 }
449
450 /**
451  * Enable/disable interrupts on IPoIB network device
452  *
453  * @v netdev            Network device
454  * @v enable            Interrupts should be enabled
455  */
456 static void ipoib_irq ( struct net_device *netdev __unused,
457                         int enable __unused ) {
458         /* No implementation */
459 }
460
461 /**
462  * Handle IPv4 broadcast multicast group join completion
463  *
464  * @v ibdev             Infiniband device
465  * @v qp                Queue pair
466  * @v membership        Multicast group membership
467  * @v rc                Status code
468  * @v mad               Response MAD (or NULL on error)
469  */
470 void ipoib_join_complete ( struct ib_device *ibdev __unused,
471                            struct ib_queue_pair *qp __unused,
472                            struct ib_mc_membership *membership, int rc,
473                            union ib_mad *mad __unused ) {
474         struct ipoib_device *ipoib = container_of ( membership,
475                                    struct ipoib_device, broadcast_membership );
476
477         /* Record join status as link status */
478         netdev_link_err ( ipoib->netdev, rc );
479 }
480
481 /**
482  * Join IPv4 broadcast multicast group
483  *
484  * @v ipoib             IPoIB device
485  * @ret rc              Return status code
486  */
487 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
488         int rc;
489
490         if ( ( rc = ib_mcast_join ( ipoib->ibdev, ipoib->qp,
491                                     &ipoib->broadcast_membership,
492                                     &ipoib->broadcast.gid,
493                                     ipoib_join_complete ) ) != 0 ) {
494                 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
495                        ipoib, strerror ( rc ) );
496                 return rc;
497         }
498         ipoib->broadcast_joined = 1;
499
500         return 0;
501 }
502
503 /**
504  * Leave IPv4 broadcast multicast group
505  *
506  * @v ipoib             IPoIB device
507  */
508 static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) {
509
510         if ( ipoib->broadcast_joined ) {
511                 ib_mcast_leave ( ipoib->ibdev, ipoib->qp,
512                                  &ipoib->broadcast_membership );
513                 ipoib->broadcast_joined = 0;
514         }
515 }
516
517 /**
518  * Open IPoIB network device
519  *
520  * @v netdev            Network device
521  * @ret rc              Return status code
522  */
523 static int ipoib_open ( struct net_device *netdev ) {
524         struct ipoib_device *ipoib = netdev->priv;
525         struct ib_device *ibdev = ipoib->ibdev;
526         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
527         int rc;
528
529         /* Open IB device */
530         if ( ( rc = ib_open ( ibdev ) ) != 0 ) {
531                 DBGC ( ipoib, "IPoIB %p could not open device: %s\n",
532                        ipoib, strerror ( rc ) );
533                 goto err_ib_open;
534         }
535
536         /* Allocate completion queue */
537         ipoib->cq = ib_create_cq ( ibdev, IPOIB_NUM_CQES, &ipoib_cq_op );
538         if ( ! ipoib->cq ) {
539                 DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
540                        ipoib );
541                 rc = -ENOMEM;
542                 goto err_create_cq;
543         }
544
545         /* Allocate queue pair */
546         ipoib->qp = ib_create_qp ( ibdev, IB_QPT_UD,
547                                    IPOIB_NUM_SEND_WQES, ipoib->cq,
548                                    IPOIB_NUM_RECV_WQES, ipoib->cq );
549         if ( ! ipoib->qp ) {
550                 DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
551                        ipoib );
552                 rc = -ENOMEM;
553                 goto err_create_qp;
554         }
555         ib_qp_set_ownerdata ( ipoib->qp, ipoib );
556
557         /* Update MAC address with QPN */
558         mac->qpn = htonl ( ipoib->qp->qpn );
559
560         /* Fill receive rings */
561         ib_refill_recv ( ibdev, ipoib->qp );
562
563         /* Fake a link status change to join the broadcast group */
564         ipoib_link_state_changed ( ibdev );
565
566         return 0;
567
568         ib_destroy_qp ( ibdev, ipoib->qp );
569  err_create_qp:
570         ib_destroy_cq ( ibdev, ipoib->cq );
571  err_create_cq:
572         ib_close ( ibdev );
573  err_ib_open:
574         return rc;
575 }
576
577 /**
578  * Close IPoIB network device
579  *
580  * @v netdev            Network device
581  */
582 static void ipoib_close ( struct net_device *netdev ) {
583         struct ipoib_device *ipoib = netdev->priv;
584         struct ib_device *ibdev = ipoib->ibdev;
585         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
586
587         /* Leave broadcast group */
588         ipoib_leave_broadcast_group ( ipoib );
589
590         /* Remove QPN from MAC address */
591         mac->qpn = 0;
592
593         /* Tear down the queues */
594         ib_destroy_qp ( ibdev, ipoib->qp );
595         ib_destroy_cq ( ibdev, ipoib->cq );
596
597         /* Close IB device */
598         ib_close ( ibdev );
599 }
600
601 /** IPoIB network device operations */
602 static struct net_device_operations ipoib_operations = {
603         .open           = ipoib_open,
604         .close          = ipoib_close,
605         .transmit       = ipoib_transmit,
606         .poll           = ipoib_poll,
607         .irq            = ipoib_irq,
608 };
609
610 /**
611  * Update IPoIB dynamic Infiniband parameters
612  *
613  * @v ipoib             IPoIB device
614  *
615  * The Infiniband port GID and partition key will change at runtime,
616  * when the link is established (or lost).  The MAC address is based
617  * on the port GID, and the broadcast GID is based on the partition
618  * key.  This function recalculates these IPoIB device parameters.
619  */
620 static void ipoib_set_ib_params ( struct ipoib_device *ipoib ) {
621         struct ib_device *ibdev = ipoib->ibdev;
622         struct net_device *netdev = ipoib->netdev;
623         struct ipoib_mac *mac;
624
625         /* Calculate GID portion of MAC address based on port GID */
626         mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
627         memcpy ( &mac->gid, &ibdev->gid, sizeof ( mac->gid ) );
628
629         /* Calculate broadcast GID based on partition key */
630         memcpy ( &ipoib->broadcast, &ipoib_broadcast,
631                  sizeof ( ipoib->broadcast ) );
632         ipoib->broadcast.gid.u.words[2] = htons ( ibdev->pkey );
633
634         /* Set net device link state to reflect Infiniband link state */
635         if ( ib_link_ok ( ibdev ) ) {
636                 netdev_link_up ( netdev );
637         } else {
638                 netdev_link_down ( netdev );
639         }
640 }
641
642 /**
643  * Handle link status change
644  *
645  * @v ibdev             Infiniband device
646  */
647 void ipoib_link_state_changed ( struct ib_device *ibdev ) {
648         struct net_device *netdev = ib_get_ownerdata ( ibdev );
649         struct ipoib_device *ipoib = netdev->priv;
650         int rc;
651
652         /* Leave existing broadcast group */
653         ipoib_leave_broadcast_group ( ipoib );
654
655         /* Update MAC address and broadcast GID based on new port GID
656          * and partition key.
657          */
658         ipoib_set_ib_params ( ipoib );
659
660         /* Join new broadcast group */
661         if ( ib_link_ok ( ibdev ) &&
662              ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) {
663                 DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
664                        "%s\n", ipoib, strerror ( rc ) );
665                 return;
666         }
667 }
668
669 /**
670  * Probe IPoIB device
671  *
672  * @v ibdev             Infiniband device
673  * @ret rc              Return status code
674  */
675 int ipoib_probe ( struct ib_device *ibdev ) {
676         struct net_device *netdev;
677         struct ipoib_device *ipoib;
678         int rc;
679
680         /* Allocate network device */
681         netdev = alloc_ipoibdev ( sizeof ( *ipoib ) );
682         if ( ! netdev )
683                 return -ENOMEM;
684         netdev_init ( netdev, &ipoib_operations );
685         ipoib = netdev->priv;
686         ib_set_ownerdata ( ibdev, netdev );
687         netdev->dev = ibdev->dev;
688         netdev->ll_broadcast = ( ( uint8_t * ) &ipoib->broadcast );
689         memset ( ipoib, 0, sizeof ( *ipoib ) );
690         ipoib->netdev = netdev;
691         ipoib->ibdev = ibdev;
692
693         /* Calculate as much of the broadcast GID and the MAC address
694          * as we can.  We won't know either of these in full until we
695          * have link-up.
696          */
697         ipoib_set_ib_params ( ipoib );
698
699         /* Register network device */
700         if ( ( rc = register_netdev ( netdev ) ) != 0 )
701                 goto err_register_netdev;
702
703         return 0;
704
705  err_register_netdev:
706         netdev_nullify ( netdev );
707         netdev_put ( netdev );
708         return rc;
709 }
710
711 /**
712  * Remove IPoIB device
713  *
714  * @v ibdev             Infiniband device
715  */
716 void ipoib_remove ( struct ib_device *ibdev ) {
717         struct net_device *netdev = ib_get_ownerdata ( ibdev );
718
719         unregister_netdev ( netdev );
720         netdev_nullify ( netdev );
721         netdev_put ( netdev );
722 }