2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
6 * Authors: Heiko J Schick <schickhj@de.ibm.com>
7 * Christoph Raisch <raisch@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 <linux/gfp.h>
44 #include "ehca_tools.h"
45 #include "ehca_iverbs.h"
48 static unsigned int limit_uint(unsigned int value
)
50 return min_t(unsigned int, value
, INT_MAX
);
53 int ehca_query_device(struct ib_device
*ibdev
, struct ib_device_attr
*props
,
57 struct ehca_shca
*shca
= container_of(ibdev
, struct ehca_shca
,
59 struct hipz_query_hca
*rblock
;
61 static const u32 cap_mapping
[] = {
62 IB_DEVICE_RESIZE_MAX_WR
, HCA_CAP_WQE_RESIZE
,
63 IB_DEVICE_BAD_PKEY_CNTR
, HCA_CAP_BAD_P_KEY_CTR
,
64 IB_DEVICE_BAD_QKEY_CNTR
, HCA_CAP_Q_KEY_VIOL_CTR
,
65 IB_DEVICE_RAW_MULTI
, HCA_CAP_RAW_PACKET_MCAST
,
66 IB_DEVICE_AUTO_PATH_MIG
, HCA_CAP_AUTO_PATH_MIG
,
67 IB_DEVICE_CHANGE_PHY_PORT
, HCA_CAP_SQD_RTS_PORT_CHANGE
,
68 IB_DEVICE_UD_AV_PORT_ENFORCE
, HCA_CAP_AH_PORT_NR_CHECK
,
69 IB_DEVICE_CURR_QP_STATE_MOD
, HCA_CAP_CUR_QP_STATE_MOD
,
70 IB_DEVICE_SHUTDOWN_PORT
, HCA_CAP_SHUTDOWN_PORT
,
71 IB_DEVICE_INIT_TYPE
, HCA_CAP_INIT_TYPE
,
72 IB_DEVICE_PORT_ACTIVE_EVENT
, HCA_CAP_PORT_ACTIVE_EVENT
,
75 if (uhw
->inlen
|| uhw
->outlen
)
78 rblock
= ehca_alloc_fw_ctrlblock(GFP_KERNEL
);
80 ehca_err(&shca
->ib_device
, "Can't allocate rblock memory.");
84 if (hipz_h_query_hca(shca
->ipz_hca_handle
, rblock
) != H_SUCCESS
) {
85 ehca_err(&shca
->ib_device
, "Can't query device properties");
90 memset(props
, 0, sizeof(struct ib_device_attr
));
91 props
->page_size_cap
= shca
->hca_cap_mr_pgsize
;
92 props
->fw_ver
= rblock
->hw_ver
;
93 props
->max_mr_size
= rblock
->max_mr_size
;
94 props
->vendor_id
= rblock
->vendor_id
>> 8;
95 props
->vendor_part_id
= rblock
->vendor_part_id
>> 16;
96 props
->hw_ver
= rblock
->hw_ver
;
97 props
->max_qp
= limit_uint(rblock
->max_qp
);
98 props
->max_qp_wr
= limit_uint(rblock
->max_wqes_wq
);
99 props
->max_sge
= limit_uint(rblock
->max_sge
);
100 props
->max_sge_rd
= limit_uint(rblock
->max_sge_rd
);
101 props
->max_cq
= limit_uint(rblock
->max_cq
);
102 props
->max_cqe
= limit_uint(rblock
->max_cqe
);
103 props
->max_mr
= limit_uint(rblock
->max_mr
);
104 props
->max_mw
= limit_uint(rblock
->max_mw
);
105 props
->max_pd
= limit_uint(rblock
->max_pd
);
106 props
->max_ah
= limit_uint(rblock
->max_ah
);
107 props
->max_ee
= limit_uint(rblock
->max_rd_ee_context
);
108 props
->max_rdd
= limit_uint(rblock
->max_rd_domain
);
109 props
->max_fmr
= limit_uint(rblock
->max_mr
);
110 props
->max_qp_rd_atom
= limit_uint(rblock
->max_rr_qp
);
111 props
->max_ee_rd_atom
= limit_uint(rblock
->max_rr_ee_context
);
112 props
->max_res_rd_atom
= limit_uint(rblock
->max_rr_hca
);
113 props
->max_qp_init_rd_atom
= limit_uint(rblock
->max_act_wqs_qp
);
114 props
->max_ee_init_rd_atom
= limit_uint(rblock
->max_act_wqs_ee_context
);
116 if (EHCA_BMASK_GET(HCA_CAP_SRQ
, shca
->hca_cap
)) {
117 props
->max_srq
= limit_uint(props
->max_qp
);
118 props
->max_srq_wr
= limit_uint(props
->max_qp_wr
);
119 props
->max_srq_sge
= 3;
122 props
->max_pkeys
= 16;
123 /* Some FW versions say 0 here; insert sensible value in that case */
124 props
->local_ca_ack_delay
= rblock
->local_ca_ack_delay
?
125 min_t(u8
, rblock
->local_ca_ack_delay
, 255) : 12;
126 props
->max_raw_ipv6_qp
= limit_uint(rblock
->max_raw_ipv6_qp
);
127 props
->max_raw_ethy_qp
= limit_uint(rblock
->max_raw_ethy_qp
);
128 props
->max_mcast_grp
= limit_uint(rblock
->max_mcast_grp
);
129 props
->max_mcast_qp_attach
= limit_uint(rblock
->max_mcast_qp_attach
);
130 props
->max_total_mcast_qp_attach
131 = limit_uint(rblock
->max_total_mcast_qp_attach
);
133 /* translate device capabilities */
134 props
->device_cap_flags
= IB_DEVICE_SYS_IMAGE_GUID
|
135 IB_DEVICE_RC_RNR_NAK_GEN
| IB_DEVICE_N_NOTIFY_CQ
;
136 for (i
= 0; i
< ARRAY_SIZE(cap_mapping
); i
+= 2)
137 if (rblock
->hca_cap_indicators
& cap_mapping
[i
+ 1])
138 props
->device_cap_flags
|= cap_mapping
[i
];
141 ehca_free_fw_ctrlblock(rblock
);
146 static enum ib_mtu
map_mtu(struct ehca_shca
*shca
, u32 fw_mtu
)
160 ehca_err(&shca
->ib_device
, "Unknown MTU size: %x.",
166 static u8
map_number_of_vls(struct ehca_shca
*shca
, u32 vl_cap
)
180 ehca_err(&shca
->ib_device
, "invalid Vl Capability: %x.",
186 int ehca_query_port(struct ib_device
*ibdev
,
187 u8 port
, struct ib_port_attr
*props
)
191 struct ehca_shca
*shca
= container_of(ibdev
, struct ehca_shca
,
193 struct hipz_query_port
*rblock
;
195 rblock
= ehca_alloc_fw_ctrlblock(GFP_KERNEL
);
197 ehca_err(&shca
->ib_device
, "Can't allocate rblock memory.");
201 h_ret
= hipz_h_query_port(shca
->ipz_hca_handle
, port
, rblock
);
202 if (h_ret
!= H_SUCCESS
) {
203 ehca_err(&shca
->ib_device
, "Can't query port properties");
208 memset(props
, 0, sizeof(struct ib_port_attr
));
210 props
->active_mtu
= props
->max_mtu
= map_mtu(shca
, rblock
->max_mtu
);
211 props
->port_cap_flags
= rblock
->capability_mask
;
212 props
->gid_tbl_len
= rblock
->gid_tbl_len
;
213 if (rblock
->max_msg_sz
)
214 props
->max_msg_sz
= rblock
->max_msg_sz
;
216 props
->max_msg_sz
= 0x1 << 31;
217 props
->bad_pkey_cntr
= rblock
->bad_pkey_cntr
;
218 props
->qkey_viol_cntr
= rblock
->qkey_viol_cntr
;
219 props
->pkey_tbl_len
= rblock
->pkey_tbl_len
;
220 props
->lid
= rblock
->lid
;
221 props
->sm_lid
= rblock
->sm_lid
;
222 props
->lmc
= rblock
->lmc
;
223 props
->sm_sl
= rblock
->sm_sl
;
224 props
->subnet_timeout
= rblock
->subnet_timeout
;
225 props
->init_type_reply
= rblock
->init_type_reply
;
226 props
->max_vl_num
= map_number_of_vls(shca
, rblock
->vl_cap
);
228 if (rblock
->state
&& rblock
->phys_width
) {
229 props
->phys_state
= rblock
->phys_pstate
;
230 props
->state
= rblock
->phys_state
;
231 props
->active_width
= rblock
->phys_width
;
232 props
->active_speed
= rblock
->phys_speed
;
234 /* old firmware releases don't report physical
235 * port info, so use default values
237 props
->phys_state
= 5;
238 props
->state
= rblock
->state
;
239 props
->active_width
= IB_WIDTH_12X
;
240 props
->active_speed
= IB_SPEED_SDR
;
244 ehca_free_fw_ctrlblock(rblock
);
249 int ehca_query_sma_attr(struct ehca_shca
*shca
,
250 u8 port
, struct ehca_sma_attr
*attr
)
254 struct hipz_query_port
*rblock
;
256 rblock
= ehca_alloc_fw_ctrlblock(GFP_ATOMIC
);
258 ehca_err(&shca
->ib_device
, "Can't allocate rblock memory.");
262 h_ret
= hipz_h_query_port(shca
->ipz_hca_handle
, port
, rblock
);
263 if (h_ret
!= H_SUCCESS
) {
264 ehca_err(&shca
->ib_device
, "Can't query port properties");
266 goto query_sma_attr1
;
269 memset(attr
, 0, sizeof(struct ehca_sma_attr
));
271 attr
->lid
= rblock
->lid
;
272 attr
->lmc
= rblock
->lmc
;
273 attr
->sm_sl
= rblock
->sm_sl
;
274 attr
->sm_lid
= rblock
->sm_lid
;
276 attr
->pkey_tbl_len
= rblock
->pkey_tbl_len
;
277 memcpy(attr
->pkeys
, rblock
->pkey_entries
, sizeof(attr
->pkeys
));
280 ehca_free_fw_ctrlblock(rblock
);
285 int ehca_query_pkey(struct ib_device
*ibdev
, u8 port
, u16 index
, u16
*pkey
)
289 struct ehca_shca
*shca
;
290 struct hipz_query_port
*rblock
;
292 shca
= container_of(ibdev
, struct ehca_shca
, ib_device
);
294 ehca_err(&shca
->ib_device
, "Invalid index: %x.", index
);
298 rblock
= ehca_alloc_fw_ctrlblock(GFP_KERNEL
);
300 ehca_err(&shca
->ib_device
, "Can't allocate rblock memory.");
304 h_ret
= hipz_h_query_port(shca
->ipz_hca_handle
, port
, rblock
);
305 if (h_ret
!= H_SUCCESS
) {
306 ehca_err(&shca
->ib_device
, "Can't query port properties");
311 memcpy(pkey
, &rblock
->pkey_entries
+ index
, sizeof(u16
));
314 ehca_free_fw_ctrlblock(rblock
);
319 int ehca_query_gid(struct ib_device
*ibdev
, u8 port
,
320 int index
, union ib_gid
*gid
)
324 struct ehca_shca
*shca
= container_of(ibdev
, struct ehca_shca
,
326 struct hipz_query_port
*rblock
;
328 if (index
< 0 || index
> 255) {
329 ehca_err(&shca
->ib_device
, "Invalid index: %x.", index
);
333 rblock
= ehca_alloc_fw_ctrlblock(GFP_KERNEL
);
335 ehca_err(&shca
->ib_device
, "Can't allocate rblock memory.");
339 h_ret
= hipz_h_query_port(shca
->ipz_hca_handle
, port
, rblock
);
340 if (h_ret
!= H_SUCCESS
) {
341 ehca_err(&shca
->ib_device
, "Can't query port properties");
346 memcpy(&gid
->raw
[0], &rblock
->gid_prefix
, sizeof(u64
));
347 memcpy(&gid
->raw
[8], &rblock
->guid_entries
[index
], sizeof(u64
));
350 ehca_free_fw_ctrlblock(rblock
);
355 static const u32 allowed_port_caps
= (
356 IB_PORT_SM
| IB_PORT_LED_INFO_SUP
| IB_PORT_CM_SUP
|
357 IB_PORT_SNMP_TUNNEL_SUP
| IB_PORT_DEVICE_MGMT_SUP
|
358 IB_PORT_VENDOR_CLASS_SUP
);
360 int ehca_modify_port(struct ib_device
*ibdev
,
361 u8 port
, int port_modify_mask
,
362 struct ib_port_modify
*props
)
365 struct ehca_shca
*shca
;
366 struct hipz_query_port
*rblock
;
370 shca
= container_of(ibdev
, struct ehca_shca
, ib_device
);
371 if ((props
->set_port_cap_mask
| props
->clr_port_cap_mask
)
372 & ~allowed_port_caps
) {
373 ehca_err(&shca
->ib_device
, "Non-changeable bits set in masks "
374 "set=%x clr=%x allowed=%x", props
->set_port_cap_mask
,
375 props
->clr_port_cap_mask
, allowed_port_caps
);
379 if (mutex_lock_interruptible(&shca
->modify_mutex
))
382 rblock
= ehca_alloc_fw_ctrlblock(GFP_KERNEL
);
384 ehca_err(&shca
->ib_device
, "Can't allocate rblock memory.");
389 hret
= hipz_h_query_port(shca
->ipz_hca_handle
, port
, rblock
);
390 if (hret
!= H_SUCCESS
) {
391 ehca_err(&shca
->ib_device
, "Can't query port properties");
396 cap
= (rblock
->capability_mask
| props
->set_port_cap_mask
)
397 & ~props
->clr_port_cap_mask
;
399 hret
= hipz_h_modify_port(shca
->ipz_hca_handle
, port
,
400 cap
, props
->init_type
, port_modify_mask
);
401 if (hret
!= H_SUCCESS
) {
402 ehca_err(&shca
->ib_device
, "Modify port failed h_ret=%lli",
408 ehca_free_fw_ctrlblock(rblock
);
411 mutex_unlock(&shca
->modify_mutex
);