Esempio n. 1
0
void print_error_data(u64 *data)
{
	int length;
	u64 type = EHEA_BMASK_GET(ERROR_DATA_TYPE, data[2]);
	u64 resource = data[1];

	length = EHEA_BMASK_GET(ERROR_DATA_LENGTH, data[0]);

	if (length > EHEA_PAGESIZE)
		length = EHEA_PAGESIZE;

	if (type == 0x8) /* Queue Pair */
		ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, "
			   "port=%lX", resource, data[6], data[12], data[22]);

	if (type == 0x4) /* Completion Queue */
		ehea_error("CQ (resource=%lX) state: AER=0x%lX", resource,
			   data[6]);

	if (type == 0x3) /* Event Queue */
		ehea_error("EQ (resource=%lX) state: AER=0x%lX", resource,
			   data[6]);

	ehea_dump(data, length, "error data");
}
static long ehea_plpar_hcall9(unsigned long opcode,
			      unsigned long *outs, /* array of 9 outputs */
			      unsigned long arg1,
			      unsigned long arg2,
			      unsigned long arg3,
			      unsigned long arg4,
			      unsigned long arg5,
			      unsigned long arg6,
			      unsigned long arg7,
			      unsigned long arg8,
			      unsigned long arg9)
{
	long ret;
	int i, sleep_msecs;
	u8 cb_cat;

	for (i = 0; i < 5; i++) {
		ret = plpar_hcall9(opcode, outs,
				   arg1, arg2, arg3, arg4, arg5,
				   arg6, arg7, arg8, arg9);

		if (H_IS_LONG_BUSY(ret)) {
			sleep_msecs = get_longbusy_msecs(ret);
			msleep_interruptible(sleep_msecs);
			continue;
		}

		cb_cat = EHEA_BMASK_GET(H_MEHEAPORT_CAT, arg2);

		if ((ret < H_SUCCESS) && !(((ret == H_AUTHORITY)
		    && (opcode == H_MODIFY_HEA_PORT))
		    && (((cb_cat == H_PORT_CB4) && ((arg3 == H_PORT_CB4_JUMBO)
		    || (arg3 == H_PORT_CB4_SPEED))) || ((cb_cat == H_PORT_CB7)
		    && (arg3 == H_PORT_CB7_DUCQPN)))))
			pr_err("opcode=%lx ret=%lx"
			       " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
			       " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
			       " arg9=%lx"
			       " out1=%lx out2=%lx out3=%lx out4=%lx"
			       " out5=%lx out6=%lx out7=%lx out8=%lx"
			       " out9=%lx\n",
			       opcode, ret,
			       arg1, arg2, arg3, arg4, arg5,
			       arg6, arg7, arg8, arg9,
			       outs[0], outs[1], outs[2], outs[3], outs[4],
			       outs[5], outs[6], outs[7], outs[8]);
		return ret;
	}

	return H_BUSY;
}
u64 ehea_h_alloc_resource_qp(const u64 adapter_handle,
			     struct ehea_qp_init_attr *init_attr, const u32 pd,
			     u64 *qp_handle, struct h_epas *h_epas)
{
	u64 hret;
	unsigned long outs[PLPAR_HCALL9_BUFSIZE];

	u64 allocate_controls =
	    EHEA_BMASK_SET(H_ALL_RES_QP_EQPO, init_attr->low_lat_rq1 ? 1 : 0)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_QPP, 0)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_RQR, 6)	/* rq1 & rq2 & rq3 */
	    | EHEA_BMASK_SET(H_ALL_RES_QP_EQEG, 0)	/* EQE gen. disabled */
	    | EHEA_BMASK_SET(H_ALL_RES_QP_LL_QP, init_attr->low_lat_rq1)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_DMA128, 0)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_HSM, 0)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_SIGT, init_attr->signalingtype)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_RES_TYP, H_ALL_RES_TYPE_QP);

	u64 r9_reg = EHEA_BMASK_SET(H_ALL_RES_QP_PD, pd)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_TOKEN, init_attr->qp_token);

	u64 max_r10_reg =
	    EHEA_BMASK_SET(H_ALL_RES_QP_MAX_SWQE,
			   get_order_of_qentries(init_attr->max_nr_send_wqes))
	    | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R1WQE,
			     get_order_of_qentries(init_attr->max_nr_rwqes_rq1))
	    | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R2WQE,
			     get_order_of_qentries(init_attr->max_nr_rwqes_rq2))
	    | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R3WQE,
			     get_order_of_qentries(init_attr->max_nr_rwqes_rq3))
	    | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_SSGE, init_attr->wqe_size_enc_sq)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R1SGE,
			     init_attr->wqe_size_enc_rq1)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R2SGE,
			     init_attr->wqe_size_enc_rq2)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R3SGE,
			     init_attr->wqe_size_enc_rq3);

	u64 r11_in =
	    EHEA_BMASK_SET(H_ALL_RES_QP_SWQE_IDL, init_attr->swqe_imm_data_len)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_PORT_NUM, init_attr->port_nr);
	u64 threshold =
	    EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ2, init_attr->rq2_threshold)
	    | EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ3, init_attr->rq3_threshold);

	hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE,
				 outs,
				 adapter_handle,		/* R4 */
				 allocate_controls,		/* R5 */
				 init_attr->send_cq_handle,	/* R6 */
				 init_attr->recv_cq_handle,	/* R7 */
				 init_attr->aff_eq_handle,	/* R8 */
				 r9_reg,			/* R9 */
				 max_r10_reg,			/* R10 */
				 r11_in,			/* R11 */
				 threshold);			/* R12 */

	*qp_handle = outs[0];
	init_attr->qp_nr = (u32)outs[1];

	init_attr->act_nr_send_wqes =
	    (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_SWQE, outs[2]);
	init_attr->act_nr_rwqes_rq1 =
	    (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R1WQE, outs[2]);
	init_attr->act_nr_rwqes_rq2 =
	    (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R2WQE, outs[2]);
	init_attr->act_nr_rwqes_rq3 =
	    (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R3WQE, outs[2]);

	init_attr->act_wqe_size_enc_sq = init_attr->wqe_size_enc_sq;
	init_attr->act_wqe_size_enc_rq1 = init_attr->wqe_size_enc_rq1;
	init_attr->act_wqe_size_enc_rq2 = init_attr->wqe_size_enc_rq2;
	init_attr->act_wqe_size_enc_rq3 = init_attr->wqe_size_enc_rq3;

	init_attr->nr_sq_pages =
	    (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_SQ, outs[4]);
	init_attr->nr_rq1_pages =
	    (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ1, outs[4]);
	init_attr->nr_rq2_pages =
	    (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ2, outs[5]);
	init_attr->nr_rq3_pages =
	    (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ3, outs[5]);

	init_attr->liobn_sq =
	    (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_SQ, outs[7]);
	init_attr->liobn_rq1 =
	    (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ1, outs[7]);
	init_attr->liobn_rq2 =
	    (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ2, outs[8]);
	init_attr->liobn_rq3 =
	    (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ3, outs[8]);

	if (!hret)
		hcp_epas_ctor(h_epas, outs[6], outs[6]);

	return hret;
}