Merge branch 'sh/pci-express-integration'
[pandora-kernel.git] / drivers / infiniband / hw / ehca / hcp_if.c
1 /*
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>
8  *           Joachim Fenkes <fenkes@de.ibm.com>
9  *           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)
55 #define H_ALL_RES_QP_STORAGE            EHCA_BMASK_IBM(16, 17)
56 #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)
60 #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)
62 #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
69 #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
75 #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
83 #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
87 #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
91 static DEFINE_SPINLOCK(hcall_lock);
92
93 static 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
113 static 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;
123         int i, sleep_msecs;
124         unsigned long flags = 0;
125
126         if (unlikely(ehca_debug_level >= 2))
127                 ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT,
128                              opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
129
130         for (i = 0; i < 5; i++) {
131                 /* serialize hCalls to work around firmware issue */
132                 if (ehca_lock_hcalls)
133                         spin_lock_irqsave(&hcall_lock, flags);
134
135                 ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4,
136                                          arg5, arg6, arg7);
137
138                 if (ehca_lock_hcalls)
139                         spin_unlock_irqrestore(&hcall_lock, flags);
140
141                 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)
148                         ehca_gen_err("opcode=%lx ret=%li " HCALL7_REGS_FORMAT,
149                                      opcode, ret, arg1, arg2, arg3,
150                                      arg4, arg5, arg6, arg7);
151                 else
152                         if (unlikely(ehca_debug_level >= 2))
153                                 ehca_gen_dbg("opcode=%lx ret=%li", opcode, ret);
154
155                 return ret;
156         }
157
158         return H_BUSY;
159 }
160
161 static 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;
174         int i, sleep_msecs;
175         unsigned long flags = 0;
176
177         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);
181
182         for (i = 0; i < 5; i++) {
183                 /* serialize hCalls to work around firmware issue */
184                 if (ehca_lock_hcalls)
185                         spin_lock_irqsave(&hcall_lock, flags);
186
187                 ret = plpar_hcall9(opcode, outs,
188                                    arg1, arg2, arg3, arg4, arg5,
189                                    arg6, arg7, arg8, arg9);
190
191                 if (ehca_lock_hcalls)
192                         spin_unlock_irqrestore(&hcall_lock, flags);
193
194                 if (H_IS_LONG_BUSY(ret)) {
195                         sleep_msecs = get_longbusy_msecs(ret);
196                         msleep_interruptible(sleep_msecs);
197                         continue;
198                 }
199
200                 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],
206                                      outs[4], outs[5], outs[6], outs[7],
207                                      outs[8]);
208                 } else if (unlikely(ehca_debug_level >= 2))
209                         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]);
213                 return ret;
214         }
215
216         return H_BUSY;
217 }
218
219 u64 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;
229         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
230         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)
252                 ehca_gen_err("Not enough resource - ret=%lli ", ret);
253
254         return ret;
255 }
256
257 u64 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
268 u64 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         int rc;
273         u64 ret;
274         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
275
276         ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
277                                 adapter_handle.handle,   /* r4  */
278                                 2,                       /* r5  */
279                                 param->eq_handle.handle, /* r6  */
280                                 cq->token,               /* r7  */
281                                 param->nr_cqe,           /* r8  */
282                                 0, 0, 0, 0);
283         cq->ipz_cq_handle.handle = outs[0];
284         param->act_nr_of_entries = (u32)outs[3];
285         param->act_pages = (u32)outs[4];
286
287         if (ret == H_SUCCESS) {
288                 rc = hcp_galpas_ctor(&cq->galpas, 0, outs[5], outs[6]);
289                 if (rc) {
290                         ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
291                                      rc, outs[5]);
292
293                         ehca_plpar_hcall_norets(H_FREE_RESOURCE,
294                                                 adapter_handle.handle,     /* r4 */
295                                                 cq->ipz_cq_handle.handle,  /* r5 */
296                                                 0, 0, 0, 0, 0);
297                         ret = H_NO_MEM;
298                 }
299         }
300
301         if (ret == H_NOT_ENOUGH_RESOURCES)
302                 ehca_gen_err("Not enough resources. ret=%lli", ret);
303
304         return ret;
305 }
306
307 u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
308                              struct ehca_alloc_qp_parms *parms, int is_user)
309 {
310         int rc;
311         u64 ret;
312         u64 allocate_controls, max_r10_reg, r11, r12;
313         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
314
315         allocate_controls =
316                 EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS, parms->ext_type)
317                 | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0)
318                 | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype)
319                 | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype)
320                 | EHCA_BMASK_SET(H_ALL_RES_QP_STORAGE, parms->qp_storage)
321                 | EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_SQ_PAGE_SIZE,
322                                  parms->squeue.page_size)
323                 | EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_RQ_PAGE_SIZE,
324                                  parms->rqueue.page_size)
325                 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING,
326                                  !!(parms->ll_comp_flags & LLQP_RECV_COMP))
327                 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING,
328                                  !!(parms->ll_comp_flags & LLQP_SEND_COMP))
329                 | EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL,
330                                  parms->ud_av_l_key_ctl)
331                 | EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE, 1);
332
333         max_r10_reg =
334                 EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
335                                parms->squeue.max_wr + 1)
336                 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
337                                  parms->rqueue.max_wr + 1)
338                 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
339                                  parms->squeue.max_sge)
340                 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
341                                  parms->rqueue.max_sge);
342
343         r11 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QP_TOKEN, parms->srq_token);
344
345         if (parms->ext_type == EQPT_SRQ)
346                 r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_LIMIT, parms->srq_limit);
347         else
348                 r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QPN, parms->srq_qpn);
349
350         ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
351                                 adapter_handle.handle,             /* r4  */
352                                 allocate_controls,                 /* r5  */
353                                 parms->send_cq_handle.handle,
354                                 parms->recv_cq_handle.handle,
355                                 parms->eq_handle.handle,
356                                 ((u64)parms->token << 32) | parms->pd.value,
357                                 max_r10_reg, r11, r12);
358
359         parms->qp_handle.handle = outs[0];
360         parms->real_qp_num = (u32)outs[1];
361         parms->squeue.act_nr_wqes =
362                 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
363         parms->rqueue.act_nr_wqes =
364                 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
365         parms->squeue.act_nr_sges =
366                 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]);
367         parms->rqueue.act_nr_sges =
368                 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]);
369         parms->squeue.queue_size =
370                 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]);
371         parms->rqueue.queue_size =
372                 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
373
374         if (ret == H_SUCCESS) {
375                 rc = hcp_galpas_ctor(&parms->galpas, is_user, outs[6], outs[6]);
376                 if (rc) {
377                         ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
378                                      rc, outs[6]);
379
380                         ehca_plpar_hcall_norets(H_FREE_RESOURCE,
381                                                 adapter_handle.handle,     /* r4 */
382                                                 parms->qp_handle.handle,  /* r5 */
383                                                 0, 0, 0, 0, 0);
384                         ret = H_NO_MEM;
385                 }
386         }
387
388         if (ret == H_NOT_ENOUGH_RESOURCES)
389                 ehca_gen_err("Not enough resources. ret=%lli", ret);
390
391         return ret;
392 }
393
394 u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
395                       const u8 port_id,
396                       struct hipz_query_port *query_port_response_block)
397 {
398         u64 ret;
399         u64 r_cb = virt_to_abs(query_port_response_block);
400
401         if (r_cb & (EHCA_PAGESIZE-1)) {
402                 ehca_gen_err("response block not page aligned");
403                 return H_PARAMETER;
404         }
405
406         ret = ehca_plpar_hcall_norets(H_QUERY_PORT,
407                                       adapter_handle.handle, /* r4 */
408                                       port_id,               /* r5 */
409                                       r_cb,                  /* r6 */
410                                       0, 0, 0, 0);
411
412         if (ehca_debug_level >= 2)
413                 ehca_dmp(query_port_response_block, 64, "response_block");
414
415         return ret;
416 }
417
418 u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle,
419                        const u8 port_id, const u32 port_cap,
420                        const u8 init_type, const int modify_mask)
421 {
422         u64 port_attributes = port_cap;
423
424         if (modify_mask & IB_PORT_SHUTDOWN)
425                 port_attributes |= EHCA_BMASK_SET(H_MP_SHUTDOWN, 1);
426         if (modify_mask & IB_PORT_INIT_TYPE)
427                 port_attributes |= EHCA_BMASK_SET(H_MP_INIT_TYPE, init_type);
428         if (modify_mask & IB_PORT_RESET_QKEY_CNTR)
429                 port_attributes |= EHCA_BMASK_SET(H_MP_RESET_QKEY_CTR, 1);
430
431         return ehca_plpar_hcall_norets(H_MODIFY_PORT,
432                                        adapter_handle.handle, /* r4 */
433                                        port_id,               /* r5 */
434                                        port_attributes,       /* r6 */
435                                        0, 0, 0, 0);
436 }
437
438 u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
439                      struct hipz_query_hca *query_hca_rblock)
440 {
441         u64 r_cb = virt_to_abs(query_hca_rblock);
442
443         if (r_cb & (EHCA_PAGESIZE-1)) {
444                 ehca_gen_err("response_block=%p not page aligned",
445                              query_hca_rblock);
446                 return H_PARAMETER;
447         }
448
449         return ehca_plpar_hcall_norets(H_QUERY_HCA,
450                                        adapter_handle.handle, /* r4 */
451                                        r_cb,                  /* r5 */
452                                        0, 0, 0, 0, 0);
453 }
454
455 u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,
456                           const u8 pagesize,
457                           const u8 queue_type,
458                           const u64 resource_handle,
459                           const u64 logical_address_of_page,
460                           u64 count)
461 {
462         return ehca_plpar_hcall_norets(H_REGISTER_RPAGES,
463                                        adapter_handle.handle,      /* r4  */
464                                        (u64)queue_type | ((u64)pagesize) << 8,
465                                        /* r5  */
466                                        resource_handle,            /* r6  */
467                                        logical_address_of_page,    /* r7  */
468                                        count,                      /* r8  */
469                                        0, 0);
470 }
471
472 u64 hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle,
473                              const struct ipz_eq_handle eq_handle,
474                              struct ehca_pfeq *pfeq,
475                              const u8 pagesize,
476                              const u8 queue_type,
477                              const u64 logical_address_of_page,
478                              const u64 count)
479 {
480         if (count != 1) {
481                 ehca_gen_err("Ppage counter=%llx", count);
482                 return H_PARAMETER;
483         }
484         return hipz_h_register_rpage(adapter_handle,
485                                      pagesize,
486                                      queue_type,
487                                      eq_handle.handle,
488                                      logical_address_of_page, count);
489 }
490
491 u64 hipz_h_query_int_state(const struct ipz_adapter_handle adapter_handle,
492                            u32 ist)
493 {
494         u64 ret;
495         ret = ehca_plpar_hcall_norets(H_QUERY_INT_STATE,
496                                       adapter_handle.handle, /* r4 */
497                                       ist,                   /* r5 */
498                                       0, 0, 0, 0, 0);
499
500         if (ret != H_SUCCESS && ret != H_BUSY)
501                 ehca_gen_err("Could not query interrupt state.");
502
503         return ret;
504 }
505
506 u64 hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle,
507                              const struct ipz_cq_handle cq_handle,
508                              struct ehca_pfcq *pfcq,
509                              const u8 pagesize,
510                              const u8 queue_type,
511                              const u64 logical_address_of_page,
512                              const u64 count,
513                              const struct h_galpa gal)
514 {
515         if (count != 1) {
516                 ehca_gen_err("Page counter=%llx", count);
517                 return H_PARAMETER;
518         }
519
520         return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
521                                      cq_handle.handle, logical_address_of_page,
522                                      count);
523 }
524
525 u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
526                              const struct ipz_qp_handle qp_handle,
527                              struct ehca_pfqp *pfqp,
528                              const u8 pagesize,
529                              const u8 queue_type,
530                              const u64 logical_address_of_page,
531                              const u64 count,
532                              const struct h_galpa galpa)
533 {
534         if (count > 1) {
535                 ehca_gen_err("Page counter=%llx", count);
536                 return H_PARAMETER;
537         }
538
539         return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
540                                      qp_handle.handle, logical_address_of_page,
541                                      count);
542 }
543
544 u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
545                                const struct ipz_qp_handle qp_handle,
546                                struct ehca_pfqp *pfqp,
547                                void **log_addr_next_sq_wqe2processed,
548                                void **log_addr_next_rq_wqe2processed,
549                                int dis_and_get_function_code)
550 {
551         u64 ret;
552         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
553
554         ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
555                                 adapter_handle.handle,     /* r4 */
556                                 dis_and_get_function_code, /* r5 */
557                                 qp_handle.handle,          /* r6 */
558                                 0, 0, 0, 0, 0, 0);
559         if (log_addr_next_sq_wqe2processed)
560                 *log_addr_next_sq_wqe2processed = (void *)outs[0];
561         if (log_addr_next_rq_wqe2processed)
562                 *log_addr_next_rq_wqe2processed = (void *)outs[1];
563
564         return ret;
565 }
566
567 u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
568                      const struct ipz_qp_handle qp_handle,
569                      struct ehca_pfqp *pfqp,
570                      const u64 update_mask,
571                      struct hcp_modify_qp_control_block *mqpcb,
572                      struct h_galpa gal)
573 {
574         u64 ret;
575         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
576         ret = ehca_plpar_hcall9(H_MODIFY_QP, outs,
577                                 adapter_handle.handle, /* r4 */
578                                 qp_handle.handle,      /* r5 */
579                                 update_mask,           /* r6 */
580                                 virt_to_abs(mqpcb),    /* r7 */
581                                 0, 0, 0, 0, 0);
582
583         if (ret == H_NOT_ENOUGH_RESOURCES)
584                 ehca_gen_err("Insufficient resources ret=%lli", ret);
585
586         return ret;
587 }
588
589 u64 hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle,
590                     const struct ipz_qp_handle qp_handle,
591                     struct ehca_pfqp *pfqp,
592                     struct hcp_modify_qp_control_block *qqpcb,
593                     struct h_galpa gal)
594 {
595         return ehca_plpar_hcall_norets(H_QUERY_QP,
596                                        adapter_handle.handle, /* r4 */
597                                        qp_handle.handle,      /* r5 */
598                                        virt_to_abs(qqpcb),    /* r6 */
599                                        0, 0, 0, 0);
600 }
601
602 u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
603                       struct ehca_qp *qp)
604 {
605         u64 ret;
606         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
607
608         ret = hcp_galpas_dtor(&qp->galpas);
609         if (ret) {
610                 ehca_gen_err("Could not destruct qp->galpas");
611                 return H_RESOURCE;
612         }
613         ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
614                                 adapter_handle.handle,     /* r4 */
615                                 /* function code */
616                                 1,                         /* r5 */
617                                 qp->ipz_qp_handle.handle,  /* r6 */
618                                 0, 0, 0, 0, 0, 0);
619         if (ret == H_HARDWARE)
620                 ehca_gen_err("HCA not operational. ret=%lli", ret);
621
622         ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
623                                       adapter_handle.handle,     /* r4 */
624                                       qp->ipz_qp_handle.handle,  /* r5 */
625                                       0, 0, 0, 0, 0);
626
627         if (ret == H_RESOURCE)
628                 ehca_gen_err("Resource still in use. ret=%lli", ret);
629
630         return ret;
631 }
632
633 u64 hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle,
634                        const struct ipz_qp_handle qp_handle,
635                        struct h_galpa gal,
636                        u32 port)
637 {
638         return ehca_plpar_hcall_norets(H_DEFINE_AQP0,
639                                        adapter_handle.handle, /* r4 */
640                                        qp_handle.handle,      /* r5 */
641                                        port,                  /* r6 */
642                                        0, 0, 0, 0);
643 }
644
645 u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
646                        const struct ipz_qp_handle qp_handle,
647                        struct h_galpa gal,
648                        u32 port, u32 * pma_qp_nr,
649                        u32 * bma_qp_nr)
650 {
651         u64 ret;
652         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
653
654         ret = ehca_plpar_hcall9(H_DEFINE_AQP1, outs,
655                                 adapter_handle.handle, /* r4 */
656                                 qp_handle.handle,      /* r5 */
657                                 port,                  /* r6 */
658                                 0, 0, 0, 0, 0, 0);
659         *pma_qp_nr = (u32)outs[0];
660         *bma_qp_nr = (u32)outs[1];
661
662         if (ret == H_ALIAS_EXIST)
663                 ehca_gen_err("AQP1 already exists. ret=%lli", ret);
664
665         return ret;
666 }
667
668 u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle,
669                        const struct ipz_qp_handle qp_handle,
670                        struct h_galpa gal,
671                        u16 mcg_dlid,
672                        u64 subnet_prefix, u64 interface_id)
673 {
674         u64 ret;
675
676         ret = ehca_plpar_hcall_norets(H_ATTACH_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         if (ret == H_NOT_ENOUGH_RESOURCES)
685                 ehca_gen_err("Not enough resources. ret=%lli", ret);
686
687         return ret;
688 }
689
690 u64 hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle,
691                        const struct ipz_qp_handle qp_handle,
692                        struct h_galpa gal,
693                        u16 mcg_dlid,
694                        u64 subnet_prefix, u64 interface_id)
695 {
696         return ehca_plpar_hcall_norets(H_DETACH_MCQP,
697                                        adapter_handle.handle, /* r4 */
698                                        qp_handle.handle,      /* r5 */
699                                        mcg_dlid,              /* r6 */
700                                        interface_id,          /* r7 */
701                                        subnet_prefix,         /* r8 */
702                                        0, 0);
703 }
704
705 u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle,
706                       struct ehca_cq *cq,
707                       u8 force_flag)
708 {
709         u64 ret;
710
711         ret = hcp_galpas_dtor(&cq->galpas);
712         if (ret) {
713                 ehca_gen_err("Could not destruct cp->galpas");
714                 return H_RESOURCE;
715         }
716
717         ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
718                                       adapter_handle.handle,     /* r4 */
719                                       cq->ipz_cq_handle.handle,  /* r5 */
720                                       force_flag != 0 ? 1L : 0L, /* r6 */
721                                       0, 0, 0, 0);
722
723         if (ret == H_RESOURCE)
724                 ehca_gen_err("H_FREE_RESOURCE failed ret=%lli ", ret);
725
726         return ret;
727 }
728
729 u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle,
730                       struct ehca_eq *eq)
731 {
732         u64 ret;
733
734         ret = hcp_galpas_dtor(&eq->galpas);
735         if (ret) {
736                 ehca_gen_err("Could not destruct eq->galpas");
737                 return H_RESOURCE;
738         }
739
740         ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
741                                       adapter_handle.handle,     /* r4 */
742                                       eq->ipz_eq_handle.handle,  /* r5 */
743                                       0, 0, 0, 0, 0);
744
745         if (ret == H_RESOURCE)
746                 ehca_gen_err("Resource in use. ret=%lli ", ret);
747
748         return ret;
749 }
750
751 u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
752                              const struct ehca_mr *mr,
753                              const u64 vaddr,
754                              const u64 length,
755                              const u32 access_ctrl,
756                              const struct ipz_pd pd,
757                              struct ehca_mr_hipzout_parms *outparms)
758 {
759         u64 ret;
760         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
761
762         ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
763                                 adapter_handle.handle,            /* r4 */
764                                 5,                                /* r5 */
765                                 vaddr,                            /* r6 */
766                                 length,                           /* r7 */
767                                 (((u64)access_ctrl) << 32ULL),    /* r8 */
768                                 pd.value,                         /* r9 */
769                                 0, 0, 0);
770         outparms->handle.handle = outs[0];
771         outparms->lkey = (u32)outs[2];
772         outparms->rkey = (u32)outs[3];
773
774         return ret;
775 }
776
777 u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
778                              const struct ehca_mr *mr,
779                              const u8 pagesize,
780                              const u8 queue_type,
781                              const u64 logical_address_of_page,
782                              const u64 count)
783 {
784         u64 ret;
785
786         if (unlikely(ehca_debug_level >= 3)) {
787                 if (count > 1) {
788                         u64 *kpage;
789                         int i;
790                         kpage = (u64 *)abs_to_virt(logical_address_of_page);
791                         for (i = 0; i < count; i++)
792                                 ehca_gen_dbg("kpage[%d]=%p",
793                                              i, (void *)kpage[i]);
794                 } else
795                         ehca_gen_dbg("kpage=%p",
796                                      (void *)logical_address_of_page);
797         }
798
799         if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) {
800                 ehca_gen_err("logical_address_of_page not on a 4k boundary "
801                              "adapter_handle=%llx mr=%p mr_handle=%llx "
802                              "pagesize=%x queue_type=%x "
803                              "logical_address_of_page=%llx count=%llx",
804                              adapter_handle.handle, mr,
805                              mr->ipz_mr_handle.handle, pagesize, queue_type,
806                              logical_address_of_page, count);
807                 ret = H_PARAMETER;
808         } else
809                 ret = hipz_h_register_rpage(adapter_handle, pagesize,
810                                             queue_type,
811                                             mr->ipz_mr_handle.handle,
812                                             logical_address_of_page, count);
813         return ret;
814 }
815
816 u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,
817                     const struct ehca_mr *mr,
818                     struct ehca_mr_hipzout_parms *outparms)
819 {
820         u64 ret;
821         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
822
823         ret = ehca_plpar_hcall9(H_QUERY_MR, outs,
824                                 adapter_handle.handle,     /* r4 */
825                                 mr->ipz_mr_handle.handle,  /* r5 */
826                                 0, 0, 0, 0, 0, 0, 0);
827         outparms->len = outs[0];
828         outparms->vaddr = outs[1];
829         outparms->acl  = outs[4] >> 32;
830         outparms->lkey = (u32)(outs[5] >> 32);
831         outparms->rkey = (u32)(outs[5] & (0xffffffff));
832
833         return ret;
834 }
835
836 u64 hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle,
837                             const struct ehca_mr *mr)
838 {
839         return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
840                                        adapter_handle.handle,    /* r4 */
841                                        mr->ipz_mr_handle.handle, /* r5 */
842                                        0, 0, 0, 0, 0);
843 }
844
845 u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,
846                           const struct ehca_mr *mr,
847                           const u64 vaddr_in,
848                           const u64 length,
849                           const u32 access_ctrl,
850                           const struct ipz_pd pd,
851                           const u64 mr_addr_cb,
852                           struct ehca_mr_hipzout_parms *outparms)
853 {
854         u64 ret;
855         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
856
857         ret = ehca_plpar_hcall9(H_REREGISTER_PMR, outs,
858                                 adapter_handle.handle,    /* r4 */
859                                 mr->ipz_mr_handle.handle, /* r5 */
860                                 vaddr_in,                 /* r6 */
861                                 length,                   /* r7 */
862                                 /* r8 */
863                                 ((((u64)access_ctrl) << 32ULL) | pd.value),
864                                 mr_addr_cb,               /* r9 */
865                                 0, 0, 0);
866         outparms->vaddr = outs[1];
867         outparms->lkey = (u32)outs[2];
868         outparms->rkey = (u32)outs[3];
869
870         return ret;
871 }
872
873 u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,
874                         const struct ehca_mr *mr,
875                         const struct ehca_mr *orig_mr,
876                         const u64 vaddr_in,
877                         const u32 access_ctrl,
878                         const struct ipz_pd pd,
879                         struct ehca_mr_hipzout_parms *outparms)
880 {
881         u64 ret;
882         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
883
884         ret = ehca_plpar_hcall9(H_REGISTER_SMR, outs,
885                                 adapter_handle.handle,            /* r4 */
886                                 orig_mr->ipz_mr_handle.handle,    /* r5 */
887                                 vaddr_in,                         /* r6 */
888                                 (((u64)access_ctrl) << 32ULL),    /* r7 */
889                                 pd.value,                         /* r8 */
890                                 0, 0, 0, 0);
891         outparms->handle.handle = outs[0];
892         outparms->lkey = (u32)outs[2];
893         outparms->rkey = (u32)outs[3];
894
895         return ret;
896 }
897
898 u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,
899                              const struct ehca_mw *mw,
900                              const struct ipz_pd pd,
901                              struct ehca_mw_hipzout_parms *outparms)
902 {
903         u64 ret;
904         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
905
906         ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
907                                 adapter_handle.handle,      /* r4 */
908                                 6,                          /* r5 */
909                                 pd.value,                   /* r6 */
910                                 0, 0, 0, 0, 0, 0);
911         outparms->handle.handle = outs[0];
912         outparms->rkey = (u32)outs[3];
913
914         return ret;
915 }
916
917 u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,
918                     const struct ehca_mw *mw,
919                     struct ehca_mw_hipzout_parms *outparms)
920 {
921         u64 ret;
922         unsigned long outs[PLPAR_HCALL9_BUFSIZE];
923
924         ret = ehca_plpar_hcall9(H_QUERY_MW, outs,
925                                 adapter_handle.handle,    /* r4 */
926                                 mw->ipz_mw_handle.handle, /* r5 */
927                                 0, 0, 0, 0, 0, 0, 0);
928         outparms->rkey = (u32)outs[3];
929
930         return ret;
931 }
932
933 u64 hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle,
934                             const struct ehca_mw *mw)
935 {
936         return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
937                                        adapter_handle.handle,    /* r4 */
938                                        mw->ipz_mw_handle.handle, /* r5 */
939                                        0, 0, 0, 0, 0);
940 }
941
942 u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
943                       const u64 ressource_handle,
944                       void *rblock,
945                       unsigned long *byte_count)
946 {
947         u64 r_cb = virt_to_abs(rblock);
948
949         if (r_cb & (EHCA_PAGESIZE-1)) {
950                 ehca_gen_err("rblock not page aligned.");
951                 return H_PARAMETER;
952         }
953
954         return ehca_plpar_hcall_norets(H_ERROR_DATA,
955                                        adapter_handle.handle,
956                                        ressource_handle,
957                                        r_cb,
958                                        0, 0, 0, 0);
959 }
960
961 u64 hipz_h_eoi(int irq)
962 {
963         unsigned long xirr;
964
965         iosync();
966         xirr = (0xffULL << 24) | irq;
967
968         return plpar_hcall_norets(H_EOI, xirr);
969 }