linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] eHCA: Add "Modify Port" verb
@ 2007-04-23 16:23 Joachim Fenkes
  2007-04-23 19:20 ` Roland Dreier
  0 siblings, 1 reply; 5+ messages in thread
From: Joachim Fenkes @ 2007-04-23 16:23 UTC (permalink / raw)
  To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier

Add "Modify Port" verb support to eHCA driver.
ib_cm needs this to initialize properly.


Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---

 ehca_hca.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++--
 hcp_if.c   |   24 ++++++++++++++++++++++++
 hcp_if.h   |    4 ++++
 3 files changed, 74 insertions(+), 2 deletions(-)

diff -urp a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
--- a/drivers/infiniband/hw/ehca/ehca_hca.c	2007-02-04 19:44:54.000000000 +0100
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c	2007-04-23 18:09:38.000000000 +0200
@@ -147,6 +147,7 @@ int ehca_query_port(struct ib_device *ib
 		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;
@@ -233,10 +234,53 @@ query_gid1:
 	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;
+	}
+
+	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
+	if (!rblock) {
+		ehca_err(&shca->ib_device,  "Can't allocate rblock memory.");
+		return -ENOMEM;
+	}
+
+	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_port1;
+	}
+
+	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_port1:
+	ehca_free_fw_ctrlblock(rblock);
+
+	return ret;
 }
diff -urp a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
--- a/drivers/infiniband/hw/ehca/hcp_if.c	2007-02-04 19:44:54.000000000 +0100
+++ b/drivers/infiniband/hw/ehca/hcp_if.c	2007-04-23 18:06:09.000000000 +0200
@@ -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_a
 	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)
 {
diff -urp a/drivers/infiniband/hw/ehca/hcp_if.h b/drivers/infiniband/hw/ehca/hcp_if.h
--- a/drivers/infiniband/hw/ehca/hcp_if.h	2007-02-04 19:44:54.000000000 +0100
+++ b/drivers/infiniband/hw/ehca/hcp_if.h	2007-04-23 18:06:09.000000000 +0200
@@ -85,6 +85,10 @@ u64 hipz_h_query_port(const struct ipz_a
 		      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);
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] eHCA: Add "Modify Port" verb
  2007-04-23 16:23 Joachim Fenkes
@ 2007-04-23 19:20 ` Roland Dreier
  2007-04-24 12:25   ` Joachim Fenkes
  0 siblings, 1 reply; 5+ messages in thread
From: Roland Dreier @ 2007-04-23 19:20 UTC (permalink / raw)
  To: Joachim Fenkes; +Cc: LinuxPPC-Dev, LKML, OF-General

 > +	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_port1;
 > +	}
 > +
 > +	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);

Is this thread-safe?  What if two different bits are set at the same
time from two different threads?  It seems that both calls could get
the same result from hipz_h_query_port(), and then the second call to
hipz_h_modify_port() would overwrite the first call.

You could look at the implementation in mthca to see the locking I
used there.

 - R.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] eHCA: Add "Modify Port" verb
  2007-04-23 19:20 ` Roland Dreier
@ 2007-04-24 12:25   ` Joachim Fenkes
  0 siblings, 0 replies; 5+ messages in thread
From: Joachim Fenkes @ 2007-04-24 12:25 UTC (permalink / raw)
  To: Roland Dreier; +Cc: LinuxPPC-Dev, LKML, OF-General

Roland Dreier <rdreier@cisco.com> wrote on 23.04.2007 21:20:14:

>  > +   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_port1;
>  > +   }
>  > +
>  > +   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);
> 
> Is this thread-safe?  What if two different bits are set at the same
> time from two different threads?  It seems that both calls could get
> the same result from hipz_h_query_port(), and then the second call to
> hipz_h_modify_port() would overwrite the first call.

Yes, you're so right.
 
> You could look at the implementation in mthca to see the locking I
> used there.

I'll do that, thanks for the hint!

Joachim

---
Joachim Fenkes  --  eHCA Linux Driver Developer and Hardware Tamer
IBM Deutschland Entwicklung GmbH  --  Dept. 3627 (I/O Firmware Dev. 2)
Schoenaicher Strasse 220  --  71032 Boeblingen  --  Germany
eMail: fenkes@de.ibm.com  --  Phone: +49 7031 16 1239 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] eHCA: Add "Modify Port" verb
@ 2007-04-24 15:44 Joachim Fenkes
  2007-04-24 17:52 ` Roland Dreier
  0 siblings, 1 reply; 5+ messages in thread
From: Joachim Fenkes @ 2007-04-24 15:44 UTC (permalink / raw)
  To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier

Add "Modify Port" verb support to eHCA driver.
ib_cm needs this to initialize properly.


Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---

This is the shiny new version of this patch with proper locking.
Tested and works.

 ehca_classes.h |    1 +
 ehca_hca.c     |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 ehca_main.c    |    1 +
 hcp_if.c       |   24 ++++++++++++++++++++++++
 hcp_if.h       |    4 ++++
 5 files changed, 83 insertions(+), 2 deletions(-)

diff -urp a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
--- a/drivers/infiniband/hw/ehca/ehca_classes.h	2007-02-04 19:44:54.000000000 +0100
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h	2007-04-24 14:51:38.000000000 +0200
@@ -96,6 +96,7 @@ struct ehca_shca {
 	struct ehca_mr *maxmr;
 	struct ehca_pd *pd;
 	struct h_galpas galpas;
+	struct mutex modify_mutex;
 };
 
 struct ehca_pd {
diff -urp a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
--- a/drivers/infiniband/hw/ehca/ehca_hca.c	2007-02-04 19:44:54.000000000 +0100
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c	2007-04-24 14:50:43.000000000 +0200
@@ -147,6 +147,7 @@ int ehca_query_port(struct ib_device *ib
 		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;
@@ -233,10 +234,60 @@ query_gid1:
 	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;
 }
diff -urp a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
--- a/drivers/infiniband/hw/ehca/ehca_main.c	2007-02-04 19:44:54.000000000 +0100
+++ b/drivers/infiniband/hw/ehca/ehca_main.c	2007-04-24 14:50:43.000000000 +0200
@@ -583,6 +583,7 @@ static int __devinit ehca_probe(struct i
 		ehca_gen_err("Cannot allocate shca memory.");
 		return -ENOMEM;
 	}
+	mutex_init(&shca->modify_mutex);
 
 	shca->ibmebus_dev = dev;
 	shca->ipz_hca_handle.handle = *handle;
diff -urp a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
--- a/drivers/infiniband/hw/ehca/hcp_if.c	2007-02-04 19:44:54.000000000 +0100
+++ b/drivers/infiniband/hw/ehca/hcp_if.c	2007-04-23 18:06:09.000000000 +0200
@@ -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_a
 	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)
 {
diff -urp a/drivers/infiniband/hw/ehca/hcp_if.h b/drivers/infiniband/hw/ehca/hcp_if.h
--- a/drivers/infiniband/hw/ehca/hcp_if.h	2007-02-04 19:44:54.000000000 +0100
+++ b/drivers/infiniband/hw/ehca/hcp_if.h	2007-04-23 18:06:09.000000000 +0200
@@ -85,6 +85,10 @@ u64 hipz_h_query_port(const struct ipz_a
 		      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);
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] eHCA: Add "Modify Port" verb
  2007-04-24 15:44 [PATCH] eHCA: Add "Modify Port" verb Joachim Fenkes
@ 2007-04-24 17:52 ` Roland Dreier
  0 siblings, 0 replies; 5+ messages in thread
From: Roland Dreier @ 2007-04-24 17:52 UTC (permalink / raw)
  To: Joachim Fenkes; +Cc: LinuxPPC-Dev, LKML, OF-General

Looks good, applied for 2.6.22.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-04-24 17:52 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-24 15:44 [PATCH] eHCA: Add "Modify Port" verb Joachim Fenkes
2007-04-24 17:52 ` Roland Dreier
  -- strict thread matches above, loose matches on Subject: below --
2007-04-23 16:23 Joachim Fenkes
2007-04-23 19:20 ` Roland Dreier
2007-04-24 12:25   ` Joachim Fenkes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).