diff options
author | Joachim Fenkes <fenkes@de.ibm.com> | 2007-04-24 11:44:31 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-04-25 00:30:38 -0400 |
commit | c4ed790dfd4b2182c76e0fcd79d4aa85ab02eccf (patch) | |
tree | 488e7a1b7130540536707bdef467617d14a76232 /drivers/infiniband/hw | |
parent | bd8031b49a9b05933fb1ec1c36620ed4e1e67793 (diff) |
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: Joachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_classes.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_hca.c | 55 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_main.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/hcp_if.c | 24 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/hcp_if.h | 4 |
5 files changed, 83 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 82ded44c6cee..10fb8fbafa0c 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h | |||
@@ -106,6 +106,7 @@ struct ehca_shca { | |||
106 | struct ehca_mr *maxmr; | 106 | struct ehca_mr *maxmr; |
107 | struct ehca_pd *pd; | 107 | struct ehca_pd *pd; |
108 | struct h_galpas galpas; | 108 | struct h_galpas galpas; |
109 | struct mutex modify_mutex; | ||
109 | }; | 110 | }; |
110 | 111 | ||
111 | struct ehca_pd { | 112 | struct ehca_pd { |
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c index 30eb45df9f0b..32b55a4f0e5b 100644 --- a/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/drivers/infiniband/hw/ehca/ehca_hca.c | |||
@@ -147,6 +147,7 @@ int ehca_query_port(struct ib_device *ibdev, | |||
147 | break; | 147 | break; |
148 | } | 148 | } |
149 | 149 | ||
150 | props->port_cap_flags = rblock->capability_mask; | ||
150 | props->gid_tbl_len = rblock->gid_tbl_len; | 151 | props->gid_tbl_len = rblock->gid_tbl_len; |
151 | props->max_msg_sz = rblock->max_msg_sz; | 152 | props->max_msg_sz = rblock->max_msg_sz; |
152 | props->bad_pkey_cntr = rblock->bad_pkey_cntr; | 153 | props->bad_pkey_cntr = rblock->bad_pkey_cntr; |
@@ -236,10 +237,60 @@ query_gid1: | |||
236 | return ret; | 237 | return ret; |
237 | } | 238 | } |
238 | 239 | ||
240 | const u32 allowed_port_caps = ( | ||
241 | IB_PORT_SM | IB_PORT_LED_INFO_SUP | IB_PORT_CM_SUP | | ||
242 | IB_PORT_SNMP_TUNNEL_SUP | IB_PORT_DEVICE_MGMT_SUP | | ||
243 | IB_PORT_VENDOR_CLASS_SUP); | ||
244 | |||
239 | int ehca_modify_port(struct ib_device *ibdev, | 245 | int ehca_modify_port(struct ib_device *ibdev, |
240 | u8 port, int port_modify_mask, | 246 | u8 port, int port_modify_mask, |
241 | struct ib_port_modify *props) | 247 | struct ib_port_modify *props) |
242 | { | 248 | { |
243 | /* Not implemented yet */ | 249 | int ret = 0; |
244 | return -EFAULT; | 250 | struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device); |
251 | struct hipz_query_port *rblock; | ||
252 | u32 cap; | ||
253 | u64 hret; | ||
254 | |||
255 | if ((props->set_port_cap_mask | props->clr_port_cap_mask) | ||
256 | & ~allowed_port_caps) { | ||
257 | ehca_err(&shca->ib_device, "Non-changeable bits set in masks " | ||
258 | "set=%x clr=%x allowed=%x", props->set_port_cap_mask, | ||
259 | props->clr_port_cap_mask, allowed_port_caps); | ||
260 | return -EINVAL; | ||
261 | } | ||
262 | |||
263 | if (mutex_lock_interruptible(&shca->modify_mutex)) | ||
264 | return -ERESTARTSYS; | ||
265 | |||
266 | rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); | ||
267 | if (!rblock) { | ||
268 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | ||
269 | ret = -ENOMEM; | ||
270 | goto modify_port1; | ||
271 | } | ||
272 | |||
273 | if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) { | ||
274 | ehca_err(&shca->ib_device, "Can't query port properties"); | ||
275 | ret = -EINVAL; | ||
276 | goto modify_port2; | ||
277 | } | ||
278 | |||
279 | cap = (rblock->capability_mask | props->set_port_cap_mask) | ||
280 | & ~props->clr_port_cap_mask; | ||
281 | |||
282 | hret = hipz_h_modify_port(shca->ipz_hca_handle, port, | ||
283 | cap, props->init_type, port_modify_mask); | ||
284 | if (hret != H_SUCCESS) { | ||
285 | ehca_err(&shca->ib_device, "Modify port failed hret=%lx", hret); | ||
286 | ret = -EINVAL; | ||
287 | } | ||
288 | |||
289 | modify_port2: | ||
290 | ehca_free_fw_ctrlblock(rblock); | ||
291 | |||
292 | modify_port1: | ||
293 | mutex_unlock(&shca->modify_mutex); | ||
294 | |||
295 | return ret; | ||
245 | } | 296 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 059da9628bb5..3b23d677cb86 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -587,6 +587,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, | |||
587 | ehca_gen_err("Cannot allocate shca memory."); | 587 | ehca_gen_err("Cannot allocate shca memory."); |
588 | return -ENOMEM; | 588 | return -ENOMEM; |
589 | } | 589 | } |
590 | mutex_init(&shca->modify_mutex); | ||
590 | 591 | ||
591 | shca->ibmebus_dev = dev; | 592 | shca->ibmebus_dev = dev; |
592 | shca->ipz_hca_handle.handle = *handle; | 593 | shca->ipz_hca_handle.handle = *handle; |
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index 3fb46e67df87..b564fcd3b282 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c | |||
@@ -70,6 +70,10 @@ | |||
70 | #define H_ALL_RES_QP_SQUEUE_SIZE_PAGES EHCA_BMASK_IBM(0, 31) | 70 | #define H_ALL_RES_QP_SQUEUE_SIZE_PAGES EHCA_BMASK_IBM(0, 31) |
71 | #define H_ALL_RES_QP_RQUEUE_SIZE_PAGES EHCA_BMASK_IBM(32, 63) | 71 | #define H_ALL_RES_QP_RQUEUE_SIZE_PAGES EHCA_BMASK_IBM(32, 63) |
72 | 72 | ||
73 | #define H_MP_INIT_TYPE EHCA_BMASK_IBM(44, 47) | ||
74 | #define H_MP_SHUTDOWN EHCA_BMASK_IBM(48, 48) | ||
75 | #define H_MP_RESET_QKEY_CTR EHCA_BMASK_IBM(49, 49) | ||
76 | |||
73 | /* direct access qp controls */ | 77 | /* direct access qp controls */ |
74 | #define DAQP_CTRL_ENABLE 0x01 | 78 | #define DAQP_CTRL_ENABLE 0x01 |
75 | #define DAQP_CTRL_SEND_COMP 0x20 | 79 | #define DAQP_CTRL_SEND_COMP 0x20 |
@@ -364,6 +368,26 @@ u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle, | |||
364 | return ret; | 368 | return ret; |
365 | } | 369 | } |
366 | 370 | ||
371 | u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle, | ||
372 | const u8 port_id, const u32 port_cap, | ||
373 | const u8 init_type, const int modify_mask) | ||
374 | { | ||
375 | u64 port_attributes = port_cap; | ||
376 | |||
377 | if (modify_mask & IB_PORT_SHUTDOWN) | ||
378 | port_attributes |= EHCA_BMASK_SET(H_MP_SHUTDOWN, 1); | ||
379 | if (modify_mask & IB_PORT_INIT_TYPE) | ||
380 | port_attributes |= EHCA_BMASK_SET(H_MP_INIT_TYPE, init_type); | ||
381 | if (modify_mask & IB_PORT_RESET_QKEY_CNTR) | ||
382 | port_attributes |= EHCA_BMASK_SET(H_MP_RESET_QKEY_CTR, 1); | ||
383 | |||
384 | return ehca_plpar_hcall_norets(H_MODIFY_PORT, | ||
385 | adapter_handle.handle, /* r4 */ | ||
386 | port_id, /* r5 */ | ||
387 | port_attributes, /* r6 */ | ||
388 | 0, 0, 0, 0); | ||
389 | } | ||
390 | |||
367 | u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle, | 391 | u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle, |
368 | struct hipz_query_hca *query_hca_rblock) | 392 | struct hipz_query_hca *query_hca_rblock) |
369 | { | 393 | { |
diff --git a/drivers/infiniband/hw/ehca/hcp_if.h b/drivers/infiniband/hw/ehca/hcp_if.h index 587ebd470959..2869f7dd6196 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.h +++ b/drivers/infiniband/hw/ehca/hcp_if.h | |||
@@ -85,6 +85,10 @@ u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle, | |||
85 | const u8 port_id, | 85 | const u8 port_id, |
86 | struct hipz_query_port *query_port_response_block); | 86 | struct hipz_query_port *query_port_response_block); |
87 | 87 | ||
88 | u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle, | ||
89 | const u8 port_id, const u32 port_cap, | ||
90 | const u8 init_type, const int modify_mask); | ||
91 | |||
88 | u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle, | 92 | u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle, |
89 | struct hipz_query_hca *query_hca_rblock); | 93 | struct hipz_query_hca *query_hca_rblock); |
90 | 94 | ||