osm_switch.h revision 219820
1/*
2 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2008 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_switch_t.
39 *	This object represents an IBA switch.
40 *	This object is part of the OpenSM family of objects.
41 */
42
43#ifndef _OSM_SWITCH_H_
44#define _OSM_SWITCH_H_
45
46#include <iba/ib_types.h>
47#include <opensm/osm_base.h>
48#include <opensm/osm_madw.h>
49#include <opensm/osm_node.h>
50#include <opensm/osm_port.h>
51#include <opensm/osm_mcast_tbl.h>
52#include <opensm/osm_port_profile.h>
53
54#ifdef __cplusplus
55#  define BEGIN_C_DECLS extern "C" {
56#  define END_C_DECLS   }
57#else				/* !__cplusplus */
58#  define BEGIN_C_DECLS
59#  define END_C_DECLS
60#endif				/* __cplusplus */
61
62BEGIN_C_DECLS
63/****h* OpenSM/Switch
64* NAME
65*	Switch
66*
67* DESCRIPTION
68*	The Switch object encapsulates the information needed by the
69*	OpenSM to manage switches.  The OpenSM allocates one switch object
70*	per switch in the IBA subnet.
71*
72*	The Switch object is not thread safe, thus callers must provide
73*	serialization.
74*
75*	This object should be treated as opaque and should be
76*	manipulated only through the provided functions.
77*
78* AUTHOR
79*	Steve King, Intel
80*
81*********/
82/****s* OpenSM: Switch/osm_switch_t
83* NAME
84*	osm_switch_t
85*
86* DESCRIPTION
87*	Switch structure.
88*
89*	This object should be treated as opaque and should
90*	be manipulated only through the provided functions.
91*
92* SYNOPSIS
93*/
94typedef struct osm_switch {
95	cl_map_item_t map_item;
96	osm_node_t *p_node;
97	ib_switch_info_t switch_info;
98	uint16_t max_lid_ho;
99	uint8_t num_ports;
100	uint16_t num_hops;
101	uint8_t **hops;
102	osm_port_profile_t *p_prof;
103	uint8_t *lft;
104	uint8_t *new_lft;
105	osm_mcast_tbl_t mcast_tbl;
106	uint32_t discovery_count;
107	unsigned need_update;
108	void *priv;
109} osm_switch_t;
110/*
111* FIELDS
112*	map_item
113*		Linkage structure for cl_qmap.  MUST BE FIRST MEMBER!
114*
115*	p_node
116*		Pointer to the Node object for this switch.
117*
118*	switch_info
119*		IBA defined SwitchInfo structure for this switch.
120*
121*	max_lid_ho
122*		Max LID that is accessible from this switch.
123*
124*	num_ports
125*		Number of ports for this switch.
126*
127*	num_hops
128*		Size of hops table for this switch.
129*
130*	hops
131*		LID Matrix for this switch containing the hop count
132*		to every LID from every port.
133*
134*	p_prof
135*		Pointer to array of Port Profile objects for this switch.
136*
137*	lft
138*		This switch's linear forwarding table.
139*
140*	new_lft
141*		This switch's linear forwarding table, as was
142*		calculated by the last routing engine execution.
143*
144*	mcast_tbl
145*		Multicast forwarding table for this switch.
146*
147*	discovery_count
148*		The number of times this switch has been discovered
149*		during the current fabric sweep.  This number is reset
150*		to zero at the start of a sweep.
151*
152*	need_update
153*		When set indicates that switch was probably reset, so
154*		fwd tables and rest cached data should be flushed
155*
156* SEE ALSO
157*	Switch object
158*********/
159
160/****s* OpenSM: Switch/struct osm_remote_guids_count
161* NAME
162*	struct osm_remote_guids_count
163*
164* DESCRIPTION
165*	Stores array of pointers to remote node and the numbers of
166*	times a switch has forwarded to it.
167*
168* SYNOPSIS
169*/
170struct osm_remote_guids_count {
171	unsigned count;
172	struct osm_remote_node {
173		osm_node_t *node;
174		unsigned forwarded_to;
175	} guids[0];
176};
177/*
178* FIELDS
179*	count
180*		A number of used entries in array.
181*
182*	node
183*		A pointer to node.
184*
185*	forwarded_to
186*		A count of lids forwarded to this node.
187*********/
188
189/****f* OpenSM: Switch/osm_switch_delete
190* NAME
191*	osm_switch_delete
192*
193* DESCRIPTION
194*	Destroys and deallocates the object.
195*
196* SYNOPSIS
197*/
198void osm_switch_delete(IN OUT osm_switch_t ** const pp_sw);
199/*
200* PARAMETERS
201*	p_sw
202*		[in] Pointer to the object to destroy.
203*
204* RETURN VALUE
205*	None.
206*
207* NOTES
208*
209* SEE ALSO
210*	Switch object, osm_switch_new
211*********/
212
213/****f* OpenSM: Switch/osm_switch_new
214* NAME
215*	osm_switch_new
216*
217* DESCRIPTION
218*	The osm_switch_new function initializes a Switch object for use.
219*
220* SYNOPSIS
221*/
222osm_switch_t *osm_switch_new(IN osm_node_t * const p_node,
223			     IN const osm_madw_t * const p_madw);
224/*
225* PARAMETERS
226*	p_node
227*		[in] Pointer to the node object of this switch
228*
229*	p_madw
230*		[in] Pointer to the MAD Wrapper containing the switch's
231*		SwitchInfo attribute.
232*
233* RETURN VALUES
234*	Pointer to the new initialized switch object.
235*
236* NOTES
237*
238* SEE ALSO
239*	Switch object, osm_switch_delete
240*********/
241
242/****f* OpenSM: Switch/osm_switch_get_hop_count
243* NAME
244*	osm_switch_get_hop_count
245*
246* DESCRIPTION
247*	Returns the hop count at the specified LID/Port intersection.
248*
249* SYNOPSIS
250*/
251static inline uint8_t
252osm_switch_get_hop_count(IN const osm_switch_t * const p_sw,
253			 IN const uint16_t lid_ho, IN const uint8_t port_num)
254{
255	return (lid_ho > p_sw->max_lid_ho || !p_sw->hops[lid_ho]) ?
256	    OSM_NO_PATH : p_sw->hops[lid_ho][port_num];
257}
258/*
259* PARAMETERS
260*	p_sw
261*		[in] Pointer to a Switch object.
262*
263*	lid_ho
264*		[in] LID value (host order) for which to return the hop count
265*
266*	port_num
267*		[in] Port number in the switch
268*
269* RETURN VALUES
270*	Returns the hop count at the specified LID/Port intersection.
271*
272* NOTES
273*
274* SEE ALSO
275*********/
276
277/****f* OpenSM: Switch/osm_switch_set_hops
278* NAME
279*	osm_switch_set_hops
280*
281* DESCRIPTION
282*	Sets the hop count at the specified LID/Port intersection.
283*
284* SYNOPSIS
285*/
286cl_status_t
287osm_switch_set_hops(IN osm_switch_t * const p_sw,
288		    IN const uint16_t lid_ho,
289		    IN const uint8_t port_num, IN const uint8_t num_hops);
290/*
291* PARAMETERS
292*	p_sw
293*		[in] Pointer to a Switch object.
294*
295*	lid_ho
296*		[in] LID value (host order) for which to set the count.
297*
298*	port_num
299*		[in] port number for which to set the count.
300*
301*	num_hops
302*		[in] value to assign to this entry.
303*
304* RETURN VALUES
305*	Returns the hop count at the specified LID/Port intersection.
306*
307* NOTES
308*
309* SEE ALSO
310*********/
311
312/****f* OpenSM: Switch/osm_switch_clear_hops
313* NAME
314*	osm_switch_clear_hops
315*
316* DESCRIPTION
317*	Cleanup existing hops tables (lid matrix)
318*
319* SYNOPSIS
320*/
321void osm_switch_clear_hops(IN osm_switch_t * p_sw);
322/*
323* PARAMETERS
324*	p_sw
325*		[in] Pointer to a Switch object.
326*
327* NOTES
328*
329* SEE ALSO
330*********/
331
332/****f* OpenSM: Switch/osm_switch_get_least_hops
333* NAME
334*	osm_switch_get_least_hops
335*
336* DESCRIPTION
337*	Returns the number of hops in the short path to this lid from
338*	any port on the switch.
339*
340* SYNOPSIS
341*/
342static inline uint8_t
343osm_switch_get_least_hops(IN const osm_switch_t * const p_sw,
344			  IN const uint16_t lid_ho)
345{
346	return (lid_ho > p_sw->max_lid_ho || !p_sw->hops[lid_ho]) ?
347	    OSM_NO_PATH : p_sw->hops[lid_ho][0];
348}
349/*
350* PARAMETERS
351*	p_sw
352*		[in] Pointer to an osm_switch_t object.
353*
354*	lid_ho
355*		[in] LID (host order) for which to retrieve the shortest hop count.
356*
357* RETURN VALUES
358*	Returns the number of hops in the short path to this lid from
359*	any port on the switch.
360*
361* NOTES
362*
363* SEE ALSO
364*	Switch object
365*********/
366
367/****f* OpenSM: Switch/osm_switch_get_port_least_hops
368* NAME
369*	osm_switch_get_port_least_hops
370*
371* DESCRIPTION
372*	Returns the number of hops in the short path to this port from
373*	any port on the switch.
374*
375* SYNOPSIS
376*/
377uint8_t
378osm_switch_get_port_least_hops(IN const osm_switch_t * const p_sw,
379			       IN const osm_port_t * p_port);
380/*
381* PARAMETERS
382*	p_sw
383*		[in] Pointer to an osm_switch_t object.
384*
385*	p_port
386*		[in] Pointer to an osm_port_t object for which to
387*		retrieve the shortest hop count.
388*
389* RETURN VALUES
390*	Returns the number of hops in the short path to this lid from
391*	any port on the switch.
392*
393* NOTES
394*
395* SEE ALSO
396*	Switch object
397*********/
398
399/****f* OpenSM: Switch/osm_switch_get_port_by_lid
400* NAME
401*	osm_switch_get_port_by_lid
402*
403* DESCRIPTION
404*	Returns the switch port number on which the specified LID is routed.
405*
406* SYNOPSIS
407*/
408static inline uint8_t
409osm_switch_get_port_by_lid(IN const osm_switch_t * const p_sw,
410			   IN const uint16_t lid_ho)
411{
412	if (lid_ho == 0 || lid_ho > IB_LID_UCAST_END_HO)
413		return OSM_NO_PATH;
414	return p_sw->lft[lid_ho];
415}
416/*
417* PARAMETERS
418*	p_sw
419*		[in] Pointer to an osm_switch_t object.
420*
421*	lid_ho
422*		[in] LID (host order) for which to retrieve the shortest hop count.
423*
424* RETURN VALUES
425*	Returns the switch port on which the specified LID is routed.
426*
427* NOTES
428*
429* SEE ALSO
430*	Switch object
431*********/
432
433/****f* OpenSM: Switch/osm_switch_get_physp_ptr
434* NAME
435*	osm_switch_get_physp_ptr
436*
437* DESCRIPTION
438*	Gets the Physical Port Object at the specified port number.
439*
440* SYNOPSIS
441*/
442osm_physp_t *osm_switch_get_physp_ptr(IN const osm_switch_t * const p_sw,
443				      IN const uint32_t port_num);
444/*
445* PARAMETERS
446*	p_sw
447*		[in] Pointer to an osm_switch_t object.
448*
449*	port_num
450*		[in] Port number for which to retrieve the Physical Port Object.
451*
452* RETURN VALUES
453*	Returns a pointer to the Physical Port Object object at the specified
454*	port number.
455*	A return value of zero means the port number was out of range.
456*
457*
458* NOTES
459*
460* SEE ALSO
461*	Switch object
462*********/
463
464/****f* OpenSM: Switch/osm_switch_get_route_by_lid
465* NAME
466*	osm_switch_get_route_by_lid
467*
468* DESCRIPTION
469*	Gets the physical port object that routes the specified LID.
470*
471* SYNOPSIS
472*/
473static inline osm_physp_t *osm_switch_get_route_by_lid(IN const osm_switch_t *
474						       const p_sw,
475						       IN const ib_net16_t lid)
476{
477	uint8_t port_num;
478
479	CL_ASSERT(p_sw);
480	CL_ASSERT(lid);
481
482	port_num = osm_switch_get_port_by_lid(p_sw, cl_ntoh16(lid));
483
484	/*
485	   In order to avoid holes in the subnet (usually happens when
486	   running UPDN algorithm), i.e. cases where port is
487	   unreachable through a switch (we put an OSM_NO_PATH value at
488	   the port entry, we do not assert on unreachable lid entries
489	   at the fwd table but return NULL
490	 */
491	if (port_num != OSM_NO_PATH)
492		return (osm_node_get_physp_ptr(p_sw->p_node, port_num));
493	else
494		return NULL;
495}
496/*
497* PARAMETERS
498*	p_sw
499*		[in] Pointer to an osm_switch_t object.
500*
501*	lid
502*		[in] LID for which to find a route.  This must be a unicast
503*		LID value < 0xC000.
504*
505* RETURN VALUES
506*	Returns a pointer to the Physical Port Object object that
507*	routes the specified LID.  A return value of zero means
508*	there is no route for the lid through this switch.
509*	The lid value must be a unicast LID.
510*
511* NOTES
512*
513* SEE ALSO
514*	Switch object
515*********/
516
517/****f* OpenSM: Switch/osm_switch_sp0_is_lmc_capable
518* NAME
519*	osm_switch_sp0_is_lmc_capable
520*
521* DESCRIPTION
522*	Returns whether switch port 0 (SP0) can support LMC
523*
524*/
525static inline unsigned
526osm_switch_sp0_is_lmc_capable(IN const osm_switch_t * const p_sw,
527			      IN osm_subn_t * p_subn)
528{
529	return (p_subn->opt.lmc_esp0 &&
530		ib_switch_info_is_enhanced_port0(&p_sw->switch_info)) ? 1 : 0;
531}
532/*
533* PARAMETERS
534*	p_sw
535*		[in] Pointer to an osm_switch_t object.
536*
537*	p_subn
538*		[in] Pointer to an osm_subn_t object.
539*
540* RETURN VALUES
541*	TRUE if SP0 is enhanced and globally enabled. FALSE otherwise.
542*
543* NOTES
544*	This is workaround function, it takes into account user defined
545*	p_subn->opt.lmc_esp0 parameter.
546*
547* SEE ALSO
548*********/
549
550/****f* OpenSM: Switch/osm_switch_get_max_block_id_in_use
551* NAME
552*	osm_switch_get_max_block_id_in_use
553*
554* DESCRIPTION
555*	Returns the maximum block ID (host order) of this switch that
556*	is used for unicast routing.
557*
558* SYNOPSIS
559*/
560static inline uint16_t
561osm_switch_get_max_block_id_in_use(IN const osm_switch_t * const p_sw)
562{
563	return cl_ntoh16(p_sw->switch_info.lin_top) / IB_SMP_DATA_SIZE;
564}
565/*
566* PARAMETERS
567*	p_sw
568*		[in] Pointer to an osm_switch_t object.
569*
570* RETURN VALUES
571*	Returns the maximum block ID (host order) of this switch.
572*
573* NOTES
574*
575* SEE ALSO
576*	Switch object
577*********/
578
579/****f* OpenSM: Switch/osm_switch_get_lft_block
580* NAME
581*	osm_switch_get_lft_block
582*
583* DESCRIPTION
584*	Retrieve a linear forwarding table block.
585*
586* SYNOPSIS
587*/
588boolean_t
589osm_switch_get_lft_block(IN const osm_switch_t * const p_sw,
590			 IN const uint16_t block_id,
591			 OUT uint8_t * const p_block);
592/*
593* PARAMETERS
594*	p_sw
595*		[in] Pointer to an osm_switch_t object.
596*
597*	block_ID
598*		[in] The block_id to retrieve.
599*
600*	p_block
601*		[out] Pointer to the 64 byte array to store the
602*		forwarding table clock specified by block_id.
603*
604* RETURN VALUES
605*	Returns true if there are more blocks necessary to
606*	configure all the LIDs reachable from this switch.
607*	FALSE otherwise.
608*
609* NOTES
610*
611* SEE ALSO
612*********/
613
614/****f* OpenSM: Switch/osm_switch_supports_mcast
615* NAME
616*	osm_switch_supports_mcast
617*
618* DESCRIPTION
619*	Indicates if a switch supports multicast.
620*
621* SYNOPSIS
622*/
623static inline boolean_t
624osm_switch_supports_mcast(IN const osm_switch_t * const p_sw)
625{
626	return (p_sw->switch_info.mcast_cap != 0);
627}
628/*
629* PARAMETERS
630*	p_sw
631*		[in] Pointer to an osm_switch_t object.
632*
633* RETURN VALUES
634*	Returns TRUE if the switch supports multicast.
635*	FALSE otherwise.
636*
637* NOTES
638*
639* SEE ALSO
640*********/
641
642/****f* OpenSM: Switch/osm_switch_set_switch_info
643* NAME
644*	osm_switch_set_switch_info
645*
646* DESCRIPTION
647*	Updates the switch info attribute of this switch.
648*
649* SYNOPSIS
650*/
651static inline void
652osm_switch_set_switch_info(IN osm_switch_t * const p_sw,
653			   IN const ib_switch_info_t * const p_si)
654{
655	CL_ASSERT(p_sw);
656	CL_ASSERT(p_si);
657	p_sw->switch_info = *p_si;
658}
659/*
660* PARAMETERS
661*	p_sw
662*		[in] Pointer to a Switch object.
663*
664*	p_si
665*		[in] Pointer to the SwitchInfo attribute for this switch.
666*
667* RETURN VALUES
668*	None.
669*
670* NOTES
671*
672* SEE ALSO
673*********/
674
675/****f* OpenSM: Switch/osm_switch_count_path
676* NAME
677*	osm_switch_count_path
678*
679* DESCRIPTION
680*	Counts this path in port profile.
681*
682* SYNOPSIS
683*/
684static inline void
685osm_switch_count_path(IN osm_switch_t * const p_sw, IN const uint8_t port)
686{
687	osm_port_prof_path_count_inc(&p_sw->p_prof[port]);
688}
689/*
690* PARAMETERS
691*	p_sw
692*		[in] Pointer to the switch object.
693*
694*	port
695*		[in] Port to count path.
696*
697* RETURN VALUE
698*	None.
699*
700* NOTES
701*
702* SEE ALSO
703*********/
704
705/****f* OpenSM: Switch/osm_switch_set_lft_block
706* NAME
707*	osm_switch_set_lft_block
708*
709* DESCRIPTION
710*	Copies in the specified block into
711*	the switch's Linear Forwarding Table.
712*
713* SYNOPSIS
714*/
715static inline ib_api_status_t
716osm_switch_set_lft_block(IN osm_switch_t * const p_sw,
717			 IN const uint8_t * const p_block,
718			 IN const uint32_t block_num)
719{
720	uint16_t lid_start =
721		(uint16_t) (block_num * IB_SMP_DATA_SIZE);
722	CL_ASSERT(p_sw);
723
724	if (lid_start + IB_SMP_DATA_SIZE > IB_LID_UCAST_END_HO)
725		return IB_INVALID_PARAMETER;
726
727	memcpy(&p_sw->lft[lid_start], p_block, IB_SMP_DATA_SIZE);
728	return IB_SUCCESS;
729}
730/*
731* PARAMETERS
732*	p_sw
733*		[in] Pointer to the switch object.
734*
735*	p_block
736*		[in] Pointer to the forwarding table block.
737*
738*	block_num
739*		[in] Block number for this block
740*
741* RETURN VALUE
742*	None.
743*
744* NOTES
745*
746* SEE ALSO
747*********/
748
749/****f* OpenSM: Switch/osm_switch_set_mft_block
750* NAME
751*	osm_switch_set_mft_block
752*
753* DESCRIPTION
754*	Sets a block of multicast port masks into the multicast table.
755*
756* SYNOPSIS
757*/
758static inline ib_api_status_t
759osm_switch_set_mft_block(IN osm_switch_t * const p_sw,
760			 IN const ib_net16_t * const p_block,
761			 IN const uint16_t block_num, IN const uint8_t position)
762{
763	CL_ASSERT(p_sw);
764	return (osm_mcast_tbl_set_block(&p_sw->mcast_tbl, p_block,
765					block_num, position));
766}
767/*
768* PARAMETERS
769*	p_sw
770*		[in] Pointer to the switch object.
771*
772*	p_block
773*		[in] Pointer to the block of port masks to set.
774*
775*	block_num
776*		[in] Block number (0-511) to set.
777*
778*	position
779*		[in] Port mask position (0-15) to set.
780*
781* RETURN VALUE
782*	IB_SUCCESS on success.
783*
784* NOTES
785*
786* SEE ALSO
787*********/
788
789/****f* OpenSM: Switch/osm_switch_get_mft_block
790* NAME
791*	osm_switch_get_mft_block
792*
793* DESCRIPTION
794*	Retrieve a block of multicast port masks from the multicast table.
795*
796* SYNOPSIS
797*/
798static inline boolean_t
799osm_switch_get_mft_block(IN osm_switch_t * const p_sw,
800			 IN const uint16_t block_num,
801			 IN const uint8_t position,
802			 OUT ib_net16_t * const p_block)
803{
804	CL_ASSERT(p_sw);
805	return (osm_mcast_tbl_get_block(&p_sw->mcast_tbl,
806					block_num, position, p_block));
807}
808/*
809* PARAMETERS
810*	p_sw
811*		[in] Pointer to the switch object.
812*
813*	block_num
814*		[in] Block number (0-511) to set.
815*
816*	position
817*		[in] Port mask position (0-15) to set.
818*
819*	p_block
820*		[out] Pointer to the block of port masks stored.
821*
822* RETURN VALUES
823*	Returns true if there are more blocks necessary to
824*	configure all the MLIDs reachable from this switch.
825*	FALSE otherwise.
826*
827* NOTES
828*
829* SEE ALSO
830*********/
831
832/****f* OpenSM: Switch/osm_switch_get_mft_max_block
833* NAME
834*	osm_switch_get_mft_max_block
835*
836* DESCRIPTION
837*       Get the max_block from the associated multicast table.
838*
839* SYNOPSIS
840*/
841static inline uint16_t
842osm_switch_get_mft_max_block(IN osm_switch_t * const p_sw)
843{
844	CL_ASSERT(p_sw);
845	return (osm_mcast_tbl_get_max_block(&p_sw->mcast_tbl));
846}
847/*
848* PARAMETERS
849*	p_sw
850*		[in] Pointer to the switch object.
851*
852* RETURN VALUE
853*/
854
855/****f* OpenSM: Switch/osm_switch_get_mft_max_block_in_use
856* NAME
857*	osm_switch_get_mft_max_block_in_use
858*
859* DESCRIPTION
860*	Get the max_block_in_use from the associated multicast table.
861*
862* SYNOPSIS
863*/
864static inline int16_t
865osm_switch_get_mft_max_block_in_use(IN osm_switch_t * const p_sw)
866{
867	CL_ASSERT(p_sw);
868	return (osm_mcast_tbl_get_max_block_in_use(&p_sw->mcast_tbl));
869}
870/*
871* PARAMETERS
872*	p_sw
873*		[in] Pointer to the switch object.
874*
875* RETURN VALUES
876*	Returns the maximum block ID in use in this switch's mcast table.
877*	A value of -1 indicates no blocks are in use.
878*
879* NOTES
880*
881* SEE ALSO
882*/
883
884/****f* OpenSM: Switch/osm_switch_get_mft_max_position
885* NAME
886*	osm_switch_get_mft_max_position
887*
888* DESCRIPTION
889*       Get the max_position from the associated multicast table.
890*
891* SYNOPSIS
892*/
893static inline uint8_t
894osm_switch_get_mft_max_position(IN osm_switch_t * const p_sw)
895{
896	CL_ASSERT(p_sw);
897	return (osm_mcast_tbl_get_max_position(&p_sw->mcast_tbl));
898}
899/*
900* PARAMETERS
901*	p_sw
902*		[in] Pointer to the switch object.
903*
904* RETURN VALUE
905*/
906
907/****f* OpenSM: Switch/osm_switch_recommend_path
908* NAME
909*	osm_switch_recommend_path
910*
911* DESCRIPTION
912*	Returns the recommended port on which to route this LID.
913*	In cases where LMC > 0, the remote side system and node
914*	used for the routing are tracked in the provided arrays
915*	(and counts) such that other lid for the same port will
916*	try and avoid going through the same remote system/node.
917*
918* SYNOPSIS
919*/
920uint8_t
921osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
922			  IN osm_port_t * p_port,
923			  IN const uint16_t lid_ho,
924			  IN unsigned start_from,
925			  IN const boolean_t ignore_existing,
926			  IN const boolean_t dor);
927/*
928* PARAMETERS
929*	p_sw
930*		[in] Pointer to the switch object.
931*
932*	p_port
933*		[in] Pointer to the port object for which to get a path
934*		advisory.
935*
936*	lid_ho
937*		[in] LID value (host order) for which to get a path advisory.
938*
939*	start_from
940*		[in] Port number from where to start balance counting.
941*
942*	ignore_existing
943*		[in] Set to cause the switch to choose the optimal route
944*		regardless of existing paths.
945*		If false, the switch will choose an existing route if one
946*		exists, otherwise will choose the optimal route.
947*
948*	dor
949*		[in] If TRUE, Dimension Order Routing will be done.
950*
951* RETURN VALUE
952*	Returns the recommended port on which to route this LID.
953*
954* NOTES
955*
956* SEE ALSO
957*********/
958
959/****f* OpenSM: Switch/osm_switch_recommend_mcast_path
960* NAME
961*	osm_switch_recommend_mcast_path
962*
963* DESCRIPTION
964*	Returns the recommended port on which to route this LID.
965*
966* SYNOPSIS
967*/
968uint8_t
969osm_switch_recommend_mcast_path(IN osm_switch_t * const p_sw,
970				IN osm_port_t * p_port,
971				IN const uint16_t mlid_ho,
972				IN const boolean_t ignore_existing);
973/*
974* PARAMETERS
975*	p_sw
976*		[in] Pointer to the switch object.
977*
978*	p_port
979*		[in] Pointer to the port object for which to get
980*		the multicast path.
981*
982*	mlid_ho
983*		[in] MLID for the multicast group in question.
984*
985*	ignore_existing
986*		[in] Set to cause the switch to choose the optimal route
987*		regardless of existing paths.
988*		If false, the switch will choose an existing route if one exists,
989*		otherwise will choose the optimal route.
990*
991* RETURN VALUE
992*	Returns the recommended port on which to route this LID.
993*
994* NOTES
995*
996* SEE ALSO
997*********/
998
999/****f* OpenSM: Switch/osm_switch_get_mcast_fwd_tbl_size
1000* NAME
1001*	osm_switch_get_mcast_fwd_tbl_size
1002*
1003* DESCRIPTION
1004*	Returns the number of entries available in the multicast forwarding table.
1005*
1006* SYNOPSIS
1007*/
1008static inline uint16_t
1009osm_switch_get_mcast_fwd_tbl_size(IN const osm_switch_t * const p_sw)
1010{
1011	return (cl_ntoh16(p_sw->switch_info.mcast_cap));
1012}
1013/*
1014* PARAMETERS
1015*	p_sw
1016*		[in] Pointer to the switch.
1017*
1018* RETURN VALUE
1019*	Returns the number of entries available in the multicast forwarding table.
1020*
1021* NOTES
1022*
1023* SEE ALSO
1024*********/
1025
1026/****f* OpenSM: Switch/osm_switch_path_count_get
1027* NAME
1028*	osm_switch_path_count_get
1029*
1030* DESCRIPTION
1031*	Returns the count of the number of paths going through this port.
1032*
1033* SYNOPSIS
1034*/
1035static inline uint32_t
1036osm_switch_path_count_get(IN const osm_switch_t * const p_sw,
1037			  IN const uint8_t port_num)
1038{
1039	return (osm_port_prof_path_count_get(&p_sw->p_prof[port_num]));
1040}
1041/*
1042* PARAMETERS
1043*	p_sw
1044*		[in] Pointer to the Switch object.
1045*
1046*	port_num
1047*		[in] Port number for which to get path count.
1048*
1049* RETURN VALUE
1050*	Returns the count of the number of paths going through this port.
1051*
1052* NOTES
1053*
1054* SEE ALSO
1055*********/
1056
1057/****f* OpenSM: Switch/osm_switch_prepare_path_rebuild
1058* NAME
1059*	osm_switch_prepare_path_rebuild
1060*
1061* DESCRIPTION
1062*	Prepares a switch to rebuild pathing information.
1063*
1064* SYNOPSIS
1065*/
1066int
1067osm_switch_prepare_path_rebuild(IN osm_switch_t * p_sw, IN uint16_t max_lids);
1068/*
1069* PARAMETERS
1070*	p_sw
1071*		[in] Pointer to the Switch object.
1072*
1073*	max_lids
1074*		[in] Max number of lids in the subnet.
1075*
1076* RETURN VALUE
1077*	Returns zero on success, or negative value if an error occurred.
1078*
1079* NOTES
1080*
1081* SEE ALSO
1082*********/
1083
1084/****f* OpenSM: Switch/osm_switch_get_mcast_tbl_ptr
1085* NAME
1086*	osm_switch_get_mcast_tbl_ptr
1087*
1088* DESCRIPTION
1089*	Returns a pointer to the switch's multicast table.
1090*
1091* SYNOPSIS
1092*/
1093static inline osm_mcast_tbl_t *osm_switch_get_mcast_tbl_ptr(IN const
1094							    osm_switch_t *
1095							    const p_sw)
1096{
1097	return ((osm_mcast_tbl_t *) & p_sw->mcast_tbl);
1098}
1099/*
1100* PARAMETERS
1101*	p_sw
1102*		[in] Pointer to the switch.
1103*
1104* RETURN VALUE
1105*	Returns a pointer to the switch's multicast table.
1106*
1107* NOTES
1108*
1109* SEE ALSO
1110*********/
1111
1112/****f* OpenSM: Switch/osm_switch_is_in_mcast_tree
1113* NAME
1114*	osm_switch_is_in_mcast_tree
1115*
1116* DESCRIPTION
1117*	Returns true if this switch already belongs in the tree for the specified
1118*	multicast group.
1119*
1120* SYNOPSIS
1121*/
1122static inline boolean_t
1123osm_switch_is_in_mcast_tree(IN const osm_switch_t * const p_sw,
1124			    IN const uint16_t mlid_ho)
1125{
1126	const osm_mcast_tbl_t *p_tbl;
1127
1128	p_tbl = &p_sw->mcast_tbl;
1129	if (p_tbl)
1130		return (osm_mcast_tbl_is_any_port(&p_sw->mcast_tbl, mlid_ho));
1131	else
1132		return (FALSE);
1133}
1134/*
1135* PARAMETERS
1136*	p_sw
1137*		[in] Pointer to the switch.
1138*
1139*	mlid_ho
1140*		[in] MLID (host order) of the multicast tree to check.
1141*
1142* RETURN VALUE
1143*	Returns true if this switch already belongs in the tree for the specified
1144*	multicast group.
1145*
1146* NOTES
1147*
1148* SEE ALSO
1149*********/
1150
1151END_C_DECLS
1152#endif				/* _OSM_SWITCH_H_ */
1153