summaryrefslogtreecommitdiffstats
path: root/src/drivers/infiniband
diff options
context:
space:
mode:
authorMichael Brown2008-11-12 16:35:45 +0100
committerMichael Brown2008-11-12 16:35:45 +0100
commit1b3edd9e11019240fd989de40defe444634cb094 (patch)
treec8320e8f86d240228cd967415aca256b8ec281d9 /src/drivers/infiniband
parent[romprefix] Use smaller PMM allocations if possible (diff)
downloadipxe-1b3edd9e11019240fd989de40defe444634cb094.tar.gz
ipxe-1b3edd9e11019240fd989de40defe444634cb094.tar.xz
ipxe-1b3edd9e11019240fd989de40defe444634cb094.zip
[infiniband] Respect hop pointer when building directed route SMP return path
The return path in directed route SMPs lists the egress ports in order from SM to node, rather than from node to SM. To write to the correct offset within the return path, we need to parse the hop pointer. This is held within the class-specific data portion of the MAD header, which was previously unused by us and defined to be a uint16_t. Define this field to be a union type; this requires some rearrangement of ib_mad.h and corresponding changes to ipoib.c.
Diffstat (limited to 'src/drivers/infiniband')
-rw-r--r--src/drivers/infiniband/ib_sma.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/drivers/infiniband/ib_sma.c b/src/drivers/infiniband/ib_sma.c
index 7d43f13c7..9426c8f1e 100644
--- a/src/drivers/infiniband/ib_sma.c
+++ b/src/drivers/infiniband/ib_sma.c
@@ -264,6 +264,8 @@ static int ib_sma_mad ( struct ib_sma *sma, union ib_mad *mad ) {
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 "
@@ -336,7 +338,17 @@ static int ib_sma_mad ( struct ib_sma *sma, union ib_mad *mad ) {
/* 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 );
- smp->return_path.hops[0] = ibdev->port;
+ 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",