aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Bohrer <sbohrer@rgmadvisors.com>2012-02-24 10:32:30 -0600
committerRoland Dreier <roland@purestorage.com>2012-03-26 15:09:35 -0700
commitd9c111c54463da3e711ca9dd19c0080cbcd66789 (patch)
treec30040e27365bc000181e2f86c8a584449580ed3
parent0c429092fe0bdc14d8ca051a3f6b0895b11a1db0 (diff)
downloadlibmlx4-d9c111c54463da3e711ca9dd19c0080cbcd66789.tar.gz
Add IBoE multicast support
Add multicast support for IBoE to the address handle creation flow. Derived from work by Eli Cohen <eli@mellanox.co.il> Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--src/verbs.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/src/verbs.c b/src/verbs.c
index 18ec4f1..408fc6d 100644
--- a/src/verbs.c
+++ b/src/verbs.c
@@ -632,6 +632,11 @@ static int link_local_gid(const union ibv_gid *gid)
return 0;
}
+static int is_multicast_gid(const union ibv_gid *gid)
+{
+ return gid->raw[0] == 0xff;
+}
+
static uint16_t get_vlan_id(union ibv_gid *gid)
{
uint16_t vid;
@@ -639,9 +644,12 @@ static uint16_t get_vlan_id(union ibv_gid *gid)
return vid < 0x1000 ? vid : 0xffff;
}
-static int mlx4_resolve_grh_to_l2(struct mlx4_ah *ah, struct ibv_ah_attr *attr)
+static int mlx4_resolve_grh_to_l2(struct ibv_pd *pd, struct mlx4_ah *ah,
+ struct ibv_ah_attr *attr)
{
+ int err, i;
uint16_t vid;
+ union ibv_gid sgid;
if (link_local_gid(&attr->grh.dgid)) {
memcpy(ah->mac, &attr->grh.dgid.raw[8], 3);
@@ -649,13 +657,30 @@ static int mlx4_resolve_grh_to_l2(struct mlx4_ah *ah, struct ibv_ah_attr *attr)
ah->mac[0] ^= 2;
vid = get_vlan_id(&attr->grh.dgid);
- if (vid != 0xffff) {
- ah->av.port_pd |= htonl(1 << 29);
- ah->vlan = vid | ((attr->sl & 7) << 13);
- }
- return 0;
+ } else if (is_multicast_gid(&attr->grh.dgid)) {
+ ah->mac[0] = 0x33;
+ ah->mac[1] = 0x33;
+ for (i = 2; i < 6; ++i)
+ ah->mac[i] = attr->grh.dgid.raw[i + 10];
+
+ err = ibv_query_gid(pd->context, attr->port_num,
+ attr->grh.sgid_index, &sgid);
+ if (err)
+ return err;
+
+ ah->av.dlid = htons(0xc000);
+ ah->av.port_pd |= htonl(1 << 31);
+
+ vid = get_vlan_id(&sgid);
} else
return 1;
+
+ if (vid != 0xffff) {
+ ah->av.port_pd |= htonl(1 << 29);
+ ah->vlan = vid | ((attr->sl & 7) << 13);
+ }
+
+ return 0;
}
struct ibv_ah *mlx4_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
@@ -696,7 +721,7 @@ struct ibv_ah *mlx4_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
}
if (port_attr.link_layer == IBV_LINK_LAYER_ETHERNET)
- if (mlx4_resolve_grh_to_l2(ah, attr)) {
+ if (mlx4_resolve_grh_to_l2(pd, ah, attr)) {
free(ah);
return NULL;
}