Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c83b5b1c authored by Stefan Roscher's avatar Stefan Roscher Committed by Roland Dreier
Browse files

IB/ehca: Support all ibv_devinfo values in query_device() and query_port()



Also, introduce a few inline helper functions to make the code more readable.

Signed-off-by: default avatarStefan Roscher <stefan.roscher@de.ibm.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 4cd1e5eb
Loading
Loading
Loading
Loading
+79 −48
Original line number Original line Diff line number Diff line
@@ -43,6 +43,11 @@
#include "ehca_iverbs.h"
#include "ehca_iverbs.h"
#include "hcp_if.h"
#include "hcp_if.h"


static unsigned int limit_uint(unsigned int value)
{
	return min_t(unsigned int, value, INT_MAX);
}

int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
{
{
	int i, ret = 0;
	int i, ret = 0;
@@ -83,37 +88,40 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
	props->vendor_id       = rblock->vendor_id >> 8;
	props->vendor_id       = rblock->vendor_id >> 8;
	props->vendor_part_id  = rblock->vendor_part_id >> 16;
	props->vendor_part_id  = rblock->vendor_part_id >> 16;
	props->hw_ver          = rblock->hw_ver;
	props->hw_ver          = rblock->hw_ver;
	props->max_qp          = min_t(unsigned, rblock->max_qp, INT_MAX);
	props->max_qp          = limit_uint(rblock->max_qp);
	props->max_qp_wr       = min_t(unsigned, rblock->max_wqes_wq, INT_MAX);
	props->max_qp_wr       = limit_uint(rblock->max_wqes_wq);
	props->max_sge         = min_t(unsigned, rblock->max_sge, INT_MAX);
	props->max_sge         = limit_uint(rblock->max_sge);
	props->max_sge_rd      = min_t(unsigned, rblock->max_sge_rd, INT_MAX);
	props->max_sge_rd      = limit_uint(rblock->max_sge_rd);
	props->max_cq          = min_t(unsigned, rblock->max_cq, INT_MAX);
	props->max_cq          = limit_uint(rblock->max_cq);
	props->max_cqe         = min_t(unsigned, rblock->max_cqe, INT_MAX);
	props->max_cqe         = limit_uint(rblock->max_cqe);
	props->max_mr          = min_t(unsigned, rblock->max_mr, INT_MAX);
	props->max_mr          = limit_uint(rblock->max_mr);
	props->max_mw          = min_t(unsigned, rblock->max_mw, INT_MAX);
	props->max_mw          = limit_uint(rblock->max_mw);
	props->max_pd          = min_t(unsigned, rblock->max_pd, INT_MAX);
	props->max_pd          = limit_uint(rblock->max_pd);
	props->max_ah          = min_t(unsigned, rblock->max_ah, INT_MAX);
	props->max_ah          = limit_uint(rblock->max_ah);
	props->max_fmr         = min_t(unsigned, rblock->max_mr, INT_MAX);
	props->max_ee          = limit_uint(rblock->max_rd_ee_context);
	props->max_rdd         = limit_uint(rblock->max_rd_domain);
	props->max_fmr         = limit_uint(rblock->max_mr);
	props->local_ca_ack_delay  = limit_uint(rblock->local_ca_ack_delay);
	props->max_qp_rd_atom  = limit_uint(rblock->max_rr_qp);
	props->max_ee_rd_atom  = limit_uint(rblock->max_rr_ee_context);
	props->max_res_rd_atom = limit_uint(rblock->max_rr_hca);
	props->max_qp_init_rd_atom = limit_uint(rblock->max_act_wqs_qp);
	props->max_ee_init_rd_atom = limit_uint(rblock->max_act_wqs_ee_context);


	if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
	if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
		props->max_srq         = props->max_qp;
		props->max_srq         = limit_uint(props->max_qp);
		props->max_srq_wr      = props->max_qp_wr;
		props->max_srq_wr      = limit_uint(props->max_qp_wr);
		props->max_srq_sge     = 3;
		props->max_srq_sge     = 3;
	}
	}


	props->max_pkeys           = 16;
	props->max_pkeys           = 16;
	props->local_ca_ack_delay
	props->local_ca_ack_delay  = limit_uint(rblock->local_ca_ack_delay);
		= rblock->local_ca_ack_delay;
	props->max_raw_ipv6_qp     = limit_uint(rblock->max_raw_ipv6_qp);
	props->max_raw_ipv6_qp
	props->max_raw_ethy_qp     = limit_uint(rblock->max_raw_ethy_qp);
		= min_t(unsigned, rblock->max_raw_ipv6_qp, INT_MAX);
	props->max_mcast_grp       = limit_uint(rblock->max_mcast_grp);
	props->max_raw_ethy_qp
	props->max_mcast_qp_attach = limit_uint(rblock->max_mcast_qp_attach);
		= min_t(unsigned, rblock->max_raw_ethy_qp, INT_MAX);
	props->max_mcast_grp
		= min_t(unsigned, rblock->max_mcast_grp, INT_MAX);
	props->max_mcast_qp_attach
		= min_t(unsigned, rblock->max_mcast_qp_attach, INT_MAX);
	props->max_total_mcast_qp_attach
	props->max_total_mcast_qp_attach
		= min_t(unsigned, rblock->max_total_mcast_qp_attach, INT_MAX);
		= limit_uint(rblock->max_total_mcast_qp_attach);


	/* translate device capabilities */
	/* translate device capabilities */
	props->device_cap_flags = IB_DEVICE_SYS_IMAGE_GUID |
	props->device_cap_flags = IB_DEVICE_SYS_IMAGE_GUID |
@@ -128,6 +136,46 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
	return ret;
	return ret;
}
}


static int map_mtu(struct ehca_shca *shca, u32 fw_mtu)
{
	switch (fw_mtu) {
	case 0x1:
		return IB_MTU_256;
	case 0x2:
		return IB_MTU_512;
	case 0x3:
		return IB_MTU_1024;
	case 0x4:
		return IB_MTU_2048;
	case 0x5:
		return IB_MTU_4096;
	default:
		ehca_err(&shca->ib_device, "Unknown MTU size: %x.",
			 fw_mtu);
		return 0;
	}
}

static int map_number_of_vls(struct ehca_shca *shca, u32 vl_cap)
{
	switch (vl_cap) {
	case 0x1:
		return 1;
	case 0x2:
		return 2;
	case 0x3:
		return 4;
	case 0x4:
		return 8;
	case 0x5:
		return 15;
	default:
		ehca_err(&shca->ib_device, "invalid Vl Capability: %x.",
			 vl_cap);
		return 0;
	}
}

int ehca_query_port(struct ib_device *ibdev,
int ehca_query_port(struct ib_device *ibdev,
		    u8 port, struct ib_port_attr *props)
		    u8 port, struct ib_port_attr *props)
{
{
@@ -152,31 +200,13 @@ int ehca_query_port(struct ib_device *ibdev,


	memset(props, 0, sizeof(struct ib_port_attr));
	memset(props, 0, sizeof(struct ib_port_attr));


	switch (rblock->max_mtu) {
	props->active_mtu = props->max_mtu = map_mtu(shca, rblock->max_mtu);
	case 0x1:
		props->active_mtu = props->max_mtu = IB_MTU_256;
		break;
	case 0x2:
		props->active_mtu = props->max_mtu = IB_MTU_512;
		break;
	case 0x3:
		props->active_mtu = props->max_mtu = IB_MTU_1024;
		break;
	case 0x4:
		props->active_mtu = props->max_mtu = IB_MTU_2048;
		break;
	case 0x5:
		props->active_mtu = props->max_mtu = IB_MTU_4096;
		break;
	default:
		ehca_err(&shca->ib_device, "Unknown MTU size: %x.",
			 rblock->max_mtu);
		break;
	}

	props->port_cap_flags  = rblock->capability_mask;
	props->port_cap_flags  = rblock->capability_mask;
	props->gid_tbl_len     = rblock->gid_tbl_len;
	props->gid_tbl_len     = rblock->gid_tbl_len;
	if (rblock->max_msg_sz)
		props->max_msg_sz      = rblock->max_msg_sz;
		props->max_msg_sz      = rblock->max_msg_sz;
	else
		props->max_msg_sz      = 0x1 << 31;
	props->bad_pkey_cntr   = rblock->bad_pkey_cntr;
	props->bad_pkey_cntr   = rblock->bad_pkey_cntr;
	props->qkey_viol_cntr  = rblock->qkey_viol_cntr;
	props->qkey_viol_cntr  = rblock->qkey_viol_cntr;
	props->pkey_tbl_len    = rblock->pkey_tbl_len;
	props->pkey_tbl_len    = rblock->pkey_tbl_len;
@@ -186,6 +216,7 @@ int ehca_query_port(struct ib_device *ibdev,
	props->sm_sl           = rblock->sm_sl;
	props->sm_sl           = rblock->sm_sl;
	props->subnet_timeout  = rblock->subnet_timeout;
	props->subnet_timeout  = rblock->subnet_timeout;
	props->init_type_reply = rblock->init_type_reply;
	props->init_type_reply = rblock->init_type_reply;
	props->max_vl_num      = map_number_of_vls(shca, rblock->vl_cap);


	if (rblock->state && rblock->phys_width) {
	if (rblock->state && rblock->phys_width) {
		props->phys_state      = rblock->phys_pstate;
		props->phys_state      = rblock->phys_pstate;