Revert to dev_priv/owner_priv scheme, rather than container_of; it
[people/pcmattman/gpxe.git] / src / net / infiniband.c
index c7fabd0..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>
  *
  */
 
+/**
+ * Create completion queue
+ *
+ * @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
+ * @v is_send          Find send work queue (rather than receive)
+ * @ret wq             Work queue, or NULL if not found
+ */
+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 ( wq, &cq->work_queues, list ) {
+               if ( ( wq->qp->qpn == qpn ) && ( wq->is_send == is_send ) )
+                       return wq;
+       }
+       return NULL;
+}
+
+
+
 /** Infiniband broadcast MAC address */
 static uint8_t ib_broadcast[IB_ALEN] = { 0xff, };
 
@@ -50,12 +122,12 @@ static int ib_tx ( struct io_buffer *iobuf, struct net_device *netdev,
                   struct net_protocol *net_protocol, const void *ll_dest ) {
        struct ibhdr *ibhdr = iob_push ( iobuf, sizeof ( *ibhdr ) );
 
-
        /* Build Infiniband header */
-       memcpy ( ibhdr->peer, ll_dest, IB_ALEN );
        ibhdr->proto = net_protocol->net_proto;
        ibhdr->reserved = 0;
 
+       ( void ) ll_dest;
+
        /* Hand off to network device */
        return netdev_tx ( netdev, iobuf );
 }
@@ -70,17 +142,6 @@ static int ib_tx ( struct io_buffer *iobuf, struct net_device *netdev,
  * network-layer protocol.
  */
 static int ib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
-
-       struct {
-               uint16_t proto;
-               uint16_t reserved;
-       } * header = iobuf->data;
-
-       iob_pull ( iobuf, sizeof ( *header ) );
-       return net_rx ( iobuf, netdev, header->proto, NULL );
-
-
-
        struct ibhdr *ibhdr = iobuf->data;
 
        /* Sanity check */
@@ -95,7 +156,7 @@ static int ib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
        iob_pull ( iobuf, sizeof ( *ibhdr ) );
 
        /* Hand off to network-layer protocol */
-       return net_rx ( iobuf, netdev, ibhdr->proto, ibhdr->peer );
+       return net_rx ( iobuf, netdev, ibhdr->proto, NULL );
 }
 
 /**