Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/infiniband/hw/ehca/ehca_mcast.c
15112 views
1
/*
2
* IBM eServer eHCA Infiniband device driver for Linux on POWER
3
*
4
* mcast functions
5
*
6
* Authors: Khadija Souissi <[email protected]>
7
* Waleri Fomin <[email protected]>
8
* Reinhard Ernst <[email protected]>
9
* Hoang-Nam Nguyen <[email protected]>
10
* Heiko J Schick <[email protected]>
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
45
#include <linux/module.h>
46
#include <linux/err.h>
47
#include "ehca_classes.h"
48
#include "ehca_tools.h"
49
#include "ehca_qes.h"
50
#include "ehca_iverbs.h"
51
#include "hcp_if.h"
52
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))
58
59
int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
60
{
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,
63
ib_device);
64
union ib_gid my_gid;
65
u64 subnet_prefix, interface_id, h_ret;
66
67
if (ibqp->qp_type != IB_QPT_UD) {
68
ehca_err(ibqp->device, "invalid qp_type=%x", ibqp->qp_type);
69
return -EINVAL;
70
}
71
72
if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
73
ehca_err(ibqp->device, "invalid mulitcast gid");
74
return -EINVAL;
75
} else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
76
ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
77
return -EINVAL;
78
}
79
80
memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
81
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,
85
my_qp->ipz_qp_handle,
86
my_qp->galpas.kernel,
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);
92
93
return ehca2ib_return_code(h_ret);
94
}
95
96
int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
97
{
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);
101
union ib_gid my_gid;
102
u64 subnet_prefix, interface_id, h_ret;
103
104
if (ibqp->qp_type != IB_QPT_UD) {
105
ehca_err(ibqp->device, "invalid qp_type %x", ibqp->qp_type);
106
return -EINVAL;
107
}
108
109
if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
110
ehca_err(ibqp->device, "invalid mulitcast gid");
111
return -EINVAL;
112
} else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
113
ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
114
return -EINVAL;
115
}
116
117
memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
118
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);
129
130
return ehca2ib_return_code(h_ret);
131
}
132
133