ehca_mcast.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * IBM eServer eHCA Infiniband device driver for Linux on POWER
  3. *
  4. * mcast functions
  5. *
  6. * Authors: Khadija Souissi <souissik@de.ibm.com>
  7. * Waleri Fomin <fomin@de.ibm.com>
  8. * Reinhard Ernst <rernst@de.ibm.com>
  9. * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
  10. * Heiko J Schick <schickhj@de.ibm.com>
  11. *
  12. * Copyright (c) 2005 IBM Corporation
  13. *
  14. * All rights reserved.
  15. *
  16. * This source code is distributed under a dual license of GPL v2.0 and OpenIB
  17. * BSD.
  18. *
  19. * OpenIB BSD License
  20. *
  21. * Redistribution and use in source and binary forms, with or without
  22. * modification, are permitted provided that the following conditions are met:
  23. *
  24. * Redistributions of source code must retain the above copyright notice, this
  25. * list of conditions and the following disclaimer.
  26. *
  27. * Redistributions in binary form must reproduce the above copyright notice,
  28. * this list of conditions and the following disclaimer in the documentation
  29. * and/or other materials
  30. * provided with the distribution.
  31. *
  32. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  33. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  36. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  37. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  38. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  39. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  40. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42. * POSSIBILITY OF SUCH DAMAGE.
  43. */
  44. #include <linux/module.h>
  45. #include <linux/err.h>
  46. #include "ehca_classes.h"
  47. #include "ehca_tools.h"
  48. #include "ehca_qes.h"
  49. #include "ehca_iverbs.h"
  50. #include "hcp_if.h"
  51. #define MAX_MC_LID 0xFFFE
  52. #define MIN_MC_LID 0xC000 /* Multicast limits */
  53. #define EHCA_VALID_MULTICAST_GID(gid) ((gid)[0] == 0xFF)
  54. #define EHCA_VALID_MULTICAST_LID(lid) \
  55. (((lid) >= MIN_MC_LID) && ((lid) <= MAX_MC_LID))
  56. int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
  57. {
  58. struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
  59. struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca,
  60. ib_device);
  61. union ib_gid my_gid;
  62. u64 subnet_prefix, interface_id, h_ret;
  63. if (ibqp->qp_type != IB_QPT_UD) {
  64. ehca_err(ibqp->device, "invalid qp_type=%x", ibqp->qp_type);
  65. return -EINVAL;
  66. }
  67. if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
  68. ehca_err(ibqp->device, "invalid mulitcast gid");
  69. return -EINVAL;
  70. } else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
  71. ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
  72. return -EINVAL;
  73. }
  74. memcpy(&my_gid, gid->raw, sizeof(union ib_gid));
  75. subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
  76. interface_id = be64_to_cpu(my_gid.global.interface_id);
  77. h_ret = hipz_h_attach_mcqp(shca->ipz_hca_handle,
  78. my_qp->ipz_qp_handle,
  79. my_qp->galpas.kernel,
  80. lid, subnet_prefix, interface_id);
  81. if (h_ret != H_SUCCESS)
  82. ehca_err(ibqp->device,
  83. "ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed "
  84. "h_ret=%lli", my_qp, ibqp->qp_num, h_ret);
  85. return ehca2ib_return_code(h_ret);
  86. }
  87. int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
  88. {
  89. struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
  90. struct ehca_shca *shca = container_of(ibqp->pd->device,
  91. struct ehca_shca, ib_device);
  92. union ib_gid my_gid;
  93. u64 subnet_prefix, interface_id, h_ret;
  94. if (ibqp->qp_type != IB_QPT_UD) {
  95. ehca_err(ibqp->device, "invalid qp_type %x", ibqp->qp_type);
  96. return -EINVAL;
  97. }
  98. if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
  99. ehca_err(ibqp->device, "invalid mulitcast gid");
  100. return -EINVAL;
  101. } else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
  102. ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
  103. return -EINVAL;
  104. }
  105. memcpy(&my_gid, gid->raw, sizeof(union ib_gid));
  106. subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
  107. interface_id = be64_to_cpu(my_gid.global.interface_id);
  108. h_ret = hipz_h_detach_mcqp(shca->ipz_hca_handle,
  109. my_qp->ipz_qp_handle,
  110. my_qp->galpas.kernel,
  111. lid, subnet_prefix, interface_id);
  112. if (h_ret != H_SUCCESS)
  113. ehca_err(ibqp->device,
  114. "ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed "
  115. "h_ret=%lli", my_qp, ibqp->qp_num, h_ret);
  116. return ehca2ib_return_code(h_ret);
  117. }