[OPENSM] fixed build problem.
[mirror/winof/.git] / ulp / opensm / user / opensm / osm_sa_class_port_info.c
1 /*
2  * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.
4  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5  *
6  * This software is available to you under the OpenIB.org BSD license
7  * below:
8  *
9  *     Redistribution and use in source and binary forms, with or
10  *     without modification, are permitted provided that the following
11  *     conditions are met:
12  *
13  *      - Redistributions of source code must retain the above
14  *        copyright notice, this list of conditions and the following
15  *        disclaimer.
16  *
17  *      - Redistributions in binary form must reproduce the above
18  *        copyright notice, this list of conditions and the following
19  *        disclaimer in the documentation and/or other materials
20  *        provided with the distribution.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
26  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29  * SOFTWARE.
30  *
31  * $Id$
32  */
33
34
35
36 /*
37  * Abstract:
38  *    Implementation of osm_cpi_rcv_t.
39  * This object represents the ClassPortInfo Receiver object.
40  * This object is part of the opensm family of objects.
41  *
42  * Environment:
43  *    Linux User Mode
44  *
45  * $Revision: 1.8 $
46  */
47
48 #if HAVE_CONFIG_H
49 #  include <config.h>
50 #endif /* HAVE_CONFIG_H */
51
52 #include <string.h>
53 #include <iba/ib_types.h>
54 #include <complib/cl_qmap.h>
55 #include <complib/cl_passivelock.h>
56 #include <complib/cl_debug.h>
57 #include <complib/cl_qlist.h>
58 #include <opensm/osm_sa_class_port_info.h>
59 #include <vendor/osm_vendor.h>
60 #include <vendor/osm_vendor_api.h>
61 #include <opensm/osm_helper.h>
62
63 #define MAX_MSECS_TO_RTV 24
64 /* Precalculated table in msec (index is related to encoded value) */
65 /* 4.096 usec * 2 ** n (where n = 8 - 31) */
66 static uint32_t __msecs_to_rtv_table[MAX_MSECS_TO_RTV] =
67                                         { 1, 2, 4, 8,
68                                           16, 33, 67, 134, 
69                                           268, 536, 1073, 2147,
70                                           4294, 8589, 17179, 34359,
71                                           68719, 137438, 274877, 549755,
72                                           1099511, 2199023, 4398046, 8796093 };
73
74 /**********************************************************************
75  **********************************************************************/
76 void
77 osm_cpi_rcv_construct(
78   IN osm_cpi_rcv_t* const p_rcv )
79 {
80   memset( p_rcv, 0, sizeof(*p_rcv) );
81 }
82
83 /**********************************************************************
84  **********************************************************************/
85 void
86 osm_cpi_rcv_destroy(
87   IN osm_cpi_rcv_t* const p_rcv )
88 {
89   OSM_LOG_ENTER( p_rcv->p_log, osm_cpi_rcv_destroy );
90   OSM_LOG_EXIT( p_rcv->p_log );
91 }
92
93 /**********************************************************************
94  **********************************************************************/
95 ib_api_status_t
96 osm_cpi_rcv_init(
97   IN osm_cpi_rcv_t*     const p_rcv,
98   IN osm_sa_resp_t*     const p_resp,
99   IN osm_mad_pool_t*    const p_mad_pool,
100   IN osm_subn_t*        const p_subn,
101   IN osm_log_t*         const p_log,
102   IN cl_plock_t*        const p_lock )
103 {
104   ib_api_status_t status = IB_SUCCESS;
105
106   OSM_LOG_ENTER( p_log, osm_cpi_rcv_init );
107
108   osm_cpi_rcv_construct( p_rcv );
109
110   p_rcv->p_log = p_log;
111   p_rcv->p_subn = p_subn;
112   p_rcv->p_lock = p_lock;
113   p_rcv->p_resp = p_resp;
114   p_rcv->p_mad_pool = p_mad_pool;
115
116   OSM_LOG_EXIT( p_rcv->p_log );
117   return( status );
118 }
119
120 /**********************************************************************
121  **********************************************************************/
122 static void
123 __osm_cpi_rcv_respond(
124   IN osm_cpi_rcv_t*        const p_rcv,
125   IN const osm_madw_t*     const p_madw )
126 {
127   osm_madw_t*              p_resp_madw;
128   const ib_sa_mad_t*       p_sa_mad;
129   ib_sa_mad_t*             p_resp_sa_mad;
130   ib_class_port_info_t    *p_resp_cpi;
131   ib_api_status_t          status;
132   ib_gid_t                 zero_gid;
133   uint8_t                  rtv;
134
135   OSM_LOG_ENTER( p_rcv->p_log, __osm_cpi_rcv_respond );
136
137   memset(&zero_gid, 0, sizeof(ib_gid_t));
138
139   /*
140     Get a MAD to reply. Address of Mad is in the received mad_wrapper
141   */
142   p_resp_madw = osm_mad_pool_get( p_rcv->p_mad_pool, 
143                                   p_madw->h_bind,
144                                   MAD_BLOCK_SIZE,
145                                   &p_madw->mad_addr );
146   if( !p_resp_madw )
147   {
148     osm_log( p_rcv->p_log, OSM_LOG_ERROR,
149              "__osm_cpi_rcv_respond: ERR 1408: "
150              "Unable to allocate MAD\n" );
151     goto Exit;
152   }
153
154   p_sa_mad = osm_madw_get_sa_mad_ptr( p_madw );
155   p_resp_sa_mad = osm_madw_get_sa_mad_ptr( p_resp_madw );
156
157   memcpy( p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE );
158   p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
159   /* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
160   p_resp_sa_mad->sm_key = 0;
161
162   p_resp_cpi = (ib_class_port_info_t*)ib_sa_mad_get_payload_ptr( p_resp_sa_mad );
163
164   /* finally do it (the job) man ! */
165   p_resp_cpi->base_ver = 1;
166   p_resp_cpi->class_ver = 2;
167   /* Calculate encoded response time value */
168   /* transaction timeout is in msec */
169   if (p_rcv->p_subn->opt.transaction_timeout > __msecs_to_rtv_table[MAX_MSECS_TO_RTV])
170     rtv = MAX_MSECS_TO_RTV - 1;
171   else
172   {
173     for (rtv = 0; rtv < MAX_MSECS_TO_RTV; rtv++) {
174       if (p_rcv->p_subn->opt.transaction_timeout <= __msecs_to_rtv_table[rtv])
175          break;
176     }
177   }
178   rtv += 8;
179   p_resp_cpi->cap_mask2_resp_time = rtv;
180   p_resp_cpi->redir_gid = zero_gid;
181   p_resp_cpi->redir_tc_sl_fl = 0;
182   p_resp_cpi->redir_lid = 0;
183   p_resp_cpi->redir_pkey = 0;
184   p_resp_cpi->redir_qp = CL_NTOH32(1);
185   p_resp_cpi->redir_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
186   p_resp_cpi->trap_gid = zero_gid;
187   p_resp_cpi->trap_tc_sl_fl = 0;
188   p_resp_cpi->trap_lid = 0;
189   p_resp_cpi->trap_pkey = 0;
190   p_resp_cpi->trap_hop_qp = 0;
191   p_resp_cpi->trap_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
192
193   /* set specific capability mask bits */
194   /* we do not support the following optional records:
195      OSM_CAP_IS_SUBN_OPT_RECS_SUP :
196      RandomForwardingTableRecord,
197      ServiceAssociationRecord
198      other optional records supported "under the table"
199
200      OSM_CAP_IS_MULTIPATH_SUP:
201      TraceRecord
202
203      OSM_CAP_IS_REINIT_SUP:
204      For reinitialization functionality.
205
206      So not sending traps, but supporting Get(Notice) and Set(Notice).
207   */
208
209   /* Note host notation replaced later */
210 #if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
211   p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP |
212                          OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED |
213                          OSM_CAP_IS_MULTIPATH_SUP;
214 #else
215   p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP |
216                          OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED;
217 #endif
218   if (p_rcv->p_subn->opt.no_multicast_option != TRUE)
219     p_resp_cpi->cap_mask |= OSM_CAP_IS_UD_MCAST_SUP;
220   p_resp_cpi->cap_mask = cl_hton16(p_resp_cpi->cap_mask);
221
222   if( osm_log_is_active( p_rcv->p_log, OSM_LOG_FRAMES ) )
223     osm_dump_sa_mad( p_rcv->p_log, p_resp_sa_mad, OSM_LOG_FRAMES );
224
225   status = osm_vendor_send( p_resp_madw->h_bind, p_resp_madw,  FALSE );
226   if( status != IB_SUCCESS )
227   {
228     osm_log( p_rcv->p_log, OSM_LOG_ERROR,
229              "__osm_cpi_rcv_respond: ERR 1409: "
230              "Unable to send MAD (%s)\n", ib_get_err_str( status ) );
231     /*  osm_mad_pool_put( p_rcv->p_mad_pool, p_resp_madw ); */
232     goto Exit;
233   }
234
235  Exit:
236   OSM_LOG_EXIT( p_rcv->p_log );
237 }
238
239 /**********************************************************************
240  * This code actually handles the call
241  **********************************************************************/
242 void
243 osm_cpi_rcv_process(
244   IN osm_cpi_rcv_t*        const p_rcv,
245   IN const osm_madw_t*     const p_madw )
246 {
247   const ib_path_rec_t*     p_pr;
248   const ib_sa_mad_t*    p_sa_mad;
249
250   OSM_LOG_ENTER( p_rcv->p_log, osm_cpi_rcv_process );
251
252   CL_ASSERT( p_madw );
253
254   p_sa_mad = osm_madw_get_sa_mad_ptr( p_madw );
255
256   /* we only support GET */
257   if (p_sa_mad->method != IB_MAD_METHOD_GET)
258   {
259     osm_log( p_rcv->p_log, OSM_LOG_ERROR,
260              "osm_cpi_rcv_process: ERR 1403: "
261              "Unsupported Method (%s)\n",
262              ib_get_sa_method_str( p_sa_mad->method ) );
263     osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
264     goto Exit;
265   }
266
267   p_pr = (ib_path_rec_t*)ib_sa_mad_get_payload_ptr( p_sa_mad );
268
269   CL_ASSERT( p_sa_mad->attr_id == IB_MAD_ATTR_CLASS_PORT_INFO );
270
271   /*
272     CLASS PORT INFO does not really look on the SMDB - no lock required.
273   */
274
275   __osm_cpi_rcv_respond( p_rcv, p_madw);
276
277  Exit:
278   OSM_LOG_EXIT( p_rcv->p_log );
279 }
280