summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/infiniband/linda.c4
-rw-r--r--src/drivers/infiniband/qib7322.c2
-rw-r--r--src/include/ipxe/infiniband.h7
-rw-r--r--src/net/infiniband.c16
-rw-r--r--src/net/infiniband/ib_cm.c2
-rw-r--r--src/net/infiniband/ib_sma.c15
-rw-r--r--src/net/infiniband/ib_smc.c92
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.
*/