示例#1
0
u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
			     struct ehca_cq *cq,
			     struct ehca_alloc_cq_parms *param)
{
	u64 ret;
	u64 outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
				adapter_handle.handle,   /* r4  */
				2,	                 /* r5  */
				param->eq_handle.handle, /* r6  */
				cq->token,	         /* r7  */
				param->nr_cqe,           /* r8  */
				0, 0, 0, 0);
	cq->ipz_cq_handle.handle = outs[0];
	param->act_nr_of_entries = (u32)outs[3];
	param->act_pages = (u32)outs[4];

	if (ret == H_SUCCESS)
		hcp_galpas_ctor(&cq->galpas, outs[5], outs[6]);

	if (ret == H_NOT_ENOUGH_RESOURCES)
		ehca_gen_err("Not enough resources. ret=%lx", ret);

	return ret;
}
u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,
			  const struct ehca_mr *mr,
			  const u64 vaddr_in,
			  const u64 length,
			  const u32 access_ctrl,
			  const struct ipz_pd pd,
			  const u64 mr_addr_cb,
			  struct ehca_mr_hipzout_parms *outparms)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_REREGISTER_PMR, outs,
				adapter_handle.handle,    
				mr->ipz_mr_handle.handle, 
				vaddr_in,	          
				length,                   
				
				((((u64)access_ctrl) << 32ULL) | pd.value),
				mr_addr_cb,               
				0, 0, 0);
	outparms->vaddr = outs[1];
	outparms->lkey = (u32)outs[2];
	outparms->rkey = (u32)outs[3];

	return ret;
}
u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
			     const struct ehca_mr *mr,
			     const u64 vaddr,
			     const u64 length,
			     const u32 access_ctrl,
			     const struct ipz_pd pd,
			     struct ehca_mr_hipzout_parms *outparms)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
				adapter_handle.handle,            
				5,                                
				vaddr,                            
				length,                           
				(((u64)access_ctrl) << 32ULL),    
				pd.value,                         
				0, 0, 0);
	outparms->handle.handle = outs[0];
	outparms->lkey = (u32)outs[2];
	outparms->rkey = (u32)outs[3];

	return ret;
}
u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
		      struct ehca_qp *qp)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = hcp_galpas_dtor(&qp->galpas);
	if (ret) {
		ehca_gen_err("Could not destruct qp->galpas");
		return H_RESOURCE;
	}
	ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
				adapter_handle.handle,     
				
				1,	                   
				qp->ipz_qp_handle.handle,  
				0, 0, 0, 0, 0, 0);
	if (ret == H_HARDWARE)
		ehca_gen_err("HCA not operational. ret=%lli", ret);

	ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
				      adapter_handle.handle,     
				      qp->ipz_qp_handle.handle,  
				      0, 0, 0, 0, 0);

	if (ret == H_RESOURCE)
		ehca_gen_err("Resource still in use. ret=%lli", ret);

	return ret;
}
u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,
		    const struct ehca_mw *mw,
		    struct ehca_mw_hipzout_parms *outparms)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_QUERY_MW, outs,
				adapter_handle.handle,    
				mw->ipz_mw_handle.handle, 
				0, 0, 0, 0, 0, 0, 0);
	outparms->rkey = (u32)outs[3];

	return ret;
}
u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,
			     const struct ehca_mw *mw,
			     const struct ipz_pd pd,
			     struct ehca_mw_hipzout_parms *outparms)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
				adapter_handle.handle,      
				6,                          
				pd.value,                   
				0, 0, 0, 0, 0, 0);
	outparms->handle.handle = outs[0];
	outparms->rkey = (u32)outs[3];

	return ret;
}
u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,
		    const struct ehca_mr *mr,
		    struct ehca_mr_hipzout_parms *outparms)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_QUERY_MR, outs,
				adapter_handle.handle,     
				mr->ipz_mr_handle.handle,  
				0, 0, 0, 0, 0, 0, 0);
	outparms->len = outs[0];
	outparms->vaddr = outs[1];
	outparms->acl  = outs[4] >> 32;
	outparms->lkey = (u32)(outs[5] >> 32);
	outparms->rkey = (u32)(outs[5] & (0xffffffff));

	return ret;
}
u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
		     const struct ipz_qp_handle qp_handle,
		     struct ehca_pfqp *pfqp,
		     const u64 update_mask,
		     struct hcp_modify_qp_control_block *mqpcb,
		     struct h_galpa gal)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
	ret = ehca_plpar_hcall9(H_MODIFY_QP, outs,
				adapter_handle.handle, 
				qp_handle.handle,      
				update_mask,	       
				virt_to_abs(mqpcb),    
				0, 0, 0, 0, 0);

	if (ret == H_NOT_ENOUGH_RESOURCES)
		ehca_gen_err("Insufficient resources ret=%lli", ret);

	return ret;
}
u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
		       const struct ipz_qp_handle qp_handle,
		       struct h_galpa gal,
		       u32 port, u32 * pma_qp_nr,
		       u32 * bma_qp_nr)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_DEFINE_AQP1, outs,
				adapter_handle.handle, 
				qp_handle.handle,      
				port,	               
				0, 0, 0, 0, 0, 0);
	*pma_qp_nr = (u32)outs[0];
	*bma_qp_nr = (u32)outs[1];

	if (ret == H_ALIAS_EXIST)
		ehca_gen_err("AQP1 already exists. ret=%lli", ret);

	return ret;
}
u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
			       const struct ipz_qp_handle qp_handle,
			       struct ehca_pfqp *pfqp,
			       void **log_addr_next_sq_wqe2processed,
			       void **log_addr_next_rq_wqe2processed,
			       int dis_and_get_function_code)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
				adapter_handle.handle,     
				dis_and_get_function_code, 
				qp_handle.handle,	   
				0, 0, 0, 0, 0, 0);
	if (log_addr_next_sq_wqe2processed)
		*log_addr_next_sq_wqe2processed = (void *)outs[0];
	if (log_addr_next_rq_wqe2processed)
		*log_addr_next_rq_wqe2processed = (void *)outs[1];

	return ret;
}
u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
			     struct ehca_cq *cq,
			     struct ehca_alloc_cq_parms *param)
{
	int rc;
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
				adapter_handle.handle,   
				2,	                 
				param->eq_handle.handle, 
				cq->token,	         
				param->nr_cqe,           
				0, 0, 0, 0);
	cq->ipz_cq_handle.handle = outs[0];
	param->act_nr_of_entries = (u32)outs[3];
	param->act_pages = (u32)outs[4];

	if (ret == H_SUCCESS) {
		rc = hcp_galpas_ctor(&cq->galpas, 0, outs[5], outs[6]);
		if (rc) {
			ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
				     rc, outs[5]);

			ehca_plpar_hcall_norets(H_FREE_RESOURCE,
						adapter_handle.handle,     
						cq->ipz_cq_handle.handle,  
						0, 0, 0, 0, 0);
			ret = H_NO_MEM;
		}
	}

	if (ret == H_NOT_ENOUGH_RESOURCES)
		ehca_gen_err("Not enough resources. ret=%lli", ret);

	return ret;
}
u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
			     struct ehca_pfeq *pfeq,
			     const u32 neq_control,
			     const u32 number_of_entries,
			     struct ipz_eq_handle *eq_handle,
			     u32 *act_nr_of_entries,
			     u32 *act_pages,
			     u32 *eq_ist)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
	u64 allocate_controls;

	
	allocate_controls = 3ULL;

	
	if (neq_control != 1)
		allocate_controls = (1ULL << (63 - 7)) | allocate_controls;
	else 
		allocate_controls = (1ULL << 63) | allocate_controls;

	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
				adapter_handle.handle,  
				allocate_controls,      
				number_of_entries,      
				0, 0, 0, 0, 0, 0);
	eq_handle->handle = outs[0];
	*act_nr_of_entries = (u32)outs[3];
	*act_pages = (u32)outs[4];
	*eq_ist = (u32)outs[5];

	if (ret == H_NOT_ENOUGH_RESOURCES)
		ehca_gen_err("Not enough resource - ret=%lli ", ret);

	return ret;
}
示例#13
0
u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
			     struct ehca_pfeq *pfeq,
			     const u32 neq_control,
			     const u32 number_of_entries,
			     struct ipz_eq_handle *eq_handle,
			     u32 *act_nr_of_entries,
			     u32 *act_pages,
			     u32 *eq_ist)
{
	u64 ret;
	u64 outs[PLPAR_HCALL9_BUFSIZE];
	u64 allocate_controls;

	/* resource type */
	allocate_controls = 3ULL;

	/* ISN is associated */
	if (neq_control != 1)
		allocate_controls = (1ULL << (63 - 7)) | allocate_controls;
	else /* notification event queue */
		allocate_controls = (1ULL << 63) | allocate_controls;

	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
				adapter_handle.handle,  /* r4 */
				allocate_controls,      /* r5 */
				number_of_entries,      /* r6 */
				0, 0, 0, 0, 0, 0);
	eq_handle->handle = outs[0];
	*act_nr_of_entries = (u32)outs[3];
	*act_pages = (u32)outs[4];
	*eq_ist = (u32)outs[5];

	if (ret == H_NOT_ENOUGH_RESOURCES)
		ehca_gen_err("Not enough resource - ret=%lx ", ret);

	return ret;
}
u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,
			const struct ehca_mr *mr,
			const struct ehca_mr *orig_mr,
			const u64 vaddr_in,
			const u32 access_ctrl,
			const struct ipz_pd pd,
			struct ehca_mr_hipzout_parms *outparms)
{
	u64 ret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	ret = ehca_plpar_hcall9(H_REGISTER_SMR, outs,
				adapter_handle.handle,            
				orig_mr->ipz_mr_handle.handle,    
				vaddr_in,                         
				(((u64)access_ctrl) << 32ULL),    
				pd.value,                         
				0, 0, 0, 0);
	outparms->handle.handle = outs[0];
	outparms->lkey = (u32)outs[2];
	outparms->rkey = (u32)outs[3];

	return ret;
}
u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
			     struct ehca_alloc_qp_parms *parms, int is_user)
{
	int rc;
	u64 ret;
	u64 allocate_controls, max_r10_reg, r11, r12;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	allocate_controls =
		EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS, parms->ext_type)
		| EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0)
		| EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype)
		| EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype)
		| EHCA_BMASK_SET(H_ALL_RES_QP_STORAGE, parms->qp_storage)
		| EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_SQ_PAGE_SIZE,
				 parms->squeue.page_size)
		| EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_RQ_PAGE_SIZE,
				 parms->rqueue.page_size)
		| EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING,
				 !!(parms->ll_comp_flags & LLQP_RECV_COMP))
		| EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING,
				 !!(parms->ll_comp_flags & LLQP_SEND_COMP))
		| EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL,
				 parms->ud_av_l_key_ctl)
		| EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE, 1);

	max_r10_reg =
		EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
			       parms->squeue.max_wr + 1)
		| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
				 parms->rqueue.max_wr + 1)
		| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
				 parms->squeue.max_sge)
		| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
				 parms->rqueue.max_sge);

	r11 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QP_TOKEN, parms->srq_token);

	if (parms->ext_type == EQPT_SRQ)
		r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_LIMIT, parms->srq_limit);
	else
		r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QPN, parms->srq_qpn);

	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
				adapter_handle.handle,	           
				allocate_controls,	           
				parms->send_cq_handle.handle,
				parms->recv_cq_handle.handle,
				parms->eq_handle.handle,
				((u64)parms->token << 32) | parms->pd.value,
				max_r10_reg, r11, r12);

	parms->qp_handle.handle = outs[0];
	parms->real_qp_num = (u32)outs[1];
	parms->squeue.act_nr_wqes =
		(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
	parms->rqueue.act_nr_wqes =
		(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
	parms->squeue.act_nr_sges =
		(u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]);
	parms->rqueue.act_nr_sges =
		(u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]);
	parms->squeue.queue_size =
		(u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]);
	parms->rqueue.queue_size =
		(u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);

	if (ret == H_SUCCESS) {
		rc = hcp_galpas_ctor(&parms->galpas, is_user, outs[6], outs[6]);
		if (rc) {
			ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
				     rc, outs[6]);

			ehca_plpar_hcall_norets(H_FREE_RESOURCE,
						adapter_handle.handle,     
						parms->qp_handle.handle,  
						0, 0, 0, 0, 0);
			ret = H_NO_MEM;
		}
	}

	if (ret == H_NOT_ENOUGH_RESOURCES)
		ehca_gen_err("Not enough resources. ret=%lli", ret);

	return ret;
}
示例#16
0
u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
			     struct ehca_qp *qp,
			     struct ehca_alloc_qp_parms *parms)
{
	u64 ret;
	u64 allocate_controls;
	u64 max_r10_reg;
	u64 outs[PLPAR_HCALL9_BUFSIZE];
	u16 max_nr_receive_wqes = qp->init_attr.cap.max_recv_wr + 1;
	u16 max_nr_send_wqes = qp->init_attr.cap.max_send_wr + 1;
	int daqp_ctrl = parms->daqp_ctrl;

	allocate_controls =
		EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS,
			       (daqp_ctrl & DAQP_CTRL_ENABLE) ? 1 : 0)
		| EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0)
		| EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype)
		| EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype)
		| EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING,
				 (daqp_ctrl & DAQP_CTRL_RECV_COMP) ? 1 : 0)
		| EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING,
				 (daqp_ctrl & DAQP_CTRL_SEND_COMP) ? 1 : 0)
		| EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL,
				 parms->ud_av_l_key_ctl)
		| EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE, 1);

	max_r10_reg =
		EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
			       max_nr_send_wqes)
		| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
				 max_nr_receive_wqes)
		| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
				 parms->max_send_sge)
		| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
				 parms->max_recv_sge);

	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
				adapter_handle.handle,	           /* r4  */
				allocate_controls,	           /* r5  */
				qp->send_cq->ipz_cq_handle.handle,
				qp->recv_cq->ipz_cq_handle.handle,
				parms->ipz_eq_handle.handle,
				((u64)qp->token << 32) | parms->pd.value,
				max_r10_reg,	                   /* r10 */
				parms->ud_av_l_key_ctl,            /* r11 */
				0);
	qp->ipz_qp_handle.handle = outs[0];
	qp->real_qp_num = (u32)outs[1];
	parms->act_nr_send_wqes =
		(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
	parms->act_nr_recv_wqes =
		(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
	parms->act_nr_send_sges =
		(u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]);
	parms->act_nr_recv_sges =
		(u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]);
	parms->nr_sq_pages =
		(u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]);
	parms->nr_rq_pages =
		(u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);

	if (ret == H_SUCCESS)
		hcp_galpas_ctor(&qp->galpas, outs[6], outs[6]);

	if (ret == H_NOT_ENOUGH_RESOURCES)
		ehca_gen_err("Not enough resources. ret=%lx", ret);

	return ret;
}