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

Commit c4ed790d authored by Joachim Fenkes's avatar Joachim Fenkes Committed by Roland Dreier
Browse files

IB/ehca: Implement modify_port



Add "Modify Port" verb support to eHCA driver.  The IB communication
manager needs this to set the IsCM port capability bit when
initializing.

Signed-off-by: default avatarJoachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent bd8031b4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -106,6 +106,7 @@ struct ehca_shca {
	struct ehca_mr *maxmr;
	struct ehca_pd *pd;
	struct h_galpas galpas;
	struct mutex modify_mutex;
};

struct ehca_pd {
+53 −2
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ int ehca_query_port(struct ib_device *ibdev,
		break;
	}

	props->port_cap_flags  = rblock->capability_mask;
	props->gid_tbl_len     = rblock->gid_tbl_len;
	props->max_msg_sz      = rblock->max_msg_sz;
	props->bad_pkey_cntr   = rblock->bad_pkey_cntr;
@@ -236,10 +237,60 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port,
	return ret;
}

const u32 allowed_port_caps = (
	IB_PORT_SM | IB_PORT_LED_INFO_SUP | IB_PORT_CM_SUP |
	IB_PORT_SNMP_TUNNEL_SUP | IB_PORT_DEVICE_MGMT_SUP |
	IB_PORT_VENDOR_CLASS_SUP);

int ehca_modify_port(struct ib_device *ibdev,
		     u8 port, int port_modify_mask,
		     struct ib_port_modify *props)
{
	/* Not implemented yet */
	return -EFAULT;
	int ret = 0;
	struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device);
	struct hipz_query_port *rblock;
	u32 cap;
	u64 hret;

	if ((props->set_port_cap_mask | props->clr_port_cap_mask)
	    & ~allowed_port_caps) {
		ehca_err(&shca->ib_device, "Non-changeable bits set in masks  "
			 "set=%x  clr=%x  allowed=%x", props->set_port_cap_mask,
			 props->clr_port_cap_mask, allowed_port_caps);
		return -EINVAL;
	}

	if (mutex_lock_interruptible(&shca->modify_mutex))
                return -ERESTARTSYS;

	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
	if (!rblock) {
		ehca_err(&shca->ib_device,  "Can't allocate rblock memory.");
		ret = -ENOMEM;
		goto modify_port1;
	}

	if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
		ehca_err(&shca->ib_device, "Can't query port properties");
		ret = -EINVAL;
		goto modify_port2;
	}

	cap = (rblock->capability_mask | props->set_port_cap_mask)
		& ~props->clr_port_cap_mask;

	hret = hipz_h_modify_port(shca->ipz_hca_handle, port,
				  cap, props->init_type, port_modify_mask);
	if (hret != H_SUCCESS) {
		ehca_err(&shca->ib_device, "Modify port failed  hret=%lx", hret);
		ret = -EINVAL;
	}

modify_port2:
	ehca_free_fw_ctrlblock(rblock);

modify_port1:
        mutex_unlock(&shca->modify_mutex);

	return ret;
}
+1 −0
Original line number Diff line number Diff line
@@ -587,6 +587,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
		ehca_gen_err("Cannot allocate shca memory.");
		return -ENOMEM;
	}
	mutex_init(&shca->modify_mutex);

	shca->ibmebus_dev = dev;
	shca->ipz_hca_handle.handle = *handle;
+24 −0
Original line number Diff line number Diff line
@@ -70,6 +70,10 @@
#define H_ALL_RES_QP_SQUEUE_SIZE_PAGES  EHCA_BMASK_IBM(0, 31)
#define H_ALL_RES_QP_RQUEUE_SIZE_PAGES  EHCA_BMASK_IBM(32, 63)

#define H_MP_INIT_TYPE                  EHCA_BMASK_IBM(44, 47)
#define H_MP_SHUTDOWN                   EHCA_BMASK_IBM(48, 48)
#define H_MP_RESET_QKEY_CTR             EHCA_BMASK_IBM(49, 49)

/* direct access qp controls */
#define DAQP_CTRL_ENABLE    0x01
#define DAQP_CTRL_SEND_COMP 0x20
@@ -364,6 +368,26 @@ u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
	return ret;
}

u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle,
		       const u8 port_id, const u32 port_cap,
		       const u8 init_type, const int modify_mask)
{
	u64 port_attributes = port_cap;

	if (modify_mask & IB_PORT_SHUTDOWN)
		port_attributes |= EHCA_BMASK_SET(H_MP_SHUTDOWN, 1);
	if (modify_mask & IB_PORT_INIT_TYPE)
		port_attributes |= EHCA_BMASK_SET(H_MP_INIT_TYPE, init_type);
	if (modify_mask & IB_PORT_RESET_QKEY_CNTR)
		port_attributes |= EHCA_BMASK_SET(H_MP_RESET_QKEY_CTR, 1);

	return ehca_plpar_hcall_norets(H_MODIFY_PORT,
				       adapter_handle.handle, /* r4 */
				       port_id,               /* r5 */
				       port_attributes,       /* r6 */
				       0, 0, 0, 0);
}

u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
		     struct hipz_query_hca *query_hca_rblock)
{
+4 −0
Original line number Diff line number Diff line
@@ -85,6 +85,10 @@ u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
		      const u8 port_id,
		      struct hipz_query_port *query_port_response_block);

u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle,
		       const u8 port_id, const u32 port_cap,
		       const u8 init_type, const int modify_mask);

u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
		     struct hipz_query_hca *query_hca_rblock);