diff options
author | Michael Brown <mcb30@etherboot.org> | 2009-07-07 18:30:15 +0100 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2009-07-17 23:06:34 +0100 |
commit | 165074c1881e7ce86e4d6d2e3caa20231f42560b (patch) | |
tree | 12ead5a76c154e17bfffd0a7c195345609ea9937 /src/net/infiniband | |
parent | 8a852280eb84ff6a43f8c08aeb52c3e21a5da31b (diff) | |
download | ipxe-165074c1881e7ce86e4d6d2e3caa20231f42560b.tar.gz |
[infiniband] Implement SMA as an instance of a GMA
The GMA code was based upon the SMA code. We can save space by making
the SMA simply an instance of the GMA.
Diffstat (limited to 'src/net/infiniband')
-rw-r--r-- | src/net/infiniband/ib_gma.c | 3 | ||||
-rw-r--r-- | src/net/infiniband/ib_sma.c | 457 |
2 files changed, 144 insertions, 316 deletions
diff --git a/src/net/infiniband/ib_gma.c b/src/net/infiniband/ib_gma.c index 89f0eeb1..405d7861 100644 --- a/src/net/infiniband/ib_gma.c +++ b/src/net/infiniband/ib_gma.c @@ -86,7 +86,8 @@ static int ib_handle_mad ( struct ib_gma *gma, union ib_mad *mad ) { struct ib_gma_handler *handler; for_each_table_entry ( handler, IB_GMA_HANDLERS ) { - if ( ( handler->mgmt_class == hdr->mgmt_class ) && + if ( ( ( handler->mgmt_class & ~handler->mgmt_class_ignore ) == + ( hdr->mgmt_class & ~handler->mgmt_class_ignore ) ) && ( handler->class_version == hdr->class_version ) && ( handler->method == hdr->method ) && ( handler->attr_id == hdr->attr_id ) ) { diff --git a/src/net/infiniband/ib_sma.c b/src/net/infiniband/ib_sma.c index 007b4d1a..9e99703f 100644 --- a/src/net/infiniband/ib_sma.c +++ b/src/net/infiniband/ib_sma.c @@ -26,7 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <unistd.h> #include <byteswap.h> #include <gpxe/infiniband.h> -#include <gpxe/iobuf.h> +#include <gpxe/ib_gma.h> #include <gpxe/ib_sma.h> /** @@ -39,13 +39,14 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** * Get node information * - * @v sma Subnet management agent - * @v get Attribute to get + * @v gma General management agent + * @v mad MAD + * @ret rc Return status code */ -static void ib_sma_get_node_info ( struct ib_sma *sma, - union ib_smp_data *get ) { - struct ib_device *ibdev = sma->ibdev; - struct ib_node_info *node_info = &get->node_info; +static int ib_sma_get_node_info ( struct ib_gma *gma, + union ib_mad *mad ) { + struct ib_device *ibdev = gma->ibdev; + struct ib_node_info *node_info = &mad->smp.smp_data.node_info; memset ( node_info, 0, sizeof ( *node_info ) ); node_info->base_version = IB_MGMT_BASE_VERSION; @@ -58,18 +59,21 @@ static void ib_sma_get_node_info ( struct ib_sma *sma, sizeof ( node_info->port_guid ) ); node_info->partition_cap = htons ( 1 ); node_info->local_port_num = ibdev->port; + + return 0; } /** * Get node description * - * @v sma Subnet management agent - * @v get Attribute to get + * @v gma General management agent + * @v mad MAD + * @ret rc Return status code */ -static void ib_sma_get_node_desc ( struct ib_sma *sma, - union ib_smp_data *get ) { - struct ib_device *ibdev = sma->ibdev; - struct ib_node_desc *node_desc = &get->node_desc; +static int ib_sma_get_node_desc ( struct ib_gma *gma, + union ib_mad *mad ) { + struct ib_device *ibdev = gma->ibdev; + struct ib_node_desc *node_desc = &mad->smp.smp_data.node_desc; struct ib_gid_half *guid = &ibdev->gid.u.half[1]; memset ( node_desc, 0, sizeof ( *node_desc ) ); @@ -78,34 +82,40 @@ static void ib_sma_get_node_desc ( struct ib_sma *sma, guid->bytes[0], guid->bytes[1], guid->bytes[2], guid->bytes[3], guid->bytes[4], guid->bytes[5], guid->bytes[6], guid->bytes[7], ibdev->dev->name ); + + return 0; } /** * Get GUID information * - * @v sma Subnet management agent - * @v get Attribute to get + * @v gma General management agent + * @v mad MAD + * @ret rc Return status code */ -static void ib_sma_get_guid_info ( struct ib_sma *sma, - union ib_smp_data *get ) { - struct ib_device *ibdev = sma->ibdev; - struct ib_guid_info *guid_info = &get->guid_info; +static int ib_sma_get_guid_info ( struct ib_gma *gma, + union ib_mad *mad ) { + struct ib_device *ibdev = gma->ibdev; + struct ib_guid_info *guid_info = &mad->smp.smp_data.guid_info; memset ( guid_info, 0, sizeof ( *guid_info ) ); memcpy ( guid_info->guid[0], &ibdev->gid.u.half[1], sizeof ( guid_info->guid[0] ) ); + + return 0; } /** * Get port information * - * @v sma Subnet management agent - * @v get Attribute to get + * @v gma General management agent + * @v mad MAD + * @ret rc Return status code */ -static void ib_sma_get_port_info ( struct ib_sma *sma, - union ib_smp_data *get ) { - struct ib_device *ibdev = sma->ibdev; - struct ib_port_info *port_info = &get->port_info; +static int ib_sma_get_port_info ( struct ib_gma *gma, + union ib_mad *mad ) { + struct ib_device *ibdev = gma->ibdev; + struct ib_port_info *port_info = &mad->smp.smp_data.port_info; memset ( port_info, 0, sizeof ( *port_info ) ); memcpy ( port_info->gid_prefix, &ibdev->gid.u.half[0], @@ -129,19 +139,22 @@ static void ib_sma_get_port_info ( struct ib_sma *sma, port_info->init_type_reply__mtu_cap = IB_MTU_2048; port_info->operational_vls__enforcement = ( IB_VL_0 << 4 ); port_info->guid_cap = 1; + + return 0; } /** * Set port information * - * @v sma Subnet management agent - * @v set Attribute to set + * @v gma General management agent + * @v mad MAD * @ret rc Return status code */ -static int ib_sma_set_port_info ( struct ib_sma *sma, - const union ib_smp_data *set ) { - struct ib_device *ibdev = sma->ibdev; - const struct ib_port_info *port_info = &set->port_info; +static int ib_sma_set_port_info ( struct ib_gma *gma, + union ib_mad *mad ) { + struct ib_device *ibdev = gma->ibdev; + const struct ib_port_info *port_info = &mad->smp.smp_data.port_info; + int rc; memcpy ( &ibdev->gid.u.half[0], port_info->gid_prefix, sizeof ( ibdev->gid.u.half[0] ) ); @@ -149,280 +162,116 @@ static int ib_sma_set_port_info ( struct ib_sma *sma, ibdev->sm_lid = ntohs ( port_info->mastersm_lid ); ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf ); - if ( ! sma->op->set_port_info ) { - /* Not an error; we just ignore all other settings */ - return 0; + if ( ( rc = ib_set_port_info ( ibdev, port_info ) ) != 0 ) { + DBGC ( ibdev, "IBDEV %p could not set port information: %s\n", + ibdev, strerror ( rc ) ); + mad->hdr.status = + htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR ); } - return sma->op->set_port_info ( ibdev, port_info ); + return ib_sma_get_port_info ( gma, mad ); } /** * Get partition key table * - * @v sma Subnet management agent - * @v get Attribute to get + * @v gma General management agent + * @v mad MAD + * @ret rc Return status code */ -static void ib_sma_get_pkey_table ( struct ib_sma *sma, - union ib_smp_data *get ) { - struct ib_device *ibdev = sma->ibdev; - struct ib_pkey_table *pkey_table = &get->pkey_table; +static int ib_sma_get_pkey_table ( struct ib_gma *gma, + union ib_mad *mad ) { + struct ib_device *ibdev = gma->ibdev; + struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table; memset ( pkey_table, 0, sizeof ( *pkey_table ) ); pkey_table->pkey[0] = htons ( ibdev->pkey ); -} -/** - * Set partition key table - * - * @v sma Subnet management agent - * @v set Attribute to set - */ -static int ib_sma_set_pkey_table ( struct ib_sma *sma, - const union ib_smp_data *get ) { - struct ib_device *ibdev = sma->ibdev; - const struct ib_pkey_table *pkey_table = &get->pkey_table; - - ibdev->pkey = ntohs ( pkey_table->pkey[0] ); return 0; } -/** An attribute handler */ -struct ib_sma_handler { - /** Attribute (in network byte order) */ - uint16_t attr_id; - /** Get attribute - * - * @v sma Subnet management agent - * @v get Attribute to get - * @ret rc Return status code - */ - void ( * get ) ( struct ib_sma *sma, union ib_smp_data *get ); - /** Set attribute - * - * @v sma Subnet management agent - * @v set Attribute to set - * @ret rc Return status code - */ - int ( * set ) ( struct ib_sma *sma, const union ib_smp_data *set ); -}; - -/** List of attribute handlers */ -static struct ib_sma_handler ib_sma_handlers[] = { - { htons ( IB_SMP_ATTR_NODE_DESC ), - ib_sma_get_node_desc, NULL }, - { htons ( IB_SMP_ATTR_NODE_INFO ), - ib_sma_get_node_info, NULL }, - { htons ( IB_SMP_ATTR_GUID_INFO ), - ib_sma_get_guid_info, NULL }, - { htons ( IB_SMP_ATTR_PORT_INFO ), - ib_sma_get_port_info, ib_sma_set_port_info }, - { htons ( IB_SMP_ATTR_PKEY_TABLE ), - ib_sma_get_pkey_table, ib_sma_set_pkey_table }, -}; - -/** - * Identify attribute handler - * - * @v attr_id Attribute ID (in network byte order) - * @ret handler Attribute handler (or NULL) - */ -static struct ib_sma_handler * ib_sma_handler ( uint16_t attr_id ) { - struct ib_sma_handler *handler; - unsigned int i; - - for ( i = 0 ; i < ( sizeof ( ib_sma_handlers ) / - sizeof ( ib_sma_handlers[0] ) ) ; i++ ) { - handler = &ib_sma_handlers[i]; - if ( handler->attr_id == attr_id ) - return handler; - } - - return NULL; -} - /** - * Respond to management datagram + * Set partition key table * - * @v sma Subnet management agent - * @v mad Management datagram + * @v gma General management agent + * @v mad MAD * @ret rc Return status code */ -static int ib_sma_mad ( struct ib_sma *sma, union ib_mad *mad ) { - struct ib_device *ibdev = sma->ibdev; - struct ib_mad_hdr *hdr = &mad->hdr; - struct ib_mad_smp *smp = &mad->smp; - struct ib_sma_handler *handler = NULL; - unsigned int hop_pointer; - unsigned int hop_count; - int rc; - - DBGC ( sma, "SMA %p received SMP with bv=%02x mc=%02x cv=%02x " - "meth=%02x attr=%04x mod=%08x\n", sma, hdr->base_version, - hdr->mgmt_class, hdr->class_version, hdr->method, - ntohs ( hdr->attr_id ), ntohl ( hdr->attr_mod ) ); - DBGC2_HDA ( sma, 0, mad, sizeof ( *mad ) ); - - /* Sanity checks */ - if ( hdr->base_version != IB_MGMT_BASE_VERSION ) { - DBGC ( sma, "SMA %p unsupported base version %x\n", - sma, hdr->base_version ); - return -ENOTSUP; - } - if ( ( hdr->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE ) && - ( hdr->mgmt_class != IB_MGMT_CLASS_SUBN_LID_ROUTED ) ) { - DBGC ( sma, "SMA %p unsupported management class %x\n", - sma, hdr->mgmt_class ); - return -ENOTSUP; - } - if ( hdr->class_version != IB_SMP_CLASS_VERSION ) { - DBGC ( sma, "SMA %p unsupported class version %x\n", - sma, hdr->class_version ); - return -ENOTSUP; - } - if ( ( hdr->method != IB_MGMT_METHOD_GET ) && - ( hdr->method != IB_MGMT_METHOD_SET ) ) { - DBGC ( sma, "SMA %p unsupported method %x\n", - sma, hdr->method ); - return -ENOTSUP; - } - - /* Identify handler */ - if ( ! ( handler = ib_sma_handler ( hdr->attr_id ) ) ) { - DBGC ( sma, "SMA %p unsupported attribute %x\n", - sma, ntohs ( hdr->attr_id ) ); - hdr->status = htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR ); - goto respond_without_data; - } - - /* Set attribute (if applicable) */ - if ( hdr->method != IB_MGMT_METHOD_SET ) { - hdr->status = htons ( IB_MGMT_STATUS_OK ); - goto respond; - } - if ( ! handler->set ) { - DBGC ( sma, "SMA %p attribute %x is unsettable\n", - sma, ntohs ( hdr->attr_id ) ); - hdr->status = htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR ); - goto respond; - } - if ( ( rc = handler->set ( sma, &smp->smp_data ) ) != 0 ) { - DBGC ( sma, "SMA %p could not set attribute %x: %s\n", - sma, ntohs ( hdr->attr_id ), strerror ( rc ) ); - hdr->status = htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR ); - goto respond; - } - - hdr->status = htons ( IB_MGMT_STATUS_OK ); - - respond: - /* Get attribute */ - handler->get ( sma, &smp->smp_data ); - - respond_without_data: - - /* Set method to "Get Response" */ - hdr->method = IB_MGMT_METHOD_GET_RESP; - - /* Set response fields for directed route SMPs */ - if ( hdr->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE ) { - hdr->status |= htons ( IB_SMP_STATUS_D_INBOUND ); - hop_pointer = smp->mad_hdr.class_specific.smp.hop_pointer; - hop_count = smp->mad_hdr.class_specific.smp.hop_count; - assert ( hop_count == hop_pointer ); - if ( hop_pointer < ( sizeof ( smp->return_path.hops ) / - sizeof ( smp->return_path.hops[0] ) ) ) { - smp->return_path.hops[hop_pointer] = ibdev->port; - } else { - DBGC ( sma, "SMA %p invalid hop pointer %d\n", - sma, hop_pointer ); - return -EINVAL; - } - } - - DBGC ( sma, "SMA %p responding with status=%04x\n", - sma, ntohs ( hdr->status ) ); - DBGC2_HDA ( sma, 0, mad, sizeof ( *mad ) ); - - return 0; -} - -/** - * Complete SMA send - * - * - * @v ibdev Infiniband device - * @v qp Queue pair - * @v iobuf I/O buffer - * @v rc Completion status code - */ -static void ib_sma_complete_send ( struct ib_device *ibdev __unused, - struct ib_queue_pair *qp, - struct io_buffer *iobuf, int rc ) { - struct ib_sma *sma = ib_qp_get_ownerdata ( qp ); +static int ib_sma_set_pkey_table ( struct ib_gma *gma, + union ib_mad *mad ) { + struct ib_device *ibdev = gma->ibdev; + struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table; - if ( rc != 0 ) { - DBGC ( sma, "SMA %p send completion error: %s\n", - sma, strerror ( rc ) ); - } - free_iob ( iobuf ); -} - -/** - * Complete SMA receive - * - * - * @v ibdev Infiniband device - * @v qp Queue pair - * @v av Address vector - * @v iobuf I/O buffer - * @v rc Completion status code - */ -static void ib_sma_complete_recv ( struct ib_device *ibdev, - struct ib_queue_pair *qp, - struct ib_address_vector *av, - struct io_buffer *iobuf, int rc ) { - struct ib_sma *sma = ib_qp_get_ownerdata ( qp ); - union ib_mad *mad; - - /* Ignore errors */ - if ( rc != 0 ) { - DBGC ( sma, "SMA %p RX error: %s\n", sma, strerror ( rc ) ); - goto err; - } - - /* Sanity check */ - if ( iob_len ( iobuf ) != sizeof ( *mad ) ) { - DBGC ( sma, "SMA %p RX bad size (%zd bytes)\n", - sma, iob_len ( iobuf ) ); - goto err; - } - mad = iobuf->data; - - /* Construct MAD response */ - if ( ( rc = ib_sma_mad ( sma, mad ) ) != 0 ) { - DBGC ( sma, "SMA %p could not construct MAD response: %s\n", - sma, strerror ( rc ) ); - goto err; - } - - /* Send MAD response */ - if ( ( rc = ib_post_send ( ibdev, qp, av, iobuf ) ) != 0 ) { - DBGC ( sma, "SMA %p could not send MAD response: %s\n", - sma, strerror ( rc ) ); - goto err; - } - - return; + ibdev->pkey = ntohs ( pkey_table->pkey[0] ); - err: - free_iob ( iobuf ); + return ib_sma_get_pkey_table ( gma, mad ); } -/** SMA completion operations */ -static struct ib_completion_queue_operations ib_sma_completion_ops = { - .complete_send = ib_sma_complete_send, - .complete_recv = ib_sma_complete_recv, +/** List of attribute handlers */ +struct ib_gma_handler ib_sma_handlers[] __ib_gma_handler = { + { + .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, + .mgmt_class_ignore = IB_SMP_CLASS_IGNORE, + .class_version = IB_SMP_CLASS_VERSION, + .method = IB_MGMT_METHOD_GET, + .resp_method = IB_MGMT_METHOD_GET_RESP, + .attr_id = htons ( IB_SMP_ATTR_NODE_INFO ), + .handle = ib_sma_get_node_info, + }, + { + .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, + .mgmt_class_ignore = IB_SMP_CLASS_IGNORE, + .class_version = IB_SMP_CLASS_VERSION, + .method = IB_MGMT_METHOD_GET, + .resp_method = IB_MGMT_METHOD_GET_RESP, + .attr_id = htons ( IB_SMP_ATTR_NODE_DESC ), + .handle = ib_sma_get_node_desc, + }, + { + .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, + .mgmt_class_ignore = IB_SMP_CLASS_IGNORE, + .class_version = IB_SMP_CLASS_VERSION, + .method = IB_MGMT_METHOD_GET, + .resp_method = IB_MGMT_METHOD_GET_RESP, + .attr_id = htons ( IB_SMP_ATTR_GUID_INFO ), + .handle = ib_sma_get_guid_info, + }, + { + .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, + .mgmt_class_ignore = IB_SMP_CLASS_IGNORE, + .class_version = IB_SMP_CLASS_VERSION, + .method = IB_MGMT_METHOD_GET, + .resp_method = IB_MGMT_METHOD_GET_RESP, + .attr_id = htons ( IB_SMP_ATTR_PORT_INFO ), + .handle = ib_sma_get_port_info, + }, + { + .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, + .mgmt_class_ignore = IB_SMP_CLASS_IGNORE, + .class_version = IB_SMP_CLASS_VERSION, + .method = IB_MGMT_METHOD_SET, + .resp_method = IB_MGMT_METHOD_GET_RESP, + .attr_id = htons ( IB_SMP_ATTR_PORT_INFO ), + .handle = ib_sma_set_port_info, + }, + { + .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, + .mgmt_class_ignore = IB_SMP_CLASS_IGNORE, + .class_version = IB_SMP_CLASS_VERSION, + .method = IB_MGMT_METHOD_GET, + .resp_method = IB_MGMT_METHOD_GET_RESP, + .attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ), + .handle = ib_sma_get_pkey_table, + }, + { + .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, + .mgmt_class_ignore = IB_SMP_CLASS_IGNORE, + .class_version = IB_SMP_CLASS_VERSION, + .method = IB_MGMT_METHOD_SET, + .resp_method = IB_MGMT_METHOD_GET_RESP, + .attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ), + .handle = ib_sma_set_pkey_table, + }, }; /** @@ -433,49 +282,29 @@ static struct ib_completion_queue_operations ib_sma_completion_ops = { * @v op Subnet management operations * @ret rc Return status code */ -int ib_create_sma ( struct ib_sma *sma, struct ib_device *ibdev, - struct ib_sma_operations *op ) { +int ib_create_sma ( struct ib_sma *sma, struct ib_device *ibdev ) { int rc; - /* Initialise fields */ - memset ( sma, 0, sizeof ( *sma ) ); - sma->ibdev = ibdev; - sma->op = op; - - /* Create completion queue */ - sma->cq = ib_create_cq ( ibdev, IB_SMA_NUM_CQES, - &ib_sma_completion_ops ); - if ( ! sma->cq ) { - rc = -ENOMEM; - goto err_create_cq; - } - - /* Create queue pair */ - sma->qp = ib_create_qp ( ibdev, IB_SMA_NUM_SEND_WQES, sma->cq, - IB_SMA_NUM_RECV_WQES, sma->cq, 0 ); - if ( ! sma->qp ) { - rc = -ENOMEM; - goto err_create_qp; + /* Initialise GMA */ + if ( ( rc = ib_create_gma ( &sma->gma, ibdev, 0 ) ) != 0 ) { + DBGC ( sma, "SMA %p could not create GMA: %s\n", + sma, strerror ( rc ) ); + goto err_create_gma; } - ib_qp_set_ownerdata ( sma->qp, sma ); /* If we don't get QP0, we can't function */ - if ( sma->qp->qpn != IB_QPN_SMA ) { + if ( sma->gma.qp->qpn != IB_QPN_SMA ) { DBGC ( sma, "SMA %p on QPN %lx, needs to be on QPN 0\n", - sma, sma->qp->qpn ); + sma, sma->gma.qp->qpn ); rc = -ENOTSUP; goto err_not_qp0; } - /* Fill receive ring */ - ib_refill_recv ( ibdev, sma->qp ); return 0; err_not_qp0: - ib_destroy_qp ( ibdev, sma->qp ); - err_create_qp: - ib_destroy_cq ( ibdev, sma->cq ); - err_create_cq: + ib_destroy_gma ( &sma->gma ); + err_create_gma: return rc; } @@ -485,8 +314,6 @@ int ib_create_sma ( struct ib_sma *sma, struct ib_device *ibdev, * @v sma Subnet management agent */ void ib_destroy_sma ( struct ib_sma *sma ) { - struct ib_device *ibdev = sma->ibdev; - ib_destroy_qp ( ibdev, sma->qp ); - ib_destroy_cq ( ibdev, sma->cq ); + ib_destroy_gma ( &sma->gma ); } |