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_classes.h1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_irq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_iverbs.h5
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_sqp.c91
6 files changed, 104 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index f281d16040f5..92cce8aacbb7 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -101,6 +101,7 @@ struct ehca_sport {
101 spinlock_t mod_sqp_lock; 101 spinlock_t mod_sqp_lock;
102 enum ib_port_state port_state; 102 enum ib_port_state port_state;
103 struct ehca_sma_attr saved_attr; 103 struct ehca_sma_attr saved_attr;
104 u32 pma_qp_nr;
104}; 105};
105 106
106#define HCA_CAP_MR_PGSIZE_4K 0x80000000 107#define HCA_CAP_MR_PGSIZE_4K 0x80000000
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 863b34fa9ff9..b5ca94c6b8d9 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -403,6 +403,8 @@ static void parse_ec(struct ehca_shca *shca, u64 eqe)
403 sport->port_state = IB_PORT_ACTIVE; 403 sport->port_state = IB_PORT_ACTIVE;
404 dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE, 404 dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE,
405 "is active"); 405 "is active");
406 ehca_query_sma_attr(shca, port,
407 &sport->saved_attr);
406 } else 408 } else
407 notify_port_conf_change(shca, port); 409 notify_port_conf_change(shca, port);
408 break; 410 break;
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index c469bfde2708..a8a2ea585d2f 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -187,6 +187,11 @@ int ehca_dealloc_ucontext(struct ib_ucontext *context);
187 187
188int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); 188int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
189 189
190int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
191 struct ib_wc *in_wc, struct ib_grh *in_grh,
192 struct ib_mad *in_mad,
193 struct ib_mad *out_mad);
194
190void ehca_poll_eqs(unsigned long data); 195void ehca_poll_eqs(unsigned long data);
191 196
192int ehca_calc_ipd(struct ehca_shca *shca, int port, 197int ehca_calc_ipd(struct ehca_shca *shca, int port,
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 84c9b7b8669b..a86ebcc79a95 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -472,7 +472,7 @@ int ehca_init_device(struct ehca_shca *shca)
472 shca->ib_device.dealloc_fmr = ehca_dealloc_fmr; 472 shca->ib_device.dealloc_fmr = ehca_dealloc_fmr;
473 shca->ib_device.attach_mcast = ehca_attach_mcast; 473 shca->ib_device.attach_mcast = ehca_attach_mcast;
474 shca->ib_device.detach_mcast = ehca_detach_mcast; 474 shca->ib_device.detach_mcast = ehca_detach_mcast;
475 /* shca->ib_device.process_mad = ehca_process_mad; */ 475 shca->ib_device.process_mad = ehca_process_mad;
476 shca->ib_device.mmap = ehca_mmap; 476 shca->ib_device.mmap = ehca_mmap;
477 477
478 if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) { 478 if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index 3aacc8cf1e44..2ce8cffb8664 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -209,6 +209,10 @@ static inline int ehca_write_swqe(struct ehca_qp *qp,
209 ehca_gen_err("wr.ud.ah is NULL. qp=%p", qp); 209 ehca_gen_err("wr.ud.ah is NULL. qp=%p", qp);
210 return -EINVAL; 210 return -EINVAL;
211 } 211 }
212 if (unlikely(send_wr->wr.ud.remote_qpn == 0)) {
213 ehca_gen_err("dest QP# is 0. qp=%x", qp->real_qp_num);
214 return -EINVAL;
215 }
212 my_av = container_of(send_wr->wr.ud.ah, struct ehca_av, ib_ah); 216 my_av = container_of(send_wr->wr.ud.ah, struct ehca_av, ib_ah);
213 wqe_p->u.ud_av.ud_av = my_av->av; 217 wqe_p->u.ud_av.ud_av = my_av->av;
214 218
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c
index 79e72b25b252..706d97ad5555 100644
--- a/drivers/infiniband/hw/ehca/ehca_sqp.c
+++ b/drivers/infiniband/hw/ehca/ehca_sqp.c
@@ -39,12 +39,18 @@
39 * POSSIBILITY OF SUCH DAMAGE. 39 * POSSIBILITY OF SUCH DAMAGE.
40 */ 40 */
41 41
42#include <rdma/ib_mad.h>
42 43
43#include "ehca_classes.h" 44#include "ehca_classes.h"
44#include "ehca_tools.h" 45#include "ehca_tools.h"
45#include "ehca_iverbs.h" 46#include "ehca_iverbs.h"
46#include "hcp_if.h" 47#include "hcp_if.h"
47 48
49#define IB_MAD_STATUS_REDIRECT __constant_htons(0x0002)
50#define IB_MAD_STATUS_UNSUP_VERSION __constant_htons(0x0004)
51#define IB_MAD_STATUS_UNSUP_METHOD __constant_htons(0x0008)
52
53#define IB_PMA_CLASS_PORT_INFO __constant_htons(0x0001)
48 54
49/** 55/**
50 * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue 56 * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
@@ -83,6 +89,9 @@ u64 ehca_define_sqp(struct ehca_shca *shca,
83 port, ret); 89 port, ret);
84 return ret; 90 return ret;
85 } 91 }
92 shca->sport[port - 1].pma_qp_nr = pma_qp_nr;
93 ehca_dbg(&shca->ib_device, "port=%x pma_qp_nr=%x",
94 port, pma_qp_nr);
86 break; 95 break;
87 default: 96 default:
88 ehca_err(&shca->ib_device, "invalid qp_type=%x", 97 ehca_err(&shca->ib_device, "invalid qp_type=%x",
@@ -109,3 +118,85 @@ u64 ehca_define_sqp(struct ehca_shca *shca,
109 118
110 return H_SUCCESS; 119 return H_SUCCESS;
111} 120}
121
122struct ib_perf {
123 struct ib_mad_hdr mad_hdr;
124 u8 reserved[40];
125 u8 data[192];
126} __attribute__ ((packed));
127
128
129static int ehca_process_perf(struct ib_device *ibdev, u8 port_num,
130 struct ib_mad *in_mad, struct ib_mad *out_mad)
131{
132 struct ib_perf *in_perf = (struct ib_perf *)in_mad;
133 struct ib_perf *out_perf = (struct ib_perf *)out_mad;
134 struct ib_class_port_info *poi =
135 (struct ib_class_port_info *)out_perf->data;
136 struct ehca_shca *shca =
137 container_of(ibdev, struct ehca_shca, ib_device);
138 struct ehca_sport *sport = &shca->sport[port_num - 1];
139
140 ehca_dbg(ibdev, "method=%x", in_perf->mad_hdr.method);
141
142 *out_mad = *in_mad;
143
144 if (in_perf->mad_hdr.class_version != 1) {
145 ehca_warn(ibdev, "Unsupported class_version=%x",
146 in_perf->mad_hdr.class_version);
147 out_perf->mad_hdr.status = IB_MAD_STATUS_UNSUP_VERSION;
148 goto perf_reply;
149 }
150
151 switch (in_perf->mad_hdr.method) {
152 case IB_MGMT_METHOD_GET:
153 case IB_MGMT_METHOD_SET:
154 /* set class port info for redirection */
155 out_perf->mad_hdr.attr_id = IB_PMA_CLASS_PORT_INFO;
156 out_perf->mad_hdr.status = IB_MAD_STATUS_REDIRECT;
157 memset(poi, 0, sizeof(*poi));
158 poi->base_version = 1;
159 poi->class_version = 1;
160 poi->resp_time_value = 18;
161 poi->redirect_lid = sport->saved_attr.lid;
162 poi->redirect_qp = sport->pma_qp_nr;
163 poi->redirect_qkey = IB_QP1_QKEY;
164 poi->redirect_pkey = IB_DEFAULT_PKEY_FULL;
165
166 ehca_dbg(ibdev, "ehca_pma_lid=%x ehca_pma_qp=%x",
167 sport->saved_attr.lid, sport->pma_qp_nr);
168 break;
169
170 case IB_MGMT_METHOD_GET_RESP:
171 return IB_MAD_RESULT_FAILURE;
172
173 default:
174 out_perf->mad_hdr.status = IB_MAD_STATUS_UNSUP_METHOD;
175 break;
176 }
177
178perf_reply:
179 out_perf->mad_hdr.method = IB_MGMT_METHOD_GET_RESP;
180
181 return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
182}
183
184int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
185 struct ib_wc *in_wc, struct ib_grh *in_grh,
186 struct ib_mad *in_mad,
187 struct ib_mad *out_mad)
188{
189 int ret;
190
191 if (!port_num || port_num > ibdev->phys_port_cnt)
192 return IB_MAD_RESULT_FAILURE;
193
194 /* accept only pma request */
195 if (in_mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_PERF_MGMT)
196 return IB_MAD_RESULT_SUCCESS;
197
198 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);
200
201 return ret;
202}