ehea: queue management
Subsystems (2)
PATCH 3/7 ehea: queue management
Signed-off-by Jan-Bernd Themann <[email protected]>
drivers/net/ehea/ehea_qmr.c | 757 ++++++++++++++++++++++++++++++++++++++++++++ drivers/net/ehea/ehea_qmr.h | 392 ++++++++++++++++++++++ 2 files changed, 1149 insertions(+)
drivers/net/ehea/ehea_qmr.c +757 -0
@@ -0,0 +1,757 @@ +/* +* linux/drivers/net/ehea/ehea_qmr.c +* +* eHEA ethernet device driver for IBM eServer System p +* +* (C) Copyright IBM Corp. 2006 +* +* Authors: +* Christoph Raisch <[email protected]> +* Jan-Bernd Themann <[email protected]> +* Heiko-Joerg Schick <[email protected]> +* Thomas Klein <[email protected]> +* +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "ehea.h" +#include "ehea_phyp.h" +#include "ehea_qmr.h" + +static void *hw_qpageit_get_inc (struct hw_queue *queue) +{ +void *retvalue =hw_qeit_get (queue); + queue->current_q_offset += queue->pagesize; +if (queue->current_q_offset > queue->queue_length) { + queue->current_q_offset -= queue->pagesize; + retvalue =NULL ; + } +else if ((((u64 ) retvalue) & (EHEA_PAGESIZE -1 )) !=0 ) { +EDEB_ERR (4 ,"ERROR!! not at PAGE-Boundary" ); +return NULL ; + } +EDEB (7 ,"queue=%p retvalue=%p" , queue, retvalue); +return retvalue; +} + +static int hw_queue_ctor (struct hw_queue *queue,const u32 nr_of_pages, +const u32 pagesize,const u32 qe_size) +{ +int pages_per_kpage =PAGE_SIZE / pagesize; +int i; + +EDEB_EN (7 ,"nr_of_pages=%x pagesize=%x qe_size=%x pages_per_kpage=%x" , + nr_of_pages, pagesize, qe_size, pages_per_kpage); +if (pagesize >PAGE_SIZE ) { +EDEB_ERR (4 ,"FATAL ERROR: pagesize=%x is greater than " +"kernel page size" , pagesize); +return 0 ; + } +if (!pages_per_kpage) { +EDEB_ERR (4 ,"FATAL ERROR: invalid kernel page size. " +"pages_per_kpage=%x" , pages_per_kpage); +return 0 ; + } + queue->queue_length = nr_of_pages * pagesize; + queue->queue_pages =vmalloc (nr_of_pages *sizeof (void *)); +if (!queue->queue_pages) { +EDEB (4 ,"ERROR!! didn't get the memory" ); +return 0 ; + } +memset (queue->queue_pages,0 , nr_of_pages *sizeof (void *)); +/* +* allocate pages for queue: +* outer loop allocates whole kernel pages (page aligned) and +* inner loop divides a kernel page into smaller hea queue pages +*/ + i =0 ; +while (i < nr_of_pages) { +u8 *kpage = (u8 *)get_zeroed_page (GFP_KERNEL ); +int k; +if (!kpage) + goto hw_queue_ctor_exit0;/*NOMEM*/ +for (k =0 ; k < pages_per_kpage && i < nr_of_pages; k++) { + (queue->queue_pages)[i] = (struct ehea_page *)kpage; + kpage += pagesize; + i++; + } + } + + queue->current_q_offset =0 ; + queue->qe_size = qe_size; + queue->pagesize = pagesize; + queue->toggle_state =1 ; +EDEB_EX (7 ,"queue_length=%x queue_pages=%p qe_size=%x" , + queue->queue_length, queue->queue_pages, + queue->qe_size); +return 1 ; + + hw_queue_ctor_exit0: +EDEB_ERR (4 ,"Couldn't get alloc pages queue=%p f=%x nr_of_pages=%x" , + queue, i, nr_of_pages); +for (i =0 ; i < nr_of_pages; i += pages_per_kpage) { +if (!(queue->queue_pages)[i]) +break ; +free_page ((unsigned long )(queue->queue_pages)[i]); + } +return 0 ; +} + +static int hw_queue_dtor (struct hw_queue *queue) +{ +int pages_per_kpage =PAGE_SIZE / queue->pagesize; +int i; +int nr_pages; + +EDEB_EN (7 ,"hw_queue pointer=%p" , queue); +if (!queue || !queue->queue_pages) { +EDEB_ERR (4 ,"queue or queue_pages is NULL" ); +return 0 ; + } +EDEB (7 ,"destructing a queue with the following " +"properties:\n pagesize=%x qe_size=%x" , + queue->pagesize, queue->qe_size); + nr_pages = queue->queue_length / queue->pagesize; +for (i =0 ; i < nr_pages; i += pages_per_kpage) +free_page ((unsigned long )(queue->queue_pages)[i]); +vfree (queue->queue_pages); + +EDEB_EX (7 ,"queue freed!" ); +return 1 ; +} + +struct ehea_cq *ehea_create_cq (struct ehea_adapter *adapter, +int nr_of_cqe,u64 eq_handle,u32 cq_token) +{ +struct ehea_cq *cq =NULL ; +struct h_epa epa; + +u64 *cq_handle_ref; +u32 act_nr_of_entries; +u32 act_pages; +u64 hret =H_HARDWARE ; +int hwret; +u32 counter; +void *vpage =NULL ; +u64 rpage =0 ; + +EDEB_EN (7 ,"adapter=%p nr_of_cqe=%x , eq_handle: %016lX" , + adapter, nr_of_cqe, eq_handle); + + cq =kzalloc (sizeof (*cq),GFP_KERNEL ); +if (!cq) { + cq =NULL ; +EDEB_ERR (4 ,"ehea_create_cq ret=%p (-ENOMEM)" , cq); + goto create_cq_exit0; + } + + cq->attr.max_nr_of_cqes = nr_of_cqe; + cq->attr.cq_token = cq_token; + cq->attr.eq_handle = eq_handle; + + cq->adapter = adapter; + + cq_handle_ref = &cq->fw_handle; + act_nr_of_entries =0 ; + act_pages =0 ; + + hret =ehea_h_alloc_resource_cq (adapter->handle, cq, &cq->attr, + &cq->fw_handle, &cq->epas); +if (hret !=H_SUCCESS ) { +EDEB_ERR (4 ,"ehea_h_alloc_resource_cq failed. hret=%lx" , hret); + goto create_cq_exit1; + } + + hwret =hw_queue_ctor (&cq->hw_queue, cq->attr.nr_pages, +EHEA_PAGESIZE ,sizeof (struct ehea_cqe )); +if (!hwret) + goto create_cq_exit2; + +for (counter =0 ; counter < cq->attr.nr_pages; counter++) { + vpage =hw_qpageit_get_inc (&cq->hw_queue); +if (!vpage) { +EDEB_ERR (4 ,"hw_qpageit_get_inc() " +"returns NULL adapter=%p" , adapter); + goto create_cq_exit3; + } + + rpage =virt_to_abs (vpage); + + hret =ehea_h_register_rpage_cq (adapter->handle, + cq->fw_handle, +0 , +EHEA_CQ_REGISTER_ORIG , + rpage,1 , cq->epas.kernel); + +if (hret <H_SUCCESS ) { +EDEB_ERR (4 ,"ehea_h_register_rpage_cq() failed " +"ehea_cq=%p hret=%lx " +"counter=%i act_pages=%i" , + cq, hret, counter, cq->attr.nr_pages); + goto create_cq_exit3; + } + +if (counter == (cq->attr.nr_pages -1 )) { + vpage =hw_qpageit_get_inc (&cq->hw_queue); + +if ((hret !=H_SUCCESS ) || (vpage)) { +EDEB_ERR (4 ,"Registration of pages not " +"complete ehea_cq=%p hret=%lx" , + cq, hret) + goto create_cq_exit3; + } + }else { +if ((hret !=H_PAGE_REGISTERED ) || (!vpage)) { +EDEB_ERR (4 ,"Registration of page failed " +"ehea_cq=%p hret=%lx" +"counter=%i act_pages=%i" , + cq, hret, counter, cq->attr.nr_pages); + goto create_cq_exit3; + } + } + } + +hw_qeit_reset (&cq->hw_queue); + epa = cq->epas.kernel; +ehea_reset_cq_ep (cq); +ehea_reset_cq_n1 (cq); + +EDEB_EX (7 ,"ret=%p " , cq); +return cq; + +create_cq_exit3: +hw_queue_dtor (&cq->hw_queue); + +create_cq_exit2: +ehea_h_destroy_cq (adapter->handle, cq, cq->fw_handle, &cq->epas); + +create_cq_exit1: +kfree (cq); + +create_cq_exit0: +EDEB_EX (7 ,"ret=NULL" ); +return NULL ; +} + +int ehea_destroy_cq (struct ehea_cq *cq) +{ +int ret =0 ; +u64 adapter_handle; +u64 hret =H_HARDWARE ; + + adapter_handle = cq->adapter->handle; +EDEB_EN (7 ,"adapter=%p cq=%p" , cq->adapter, cq); + +if (!cq) +return 0 ; + +/* deregister all previous registered pages */ + hret =ehea_h_destroy_cq (adapter_handle, cq, cq->fw_handle, + &cq->epas); +if (hret !=H_SUCCESS ) { +EDEB_ERR (4 ,"destroy CQ failed!" ); +return -EINVAL ; + } +hw_queue_dtor (&cq->hw_queue); +kfree (cq); + +EDEB_EX (7 ,"ret=%x " , ret); +return ret; +} + +struct ehea_eq *ehea_create_eq (struct ehea_adapter *adapter, +const enum ehea_eq_type type, +const u32 max_nr_of_eqes,const u8 eqe_gen) +{ +u64 hret =H_HARDWARE ; +int ret =0 ; +u32 i; +void *vpage =NULL ; +u64 rpage =0 ; +struct ehea_eq *eq; + +EDEB_EN (7 ,"adapter=%p, max_nr_of_eqes=%x" , adapter, max_nr_of_eqes); + + eq =kzalloc (sizeof (*eq),GFP_KERNEL ); +if (!eq) +return NULL ; + + eq->adapter = adapter; + eq->attr.type = type; + eq->attr.max_nr_of_eqes = max_nr_of_eqes; + eq->attr.eqe_gen = eqe_gen; +spin_lock_init (&eq->spinlock); + + hret =ehea_h_alloc_resource_eq (adapter->handle, + eq, &eq->attr, &eq->fw_handle); + +if (hret !=H_SUCCESS ) { +EDEB_ERR (4 ,"ehea_h_alloc_resource_eq failed. hret=%lx" , hret); + goto free_eq_mem; + } + + ret =hw_queue_ctor (&eq->hw_queue, eq->attr.nr_pages, +EHEA_PAGESIZE ,sizeof (struct ehea_eqe )); +if (!ret) { +EDEB_ERR (4 ,"can't allocate EQ pages" ); + goto alloc_pages_failed; + } + +for (i =0 ; i < eq->attr.nr_pages; i++) { + vpage =hw_qpageit_get_inc (&eq->hw_queue); +if (!vpage) { + hret =H_RESOURCE ; + goto register_page_failed; + } + + rpage =virt_to_abs (vpage); + + hret =ehea_h_register_rpage_eq (adapter->handle, + eq->fw_handle, +0 , +EHEA_EQ_REGISTER_ORIG , + rpage,1 ); + +if (i == (eq->attr.nr_pages -1 )) { +/* last page */ + vpage =hw_qpageit_get_inc (&eq->hw_queue); +if ((hret !=H_SUCCESS ) || (vpage)) { + goto register_page_failed; + } + }else { +if ((hret !=H_PAGE_REGISTERED ) || (!vpage)) { + goto register_page_failed; + } + } + } + +hw_qeit_reset (&eq->hw_queue); + +EDEB_EX (7 ,"hret=%lx" , hret); +return eq; + +register_page_failed: +hw_queue_dtor (&eq->hw_queue); + +alloc_pages_failed: +ehea_h_destroy_eq (adapter->handle, eq, eq->fw_handle, &eq->epas); +free_eq_mem: +kfree (eq); + +EDEB_EX (7 ,"return with error hret=%lx" , hret); +return NULL ; +} + +struct ehea_eqe *ehea_poll_eq (struct ehea_eq *eq) +{ +struct ehea_eqe *eqe =NULL ; +unsigned long flags =0 ; + +EDEB_EN (7 ,"adapter=%p eq=%p" , eq->adapter, eq); + +spin_lock_irqsave (&eq->spinlock, flags); + eqe = (struct ehea_eqe *)hw_eqit_eq_get_inc_valid (&eq->hw_queue); +spin_unlock_irqrestore (&eq->spinlock, flags); + +EDEB_EX (7 ,"eqe=%p" , eqe); + +return eqe; +} + +int ehea_destroy_eq (struct ehea_eq *eq) +{ +unsigned long flags =0 ; +u64 hret =H_HARDWARE ; + +EDEB_EN (7 ,"adapter=%p eq=%p" , eq->adapter, eq); + +if (!eq) +return 0 ; + +spin_lock_irqsave (&eq->spinlock, flags); + + hret =ehea_h_destroy_eq (eq->adapter->handle, eq, eq->fw_handle, + &eq->epas); +spin_unlock_irqrestore (&eq->spinlock, flags); + +if (hret !=H_SUCCESS ) { +EDEB_ERR (4 ,"Failed freeing EQ resources. hret=%lx" , hret); +return -EINVAL ; + } +hw_queue_dtor (&eq->hw_queue); +kfree (eq); +EDEB_EX (7 ,"" ); + +return 0 ; +} + +/** +* allocates memory for a queue and registers pages in phyp +*/ +int ehea_qp_alloc_register (struct ehea_qp *qp, +struct hw_queue *hw_queue, +int nr_pages, +int wqe_size, +int act_nr_sges, +struct ehea_adapter *adapter,int h_call_q_selector) +{ +u64 hret =H_HARDWARE ; +u64 rpage =0 ; +int iret =0 ; +int cnt =0 ; +void *vpage =NULL ; + + iret =hw_queue_ctor (hw_queue, + nr_pages,EHEA_PAGESIZE , wqe_size); +if (!iret) { +EDEB_ERR (4 ,"Cannot allocate page for queue. iret=%x" , iret); +return -ENOMEM ; + } + +EDEB (7 ,"queue_size=%x, alloc_len=%x, toggle_state=%d" , + hw_queue->qe_size, + hw_queue->queue_length, hw_queue->toggle_state); + +for (cnt =0 ; cnt < nr_pages; cnt++) { + vpage =hw_qpageit_get_inc (hw_queue); +if (!vpage) { +EDEB_ERR (4 ,"SQ hw_qpageit_get_inc() " +"failed p_vpage= %p" , vpage); + goto qp_alloc_register_exit0; + } + rpage =virt_to_abs (vpage); + + hret =ehea_h_register_rpage_qp (adapter->handle, qp->fw_handle, +0 , h_call_q_selector, rpage,1 , + qp->epas.kernel); +if (hret <H_SUCCESS ) { +EDEB_ERR (4 ,"ehea_h_register_rpage_qp failed. hret=%lx" , + hret); + goto qp_alloc_register_exit0; + } + } +hw_qeit_reset (hw_queue); + +return 0 ; + +qp_alloc_register_exit0: +hw_queue_dtor (hw_queue); +return -EINVAL ; +} + +static inline u32 map_wqe_size (u8 wqe_enc_size) +{ +return 128 << wqe_enc_size; +} + +struct ehea_qp *ehea_create_qp (struct ehea_adapter *adapter, +u32 pd,struct ehea_qp_init_attr *init_attr) +{ +struct ehea_qp *qp; +u64 hret =H_HARDWARE ; + +u32 wqe_size_in_bytes_sq =0 ; +u32 wqe_size_in_bytes_rq1 =0 ; +u32 wqe_size_in_bytes_rq2 =0 ; +u32 wqe_size_in_bytes_rq3 =0 ; + +int ret =-1 ; + +EDEB_EN (7 ,"init_attr=%p" , init_attr); + + qp =kzalloc (sizeof (*qp),GFP_KERNEL ); + +if (!qp) { +EDEB_ERR (4 ,"pd=%X not enough memory to alloc qp" , pd); +return NULL ; + } + qp->adapter = adapter; + +EDEB (7 ,"send_ehea_cq->fw_handle=0x%lX" +"recv_ehea_cq->fw_handle=0x%lX" , init_attr->send_cq_handle, + init_attr->recv_cq_handle); + + + hret =ehea_h_alloc_resource_qp (adapter->handle, qp, init_attr, pd, + &qp->fw_handle, &qp->epas); +if (hret !=H_SUCCESS ) { +EDEB_ERR (4 ,"ehea_h_alloc_resource_qp failed. hret=%lx" , hret); + goto create_qp_exit1; + } + + wqe_size_in_bytes_sq =map_wqe_size (init_attr->act_wqe_size_enc_sq); +EDEB (7 ,"SWQE SG %d" , init_attr->wqe_size_enc_sq); + + wqe_size_in_bytes_rq1 =map_wqe_size (init_attr->act_wqe_size_enc_rq1); + wqe_size_in_bytes_rq2 =map_wqe_size (init_attr->act_wqe_size_enc_rq2); + wqe_size_in_bytes_rq3 =map_wqe_size (init_attr->act_wqe_size_enc_rq3); + +EDEB (7 ,"SQ pages: %d, SQ WQE size:%d, max SWQE size enc: %d" , + init_attr->nr_sq_pages, + wqe_size_in_bytes_sq, init_attr->act_wqe_size_enc_sq); + +EDEB (7 ,"RQ1 pages: %d, RQ1 WQE size:%d, max RWQE size enc: %d" , + init_attr->nr_rq1_pages, + wqe_size_in_bytes_rq1, init_attr->act_wqe_size_enc_rq1); + +EDEB (7 ,"RQ2 pages: %d, RQ2 WQE size:%d, max RWQE size enc: %d" , + init_attr->nr_rq2_pages, + wqe_size_in_bytes_rq2, init_attr->act_wqe_size_enc_rq2); + +EDEB (7 ,"RQ3 pages: %d, RQ3 WQE size:%d, max RWQE size enc: %d" , + init_attr->nr_rq3_pages, + wqe_size_in_bytes_rq3, init_attr->act_wqe_size_enc_rq3); + + ret =ehea_qp_alloc_register (qp, + &qp->hw_squeue, + init_attr->nr_sq_pages, + wqe_size_in_bytes_sq, + init_attr->act_wqe_size_enc_sq, adapter, +0 ); +if (ret <H_SUCCESS ) { +EDEB_ERR (4 ,"can't register for sq hret=%x" , ret); + goto create_qp_exit2; + } + + ret =ehea_qp_alloc_register (qp, + &qp->hw_rqueue1, + init_attr->nr_rq1_pages, + wqe_size_in_bytes_rq1, + init_attr->act_wqe_size_enc_rq1, + adapter,1 ); + +if (ret <0 ) { +EDEB_ERR (4 ,"can't register for rq1 hret=%x" , ret); + goto create_qp_exit3; + } + +if (init_attr->rq_count >1 ) { + ret =ehea_qp_alloc_register (qp, + &qp->hw_rqueue2, + init_attr->nr_rq2_pages, + wqe_size_in_bytes_rq2, + init_attr->act_wqe_size_enc_rq2, + adapter,2 ); + +if (ret <0 ) { +EDEB_ERR (4 ,"can't register for rq2 hret=%x" , ret); + goto create_qp_exit4; + } + } + +if (init_attr->rq_count >2 ) { + ret =ehea_qp_alloc_register (qp, + &qp->hw_rqueue3, + init_attr->nr_rq3_pages, + wqe_size_in_bytes_rq3, + init_attr->act_wqe_size_enc_rq3, + adapter,3 ); + +if (ret !=0 ) { +EDEB_ERR (4 ,"can't register for rq3 hret=%x" , ret); + goto create_qp_exit5; + } + } + + qp->init_attr = *init_attr; + +EDEB_EX (7 ,"" ); +return qp; + +create_qp_exit5: +hw_queue_dtor (&qp->hw_rqueue2); + +create_qp_exit4: +hw_queue_dtor (&qp->hw_rqueue1); + +create_qp_exit3: +hw_queue_dtor (&qp->hw_squeue); + +create_qp_exit2: + hret =ehea_h_destroy_qp (adapter->handle, qp, qp->fw_handle, &qp->epas); + +create_qp_exit1: +kfree (qp); + +EDEB_EX (7 ,"hret=NULL" ); +return NULL ; + +} + +int ehea_destroy_qp (struct ehea_qp *qp) +{ +int ret =0 ; +u64 hret =H_HARDWARE ; +struct ehea_qp_init_attr *qp_attr = &qp->init_attr; +EDEB_EX (7 ,"" ); + +if (!qp) +return 0 ; + + hret =ehea_h_destroy_qp (qp->adapter->handle, qp, qp->fw_handle, + &qp->epas); +if (hret !=H_SUCCESS ) { +EDEB_ERR (4 ,"destroy QP failed!" ); + ret = -EINVAL ; + } + +hw_queue_dtor (&qp->hw_squeue); +hw_queue_dtor (&qp->hw_rqueue1); + +if (qp_attr->rq_count >1 ) +hw_queue_dtor (&qp->hw_rqueue2); +if (qp_attr->rq_count >2 ) +hw_queue_dtor (&qp->hw_rqueue3); +kfree (qp); + +EDEB_EX (7 ,"hret=%lx" , hret); + +return ret; +} + +int ehea_reg_mr_adapter (struct ehea_adapter *adapter) +{ +int i =0 ; +int k =0 ; +u64 hret =H_HARDWARE ; +u64 start =KERNELBASE ; +u64 end = (u64 ) high_memory; +u64 nr_pages = (end - start) /PAGE_SIZE ; +u32 acc_ctrl =EHEA_MR_ACC_CTRL ; +u64 pt_abs =0 ; +u64 *pt; + +EDEB_EN (7 ,"adapter=%p" , adapter); + pt =kzalloc (PAGE_SIZE ,GFP_KERNEL ); +if (!pt) { +EDEB_ERR (4 ,"allocating page failed" ); +return -EINVAL ; + } + pt_abs =virt_to_abs (pt); + + hret =ehea_h_alloc_resource_mr (adapter->handle, + start, + end - start, + acc_ctrl, + adapter->pd, + &adapter->mr.handle, + &adapter->mr.lkey); +if (hret !=H_SUCCESS ) { +EDEB_EX (4 ,"Error: hret=%lX\n" , hret); +return -EINVAL ; + } + + adapter->mr.vaddr =KERNELBASE ; + +while (nr_pages >0 ) { +if (nr_pages >1 ) { +u64 num_pages =min (nr_pages, (u64 )512 ); +for (i =0 ; i < num_pages; i++) + pt[i] =virt_to_abs ((void *)(((u64 )start) + + ((k++) * +PAGE_SIZE ))); + + hret =ehea_h_register_rpage_mr (adapter->handle, + adapter->mr.handle,0 , +0 , (u64 )pt_abs, + num_pages); + nr_pages -= num_pages; + }else { +u64 abs_adr =virt_to_abs ((void *)(((u64 )start) + + (k *PAGE_SIZE ))); + hret =ehea_h_register_rpage_mr (adapter->handle, + adapter->mr.handle,0 , +0 , abs_adr,1 ); + nr_pages--; + } + +if ((hret !=H_SUCCESS ) && (hret !=H_PAGE_REGISTERED )) { +ehea_h_free_resource_mr (adapter->handle, + adapter->mr.handle); +EDEB_EX (4 ," register rpage_mr: hret=%lX\n" , hret); +return -EINVAL ; + } + } + +if (hret !=H_SUCCESS ) { +ehea_h_free_resource_mr (adapter->handle, adapter->mr.handle); +EDEB_EX (4 ," register rpage_mr failed for last page: hret=%lX" , + hret); +return -EINVAL ; + } + +EDEB_EX (7 ,"lkey=0x%X, mr_handle=0x%lX" , adapter->mr.lkey, + adapter->mr.handle); +return 0 ; +} + +int ehea_reg_mr_pages (struct ehea_adapter *adapter, +struct ehea_mr *mr, +u64 start,u64 *pt,int nr_pages) +{ +u64 hret =H_HARDWARE ; +u32 acc_ctrl =EHEA_MR_ACC_CTRL ; + +u64 pt_abs =virt_to_abs (pt); +u64 first_page = pt[0 ]; + + hret =ehea_h_alloc_resource_mr (adapter->handle, + start, +PAGE_SIZE * nr_pages, + acc_ctrl, + adapter->pd, + &mr->handle, + &mr->lkey); +if (hret !=H_SUCCESS ) { +EDEB_EX (4 ,"Error: hret=%lX\n" , hret); +return -EINVAL ; + } + +if (nr_pages >1 ) + hret =ehea_h_register_rpage_mr (adapter->handle, + mr->handle,0 ,0 , (u64 )pt_abs, + nr_pages); +else + hret =ehea_h_register_rpage_mr (adapter->handle, + mr->handle,0 ,0 , first_page, +1 ); + +if (hret !=H_SUCCESS ) { +ehea_h_free_resource_mr (adapter->handle, mr->handle); +EDEB_EX (4 ," register rpage_mr failed for last page:" +"hret=%lX\n" , hret); +return -EINVAL ; + } + mr->vaddr = start; + +EDEB_EX (7 ,"" ); +return 0 ; +} + + + +int ehea_dereg_mr_adapter (struct ehea_adapter *adapter) +{ +u64 hret =H_HARDWARE ; +EDEB_EN (7 ,"adapter=%p" , adapter); + hret =ehea_h_free_resource_mr (adapter->handle, adapter->mr.handle); +if (hret !=H_SUCCESS ) { +EDEB_EX (4 ,"deregistering memory region failed" ); +return -EINVAL ; + } +EDEB_EX (7 ,"" ); +return 0 ; +}
drivers/net/ehea/ehea_qmr.h +392 -0
392 lines not on this page · raw message