summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2008-04-21 14:23:11 +0200
committerMichael Brown2008-04-21 14:23:11 +0200
commit35a583667780122e8dabc72737be51fe914b4257 (patch)
tree1407b011e3a8659a45c55fe6792797507a802364
parent[Hermon] Fix event queue doorbells. (diff)
downloadipxe-35a583667780122e8dabc72737be51fe914b4257.tar.gz
ipxe-35a583667780122e8dabc72737be51fe914b4257.tar.xz
ipxe-35a583667780122e8dabc72737be51fe914b4257.zip
[Infiniband] Move event-queue process from driver to Infiniband core
-rw-r--r--src/drivers/infiniband/arbel.c46
-rw-r--r--src/drivers/infiniband/hermon.c432
-rw-r--r--src/drivers/infiniband/hermon.h3
-rw-r--r--src/include/gpxe/infiniband.h34
-rw-r--r--src/net/infiniband.c89
5 files changed, 348 insertions, 256 deletions
diff --git a/src/drivers/infiniband/arbel.c b/src/drivers/infiniband/arbel.c
index 462638eae..2409e285c 100644
--- a/src/drivers/infiniband/arbel.c
+++ b/src/drivers/infiniband/arbel.c
@@ -836,6 +836,27 @@ static int arbel_create_qp ( struct ib_device *ibdev,
}
/**
+ * Modify queue pair
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v mod_list Modification list
+ * @ret rc Return status code
+ */
+static int arbel_modify_qp ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp,
+ unsigned long mod_list ) {
+ struct arbel *arbel = ib_get_drvdata ( ibdev );
+
+ /* TODO */
+ ( void ) arbel;
+ ( void ) qp;
+ ( void ) mod_list;
+
+ return -ENOTSUP;
+}
+
+/**
* Destroy queue pair
*
* @v ibdev Infiniband device
@@ -1204,6 +1225,25 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
/***************************************************************************
*
+ * Event queues
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Poll event queue
+ *
+ * @v ibdev Infiniband device
+ */
+static void arbel_poll_eq ( struct ib_device *ibdev ) {
+ struct arbel *arbel = ib_get_drvdata ( ibdev );
+
+ /* TODO */
+ ( void ) arbel;
+}
+
+/***************************************************************************
+ *
* Infiniband link-layer operations
*
***************************************************************************
@@ -1399,10 +1439,12 @@ static struct ib_device_operations arbel_ib_operations = {
.create_cq = arbel_create_cq,
.destroy_cq = arbel_destroy_cq,
.create_qp = arbel_create_qp,
+ .modify_qp = arbel_modify_qp,
.destroy_qp = arbel_destroy_qp,
.post_send = arbel_post_send,
.post_recv = arbel_post_recv,
.poll_cq = arbel_poll_cq,
+ .poll_eq = arbel_poll_eq,
.open = arbel_open,
.close = arbel_close,
.mcast_attach = arbel_mcast_attach,
@@ -1938,7 +1980,7 @@ static int arbel_probe ( struct pci_device *pci,
i = ( ARBEL_NUM_PORTS - 1 );
err_alloc_ibdev:
for ( ; i >= 0 ; i-- )
- free_ibdev ( arbel->ibdev[i] );
+ ibdev_put ( arbel->ibdev[i] );
free ( arbel );
err_alloc_arbel:
return rc;
@@ -1962,7 +2004,7 @@ static void arbel_remove ( struct pci_device *pci ) {
free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE );
free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
for ( i = ( ARBEL_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
- free_ibdev ( arbel->ibdev[i] );
+ ibdev_put ( arbel->ibdev[i] );
free ( arbel );
}
diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c
index 7d1b30acd..c198556ec 100644
--- a/src/drivers/infiniband/hermon.c
+++ b/src/drivers/infiniband/hermon.c
@@ -30,7 +30,6 @@
#include <gpxe/umalloc.h>
#include <gpxe/iobuf.h>
#include <gpxe/netdevice.h>
-#include <gpxe/process.h>
#include <gpxe/infiniband.h>
#include "hermon.h"
@@ -1228,215 +1227,6 @@ static void hermon_poll_cq ( struct ib_device *ibdev,
/***************************************************************************
*
- * Infiniband link-layer operations
- *
- ***************************************************************************
- */
-
-/**
- * Initialise Infiniband link
- *
- * @v ibdev Infiniband device
- * @ret rc Return status code
- */
-static int hermon_open ( struct ib_device *ibdev ) {
- struct hermon *hermon = ib_get_drvdata ( ibdev );
- struct hermonprm_init_port init_port;
- int rc;
-
- memset ( &init_port, 0, sizeof ( init_port ) );
- MLX_FILL_2 ( &init_port, 0,
- port_width_cap, 3,
- vl_cap, 1 );
- MLX_FILL_2 ( &init_port, 1,
- mtu, HERMON_MTU_2048,
- max_gid, 1 );
- MLX_FILL_1 ( &init_port, 2, max_pkey, 64 );
- if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port,
- &init_port ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p could not intialise port: %s\n",
- hermon, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Close Infiniband link
- *
- * @v ibdev Infiniband device
- */
-static void hermon_close ( struct ib_device *ibdev ) {
- struct hermon *hermon = ib_get_drvdata ( ibdev );
- int rc;
-
- if ( ( rc = hermon_cmd_close_port ( hermon, ibdev->port ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p could not close port: %s\n",
- hermon, strerror ( rc ) );
- /* Nothing we can do about this */
- }
-}
-
-/***************************************************************************
- *
- * Multicast group operations
- *
- ***************************************************************************
- */
-
-/**
- * Attach to multicast group
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @v gid Multicast GID
- * @ret rc Return status code
- */
-static int hermon_mcast_attach ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- struct ib_gid *gid ) {
- struct hermon *hermon = ib_get_drvdata ( ibdev );
- struct hermonprm_mgm_hash hash;
- struct hermonprm_mcg_entry mcg;
- unsigned int index;
- int rc;
-
- /* Generate hash table index */
- if ( ( rc = hermon_cmd_mgid_hash ( hermon, gid, &hash ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p could not hash GID: %s\n",
- hermon, strerror ( rc ) );
- return rc;
- }
- index = MLX_GET ( &hash, hash );
-
- /* Check for existing hash table entry */
- if ( ( rc = hermon_cmd_read_mcg ( hermon, index, &mcg ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p could not read MCG %#x: %s\n",
- hermon, index, strerror ( rc ) );
- return rc;
- }
- if ( MLX_GET ( &mcg, hdr.members_count ) != 0 ) {
- /* FIXME: this implementation allows only a single QP
- * per multicast group, and doesn't handle hash
- * collisions. Sufficient for IPoIB but may need to
- * be extended in future.
- */
- DBGC ( hermon, "Hermon %p MGID index %#x already in use\n",
- hermon, index );
- return -EBUSY;
- }
-
- /* Update hash table entry */
- MLX_FILL_1 ( &mcg, 1, hdr.members_count, 1 );
- MLX_FILL_1 ( &mcg, 8, qp[0].qpn, qp->qpn );
- memcpy ( &mcg.u.dwords[4], gid, sizeof ( *gid ) );
- if ( ( rc = hermon_cmd_write_mcg ( hermon, index, &mcg ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p could not write MCG %#x: %s\n",
- hermon, index, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Detach from multicast group
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @v gid Multicast GID
- */
-static void hermon_mcast_detach ( struct ib_device *ibdev,
- struct ib_queue_pair *qp __unused,
- struct ib_gid *gid ) {
- struct hermon *hermon = ib_get_drvdata ( ibdev );
- struct hermonprm_mgm_hash hash;
- struct hermonprm_mcg_entry mcg;
- unsigned int index;
- int rc;
-
- /* Generate hash table index */
- if ( ( rc = hermon_cmd_mgid_hash ( hermon, gid, &hash ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p could not hash GID: %s\n",
- hermon, strerror ( rc ) );
- return;
- }
- index = MLX_GET ( &hash, hash );
-
- /* Clear hash table entry */
- memset ( &mcg, 0, sizeof ( mcg ) );
- if ( ( rc = hermon_cmd_write_mcg ( hermon, index, &mcg ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p could not write MCG %#x: %s\n",
- hermon, index, strerror ( rc ) );
- return;
- }
-}
-
-/***************************************************************************
- *
- * MAD operations
- *
- ***************************************************************************
- */
-
-/**
- * Issue management datagram
- *
- * @v ibdev Infiniband device
- * @v mad Management datagram
- * @v len Length of management datagram
- * @ret rc Return status code
- */
-static int hermon_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
- size_t len ) {
- struct hermon *hermon = ib_get_drvdata ( ibdev );
- union hermonprm_mad mad_ifc;
- int rc;
-
- /* Copy in request packet */
- memset ( &mad_ifc, 0, sizeof ( mad_ifc ) );
- assert ( len <= sizeof ( mad_ifc.mad ) );
- memcpy ( &mad_ifc.mad, mad, len );
-
- /* Issue MAD */
- if ( ( rc = hermon_cmd_mad_ifc ( hermon, ibdev->port,
- &mad_ifc ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p could not issue MAD IFC: %s\n",
- hermon, strerror ( rc ) );
- return rc;
- }
-
- /* Copy out reply packet */
- memcpy ( mad, &mad_ifc.mad, len );
-
- if ( mad->status != 0 ) {
- DBGC ( hermon, "Hermon %p MAD IFC status %04x\n",
- hermon, ntohs ( mad->status ) );
- return -EIO;
- }
- return 0;
-}
-
-/** Hermon Infiniband operations */
-static struct ib_device_operations hermon_ib_operations = {
- .create_cq = hermon_create_cq,
- .destroy_cq = hermon_destroy_cq,
- .create_qp = hermon_create_qp,
- .modify_qp = hermon_modify_qp,
- .destroy_qp = hermon_destroy_qp,
- .post_send = hermon_post_send,
- .post_recv = hermon_post_recv,
- .poll_cq = hermon_poll_cq,
- .open = hermon_open,
- .close = hermon_close,
- .mcast_attach = hermon_mcast_attach,
- .mcast_detach = hermon_mcast_detach,
- .mad = hermon_mad,
-};
-
-/***************************************************************************
- *
* Event queues
*
***************************************************************************
@@ -1597,9 +1387,10 @@ static void hermon_event_port_state_change ( struct hermon *hermon,
/**
* Poll event queue
*
- * @v hermon Hermon device
+ * @v ibdev Infiniband device
*/
-static void hermon_poll_eq ( struct hermon *hermon ) {
+static void hermon_poll_eq ( struct ib_device *ibdev ) {
+ struct hermon *hermon = ib_get_drvdata ( ibdev );
struct hermon_event_queue *hermon_eq = &hermon->eq;
union hermonprm_event_entry *eqe;
union hermonprm_doorbell_register db_reg;
@@ -1644,20 +1435,218 @@ static void hermon_poll_eq ( struct hermon *hermon ) {
}
}
+/***************************************************************************
+ *
+ * Infiniband link-layer operations
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Initialise Infiniband link
+ *
+ * @v ibdev Infiniband device
+ * @ret rc Return status code
+ */
+static int hermon_open ( struct ib_device *ibdev ) {
+ struct hermon *hermon = ib_get_drvdata ( ibdev );
+ struct hermonprm_init_port init_port;
+ int rc;
+
+ memset ( &init_port, 0, sizeof ( init_port ) );
+ MLX_FILL_2 ( &init_port, 0,
+ port_width_cap, 3,
+ vl_cap, 1 );
+ MLX_FILL_2 ( &init_port, 1,
+ mtu, HERMON_MTU_2048,
+ max_gid, 1 );
+ MLX_FILL_1 ( &init_port, 2, max_pkey, 64 );
+ if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port,
+ &init_port ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p could not intialise port: %s\n",
+ hermon, strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
/**
- * Event queue poll processor
+ * Close Infiniband link
*
- * @v process Hermon event queue process
+ * @v ibdev Infiniband device
*/
-static void hermon_step ( struct process *process ) {
- struct hermon *hermon =
- container_of ( process, struct hermon, event_process );
+static void hermon_close ( struct ib_device *ibdev ) {
+ struct hermon *hermon = ib_get_drvdata ( ibdev );
+ int rc;
- hermon_poll_eq ( hermon );
+ if ( ( rc = hermon_cmd_close_port ( hermon, ibdev->port ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p could not close port: %s\n",
+ hermon, strerror ( rc ) );
+ /* Nothing we can do about this */
+ }
}
/***************************************************************************
*
+ * Multicast group operations
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Attach to multicast group
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v gid Multicast GID
+ * @ret rc Return status code
+ */
+static int hermon_mcast_attach ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp,
+ struct ib_gid *gid ) {
+ struct hermon *hermon = ib_get_drvdata ( ibdev );
+ struct hermonprm_mgm_hash hash;
+ struct hermonprm_mcg_entry mcg;
+ unsigned int index;
+ int rc;
+
+ /* Generate hash table index */
+ if ( ( rc = hermon_cmd_mgid_hash ( hermon, gid, &hash ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p could not hash GID: %s\n",
+ hermon, strerror ( rc ) );
+ return rc;
+ }
+ index = MLX_GET ( &hash, hash );
+
+ /* Check for existing hash table entry */
+ if ( ( rc = hermon_cmd_read_mcg ( hermon, index, &mcg ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p could not read MCG %#x: %s\n",
+ hermon, index, strerror ( rc ) );
+ return rc;
+ }
+ if ( MLX_GET ( &mcg, hdr.members_count ) != 0 ) {
+ /* FIXME: this implementation allows only a single QP
+ * per multicast group, and doesn't handle hash
+ * collisions. Sufficient for IPoIB but may need to
+ * be extended in future.
+ */
+ DBGC ( hermon, "Hermon %p MGID index %#x already in use\n",
+ hermon, index );
+ return -EBUSY;
+ }
+
+ /* Update hash table entry */
+ MLX_FILL_1 ( &mcg, 1, hdr.members_count, 1 );
+ MLX_FILL_1 ( &mcg, 8, qp[0].qpn, qp->qpn );
+ memcpy ( &mcg.u.dwords[4], gid, sizeof ( *gid ) );
+ if ( ( rc = hermon_cmd_write_mcg ( hermon, index, &mcg ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p could not write MCG %#x: %s\n",
+ hermon, index, strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/**
+ * Detach from multicast group
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v gid Multicast GID
+ */
+static void hermon_mcast_detach ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp __unused,
+ struct ib_gid *gid ) {
+ struct hermon *hermon = ib_get_drvdata ( ibdev );
+ struct hermonprm_mgm_hash hash;
+ struct hermonprm_mcg_entry mcg;
+ unsigned int index;
+ int rc;
+
+ /* Generate hash table index */
+ if ( ( rc = hermon_cmd_mgid_hash ( hermon, gid, &hash ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p could not hash GID: %s\n",
+ hermon, strerror ( rc ) );
+ return;
+ }
+ index = MLX_GET ( &hash, hash );
+
+ /* Clear hash table entry */
+ memset ( &mcg, 0, sizeof ( mcg ) );
+ if ( ( rc = hermon_cmd_write_mcg ( hermon, index, &mcg ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p could not write MCG %#x: %s\n",
+ hermon, index, strerror ( rc ) );
+ return;
+ }
+}
+
+/***************************************************************************
+ *
+ * MAD operations
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Issue management datagram
+ *
+ * @v ibdev Infiniband device
+ * @v mad Management datagram
+ * @v len Length of management datagram
+ * @ret rc Return status code
+ */
+static int hermon_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
+ size_t len ) {
+ struct hermon *hermon = ib_get_drvdata ( ibdev );
+ union hermonprm_mad mad_ifc;
+ int rc;
+
+ /* Copy in request packet */
+ memset ( &mad_ifc, 0, sizeof ( mad_ifc ) );
+ assert ( len <= sizeof ( mad_ifc.mad ) );
+ memcpy ( &mad_ifc.mad, mad, len );
+
+ /* Issue MAD */
+ if ( ( rc = hermon_cmd_mad_ifc ( hermon, ibdev->port,
+ &mad_ifc ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p could not issue MAD IFC: %s\n",
+ hermon, strerror ( rc ) );
+ return rc;
+ }
+
+ /* Copy out reply packet */
+ memcpy ( mad, &mad_ifc.mad, len );
+
+ if ( mad->status != 0 ) {
+ DBGC ( hermon, "Hermon %p MAD IFC status %04x\n",
+ hermon, ntohs ( mad->status ) );
+ return -EIO;
+ }
+ return 0;
+}
+
+/** Hermon Infiniband operations */
+static struct ib_device_operations hermon_ib_operations = {
+ .create_cq = hermon_create_cq,
+ .destroy_cq = hermon_destroy_cq,
+ .create_qp = hermon_create_qp,
+ .modify_qp = hermon_modify_qp,
+ .destroy_qp = hermon_destroy_qp,
+ .post_send = hermon_post_send,
+ .post_recv = hermon_post_recv,
+ .poll_cq = hermon_poll_cq,
+ .poll_eq = hermon_poll_eq,
+ .open = hermon_open,
+ .close = hermon_close,
+ .mcast_attach = hermon_mcast_attach,
+ .mcast_detach = hermon_mcast_detach,
+ .mad = hermon_mad,
+};
+
+/***************************************************************************
+ *
* Firmware control
*
***************************************************************************
@@ -2168,7 +2157,6 @@ static int hermon_probe ( struct pci_device *pci,
goto err_alloc_hermon;
}
pci_set_drvdata ( pci, hermon );
- process_init ( &hermon->event_process, hermon_step, NULL );
/* Allocate Infiniband devices */
for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ ) {
@@ -2270,8 +2258,7 @@ static int hermon_probe ( struct pci_device *pci,
i = ( HERMON_NUM_PORTS - 1 );
err_alloc_ibdev:
for ( ; i >= 0 ; i-- )
- free_ibdev ( hermon->ibdev[i] );
- process_del ( &hermon->event_process );
+ ibdev_put ( hermon->ibdev[i] );
free ( hermon );
err_alloc_hermon:
return rc;
@@ -2296,8 +2283,7 @@ static void hermon_remove ( struct pci_device *pci ) {
free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
for ( i = ( HERMON_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
- free_ibdev ( hermon->ibdev[i] );
- process_del ( &hermon->event_process );
+ ibdev_put ( hermon->ibdev[i] );
free ( hermon );
}
diff --git a/src/drivers/infiniband/hermon.h b/src/drivers/infiniband/hermon.h
index 45d7a1ce8..1ae27780f 100644
--- a/src/drivers/infiniband/hermon.h
+++ b/src/drivers/infiniband/hermon.h
@@ -9,7 +9,6 @@
#include <stdint.h>
#include <gpxe/uaccess.h>
-#include <gpxe/process.h>
#include "mlx_bitops.h"
#include "MT25408_PRM.h"
@@ -465,8 +464,6 @@ struct hermon {
/** Event queue */
struct hermon_event_queue eq;
- /** Event queue process */
- struct process event_process;
/** Completion queue in-use bitmask */
hermon_bitmask_t cq_inuse[ HERMON_BITMASK_SIZE ( HERMON_MAX_CQS ) ];
diff --git a/src/include/gpxe/infiniband.h b/src/include/gpxe/infiniband.h
index 8fc928c71..f9e65348e 100644
--- a/src/include/gpxe/infiniband.h
+++ b/src/include/gpxe/infiniband.h
@@ -8,6 +8,7 @@
*/
#include <stdint.h>
+#include <gpxe/refcnt.h>
#include <gpxe/device.h>
/** Subnet administrator QPN */
@@ -255,6 +256,12 @@ struct ib_device_operations {
ib_completer_t complete_send,
ib_completer_t complete_recv );
/**
+ * Poll event queue
+ *
+ * @v ibdev Infiniband device
+ */
+ void ( * poll_eq ) ( struct ib_device *ibdev );
+ /**
* Open port
*
* @v ibdev Infiniband device
@@ -300,6 +307,10 @@ struct ib_device_operations {
/** An Infiniband device */
struct ib_device {
+ /** Reference counter */
+ struct refcnt refcnt;
+ /** List of Infiniband devices */
+ struct list_head list;
/** Underlying device */
struct device *dev;
/** Infiniband operations */
@@ -337,7 +348,6 @@ extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
extern struct ib_device * alloc_ibdev ( size_t priv_size );
extern int register_ibdev ( struct ib_device *ibdev );
extern void unregister_ibdev ( struct ib_device *ibdev );
-extern void free_ibdev ( struct ib_device *ibdev );
extern void ib_link_state_changed ( struct ib_device *ibdev );
/**
@@ -445,6 +455,28 @@ ib_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad, size_t len ) {
}
/**
+ * Get reference to Infiniband device
+ *
+ * @v ibdev Infiniband device
+ * @ret ibdev Infiniband device
+ */
+static inline __attribute__ (( always_inline )) struct ib_device *
+ibdev_get ( struct ib_device *ibdev ) {
+ ref_get ( &ibdev->refcnt );
+ return ibdev;
+}
+
+/**
+ * Drop reference to Infiniband device
+ *
+ * @v ibdev Infiniband device
+ */
+static inline __attribute__ (( always_inline )) void
+ibdev_put ( struct ib_device *ibdev ) {
+ ref_put ( &ibdev->refcnt );
+}
+
+/**
* Set Infiniband work queue driver-private data
*
* @v wq Work queue
diff --git a/src/net/infiniband.c b/src/net/infiniband.c
index e5c79e961..ab76742e7 100644
--- a/src/net/infiniband.c
+++ b/src/net/infiniband.c
@@ -29,6 +29,7 @@
#include <gpxe/netdevice.h>
#include <gpxe/iobuf.h>
#include <gpxe/ipoib.h>
+#include <gpxe/process.h>
#include <gpxe/infiniband.h>
/** @file
@@ -37,6 +38,9 @@
*
*/
+/** List of Infiniband devices */
+struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices );
+
/**
* Create completion queue
*
@@ -351,6 +355,50 @@ static int ib_get_mad_params ( struct ib_device *ibdev ) {
/***************************************************************************
*
+ * Event queues
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Handle Infiniband link state change
+ *
+ * @v ibdev Infiniband device
+ */
+void ib_link_state_changed ( struct ib_device *ibdev ) {
+ int rc;
+
+ /* Update MAD parameters */
+ if ( ( rc = ib_get_mad_params ( ibdev ) ) != 0 ) {
+ DBGC ( ibdev, "IBDEV %p could not update MAD parameters: %s\n",
+ ibdev, strerror ( rc ) );
+ return;
+ }
+
+ /* Notify IPoIB of link state change */
+ ipoib_link_state_changed ( ibdev );
+}
+
+/**
+ * Single-step the Infiniband event queue
+ *
+ * @v process Infiniband event queue process
+ */
+static void ib_step ( struct process *process __unused ) {
+ struct ib_device *ibdev;
+
+ list_for_each_entry ( ibdev, &ib_devices, list ) {
+ ibdev->op->poll_eq ( ibdev );
+ }
+}
+
+/** Infiniband event queue process */
+struct process ib_process __permanent_process = {
+ .step = ib_step,
+};
+
+/***************************************************************************
+ *
* Infiniband device creation/destruction
*
***************************************************************************
@@ -385,6 +433,10 @@ struct ib_device * alloc_ibdev ( size_t priv_size ) {
int register_ibdev ( struct ib_device *ibdev ) {
int rc;
+ /* Add to device list */
+ ibdev_get ( ibdev );
+ list_add_tail ( &ibdev->list, &ib_devices );
+
/* Open link */
if ( ( rc = ib_open ( ibdev ) ) != 0 )
goto err_open;
@@ -400,12 +452,16 @@ int register_ibdev ( struct ib_device *ibdev ) {
goto err_ipoib_probe;
}
+ DBGC ( ibdev, "IBDEV %p registered (phys %s)\n", ibdev,
+ ibdev->dev->name );
return 0;
err_ipoib_probe:
err_get_mad_params:
ib_close ( ibdev );
err_open:
+ list_del ( &ibdev->list );
+ ibdev_put ( ibdev );
return rc;
}
@@ -415,34 +471,13 @@ int register_ibdev ( struct ib_device *ibdev ) {
* @v ibdev Infiniband device
*/
void unregister_ibdev ( struct ib_device *ibdev ) {
+
+ /* Close device */
ipoib_remove ( ibdev );
ib_close ( ibdev );
-}
-
-/**
- * Free Infiniband device
- *
- * @v ibdev Infiniband device
- */
-void free_ibdev ( struct ib_device *ibdev ) {
- free ( ibdev );
-}
-
-/**
- * Handle Infiniband link state change
- *
- * @v ibdev Infiniband device
- */
-void ib_link_state_changed ( struct ib_device *ibdev ) {
- int rc;
- /* Update MAD parameters */
- if ( ( rc = ib_get_mad_params ( ibdev ) ) != 0 ) {
- DBGC ( ibdev, "IBDEV %p could not update MAD parameters: %s\n",
- ibdev, strerror ( rc ) );
- return;
- }
-
- /* Notify IPoIB of link state change */
- ipoib_link_state_changed ( ibdev );
+ /* Remove from device list */
+ list_del ( &ibdev->list );
+ ibdev_put ( ibdev );
+ DBGC ( ibdev, "IBDEV %p unregistered\n", ibdev );
}