aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ehca
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ehca')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c8
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c6
-rw-r--r--drivers/infiniband/hw/ehca/ehca_sqp.c47
3 files changed, 50 insertions, 11 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index fab18a2c74a8..5b635aa5947e 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -52,7 +52,7 @@
52#include "ehca_tools.h" 52#include "ehca_tools.h"
53#include "hcp_if.h" 53#include "hcp_if.h"
54 54
55#define HCAD_VERSION "0028" 55#define HCAD_VERSION "0029"
56 56
57MODULE_LICENSE("Dual BSD/GPL"); 57MODULE_LICENSE("Dual BSD/GPL");
58MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); 58MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
@@ -64,7 +64,7 @@ static int ehca_hw_level = 0;
64static int ehca_poll_all_eqs = 1; 64static int ehca_poll_all_eqs = 1;
65 65
66int ehca_debug_level = 0; 66int ehca_debug_level = 0;
67int ehca_nr_ports = 2; 67int ehca_nr_ports = -1;
68int ehca_use_hp_mr = 0; 68int ehca_use_hp_mr = 0;
69int ehca_port_act_time = 30; 69int ehca_port_act_time = 30;
70int ehca_static_rate = -1; 70int ehca_static_rate = -1;
@@ -95,8 +95,8 @@ MODULE_PARM_DESC(hw_level,
95 "Hardware level (0: autosensing (default), " 95 "Hardware level (0: autosensing (default), "
96 "0x10..0x14: eHCA, 0x20..0x23: eHCA2)"); 96 "0x10..0x14: eHCA, 0x20..0x23: eHCA2)");
97MODULE_PARM_DESC(nr_ports, 97MODULE_PARM_DESC(nr_ports,
98 "number of connected ports (-1: autodetect, 1: port one only, " 98 "number of connected ports (-1: autodetect (default), "
99 "2: two ports (default)"); 99 "1: port one only, 2: two ports)");
100MODULE_PARM_DESC(use_hp_mr, 100MODULE_PARM_DESC(use_hp_mr,
101 "Use high performance MRs (default: no)"); 101 "Use high performance MRs (default: no)");
102MODULE_PARM_DESC(port_act_time, 102MODULE_PARM_DESC(port_act_time,
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index 5a3d96f84c79..8fd88cd828fd 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -786,7 +786,11 @@ repoll:
786 wc->slid = cqe->rlid; 786 wc->slid = cqe->rlid;
787 wc->dlid_path_bits = cqe->dlid; 787 wc->dlid_path_bits = cqe->dlid;
788 wc->src_qp = cqe->remote_qp_number; 788 wc->src_qp = cqe->remote_qp_number;
789 wc->wc_flags = cqe->w_completion_flags; 789 /*
790 * HW has "Immed data present" and "GRH present" in bits 6 and 5.
791 * SW defines those in bits 1 and 0, so we can just shift and mask.
792 */
793 wc->wc_flags = (cqe->w_completion_flags >> 5) & 3;
790 wc->ex.imm_data = cpu_to_be32(cqe->immediate_data); 794 wc->ex.imm_data = cpu_to_be32(cqe->immediate_data);
791 wc->sl = cqe->service_level; 795 wc->sl = cqe->service_level;
792 796
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c
index c568b28f4e20..8c1213f8916a 100644
--- a/drivers/infiniband/hw/ehca/ehca_sqp.c
+++ b/drivers/infiniband/hw/ehca/ehca_sqp.c
@@ -125,14 +125,30 @@ struct ib_perf {
125 u8 data[192]; 125 u8 data[192];
126} __attribute__ ((packed)); 126} __attribute__ ((packed));
127 127
128/* TC/SL/FL packed into 32 bits, as in ClassPortInfo */
129struct tcslfl {
130 u32 tc:8;
131 u32 sl:4;
132 u32 fl:20;
133} __attribute__ ((packed));
134
135/* IP Version/TC/FL packed into 32 bits, as in GRH */
136struct vertcfl {
137 u32 ver:4;
138 u32 tc:8;
139 u32 fl:20;
140} __attribute__ ((packed));
128 141
129static int ehca_process_perf(struct ib_device *ibdev, u8 port_num, 142static int ehca_process_perf(struct ib_device *ibdev, u8 port_num,
143 struct ib_wc *in_wc, struct ib_grh *in_grh,
130 struct ib_mad *in_mad, struct ib_mad *out_mad) 144 struct ib_mad *in_mad, struct ib_mad *out_mad)
131{ 145{
132 struct ib_perf *in_perf = (struct ib_perf *)in_mad; 146 struct ib_perf *in_perf = (struct ib_perf *)in_mad;
133 struct ib_perf *out_perf = (struct ib_perf *)out_mad; 147 struct ib_perf *out_perf = (struct ib_perf *)out_mad;
134 struct ib_class_port_info *poi = 148 struct ib_class_port_info *poi =
135 (struct ib_class_port_info *)out_perf->data; 149 (struct ib_class_port_info *)out_perf->data;
150 struct tcslfl *tcslfl =
151 (struct tcslfl *)&poi->redirect_tcslfl;
136 struct ehca_shca *shca = 152 struct ehca_shca *shca =
137 container_of(ibdev, struct ehca_shca, ib_device); 153 container_of(ibdev, struct ehca_shca, ib_device);
138 struct ehca_sport *sport = &shca->sport[port_num - 1]; 154 struct ehca_sport *sport = &shca->sport[port_num - 1];
@@ -158,10 +174,29 @@ static int ehca_process_perf(struct ib_device *ibdev, u8 port_num,
158 poi->base_version = 1; 174 poi->base_version = 1;
159 poi->class_version = 1; 175 poi->class_version = 1;
160 poi->resp_time_value = 18; 176 poi->resp_time_value = 18;
161 poi->redirect_lid = sport->saved_attr.lid; 177
162 poi->redirect_qp = sport->pma_qp_nr; 178 /* copy local routing information from WC where applicable */
179 tcslfl->sl = in_wc->sl;
180 poi->redirect_lid =
181 sport->saved_attr.lid | in_wc->dlid_path_bits;
182 poi->redirect_qp = sport->pma_qp_nr;
163 poi->redirect_qkey = IB_QP1_QKEY; 183 poi->redirect_qkey = IB_QP1_QKEY;
164 poi->redirect_pkey = IB_DEFAULT_PKEY_FULL; 184
185 ehca_query_pkey(ibdev, port_num, in_wc->pkey_index,
186 &poi->redirect_pkey);
187
188 /* if request was globally routed, copy route info */
189 if (in_grh) {
190 struct vertcfl *vertcfl =
191 (struct vertcfl *)&in_grh->version_tclass_flow;
192 memcpy(poi->redirect_gid, in_grh->dgid.raw,
193 sizeof(poi->redirect_gid));
194 tcslfl->tc = vertcfl->tc;
195 tcslfl->fl = vertcfl->fl;
196 } else
197 /* else only fill in default GID */
198 ehca_query_gid(ibdev, port_num, 0,
199 (union ib_gid *)&poi->redirect_gid);
165 200
166 ehca_dbg(ibdev, "ehca_pma_lid=%x ehca_pma_qp=%x", 201 ehca_dbg(ibdev, "ehca_pma_lid=%x ehca_pma_qp=%x",
167 sport->saved_attr.lid, sport->pma_qp_nr); 202 sport->saved_attr.lid, sport->pma_qp_nr);
@@ -183,8 +218,7 @@ perf_reply:
183 218
184int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 219int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
185 struct ib_wc *in_wc, struct ib_grh *in_grh, 220 struct ib_wc *in_wc, struct ib_grh *in_grh,
186 struct ib_mad *in_mad, 221 struct ib_mad *in_mad, struct ib_mad *out_mad)
187 struct ib_mad *out_mad)
188{ 222{
189 int ret; 223 int ret;
190 224
@@ -196,7 +230,8 @@ int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
196 return IB_MAD_RESULT_SUCCESS; 230 return IB_MAD_RESULT_SUCCESS;
197 231
198 ehca_dbg(ibdev, "port_num=%x src_qp=%x", port_num, in_wc->src_qp); 232 ehca_dbg(ibdev, "port_num=%x src_qp=%x", port_num, in_wc->src_qp);
199 ret = ehca_process_perf(ibdev, port_num, in_mad, out_mad); 233 ret = ehca_process_perf(ibdev, port_num, in_wc, in_grh,
234 in_mad, out_mad);
200 235
201 return ret; 236 return ret;
202} 237}