blob: 0cfc2bc1a27b8a6c4ce49860a10f4e8999c50156 [file] [log] [blame]
Jan-Bernd Themann7a291082006-09-13 17:44:31 +02001/*
2 * linux/drivers/net/ehea/ehea_phyp.c
3 *
4 * eHEA ethernet device driver for IBM eServer System p
5 *
6 * (C) Copyright IBM Corp. 2006
7 *
8 * Authors:
9 * Christoph Raisch <raisch@de.ibm.com>
10 * Jan-Bernd Themann <themann@de.ibm.com>
11 * Thomas Klein <tklein@de.ibm.com>
12 *
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include "ehea_phyp.h"
30
31
32static inline u16 get_order_of_qentries(u16 queue_entries)
33{
34 u8 ld = 1; /* logarithmus dualis */
35 while (((1U << ld) - 1) < queue_entries)
36 ld++;
37 return ld - 1;
38}
39
40/* Defines for H_CALL H_ALLOC_RESOURCE */
41#define H_ALL_RES_TYPE_QP 1
42#define H_ALL_RES_TYPE_CQ 2
43#define H_ALL_RES_TYPE_EQ 3
44#define H_ALL_RES_TYPE_MR 5
45#define H_ALL_RES_TYPE_MW 6
46
Jan-Bernd Themann08093c82006-10-05 16:53:12 +020047static long ehea_plpar_hcall_norets(unsigned long opcode,
48 unsigned long arg1,
49 unsigned long arg2,
50 unsigned long arg3,
51 unsigned long arg4,
52 unsigned long arg5,
53 unsigned long arg6,
54 unsigned long arg7)
Jan-Bernd Themann7a291082006-09-13 17:44:31 +020055{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +020056 long ret;
Jan-Bernd Themann7a291082006-09-13 17:44:31 +020057 int i, sleep_msecs;
58
59 for (i = 0; i < 5; i++) {
Jan-Bernd Themann08093c82006-10-05 16:53:12 +020060 ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4,
61 arg5, arg6, arg7);
62
63 if (H_IS_LONG_BUSY(ret)) {
64 sleep_msecs = get_longbusy_msecs(ret);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +020065 msleep_interruptible(sleep_msecs);
66 continue;
67 }
68
Jan-Bernd Themann08093c82006-10-05 16:53:12 +020069 if (ret < H_SUCCESS)
70 ehea_error("opcode=%lx ret=%lx"
71 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
72 " arg5=%lx arg6=%lx arg7=%lx ",
73 opcode, ret,
74 arg1, arg2, arg3, arg4, arg5,
75 arg6, arg7);
76
77 return ret;
Jan-Bernd Themann7a291082006-09-13 17:44:31 +020078 }
Jan-Bernd Themann08093c82006-10-05 16:53:12 +020079
80 return H_BUSY;
81}
82
83static long ehea_plpar_hcall9(unsigned long opcode,
84 unsigned long *outs, /* array of 9 outputs */
85 unsigned long arg1,
86 unsigned long arg2,
87 unsigned long arg3,
88 unsigned long arg4,
89 unsigned long arg5,
90 unsigned long arg6,
91 unsigned long arg7,
92 unsigned long arg8,
93 unsigned long arg9)
94{
95 long ret;
96 int i, sleep_msecs;
97
98 for (i = 0; i < 5; i++) {
99 ret = plpar_hcall9(opcode, outs,
100 arg1, arg2, arg3, arg4, arg5,
101 arg6, arg7, arg8, arg9);
102
103 if (H_IS_LONG_BUSY(ret)) {
104 sleep_msecs = get_longbusy_msecs(ret);
105 msleep_interruptible(sleep_msecs);
106 continue;
107 }
108
109 if (ret < H_SUCCESS)
110 ehea_error("opcode=%lx ret=%lx"
111 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
112 " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
113 " arg9=%lx"
114 " out1=%lx out2=%lx out3=%lx out4=%lx"
115 " out5=%lx out6=%lx out7=%lx out8=%lx"
116 " out9=%lx",
117 opcode, ret,
118 arg1, arg2, arg3, arg4, arg5,
119 arg6, arg7, arg8, arg9,
120 outs[0], outs[1], outs[2], outs[3],
121 outs[4], outs[5], outs[6], outs[7],
122 outs[8]);
123
124 return ret;
125 }
126
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200127 return H_BUSY;
128}
129
130u64 ehea_h_query_ehea_qp(const u64 adapter_handle, const u8 qp_category,
131 const u64 qp_handle, const u64 sel_mask, void *cb_addr)
132{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200133 return ehea_plpar_hcall_norets(H_QUERY_HEA_QP,
134 adapter_handle, /* R4 */
135 qp_category, /* R5 */
136 qp_handle, /* R6 */
137 sel_mask, /* R7 */
138 virt_to_abs(cb_addr), /* R8 */
139 0, 0);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200140}
141
142/* input param R5 */
143#define H_ALL_RES_QP_EQPO EHEA_BMASK_IBM(9, 11)
144#define H_ALL_RES_QP_QPP EHEA_BMASK_IBM(12, 12)
145#define H_ALL_RES_QP_RQR EHEA_BMASK_IBM(13, 15)
146#define H_ALL_RES_QP_EQEG EHEA_BMASK_IBM(16, 16)
147#define H_ALL_RES_QP_LL_QP EHEA_BMASK_IBM(17, 17)
148#define H_ALL_RES_QP_DMA128 EHEA_BMASK_IBM(19, 19)
149#define H_ALL_RES_QP_HSM EHEA_BMASK_IBM(20, 21)
150#define H_ALL_RES_QP_SIGT EHEA_BMASK_IBM(22, 23)
151#define H_ALL_RES_QP_TENURE EHEA_BMASK_IBM(48, 55)
152#define H_ALL_RES_QP_RES_TYP EHEA_BMASK_IBM(56, 63)
153
154/* input param R9 */
155#define H_ALL_RES_QP_TOKEN EHEA_BMASK_IBM(0, 31)
156#define H_ALL_RES_QP_PD EHEA_BMASK_IBM(32,63)
157
158/* input param R10 */
159#define H_ALL_RES_QP_MAX_SWQE EHEA_BMASK_IBM(4, 7)
160#define H_ALL_RES_QP_MAX_R1WQE EHEA_BMASK_IBM(12, 15)
161#define H_ALL_RES_QP_MAX_R2WQE EHEA_BMASK_IBM(20, 23)
162#define H_ALL_RES_QP_MAX_R3WQE EHEA_BMASK_IBM(28, 31)
163/* Max Send Scatter Gather Elements */
164#define H_ALL_RES_QP_MAX_SSGE EHEA_BMASK_IBM(37, 39)
165#define H_ALL_RES_QP_MAX_R1SGE EHEA_BMASK_IBM(45, 47)
166/* Max Receive SG Elements RQ1 */
167#define H_ALL_RES_QP_MAX_R2SGE EHEA_BMASK_IBM(53, 55)
168#define H_ALL_RES_QP_MAX_R3SGE EHEA_BMASK_IBM(61, 63)
169
170/* input param R11 */
171#define H_ALL_RES_QP_SWQE_IDL EHEA_BMASK_IBM(0, 7)
172/* max swqe immediate data length */
173#define H_ALL_RES_QP_PORT_NUM EHEA_BMASK_IBM(48, 63)
174
175/* input param R12 */
176#define H_ALL_RES_QP_TH_RQ2 EHEA_BMASK_IBM(0, 15)
177/* Threshold RQ2 */
178#define H_ALL_RES_QP_TH_RQ3 EHEA_BMASK_IBM(16, 31)
179/* Threshold RQ3 */
180
181/* output param R6 */
182#define H_ALL_RES_QP_ACT_SWQE EHEA_BMASK_IBM(0, 15)
183#define H_ALL_RES_QP_ACT_R1WQE EHEA_BMASK_IBM(16, 31)
184#define H_ALL_RES_QP_ACT_R2WQE EHEA_BMASK_IBM(32, 47)
185#define H_ALL_RES_QP_ACT_R3WQE EHEA_BMASK_IBM(48, 63)
186
187/* output param, R7 */
188#define H_ALL_RES_QP_ACT_SSGE EHEA_BMASK_IBM(0, 7)
189#define H_ALL_RES_QP_ACT_R1SGE EHEA_BMASK_IBM(8, 15)
190#define H_ALL_RES_QP_ACT_R2SGE EHEA_BMASK_IBM(16, 23)
191#define H_ALL_RES_QP_ACT_R3SGE EHEA_BMASK_IBM(24, 31)
192#define H_ALL_RES_QP_ACT_SWQE_IDL EHEA_BMASK_IBM(32, 39)
193
194/* output param R8,R9 */
195#define H_ALL_RES_QP_SIZE_SQ EHEA_BMASK_IBM(0, 31)
196#define H_ALL_RES_QP_SIZE_RQ1 EHEA_BMASK_IBM(32, 63)
197#define H_ALL_RES_QP_SIZE_RQ2 EHEA_BMASK_IBM(0, 31)
198#define H_ALL_RES_QP_SIZE_RQ3 EHEA_BMASK_IBM(32, 63)
199
200/* output param R11,R12 */
201#define H_ALL_RES_QP_LIOBN_SQ EHEA_BMASK_IBM(0, 31)
202#define H_ALL_RES_QP_LIOBN_RQ1 EHEA_BMASK_IBM(32, 63)
203#define H_ALL_RES_QP_LIOBN_RQ2 EHEA_BMASK_IBM(0, 31)
204#define H_ALL_RES_QP_LIOBN_RQ3 EHEA_BMASK_IBM(32, 63)
205
206u64 ehea_h_alloc_resource_qp(const u64 adapter_handle,
207 struct ehea_qp_init_attr *init_attr, const u32 pd,
208 u64 *qp_handle, struct h_epas *h_epas)
209{
210 u64 hret;
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200211 u64 outs[PLPAR_HCALL9_BUFSIZE];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200212
213 u64 allocate_controls =
214 EHEA_BMASK_SET(H_ALL_RES_QP_EQPO, init_attr->low_lat_rq1 ? 1 : 0)
215 | EHEA_BMASK_SET(H_ALL_RES_QP_QPP, 0)
216 | EHEA_BMASK_SET(H_ALL_RES_QP_RQR, 6) /* rq1 & rq2 & rq3 */
217 | EHEA_BMASK_SET(H_ALL_RES_QP_EQEG, 0) /* EQE gen. disabled */
218 | EHEA_BMASK_SET(H_ALL_RES_QP_LL_QP, init_attr->low_lat_rq1)
219 | EHEA_BMASK_SET(H_ALL_RES_QP_DMA128, 0)
220 | EHEA_BMASK_SET(H_ALL_RES_QP_HSM, 0)
221 | EHEA_BMASK_SET(H_ALL_RES_QP_SIGT, init_attr->signalingtype)
222 | EHEA_BMASK_SET(H_ALL_RES_QP_RES_TYP, H_ALL_RES_TYPE_QP);
223
224 u64 r9_reg = EHEA_BMASK_SET(H_ALL_RES_QP_PD, pd)
225 | EHEA_BMASK_SET(H_ALL_RES_QP_TOKEN, init_attr->qp_token);
226
227 u64 max_r10_reg =
228 EHEA_BMASK_SET(H_ALL_RES_QP_MAX_SWQE,
229 get_order_of_qentries(init_attr->max_nr_send_wqes))
230 | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R1WQE,
231 get_order_of_qentries(init_attr->max_nr_rwqes_rq1))
232 | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R2WQE,
233 get_order_of_qentries(init_attr->max_nr_rwqes_rq2))
234 | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R3WQE,
235 get_order_of_qentries(init_attr->max_nr_rwqes_rq3))
236 | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_SSGE, init_attr->wqe_size_enc_sq)
237 | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R1SGE,
238 init_attr->wqe_size_enc_rq1)
239 | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R2SGE,
240 init_attr->wqe_size_enc_rq2)
241 | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R3SGE,
242 init_attr->wqe_size_enc_rq3);
243
244 u64 r11_in =
245 EHEA_BMASK_SET(H_ALL_RES_QP_SWQE_IDL, init_attr->swqe_imm_data_len)
246 | EHEA_BMASK_SET(H_ALL_RES_QP_PORT_NUM, init_attr->port_nr);
247 u64 threshold =
248 EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ2, init_attr->rq2_threshold)
249 | EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ3, init_attr->rq3_threshold);
250
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200251 hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE,
252 outs,
253 adapter_handle, /* R4 */
254 allocate_controls, /* R5 */
255 init_attr->send_cq_handle, /* R6 */
256 init_attr->recv_cq_handle, /* R7 */
257 init_attr->aff_eq_handle, /* R8 */
258 r9_reg, /* R9 */
259 max_r10_reg, /* R10 */
260 r11_in, /* R11 */
261 threshold); /* R12 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200262
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200263 *qp_handle = outs[0];
264 init_attr->qp_nr = (u32)outs[1];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200265
266 init_attr->act_nr_send_wqes =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200267 (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_SWQE, outs[2]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200268 init_attr->act_nr_rwqes_rq1 =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200269 (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R1WQE, outs[2]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200270 init_attr->act_nr_rwqes_rq2 =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200271 (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R2WQE, outs[2]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200272 init_attr->act_nr_rwqes_rq3 =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200273 (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R3WQE, outs[2]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200274
275 init_attr->act_wqe_size_enc_sq = init_attr->wqe_size_enc_sq;
276 init_attr->act_wqe_size_enc_rq1 = init_attr->wqe_size_enc_rq1;
277 init_attr->act_wqe_size_enc_rq2 = init_attr->wqe_size_enc_rq2;
278 init_attr->act_wqe_size_enc_rq3 = init_attr->wqe_size_enc_rq3;
279
280 init_attr->nr_sq_pages =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200281 (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_SQ, outs[4]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200282 init_attr->nr_rq1_pages =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200283 (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ1, outs[4]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200284 init_attr->nr_rq2_pages =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200285 (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ2, outs[5]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200286 init_attr->nr_rq3_pages =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200287 (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ3, outs[5]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200288
289 init_attr->liobn_sq =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200290 (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_SQ, outs[7]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200291 init_attr->liobn_rq1 =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200292 (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ1, outs[7]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200293 init_attr->liobn_rq2 =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200294 (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ2, outs[8]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200295 init_attr->liobn_rq3 =
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200296 (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ3, outs[8]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200297
298 if (!hret)
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200299 hcp_epas_ctor(h_epas, outs[6], outs[6]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200300
301 return hret;
302}
303
304u64 ehea_h_alloc_resource_cq(const u64 adapter_handle,
305 struct ehea_cq_attr *cq_attr,
306 u64 *cq_handle, struct h_epas *epas)
307{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200308 u64 hret;
309 u64 outs[PLPAR_HCALL9_BUFSIZE];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200310
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200311 hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE,
312 outs,
313 adapter_handle, /* R4 */
314 H_ALL_RES_TYPE_CQ, /* R5 */
315 cq_attr->eq_handle, /* R6 */
316 cq_attr->cq_token, /* R7 */
317 cq_attr->max_nr_of_cqes, /* R8 */
318 0, 0, 0, 0); /* R9-R12 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200319
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200320 *cq_handle = outs[0];
321 cq_attr->act_nr_of_cqes = outs[3];
322 cq_attr->nr_pages = outs[4];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200323
324 if (!hret)
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200325 hcp_epas_ctor(epas, outs[5], outs[6]);
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200326
327 return hret;
328}
329
330/* Defines for H_CALL H_ALLOC_RESOURCE */
331#define H_ALL_RES_TYPE_QP 1
332#define H_ALL_RES_TYPE_CQ 2
333#define H_ALL_RES_TYPE_EQ 3
334#define H_ALL_RES_TYPE_MR 5
335#define H_ALL_RES_TYPE_MW 6
336
337/* input param R5 */
338#define H_ALL_RES_EQ_NEQ EHEA_BMASK_IBM(0, 0)
339#define H_ALL_RES_EQ_NON_NEQ_ISN EHEA_BMASK_IBM(6, 7)
340#define H_ALL_RES_EQ_INH_EQE_GEN EHEA_BMASK_IBM(16, 16)
341#define H_ALL_RES_EQ_RES_TYPE EHEA_BMASK_IBM(56, 63)
342/* input param R6 */
343#define H_ALL_RES_EQ_MAX_EQE EHEA_BMASK_IBM(32, 63)
344
345/* output param R6 */
346#define H_ALL_RES_EQ_LIOBN EHEA_BMASK_IBM(32, 63)
347
348/* output param R7 */
349#define H_ALL_RES_EQ_ACT_EQE EHEA_BMASK_IBM(32, 63)
350
351/* output param R8 */
352#define H_ALL_RES_EQ_ACT_PS EHEA_BMASK_IBM(32, 63)
353
354/* output param R9 */
355#define H_ALL_RES_EQ_ACT_EQ_IST_C EHEA_BMASK_IBM(30, 31)
356#define H_ALL_RES_EQ_ACT_EQ_IST_1 EHEA_BMASK_IBM(40, 63)
357
358/* output param R10 */
359#define H_ALL_RES_EQ_ACT_EQ_IST_2 EHEA_BMASK_IBM(40, 63)
360
361/* output param R11 */
362#define H_ALL_RES_EQ_ACT_EQ_IST_3 EHEA_BMASK_IBM(40, 63)
363
364/* output param R12 */
365#define H_ALL_RES_EQ_ACT_EQ_IST_4 EHEA_BMASK_IBM(40, 63)
366
367u64 ehea_h_alloc_resource_eq(const u64 adapter_handle,
368 struct ehea_eq_attr *eq_attr, u64 *eq_handle)
369{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200370 u64 hret, allocate_controls;
371 u64 outs[PLPAR_HCALL9_BUFSIZE];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200372
373 /* resource type */
374 allocate_controls =
375 EHEA_BMASK_SET(H_ALL_RES_EQ_RES_TYPE, H_ALL_RES_TYPE_EQ)
376 | EHEA_BMASK_SET(H_ALL_RES_EQ_NEQ, eq_attr->type ? 1 : 0)
377 | EHEA_BMASK_SET(H_ALL_RES_EQ_INH_EQE_GEN, !eq_attr->eqe_gen)
378 | EHEA_BMASK_SET(H_ALL_RES_EQ_NON_NEQ_ISN, 1);
379
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200380 hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE,
381 outs,
382 adapter_handle, /* R4 */
383 allocate_controls, /* R5 */
384 eq_attr->max_nr_of_eqes, /* R6 */
385 0, 0, 0, 0, 0, 0); /* R7-R10 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200386
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200387 *eq_handle = outs[0];
388 eq_attr->act_nr_of_eqes = outs[3];
389 eq_attr->nr_pages = outs[4];
390 eq_attr->ist1 = outs[5];
391 eq_attr->ist2 = outs[6];
392 eq_attr->ist3 = outs[7];
393 eq_attr->ist4 = outs[8];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200394
395 return hret;
396}
397
398u64 ehea_h_modify_ehea_qp(const u64 adapter_handle, const u8 cat,
399 const u64 qp_handle, const u64 sel_mask,
400 void *cb_addr, u64 *inv_attr_id, u64 *proc_mask,
401 u16 *out_swr, u16 *out_rwr)
402{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200403 u64 hret;
404 u64 outs[PLPAR_HCALL9_BUFSIZE];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200405
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200406 hret = ehea_plpar_hcall9(H_MODIFY_HEA_QP,
407 outs,
408 adapter_handle, /* R4 */
409 (u64) cat, /* R5 */
410 qp_handle, /* R6 */
411 sel_mask, /* R7 */
412 virt_to_abs(cb_addr), /* R8 */
413 0, 0, 0, 0); /* R9-R12 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200414
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200415 *inv_attr_id = outs[0];
416 *out_swr = outs[3];
417 *out_rwr = outs[4];
418 *proc_mask = outs[5];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200419
420 return hret;
421}
422
423u64 ehea_h_register_rpage(const u64 adapter_handle, const u8 pagesize,
424 const u8 queue_type, const u64 resource_handle,
425 const u64 log_pageaddr, u64 count)
426{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200427 u64 reg_control;
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200428
429 reg_control = EHEA_BMASK_SET(H_REG_RPAGE_PAGE_SIZE, pagesize)
430 | EHEA_BMASK_SET(H_REG_RPAGE_QT, queue_type);
431
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200432 return ehea_plpar_hcall_norets(H_REGISTER_HEA_RPAGES,
433 adapter_handle, /* R4 */
434 reg_control, /* R5 */
435 resource_handle, /* R6 */
436 log_pageaddr, /* R7 */
437 count, /* R8 */
438 0, 0); /* R9-R10 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200439}
440
441u64 ehea_h_register_smr(const u64 adapter_handle, const u64 orig_mr_handle,
442 const u64 vaddr_in, const u32 access_ctrl, const u32 pd,
443 struct ehea_mr *mr)
444{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200445 u64 hret;
446 u64 outs[PLPAR_HCALL9_BUFSIZE];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200447
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200448 hret = ehea_plpar_hcall9(H_REGISTER_SMR,
449 outs,
450 adapter_handle , /* R4 */
451 orig_mr_handle, /* R5 */
452 vaddr_in, /* R6 */
453 (((u64)access_ctrl) << 32ULL), /* R7 */
454 pd, /* R8 */
455 0, 0, 0, 0); /* R9-R12 */
456
457 mr->handle = outs[0];
458 mr->lkey = (u32)outs[2];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200459
460 return hret;
461}
462
463u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle)
464{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200465 u64 outs[PLPAR_HCALL9_BUFSIZE];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200466
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200467 return ehea_plpar_hcall9(H_DISABLE_AND_GET_HEA,
468 outs,
469 adapter_handle, /* R4 */
470 H_DISABLE_GET_EHEA_WQE_P, /* R5 */
471 qp_handle, /* R6 */
472 0, 0, 0, 0, 0, 0); /* R7-R12 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200473}
474
475u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle)
476{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200477 return ehea_plpar_hcall_norets(H_FREE_RESOURCE,
478 adapter_handle, /* R4 */
479 res_handle, /* R5 */
480 0, 0, 0, 0, 0); /* R6-R10 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200481}
482
483u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr,
484 const u64 length, const u32 access_ctrl,
485 const u32 pd, u64 *mr_handle, u32 *lkey)
486{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200487 u64 hret;
488 u64 outs[PLPAR_HCALL9_BUFSIZE];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200489
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200490 hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE,
491 outs,
492 adapter_handle, /* R4 */
493 5, /* R5 */
494 vaddr, /* R6 */
495 length, /* R7 */
496 (((u64) access_ctrl) << 32ULL), /* R8 */
497 pd, /* R9 */
498 0, 0, 0); /* R10-R12 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200499
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200500 *mr_handle = outs[0];
501 *lkey = (u32)outs[2];
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200502 return hret;
503}
504
505u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle,
506 const u8 pagesize, const u8 queue_type,
507 const u64 log_pageaddr, const u64 count)
508{
Thomas Kleina1d261c2006-11-03 17:48:23 +0100509 if ((count > 1) && (log_pageaddr & ~PAGE_MASK)) {
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200510 ehea_error("not on pageboundary");
511 return H_PARAMETER;
512 }
513
514 return ehea_h_register_rpage(adapter_handle, pagesize,
515 queue_type, mr_handle,
516 log_pageaddr, count);
517}
518
519u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr)
520{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200521 u64 hret, cb_logaddr;
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200522
523 cb_logaddr = virt_to_abs(cb_addr);
524
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200525 hret = ehea_plpar_hcall_norets(H_QUERY_HEA,
526 adapter_handle, /* R4 */
527 cb_logaddr, /* R5 */
528 0, 0, 0, 0, 0); /* R6-R10 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200529#ifdef DEBUG
530 ehea_dmp(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea");
531#endif
532 return hret;
533}
534
535u64 ehea_h_query_ehea_port(const u64 adapter_handle, const u16 port_num,
536 const u8 cb_cat, const u64 select_mask,
537 void *cb_addr)
538{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200539 u64 port_info;
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200540 u64 cb_logaddr = virt_to_abs(cb_addr);
541 u64 arr_index = 0;
542
543 port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat)
544 | EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num);
545
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200546 return ehea_plpar_hcall_norets(H_QUERY_HEA_PORT,
547 adapter_handle, /* R4 */
548 port_info, /* R5 */
549 select_mask, /* R6 */
550 arr_index, /* R7 */
551 cb_logaddr, /* R8 */
552 0, 0); /* R9-R10 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200553}
554
555u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,
556 const u8 cb_cat, const u64 select_mask,
557 void *cb_addr)
558{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200559 u64 outs[PLPAR_HCALL9_BUFSIZE];
560 u64 port_info;
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200561 u64 arr_index = 0;
562 u64 cb_logaddr = virt_to_abs(cb_addr);
563
564 port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat)
565 | EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num);
566#ifdef DEBUG
567 ehea_dump(cb_addr, sizeof(struct hcp_ehea_port_cb0), "Before HCALL");
568#endif
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200569 return ehea_plpar_hcall9(H_MODIFY_HEA_PORT,
570 outs,
571 adapter_handle, /* R4 */
572 port_info, /* R5 */
573 select_mask, /* R6 */
574 arr_index, /* R7 */
575 cb_logaddr, /* R8 */
576 0, 0, 0, 0); /* R9-R12 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200577}
578
579u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num,
580 const u8 reg_type, const u64 mc_mac_addr,
581 const u16 vlan_id, const u32 hcall_id)
582{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200583 u64 r5_port_num, r6_reg_type, r7_mc_mac_addr, r8_vlan_id;
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200584 u64 mac_addr = mc_mac_addr >> 16;
585
586 r5_port_num = EHEA_BMASK_SET(H_REGBCMC_PN, port_num);
587 r6_reg_type = EHEA_BMASK_SET(H_REGBCMC_REGTYPE, reg_type);
588 r7_mc_mac_addr = EHEA_BMASK_SET(H_REGBCMC_MACADDR, mac_addr);
589 r8_vlan_id = EHEA_BMASK_SET(H_REGBCMC_VLANID, vlan_id);
590
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200591 return ehea_plpar_hcall_norets(hcall_id,
592 adapter_handle, /* R4 */
593 r5_port_num, /* R5 */
594 r6_reg_type, /* R6 */
595 r7_mc_mac_addr, /* R7 */
596 r8_vlan_id, /* R8 */
597 0, 0); /* R9-R12 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200598}
599
600u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle,
601 const u64 event_mask)
602{
Jan-Bernd Themann08093c82006-10-05 16:53:12 +0200603 return ehea_plpar_hcall_norets(H_RESET_EVENTS,
604 adapter_handle, /* R4 */
605 neq_handle, /* R5 */
606 event_mask, /* R6 */
607 0, 0, 0, 0); /* R7-R12 */
Jan-Bernd Themann7a291082006-09-13 17:44:31 +0200608}