dde4ee5a304d23cba1b006e138f02efe6c066b85
[people/meteger/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  * Initialise IPoIB link-layer address
254  *
255  * @v hw_addr           Hardware address
256  * @v ll_addr           Link-layer address
257  */
258 static void ipoib_init_addr ( const void *hw_addr, void *ll_addr ) {
259         const struct ib_gid_half *guid = hw_addr;
260         struct ipoib_mac *mac = ll_addr;
261
262         memset ( mac, 0, sizeof ( *mac ) );
263         memcpy ( &mac->gid.u.half[1], guid, sizeof ( mac->gid.u.half[1] ) );
264 }
265
266 /**
267  * Transcribe IPoIB link-layer address
268  *
269  * @v ll_addr   Link-layer address
270  * @ret string  Link-layer address in human-readable format
271  */
272 const char * ipoib_ntoa ( const void *ll_addr ) {
273         static char buf[45];
274         const struct ipoib_mac *mac = ll_addr;
275
276         snprintf ( buf, sizeof ( buf ), "%08x:%08x:%08x:%08x:%08x",
277                    htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
278                    htonl ( mac->gid.u.dwords[1] ),
279                    htonl ( mac->gid.u.dwords[2] ),
280                    htonl ( mac->gid.u.dwords[3] ) );
281         return buf;
282 }
283
284 /**
285  * Hash multicast address
286  *
287  * @v af                Address family
288  * @v net_addr          Network-layer address
289  * @v ll_addr           Link-layer address to fill in
290  * @ret rc              Return status code
291  */
292 static int ipoib_mc_hash ( unsigned int af __unused,
293                            const void *net_addr __unused,
294                            void *ll_addr __unused ) {
295
296         return -ENOTSUP;
297 }
298
299 /** IPoIB protocol */
300 struct ll_protocol ipoib_protocol __ll_protocol = {
301         .name           = "IPoIB",
302         .ll_proto       = htons ( ARPHRD_INFINIBAND ),
303         .hw_addr_len    = sizeof ( struct ib_gid_half ),
304         .ll_addr_len    = IPOIB_ALEN,
305         .ll_header_len  = IPOIB_HLEN,
306         .push           = ipoib_push,
307         .pull           = ipoib_pull,
308         .init_addr      = ipoib_init_addr,
309         .ntoa           = ipoib_ntoa,
310         .mc_hash        = ipoib_mc_hash,
311 };
312
313 /**
314  * Allocate IPoIB device
315  *
316  * @v priv_size         Size of driver private data
317  * @ret netdev          Network device, or NULL
318  */
319 struct net_device * alloc_ipoibdev ( size_t priv_size ) {
320         struct net_device *netdev;
321
322         netdev = alloc_netdev ( priv_size );
323         if ( netdev ) {
324                 netdev->ll_protocol = &ipoib_protocol;
325                 netdev->ll_broadcast = ( uint8_t * ) &ipoib_broadcast;
326                 netdev->max_pkt_len = IB_MAX_PAYLOAD_SIZE;
327         }
328         return netdev;
329 }
330
331 /****************************************************************************
332  *
333  * IPoIB network device
334  *
335  ****************************************************************************
336  */
337
338 /**
339  * Transmit packet via IPoIB network device
340  *
341  * @v netdev            Network device
342  * @v iobuf             I/O buffer
343  * @ret rc              Return status code
344  */
345 static int ipoib_transmit ( struct net_device *netdev,
346                             struct io_buffer *iobuf ) {
347         struct ipoib_device *ipoib = netdev->priv;
348         struct ib_device *ibdev = ipoib->ibdev;
349         struct ipoib_hdr *ipoib_hdr;
350         struct ipoib_peer *dest;
351         struct ib_address_vector av;
352         int rc;
353
354         /* Sanity check */
355         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
356                 DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
357                 return -EINVAL;
358         }
359         ipoib_hdr = iobuf->data;
360
361         /* Attempting transmission while link is down will put the
362          * queue pair into an error state, so don't try it.
363          */
364         if ( ! ib_link_ok ( ibdev ) )
365                 return -ENETUNREACH;
366
367         /* Identify destination address */
368         dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest );
369         if ( ! dest )
370                 return -ENXIO;
371         ipoib_hdr->u.reserved = 0;
372
373         /* Construct address vector */
374         memset ( &av, 0, sizeof ( av ) );
375         av.qpn = ntohl ( dest->mac.qpn );
376         av.gid_present = 1;
377         memcpy ( &av.gid, &dest->mac.gid, sizeof ( av.gid ) );
378         if ( ( rc = ib_resolve_path ( ibdev, &av ) ) != 0 ) {
379                 /* Path not resolved yet */
380                 return rc;
381         }
382
383         return ib_post_send ( ibdev, ipoib->qp, &av, iobuf );
384 }
385
386 /**
387  * Handle IPoIB send completion
388  *
389  * @v ibdev             Infiniband device
390  * @v qp                Queue pair
391  * @v iobuf             I/O buffer
392  * @v rc                Completion status code
393  */
394 static void ipoib_complete_send ( struct ib_device *ibdev __unused,
395                                   struct ib_queue_pair *qp,
396                                   struct io_buffer *iobuf, int rc ) {
397         struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp );
398
399         netdev_tx_complete_err ( ipoib->netdev, iobuf, rc );
400 }
401
402 /**
403  * Handle IPoIB receive completion
404  *
405  * @v ibdev             Infiniband device
406  * @v qp                Queue pair
407  * @v av                Address vector, or NULL
408  * @v iobuf             I/O buffer
409  * @v rc                Completion status code
410  */
411 static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
412                                   struct ib_queue_pair *qp,
413                                   struct ib_address_vector *av,
414                                   struct io_buffer *iobuf, int rc ) {
415         struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp );
416         struct net_device *netdev = ipoib->netdev;
417         struct ipoib_hdr *ipoib_hdr;
418         struct ipoib_mac ll_src;
419         struct ipoib_peer *src;
420
421         if ( rc != 0 ) {
422                 netdev_rx_err ( netdev, iobuf, rc );
423                 return;
424         }
425
426         /* Sanity check */
427         if ( iob_len ( iobuf ) < sizeof ( struct ipoib_hdr ) ) {
428                 DBGC ( ipoib, "IPoIB %p received packet too short to "
429                        "contain IPoIB header\n", ipoib );
430                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
431                 netdev_rx_err ( netdev, iobuf, -EIO );
432                 return;
433         }
434         ipoib_hdr = iobuf->data;
435
436         /* Parse source address */
437         if ( av->gid_present ) {
438                 ll_src.qpn = htonl ( av->qpn );
439                 memcpy ( &ll_src.gid, &av->gid, sizeof ( ll_src.gid ) );
440                 src = ipoib_cache_peer ( &ll_src );
441                 ipoib_hdr->u.peer.src = src->key;
442         }
443
444         /* Hand off to network layer */
445         netdev_rx ( netdev, iobuf );
446 }
447
448 /** IPoIB completion operations */
449 static struct ib_completion_queue_operations ipoib_cq_op = {
450         .complete_send = ipoib_complete_send,
451         .complete_recv = ipoib_complete_recv,
452 };
453
454 /**
455  * Poll IPoIB network device
456  *
457  * @v netdev            Network device
458  */
459 static void ipoib_poll ( struct net_device *netdev ) {
460         struct ipoib_device *ipoib = netdev->priv;
461         struct ib_device *ibdev = ipoib->ibdev;
462
463         ib_poll_eq ( ibdev );
464 }
465
466 /**
467  * Enable/disable interrupts on IPoIB network device
468  *
469  * @v netdev            Network device
470  * @v enable            Interrupts should be enabled
471  */
472 static void ipoib_irq ( struct net_device *netdev __unused,
473                         int enable __unused ) {
474         /* No implementation */
475 }
476
477 /**
478  * Handle IPv4 broadcast multicast group join completion
479  *
480  * @v ibdev             Infiniband device
481  * @v qp                Queue pair
482  * @v membership        Multicast group membership
483  * @v rc                Status code
484  * @v mad               Response MAD (or NULL on error)
485  */
486 void ipoib_join_complete ( struct ib_device *ibdev __unused,
487                            struct ib_queue_pair *qp __unused,
488                            struct ib_mc_membership *membership, int rc,
489                            union ib_mad *mad __unused ) {
490         struct ipoib_device *ipoib = container_of ( membership,
491                                    struct ipoib_device, broadcast_membership );
492
493         /* Record join status as link status */
494         netdev_link_err ( ipoib->netdev, rc );
495 }
496
497 /**
498  * Join IPv4 broadcast multicast group
499  *
500  * @v ipoib             IPoIB device
501  * @ret rc              Return status code
502  */
503 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
504         int rc;
505
506         if ( ( rc = ib_mcast_join ( ipoib->ibdev, ipoib->qp,
507                                     &ipoib->broadcast_membership,
508                                     &ipoib->broadcast.gid,
509                                     ipoib_join_complete ) ) != 0 ) {
510                 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
511                        ipoib, strerror ( rc ) );
512                 return rc;
513         }
514         ipoib->broadcast_joined = 1;
515
516         return 0;
517 }
518
519 /**
520  * Leave IPv4 broadcast multicast group
521  *
522  * @v ipoib             IPoIB device
523  */
524 static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) {
525
526         if ( ipoib->broadcast_joined ) {
527                 ib_mcast_leave ( ipoib->ibdev, ipoib->qp,
528                                  &ipoib->broadcast_membership );
529                 ipoib->broadcast_joined = 0;
530         }
531 }
532
533 /**
534  * Open IPoIB network device
535  *
536  * @v netdev            Network device
537  * @ret rc              Return status code
538  */
539 static int ipoib_open ( struct net_device *netdev ) {
540         struct ipoib_device *ipoib = netdev->priv;
541         struct ib_device *ibdev = ipoib->ibdev;
542         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
543         int rc;
544
545         /* Open IB device */
546         if ( ( rc = ib_open ( ibdev ) ) != 0 ) {
547                 DBGC ( ipoib, "IPoIB %p could not open device: %s\n",
548                        ipoib, strerror ( rc ) );
549                 goto err_ib_open;
550         }
551
552         /* Allocate completion queue */
553         ipoib->cq = ib_create_cq ( ibdev, IPOIB_NUM_CQES, &ipoib_cq_op );
554         if ( ! ipoib->cq ) {
555                 DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
556                        ipoib );
557                 rc = -ENOMEM;
558                 goto err_create_cq;
559         }
560
561         /* Allocate queue pair */
562         ipoib->qp = ib_create_qp ( ibdev, IB_QPT_UD,
563                                    IPOIB_NUM_SEND_WQES, ipoib->cq,
564                                    IPOIB_NUM_RECV_WQES, ipoib->cq );
565         if ( ! ipoib->qp ) {
566                 DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
567                        ipoib );
568                 rc = -ENOMEM;
569                 goto err_create_qp;
570         }
571         ib_qp_set_ownerdata ( ipoib->qp, ipoib );
572
573         /* Update MAC address with QPN */
574         mac->qpn = htonl ( ipoib->qp->qpn );
575
576         /* Fill receive rings */
577         ib_refill_recv ( ibdev, ipoib->qp );
578
579         /* Fake a link status change to join the broadcast group */
580         ipoib_link_state_changed ( ibdev );
581
582         return 0;
583
584         ib_destroy_qp ( ibdev, ipoib->qp );
585  err_create_qp:
586         ib_destroy_cq ( ibdev, ipoib->cq );
587  err_create_cq:
588         ib_close ( ibdev );
589  err_ib_open:
590         return rc;
591 }
592
593 /**
594  * Close IPoIB network device
595  *
596  * @v netdev            Network device
597  */
598 static void ipoib_close ( struct net_device *netdev ) {
599         struct ipoib_device *ipoib = netdev->priv;
600         struct ib_device *ibdev = ipoib->ibdev;
601         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
602
603         /* Leave broadcast group */
604         ipoib_leave_broadcast_group ( ipoib );
605
606         /* Remove QPN from MAC address */
607         mac->qpn = 0;
608
609         /* Tear down the queues */
610         ib_destroy_qp ( ibdev, ipoib->qp );
611         ib_destroy_cq ( ibdev, ipoib->cq );
612
613         /* Close IB device */
614         ib_close ( ibdev );
615 }
616
617 /** IPoIB network device operations */
618 static struct net_device_operations ipoib_operations = {
619         .open           = ipoib_open,
620         .close          = ipoib_close,
621         .transmit       = ipoib_transmit,
622         .poll           = ipoib_poll,
623         .irq            = ipoib_irq,
624 };
625
626 /**
627  * Handle link status change
628  *
629  * @v ibdev             Infiniband device
630  */
631 void ipoib_link_state_changed ( struct ib_device *ibdev ) {
632         struct net_device *netdev = ib_get_ownerdata ( ibdev );
633         struct ipoib_device *ipoib = netdev->priv;
634         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
635         int rc;
636
637         /* Leave existing broadcast group */
638         ipoib_leave_broadcast_group ( ipoib );
639
640         /* Update MAC address based on potentially-new GID prefix */
641         memcpy ( &mac->gid.u.half[0], &ibdev->gid.u.half[0],
642                  sizeof ( mac->gid.u.half[0] ) );
643
644         /* Update broadcast GID based on potentially-new partition key */
645         ipoib->broadcast.gid.u.words[2] = htons ( ibdev->pkey );
646
647         /* Set net device link state to reflect Infiniband link state */
648         if ( ib_link_ok ( ibdev ) ) {
649                 netdev_link_up ( netdev );
650         } else {
651                 netdev_link_down ( netdev );
652         }
653
654         /* Join new broadcast group */
655         if ( ib_link_ok ( ibdev ) &&
656              ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) {
657                 DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
658                        "%s\n", ipoib, strerror ( rc ) );
659                 return;
660         }
661 }
662
663 /**
664  * Probe IPoIB device
665  *
666  * @v ibdev             Infiniband device
667  * @ret rc              Return status code
668  */
669 int ipoib_probe ( struct ib_device *ibdev ) {
670         struct net_device *netdev;
671         struct ipoib_device *ipoib;
672         int rc;
673
674         /* Allocate network device */
675         netdev = alloc_ipoibdev ( sizeof ( *ipoib ) );
676         if ( ! netdev )
677                 return -ENOMEM;
678         netdev_init ( netdev, &ipoib_operations );
679         ipoib = netdev->priv;
680         ib_set_ownerdata ( ibdev, netdev );
681         netdev->dev = ibdev->dev;
682         memset ( ipoib, 0, sizeof ( *ipoib ) );
683         ipoib->netdev = netdev;
684         ipoib->ibdev = ibdev;
685
686         /* Extract hardware address */
687         memcpy ( netdev->hw_addr, &ibdev->gid.u.half[1],
688                  sizeof ( ibdev->gid.u.half[1] ) );
689
690         /* Set default broadcast address */
691         memcpy ( &ipoib->broadcast, &ipoib_broadcast,
692                  sizeof ( ipoib->broadcast ) );
693         netdev->ll_broadcast = ( ( uint8_t * ) &ipoib->broadcast );
694
695         /* Register network device */
696         if ( ( rc = register_netdev ( netdev ) ) != 0 )
697                 goto err_register_netdev;
698
699         return 0;
700
701  err_register_netdev:
702         netdev_nullify ( netdev );
703         netdev_put ( netdev );
704         return rc;
705 }
706
707 /**
708  * Remove IPoIB device
709  *
710  * @v ibdev             Infiniband device
711  */
712 void ipoib_remove ( struct ib_device *ibdev ) {
713         struct net_device *netdev = ib_get_ownerdata ( ibdev );
714
715         unregister_netdev ( netdev );
716         netdev_nullify ( netdev );
717         netdev_put ( netdev );
718 }