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 */
159 ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
160 "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx",
161 opcode
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
,
164 for (i
= 0; i
< 5; i
++) {
165 ret
= plpar_hcall9(opcode
, outs
,
166 arg1
, arg2
, arg3
, arg4
, arg5
,
167 arg6
, arg7
, arg8
, arg9
);
169 if (H_IS_LONG_BUSY(ret
)) {
170 sleep_msecs
= get_longbusy_msecs(ret
);
171 msleep_interruptible(sleep_msecs
);
176 ehca_gen_err("opcode=%lx ret=%lx"
177 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
178 " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
180 " out1=%lx out2=%lx out3=%lx out4=%lx"
181 " out5=%lx out6=%lx out7=%lx out8=%lx"
184 arg1
, arg2
, arg3
, arg4
, arg5
,
185 arg6
, arg7
, arg8
, arg9
,
186 outs
[0], outs
[1], outs
[2], outs
[3],
187 outs
[4], outs
[5], outs
[6], outs
[7],
190 ehca_gen_dbg("opcode=%lx ret=%lx out1=%lx out2=%lx out3=%lx "
191 "out4=%lx out5=%lx out6=%lx out7=%lx out8=%lx "
193 opcode
, ret
, outs
[0], outs
[1], outs
[2], outs
[3],
194 outs
[4], outs
[5], outs
[6], outs
[7], outs
[8]);
201 u64
hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle
,
202 struct ehca_pfeq
*pfeq
,
203 const u32 neq_control
,
204 const u32 number_of_entries
,
205 struct ipz_eq_handle
*eq_handle
,
206 u32
*act_nr_of_entries
,
211 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
212 u64 allocate_controls
;
215 allocate_controls
= 3ULL;
217 /* ISN is associated */
218 if (neq_control
!= 1)
219 allocate_controls
= (1ULL << (63 - 7)) | allocate_controls
;
220 else /* notification event queue */
221 allocate_controls
= (1ULL << 63) | allocate_controls
;
223 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
224 adapter_handle
.handle
, /* r4 */
225 allocate_controls
, /* r5 */
226 number_of_entries
, /* r6 */
228 eq_handle
->handle
= outs
[0];
229 *act_nr_of_entries
= (u32
)outs
[3];
230 *act_pages
= (u32
)outs
[4];
231 *eq_ist
= (u32
)outs
[5];
233 if (ret
== H_NOT_ENOUGH_RESOURCES
)
234 ehca_gen_err("Not enough resource - ret=%lx ", ret
);
239 u64
hipz_h_reset_event(const struct ipz_adapter_handle adapter_handle
,
240 struct ipz_eq_handle eq_handle
,
241 const u64 event_mask
)
243 return ehca_plpar_hcall_norets(H_RESET_EVENTS
,
244 adapter_handle
.handle
, /* r4 */
245 eq_handle
.handle
, /* r5 */
250 u64
hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle
,
252 struct ehca_alloc_cq_parms
*param
)
255 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
257 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
258 adapter_handle
.handle
, /* r4 */
260 param
->eq_handle
.handle
, /* r6 */
262 param
->nr_cqe
, /* r8 */
264 cq
->ipz_cq_handle
.handle
= outs
[0];
265 param
->act_nr_of_entries
= (u32
)outs
[3];
266 param
->act_pages
= (u32
)outs
[4];
268 if (ret
== H_SUCCESS
)
269 hcp_galpas_ctor(&cq
->galpas
, outs
[5], outs
[6]);
271 if (ret
== H_NOT_ENOUGH_RESOURCES
)
272 ehca_gen_err("Not enough resources. ret=%lx", ret
);
277 u64
hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle
,
279 struct ehca_alloc_qp_parms
*parms
)
282 u64 allocate_controls
;
284 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
285 u16 max_nr_receive_wqes
= qp
->init_attr
.cap
.max_recv_wr
+ 1;
286 u16 max_nr_send_wqes
= qp
->init_attr
.cap
.max_send_wr
+ 1;
287 int daqp_ctrl
= parms
->daqp_ctrl
;
290 EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS
,
291 (daqp_ctrl
& DAQP_CTRL_ENABLE
) ? 1 : 0)
292 | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN
, 0)
293 | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE
, parms
->servicetype
)
294 | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE
, parms
->sigtype
)
295 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING
,
296 (daqp_ctrl
& DAQP_CTRL_RECV_COMP
) ? 1 : 0)
297 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING
,
298 (daqp_ctrl
& DAQP_CTRL_SEND_COMP
) ? 1 : 0)
299 | EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL
,
300 parms
->ud_av_l_key_ctl
)
301 | EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE
, 1);
304 EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR
,
306 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR
,
308 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE
,
310 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE
,
311 parms
->max_recv_sge
);
313 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
314 adapter_handle
.handle
, /* r4 */
315 allocate_controls
, /* r5 */
316 qp
->send_cq
->ipz_cq_handle
.handle
,
317 qp
->recv_cq
->ipz_cq_handle
.handle
,
318 parms
->ipz_eq_handle
.handle
,
319 ((u64
)qp
->token
<< 32) | parms
->pd
.value
,
320 max_r10_reg
, /* r10 */
321 parms
->ud_av_l_key_ctl
, /* r11 */
323 qp
->ipz_qp_handle
.handle
= outs
[0];
324 qp
->real_qp_num
= (u32
)outs
[1];
325 parms
->act_nr_send_sges
=
326 (u16
)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR
, outs
[2]);
327 parms
->act_nr_recv_wqes
=
328 (u16
)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR
, outs
[2]);
329 parms
->act_nr_send_sges
=
330 (u8
)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE
, outs
[3]);
331 parms
->act_nr_recv_sges
=
332 (u8
)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE
, outs
[3]);
334 (u32
)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES
, outs
[4]);
336 (u32
)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES
, outs
[4]);
338 if (ret
== H_SUCCESS
)
339 hcp_galpas_ctor(&qp
->galpas
, outs
[6], outs
[6]);
341 if (ret
== H_NOT_ENOUGH_RESOURCES
)
342 ehca_gen_err("Not enough resources. ret=%lx", ret
);
347 u64
hipz_h_query_port(const struct ipz_adapter_handle adapter_handle
,
349 struct hipz_query_port
*query_port_response_block
)
352 u64 r_cb
= virt_to_abs(query_port_response_block
);
354 if (r_cb
& (EHCA_PAGESIZE
-1)) {
355 ehca_gen_err("response block not page aligned");
359 ret
= ehca_plpar_hcall_norets(H_QUERY_PORT
,
360 adapter_handle
.handle
, /* r4 */
365 if (ehca_debug_level
)
366 ehca_dmp(query_port_response_block
, 64, "response_block");
371 u64
hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle
,
372 const u8 port_id
, const u32 port_cap
,
373 const u8 init_type
, const int modify_mask
)
375 u64 port_attributes
= port_cap
;
377 if (modify_mask
& IB_PORT_SHUTDOWN
)
378 port_attributes
|= EHCA_BMASK_SET(H_MP_SHUTDOWN
, 1);
379 if (modify_mask
& IB_PORT_INIT_TYPE
)
380 port_attributes
|= EHCA_BMASK_SET(H_MP_INIT_TYPE
, init_type
);
381 if (modify_mask
& IB_PORT_RESET_QKEY_CNTR
)
382 port_attributes
|= EHCA_BMASK_SET(H_MP_RESET_QKEY_CTR
, 1);
384 return ehca_plpar_hcall_norets(H_MODIFY_PORT
,
385 adapter_handle
.handle
, /* r4 */
387 port_attributes
, /* r6 */
391 u64
hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle
,
392 struct hipz_query_hca
*query_hca_rblock
)
394 u64 r_cb
= virt_to_abs(query_hca_rblock
);
396 if (r_cb
& (EHCA_PAGESIZE
-1)) {
397 ehca_gen_err("response_block=%p not page aligned",
402 return ehca_plpar_hcall_norets(H_QUERY_HCA
,
403 adapter_handle
.handle
, /* r4 */
408 u64
hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle
,
411 const u64 resource_handle
,
412 const u64 logical_address_of_page
,
415 return ehca_plpar_hcall_norets(H_REGISTER_RPAGES
,
416 adapter_handle
.handle
, /* r4 */
417 queue_type
| pagesize
<< 8, /* r5 */
418 resource_handle
, /* r6 */
419 logical_address_of_page
, /* r7 */
424 u64
hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle
,
425 const struct ipz_eq_handle eq_handle
,
426 struct ehca_pfeq
*pfeq
,
429 const u64 logical_address_of_page
,
433 ehca_gen_err("Ppage counter=%lx", count
);
436 return hipz_h_register_rpage(adapter_handle
,
440 logical_address_of_page
, count
);
443 u64
hipz_h_query_int_state(const struct ipz_adapter_handle adapter_handle
,
447 ret
= ehca_plpar_hcall_norets(H_QUERY_INT_STATE
,
448 adapter_handle
.handle
, /* r4 */
452 if (ret
!= H_SUCCESS
&& ret
!= H_BUSY
)
453 ehca_gen_err("Could not query interrupt state.");
458 u64
hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle
,
459 const struct ipz_cq_handle cq_handle
,
460 struct ehca_pfcq
*pfcq
,
463 const u64 logical_address_of_page
,
465 const struct h_galpa gal
)
468 ehca_gen_err("Page counter=%lx", count
);
472 return hipz_h_register_rpage(adapter_handle
, pagesize
, queue_type
,
473 cq_handle
.handle
, logical_address_of_page
,
477 u64
hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle
,
478 const struct ipz_qp_handle qp_handle
,
479 struct ehca_pfqp
*pfqp
,
482 const u64 logical_address_of_page
,
484 const struct h_galpa galpa
)
487 ehca_gen_err("Page counter=%lx", count
);
491 return hipz_h_register_rpage(adapter_handle
,pagesize
,queue_type
,
492 qp_handle
.handle
,logical_address_of_page
,
496 u64
hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle
,
497 const struct ipz_qp_handle qp_handle
,
498 struct ehca_pfqp
*pfqp
,
499 void **log_addr_next_sq_wqe2processed
,
500 void **log_addr_next_rq_wqe2processed
,
501 int dis_and_get_function_code
)
504 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
506 ret
= ehca_plpar_hcall9(H_DISABLE_AND_GETC
, outs
,
507 adapter_handle
.handle
, /* r4 */
508 dis_and_get_function_code
, /* r5 */
509 qp_handle
.handle
, /* r6 */
511 if (log_addr_next_sq_wqe2processed
)
512 *log_addr_next_sq_wqe2processed
= (void*)outs
[0];
513 if (log_addr_next_rq_wqe2processed
)
514 *log_addr_next_rq_wqe2processed
= (void*)outs
[1];
519 u64
hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle
,
520 const struct ipz_qp_handle qp_handle
,
521 struct ehca_pfqp
*pfqp
,
522 const u64 update_mask
,
523 struct hcp_modify_qp_control_block
*mqpcb
,
527 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
528 ret
= ehca_plpar_hcall9(H_MODIFY_QP
, outs
,
529 adapter_handle
.handle
, /* r4 */
530 qp_handle
.handle
, /* r5 */
531 update_mask
, /* r6 */
532 virt_to_abs(mqpcb
), /* r7 */
535 if (ret
== H_NOT_ENOUGH_RESOURCES
)
536 ehca_gen_err("Insufficient resources ret=%lx", ret
);
541 u64
hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle
,
542 const struct ipz_qp_handle qp_handle
,
543 struct ehca_pfqp
*pfqp
,
544 struct hcp_modify_qp_control_block
*qqpcb
,
547 return ehca_plpar_hcall_norets(H_QUERY_QP
,
548 adapter_handle
.handle
, /* r4 */
549 qp_handle
.handle
, /* r5 */
550 virt_to_abs(qqpcb
), /* r6 */
554 u64
hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle
,
558 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
560 ret
= hcp_galpas_dtor(&qp
->galpas
);
562 ehca_gen_err("Could not destruct qp->galpas");
565 ret
= ehca_plpar_hcall9(H_DISABLE_AND_GETC
, outs
,
566 adapter_handle
.handle
, /* r4 */
569 qp
->ipz_qp_handle
.handle
, /* r6 */
571 if (ret
== H_HARDWARE
)
572 ehca_gen_err("HCA not operational. ret=%lx", ret
);
574 ret
= ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
575 adapter_handle
.handle
, /* r4 */
576 qp
->ipz_qp_handle
.handle
, /* r5 */
579 if (ret
== H_RESOURCE
)
580 ehca_gen_err("Resource still in use. ret=%lx", ret
);
585 u64
hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle
,
586 const struct ipz_qp_handle qp_handle
,
590 return ehca_plpar_hcall_norets(H_DEFINE_AQP0
,
591 adapter_handle
.handle
, /* r4 */
592 qp_handle
.handle
, /* r5 */
597 u64
hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle
,
598 const struct ipz_qp_handle qp_handle
,
600 u32 port
, u32
* pma_qp_nr
,
604 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
606 ret
= ehca_plpar_hcall9(H_DEFINE_AQP1
, outs
,
607 adapter_handle
.handle
, /* r4 */
608 qp_handle
.handle
, /* r5 */
611 *pma_qp_nr
= (u32
)outs
[0];
612 *bma_qp_nr
= (u32
)outs
[1];
614 if (ret
== H_ALIAS_EXIST
)
615 ehca_gen_err("AQP1 already exists. ret=%lx", ret
);
620 u64
hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle
,
621 const struct ipz_qp_handle qp_handle
,
624 u64 subnet_prefix
, u64 interface_id
)
628 ret
= ehca_plpar_hcall_norets(H_ATTACH_MCQP
,
629 adapter_handle
.handle
, /* r4 */
630 qp_handle
.handle
, /* r5 */
632 interface_id
, /* r7 */
633 subnet_prefix
, /* r8 */
636 if (ret
== H_NOT_ENOUGH_RESOURCES
)
637 ehca_gen_err("Not enough resources. ret=%lx", ret
);
642 u64
hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle
,
643 const struct ipz_qp_handle qp_handle
,
646 u64 subnet_prefix
, u64 interface_id
)
648 return ehca_plpar_hcall_norets(H_DETACH_MCQP
,
649 adapter_handle
.handle
, /* r4 */
650 qp_handle
.handle
, /* r5 */
652 interface_id
, /* r7 */
653 subnet_prefix
, /* r8 */
657 u64
hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle
,
663 ret
= hcp_galpas_dtor(&cq
->galpas
);
665 ehca_gen_err("Could not destruct cp->galpas");
669 ret
= ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
670 adapter_handle
.handle
, /* r4 */
671 cq
->ipz_cq_handle
.handle
, /* r5 */
672 force_flag
!= 0 ? 1L : 0L, /* r6 */
675 if (ret
== H_RESOURCE
)
676 ehca_gen_err("H_FREE_RESOURCE failed ret=%lx ", ret
);
681 u64
hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle
,
686 ret
= hcp_galpas_dtor(&eq
->galpas
);
688 ehca_gen_err("Could not destruct eq->galpas");
692 ret
= ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
693 adapter_handle
.handle
, /* r4 */
694 eq
->ipz_eq_handle
.handle
, /* r5 */
697 if (ret
== H_RESOURCE
)
698 ehca_gen_err("Resource in use. ret=%lx ", ret
);
703 u64
hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle
,
704 const struct ehca_mr
*mr
,
707 const u32 access_ctrl
,
708 const struct ipz_pd pd
,
709 struct ehca_mr_hipzout_parms
*outparms
)
712 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
714 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
715 adapter_handle
.handle
, /* r4 */
719 (((u64
)access_ctrl
) << 32ULL), /* r8 */
722 outparms
->handle
.handle
= outs
[0];
723 outparms
->lkey
= (u32
)outs
[2];
724 outparms
->rkey
= (u32
)outs
[3];
729 u64
hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle
,
730 const struct ehca_mr
*mr
,
733 const u64 logical_address_of_page
,
738 if ((count
> 1) && (logical_address_of_page
& (EHCA_PAGESIZE
-1))) {
739 ehca_gen_err("logical_address_of_page not on a 4k boundary "
740 "adapter_handle=%lx mr=%p mr_handle=%lx "
741 "pagesize=%x queue_type=%x "
742 "logical_address_of_page=%lx count=%lx",
743 adapter_handle
.handle
, mr
,
744 mr
->ipz_mr_handle
.handle
, pagesize
, queue_type
,
745 logical_address_of_page
, count
);
748 ret
= hipz_h_register_rpage(adapter_handle
, pagesize
,
750 mr
->ipz_mr_handle
.handle
,
751 logical_address_of_page
, count
);
755 u64
hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle
,
756 const struct ehca_mr
*mr
,
757 struct ehca_mr_hipzout_parms
*outparms
)
760 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
762 ret
= ehca_plpar_hcall9(H_QUERY_MR
, outs
,
763 adapter_handle
.handle
, /* r4 */
764 mr
->ipz_mr_handle
.handle
, /* r5 */
765 0, 0, 0, 0, 0, 0, 0);
766 outparms
->len
= outs
[0];
767 outparms
->vaddr
= outs
[1];
768 outparms
->acl
= outs
[4] >> 32;
769 outparms
->lkey
= (u32
)(outs
[5] >> 32);
770 outparms
->rkey
= (u32
)(outs
[5] & (0xffffffff));
775 u64
hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle
,
776 const struct ehca_mr
*mr
)
778 return ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
779 adapter_handle
.handle
, /* r4 */
780 mr
->ipz_mr_handle
.handle
, /* r5 */
784 u64
hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle
,
785 const struct ehca_mr
*mr
,
788 const u32 access_ctrl
,
789 const struct ipz_pd pd
,
790 const u64 mr_addr_cb
,
791 struct ehca_mr_hipzout_parms
*outparms
)
794 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
796 ret
= ehca_plpar_hcall9(H_REREGISTER_PMR
, outs
,
797 adapter_handle
.handle
, /* r4 */
798 mr
->ipz_mr_handle
.handle
, /* r5 */
802 ((((u64
)access_ctrl
) << 32ULL) | pd
.value
),
805 outparms
->vaddr
= outs
[1];
806 outparms
->lkey
= (u32
)outs
[2];
807 outparms
->rkey
= (u32
)outs
[3];
812 u64
hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle
,
813 const struct ehca_mr
*mr
,
814 const struct ehca_mr
*orig_mr
,
816 const u32 access_ctrl
,
817 const struct ipz_pd pd
,
818 struct ehca_mr_hipzout_parms
*outparms
)
821 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
823 ret
= ehca_plpar_hcall9(H_REGISTER_SMR
, outs
,
824 adapter_handle
.handle
, /* r4 */
825 orig_mr
->ipz_mr_handle
.handle
, /* r5 */
827 (((u64
)access_ctrl
) << 32ULL), /* r7 */
830 outparms
->handle
.handle
= outs
[0];
831 outparms
->lkey
= (u32
)outs
[2];
832 outparms
->rkey
= (u32
)outs
[3];
837 u64
hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle
,
838 const struct ehca_mw
*mw
,
839 const struct ipz_pd pd
,
840 struct ehca_mw_hipzout_parms
*outparms
)
843 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
845 ret
= ehca_plpar_hcall9(H_ALLOC_RESOURCE
, outs
,
846 adapter_handle
.handle
, /* r4 */
850 outparms
->handle
.handle
= outs
[0];
851 outparms
->rkey
= (u32
)outs
[3];
856 u64
hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle
,
857 const struct ehca_mw
*mw
,
858 struct ehca_mw_hipzout_parms
*outparms
)
861 u64 outs
[PLPAR_HCALL9_BUFSIZE
];
863 ret
= ehca_plpar_hcall9(H_QUERY_MW
, outs
,
864 adapter_handle
.handle
, /* r4 */
865 mw
->ipz_mw_handle
.handle
, /* r5 */
866 0, 0, 0, 0, 0, 0, 0);
867 outparms
->rkey
= (u32
)outs
[3];
872 u64
hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle
,
873 const struct ehca_mw
*mw
)
875 return ehca_plpar_hcall_norets(H_FREE_RESOURCE
,
876 adapter_handle
.handle
, /* r4 */
877 mw
->ipz_mw_handle
.handle
, /* r5 */
881 u64
hipz_h_error_data(const struct ipz_adapter_handle adapter_handle
,
882 const u64 ressource_handle
,
884 unsigned long *byte_count
)
886 u64 r_cb
= virt_to_abs(rblock
);
888 if (r_cb
& (EHCA_PAGESIZE
-1)) {
889 ehca_gen_err("rblock not page aligned.");
893 return ehca_plpar_hcall_norets(H_ERROR_DATA
,
894 adapter_handle
.handle
,