diff options
author | Michael Brown | 2008-04-21 14:23:11 +0200 |
---|---|---|
committer | Michael Brown | 2008-04-21 14:23:11 +0200 |
commit | 35a583667780122e8dabc72737be51fe914b4257 (patch) | |
tree | 1407b011e3a8659a45c55fe6792797507a802364 /src/drivers | |
parent | [Hermon] Fix event queue doorbells. (diff) | |
download | ipxe-35a583667780122e8dabc72737be51fe914b4257.tar.gz ipxe-35a583667780122e8dabc72737be51fe914b4257.tar.xz ipxe-35a583667780122e8dabc72737be51fe914b4257.zip |
[Infiniband] Move event-queue process from driver to Infiniband core
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/infiniband/arbel.c | 46 | ||||
-rw-r--r-- | src/drivers/infiniband/hermon.c | 432 | ||||
-rw-r--r-- | src/drivers/infiniband/hermon.h | 3 |
3 files changed, 253 insertions, 228 deletions
diff --git a/src/drivers/infiniband/arbel.c b/src/drivers/infiniband/arbel.c index 462638ea..2409e285 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 7d1b30ac..c198556e 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 45d7a1ce..1ae27780 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 ) ]; |