[ipoib] Mask out non-QPN bits in the IPoIB destination MAC when sending
authorMichael Brown <mcb30@etherboot.org>
Fri, 13 Nov 2009 22:34:47 +0000 (22:34 +0000)
committerMichael Brown <mcb30@etherboot.org>
Mon, 16 Nov 2009 22:15:29 +0000 (22:15 +0000)
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
src/include/gpxe/infiniband.h
src/include/gpxe/ipoib.h

index b833891..4b3741e 100644 (file)
@@ -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 );
index 70b930d..d90b1c1 100644 (file)
@@ -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
 
index f8231db..1d02f79 100644 (file)
@@ -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 ));