• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/drivers/infiniband/hw/ehca/
1/*
2 *  IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 *  HCA query functions
5 *
6 *  Authors: Heiko J Schick <schickhj@de.ibm.com>
7 *           Christoph Raisch <raisch@de.ibm.com>
8 *
9 *  Copyright (c) 2005 IBM Corporation
10 *
11 *  All rights reserved.
12 *
13 *  This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 *  BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
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.
28 *
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.
40 */
41
42#include "ehca_tools.h"
43#include "ehca_iverbs.h"
44#include "hcp_if.h"
45
46int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
47{
48	int ret = 0;
49	struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
50					      ib_device);
51	struct hipz_query_hca *rblock;
52
53	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
54	if (!rblock) {
55		ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
56		return -ENOMEM;
57	}
58
59	if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) {
60		ehca_err(&shca->ib_device, "Can't query device properties");
61		ret = -EINVAL;
62		goto query_device1;
63	}
64
65	memset(props, 0, sizeof(struct ib_device_attr));
66	props->fw_ver          = rblock->hw_ver;
67	props->max_mr_size     = rblock->max_mr_size;
68	props->vendor_id       = rblock->vendor_id >> 8;
69	props->vendor_part_id  = rblock->vendor_part_id >> 16;
70	props->hw_ver          = rblock->hw_ver;
71	props->max_qp          = min_t(int, rblock->max_qp, INT_MAX);
72	props->max_qp_wr       = min_t(int, rblock->max_wqes_wq, INT_MAX);
73	props->max_sge         = min_t(int, rblock->max_sge, INT_MAX);
74	props->max_sge_rd      = min_t(int, rblock->max_sge_rd, INT_MAX);
75	props->max_cq          = min_t(int, rblock->max_cq, INT_MAX);
76	props->max_cqe         = min_t(int, rblock->max_cqe, INT_MAX);
77	props->max_mr          = min_t(int, rblock->max_mr, INT_MAX);
78	props->max_mw          = min_t(int, rblock->max_mw, INT_MAX);
79	props->max_pd          = min_t(int, rblock->max_pd, INT_MAX);
80	props->max_ah          = min_t(int, rblock->max_ah, INT_MAX);
81	props->max_fmr         = min_t(int, rblock->max_mr, INT_MAX);
82	props->max_srq         = 0;
83	props->max_srq_wr      = 0;
84	props->max_srq_sge     = 0;
85	props->max_pkeys       = 16;
86	props->local_ca_ack_delay
87		= rblock->local_ca_ack_delay;
88	props->max_raw_ipv6_qp
89		= min_t(int, rblock->max_raw_ipv6_qp, INT_MAX);
90	props->max_raw_ethy_qp
91		= min_t(int, rblock->max_raw_ethy_qp, INT_MAX);
92	props->max_mcast_grp
93		= min_t(int, rblock->max_mcast_grp, INT_MAX);
94	props->max_mcast_qp_attach
95		= min_t(int, rblock->max_mcast_qp_attach, INT_MAX);
96	props->max_total_mcast_qp_attach
97		= min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX);
98
99query_device1:
100	ehca_free_fw_ctrlblock(rblock);
101
102	return ret;
103}
104
105int ehca_query_port(struct ib_device *ibdev,
106		    u8 port, struct ib_port_attr *props)
107{
108	int ret = 0;
109	struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
110					      ib_device);
111	struct hipz_query_port *rblock;
112
113	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
114	if (!rblock) {
115		ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
116		return -ENOMEM;
117	}
118
119	if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
120		ehca_err(&shca->ib_device, "Can't query port properties");
121		ret = -EINVAL;
122		goto query_port1;
123	}
124
125	memset(props, 0, sizeof(struct ib_port_attr));
126	props->state = rblock->state;
127
128	switch (rblock->max_mtu) {
129	case 0x1:
130		props->active_mtu = props->max_mtu = IB_MTU_256;
131		break;
132	case 0x2:
133		props->active_mtu = props->max_mtu = IB_MTU_512;
134		break;
135	case 0x3:
136		props->active_mtu = props->max_mtu = IB_MTU_1024;
137		break;
138	case 0x4:
139		props->active_mtu = props->max_mtu = IB_MTU_2048;
140		break;
141	case 0x5:
142		props->active_mtu = props->max_mtu = IB_MTU_4096;
143		break;
144	default:
145		ehca_err(&shca->ib_device, "Unknown MTU size: %x.",
146			 rblock->max_mtu);
147		break;
148	}
149
150	props->port_cap_flags  = rblock->capability_mask;
151	props->gid_tbl_len     = rblock->gid_tbl_len;
152	props->max_msg_sz      = rblock->max_msg_sz;
153	props->bad_pkey_cntr   = rblock->bad_pkey_cntr;
154	props->qkey_viol_cntr  = rblock->qkey_viol_cntr;
155	props->pkey_tbl_len    = rblock->pkey_tbl_len;
156	props->lid             = rblock->lid;
157	props->sm_lid          = rblock->sm_lid;
158	props->lmc             = rblock->lmc;
159	props->sm_sl           = rblock->sm_sl;
160	props->subnet_timeout  = rblock->subnet_timeout;
161	props->init_type_reply = rblock->init_type_reply;
162
163	props->active_width    = IB_WIDTH_12X;
164	props->active_speed    = 0x1;
165
166	/* at the moment (logical) link state is always LINK_UP */
167	props->phys_state      = 0x5;
168
169query_port1:
170	ehca_free_fw_ctrlblock(rblock);
171
172	return ret;
173}
174
175int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
176{
177	int ret = 0;
178	struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device);
179	struct hipz_query_port *rblock;
180
181	if (index > 16) {
182		ehca_err(&shca->ib_device, "Invalid index: %x.", index);
183		return -EINVAL;
184	}
185
186	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
187	if (!rblock) {
188		ehca_err(&shca->ib_device,  "Can't allocate rblock memory.");
189		return -ENOMEM;
190	}
191
192	if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
193		ehca_err(&shca->ib_device, "Can't query port properties");
194		ret = -EINVAL;
195		goto query_pkey1;
196	}
197
198	memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16));
199
200query_pkey1:
201	ehca_free_fw_ctrlblock(rblock);
202
203	return ret;
204}
205
206int ehca_query_gid(struct ib_device *ibdev, u8 port,
207		   int index, union ib_gid *gid)
208{
209	int ret = 0;
210	struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
211					      ib_device);
212	struct hipz_query_port *rblock;
213
214	if (index > 255) {
215		ehca_err(&shca->ib_device, "Invalid index: %x.", index);
216		return -EINVAL;
217	}
218
219	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
220	if (!rblock) {
221		ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
222		return -ENOMEM;
223	}
224
225	if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
226		ehca_err(&shca->ib_device, "Can't query port properties");
227		ret = -EINVAL;
228		goto query_gid1;
229	}
230
231	memcpy(&gid->raw[0], &rblock->gid_prefix, sizeof(u64));
232	memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64));
233
234query_gid1:
235	ehca_free_fw_ctrlblock(rblock);
236
237	return ret;
238}
239
240const u32 allowed_port_caps = (
241	IB_PORT_SM | IB_PORT_LED_INFO_SUP | IB_PORT_CM_SUP |
242	IB_PORT_SNMP_TUNNEL_SUP | IB_PORT_DEVICE_MGMT_SUP |
243	IB_PORT_VENDOR_CLASS_SUP);
244
245int ehca_modify_port(struct ib_device *ibdev,
246		     u8 port, int port_modify_mask,
247		     struct ib_port_modify *props)
248{
249	int ret = 0;
250	struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device);
251	struct hipz_query_port *rblock;
252	u32 cap;
253	u64 hret;
254
255	if ((props->set_port_cap_mask | props->clr_port_cap_mask)
256	    & ~allowed_port_caps) {
257		ehca_err(&shca->ib_device, "Non-changeable bits set in masks  "
258			 "set=%x  clr=%x  allowed=%x", props->set_port_cap_mask,
259			 props->clr_port_cap_mask, allowed_port_caps);
260		return -EINVAL;
261	}
262
263	if (mutex_lock_interruptible(&shca->modify_mutex))
264                return -ERESTARTSYS;
265
266	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
267	if (!rblock) {
268		ehca_err(&shca->ib_device,  "Can't allocate rblock memory.");
269		ret = -ENOMEM;
270		goto modify_port1;
271	}
272
273	if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
274		ehca_err(&shca->ib_device, "Can't query port properties");
275		ret = -EINVAL;
276		goto modify_port2;
277	}
278
279	cap = (rblock->capability_mask | props->set_port_cap_mask)
280		& ~props->clr_port_cap_mask;
281
282	hret = hipz_h_modify_port(shca->ipz_hca_handle, port,
283				  cap, props->init_type, port_modify_mask);
284	if (hret != H_SUCCESS) {
285		ehca_err(&shca->ib_device, "Modify port failed  hret=%lx", hret);
286		ret = -EINVAL;
287	}
288
289modify_port2:
290	ehca_free_fw_ctrlblock(rblock);
291
292modify_port1:
293        mutex_unlock(&shca->modify_mutex);
294
295	return ret;
296}
297