[openib-general] [PATCH][1/18] InfiniBand/IPoIB: use correct static rate in IpoIB

Roland Dreier roland at topspin.com
Wed Jan 12 13:46:22 PST 2005


Calculate static rate for IPoIB address handles based on local
width/speed and path rate.

Signed-off-by: Roland Dreier <roland at topspin.com>

--- linux/drivers/infiniband/include/ib_sa.h	(revision 1409)
+++ linux/drivers/infiniband/include/ib_sa.h	(revision 1410)
@@ -59,6 +59,34 @@
 	IB_SA_BEST = 3
 };
 
+enum ib_sa_rate {
+	IB_SA_RATE_2_5_GBPS = 2,
+	IB_SA_RATE_5_GBPS   = 5,
+	IB_SA_RATE_10_GBPS  = 3,
+	IB_SA_RATE_20_GBPS  = 6,
+	IB_SA_RATE_30_GBPS  = 4,
+	IB_SA_RATE_40_GBPS  = 7,
+	IB_SA_RATE_60_GBPS  = 8,
+	IB_SA_RATE_80_GBPS  = 9,
+	IB_SA_RATE_120_GBPS = 10
+};
+
+static inline int ib_sa_rate_enum_to_int(enum ib_sa_rate rate)
+{
+	switch (rate) {
+	case IB_SA_RATE_2_5_GBPS: return  1;
+	case IB_SA_RATE_5_GBPS:   return  2;
+	case IB_SA_RATE_10_GBPS:  return  4;
+	case IB_SA_RATE_20_GBPS:  return  8;
+	case IB_SA_RATE_30_GBPS:  return 12;
+	case IB_SA_RATE_40_GBPS:  return 16;
+	case IB_SA_RATE_60_GBPS:  return 24;
+	case IB_SA_RATE_80_GBPS:  return 32;
+	case IB_SA_RATE_120_GBPS: return 48;
+	default: 	          return -1;
+	}
+}
+
 typedef u64 __bitwise ib_sa_comp_mask;
 
 #define IB_SA_COMP_MASK(n)	((__force ib_sa_comp_mask) cpu_to_be64(1ull << n))
--- linux/drivers/infiniband/ulp/ipoib/ipoib_main.c	(revision 1410)
+++ linux/drivers/infiniband/ulp/ipoib/ipoib_main.c	(revision 1411)
@@ -283,21 +283,21 @@
 	skb_queue_head_init(&skqueue);
 
 	if (!status) {
-		/*
-		 * For now we set static_rate to 0.  This is not
-		 * really correct: we should look at the rate
-		 * component of the path member record, compare it
-		 * with the rate of our local port (calculated from
-		 * the active link speed and link width) and set an
-		 * inter-packet delay appropriately.
-		 */
 		struct ib_ah_attr av = {
 			.dlid 	       = be16_to_cpu(pathrec->dlid),
 			.sl 	       = pathrec->sl,
-			.static_rate   = 0,
 			.port_num      = priv->port
 		};
 
+		if (ib_sa_rate_enum_to_int(pathrec->rate) > 0)
+			av.static_rate = (2 * priv->local_rate -
+					  ib_sa_rate_enum_to_int(pathrec->rate) - 1) /
+				(priv->local_rate ? priv->local_rate : 1);
+
+		ipoib_dbg(priv, "static_rate %d for local port %dX, path %dX\n",
+			  av.static_rate, priv->local_rate,
+			  ib_sa_rate_enum_to_int(pathrec->rate));
+
 		ah = ipoib_create_ah(dev, priv->pd, &av);
 	}
 
--- linux/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	(revision 1410)
+++ linux/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	(revision 1411)
@@ -238,19 +238,10 @@
 	}
 
 	{
-		/*
-		 * For now we set static_rate to 0.  This is not
-		 * really correct: we should look at the rate
-		 * component of the MC member record, compare it with
-		 * the rate of our local port (calculated from the
-		 * active link speed and link width) and set an
-		 * inter-packet delay appropriately.
-		 */
 		struct ib_ah_attr av = {
 			.dlid	       = be16_to_cpu(mcast->mcmember.mlid),
 			.port_num      = priv->port,
 			.sl	       = mcast->mcmember.sl,
-			.static_rate   = 0,
 			.ah_flags      = IB_AH_GRH,
 			.grh	       = {
 				.flow_label    = be32_to_cpu(mcast->mcmember.flow_label),
@@ -262,6 +253,15 @@
 
 		av.grh.dgid = mcast->mcmember.mgid;
 
+		if (ib_sa_rate_enum_to_int(mcast->mcmember.rate) > 0)
+			av.static_rate = (2 * priv->local_rate -
+					  ib_sa_rate_enum_to_int(mcast->mcmember.rate) - 1) /
+				(priv->local_rate ? priv->local_rate : 1);
+
+		ipoib_dbg_mcast(priv, "static_rate %d for local port %dX, mcmember %dX\n",
+				av.static_rate, priv->local_rate,
+				ib_sa_rate_enum_to_int(mcast->mcmember.rate));
+
 		mcast->ah = ipoib_create_ah(dev, priv->pd, &av);
 		if (!mcast->ah) {
 			ipoib_warn(priv, "ib_address_create failed\n");
@@ -506,6 +506,17 @@
 	else
 		memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid));
 
+	{
+		struct ib_port_attr attr;
+
+		if (!ib_query_port(priv->ca, priv->port, &attr)) {
+			priv->local_lid  = attr.lid;
+			priv->local_rate = attr.active_speed *
+				ib_width_enum_to_int(attr.active_width);
+		} else
+			ipoib_warn(priv, "ib_query_port failed\n");
+	}
+
 	if (!priv->broadcast) {
 		priv->broadcast = ipoib_mcast_alloc(dev, 1);
 		if (!priv->broadcast) {
@@ -554,15 +565,6 @@
 		return;
 	}
 
-	{
-		struct ib_port_attr attr;
-
-		if (!ib_query_port(priv->ca, priv->port, &attr))
-			priv->local_lid = attr.lid;
-		else
-			ipoib_warn(priv, "ib_query_port failed\n");
-	}
-
 	priv->mcast_mtu = ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu) -
 		IPOIB_ENCAP_LEN;
 	dev->mtu = min(priv->mcast_mtu, priv->admin_mtu);
--- linux/drivers/infiniband/ulp/ipoib/ipoib.h	(revision 1410)
+++ linux/drivers/infiniband/ulp/ipoib/ipoib.h	(revision 1411)
@@ -143,6 +143,7 @@
 
 	union ib_gid local_gid;
 	u16          local_lid;
+	u8           local_rate;
 
 	unsigned int admin_mtu;
 	unsigned int mcast_mtu;




More information about the general mailing list