blob: d0ab0c0d5e91719dd4774de548f23c361c865650 [file] [log] [blame]
Heiko J Schickfab97222006-09-22 15:22:22 -07001/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Firmware Infiniband Interface code for POWER
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Joachim Fenkesa6a12942007-07-09 15:25:10 +02008 * Joachim Fenkes <fenkes@de.ibm.com>
Heiko J Schickfab97222006-09-22 15:22:22 -07009 * Gerd Bayer <gerd.bayer@de.ibm.com>
10 * Waleri Fomin <fomin@de.ibm.com>
11 *
12 * Copyright (c) 2005 IBM Corporation
13 *
14 * All rights reserved.
15 *
16 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
17 * BSD.
18 *
19 * OpenIB BSD License
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 *
24 * Redistributions of source code must retain the above copyright notice, this
25 * list of conditions and the following disclaimer.
26 *
27 * Redistributions in binary form must reproduce the above copyright notice,
28 * this list of conditions and the following disclaimer in the documentation
29 * and/or other materials
30 * provided with the distribution.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
36 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
40 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGE.
43 */
44
45#include <asm/hvcall.h>
46#include "ehca_tools.h"
47#include "hcp_if.h"
48#include "hcp_phyp.h"
49#include "hipz_fns.h"
50#include "ipz_pt_fn.h"
51
52#define H_ALL_RES_QP_ENHANCED_OPS EHCA_BMASK_IBM(9, 11)
53#define H_ALL_RES_QP_PTE_PIN EHCA_BMASK_IBM(12, 12)
54#define H_ALL_RES_QP_SERVICE_TYPE EHCA_BMASK_IBM(13, 15)
Stefan Roschere2f81da2007-07-20 16:04:17 +020055#define H_ALL_RES_QP_STORAGE EHCA_BMASK_IBM(16, 17)
Heiko J Schickfab97222006-09-22 15:22:22 -070056#define H_ALL_RES_QP_LL_RQ_CQE_POSTING EHCA_BMASK_IBM(18, 18)
57#define H_ALL_RES_QP_LL_SQ_CQE_POSTING EHCA_BMASK_IBM(19, 21)
58#define H_ALL_RES_QP_SIGNALING_TYPE EHCA_BMASK_IBM(22, 23)
59#define H_ALL_RES_QP_UD_AV_LKEY_CTRL EHCA_BMASK_IBM(31, 31)
Stefan Roschere2f81da2007-07-20 16:04:17 +020060#define H_ALL_RES_QP_SMALL_SQ_PAGE_SIZE EHCA_BMASK_IBM(32, 35)
61#define H_ALL_RES_QP_SMALL_RQ_PAGE_SIZE EHCA_BMASK_IBM(36, 39)
Heiko J Schickfab97222006-09-22 15:22:22 -070062#define H_ALL_RES_QP_RESOURCE_TYPE EHCA_BMASK_IBM(56, 63)
63
64#define H_ALL_RES_QP_MAX_OUTST_SEND_WR EHCA_BMASK_IBM(0, 15)
65#define H_ALL_RES_QP_MAX_OUTST_RECV_WR EHCA_BMASK_IBM(16, 31)
66#define H_ALL_RES_QP_MAX_SEND_SGE EHCA_BMASK_IBM(32, 39)
67#define H_ALL_RES_QP_MAX_RECV_SGE EHCA_BMASK_IBM(40, 47)
68
Joachim Fenkesa6a12942007-07-09 15:25:10 +020069#define H_ALL_RES_QP_UD_AV_LKEY EHCA_BMASK_IBM(32, 63)
70#define H_ALL_RES_QP_SRQ_QP_TOKEN EHCA_BMASK_IBM(0, 31)
71#define H_ALL_RES_QP_SRQ_QP_HANDLE EHCA_BMASK_IBM(0, 64)
72#define H_ALL_RES_QP_SRQ_LIMIT EHCA_BMASK_IBM(48, 63)
73#define H_ALL_RES_QP_SRQ_QPN EHCA_BMASK_IBM(40, 63)
74
Heiko J Schickfab97222006-09-22 15:22:22 -070075#define H_ALL_RES_QP_ACT_OUTST_SEND_WR EHCA_BMASK_IBM(16, 31)
76#define H_ALL_RES_QP_ACT_OUTST_RECV_WR EHCA_BMASK_IBM(48, 63)
77#define H_ALL_RES_QP_ACT_SEND_SGE EHCA_BMASK_IBM(8, 15)
78#define H_ALL_RES_QP_ACT_RECV_SGE EHCA_BMASK_IBM(24, 31)
79
80#define H_ALL_RES_QP_SQUEUE_SIZE_PAGES EHCA_BMASK_IBM(0, 31)
81#define H_ALL_RES_QP_RQUEUE_SIZE_PAGES EHCA_BMASK_IBM(32, 63)
82
Joachim Fenkesc4ed7902007-04-24 17:44:31 +020083#define H_MP_INIT_TYPE EHCA_BMASK_IBM(44, 47)
84#define H_MP_SHUTDOWN EHCA_BMASK_IBM(48, 48)
85#define H_MP_RESET_QKEY_CTR EHCA_BMASK_IBM(49, 49)
86
Joachim Fenkes2863ad42007-09-11 15:31:49 +020087#define HCALL4_REGS_FORMAT "r4=%lx r5=%lx r6=%lx r7=%lx"
88#define HCALL7_REGS_FORMAT HCALL4_REGS_FORMAT " r8=%lx r9=%lx r10=%lx"
89#define HCALL9_REGS_FORMAT HCALL7_REGS_FORMAT " r11=%lx r12=%lx"
90
Joachim Fenkes9844b712007-07-09 15:29:03 +020091static DEFINE_SPINLOCK(hcall_lock);
92
Heiko J Schickfab97222006-09-22 15:22:22 -070093static u32 get_longbusy_msecs(int longbusy_rc)
94{
95 switch (longbusy_rc) {
96 case H_LONG_BUSY_ORDER_1_MSEC:
97 return 1;
98 case H_LONG_BUSY_ORDER_10_MSEC:
99 return 10;
100 case H_LONG_BUSY_ORDER_100_MSEC:
101 return 100;
102 case H_LONG_BUSY_ORDER_1_SEC:
103 return 1000;
104 case H_LONG_BUSY_ORDER_10_SEC:
105 return 10000;
106 case H_LONG_BUSY_ORDER_100_SEC:
107 return 100000;
108 default:
109 return 1;
110 }
111}
112
113static long ehca_plpar_hcall_norets(unsigned long opcode,
114 unsigned long arg1,
115 unsigned long arg2,
116 unsigned long arg3,
117 unsigned long arg4,
118 unsigned long arg5,
119 unsigned long arg6,
120 unsigned long arg7)
121{
122 long ret;
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100123 int i, sleep_msecs;
124 unsigned long flags = 0;
Heiko J Schickfab97222006-09-22 15:22:22 -0700125
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700126 if (unlikely(ehca_debug_level >= 2))
127 ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT,
128 opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
Heiko J Schickfab97222006-09-22 15:22:22 -0700129
130 for (i = 0; i < 5; i++) {
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100131 /* serialize hCalls to work around firmware issue */
132 if (ehca_lock_hcalls)
Joachim Fenkes0b5de962007-09-11 15:34:35 +0200133 spin_lock_irqsave(&hcall_lock, flags);
134
Heiko J Schickfab97222006-09-22 15:22:22 -0700135 ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4,
136 arg5, arg6, arg7);
137
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100138 if (ehca_lock_hcalls)
Joachim Fenkes0b5de962007-09-11 15:34:35 +0200139 spin_unlock_irqrestore(&hcall_lock, flags);
140
Heiko J Schickfab97222006-09-22 15:22:22 -0700141 if (H_IS_LONG_BUSY(ret)) {
142 sleep_msecs = get_longbusy_msecs(ret);
143 msleep_interruptible(sleep_msecs);
144 continue;
145 }
146
147 if (ret < H_SUCCESS)
Joachim Fenkes2863ad42007-09-11 15:31:49 +0200148 ehca_gen_err("opcode=%lx ret=%li " HCALL7_REGS_FORMAT,
149 opcode, ret, arg1, arg2, arg3,
150 arg4, arg5, arg6, arg7);
151 else
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700152 if (unlikely(ehca_debug_level >= 2))
153 ehca_gen_dbg("opcode=%lx ret=%li", opcode, ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700154
Heiko J Schickfab97222006-09-22 15:22:22 -0700155 return ret;
Heiko J Schickfab97222006-09-22 15:22:22 -0700156 }
157
158 return H_BUSY;
159}
160
161static long ehca_plpar_hcall9(unsigned long opcode,
162 unsigned long *outs, /* array of 9 outputs */
163 unsigned long arg1,
164 unsigned long arg2,
165 unsigned long arg3,
166 unsigned long arg4,
167 unsigned long arg5,
168 unsigned long arg6,
169 unsigned long arg7,
170 unsigned long arg8,
171 unsigned long arg9)
172{
173 long ret;
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100174 int i, sleep_msecs;
Joachim Fenkesa6a12942007-07-09 15:25:10 +0200175 unsigned long flags = 0;
Heiko J Schickfab97222006-09-22 15:22:22 -0700176
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700177 if (unlikely(ehca_debug_level >= 2))
178 ehca_gen_dbg("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode,
179 arg1, arg2, arg3, arg4, arg5,
180 arg6, arg7, arg8, arg9);
Heiko J Schickfab97222006-09-22 15:22:22 -0700181
182 for (i = 0; i < 5; i++) {
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100183 /* serialize hCalls to work around firmware issue */
184 if (ehca_lock_hcalls)
Stefan Roscher5d882782007-05-09 13:47:56 +0200185 spin_lock_irqsave(&hcall_lock, flags);
Stefan Roscher5d882782007-05-09 13:47:56 +0200186
Heiko J Schickfab97222006-09-22 15:22:22 -0700187 ret = plpar_hcall9(opcode, outs,
188 arg1, arg2, arg3, arg4, arg5,
189 arg6, arg7, arg8, arg9);
190
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100191 if (ehca_lock_hcalls)
Stefan Roscher5d882782007-05-09 13:47:56 +0200192 spin_unlock_irqrestore(&hcall_lock, flags);
193
Heiko J Schickfab97222006-09-22 15:22:22 -0700194 if (H_IS_LONG_BUSY(ret)) {
195 sleep_msecs = get_longbusy_msecs(ret);
196 msleep_interruptible(sleep_msecs);
197 continue;
198 }
199
Joachim Fenkes2863ad42007-09-11 15:31:49 +0200200 if (ret < H_SUCCESS) {
201 ehca_gen_err("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT,
202 opcode, arg1, arg2, arg3, arg4, arg5,
203 arg6, arg7, arg8, arg9);
204 ehca_gen_err("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT,
205 ret, outs[0], outs[1], outs[2], outs[3],
Heiko J Schickfab97222006-09-22 15:22:22 -0700206 outs[4], outs[5], outs[6], outs[7],
207 outs[8]);
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700208 } else if (unlikely(ehca_debug_level >= 2))
Joachim Fenkes2863ad42007-09-11 15:31:49 +0200209 ehca_gen_dbg("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT,
210 ret, outs[0], outs[1], outs[2], outs[3],
211 outs[4], outs[5], outs[6], outs[7],
212 outs[8]);
Heiko J Schickfab97222006-09-22 15:22:22 -0700213 return ret;
Heiko J Schickfab97222006-09-22 15:22:22 -0700214 }
215
216 return H_BUSY;
217}
Stefan Roscher5d882782007-05-09 13:47:56 +0200218
Heiko J Schickfab97222006-09-22 15:22:22 -0700219u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
220 struct ehca_pfeq *pfeq,
221 const u32 neq_control,
222 const u32 number_of_entries,
223 struct ipz_eq_handle *eq_handle,
224 u32 *act_nr_of_entries,
225 u32 *act_pages,
226 u32 *eq_ist)
227{
228 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800229 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700230 u64 allocate_controls;
231
232 /* resource type */
233 allocate_controls = 3ULL;
234
235 /* ISN is associated */
236 if (neq_control != 1)
237 allocate_controls = (1ULL << (63 - 7)) | allocate_controls;
238 else /* notification event queue */
239 allocate_controls = (1ULL << 63) | allocate_controls;
240
241 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
242 adapter_handle.handle, /* r4 */
243 allocate_controls, /* r5 */
244 number_of_entries, /* r6 */
245 0, 0, 0, 0, 0, 0);
246 eq_handle->handle = outs[0];
247 *act_nr_of_entries = (u32)outs[3];
248 *act_pages = (u32)outs[4];
249 *eq_ist = (u32)outs[5];
250
251 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800252 ehca_gen_err("Not enough resource - ret=%lli ", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700253
254 return ret;
255}
256
257u64 hipz_h_reset_event(const struct ipz_adapter_handle adapter_handle,
258 struct ipz_eq_handle eq_handle,
259 const u64 event_mask)
260{
261 return ehca_plpar_hcall_norets(H_RESET_EVENTS,
262 adapter_handle.handle, /* r4 */
263 eq_handle.handle, /* r5 */
264 event_mask, /* r6 */
265 0, 0, 0, 0);
266}
267
268u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
269 struct ehca_cq *cq,
270 struct ehca_alloc_cq_parms *param)
271{
272 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800273 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700274
275 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
276 adapter_handle.handle, /* r4 */
277 2, /* r5 */
278 param->eq_handle.handle, /* r6 */
279 cq->token, /* r7 */
280 param->nr_cqe, /* r8 */
281 0, 0, 0, 0);
282 cq->ipz_cq_handle.handle = outs[0];
283 param->act_nr_of_entries = (u32)outs[3];
284 param->act_pages = (u32)outs[4];
285
286 if (ret == H_SUCCESS)
287 hcp_galpas_ctor(&cq->galpas, outs[5], outs[6]);
288
289 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800290 ehca_gen_err("Not enough resources. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700291
292 return ret;
293}
294
295u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
Heiko J Schickfab97222006-09-22 15:22:22 -0700296 struct ehca_alloc_qp_parms *parms)
297{
298 u64 ret;
Joachim Fenkesa6a12942007-07-09 15:25:10 +0200299 u64 allocate_controls, max_r10_reg, r11, r12;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800300 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700301
302 allocate_controls =
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200303 EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS, parms->ext_type)
Heiko J Schickfab97222006-09-22 15:22:22 -0700304 | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0)
305 | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype)
306 | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype)
Stefan Roschere2f81da2007-07-20 16:04:17 +0200307 | EHCA_BMASK_SET(H_ALL_RES_QP_STORAGE, parms->qp_storage)
308 | EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_SQ_PAGE_SIZE,
309 parms->squeue.page_size)
310 | EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_RQ_PAGE_SIZE,
311 parms->rqueue.page_size)
Heiko J Schickfab97222006-09-22 15:22:22 -0700312 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING,
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200313 !!(parms->ll_comp_flags & LLQP_RECV_COMP))
Heiko J Schickfab97222006-09-22 15:22:22 -0700314 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING,
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200315 !!(parms->ll_comp_flags & LLQP_SEND_COMP))
Heiko J Schickfab97222006-09-22 15:22:22 -0700316 | EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL,
317 parms->ud_av_l_key_ctl)
318 | EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE, 1);
319
320 max_r10_reg =
321 EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
Stefan Roschere2f81da2007-07-20 16:04:17 +0200322 parms->squeue.max_wr + 1)
Heiko J Schickfab97222006-09-22 15:22:22 -0700323 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
Stefan Roschere2f81da2007-07-20 16:04:17 +0200324 parms->rqueue.max_wr + 1)
Heiko J Schickfab97222006-09-22 15:22:22 -0700325 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
Stefan Roschere2f81da2007-07-20 16:04:17 +0200326 parms->squeue.max_sge)
Heiko J Schickfab97222006-09-22 15:22:22 -0700327 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
Stefan Roschere2f81da2007-07-20 16:04:17 +0200328 parms->rqueue.max_sge);
Heiko J Schickfab97222006-09-22 15:22:22 -0700329
Joachim Fenkesa6a12942007-07-09 15:25:10 +0200330 r11 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QP_TOKEN, parms->srq_token);
331
332 if (parms->ext_type == EQPT_SRQ)
333 r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_LIMIT, parms->srq_limit);
334 else
335 r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QPN, parms->srq_qpn);
336
Heiko J Schickfab97222006-09-22 15:22:22 -0700337 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
338 adapter_handle.handle, /* r4 */
339 allocate_controls, /* r5 */
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200340 parms->send_cq_handle.handle,
341 parms->recv_cq_handle.handle,
342 parms->eq_handle.handle,
343 ((u64)parms->token << 32) | parms->pd.value,
Joachim Fenkesa6a12942007-07-09 15:25:10 +0200344 max_r10_reg, r11, r12);
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200345
346 parms->qp_handle.handle = outs[0];
347 parms->real_qp_num = (u32)outs[1];
Stefan Roschere2f81da2007-07-20 16:04:17 +0200348 parms->squeue.act_nr_wqes =
Heiko J Schickfab97222006-09-22 15:22:22 -0700349 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200350 parms->rqueue.act_nr_wqes =
Heiko J Schickfab97222006-09-22 15:22:22 -0700351 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200352 parms->squeue.act_nr_sges =
Heiko J Schickfab97222006-09-22 15:22:22 -0700353 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200354 parms->rqueue.act_nr_sges =
Heiko J Schickfab97222006-09-22 15:22:22 -0700355 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200356 parms->squeue.queue_size =
Heiko J Schickfab97222006-09-22 15:22:22 -0700357 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200358 parms->rqueue.queue_size =
Heiko J Schickfab97222006-09-22 15:22:22 -0700359 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
360
361 if (ret == H_SUCCESS)
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200362 hcp_galpas_ctor(&parms->galpas, outs[6], outs[6]);
Heiko J Schickfab97222006-09-22 15:22:22 -0700363
364 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800365 ehca_gen_err("Not enough resources. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700366
367 return ret;
368}
369
370u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
371 const u8 port_id,
372 struct hipz_query_port *query_port_response_block)
373{
374 u64 ret;
375 u64 r_cb = virt_to_abs(query_port_response_block);
376
377 if (r_cb & (EHCA_PAGESIZE-1)) {
378 ehca_gen_err("response block not page aligned");
379 return H_PARAMETER;
380 }
381
382 ret = ehca_plpar_hcall_norets(H_QUERY_PORT,
383 adapter_handle.handle, /* r4 */
384 port_id, /* r5 */
385 r_cb, /* r6 */
386 0, 0, 0, 0);
387
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700388 if (ehca_debug_level >= 2)
Heiko J Schickfab97222006-09-22 15:22:22 -0700389 ehca_dmp(query_port_response_block, 64, "response_block");
390
391 return ret;
392}
393
Joachim Fenkesc4ed7902007-04-24 17:44:31 +0200394u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle,
395 const u8 port_id, const u32 port_cap,
396 const u8 init_type, const int modify_mask)
397{
398 u64 port_attributes = port_cap;
399
400 if (modify_mask & IB_PORT_SHUTDOWN)
401 port_attributes |= EHCA_BMASK_SET(H_MP_SHUTDOWN, 1);
402 if (modify_mask & IB_PORT_INIT_TYPE)
403 port_attributes |= EHCA_BMASK_SET(H_MP_INIT_TYPE, init_type);
404 if (modify_mask & IB_PORT_RESET_QKEY_CNTR)
405 port_attributes |= EHCA_BMASK_SET(H_MP_RESET_QKEY_CTR, 1);
406
407 return ehca_plpar_hcall_norets(H_MODIFY_PORT,
408 adapter_handle.handle, /* r4 */
409 port_id, /* r5 */
410 port_attributes, /* r6 */
411 0, 0, 0, 0);
412}
413
Heiko J Schickfab97222006-09-22 15:22:22 -0700414u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
415 struct hipz_query_hca *query_hca_rblock)
416{
417 u64 r_cb = virt_to_abs(query_hca_rblock);
418
419 if (r_cb & (EHCA_PAGESIZE-1)) {
420 ehca_gen_err("response_block=%p not page aligned",
421 query_hca_rblock);
422 return H_PARAMETER;
423 }
424
425 return ehca_plpar_hcall_norets(H_QUERY_HCA,
426 adapter_handle.handle, /* r4 */
427 r_cb, /* r5 */
428 0, 0, 0, 0, 0);
429}
430
431u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,
432 const u8 pagesize,
433 const u8 queue_type,
434 const u64 resource_handle,
435 const u64 logical_address_of_page,
436 u64 count)
437{
438 return ehca_plpar_hcall_norets(H_REGISTER_RPAGES,
439 adapter_handle.handle, /* r4 */
Hoang-Nam Nguyen5bb7d922007-07-20 16:01:51 +0200440 (u64)queue_type | ((u64)pagesize) << 8,
441 /* r5 */
Heiko J Schickfab97222006-09-22 15:22:22 -0700442 resource_handle, /* r6 */
443 logical_address_of_page, /* r7 */
444 count, /* r8 */
445 0, 0);
446}
447
448u64 hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle,
449 const struct ipz_eq_handle eq_handle,
450 struct ehca_pfeq *pfeq,
451 const u8 pagesize,
452 const u8 queue_type,
453 const u64 logical_address_of_page,
454 const u64 count)
455{
456 if (count != 1) {
Stephen Rothwell3750f602009-01-16 14:55:28 -0800457 ehca_gen_err("Ppage counter=%llx", count);
Heiko J Schickfab97222006-09-22 15:22:22 -0700458 return H_PARAMETER;
459 }
460 return hipz_h_register_rpage(adapter_handle,
461 pagesize,
462 queue_type,
463 eq_handle.handle,
464 logical_address_of_page, count);
465}
466
467u64 hipz_h_query_int_state(const struct ipz_adapter_handle adapter_handle,
468 u32 ist)
469{
470 u64 ret;
471 ret = ehca_plpar_hcall_norets(H_QUERY_INT_STATE,
472 adapter_handle.handle, /* r4 */
473 ist, /* r5 */
474 0, 0, 0, 0, 0);
475
476 if (ret != H_SUCCESS && ret != H_BUSY)
477 ehca_gen_err("Could not query interrupt state.");
478
479 return ret;
480}
481
482u64 hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle,
483 const struct ipz_cq_handle cq_handle,
484 struct ehca_pfcq *pfcq,
485 const u8 pagesize,
486 const u8 queue_type,
487 const u64 logical_address_of_page,
488 const u64 count,
489 const struct h_galpa gal)
490{
491 if (count != 1) {
Stephen Rothwell3750f602009-01-16 14:55:28 -0800492 ehca_gen_err("Page counter=%llx", count);
Heiko J Schickfab97222006-09-22 15:22:22 -0700493 return H_PARAMETER;
494 }
495
496 return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
497 cq_handle.handle, logical_address_of_page,
498 count);
499}
500
501u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
502 const struct ipz_qp_handle qp_handle,
503 struct ehca_pfqp *pfqp,
504 const u8 pagesize,
505 const u8 queue_type,
506 const u64 logical_address_of_page,
507 const u64 count,
508 const struct h_galpa galpa)
509{
Stefan Roschere2f81da2007-07-20 16:04:17 +0200510 if (count > 1) {
Stephen Rothwell3750f602009-01-16 14:55:28 -0800511 ehca_gen_err("Page counter=%llx", count);
Heiko J Schickfab97222006-09-22 15:22:22 -0700512 return H_PARAMETER;
513 }
514
Hoang-Nam Nguyen2b943972007-07-12 17:53:47 +0200515 return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
516 qp_handle.handle, logical_address_of_page,
Heiko J Schickfab97222006-09-22 15:22:22 -0700517 count);
518}
519
520u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
521 const struct ipz_qp_handle qp_handle,
522 struct ehca_pfqp *pfqp,
523 void **log_addr_next_sq_wqe2processed,
524 void **log_addr_next_rq_wqe2processed,
525 int dis_and_get_function_code)
526{
527 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800528 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700529
530 ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
531 adapter_handle.handle, /* r4 */
532 dis_and_get_function_code, /* r5 */
533 qp_handle.handle, /* r6 */
534 0, 0, 0, 0, 0, 0);
535 if (log_addr_next_sq_wqe2processed)
Hoang-Nam Nguyen2b943972007-07-12 17:53:47 +0200536 *log_addr_next_sq_wqe2processed = (void *)outs[0];
Heiko J Schickfab97222006-09-22 15:22:22 -0700537 if (log_addr_next_rq_wqe2processed)
Hoang-Nam Nguyen2b943972007-07-12 17:53:47 +0200538 *log_addr_next_rq_wqe2processed = (void *)outs[1];
Heiko J Schickfab97222006-09-22 15:22:22 -0700539
540 return ret;
541}
542
543u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
544 const struct ipz_qp_handle qp_handle,
545 struct ehca_pfqp *pfqp,
546 const u64 update_mask,
547 struct hcp_modify_qp_control_block *mqpcb,
548 struct h_galpa gal)
549{
550 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800551 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700552 ret = ehca_plpar_hcall9(H_MODIFY_QP, outs,
553 adapter_handle.handle, /* r4 */
554 qp_handle.handle, /* r5 */
555 update_mask, /* r6 */
556 virt_to_abs(mqpcb), /* r7 */
557 0, 0, 0, 0, 0);
558
559 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800560 ehca_gen_err("Insufficient resources ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700561
562 return ret;
563}
564
565u64 hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle,
566 const struct ipz_qp_handle qp_handle,
567 struct ehca_pfqp *pfqp,
568 struct hcp_modify_qp_control_block *qqpcb,
569 struct h_galpa gal)
570{
571 return ehca_plpar_hcall_norets(H_QUERY_QP,
572 adapter_handle.handle, /* r4 */
573 qp_handle.handle, /* r5 */
574 virt_to_abs(qqpcb), /* r6 */
575 0, 0, 0, 0);
576}
577
578u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
579 struct ehca_qp *qp)
580{
581 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800582 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700583
584 ret = hcp_galpas_dtor(&qp->galpas);
585 if (ret) {
586 ehca_gen_err("Could not destruct qp->galpas");
587 return H_RESOURCE;
588 }
589 ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
590 adapter_handle.handle, /* r4 */
591 /* function code */
592 1, /* r5 */
593 qp->ipz_qp_handle.handle, /* r6 */
594 0, 0, 0, 0, 0, 0);
595 if (ret == H_HARDWARE)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800596 ehca_gen_err("HCA not operational. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700597
598 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
599 adapter_handle.handle, /* r4 */
600 qp->ipz_qp_handle.handle, /* r5 */
601 0, 0, 0, 0, 0);
602
603 if (ret == H_RESOURCE)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800604 ehca_gen_err("Resource still in use. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700605
606 return ret;
607}
608
609u64 hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle,
610 const struct ipz_qp_handle qp_handle,
611 struct h_galpa gal,
612 u32 port)
613{
614 return ehca_plpar_hcall_norets(H_DEFINE_AQP0,
615 adapter_handle.handle, /* r4 */
616 qp_handle.handle, /* r5 */
617 port, /* r6 */
618 0, 0, 0, 0);
619}
620
621u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
622 const struct ipz_qp_handle qp_handle,
623 struct h_galpa gal,
624 u32 port, u32 * pma_qp_nr,
625 u32 * bma_qp_nr)
626{
627 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800628 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700629
630 ret = ehca_plpar_hcall9(H_DEFINE_AQP1, outs,
631 adapter_handle.handle, /* r4 */
632 qp_handle.handle, /* r5 */
633 port, /* r6 */
634 0, 0, 0, 0, 0, 0);
635 *pma_qp_nr = (u32)outs[0];
636 *bma_qp_nr = (u32)outs[1];
637
638 if (ret == H_ALIAS_EXIST)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800639 ehca_gen_err("AQP1 already exists. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700640
641 return ret;
642}
643
644u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle,
645 const struct ipz_qp_handle qp_handle,
646 struct h_galpa gal,
647 u16 mcg_dlid,
648 u64 subnet_prefix, u64 interface_id)
649{
650 u64 ret;
651
652 ret = ehca_plpar_hcall_norets(H_ATTACH_MCQP,
653 adapter_handle.handle, /* r4 */
654 qp_handle.handle, /* r5 */
655 mcg_dlid, /* r6 */
656 interface_id, /* r7 */
657 subnet_prefix, /* r8 */
658 0, 0);
659
660 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800661 ehca_gen_err("Not enough resources. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700662
663 return ret;
664}
665
666u64 hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle,
667 const struct ipz_qp_handle qp_handle,
668 struct h_galpa gal,
669 u16 mcg_dlid,
670 u64 subnet_prefix, u64 interface_id)
671{
672 return ehca_plpar_hcall_norets(H_DETACH_MCQP,
673 adapter_handle.handle, /* r4 */
674 qp_handle.handle, /* r5 */
675 mcg_dlid, /* r6 */
676 interface_id, /* r7 */
677 subnet_prefix, /* r8 */
678 0, 0);
679}
680
681u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle,
682 struct ehca_cq *cq,
683 u8 force_flag)
684{
685 u64 ret;
686
687 ret = hcp_galpas_dtor(&cq->galpas);
688 if (ret) {
689 ehca_gen_err("Could not destruct cp->galpas");
690 return H_RESOURCE;
691 }
692
693 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
694 adapter_handle.handle, /* r4 */
695 cq->ipz_cq_handle.handle, /* r5 */
696 force_flag != 0 ? 1L : 0L, /* r6 */
697 0, 0, 0, 0);
698
699 if (ret == H_RESOURCE)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800700 ehca_gen_err("H_FREE_RESOURCE failed ret=%lli ", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700701
702 return ret;
703}
704
705u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle,
706 struct ehca_eq *eq)
707{
708 u64 ret;
709
710 ret = hcp_galpas_dtor(&eq->galpas);
711 if (ret) {
712 ehca_gen_err("Could not destruct eq->galpas");
713 return H_RESOURCE;
714 }
715
716 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
717 adapter_handle.handle, /* r4 */
718 eq->ipz_eq_handle.handle, /* r5 */
719 0, 0, 0, 0, 0);
720
721 if (ret == H_RESOURCE)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800722 ehca_gen_err("Resource in use. ret=%lli ", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700723
724 return ret;
725}
726
727u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
728 const struct ehca_mr *mr,
729 const u64 vaddr,
730 const u64 length,
731 const u32 access_ctrl,
732 const struct ipz_pd pd,
733 struct ehca_mr_hipzout_parms *outparms)
734{
735 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800736 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700737
738 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
739 adapter_handle.handle, /* r4 */
740 5, /* r5 */
741 vaddr, /* r6 */
742 length, /* r7 */
743 (((u64)access_ctrl) << 32ULL), /* r8 */
744 pd.value, /* r9 */
745 0, 0, 0);
746 outparms->handle.handle = outs[0];
747 outparms->lkey = (u32)outs[2];
748 outparms->rkey = (u32)outs[3];
749
750 return ret;
751}
752
753u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
754 const struct ehca_mr *mr,
755 const u8 pagesize,
756 const u8 queue_type,
757 const u64 logical_address_of_page,
758 const u64 count)
759{
760 u64 ret;
761
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700762 if (unlikely(ehca_debug_level >= 3)) {
Hoang-Nam Nguyen5bb7d922007-07-20 16:01:51 +0200763 if (count > 1) {
764 u64 *kpage;
765 int i;
766 kpage = (u64 *)abs_to_virt(logical_address_of_page);
767 for (i = 0; i < count; i++)
768 ehca_gen_dbg("kpage[%d]=%p",
769 i, (void *)kpage[i]);
770 } else
771 ehca_gen_dbg("kpage=%p",
772 (void *)logical_address_of_page);
773 }
774
Heiko J Schickfab97222006-09-22 15:22:22 -0700775 if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) {
776 ehca_gen_err("logical_address_of_page not on a 4k boundary "
Stephen Rothwell3750f602009-01-16 14:55:28 -0800777 "adapter_handle=%llx mr=%p mr_handle=%llx "
Heiko J Schickfab97222006-09-22 15:22:22 -0700778 "pagesize=%x queue_type=%x "
Stephen Rothwell3750f602009-01-16 14:55:28 -0800779 "logical_address_of_page=%llx count=%llx",
Heiko J Schickfab97222006-09-22 15:22:22 -0700780 adapter_handle.handle, mr,
781 mr->ipz_mr_handle.handle, pagesize, queue_type,
782 logical_address_of_page, count);
783 ret = H_PARAMETER;
784 } else
785 ret = hipz_h_register_rpage(adapter_handle, pagesize,
786 queue_type,
787 mr->ipz_mr_handle.handle,
788 logical_address_of_page, count);
789 return ret;
790}
791
792u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,
793 const struct ehca_mr *mr,
794 struct ehca_mr_hipzout_parms *outparms)
795{
796 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800797 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700798
799 ret = ehca_plpar_hcall9(H_QUERY_MR, outs,
800 adapter_handle.handle, /* r4 */
801 mr->ipz_mr_handle.handle, /* r5 */
802 0, 0, 0, 0, 0, 0, 0);
803 outparms->len = outs[0];
804 outparms->vaddr = outs[1];
805 outparms->acl = outs[4] >> 32;
806 outparms->lkey = (u32)(outs[5] >> 32);
807 outparms->rkey = (u32)(outs[5] & (0xffffffff));
808
809 return ret;
810}
811
812u64 hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle,
813 const struct ehca_mr *mr)
814{
815 return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
816 adapter_handle.handle, /* r4 */
817 mr->ipz_mr_handle.handle, /* r5 */
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100818 0, 0, 0, 0, 0);
Heiko J Schickfab97222006-09-22 15:22:22 -0700819}
820
821u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,
822 const struct ehca_mr *mr,
823 const u64 vaddr_in,
824 const u64 length,
825 const u32 access_ctrl,
826 const struct ipz_pd pd,
827 const u64 mr_addr_cb,
828 struct ehca_mr_hipzout_parms *outparms)
829{
830 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800831 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700832
833 ret = ehca_plpar_hcall9(H_REREGISTER_PMR, outs,
834 adapter_handle.handle, /* r4 */
835 mr->ipz_mr_handle.handle, /* r5 */
836 vaddr_in, /* r6 */
837 length, /* r7 */
838 /* r8 */
839 ((((u64)access_ctrl) << 32ULL) | pd.value),
840 mr_addr_cb, /* r9 */
841 0, 0, 0);
842 outparms->vaddr = outs[1];
843 outparms->lkey = (u32)outs[2];
844 outparms->rkey = (u32)outs[3];
845
846 return ret;
847}
848
849u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,
850 const struct ehca_mr *mr,
851 const struct ehca_mr *orig_mr,
852 const u64 vaddr_in,
853 const u32 access_ctrl,
854 const struct ipz_pd pd,
855 struct ehca_mr_hipzout_parms *outparms)
856{
857 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800858 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700859
860 ret = ehca_plpar_hcall9(H_REGISTER_SMR, outs,
861 adapter_handle.handle, /* r4 */
862 orig_mr->ipz_mr_handle.handle, /* r5 */
863 vaddr_in, /* r6 */
864 (((u64)access_ctrl) << 32ULL), /* r7 */
865 pd.value, /* r8 */
866 0, 0, 0, 0);
867 outparms->handle.handle = outs[0];
868 outparms->lkey = (u32)outs[2];
869 outparms->rkey = (u32)outs[3];
870
871 return ret;
872}
873
874u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,
875 const struct ehca_mw *mw,
876 const struct ipz_pd pd,
877 struct ehca_mw_hipzout_parms *outparms)
878{
879 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800880 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700881
882 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
883 adapter_handle.handle, /* r4 */
884 6, /* r5 */
885 pd.value, /* r6 */
886 0, 0, 0, 0, 0, 0);
887 outparms->handle.handle = outs[0];
888 outparms->rkey = (u32)outs[3];
889
890 return ret;
891}
892
893u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,
894 const struct ehca_mw *mw,
895 struct ehca_mw_hipzout_parms *outparms)
896{
897 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800898 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700899
900 ret = ehca_plpar_hcall9(H_QUERY_MW, outs,
901 adapter_handle.handle, /* r4 */
902 mw->ipz_mw_handle.handle, /* r5 */
903 0, 0, 0, 0, 0, 0, 0);
904 outparms->rkey = (u32)outs[3];
905
906 return ret;
907}
908
909u64 hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle,
910 const struct ehca_mw *mw)
911{
912 return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
913 adapter_handle.handle, /* r4 */
914 mw->ipz_mw_handle.handle, /* r5 */
915 0, 0, 0, 0, 0);
916}
917
918u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
919 const u64 ressource_handle,
920 void *rblock,
921 unsigned long *byte_count)
922{
923 u64 r_cb = virt_to_abs(rblock);
924
925 if (r_cb & (EHCA_PAGESIZE-1)) {
926 ehca_gen_err("rblock not page aligned.");
927 return H_PARAMETER;
928 }
929
930 return ehca_plpar_hcall_norets(H_ERROR_DATA,
931 adapter_handle.handle,
932 ressource_handle,
933 r_cb,
934 0, 0, 0, 0);
935}
Stefan Roscher6f7bc012008-07-14 23:48:47 -0700936
937u64 hipz_h_eoi(int irq)
938{
939 unsigned long xirr;
940
941 iosync();
942 xirr = (0xffULL << 24) | irq;
943
944 return plpar_hcall_norets(H_EOI, xirr);
945}