Commit acac37f7 authored by Roland Dreier's avatar Roland Dreier Committed by Linus Torvalds

[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: default avatarRoland Dreier <roland@topspin.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b6aff4aa
......@@ -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))
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment