]> err.no Git - linux-2.6/blobdiff - drivers/infiniband/hw/ehca/ehca_av.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[linux-2.6] / drivers / infiniband / hw / ehca / ehca_av.c
index 97d108634c5830c27012869d494be6656f92c23d..56735ea2fc576746ebb22350e8c3b18009279f79 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  IBM eServer eHCA Infiniband device driver for Linux on POWER
  *
- *  adress vector functions
+ *  address vector functions
  *
  *  Authors: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
  *           Khadija Souissi <souissik@de.ibm.com>
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-
-#include <asm/current.h>
-
 #include "ehca_tools.h"
 #include "ehca_iverbs.h"
 #include "hcp_if.h"
 
 static struct kmem_cache *av_cache;
 
+int ehca_calc_ipd(struct ehca_shca *shca, int port,
+                 enum ib_rate path_rate, u32 *ipd)
+{
+       int path = ib_rate_to_mult(path_rate);
+       int link, ret;
+       struct ib_port_attr pa;
+
+       if (path_rate == IB_RATE_PORT_CURRENT) {
+               *ipd = 0;
+               return 0;
+       }
+
+       if (unlikely(path < 0)) {
+               ehca_err(&shca->ib_device, "Invalid static rate! path_rate=%x",
+                        path_rate);
+               return -EINVAL;
+       }
+
+       ret = ehca_query_port(&shca->ib_device, port, &pa);
+       if (unlikely(ret < 0)) {
+               ehca_err(&shca->ib_device, "Failed to query port  ret=%i", ret);
+               return ret;
+       }
+
+       link = ib_width_enum_to_int(pa.active_width) * pa.active_speed;
+
+       if (path >= link)
+               /* no need to throttle if path faster than link */
+               *ipd = 0;
+       else
+               /* IPD = round((link / path) - 1) */
+               *ipd = ((link + (path >> 1)) / path) - 1;
+
+       return 0;
+}
+
 struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
 {
        int ret;
@@ -69,15 +102,13 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
        av->av.slid_path_bits = ah_attr->src_path_bits;
 
        if (ehca_static_rate < 0) {
-               int ah_mult = ib_rate_to_mult(ah_attr->static_rate);
-               int ehca_mult =
-                       ib_rate_to_mult(shca->sport[ah_attr->port_num].rate );
-
-               if (ah_mult >= ehca_mult)
-                       av->av.ipd = 0;
-               else
-                       av->av.ipd = (ah_mult > 0) ?
-                               ((ehca_mult - 1) / ah_mult) : 0;
+               u32 ipd;
+               if (ehca_calc_ipd(shca, ah_attr->port_num,
+                                 ah_attr->static_rate, &ipd)) {
+                       ret = -EINVAL;
+                       goto create_ah_exit1;
+               }
+               av->av.ipd = ipd;
        } else
                av->av.ipd = ehca_static_rate;
 
@@ -136,17 +167,8 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
 {
        struct ehca_av *av;
        struct ehca_ud_av new_ehca_av;
-       struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd);
        struct ehca_shca *shca = container_of(ah->pd->device, struct ehca_shca,
                                              ib_device);
-       u32 cur_pid = current->tgid;
-
-       if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
-           my_pd->ownpid != cur_pid) {
-               ehca_err(ah->device, "Invalid caller pid=%x ownpid=%x",
-                        cur_pid, my_pd->ownpid);
-               return -EINVAL;
-       }
 
        memset(&new_ehca_av, 0, sizeof(new_ehca_av));
        new_ehca_av.sl = ah_attr->sl;
@@ -208,15 +230,6 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
 int ehca_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
 {
        struct ehca_av *av = container_of(ah, struct ehca_av, ib_ah);
-       struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd);
-       u32 cur_pid = current->tgid;
-
-       if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
-           my_pd->ownpid != cur_pid) {
-               ehca_err(ah->device, "Invalid caller pid=%x ownpid=%x",
-                        cur_pid, my_pd->ownpid);
-               return -EINVAL;
-       }
 
        memcpy(&ah_attr->grh.dgid, &av->av.grh.word_3,
               sizeof(ah_attr->grh.dgid));
@@ -239,16 +252,6 @@ int ehca_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
 
 int ehca_destroy_ah(struct ib_ah *ah)
 {
-       struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd);
-       u32 cur_pid = current->tgid;
-
-       if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
-           my_pd->ownpid != cur_pid) {
-               ehca_err(ah->device, "Invalid caller pid=%x ownpid=%x",
-                        cur_pid, my_pd->ownpid);
-               return -EINVAL;
-       }
-
        kmem_cache_free(av_cache, container_of(ah, struct ehca_av, ib_ah));
 
        return 0;