aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRoland Dreier <roland@topspin.com>2005-01-14 23:15:55 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-14 23:15:55 -0800
commitacac37f70b0d08812b830b2818a906ec483a5b95 (patch)
treef9a23394718985a19e1f00c92e60b40bacac9e6c /drivers
parentb6aff4aa539a7be12c970cd8b52767a60572bfd5 (diff)
downloadhistory-acac37f70b0d08812b830b2818a906ec483a5b95.tar.gz
[PATCH] InfiniBand/IPoIB: use correct static rate in IpoIB
Calculate static rate for IPoIB address handles based on local width/speed and path rate. Signed-off-by: Roland Dreier <roland@topspin.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/include/ib_sa.h28
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c18
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c38
4 files changed, 58 insertions, 27 deletions
diff --git a/drivers/infiniband/include/ib_sa.h b/drivers/infiniband/include/ib_sa.h
index 5f6a9fc99e8268..f4f747707b30d4 100644
--- a/drivers/infiniband/include/ib_sa.h
+++ b/drivers/infiniband/include/ib_sa.h
@@ -59,6 +59,34 @@ enum ib_sa_selector {
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))
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index a1db3d17752902..cef1a40b08024c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -143,6 +143,7 @@ struct ipoib_dev_priv {
union ib_gid local_gid;
u16 local_lid;
+ u8 local_rate;
unsigned int admin_mtu;
unsigned int mcast_mtu;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index d225f457697b31..1551463270673b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -283,21 +283,21 @@ static void path_rec_completion(int status,
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);
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 804c5ba6f810c1..2dd8342441df10 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -238,19 +238,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
}
{
- /*
- * 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 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
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 @@ void ipoib_mcast_join_task(void *dev_ptr)
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 @@ void ipoib_mcast_join_task(void *dev_ptr)
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);