Blame Esm/ib/src/pm/include/pm_topology.h

Packit 857059
/* BEGIN_ICS_COPYRIGHT7 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015-2018, Intel Corporation
Packit 857059
Packit 857059
Redistribution and use in source and binary forms, with or without
Packit 857059
modification, are permitted provided that the following conditions are met:
Packit 857059
Packit 857059
    * Redistributions of source code must retain the above copyright notice,
Packit 857059
      this list of conditions and the following disclaimer.
Packit 857059
    * Redistributions in binary form must reproduce the above copyright
Packit 857059
      notice, this list of conditions and the following disclaimer in the
Packit 857059
      documentation and/or other materials provided with the distribution.
Packit 857059
    * Neither the name of Intel Corporation nor the names of its contributors
Packit 857059
      may be used to endorse or promote products derived from this software
Packit 857059
      without specific prior written permission.
Packit 857059
Packit 857059
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 857059
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 857059
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit 857059
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit 857059
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 857059
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 857059
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit 857059
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit 857059
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 857059
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 857059
Packit 857059
** END_ICS_COPYRIGHT7   ****************************************/
Packit 857059
Packit 857059
/* [ICS VERSION STRING: unknown] */
Packit 857059
Packit 857059
#ifndef _PM_TOPOLOGY_H
Packit 857059
#define _PM_TOPOLOGY_H
Packit 857059
Packit 857059
#include "sm_l.h"
Packit 857059
#include "pm_l.h"
Packit 857059
#include <iba/ibt.h>
Packit 857059
#include <iba/ipublic.h>
Packit 857059
#include <stdio.h>
Packit 857059
#include <stdlib.h>
Packit 857059
#include <stdarg.h>
Packit 857059
#include <unistd.h>
Packit 857059
#include <ctype.h>
Packit 857059
#define _GNU_SOURCE
Packit 857059
#include <iba/ib_mad.h>
Packit 857059
#include <iba/stl_pm.h>
Packit 857059
#include <iba/stl_pa_priv.h>
Packit 857059
#include <iba/public/ispinlock.h>	// for ATOMIC_UINT
Packit 857059
#include <iba/public/iquickmap.h>	// for cl_qmap_t
Packit 857059
#include <limits.h>
Packit 857059
#include "cs_context.h"
Packit 857059
Packit 857059
#ifdef __cplusplus
Packit 857059
extern "C" {
Packit 857059
#endif
Packit 857059
Packit 857059
#include "iba/public/ipackon.h"
Packit 857059
Packit 857059
		// used to mark unused entries in history and freezeFrame
Packit 857059
		// also used in LastSweepIndex to indicate no sweeps done yet
Packit 857059
#define PM_IMAGE_INDEX_INVALID 0xffffffff
Packit 857059
Packit 857059
// Used By Get/Clear Vf PortCounters to Access VL 15 Counters
Packit 857059
#define HIDDEN_VL15_VF	"HIDDEN_VL15_VF"
Packit 857059
#define PA_ALL_GROUP_NAME "All"
Packit 857059
Packit 857059
// special ImageId of 0 is used to access live data
Packit 857059
// -1 is used to request Images by time
Packit 857059
// other non-zero values are of the format below
Packit 857059
// This is an opaque format, the only user known ImageIds are 0 to access
Packit 857059
// live data and -1 (0xffffffffffffffff) for images by time
Packit 857059
#define IMAGEID_LIVE_DATA			 0	// 64 bit ImageId to access live data
Packit 857059
#define IMAGEID_ABSOLUTE_TIME		-1	// 64 bit ImageID to request image by time
Packit 857059
Packit 857059
// values for ImageId.s.type field, used to determine which table to look in, or
Packit 857059
// to determine if an image came from disk.
Packit 857059
#define IMAGEID_TYPE_ANY			0	// Matches any image ID type
Packit 857059
#define IMAGEID_TYPE_FREEZE_FRAME	1	// client requested Freeze Frame
Packit 857059
#define IMAGEID_TYPE_HISTORY		2	// last sweep and recent history
Packit 857059
#define IMAGEID_TYPE_HISTORY_DISK	3	// Recent history *disk only*
Packit 857059
Packit 857059
#define IMAGEID_MAX_INSTANCE_ID		256	// 8 bit field
Packit 857059
Packit 857059
typedef union {
Packit 857059
	uint64_t	AsReg64;
Packit 857059
	struct {
Packit 857059
		// this is opaque so bitt order doesn't matter, but we use IB_BITFIELD
Packit 857059
		// so its more readable when displayed as a uint64 in debug logging
Packit 857059
		IB_BITFIELD5(uint64,
Packit 857059
			type:2,		// type of image
Packit 857059
			clientId:6,	// bit number of client within Freeze Ref Count
Packit 857059
			sweepNum:32,	// NumSweeps to provide uniqueness
Packit 857059
			instanceId:8,	// instanceId ot provide uniqueness between PM instances
Packit 857059
			index:16		// look aside index
Packit 857059
		)
Packit 857059
	} s;
Packit 857059
} ImageId_t;
Packit 857059
Packit 857059
// TBD - if we malloc Pm_t.Groups[], maybe number of groups could be dynamic
Packit 857059
#define PM_MAX_GROUPS 10	// max user configured groups
Packit 857059
#define PM_MAX_GROUPS_PER_PORT 4	// we keep this small to bound compute needs
Packit 857059
			// 4 groups plus the All group gives max of 5 groups per port
Packit 857059
			// IntLinkFlags must be at least this many bits, presently 8 bits
Packit 857059
			// and portImage->numGroups must be able to hold this value
Packit 857059
Packit 857059
// how much beyond maxLid to allocate to allow for growth without realloc
Packit 857059
#define PM_LID_MAP_SPARE	512
Packit 857059
// how much below maxLid to trigger free
Packit 857059
#define PM_LID_MAP_FREE_THRESHOLD	1024
Packit 857059
// TBD - pre-size based on subnet size?  Or perhaps have above be a function
Packit 857059
// of subnet size?
Packit 857059
Packit 857059
#ifdef __VXWORKS__
Packit 857059
/* Use 1000 to match HSM's define for MAX_VABRICS which is a redefinition
Packit 857059
 * of MAX_ENABLED_VFABRICS. MAX_ENABLED_VFABRICS is defined in fm_xml.h.
Packit 857059
 */
Packit 857059
#define MAX_PM_COMP_VFABRICS 1000
Packit 857059
#else /* __VXWORKS__ */
Packit 857059
#define MAX_PM_COMP_VFABRICS MAX_VFABRICS
Packit 857059
#endif /* __VXWORKS__ */
Packit 857059
Packit 857059
extern uint32_t g_pmDebugPerf;
Packit 857059
Packit 857059
// This is a consolidation of the counters of interest from PortStatus
Packit 857059
// We use the same datatypes for each counter (hence same range) as in PMA
Packit 857059
typedef struct PmCompositePortCounters_s {
Packit 857059
	uint8	PortNumber;
Packit 857059
	uint8	Reserved[3];
Packit 857059
	uint32	VLSelectMask;
Packit 857059
	uint64	PortXmitData;
Packit 857059
	uint64	PortRcvData;
Packit 857059
	uint64	PortXmitPkts;
Packit 857059
	uint64	PortRcvPkts;
Packit 857059
	uint64	PortMulticastXmitPkts;
Packit 857059
	uint64	PortMulticastRcvPkts;
Packit 857059
	uint64	PortXmitWait;
Packit 857059
	uint64	SwPortCongestion;
Packit 857059
	uint64	PortRcvFECN;
Packit 857059
	uint64	PortRcvBECN;
Packit 857059
	uint64	PortXmitTimeCong;
Packit 857059
	uint64	PortXmitWastedBW;
Packit 857059
	uint64	PortXmitWaitData;
Packit 857059
	uint64	PortRcvBubble;
Packit 857059
	uint64	PortMarkFECN;
Packit 857059
	uint64	PortRcvConstraintErrors;
Packit 857059
	uint64	PortRcvSwitchRelayErrors;
Packit 857059
	uint64	PortXmitDiscards;
Packit 857059
	uint64	PortXmitConstraintErrors;
Packit 857059
	uint64	PortRcvRemotePhysicalErrors;
Packit 857059
	uint64	LocalLinkIntegrityErrors;
Packit 857059
	uint64	PortRcvErrors;
Packit 857059
	uint64	ExcessiveBufferOverruns;
Packit 857059
	uint64	FMConfigErrors;
Packit 857059
	uint32	LinkErrorRecovery;
Packit 857059
	uint32	LinkDowned;
Packit 857059
	uint8	UncorrectableErrors;
Packit 857059
	union {
Packit 857059
		uint8 AsReg8;
Packit 857059
		struct {
Packit 857059
#if CPU_BE
Packit 857059
			uint8 NumLanesDown:4;
Packit 857059
			uint8 Reserved:1;
Packit 857059
			uint8 LinkQualityIndicator:3;
Packit 857059
#else
Packit 857059
			uint8 LinkQualityIndicator:3;
Packit 857059
			uint8 Reserved:1;
Packit 857059
			uint8 NumLanesDown:4;
Packit 857059
#endif	// CPU_BE
Packit 857059
		} s;
Packit 857059
	} lq;
Packit 857059
Packit 857059
	uint8	Reserved2[30];
Packit 857059
Packit 857059
} PmCompositePortCounters_t;
Packit 857059
Packit 857059
typedef struct _vls_pctrs PmCompositeVLCounters_t;
Packit 857059
Packit 857059
Packit 857059
typedef struct PmCompositeVfvlmap_s {
Packit 857059
	uint32	vlmask;
Packit 857059
	uint32  VF; //index into vf array
Packit 857059
} PmCompositeVfvlmap_t;
Packit 857059
Packit 857059
typedef struct _port_error_info PmCompositeErrorInfo_t;
Packit 857059
Packit 857059
#define UPDATE_MAX(max, cnt) do { if (cnt > max) max = cnt; } while (0)
Packit 857059
#define UPDATE_MIN(min, cnt) do { if (cnt < min) min = cnt; } while (0)
Packit 857059
Packit 857059
Packit 857059
// for tracking Bandwidth utilization, we use MB/s in uint32 containers
Packit 857059
// for reference the maximum theoretical MB/s is as follows:
Packit 857059
// where MB = 1024*1024 Bytes
Packit 857059
// Max MBps 1x SDR=238
Packit 857059
// Max MBps 4x SDR=953
Packit 857059
// Max MBps 4x DDR=1907
Packit 857059
// Max MBps 4x QDR=3814
Packit 857059
// Max MBps 8x QDR=7629
Packit 857059
// Max MBps 8x EDR=15258
Packit 857059
// Max MBps 8x HDR=30516
Packit 857059
// Max MBps 12x HDR=45768
Packit 857059
Packit 857059
// for tracking packet rate, we use Kilo packet/s units in uint32 containers
Packit 857059
// where KP = 1024 packets
Packit 857059
// Max KPps 1x SDR=8704
Packit 857059
// Max KPps 4x SDR=34852
Packit 857059
// Max KPps 4x DDR=69741
Packit 857059
// Max KPps 4x QDR=139483
Packit 857059
// Max KPps 8x QDR=279003
Packit 857059
// Max KPps 8x EDR=558006
Packit 857059
// Max KPps 8x HDR=1116013
Packit 857059
// Max KPps 12x HDR=1673801
Packit 857059
Packit 857059
// number of errors of each "error class" per interval (NOT per second).
Packit 857059
// tracked per "half link".  Problem is associated with direction
Packit 857059
// having problem, we associate count with "destination" port although
Packit 857059
// both sides can be partial causes.
Packit 857059
// counters are same size as PMA(PortCounters) since beyond that
Packit 857059
// PMA will peg counter for given analysis interval
Packit 857059
typedef struct ErrorSummary_s {
Packit 857059
	uint32 Integrity;
Packit 857059
	uint32 Congestion;
Packit 857059
	uint32 SmaCongestion;
Packit 857059
	uint32 Bubble;
Packit 857059
	uint32 Security;
Packit 857059
	uint32 Routing;
Packit 857059
Packit 857059
	uint16 UtilizationPct10;        	/* in units of 10% */
Packit 857059
	uint16 DiscardsPct10;           	/* in units of 10% */
Packit 857059
	uint32 Reserved;
Packit 857059
} PACK_SUFFIX ErrorSummary_t;
Packit 857059
Packit 857059
// weight to use for each Integrity counter in weighted sum
Packit 857059
typedef struct IntegrityWeights_s {
Packit 857059
	uint8 LocalLinkIntegrityErrors;
Packit 857059
	uint8 PortRcvErrors;
Packit 857059
	uint8 ExcessiveBufferOverruns;
Packit 857059
	uint8 LinkErrorRecovery;
Packit 857059
	uint8 LinkDowned;
Packit 857059
	uint8 UncorrectableErrors;
Packit 857059
	uint8 FMConfigErrors;
Packit 857059
	uint8 LinkQualityIndicator;
Packit 857059
	uint8 LinkWidthDowngrade;
Packit 857059
} IntegrityWeights_t;
Packit 857059
Packit 857059
// weight to use for each Congestion counter in weighted sum
Packit 857059
typedef struct CongestionWeights_s {
Packit 857059
	uint8 PortXmitWait;
Packit 857059
	uint8 SwPortCongestion;
Packit 857059
	uint8 PortRcvFECN;
Packit 857059
	uint8 PortRcvBECN;
Packit 857059
	uint8 PortXmitTimeCong;
Packit 857059
	uint8 PortMarkFECN;
Packit 857059
} CongestionWeights_t;
Packit 857059
Packit 857059
// this type counts number of ports in given "% bucket" of util/errors
Packit 857059
// for a 20K node fabric with 4 FBB tiers, we can have 60K links with 120K ports
Packit 857059
// hence we need a uint32
Packit 857059
typedef uint32 pm_bucket_t;
Packit 857059
Packit 857059
// number of ports in this bucket for each class of errors
Packit 857059
// error class association to PMA Counters is same as in ErrorSummary_t
Packit 857059
// determination of % (to select bucket) is based on configured threshold
Packit 857059
typedef struct ErrorBucket_s {
Packit 857059
	pm_bucket_t Integrity;
Packit 857059
	pm_bucket_t Congestion;
Packit 857059
	pm_bucket_t SmaCongestion;
Packit 857059
	pm_bucket_t Bubble;
Packit 857059
	pm_bucket_t Security;
Packit 857059
	pm_bucket_t Routing;
Packit 857059
} PACK_SUFFIX ErrorBucket_t;
Packit 857059
Packit 857059
// summary of utilization statistics for a group of ports
Packit 857059
typedef struct PmUtilStats_s {
Packit 857059
	// internal intermediate data
Packit 857059
	// TBD - might be useful to report for Ext of groups like SWs and HFIs
Packit 857059
	uint64 TotMBps;	// Total of MBps of all selected ports, used to compute Avg
Packit 857059
	uint64 TotKPps;	// Total of KPps of all selected ports, used to compute Avg
Packit 857059
Packit 857059
	// bandwidth
Packit 857059
	uint32 AvgMBps;	// average MB per second of all selected ports
Packit 857059
	uint32 MinMBps;	// minimum MB per second of all selected ports
Packit 857059
	uint32 MaxMBps;	// maximum MB per second of all selected ports
Packit 857059
Packit 857059
	// Counter below counts number of ports within given % of BW utilization
Packit 857059
	pm_bucket_t BwPorts[STL_PM_UTIL_BUCKETS];
Packit 857059
Packit 857059
	// packets/sec tracking
Packit 857059
	uint32 AvgKPps;	// average kilo packets/sec of all selected ports
Packit 857059
	uint32 MinKPps;	// minimum kilo packets/sec of all selected ports
Packit 857059
	uint32 MaxKPps;	// maximum kilo packets/sec of all selected ports
Packit 857059
Packit 857059
	uint16 pmaNoRespPorts;  // Number of ports with failures but were still able
Packit 857059
							// to be included in Group/Vf Stats
Packit 857059
	uint16 topoIncompPorts; // Number of ports with failures that were not able
Packit 857059
							// to be included in Group/Vf Stats
Packit 857059
	// buckets for packets/sec % don't make much sense since theroretical
Packit 857059
	// limit is a function of packet size, hence confusing to report
Packit 857059
Packit 857059
	uint32 reserved;
Packit 857059
Packit 857059
} PACK_SUFFIX PmUtilStats_t;
Packit 857059
Packit 857059
// summary of error statistics for a group of ports
Packit 857059
typedef struct PmErrStats_s {
Packit 857059
	// For between-group stats, we take Max of us and our neighbor
Packit 857059
	// In context of Errors, Avg and Min is of limited value, hopefully
Packit 857059
	// very few ports have errors so Avg would be low and Min would be 0
Packit 857059
	// hence we only track Max
Packit 857059
	ErrorSummary_t Max;	// maximum of each count for all selected ports
Packit 857059
Packit 857059
	// Number of "half-links"/ports exceeding threshold
Packit 857059
	// for between-group buckets, we count one using the worst port in link
Packit 857059
	// for in-group we count one for each port in group
Packit 857059
	// buckets are based on % of configured threshold,
Packit 857059
	// last bucket is for >=100% of threshold
Packit 857059
	ErrorBucket_t Ports[STL_PM_CATEGORY_BUCKETS];// in group
Packit 857059
} PACK_SUFFIX PmErrStats_t;
Packit 857059
Packit 857059
struct PmPort_s;
Packit 857059
struct PmImage_s;
Packit 857059
typedef boolean (*PmComparePortFunc_t)(struct PmImage_s *pmimagep, struct PmPort_s *pmportp, char *groupName);
Packit 857059
Packit 857059
// a group is a set of ports.  A given link can be:
Packit 857059
// 	in-group - both ports are within the same group
Packit 857059
// 	between-group - one port is in and one port is outside
Packit 857059
// 		in which case we talk about Send/Recv direction relative to group
Packit 857059
// This allows customers to monitor traffic across selected links (such as
Packit 857059
// to/from storage) by putting only 1 port of link in a given group
Packit 857059
//
Packit 857059
// For error statistics, root cause is less obvious, so when going between-group
Packit 857059
// we consider an error on either side of the link as an error associated with
Packit 857059
// the External Errors
Packit 857059
//
Packit 857059
// Should be able to fit in a single MAD all the Internal Stats
Packit 857059
// 		(Ports, Util, Errors) 168 bytes
Packit 857059
// On external stats
Packit 857059
// 		(Ports, SendUtil, RecvUtil, Errors) 232 bytes
Packit 857059
typedef struct PmGroup_s {
Packit 857059
	// configuration  - unchanging, no lock needed
Packit 857059
	char Name[STL_PM_GROUPNAMELEN];	// \0 terminated
Packit 857059
	uint32_t pg_index; // index into PmImage_t.Groups[]
Packit 857059
Packit 857059
	// function to decide if new ports in topology should be added to group
Packit 857059
	PmComparePortFunc_t ComparePortFunc;
Packit 857059
Packit 857059
	// dg_index from pm_config
Packit 857059
	uint16 dg_index[STL_PM_MAX_DG_PER_PMPG]; // (-1)0xFFFF = not used
Packit 857059
} PmGroup_t;
Packit 857059
Packit 857059
typedef struct PmGroupImage_s {
Packit 857059
	uint32	NumIntPorts;	// # of ports in group for links in-group
Packit 857059
	uint32	NumExtPorts;	// # of ports in group for links between-group
Packit 857059
Packit 857059
	// statistics
Packit 857059
	PmUtilStats_t IntUtil;	// when both ports in group
Packit 857059
	PmUtilStats_t SendUtil;	// send from group to outside
Packit 857059
	PmUtilStats_t RecvUtil;	// recv by group from outside
Packit 857059
Packit 857059
// TBD better wording, don't want customer to confuse Internal to a group
Packit 857059
// with Internal to a chassis
Packit 857059
	// for Internal (in-group) we count one each port (both are in group)
Packit 857059
	// for External (between-group), we count worst of our port and its neighbor
Packit 857059
	PmErrStats_t IntErr;// in group
Packit 857059
	PmErrStats_t ExtErr;// between groups
Packit 857059
	uint8	MinIntRate;
Packit 857059
	uint8	MaxIntRate;
Packit 857059
	uint8	MinExtRate;
Packit 857059
	uint8	MaxExtRate;
Packit 857059
	uint32	padding;	// for alignment
Packit 857059
} PmGroupImage_t;
Packit 857059
Packit 857059
typedef struct PmVF_s {
Packit 857059
	char Name[MAX_VFABRIC_NAME]; // \0 terminated
Packit 857059
	uint8 isActive;
Packit 857059
} PmVF_t;
Packit 857059
Packit 857059
typedef	struct PmVFImage_s {
Packit 857059
	uint32	NumPorts;		// # of ports in VF
Packit 857059
Packit 857059
	// statistics
Packit 857059
	PmUtilStats_t IntUtil;	// all stats for VF are internal
Packit 857059
Packit 857059
	PmErrStats_t IntErr;// in VF
Packit 857059
Packit 857059
	uint8	MinIntRate;
Packit 857059
	uint8	MaxIntRate;
Packit 857059
} PmVFImage_t;
Packit 857059
Packit 857059
// for FI, one instance per Active Port
Packit 857059
// for Switch, one instance per Switch
Packit 857059
// This is not persee a node, but really a lid'ed port
Packit 857059
typedef struct PmNode_s {
Packit 857059
	ATOMIC_UINT		refCount;
Packit 857059
	cl_map_item_t	AllNodesEntry;	// engine use only, key is portGuid
Packit 857059
Packit 857059
	// these fields do not change and are tracked once for the Node
Packit 857059
	Guid_t			NodeGUID;
Packit 857059
	Guid_t			SystemImageGUID;
Packit 857059
// TBD - track system image guid?
Packit 857059
	STL_NODE_DESCRIPTION		nodeDesc;	// we keep latest name, rarely changes
Packit 857059
	uint32			changed_count;	// topology_changed_count when last saw node
Packit 857059
	uint32			deviceRevision;	// NodeInfo.Device Revision
Packit 857059
	union {
Packit 857059
		struct PmPort_s **swPorts;	// for switches only
Packit 857059
								// sized by numPorts
Packit 857059
								// some may be NULL
Packit 857059
		struct PmPort_s *caPortp;	// for FI and RTR
Packit 857059
								// exactly 1 port per FI tracked per PmNode_t
Packit 857059
								// one PmNode_t per active FI port
Packit 857059
	} up;
Packit 857059
Packit 857059
	uint8			nodeType;	// for switches only
Packit 857059
	uint8			numPorts;
Packit 857059
	// keep latest flags here, they rarely change
Packit 857059
	union {
Packit 857059
		uint16		AsReg16;
Packit 857059
		struct {
Packit 857059
			uint16	PmaAvoid:1; 			// node does not have a working PMA or
Packit 857059
											//  PM sweeping has been disabled for this Node
Packit 857059
			uint16	PmaGotClassPortInfo:1;	// has Pma capabilities been init'ed
Packit 857059
Packit 857059
			uint16	Reserved:14;			// 14 spare bits
Packit 857059
Packit 857059
		} s;
Packit 857059
	} u;
Packit 857059
Packit 857059
	// Path Information to talk to Node's PMA
Packit 857059
	// we keep latest information here, only used when doing current sweep
Packit 857059
	STL_LID			dlid;		// for PMA Redirect
Packit 857059
	uint16			pkey;		// for PMA Redirect
Packit 857059
	uint32			qpn:24;		// for PMA Redirect
Packit 857059
	uint32			sl:4;		// set when update_path
Packit 857059
	uint32			qkey;		// for PMA Redirect
Packit 857059
Packit 857059
	// per Image data protected by Pm.Image[].imageLock
Packit 857059
	// must be last in structure so can dynamically size total images in future
Packit 857059
	struct PmNodeImage_s {
Packit 857059
		// can change per sweep, so track per sweep and can be Freeze Framed
Packit 857059
		STL_LID		lid;		// for switch, its lid of port 0
Packit 857059
	} Image[1];	// sized when allocate PmNode_t
Packit 857059
} PmNode_t;
Packit 857059
Packit 857059
typedef	struct PmNodeImage_s PmNodeImage_t;
Packit 857059
Packit 857059
// queryStatus for Port
Packit 857059
#define PM_QUERY_STATUS_OK			0x0	// query success (or not yet attempted)
Packit 857059
#define PM_QUERY_STATUS_SKIP		0x1	// port skipped, no PMA or filtered
Packit 857059
#define PM_QUERY_STATUS_FAIL_QUERY	0x2	// failed to get port counters,
Packit 857059
										// path, or classportinfo
Packit 857059
#define PM_QUERY_STATUS_FAIL_CLEAR	0x3	// query ok, but failed clear
Packit 857059
Packit 857059
typedef struct _vfmap {
Packit 857059
	uint32 vlmask;
Packit 857059
} vfmap_t;
Packit 857059
Packit 857059
typedef union {
Packit 857059
	uint32 AsReg32;
Packit 857059
	struct { IB_BITFIELD8(uint32,
Packit 857059
		UtilBucket:4,	// MBps utilization bucket: 0 - PM_UTIL_BUCKETS-1
Packit 857059
						// Error Buckets (0-PM_ERR_BUCKETS-1)
Packit 857059
Packit 857059
		IntegrityBucket:3, 		// Integrity
Packit 857059
		CongestionBucket:3,		// Congestion
Packit 857059
		SmaCongestionBucket:3,	// SMA Congestion
Packit 857059
		BubbleBucket:3,			// Bubble
Packit 857059
		SecurityBucket:3,		// Security
Packit 857059
		RoutingBucket:3,		// Routing
Packit 857059
		Reserved:10)
Packit 857059
	} s;
Packit 857059
} BucketMask_t;
Packit 857059
Packit 857059
// This tracks Switch, FI and router ports
Packit 857059
typedef struct PmPort_s {
Packit 857059
	// these fields do not change and are tracked once for the Port
Packit 857059
	Guid_t			guid;           // can be 0 for switch portNum != 0
Packit 857059
	PmNode_t		*pmnodep;
Packit 857059
	uint32			capmask;        // keep latest, rarely changes
Packit 857059
Packit 857059
	uint8			portNum;
Packit 857059
	// keep latest status here, they rarely change
Packit 857059
	union {
Packit 857059
		uint8	AsReg8;
Packit 857059
		struct { IB_BITFIELD2(uint8,
Packit 857059
			PmaAvoid:1,				// PM should not sweep PMA on this Port
Packit 857059
			Reserved:7)
Packit 857059
		} s;
Packit 857059
	} u;
Packit 857059
Packit 857059
	// lid/portnum of neighbor is temp data only used while doing sweep
Packit 857059
	STL_LID 		neighbor_lid;
Packit 857059
	PORT 			neighbor_portNum;	// only valid if neighbor_lid != 0
Packit 857059
Packit 857059
	bitset_t dgMember; // Copy of DeviceGroup Memebership from SM
Packit 857059
Packit 857059
	// count warnings
Packit 857059
	uint32 groupWarnings;
Packit 857059
Packit 857059
	// protected by Pm_t.totalsLock
Packit 857059
	PmCompositePortCounters_t StlPortCountersTotal; // running total
Packit 857059
	PmCompositeVLCounters_t StlVLPortCountersTotal[MAX_PM_VLS];
Packit 857059
	// somehow configure this based on pm_config.process_vl_counters
Packit 857059
Packit 857059
	// per Image data protected by Pm.Image[].imageLock
Packit 857059
	// must be last in structure so can dynamically size total images in future
Packit 857059
	struct PmPortImage_s {
Packit 857059
		union {
Packit 857059
			uint32	AsReg32;
Packit 857059
			struct { IB_BITFIELD12(uint32,
Packit 857059
				active:1, 			// is port IB_PORT_ACTIVE (SW port 0 fixed up)
Packit 857059
				mtu:4,				// enum IB_MTU - due to actual range, 3 bits
Packit 857059
				txActiveWidth:4,	// LinkWidthDowngrade.txActive
Packit 857059
				rxActiveWidth:4,	// LinkWidthDowngrade.rxActive
Packit 857059
				activeSpeed:3,		// LinkSeed.Active
Packit 857059
				Initialized:1,		// has group membership been initialized
Packit 857059
				queryStatus:2,		// PMA query or clear result
Packit 857059
				UnexpectedClear:1,	// PMA Counters unexpectedly cleared
Packit 857059
				gotDataCntrs:1,		// Were Data Counters updated
Packit 857059
				gotErrorCntrs:1,	// Were Error Counters updated
Packit 857059
				gotErrorInfo:1,		// Was Error Info captured
Packit 857059
				Reserved:9)
Packit 857059
			} s;
Packit 857059
		} u;
Packit 857059
		struct PmPort_s	*neighbor;		// Pointer to Neighbor Port
Packit 857059
Packit 857059
		PmGroup_t 	*Groups[PM_MAX_GROUPS_PER_PORT];	// PortGroups (In additon to All) this port is a member of.
Packit 857059
		uint8		numGroups;							// Number of PortGroups
Packit 857059
		uint8		InternalBitMask;					// If Port is Internal to PortGroup Bit Mask (this and neighbor in group)
Packit 857059
Packit 857059
		uint32 		numVFs;                             // Number of VFs
Packit 857059
		vfmap_t 	vfvlmap[MAX_VFABRICS];				// VFs this port is a member of.
Packit 857059
Packit 857059
		uint32_t 	vlSelectMask;                       // Aggreate of Active VLs used by VFs (also VL 15)
Packit 857059
		CounterSelectMask_t 		clearSelectMask;	// Counter Mask of Counters Cleared after the above data was recorded
Packit 857059
Packit 857059
		// Raw PortCounters
Packit 857059
		PmCompositePortCounters_t	StlPortCounters;					// Port Level Counters
Packit 857059
		PmCompositeVLCounters_t		StlVLPortCounters[MAX_PM_VLS];		// VL Level Counters
Packit 857059
		// Delta PortCounters
Packit 857059
		PmCompositePortCounters_t	DeltaStlPortCounters;				// Port Level Counters
Packit 857059
		PmCompositeVLCounters_t		DeltaStlVLPortCounters[MAX_PM_VLS];	// VL Level Counters
Packit 857059
Packit 857059
		PmCompositeErrorInfo_t      ErrorInfo;
Packit 857059
Packit 857059
	} Image[1]; // sized when allocate PmPort_t
Packit 857059
} PmPort_t;
Packit 857059
Packit 857059
#define PM_PORT_ERROR_SUMMARY(portImage, lli, ler) \
Packit 857059
	((portImage)->StlPortCounters.PortRcvConstraintErrors + \
Packit 857059
	(portImage)->StlPortCounters.PortRcvSwitchRelayErrors + \
Packit 857059
	(portImage)->StlPortCounters.PortRcvSwitchRelayErrors + \
Packit 857059
	(portImage)->StlPortCounters.PortXmitDiscards         + \
Packit 857059
	(portImage)->StlPortCounters.PortXmitConstraintErrors + \
Packit 857059
	(portImage)->StlPortCounters.PortRcvRemotePhysicalErrors + \
Packit 857059
	((portImage)->StlPortCounters.LocalLinkIntegrityErrors >> (lli?(lli + RES_ADDER_LLI):0)) + \
Packit 857059
	(portImage)->StlPortCounters.PortRcvErrors            + \
Packit 857059
	(portImage)->StlPortCounters.ExcessiveBufferOverruns  + \
Packit 857059
	(portImage)->StlPortCounters.FMConfigErrors           + \
Packit 857059
	((portImage)->StlPortCounters.LinkErrorRecovery >> (ler?(ler + RES_ADDER_LER):0)) + \
Packit 857059
	(portImage)->StlPortCounters.LinkDowned               + \
Packit 857059
	(portImage)->StlPortCounters.UncorrectableErrors)
Packit 857059
Packit 857059
Packit 857059
typedef	struct PmPortImage_s PmPortImage_t;
Packit 857059
Packit 857059
// FI port or 1st Port of switch
Packit 857059
#define pm_node_lided_port(pmnodep) \
Packit 857059
		((pmnodep->nodeType == STL_NODE_SW) \
Packit 857059
		 	?pmnodep->up.swPorts[0]:pmnodep->up.caPortp)
Packit 857059
Packit 857059
// Image States
Packit 857059
#define PM_IMAGE_INVALID 	0	// uninitialized
Packit 857059
#define PM_IMAGE_VALID		1	// valid, available for PA queries
Packit 857059
#define PM_IMAGE_INPROGRESS	2	// in process of being swept
Packit 857059
Packit 857059
// The dispatcher allows the PM to issue multiple requests in parallel
Packit 857059
// A DispatcherNode is retained for each Node being queried in parallel
Packit 857059
// 	(up to MaxParallelNodes)
Packit 857059
// Within each DispatcherNode a list of DispatcherPorts is retained for each
Packit 857059
// Port in the node being queries in parallel (up to PmaBatchSize)
Packit 857059
typedef enum {
Packit 857059
	PM_DISP_PORT_NONE					= 0,
Packit 857059
	PM_DISP_PORT_GET_PORTSTATUS			= 1,	// Get(PortStatus) outstanding
Packit 857059
	PM_DISP_PORT_GET_PORTCOUNTERS		= 2,	// Get(PortCounters) outstanding
Packit 857059
	PM_DISP_PORT_DONE					= 3,	// all processing done for this port
Packit 857059
} PmDispPortState_t;
Packit 857059
Packit 857059
struct PmDispatcherNode_s;
Packit 857059
Packit 857059
// Return Values for MergePortIntoPacket()
Packit 857059
#define PM_DISP_SW_MERGE_DONE       0
Packit 857059
#define PM_DISP_SW_MERGE_ERROR      1
Packit 857059
#define PM_DISP_SW_MERGE_CONTINUE   2
Packit 857059
#define PM_DISP_SW_MERGE_NOMERGE    3
Packit 857059
Packit 857059
typedef struct PmDispatcherPort_s {
Packit 857059
	PmPort_t *pmportp;
Packit 857059
    struct PmDispatcherSwitchPort_s *dispNodeSwPort;
Packit 857059
	struct PmDispatcherNode_s *dispnode;	// setup once at boot
Packit 857059
	PmPortImage_t *pPortImage;
Packit 857059
	PmPortImage_t *pPortImagePrev;
Packit 857059
} PmDispatcherPort_t;
Packit 857059
Packit 857059
typedef struct PmDispatcherPacket_s {
Packit 857059
	uint64                      PortSelectMask[4];  // Ports in Packet
Packit 857059
	uint32                      VLSelectMask;
Packit 857059
	uint8                       numPorts;
Packit 857059
	uint8                       numVLs;
Packit 857059
	struct PmDispatcherNode_s  *dispnode;	        // setup once at boot
Packit 857059
	PmDispatcherPort_t         *DispPorts;
Packit 857059
} PmDispatcherPacket_t;
Packit 857059
Packit 857059
typedef enum {
Packit 857059
	PM_DISP_NODE_NONE				= 0,
Packit 857059
	PM_DISP_NODE_CLASS_INFO			= 1,	// Get(ClassPortInfo) outstanding
Packit 857059
											// Ports[0] has request
Packit 857059
	PM_DISP_NODE_GET_DATACOUNTERS	= 2,	// Getting Data Counters for Ports[]
Packit 857059
	PM_DISP_NODE_GET_ERRORCOUNTERS	= 3,	// Getting Error Counters for Ports[]
Packit 857059
	PM_DISP_NODE_CLR_PORT_STATUS	= 4,	// Clearing Counters for Ports[]
Packit 857059
	PM_DISP_NODE_GET_ERRORINFO		= 5,	// Getting ErrorInfo for Ports[]
Packit 857059
	PM_DISP_NODE_CLR_ERRORINFO		= 6,	// Clearing ErrorInfo for Ports[]
Packit 857059
	PM_DISP_NODE_DONE				= 7,	// all processing done for this node
Packit 857059
} PmDispNodeState_t;
Packit 857059
Packit 857059
struct Pm_s;
Packit 857059
Packit 857059
typedef struct PmDispatcherSwitchPort_s {
Packit 857059
	uint8	portNum;
Packit 857059
	union {
Packit 857059
		uint8	AsReg8;
Packit 857059
		struct {
Packit 857059
				uint8	IsDispatched:1;		// Port has been dispatched
Packit 857059
				uint8	DoNotMerge:1;		// Query failed, retry with out mergeing to isolate port
Packit 857059
				uint8	NeedsClear:1;		// Replaces 256-bit mask in Node Struct.
Packit 857059
				uint8	NeedsError:1;
Packit 857059
				uint8	Skip:1;				// Any other reason we should skip this packet.
Packit 857059
				uint8	NeedsErrorInfo:1;
Packit 857059
				uint8	NeedsClearErrorInfo:1;
Packit 857059
				uint8	Reserved:1;
Packit 857059
		} s;
Packit 857059
	} flags;
Packit 857059
	uint8	NumVLs;							// Number of active VLs in the Mask
Packit 857059
Packit 857059
	uint32	VLSelectMask;					// VLSelect Mask associated with port.
Packit 857059
} PmDispatcherSwitchPort_t;
Packit 857059
Packit 857059
typedef struct PmDispatcherNode_s {
Packit 857059
	struct {
Packit 857059
		PmNode_t *pmnodep;
Packit 857059
		PmDispNodeState_t state;
Packit 857059
		union {
Packit 857059
			uint8	AsReg8;
Packit 857059
			struct {
Packit 857059
				uint8	failed:1;
Packit 857059
				uint8	redirected:1;	// got PMA redirect response
Packit 857059
				uint8	needError:1;	// Summary NeedsError from PmDispatcherSwitchPort_t
Packit 857059
				uint8	needClearSome:1;
Packit 857059
				uint8	canClearAll:1;
Packit 857059
				uint8	needErrorInfo:1;	// Summary NeedsError from PmDispatcherSwitchPort_t
Packit 857059
				uint8	needClearErrorInfo:1;	// Summary NeedsError from PmDispatcherSwitchPort_t
Packit 857059
				// 1 spare bits
Packit 857059
			} s;
Packit 857059
		} u;
Packit 857059
		uint32	clearCounterSelect;	                // assumed to be same for all ports
Packit 857059
        uint8	numOutstandingPackets;	            // num packets in Dispatcher.Nodes[].Packets
Packit 857059
		uint8	numPorts;							// pmnodep structs sometimes wrong; NOW HFI=1 (always) and SW=pmnodep->numPorts+1 to include port 0
Packit 857059
        struct  PmDispatcherSwitchPort_s *nextPort; // next port to be dispatched within activePorts
Packit 857059
        PmDispatcherSwitchPort_t *activePorts;      // Array of Structures to keep track usefull information relating to a port
Packit 857059
	} info;
Packit 857059
	struct Pm_s *pm;	                // setup once at boot
Packit 857059
	PmDispatcherPacket_t *DispPackets;	// allocated array of PmaBatchSize
Packit 857059
} PmDispatcherNode_t;
Packit 857059
Packit 857059
typedef struct PmImage_s {
Packit 857059
	// These fields are protected by Pm.stateLock
Packit 857059
	uint8		state;		// Image State
Packit 857059
	uint8		nextClientId;// next clientId for FreezeFrame of this image
Packit 857059
	uint32		sweepNum;	// NumSweeps when we did this sweep
Packit 857059
	uint32 		historyIndex;// history index corresponding to this image
Packit 857059
	uint64		ffRefCount;	// 1 bit per FF clientId, indicates image in
Packit 857059
							// use by FreezeFrame with given ClientId
Packit 857059
							// when 0, no FreezeFrames reference this Image
Packit 857059
	time_t		lastUsed;	// timestamp of last reference, used to age FF
Packit 857059
Packit 857059
Packit 857059
	Lock_t		imageLock;	// Lock image data (except state and imageId).
Packit 857059
							// also protects Port.Image, Node.Image
Packit 857059
							// and Group.Image for given imageIndex
Packit 857059
Packit 857059
	// for rapid lookup, we index by LID.  < 48K LIDs, so mem size tolerable
Packit 857059
	// We dynamic allocate and size based on old_topology.maxLid
Packit 857059
	// allocates PM_LID_MAP_SPARE extra when grows and only releases when
Packit 857059
	// more than PM_LIB_MAP_FREE_THRESHOLD decrease in maxLid, hence
Packit 857059
	// avoiding resizing for minor fabric changes.
Packit 857059
// TBD - SM LidMap could similarly use an array for rapid lookup
Packit 857059
// and keep lidmap, maxlid, size per sweep
Packit 857059
	PmNode_t	**LidMap;
Packit 857059
	STL_LID	lidMapSize;	// number of entries allocated in LidMap
Packit 857059
	STL_LID	maxLid;
Packit 857059
Packit 857059
	time_t		sweepStart;	// when started sweep, seconds since 1970
Packit 857059
	uint32		sweepDuration;	// in usec
Packit 857059
	uint32      imageInterval; // in sec
Packit 857059
Packit 857059
	// counts of devices found during this sweep
Packit 857059
	uint16		HFIPorts;		// count of active HFI ports
Packit 857059
// TFI not included in Gen1
Packit 857059
//	uint16		TFIPorts;		// count of active TFI ports
Packit 857059
	uint16		SwitchNodes;	// count of Switch Nodes
Packit 857059
	uint32		SwitchPorts;	// count of Switch Ports (includes Port 0)
Packit 857059
	uint32		NumLinks;		// count of links (includes internal)
Packit 857059
	uint32		NumSMs;			// count of SMs (including us)
Packit 857059
	struct PmSmInfo {
Packit 857059
		STL_LID	smLid;			// implies port, 0 if empty record
Packit 857059
		uint8	priority:4;		// present priority
Packit 857059
		uint8	state:4;		// present state
Packit 857059
	} SMs[2];					// track just master and 1st secondary
Packit 857059
	// summary of errors during of sweep
Packit 857059
								// Nodes = Switch Node or a FI Port
Packit 857059
	uint32		NoRespNodes;	// failed to get path or access PMA >=1 port
Packit 857059
	uint32		NoRespPorts;	// failed to get path or access PMA
Packit 857059
	uint32		SkippedNodes;	// Skipped all ports on Node
Packit 857059
	uint32		SkippedPorts;	// No PMA or filtered
Packit 857059
	uint32		UnexpectedClearPorts;	// Ports which whose counters decreased
Packit 857059
	uint32		DowngradedPorts; // Ports whose Link Width has been downgraded
Packit 857059
	uint32		ErrorInfoPorts;
Packit 857059
Packit 857059
	// User Configured Groups + HFIs and SWs (All is implied)
Packit 857059
	uint32 NumGroups;
Packit 857059
	PmGroup_t Groups[PM_MAX_GROUPS];
Packit 857059
Packit 857059
	uint32 NumVFs;
Packit 857059
	uint32 NumVFsActive;
Packit 857059
	PmVF_t VFs[MAX_VFABRICS];
Packit 857059
} PmImage_t;
Packit 857059
Packit 857059
// --------------- Short-Term PA History --------------------
Packit 857059
//TBD: OPA_VERSION_MAJOR should be moved to a more generic location
Packit 857059
#define OPA_VERSION_MAJOR 10
Packit 857059
#define PM_HISTORY_VERSION (11 | (OPA_VERSION_MAJOR << 24))
Packit 857059
// Old version currently supported by PA
Packit 857059
#define PM_HISTORY_VERSION_OLD 10
Packit 857059
Packit 857059
#define PM_HISTORY_FILENAME_LEN 136		// max length of full filepath
Packit 857059
										// MUST BE MULTIPLE OF 8
Packit 857059
#define PM_HISTORY_MAX_IMAGES_PER_COMPOSITE 60
Packit 857059
#define PM_HISTORY_MAX_SMS_PER_COMPOSITE 2
Packit 857059
#define PM_HISTORY_MAX_LOCATION_LEN 111
Packit 857059
Packit 857059
#define PM_MAX_COMPRESSION_DIVISIONS 32
Packit 857059
#define PM_HISTORY_STHFILE_LEN 15 // the exact length of the filename, not full path
Packit 857059
Packit 857059
typedef struct PmCompositePort_s {
Packit 857059
	uint64	guid;
Packit 857059
	union {
Packit 857059
		uint32	AsReg32;
Packit 857059
		struct { IB_BITFIELD11(uint32,
Packit 857059
			active:1, 			// is port IB_PORT_ACTIVE (SW port 0 fixed up)
Packit 857059
			mtu:4,				// enum IB_MTU - due to actual range, 3 bits
Packit 857059
			txActiveWidth:4,	// LinkWidthDowngrade.txActive
Packit 857059
			rxActiveWidth:4,	// LinkWidthDowngrade.rxActive
Packit 857059
			activeSpeed:3,		// LinkSeed.Active
Packit 857059
			Initialized:1,		// has group membership been initialized
Packit 857059
			queryStatus:2,		// PMA query or clear result
Packit 857059
			UnexpectedClear:1,	// PMA Counters unexpectedly cleared
Packit 857059
			gotDataCntrs:1,		// Were Data Counters updated
Packit 857059
			gotErrorCntrs:1,	// Were Error Counters updated
Packit 857059
			Reserved:10)
Packit 857059
		} s;
Packit 857059
	} u;
Packit 857059
	STL_LID neighborLid;
Packit 857059
Packit 857059
	PORT	portNum;
Packit 857059
	PORT	neighborPort;
Packit 857059
	uint8   InternalBitMask;
Packit 857059
	uint8	numGroups;
Packit 857059
	uint8	groups[PM_MAX_GROUPS_PER_PORT];
Packit 857059
Packit 857059
	uint32 numVFs;
Packit 857059
	uint32 vlSelectMask;
Packit 857059
Packit 857059
	CounterSelectMask_t clearSelectMask;
Packit 857059
	uint32 reserved99;
Packit 857059
Packit 857059
	PmCompositeVfvlmap_t compVfVlmap[MAX_PM_COMP_VFABRICS];
Packit 857059
Packit 857059
	PmCompositePortCounters_t	stlPortCounters;
Packit 857059
	PmCompositeVLCounters_t	stlVLPortCounters[MAX_PM_VLS];
Packit 857059
	PmCompositePortCounters_t	DeltaStlPortCounters;
Packit 857059
	PmCompositeVLCounters_t	DeltaStlVLPortCounters[MAX_PM_VLS];
Packit 857059
} PACK_SUFFIX PmCompositePort_t;
Packit 857059
Packit 857059
typedef struct PmCompositeNode_s {
Packit 857059
	uint64				NodeGUID;
Packit 857059
	uint64				SystemImageGUID;
Packit 857059
	char				nodeDesc[STL_NODE_DESCRIPTION_ARRAY_SIZE];
Packit 857059
	STL_LID 			lid;
Packit 857059
	uint8				nodeType;
Packit 857059
	uint8				numPorts;
Packit 857059
Packit 857059
	uint8				Reserved;
Packit 857059
Packit 857059
	uint8				reserved;
Packit 857059
	PmCompositePort_t	**ports;
Packit 857059
} PACK_SUFFIX PmCompositeNode_t;
Packit 857059
Packit 857059
typedef struct PmCompositeVF_s {
Packit 857059
	char  name[MAX_VFABRIC_NAME];
Packit 857059
	uint8 isActive;
Packit 857059
	uint8 reserved[7];
Packit 857059
} PACK_SUFFIX PmCompositeVF_t;
Packit 857059
Packit 857059
typedef struct PmCompositeGroups_s {
Packit 857059
	char name[STL_PM_GROUPNAMELEN];
Packit 857059
} PACK_SUFFIX PmCompositeGroup_t;
Packit 857059
Packit 857059
typedef struct PmHistoryHeaderCommon_s {
Packit 857059
	uint32	historyVersion;			// Must remain fixed for all versions
Packit 857059
	uint32	imageTime;
Packit 857059
	char 	filename[PM_HISTORY_FILENAME_LEN];
Packit 857059
	uint64	timestamp;
Packit 857059
	uint8	isCompressed;
Packit 857059
	uint8	reserved2;
Packit 857059
	uint16	imagesPerComposite;
Packit 857059
	uint32	imageSweepInterval;
Packit 857059
	uint64	imageIDs[PM_HISTORY_MAX_IMAGES_PER_COMPOSITE];
Packit 857059
} PACK_SUFFIX PmHistoryHeaderCommon_t;
Packit 857059
Packit 857059
typedef struct PmFileHeader_s {
Packit 857059
	PmHistoryHeaderCommon_t common;
Packit 857059
	uint64	flatSize;
Packit 857059
	uint8	numDivisions;
Packit 857059
	uint8	reserved[7];
Packit 857059
	uint64	divisionSizes[PM_MAX_COMPRESSION_DIVISIONS];
Packit 857059
} PACK_SUFFIX PmFileHeader_t;
Packit 857059
Packit 857059
typedef struct PmCompositeSmInfo_s {
Packit 857059
	STL_LID	smLid;			// implies port, 0 if empty record
Packit 857059
#if CPU_BE
Packit 857059
	uint8		priority:4;		// present priority
Packit 857059
	uint8		state:4;		// present state
Packit 857059
#else
Packit 857059
	uint8		state:4;
Packit 857059
	uint8		priority:4;
Packit 857059
#endif
Packit 857059
	uint8		reserved[3];
Packit 857059
} PACK_SUFFIX PmCompositeSmInfo_t;
Packit 857059
Packit 857059
typedef struct PmCompositeImage_s {
Packit 857059
	PmFileHeader_t	header;
Packit 857059
	uint64	sweepStart;
Packit 857059
	uint32	sweepDuration;
Packit 857059
	uint8	reserved[2];
Packit 857059
	uint16	HFIPorts;
Packit 857059
	uint16	switchNodes;
Packit 857059
	uint16	reserved2;
Packit 857059
	uint32	switchPorts;
Packit 857059
	uint32	numLinks;
Packit 857059
	uint32 	numSMs;
Packit 857059
	uint32	noRespNodes;
Packit 857059
	uint32	noRespPorts;
Packit 857059
	uint32	skippedNodes;
Packit 857059
	uint32	skippedPorts;
Packit 857059
	uint32	unexpectedClearPorts;
Packit 857059
	uint32  downgradedPorts;
Packit 857059
	uint32	numGroups;
Packit 857059
	uint32	numVFs;
Packit 857059
	uint32	numVFsActive;
Packit 857059
	STL_LID	maxLid;
Packit 857059
	uint32	numPorts;
Packit 857059
	PmCompositeSmInfo_t SMs[PM_HISTORY_MAX_SMS_PER_COMPOSITE];
Packit 857059
	uint32  reserved3;
Packit 857059
	PmCompositeGroup_t  groups[PM_MAX_GROUPS];
Packit 857059
	PmCompositeVF_t     VFs[MAX_PM_COMP_VFABRICS];
Packit 857059
	PmCompositeNode_t   **nodes;
Packit 857059
} PACK_SUFFIX PmCompositeImage_t;
Packit 857059
Packit 857059
#define INDEX_NOT_IN_USE 0xffffffff
Packit 857059
typedef struct PmHistoryRecord_s {
Packit 857059
	PmHistoryHeaderCommon_t header;
Packit 857059
	uint32	index;
Packit 857059
	struct _imageEntry {
Packit 857059
		cl_map_item_t	historyImageEntry;	// key is image ID
Packit 857059
		uint32 inx;
Packit 857059
	} historyImageEntries[PM_HISTORY_MAX_IMAGES_PER_COMPOSITE];
Packit 857059
	cl_map_item_t imageTimeEntry;
Packit 857059
} PmHistoryRecord_t;
Packit 857059
Packit 857059
typedef struct _imageEntry PmHistoryImageEntry_t;
Packit 857059
Packit 857059
typedef struct PmShortTermHistory_s {
Packit 857059
	char	filepath[PM_HISTORY_MAX_LOCATION_LEN];
Packit 857059
	PmCompositeImage_t	*currentComposite;
Packit 857059
	uint8 compositeWritten;
Packit 857059
	uint32	currentRecordIndex;
Packit 857059
	uint64	totalDiskUsage;
Packit 857059
	cl_qmap_t	historyImages;	// map of all short term history Records, keyed by image IDs
Packit 857059
	cl_qmap_t   imageTimes;       // map of all short term history images, keyed by start time
Packit 857059
	uint32	totalHistoryRecords;
Packit 857059
	uint8	currentInstanceId;
Packit 857059
	struct _cached_images {
Packit 857059
		PmCompositeImage_t **cachedComposite;   // Array of allocated Frozen STH CompImages
Packit 857059
		time_t *lastUsed;                       // Array of last time used for the same index image
Packit 857059
		PmHistoryRecord_t **records;            // Array to indicate what record is frozen in above arrays
Packit 857059
	} CachedImages;
Packit 857059
	struct _loaded_image {
Packit 857059
		PmImage_t *img;
Packit 857059
		PmHistoryRecord_t *record;  // pointer to record of the loaded image
Packit 857059
		time_t lastUsed; // time of last access.
Packit 857059
	} LoadedImage;
Packit 857059
	char	**invalidFiles; // keeps track of history filenames with a version mismatch
Packit 857059
	uint32	oldestInvalid; // index of the oldest invalid file
Packit 857059
	PmHistoryRecord_t	**historyRecords;
Packit 857059
} PmShortTermHistory_t;
Packit 857059
Packit 857059
// ----------------------------------------------------------
Packit 857059
typedef struct PmDispPerfMap_s {
Packit 857059
	uint16 phase_aid;
Packit 857059
	uint8  phase_node_type;
Packit 857059
	uint8  phase_method;
Packit 857059
	size_t phase_offset;
Packit 857059
} PmDispPerfMap_t;
Packit 857059
Packit 857059
typedef struct PmDispatcherPerfPhase_s {
Packit 857059
	uint64_t phase_start;
Packit 857059
	uint64_t phase_end;
Packit 857059
	uint64_t min_roundtrip_time;
Packit 857059
	uint64_t max_roundtrip_time;
Packit 857059
	uint64_t sum_roundtrip_time;
Packit 857059
	uint64_t phase_count;
Packit 857059
} PmDispatcherPerfPhase_t;
Packit 857059
typedef struct PmDispatcherPerf_s {
Packit 857059
	uint64_t callback_calc_time;
Packit 857059
	PmDispatcherPerfPhase_t hfi_get_cpi;
Packit 857059
	PmDispatcherPerfPhase_t sw_get_cpi;
Packit 857059
	PmDispatcherPerfPhase_t hfi_get_cntrs;
Packit 857059
	PmDispatcherPerfPhase_t sw_get_data_cntrs;
Packit 857059
	PmDispatcherPerfPhase_t sw_get_error_cntrs;
Packit 857059
	PmDispatcherPerfPhase_t hfi_clr_cntrs;
Packit 857059
	PmDispatcherPerfPhase_t sw_clr_cntrs;
Packit 857059
	PmDispatcherPerfPhase_t hfi_get_error_info;
Packit 857059
	PmDispatcherPerfPhase_t sw_get_error_info;
Packit 857059
	PmDispatcherPerfPhase_t hfi_set_error_info;
Packit 857059
	PmDispatcherPerfPhase_t sw_set_error_info;
Packit 857059
} PmDispatcherPerf_t;
Packit 857059
Packit 857059
// high level PM configuration and statistics
Packit 857059
typedef struct Pm_s {
Packit 857059
	ATOMIC_UINT		refCount;	// used to avoid race between engine shutdown
Packit 857059
								// and PA client.  Counts number of PA client
Packit 857059
								// queries in progress.
Packit 857059
	Lock_t			stateLock;	// a RWTHREAD_LOCK.
Packit 857059
							// Protects: LastSweepIndex, NumSweeps,
Packit 857059
							//      lastHistoryIndex, history[], freezeFrames[]
Packit 857059
							// and the following Image[] fields:
Packit 857059
							//      state, nextClientId, sweepNum, ffRefCount,
Packit 857059
							//      lastUsed, historyIndex
Packit 857059
	uint32 LastSweepIndex;	// last completed sweep, see PM_SWEEP_INDEX_INVALID
Packit 857059
	uint32 lastHistoryIndex;// history index corresponding to lastSweepIndex
Packit 857059
	uint32 NumSweeps;	// total sweeps completed, only written by engine thread
Packit 857059
Packit 857059
	Lock_t			totalsLock;	// a RWTHREAD_LOCK.
Packit 857059
							// Protects: PmPort_t.PortCountersTotal
Packit 857059
Packit 857059
	// these are look aside buffers to translate from a ImageId to an ImageIndex
Packit 857059
	uint32 *history;			// exclusively for HISTORY
Packit 857059
	uint32 *freezeFrames;		// exclusively for FREEZE_FRAME
Packit 857059
Packit 857059
	// configuration settings
Packit 857059
	uint32 pmFlags;     // configured (see stl_pa_types.h pmFlags for a list)
Packit 857059
	uint16 interval;    // Sweep Interval (in seconds)
Packit 857059
	ErrorSummary_t Thresholds;             // Category Threshold Values
Packit 857059
	IntegrityWeights_t integrityWeights;   // Weight applied to Counters before calculating Category
Packit 857059
	CongestionWeights_t congestionWeights; // Weight applied to Counters before calculating Category
Packit 857059
	CounterSelectMask_t clearCounterSelect;     // List of counters to check against ClearThreshold
Packit 857059
	PmCompositePortCounters_t ClearThresholds;  // MAX_VALUE * (ErrorClear/8)
Packit 857059
	uint16 ErrorClear;                          // Number of 8ths before we clear a counter
Packit 857059
	// Copy from pm_config
Packit 857059
	uint32 NumGroups; // User Configured Groups + HFIs and SWs (All is implied)
Packit 857059
	PmGroup_t Groups[PM_MAX_GROUPS];
Packit 857059
Packit 857059
	// keep these as scratch area for use by current sweep, not kept per image
Packit 857059
	// private to engine thread, not protected by lock
Packit 857059
	STL_LID 	pm_slid;	// SLID for packets we send
Packit 857059
	uint32		changed_count;	// last pass synchronized topology with SM
Packit 857059
	uint32 		SweepIndex;	// sweep in progress, no lock needed
Packit 857059
	cl_qmap_t	AllNodes;	// all PmNode_t keyed by portGuid, engine use only
Packit 857059
Packit 857059
	// these are private to engine, used to hold sizes for various structures
Packit 857059
	// to account for the current pm_total_images value being used
Packit 857059
	uint32		PmPortSize;	// PmPort_t size
Packit 857059
	uint32		PmNodeSize;	// PmNode_t size
Packit 857059
Packit 857059
	struct PmDispatcher_s {
Packit 857059
		generic_cntxt_t cntx;
Packit 857059
		PmDispatcherPerf_t perf_stats;
Packit 857059
		Event_t sweepDone;
Packit 857059
		uint8	postedEvent;			// have we posted the sweepDone event
Packit 857059
		STL_LID	nextLid;
Packit 857059
		uint16	numOutstandingNodes;	// num nodes in Dispatcher.Nodes
Packit 857059
		PmDispatcherNode_t *DispNodes;	// allocated array of PmMaxParallelNodes
Packit 857059
	} Dispatcher;
Packit 857059
Packit 857059
	PmShortTermHistory_t ShortTermHistory;
Packit 857059
Packit 857059
	// must be last in structure so can dynamically size total images in future
Packit 857059
	PmImage_t *Image;
Packit 857059
} Pm_t;
Packit 857059
Packit 857059
typedef struct PmVFFocusPortComputeData_s {
Packit 857059
	uint32 imageInterval;
Packit 857059
	int vfIdx;
Packit 857059
	CongestionWeights_t congestionWeights;
Packit 857059
} PmVFFocusPortComputeData_t;
Packit 857059
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_COMPOSITE_VFVLMAP(PmCompositeVfvlmap_t *Dest, uint32 numVFs)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	uint32 i;
Packit 857059
Packit 857059
	for (i = 0; i < numVFs; i++) {
Packit 857059
		Dest[i].vlmask = ntoh32(Dest[i].vlmask);
Packit 857059
	}
Packit 857059
#endif
Packit 857059
}	// End of BSWAP_PM_COMPOSITE_VFVLMAP
Packit 857059
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_COMPOSITE_PORT_COUNTERS(PmCompositePortCounters_t *Dest)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	Dest->VLSelectMask = ntoh32(Dest->VLSelectMask);
Packit 857059
	Dest->PortXmitData = ntoh64(Dest->PortXmitData);
Packit 857059
	Dest->PortRcvData = ntoh64(Dest->PortRcvData);
Packit 857059
	Dest->PortXmitPkts = ntoh64(Dest->PortXmitPkts);
Packit 857059
	Dest->PortRcvPkts = ntoh64(Dest->PortRcvPkts);
Packit 857059
	Dest->PortMulticastXmitPkts = ntoh64(Dest->PortMulticastXmitPkts);
Packit 857059
	Dest->PortMulticastRcvPkts = ntoh64(Dest->PortMulticastRcvPkts);
Packit 857059
	Dest->SwPortCongestion = ntoh64(Dest->SwPortCongestion);
Packit 857059
	Dest->SwPortCongestion = ntoh64(Dest->SwPortCongestion);
Packit 857059
	Dest->PortRcvFECN = ntoh64(Dest->PortRcvFECN);
Packit 857059
	Dest->PortRcvBECN = ntoh64(Dest->PortRcvBECN);
Packit 857059
	Dest->PortXmitTimeCong = ntoh64(Dest->PortXmitTimeCong);
Packit 857059
	Dest->PortXmitWastedBW = ntoh64(Dest->PortXmitWastedBW);
Packit 857059
	Dest->PortXmitWaitData = ntoh64(Dest->PortXmitWaitData);
Packit 857059
	Dest->PortRcvBubble = ntoh64(Dest->PortRcvBubble);
Packit 857059
	Dest->PortMarkFECN = ntoh64(Dest->PortMarkFECN);
Packit 857059
	Dest->PortRcvConstraintErrors = ntoh64(Dest->PortRcvConstraintErrors);
Packit 857059
	Dest->PortRcvSwitchRelayErrors = ntoh64(Dest->PortRcvSwitchRelayErrors);
Packit 857059
	Dest->PortXmitDiscards = ntoh64(Dest->PortXmitDiscards);
Packit 857059
	Dest->PortXmitConstraintErrors = ntoh64(Dest->PortXmitConstraintErrors);
Packit 857059
	Dest->PortRcvRemotePhysicalErrors = ntoh64(Dest->PortRcvRemotePhysicalErrors);
Packit 857059
	Dest->LocalLinkIntegrityErrors = ntoh64(Dest->LocalLinkIntegrityErrors);
Packit 857059
	Dest->PortRcvErrors = ntoh64(Dest->PortRcvErrors);
Packit 857059
	Dest->ExcessiveBufferOverruns = ntoh64(Dest->ExcessiveBufferOverruns);
Packit 857059
	Dest->FMConfigErrors = ntoh64(Dest->FMConfigErrors);
Packit 857059
	Dest->LinkErrorRecovery = ntoh32(Dest->LinkErrorRecovery);
Packit 857059
	Dest->LinkDowned = ntoh32(Dest->LinkDowned);
Packit 857059
Packit 857059
Packit 857059
#endif
Packit 857059
}	// End of BSWAP_PM_COMPOSITE_PORT_COUNTERS
Packit 857059
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_COMPOSITE_VL_COUNTERS(PmCompositeVLCounters_t *Dest, uint32 numVLs)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	uint32 i;
Packit 857059
Packit 857059
	for (i = 0; i < numVLs; i++) {
Packit 857059
		Dest[i].PortVLXmitData = ntoh64(Dest[i].PortVLXmitData);
Packit 857059
		Dest[i].PortVLRcvData = ntoh64(Dest[i].PortVLRcvData);
Packit 857059
		Dest[i].PortVLXmitPkts = ntoh64(Dest[i].PortVLXmitPkts);
Packit 857059
		Dest[i].PortVLRcvPkts = ntoh64(Dest[i].PortVLRcvPkts);
Packit 857059
		Dest[i].PortVLXmitWait = ntoh64(Dest[i].PortVLXmitWait);
Packit 857059
		Dest[i].SwPortVLCongestion = ntoh64(Dest[i].SwPortVLCongestion);
Packit 857059
		Dest[i].PortVLRcvFECN = ntoh64(Dest[i].PortVLRcvFECN);
Packit 857059
		Dest[i].PortVLRcvBECN = ntoh64(Dest[i].PortVLRcvBECN);
Packit 857059
		Dest[i].PortVLXmitTimeCong = ntoh64(Dest[i].PortVLXmitTimeCong);
Packit 857059
		Dest[i].PortVLXmitWastedBW = ntoh64(Dest[i].PortVLXmitWastedBW);
Packit 857059
		Dest[i].PortVLXmitWaitData = ntoh64(Dest[i].PortVLXmitWaitData);
Packit 857059
		Dest[i].PortVLRcvBubble = ntoh64(Dest[i].PortVLRcvBubble);
Packit 857059
		Dest[i].PortVLMarkFECN = ntoh64(Dest[i].PortVLMarkFECN);
Packit 857059
		Dest[i].PortVLXmitDiscards = ntoh64(Dest[i].PortVLXmitDiscards);
Packit 857059
	}
Packit 857059
#endif
Packit 857059
}	// End of BSWAP_PM_COMPOSITE_VL_COUNTERS
Packit 857059
Packit 857059
// Composite Ports are flattened (not array of pointers)
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_COMPOSITE_PORT(PmCompositePort_t *Dest, uint32 numPorts)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	uint32 i;
Packit 857059
Packit 857059
	for (i = 0; i < numPorts; i++) {
Packit 857059
		Dest[i].guid = ntoh64(Dest[i].guid);
Packit 857059
Packit 857059
		Dest[i].u.AsReg32 = ntoh32(Dest[i].u.AsReg32);
Packit 857059
		Dest[i].neighborLid = ntoh32(Dest[i].neighborLid);
Packit 857059
Packit 857059
		Dest[i].vlSelectMask = ntoh32(Dest[i].vlSelectMask);
Packit 857059
		Dest[i].clearSelectMask.AsReg32 = ntoh32(Dest[i].clearSelectMask.AsReg32);
Packit 857059
Packit 857059
		BSWAP_PM_COMPOSITE_VFVLMAP(Dest[i].compVfVlmap, MAX_VFABRICS);
Packit 857059
Packit 857059
		BSWAP_PM_COMPOSITE_PORT_COUNTERS(&Dest[i].stlPortCounters);
Packit 857059
		BSWAP_PM_COMPOSITE_VL_COUNTERS(Dest[i].stlVLPortCounters, MAX_PM_VLS);
Packit 857059
Packit 857059
		BSWAP_PM_COMPOSITE_PORT_COUNTERS(&Dest[i].DeltaStlPortCounters);
Packit 857059
		BSWAP_PM_COMPOSITE_VL_COUNTERS(Dest[i].DeltaStlVLPortCounters, MAX_PM_VLS);
Packit 857059
	}
Packit 857059
#endif
Packit 857059
}	// End of BSWAP_PM_COMPOSITE_PORT
Packit 857059
Packit 857059
// Composite Nodes are flattened (not array of pointers)
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_COMPOSITE_NODE(PmCompositeNode_t *Dest, uint32 numNodes)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	PmCompositeNode_t *cnode = Dest;
Packit 857059
	uint32 i, numPorts;
Packit 857059
Packit 857059
	for (i = 0; i < numNodes; i++) {
Packit 857059
		numPorts = (cnode->nodeType == STL_NODE_SW ? cnode->numPorts+1 : cnode->numPorts);
Packit 857059
		cnode->NodeGUID = ntoh64(cnode->NodeGUID);
Packit 857059
		cnode->SystemImageGUID = ntoh64(cnode->SystemImageGUID);
Packit 857059
		cnode->lid = ntoh32(cnode->lid);
Packit 857059
		BSWAP_PM_COMPOSITE_PORT((PmCompositePort_t *)&cnode->ports, numPorts);
Packit 857059
		// Calc address of next (flattened) composite node
Packit 857059
		cnode = (PmCompositeNode_t *)((size_t)cnode
Packit 857059
				+ (sizeof(PmCompositeNode_t) - sizeof(PmCompositePort_t **))
Packit 857059
				+ (sizeof(PmCompositePort_t) * numPorts));
Packit 857059
	}
Packit 857059
#endif
Packit 857059
}	// End of BSWAP_PM_COMPOSITE_NODE
Packit 857059
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_COMPOSITE_SM_INFO(PmCompositeSmInfo_t *Dest, uint32 numSMs)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	uint32 i;
Packit 857059
	for (i = 0; i < numSMs; i++)
Packit 857059
		Dest[i].smLid = ntoh32(Dest[i].smLid);
Packit 857059
#endif
Packit 857059
}	// End of BSWAP_PM_COMPOSITE_SM_INFO
Packit 857059
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_HISTORY_VERSION(uint32 *Dest)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	*Dest = ntoh32(*Dest);
Packit 857059
#endif
Packit 857059
}   // End of BSWAP_PM_HISTORY_VERSION
Packit 857059
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_HISTORY_HEADER_COMMON(PmHistoryHeaderCommon_t *Dest)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	uint32 i;
Packit 857059
Packit 857059
	BSWAP_PM_HISTORY_VERSION(&Dest->historyVersion);
Packit 857059
	Dest->imageTime = ntoh32(Dest->imageTime);
Packit 857059
	Dest->timestamp = ntoh64(Dest->timestamp);
Packit 857059
	Dest->imagesPerComposite = ntoh16(Dest->imagesPerComposite);
Packit 857059
	Dest->imageSweepInterval = ntoh32(Dest->imageSweepInterval);
Packit 857059
	for (i = 0; i < PM_HISTORY_MAX_IMAGES_PER_COMPOSITE; i++)
Packit 857059
		Dest->imageIDs[i] = ntoh64(Dest->imageIDs[i]);
Packit 857059
Packit 857059
#endif
Packit 857059
}	// End of BSWAP_PM_HISTORY_HEADER_COMMON
Packit 857059
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_FILE_HEADER(PmFileHeader_t *Dest)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	uint32 i;
Packit 857059
Packit 857059
	BSWAP_PM_HISTORY_HEADER_COMMON(&Dest->common);
Packit 857059
	Dest->flatSize = ntoh64(Dest->flatSize);
Packit 857059
	for (i = 0; i < PM_MAX_COMPRESSION_DIVISIONS; i++)
Packit 857059
		Dest->divisionSizes[i] = ntoh64(Dest->divisionSizes[i]);
Packit 857059
#endif
Packit 857059
}	// End of BSWAP_PM_FILE_HEADER
Packit 857059
Packit 857059
// Byte-swap flattened Composite Image
Packit 857059
static __inline
Packit 857059
void
Packit 857059
BSWAP_PM_COMPOSITE_IMAGE_FLAT(PmCompositeImage_t *Dest, boolean hton /*, uint32 historyVersion*/)
Packit 857059
{
Packit 857059
#if CPU_LE
Packit 857059
	uint32 numNodes;
Packit 857059
	PmCompositeNode_t *cnodes = (PmCompositeNode_t *)&Dest->nodes;
Packit 857059
Packit 857059
	// Note that header is swapped independently
Packit 857059
	if (hton) {
Packit 857059
		numNodes = Dest->maxLid + 1;
Packit 857059
		Dest->maxLid = ntoh32(Dest->maxLid);
Packit 857059
	} else {
Packit 857059
		Dest->maxLid = ntoh32(Dest->maxLid);
Packit 857059
		numNodes = Dest->maxLid + 1;
Packit 857059
	}
Packit 857059
	Dest->sweepStart = ntoh64(Dest->sweepStart);
Packit 857059
	Dest->sweepDuration = ntoh32(Dest->sweepDuration);
Packit 857059
	Dest->HFIPorts = ntoh16(Dest->HFIPorts);
Packit 857059
	Dest->switchNodes = ntoh16(Dest->switchNodes);
Packit 857059
	Dest->switchPorts = ntoh32(Dest->switchPorts);
Packit 857059
	Dest->numLinks = ntoh32(Dest->numLinks);
Packit 857059
	Dest->numSMs = ntoh32(Dest->numSMs);
Packit 857059
	Dest->noRespNodes = ntoh32(Dest->noRespNodes);
Packit 857059
	Dest->noRespPorts = ntoh32(Dest->noRespPorts);
Packit 857059
	Dest->skippedNodes = ntoh32(Dest->skippedNodes);
Packit 857059
	Dest->skippedPorts = ntoh32(Dest->skippedPorts);
Packit 857059
	Dest->unexpectedClearPorts = ntoh32(Dest->unexpectedClearPorts);
Packit 857059
	Dest->downgradedPorts = ntoh32(Dest->downgradedPorts);
Packit 857059
	Dest->numGroups = ntoh32(Dest->numGroups);
Packit 857059
	Dest->numVFs = ntoh32(Dest->numVFs);
Packit 857059
	Dest->numVFsActive = ntoh32(Dest->numVFsActive);
Packit 857059
	Dest->numPorts = ntoh32(Dest->numPorts);
Packit 857059
	BSWAP_PM_COMPOSITE_SM_INFO(Dest->SMs, PM_HISTORY_MAX_SMS_PER_COMPOSITE);
Packit 857059
Packit 857059
	BSWAP_PM_COMPOSITE_NODE(cnodes, numNodes);
Packit 857059
#endif
Packit 857059
}	// End of BSWAP_PM_COMPOSITE_IMAGE_FLAT
Packit 857059
Packit 857059
void clearLoadedImage(PmShortTermHistory_t *sth);
Packit 857059
size_t computeCompositeSize(void);
Packit 857059
FSTATUS decompressAndReassemble(unsigned char *input_data, size_t input_size, uint8 divs, size_t *input_sizes, unsigned char *output_data, size_t output_size);
Packit 857059
FSTATUS rebuildComposite(PmCompositeImage_t *cimg, unsigned char *data, uint32 history_version);
Packit 857059
void writeImageToBuffer(Pm_t *pm, uint32 histindex, uint8_t isCompressed, uint8_t *buffer, uint32_t *bIndex);
Packit 857059
void PmFreeComposite(PmCompositeImage_t *cimg);
Packit 857059
FSTATUS PmLoadComposite(Pm_t *pm, PmHistoryRecord_t *record, PmCompositeImage_t **cimg);
Packit 857059
FSTATUS PmFreezeComposite(Pm_t *pm, PmHistoryRecord_t *record, int *idx);
Packit 857059
FSTATUS PmFreezeCurrent(Pm_t *pm, int *idx);
Packit 857059
void PmReconstituteVFImage(PmCompositeVF_t *cVF, PmVF_t *pmVFP);
Packit 857059
void PmReconstituteGroupImage(PmCompositeGroup_t *cgroup, PmGroup_t *pmGroupP);
Packit 857059
PmPort_t *PmReconstitutePortImage(PmImage_t *img, PmCompositePort_t *cport);
Packit 857059
PmNode_t *PmReconstituteNodeImage(PmImage_t *img, PmCompositeNode_t *cnode);
Packit 857059
PmImage_t *PmReconstituteImage(PmCompositeImage_t *cimg);
Packit 857059
FSTATUS PmReconstitute(PmShortTermHistory_t *sth, PmCompositeImage_t *cimg);
Packit 857059
Packit 857059
// Lock Heirachy (acquire in this order):
Packit 857059
// 		SM topology locks
Packit 857059
// 		Pm.stateLock
Packit 857059
// 		Image.imageLock for freeze frames, (in index order, low to high)
Packit 857059
// 		Image.imageLock for sweeps, (in index order, most recent to oldest)
Packit 857059
// 		Pm.totalsLock
Packit 857059
//
Packit 857059
// Pm.stateLock is a rwlock, protects:
Packit 857059
//     LastSweepIndex, NumSweeps, lastHistoryIndex, history[], freezeFrames[]
Packit 857059
//     and the following Image[] fields:
Packit 857059
//         state, nextClientId, sweepNum, ffRefCount, lastUsed, historyIndex
Packit 857059
// Note that NumSweeps and LastSweepIndex are only changed by engine thread,
Packit 857059
// hence engine thread can safely read it without a lock
Packit 857059
// Pm.SweepIndex is for use by engine only, no lock needed
Packit 857059
//
Packit 857059
// Pm.Image[index].imageLock is a rwlock, protects:
Packit 857059
// 	all data in image (including PmPort_t.Image[index], PmNode_t.Image[index]
Packit 857059
// 		and Pmgroup_t.Image[index]
Packit 857059
// 		except for fields protected by Pm.stateLock
Packit 857059
// 	pa_access must have this lock and verify state == VALID
Packit 857059
// 	Engine must get this lock in order to update topology or per image stats
Packit 857059
//
Packit 857059
// Pm.totalsLock is a rwlock, protects:
Packit 857059
//     PmPort_t.PortCountersTotal
Packit 857059
//
Packit 857059
// INPROGRESS state helps avoid clients blocking for long duration once
Packit 857059
// engine starts sweep.  It can also be used in ASSERTs as a secondary check
Packit 857059
// to make sure clients are accessing valid data.
Packit 857059
// Algorithm for stateLock allows client to check state before tring to
Packit 857059
// get imageLock.
Packit 857059
//
Packit 857059
// pa_access query (for lastsweep, history or freeze frame query):
Packit 857059
// 	rdlock Pm.stateLock
Packit 857059
// 	index= convert image Id using Pm.LastSweepIndex	//copy to local while locked
Packit 857059
//  if Pm.Image[index].state != VALID - error
Packit 857059
//  		(client should not access a freeze area until gets response)
Packit 857059
// 	rdlock Pm.Image[index].imageLock
Packit 857059
// 	rwunlock Pm.stateLock
Packit 857059
// 	if accessing PortCountersTotal, rdlock Pm.totalsLock (wrlock to clear Total)
Packit 857059
// 	analyze data in Pm.Image[index]
Packit 857059
// 	if accessed PortCountersTotal, rwunlock Pm.totalsLock
Packit 857059
// 	rwunlock Pm.Image[index].imageLock
Packit 857059
//
Packit 857059
// Engine Sweep
Packit 857059
// 	wrlock Pm.stateLock
Packit 857059
//  index=Pm.SweepIndex	// engine can access SweepIndex anytime w/o a lock
Packit 857059
//  Pm.Image[index].state = INPROGRESS
Packit 857059
//  wrlock Pm.Image[index].imageLock	// make sure clients out
Packit 857059
//  rwunlock Pm.stateLock - we have in progress flag set
Packit 857059
// 	perform sweep - since it is the "active sweep" pa_access should not try to
Packit 857059
// 		lock it while we sweep, INPROGRESS also protects it
Packit 857059
// 		if alloc or resize lidmap, set to NULLs.
Packit 857059
// 			As populate, inc ref count on node
Packit 857059
// 		when done building lidmap, if have old lidmap to free, dec ref counts
Packit 857059
// 			and free nodes now 0, then free lidmap
Packit 857059
//  rwunlock Pm.Image[index].imageLock
Packit 857059
// 	wrlock Pm.stateLock
Packit 857059
// 	Pm.Image[index].state = VALID
Packit 857059
// 	update Pm.lastSweepIndex
Packit 857059
// 	rwunlock Pm.stateLock
Packit 857059
//
Packit 857059
// PA client Freeze Frame (very similar to engine sweeps):
Packit 857059
// 	wrlock Pm.stateLock
Packit 857059
// 	image = requested input image (must not be a freeze frame)
Packit 857059
// 	if Pm.Image[image].state != VALID - error
Packit 857059
// 	pick a Pm.freezeFrames[] to use (one with INVALID or already
Packit 857059
// 			pointing to image)
Packit 857059
// 			while searching, mark as invalid any freezeFrames which are stale
Packit 857059
//	pick next unused clientId in Pm.Image, set Image[image].ffRefCount bit
Packit 857059
//	Pm.freezeFrames[] = image
Packit 857059
// 	rwunlock Pm.stateLock
Packit 857059
//
Packit 857059
// freeze Frame release:
Packit 857059
//  index must specify a freeze frame type image
Packit 857059
// 	wrlock Pm.stateLock
Packit 857059
//	if Pm.Image[index].state == INVALID or INPROGRESS - error
Packit 857059
// 	reset Pm.Image[index].ffRefCount bit for Freeze Frame Client Id
Packit 857059
// 	rwunlock Pm.stateLock
Packit 857059
//
Packit 857059
// shutdown synchronization between PA and Engine
Packit 857059
// Pm.refCount counts when PA is in PM, so don't free PM while client is
Packit 857059
// still using.
Packit 857059
// Engine shutdown:
Packit 857059
// 		set not running
Packit 857059
// 		wait for refCount to be 0
Packit 857059
// 		PmDestroy
Packit 857059
// 			if want to be paranoid, could wrlock each image before try to free
Packit 857059
// 			that way can be really sure no one is inside the image
Packit 857059
// PA client packet processing:
Packit 857059
// 		increment Pm refCount
Packit 857059
// 		check is running - dec refCount, fail query
Packit 857059
// 		do normal processing algorithm:
Packit 857059
// 			lock Pm.stateLock
Packit 857059
// 			process state
Packit 857059
// 			lock imageLock
Packit 857059
// 			unlock Pm.stateLock
Packit 857059
// 			process image
Packit 857059
// 			send response packet
Packit 857059
// 			unlock imageLock
Packit 857059
// 		dec refCount
Packit 857059
Packit 857059
//
Packit 857059
// PA protocol updates:
Packit 857059
// - can specify freeze frame index
Packit 857059
// - can specify history index 0 to N
Packit 857059
// - bit to indicate if given index is history or freeze frame
Packit 857059
// - in sweep summary query, have timestamps, maxLids, etc
Packit 857059
Packit 857059
#define PM_ENGINE_STOPPED 0
Packit 857059
#define PM_ENGINE_STARTED 1
Packit 857059
#define PM_ENGINE_STOPPING 2
Packit 857059
extern int	g_pmEngineState;
Packit 857059
Packit 857059
extern boolean g_pmAsyncRcvThreadRunning;
Packit 857059
extern Sema_t g_pmAsyncRcvSema;	// indicates AsyncRcvThread is ready
Packit 857059
extern IBhandle_t hpma, pm_fd;
Packit 857059
Packit 857059
#define PM_ALLBITS_SET(select, mask) (((select) & (mask)) == (mask))
Packit 857059
Packit 857059
// Lookup a node in pmImage based on lid
Packit 857059
// caller should have pmImage->imageLock held
Packit 857059
PmNode_t *pm_find_node(PmImage_t *pmimagep, STL_LID lid);
Packit 857059
Packit 857059
// Lookup a port in pmImage based on lid and portNum
Packit 857059
// does not have to be a "lid"'ed port
Packit 857059
// caller should have pmImage->imageLock held
Packit 857059
PmPort_t *pm_find_port(PmImage_t *pmImage, STL_LID lid, uint8 portNum);
Packit 857059
Packit 857059
// Lookup a node in Pm Topology based on nodeguid
Packit 857059
PmNode_t *pm_find_nodeguid(Pm_t *pm, uint64 nodeGUID);
Packit 857059
Packit 857059
// Clear Running totals for a given Node.  This simulates a PMA clear so
Packit 857059
// that tools like opareport can work against the Running totals until we
Packit 857059
// have a history feature.
Packit 857059
// caller must have totalsLock held for write
Packit 857059
FSTATUS PmClearNodeRunningCounters(PmNode_t *pmnodep, CounterSelectMask_t select);
Packit 857059
FSTATUS PmClearNodeRunningVFCounters(Pm_t *pm, PmNode_t *pmnodep, STLVlCounterSelectMask select,
Packit 857059
	int vfIdx, boolean useHiddenVF);
Packit 857059
Packit 857059
// in mad_info.c
Packit 857059
void PmUpdateNodePmaCapabilities(PmNode_t *pmnodep, Node_t *nodep, boolean ProcessHFICounters);
Packit 857059
void PmUpdatePortPmaCapabilities(PmPort_t *pmportp, Port_t *portp);
Packit 857059
Packit 857059
// pm_mad.c
Packit 857059
FSTATUS ProcessPmaClassPortInfo(PmNode_t* pmnodep, STL_CLASS_PORT_INFO *classp);
Packit 857059
Packit 857059
// pm_dispatch.c
Packit 857059
Status_t PmDispatcherInit(Pm_t *pm);
Packit 857059
void PmDispatcherDestroy(Pm_t *pm);
Packit 857059
FSTATUS PmSweepAllPortCounters(Pm_t *pm);
Packit 857059
Packit 857059
static __inline boolean isErrorInfoNeeded(Pm_t *pm,
Packit 857059
	PmCompositePortCounters_t *curr, PmCompositePortCounters_t *prev)
Packit 857059
{
Packit 857059
	if ((pm->pmFlags & STL_PM_PROCESS_ERRORINFO) == 0) return FALSE;
Packit 857059
	if (!prev) return TRUE;
Packit 857059
Packit 857059
	// Some counters can be cleared on link bounce, so just check if they are
Packit 857059
	// different instead of current greater than previous.
Packit 857059
#define IS_DIFF_VAL(cntr) if (curr->cntr != prev->cntr) return TRUE
Packit 857059
	IS_DIFF_VAL(LinkDowned);
Packit 857059
	IS_DIFF_VAL(PortRcvErrors);
Packit 857059
	IS_DIFF_VAL(ExcessiveBufferOverruns);
Packit 857059
	IS_DIFF_VAL(PortXmitConstraintErrors);
Packit 857059
	IS_DIFF_VAL(PortRcvConstraintErrors);
Packit 857059
	IS_DIFF_VAL(PortRcvSwitchRelayErrors);
Packit 857059
	IS_DIFF_VAL(UncorrectableErrors);
Packit 857059
	IS_DIFF_VAL(FMConfigErrors);
Packit 857059
#undef IS_DIFF_VAL
Packit 857059
Packit 857059
	return FALSE;
Packit 857059
}
Packit 857059
Packit 857059
static __inline boolean isErrorInfoStatusSet(PmCompositeErrorInfo_t *pErrorInfo)
Packit 857059
{
Packit 857059
	if (pErrorInfo->PortRcvErrorInfo.s.Status)            return TRUE;
Packit 857059
	if (pErrorInfo->ExcessiveBufferOverrunInfo.s.Status)  return TRUE;
Packit 857059
	if (pErrorInfo->PortXmitConstraintErrorInfo.s.Status) return TRUE;
Packit 857059
	if (pErrorInfo->PortRcvConstraintErrorInfo.s.Status)  return TRUE;
Packit 857059
	if (pErrorInfo->PortRcvSwitchRelayErrorInfo.s.Status) return TRUE;
Packit 857059
	if (pErrorInfo->UncorrectableErrorInfo.s.Status)      return TRUE;
Packit 857059
	if (pErrorInfo->FMConfigErrorInfo.s.Status)           return TRUE;
Packit 857059
Packit 857059
	return FALSE;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
// pm_async_rcv.c
Packit 857059
extern generic_cntxt_t     *pm_async_send_rcv_cntxt;
Packit 857059
void pm_async_rcv(uint32_t argc, uint8_t ** argv);
Packit 857059
void pm_async_rcv_kill(void);
Packit 857059
Packit 857059
#define	PM_Filter_Init(FILTERP) {						\
Packit 857059
	Filter_Init(FILTERP, 0, 0);						\
Packit 857059
										\
Packit 857059
	(FILTERP)->active |= MAI_ACT_ADDRINFO; \
Packit 857059
	(FILTERP)->active |= MAI_ACT_BASE;					\
Packit 857059
	(FILTERP)->active |= MAI_ACT_TYPE;					\
Packit 857059
	(FILTERP)->active |= MAI_ACT_DATA;					\
Packit 857059
	(FILTERP)->active |= MAI_ACT_DEV;					\
Packit 857059
	(FILTERP)->active |= MAI_ACT_PORT;					\
Packit 857059
	(FILTERP)->active |= MAI_ACT_QP;					\
Packit 857059
	(FILTERP)->active |= MAI_ACT_FMASK;					\
Packit 857059
										\
Packit 857059
	(FILTERP)->type = MAI_TYPE_EXTERNAL;						\
Packit 857059
										\
Packit 857059
	(FILTERP)->dev = pm_config.hca;						\
Packit 857059
	(FILTERP)->port = (pm_config.port == 0) ? MAI_TYPE_ANY : pm_config.port;		\
Packit 857059
	(FILTERP)->qp = 1;							\
Packit 857059
}
Packit 857059
Packit 857059
// pm_sweep.c
Packit 857059
void PmClearAllNodes(Pm_t *pm);
Packit 857059
void PmSkipPort(Pm_t *pm, PmPort_t *pmportp);
Packit 857059
void PmSkipNode(Pm_t *pm, PmNode_t *pmnodep);
Packit 857059
Packit 857059
void PmFailPort(Pm_t *pm, PmPort_t *pmportp, uint8 queryStatus, uint8 method, uint16 aid);
Packit 857059
void PmFailPacket(Pm_t *pm, PmDispatcherPacket_t *disppacket, uint8 queryStatus, uint8 method, uint16 aid);
Packit 857059
void PmFailNode(Pm_t *pm, PmNode_t *pmnodep, uint8 queryStatus, uint8 method, uint16 aid);
Packit 857059
Packit 857059
// pm_debug.c
Packit 857059
void DisplayPm(Pm_t *pm);
Packit 857059
Packit 857059
uint32 computeSendMBps(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeSendKPkts(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeIntegrity(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeCongestion(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeSmaCongestion(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeBubble(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeSecurity(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeRouting(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeUtilizationPct10(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeDiscardsPct10(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeVFSendMBps(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeVFSendKPkts(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeVFCongestion(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeVFBubble(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
uint32 computeVFUtilizationPct10(Pm_t *pm, uint32 imageIndex, PmPort_t *port, void *data);
Packit 857059
Packit 857059
Packit 857059
// Given a MBps transfer rate and a theoretical maxMBps, compute the
Packit 857059
//  utilization bucket number from 0 to PM_UTIL_BUCKETS-1
Packit 857059
static __inline uint8 ComputeUtilBucket(uint32 SendMBps, uint32 maxMBps)
Packit 857059
{
Packit 857059
	if (maxMBps) {
Packit 857059
		// directly compute bucket to reduce overflow chances
Packit 857059
		uint8 utilBucket = (SendMBps * STL_PM_UTIL_BUCKETS) / maxMBps;
Packit 857059
		if (utilBucket >= STL_PM_UTIL_BUCKETS)
Packit 857059
			return STL_PM_UTIL_BUCKETS-1;
Packit 857059
		else
Packit 857059
			return utilBucket;
Packit 857059
	} else {
Packit 857059
		return 0;
Packit 857059
	}
Packit 857059
}
Packit 857059
Packit 857059
// Given a Counter Category Value and a threshold, compute the bucket number
Packit 857059
//  from 0 to PM_ERR_BUCKETS-1
Packit 857059
static __inline uint8 ComputeErrBucket(uint32 errCnt, uint32 errThreshold)
Packit 857059
{
Packit 857059
	uint8 errBucket;
Packit 857059
	if (! errThreshold) return 0;
Packit 857059
Packit 857059
	errBucket = (errCnt * (STL_PM_CATEGORY_BUCKETS-1)) / errThreshold;
Packit 857059
	if (errBucket >= STL_PM_CATEGORY_BUCKETS)
Packit 857059
		 return STL_PM_CATEGORY_BUCKETS-1;
Packit 857059
	else
Packit 857059
		 return errBucket;
Packit 857059
}
Packit 857059
Packit 857059
void PmPrintExceededPort(char *buf, size_t bufSize, PmPort_t *pmportp, uint32 index, const char *statistic, uint32 threshold, uint32 value);
Packit 857059
void PmPrintExceededPortDetailsIntegrity(char *exceededMessage, Pm_t *pm, PmPort_t *pmportp, PmPort_t *pmportneighborp, uint32 imageIndex);
Packit 857059
void PmPrintExceededPortDetailsCongestion(char *exceededMessage, Pm_t *pm, PmPort_t *pmportp, PmPort_t *pmportneighborp, uint32 imageIndex);
Packit 857059
void PmPrintExceededPortDetailsSmaCongestion(char *exceededMessage, Pm_t *pm, PmPort_t *pmportp, PmPort_t *pmportneighborp, uint32 imageIndex);
Packit 857059
void PmPrintExceededPortDetailsBubble(char *exceededMessage, Pm_t *pm, PmPort_t *pmportp, PmPort_t *pmportneighborp, uint32 imageIndex);
Packit 857059
void PmPrintExceededPortDetailsSecurity(char *exceededMessage, Pm_t *pm, PmPort_t *pmportp, PmPort_t *pmportneighborp, uint32 imageIndex);
Packit 857059
void PmPrintExceededPortDetailsRouting(char *exceededMessage, Pm_t *pm, PmPort_t *pmportp, PmPort_t *pmportneighborp, uint32 imageIndex);
Packit 857059
void PmFinalizePortStats(Pm_t *pm, PmPort_t *portp, uint32 index);
Packit 857059
boolean PmTabulatePort(Pm_t *pm, PmPort_t *portp, uint32 index,
Packit 857059
			   			uint32 *counterSelect);
Packit 857059
void ClearGroupStats(PmGroupImage_t *groupImage);
Packit 857059
void ClearVFStats(PmVFImage_t *vfImage);
Packit 857059
void FinalizeGroupStats(PmGroupImage_t *groupImage);
Packit 857059
void PmClearPortImage(PmPortImage_t *portImage);
Packit 857059
void FinalizeVFStats(PmVFImage_t *vfImage);
Packit 857059
Packit 857059
uint32_t PmCalculateRate(uint32_t speed, uint32_t width);
Packit 857059
void UpdateInGroupStats(Pm_t *pm, uint32 imageIndex, PmPort_t *port, PmGroupImage_t *groupImage, uint32 imageInterval);
Packit 857059
void UpdateExtGroupStats(Pm_t *pm, uint32 imageIndex, PmPort_t *port, PmGroupImage_t *groupImage, uint32 imageInterval);
Packit 857059
void UpdateVFStats(Pm_t *pm, uint32 imageIndex, PmPort_t *port, PmVFImage_t *vfImage, uint32 imageInterval);
Packit 857059
Packit 857059
// Clear Running totals for a given Port.  This simulates a PMA clear so
Packit 857059
// that tools like opareport can work against the Running totals until we
Packit 857059
// have a history feature.
Packit 857059
// caller must have totalsLock held for write
Packit 857059
extern FSTATUS PmClearPortRunningCounters(PmPort_t *pmportp, CounterSelectMask_t select);
Packit 857059
extern FSTATUS PmClearPortRunningVFCounters(Pm_t *pm, PmPort_t *pmportp, STLVlCounterSelectMask select, int vfIdx, boolean useHiddenVF);
Packit 857059
Packit 857059
// ? PMA Counter control allows interval and auto restart of counters, can remove
Packit 857059
// effect of PMA packet delays, etc.  Should we use it?  Does HW support it?
Packit 857059
Packit 857059
// compute theoretical limits for each rate
Packit 857059
//extern void PM_InitLswfToMBps(void);
Packit 857059
// ideally should be static, extern due to split of sweep.c and calc.c
Packit 857059
uint32 s_StaticRateToMBps[IB_STATIC_RATE_MAX+1];
Packit 857059
Packit 857059
// This group of functions accept an index into the pmportp->Groups[]
Packit 857059
// caller should search for appropriate entry in array to act on
Packit 857059
// adds a port to a group. used by PmAddExtPort and PmAddIntPort
Packit 857059
void PmAddPortToGroupIndex(PmPortImage_t* portImage, uint32 grpIndex, PmGroup_t *groupp, boolean internal);
Packit 857059
Packit 857059
boolean PmIsPortInGroup(PmImage_t *pmimagep, PmPortImage_t *portImage,
Packit 857059
	int groupIndex, boolean isAllGroup, boolean *isInternal);
Packit 857059
boolean PmIsPortInVF(PmImage_t *pmimagep, PmPortImage_t *portImage,
Packit 857059
	int vfIndex);
Packit 857059
Packit 857059
// adds a port to a group where the neighbor of the port WILL NOT be in
Packit 857059
// the given group
Packit 857059
void PmAddExtPortToGroupIndex(PmPortImage_t* portImage, uint32 grpIndex, PmGroup_t *groupp, uint32 imageIndex);
Packit 857059
Packit 857059
// adds a port to a group where the neighbor of the port WILL be in
Packit 857059
// the given group
Packit 857059
// This DOES NOT add the neighbor.  Caller must do that separately.
Packit 857059
void PmAddIntPortToGroupIndex(PmPortImage_t* portImage, uint32 grpIndex, PmGroup_t *groupp, uint32 imageIndex);
Packit 857059
Packit 857059
// compute reasonable clearThresholds based on given threshold and weights
Packit 857059
// This can be used to initialize clearThreshold and then override just
Packit 857059
// a few of the computed defaults in the even user wanted to control just a few
Packit 857059
// and default the rest
Packit 857059
void PmComputeClearThresholds(PmCompositePortCounters_t *clearThresholds,
Packit 857059
							  CounterSelectMask_t *select, uint8 errorClear);
Packit 857059
Packit 857059
// build counter select to use when clearing counters
Packit 857059
void PM_BuildClearCounterSelect(CounterSelectMask_t *select, boolean clearXfer, boolean clear64bit,
Packit 857059
								 boolean clear32bit, boolean clear8bit);
Packit 857059
Packit 857059
//  insert a shortterm history file from the Master PM into the local history filelist
Packit 857059
FSTATUS injectHistoryFile(Pm_t *pm, char *filename, uint8_t *buffer, uint32_t filelen);
Packit 857059
Packit 857059
void PmDispatcherPerfInit(PmDispatcherPerf_t *perf);
Packit 857059
Packit 857059
Packit 857059
Packit 857059
// PM Loop MACROS
Packit 857059
#define for_some_pmnodes(PMIMAGE, PMNODE, LID, START, END) \
Packit 857059
	for (LID = START, PMNODE = (PMIMAGE)->LidMap[LID]; LID <= END; ++LID, PMNODE = (PMIMAGE)->LidMap[LID]) \
Packit 857059
	if (PMNODE)
Packit 857059
Packit 857059
#define for_all_pmnodes(PMIMAGE, PMNODE, LID) \
Packit 857059
	for_some_pmnodes(PMIMAGE, PMNODE, LID, 1, (PMIMAGE)->maxLid)
Packit 857059
Packit 857059
#define pm_get_port(PMNODE, PORTNUM) ((PMNODE)->nodeType == STL_NODE_SW ? (PMNODE)->up.swPorts[PORTNUM] : (PMNODE)->up.caPortp)
Packit 857059
#define pm_get_port_idx(PMNODE) ((PMNODE)->nodeType == STL_NODE_SW ? 0 : 1)
Packit 857059
Packit 857059
#define for_some_pmports(PMNODE, PMPORT, PORTNUM, START, END) \
Packit 857059
	for (PORTNUM = START, PMPORT = pm_get_port(PMNODE, PORTNUM); \
Packit 857059
		PORTNUM <= END; \
Packit 857059
		++PORTNUM, PMPORT = pm_get_port(PMNODE, PORTNUM))
Packit 857059
Packit 857059
#define for_all_pmports(PMNODE, PMPORT, PORTNUM) \
Packit 857059
	for_some_pmports(PMNODE, PMPORT, PORTNUM, pm_get_port_idx(PMNODE), (PMNODE)->numPorts)
Packit 857059
Packit 857059
#include "iba/public/ipackoff.h"
Packit 857059
Packit 857059
#ifdef __cplusplus
Packit 857059
};
Packit 857059
#endif
Packit 857059
Packit 857059
#endif /* _PM_TOPOLOGY_H */