2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
4 * Firmware Infiniband Interface code for POWER
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Gerd Bayer <gerd.bayer@de.ibm.com>
9 * Waleri Fomin <fomin@de.ibm.com>
11 * Copyright (c) 2005 IBM Corporation
13 * All rights reserved.
15 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
23 * Redistributions of source code must retain the above copyright notice, this
24 * list of conditions and the following disclaimer.
26 * Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following disclaimer in the documentation
28 * and/or other materials
29 * provided with the distribution.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
44 #include <asm/hvcall.h>
45 #include "ehca_tools.h"
49 #include "ipz_pt_fn.h"
51 #define H_ALL_RES_QP_ENHANCED_OPS EHCA_BMASK_IBM(9, 11)
52 #define H_ALL_RES_QP_PTE_PIN EHCA_BMASK_IBM(12, 12)
53 #define H_ALL_RES_QP_SERVICE_TYPE EHCA_BMASK_IBM(13, 15)
54 #define H_ALL_RES_QP_LL_RQ_CQE_POSTING EHCA_BMASK_IBM(18, 18)
55 #define H_ALL_RES_QP_LL_SQ_CQE_POSTING EHCA_BMASK_IBM(19, 21)
56 #define H_ALL_RES_QP_SIGNALING_TYPE EHCA_BMASK_IBM(22, 23)
57 #define H_ALL_RES_QP_UD_AV_LKEY_CTRL EHCA_BMASK_IBM(31, 31)
58 #define H_ALL_RES_QP_RESOURCE_TYPE EHCA_BMASK_IBM(56, 63)
60 #define H_ALL_RES_QP_MAX_OUTST_SEND_WR EHCA_BMASK_IBM(0, 15)
61 #define H_ALL_RES_QP_MAX_OUTST_RECV_WR EHCA_BMASK_IBM(16, 31)
62 #define H_ALL_RES_QP_MAX_SEND_SGE EHCA_BMASK_IBM(32, 39)
63 #define H_ALL_RES_QP_MAX_RECV_SGE EHCA_BMASK_IBM(40, 47)
65 #define H_ALL_RES_QP_ACT_OUTST_SEND_WR EHCA_BMASK_IBM(16, 31)
66 #define H_ALL_RES_QP_ACT_OUTST_RECV_WR EHCA_BMASK_IBM(48, 63)
67 #define H_ALL_RES_QP_ACT_SEND_SGE EHCA_BMASK_IBM(8, 15)
68 #define H_ALL_RES_QP_ACT_RECV_SGE EHCA_BMASK_IBM(24, 31)
70 #define H_ALL_RES_QP_SQUEUE_SIZE_PAGES EHCA_BMASK_IBM(0, 31)
71 #define H_ALL_RES_QP_RQUEUE_SIZE_PAGES EHCA_BMASK_IBM(32, 63)
73 #define H_MP_INIT_TYPE EHCA_BMASK_IBM(44, 47)
74 #define H_MP_SHUTDOWN EHCA_BMASK_IBM(48, 48)
75 #define H_MP_RESET_QKEY_CTR EHCA_BMASK_IBM(49, 49)
77 /* direct access qp controls */
78 #define DAQP_CTRL_ENABLE 0x01
79 #define DAQP_CTRL_SEND_COMP 0x20
80 #define DAQP_CTRL_RECV_COMP 0x40
82 static u32
get_longbusy_msecs(int longbusy_rc
)
84 switch (longbusy_rc
) {
85 case H_LONG_BUSY_ORDER_1_MSEC
:
87 case H_LONG_BUSY_ORDER_10_MSEC
:
89 case H_LONG_BUSY_ORDER_100_MSEC
:
91 case H_LONG_BUSY_ORDER_1_SEC
:
93 case H_LONG_BUSY_ORDER_10_SEC
:
95 case H_LONG_BUSY_ORDER_100_SEC
:
102 static long ehca_plpar_hcall_norets(unsigned long opcode
,
114 ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
115 "arg5=%lx arg6=%lx arg7=%lx",
116 opcode
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
);
118 for (i
= 0; i
< 5; i
++) {
119 ret
= plpar_hcall_norets(opcode
, arg1
, arg2
, arg3
, arg4
,
122 if (H_IS_LONG_BUSY(ret
)) {
123 sleep_msecs
= get_longbusy_msecs(ret
);
124 msleep_interruptible(sleep_msecs
);
129 ehca_gen_err("opcode=%lx ret=%lx"
130 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
131 " arg5=%lx arg6=%lx arg7=%lx ",
133 arg1
, arg2
, arg3
, arg4
, arg5
,
136 ehca_gen_dbg("opcode=%lx ret=%lx", opcode
, ret
);
144 static long ehca_plpar_hcall9(unsigned long opcode
,
145 unsigned long *outs
, /* array of 9 outputs */
157 int i
, sleep_msecs
, lock_is_set
= 0;
160 ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
161 "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx",
162 opcode
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
,
165 for (i
= 0; i
< 5; i
++) {
166 if ((opcode
== H_ALLOC_RESOURCE
) && (arg2
== 5)) {
167 spin_lock_irqsave(&hcall_lock
, flags
);
171 ret
= plpar_hcall9(opcode
, outs
,
172 arg1
, arg2
, arg3
, arg4
, arg5
,
173 arg6
, arg7
, arg8
, arg9
);
176 spin_unlock_irqrestore(&hcall_lock
, flags
);
178 if (H_IS_LONG_BUSY(ret
)) {
179 sleep_msecs
= get_longbusy_msecs(ret
);
180 msleep_interruptible(sleep_msecs
);
185 ehca_gen_err("opcode=%lx ret=%lx"
186 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
187 " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
189 " out1=%lx out2=%lx out3=%lx out4=%lx"
190 " out5=%lx out6=%lx out7=%lx out8=%lx"
193 arg1
, arg2
, arg3
, arg4
, arg5
,
194 arg6
, arg7
, arg8
, arg9
,
195 outs
[0], outs
[1], outs
[2], outs
[3],
196 outs
[4], outs
[5], outs
[6], outs
[7],
199 ehca_gen_dbg("opcode=%lx ret=%lx out1=%lx out2=%lx out3=%lx "
200 "out4=%lx out5=%lx out6=%lx out7=%lx out8=%lx "
202 opcode
, ret
, outs
[0], outs
[1], outs
[2], outs
[3],
203 outs
[4], outs
[5], outs
[6], outs
[7], outs
[8]);
210 u64
hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle
,
211 struct ehca_pfeq
*pfeq
,
212 const u32 neq_control
,
213 const u32 number_of_entries
,
214 struct ipz_eq_handle
*eq_handle
,
215 u32
*act_nr_of_entries
,
220 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
221 u64 allocate_controls
;
224 allocate_controls
= 3ULL;
226 /* ISN is associated */
227 if (neq_control
!= 1)
228 allocate_controls
= (1ULL << (63 - 7)) | allocate_controls
;
229 else /* notification event queue */
230 allocate_controls
= (1ULL << 63) | allocate_controls
;
232 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
233 adapter_handle
.handle
, /* r4 */
234 allocate_controls
, /* r5 */
235 number_of_entries
, /* r6 */
237 eq_handle
->handle
= outs
[0];
238 *act_nr_of_entries
= (u32
)outs
[3];
239 *act_pages
= (u32
)outs
[4];
240 *eq_ist
= (u32
)outs
[5];
242 if (ret
== H_NOT_ENOUGH_RESOURCES
)
243 ehca_gen_err("Not enough resource - ret=%lx ", ret
);
248 u64
hipz_h_reset_event(const struct ipz_adapter_handle adapter_handle
,
249 struct ipz_eq_handle eq_handle
,
250 const u64 event_mask
)
252 return ehca_plpar_hcall_norets(H_RESET_EVENTS
,
253 adapter_handle
.handle
, /* r4 */
254 eq_handle
.handle
, /* r5 */
259 u64
hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle
,
261 struct ehca_alloc_cq_parms
*param
)
264 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
266 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
267 adapter_handle
.handle
, /* r4 */
269 param
->eq_handle
.handle
, /* r6 */
271 param
->nr_cqe
, /* r8 */
273 cq
->ipz_cq_handle
.handle
= outs
[0];
274 param
->act_nr_of_entries
= (u32
)outs
[3];
275 param
->act_pages
= (u32
)outs
[4];
277 if (ret
== H_SUCCESS
)
278 hcp_galpas_ctor(&cq
->galpas
, outs
[5], outs
[6]);
280 if (ret
== H_NOT_ENOUGH_RESOURCES
)
281 ehca_gen_err("Not enough resources. ret=%lx", ret
);
286 u64
hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle
,
288 struct ehca_alloc_qp_parms
*parms
)
291 u64 allocate_controls
;
293 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
294 u16 max_nr_receive_wqes
= qp
->init_attr
.cap
.max_recv_wr
+ 1;
295 u16 max_nr_send_wqes
= qp
->init_attr
.cap
.max_send_wr
+ 1;
296 int daqp_ctrl
= parms
->daqp_ctrl
;
299 EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS
,
300 (daqp_ctrl
& DAQP_CTRL_ENABLE
) ? 1 : 0)
301 | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN
, 0)
302 | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE
, parms
->servicetype
)
303 | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE
, parms
->sigtype
)
304 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING
,
305 (daqp_ctrl
& DAQP_CTRL_RECV_COMP
) ? 1 : 0)
306 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING
,
307 (daqp_ctrl
& DAQP_CTRL_SEND_COMP
) ? 1 : 0)
308 | EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL
,
309 parms
->ud_av_l_key_ctl
)
310 | EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE
, 1);
313 EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR
,
315 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR
,
317 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE
,
319 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE
,
320 parms
->max_recv_sge
);
322 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
323 adapter_handle
.handle
, /* r4 */
324 allocate_controls
, /* r5 */
325 qp
->send_cq
->ipz_cq_handle
.handle
,
326 qp
->recv_cq
->ipz_cq_handle
.handle
,
327 parms
->ipz_eq_handle
.handle
,
328 ((u64
)qp
->token
<< 32) | parms
->pd
.value
,
329 max_r10_reg
, /* r10 */
330 parms
->ud_av_l_key_ctl
, /* r11 */
332 qp
->ipz_qp_handle
.handle
= outs
[0];
333 qp
->real_qp_num
= (u32
)outs
[1];
334 parms
->act_nr_send_wqes
=
335 (u16
)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR
, outs
[2]);
336 parms
->act_nr_recv_wqes
=
337 (u16
)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR
, outs
[2]);
338 parms
->act_nr_send_sges
=
339 (u8
)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE
, outs
[3]);
340 parms
->act_nr_recv_sges
=
341 (u8
)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE
, outs
[3]);
343 (u32
)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES
, outs
[4]);
345 (u32
)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES
, outs
[4]);
347 if (ret
== H_SUCCESS
)
348 hcp_galpas_ctor(&qp
->galpas
, outs
[6], outs
[6]);
350 if (ret
== H_NOT_ENOUGH_RESOURCES
)
351 ehca_gen_err("Not enough resources. ret=%lx", ret
);
356 u64
hipz_h_query_port(const struct ipz_adapter_handle adapter_handle
,
358 struct hipz_query_port
*query_port_response_block
)
361 u64 r_cb
= virt_to_abs(query_port_response_block
);
363 if (r_cb
& (EHCA_PAGESIZE
-1)) {
364 ehca_gen_err("response block not page aligned");
368 ret
= ehca_plpar_hcall_norets(H_QUERY_PORT
,
369 adapter_handle
.handle
, /* r4 */
374 if (ehca_debug_level
)
375 ehca_dmp(query_port_response_block
, 64, "response_block");
380 u64
hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle
,
381 const u8 port_id
, const u32 port_cap
,
382 const u8 init_type
, const int modify_mask
)
384 u64 port_attributes
= port_cap
;
386 if (modify_mask
& IB_PORT_SHUTDOWN
)
387 port_attributes
|= EHCA_BMASK_SET(H_MP_SHUTDOWN
, 1);
388 if (modify_mask
& IB_PORT_INIT_TYPE
)
389 port_attributes
|= EHCA_BMASK_SET(H_MP_INIT_TYPE
, init_type
);
390 if (modify_mask
& IB_PORT_RESET_QKEY_CNTR
)
391 port_attributes
|= EHCA_BMASK_SET(H_MP_RESET_QKEY_CTR
, 1);
393 return ehca_plpar_hcall_norets(H_MODIFY_PORT
,
394 adapter_handle
.handle
, /* r4 */
396 port_attributes
, /* r6 */
400 u64
hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle
,
401 struct hipz_query_hca
*query_hca_rblock
)
403 u64 r_cb
= virt_to_abs(query_hca_rblock
);
405 if (r_cb
& (EHCA_PAGESIZE
-1)) {
406 ehca_gen_err("response_block=%p not page aligned",
411 return ehca_plpar_hcall_norets(H_QUERY_HCA
,
412 adapter_handle
.handle
, /* r4 */
417 u64
hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle
,
420 const u64 resource_handle
,
421 const u64 logical_address_of_page
,
424 return ehca_plpar_hcall_norets(H_REGISTER_RPAGES
,
425 adapter_handle
.handle
, /* r4 */
426 queue_type
| pagesize
<< 8, /* r5 */
427 resource_handle
, /* r6 */
428 logical_address_of_page
, /* r7 */
433 u64
hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle
,
434 const struct ipz_eq_handle eq_handle
,
435 struct ehca_pfeq
*pfeq
,
438 const u64 logical_address_of_page
,
442 ehca_gen_err("Ppage counter=%lx", count
);
445 return hipz_h_register_rpage(adapter_handle
,
449 logical_address_of_page
, count
);
452 u64
hipz_h_query_int_state(const struct ipz_adapter_handle adapter_handle
,
456 ret
= ehca_plpar_hcall_norets(H_QUERY_INT_STATE
,
457 adapter_handle
.handle
, /* r4 */
461 if (ret
!= H_SUCCESS
&& ret
!= H_BUSY
)
462 ehca_gen_err("Could not query interrupt state.");
467 u64
hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle
,
468 const struct ipz_cq_handle cq_handle
,
469 struct ehca_pfcq
*pfcq
,
472 const u64 logical_address_of_page
,
474 const struct h_galpa gal
)
477 ehca_gen_err("Page counter=%lx", count
);
481 return hipz_h_register_rpage(adapter_handle
, pagesize
, queue_type
,
482 cq_handle
.handle
, logical_address_of_page
,
486 u64
hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle
,
487 const struct ipz_qp_handle qp_handle
,
488 struct ehca_pfqp
*pfqp
,
491 const u64 logical_address_of_page
,
493 const struct h_galpa galpa
)
496 ehca_gen_err("Page counter=%lx", count
);
500 return hipz_h_register_rpage(adapter_handle
,pagesize
,queue_type
,
501 qp_handle
.handle
,logical_address_of_page
,
505 u64
hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle
,
506 const struct ipz_qp_handle qp_handle
,
507 struct ehca_pfqp
*pfqp
,
508 void **log_addr_next_sq_wqe2processed
,
509 void **log_addr_next_rq_wqe2processed
,
510 int dis_and_get_function_code
)
513 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
515 ret
= ehca_plpar_hcall9(H_DISABLE_AND_GETC
, outs
,
516 adapter_handle
.handle
, /* r4 */
517 dis_and_get_function_code
, /* r5 */
518 qp_handle
.handle
, /* r6 */
520 if (log_addr_next_sq_wqe2processed
)
521 *log_addr_next_sq_wqe2processed
= (void*)outs
[0];
522 if (log_addr_next_rq_wqe2processed
)
523 *log_addr_next_rq_wqe2processed
= (void*)outs
[1];
528 u64
hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle
,
529 const struct ipz_qp_handle qp_handle
,
530 struct ehca_pfqp
*pfqp
,
531 const u64 update_mask
,
532 struct hcp_modify_qp_control_block
*mqpcb
,
536 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
537 ret
= ehca_plpar_hcall9(H_MODIFY_QP
, outs
,
538 adapter_handle
.handle
, /* r4 */
539 qp_handle
.handle
, /* r5 */
540 update_mask
, /* r6 */
541 virt_to_abs(mqpcb
), /* r7 */
544 if (ret
== H_NOT_ENOUGH_RESOURCES
)
545 ehca_gen_err("Insufficient resources ret=%lx", ret
);
550 u64
hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle
,
551 const struct ipz_qp_handle qp_handle
,
552 struct ehca_pfqp
*pfqp
,
553 struct hcp_modify_qp_control_block
*qqpcb
,
556 return ehca_plpar_hcall_norets(H_QUERY_QP
,
557 adapter_handle
.handle
, /* r4 */
558 qp_handle
.handle
, /* r5 */
559 virt_to_abs(qqpcb
), /* r6 */
563 u64
hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle
,
567 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
569 ret
= hcp_galpas_dtor(&qp
->galpas
);
571 ehca_gen_err("Could not destruct qp->galpas");
574 ret
= ehca_plpar_hcall9(H_DISABLE_AND_GETC
, outs
,
575 adapter_handle
.handle
, /* r4 */
578 qp
->ipz_qp_handle
.handle
, /* r6 */
580 if (ret
== H_HARDWARE
)
581 ehca_gen_err("HCA not operational. ret=%lx", ret
);
583 ret
= ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
584 adapter_handle
.handle
, /* r4 */
585 qp
->ipz_qp_handle
.handle
, /* r5 */
588 if (ret
== H_RESOURCE
)
589 ehca_gen_err("Resource still in use. ret=%lx", ret
);
594 u64
hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle
,
595 const struct ipz_qp_handle qp_handle
,
599 return ehca_plpar_hcall_norets(H_DEFINE_AQP0
,
600 adapter_handle
.handle
, /* r4 */
601 qp_handle
.handle
, /* r5 */
606 u64
hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle
,
607 const struct ipz_qp_handle qp_handle
,
609 u32 port
, u32
* pma_qp_nr
,
613 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
615 ret
= ehca_plpar_hcall9(H_DEFINE_AQP1
, outs
,
616 adapter_handle
.handle
, /* r4 */
617 qp_handle
.handle
, /* r5 */
620 *pma_qp_nr
= (u32
)outs
[0];
621 *bma_qp_nr
= (u32
)outs
[1];
623 if (ret
== H_ALIAS_EXIST
)
624 ehca_gen_err("AQP1 already exists. ret=%lx", ret
);
629 u64
hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle
,
630 const struct ipz_qp_handle qp_handle
,
633 u64 subnet_prefix
, u64 interface_id
)
637 ret
= ehca_plpar_hcall_norets(H_ATTACH_MCQP
,
638 adapter_handle
.handle
, /* r4 */
639 qp_handle
.handle
, /* r5 */
641 interface_id
, /* r7 */
642 subnet_prefix
, /* r8 */
645 if (ret
== H_NOT_ENOUGH_RESOURCES
)
646 ehca_gen_err("Not enough resources. ret=%lx", ret
);
651 u64
hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle
,
652 const struct ipz_qp_handle qp_handle
,
655 u64 subnet_prefix
, u64 interface_id
)
657 return ehca_plpar_hcall_norets(H_DETACH_MCQP
,
658 adapter_handle
.handle
, /* r4 */
659 qp_handle
.handle
, /* r5 */
661 interface_id
, /* r7 */
662 subnet_prefix
, /* r8 */
666 u64
hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle
,
672 ret
= hcp_galpas_dtor(&cq
->galpas
);
674 ehca_gen_err("Could not destruct cp->galpas");
678 ret
= ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
679 adapter_handle
.handle
, /* r4 */
680 cq
->ipz_cq_handle
.handle
, /* r5 */
681 force_flag
!= 0 ? 1L : 0L, /* r6 */
684 if (ret
== H_RESOURCE
)
685 ehca_gen_err("H_FREE_RESOURCE failed ret=%lx ", ret
);
690 u64
hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle
,
695 ret
= hcp_galpas_dtor(&eq
->galpas
);
697 ehca_gen_err("Could not destruct eq->galpas");
701 ret
= ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
702 adapter_handle
.handle
, /* r4 */
703 eq
->ipz_eq_handle
.handle
, /* r5 */
706 if (ret
== H_RESOURCE
)
707 ehca_gen_err("Resource in use. ret=%lx ", ret
);
712 u64
hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle
,
713 const struct ehca_mr
*mr
,
716 const u32 access_ctrl
,
717 const struct ipz_pd pd
,
718 struct ehca_mr_hipzout_parms
*outparms
)
721 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
723 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
724 adapter_handle
.handle
, /* r4 */
728 (((u64
)access_ctrl
) << 32ULL), /* r8 */
731 outparms
->handle
.handle
= outs
[0];
732 outparms
->lkey
= (u32
)outs
[2];
733 outparms
->rkey
= (u32
)outs
[3];
738 u64
hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle
,
739 const struct ehca_mr
*mr
,
742 const u64 logical_address_of_page
,
747 if ((count
> 1) && (logical_address_of_page
& (EHCA_PAGESIZE
-1))) {
748 ehca_gen_err("logical_address_of_page not on a 4k boundary "
749 "adapter_handle=%lx mr=%p mr_handle=%lx "
750 "pagesize=%x queue_type=%x "
751 "logical_address_of_page=%lx count=%lx",
752 adapter_handle
.handle
, mr
,
753 mr
->ipz_mr_handle
.handle
, pagesize
, queue_type
,
754 logical_address_of_page
, count
);
757 ret
= hipz_h_register_rpage(adapter_handle
, pagesize
,
759 mr
->ipz_mr_handle
.handle
,
760 logical_address_of_page
, count
);
764 u64
hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle
,
765 const struct ehca_mr
*mr
,
766 struct ehca_mr_hipzout_parms
*outparms
)
769 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
771 ret
= ehca_plpar_hcall9(H_QUERY_MR
, outs
,
772 adapter_handle
.handle
, /* r4 */
773 mr
->ipz_mr_handle
.handle
, /* r5 */
774 0, 0, 0, 0, 0, 0, 0);
775 outparms
->len
= outs
[0];
776 outparms
->vaddr
= outs
[1];
777 outparms
->acl
= outs
[4] >> 32;
778 outparms
->lkey
= (u32
)(outs
[5] >> 32);
779 outparms
->rkey
= (u32
)(outs
[5] & (0xffffffff));
784 u64
hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle
,
785 const struct ehca_mr
*mr
)
787 return ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
788 adapter_handle
.handle
, /* r4 */
789 mr
->ipz_mr_handle
.handle
, /* r5 */
793 u64
hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle
,
794 const struct ehca_mr
*mr
,
797 const u32 access_ctrl
,
798 const struct ipz_pd pd
,
799 const u64 mr_addr_cb
,
800 struct ehca_mr_hipzout_parms
*outparms
)
803 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
805 ret
= ehca_plpar_hcall9(H_REREGISTER_PMR
, outs
,
806 adapter_handle
.handle
, /* r4 */
807 mr
->ipz_mr_handle
.handle
, /* r5 */
811 ((((u64
)access_ctrl
) << 32ULL) | pd
.value
),
814 outparms
->vaddr
= outs
[1];
815 outparms
->lkey
= (u32
)outs
[2];
816 outparms
->rkey
= (u32
)outs
[3];
821 u64
hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle
,
822 const struct ehca_mr
*mr
,
823 const struct ehca_mr
*orig_mr
,
825 const u32 access_ctrl
,
826 const struct ipz_pd pd
,
827 struct ehca_mr_hipzout_parms
*outparms
)
830 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
832 ret
= ehca_plpar_hcall9(H_REGISTER_SMR
, outs
,
833 adapter_handle
.handle
, /* r4 */
834 orig_mr
->ipz_mr_handle
.handle
, /* r5 */
836 (((u64
)access_ctrl
) << 32ULL), /* r7 */
839 outparms
->handle
.handle
= outs
[0];
840 outparms
->lkey
= (u32
)outs
[2];
841 outparms
->rkey
= (u32
)outs
[3];
846 u64
hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle
,
847 const struct ehca_mw
*mw
,
848 const struct ipz_pd pd
,
849 struct ehca_mw_hipzout_parms
*outparms
)
852 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
854 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
855 adapter_handle
.handle
, /* r4 */
859 outparms
->handle
.handle
= outs
[0];
860 outparms
->rkey
= (u32
)outs
[3];
865 u64
hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle
,
866 const struct ehca_mw
*mw
,
867 struct ehca_mw_hipzout_parms
*outparms
)
870 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
872 ret
= ehca_plpar_hcall9(H_QUERY_MW
, outs
,
873 adapter_handle
.handle
, /* r4 */
874 mw
->ipz_mw_handle
.handle
, /* r5 */
875 0, 0, 0, 0, 0, 0, 0);
876 outparms
->rkey
= (u32
)outs
[3];
881 u64
hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle
,
882 const struct ehca_mw
*mw
)
884 return ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
885 adapter_handle
.handle
, /* r4 */
886 mw
->ipz_mw_handle
.handle
, /* r5 */
890 u64
hipz_h_error_data(const struct ipz_adapter_handle adapter_handle
,
891 const u64 ressource_handle
,
893 unsigned long *byte_count
)
895 u64 r_cb
= virt_to_abs(rblock
);
897 if (r_cb
& (EHCA_PAGESIZE
-1)) {
898 ehca_gen_err("rblock not page aligned.");
902 return ehca_plpar_hcall_norets(H_ERROR_DATA
,
903 adapter_handle
.handle
,