Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c4ed790dfd4b2182c76e0fcd79d4aa85ab02eccf
Commit:     c4ed790dfd4b2182c76e0fcd79d4aa85ab02eccf
Parent:     bd8031b49a9b05933fb1ec1c36620ed4e1e67793
Author:     Joachim Fenkes <[EMAIL PROTECTED]>
AuthorDate: Tue Apr 24 17:44:31 2007 +0200
Committer:  Roland Dreier <[EMAIL PROTECTED]>
CommitDate: Tue Apr 24 21:30:38 2007 -0700

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Roland Dreier <[EMAIL PROTECTED]>
---
 drivers/infiniband/hw/ehca/ehca_classes.h |    1 +
 drivers/infiniband/hw/ehca/ehca_hca.c     |   55 +++++++++++++++++++++++++++-
 drivers/infiniband/hw/ehca/ehca_main.c    |    1 +
 drivers/infiniband/hw/ehca/hcp_if.c       |   24 ++++++++++++
 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 82ded44..10fb8fb 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -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 {
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c 
b/drivers/infiniband/hw/ehca/ehca_hca.c
index 30eb45d..32b55a4 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,
                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 @@ 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 --git a/drivers/infiniband/hw/ehca/ehca_main.c 
b/drivers/infiniband/hw/ehca/ehca_main.c
index 059da96..3b23d67 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,
                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 --git a/drivers/infiniband/hw/ehca/hcp_if.c 
b/drivers/infiniband/hw/ehca/hcp_if.c
index 3fb46e6..b564fcd 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -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)
 {
diff --git a/drivers/infiniband/hw/ehca/hcp_if.h 
b/drivers/infiniband/hw/ehca/hcp_if.h
index 587ebd4..2869f7d 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,
                      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);
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to