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