Revert to dev_priv/owner_priv scheme, rather than container_of; it
[people/pcmattman/gpxe.git] / src / net / infiniband.c
index edc93b6..2a29c5b 100644 (file)
  */
 
 #include <stdint.h>
+#include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <byteswap.h>
 #include <errno.h>
 #include <assert.h>
+#include <gpxe/list.h>
 #include <gpxe/if_arp.h>
 #include <gpxe/netdevice.h>
 #include <gpxe/iobuf.h>
  */
 
 /**
- * Find queue pair from a list
+ * Create completion queue
  *
- * @v list             List of queue pairs
+ * @v ibdev            Infiniband device
+ * @v num_cqes         Number of completion queue entries
+ * @ret cq             New completion queue
+ */
+struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
+                                           unsigned int num_cqes ) {
+       struct ib_completion_queue *cq;
+       int rc;
+
+       DBGC ( ibdev, "IBDEV %p creating completion queue\n", ibdev );
+
+       /* Allocate and initialise data structure */
+       cq = zalloc ( sizeof ( *cq ) );
+       if ( ! cq )
+               return NULL;
+       cq->num_cqes = num_cqes;
+       INIT_LIST_HEAD ( &cq->work_queues );
+
+       /* Perform device-specific initialisation and get CQN */
+       if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
+               DBGC ( ibdev, "IBDEV %p could not initialise CQ: %s\n",
+                      ibdev, strerror ( rc ) );
+               free ( cq );
+               return NULL;
+       }
+
+       DBGC ( ibdev, "IBDEV %p created completion queue %#lx\n",
+              ibdev, cq->cqn );
+       return cq;
+}
+
+/**
+ * Destroy completion queue
+ *
+ * @v ibdev            Infiniband device
+ * @v cq               Completion queue
+ */
+void ib_destroy_cq ( struct ib_device *ibdev,
+                    struct ib_completion_queue *cq ) {
+       DBGC ( ibdev, "IBDEV %p destroying completion queue %#lx\n",
+              ibdev, cq->cqn );
+       assert ( list_empty ( &cq->work_queues ) );
+       ibdev->op->destroy_cq ( ibdev, cq );
+       free ( cq );
+}
+
+/**
+ * Find work queue belonging to completion queue
+ *
+ * @v cq               Completion queue
  * @v qpn              Queue pair number
- * @ret qp             Queue pair, or NULL if not found
+ * @v is_send          Find send work queue (rather than receive)
+ * @ret wq             Work queue, or NULL if not found
  */
-struct ib_queue_pair * ib_find_qp ( struct list_head *list,
-                                   unsigned long qpn ) {
-       struct ib_queue_pair *qp;
+struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
+                                   unsigned long qpn, int is_send ) {
+       struct ib_work_queue *wq;
 
-       list_for_each_entry ( qp, list, list ) {
-               if ( qp->qpn == qpn )
-                       return qp;
+       list_for_each_entry ( wq, &cq->work_queues, list ) {
+               if ( ( wq->qp->qpn == qpn ) && ( wq->is_send == is_send ) )
+                       return wq;
        }
        return NULL;
 }