aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJoachim Fenkes <fenkes@de.ibm.com>2007-11-02 09:41:49 -0400
committerRoland Dreier <rolandd@cisco.com>2007-11-13 18:27:00 -0500
commit51aaa54eb9e9f01878aa5d62277fd156e458dfe1 (patch)
tree135d4f2f8ae6543f034e9607ae58fa05b8944451 /drivers
parent40ebb5615e2e069d3b8936b894ceff436c914003 (diff)
IB/ehca: Fix static rate calculation
The IPD (inter-packet delay) formula was a little off and assumed a fixed physical link rate; fix the formula and query the actual physical link rate, now that we can get it. Also, refactor the calculation into a common function ehca_calc_ipd() and use that instead of duplicating code. Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_av.c48
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_iverbs.h3
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c3
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c29
5 files changed, 54 insertions, 30 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c
index 97d108634c58..453eb995c1d4 100644
--- a/drivers/infiniband/hw/ehca/ehca_av.c
+++ b/drivers/infiniband/hw/ehca/ehca_av.c
@@ -50,6 +50,38 @@
50 50
51static struct kmem_cache *av_cache; 51static struct kmem_cache *av_cache;
52 52
53int ehca_calc_ipd(struct ehca_shca *shca, int port,
54 enum ib_rate path_rate, u32 *ipd)
55{
56 int path = ib_rate_to_mult(path_rate);
57 int link, ret;
58 struct ib_port_attr pa;
59
60 if (path_rate == IB_RATE_PORT_CURRENT) {
61 *ipd = 0;
62 return 0;
63 }
64
65 if (unlikely(path < 0)) {
66 ehca_err(&shca->ib_device, "Invalid static rate! path_rate=%x",
67 path_rate);
68 return -EINVAL;
69 }
70
71 ret = ehca_query_port(&shca->ib_device, port, &pa);
72 if (unlikely(ret < 0)) {
73 ehca_err(&shca->ib_device, "Failed to query port ret=%i", ret);
74 return ret;
75 }
76
77 link = ib_width_enum_to_int(pa.active_width) * pa.active_speed;
78
79 /* IPD = round((link / path) - 1) */
80 *ipd = ((link + (path >> 1)) / path) - 1;
81
82 return 0;
83}
84
53struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) 85struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
54{ 86{
55 int ret; 87 int ret;
@@ -69,15 +101,13 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
69 av->av.slid_path_bits = ah_attr->src_path_bits; 101 av->av.slid_path_bits = ah_attr->src_path_bits;
70 102
71 if (ehca_static_rate < 0) { 103 if (ehca_static_rate < 0) {
72 int ah_mult = ib_rate_to_mult(ah_attr->static_rate); 104 u32 ipd;
73 int ehca_mult = 105 if (ehca_calc_ipd(shca, ah_attr->port_num,
74 ib_rate_to_mult(shca->sport[ah_attr->port_num].rate ); 106 ah_attr->static_rate, &ipd)) {
75 107 ret = -EINVAL;
76 if (ah_mult >= ehca_mult) 108 goto create_ah_exit1;
77 av->av.ipd = 0; 109 }
78 else 110 av->av.ipd = ipd;
79 av->av.ipd = (ah_mult > 0) ?
80 ((ehca_mult - 1) / ah_mult) : 0;
81 } else 111 } else
82 av->av.ipd = ehca_static_rate; 112 av->av.ipd = ehca_static_rate;
83 113
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 2d660ae189e5..87f12d4312a7 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -95,7 +95,6 @@ struct ehca_sma_attr {
95struct ehca_sport { 95struct ehca_sport {
96 struct ib_cq *ibcq_aqp1; 96 struct ib_cq *ibcq_aqp1;
97 struct ib_qp *ibqp_aqp1; 97 struct ib_qp *ibqp_aqp1;
98 enum ib_rate rate;
99 enum ib_port_state port_state; 98 enum ib_port_state port_state;
100 struct ehca_sma_attr saved_attr; 99 struct ehca_sma_attr saved_attr;
101}; 100};
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index dce503bb7d6b..5485799cdc8d 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -189,6 +189,9 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
189 189
190void ehca_poll_eqs(unsigned long data); 190void ehca_poll_eqs(unsigned long data);
191 191
192int ehca_calc_ipd(struct ehca_shca *shca, int port,
193 enum ib_rate path_rate, u32 *ipd);
194
192#ifdef CONFIG_PPC_64K_PAGES 195#ifdef CONFIG_PPC_64K_PAGES
193void *ehca_alloc_fw_ctrlblock(gfp_t flags); 196void *ehca_alloc_fw_ctrlblock(gfp_t flags);
194void ehca_free_fw_ctrlblock(void *ptr); 197void ehca_free_fw_ctrlblock(void *ptr);
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index c6cd38c5321f..90d4334179bf 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -327,9 +327,6 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
327 shca->hw_level = ehca_hw_level; 327 shca->hw_level = ehca_hw_level;
328 ehca_gen_dbg(" ... hardware level=%x", shca->hw_level); 328 ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
329 329
330 shca->sport[0].rate = IB_RATE_30_GBPS;
331 shca->sport[1].rate = IB_RATE_30_GBPS;
332
333 shca->hca_cap = rblock->hca_cap_indicators; 330 shca->hca_cap = rblock->hca_cap_indicators;
334 ehca_gen_dbg(" ... HCA capabilities:"); 331 ehca_gen_dbg(" ... HCA capabilities:");
335 for (i = 0; i < ARRAY_SIZE(hca_cap_descr); i++) 332 for (i = 0; i < ARRAY_SIZE(hca_cap_descr); i++)
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index de182648b282..2e3e6547cb78 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -1196,10 +1196,6 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1196 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_QKEY, 1); 1196 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_QKEY, 1);
1197 } 1197 }
1198 if (attr_mask & IB_QP_AV) { 1198 if (attr_mask & IB_QP_AV) {
1199 int ah_mult = ib_rate_to_mult(attr->ah_attr.static_rate);
1200 int ehca_mult = ib_rate_to_mult(shca->sport[my_qp->
1201 init_attr.port_num].rate);
1202
1203 mqpcb->dlid = attr->ah_attr.dlid; 1199 mqpcb->dlid = attr->ah_attr.dlid;
1204 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_DLID, 1); 1200 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_DLID, 1);
1205 mqpcb->source_path_bits = attr->ah_attr.src_path_bits; 1201 mqpcb->source_path_bits = attr->ah_attr.src_path_bits;
@@ -1207,11 +1203,12 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1207 mqpcb->service_level = attr->ah_attr.sl; 1203 mqpcb->service_level = attr->ah_attr.sl;
1208 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SERVICE_LEVEL, 1); 1204 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SERVICE_LEVEL, 1);
1209 1205
1210 if (ah_mult < ehca_mult) 1206 if (ehca_calc_ipd(shca, my_qp->init_attr.port_num,
1211 mqpcb->max_static_rate = (ah_mult > 0) ? 1207 attr->ah_attr.static_rate,
1212 ((ehca_mult - 1) / ah_mult) : 0; 1208 &mqpcb->max_static_rate)) {
1213 else 1209 ret = -EINVAL;
1214 mqpcb->max_static_rate = 0; 1210 goto modify_qp_exit2;
1211 }
1215 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE, 1); 1212 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE, 1);
1216 1213
1217 /* 1214 /*
@@ -1280,10 +1277,6 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1280 (MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP, 1); 1277 (MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP, 1);
1281 } 1278 }
1282 if (attr_mask & IB_QP_ALT_PATH) { 1279 if (attr_mask & IB_QP_ALT_PATH) {
1283 int ah_mult = ib_rate_to_mult(attr->alt_ah_attr.static_rate);
1284 int ehca_mult = ib_rate_to_mult(
1285 shca->sport[my_qp->init_attr.port_num].rate);
1286
1287 if (attr->alt_port_num < 1 1280 if (attr->alt_port_num < 1
1288 || attr->alt_port_num > shca->num_ports) { 1281 || attr->alt_port_num > shca->num_ports) {
1289 ret = -EINVAL; 1282 ret = -EINVAL;
@@ -1309,10 +1302,12 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1309 mqpcb->source_path_bits_al = attr->alt_ah_attr.src_path_bits; 1302 mqpcb->source_path_bits_al = attr->alt_ah_attr.src_path_bits;
1310 mqpcb->service_level_al = attr->alt_ah_attr.sl; 1303 mqpcb->service_level_al = attr->alt_ah_attr.sl;
1311 1304
1312 if (ah_mult > 0 && ah_mult < ehca_mult) 1305 if (ehca_calc_ipd(shca, my_qp->init_attr.port_num,
1313 mqpcb->max_static_rate_al = (ehca_mult - 1) / ah_mult; 1306 attr->alt_ah_attr.static_rate,
1314 else 1307 &mqpcb->max_static_rate_al)) {
1315 mqpcb->max_static_rate_al = 0; 1308 ret = -EINVAL;
1309 goto modify_qp_exit2;
1310 }
1316 1311
1317 /* OpenIB doesn't support alternate retry counts - copy them */ 1312 /* OpenIB doesn't support alternate retry counts - copy them */
1318 mqpcb->retry_count_al = mqpcb->retry_count; 1313 mqpcb->retry_count_al = mqpcb->retry_count;