2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
6 * Authors: Khadija Souissi <souissi@de.ibm.com>
7 * Heiko J Schick <schickhj@de.ibm.com>
9 * Copyright (c) 2005 IBM Corporation
11 * All rights reserved.
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
42 #include <rdma/ib_mad.h>
44 #include "ehca_classes.h"
45 #include "ehca_tools.h"
46 #include "ehca_iverbs.h"
49 #define IB_MAD_STATUS_REDIRECT cpu_to_be16(0x0002)
50 #define IB_MAD_STATUS_UNSUP_VERSION cpu_to_be16(0x0004)
51 #define IB_MAD_STATUS_UNSUP_METHOD cpu_to_be16(0x0008)
53 #define IB_PMA_CLASS_PORT_INFO cpu_to_be16(0x0001)
56 * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
57 * pair is created successfully, the corresponding port gets active.
59 * Define Special Queue pair 0 (SMI QP) is still not supported.
61 * @qp_init_attr: Queue pair init attributes with port and queue pair type
64 u64
ehca_define_sqp(struct ehca_shca
*shca
,
65 struct ehca_qp
*ehca_qp
,
66 struct ib_qp_init_attr
*qp_init_attr
)
68 u32 pma_qp_nr
, bma_qp_nr
;
70 u8 port
= qp_init_attr
->port_num
;
73 shca
->sport
[port
- 1].port_state
= IB_PORT_DOWN
;
75 switch (qp_init_attr
->qp_type
) {
77 /* function not supported yet */
80 ret
= hipz_h_define_aqp1(shca
->ipz_hca_handle
,
81 ehca_qp
->ipz_qp_handle
,
82 ehca_qp
->galpas
.kernel
,
83 (u32
) qp_init_attr
->port_num
,
84 &pma_qp_nr
, &bma_qp_nr
);
86 if (ret
!= H_SUCCESS
) {
87 ehca_err(&shca
->ib_device
,
88 "Can't define AQP1 for port %x. h_ret=%lli",
92 shca
->sport
[port
- 1].pma_qp_nr
= pma_qp_nr
;
93 ehca_dbg(&shca
->ib_device
, "port=%x pma_qp_nr=%x",
97 ehca_err(&shca
->ib_device
, "invalid qp_type=%x",
98 qp_init_attr
->qp_type
);
102 if (ehca_nr_ports
< 0) /* autodetect mode */
106 shca
->sport
[port
- 1].port_state
!= IB_PORT_ACTIVE
&&
107 counter
< ehca_port_act_time
;
109 ehca_dbg(&shca
->ib_device
, "... wait until port %x is active",
111 msleep_interruptible(1000);
114 if (counter
== ehca_port_act_time
) {
115 ehca_err(&shca
->ib_device
, "Port %x is not active.", port
);
123 struct ib_mad_hdr mad_hdr
;
126 } __attribute__ ((packed
));
129 static int ehca_process_perf(struct ib_device
*ibdev
, u8 port_num
,
130 struct ib_mad
*in_mad
, struct ib_mad
*out_mad
)
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];
140 ehca_dbg(ibdev
, "method=%x", in_perf
->mad_hdr
.method
);
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
;
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
;
166 ehca_dbg(ibdev
, "ehca_pma_lid=%x ehca_pma_qp=%x",
167 sport
->saved_attr
.lid
, sport
->pma_qp_nr
);
170 case IB_MGMT_METHOD_GET_RESP
:
171 return IB_MAD_RESULT_FAILURE
;
174 out_perf
->mad_hdr
.status
= IB_MAD_STATUS_UNSUP_METHOD
;
179 out_perf
->mad_hdr
.method
= IB_MGMT_METHOD_GET_RESP
;
181 return IB_MAD_RESULT_SUCCESS
| IB_MAD_RESULT_REPLY
;
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
)
191 if (!port_num
|| port_num
> ibdev
->phys_port_cnt
)
192 return IB_MAD_RESULT_FAILURE
;
194 /* accept only pma request */
195 if (in_mad
->mad_hdr
.mgmt_class
!= IB_MGMT_CLASS_PERF_MGMT
)
196 return IB_MAD_RESULT_SUCCESS
;
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
);