blob: 89517ffb4389ed8b1d781ef658b4f54b0ccd7a98 [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 long ehca_plpar_hcall_norets(unsigned long opcode,
94 unsigned long arg1,
95 unsigned long arg2,
96 unsigned long arg3,
97 unsigned long arg4,
98 unsigned long arg5,
99 unsigned long arg6,
100 unsigned long arg7)
101{
102 long ret;
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100103 int i, sleep_msecs;
104 unsigned long flags = 0;
Heiko J Schickfab97222006-09-22 15:22:22 -0700105
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700106 if (unlikely(ehca_debug_level >= 2))
107 ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT,
108 opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
Heiko J Schickfab97222006-09-22 15:22:22 -0700109
110 for (i = 0; i < 5; i++) {
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100111 /* serialize hCalls to work around firmware issue */
112 if (ehca_lock_hcalls)
Joachim Fenkes0b5de962007-09-11 15:34:35 +0200113 spin_lock_irqsave(&hcall_lock, flags);
114
Heiko J Schickfab97222006-09-22 15:22:22 -0700115 ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4,
116 arg5, arg6, arg7);
117
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100118 if (ehca_lock_hcalls)
Joachim Fenkes0b5de962007-09-11 15:34:35 +0200119 spin_unlock_irqrestore(&hcall_lock, flags);
120
Heiko J Schickfab97222006-09-22 15:22:22 -0700121 if (H_IS_LONG_BUSY(ret)) {
122 sleep_msecs = get_longbusy_msecs(ret);
123 msleep_interruptible(sleep_msecs);
124 continue;
125 }
126
127 if (ret < H_SUCCESS)
Joachim Fenkes2863ad42007-09-11 15:31:49 +0200128 ehca_gen_err("opcode=%lx ret=%li " HCALL7_REGS_FORMAT,
129 opcode, ret, arg1, arg2, arg3,
130 arg4, arg5, arg6, arg7);
131 else
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700132 if (unlikely(ehca_debug_level >= 2))
133 ehca_gen_dbg("opcode=%lx ret=%li", opcode, ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700134
Heiko J Schickfab97222006-09-22 15:22:22 -0700135 return ret;
Heiko J Schickfab97222006-09-22 15:22:22 -0700136 }
137
138 return H_BUSY;
139}
140
141static long ehca_plpar_hcall9(unsigned long opcode,
142 unsigned long *outs, /* array of 9 outputs */
143 unsigned long arg1,
144 unsigned long arg2,
145 unsigned long arg3,
146 unsigned long arg4,
147 unsigned long arg5,
148 unsigned long arg6,
149 unsigned long arg7,
150 unsigned long arg8,
151 unsigned long arg9)
152{
153 long ret;
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100154 int i, sleep_msecs;
Joachim Fenkesa6a12942007-07-09 15:25:10 +0200155 unsigned long flags = 0;
Heiko J Schickfab97222006-09-22 15:22:22 -0700156
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700157 if (unlikely(ehca_debug_level >= 2))
158 ehca_gen_dbg("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode,
159 arg1, arg2, arg3, arg4, arg5,
160 arg6, arg7, arg8, arg9);
Heiko J Schickfab97222006-09-22 15:22:22 -0700161
162 for (i = 0; i < 5; i++) {
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100163 /* serialize hCalls to work around firmware issue */
164 if (ehca_lock_hcalls)
Stefan Roscher5d882782007-05-09 13:47:56 +0200165 spin_lock_irqsave(&hcall_lock, flags);
Stefan Roscher5d882782007-05-09 13:47:56 +0200166
Heiko J Schickfab97222006-09-22 15:22:22 -0700167 ret = plpar_hcall9(opcode, outs,
168 arg1, arg2, arg3, arg4, arg5,
169 arg6, arg7, arg8, arg9);
170
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100171 if (ehca_lock_hcalls)
Stefan Roscher5d882782007-05-09 13:47:56 +0200172 spin_unlock_irqrestore(&hcall_lock, flags);
173
Heiko J Schickfab97222006-09-22 15:22:22 -0700174 if (H_IS_LONG_BUSY(ret)) {
175 sleep_msecs = get_longbusy_msecs(ret);
176 msleep_interruptible(sleep_msecs);
177 continue;
178 }
179
Joachim Fenkes2863ad42007-09-11 15:31:49 +0200180 if (ret < H_SUCCESS) {
181 ehca_gen_err("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT,
182 opcode, arg1, arg2, arg3, arg4, arg5,
183 arg6, arg7, arg8, arg9);
184 ehca_gen_err("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT,
185 ret, outs[0], outs[1], outs[2], outs[3],
Heiko J Schickfab97222006-09-22 15:22:22 -0700186 outs[4], outs[5], outs[6], outs[7],
187 outs[8]);
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700188 } else if (unlikely(ehca_debug_level >= 2))
Joachim Fenkes2863ad42007-09-11 15:31:49 +0200189 ehca_gen_dbg("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT,
190 ret, outs[0], outs[1], outs[2], outs[3],
191 outs[4], outs[5], outs[6], outs[7],
192 outs[8]);
Heiko J Schickfab97222006-09-22 15:22:22 -0700193 return ret;
Heiko J Schickfab97222006-09-22 15:22:22 -0700194 }
195
196 return H_BUSY;
197}
Stefan Roscher5d882782007-05-09 13:47:56 +0200198
Heiko J Schickfab97222006-09-22 15:22:22 -0700199u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
200 struct ehca_pfeq *pfeq,
201 const u32 neq_control,
202 const u32 number_of_entries,
203 struct ipz_eq_handle *eq_handle,
204 u32 *act_nr_of_entries,
205 u32 *act_pages,
206 u32 *eq_ist)
207{
208 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800209 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700210 u64 allocate_controls;
211
212 /* resource type */
213 allocate_controls = 3ULL;
214
215 /* ISN is associated */
216 if (neq_control != 1)
217 allocate_controls = (1ULL << (63 - 7)) | allocate_controls;
218 else /* notification event queue */
219 allocate_controls = (1ULL << 63) | allocate_controls;
220
221 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
222 adapter_handle.handle, /* r4 */
223 allocate_controls, /* r5 */
224 number_of_entries, /* r6 */
225 0, 0, 0, 0, 0, 0);
226 eq_handle->handle = outs[0];
227 *act_nr_of_entries = (u32)outs[3];
228 *act_pages = (u32)outs[4];
229 *eq_ist = (u32)outs[5];
230
231 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800232 ehca_gen_err("Not enough resource - ret=%lli ", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700233
234 return ret;
235}
236
237u64 hipz_h_reset_event(const struct ipz_adapter_handle adapter_handle,
238 struct ipz_eq_handle eq_handle,
239 const u64 event_mask)
240{
241 return ehca_plpar_hcall_norets(H_RESET_EVENTS,
242 adapter_handle.handle, /* r4 */
243 eq_handle.handle, /* r5 */
244 event_mask, /* r6 */
245 0, 0, 0, 0);
246}
247
248u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
249 struct ehca_cq *cq,
250 struct ehca_alloc_cq_parms *param)
251{
Alexander Schmidte675b6d2010-07-05 16:19:25 +0000252 int rc;
Heiko J Schickfab97222006-09-22 15:22:22 -0700253 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800254 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700255
256 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
257 adapter_handle.handle, /* r4 */
258 2, /* r5 */
259 param->eq_handle.handle, /* r6 */
260 cq->token, /* r7 */
261 param->nr_cqe, /* r8 */
262 0, 0, 0, 0);
263 cq->ipz_cq_handle.handle = outs[0];
264 param->act_nr_of_entries = (u32)outs[3];
265 param->act_pages = (u32)outs[4];
266
Alexander Schmidte675b6d2010-07-05 16:19:25 +0000267 if (ret == H_SUCCESS) {
268 rc = hcp_galpas_ctor(&cq->galpas, 0, outs[5], outs[6]);
269 if (rc) {
270 ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
271 rc, outs[5]);
272
273 ehca_plpar_hcall_norets(H_FREE_RESOURCE,
274 adapter_handle.handle, /* r4 */
275 cq->ipz_cq_handle.handle, /* r5 */
276 0, 0, 0, 0, 0);
277 ret = H_NO_MEM;
278 }
279 }
Heiko J Schickfab97222006-09-22 15:22:22 -0700280
281 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800282 ehca_gen_err("Not enough resources. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700283
284 return ret;
285}
286
287u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
Stefan Roscher1988d1f2009-05-13 16:52:43 -0700288 struct ehca_alloc_qp_parms *parms, int is_user)
Heiko J Schickfab97222006-09-22 15:22:22 -0700289{
Alexander Schmidte675b6d2010-07-05 16:19:25 +0000290 int rc;
Heiko J Schickfab97222006-09-22 15:22:22 -0700291 u64 ret;
Joachim Fenkesa6a12942007-07-09 15:25:10 +0200292 u64 allocate_controls, max_r10_reg, r11, r12;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800293 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700294
295 allocate_controls =
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200296 EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS, parms->ext_type)
Heiko J Schickfab97222006-09-22 15:22:22 -0700297 | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0)
298 | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype)
299 | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype)
Stefan Roschere2f81da2007-07-20 16:04:17 +0200300 | EHCA_BMASK_SET(H_ALL_RES_QP_STORAGE, parms->qp_storage)
301 | EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_SQ_PAGE_SIZE,
302 parms->squeue.page_size)
303 | EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_RQ_PAGE_SIZE,
304 parms->rqueue.page_size)
Heiko J Schickfab97222006-09-22 15:22:22 -0700305 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING,
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200306 !!(parms->ll_comp_flags & LLQP_RECV_COMP))
Heiko J Schickfab97222006-09-22 15:22:22 -0700307 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING,
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200308 !!(parms->ll_comp_flags & LLQP_SEND_COMP))
Heiko J Schickfab97222006-09-22 15:22:22 -0700309 | EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL,
310 parms->ud_av_l_key_ctl)
311 | EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE, 1);
312
313 max_r10_reg =
314 EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
Stefan Roschere2f81da2007-07-20 16:04:17 +0200315 parms->squeue.max_wr + 1)
Heiko J Schickfab97222006-09-22 15:22:22 -0700316 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
Stefan Roschere2f81da2007-07-20 16:04:17 +0200317 parms->rqueue.max_wr + 1)
Heiko J Schickfab97222006-09-22 15:22:22 -0700318 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
Stefan Roschere2f81da2007-07-20 16:04:17 +0200319 parms->squeue.max_sge)
Heiko J Schickfab97222006-09-22 15:22:22 -0700320 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
Stefan Roschere2f81da2007-07-20 16:04:17 +0200321 parms->rqueue.max_sge);
Heiko J Schickfab97222006-09-22 15:22:22 -0700322
Joachim Fenkesa6a12942007-07-09 15:25:10 +0200323 r11 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QP_TOKEN, parms->srq_token);
324
325 if (parms->ext_type == EQPT_SRQ)
326 r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_LIMIT, parms->srq_limit);
327 else
328 r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QPN, parms->srq_qpn);
329
Heiko J Schickfab97222006-09-22 15:22:22 -0700330 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
331 adapter_handle.handle, /* r4 */
332 allocate_controls, /* r5 */
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200333 parms->send_cq_handle.handle,
334 parms->recv_cq_handle.handle,
335 parms->eq_handle.handle,
336 ((u64)parms->token << 32) | parms->pd.value,
Joachim Fenkesa6a12942007-07-09 15:25:10 +0200337 max_r10_reg, r11, r12);
Joachim Fenkes9a79fc02007-07-09 15:23:15 +0200338
339 parms->qp_handle.handle = outs[0];
340 parms->real_qp_num = (u32)outs[1];
Stefan Roschere2f81da2007-07-20 16:04:17 +0200341 parms->squeue.act_nr_wqes =
Heiko J Schickfab97222006-09-22 15:22:22 -0700342 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200343 parms->rqueue.act_nr_wqes =
Heiko J Schickfab97222006-09-22 15:22:22 -0700344 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200345 parms->squeue.act_nr_sges =
Heiko J Schickfab97222006-09-22 15:22:22 -0700346 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200347 parms->rqueue.act_nr_sges =
Heiko J Schickfab97222006-09-22 15:22:22 -0700348 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200349 parms->squeue.queue_size =
Heiko J Schickfab97222006-09-22 15:22:22 -0700350 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]);
Stefan Roschere2f81da2007-07-20 16:04:17 +0200351 parms->rqueue.queue_size =
Heiko J Schickfab97222006-09-22 15:22:22 -0700352 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
353
Alexander Schmidte675b6d2010-07-05 16:19:25 +0000354 if (ret == H_SUCCESS) {
355 rc = hcp_galpas_ctor(&parms->galpas, is_user, outs[6], outs[6]);
356 if (rc) {
357 ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
358 rc, outs[6]);
359
360 ehca_plpar_hcall_norets(H_FREE_RESOURCE,
361 adapter_handle.handle, /* r4 */
362 parms->qp_handle.handle, /* r5 */
363 0, 0, 0, 0, 0);
364 ret = H_NO_MEM;
365 }
366 }
Heiko J Schickfab97222006-09-22 15:22:22 -0700367
368 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800369 ehca_gen_err("Not enough resources. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700370
371 return ret;
372}
373
374u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
375 const u8 port_id,
376 struct hipz_query_port *query_port_response_block)
377{
378 u64 ret;
Michael Ellermanb4b8d1e2012-07-25 21:19:53 +0000379 u64 r_cb = __pa(query_port_response_block);
Heiko J Schickfab97222006-09-22 15:22:22 -0700380
381 if (r_cb & (EHCA_PAGESIZE-1)) {
382 ehca_gen_err("response block not page aligned");
383 return H_PARAMETER;
384 }
385
386 ret = ehca_plpar_hcall_norets(H_QUERY_PORT,
387 adapter_handle.handle, /* r4 */
388 port_id, /* r5 */
389 r_cb, /* r6 */
390 0, 0, 0, 0);
391
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700392 if (ehca_debug_level >= 2)
Heiko J Schickfab97222006-09-22 15:22:22 -0700393 ehca_dmp(query_port_response_block, 64, "response_block");
394
395 return ret;
396}
397
Joachim Fenkesc4ed7902007-04-24 17:44:31 +0200398u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle,
399 const u8 port_id, const u32 port_cap,
400 const u8 init_type, const int modify_mask)
401{
402 u64 port_attributes = port_cap;
403
404 if (modify_mask & IB_PORT_SHUTDOWN)
405 port_attributes |= EHCA_BMASK_SET(H_MP_SHUTDOWN, 1);
406 if (modify_mask & IB_PORT_INIT_TYPE)
407 port_attributes |= EHCA_BMASK_SET(H_MP_INIT_TYPE, init_type);
408 if (modify_mask & IB_PORT_RESET_QKEY_CNTR)
409 port_attributes |= EHCA_BMASK_SET(H_MP_RESET_QKEY_CTR, 1);
410
411 return ehca_plpar_hcall_norets(H_MODIFY_PORT,
412 adapter_handle.handle, /* r4 */
413 port_id, /* r5 */
414 port_attributes, /* r6 */
415 0, 0, 0, 0);
416}
417
Heiko J Schickfab97222006-09-22 15:22:22 -0700418u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
419 struct hipz_query_hca *query_hca_rblock)
420{
Michael Ellermanb4b8d1e2012-07-25 21:19:53 +0000421 u64 r_cb = __pa(query_hca_rblock);
Heiko J Schickfab97222006-09-22 15:22:22 -0700422
423 if (r_cb & (EHCA_PAGESIZE-1)) {
424 ehca_gen_err("response_block=%p not page aligned",
425 query_hca_rblock);
426 return H_PARAMETER;
427 }
428
429 return ehca_plpar_hcall_norets(H_QUERY_HCA,
430 adapter_handle.handle, /* r4 */
431 r_cb, /* r5 */
432 0, 0, 0, 0, 0);
433}
434
435u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,
436 const u8 pagesize,
437 const u8 queue_type,
438 const u64 resource_handle,
439 const u64 logical_address_of_page,
440 u64 count)
441{
442 return ehca_plpar_hcall_norets(H_REGISTER_RPAGES,
443 adapter_handle.handle, /* r4 */
Hoang-Nam Nguyen5bb7d922007-07-20 16:01:51 +0200444 (u64)queue_type | ((u64)pagesize) << 8,
445 /* r5 */
Heiko J Schickfab97222006-09-22 15:22:22 -0700446 resource_handle, /* r6 */
447 logical_address_of_page, /* r7 */
448 count, /* r8 */
449 0, 0);
450}
451
452u64 hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle,
453 const struct ipz_eq_handle eq_handle,
454 struct ehca_pfeq *pfeq,
455 const u8 pagesize,
456 const u8 queue_type,
457 const u64 logical_address_of_page,
458 const u64 count)
459{
460 if (count != 1) {
Stephen Rothwell3750f602009-01-16 14:55:28 -0800461 ehca_gen_err("Ppage counter=%llx", count);
Heiko J Schickfab97222006-09-22 15:22:22 -0700462 return H_PARAMETER;
463 }
464 return hipz_h_register_rpage(adapter_handle,
465 pagesize,
466 queue_type,
467 eq_handle.handle,
468 logical_address_of_page, count);
469}
470
471u64 hipz_h_query_int_state(const struct ipz_adapter_handle adapter_handle,
472 u32 ist)
473{
474 u64 ret;
475 ret = ehca_plpar_hcall_norets(H_QUERY_INT_STATE,
476 adapter_handle.handle, /* r4 */
477 ist, /* r5 */
478 0, 0, 0, 0, 0);
479
480 if (ret != H_SUCCESS && ret != H_BUSY)
481 ehca_gen_err("Could not query interrupt state.");
482
483 return ret;
484}
485
486u64 hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle,
487 const struct ipz_cq_handle cq_handle,
488 struct ehca_pfcq *pfcq,
489 const u8 pagesize,
490 const u8 queue_type,
491 const u64 logical_address_of_page,
492 const u64 count,
493 const struct h_galpa gal)
494{
495 if (count != 1) {
Stephen Rothwell3750f602009-01-16 14:55:28 -0800496 ehca_gen_err("Page counter=%llx", count);
Heiko J Schickfab97222006-09-22 15:22:22 -0700497 return H_PARAMETER;
498 }
499
500 return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
501 cq_handle.handle, logical_address_of_page,
502 count);
503}
504
505u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
506 const struct ipz_qp_handle qp_handle,
507 struct ehca_pfqp *pfqp,
508 const u8 pagesize,
509 const u8 queue_type,
510 const u64 logical_address_of_page,
511 const u64 count,
512 const struct h_galpa galpa)
513{
Stefan Roschere2f81da2007-07-20 16:04:17 +0200514 if (count > 1) {
Stephen Rothwell3750f602009-01-16 14:55:28 -0800515 ehca_gen_err("Page counter=%llx", count);
Heiko J Schickfab97222006-09-22 15:22:22 -0700516 return H_PARAMETER;
517 }
518
Hoang-Nam Nguyen2b943972007-07-12 17:53:47 +0200519 return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
520 qp_handle.handle, logical_address_of_page,
Heiko J Schickfab97222006-09-22 15:22:22 -0700521 count);
522}
523
524u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
525 const struct ipz_qp_handle qp_handle,
526 struct ehca_pfqp *pfqp,
527 void **log_addr_next_sq_wqe2processed,
528 void **log_addr_next_rq_wqe2processed,
529 int dis_and_get_function_code)
530{
531 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800532 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700533
534 ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
535 adapter_handle.handle, /* r4 */
536 dis_and_get_function_code, /* r5 */
537 qp_handle.handle, /* r6 */
538 0, 0, 0, 0, 0, 0);
539 if (log_addr_next_sq_wqe2processed)
Hoang-Nam Nguyen2b943972007-07-12 17:53:47 +0200540 *log_addr_next_sq_wqe2processed = (void *)outs[0];
Heiko J Schickfab97222006-09-22 15:22:22 -0700541 if (log_addr_next_rq_wqe2processed)
Hoang-Nam Nguyen2b943972007-07-12 17:53:47 +0200542 *log_addr_next_rq_wqe2processed = (void *)outs[1];
Heiko J Schickfab97222006-09-22 15:22:22 -0700543
544 return ret;
545}
546
547u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
548 const struct ipz_qp_handle qp_handle,
549 struct ehca_pfqp *pfqp,
550 const u64 update_mask,
551 struct hcp_modify_qp_control_block *mqpcb,
552 struct h_galpa gal)
553{
554 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800555 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700556 ret = ehca_plpar_hcall9(H_MODIFY_QP, outs,
557 adapter_handle.handle, /* r4 */
558 qp_handle.handle, /* r5 */
559 update_mask, /* r6 */
Michael Ellermanb4b8d1e2012-07-25 21:19:53 +0000560 __pa(mqpcb), /* r7 */
Heiko J Schickfab97222006-09-22 15:22:22 -0700561 0, 0, 0, 0, 0);
562
563 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800564 ehca_gen_err("Insufficient resources ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700565
566 return ret;
567}
568
569u64 hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle,
570 const struct ipz_qp_handle qp_handle,
571 struct ehca_pfqp *pfqp,
572 struct hcp_modify_qp_control_block *qqpcb,
573 struct h_galpa gal)
574{
575 return ehca_plpar_hcall_norets(H_QUERY_QP,
576 adapter_handle.handle, /* r4 */
577 qp_handle.handle, /* r5 */
Michael Ellermanb4b8d1e2012-07-25 21:19:53 +0000578 __pa(qqpcb), /* r6 */
Heiko J Schickfab97222006-09-22 15:22:22 -0700579 0, 0, 0, 0);
580}
581
582u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
583 struct ehca_qp *qp)
584{
585 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800586 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700587
588 ret = hcp_galpas_dtor(&qp->galpas);
589 if (ret) {
590 ehca_gen_err("Could not destruct qp->galpas");
591 return H_RESOURCE;
592 }
593 ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
594 adapter_handle.handle, /* r4 */
595 /* function code */
596 1, /* r5 */
597 qp->ipz_qp_handle.handle, /* r6 */
598 0, 0, 0, 0, 0, 0);
599 if (ret == H_HARDWARE)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800600 ehca_gen_err("HCA not operational. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700601
602 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
603 adapter_handle.handle, /* r4 */
604 qp->ipz_qp_handle.handle, /* r5 */
605 0, 0, 0, 0, 0);
606
607 if (ret == H_RESOURCE)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800608 ehca_gen_err("Resource still in use. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700609
610 return ret;
611}
612
613u64 hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle,
614 const struct ipz_qp_handle qp_handle,
615 struct h_galpa gal,
616 u32 port)
617{
618 return ehca_plpar_hcall_norets(H_DEFINE_AQP0,
619 adapter_handle.handle, /* r4 */
620 qp_handle.handle, /* r5 */
621 port, /* r6 */
622 0, 0, 0, 0);
623}
624
625u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
626 const struct ipz_qp_handle qp_handle,
627 struct h_galpa gal,
628 u32 port, u32 * pma_qp_nr,
629 u32 * bma_qp_nr)
630{
631 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800632 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700633
634 ret = ehca_plpar_hcall9(H_DEFINE_AQP1, outs,
635 adapter_handle.handle, /* r4 */
636 qp_handle.handle, /* r5 */
637 port, /* r6 */
638 0, 0, 0, 0, 0, 0);
639 *pma_qp_nr = (u32)outs[0];
640 *bma_qp_nr = (u32)outs[1];
641
642 if (ret == H_ALIAS_EXIST)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800643 ehca_gen_err("AQP1 already exists. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700644
645 return ret;
646}
647
648u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle,
649 const struct ipz_qp_handle qp_handle,
650 struct h_galpa gal,
651 u16 mcg_dlid,
652 u64 subnet_prefix, u64 interface_id)
653{
654 u64 ret;
655
656 ret = ehca_plpar_hcall_norets(H_ATTACH_MCQP,
657 adapter_handle.handle, /* r4 */
658 qp_handle.handle, /* r5 */
659 mcg_dlid, /* r6 */
660 interface_id, /* r7 */
661 subnet_prefix, /* r8 */
662 0, 0);
663
664 if (ret == H_NOT_ENOUGH_RESOURCES)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800665 ehca_gen_err("Not enough resources. ret=%lli", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700666
667 return ret;
668}
669
670u64 hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle,
671 const struct ipz_qp_handle qp_handle,
672 struct h_galpa gal,
673 u16 mcg_dlid,
674 u64 subnet_prefix, u64 interface_id)
675{
676 return ehca_plpar_hcall_norets(H_DETACH_MCQP,
677 adapter_handle.handle, /* r4 */
678 qp_handle.handle, /* r5 */
679 mcg_dlid, /* r6 */
680 interface_id, /* r7 */
681 subnet_prefix, /* r8 */
682 0, 0);
683}
684
685u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle,
686 struct ehca_cq *cq,
687 u8 force_flag)
688{
689 u64 ret;
690
691 ret = hcp_galpas_dtor(&cq->galpas);
692 if (ret) {
693 ehca_gen_err("Could not destruct cp->galpas");
694 return H_RESOURCE;
695 }
696
697 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
698 adapter_handle.handle, /* r4 */
699 cq->ipz_cq_handle.handle, /* r5 */
700 force_flag != 0 ? 1L : 0L, /* r6 */
701 0, 0, 0, 0);
702
703 if (ret == H_RESOURCE)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800704 ehca_gen_err("H_FREE_RESOURCE failed ret=%lli ", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700705
706 return ret;
707}
708
709u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle,
710 struct ehca_eq *eq)
711{
712 u64 ret;
713
714 ret = hcp_galpas_dtor(&eq->galpas);
715 if (ret) {
716 ehca_gen_err("Could not destruct eq->galpas");
717 return H_RESOURCE;
718 }
719
720 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
721 adapter_handle.handle, /* r4 */
722 eq->ipz_eq_handle.handle, /* r5 */
723 0, 0, 0, 0, 0);
724
725 if (ret == H_RESOURCE)
Stephen Rothwell3750f602009-01-16 14:55:28 -0800726 ehca_gen_err("Resource in use. ret=%lli ", ret);
Heiko J Schickfab97222006-09-22 15:22:22 -0700727
728 return ret;
729}
730
731u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
732 const struct ehca_mr *mr,
733 const u64 vaddr,
734 const u64 length,
735 const u32 access_ctrl,
736 const struct ipz_pd pd,
737 struct ehca_mr_hipzout_parms *outparms)
738{
739 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800740 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700741
742 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
743 adapter_handle.handle, /* r4 */
744 5, /* r5 */
745 vaddr, /* r6 */
746 length, /* r7 */
747 (((u64)access_ctrl) << 32ULL), /* r8 */
748 pd.value, /* r9 */
749 0, 0, 0);
750 outparms->handle.handle = outs[0];
751 outparms->lkey = (u32)outs[2];
752 outparms->rkey = (u32)outs[3];
753
754 return ret;
755}
756
757u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
758 const struct ehca_mr *mr,
759 const u8 pagesize,
760 const u8 queue_type,
761 const u64 logical_address_of_page,
762 const u64 count)
763{
764 u64 ret;
765
Joachim Fenkes4da27d62008-04-23 11:55:45 -0700766 if (unlikely(ehca_debug_level >= 3)) {
Hoang-Nam Nguyen5bb7d922007-07-20 16:01:51 +0200767 if (count > 1) {
768 u64 *kpage;
769 int i;
Michael Ellermanb4b8d1e2012-07-25 21:19:53 +0000770 kpage = __va(logical_address_of_page);
Hoang-Nam Nguyen5bb7d922007-07-20 16:01:51 +0200771 for (i = 0; i < count; i++)
772 ehca_gen_dbg("kpage[%d]=%p",
773 i, (void *)kpage[i]);
774 } else
775 ehca_gen_dbg("kpage=%p",
776 (void *)logical_address_of_page);
777 }
778
Heiko J Schickfab97222006-09-22 15:22:22 -0700779 if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) {
780 ehca_gen_err("logical_address_of_page not on a 4k boundary "
Stephen Rothwell3750f602009-01-16 14:55:28 -0800781 "adapter_handle=%llx mr=%p mr_handle=%llx "
Heiko J Schickfab97222006-09-22 15:22:22 -0700782 "pagesize=%x queue_type=%x "
Stephen Rothwell3750f602009-01-16 14:55:28 -0800783 "logical_address_of_page=%llx count=%llx",
Heiko J Schickfab97222006-09-22 15:22:22 -0700784 adapter_handle.handle, mr,
785 mr->ipz_mr_handle.handle, pagesize, queue_type,
786 logical_address_of_page, count);
787 ret = H_PARAMETER;
788 } else
789 ret = hipz_h_register_rpage(adapter_handle, pagesize,
790 queue_type,
791 mr->ipz_mr_handle.handle,
792 logical_address_of_page, count);
793 return ret;
794}
795
796u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,
797 const struct ehca_mr *mr,
798 struct ehca_mr_hipzout_parms *outparms)
799{
800 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800801 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700802
803 ret = ehca_plpar_hcall9(H_QUERY_MR, outs,
804 adapter_handle.handle, /* r4 */
805 mr->ipz_mr_handle.handle, /* r5 */
806 0, 0, 0, 0, 0, 0, 0);
807 outparms->len = outs[0];
808 outparms->vaddr = outs[1];
809 outparms->acl = outs[4] >> 32;
810 outparms->lkey = (u32)(outs[5] >> 32);
811 outparms->rkey = (u32)(outs[5] & (0xffffffff));
812
813 return ret;
814}
815
816u64 hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle,
817 const struct ehca_mr *mr)
818{
819 return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
820 adapter_handle.handle, /* r4 */
821 mr->ipz_mr_handle.handle, /* r5 */
Joachim Fenkes4faf7752007-12-10 18:59:10 +0100822 0, 0, 0, 0, 0);
Heiko J Schickfab97222006-09-22 15:22:22 -0700823}
824
825u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,
826 const struct ehca_mr *mr,
827 const u64 vaddr_in,
828 const u64 length,
829 const u32 access_ctrl,
830 const struct ipz_pd pd,
831 const u64 mr_addr_cb,
832 struct ehca_mr_hipzout_parms *outparms)
833{
834 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800835 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700836
837 ret = ehca_plpar_hcall9(H_REREGISTER_PMR, outs,
838 adapter_handle.handle, /* r4 */
839 mr->ipz_mr_handle.handle, /* r5 */
840 vaddr_in, /* r6 */
841 length, /* r7 */
842 /* r8 */
843 ((((u64)access_ctrl) << 32ULL) | pd.value),
844 mr_addr_cb, /* r9 */
845 0, 0, 0);
846 outparms->vaddr = outs[1];
847 outparms->lkey = (u32)outs[2];
848 outparms->rkey = (u32)outs[3];
849
850 return ret;
851}
852
853u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,
854 const struct ehca_mr *mr,
855 const struct ehca_mr *orig_mr,
856 const u64 vaddr_in,
857 const u32 access_ctrl,
858 const struct ipz_pd pd,
859 struct ehca_mr_hipzout_parms *outparms)
860{
861 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800862 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700863
864 ret = ehca_plpar_hcall9(H_REGISTER_SMR, outs,
865 adapter_handle.handle, /* r4 */
866 orig_mr->ipz_mr_handle.handle, /* r5 */
867 vaddr_in, /* r6 */
868 (((u64)access_ctrl) << 32ULL), /* r7 */
869 pd.value, /* r8 */
870 0, 0, 0, 0);
871 outparms->handle.handle = outs[0];
872 outparms->lkey = (u32)outs[2];
873 outparms->rkey = (u32)outs[3];
874
875 return ret;
876}
877
878u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,
879 const struct ehca_mw *mw,
880 const struct ipz_pd pd,
881 struct ehca_mw_hipzout_parms *outparms)
882{
883 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800884 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700885
886 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
887 adapter_handle.handle, /* r4 */
888 6, /* r5 */
889 pd.value, /* r6 */
890 0, 0, 0, 0, 0, 0);
891 outparms->handle.handle = outs[0];
892 outparms->rkey = (u32)outs[3];
893
894 return ret;
895}
896
897u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,
898 const struct ehca_mw *mw,
899 struct ehca_mw_hipzout_parms *outparms)
900{
901 u64 ret;
Stephen Rothwellee96aae2009-01-16 14:55:40 -0800902 unsigned long outs[PLPAR_HCALL9_BUFSIZE];
Heiko J Schickfab97222006-09-22 15:22:22 -0700903
904 ret = ehca_plpar_hcall9(H_QUERY_MW, outs,
905 adapter_handle.handle, /* r4 */
906 mw->ipz_mw_handle.handle, /* r5 */
907 0, 0, 0, 0, 0, 0, 0);
908 outparms->rkey = (u32)outs[3];
909
910 return ret;
911}
912
913u64 hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle,
914 const struct ehca_mw *mw)
915{
916 return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
917 adapter_handle.handle, /* r4 */
918 mw->ipz_mw_handle.handle, /* r5 */
919 0, 0, 0, 0, 0);
920}
921
922u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
923 const u64 ressource_handle,
924 void *rblock,
925 unsigned long *byte_count)
926{
Michael Ellermanb4b8d1e2012-07-25 21:19:53 +0000927 u64 r_cb = __pa(rblock);
Heiko J Schickfab97222006-09-22 15:22:22 -0700928
929 if (r_cb & (EHCA_PAGESIZE-1)) {
930 ehca_gen_err("rblock not page aligned.");
931 return H_PARAMETER;
932 }
933
934 return ehca_plpar_hcall_norets(H_ERROR_DATA,
935 adapter_handle.handle,
936 ressource_handle,
937 r_cb,
938 0, 0, 0, 0);
939}
Stefan Roscher6f7bc012008-07-14 23:48:47 -0700940
941u64 hipz_h_eoi(int irq)
942{
943 unsigned long xirr;
944
945 iosync();
946 xirr = (0xffULL << 24) | irq;
947
948 return plpar_hcall_norets(H_EOI, xirr);
949}