1/*
2 * Copyright (c) 2004-2008 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
61BEGIN_C_DECLS
62
63struct 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*/
97typedef 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	osm_physp_t physp_table[1];
106} osm_node_t;
107/*
108* FIELDS
109*	map_item
110*		Linkage structure for cl_qmap.  MUST BE FIRST MEMBER!
111*
112*	sw
113*		For switch node contains pointer to appropriate osm_switch
114*		structure. NULL for non-switch nodes. Can be used for fast
115*		access to switch object and for simple node type detection
116*
117*	node_info
118*		The IBA defined NodeInfo data for this node.
119*
120*	node_desc
121*		The IBA defined NodeDescription data for this node.
122*
123*	discovery_count
124*		The number of times this node has been discovered
125*		during the current fabric sweep.  This number is reset
126*		to zero at the start of a sweep.
127*
128*	phsyp_tbl_size
129*		The size of the physp_table array.  This value is one greater
130*		than the number of ports in the node, since port numbers
131*		start with 1 for some bizzare reason.
132*
133*	print_desc
134*		A printable version of the node description.
135*
136*	phsyp_table
137*		Array of physical port objects belonging to this node.
138*		Index is contiguous by local port number.
139*		For switches, port 0 is the always the management port (14.2.5.6).
140*		MUST BE LAST MEMBER! - Since it grows !!!!
141*
142* SEE ALSO
143*	Node object
144*********/
145
146/****f* OpenSM: Node/osm_node_delete
147* NAME
148*	osm_node_delete
149*
150* DESCRIPTION
151*	The osm_node_delete function destroys a node, releasing
152*	all resources.
153*
154* SYNOPSIS
155*/
156void osm_node_delete(IN OUT osm_node_t ** const p_node);
157/*
158* PARAMETERS
159*	p_node
160*		[in][out] Pointer to a Pointer a Node object to destroy.
161*		On return, the pointer to set to NULL.
162*
163* RETURN VALUE
164*	This function does not return a value.
165*
166* NOTES
167*	Performs any necessary cleanup of the specified Node object.
168*	This function should only be called after a call to osm_node_new.
169*
170* SEE ALSO
171*	Node object, osm_node_new
172*********/
173
174/****f* OpenSM: Node/osm_node_new
175* NAME
176*	osm_node_new
177*
178* DESCRIPTION
179*	The osm_node_new function initializes a Node object for use.
180*
181* SYNOPSIS
182*/
183osm_node_t *osm_node_new(IN const osm_madw_t * const p_madw);
184/*
185* PARAMETERS
186*	p_madw
187*		[in] Pointer to a osm_madw_t object containing a mad with
188*		the node's NodeInfo attribute.  The caller may discard the
189*		osm_madw_t structure after calling osm_node_new.
190*
191* RETURN VALUES
192*	On success, a pointer to the new initialized osm_node_t structure.
193*	NULL otherwise.
194*
195* NOTES
196*
197* SEE ALSO
198*	Node object
199*********/
200
201/****f* OpenSM: Node/osm_node_get_physp_ptr
202* NAME
203*	osm_node_get_physp_ptr
204*
205* DESCRIPTION
206*	Returns a pointer to the physical port object at the
207*	specified local port number.
208*
209* SYNOPSIS
210*/
211static inline osm_physp_t *osm_node_get_physp_ptr(IN osm_node_t * const p_node,
212						  IN const uint32_t port_num)
213{
214
215	CL_ASSERT(port_num < p_node->physp_tbl_size);
216	return osm_physp_is_valid(&p_node->physp_table[port_num]) ?
217		&p_node->physp_table[port_num] : NULL;
218}
219
220/*
221* PARAMETERS
222*	p_node
223*		[in] Pointer to an osm_node_t object.
224*
225*	port_num
226*		[in] Local port number.
227*
228* RETURN VALUES
229*	Returns a pointer to the physical port object at the
230*	specified local port number.
231*	A return value of zero means the port number was out of range.
232*
233* NOTES
234*
235* SEE ALSO
236*	Node object
237*********/
238
239/****f* OpenSM: Node/osm_node_get_type
240* NAME
241*	osm_node_get_type
242*
243* DESCRIPTION
244*	Returns the type of this node.
245*
246* SYNOPSIS
247*/
248static inline uint8_t osm_node_get_type(IN const osm_node_t * const p_node)
249{
250	return (p_node->node_info.node_type);
251}
252
253/*
254* PARAMETERS
255*	p_node
256*		[in] Pointer to an osm_node_t object.
257*
258* RETURN VALUES
259*	Returns the IBA defined type of this node.
260*
261* NOTES
262*
263* SEE ALSO
264*	Node object
265*********/
266
267/****f* OpenSM: Node/osm_node_get_num_physp
268* NAME
269*	osm_node_get_num_physp
270*
271* DESCRIPTION
272*	Returns the type of this node.
273*
274* SYNOPSIS
275*/
276static inline uint8_t osm_node_get_num_physp(IN const osm_node_t * const p_node)
277{
278	return ((uint8_t) p_node->physp_tbl_size);
279}
280
281/*
282* PARAMETERS
283*	p_node
284*		[in] Pointer to an osm_node_t object.
285*
286* RETURN VALUES
287*	Returns the IBA defined type of this node.
288*
289* NOTES
290*
291* SEE ALSO
292*	Node object
293*********/
294
295/****f* OpenSM: Node/osm_node_get_remote_node
296* NAME
297*	osm_node_get_remote_node
298*
299* DESCRIPTION
300*	Returns a pointer to the node on the other end of the
301*	specified port.
302*	Returns NULL if no remote node exists.
303*
304* SYNOPSIS
305*/
306osm_node_t *osm_node_get_remote_node(IN osm_node_t * const p_node,
307				     IN const uint8_t port_num,
308				     OUT uint8_t * p_remote_port_num);
309/*
310* PARAMETERS
311*	p_node
312*		[in] Pointer to an osm_node_t object.
313*
314*	port_num
315*		[in] Port number in p_node through which to get the remote node.
316*
317*	p_remote_port_num
318*		[out] Port number in the remote's node through which this
319*		link exists.  The caller may specify NULL for this pointer
320*		if the port number isn't needed.
321*
322* RETURN VALUES
323*	Returns a pointer to the node on the other end of the
324*	specified port.
325*	Returns NULL if no remote node exists.
326*
327* NOTES
328*
329* SEE ALSO
330*	Node object
331*********/
332
333/****f* OpenSM: Node/osm_node_get_base_lid
334* NAME
335*	osm_node_get_base_lid
336*
337* DESCRIPTION
338*	Returns the LID value of the specified port on this node.
339*
340* SYNOPSIS
341*/
342static inline ib_net16_t
343osm_node_get_base_lid(IN const osm_node_t * const p_node,
344		      IN const uint32_t port_num)
345{
346	CL_ASSERT(port_num < p_node->physp_tbl_size);
347	return (osm_physp_get_base_lid(&p_node->physp_table[port_num]));
348}
349
350/*
351* PARAMETERS
352*	p_node
353*		[in] Pointer to an osm_node_t object.
354*
355*	port_num
356*		[in] Local port number.
357*
358* RETURN VALUES
359*	Returns a pointer to the physical port object at the
360*	specified local port number.
361*	A return value of zero means the port number was out of range.
362*
363* NOTES
364*
365* SEE ALSO
366*	Node object
367*********/
368
369/****f* OpenSM: Node/osm_node_get_remote_base_lid
370* NAME
371*	osm_node_get_remote_base_lid
372*
373* DESCRIPTION
374*	Returns the base LID value of the port on the other side
375*	of the wire from the specified port on this node.
376*
377* SYNOPSIS
378*/
379ib_net16_t
380osm_node_get_remote_base_lid(IN osm_node_t * const p_node,
381			     IN const uint32_t port_num);
382/*
383* PARAMETERS
384*	p_node
385*		[in] Pointer to an osm_node_t object.
386*
387*	port_num
388*		[in] Local port number.
389*
390* RETURN VALUES
391*	Returns a pointer to the physical port object at the
392*	specified local port number.
393*	A return value of zero means the port number was out of range.
394*
395* NOTES
396*
397* SEE ALSO
398*	Node object
399*********/
400
401/****f* OpenSM: Node/osm_node_get_lmc
402* NAME
403*	osm_node_get_lmc
404*
405* DESCRIPTION
406*	Returns the LMC value of the specified port on this node.
407*
408* SYNOPSIS
409*/
410static inline uint8_t
411osm_node_get_lmc(IN const osm_node_t * const p_node, IN const uint32_t port_num)
412{
413	CL_ASSERT(port_num < p_node->physp_tbl_size);
414	return (osm_physp_get_lmc(&p_node->physp_table[port_num]));
415}
416
417/*
418* PARAMETERS
419*	p_node
420*		[in] Pointer to an osm_node_t object.
421*
422*	port_num
423*		[in] Local port number.
424*
425* RETURN VALUES
426*	Returns the LMC value of the specified port on this node.
427*
428* NOTES
429*
430* SEE ALSO
431*	Node object
432*********/
433
434/****f* OpenSM: Node/osm_node_init_physp
435* NAME
436*	osm_node_init_physp
437*
438* DESCRIPTION
439*	Initializes a physical port for the given node.
440*
441* SYNOPSIS
442*/
443void
444osm_node_init_physp(IN osm_node_t * const p_node,
445		    IN const osm_madw_t * const p_madw);
446/*
447* PARAMETERS
448*	p_node
449*		[in] Pointer to an osm_node_t object.
450*
451*	p_madw
452*		[in] Pointer to a osm_madw_t object containing a mad with
453*		the node's NodeInfo attribute as discovered through the
454*		Physical Port to add to the node.  The caller may discard the
455*		osm_madw_t structure after calling osm_node_new.
456*
457* RETURN VALUES
458*	None.
459*
460* NOTES
461*
462* SEE ALSO
463*	Node object, Physical Port object.
464*********/
465
466/****f* OpenSM: Node/osm_node_get_node_guid
467* NAME
468*	osm_node_get_node_guid
469*
470* DESCRIPTION
471*	Returns the node GUID of this node.
472*
473* SYNOPSIS
474*/
475static inline ib_net64_t
476osm_node_get_node_guid(IN const osm_node_t * const p_node)
477{
478	return (p_node->node_info.node_guid);
479}
480
481/*
482* PARAMETERS
483*	p_node
484*		[in] Pointer to an osm_node_t object.
485*
486* RETURN VALUES
487*	Returns the node GUID of this node.
488*
489* NOTES
490*
491* SEE ALSO
492*	Node object
493*********/
494
495/****f* OpenSM: Node/osm_node_link
496* NAME
497*	osm_node_link
498*
499* DESCRIPTION
500*	Logically connects a node to another node through the specified port.
501*
502* SYNOPSIS
503*/
504void
505osm_node_link(IN osm_node_t * const p_node,
506	      IN const uint8_t port_num,
507	      IN osm_node_t * const p_remote_node,
508	      IN const uint8_t remote_port_num);
509/*
510* PARAMETERS
511*	p_node
512*		[in] Pointer to an osm_node_t object.
513*
514*	port_num
515*		[in] Port number in p_node through which to create the link.
516*
517*	p_remote_node
518*		[in] Pointer to the remote port object.
519*
520*	remote_port_num
521*		[in] Port number in the remote's node through which to
522*		create this link.
523*
524* RETURN VALUES
525*	None.
526*
527* NOTES
528*
529* SEE ALSO
530*	Node object
531*********/
532
533/****f* OpenSM: Node/osm_node_unlink
534* NAME
535*	osm_node_unlink
536*
537* DESCRIPTION
538*	Logically disconnects a node from another node through
539*	the specified port.
540*
541* SYNOPSIS
542*/
543void
544osm_node_unlink(IN osm_node_t * const p_node,
545		IN const uint8_t port_num,
546		IN osm_node_t * const p_remote_node,
547		IN const uint8_t remote_port_num);
548/*
549* PARAMETERS
550*	p_node
551*		[in] Pointer to an osm_node_t object.
552*
553*	port_num
554*		[in] Port number in p_node through which to unlink.
555*
556*	p_remote_node
557*		[in] Pointer to the remote port object.
558*
559*	remote_port_num
560*		[in] Port number in the remote's node through which to unlink.
561*
562* RETURN VALUES
563*	None.
564*
565* NOTES
566*
567* SEE ALSO
568*	Node object
569*********/
570
571/****f* OpenSM: Node/osm_node_link_exists
572* NAME
573*	osm_node_link_exists
574*
575* DESCRIPTION
576*	Return TRUE if a link exists between the specified nodes on
577*	the specified ports.
578*	Returns FALSE otherwise.
579*
580* SYNOPSIS
581*/
582boolean_t
583osm_node_link_exists(IN osm_node_t * const p_node,
584		     IN const uint8_t port_num,
585		     IN osm_node_t * const p_remote_node,
586		     IN const uint8_t remote_port_num);
587/*
588* PARAMETERS
589*	p_node
590*		[in] Pointer to an osm_node_t object.
591*
592*	port_num
593*		[in] Port number in p_node through which to check the link.
594*
595*	p_remote_node
596*		[in] Pointer to the remote port object.
597*
598*	remote_port_num
599*		[in] Port number in the remote's node through which to
600*		check this link.
601*
602* RETURN VALUES
603*	Return TRUE if a link exists between the specified nodes on
604*	the specified ports.
605*	Returns FALSE otherwise.
606*
607* NOTES
608*
609* SEE ALSO
610*	Node object
611*********/
612
613/****f* OpenSM: Node/osm_node_has_any_link
614* NAME
615*	osm_node_has_any_link
616*
617* DESCRIPTION
618*	Return TRUE if a any link exists from the specified nodes on
619*	the specified port.
620*	Returns FALSE otherwise.
621*
622* SYNOPSIS
623*/
624boolean_t
625osm_node_has_any_link(IN osm_node_t * const p_node, IN const uint8_t port_num);
626/*
627* PARAMETERS
628*	p_node
629*		[in] Pointer to an osm_node_t object.
630*
631*	port_num
632*		[in] Port number in p_node through which to check the link.
633*
634* RETURN VALUES
635*	Return TRUE if a any link exists from the specified nodes on
636*	the specified port.
637*	Returns FALSE otherwise.
638*
639* NOTES
640*
641* SEE ALSO
642*	Node object
643*********/
644
645/****f* OpenSM: Node/osm_node_link_has_valid_ports
646* NAME
647*	osm_node_link_has_valid_ports
648*
649* DESCRIPTION
650*	Return TRUE if both ports in the link are valid (initialized).
651*	Returns FALSE otherwise.
652*
653* SYNOPSIS
654*/
655boolean_t
656osm_node_link_has_valid_ports(IN osm_node_t * const p_node,
657			      IN const uint8_t port_num,
658			      IN osm_node_t * const p_remote_node,
659			      IN const uint8_t remote_port_num);
660/*
661* PARAMETERS
662*	p_node
663*		[in] Pointer to an osm_node_t object.
664*
665*	port_num
666*		[in] Port number in p_node through which to check the link.
667*
668* RETURN VALUES
669*	Return TRUE if both ports in the link are valid (initialized).
670*	Returns FALSE otherwise.
671*
672* NOTES
673*
674* SEE ALSO
675*	Node object
676*********/
677
678END_C_DECLS
679#endif				/* _OSM_NODE_H_ */
680