1 /*
2 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 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 a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 *
34 */
35
36 /*
37 * Abstract:
38 * Declaration of osm_node_t.
39 * This object represents an IBA node.
40 * This object is part of the OpenSM family of objects.
41 */
42
43 #ifndef _OSM_NODE_H_
44 #define _OSM_NODE_H_
45
46 #include <complib/cl_qmap.h>
47 #include <iba/ib_types.h>
48 #include <opensm/osm_base.h>
49 #include <opensm/osm_port.h>
50 #include <opensm/osm_path.h>
51 #include <opensm/osm_madw.h>
52
53 #ifdef __cplusplus
54 # define BEGIN_C_DECLS extern "C" {
55 # define END_C_DECLS }
56 #else /* !__cplusplus */
57 # define BEGIN_C_DECLS
58 # define END_C_DECLS
59 #endif /* __cplusplus */
60
61 BEGIN_C_DECLS
62
63 struct osm_switch;
64
65 /****h* OpenSM/Node
66 * NAME
67 * Node
68 *
69 * DESCRIPTION
70 * The Node object encapsulates the information needed by the
71 * OpenSM to manage nodes. The OpenSM allocates one Node object
72 * per node in the IBA subnet.
73 *
74 * The Node object is not thread safe, thus callers must provide
75 * serialization.
76 *
77 * This object should be treated as opaque and should be
78 * manipulated only through the provided functions.
79 *
80 * AUTHOR
81 * Steve King, Intel
82 *
83 *********/
84
85 /****s* OpenSM: Node/osm_node_t
86 * NAME
87 * osm_node_t
88 *
89 * DESCRIPTION
90 * Node structure.
91 *
92 * This object should be treated as opaque and should
93 * be manipulated only through the provided functions.
94 *
95 * SYNOPSIS
96 */
97 typedef struct osm_node {
98 cl_map_item_t map_item;
99 struct osm_switch *sw;
100 ib_node_info_t node_info;
101 ib_node_desc_t node_desc;
102 uint32_t discovery_count;
103 uint32_t physp_tbl_size;
104 char *print_desc;
105 uint8_t *physp_discovered;
106 osm_physp_t physp_table[1];
107 } osm_node_t;
108 /*
109 * FIELDS
110 * map_item
111 * Linkage structure for cl_qmap. MUST BE FIRST MEMBER!
112 *
113 * sw
114 * For switch node contains pointer to appropriate osm_switch
115 * structure. NULL for non-switch nodes. Can be used for fast
116 * access to switch object and for simple node type detection
117 *
118 * node_info
119 * The IBA defined NodeInfo data for this node.
120 *
121 * node_desc
122 * The IBA defined NodeDescription data for this node.
123 *
124 * discovery_count
125 * The number of times this node has been discovered
126 * during the current fabric sweep. This number is reset
127 * to zero at the start of a sweep.
128 *
129 * physp_tbl_size
130 * The size of the physp_table array. This value is one greater
131 * than the number of ports in the node, since port numbers
132 * start with 1 for some bizarre reason.
133 *
134 * print_desc
135 * A printable version of the node description.
136 *
137 * physp_discovered
138 * Array of physp_discovered objects for all ports of this node.
139 * Each object indiactes whether the port has been discovered
140 * during the sweep or not. 1 means that the port had been discovered.
141 *
142 * physp_table
143 * Array of physical port objects belonging to this node.
144 * Index is contiguous by local port number.
145 * For switches, port 0 is the always the management port (14.2.5.6).
146 * MUST BE LAST MEMBER! - Since it grows !!!!
147 *
148 * SEE ALSO
149 * Node object
150 *********/
151
152 /****f* OpenSM: Node/osm_node_delete
153 * NAME
154 * osm_node_delete
155 *
156 * DESCRIPTION
157 * The osm_node_delete function destroys a node, releasing
158 * all resources.
159 *
160 * SYNOPSIS
161 */
162 void osm_node_delete(IN OUT osm_node_t ** p_node);
163 /*
164 * PARAMETERS
165 * p_node
166 * [in][out] Pointer to a Pointer a Node object to destroy.
167 * On return, the pointer to set to NULL.
168 *
169 * RETURN VALUE
170 * This function does not return a value.
171 *
172 * NOTES
173 * Performs any necessary cleanup of the specified Node object.
174 * This function should only be called after a call to osm_node_new.
175 *
176 * SEE ALSO
177 * Node object, osm_node_new
178 *********/
179
180 /****f* OpenSM: Node/osm_node_new
181 * NAME
182 * osm_node_new
183 *
184 * DESCRIPTION
185 * The osm_node_new function initializes a Node object for use.
186 *
187 * SYNOPSIS
188 */
189 osm_node_t *osm_node_new(IN const osm_madw_t * p_madw);
190 /*
191 * PARAMETERS
192 * p_madw
193 * [in] Pointer to a osm_madw_t object containing a mad with
194 * the node's NodeInfo attribute. The caller may discard the
195 * osm_madw_t structure after calling osm_node_new.
196 *
197 * RETURN VALUES
198 * On success, a pointer to the new initialized osm_node_t structure.
199 * NULL otherwise.
200 *
201 * NOTES
202 *
203 * SEE ALSO
204 * Node object
205 *********/
206
207 /****f* OpenSM: Node/osm_node_get_physp_ptr
208 * NAME
209 * osm_node_get_physp_ptr
210 *
211 * DESCRIPTION
212 * Returns a pointer to the physical port object at the
213 * specified local port number.
214 *
215 * SYNOPSIS
216 */
osm_node_get_physp_ptr(IN osm_node_t * p_node,IN uint32_t port_num)217 static inline osm_physp_t *osm_node_get_physp_ptr(IN osm_node_t * p_node,
218 IN uint32_t port_num)
219 {
220
221 CL_ASSERT(port_num < p_node->physp_tbl_size);
222 return osm_physp_is_valid(&p_node->physp_table[port_num]) ?
223 &p_node->physp_table[port_num] : NULL;
224 }
225
226 /*
227 * PARAMETERS
228 * p_node
229 * [in] Pointer to an osm_node_t object.
230 *
231 * port_num
232 * [in] Local port number.
233 *
234 * RETURN VALUES
235 * Returns a pointer to the physical port object at the
236 * specified local port number.
237 * A return value of zero means the port number was out of range.
238 *
239 * NOTES
240 *
241 * SEE ALSO
242 * Node object
243 *********/
244
245 /****f* OpenSM: Node/osm_node_get_type
246 * NAME
247 * osm_node_get_type
248 *
249 * DESCRIPTION
250 * Returns the type of this node.
251 *
252 * SYNOPSIS
253 */
osm_node_get_type(IN const osm_node_t * p_node)254 static inline uint8_t osm_node_get_type(IN const osm_node_t * p_node)
255 {
256 return p_node->node_info.node_type;
257 }
258
259 /*
260 * PARAMETERS
261 * p_node
262 * [in] Pointer to an osm_node_t object.
263 *
264 * RETURN VALUES
265 * Returns the IBA defined type of this node.
266 *
267 * NOTES
268 *
269 * SEE ALSO
270 * Node object
271 *********/
272
273 /****f* OpenSM: Node/osm_node_get_num_physp
274 * NAME
275 * osm_node_get_num_physp
276 *
277 * DESCRIPTION
278 * Returns the number of osm_physp ports allocated for this node.
279 * For switches, it is the number of external physical ports plus
280 * port 0. For CAs and routers, it is the number of external physical
281 * ports plus 1.
282 *
283 * SYNOPSIS
284 */
osm_node_get_num_physp(IN const osm_node_t * p_node)285 static inline uint8_t osm_node_get_num_physp(IN const osm_node_t * p_node)
286 {
287 return (uint8_t) p_node->physp_tbl_size;
288 }
289
290 /*
291 * PARAMETERS
292 * p_node
293 * [in] Pointer to an osm_node_t object.
294 *
295 * RETURN VALUES
296 * Returns the IBA defined type of this node.
297 *
298 * NOTES
299 *
300 * SEE ALSO
301 * Node object
302 *********/
303
304 /****f* OpenSM: Node/osm_node_get_remote_node
305 * NAME
306 * osm_node_get_remote_node
307 *
308 * DESCRIPTION
309 * Returns a pointer to the node on the other end of the
310 * specified port.
311 * Returns NULL if no remote node exists.
312 *
313 * SYNOPSIS
314 */
315 osm_node_t *osm_node_get_remote_node(IN osm_node_t * p_node,
316 IN uint8_t port_num,
317 OUT uint8_t * p_remote_port_num);
318 /*
319 * PARAMETERS
320 * p_node
321 * [in] Pointer to an osm_node_t object.
322 *
323 * port_num
324 * [in] Port number in p_node through which to get the remote node.
325 *
326 * p_remote_port_num
327 * [out] Port number in the remote's node through which this
328 * link exists. The caller may specify NULL for this pointer
329 * if the port number isn't needed.
330 *
331 * RETURN VALUES
332 * Returns a pointer to the node on the other end of the
333 * specified port.
334 * Returns NULL if no remote node exists.
335 *
336 * NOTES
337 *
338 * SEE ALSO
339 * Node object
340 *********/
341
342 /****f* OpenSM: Node/osm_node_get_base_lid
343 * NAME
344 * osm_node_get_base_lid
345 *
346 * DESCRIPTION
347 * Returns the LID value of the specified port on this node.
348 *
349 * SYNOPSIS
350 */
osm_node_get_base_lid(IN const osm_node_t * p_node,IN uint32_t port_num)351 static inline ib_net16_t osm_node_get_base_lid(IN const osm_node_t * p_node,
352 IN uint32_t port_num)
353 {
354 CL_ASSERT(port_num < p_node->physp_tbl_size);
355 return osm_physp_get_base_lid(&p_node->physp_table[port_num]);
356 }
357
358 /*
359 * PARAMETERS
360 * p_node
361 * [in] Pointer to an osm_node_t object.
362 *
363 * port_num
364 * [in] Local port number.
365 *
366 * RETURN VALUES
367 * Returns a pointer to the physical port object at the
368 * specified local port number.
369 * A return value of zero means the port number was out of range.
370 *
371 * NOTES
372 *
373 * SEE ALSO
374 * Node object
375 *********/
376
377 /****f* OpenSM: Node/osm_node_get_remote_base_lid
378 * NAME
379 * osm_node_get_remote_base_lid
380 *
381 * DESCRIPTION
382 * Returns the base LID value of the port on the other side
383 * of the wire from the specified port on this node.
384 *
385 * SYNOPSIS
386 */
387 ib_net16_t osm_node_get_remote_base_lid(IN osm_node_t * p_node,
388 IN uint32_t port_num);
389 /*
390 * PARAMETERS
391 * p_node
392 * [in] Pointer to an osm_node_t object.
393 *
394 * port_num
395 * [in] Local port number.
396 *
397 * RETURN VALUES
398 * Returns a pointer to the physical port object at the
399 * specified local port number.
400 * A return value of zero means the port number was out of range.
401 *
402 * NOTES
403 *
404 * SEE ALSO
405 * Node object
406 *********/
407
408 /****f* OpenSM: Node/osm_node_get_lmc
409 * NAME
410 * osm_node_get_lmc
411 *
412 * DESCRIPTION
413 * Returns the LMC value of the specified port on this node.
414 *
415 * SYNOPSIS
416 */
osm_node_get_lmc(IN const osm_node_t * p_node,IN uint32_t port_num)417 static inline uint8_t osm_node_get_lmc(IN const osm_node_t * p_node,
418 IN uint32_t port_num)
419 {
420 CL_ASSERT(port_num < p_node->physp_tbl_size);
421 return osm_physp_get_lmc(&p_node->physp_table[port_num]);
422 }
423
424 /*
425 * PARAMETERS
426 * p_node
427 * [in] Pointer to an osm_node_t object.
428 *
429 * port_num
430 * [in] Local port number.
431 *
432 * RETURN VALUES
433 * Returns the LMC value of the specified port on this node.
434 *
435 * NOTES
436 *
437 * SEE ALSO
438 * Node object
439 *********/
440
441 /****f* OpenSM: Node/osm_node_init_physp
442 * NAME
443 * osm_node_init_physp
444 *
445 * DESCRIPTION
446 * Initializes a physical port for the given node.
447 *
448 * SYNOPSIS
449 */
450 void osm_node_init_physp(IN osm_node_t * p_node, uint8_t port_num,
451 IN const osm_madw_t * p_madw);
452 /*
453 * PARAMETERS
454 * p_node
455 * [in] Pointer to an osm_node_t object.
456 *
457 * p_madw
458 * [in] Pointer to a osm_madw_t object containing a mad with
459 * the node's NodeInfo attribute as discovered through the
460 * Physical Port to add to the node. The caller may discard the
461 * osm_madw_t structure after calling osm_node_new.
462 *
463 * RETURN VALUES
464 * None.
465 *
466 * NOTES
467 *
468 * SEE ALSO
469 * Node object, Physical Port object.
470 *********/
471
472 /****f* OpenSM: Node/osm_node_get_node_guid
473 * NAME
474 * osm_node_get_node_guid
475 *
476 * DESCRIPTION
477 * Returns the node GUID of this node.
478 *
479 * SYNOPSIS
480 */
osm_node_get_node_guid(IN const osm_node_t * p_node)481 static inline ib_net64_t osm_node_get_node_guid(IN const osm_node_t * p_node)
482 {
483 return p_node->node_info.node_guid;
484 }
485
486 /*
487 * PARAMETERS
488 * p_node
489 * [in] Pointer to an osm_node_t object.
490 *
491 * RETURN VALUES
492 * Returns the node GUID of this node.
493 *
494 * NOTES
495 *
496 * SEE ALSO
497 * Node object
498 *********/
499
500 /****f* OpenSM: Node/osm_node_link
501 * NAME
502 * osm_node_link
503 *
504 * DESCRIPTION
505 * Logically connects a node to another node through the specified port.
506 *
507 * SYNOPSIS
508 */
509 void osm_node_link(IN osm_node_t * p_node, IN uint8_t port_num,
510 IN osm_node_t * p_remote_node, IN uint8_t remote_port_num);
511 /*
512 * PARAMETERS
513 * p_node
514 * [in] Pointer to an osm_node_t object.
515 *
516 * port_num
517 * [in] Port number in p_node through which to create the link.
518 *
519 * p_remote_node
520 * [in] Pointer to the remote port object.
521 *
522 * remote_port_num
523 * [in] Port number in the remote's node through which to
524 * create this link.
525 *
526 * RETURN VALUES
527 * None.
528 *
529 * NOTES
530 *
531 * SEE ALSO
532 * Node object
533 *********/
534
535 /****f* OpenSM: Node/osm_node_unlink
536 * NAME
537 * osm_node_unlink
538 *
539 * DESCRIPTION
540 * Logically disconnects a node from another node through
541 * the specified port.
542 *
543 * SYNOPSIS
544 */
545 void osm_node_unlink(IN osm_node_t * p_node, IN uint8_t port_num,
546 IN osm_node_t * p_remote_node, IN uint8_t remote_port_num);
547 /*
548 * PARAMETERS
549 * p_node
550 * [in] Pointer to an osm_node_t object.
551 *
552 * port_num
553 * [in] Port number in p_node through which to unlink.
554 *
555 * p_remote_node
556 * [in] Pointer to the remote port object.
557 *
558 * remote_port_num
559 * [in] Port number in the remote's node through which to unlink.
560 *
561 * RETURN VALUES
562 * None.
563 *
564 * NOTES
565 *
566 * SEE ALSO
567 * Node object
568 *********/
569
570 /****f* OpenSM: Node/osm_node_link_exists
571 * NAME
572 * osm_node_link_exists
573 *
574 * DESCRIPTION
575 * Return TRUE if a link exists between the specified nodes on
576 * the specified ports.
577 * Returns FALSE otherwise.
578 *
579 * SYNOPSIS
580 */
581 boolean_t osm_node_link_exists(IN osm_node_t * p_node, IN uint8_t port_num,
582 IN osm_node_t * p_remote_node,
583 IN uint8_t remote_port_num);
584 /*
585 * PARAMETERS
586 * p_node
587 * [in] Pointer to an osm_node_t object.
588 *
589 * port_num
590 * [in] Port number in p_node through which to check the link.
591 *
592 * p_remote_node
593 * [in] Pointer to the remote port object.
594 *
595 * remote_port_num
596 * [in] Port number in the remote's node through which to
597 * check this link.
598 *
599 * RETURN VALUES
600 * Return TRUE if a link exists between the specified nodes on
601 * the specified ports.
602 * Returns FALSE otherwise.
603 *
604 * NOTES
605 *
606 * SEE ALSO
607 * Node object
608 *********/
609
610 /****f* OpenSM: Node/osm_node_has_any_link
611 * NAME
612 * osm_node_has_any_link
613 *
614 * DESCRIPTION
615 * Return TRUE if a any link exists from the specified nodes on
616 * the specified port.
617 * Returns FALSE otherwise.
618 *
619 * SYNOPSIS
620 */
621 boolean_t osm_node_has_any_link(IN osm_node_t * p_node, IN uint8_t port_num);
622 /*
623 * PARAMETERS
624 * p_node
625 * [in] Pointer to an osm_node_t object.
626 *
627 * port_num
628 * [in] Port number in p_node through which to check the link.
629 *
630 * RETURN VALUES
631 * Return TRUE if a any link exists from the specified nodes on
632 * the specified port.
633 * Returns FALSE otherwise.
634 *
635 * NOTES
636 *
637 * SEE ALSO
638 * Node object
639 *********/
640
641 /****f* OpenSM: Node/osm_node_link_has_valid_ports
642 * NAME
643 * osm_node_link_has_valid_ports
644 *
645 * DESCRIPTION
646 * Return TRUE if both ports in the link are valid (initialized).
647 * Returns FALSE otherwise.
648 *
649 * SYNOPSIS
650 */
651 boolean_t osm_node_link_has_valid_ports(IN osm_node_t * p_node,
652 IN uint8_t port_num,
653 IN osm_node_t * p_remote_node,
654 IN uint8_t remote_port_num);
655 /*
656 * PARAMETERS
657 * p_node
658 * [in] Pointer to an osm_node_t object.
659 *
660 * port_num
661 * [in] Port number in p_node through which to check the link.
662 *
663 * RETURN VALUES
664 * Return TRUE if both ports in the link are valid (initialized).
665 * Returns FALSE otherwise.
666 *
667 * NOTES
668 *
669 * SEE ALSO
670 * Node object
671 *********/
672
673 END_C_DECLS
674 #endif /* _OSM_NODE_H_ */
675