[MT23108] Removed linker dependency on IBAL.
[mirror/winof/.git] / hw / mt23108 / 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$\r
31  */\r
32 \r
33 \r
34 #include <iba/ib_ci.h>\r
35 #include <complib/comp_lib.h>\r
36 \r
37 #include <vapi.h>\r
38 #include <evapi.h>\r
39 #include <thhul_pdm.h>\r
40 #include <thhul_cqm.h>\r
41 #include <thhul_qpm.h>\r
42 \r
43 #include "hca_data.h"\r
44 \r
45 /*\r
46 *       Multicast Support Verbs.\r
47 */\r
48 ib_api_status_t\r
49 mlnx_attach_mcast (\r
50         IN              const   ib_qp_handle_t                          h_qp,\r
51         IN              const   ib_gid_t                                        *p_mcast_gid,\r
52         IN              const   uint16_t                                        mcast_lid,\r
53                 OUT                     ib_mcast_handle_t                       *ph_mcast,\r
54         IN      OUT                     ci_umv_buf_t                            *p_umv_buf )\r
55 {\r
56         ib_api_status_t         status;\r
57 \r
58         u_int32_t                       hca_idx = QP_HCA_FROM_HNDL(h_qp);\r
59         u_int32_t                       qp_num  = QP_NUM_FROM_HNDL(h_qp);\r
60         u_int32_t                       qp_idx  = 0;\r
61         mlnx_mcast_t            *mcast_p = NULL;\r
62         mlnx_hobul_t            *hobul_p;\r
63 \r
64         CL_ENTER(MLNX_DBG_TRACE, g_mlnx_dbg_lvl);\r
65 \r
66         UNUSED_PARAM( mcast_lid );\r
67 \r
68         if (!p_mcast_gid || !ph_mcast) {\r
69                 status = IB_INVALID_PARAMETER;\r
70                 goto cleanup;\r
71         }\r
72 \r
73         if (NULL == (mcast_p = cl_zalloc( sizeof(mlnx_mcast_t)))) {\r
74                 status = IB_INSUFFICIENT_MEMORY;\r
75                 goto cleanup;\r
76         }\r
77 \r
78         VALIDATE_INDEX(hca_idx, MLNX_MAX_HCA, IB_INVALID_CA_HANDLE, cleanup);\r
79         hobul_p = mlnx_hobul_array[hca_idx];\r
80         if (NULL == hobul_p) {\r
81                 status = IB_INVALID_QP_HANDLE;\r
82                 goto cleanup;\r
83         }\r
84 \r
85         qp_idx = qp_num & hobul_p->qp_idx_mask;\r
86 \r
87         VALIDATE_INDEX(qp_idx, hobul_p->max_qp, IB_INVALID_QP_HANDLE, cleanup);\r
88         if ( E_MARK_QP != hobul_p->qp_info_tbl[qp_idx].mark ) {\r
89                 status =  IB_INVALID_QP_HANDLE;\r
90                 goto cleanup;\r
91         }\r
92 \r
93         memcpy(&mcast_p->mcast_gid, &p_mcast_gid->raw[0], sizeof(IB_gid_t));\r
94         mcast_p->hca_idx = hca_idx;\r
95         mcast_p->qp_num  = qp_num;\r
96         mcast_p->mark = E_MARK_MG;\r
97 \r
98         cl_mutex_acquire(&hobul_p->qp_info_tbl[qp_idx].mutex);\r
99 \r
100         if (HH_OK != THH_hob_attach_to_multicast( hobul_p->hh_hndl, qp_num, mcast_p->mcast_gid)) {\r
101                 status = IB_ERROR;\r
102                 goto cleanup_locked;\r
103         }\r
104 \r
105         cl_mutex_release(&hobul_p->qp_info_tbl[qp_idx].mutex);\r
106 \r
107         *ph_mcast = (ib_mcast_handle_t)mcast_p;\r
108 \r
109         if( p_umv_buf && p_umv_buf->command )\r
110         {\r
111                 p_umv_buf->output_size = 0;\r
112                 p_umv_buf->status = IB_SUCCESS;\r
113         }\r
114         CL_EXIT(MLNX_DBG_TRACE, g_mlnx_dbg_lvl);\r
115         return IB_SUCCESS;\r
116 \r
117 cleanup_locked:\r
118         cl_mutex_release(&hobul_p->qp_info_tbl[qp_idx].mutex);\r
119 cleanup:\r
120         if (mcast_p) cl_free( mcast_p);\r
121 \r
122         if( p_umv_buf && p_umv_buf->command )\r
123         {\r
124                 p_umv_buf->output_size = 0;\r
125                 p_umv_buf->status = status;\r
126         }\r
127 \r
128         CL_TRACE(CL_DBG_ERROR, g_mlnx_dbg_lvl, ("completes with ERROR status %d\n", status));\r
129         CL_EXIT(MLNX_DBG_TRACE, g_mlnx_dbg_lvl);\r
130         return status;\r
131 }\r
132 \r
133 ib_api_status_t\r
134 mlnx_detach_mcast (\r
135         IN              const   ib_mcast_handle_t                       h_mcast)\r
136 {\r
137         ib_api_status_t         status;\r
138         mlnx_mcast_t            *mcast_p = (mlnx_mcast_t *)h_mcast;\r
139 \r
140         u_int32_t                       hca_idx;\r
141         u_int32_t                       qp_num;\r
142         u_int32_t                       qp_idx  = 0;\r
143         mlnx_hobul_t            *hobul_p;\r
144 \r
145         CL_ENTER(MLNX_DBG_TRACE, g_mlnx_dbg_lvl);\r
146 \r
147         if (!mcast_p || mcast_p->mark != E_MARK_MG) {\r
148                 status = IB_INVALID_PARAMETER;\r
149                 goto cleanup;\r
150         }\r
151         hca_idx = mcast_p->hca_idx;\r
152         qp_num = mcast_p->qp_num;\r
153 \r
154         VALIDATE_INDEX(hca_idx, MLNX_MAX_HCA, IB_INVALID_CA_HANDLE, cleanup);\r
155         hobul_p = mlnx_hobul_array[hca_idx];\r
156         if (NULL == hobul_p) {\r
157                 status = IB_INVALID_QP_HANDLE;\r
158                 goto cleanup;\r
159         }\r
160 \r
161         qp_idx = qp_num & hobul_p->qp_idx_mask;\r
162 \r
163         VALIDATE_INDEX(qp_idx, hobul_p->max_qp, IB_INVALID_QP_HANDLE, cleanup);\r
164         if ( E_MARK_QP != hobul_p->qp_info_tbl[qp_idx].mark ) {\r
165                 status =  IB_INVALID_QP_HANDLE;\r
166                 goto cleanup;\r
167         }\r
168 \r
169         cl_mutex_acquire(&hobul_p->qp_info_tbl[qp_idx].mutex);\r
170 \r
171         if (HH_OK != THH_hob_detach_from_multicast( hobul_p->hh_hndl, qp_num, mcast_p->mcast_gid)) {\r
172                 status = IB_ERROR;\r
173                 goto cleanup_locked;\r
174         }\r
175 \r
176         cl_mutex_release(&hobul_p->qp_info_tbl[qp_idx].mutex);\r
177 \r
178         mcast_p->mark = E_MARK_INVALID;\r
179         cl_free( mcast_p);\r
180 \r
181         CL_EXIT(MLNX_DBG_TRACE, g_mlnx_dbg_lvl);\r
182         return IB_SUCCESS;\r
183 \r
184 cleanup_locked:\r
185         cl_mutex_release(&hobul_p->qp_info_tbl[qp_idx].mutex);\r
186 cleanup:\r
187         if (mcast_p) {\r
188                 mcast_p->mark = E_MARK_INVALID;\r
189                 cl_free( mcast_p);\r
190         }\r
191 \r
192         CL_TRACE(CL_DBG_ERROR, g_mlnx_dbg_lvl, ("completes with ERROR status %d\n", status));\r
193         CL_EXIT(MLNX_DBG_TRACE, g_mlnx_dbg_lvl);\r
194         return status;\r
195 }\r
196 \r
197 \r
198 void\r
199 mlnx_mcast_if(\r
200         IN      OUT                     ci_interface_t                          *p_interface )\r
201 {\r
202         p_interface->attach_mcast = mlnx_attach_mcast;\r
203         p_interface->detach_mcast = mlnx_detach_mcast;\r
204 }\r