2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
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>
12 * Copyright (c) 2005 IBM Corporation
14 * All rights reserved.
16 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
24 * Redistributions of source code must retain the above copyright notice, this
25 * list of conditions and the following disclaimer.
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.
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.
45 #include <linux/module.h>
46 #include <linux/err.h>
47 #include "ehca_classes.h"
48 #include "ehca_tools.h"
50 #include "ehca_iverbs.h"
53 #define MAX_MC_LID 0xFFFE
54 #define MIN_MC_LID 0xC000 /* Multicast limits */
55 #define EHCA_VALID_MULTICAST_GID(gid) ((gid)[0] == 0xFF)
56 #define EHCA_VALID_MULTICAST_LID(lid) \
57 (((lid) >= MIN_MC_LID) && ((lid) <= MAX_MC_LID))
59 int ehca_attach_mcast(struct ib_qp
*ibqp
, union ib_gid
*gid
, u16 lid
)
61 struct ehca_qp
*my_qp
= container_of(ibqp
, struct ehca_qp
, ib_qp
);
62 struct ehca_shca
*shca
= container_of(ibqp
->device
, struct ehca_shca
,
65 u64 subnet_prefix
, interface_id
, h_ret
;
67 if (ibqp
->qp_type
!= IB_QPT_UD
) {
68 ehca_err(ibqp
->device
, "invalid qp_type=%x", ibqp
->qp_type
);
72 if (!(EHCA_VALID_MULTICAST_GID(gid
->raw
))) {
73 ehca_err(ibqp
->device
, "invalid mulitcast gid");
75 } else if ((lid
< MIN_MC_LID
) || (lid
> MAX_MC_LID
)) {
76 ehca_err(ibqp
->device
, "invalid mulitcast lid=%x", lid
);
80 memcpy(&my_gid
.raw
, gid
->raw
, sizeof(union ib_gid
));
82 subnet_prefix
= be64_to_cpu(my_gid
.global
.subnet_prefix
);
83 interface_id
= be64_to_cpu(my_gid
.global
.interface_id
);
84 h_ret
= hipz_h_attach_mcqp(shca
->ipz_hca_handle
,
87 lid
, subnet_prefix
, interface_id
);
88 if (h_ret
!= H_SUCCESS
)
89 ehca_err(ibqp
->device
,
90 "ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed "
91 "h_ret=%lli", my_qp
, ibqp
->qp_num
, h_ret
);
93 return ehca2ib_return_code(h_ret
);
96 int ehca_detach_mcast(struct ib_qp
*ibqp
, union ib_gid
*gid
, u16 lid
)
98 struct ehca_qp
*my_qp
= container_of(ibqp
, struct ehca_qp
, ib_qp
);
99 struct ehca_shca
*shca
= container_of(ibqp
->pd
->device
,
100 struct ehca_shca
, ib_device
);
102 u64 subnet_prefix
, interface_id
, h_ret
;
104 if (ibqp
->qp_type
!= IB_QPT_UD
) {
105 ehca_err(ibqp
->device
, "invalid qp_type %x", ibqp
->qp_type
);
109 if (!(EHCA_VALID_MULTICAST_GID(gid
->raw
))) {
110 ehca_err(ibqp
->device
, "invalid mulitcast gid");
112 } else if ((lid
< MIN_MC_LID
) || (lid
> MAX_MC_LID
)) {
113 ehca_err(ibqp
->device
, "invalid mulitcast lid=%x", lid
);
117 memcpy(&my_gid
.raw
, gid
->raw
, sizeof(union ib_gid
));
119 subnet_prefix
= be64_to_cpu(my_gid
.global
.subnet_prefix
);
120 interface_id
= be64_to_cpu(my_gid
.global
.interface_id
);
121 h_ret
= hipz_h_detach_mcqp(shca
->ipz_hca_handle
,
122 my_qp
->ipz_qp_handle
,
123 my_qp
->galpas
.kernel
,
124 lid
, subnet_prefix
, interface_id
);
125 if (h_ret
!= H_SUCCESS
)
126 ehca_err(ibqp
->device
,
127 "ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed "
128 "h_ret=%lli", my_qp
, ibqp
->qp_num
, h_ret
);
130 return ehca2ib_return_code(h_ret
);