xref: /trueos/contrib/ofed/management/opensm/include/opensm/osm_switch.h (revision 8fe640108653f13042f1b15213769e338aa524f6)
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 
62 BEGIN_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 */
94 typedef 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 */
170 struct 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 */
198 void 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 */
222 osm_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 */
251 static inline uint8_t
osm_switch_get_hop_count(IN const osm_switch_t * const p_sw,IN const uint16_t lid_ho,IN const uint8_t port_num)252 osm_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 */
286 cl_status_t
287 osm_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 */
321 void 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 */
342 static inline uint8_t
osm_switch_get_least_hops(IN const osm_switch_t * const p_sw,IN const uint16_t lid_ho)343 osm_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 */
377 uint8_t
378 osm_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 */
408 static inline uint8_t
osm_switch_get_port_by_lid(IN const osm_switch_t * const p_sw,IN const uint16_t lid_ho)409 osm_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 */
442 osm_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 */
osm_switch_get_route_by_lid(IN const osm_switch_t * const p_sw,IN const ib_net16_t lid)473 static 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 */
525 static inline unsigned
osm_switch_sp0_is_lmc_capable(IN const osm_switch_t * const p_sw,IN osm_subn_t * p_subn)526 osm_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 */
560 static inline uint16_t
osm_switch_get_max_block_id_in_use(IN const osm_switch_t * const p_sw)561 osm_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 */
588 boolean_t
589 osm_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 */
623 static inline boolean_t
osm_switch_supports_mcast(IN const osm_switch_t * const p_sw)624 osm_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 */
651 static inline void
osm_switch_set_switch_info(IN osm_switch_t * const p_sw,IN const ib_switch_info_t * const p_si)652 osm_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 */
684 static inline void
osm_switch_count_path(IN osm_switch_t * const p_sw,IN const uint8_t port)685 osm_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 */
715 static inline ib_api_status_t
osm_switch_set_lft_block(IN osm_switch_t * const p_sw,IN const uint8_t * const p_block,IN const uint32_t block_num)716 osm_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 */
758 static inline ib_api_status_t
osm_switch_set_mft_block(IN osm_switch_t * const p_sw,IN const ib_net16_t * const p_block,IN const uint16_t block_num,IN const uint8_t position)759 osm_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 */
798 static inline boolean_t
osm_switch_get_mft_block(IN osm_switch_t * const p_sw,IN const uint16_t block_num,IN const uint8_t position,OUT ib_net16_t * const p_block)799 osm_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 */
841 static inline uint16_t
osm_switch_get_mft_max_block(IN osm_switch_t * const p_sw)842 osm_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 */
864 static inline int16_t
osm_switch_get_mft_max_block_in_use(IN osm_switch_t * const p_sw)865 osm_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 */
893 static inline uint8_t
osm_switch_get_mft_max_position(IN osm_switch_t * const p_sw)894 osm_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 */
920 uint8_t
921 osm_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 */
968 uint8_t
969 osm_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 */
1008 static inline uint16_t
osm_switch_get_mcast_fwd_tbl_size(IN const osm_switch_t * const p_sw)1009 osm_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 */
1035 static inline uint32_t
osm_switch_path_count_get(IN const osm_switch_t * const p_sw,IN const uint8_t port_num)1036 osm_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 */
1066 int
1067 osm_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 */
osm_switch_get_mcast_tbl_ptr(IN const osm_switch_t * const p_sw)1093 static 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 */
1122 static inline boolean_t
osm_switch_is_in_mcast_tree(IN const osm_switch_t * const p_sw,IN const uint16_t mlid_ho)1123 osm_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 
1151 END_C_DECLS
1152 #endif				/* _OSM_SWITCH_H_ */
1153