/* BEGIN_ICS_COPYRIGHT7 **************************************** Copyright (c) 2015-2017, Intel Corporation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** END_ICS_COPYRIGHT7 ****************************************/ /* [ICS VERSION STRING: unknown] */ #ifndef _TOPOLOGY_H #define _TOPOLOGY_H #include #include #if !defined(VXWORKS) || defined(BUILD_DMC) #include #endif #include #include #include #include #include #include #include #include #include #include #if !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif #include #ifdef __cplusplus extern "C" { #endif #define CL_TIME_DIVISOR 1000000 struct ExpectedLink_s; struct ExpectedNode_s; struct ExpectedSM_s; struct NodeData_s; struct SystemData_s; struct omgt_port; // Selection indicies for SCVL* tables typedef enum { Enum_SCVLt, Enum_SCVLnt, Enum_SCVLr } ScvlEnum_t; // selection of PortState for FindPortStatePoint, includes all of IB_PORT_STATE // plus these additional special searches #define PORT_STATE_SEARCH_NOTACTIVE (IB_PORT_STATE_MAX+1) // != active #define PORT_STATE_SEARCH_INITARMED (IB_PORT_STATE_MAX+2) // init or armed typedef struct PortMaskSC2SCMap_s { LIST_ITEM SC2SCMapListEntry; // QOSData.SC2SCMapList STL_PORTMASK outports[STL_MAX_PORTMASK]; // egress ports for this map STL_SCSCMAP *SC2SCMap; } PortMaskSC2SCMap; #define SC2SCMAPLIST_MAX 1 // QOS information for a Port in the fabric typedef struct QOSData_s { union { STL_VLARB_TABLE VLArbTable[4]; // One table per type, low, high, preempt, preempt matrix } u; QUICK_LIST SC2SCMapList[SC2SCMAPLIST_MAX]; // PortMaskSC2SCMap STL_SLSCMAP *SL2SCMap; // only defined for HFI and SW port 0 STL_SCSLMAP *SC2SLMap; // only defined for HFI and SW port 0 STL_SCVLMAP SC2VLMaps[3]; // VL_t, _nt, and _r; indicies given by ScvlEnum_t } QOSData; // How many STL_CABLE_INFO structs to store per port #define PORTDATA_CABLEINFO_SIZE 4 #define IFACE_MACLIST_SIZE 512 // information about an IB Port in the fabric // for switches a GUID and LID are only available for Port 0 of the switch // for all other switch ports, LID is port 0 LID (LID for whole switch) // and port GUID is NA and hence 0. typedef struct PortData_s { cl_map_item_t NodePortsEntry; // NodeData.Ports, key is PortNum cl_map_item_t AllLidsEntry; // g_AllLids, key is LID (if GUID non-zero) LIST_ITEM AllPortsEntry; // g_AllPorts EUI64 PortGUID; // 0 for all but port 0 of a switch struct PortData_s *neighbor; // adjacent port this is cabled to struct NodeData_s *nodep; // parent node uint8 PortNum; // port number within Node uint8 from:1; // is this the from port in link record // (avoids double reporting of links) uint8 PmaGotClassPortInfo:1; // have issued a ClassPortInfo uint8 spare:6; uint32 rate; // Active rate for this port STL_LID EndPortLID; // LID to get to device with this port STL_PORT_INFO PortInfo; // do not use LocalPortNum,use PortNum above STL_LINKDOWN_REASON LinkDownReasons[STL_NUM_LINKDOWN_REASONS]; STL_LED_INFO LedInfo; //Led Info for this port IB_PATH_RECORD *pathp; // Path Record to send to this port STL_PORT_COUNTERS_DATA *pPortCounters; struct ExpectedLink_s *elinkp; // if supplied in topology input QOSData *pQOS; // optional QOS STL_PKEY_ELEMENT *pPartitionTable; // optional Partition Table union { struct { uint32 downlinkBasePaths; uint32 uplinkBasePaths; uint32 downlinkAllPaths; uint32 uplinkAllPaths; } fatTreeRoutes; // for TabulateRoutes of fattree struct { uint32 recvBasePaths; uint32 xmitBasePaths; uint32 recvAllPaths; uint32 xmitAllPaths; } routes; // for TabulateRoutes of any topology } analysisData; // per port holding space for transient analysis data STL_BUFFER_CONTROL_TABLE *pBufCtrlTable; // 128 table entries allocate when needed STL_HFI_CONGESTION_CONTROL_TABLE_ENTRY *pCongestionControlTableEntries; uint16_t CCTI_Limit; // CableInfo is organized in 128-byte pages but is stored in // 64-byte half-pages // We only store STL_CIB_STD_HIGH_PAGE_ADDR to STL_CIB_STD_END_ADDR with // STL_CIB_STD_HIGH_PAGE_ADDR stored starting at pCableInfoData[0] uint8_t *pCableInfoData; void *context; // application specific field } PortData; // additional information about cable for a link, from topology input // we limit sizes to make output formatting easier #define CABLE_LENGTH_STRLEN 10 #define CABLE_LABEL_STRLEN 57 #define CABLE_DETAILS_STRLEN 64 typedef struct CableData_s { char *length; // user specified length char *label; // user label on cable char *details; // user description of cable } CableData; typedef struct ExpectedNode_s ExpectedNode; #define PORT_DETAILS_STRLEN 64 // port selector from topology input typedef struct PortSelector_s { EUI64 PortGUID; // 0 if not specified EUI64 NodeGUID; // 0 if not specified uint8 PortNum; // 0-255 are valid port numbers uint8 gotPortNum; // 0 if PortNum not specified uint8 NodeType; // 0 if not specified char *NodeDesc; // NULL if not specified char *details; // user description of port ExpectedNode *enodep; // associated ExpectedNode, set by // TopologyValidate if match is found } PortSelector; #define LINK_DETAILS_STRLEN 64 // additional information about a link, from topology input typedef struct ExpectedLink_s { LIST_ITEM ExpectedLinksEntry; // g_ExpectedLinks PortSelector *portselp1; // input selector PortSelector *portselp2; // input selector PortData *portp1; // NULL if not found PortData *portp2; // NULL if not found // the 4 fields below could become bit fields to save space if necessary // MTU=4 bits, rate=6 bits, internal=1 bit, matchLevel = 3 bits uint8 expected_rate; // Expected Active rate for this link, IB_STATIC_RATE enum uint8 expected_mtu; // Expected Active MTU for this link, an IB_MTU enum uint8 internal; // Is link an internal link uint8 matchLevel; // degree of match with portp1 and 2, higher is better // used internally when matching ports to links to pick best // matches char *details; // user description of link CableData CableData; // user supplied info about cable uint64 lineno; // line number in XML of starting tag, for error messages } ExpectedLink; /* * Limited port information possibly produced originally from * full PortData. */ typedef struct ExpectedPort_s { uint8 PortNum; STL_LID lid; uint8 lmc; EUI64 PortGuid; ExpectedLink *elinkp; } ExpectedPort; #define NODE_DETAILS_STRLEN 64 // additional information about a node, from topology input struct ExpectedNode_s { LIST_ITEM ExpectedNodesEntry; // g_ExpectedFIs, g_ExpectedSWs cl_map_item_t ExpectedNodeGuidMapEntry; // key is NodeGuid struct NodeData_s *nodep; // NULL if not found EUI64 NodeGUID; // 0 if not specified EUI64 SystemImageGUID; // 0 if not specified uint8 NodeType; // 0 if not specified char *NodeDesc; // NULL if not specified char *details; // user description of node uint8 portsSize; ExpectedPort **ports; uint8 connected; //internally used to validate node is reachable, set by TopologyValidate void *context; // application specific field uint64 lineno; // line number in XML of starting tag, for error messages }; #define SM_DETAILS_STRLEN 64 // additional information about a SM, from topology input typedef struct ExpectedSM_s { LIST_ITEM ExpectedSMsEntry; // g_ExpectedSMs struct SMData_s *smp; // NULL if not found EUI64 PortGUID; // 0 if not specified EUI64 NodeGUID; // 0 if not specified uint8 PortNum; // 0-255 are valid port numbers uint8 gotPortNum; // 0 if PortNum not specified uint8 NodeType; // 0 if not specified char *NodeDesc; // NULL if not specified char *details; // user description of SM } ExpectedSM; #if !defined(VXWORKS) || defined(BUILD_DMC) struct IouData_s; typedef struct IocData_s { LIST_ITEM IouIocsEntry; // IouData.Iocs, sorted by IOC slot # cl_map_item_t AllIOCsEntry; // g_AllIOCs, key is IOC GUID IOC_PROFILE IocProfile; uint8 IocSlot; struct IouData_s *ioup; // parent IOU IOC_SERVICE *Services; // IO Services indexed by service num void *context; // application specific field } IocData; typedef struct IouData_s { LIST_ITEM AllIOUsEntry; // g_AllIOUs struct NodeData_s *nodep; // parent node IOUnitInfo IouInfo; QUICK_LIST Iocs; // Iocs, IocData sorted by IOC slot # void *context; // application specific field } IouData; #endif // detailed information specific to an IB Switch in the fabric typedef struct SwitchData_s { /** Lower upper-bound on number of entries allocated. Should be set to LinearFDBTop + 1. Should be set to 0 when LinearFDBTop is invalid. Prefer LinearFDBTop & LinearFDBCap from NodeData when available. */ uint32 LinearFDBSize; STL_LINEAR_FORWARDING_TABLE *LinearFDB; /** Lower upper-bound on number of entries allocated. Should be set to MulticastFDBTop + 1. Should be set to 0 when MulticastFDBTop is invalid. Users are responsible for knowing where the multicast address space starts. Prefer MulticastFDBTop & MulticastFDBCap from NodeData when available. */ uint32 MulticastFDBSize; STL_PORTMASK *MulticastFDB[STL_NUM_MFT_POSITIONS_MASK]; uint8 HasBeenVisited; //indicates 0: no; 1: yes when searching for MC routes /** Lower upper-bound on number of entries allocated. Should be set to PortGroupTop + 1. Should be set to 0 when PortGroupTop is invalid. Prefer PortGroupTop & PortGroupCap from NodeData when available. */ uint16 PortGroupSize; STL_PORTMASK* PortGroupElements; uint32 PortGroupFDBSize; STL_PORT_GROUP_FORWARDING_TABLE *PortGroupFDB; } SwitchData; /* Information about a Node in the fabric. The SA reports a NodeRecord per port, we coallese all nodes with the same GUID into a single structure. As such the Port specific fields in the NodeInfo (PortGUID and LocalPortNumber) are zeroed and should not be used. @c NodeInfo.(Base|Class)Version should have the same values as the data that was used to create this record. */ typedef struct NodeData_s { cl_map_item_t AllNodesEntry; // g_AllNodes, key is NodeGuid cl_map_item_t SystemNodesEntry; // SystemData.Nodes, key is NodeGuid LIST_ITEM AllTypesEntry; // g_AllFIs, g_AllSWs struct SystemData_s *systemp; // parent system STL_NODE_INFO NodeInfo; // port specific fields are 0 STL_NODE_DESCRIPTION NodeDesc; cl_qmap_t Ports; // items are PortData, key is PortNum #if !defined(VXWORKS) || defined(BUILD_DMC) IouData *ioup; // optional IOU #endif STL_SWITCHINFO_RECORD *pSwitchInfo; // optional SwitchInfo // also holds LID for accessing switch // for devices without vendor specific // capabilities, extra fields and capability // mask is zeroed SwitchData *switchp; // optional Switch specific data struct ExpectedNode_s *enodep; // if supplied in topology input void *context; // application specific field uint8 PmaAvoid:1; // node PMA has instability uint8 PmaAvoidClassPortInfo:1; // node has instability in ClassPortInfo uint8 PmaValidateRedirectQP:1; // validate QP in response uint8 analysis:5; // for TabulateRoutes, tier in fabric STL_CONGESTION_INFO CongestionInfo; /* CCA CongestionSetting */ union { STL_SWITCH_CONGESTION_SETTING Switch; STL_HFI_CONGESTION_SETTING Hfi; } CongestionSetting; union { STL_SWITCH_CONGESTION_LOG Switch; STL_HFI_CONGESTION_LOG Hfi; } CongestionLog; uint8_t coreSwitch; // (fabric_sim) fat tree non-edge switch uint8_t visited; // (opasnapconfig) has this node been visited uint8_t valid; // (opasnapconfig) whether node exists in proper location from snapshot uint8_t path[64]; // (opasnapconfig) path we traversed to get to this node } NodeData; typedef uint8 MCROUTESTATUS; #define MAXMCROUTESTATUS 5 // 5 different status for MC routes #define MC_NO_TRACE 0x00 #define MC_NOT_FOUND 0x01 #define MC_UNAVAILABLE 0x02 #define MC_LOOP 0x03 #define MC_NOGROUP 0x04 typedef struct McGroupData_s { // entry to AllMcGroups // holds info of McGroup Members as well as switches that // belong to the group LIST_ITEM AllMcGMembersEntry; QUICK_LIST AllMcGroupMembers; //datatype: McMemberData int NumOfMembers; STL_LID MLID; IB_GID MGID; IB_MCMEMBER_RECORD GroupInfo; //Fields corresponding to individual members should not be used QUICK_LIST EdgeSwitchesInGroup;//datatype:McHFISwitchData } McGroupData; typedef struct McEdgeSwitchData_s { // entry in McGroupData LIST_ITEM McEdgeSwitchEntry; uint8 EntryPort; PortData *pPort; uint64 NodeGUID; } McEdgeSwitchData; typedef struct McMemberData_s { // entry in McGroupData LIST_ITEM McMembersEntry; // Do not use 16-bit MemberInfo.MLID; use 32-bit MLID of containing McGroupData IB_MCMEMBER_RECORD MemberInfo; PortData *pPort; } McMemberData; typedef struct McNodeLoopInc_s { LIST_ITEM McNodeEntry; PortData *pPort; uint16 entryPort; uint16 exitPort; } McNodeLoopInc; typedef struct McLoopInc_s { QUICK_LIST AllMcNodeLoopIncR; //datatype: McNodeLoopInc LIST_ITEM LoopIncEntry; MCROUTESTATUS status; STL_LID mlid; } McLoopInc; typedef struct McRouteStatus_s { QUICK_LIST AllMcRouteStatus; MCROUTESTATUS status; } McRouteStatus; typedef struct clConnPathData_s { IB_PATH_RECORD path; } clConnPathData_t; typedef struct clConnData_s { LIST_ITEM AllConnectionEntry; uint64 FromDeviceGUID; // GUID of the HFI, TFI, switch uint8 FromPortNum; uint64 ToDeviceGUID; // GUID of the HFI, TFI, switch uint8 ToPortNum; uint32 Rate; // active rate for this port STL_VL VL; clConnPathData_t PathInfo; } clConnData_t; #define CREDIT_LOOP_DEVICE_MAX_CONNECTIONS 66 #define DIJKSTRA_INFINITY 0xffff typedef struct clDeviceData_s { cl_map_item_t AllDevicesEntry; // key is NodeGuid LIST_ITEM AllDeviceTypesEntry; STL_LID Lid; NodeData *nodep; clConnData_t *Connections[CREDIT_LOOP_DEVICE_MAX_CONNECTIONS][STL_MAX_SCS]; // 36 port switch + 1 for port zero cl_qmap_t map_dlid_to_route; } clDeviceData_t; typedef struct clRouteData_s { cl_map_item_t AllRoutesEntry; // key is DLID PortData *portp; } clRouteData_t; typedef struct clVertixData_s { cl_map_item_t AllVerticesEntry; // key is connection memory address clConnData_t *Connection; uint32 Id; uint32 RefCount; uint32 OutboundCount; uint32 OutboundInuseCount; uint32 OutboundLength; int *Outbound; uint32 InboundCount; uint32 InboundInuseCount; uint32 InboundLength; int *Inbound; } clVertixData_t; typedef struct clArcData_s { cl_map_item_t AllArcsEntry; // key is combination of source & sink ids cl_map_item_t AllArcIdsEntry; // key is arc list id uint32 Id; uint32 Source; uint32 Sink; union { uint64 AsReg64; struct { uint32 Source; uint32 Sink; } s; } u1; } clArcData_t; typedef struct clGraphData_s { uint32 NumVertices; uint32 NumActiveVertices; uint32 VerticesLength; clVertixData_t **Vertices; uint32 NumArcs; //QUICK_LIST Arcs; cl_qmap_t Arcs; cl_qmap_t map_arc_key_to_arc; QUICK_LIST map_conn_to_vertex; cl_qmap_t map_conn_to_vertex_conn; } clGraphData_t; typedef struct clVertixDataDistance_s { cl_map_item_t AllVerticesEntry; // key is Vertix Id clVertixData_t *vertixp; } clVertixDataDistance_t; typedef struct clDijkstraDistancesAndRoutes_s { uint32 **distances; uint32 **routes; uint32 nRows; uint32 nCols; } clDijkstraDistancesAndRoutes_t; /** * Get start of an entry in MulticastFDB. Should use bits MLID[13:0]. * @c pos is the portmask position; each position is 64 bits (ports) wide. */ static inline STL_PORTMASK *GetMulticastFDBEntry(NodeData *nodep, uint32 entry, uint8 pos) { if (! nodep->switchp || !nodep->switchp->MulticastFDB[pos]) return NULL; return (&nodep->switchp->MulticastFDB[pos][entry]); } // information about an IB enabled system in the fabric // Each system is a set of nodes with the same SystemImageGUID // Some 3rd party devices report a SystemImageGUID of 0, in which case // the node GUID (which should still be unique among systems with // SystemImageGUIDs of 0) is used as the key for g_AllSystems typedef struct SystemData_s { cl_map_item_t AllSystemsEntry; // g_AllSystems, key is SystemImageGUID EUI64 SystemImageGUID; cl_qmap_t Nodes; // items are NodeData, key is NodeGuid void *context; // application specific field } SystemData; typedef struct SMData_s { cl_map_item_t AllSMsEntry; // g_AllSMs, key is PortGUID in SMInfo STL_SMINFO_RECORD SMInfoRecord; // also holds LID for accessing SM struct PortData_s *portp; // port SM is running on ExpectedSM *esmp; // if supplied in topology input void *context; // application specific field } SMData; typedef struct MasterSMData_s { uint64 serviceID; // Service ID of QLogic master SM (else 0) uint32 capabilityMask; // Capability mask of QLogic master SM uint8 version; // SM Version } MasterSMData_t; typedef struct { LIST_ITEM AllVFsEntry; STL_VFINFO_RECORD record; } VFData_t; typedef enum { FF_NONE =0, FF_STATS =0x000000001, // PortCounters fetched // flags for topology_input which was provided FF_EXPECTED_NODES =0x000000002, // topology_input w/ FF_EXPECTED_LINKS =0x000000004, // topology_input w/ FF_EXPECTED_EXTLINKS=0x000000008, // topology_input w/ FF_CABLEDATA =0x000000010, // topology_input w/ some FF_LIDARRAY =0x000000020, // Keep AllLids as array instead of qmap // allows faster FindLid, but takes // approx 300K more memory FF_PMADIRECT =0x000000080, // Force direct PMA access of port counters FF_ROUTES =0x000000100, // Routing tables (linear/mcast) fetched FF_QOSDATA =0x000000200, // QOS data fetched FF_SMADIRECT =0x000000400, // Force direct SMA access FF_BUFCTRLTABLE =0x000000800, // BufferControlData collected FF_DOWNPORTINFO =0x000001000, // Get PortInfo for Down switch ports FF_CABLELOWPAGE =0x000004000, //Get Lower memory of Cable Info } FabricFlags_t; // Handling for LIDs up to 24 bits #define TOPLM_BLOCK_BITS 10 #define TOPLM_ENTRY_BITS 14 #define TOPLM_BLOCKS (1 << TOPLM_BLOCK_BITS) /* There are 2^10 blocks in the map */ #define TOPLM_ENTRIES (1 << TOPLM_ENTRY_BITS) /* Each block contains 2^14 pointers to PortData */ #define TOPLM_BLOCK_NUM(lid) ((lid) >> TOPLM_ENTRY_BITS) #define TOPLM_ENTRY_NUM(lid) ((lid) & (TOPLM_ENTRIES -1)) #define TOPLM_LID_MAX ((1 << (TOPLM_BLOCK_BITS + TOPLM_ENTRY_BITS)) - 1) // Map can handle 2^24 lids typedef struct TopLidMap_s { PortData **LidBlocks[TOPLM_BLOCKS]; } TopLidMap_t; typedef struct FabricData_s { time_t time; // when fabric data was obtained from a real fabric FabricFlags_t flags; // what data is available in FabricData // data from live fabric or snapshot cl_qmap_t AllNodes; // items are NodeData, key is node guid union { cl_qmap_t AllLids; // items are PortData, key is LID TopLidMap_t LidMap; } u; uint32 lidCount; cl_qmap_t AllSystems; // items are SystemData, key is system image guid QUICK_LIST AllPorts; // sorted by NodeGUID+PortNum QUICK_LIST AllFIs; // sorted by NodeGUID QUICK_LIST AllSWs; // sorted by NodeGUID QUICK_LIST AllVFs; // list of VFData_t #if !defined(VXWORKS) || defined(BUILD_DMC) QUICK_LIST AllIOUs; // sorted by NodeGUID // AllIOCs uses IOCGUID as the primary key and NodeGUID as secodary key cl_qmap_t AllIOCs; // items are IocData #endif cl_qmap_t AllSMs; // items are SMData, key is PortGuid // Multicast related structures QUICK_LIST AllMcGroups; // items are MCGroups, Key is MGID McRouteStatus AllMcLoopIncRoutes[MAXMCROUTESTATUS]; // items are list of loop and incomplete MC routes. uint32 NumOfMcGroups; MasterSMData_t MasterSMData; // Master SM data uint32 LinkCount; // number of links in fabric uint32 ExtLinkCount; // number of external links in fabric uint32 FILinkCount; // number of FI links in fabric uint32 ISLinkCount; // number of inter-switch links in fabric uint32 ExtISLinkCount; // number of external inter-switch links in fabric // additional information for credit loop uint32 ConnectionCount; uint32 RouteCount; QUICK_LIST FIs; QUICK_LIST Switches; cl_qmap_t map_guid_to_ib_device; // items are devices, ky is node guid clGraphData_t Graph; // additional information from topology input file QUICK_LIST ExpectedLinks; // in order read from topology input file QUICK_LIST ExpectedFIs; // in order read from topology input file QUICK_LIST ExpectedSWs; // in order read from topology input file QUICK_LIST ExpectedSMs; // in order read from topology input file //topology input data optimized for search cl_qmap_t ExpectedNodeGuidMap; //all expected FIs/SWs mapped by NodeGuid void *context; // application specific field int ms_timeout; } FabricData_t; // these callbacks are called when an object with a non-null application // specific context field is freed. They should free the object pointed to by // the context field and remove any other application references to the object // being freed typedef void (PortDataFreeCallback)(FabricData_t *fabricp, PortData *portp); #if !defined(VXWORKS) || defined(BUILD_DMC) typedef void (IocDataFreeCallback)(FabricData_t *fabricp, IocData *iocp); typedef void (IouDataFreeCallback)(FabricData_t *fabricp, IouData *ioup); #endif typedef void (NodeDataFreeCallback)(FabricData_t *fabricp, NodeData *nodep); typedef void (SystemDataFreeCallback)(FabricData_t *fabricp, SystemData *systemp); typedef void (SMDataFreeCallback)(FabricData_t *fabricp, SMData *smp); typedef void (FabricDataFreeCallback)(FabricData_t *fabricp); typedef struct Top_FreeCallbacks_s { PortDataFreeCallback *pPortDataFreeCallback; #if !defined(VXWORKS) || defined(BUILD_DMC) IocDataFreeCallback *pIocDataFreeCallback; IouDataFreeCallback *pIouDataFreeCallback; #endif NodeDataFreeCallback *pNodeDataFreeCallback; SystemDataFreeCallback *pSystemDataFreeCallback; SMDataFreeCallback *pSMDataFreeCallback; FabricDataFreeCallback *pFabricDataFreeCallback; } Top_FreeCallbacks; // For functions which generate Points, is it node pair or just node #define PAIR_FLAG_NONE 0x01 /* no pair exists */ #define PAIR_FLAG_NODE 0x02 /* pair exists */ // Identifies side of pair #define LSIDE_PAIR 0x01 /* left side of pair */ #define RSIDE_PAIR 0x02 /* right side of pair */ typedef struct NodePairList_s { DLIST nodePairList1; //members of left side of pair DLIST nodePairList2; //members of right side of pair } NodePairList_t; /* struct Point_s identifies a particular point in the fabric and * topology.xml. * Used for trace route and other "focused" reports * Presently coded in C, but a good candidate for a C++ abstract class * with a subclass for each point type */ typedef enum { POINT_TYPE_NONE, POINT_TYPE_PORT, POINT_TYPE_PORT_LIST, POINT_TYPE_NODE, POINT_TYPE_NODE_LIST, #if !defined(VXWORKS) || defined(BUILD_DMC) POINT_TYPE_IOC, POINT_TYPE_IOC_LIST, #endif POINT_TYPE_SYSTEM, POINT_TYPE_NODE_PAIR_LIST, } PointType; typedef enum { POINT_ENODE_TYPE_NONE, POINT_ENODE_TYPE_NODE, POINT_ENODE_TYPE_NODE_LIST, } PointEnodeType; typedef enum { POINT_ESM_TYPE_NONE, POINT_ESM_TYPE_SM, POINT_ESM_TYPE_SM_LIST, } PointEsmType; typedef enum { POINT_ELINK_TYPE_NONE, POINT_ELINK_TYPE_LINK, POINT_ELINK_TYPE_LINK_LIST, } PointElinkType; typedef struct Point_s { /* object(s) matched in the fabric */ PointType Type; /* if POINT_TYPE_NONE, u undefined */ boolean haveSW; /* indicates the point has SW*/ boolean haveFI; /* indicates the point has FI*/ union { PortData *portp; NodeData *nodep; #if !defined(VXWORKS) || defined(BUILD_DMC) IocData *iocp; #endif SystemData *systemp; DLIST nodeList; DLIST portList; DLIST iocList; NodePairList_t nodePairList; } u; /* ExpectedNode(s) matched in topology file */ PointEnodeType EnodeType; /* if POINT_ENODE_TYPE_NONE, u2 undefined */ union { ExpectedNode *enodep; DLIST enodeList; } u2; /* ExpectedSM(s) matched in topology file */ PointEsmType EsmType; /* if POINT_ESM_TYPE_NONE, u3 undefined */ union { ExpectedSM *esmp; DLIST esmList; } u3; /* ExpectedLink(s) matched in topology file */ PointElinkType ElinkType; /* if POINT_ELINK_TYPE_NONE, u4 undefined */ union { ExpectedLink *elinkp; DLIST elinkList; } u4; } Point; #if !defined(VXWORKS) || defined(BUILD_DMC) /* IOC types we can focus on */ typedef enum { IOC_TYPE_SRP, IOC_TYPE_OTHER } IocType; #endif // used for output of snapshot typedef struct { FabricData_t *fabricp; // fabric to dump to snapshot file int argc; // args to program ran char **argv; // args to program ran // Point *focus; } SnapshotOutputInfo_t; // used for output of ValidateAllCreditLoopRoutes typedef struct ValidateCreditLoopRoutesContext_s { uint8 format; int indent; int detail; int quiet; } ValidateCreditLoopRoutesContext_t; typedef enum { QUAL_EQ, QUAL_GE, QUAL_LE } LinkQualityCompare; // simple way to convert time_t to a localtime date string in dest // (from Topology/getdate.c) extern void Top_formattime(char *dest, size_t max, time_t t); // FabricData_t handling (Topology/fabricdata.c) extern FSTATUS InitFabricData( FabricData_t *pFabric, FabricFlags_t flags); extern PortSelector* GetPortSelector(PortData *portp); // Determine if portp and its neighbor are an internal link within a single // system. Note that some 3rd party products report SystemImageGuid of 0 in // which case we can only consider links between the same node as internal links extern boolean isInternalLink(PortData *portp); // Determine if portp and its neighbor are an Inter-switch Link extern boolean isISLink(PortData *portp); // Determine if portp or its neighbor is an FI extern boolean isFILink(PortData *portp); // Determine if elinkp is an external link within a single system. // To make sure verification is thorough, this will return true when // either the expected or resolved link(s) are external or when the // expected link is not specific as to whether it is internal or external. extern boolean isExternalExpectedLink(ExpectedLink *elinkp); // Determine if elinkp is an inter-switch link // To make sure verification is thorough, this will return true when // either the expected or resolved link(s) are SW-SW extern boolean isISExpectedLink(ExpectedLink *elinkp); // Determine if elinkp is an FI link // To make sure verification is thorough, this will return true when // either the expected or resolved link(s) include an FI extern boolean isFIExpectedLink(ExpectedLink *elinkp); extern void PortDataFreePartitionTable(FabricData_t *fabricp, PortData *portp); extern FSTATUS PortDataAllocatePartitionTable(FabricData_t *fabricp, PortData *portp); // capacity of Partition Table for the given port extern uint16 PortPartitionTableSize(PortData *portp); // Lookup PKey // ignores the Full/Limited bit, only checks low 15 bits for a match // returns index of pkey in overall table or -1 if not found // if the Partition Table for the port is not available, returns -1 extern int FindPKey(PortData *portp, uint16 pkey); // Determine if the given port is a member of the given vFabric // We don't really have all the right data here, especially if the FM has // combined multiple vFabrics into the same SL and PKey // but for most cases, we can safely conclude that if the port has the SL and // PKey configured it is a member of the vFabric. // This function will return FALSE if QoS data or SL2SCMap is not available // or if the port is not Armed/Active. // Given the current FM implementation (and the dependency on SL2SCMap), this // routine will return FALSE if invoked for non-endpoints extern boolean isVFMember(PortData *portp, VFData_t *pVFData); // count the number of armed/active links in the node extern uint32 CountInitializedPorts(FabricData_t *fabricp, NodeData *nodep); extern FSTATUS NodeDataAllocateSwitchData(FabricData_t *fabricp, NodeData *nodep, uint32 LinearFDBSize, uint32 MulticastFDBSize); extern FSTATUS NodeDataAllocateFDB(FabricData_t *fabricp, NodeData *nodep, uint32 LinearFDBSize); extern FSTATUS SwitchDataAllocateQOS(SwitchData *sw); /** Adjust amount of memory allocated for Linear and Multicast FDB tables. Copies existing values into new memory, adjusts FDB Top values, and frees existing memory. When resizing MulticastFDB, the new entry size (entries per LID) must be the same as the old size. If the multicast FDB table is to be resized and there is already a multicast FDB table and the existing MulticastFDBTop is less than LID_MCAST_START then no values will be copied from the old table to the new table, though the table will still be resized. In this case, the value of @c nodep->switchp->MulticastFDBSize will be LID_MCAST_START + @c newMfdbSize rather than MulticastFDBTop + 1. @param newLfdbSize If 0, don't change. Otherwise, realloc to min(newLfdbSize, LinearFDBCap). @param newMfdbSize If 0, don't change. Otherwise, realloc to min(newMfdbSize, MulticastFDBCap). @return FSUCCESS on success, non-FSUCCESS on failure. Existing memory is not destroyed until after new tables are successfully allocated and copied. */ FSTATUS NodeDataSwitchResizeFDB(NodeData * nodep, uint32 newLfdbSize, uint32 newMfdbSize); FSTATUS NodeDataSwitchResizeLinearFDB(NodeData * nodep, uint32 newLfdbSize); FSTATUS NodeDataSwitchResizeMcastFDB(NodeData * nodep, uint32 newMfdbSize); extern FSTATUS PortDataAllocateAllQOSData(FabricData_t *fabricp); extern FSTATUS PortDataAllocateAllBufCtrlTable(FabricData_t *fabricp); extern FSTATUS PortDataAllocateAllPartitionTable(FabricData_t *fabricp); extern FSTATUS PortDataAllocateAllCableInfo(FabricData_t *fabricp); extern FSTATUS PortDataAllocateAllCongestionControlTableEntries(FabricData_t *fabricp); extern FSTATUS PortDataAllocateAllGuidTable(FabricData_t *fabricp); /// @param fabricp optional, can be NULL extern void PortDataFreeQOSData(FabricData_t *fabricp, PortData *portp); /// @param fabricp optional, can be NULL extern FSTATUS PortDataAllocateQOSData(FabricData_t *fabricp, PortData *portp); /// @param fabricp optional, can be NULL extern void PortDataFreeBufCtrlTable(FabricData_t *fabricp, PortData *portp); /// @param fabricp optional, can be NULL extern FSTATUS PortDataAllocateBufCtrlTable(FabricData_t *fabricp, PortData *portp); /// @param fabricp optional, can be NULL extern void PortDataFreeCableInfoData(FabricData_t *fabricp, PortData *portp); /// @param fabricp optional, can be NULL extern FSTATUS PortDataAllocateCableInfoData(FabricData_t *fabricp, PortData *portp); /// @param fabricp optional, can be NULL extern void PortDataFreeCongestionControlTableEntries(FabricData_t *fabricp, PortData *portp); /// @param fabricp optional, can be NULL extern FSTATUS PortDataAllocateCongestionControlTableEntries(FabricData_t *fabricp, PortData *portp); // these routines can be used to manually build FabricData. Use as follows: // for each node // FabricDataAddNode (can be any state, including down) // if switch node // NodeDataSetSwitchInfo // for each port of Node // NodeDataAddPort // BuildFabricDataLists // for each physical link // FabricDataAddLink or FabricDataAllLinkRecord // (FabricDataAddLink may be called before BuildFabricDataLists if desired) // if desired, after building the basic topology, can build empty SMA tables: // NodeDataAllocateAllSwitchData // PortDataAllocateAllQOSData // PortDataAllocateAllBufCtrlTable // PortDataAllocateAllPartitionTable // PortDataAllocateAllGuidTable // when process Set(PortInfo) // validate PortInfo given // fill in empty/noop/readonly fields with previous PortInfo // PortDataSetPortInfo extern PortData* NodeDataAddPort(FabricData_t *fabricp, NodeData *nodep, EUI64 guid, STL_PORTINFO_RECORD *pPortInfo); extern FSTATUS NodeDataSetSwitchInfo(NodeData *nodep, STL_SWITCHINFO_RECORD *pSwitchInfo); extern NodeData *FabricDataAddNode(FabricData_t *fabricp, STL_NODE_RECORD *pNodeRecord, boolean *new_nodep); extern FSTATUS AddEdgeSwitchToGroup(FabricData_t *fabricp, McGroupData *mcgroupp, NodeData *groupswitch, uint8 SWentryport); extern McGroupData *FabricDataAddMCGroup(FabricData_t *fabricp, struct omgt_port *port, int quiet, IB_MCMEMBER_RECORD *pMCGRecord, boolean *new_nodep, FILE *verbose_file); extern FSTATUS GetAllMCGroups(EUI64 portGuid, FabricData_t *fabricp, Point *focus, int quiet); extern FSTATUS GetAllMCGroupMember(FabricData_t *fabricp, McGroupData *mcgroupp,struct omgt_port *portp,int quiet, FILE *g_verbose_file); extern boolean SupportsVendorPortCounters(NodeData *nodep, IB_CLASS_PORT_INFO *classPortInfop); extern boolean SupportsVendorPortCounters2(NodeData *nodep, IB_CLASS_PORT_INFO *classPortInfop); /* build the Fabric.AllPorts, ALLFIs, and AllSWs lists such that * AllPorts is sorted by NodeGUID, PortNum * AllFIs, ALLSWs, AllIOUs is sorted by NodeGUID */ extern void BuildFabricDataLists(FabricData_t *fabricp); extern FSTATUS FabricDataAddLink(FabricData_t *fabricp, PortData *p1, PortData *p2); extern FSTATUS FabricDataAddLinkRecord(FabricData_t *fabricp, STL_LINK_RECORD *pLinkRecord); extern FSTATUS FabricDataRemoveLink(FabricData_t *fabricp, PortData *p1); extern void QOSDataAddSCSCMap(PortData *portp, uint8_t outport, int extended, const STL_SCSCMAP *pSCSC); extern STL_SCSCMAP * QOSDataLookupSCSCMap(PortData *portp, uint8_t outport, int extended); // Set update lookup tables due to PortState, LID or LMC change for port. // Typical use is when a SetPortInfo on neighbor causes a link state change // For use by fabric simulator. extern void PortDataStateChanged(FabricData_t *fabricp, PortData *portp); // Set new Port Info based on a Set(PortInfo). For use by fabric simulator // assumes pInfo already validated and any Noop fields filled in with correct // values. extern void PortDataSetPortInfo(FabricData_t *fabricp, PortData *portp, STL_PORT_INFO *pInfo); extern void DestroyFabricData(FabricData_t *fabricp); extern NodeData * CLDataAddDevice(FabricData_t *fabricp, NodeData *nodep, STL_LID lid, int verbose, int quiet); extern FSTATUS CLDataAddConnection(FabricData_t *fabricp, PortData *portp1, PortData *portp2, clConnPathData_t *pathInfo, uint8 sc, int verbose, int quiet); extern FSTATUS CLDataAddRoute(FabricData_t *fabricp, STL_LID slid, STL_LID dlid, PortData *sportp, int verbose, int quiet); extern clGraphData_t * CLGraphDataSplit(clGraphData_t *graphp, int verbose); extern FSTATUS CLFabricDataDestroy(FabricData_t *fabricp, void *context); extern void CLGraphDataFree(clGraphData_t *graphp, void *context); extern FSTATUS CLDijkstraFindDistancesAndRoutes(clGraphData_t *graphp, clDijkstraDistancesAndRoutes_t *respData, int verbose); extern void CLDijkstraFreeDistancesAndRoutes(clDijkstraDistancesAndRoutes_t *drp); // search routines (Topology/search.c) // For functions which generate Points, indicate what is needed #define FIND_FLAG_FABRIC 0x01 /* find in live fabric */ #define FIND_FLAG_ENODE 0x02 /* find in ExpectedNodes */ #define FIND_FLAG_ESM 0x04 /* find in ExpectedSMs */ #define FIND_FLAG_ELINK 0x08 /* find in ExpectedLinks */ // The search routines involving Points tend to limit the search to the // specific objects indicated by find_flag and expect later caller use of // Compare functions to invoke the necessary Compare functions to cover the // fabric vs expected objects of interest. One exception is the comparison // for Details and Cable information which is only available in topology.xml // In this case, the fabric seach will check the resolved expected object // This permits the majority of fabric related operations, such as opareport, // to make use of Details and Cable information from topology.xml while // only considering fabric objects. // search for the PortData corresponding to the given node and port number extern PortData * FindNodePort(NodeData *nodep, uint8 port); // search for the PortData corresponding to the given lid extern PortData * FindLid(FabricData_t* fabricp, STL_LID lid); // search for the PortData corresponding to the given port Guid extern PortData * FindPortGuid(FabricData_t* fabricp, EUI64 guid); extern FSTATUS FindPortGuidPoint(FabricData_t *fabricp, EUI64 guid, Point *pPoint, uint8 find_flag, int silent); extern FSTATUS FindGidPoint(FabricData_t *fabricp, IB_GID gid, Point *pPoint, uint8 find_flag, int silent); // search for the NodeData corresponding to the given node Guid extern NodeData * FindNodeGuid(const FabricData_t* fabricp, EUI64 guid); extern FSTATUS FindNodeGuidPoint(FabricData_t *fabricp, EUI64 guid, Point *pPoint, uint8 find_flag, int silent); extern FSTATUS FindNodeNamePoint(FabricData_t* fabricp, char *name, Point *pPoint, uint8 find_flag, int silent); extern FSTATUS FindNodeNamePatPoint(FabricData_t* fabricp, char *pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindNodeNamePatPointUncompress(FabricData_t *fabricp, char *pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindNodePatPairs(FabricData_t *fabricp, char *pattern, NodePairList_t *nodePatPairs, uint8 find_flag, uint8 side); extern FSTATUS FindNodeDetailsPatPoint(FabricData_t* fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindNodeTypePoint(FabricData_t* fabricp, NODE_TYPE type, Point *pPoint, uint8 find_flag); #if !defined(VXWORKS) || defined(BUILD_DMC) extern FSTATUS FindIocNamePoint(FabricData_t* fabricp, char *name, Point *pPoint, uint8 find_flag); extern FSTATUS FindIocNamePatPoint(FabricData_t* fabricp, char *pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindIocTypePoint(FabricData_t* fabricp, IocType type, Point *pPoint, uint8 find_flag); extern FSTATUS FindIocGuid(FabricData_t* fabricp, EUI64 guid, Point *pPoint); #endif extern SystemData * FindSystemGuid(FabricData_t* fabricp, EUI64 guid); extern FSTATUS FindRatePoint(FabricData_t* fabricp, uint32 rate, Point *pPoint, uint8 find_flag); extern FSTATUS FindPortStatePoint(FabricData_t* fabricp, uint8 state, Point *pPoint, uint8 find_flag); extern FSTATUS FindLedStatePoint(FabricData_t* fabricp, uint8 state, Point *pPoint, uint8 find_flag); extern FSTATUS FindPortPhysStatePoint(FabricData_t* fabricp, IB_PORT_PHYS_STATE state, Point *pPoint, uint8 find_flag); extern FSTATUS FindCableLabelPatPoint(FabricData_t* fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindCableLenPatPoint(FabricData_t* fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindCableDetailsPatPoint(FabricData_t* fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindCabinfLenPatPoint(FabricData_t *fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindCabinfVendNamePatPoint(FabricData_t *fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindCabinfVendPNPatPoint(FabricData_t *fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindCabinfVendRevPatPoint(FabricData_t *fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindCabinfVendSNPatPoint(FabricData_t *fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindCabinfCableTypePoint(FabricData_t *fabricp, char *cablearg, Point *pPoint, uint8 find_flag); extern FSTATUS FindLinkDetailsPatPoint(FabricData_t* fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindPortDetailsPatPoint(FabricData_t* fabricp, const char* pattern, Point *pPoint, uint8 find_flag); extern FSTATUS FindMtuPoint(FabricData_t* fabricp, IB_MTU mtu, Point *pPoint, uint8 find_flag); extern PortData * FindMasterSm(FabricData_t* fabricp); extern FSTATUS FindSmDetailsPatPoint(FabricData_t *fabricp,const char* pattern, Point *pPoint, uint8 find_flag); // search for the SMData corresponding to the given PortGuid extern SMData * FindSMPort(FabricData_t *fabricp,EUI64 PortGUID); // search for the PortData corresponding to the given lid and port number // For FIs lid completely defines the port // For Switches, lid will identify the switch and port is used to select port extern PortData * FindLidPort(FabricData_t *fabricp, STL_LID lid, uint8 port); extern PortData * FindNodeGuidPort(FabricData_t *fabricp,EUI64 nodeguid, uint8 port); extern ExpectedNode* FindExpectedNodeByNodeGuid(const FabricData_t* fabricp, EUI64 nodeGuid); extern ExpectedNode* FindExpectedNodeByNodeDesc(const FabricData_t* fabricp, const char* nodeDesc, uint8 NodeType); extern ExpectedLink* FindExpectedLinkByOneSide(const FabricData_t* fabricp, EUI64 nodeGuid, uint8 portNum, uint8* side); extern FSTATUS FindLinkQualityPoint(FabricData_t *fabricp, uint16 quality, LinkQualityCompare comp, Point *pPoint, uint8 find_flag); extern FSTATUS FindLinkDownReasonPoint(FabricData_t *fabricp, uint8 ldr, Point *pPoint, uint8 find_flag); extern FSTATUS FindExpectedSMByPortGuid(FabricData_t *fabricp, EUI64 portGuid); extern FSTATUS FindExpectedSMByNodeGuid(FabricData_t *fabricp, EUI64 nodeGuid); extern void setTopologyMadVerboseFile(FILE* verbose_file); extern void setTopologyMadRetryCount(int retries); // mad queries to SMA (from Topology/mad.c) extern FSTATUS SmaGetNodeDesc(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, STL_NODE_DESCRIPTION *pNodeDesc); extern FSTATUS SmaGetNodeInfo(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, STL_NODE_INFO *pNodeInfo); extern FSTATUS SmaGetSwitchInfo(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, STL_SWITCH_INFO *pSwitchInfo); extern FSTATUS SmaGetPortInfo(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t portNum, uint8_t smConfigStarted, STL_PORT_INFO *pPortInfo); extern FSTATUS SmaGetPartTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t portNum, uint16_t block, STL_PARTITION_TABLE *pPartTable); extern FSTATUS SmaGetVLArbTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t portNum, uint8_t part, STL_VLARB_TABLE *pVLArbTable); extern FSTATUS SmaGetSLSCMappingTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, STL_SLSCMAP *pSLSCMap); extern FSTATUS SmaGetSCSLMappingTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, STL_SCSLMAP *pSCSLMap); extern FSTATUS SmaGetSCSCMappingTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t in_port, uint8_t out_port, STL_SCSCMAP *pSCSCMap); extern FSTATUS SmaGetSCVLMappingTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t port_num, STL_SCVLMAP *pSCVLMap, uint16_t attr); extern FSTATUS SmaGetLinearFDBTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint16_t block, STL_LINEAR_FORWARDING_TABLE *pFDB); extern FSTATUS SmaGetMulticastFDBTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint32_t block, uint8_t position, STL_MULTICAST_FORWARDING_TABLE *pFDB); extern FSTATUS SmaGetPortGroupFDBTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint16 block, STL_PORT_GROUP_FORWARDING_TABLE *pFDB); extern FSTATUS SmaGetPortGroupTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint16 block, STL_PORT_GROUP_TABLE *pPGT); extern FSTATUS SmaGetBufferControlTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t startPort, uint8_t endPort, STL_BUFFER_CONTROL_TABLE pBCT[]); extern FSTATUS SmaGetCableInfo(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t portNum, uint16_t addr, uint8_t len, uint8_t *data); extern FSTATUS SmaSetSwitchInfo(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, STL_SWITCH_INFO *pSwitchInfo); extern FSTATUS SmaSetPortInfo(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t portNum, STL_PORT_INFO *pPortInfo); extern FSTATUS SmaSetPartTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t portNum, uint16_t block, STL_PARTITION_TABLE *pPartTable); extern FSTATUS SmaSetVLArbTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t portNum, uint8_t part, STL_VLARB_TABLE *pVLArbTable); extern FSTATUS SmaSetSLSCMappingTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, STL_SLSCMAP *pSLSCMap); extern FSTATUS SmaSetSCSLMappingTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, STL_SCSLMAP *pSCSLMap); extern FSTATUS SmaSetSCSCMappingTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t in_port, uint8_t out_port, STL_SCSCMAP *pSCSCMap); extern FSTATUS SmaSetSCVLMappingTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, boolean asyncUpdate, boolean allPorts, uint8_t portNum, STL_SCVLMAP *pSCVLMap, uint16_t attr); extern FSTATUS SmaSetBufferControlTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint8_t startPort, uint8_t endPort, STL_BUFFER_CONTROL_TABLE pBCT[]); extern FSTATUS SmaSetLinearFDBTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint16_t block, STL_LINEAR_FORWARDING_TABLE *pFDB); extern FSTATUS SmaSetMulticastFDBTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint32_t block, uint8_t position, STL_MULTICAST_FORWARDING_TABLE *pFDB); extern FSTATUS SmaGetCongestionInfo(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, STL_CONGESTION_INFO *pCongestionInfo); extern FSTATUS SmaGetHFICongestionControlTable(struct omgt_port *port, STL_LID dlid, STL_LID slid, uint8_t* path, uint16_t block, uint16_t numBlocks, STL_HFI_CONGESTION_CONTROL_TABLE *pHfiCongestionControl); // mad queries to PMA and DMA (from Topology/mad.c) extern FSTATUS InitMad(EUI64 portguid, FILE *verbose_file); extern void DestroyMad(void); extern FSTATUS InitSmaMkey(uint64 mkey); extern boolean NodeHasPma(NodeData *nodep); extern boolean PortHasPma(PortData *portp); extern void UpdateNodePmaCapabilities(NodeData *nodep, boolean ProcessHFICounters); extern FSTATUS STLPmGetClassPortInfo(struct omgt_port *port, PortData *portp); extern FSTATUS STLPmGetPortStatus(struct omgt_port *port, PortData *portp, uint8 portNum, STL_PORT_STATUS_RSP *pPortStatus); extern FSTATUS STLPmClearPortCounters(struct omgt_port *port, PortData *portp, uint8 lastPortIndex, uint32 counterselect); #if !defined(VXWORKS) || defined(BUILD_DMC) extern FSTATUS DmGetIouInfo(struct omgt_port *port, IB_PATH_RECORD *pathp, IOUnitInfo *pIouInfo); extern FSTATUS DmGetIocProfile(struct omgt_port *port, IB_PATH_RECORD *pathp, uint8 slot, IOC_PROFILE *pIocProfile); extern FSTATUS DmGetServiceEntries(struct omgt_port *port, IB_PATH_RECORD *pathp, uint8 slot, uint8 first, uint8 last, IOC_SERVICE *pIocServices); #endif // POINT routines (from Topology/point.c) extern void PointInit(Point *point); extern boolean PointIsInInit(Point *point); extern void PointFabricDestroy(Point *point); extern void PointEnodeDestroy(Point *point); extern void PointEsmDestroy(Point *point); extern void PointElinkDestroy(Point *point); extern void PointDestroy(Point *point); extern boolean PointValid(Point *point); extern FSTATUS PointFabricCopy(Point *dest, Point *src); extern FSTATUS PointEnodeCopy(Point *dest, Point *src); extern FSTATUS PointEsmCopy(Point *dest, Point *src); extern FSTATUS PointElinkCopy(Point *dest, Point *src); extern FSTATUS PointCopy(Point *dest, Point *src); extern FSTATUS PointListAppend(Point *point, PointType type, void *object); extern FSTATUS PointEnodeListAppend(Point *point, PointEnodeType type, void *object); extern FSTATUS PointEsmListAppend(Point *point, PointEsmType type, void *object); extern FSTATUS PointElinkListAppend(Point *point, PointElinkType type, void *object); extern FSTATUS PointNodePairListAppend(Point *point, uint8 side, void *object); extern FSTATUS PointPopulateNodePairList(Point *pPoint, NodePairList_t *nodePatPairs); extern void PointFabricCompress(Point *point); extern void PointEnodeCompress(Point *point); extern void PointEsmCompress(Point *point); extern void PointElinkCompress(Point *point); extern void PointCompress(Point *point); extern FSTATUS PointListAppendUniquePort(Point *point, PortData *portp); /* These compare functions will compare the supplied object to the * specific relevant portion of the point. Callers who wish to consider * both expected and fabric objects should call all the relevant routines * for the fabric and linked expected objects * This approach provides greater flexibility for callers, and removes the need * for the Point construction and parsing routines to check all the linked * fabric and expected objects. */ /* compare the supplied port to the given point * this is used to identify focus for reports * if ! PointValid will report TRUE for all ports */ extern boolean ComparePortPoint(PortData *portp, Point *point); /* compare the supplied node to the given point * this is used to identify focus for reports * if ! PointValid will report TRUE for all nodes */ extern boolean CompareNodePoint(NodeData *nodep, Point *point); /* compare the supplied ExpectedNode to the given point * this is used to identify focus for reports * if !PointValid will report TRUE for all ExpectedNodes */ extern boolean CompareExpectedNodePoint(ExpectedNode *enodep, Point *point); /* compare the supplied ExpectedSM to the given point * this is used to identify focus for reports * if !PointValid will report TRUE for all ExpectedSMs */ extern boolean CompareExpectedSMPoint(ExpectedSM *esmp, Point *point); /* compare the supplied ExpectedLink to the given point * this is used to identify focus for reports * if !PointValid will report TRUE for all ExpectedLinks */ extern boolean CompareExpectedLinkPoint(ExpectedLink *elinkp, Point *point); #if !defined(VXWORKS) || defined(BUILD_DMC) extern boolean CompareIouPoint(IouData *ioup, Point *point); extern boolean CompareIocPoint(IocData *iocp, Point *point); #endif /* compare the supplied SM to the given point * this is used to identify focus for reports * if ! PointValid will report TRUE for all SMs */ extern boolean CompareSmPoint(SMData *smp, Point *point); extern boolean CompareSystemPoint(SystemData *systemp, Point *point); /* check arg to see if 1st characters match prefix, if so return pointer * into arg just after prefix, otherwise return NULL */ extern char* ComparePrefix(char *arg, const char *prefix); extern FSTATUS ParsePoint(FabricData_t *fabricp, char* arg, Point* pPoint, uint8 find_flag, char **pp); /* check if point is of Type NodePairList */ extern boolean PointTypeIsNodePairList(Point *pPoint); /* check if point is of Type NodeList */ extern boolean PointIsTypeNodeList(Point *pPoint); /* check if haveSW flag is set */ extern boolean PointHaveSw(Point *pPoint); /* check if haveFI flag is set */ extern boolean PointHaveFI(Point *pPoint); // snapshot input/output routines (from Topology/snapshot.c) extern void Xml2PrintSnapshot(FILE *file, SnapshotOutputInfo_t *info); struct IXmlParserState; /** Completion callback manipulators. These get called inside custom end_func definitions and typically do things like insert the completed structure into a broader data structure. The basic idea is to separate how the entity is parsed from how it is used by the parent. */ typedef int (*ParseCompleteFn)(struct IXmlParserState * state, void * object, void * parent); void SetPortDataComplete(ParseCompleteFn fn); /** only FF_LIDARRAY flag is used, others set based on file read @param allocFull When true, adjust allocated memory for linear and multicast forwarding tables to their cap values after reading in all data. */ #ifndef __VXWORKS__ extern FSTATUS Xml2ParseSnapshot(const char *input_file, int quiet, FabricData_t *fabricp, FabricFlags_t flags, boolean allocFull); #else extern FSTATUS Xml2ParseSnapshot(const char *input_file, int quiet, FabricData_t *fabricp, FabricFlags_t flags, boolean allocFull, XML_Memory_Handling_Suite* memsuite); #endif // expected topology input/output routines (from Topology/topology.c) // validation options for Xml2ParseTopology // None - no attempt to cross reference ExpectedLinks to ExpectedNodes // the ExpectedLink.portselp1 may be NULL // the ExpectedLink.portselp1->enodep will be NULL // the ExpectedLink.portselp2 may be NULL // the ExpectedLink.portselp2->enodep will be NULL // the ExpectedNode.ports[] may be empty // the ExpectedNode.ports[]->elinkp will be NULL // Loose - do a best attempt to resolve (eg. cross reference) ExpectedLinks // to ExpectedNodes filling in the elinkp and enodep pointers mentioned // above where possible. Also checks that when Node and Port GUIDs are // supplied in ExpectedNodes, that switch port 0's GUIDs are consistent. // However no error return reported by Xml2ParseTopology when unable // to resolve some links. Does not require ExpectedNodes to // explicitly list ports in topology file. Will auto-create // ExpectedNode.ports[] entries if a ExpectedLink references the given // node's port. // Somewhat strict - cross references all ExpectedLinks to ExpectedNodes as // in Loose. Also checks that all nodes are connected to the same fabric. // Any errors in resolution or checks are reported as an error by // Xml2ParseTopology. // Strict - performs all checks in Somewhat strict. Also requires that all // ExpectedLinks explicitly list PortNum in topology file and // all ExpectedNodes explicitly list ports in topology file. // In all cases its valid for a ExpectedNode to list a port which is not // connected to the fabric (eg. not referenced by an ExpectedLink). // typedef enum { TOPOVAL_NONE =0, TOPOVAL_LOOSE =1, // resolve what we can, no graph closure checks TOPOVAL_SOMEWHAT_STRICT =2, // same as strict but don't require under TOPOVAL_STRICT =3 } TopoVal_t; // in ExpectedNode in topology file #ifndef __VXWORKS__ extern FSTATUS Xml2ParseTopology(const char *input_file, int quiet, FabricData_t *fabricp, TopoVal_t validation); #else extern FSTATUS Xml2ParseTopology(const char *input_file, int quiet, FabricData_t *fabricp, XML_Memory_Handling_Suite* memsuite, TopoVal_t validation); #endif extern void Xml2PrintTopology(FILE *file, FabricData_t *fabricp); // live fabric analysis routines (from Topology/sweep.c) extern FSTATUS InitSweepVerbose(FILE *verbose_file); /* flags for Sweep */ typedef enum { SWEEP_BASIC =0, // Systems, Nodes, Ports, Links #if !defined(VXWORKS) || defined(BUILD_DMC) SWEEP_IOUS =0x000000001, // IOU and IOC Info #endif SWEEP_SWITCHINFO =0x000000002, // Switch Info SWEEP_SM =0x000000003, // SM Info SWEEP_ALL =0x000000003 } SweepFlags_t; extern FSTATUS Sweep(EUI64 portGuid, FabricData_t *fabricp, FabricFlags_t fflags, SweepFlags_t flags, int quiet, int ms_timeout); //extern FSTATUS GetPathToPort(EUI64 portGuid, PortData *portp, uint16 pkey); extern FSTATUS GetPaths(struct omgt_port *port, PortData *portp1, PortData *portp2, PQUERY_RESULT_VALUES *ppQueryResults); extern FSTATUS GetTraceRoute(struct omgt_port *port, IB_PATH_RECORD *pathp, PQUERY_RESULT_VALUES *ppQueryResults); extern FSTATUS GetAllPortCounters(EUI64 portGuid, IB_GID localGid, FabricData_t *fabricp, Point *focus, boolean limitstats, boolean quiet, uint32 begin, uint32 end); extern FSTATUS GetAllFDBs( EUI64 portGuid, FabricData_t *fabricp, Point *focus, int quiet ); extern FSTATUS GetAllPortVLInfo(EUI64 portGuid, FabricData_t *fabricp, Point *focus, int quieti, int *use_scsc); extern PQUERY_RESULT_VALUES GetAllQuarantinedNodes(struct omgt_port *port, FabricData_t *fabricp, Point *focus, int quiet); extern FSTATUS GetAllBCTs(EUI64 portGuid, FabricData_t *fabricp, Point *focus, int quiet); extern FSTATUS ClearAllPortCounters(EUI64 portGuid, IB_GID localGid, FabricData_t *fabricp, Point *focus, uint32 counterselect, boolean limitstats, boolean quiet, uint32 *node_countp, uint32 *port_countp, uint32 *fail_node_countp, uint32 *fail_port_countp); extern PQUERY_RESULT_VALUES GetAllDeviceGroupMemberRecords(struct omgt_port *port, FabricData_t *fabricp, Point *focus, int quiet); extern void XmlPrintHex64(const char *tag, uint64 value, int indent); extern FSTATUS ParseFocusPoint(EUI64 portGuid, FabricData_t *fabricp, char* arg, Point* pPoint, uint8 find_flag, char **pp, boolean allow_route); // utility routines (from Topology/util.c) extern void Top_setcmdname(const char *name); // for error messages extern void Top_setFreeCallbacks(Top_FreeCallbacks *callbacks); extern void ProgressPrint(boolean newline, const char *format, ...); extern const char* Top_truncate_str(const char *name); //#define PROGRESS_PRINT(newline, format, args...) if (! g_quiet) { ProgressPrint(newline, format, ##args); } // functions to perform routing analysis using LFT tables in FabricData //(from Topology/route.c) // For each device along the path, entry and exit port of device is provided // For the CA at the start of the route, only an exit port is provided // For the CA at the end of the route, only a entry port is provided // For switches along the route, both entry and exit ports are provided // When a switch Port 0 is the start of the route, it will be the entry port // along with the physical exit port // When a switch Port 0 is the end of the route, it will be the exit port // along with the physical entry port // The above approach parallels how TraceRoute records are reported by the // SM, so if desired a callback could build a SM TraceRoute style response // for use in other routines. typedef FSTATUS (RouteCallback_t)(PortData *entryPortp, PortData *exitPortp, uint8 vl, void *context); // returns status of callback (if not FSUCCESS) // FUNAVAILABLE - no routing tables in FabricData given // FNOT_FOUND - unable to find starting port // FNOT_DONE - unable to trace route, dlid is a dead end extern FSTATUS WalkRoutePort(FabricData_t *fabricp, PortData *portp, STL_LID dlid, uint8 SL, uint8 rc, RouteCallback_t *callback, void *context); // walk by slid to dlid extern FSTATUS WalkRoute(FabricData_t *fabricp, STL_LID slid, STL_LID dlid, RouteCallback_t *callback, void *context); // caller must free *ppTraceRecords extern FSTATUS GenTraceRoutePort(FabricData_t *fabricp, PortData *portp, STL_LID dlid, uint8 rc, STL_TRACE_RECORD **ppTraceRecords, uint32 *pNumTraceRecords); extern FSTATUS GenTraceRoute(FabricData_t *fabricp, STL_LID slid, STL_LID dlid, uint8 rc, STL_TRACE_RECORD **ppTraceRecords, uint32 *pNumTraceRecords); extern FSTATUS GenTraceRoutePath(FabricData_t *fabricp, IB_PATH_RECORD *pathp, uint8 rc, STL_TRACE_RECORD **ppTraceRecords, uint32 *pNumTraceRecords); // Generate possible Path records from portp1 to portp2 // We don't know SM config, so we just guess and generate paths of the form // 0-0, 1-1, .... // This corresponds to the PathSelection=Minimal FM config option // when LMC doesn't match we start back at base lid for other port // These may not be accurate for Torus, however the dlid is all that really // matters for route analysis, so this should be fine extern FSTATUS GenPaths(FabricData_t *fabricp, PortData *portp1, PortData *portp2, IB_PATH_RECORD **ppPathRecords, uint32 *pNumPathRecords); // tabulate all the ports along the route from slid to dlid extern FSTATUS TabulateRoute(FabricData_t *fabricp, STL_LID slid, STL_LID dlid, boolean fatTree); // tabulate all routes from portp1 to portp2 extern FSTATUS TabulateRoutes(FabricData_t *fabricp, PortData *portp1, PortData *portp2, uint32 *totalPaths, uint32 *badPaths, boolean fatTree); // tabulate all the routes between FIs, exclude loopback routes extern FSTATUS TabulateCARoutes(FabricData_t *fabricp, Point *focus, uint32 *totalPaths, uint32 *badPaths, boolean fatTree); typedef void (*ReportCallback_t)(PortData *portp1, PortData *portp2, STL_LID dlid, boolean isBaseLid, boolean flag /* TRUE=uplink or Recv */, void *context); // report all routes from portp1 to portp2 that cross reportPort extern FSTATUS ReportRoutes(FabricData_t *fabricp, PortData *portp1, PortData *portp2, PortData *reportPort, ReportCallback_t callback, void *context, boolean fatTree); // report all the routes between FIs that cross reportPort, // exclude loopback routes extern FSTATUS ReportCARoutes(FabricData_t *fabricp, PortData *reportPort, ReportCallback_t callback, void *context, boolean fatTree); // callback used to indicate that an incomplete route exists between p1 and p2 typedef void (*ValidateCallback_t)(PortData *portp1, PortData *portp2, STL_LID dlid, boolean isBaseLid, uint8 sl, void *context); // callback used to indicate a port along an incomplete route typedef void (*ValidateCallback2_t)(PortData *portp, uint8 vl, void *context); // validate all routes from portp1 to portp2 extern FSTATUS ValidateRoutes(FabricData_t *fabricp, PortData *portp1, PortData *portp2, uint32 *totalPaths, uint32 *badPaths, uint32 usedSLs, uint8, ValidateCallback_t callback, void *context, ValidateCallback2_t callback2, void *context2); // validate all the routes between all LIDs // exclude loopback routes extern FSTATUS ValidateAllRoutes(FabricData_t *fabricp, EUI64 portGuid, uint8 rc, uint32 *totalPaths, uint32 *badPaths, ValidateCallback_t callback, void *context, ValidateCallback2_t callback2, void *context2, uint8 useSCSC); // validate all MC routes between all members // exclude loopback routes extern FSTATUS ValidateAllMCRoutes(FabricData_t *fabricp, uint32 *totalPaths); extern FSTATUS ValidateMCRoutes(FabricData_t *fabricp, McGroupData *mcgroupp, McEdgeSwitchData *swp, uint32 *pathCount); extern FSTATUS WalkMCRoute(FabricData_t *fabricp, McGroupData *mcgroupp, PortData *portp, int hop, uint8 EntryPort, McLoopInc *pMcLoopInc, uint32 *pathCount); extern FSTATUS AddSwtichToGroup(FabricData_t *fabricp, McGroupData *mcgroupp, NodeData *groupswitch); extern void FreeValidateMCRoutes(FabricData_t *fabricp); typedef void (*ValidateCLRouteCallback_t)(PortData *portp1, PortData *portp2, void *context); typedef void (*ValidateCLFabricSummaryCallback_t)(FabricData_t *fabricp, const char *name, uint32 totalPaths, uint32 totalBadPaths, void *context); typedef void (*ValidateCLDataSummaryCallback_t)(clGraphData_t *graphp, const char *name, void *context); typedef void (*ValidateCLRouteSummaryCallback_t)(uint32 routesPresent, uint32 routesMissing, uint32 hopsHistogramEntries, uint32 *hopsHistogram, void *context); typedef void (*ValidateCLPathSummaryCallback_t)(FabricData_t *fabricp, clConnData_t *connp, int indent, void *context); typedef void (*ValidateCLLinkSummaryCallback_t)(uint32 id, const char *name, uint32 cycle, uint8 header, int indent, void *context); typedef void (*ValidateCLLinkStepSummaryCallback_t)(uint32 id, const char *name, uint32 step, uint8 header, int indent, void *context); #ifndef __VXWORKS__ typedef FSTATUS (*ValidateCLTimeGetCallback_t)(uint64_t *address, pthread_mutex_t *lock); extern pthread_mutex_t g_cl_lock; extern FSTATUS ValidateAllCreditLoopRoutes(FabricData_t *fabricp, EUI64 portGuid, uint8 rc, ValidateCLRouteCallback_t routeCallback, ValidateCLFabricSummaryCallback_t fabricSummaryCallback, ValidateCLDataSummaryCallback_t dataSummaryCallback, ValidateCLRouteSummaryCallback_t routeSummaryCallback, ValidateCLLinkSummaryCallback_t linkSummaryCallback, ValidateCLLinkStepSummaryCallback_t linkStepSummaryCallback, ValidateCLPathSummaryCallback_t pathSummaryCallback, ValidateCLTimeGetCallback_t timeGetCallback, void *context, uint8 snapshotInFile, uint8 useSCSC); extern void CLFabricSummary(FabricData_t *fabricp, const char *name, ValidateCLFabricSummaryCallback_t callback, uint32 totalPaths, uint32 totalBadPaths, void *context); extern void CLGraphDataSummary(clGraphData_t *graphp, const char *name, ValidateCLDataSummaryCallback_t callback, void *context); extern FSTATUS CLFabricDataBuildRouteGraph(FabricData_t *fabricp, ValidateCLRouteSummaryCallback_t routeSummaryCallback, ValidateCLTimeGetCallback_t timeGetCallback, void *context, uint32 usedSLs); extern void CLGraphDataPrune(clGraphData_t *graphp, ValidateCLTimeGetCallback_t timeGetCallback, int verbose, int quiet); extern void CLDijkstraFindCycles(FabricData_t *fabricp, clGraphData_t *graphp, clDijkstraDistancesAndRoutes_t *drp, ValidateCLLinkSummaryCallback_t linkSummaryCallback, ValidateCLLinkStepSummaryCallback_t linkStepSummaryCallback, ValidateCLPathSummaryCallback_t pathSummaryCallback, void *context); extern FSTATUS CLTimeGet(uint64_t *address); #endif extern PortData *GetMapEntry(FabricData_t *fabricp, STL_LID lid); extern FSTATUS SetMapEntry(FabricData_t *fabricp, STL_LID lid, PortData *pd); extern void FreeLidMap(FabricData_t *fabricp); static __inline uint32 ComputeMulticastFDBSize(const STL_SWITCH_INFO *pSwitchInfo) { //STL Volg1 20.2.2.6.5 return (pSwitchInfo->MulticastFDBTop >= STL_LID_MULTICAST_BEGIN) ? pSwitchInfo->MulticastFDBTop-STL_LID_MULTICAST_BEGIN+1 : 0; } static __inline int getVLArb(PortData *p, int *res) { NodeData *n = p->nodep; if (n->NodeInfo.NodeType == STL_NODE_SW && p->PortNum != 0) { cl_map_item_t *it = cl_qmap_get(&n->Ports, 0); if (it == cl_qmap_end(&n->Ports)) return 1; p = PARENT_STRUCT(it, PortData, NodePortsEntry); } *res = p->PortInfo.CapabilityMask3.s.VLSchedulingConfig == STL_VL_SCHED_MODE_VLARB; return 0; } // TODO MLID offset mask should be derived from MulticastMask in // SwitchInfo or PortInfo, not hardcoded to lower 14 bits #define MULTICAST_LID_OFFSET_MASK 0x3FFF /** * Use this function to get offset in multicast FDB without * having to know multicast LID format. */ static inline uint32 GetMulticastOffset(STL_LID mlid) { // TODO should use MulticastMask and CollectiveMask from PortInfo // or SwitchInfo to determine a) if mlid is a multicast LID and b) // how many bits in mlid are offset bits return (mlid & MULTICAST_LID_OFFSET_MASK); } static inline PortData* getCapabilityPortData(NodeData *nodep, PortData *portp) { if (nodep->NodeInfo.NodeType == STL_NODE_SW && portp->PortNum != 0) return FindNodePort(nodep, 0); return portp; } static inline int getIsVLrSupported(NodeData *nodep, PortData *portp) { PortData* port = getCapabilityPortData(nodep, portp); if (port && port->PortInfo.CapabilityMask3.s.IsVLrSupported) return 1; return 0; } static inline int getIsAsyncSC2VLSupported(NodeData *nodep, PortData *portp) { PortData* port = getCapabilityPortData(nodep, portp); if (port && port->PortInfo.CapabilityMask3.s.IsAsyncSC2VLSupported) return 1; return 0; } typedef enum { SC2VL_UPDATE_TYPE_NONE = 0, SC2VL_UPDATE_TYPE_SYNC, SC2VL_UPDATE_TYPE_ASYNC } SC2VLUpdateType; static inline SC2VLUpdateType getSC2VLUpdateType(NodeData *nodep, PortData *portp, ScvlEnum_t scvlx) { uint8_t currentPortState = portp->PortInfo.PortStates.s.PortState; boolean currentPortAsyncSC2VL = getIsAsyncSC2VLSupported(nodep, portp); // port must be at least in the Init state if (currentPortState < IB_PORT_INIT) return SC2VL_UPDATE_TYPE_NONE; // switch port 0 - special case if (nodep->NodeInfo.NodeType == STL_NODE_SW && portp->PortNum == 0) { if (scvlx == Enum_SCVLt) return SC2VL_UPDATE_TYPE_SYNC; if (scvlx == Enum_SCVLr) { if (currentPortState == IB_PORT_INIT) return SC2VL_UPDATE_TYPE_SYNC; if (currentPortAsyncSC2VL) return SC2VL_UPDATE_TYPE_ASYNC; } return SC2VL_UPDATE_TYPE_NONE; } // in link state Init only sync update is allowed if (currentPortState == IB_PORT_INIT) return SC2VL_UPDATE_TYPE_SYNC; // async update is allowed only when the link state is Armed or Active and both ports support async update if (currentPortAsyncSC2VL) { boolean neighborPortAsyncSC2VL = FALSE; if (portp->neighbor && portp->neighbor->nodep->valid) neighborPortAsyncSC2VL = getIsAsyncSC2VLSupported(portp->neighbor->nodep, portp->neighbor); if (neighborPortAsyncSC2VL) return SC2VL_UPDATE_TYPE_ASYNC; } return SC2VL_UPDATE_TYPE_NONE; } /* Port Iterator structure to hold information of the port being iterated */ typedef struct _PortIteratorData { boolean lastPortFlag; }PortIteratorData; /* Port List Iterator structure to hold information of the port List being iterated */ typedef struct _PortListIteratorData { LIST_ITERATOR currentPort; }PortListIteratorData; /* Node Iterator structure to hold information of the node being iterated */ typedef struct _NodeIteratorData { boolean lastNodeFlag; cl_map_item_t *pCurrentPort; }NodeIteratorData; /* Node List Iterator structure to hold information of the node list being iterated */ typedef struct _NodeListIteratorData { LIST_ITERATOR currentNode; cl_map_item_t *pCurrentPort; }NodeListIteratorData; /* Ioc Iterator structure to hold information of the Ioc being iterated */ #if !defined(VXWORKS) || defined(BUILD_DMC) typedef struct _IocIteratorData { boolean lastIocFlag; cl_map_item_t *pCurrentPort; }IocIteratorData; /* Ioc List Iterator structure to hold information of the Ioc Lst being iterated */ typedef struct _IocListIteratorData { LIST_ITERATOR currentNode; cl_map_item_t *pCurrentPort; }IocListIteratorData; #endif /* System Iterator structure to hold information of the system being iterated */ typedef struct _SystemListIteratorData { boolean lastSystemFlag; cl_map_item_t *pCurrentNode; cl_map_item_t *pCurrentPort; }SystemListIteratorData; /* Iterator structure to hold information of the point being iterated */ typedef struct _FIPortIterator { Point *pPoint; union { PortIteratorData PortIter; NodeIteratorData NodeIter; #if !defined(VXWORKS) || defined(BUILD_DMC) IocIteratorData IocIter; IocListIteratorData IocListIter; #endif SystemListIteratorData SystemIter; NodeListIteratorData NodeListIter; PortListIteratorData PortListIter; } u; }FIPortIterator; /*Finds the next non-SW port for each type in the point*/ extern PortData *FIPortIteratorHead(FIPortIterator *pFIPortIterator, Point *pFocus); /* Finds the first non-SW port for each type in the point.*/ extern PortData *FIPortIteratorNext(FIPortIterator *pFIPortIterator); #ifdef __cplusplus }; #endif #endif /* _TOPOLOGY_H */