diff options
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_sqp.c')
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_sqp.c | 91 |
1 files changed, 91 insertions, 0 deletions
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 | |||
122 | struct ib_perf { | ||
123 | struct ib_mad_hdr mad_hdr; | ||
124 | u8 reserved[40]; | ||
125 | u8 data[192]; | ||
126 | } __attribute__ ((packed)); | ||
127 | |||
128 | |||
129 | static 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 | |||
178 | perf_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 | |||
184 | int 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 | } | ||