From c2c77377a6025495c2bbdd4fae96ecaa2b4651f1 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 13 Nov 2009 22:34:47 +0000 Subject: [PATCH] [ipoib] Mask out non-QPN bits in the IPoIB destination MAC when sending The first byte of the IPoIB MAC address is used for flags indicating support for "connected mode". Strip out the non-QPN bits of the first dword when constructing the address vector for transmitted IPoIB packets, so as not to end up passing an invalid QPN in the BTH. --- src/drivers/net/ipoib.c | 15 +++++++-------- src/include/gpxe/infiniband.h | 3 +++ src/include/gpxe/ipoib.h | 5 +++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/drivers/net/ipoib.c b/src/drivers/net/ipoib.c index b8338916..4b3741ec 100644 --- a/src/drivers/net/ipoib.c +++ b/src/drivers/net/ipoib.c @@ -71,7 +71,7 @@ struct ipoib_device { /** Broadcast IPoIB address */ static struct ipoib_mac ipoib_broadcast = { - .qpn = htonl ( IB_QPN_BROADCAST ), + .flags__qpn = htonl ( IB_QPN_BROADCAST ), .gid.u.bytes = { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }, }; @@ -146,8 +146,7 @@ static struct ipoib_peer * ipoib_lookup_peer_by_key ( unsigned int key ) { /** * Store GID and QPN in peer cache * - * @v gid Peer GID - * @v qpn Peer QPN + * @v mac Peer MAC address * @ret peer Peer cache entry */ static struct ipoib_peer * ipoib_cache_peer ( const struct ipoib_mac *mac ) { @@ -283,7 +282,7 @@ const char * ipoib_ntoa ( const void *ll_addr ) { const struct ipoib_mac *mac = ll_addr; snprintf ( buf, sizeof ( buf ), "%08x:%08x:%08x:%08x:%08x", - htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ), + htonl ( mac->flags__qpn ), htonl ( mac->gid.u.dwords[0] ), htonl ( mac->gid.u.dwords[1] ), htonl ( mac->gid.u.dwords[2] ), htonl ( mac->gid.u.dwords[3] ) ); @@ -438,7 +437,7 @@ static int ipoib_transmit ( struct net_device *netdev, /* Construct address vector */ memset ( &av, 0, sizeof ( av ) ); - av.qpn = ntohl ( dest->mac.qpn ); + av.qpn = ( ntohl ( dest->mac.flags__qpn ) & IB_QPN_MASK ); av.gid_present = 1; memcpy ( &av.gid, &dest->mac.gid, sizeof ( av.gid ) ); if ( ( rc = ib_resolve_path ( ibdev, &av ) ) != 0 ) { @@ -501,7 +500,7 @@ static void ipoib_complete_recv ( struct ib_device *ibdev __unused, /* Parse source address */ if ( av->gid_present ) { - ll_src.qpn = htonl ( av->qpn ); + ll_src.flags__qpn = htonl ( av->qpn ); memcpy ( &ll_src.gid, &av->gid, sizeof ( ll_src.gid ) ); src = ipoib_cache_peer ( &ll_src ); ipoib_hdr->u.peer.src = src->key; @@ -637,7 +636,7 @@ static int ipoib_open ( struct net_device *netdev ) { ib_qp_set_ownerdata ( ipoib->qp, ipoib ); /* Update MAC address with QPN */ - mac->qpn = htonl ( ipoib->qp->qpn ); + mac->flags__qpn = htonl ( ipoib->qp->qpn ); /* Fill receive rings */ ib_refill_recv ( ibdev, ipoib->qp ); @@ -670,7 +669,7 @@ static void ipoib_close ( struct net_device *netdev ) { ipoib_leave_broadcast_group ( ipoib ); /* Remove QPN from MAC address */ - mac->qpn = 0; + mac->flags__qpn = 0; /* Tear down the queues */ ib_destroy_qp ( ibdev, ipoib->qp ); diff --git a/src/include/gpxe/infiniband.h b/src/include/gpxe/infiniband.h index 70b930de..d90b1c10 100644 --- a/src/include/gpxe/infiniband.h +++ b/src/include/gpxe/infiniband.h @@ -30,6 +30,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** Broadcast QPN */ #define IB_QPN_BROADCAST 0xffffffUL +/** QPN mask */ +#define IB_QPN_MASK 0xffffffUL + /** Default Infiniband partition key */ #define IB_PKEY_DEFAULT 0xffff diff --git a/src/include/gpxe/ipoib.h b/src/include/gpxe/ipoib.h index f8231db0..1d02f792 100644 --- a/src/include/gpxe/ipoib.h +++ b/src/include/gpxe/ipoib.h @@ -17,9 +17,10 @@ FILE_LICENCE ( GPL2_OR_LATER ); struct ipoib_mac { /** Queue pair number * - * MSB must be zero; QPNs are only 24-bit. + * MSB indicates support for IPoIB "connected mode". Lower 24 + * bits are the QPN. */ - uint32_t qpn; + uint32_t flags__qpn; /** Port GID */ struct ib_gid gid; } __attribute__ (( packed ));