diff options
-rw-r--r-- | src/drivers/infiniband/linda.c | 4 | ||||
-rw-r--r-- | src/drivers/infiniband/qib7322.c | 2 | ||||
-rw-r--r-- | src/include/ipxe/infiniband.h | 7 | ||||
-rw-r--r-- | src/net/infiniband.c | 16 | ||||
-rw-r--r-- | src/net/infiniband/ib_cm.c | 2 | ||||
-rw-r--r-- | src/net/infiniband/ib_sma.c | 15 | ||||
-rw-r--r-- | src/net/infiniband/ib_smc.c | 92 |
7 files changed, 90 insertions, 48 deletions
diff --git a/src/drivers/infiniband/linda.c b/src/drivers/infiniband/linda.c index 12a09a04..f3987d6e 100644 --- a/src/drivers/infiniband/linda.c +++ b/src/drivers/infiniband/linda.c @@ -2364,8 +2364,10 @@ static int linda_probe ( struct pci_device *pci, goto err_init_i2c; /* Read EEPROM parameters */ - if ( ( rc = linda_read_eeprom ( linda, &ibdev->gid.s.guid ) ) != 0 ) + if ( ( rc = linda_read_eeprom ( linda, &ibdev->node_guid ) ) != 0 ) goto err_read_eeprom; + memcpy ( &ibdev->gid.s.guid, &ibdev->node_guid, + sizeof ( ibdev->gid.s.guid ) ); /* Initialise send datapath */ if ( ( rc = linda_init_send ( linda ) ) != 0 ) diff --git a/src/drivers/infiniband/qib7322.c b/src/drivers/infiniband/qib7322.c index b1902cfa..e8c63a1f 100644 --- a/src/drivers/infiniband/qib7322.c +++ b/src/drivers/infiniband/qib7322.c @@ -2357,6 +2357,8 @@ static int qib7322_probe ( struct pci_device *pci, IB_LINK_WIDTH_4X; /* 1x does not work */ ibdev->link_speed_enabled = ibdev->link_speed_supported = IB_LINK_SPEED_SDR; /* to avoid need for link tuning */ + memcpy ( &ibdev->node_guid, &qib7322->guid, + sizeof ( ibdev->node_guid ) ); memcpy ( &ibdev->gid.s.guid, &qib7322->guid, sizeof ( ibdev->gid.s.guid ) ); assert ( ( ibdev->gid.s.guid.bytes[7] & i ) == 0 ); diff --git a/src/include/ipxe/infiniband.h b/src/include/ipxe/infiniband.h index aa67dd4a..fc04dc87 100644 --- a/src/include/ipxe/infiniband.h +++ b/src/include/ipxe/infiniband.h @@ -404,7 +404,9 @@ struct ib_device { uint8_t link_speed_enabled; /** Link speed active */ uint8_t link_speed_active; - /** Port GID */ + /** Node GUID */ + union ib_guid node_guid; + /** Port GID (comprising GID prefix and port GUID) */ union ib_gid gid; /** Port LID */ uint16_t lid; @@ -503,8 +505,7 @@ extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp, union ib_gid *gid ); extern void ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp, union ib_gid *gid ); -extern int ib_get_hca_info ( struct ib_device *ibdev, - union ib_guid *hca_guid ); +extern int ib_count_ports ( struct ib_device *ibdev ); extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad ); extern int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad ); extern struct ib_device * alloc_ibdev ( size_t priv_size ); diff --git a/src/net/infiniband.c b/src/net/infiniband.c index d7cbf697..72dd4855 100644 --- a/src/net/infiniband.c +++ b/src/net/infiniband.c @@ -761,27 +761,21 @@ void ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp, */ /** - * Get Infiniband HCA information + * Count Infiniband HCA ports * * @v ibdev Infiniband device - * @ret hca_guid HCA GUID * @ret num_ports Number of ports */ -int ib_get_hca_info ( struct ib_device *ibdev, union ib_guid *hca_guid ) { +int ib_count_ports ( struct ib_device *ibdev ) { struct ib_device *tmp; int num_ports = 0; /* Search for IB devices with the same physical device to - * identify port count and a suitable Node GUID. + * identify port count. */ for_each_ibdev ( tmp ) { - if ( tmp->dev != ibdev->dev ) - continue; - if ( num_ports == 0 ) { - memcpy ( hca_guid, &tmp->gid.s.guid, - sizeof ( *hca_guid ) ); - } - num_ports++; + if ( tmp->dev == ibdev->dev ) + num_ports++; } return num_ports; } diff --git a/src/net/infiniband/ib_cm.c b/src/net/infiniband/ib_cm.c index bbba5727..1a0646be 100644 --- a/src/net/infiniband/ib_cm.c +++ b/src/net/infiniband/ib_cm.c @@ -364,7 +364,7 @@ static void ib_cm_path_complete ( struct ib_device *ibdev, req->local_id = htonl ( conn->local_id ); memcpy ( &req->service_id, &conn->service_id, sizeof ( req->service_id ) ); - ib_get_hca_info ( ibdev, &req->local_ca ); + memcpy ( &req->local_ca, &ibdev->node_guid, sizeof ( req->local_ca ) ); req->local_qpn__responder_resources = htonl ( ( qp->qpn << 8 ) | 1 ); req->local_eecn__initiator_depth = htonl ( ( 0 << 8 ) | 1 ); req->remote_eecn__remote_timeout__service_type__ee_flow_ctrl = diff --git a/src/net/infiniband/ib_sma.c b/src/net/infiniband/ib_sma.c index 45a1e446..1f3c6d80 100644 --- a/src/net/infiniband/ib_sma.c +++ b/src/net/infiniband/ib_sma.c @@ -58,8 +58,10 @@ static void ib_sma_node_info ( struct ib_device *ibdev, node_info->base_version = IB_MGMT_BASE_VERSION; node_info->class_version = IB_SMP_CLASS_VERSION; node_info->node_type = IB_NODE_TYPE_HCA; - node_info->num_ports = ib_get_hca_info ( ibdev, &node_info->sys_guid ); - memcpy ( &node_info->node_guid, &node_info->sys_guid, + node_info->num_ports = ib_count_ports ( ibdev ); + memcpy ( &node_info->sys_guid, &ibdev->node_guid, + sizeof ( node_info->sys_guid ) ); + memcpy ( &node_info->node_guid, &ibdev->node_guid, sizeof ( node_info->node_guid ) ); memcpy ( &node_info->port_guid, &ibdev->gid.s.guid, sizeof ( node_info->port_guid ) ); @@ -88,22 +90,21 @@ static void ib_sma_node_desc ( struct ib_device *ibdev, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_node_desc *node_desc = &mad->smp.smp_data.node_desc; - union ib_guid guid; + union ib_guid *guid = &ibdev->node_guid; char hostname[ sizeof ( node_desc->node_string ) ]; int hostname_len; int rc; /* Fill in information */ memset ( node_desc, 0, sizeof ( *node_desc ) ); - ib_get_hca_info ( ibdev, &guid ); hostname_len = fetch_string_setting ( NULL, &hostname_setting, hostname, sizeof ( hostname ) ); snprintf ( node_desc->node_string, sizeof ( node_desc->node_string ), "iPXE %s%s%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (%s)", hostname, ( ( hostname_len >= 0 ) ? " " : "" ), - 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 ); + 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 ); /* Send GetResponse */ mad->hdr.method = IB_MGMT_METHOD_GET_RESP; diff --git a/src/net/infiniband/ib_smc.c b/src/net/infiniband/ib_smc.c index 2e0535ab..8196cb7e 100644 --- a/src/net/infiniband/ib_smc.c +++ b/src/net/infiniband/ib_smc.c @@ -35,16 +35,18 @@ FILE_LICENCE ( GPL2_OR_LATER ); */ /** - * Get port information + * Issue local MAD * * @v ibdev Infiniband device + * @v attr_id Attribute ID, in network byte order + * @v attr_mod Attribute modifier, in network byte order * @v local_mad Method for issuing local MADs * @v mad Management datagram to fill in * @ret rc Return status code */ -static int ib_smc_get_port_info ( struct ib_device *ibdev, - ib_local_mad_t local_mad, - union ib_mad *mad ) { +static int ib_smc_mad ( struct ib_device *ibdev, uint16_t attr_id, + uint32_t attr_mod, ib_local_mad_t local_mad, + union ib_mad *mad ) { int rc; /* Construct MAD */ @@ -53,10 +55,55 @@ static int ib_smc_get_port_info ( struct ib_device *ibdev, mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; mad->hdr.class_version = 1; mad->hdr.method = IB_MGMT_METHOD_GET; - mad->hdr.attr_id = htons ( IB_SMP_ATTR_PORT_INFO ); - mad->hdr.attr_mod = htonl ( ibdev->port ); + mad->hdr.attr_id = attr_id; + mad->hdr.attr_mod = attr_mod; + + /* Issue MAD */ + if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) + return rc; + + return 0; +} + +/** + * Get node information + * + * @v ibdev Infiniband device + * @v local_mad Method for issuing local MADs + * @v mad Management datagram to fill in + * @ret rc Return status code + */ +static int ib_smc_get_node_info ( struct ib_device *ibdev, + ib_local_mad_t local_mad, + union ib_mad *mad ) { + int rc; + + /* Issue MAD */ + if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_NODE_INFO ), 0, + local_mad, mad ) ) != 0 ) { + DBGC ( ibdev, "IBDEV %p could not get node info: %s\n", + ibdev, strerror ( rc ) ); + return rc; + } + return 0; +} - if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) { +/** + * Get port information + * + * @v ibdev Infiniband device + * @v local_mad Method for issuing local MADs + * @v mad Management datagram to fill in + * @ret rc Return status code + */ +static int ib_smc_get_port_info ( struct ib_device *ibdev, + ib_local_mad_t local_mad, + union ib_mad *mad ) { + int rc; + + /* Issue MAD */ + if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PORT_INFO ), + htonl ( ibdev->port ), local_mad, mad )) !=0){ DBGC ( ibdev, "IBDEV %p could not get port info: %s\n", ibdev, strerror ( rc ) ); return rc; @@ -77,15 +124,9 @@ static int ib_smc_get_guid_info ( struct ib_device *ibdev, union ib_mad *mad ) { int rc; - /* Construct MAD */ - memset ( mad, 0, sizeof ( *mad ) ); - mad->hdr.base_version = IB_MGMT_BASE_VERSION; - mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; - mad->hdr.class_version = 1; - mad->hdr.method = IB_MGMT_METHOD_GET; - mad->hdr.attr_id = htons ( IB_SMP_ATTR_GUID_INFO ); - - if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) { + /* Issue MAD */ + if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_GUID_INFO ), 0, + local_mad, mad ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not get GUID info: %s\n", ibdev, strerror ( rc ) ); return rc; @@ -106,15 +147,9 @@ static int ib_smc_get_pkey_table ( struct ib_device *ibdev, union ib_mad *mad ) { int rc; - /* Construct MAD */ - memset ( mad, 0, sizeof ( *mad ) ); - mad->hdr.base_version = IB_MGMT_BASE_VERSION; - mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; - mad->hdr.class_version = 1; - mad->hdr.method = IB_MGMT_METHOD_GET; - mad->hdr.attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ); - - if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) { + /* Issue MAD */ + if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PKEY_TABLE ), 0, + local_mad, mad ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not get pkey table: %s\n", ibdev, strerror ( rc ) ); return rc; @@ -131,11 +166,18 @@ static int ib_smc_get_pkey_table ( struct ib_device *ibdev, */ static int ib_smc_get ( struct ib_device *ibdev, ib_local_mad_t local_mad ) { union ib_mad mad; + struct ib_node_info *node_info = &mad.smp.smp_data.node_info; struct ib_port_info *port_info = &mad.smp.smp_data.port_info; struct ib_guid_info *guid_info = &mad.smp.smp_data.guid_info; struct ib_pkey_table *pkey_table = &mad.smp.smp_data.pkey_table; int rc; + /* Node info gives us the node GUID */ + if ( ( rc = ib_smc_get_node_info ( ibdev, local_mad, &mad ) ) != 0 ) + return rc; + memcpy ( &ibdev->node_guid, &node_info->node_guid, + sizeof ( ibdev->node_guid ) ); + /* Port info gives us the link state, the first half of the * port GID and the SM LID. */ |