aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ehca/ehca_av.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_av.c')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_av.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c
index 97d108634c5..453eb995c1d 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