iPXE
infiniband.c
Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <byteswap.h>
32 #include <errno.h>
33 #include <assert.h>
34 #include <ipxe/list.h>
35 #include <ipxe/errortab.h>
36 #include <ipxe/if_arp.h>
37 #include <ipxe/netdevice.h>
38 #include <ipxe/iobuf.h>
39 #include <ipxe/process.h>
40 #include <ipxe/profile.h>
41 #include <ipxe/infiniband.h>
42 #include <ipxe/ib_mi.h>
43 #include <ipxe/ib_sma.h>
44 
45 /** @file
46  *
47  * Infiniband protocol
48  *
49  */
50 
51 /** List of Infiniband devices */
53 
54 /** List of open Infiniband devices, in reverse order of opening */
56 
57 /** Infiniband device index */
58 static unsigned int ibdev_index = 0;
59 
60 /** Post send work queue entry profiler */
61 static struct profiler ib_post_send_profiler __profiler =
62  { .name = "ib.post_send" };
63 
64 /** Post receive work queue entry profiler */
65 static struct profiler ib_post_recv_profiler __profiler =
66  { .name = "ib.post_recv" };
67 
68 /* Disambiguate the various possible EINPROGRESSes */
69 #define EINPROGRESS_INIT __einfo_error ( EINFO_EINPROGRESS_INIT )
70 #define EINFO_EINPROGRESS_INIT __einfo_uniqify \
71  ( EINFO_EINPROGRESS, 0x01, "Initialising" )
72 #define EINPROGRESS_ARMED __einfo_error ( EINFO_EINPROGRESS_ARMED )
73 #define EINFO_EINPROGRESS_ARMED __einfo_uniqify \
74  ( EINFO_EINPROGRESS, 0x02, "Armed" )
75 
76 /** Human-readable message for the link statuses */
77 struct errortab infiniband_errors[] __errortab = {
80 };
81 
82 /***************************************************************************
83  *
84  * Completion queues
85  *
86  ***************************************************************************
87  */
88 
89 /**
90  * Create completion queue
91  *
92  * @v ibdev Infiniband device
93  * @v num_cqes Number of completion queue entries
94  * @v op Completion queue operations
95  * @v new_cq New completion queue to fill in
96  * @ret rc Return status code
97  */
98 int ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
100  struct ib_completion_queue **new_cq ) {
101  struct ib_completion_queue *cq;
102  int rc;
103 
104  DBGC ( ibdev, "IBDEV %s creating completion queue\n", ibdev->name );
105 
106  /* Allocate and initialise data structure */
107  cq = zalloc ( sizeof ( *cq ) );
108  if ( ! cq ) {
109  rc = -ENOMEM;
110  goto err_alloc_cq;
111  }
112  cq->ibdev = ibdev;
113  list_add_tail ( &cq->list, &ibdev->cqs );
114  cq->num_cqes = num_cqes;
115  INIT_LIST_HEAD ( &cq->work_queues );
116  cq->op = op;
117 
118  /* Perform device-specific initialisation and get CQN */
119  if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
120  DBGC ( ibdev, "IBDEV %s could not initialise completion "
121  "queue: %s\n", ibdev->name, strerror ( rc ) );
122  goto err_dev_create_cq;
123  }
124 
125  DBGC ( ibdev, "IBDEV %s created %d-entry completion queue %p (%p) "
126  "with CQN %#lx\n", ibdev->name, num_cqes, cq,
127  ib_cq_get_drvdata ( cq ), cq->cqn );
128  *new_cq = cq;
129  return 0;
130 
131  ibdev->op->destroy_cq ( ibdev, cq );
132  err_dev_create_cq:
133  list_del ( &cq->list );
134  free ( cq );
135  err_alloc_cq:
136  return rc;
137 }
138 
139 /**
140  * Destroy completion queue
141  *
142  * @v ibdev Infiniband device
143  * @v cq Completion queue
144  */
146  struct ib_completion_queue *cq ) {
147  DBGC ( ibdev, "IBDEV %s destroying completion queue %#lx\n",
148  ibdev->name, cq->cqn );
149  assert ( list_empty ( &cq->work_queues ) );
150  ibdev->op->destroy_cq ( ibdev, cq );
151  list_del ( &cq->list );
152  free ( cq );
153 }
154 
155 /**
156  * Poll completion queue
157  *
158  * @v ibdev Infiniband device
159  * @v cq Completion queue
160  */
161 void ib_poll_cq ( struct ib_device *ibdev,
162  struct ib_completion_queue *cq ) {
163  struct ib_work_queue *wq;
164 
165  /* Poll completion queue */
166  ibdev->op->poll_cq ( ibdev, cq );
167 
168  /* Refill receive work queues */
170  if ( ! wq->is_send )
171  ib_refill_recv ( ibdev, wq->qp );
172  }
173 }
174 
175 /***************************************************************************
176  *
177  * Work queues
178  *
179  ***************************************************************************
180  */
181 
182 /**
183  * Create queue pair
184  *
185  * @v ibdev Infiniband device
186  * @v type Queue pair type
187  * @v num_send_wqes Number of send work queue entries
188  * @v send_cq Send completion queue
189  * @v num_recv_wqes Number of receive work queue entries
190  * @v recv_cq Receive completion queue
191  * @v op Queue pair operations
192  * @v name Queue pair name
193  * @v new_qp New queue pair to fill in
194  * @ret rc Return status code
195  *
196  * The queue pair will be left in the INIT state; you must call
197  * ib_modify_qp() before it is ready to use for sending and receiving.
198  */
199 int ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type,
200  unsigned int num_send_wqes,
201  struct ib_completion_queue *send_cq,
202  unsigned int num_recv_wqes,
203  struct ib_completion_queue *recv_cq,
204  struct ib_queue_pair_operations *op, const char *name,
205  struct ib_queue_pair **new_qp ) {
206  struct ib_queue_pair *qp;
207  size_t total_size;
208  int rc;
209 
210  DBGC ( ibdev, "IBDEV %s creating queue pair\n", ibdev->name );
211 
212  /* Allocate and initialise data structure */
213  total_size = ( sizeof ( *qp ) +
214  ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ) +
215  ( num_recv_wqes * sizeof ( qp->recv.iobufs[0] ) ) );
216  qp = zalloc ( total_size );
217  if ( ! qp ) {
218  rc = -ENOMEM;
219  goto err_alloc_qp;
220  }
221  qp->ibdev = ibdev;
222  list_add_tail ( &qp->list, &ibdev->qps );
223  qp->type = type;
224  qp->send.qp = qp;
225  qp->send.is_send = 1;
226  qp->send.cq = send_cq;
227  list_add_tail ( &qp->send.list, &send_cq->work_queues );
228  qp->send.psn = ( random() & 0xffffffUL );
229  qp->send.num_wqes = num_send_wqes;
230  qp->send.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) );
231  qp->recv.qp = qp;
232  qp->recv.cq = recv_cq;
233  list_add_tail ( &qp->recv.list, &recv_cq->work_queues );
234  qp->recv.psn = ( random() & 0xffffffUL );
235  qp->recv.num_wqes = num_recv_wqes;
236  qp->recv.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) +
237  ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ));
238  INIT_LIST_HEAD ( &qp->mgids );
239  qp->op = op;
240  qp->name = name;
241 
242  /* Perform device-specific initialisation and get QPN */
243  if ( ( rc = ibdev->op->create_qp ( ibdev, qp ) ) != 0 ) {
244  DBGC ( ibdev, "IBDEV %s could not initialise queue pair: "
245  "%s\n", ibdev->name, strerror ( rc ) );
246  goto err_dev_create_qp;
247  }
248  DBGC ( ibdev, "IBDEV %s created queue pair %p (%p) with QPN %#lx\n",
249  ibdev->name, qp, ib_qp_get_drvdata ( qp ), qp->qpn );
250  DBGC ( ibdev, "IBDEV %s QPN %#lx has %d send entries at [%p,%p)\n",
251  ibdev->name, qp->qpn, num_send_wqes, qp->send.iobufs,
252  qp->recv.iobufs );
253  DBGC ( ibdev, "IBDEV %s QPN %#lx has %d receive entries at [%p,%p)\n",
254  ibdev->name, qp->qpn, num_recv_wqes, qp->recv.iobufs,
255  ( ( ( void * ) qp ) + total_size ) );
256 
257  /* Calculate externally-visible QPN */
258  switch ( type ) {
259  case IB_QPT_SMI:
260  qp->ext_qpn = IB_QPN_SMI;
261  break;
262  case IB_QPT_GSI:
263  qp->ext_qpn = IB_QPN_GSI;
264  break;
265  default:
266  qp->ext_qpn = qp->qpn;
267  break;
268  }
269  if ( qp->ext_qpn != qp->qpn ) {
270  DBGC ( ibdev, "IBDEV %s QPN %#lx has external QPN %#lx\n",
271  ibdev->name, qp->qpn, qp->ext_qpn );
272  }
273 
274  *new_qp = qp;
275  return 0;
276 
277  ibdev->op->destroy_qp ( ibdev, qp );
278  err_dev_create_qp:
279  list_del ( &qp->send.list );
280  list_del ( &qp->recv.list );
281  list_del ( &qp->list );
282  free ( qp );
283  err_alloc_qp:
284  return rc;
285 }
286 
287 /**
288  * Modify queue pair
289  *
290  * @v ibdev Infiniband device
291  * @v qp Queue pair
292  * @ret rc Return status code
293  */
294 int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
295  int rc;
296 
297  DBGC ( ibdev, "IBDEV %s modifying QPN %#lx\n", ibdev->name, qp->qpn );
298 
299  if ( ( rc = ibdev->op->modify_qp ( ibdev, qp ) ) != 0 ) {
300  DBGC ( ibdev, "IBDEV %s could not modify QPN %#lx: %s\n",
301  ibdev->name, qp->qpn, strerror ( rc ) );
302  return rc;
303  }
304 
305  return 0;
306 }
307 
308 /**
309  * Destroy queue pair
310  *
311  * @v ibdev Infiniband device
312  * @v qp Queue pair
313  */
314 void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
315  struct io_buffer *iobuf;
316  unsigned int i;
317 
318  DBGC ( ibdev, "IBDEV %s destroying QPN %#lx\n",
319  ibdev->name, qp->qpn );
320 
321  assert ( list_empty ( &qp->mgids ) );
322 
323  /* Perform device-specific destruction */
324  ibdev->op->destroy_qp ( ibdev, qp );
325 
326  /* Complete any remaining I/O buffers with errors */
327  for ( i = 0 ; i < qp->send.num_wqes ; i++ ) {
328  if ( ( iobuf = qp->send.iobufs[i] ) != NULL )
329  ib_complete_send ( ibdev, qp, iobuf, -ECANCELED );
330  }
331  for ( i = 0 ; i < qp->recv.num_wqes ; i++ ) {
332  if ( ( iobuf = qp->recv.iobufs[i] ) != NULL ) {
333  ib_complete_recv ( ibdev, qp, NULL, NULL, iobuf,
334  -ECANCELED );
335  }
336  }
337 
338  /* Remove work queues from completion queue */
339  list_del ( &qp->send.list );
340  list_del ( &qp->recv.list );
341 
342  /* Free QP */
343  list_del ( &qp->list );
344  free ( qp );
345 }
346 
347 /**
348  * Find queue pair by QPN
349  *
350  * @v ibdev Infiniband device
351  * @v qpn Queue pair number
352  * @ret qp Queue pair, or NULL
353  */
355  unsigned long qpn ) {
356  struct ib_queue_pair *qp;
357 
359  if ( ( qpn == qp->qpn ) || ( qpn == qp->ext_qpn ) )
360  return qp;
361  }
362  return NULL;
363 }
364 
365 /**
366  * Find queue pair by multicast GID
367  *
368  * @v ibdev Infiniband device
369  * @v gid Multicast GID
370  * @ret qp Queue pair, or NULL
371  */
373  union ib_gid *gid ) {
374  struct ib_queue_pair *qp;
375  struct ib_multicast_gid *mgid;
376 
377  list_for_each_entry ( qp, &ibdev->qps, list ) {
378  list_for_each_entry ( mgid, &qp->mgids, list ) {
379  if ( memcmp ( &mgid->gid, gid,
380  sizeof ( mgid->gid ) ) == 0 ) {
381  return qp;
382  }
383  }
384  }
385  return NULL;
386 }
387 
388 /**
389  * Find work queue belonging to completion queue
390  *
391  * @v cq Completion queue
392  * @v qpn Queue pair number
393  * @v is_send Find send work queue (rather than receive)
394  * @ret wq Work queue, or NULL if not found
395  */
397  unsigned long qpn, int is_send ) {
398  struct ib_work_queue *wq;
399 
401  if ( ( wq->qp->qpn == qpn ) && ( wq->is_send == is_send ) )
402  return wq;
403  }
404  return NULL;
405 }
406 
407 /**
408  * Post send work queue entry
409  *
410  * @v ibdev Infiniband device
411  * @v qp Queue pair
412  * @v dest Destination address vector
413  * @v iobuf I/O buffer
414  * @ret rc Return status code
415  */
416 int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
417  struct ib_address_vector *dest,
418  struct io_buffer *iobuf ) {
419  struct ib_address_vector dest_copy;
420  int rc;
421 
422  /* Start profiling */
423  profile_start ( &ib_post_send_profiler );
424 
425  /* Check queue fill level */
426  if ( qp->send.fill >= qp->send.num_wqes ) {
427  DBGC ( ibdev, "IBDEV %s QPN %#lx send queue full\n",
428  ibdev->name, qp->qpn );
429  return -ENOBUFS;
430  }
431 
432  /* Use default address vector if none specified */
433  if ( ! dest )
434  dest = &qp->av;
435 
436  /* Make modifiable copy of address vector */
437  memcpy ( &dest_copy, dest, sizeof ( dest_copy ) );
438  dest = &dest_copy;
439 
440  /* Fill in optional parameters in address vector */
441  if ( ! dest->qkey )
442  dest->qkey = qp->qkey;
443  if ( ! dest->rate )
444  dest->rate = IB_RATE_2_5;
445 
446  /* Post to hardware */
447  if ( ( rc = ibdev->op->post_send ( ibdev, qp, dest, iobuf ) ) != 0 ) {
448  DBGC ( ibdev, "IBDEV %s QPN %#lx could not post send WQE: "
449  "%s\n", ibdev->name, qp->qpn, strerror ( rc ) );
450  return rc;
451  }
452 
453  /* Increase fill level */
454  qp->send.fill++;
455 
456  /* Stop profiling */
457  profile_stop ( &ib_post_send_profiler );
458 
459  return 0;
460 }
461 
462 /**
463  * Post receive work queue entry
464  *
465  * @v ibdev Infiniband device
466  * @v qp Queue pair
467  * @v iobuf I/O buffer
468  * @ret rc Return status code
469  */
470 int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
471  struct io_buffer *iobuf ) {
472  int rc;
473 
474  /* Start profiling */
475  profile_start ( &ib_post_recv_profiler );
476 
477  /* Check packet length */
478  if ( iob_tailroom ( iobuf ) < IB_MAX_PAYLOAD_SIZE ) {
479  DBGC ( ibdev, "IBDEV %s QPN %#lx wrong RX buffer size (%zd)\n",
480  ibdev->name, qp->qpn, iob_tailroom ( iobuf ) );
481  return -EINVAL;
482  }
483 
484  /* Check queue fill level */
485  if ( qp->recv.fill >= qp->recv.num_wqes ) {
486  DBGC ( ibdev, "IBDEV %s QPN %#lx receive queue full\n",
487  ibdev->name, qp->qpn );
488  return -ENOBUFS;
489  }
490 
491  /* Post to hardware */
492  if ( ( rc = ibdev->op->post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
493  DBGC ( ibdev, "IBDEV %s QPN %#lx could not post receive WQE: "
494  "%s\n", ibdev->name, qp->qpn, strerror ( rc ) );
495  return rc;
496  }
497 
498  /* Increase fill level */
499  qp->recv.fill++;
500 
501  /* Stop profiling */
502  profile_stop ( &ib_post_recv_profiler );
503 
504  return 0;
505 }
506 
507 /**
508  * Complete send work queue entry
509  *
510  * @v ibdev Infiniband device
511  * @v qp Queue pair
512  * @v iobuf I/O buffer
513  * @v rc Completion status code
514  */
515 void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
516  struct io_buffer *iobuf, int rc ) {
517 
518  if ( qp->send.cq->op->complete_send ) {
519  qp->send.cq->op->complete_send ( ibdev, qp, iobuf, rc );
520  } else {
521  free_iob ( iobuf );
522  }
523  qp->send.fill--;
524 }
525 
526 /**
527  * Complete receive work queue entry
528  *
529  * @v ibdev Infiniband device
530  * @v qp Queue pair
531  * @v dest Destination address vector, or NULL
532  * @v source Source address vector, or NULL
533  * @v iobuf I/O buffer
534  * @v rc Completion status code
535  */
536 void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
537  struct ib_address_vector *dest,
538  struct ib_address_vector *source,
539  struct io_buffer *iobuf, int rc ) {
540 
541  if ( qp->recv.cq->op->complete_recv ) {
542  qp->recv.cq->op->complete_recv ( ibdev, qp, dest, source,
543  iobuf, rc );
544  } else {
545  free_iob ( iobuf );
546  }
547  qp->recv.fill--;
548 }
549 
550 /**
551  * Refill receive work queue
552  *
553  * @v ibdev Infiniband device
554  * @v qp Queue pair
555  */
556 void ib_refill_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
557  struct io_buffer *iobuf;
558  int rc;
559 
560  /* Keep filling while unfilled entries remain */
561  while ( qp->recv.fill < qp->recv.num_wqes ) {
562 
563  /* Allocate I/O buffer */
564  iobuf = qp->op->alloc_iob ( IB_MAX_PAYLOAD_SIZE );
565  if ( ! iobuf ) {
566  /* Non-fatal; we will refill on next attempt */
567  return;
568  }
569 
570  /* Post I/O buffer */
571  if ( ( rc = ib_post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
572  DBGC ( ibdev, "IBDEV %s could not refill: %s\n",
573  ibdev->name, strerror ( rc ) );
574  free_iob ( iobuf );
575  /* Give up */
576  return;
577  }
578  }
579 }
580 
581 /***************************************************************************
582  *
583  * Link control
584  *
585  ***************************************************************************
586  */
587 
588 /**
589  * Get link state
590  *
591  * @v ibdev Infiniband device
592  * @ret rc Link status code
593  */
594 int ib_link_rc ( struct ib_device *ibdev ) {
595  switch ( ibdev->port_state ) {
596  case IB_PORT_STATE_DOWN: return -ENOTCONN;
597  case IB_PORT_STATE_INIT: return -EINPROGRESS_INIT;
599  case IB_PORT_STATE_ACTIVE: return 0;
600  default: return -EINVAL;
601  }
602 }
603 
604 /**
605  * Textual representation of Infiniband link state
606  *
607  * @v ibdev Infiniband device
608  * @ret link_text Link state text
609  */
610 static const char * ib_link_state_text ( struct ib_device *ibdev ) {
611  switch ( ibdev->port_state ) {
612  case IB_PORT_STATE_DOWN: return "DOWN";
613  case IB_PORT_STATE_INIT: return "INIT";
614  case IB_PORT_STATE_ARMED: return "ARMED";
615  case IB_PORT_STATE_ACTIVE: return "ACTIVE";
616  default: return "UNKNOWN";
617  }
618 }
619 
620 /**
621  * Notify drivers of Infiniband device or link state change
622  *
623  * @v ibdev Infiniband device
624  */
625 static void ib_notify ( struct ib_device *ibdev ) {
626  struct ib_driver *driver;
627 
628  for_each_table_entry ( driver, IB_DRIVERS )
629  driver->notify ( ibdev );
630 }
631 
632 /**
633  * Notify of Infiniband link state change
634  *
635  * @v ibdev Infiniband device
636  */
637 void ib_link_state_changed ( struct ib_device *ibdev ) {
638 
639  DBGC ( ibdev, "IBDEV %s link state is %s\n",
640  ibdev->name, ib_link_state_text ( ibdev ) );
641 
642  /* Notify drivers of link state change */
643  ib_notify ( ibdev );
644 }
645 
646 /**
647  * Open port
648  *
649  * @v ibdev Infiniband device
650  * @ret rc Return status code
651  */
652 int ib_open ( struct ib_device *ibdev ) {
653  int rc;
654 
655  /* Increment device open request counter */
656  if ( ibdev->open_count++ > 0 ) {
657  /* Device was already open; do nothing */
658  return 0;
659  }
660 
661  /* Open device */
662  if ( ( rc = ibdev->op->open ( ibdev ) ) != 0 ) {
663  DBGC ( ibdev, "IBDEV %s could not open: %s\n",
664  ibdev->name, strerror ( rc ) );
665  goto err_open;
666  }
667 
668  /* Create subnet management interface */
669  if ( ( rc = ib_create_mi ( ibdev, IB_QPT_SMI, &ibdev->smi ) ) != 0 ) {
670  DBGC ( ibdev, "IBDEV %s could not create SMI: %s\n",
671  ibdev->name, strerror ( rc ) );
672  goto err_create_smi;
673  }
674 
675  /* Create subnet management agent */
676  if ( ( rc = ib_create_sma ( ibdev, ibdev->smi ) ) != 0 ) {
677  DBGC ( ibdev, "IBDEV %s could not create SMA: %s\n",
678  ibdev->name, strerror ( rc ) );
679  goto err_create_sma;
680  }
681 
682  /* Create general services interface */
683  if ( ( rc = ib_create_mi ( ibdev, IB_QPT_GSI, &ibdev->gsi ) ) != 0 ) {
684  DBGC ( ibdev, "IBDEV %s could not create GSI: %s\n",
685  ibdev->name, strerror ( rc ) );
686  goto err_create_gsi;
687  }
688 
689  /* Add to head of open devices list */
690  list_add ( &ibdev->open_list, &open_ib_devices );
691 
692  /* Notify drivers of device state change */
693  ib_notify ( ibdev );
694 
695  assert ( ibdev->open_count == 1 );
696  return 0;
697 
698  ib_destroy_mi ( ibdev, ibdev->gsi );
699  err_create_gsi:
700  ib_destroy_sma ( ibdev, ibdev->smi );
701  err_create_sma:
702  ib_destroy_mi ( ibdev, ibdev->smi );
703  err_create_smi:
704  ibdev->op->close ( ibdev );
705  err_open:
706  assert ( ibdev->open_count == 1 );
707  ibdev->open_count = 0;
708  return rc;
709 }
710 
711 /**
712  * Close port
713  *
714  * @v ibdev Infiniband device
715  */
716 void ib_close ( struct ib_device *ibdev ) {
717 
718  /* Decrement device open request counter */
719  ibdev->open_count--;
720 
721  /* Close device if this was the last remaining requested opening */
722  if ( ibdev->open_count == 0 ) {
723  ib_notify ( ibdev );
724  list_del ( &ibdev->open_list );
725  ib_destroy_mi ( ibdev, ibdev->gsi );
726  ib_destroy_sma ( ibdev, ibdev->smi );
727  ib_destroy_mi ( ibdev, ibdev->smi );
728  ibdev->op->close ( ibdev );
730  }
731 }
732 
733 /***************************************************************************
734  *
735  * Multicast
736  *
737  ***************************************************************************
738  */
739 
740 /**
741  * Attach to multicast group
742  *
743  * @v ibdev Infiniband device
744  * @v qp Queue pair
745  * @v gid Multicast GID
746  * @ret rc Return status code
747  *
748  * Note that this function handles only the local device's attachment
749  * to the multicast GID; it does not issue the relevant MADs to join
750  * the multicast group on the subnet.
751  */
752 int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
753  union ib_gid *gid ) {
754  struct ib_multicast_gid *mgid;
755  int rc;
756 
757  /* Sanity check */
758  assert ( qp != NULL );
759 
760  /* Add to software multicast GID list */
761  mgid = zalloc ( sizeof ( *mgid ) );
762  if ( ! mgid ) {
763  rc = -ENOMEM;
764  goto err_alloc_mgid;
765  }
766  memcpy ( &mgid->gid, gid, sizeof ( mgid->gid ) );
767  list_add_tail ( &mgid->list, &qp->mgids );
768 
769  /* Add to hardware multicast GID list */
770  if ( ( rc = ibdev->op->mcast_attach ( ibdev, qp, gid ) ) != 0 )
771  goto err_dev_mcast_attach;
772 
773  return 0;
774 
775  err_dev_mcast_attach:
776  list_del ( &mgid->list );
777  free ( mgid );
778  err_alloc_mgid:
779  return rc;
780 }
781 
782 /**
783  * Detach from multicast group
784  *
785  * @v ibdev Infiniband device
786  * @v qp Queue pair
787  * @v gid Multicast GID
788  */
789 void ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
790  union ib_gid *gid ) {
791  struct ib_multicast_gid *mgid;
792 
793  /* Sanity check */
794  assert ( qp != NULL );
795 
796  /* Remove from hardware multicast GID list */
797  ibdev->op->mcast_detach ( ibdev, qp, gid );
798 
799  /* Remove from software multicast GID list */
800  list_for_each_entry ( mgid, &qp->mgids, list ) {
801  if ( memcmp ( &mgid->gid, gid, sizeof ( mgid->gid ) ) == 0 ) {
802  list_del ( &mgid->list );
803  free ( mgid );
804  break;
805  }
806  }
807 }
808 
809 /***************************************************************************
810  *
811  * Miscellaneous
812  *
813  ***************************************************************************
814  */
815 
816 /**
817  * Set port information
818  *
819  * @v ibdev Infiniband device
820  * @v mad Set port information MAD
821  */
822 int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad ) {
823  int rc;
824 
825  /* Adapters with embedded SMAs do not need to support this method */
826  if ( ! ibdev->op->set_port_info ) {
827  DBGC ( ibdev, "IBDEV %s does not support setting port "
828  "information\n", ibdev->name );
829  return -ENOTSUP;
830  }
831 
832  if ( ( rc = ibdev->op->set_port_info ( ibdev, mad ) ) != 0 ) {
833  DBGC ( ibdev, "IBDEV %s could not set port information: %s\n",
834  ibdev->name, strerror ( rc ) );
835  return rc;
836  }
837 
838  return 0;
839 };
840 
841 /**
842  * Set partition key table
843  *
844  * @v ibdev Infiniband device
845  * @v mad Set partition key table MAD
846  */
847 int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad ) {
848  int rc;
849 
850  /* Adapters with embedded SMAs do not need to support this method */
851  if ( ! ibdev->op->set_pkey_table ) {
852  DBGC ( ibdev, "IBDEV %s does not support setting partition "
853  "key table\n", ibdev->name );
854  return -ENOTSUP;
855  }
856 
857  if ( ( rc = ibdev->op->set_pkey_table ( ibdev, mad ) ) != 0 ) {
858  DBGC ( ibdev, "IBDEV %s could not set partition key table: "
859  "%s\n", ibdev->name, strerror ( rc ) );
860  return rc;
861  }
862 
863  return 0;
864 };
865 
866 /***************************************************************************
867  *
868  * Event queues
869  *
870  ***************************************************************************
871  */
872 
873 /**
874  * Poll event queue
875  *
876  * @v ibdev Infiniband device
877  */
878 void ib_poll_eq ( struct ib_device *ibdev ) {
879  struct ib_completion_queue *cq;
880 
881  /* Poll device's event queue */
882  ibdev->op->poll_eq ( ibdev );
883 
884  /* Poll all completion queues */
885  list_for_each_entry ( cq, &ibdev->cqs, list )
886  ib_poll_cq ( ibdev, cq );
887 }
888 
889 /**
890  * Single-step the Infiniband event queue
891  *
892  * @v process Infiniband event queue process
893  */
894 static void ib_step ( struct process *process __unused ) {
895  struct ib_device *ibdev;
896 
898  ib_poll_eq ( ibdev );
899 }
900 
901 /** Infiniband event queue process */
902 PERMANENT_PROCESS ( ib_process, ib_step );
903 
904 /***************************************************************************
905  *
906  * Infiniband device creation/destruction
907  *
908  ***************************************************************************
909  */
910 
911 /**
912  * Allocate Infiniband device
913  *
914  * @v priv_size Size of driver private data area
915  * @ret ibdev Infiniband device, or NULL
916  */
917 struct ib_device * alloc_ibdev ( size_t priv_size ) {
918  struct ib_device *ibdev;
919  void *drv_priv;
920  size_t total_len;
921 
922  total_len = ( sizeof ( *ibdev ) + priv_size );
923  ibdev = zalloc ( total_len );
924  if ( ibdev ) {
925  drv_priv = ( ( ( void * ) ibdev ) + sizeof ( *ibdev ) );
926  ib_set_drvdata ( ibdev, drv_priv );
927  INIT_LIST_HEAD ( &ibdev->list );
928  INIT_LIST_HEAD ( &ibdev->open_list );
929  INIT_LIST_HEAD ( &ibdev->cqs );
930  INIT_LIST_HEAD ( &ibdev->qps );
932  ibdev->lid = IB_LID_NONE;
933  ibdev->pkey = IB_PKEY_DEFAULT;
934  }
935  return ibdev;
936 }
937 
938 /**
939  * Register Infiniband device
940  *
941  * @v ibdev Infiniband device
942  * @ret rc Return status code
943  */
944 int register_ibdev ( struct ib_device *ibdev ) {
945  struct ib_driver *driver;
946  int rc;
947 
948  /* Record device index and create device name */
949  if ( ibdev->name[0] == '\0' ) {
950  snprintf ( ibdev->name, sizeof ( ibdev->name ), "inf%d",
951  ibdev_index );
952  }
953  ibdev->index = ++ibdev_index;
954 
955  /* Add to device list */
956  ibdev_get ( ibdev );
957  list_add_tail ( &ibdev->list, &ib_devices );
958  DBGC ( ibdev, "IBDEV %s registered (phys %s)\n", ibdev->name,
959  ibdev->dev->name );
960 
961  /* Probe device */
962  for_each_table_entry ( driver, IB_DRIVERS ) {
963  if ( ( rc = driver->probe ( ibdev ) ) != 0 ) {
964  DBGC ( ibdev, "IBDEV %s could not add %s device: %s\n",
965  ibdev->name, driver->name, strerror ( rc ) );
966  goto err_probe;
967  }
968  }
969 
970  return 0;
971 
972  err_probe:
974  driver->remove ( ibdev );
975  list_del ( &ibdev->list );
976  ibdev_put ( ibdev );
977  return rc;
978 }
979 
980 /**
981  * Unregister Infiniband device
982  *
983  * @v ibdev Infiniband device
984  */
985 void unregister_ibdev ( struct ib_device *ibdev ) {
986  struct ib_driver *driver;
987 
988  /* Remove device */
990  driver->remove ( ibdev );
991 
992  /* Remove from device list */
993  list_del ( &ibdev->list );
994  ibdev_put ( ibdev );
995  DBGC ( ibdev, "IBDEV %s unregistered\n", ibdev->name );
996 
997  /* Reset device index if no devices remain */
998  if ( list_empty ( &ib_devices ) )
999  ibdev_index = 0;
1000 }
1001 
1002 /**
1003  * Find Infiniband device by GID
1004  *
1005  * @v gid GID
1006  * @ret ibdev Infiniband device, or NULL
1007  */
1008 struct ib_device * find_ibdev ( union ib_gid *gid ) {
1009  struct ib_device *ibdev;
1010 
1011  for_each_ibdev ( ibdev ) {
1012  if ( memcmp ( gid, &ibdev->gid, sizeof ( *gid ) ) == 0 )
1013  return ibdev;
1014  }
1015  return NULL;
1016 }
1017 
1018 /**
1019  * Get most recently opened Infiniband device
1020  *
1021  * @ret ibdev Most recently opened Infiniband device, or NULL
1022  */
1023 struct ib_device * last_opened_ibdev ( void ) {
1024  struct ib_device *ibdev;
1025 
1026  ibdev = list_first_entry ( &open_ib_devices, struct ib_device,
1027  open_list );
1028  if ( ! ibdev )
1029  return NULL;
1030 
1031  assert ( ibdev->open_count != 0 );
1032  return ibdev;
1033 }
1034 
1035 /* Drag in objects via register_ibdev() */
1037 
1038 /* Drag in Infiniband configuration */
1039 REQUIRE_OBJECT ( config_infiniband );
void unregister_ibdev(struct ib_device *ibdev)
Unregister Infiniband device.
Definition: infiniband.c:985
int ib_set_pkey_table(struct ib_device *ibdev, union ib_mad *mad)
Set partition key table.
Definition: infiniband.c:847
static void ib_notify(struct ib_device *ibdev)
Notify drivers of Infiniband device or link state change.
Definition: infiniband.c:625
struct ib_mad_interface * smi
Subnet management interface.
Definition: infiniband.h:459
A process.
Definition: process.h:17
void ib_destroy_sma(struct ib_device *ibdev __unused, struct ib_mad_interface *mi __unused)
Destroy subnet management agent and interface.
Definition: ib_sma.c:372
#define EINVAL
Invalid argument.
Definition: errno.h:428
static __always_inline void ib_set_drvdata(struct ib_device *ibdev, void *priv)
Set Infiniband device driver-private data.
Definition: infiniband.h:697
int ib_link_rc(struct ib_device *ibdev)
Get link state.
Definition: infiniband.c:594
int(* set_port_info)(struct ib_device *ibdev, union ib_mad *mad)
Set port information.
Definition: infiniband.h:381
void ib_poll_eq(struct ib_device *ibdev)
Poll event queue.
Definition: infiniband.c:878
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Infiniband management interfaces.
const char * name
Definition: ath9k_hw.c:1984
void ib_destroy_mi(struct ib_device *ibdev, struct ib_mad_interface *mi)
Destroy management interface.
Definition: ib_mi.c:411
Infiniband protocol.
int(* set_pkey_table)(struct ib_device *ibdev, union ib_mad *mad)
Set partition key table.
Definition: infiniband.h:390
#define IB_QPN_SMI
Subnet management interface QPN.
Definition: infiniband.h:21
Error message tables.
int(* probe)(struct ib_device *ibdev)
Probe device.
Definition: infiniband.h:479
char name[IBDEV_NAME_LEN]
Name of this Infiniband device.
Definition: infiniband.h:408
union ib_gid gid
Port GID (comprising GID prefix and port GUID)
Definition: infiniband.h:441
#define EINFO_EINPROGRESS_INIT
Definition: infiniband.c:70
struct ib_device * last_opened_ibdev(void)
Get most recently opened Infiniband device.
Definition: infiniband.c:1023
union ib_gid mgid
Definition: ib_mad.h:11
void(* poll_eq)(struct ib_device *ibdev)
Poll event queue.
Definition: infiniband.h:340
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
int(* open)(struct ib_device *ibdev)
Open port.
Definition: infiniband.h:347
unsigned int open_count
Port open request counter.
Definition: infiniband.h:422
Error codes.
int(* post_recv)(struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf)
Post receive work queue entry.
Definition: infiniband.h:322
void(* mcast_detach)(struct ib_device *ibdev, struct ib_queue_pair *qp, union ib_gid *gid)
Detach from multicast group.
Definition: infiniband.h:370
I/O buffers.
uint16_t lid
Port LID.
Definition: infiniband.h:443
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
uint32_t type
Operating system type.
Definition: ena.h:12
#define __einfo_errortab(einfo)
Definition: errortab.h:23
#define IB_PORT_STATE_INIT
Definition: ib_mad.h:152
int ib_modify_qp(struct ib_device *ibdev, struct ib_queue_pair *qp)
Modify queue pair.
Definition: infiniband.c:294
int ib_create_cq(struct ib_device *ibdev, unsigned int num_cqes, struct ib_completion_queue_operations *op, struct ib_completion_queue **new_cq)
Create completion queue.
Definition: infiniband.c:98
void ib_refill_recv(struct ib_device *ibdev, struct ib_queue_pair *qp)
Refill receive work queue.
Definition: infiniband.c:556
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:75
int ib_open(struct ib_device *ibdev)
Open port.
Definition: infiniband.c:652
struct device * dev
Underlying device.
Definition: infiniband.h:410
int ib_set_port_info(struct ib_device *ibdev, union ib_mad *mad)
Set port information.
Definition: infiniband.c:822
void(* notify)(struct ib_device *ibdev)
Notify of device or link state change.
Definition: infiniband.h:484
int ib_mcast_attach(struct ib_device *ibdev, struct ib_queue_pair *qp, union ib_gid *gid)
Attach to multicast group.
Definition: infiniband.c:752
static __always_inline void * ib_qp_get_drvdata(struct ib_queue_pair *qp)
Get Infiniband queue pair driver-private data.
Definition: infiniband.h:642
struct ib_mad_interface * gsi
General services interface.
Definition: infiniband.h:461
void * drv_priv
Driver private data.
Definition: infiniband.h:467
static struct profiler ib_post_send_profiler __profiler
Post send work queue entry profiler.
Definition: infiniband.c:61
An Infiniband upper-layer driver.
Definition: infiniband.h:471
static const char * ib_link_state_text(struct ib_device *ibdev)
Textual representation of Infiniband link state.
Definition: infiniband.c:610
#define IB_PKEY_DEFAULT
Default Infiniband partition key.
Definition: infiniband.h:39
void ib_link_state_changed(struct ib_device *ibdev)
Notify of Infiniband link state change.
Definition: infiniband.c:637
void ib_close(struct ib_device *ibdev)
Close port.
Definition: infiniband.c:716
int ib_create_sma(struct ib_device *ibdev, struct ib_mad_interface *mi)
Create subnet management agent and interface.
Definition: ib_sma.c:358
#define for_each_table_entry_reverse(pointer, table)
Iterate through all entries within a linker table in reverse order.
Definition: tables.h:440
A data structure for storing profiling information.
Definition: profile.h:26
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:173
static __always_inline struct ib_device * ibdev_get(struct ib_device *ibdev)
Get reference to Infiniband device.
Definition: infiniband.h:587
An Infiniband Global Identifier.
Definition: ib_packet.h:33
__be32 qpn
Definition: CIB_PRM.h:29
struct list_head list
List of multicast GIDs on this QP.
Definition: infiniband.h:132
Address Resolution Protocol constants and types.
#define IB_PORT_STATE_ARMED
Definition: ib_mad.h:153
#define ECANCELED
Operation canceled.
Definition: errno.h:343
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
void ib_destroy_cq(struct ib_device *ibdev, struct ib_completion_queue *cq)
Destroy completion queue.
Definition: infiniband.c:145
A doubly-linked list entry (or list head)
Definition: list.h:18
unsigned int index
Index of this Infiniband device.
Definition: infiniband.h:406
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
int(* mcast_attach)(struct ib_device *ibdev, struct ib_queue_pair *qp, union ib_gid *gid)
Attach to multicast group.
Definition: infiniband.h:361
An Infiniband device.
Definition: infiniband.h:398
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
struct ib_completion_queue * cq
Associated completion queue.
Definition: infiniband.h:106
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define ENOMEM
Not enough space.
Definition: errno.h:534
Infiniband completion queue operations.
Definition: infiniband.h:194
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Infiniband queue pair operations.
Definition: infiniband.h:147
const char * name
Name.
Definition: profile.h:28
#define EINPROGRESS_INIT
Definition: infiniband.c:69
#define EINPROGRESS_ARMED
Definition: infiniband.c:72
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct ib_device_operations * op
Infiniband operations.
Definition: infiniband.h:416
An Infiniband Work Queue.
Definition: infiniband.h:100
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
void ib_complete_send(struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc)
Complete send work queue entry.
Definition: infiniband.c:515
REQUIRE_OBJECT(config_infiniband)
PERMANENT_PROCESS(ib_process, ib_step)
Infiniband event queue process.
unsigned long qpn
Queue pair number.
Definition: infiniband.h:165
int(* modify_qp)(struct ib_device *ibdev, struct ib_queue_pair *qp)
Modify queue pair.
Definition: infiniband.h:284
static struct list_head open_ib_devices
List of open Infiniband devices, in reverse order of opening.
Definition: infiniband.c:55
#define IB_DRIVERS
Infiniband driver table.
Definition: infiniband.h:493
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:160
struct ib_work_queue * ib_find_wq(struct ib_completion_queue *cq, unsigned long qpn, int is_send)
Find work queue belonging to completion queue.
Definition: infiniband.c:396
Profiling.
struct list_head list
List of queue pairs on this Infiniband device.
Definition: infiniband.h:161
struct list_head work_queues
List of work queues completing to this queue.
Definition: infiniband.h:242
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
Linked lists.
struct list_head list
List of Infiniband devices.
Definition: infiniband.h:402
struct ib_completion_queue_operations * op
Completion queue operations.
Definition: infiniband.h:244
#define IB_LID_NONE
Default Infiniband LID.
Definition: ib_packet.h:83
#define IB_QPN_GSI
General service interface QPN.
Definition: infiniband.h:27
static __always_inline void ibdev_put(struct ib_device *ibdev)
Drop reference to Infiniband device.
Definition: infiniband.h:598
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
ib_queue_pair_type
An Infiniband queue pair type.
Definition: infiniband.h:138
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct ib_device * find_ibdev(union ib_gid *gid)
Find Infiniband device by GID.
Definition: infiniband.c:1008
struct ib_device * alloc_ibdev(size_t priv_size)
Allocate Infiniband device.
Definition: infiniband.c:917
void ib_mcast_detach(struct ib_device *ibdev, struct ib_queue_pair *qp, union ib_gid *gid)
Detach from multicast group.
Definition: infiniband.c:789
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
int ib_post_recv(struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf)
Post receive work queue entry.
Definition: infiniband.c:470
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:175
An Infiniband Completion Queue.
Definition: infiniband.h:224
Processes.
void ib_destroy_qp(struct ib_device *ibdev, struct ib_queue_pair *qp)
Destroy queue pair.
Definition: infiniband.c:314
int register_ibdev(struct ib_device *ibdev)
Register Infiniband device.
Definition: infiniband.c:944
#define IB_PORT_STATE_DOWN
Definition: ib_mad.h:151
struct ib_queue_pair * qp
Containing queue pair.
Definition: infiniband.h:102
struct list_head ib_devices
List of Infiniband devices.
Definition: infiniband.c:52
int(* create_qp)(struct ib_device *ibdev, struct ib_queue_pair *qp)
Create queue pair.
Definition: infiniband.h:276
struct ib_device * ibdev
Containing Infiniband device.
Definition: infiniband.h:159
void(* destroy_cq)(struct ib_device *ibdev, struct ib_completion_queue *cq)
Destroy completion queue.
Definition: infiniband.h:268
struct list_head list
List of work queues on this completion queue.
Definition: infiniband.h:108
An Infiniband Queue Pair.
Definition: infiniband.h:157
struct list_head cqs
List of completion queues.
Definition: infiniband.h:412
Network device management.
struct arbelprm_qp_db_record qp
Definition: arbel.h:13
int ib_post_send(struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *dest, struct io_buffer *iobuf)
Post send work queue entry.
Definition: infiniband.c:416
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
void(* destroy_qp)(struct ib_device *ibdev, struct ib_queue_pair *qp)
Destroy queue pair.
Definition: infiniband.h:291
struct list_head list
List of completion queues on this Infiniband device.
Definition: infiniband.h:228
static unsigned int ibdev_index
Infiniband device index.
Definition: infiniband.c:58
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
struct ib_queue_pair * ib_find_qp_mgid(struct ib_device *ibdev, union ib_gid *gid)
Find queue pair by multicast GID.
Definition: infiniband.c:372
static void ib_step(struct process *process __unused)
Single-step the Infiniband event queue.
Definition: infiniband.c:894
int ib_create_qp(struct ib_device *ibdev, enum ib_queue_pair_type type, unsigned int num_send_wqes, struct ib_completion_queue *send_cq, unsigned int num_recv_wqes, struct ib_completion_queue *recv_cq, struct ib_queue_pair_operations *op, const char *name, struct ib_queue_pair **new_qp)
Create queue pair.
Definition: infiniband.c:199
#define IB_PORT_STATE_ACTIVE
Definition: ib_mad.h:154
void(* remove)(struct ib_device *ibdev)
Remove device.
Definition: infiniband.h:489
void ib_poll_cq(struct ib_device *ibdev, struct ib_completion_queue *cq)
Poll completion queue.
Definition: infiniband.c:161
uint8_t port_state
Port state.
Definition: infiniband.h:425
void(* close)(struct ib_device *ibdev)
Close port.
Definition: infiniband.h:353
unsigned long cqn
Completion queue number.
Definition: infiniband.h:230
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
Definition: string.h:150
Infiniband subnet management agent.
unsigned int num_cqes
Number of completion queue entries.
Definition: infiniband.h:232
int(* post_send)(struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *dest, struct io_buffer *iobuf)
Post send work queue entry.
Definition: infiniband.h:306
A management datagram.
Definition: ib_mad.h:610
struct errortab infiniband_errors [] __errortab
Human-readable message for the link statuses.
Definition: infiniband.c:77
struct list_head qps
List of queue pairs.
Definition: infiniband.h:414
REQUIRING_SYMBOL(register_ibdev)
void ib_complete_recv(struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *dest, struct ib_address_vector *source, struct io_buffer *iobuf, int rc)
Complete receive work queue entry.
Definition: infiniband.c:536
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct list_head open_list
List of open Infiniband devices.
Definition: infiniband.h:404
uint16_t pkey
Partition key.
Definition: infiniband.h:449
An Infiniband Address Vector.
Definition: infiniband.h:72
const char * name
Name.
Definition: infiniband.h:473
An Infiniband multicast GID.
Definition: infiniband.h:130
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
int is_send
"Is a send queue" flag
Definition: infiniband.h:104
u8 gid[16]
Definition: CIB_PRM.h:31
#define for_each_table_entry_continue_reverse(pointer, table)
Iterate through all remaining entries within a linker table in reverse order.
Definition: tables.h:469
struct ib_queue_pair * ib_find_qp_qpn(struct ib_device *ibdev, unsigned long qpn)
Find queue pair by QPN.
Definition: infiniband.c:354
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
static __always_inline void * ib_cq_get_drvdata(struct ib_completion_queue *cq)
Get Infiniband completion queue driver-private data.
Definition: infiniband.h:686
struct ib_device * ibdev
Containing Infiniband device.
Definition: infiniband.h:226
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
void(* poll_cq)(struct ib_device *ibdev, struct ib_completion_queue *cq)
Poll completion queue.
Definition: infiniband.h:333
union ib_mad mad
Definition: arbel.h:12
int ib_create_mi(struct ib_device *ibdev, enum ib_queue_pair_type type, struct ib_mad_interface **new_mi)
Create management interface.
Definition: ib_mi.c:347
#define for_each_ibdev(ibdev)
Iterate over all network devices.
Definition: infiniband.h:555
int(* create_cq)(struct ib_device *ibdev, struct ib_completion_queue *cq)
Create completion queue.
Definition: infiniband.h:261
#define IB_MAX_PAYLOAD_SIZE
Maximum payload size.
Definition: infiniband.h:50
A persistent I/O buffer.
Definition: iobuf.h:33
#define EINFO_EINPROGRESS_ARMED
Definition: infiniband.c:73