2 * linux/drivers/net/ehea/ehea_qmr.c
4 * eHEA ethernet device driver for IBM eServer System p
6 * (C) Copyright IBM Corp. 2006
9 * Christoph Raisch <raisch@de.ibm.com>
10 * Jan-Bernd Themann <themann@de.ibm.com>
11 * Thomas Klein <tklein@de.ibm.com>
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)
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.
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.
30 #include "ehea_phyp.h"
33 static void *hw_qpageit_get_inc(struct hw_queue
*queue
)
35 void *retvalue
= hw_qeit_get(queue
);
37 queue
->current_q_offset
+= queue
->pagesize
;
38 if (queue
->current_q_offset
> queue
->queue_length
) {
39 queue
->current_q_offset
-= queue
->pagesize
;
41 } else if (((u64
) retvalue
) & (EHEA_PAGESIZE
-1)) {
42 ehea_error("not on pageboundary");
48 static int hw_queue_ctor(struct hw_queue
*queue
, const u32 nr_of_pages
,
49 const u32 pagesize
, const u32 qe_size
)
51 int pages_per_kpage
= PAGE_SIZE
/ pagesize
;
54 if ((pagesize
> PAGE_SIZE
) || (!pages_per_kpage
)) {
55 ehea_error("pagesize conflict! kernel pagesize=%d, "
56 "ehea pagesize=%d", (int)PAGE_SIZE
, (int)pagesize
);
60 queue
->queue_length
= nr_of_pages
* pagesize
;
61 queue
->queue_pages
= kmalloc(nr_of_pages
* sizeof(void*), GFP_KERNEL
);
62 if (!queue
->queue_pages
) {
63 ehea_error("no mem for queue_pages");
68 * allocate pages for queue:
69 * outer loop allocates whole kernel pages (page aligned) and
70 * inner loop divides a kernel page into smaller hea queue pages
73 while (i
< nr_of_pages
) {
74 u8
*kpage
= (u8
*)get_zeroed_page(GFP_KERNEL
);
77 for (k
= 0; k
< pages_per_kpage
&& i
< nr_of_pages
; k
++) {
78 (queue
->queue_pages
)[i
] = (struct ehea_page
*)kpage
;
84 queue
->current_q_offset
= 0;
85 queue
->qe_size
= qe_size
;
86 queue
->pagesize
= pagesize
;
87 queue
->toggle_state
= 1;
91 for (i
= 0; i
< nr_of_pages
; i
+= pages_per_kpage
) {
92 if (!(queue
->queue_pages
)[i
])
94 free_page((unsigned long)(queue
->queue_pages
)[i
]);
99 static void hw_queue_dtor(struct hw_queue
*queue
)
101 int pages_per_kpage
= PAGE_SIZE
/ queue
->pagesize
;
104 if (!queue
|| !queue
->queue_pages
)
107 nr_pages
= queue
->queue_length
/ queue
->pagesize
;
109 for (i
= 0; i
< nr_pages
; i
+= pages_per_kpage
)
110 free_page((unsigned long)(queue
->queue_pages
)[i
]);
112 kfree(queue
->queue_pages
);
115 struct ehea_cq
*ehea_create_cq(struct ehea_adapter
*adapter
,
116 int nr_of_cqe
, u64 eq_handle
, u32 cq_token
)
120 u64
*cq_handle_ref
, hret
, rpage
;
121 u32 act_nr_of_entries
, act_pages
, counter
;
125 cq
= kzalloc(sizeof(*cq
), GFP_KERNEL
);
127 ehea_error("no mem for cq");
131 cq
->attr
.max_nr_of_cqes
= nr_of_cqe
;
132 cq
->attr
.cq_token
= cq_token
;
133 cq
->attr
.eq_handle
= eq_handle
;
135 cq
->adapter
= adapter
;
137 cq_handle_ref
= &cq
->fw_handle
;
138 act_nr_of_entries
= 0;
141 hret
= ehea_h_alloc_resource_cq(adapter
->handle
, &cq
->attr
,
142 &cq
->fw_handle
, &cq
->epas
);
143 if (hret
!= H_SUCCESS
) {
144 ehea_error("alloc_resource_cq failed");
148 ret
= hw_queue_ctor(&cq
->hw_queue
, cq
->attr
.nr_pages
,
149 EHEA_PAGESIZE
, sizeof(struct ehea_cqe
));
153 for (counter
= 0; counter
< cq
->attr
.nr_pages
; counter
++) {
154 vpage
= hw_qpageit_get_inc(&cq
->hw_queue
);
156 ehea_error("hw_qpageit_get_inc failed");
160 rpage
= virt_to_abs(vpage
);
161 hret
= ehea_h_register_rpage(adapter
->handle
,
162 0, EHEA_CQ_REGISTER_ORIG
,
163 cq
->fw_handle
, rpage
, 1);
164 if (hret
< H_SUCCESS
) {
165 ehea_error("register_rpage_cq failed ehea_cq=%p "
166 "hret=%lx counter=%i act_pages=%i",
167 cq
, hret
, counter
, cq
->attr
.nr_pages
);
171 if (counter
== (cq
->attr
.nr_pages
- 1)) {
172 vpage
= hw_qpageit_get_inc(&cq
->hw_queue
);
174 if ((hret
!= H_SUCCESS
) || (vpage
)) {
175 ehea_error("registration of pages not "
176 "complete hret=%lx\n", hret
);
180 if ((hret
!= H_PAGE_REGISTERED
) || (!vpage
)) {
181 ehea_error("CQ: registration of page failed "
188 hw_qeit_reset(&cq
->hw_queue
);
189 epa
= cq
->epas
.kernel
;
190 ehea_reset_cq_ep(cq
);
191 ehea_reset_cq_n1(cq
);
196 hw_queue_dtor(&cq
->hw_queue
);
199 ehea_h_free_resource(adapter
->handle
, cq
->fw_handle
);
208 int ehea_destroy_cq(struct ehea_cq
*cq
)
210 u64 adapter_handle
, hret
;
212 adapter_handle
= cq
->adapter
->handle
;
217 /* deregister all previous registered pages */
218 hret
= ehea_h_free_resource(adapter_handle
, cq
->fw_handle
);
219 if (hret
!= H_SUCCESS
) {
220 ehea_error("destroy CQ failed");
224 hw_queue_dtor(&cq
->hw_queue
);
230 struct ehea_eq
*ehea_create_eq(struct ehea_adapter
*adapter
,
231 const enum ehea_eq_type type
,
232 const u32 max_nr_of_eqes
, const u8 eqe_gen
)
239 eq
= kzalloc(sizeof(*eq
), GFP_KERNEL
);
241 ehea_error("no mem for eq");
245 eq
->adapter
= adapter
;
246 eq
->attr
.type
= type
;
247 eq
->attr
.max_nr_of_eqes
= max_nr_of_eqes
;
248 eq
->attr
.eqe_gen
= eqe_gen
;
249 spin_lock_init(&eq
->spinlock
);
251 hret
= ehea_h_alloc_resource_eq(adapter
->handle
,
252 &eq
->attr
, &eq
->fw_handle
);
253 if (hret
!= H_SUCCESS
) {
254 ehea_error("alloc_resource_eq failed");
258 ret
= hw_queue_ctor(&eq
->hw_queue
, eq
->attr
.nr_pages
,
259 EHEA_PAGESIZE
, sizeof(struct ehea_eqe
));
261 ehea_error("can't allocate eq pages");
265 for (i
= 0; i
< eq
->attr
.nr_pages
; i
++) {
266 vpage
= hw_qpageit_get_inc(&eq
->hw_queue
);
268 ehea_error("hw_qpageit_get_inc failed");
273 rpage
= virt_to_abs(vpage
);
275 hret
= ehea_h_register_rpage(adapter
->handle
, 0,
276 EHEA_EQ_REGISTER_ORIG
,
277 eq
->fw_handle
, rpage
, 1);
279 if (i
== (eq
->attr
.nr_pages
- 1)) {
281 vpage
= hw_qpageit_get_inc(&eq
->hw_queue
);
282 if ((hret
!= H_SUCCESS
) || (vpage
)) {
286 if ((hret
!= H_PAGE_REGISTERED
) || (!vpage
)) {
292 hw_qeit_reset(&eq
->hw_queue
);
296 hw_queue_dtor(&eq
->hw_queue
);
299 ehea_h_free_resource(adapter
->handle
, eq
->fw_handle
);
306 struct ehea_eqe
*ehea_poll_eq(struct ehea_eq
*eq
)
308 struct ehea_eqe
*eqe
;
311 spin_lock_irqsave(&eq
->spinlock
, flags
);
312 eqe
= (struct ehea_eqe
*)hw_eqit_eq_get_inc_valid(&eq
->hw_queue
);
313 spin_unlock_irqrestore(&eq
->spinlock
, flags
);
318 int ehea_destroy_eq(struct ehea_eq
*eq
)
326 spin_lock_irqsave(&eq
->spinlock
, flags
);
328 hret
= ehea_h_free_resource(eq
->adapter
->handle
, eq
->fw_handle
);
329 spin_unlock_irqrestore(&eq
->spinlock
, flags
);
331 if (hret
!= H_SUCCESS
) {
332 ehea_error("destroy_eq failed");
336 hw_queue_dtor(&eq
->hw_queue
);
343 * allocates memory for a queue and registers pages in phyp
345 int ehea_qp_alloc_register(struct ehea_qp
*qp
, struct hw_queue
*hw_queue
,
346 int nr_pages
, int wqe_size
, int act_nr_sges
,
347 struct ehea_adapter
*adapter
, int h_call_q_selector
)
353 ret
= hw_queue_ctor(hw_queue
, nr_pages
, EHEA_PAGESIZE
, wqe_size
);
357 for (cnt
= 0; cnt
< nr_pages
; cnt
++) {
358 vpage
= hw_qpageit_get_inc(hw_queue
);
360 ehea_error("hw_qpageit_get_inc failed");
363 rpage
= virt_to_abs(vpage
);
364 hret
= ehea_h_register_rpage(adapter
->handle
,
365 0, h_call_q_selector
,
366 qp
->fw_handle
, rpage
, 1);
367 if (hret
< H_SUCCESS
) {
368 ehea_error("register_rpage_qp failed");
372 hw_qeit_reset(hw_queue
);
376 hw_queue_dtor(hw_queue
);
380 static inline u32
map_wqe_size(u8 wqe_enc_size
)
382 return 128 << wqe_enc_size
;
385 struct ehea_qp
*ehea_create_qp(struct ehea_adapter
*adapter
,
386 u32 pd
, struct ehea_qp_init_attr
*init_attr
)
391 u32 wqe_size_in_bytes_sq
, wqe_size_in_bytes_rq1
;
392 u32 wqe_size_in_bytes_rq2
, wqe_size_in_bytes_rq3
;
395 qp
= kzalloc(sizeof(*qp
), GFP_KERNEL
);
397 ehea_error("no mem for qp");
401 qp
->adapter
= adapter
;
403 hret
= ehea_h_alloc_resource_qp(adapter
->handle
, init_attr
, pd
,
404 &qp
->fw_handle
, &qp
->epas
);
405 if (hret
!= H_SUCCESS
) {
406 ehea_error("ehea_h_alloc_resource_qp failed");
410 wqe_size_in_bytes_sq
= map_wqe_size(init_attr
->act_wqe_size_enc_sq
);
411 wqe_size_in_bytes_rq1
= map_wqe_size(init_attr
->act_wqe_size_enc_rq1
);
412 wqe_size_in_bytes_rq2
= map_wqe_size(init_attr
->act_wqe_size_enc_rq2
);
413 wqe_size_in_bytes_rq3
= map_wqe_size(init_attr
->act_wqe_size_enc_rq3
);
415 ret
= ehea_qp_alloc_register(qp
, &qp
->hw_squeue
, init_attr
->nr_sq_pages
,
416 wqe_size_in_bytes_sq
,
417 init_attr
->act_wqe_size_enc_sq
, adapter
,
420 ehea_error("can't register for sq ret=%x", ret
);
424 ret
= ehea_qp_alloc_register(qp
, &qp
->hw_rqueue1
,
425 init_attr
->nr_rq1_pages
,
426 wqe_size_in_bytes_rq1
,
427 init_attr
->act_wqe_size_enc_rq1
,
430 ehea_error("can't register for rq1 ret=%x", ret
);
434 if (init_attr
->rq_count
> 1) {
435 ret
= ehea_qp_alloc_register(qp
, &qp
->hw_rqueue2
,
436 init_attr
->nr_rq2_pages
,
437 wqe_size_in_bytes_rq2
,
438 init_attr
->act_wqe_size_enc_rq2
,
441 ehea_error("can't register for rq2 ret=%x", ret
);
446 if (init_attr
->rq_count
> 2) {
447 ret
= ehea_qp_alloc_register(qp
, &qp
->hw_rqueue3
,
448 init_attr
->nr_rq3_pages
,
449 wqe_size_in_bytes_rq3
,
450 init_attr
->act_wqe_size_enc_rq3
,
453 ehea_error("can't register for rq3 ret=%x", ret
);
458 qp
->init_attr
= *init_attr
;
463 hw_queue_dtor(&qp
->hw_rqueue2
);
466 hw_queue_dtor(&qp
->hw_rqueue1
);
469 hw_queue_dtor(&qp
->hw_squeue
);
472 ehea_h_disable_and_get_hea(adapter
->handle
, qp
->fw_handle
);
473 ehea_h_free_resource(adapter
->handle
, qp
->fw_handle
);
480 int ehea_destroy_qp(struct ehea_qp
*qp
)
483 struct ehea_qp_init_attr
*qp_attr
= &qp
->init_attr
;
488 hret
= ehea_h_free_resource(qp
->adapter
->handle
, qp
->fw_handle
);
489 if (hret
!= H_SUCCESS
) {
490 ehea_error("destroy_qp failed");
494 hw_queue_dtor(&qp
->hw_squeue
);
495 hw_queue_dtor(&qp
->hw_rqueue1
);
497 if (qp_attr
->rq_count
> 1)
498 hw_queue_dtor(&qp
->hw_rqueue2
);
499 if (qp_attr
->rq_count
> 2)
500 hw_queue_dtor(&qp
->hw_rqueue3
);
506 int ehea_reg_mr_adapter(struct ehea_adapter
*adapter
)
509 u64 hret
, pt_abs
, start
, end
, nr_pages
;
510 u32 acc_ctrl
= EHEA_MR_ACC_CTRL
;
514 end
= (u64
)high_memory
;
515 nr_pages
= (end
- start
) / PAGE_SIZE
;
517 pt
= kzalloc(PAGE_SIZE
, GFP_KERNEL
);
519 ehea_error("no mem");
523 pt_abs
= virt_to_abs(pt
);
525 hret
= ehea_h_alloc_resource_mr(adapter
->handle
, start
, end
- start
,
526 acc_ctrl
, adapter
->pd
,
527 &adapter
->mr
.handle
, &adapter
->mr
.lkey
);
528 if (hret
!= H_SUCCESS
) {
529 ehea_error("alloc_resource_mr failed");
534 adapter
->mr
.vaddr
= KERNELBASE
;
537 while (nr_pages
> 0) {
539 u64 num_pages
= min(nr_pages
, (u64
)512);
540 for (i
= 0; i
< num_pages
; i
++)
541 pt
[i
] = virt_to_abs((void*)(((u64
)start
)
545 hret
= ehea_h_register_rpage_mr(adapter
->handle
,
546 adapter
->mr
.handle
, 0,
549 nr_pages
-= num_pages
;
551 u64 abs_adr
= virt_to_abs((void*)(((u64
)start
)
553 hret
= ehea_h_register_rpage_mr(adapter
->handle
,
554 adapter
->mr
.handle
, 0,
559 if ((hret
!= H_SUCCESS
) && (hret
!= H_PAGE_REGISTERED
)) {
560 ehea_h_free_resource(adapter
->handle
,
562 ehea_error("register_rpage_mr failed: hret = %lX",
569 if (hret
!= H_SUCCESS
) {
570 ehea_h_free_resource(adapter
->handle
, adapter
->mr
.handle
);
571 ehea_error("register_rpage failed for last page: hret = %lX",