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