49c70b9559e27f3e03827e3aea469436e42557b0
[mirror/winof/.git] / hw / mlx4 / kernel / hca / mcast.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 2004-2005 Mellanox Technologies, Inc. All rights reserved. \r
4  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id: hca_mcast.c 1936 2007-02-06 16:04:33Z sleybo $\r
31  */\r
32 \r
33 \r
34 #include "precomp.h"\r
35 \r
36 #if defined(EVENT_TRACING)\r
37 #ifdef offsetof\r
38 #undef offsetof\r
39 #endif\r
40 #include "mcast.tmh"\r
41 #endif\r
42 \r
43 /*\r
44 *       Multicast Support Verbs.\r
45 */\r
46 ib_api_status_t\r
47 mlnx_attach_mcast (\r
48         IN              const   ib_qp_handle_t                          h_qp,\r
49         IN              const   ib_gid_t                                        *p_mcast_gid,\r
50         IN              const   uint16_t                                        mcast_lid,\r
51                 OUT                     ib_mcast_handle_t                       *ph_mcast,\r
52         IN      OUT                     ci_umv_buf_t                            *p_umv_buf )\r
53 {\r
54         int err;\r
55         ib_api_status_t         status;\r
56         struct ib_qp *p_ib_qp = (struct ib_qp *)h_qp;\r
57         mlnx_mcast_t *p_mcast;\r
58 \r
59         HCA_ENTER(HCA_DBG_MCAST);\r
60 \r
61         // sanity checks\r
62         if( p_umv_buf && p_umv_buf->command ) {\r
63                 HCA_PRINT(TRACE_LEVEL_ERROR , HCA_DBG_MCAST,\r
64                         ("User mode is not supported yet\n"));\r
65                 status = IB_UNSUPPORTED;\r
66                 goto err_nosys;\r
67         }\r
68 \r
69         if( !cl_is_blockable() ) {\r
70                         status = IB_UNSUPPORTED;\r
71                         goto err_nosys;\r
72         }\r
73 \r
74         if (!p_mcast_gid || !ph_mcast) {\r
75                 status = IB_INVALID_PARAMETER;\r
76                 goto err_invalid_param;\r
77         }\r
78 \r
79         if (p_mcast_gid->raw[0] != 0xff || p_ib_qp->qp_type != IB_QPT_UD) {\r
80                 status = IB_INVALID_PARAMETER;\r
81                 goto err_invalid_param;\r
82         }\r
83 \r
84         // allocate structure\r
85         p_mcast = (mlnx_mcast_t*)kmalloc(sizeof *p_mcast, GFP_ATOMIC );\r
86         if (p_mcast == NULL) {\r
87                 status = IB_INSUFFICIENT_MEMORY;\r
88                 goto err_no_mem;\r
89         }\r
90         \r
91         // attach to mcast group\r
92         err = p_ib_qp->device->attach_mcast(p_ib_qp, \r
93                 (union ib_gid *)p_mcast_gid, mcast_lid);\r
94         if (err) {\r
95                 HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_MCAST,\r
96                         ("ibv_attach_mcast failed (%d)\n", err));\r
97                 status = errno_to_iberr(err);\r
98                 goto err_attach;\r
99         }\r
100 \r
101         // fill the structure\r
102         p_mcast->p_ib_qp = p_ib_qp;\r
103         p_mcast->mcast_lid = mcast_lid;\r
104         RtlCopyMemory(p_mcast->mcast_gid.raw, p_mcast_gid->raw, sizeof *p_mcast_gid);\r
105         HCA_PRINT(TRACE_LEVEL_INFORMATION,HCA_DBG_MCAST,\r
106                 ("mcasth %p, qp_p %p, mlid %hx, mgid %I64x`%I64x\n", \r
107                 p_mcast, p_mcast->p_ib_qp, p_mcast->mcast_lid,\r
108                 cl_ntoh64(*(uint64_t*)&p_mcast->mcast_gid.raw[0]),\r
109                 cl_ntoh64(*(uint64_t*)&p_mcast->mcast_gid.raw[8] )));\r
110         \r
111         // return the result\r
112         if (ph_mcast) *ph_mcast = (ib_mcast_handle_t)p_mcast;\r
113 \r
114         status = IB_SUCCESS;\r
115         goto end;\r
116                 \r
117 err_attach: \r
118         kfree(p_mcast);\r
119 err_no_mem:     \r
120 err_invalid_param:\r
121 end:            \r
122 err_nosys:      \r
123         if (p_umv_buf && p_umv_buf->command) \r
124                 p_umv_buf->status = status;\r
125         if (status != IB_SUCCESS) \r
126                 HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_MCAST,\r
127                         ("completes with ERROR status %x\n", status));\r
128         HCA_EXIT(HCA_DBG_MCAST);\r
129         return status;\r
130 }\r
131 \r
132 ib_api_status_t\r
133 mlnx_detach_mcast (\r
134         IN              const   ib_mcast_handle_t                       h_mcast)\r
135 {\r
136         int err;\r
137         ib_api_status_t         status;\r
138         mlnx_mcast_t *p_mcast = (mlnx_mcast_t*)h_mcast;\r
139 \r
140         \r
141         HCA_ENTER(HCA_DBG_MCAST);\r
142 \r
143         // sanity checks\r
144         if (!p_mcast || !p_mcast->p_ib_qp) {\r
145                 HCA_PRINT(TRACE_LEVEL_ERROR , HCA_DBG_MCAST,\r
146                         ("completes with ERROR status IB_INVALID_PARAMETER\n"));\r
147                 status =  IB_INVALID_PARAMETER;\r
148                 goto err_invalid_param;\r
149         }\r
150 \r
151         if( !cl_is_blockable() ) {\r
152                         status = IB_UNSUPPORTED;\r
153                         goto err_unsupported;\r
154         }\r
155 \r
156         if (p_mcast->mcast_gid.raw[0] != 0xff || p_mcast->p_ib_qp->qp_type != IB_QPT_UD) {\r
157                 status =  IB_INVALID_PARAMETER;\r
158                 goto err_invalid_param;\r
159         }\r
160 \r
161         HCA_PRINT(TRACE_LEVEL_INFORMATION,HCA_DBG_MCAST,\r
162                 ("mcasth %p, qp_p %p, mlid %hx, mgid %I64x`%I64x\n", \r
163                 p_mcast, p_mcast->p_ib_qp, p_mcast->mcast_lid,\r
164                 *(uint64_t*)&p_mcast->mcast_gid.raw[0],\r
165                 *(uint64_t*)&p_mcast->mcast_gid.raw[8] ));\r
166         \r
167         // detach\r
168         err = p_mcast->p_ib_qp->device->detach_mcast(p_mcast->p_ib_qp, \r
169                 (union ib_gid *)&p_mcast->mcast_gid, p_mcast->mcast_lid);\r
170         if (err) {\r
171                 HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_MCAST,\r
172                         ("ibv_detach_mcast failed (%d)\n", err));\r
173                 status = errno_to_iberr(err);\r
174                 goto err_detach_mcast;\r
175         }\r
176 \r
177         kfree(p_mcast);\r
178         status = IB_SUCCESS;\r
179 \r
180 err_detach_mcast:\r
181 err_unsupported:        \r
182 err_invalid_param:\r
183         if (status != IB_SUCCESS) \r
184                 HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_MCAST,\r
185                         ("completes with ERROR status %d\n", status));\r
186         HCA_EXIT(HCA_DBG_MCAST);\r
187         return status;\r
188 }\r
189 \r
190 \r
191 void\r
192 mlnx_mcast_if(\r
193         IN      OUT                     ci_interface_t                          *p_interface )\r
194 {\r
195         p_interface->attach_mcast = mlnx_attach_mcast;\r
196         p_interface->detach_mcast = mlnx_detach_mcast;\r
197 }\r