Skip to content

Commit

Permalink
IB/ehca: Implement modify_port
Browse files Browse the repository at this point in the history
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: Joachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
  • Loading branch information
Joachim Fenkes authored and Roland Dreier committed Apr 25, 2007
1 parent bd8031b commit c4ed790
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/infiniband/hw/ehca/ehca_classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
55 changes: 53 additions & 2 deletions drivers/infiniband/hw/ehca/ehca_hca.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 change: 1 addition & 0 deletions drivers/infiniband/hw/ehca/ehca_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
24 changes: 24 additions & 0 deletions drivers/infiniband/hw/ehca/hcp_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down
4 changes: 4 additions & 0 deletions drivers/infiniband/hw/ehca/hcp_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit c4ed790

Please sign in to comment.