c6bd3a24a7c4dbdcb395d417d50343416b6e4626
[mirror/winof/.git] / ulp / opensm / user / ibtrapgen / ibtrapgen.c
1 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2   This software program is available to you under a choice of one of two
3   licenses.  You may choose to be licensed under either the GNU General Public
4   License (GPL) Version 2, June 1991, available at
5   http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License,
6   the text of which follows:
7
8   "Recipient" has requested a license and Intel Corporation ("Intel")
9   is willing to grant a license for the software entitled
10   InfiniBand(tm) System Software (the "Software") being provided by
11   Intel Corporation.
12
13   The following definitions apply to this License:
14
15   "Licensed Patents" means patent claims licensable by Intel Corporation which
16   are necessarily infringed by the use or sale of the Software alone or when
17   combined with the operating system referred to below.
18
19   "Recipient" means the party to whom Intel delivers this Software.
20   "Licensee" means Recipient and those third parties that receive a license to
21   any operating system available under the GNU Public License version 2.0 or
22   later.
23
24   Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
25
26   The license is provided to Recipient and Recipient's Licensees under the
27   following terms.
28
29   Redistribution and use in source and binary forms of the Software, with or
30   without modification, are permitted provided that the following
31   conditions are met:
32   Redistributions of source code of the Software may retain the above copyright
33   notice, this list of conditions and the following disclaimer.
34
35   Redistributions in binary form of the Software may reproduce the above
36   copyright notice, this list of conditions and the following disclaimer in the
37   documentation and/or other materials provided with the distribution.
38
39   Neither the name of Intel Corporation nor the names of its contributors shall
40   be used to endorse or promote products derived from this Software without
41   specific prior written permission.
42
43   Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
44   royalty-free patent license under Licensed Patents to make, use, sell, offer
45   to sell, import and otherwise transfer the Software, if any, in source code
46   and object code form. This license shall include changes to the Software that
47   are error corrections or other minor changes to the Software that do not add
48   functionality or features when the Software is incorporated in any version of
49   a operating system that has been distributed under the GNU General Public
50   License 2.0 or later.  This patent license shall apply to the combination of
51   the Software and any operating system licensed under the GNU Public License
52   version 2.0 or later if, at the time Intel provides the Software to
53   Recipient, such addition of the Software to the then publicly
54   available versions of such operating system available under the GNU
55   Public License version 2.0 or later (whether in gold, beta or alpha
56   form) causes such combination to be covered by the Licensed
57   Patents. The patent license shall not apply to any other
58   combinations which include the Software. No hardware per se is
59   licensed hereunder.
60
61   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
62   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
64   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS CONTRIBUTORS
65   BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
66   OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
67   OF SUBSTITUTE GOODS OR SERVICES;
68   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
69   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
71   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
72   POSSIBILITY OF SUCH DAMAGE.
73   --------------------------------------------------------------------------*/
74
75 /*
76  * Abstract:
77  *    Implementation of ibtrapgen_t.
78  *
79  * Environment:
80  *    Linux User Mode
81  *
82  * $Revision: 1.1 $
83  */
84
85 #include <complib/cl_qmap.h>
86 #include <complib/cl_debug.h>
87 #include <vendor/osm_vendor_api.h>
88 #include <vendor/osm_vendor_sa_api.h>
89 #include "ibtrapgen.h"
90 #include <opensm/osm_mad_pool.h>
91 #include <opensm/osm_log.h>
92 #include <opensm/osm_helper.h>
93
94 #define GUID_ARRAY_SIZE 64
95
96 /**********************************************************************
97  **********************************************************************/
98 /*
99   This function initializes the main object, the log and the Osm Vendor
100 */
101 ib_api_status_t
102 ibtrapgen_init( IN ibtrapgen_t * const p_ibtrapgen,
103               IN ibtrapgen_opt_t * const p_opt,
104               IN const osm_log_level_t log_flags
105               )
106 {
107   ib_api_status_t status;
108
109   /* just making sure - cleanup the static global obj */
110   cl_memclr( p_ibtrapgen, sizeof( *p_ibtrapgen ) );
111
112   /* construct and init the log */
113   p_ibtrapgen->p_log = (osm_log_t *)cl_malloc(sizeof(osm_log_t));
114   osm_log_construct( p_ibtrapgen->p_log );
115   status = osm_log_init( p_ibtrapgen->p_log, p_opt->force_log_flush,
116                          0x0001, p_opt->log_file );
117   if( status != IB_SUCCESS )
118     return ( status );
119
120   osm_log_set_level( p_ibtrapgen->p_log, log_flags );
121
122   /* finaly can declare we are here ... */
123   osm_log( p_ibtrapgen->p_log, OSM_LOG_FUNCS,
124            "ibtrapgen_init: [\n" );
125
126   /* assign all the opts */
127   p_ibtrapgen->p_opt = p_opt;
128
129   /* initialize the osm vendor service object */
130   p_ibtrapgen->p_vendor = osm_vendor_new( p_ibtrapgen->p_log,
131                                         p_opt->transaction_timeout );
132
133   if( p_ibtrapgen->p_vendor == NULL )
134   {
135     status = IB_INSUFFICIENT_RESOURCES;
136     osm_log( p_ibtrapgen->p_log, OSM_LOG_ERROR,
137              "ibtrapgen_init: ERR 0001: "
138              "Unable to allocate vendor object" );
139     goto Exit;
140   }
141
142   /* all mads (actually wrappers) are taken and returned to a pool */
143   osm_mad_pool_construct( &p_ibtrapgen->mad_pool );
144   status = osm_mad_pool_init(
145     &p_ibtrapgen->mad_pool, p_ibtrapgen->p_log );
146   if( status != IB_SUCCESS )
147     goto Exit;
148
149  Exit:
150   osm_log( p_ibtrapgen->p_log, OSM_LOG_FUNCS,
151            "ibtrapgen_init: ]\n" );
152   return ( status );
153 }
154
155 /****f* opensm: SM/__ibtrapgen_rcv_callback
156  * NAME
157  * __osm_sm_mad_ctrl_rcv_callback
158  *
159  * DESCRIPTION
160  * This is the callback from the transport layer for received MADs.
161  *
162  * SYNOPSIS
163  */
164 void
165 __ibtrapgen_rcv_callback(
166   IN osm_madw_t *p_madw,
167   IN void *bind_context,
168   IN osm_madw_t *p_req_madw )
169 {
170   ibtrapgen_t* p_ibtrapgen = (ibtrapgen_t*)bind_context;
171
172   OSM_LOG_ENTER( p_ibtrapgen->p_log, __ibtrapgen_rcv_callback );
173
174   CL_ASSERT( p_madw );
175
176   osm_log( p_ibtrapgen->p_log, OSM_LOG_VERBOSE,
177            "__ibtrapgen_rcv_callback: Got callback\n",
178            cl_ntoh64(p_madw->p_mad->trans_id) );
179
180   OSM_LOG_EXIT( p_ibtrapgen->p_log );
181 }
182
183 /****f* opensm: SM/__ibtrapgen_send_err_cb
184  * NAME
185  * __ibtrapgen_send_err_cb
186  *
187  * DESCRIPTION
188  * This is the callback from the transport layer for received MADs.
189  *
190  * SYNOPSIS
191  */
192 void
193 __ibtrapgen_send_err_cb(
194   IN void *bind_context,
195   IN osm_madw_t *p_madw )
196 {
197   ibtrapgen_t* p_ibtrapgen = (ibtrapgen_t*)bind_context;
198
199   OSM_LOG_ENTER( p_ibtrapgen->p_log, __ibtrapgen_send_err_callback );
200
201   osm_log( p_ibtrapgen->p_log, OSM_LOG_ERROR,
202            "__ibtrapgen_send_err_cb: ERR 0011: "
203            "MAD completed in error (%s).\n",
204            ib_get_err_str( p_madw->status ) );
205
206   CL_ASSERT( p_madw );
207
208   osm_log( p_ibtrapgen->p_log, OSM_LOG_ERROR,
209            "__ibtrapgen_send_err_cb: ERR 0012: "
210            "We shouldn't be here!! TID:0x%" PRIx64 ".\n",
211            cl_ntoh64(p_madw->p_mad->trans_id) );
212   OSM_LOG_EXIT( p_ibtrapgen->p_log );
213 }
214
215 /**********************************************************************
216  **********************************************************************/
217 ib_api_status_t
218 ibtrapgen_bind( IN ibtrapgen_t * p_ibtrapgen )
219 {
220   ib_api_status_t status;
221   uint32_t num_ports = GUID_ARRAY_SIZE;
222   ib_port_attr_t attr_array[GUID_ARRAY_SIZE];
223   osm_bind_info_t bind_info;
224   uint8_t i;
225
226   OSM_LOG_ENTER( p_ibtrapgen->p_log, ibtrapgen_bind );
227
228   /*
229    * Call the transport layer for a list of local port
230    * GUID values.
231    */
232   status = osm_vendor_get_all_port_attr( p_ibtrapgen->p_vendor,
233                                          attr_array, &num_ports );
234   if ( status != IB_SUCCESS )
235   {
236     osm_log( p_ibtrapgen->p_log, OSM_LOG_ERROR,
237              "ibtrapgen_bind: ERR 0002: "
238              "Failure getting local port attributes (%s)\n",
239              ib_get_err_str( status ) );
240     goto Exit;
241   }
242
243   /* make sure the requested port exists */
244   if ( p_ibtrapgen->p_opt->port_num > num_ports )
245   {
246     osm_log( p_ibtrapgen->p_log, OSM_LOG_ERROR,
247              "ibtrapgen_bind: ERR 0003: "
248              "Given port number out of range %u > %u\n",
249              p_ibtrapgen->p_opt->port_num , num_ports );
250     status = IB_NOT_FOUND;
251     goto Exit;
252   }
253
254   for ( i = 0 ; i < num_ports ; i++ )
255   {
256     osm_log(p_ibtrapgen->p_log, OSM_LOG_DEBUG,
257             "ibtrapgen_bind: Found port number:%u "
258             " with GUID:0x%016"PRIx64"\n",
259             i, cl_ntoh64(attr_array[i].port_guid) );
260   }
261   /* check if the port is active */
262 /*   if (attr_array[p_ibtrapgen->p_opt->port_num - 1].link_state < 4) */
263 /*   { */
264 /*     osm_log( p_ibtrapgen->p_log, OSM_LOG_ERROR, */
265 /*              "ibtrapgen_bind: ERR 0004: " */
266 /*              "Given port number link state is not active: %s.\n", */
267 /*              ib_get_port_state_str( */
268 /*                attr_array[p_ibtrapgen->p_opt->port_num - 1].link_state ) */
269 /*              ); */
270 /*     status = IB_NOT_FOUND; */
271 /*     goto Exit; */
272 /*   } */
273
274   p_ibtrapgen->port_guid = attr_array[p_ibtrapgen->p_opt->port_num - 1].port_guid;
275  /* save sm_lid as we need it when sending the Trap (dest lid)*/
276   p_ibtrapgen->p_opt->sm_lid = attr_array[p_ibtrapgen->p_opt->port_num - 1].sm_lid;
277
278   osm_log(p_ibtrapgen->p_log, OSM_LOG_DEBUG,
279           "ibtrapgen_bind: Port Num:%u "
280           "GUID:0x%016"PRIx64"\n",
281           p_ibtrapgen->p_opt->port_num,
282           p_ibtrapgen->port_guid );
283
284   /* ok finaly bind the sa interface to this port */
285   /* TODO - BIND LIKE THE osm_sm_mad_ctrl does */
286   bind_info.class_version = 1;
287   bind_info.is_report_processor = TRUE;
288   bind_info.is_responder = TRUE;
289   bind_info.is_trap_processor = TRUE;
290   bind_info.mad_class = IB_MCLASS_SUBN_DIR;
291   bind_info.port_guid = p_ibtrapgen->port_guid;
292   bind_info.recv_q_size = OSM_SM_DEFAULT_QP0_RCV_SIZE;
293   bind_info.send_q_size = OSM_SM_DEFAULT_QP0_SEND_SIZE;
294
295   osm_log(p_ibtrapgen->p_log, OSM_LOG_DEBUG,
296           "ibtrapgen_bind: Trying to bind to GUID:0x%016"PRIx64"\n",
297           bind_info.port_guid );
298  
299   p_ibtrapgen->h_bind = osm_vendor_bind( p_ibtrapgen->p_vendor,
300                                     &bind_info,
301                                     &p_ibtrapgen->mad_pool,
302                                     __ibtrapgen_rcv_callback,
303                                     __ibtrapgen_send_err_cb,
304                                     p_ibtrapgen );
305
306   if(  p_ibtrapgen->h_bind == OSM_BIND_INVALID_HANDLE )
307   {
308     osm_log( p_ibtrapgen->p_log, OSM_LOG_ERROR,
309              "ibtrapgen_bind: ERR 0005: "     
310              "Unable to bind to SA\n" );
311     status = IB_ERROR;
312     goto Exit;
313   }
314
315  Exit:
316   OSM_LOG_EXIT( p_ibtrapgen->p_log );
317   return ( status );
318 }
319
320 /**********************************************************************
321  **********************************************************************/
322 void
323 ibtrapgen_destroy( IN ibtrapgen_t * p_ibtrapgen )
324 {
325   if( p_ibtrapgen->p_vendor )
326   {
327     osm_vendor_delete( &p_ibtrapgen->p_vendor );
328   }
329
330   osm_log_destroy( p_ibtrapgen->p_log );
331   cl_free( p_ibtrapgen->p_log );
332 }
333
334 /**********************************************************************
335  **********************************************************************/
336
337 ib_api_status_t
338 ibtrapgen_run( IN ibtrapgen_t * const p_ibtrapgen )
339 {
340   osm_madw_t*    p_report_madw;
341   ib_mad_notice_attr_t*   p_report_ntc;
342   ib_mad_t*               p_mad;
343   ib_smp_t*               p_smp_mad;
344   osm_mad_addr_t          mad_addr;
345   static atomic32_t       trap_fwd_trans_id = 0x02DAB000; 
346   ib_api_status_t         status;
347   osm_log_t *p_log =      p_ibtrapgen->p_log;
348   uint16_t                i;
349
350   OSM_LOG_ENTER( p_log, ibtrapgen_run );
351
352   osm_log( p_log, OSM_LOG_INFO,
353            "ibtrapgen_run: "
354            "Sending trap:%u from LID:0x%X %u times\n",
355            p_ibtrapgen->p_opt->trap_num,
356            p_ibtrapgen->p_opt->lid,
357            p_ibtrapgen->p_opt->number );
358   
359   printf("-V- SM lid is : 0x%04X\n",p_ibtrapgen->p_opt->sm_lid);
360   mad_addr.dest_lid = cl_ntoh16(p_ibtrapgen->p_opt->sm_lid);
361   /* ??? - what is path_bits? What should be the value here?? */
362   mad_addr.path_bits = 0;
363   /* ??? - what is static_rate? What should be the value here?? */
364   mad_addr.static_rate = 0;
365   
366   mad_addr.addr_type.smi.source_lid = cl_hton16(p_ibtrapgen->p_opt->lid);
367   mad_addr.addr_type.smi.port_num = p_ibtrapgen->p_opt->src_port;
368   
369   for (i = 1 ; i <= p_ibtrapgen->p_opt->number ; i++ )
370   {
371     p_report_madw = osm_mad_pool_get( &p_ibtrapgen->mad_pool,
372                                       p_ibtrapgen->h_bind,
373                                       MAD_BLOCK_SIZE,
374                                       &mad_addr );
375     
376     if( !p_report_madw )
377     {
378       osm_log(p_log, OSM_LOG_ERROR,
379               "ibtrapgen_run: ERR 00020: "
380               "osm_mad_pool_get failed.\n" );
381       status = IB_ERROR;
382       goto Exit;
383     }
384                                     
385     p_report_madw->resp_expected = FALSE;
386
387     /* advance trap trans id (cant simply ++ on some systems inside ntoh) */
388     p_mad = osm_madw_get_mad_ptr( p_report_madw );
389     ib_mad_init_new(p_mad,
390                     IB_MCLASS_SUBN_LID,
391                     1,
392                     IB_MAD_METHOD_TRAP,
393                     cl_hton64( (uint64_t)cl_atomic_inc( &trap_fwd_trans_id ) ),
394                     IB_MAD_ATTR_NOTICE,
395                     0);
396     
397     p_smp_mad = osm_madw_get_smp_ptr( p_report_madw );
398     
399     /* The payload is analyzed as mad notice attribute */
400     p_report_ntc = (ib_mad_notice_attr_t*)(ib_smp_get_payload_ptr(p_smp_mad));
401     
402     cl_memclr( p_report_ntc, sizeof(*p_report_ntc) );
403     p_report_ntc->generic_type = 0x83; /* is generic subn mgt type */
404     ib_notice_set_prod_type(p_report_ntc, 2); /* A switch generator */
405     p_report_ntc->g_or_v.generic.trap_num = cl_hton16(p_ibtrapgen->p_opt->trap_num);
406     p_report_ntc->issuer_lid = cl_hton16(p_ibtrapgen->p_opt->lid);
407     if (p_ibtrapgen->p_opt->trap_num == 128)
408     {
409       p_report_ntc->data_details.ntc_128.sw_lid = cl_hton16(p_ibtrapgen->p_opt->lid);
410     }
411     else 
412     {
413       p_report_ntc->data_details.ntc_129_131.lid = 
414         cl_hton16(p_ibtrapgen->p_opt->lid);
415       p_report_ntc->data_details.ntc_129_131.port_num = 
416         p_ibtrapgen->p_opt->src_port;
417     }
418
419     status = osm_vendor_send(p_report_madw->h_bind, p_report_madw, FALSE );
420     if (status != IB_SUCCESS)
421     {
422       osm_log(p_log, OSM_LOG_ERROR,
423               "ibtrapgen_run: ERR 0021: "
424               "osm_vendor_send. status = %s\n",
425               ib_get_err_str(status));
426       goto Exit;
427     }
428     osm_log(p_log, OSM_LOG_INFO,
429             "ibtrapgen_run: "
430             "Sent trap number:%u out of:%u\n",
431             i,
432             p_ibtrapgen->p_opt->number );
433     /* sleep according to rate time. The usleep is in usec - need to revert
434        the milisecs to usecs. */
435     usleep(p_ibtrapgen->p_opt->rate*1000);
436   }
437
438  Exit:
439   //  sleep(3);
440   OSM_LOG_EXIT( p_log );
441   return(status);
442 }