diff --git a/projects/amdsmi/.pre-commit-config.yaml b/projects/amdsmi/.pre-commit-config.yaml index ddf882f9a9c6..4d33afc84a32 100644 --- a/projects/amdsmi/.pre-commit-config.yaml +++ b/projects/amdsmi/.pre-commit-config.yaml @@ -26,6 +26,7 @@ exclude: | | build-.*/ | _build/ | esmi_ib_library/ + | ualoe_lib/ | third_party/ fail_fast: false diff --git a/projects/amdsmi/include/ualoe_lib/cbl_cfg/uapi.h b/projects/amdsmi/include/ualoe_lib/cbl_cfg/uapi.h index 6de99f439f3b..8b1831fd7e22 100644 --- a/projects/amdsmi/include/ualoe_lib/cbl_cfg/uapi.h +++ b/projects/amdsmi/include/ualoe_lib/cbl_cfg/uapi.h @@ -23,14 +23,23 @@ #ifndef IFOE_UAPI_H #define IFOE_UAPI_H +#include #include #include +#ifdef __KERNEL__ #include +#endif #include #define CFG_LABEL_SIZE 32 #define CFG_PCI_ADDR_MAX_LEN 32 +#define CFG_STATION_LABEL_FMT "ifoe%u" +#define CFG_NETPORT_LABEL_FMT "netport%u" + +#define CFG_NETPORT_LOGICAL_IDX(station_idx, nps, netport_rel_idx) \ + ((station_idx) * (nps) + (netport_rel_idx)) + struct cfg_label { char text[CFG_LABEL_SIZE]; }; @@ -146,6 +155,7 @@ enum cfg_telemetry_category { CFG_TELEMETRY_CATEGORY_NETPORT, CFG_TELEMETRY_CATEGORY_DERIVED_IFOE, CFG_TELEMETRY_CATEGORY_DERIVED_NETPORT, + CFG_TELEMETRY_CATEGORY_DEBUG, CFG_TELEMETRY_CATEGORY_MAX }; @@ -193,6 +203,14 @@ struct cfg_set_telemetry { #define CFG_FREE_TELEMETRY _IOW(CFG_IOC_MAGIC, 0xB, int) +struct cfg_telem_snapshot_hdr { + __u64 gen_count; + __u32 const_offset; + __u32 const_size; + __u32 dyn_offset; + __u32 dyn_size; +}; + #define CFG_L2PING_MAX_PINGS 255 /** @@ -247,16 +265,23 @@ struct cfg_l2ping_start { #define CFG_IFOE_L2PING_START _IOW(CFG_IOC_MAGIC, 0xE, struct cfg_l2ping_start) +/* Set in cfg_l2ping_netport_result.flags when the netport result does not + * reflect a real test and must be ignored (e.g. netport not bonded). + */ +#define CFG_L2PING_NETPORT_INVALID_RESULT _BITUL(0) + /** * struct cfg_l2ping_netport_result - L2 ping result for a netport * @req_failures: Count of ping failures on IFoE Request PFC channel * @resp_failures: Count of ping failures on IFoE Response PFC channel * @non_ifoe_failures: Count of ping failures on non-IFoE traffic PFC channel + * @flags: Result flags (see CFG_L2PING_NETPORT_*) */ struct cfg_l2ping_netport_result { __u8 req_failures; __u8 resp_failures; __u8 non_ifoe_failures; + __u8 flags; }; /** @@ -349,14 +374,38 @@ struct cfg_connect_cmd { * userspace process that has joined the multicast group "ifoe-cfg-mcgrp". * * CFG_EVT_CMD_PHASE_EVENT: + * - CFG_EVT_ATTR_DEV_ID: Device identifier * - CFG_EVT_ATTR_TS: Timestamp of the event * - CFG_EVT_ATTR_PHASE_EVENT: New configuration phase + * + * CFG_EVT_CMD_IFOE_LINK_EVENT: + * - CFG_EVT_ATTR_DEV_ID: Device identifier + * - CFG_EVT_ATTR_TS: Timestamp of the event + * - CFG_EVT_ATTR_LABEL: Name of the IFoE link + * - CFG_EVT_ATTR_LOGICAL_IDX: Logical index of the link + * - CFG_EVT_ATTR_LINK_DOWN: Whether the link is down + * - CFG_EVT_ATTR_DX_ISOLATED: Whether the device is isolated + * - CFG_EVT_ATTR_NETPORT_COUNT: Number of netports attached to the link + * - CFG_EVT_ATTR_NETPORT0..3: Per-netport link information (nested) + * + * CFG_EVT_CMD_NETPORT_LINK_EVENT: + * - CFG_EVT_ATTR_DEV_ID: Device identifier + * - CFG_EVT_ATTR_TS: Timestamp of the event + * - CFG_EVT_ATTR_LABEL: Name of the netport + * - CFG_EVT_ATTR_LOGICAL_IDX: Logical index of the netport + * - CFG_EVT_ATTR_LINK_DOWN: Whether the netport link is down + * + * CFG_EVT_CMD_TELEMETRY_READY_EVENT: + * - CFG_EVT_ATTR_DEV_ID: Device identifier + * - CFG_EVT_ATTR_TS: Timestamp of the event + * - CFG_EVT_ATTR_GEN_COUNT: Telemetry generation count */ enum { CFG_EVT_CMD_PHASE_EVENT = 1, CFG_EVT_CMD_IFOE_LINK_EVENT, CFG_EVT_CMD_NETPORT_LINK_EVENT, + CFG_EVT_CMD_TELEMETRY_READY_EVENT, __CFG_EVT_CMD_MAX }; #define CFG_EVT_CMD_MAX (__CFG_EVT_CMD_MAX - 1) @@ -374,6 +423,7 @@ enum { CFG_EVT_ATTR_NETPORT2, CFG_EVT_ATTR_NETPORT3, CFG_EVT_ATTR_DEV_ID, + CFG_EVT_ATTR_GEN_COUNT, __CFG_EVT_ATTR_MAX }; #define CFG_EVT_ATTR_MAX (__CFG_EVT_ATTR_MAX - 1) @@ -426,6 +476,21 @@ enum { CFG_CMD_IFOE_SET_RX_CRYPTO_KEY, CFG_CMD_NETPORT_CONFIG_LINK_AUTO, CFG_CMD_NETPORT_CONFIG_LINK_MANUAL, + CFG_CMD_NETPORT_GET_ACCELERATOR_ADDR_MAP, + CFG_CMD_IFCP_GET_NETPORT_STATE, + CFG_CMD_IFCP_GET_NETPORT_STATS, + CFG_CMD_DIAG_CONFIG_PMA_LANE, + CFG_CMD_DIAG_CONFIG_PRBS_TX, + CFG_CMD_DIAG_CONFIG_PRBS_RX, + CFG_CMD_DIAG_GET_PRBS_RESULTS, + CFG_CMD_GET_SCALEUP_FABRIC_CONFIG, + CFG_CMD_GET_SCALEUP_FABRIC_VPOD_CONFIG, + CFG_CMD_GET_SCALEUP_FABRIC_STATION_INFO, + CFG_CMD_GET_GPU_IDENTITY, + CFG_CMD_GET_TELEMETRY_CATEGORY_MASK, + CFG_CMD_SET_SCALEUP_FABRIC_CONFIG, + CFG_CMD_SET_SCALEUP_FABRIC_VPOD_CONFIG, + CFG_CMD_SET_SCALEUP_FABRIC_STATION_INFO, __CFG_CMD_MAX }; #define CFG_CMD_MAX (__CFG_CMD_MAX - 1) @@ -481,10 +546,64 @@ enum { CFG_ATTR_NETPORT3, CFG_ATTR_CATEGORY_MASK, CFG_ATTR_TELEMETRY_ENABLE, + /* IFCP per-netport state attributes (response of CFG_CMD_IFCP_GET_NETPORT_STATE) */ + CFG_ATTR_IFCP_LOCAL_PORT_ID, + CFG_ATTR_IFCP_LOCAL_LINK_UP, + CFG_ATTR_IFCP_LOCAL_IN_ERROR, + CFG_ATTR_IFCP_LOCAL_LL_UP, + CFG_ATTR_IFCP_LOCAL_MAC_ADDR, + CFG_ATTR_IFCP_PEER_DEVICE_ID, + CFG_ATTR_IFCP_PEER_PORT_ID, + CFG_ATTR_IFCP_PEER_ENABLED, + CFG_ATTR_IFCP_PEER_IN_ERROR, + CFG_ATTR_IFCP_PEER_ENCRYPT_MODE, + CFG_ATTR_IFCP_PEER_MAC_ADDR, + CFG_ATTR_IFCP_PEER_MTU, + /* IFCP per-netport stats attributes (response of CFG_CMD_IFCP_GET_NETPORT_STATS) */ + CFG_ATTR_IFCP_STATS_RX_COUNT, + CFG_ATTR_IFCP_STATS_TX_COUNT, + CFG_ATTR_IFCP_STATS_TX_ERRORS, + CFG_ATTR_IFCP_STATS_RX_DROPPED, + CFG_ATTR_LANE_IDX, + CFG_ATTR_ENABLE, + CFG_ATTR_PMA_RATE, + CFG_ATTR_TX_POLARITY, + CFG_ATTR_RX_POLARITY, + CFG_ATTR_PRBS_PATTERN, + CFG_ATTR_USER_PATTERN, + CFG_ATTR_RESYNC, + CFG_ATTR_PRBS_RESULTS, + /* Scale-up fabric config (response of CFG_CMD_GET_SCALEUP_FABRIC_CONFIG) */ + CFG_ATTR_SCALEUP_PHYSICAL_POD_ID, + CFG_ATTR_SCALEUP_PHYSICAL_POD_SIZE, + CFG_ATTR_SCALEUP_LOCAL_ACCELERATORS, + /* Scale-up fabric vpod config (response of CFG_CMD_GET_SCALEUP_FABRIC_VPOD_CONFIG) */ + CFG_ATTR_SCALEUP_VIRTUAL_POD_ID, + CFG_ATTR_SCALEUP_NPA_ADDRESS_MODE, + CFG_ATTR_NETPORT_TOTAL_COUNT, + /* Scale-up fabric station info (response of CFG_CMD_GET_SCALEUP_FABRIC_STATION_INFO) */ + CFG_ATTR_SCALEUP_STATION_COUNT, + CFG_ATTR_SCALEUP_STATION_BANDWIDTH, + CFG_ATTR_GPU_PHYS_ID, + CFG_ATTR_GPU_NUM_GPUS, + CFG_ATTR_GPU_TRAY_TYPE, + CFG_ATTR_GPU_OAM_ID, __CFG_ATTR_MAX }; #define CFG_ATTR_MAX (__CFG_ATTR_MAX - 1) +enum { + CFG_ATTR_PRBS_RESULTS_VALID = 1, + CFG_ATTR_PRBS_RESULTS_RXEQ_SUCCESS, + CFG_ATTR_PRBS_RESULTS_CDR_LOCK, + CFG_ATTR_PRBS_RESULTS_PATTERN_LOCK, + CFG_ATTR_PRBS_RESULTS_OVERFLOW, + CFG_ATTR_PRBS_RESULTS_ELAPSED_US, + CFG_ATTR_PRBS_RESULTS_ERROR_COUNT, + __CFG_ATTR_PRBS_RESULTS_MAX +}; +#define CFG_ATTR_PRBS_RESULTS_MAX (__CFG_ATTR_PRBS_RESULTS_MAX - 1) + enum { CFG_ATTR_NETPORT_STATE_IDX = 1, CFG_ATTR_NETPORT_STATE_FAULT, diff --git a/projects/amdsmi/include/ualoe_lib/ifoe_mcdi_hostapp.h b/projects/amdsmi/include/ualoe_lib/ifoe_mcdi_hostapp.h index c9e28568b71d..bddd51b99c22 100644 --- a/projects/amdsmi/include/ualoe_lib/ifoe_mcdi_hostapp.h +++ b/projects/amdsmi/include/ualoe_lib/ifoe_mcdi_hostapp.h @@ -101,6 +101,14 @@ /* enum: USER_DEFINED pattern must be accompanied with a USER_PATTERN field */ #define PMA_PRBS_PATTERN_USER_DEFINED 0xd +/* IFOE_COMPUTE_TRAY_TYPE enum: Enum used to identify the compute tray type. */ +/* enum: Compute tray type Helios-P */ +#define IFOE_COMPUTE_TRAY_TYPE_HELIOS_P 0x0 +/* enum: Compute tray type Helios-R */ +#define IFOE_COMPUTE_TRAY_TYPE_HELIOS_R 0x1 +/* enum: Compute tray type Titan */ +#define IFOE_COMPUTE_TRAY_TYPE_TITAN 0x2 + /* AN_TYPE structuredef: Auto-negotiation types defined in IEEE802.3 */ #define AN_TYPE_LEN 4 #define AN_TYPE_TYPE_OFST 0 diff --git a/projects/amdsmi/include/ualoe_lib/ifoe_telemetry.h b/projects/amdsmi/include/ualoe_lib/ifoe_telemetry.h index cbeab5066ecc..a830ff8651b9 100644 --- a/projects/amdsmi/include/ualoe_lib/ifoe_telemetry.h +++ b/projects/amdsmi/include/ualoe_lib/ifoe_telemetry.h @@ -20,1439 +20,8 @@ * THE SOFTWARE. */ -/* This file is automatically generated. DO NOT EDIT IT. To make - * changes, edit the .yml files under doc/mcdi/ and rebuild this file - * with "make mcdi_headers". */ - #pragma once -/* IFOE_TELEM_CAT enum: Enum defining the different categories of Telemetry. - * Clients can request to receive a telemetry collection with all or a subset - * of the categories included, subject to permissions. - */ -/* enum: Telemetry associated with the IFoE data path. Telemetry in this - * category is defined as a dataset per IFoE Station. - */ -#define IFOE_TELEM_CAT_IFOE 0x0 -/* enum: Telemetry associated with the ethernet switch (EX). Telemetry in this - * category is defined as a dataset per IFoE Station. - */ -#define IFOE_TELEM_CAT_SWITCH 0x1 -/* enum: Telemetry associated with the XRSEC encrypt/decrypt block. Telemetry - * in this category is defined as a dataset per IFoE Station. - */ -#define IFOE_TELEM_CAT_CRYPTO 0x2 -/* enum: Telemetry associated with the XRPFC Priority Flow Control block. - * Telemetry in this category is defined as a dataset per IFoE Station. - */ -#define IFOE_TELEM_CAT_PFC 0x3 -/* enum: Telemetry associated with the Network Port MACs. Telemetry in this - * category is defined as a dataset per Network Port. - */ -#define IFOE_TELEM_CAT_NETPORT 0x4 -/* enum: Telemetry derived/constructed by software associated with each IFoE - * Station, for example the IFoE logical link status - */ -#define IFOE_TELEM_CAT_DERIVED_IFOE 0x5 -/* enum: Telemetry derived/constructed by software associated with each Network - * Port instance, for example the Network Port status - */ -#define IFOE_TELEM_CAT_DERIVED_NETPORT 0x6 - -/* IFOE_TELEM_LINK_STATUS structuredef: Flags indicating the IFoE logical link - * status. The flags defined here apply to the telemetry data for - * IFOE_LOGICAL_LINK_STATUS. - */ -#define IFOE_TELEM_LINK_STATUS_LEN 8 -#define IFOE_TELEM_LINK_STATUS_FLAGS_OFST 0 -#define IFOE_TELEM_LINK_STATUS_FLAGS_LEN 8 -#define IFOE_TELEM_LINK_STATUS_FLAGS_LO_OFST 0 -#define IFOE_TELEM_LINK_STATUS_FLAGS_LO_LEN 4 -#define IFOE_TELEM_LINK_STATUS_FLAGS_LO_LBN 0 -#define IFOE_TELEM_LINK_STATUS_FLAGS_LO_WIDTH 32 -#define IFOE_TELEM_LINK_STATUS_FLAGS_HI_OFST 4 -#define IFOE_TELEM_LINK_STATUS_FLAGS_HI_LEN 4 -#define IFOE_TELEM_LINK_STATUS_FLAGS_HI_LBN 32 -#define IFOE_TELEM_LINK_STATUS_FLAGS_HI_WIDTH 32 -#define IFOE_TELEM_LINK_STATUS_LINK_DOWN_OFST 0 -#define IFOE_TELEM_LINK_STATUS_LINK_DOWN_LBN 0 -#define IFOE_TELEM_LINK_STATUS_LINK_DOWN_WIDTH 1 -#define IFOE_TELEM_LINK_STATUS_LINK_DEGRADED_OFST 0 -#define IFOE_TELEM_LINK_STATUS_LINK_DEGRADED_LBN 1 -#define IFOE_TELEM_LINK_STATUS_LINK_DEGRADED_WIDTH 1 -#define IFOE_TELEM_LINK_STATUS_NETPORT_FAULT_OFST 0 -#define IFOE_TELEM_LINK_STATUS_NETPORT_FAULT_LBN 32 -#define IFOE_TELEM_LINK_STATUS_NETPORT_FAULT_WIDTH 4 -#define IFOE_TELEM_LINK_STATUS_FLAGS_LBN 0 -#define IFOE_TELEM_LINK_STATUS_FLAGS_WIDTH 64 - -/* IFOE_TELEM_NETPORT_STATUS structuredef: Flags indicating the status of a - * Network Port. The flags defined here apply to the telemetry data for - * NETPORT_LINK_STATUS. A value of 0 means there that the link is up and there - * are no faults. - */ -#define IFOE_TELEM_NETPORT_STATUS_LEN 8 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_LEN 8 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_LO_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_LO_LEN 4 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_LO_LBN 0 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_LO_WIDTH 32 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_HI_OFST 4 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_HI_LEN 4 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_HI_LBN 32 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_HI_WIDTH 32 -#define IFOE_TELEM_NETPORT_STATUS_LINK_DOWN_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_LINK_DOWN_LBN 0 -#define IFOE_TELEM_NETPORT_STATUS_LINK_DOWN_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_NO_PHY_LINK_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_NO_PHY_LINK_LBN 1 -#define IFOE_TELEM_NETPORT_STATUS_NO_PHY_LINK_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_PMA_NO_CDR_LOCK_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_PMA_NO_CDR_LOCK_LBN 9 -#define IFOE_TELEM_NETPORT_STATUS_PMA_NO_CDR_LOCK_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_PMA_LOS_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_PMA_LOS_LBN 10 -#define IFOE_TELEM_NETPORT_STATUS_PMA_LOS_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_PCS_NO_BLOCK_LOCK_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_PCS_NO_BLOCK_LOCK_LBN 11 -#define IFOE_TELEM_NETPORT_STATUS_PCS_NO_BLOCK_LOCK_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_PCS_NO_AM_LOCK_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_PCS_NO_AM_LOCK_LBN 12 -#define IFOE_TELEM_NETPORT_STATUS_PCS_NO_AM_LOCK_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_PCS_NO_ALIGN_LOCK_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_PCS_NO_ALIGN_LOCK_LBN 13 -#define IFOE_TELEM_NETPORT_STATUS_PCS_NO_ALIGN_LOCK_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_PCS_HI_BER_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_PCS_HI_BER_LBN 14 -#define IFOE_TELEM_NETPORT_STATUS_PCS_HI_BER_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_FEC_NO_LOCK_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_FEC_NO_LOCK_LBN 15 -#define IFOE_TELEM_NETPORT_STATUS_FEC_NO_LOCK_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_FEC_HI_SER_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_FEC_HI_SER_LBN 16 -#define IFOE_TELEM_NETPORT_STATUS_FEC_HI_SER_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_FEC_LOCAL_DEGRADED_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_FEC_LOCAL_DEGRADED_LBN 17 -#define IFOE_TELEM_NETPORT_STATUS_FEC_LOCAL_DEGRADED_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_FEC_RM_DEGRADED_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_FEC_RM_DEGRADED_LBN 18 -#define IFOE_TELEM_NETPORT_STATUS_FEC_RM_DEGRADED_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_FEC_DEGRADED_SER_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_FEC_DEGRADED_SER_LBN 19 -#define IFOE_TELEM_NETPORT_STATUS_FEC_DEGRADED_SER_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_AN_BP_FAILED_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_AN_BP_FAILED_LBN 21 -#define IFOE_TELEM_NETPORT_STATUS_AN_BP_FAILED_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_AN_NP_FAILED_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_AN_NP_FAILED_LBN 22 -#define IFOE_TELEM_NETPORT_STATUS_AN_NP_FAILED_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_AN_NO_HCD_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_AN_NO_HCD_LBN 23 -#define IFOE_TELEM_NETPORT_STATUS_AN_NO_HCD_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_LT_NO_LOCAL_FRAME_LOCK_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_LT_NO_LOCAL_FRAME_LOCK_LBN 24 -#define IFOE_TELEM_NETPORT_STATUS_LT_NO_LOCAL_FRAME_LOCK_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_LT_NO_RM_FRAME_LOCK_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_LT_NO_RM_FRAME_LOCK_LBN 25 -#define IFOE_TELEM_NETPORT_STATUS_LT_NO_RM_FRAME_LOCK_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_LT_NO_RX_READY_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_LT_NO_RX_READY_LBN 26 -#define IFOE_TELEM_NETPORT_STATUS_LT_NO_RX_READY_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_MAC_LOCAL_FAULT_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_MAC_LOCAL_FAULT_LBN 32 -#define IFOE_TELEM_NETPORT_STATUS_MAC_LOCAL_FAULT_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_MAC_REMOTE_FAULT_OFST 0 -#define IFOE_TELEM_NETPORT_STATUS_MAC_REMOTE_FAULT_LBN 33 -#define IFOE_TELEM_NETPORT_STATUS_MAC_REMOTE_FAULT_WIDTH 1 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_LBN 0 -#define IFOE_TELEM_NETPORT_STATUS_FLAGS_WIDTH 64 - -/* IFOE_TELEM_ID structuredef: Definitions for the Telemetry IDs for IFoE. - * These IDs are immutable. Additional IDs may be added but existing IDs must - * not be modified. - */ -#define IFOE_TELEM_ID_LEN 8 -/* Telemetry category */ -#define IFOE_TELEM_ID_CATEGORY_OFST 4 -#define IFOE_TELEM_ID_CATEGORY_LEN 4 -/* enum property: index */ -/* Enum values, see field(s): */ -/* IFOE_TELEM_CAT */ -#define IFOE_TELEM_ID_CATEGORY_LBN 32 -#define IFOE_TELEM_ID_CATEGORY_WIDTH 32 -/* Telemetry IDs for the IFoE datapath */ -#define IFOE_TELEM_ID_IFOE_OFST 0 -#define IFOE_TELEM_ID_IFOE_LEN 4 -/* enum property: index */ -/* enum: Count for write requests drained from the request elastic buffer */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_WR_REQ 0x1 -/* enum: Count for read requests drained from the request elastic buffer */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RD_REQ 0x2 -/* enum: Count for atomic requests drained from the request elastic buffer */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_ATM_REQ 0x3 -/* enum: Count for originator data beats drained from the corresponding elastic - * buffer - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_ORIG_DATA 0x4 -/* enum: Count for request parcel beats generated by the packer */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_REQ_PCL 0x5 -/* enum: Count for write responses drained from the corresponding elastic - * buffer - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_WR_RSP 0x6 -/* enum: Count for read responses drained from the corresponding elastic buffer - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RD_RSP 0x7 -/* enum: Count of clock cycles during which request elastic buffer is full */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_REQ_EB_FULL 0x8 -/* enum: Count of clock cycles during which request elastic buffer is empty */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_REQ_EB_EMPTY 0x9 -/* enum: Count of clock cycles during which originator data elastic buffer is - * full - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_ORIG_DATA_EB_FULL 0xa -/* enum: Count of clock cycles during which originator data elastic buffer is - * empty - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_ORIG_DATA_EB_EMPTY 0xb -/* enum: Count of clock cycles during which write response elastic buffer is - * full - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_WR_RSP_EB_FULL 0xc -/* enum: Count of clock cycles during which write response elastic buffer is - * empty - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_WR_RSP_EB_EMPTY 0xd -/* enum: Count of clock cycles during which read response elastic buffer is - * full - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RD_RSP_EB_FULL 0xe -/* enum: Count of clock cycles during which read response elastic buffer is - * empty - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RD_RSP_EB_EMPTY 0xf -/* enum: Count of clock cycles during which request parcel queue is full */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_REQ_PCL_FULL 0x10 -/* enum: Count of clock cycles during which request parcel queue is empty */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_REQ_PCL_EMPTY 0x11 -/* enum: Count of clock cycles during which write response parcel queue is full - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_WR_RSP_PCL_FULL 0x12 -/* enum: Count of clock cycles during which write response parcel queue is - * empty - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_WR_RSP_PCL_EMPTY 0x13 -/* enum: Count of clock cycles during which read response parcel queue is full - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RD_RSP_PCL_FULL 0x14 -/* enum: Count of clock cycles during which read response parcel queue is empty - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RD_RSP_PCL_EMPTY 0x15 -/* enum: Count of clock cycles during which request buffer pool is full */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_REQ_POOL_FULL 0x16 -/* enum: Count of clock cycles during which request buffer pool is empty */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_REQ_POOL_EMPTY 0x17 -/* enum: Count of clock cycles during which response buffer pool is full */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RSP_POOL_FULL 0x18 -/* enum: Count of clock cycles during which response buffer pool is empty */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RSP_POOL_EMPTY 0x19 -/* enum: Count of errored originator data beats received through the SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_ORIG_DATA_ERROR 0x1a -/* enum: Count of errored read response data beats received through the SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RD_RSP_DATA_ERROR 0x1b -/* enum: Count of credits consumed by the originator in the request SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_REQ_CREDIT_CONSUMED 0x1c -/* enum: Count of credits released to the originator in the request SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_REQ_CREDIT_RELEASED 0x1d -/* enum: Count of credits consumed by the originator in the originator data SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_ORIG_DATA_CREDIT_CONSUMED 0x1e -/* enum: Count of credits released to the originator in the originator data SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_ORIG_DATA_CREDIT_RELEASED 0x1f -/* enum: Count of credits consumed by the completer in the write response SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_WR_RSP_CREDIT_CONSUMED 0x20 -/* enum: Count of credits released to the completer in the write response SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_WR_RSP_CREDIT_RELEASED 0x21 -/* enum: Count of credits consumed by the completer in the read response SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RD_RSP_CREDIT_CONSUMED 0x22 -/* enum: Count of credits released to the completer in the read response SDP - * interface - */ -#define IFOE_TELEM_ID_IFOE_SDP_TX_PACK_RD_RSP_CREDIT_RELEASED 0x23 -/* enum: Request free block return delayed */ -#define IFOE_TELEM_ID_IFOE_WENG_BSTATE_FREE_BLK_DELAY_REQ 0x1001 -/* enum: Response free block return delayed */ -#define IFOE_TELEM_ID_IFOE_WENG_BSTATE_FREE_BLK_DELAY_RES 0x1002 -/* enum: Request stream SDP messages */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_REQ 0x1003 -/* enum: Response stream SDP messages */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_RES 0x1004 -/* enum: Request stream SDP messages with force set */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_FORCE_REQ 0x1005 -/* enum: Response stream SDP messages with force set */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_FORCE_RES 0x1006 -/* enum: Request stream SDP messages with chain set */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_CHAIN_REQ 0x1007 -/* enum: Response stream SDP messages with chain set */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_CHAIN_RES 0x1008 -/* enum: Request stream SDP message words */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_WORD_REQ 0x1009 -/* enum: Response stream SDP message words */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_WORD_RES 0x100a -/* enum: Request stream SDP message data in 8 byte granules */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_LENGTH_REQ 0x100b -/* enum: Response stream SDP message data in 8 byte granules */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_LENGTH_RES 0x100c -/* enum: Request stream packets opened */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_PKT_OPEN_REQ 0x100d -/* enum: Response stream packets opened */ -#define IFOE_TELEM_ID_IFOE_WENG_OP_SDP_PKT_OPEN_RES 0x100e -/* enum: Request packets payload terminated in 8 byte granules */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_PAYLOAD_REQ 0x100f -/* enum: Response packets payload terminated in 8 byte granules */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_PAYLOAD_RES 0x1010 -/* enum: Request packets generated due to MTU threshold */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_MTU_REQ 0x1011 -/* enum: Response packets generated due to MTU threshold */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_MTU_RES 0x1012 -/* enum: Request packets generated due to forced SDP messages */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_FORCE_REQ 0x1013 -/* enum: Response packets generated due to forced SDP messages */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_FORCE_RES 0x1014 -/* enum: Request packets generated due to timer expiry */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_EXPIRY_REQ 0x1015 -/* enum: Response packets generated due to timer expiry */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_EXPIRY_RES 0x1016 -/* enum: Request packets without forced messages delayed by chain */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_CHAIN_DELAY_REQ 0x1017 -/* enum: Response packets without forced messages delayed by chain */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_CHAIN_DELAY_RES 0x1018 -/* enum: Request packets with forced messages delayed by chain */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_FORCE_CHAIN_DELAY_REQ 0x1019 -/* enum: Response packets with forced messages delayed by chain */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_FORCE_CHAIN_DELAY_RES 0x101a -/* enum: Request packets that reach MTU threshold due to the scheduler - * acknowledgement - */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_MTU_HOLD_DELAY_REQ 0x101b -/* enum: Response packets that reach MTU threshold due to the scheduler - * acknowledgement - */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_MTU_HOLD_DELAY_RES 0x101c -/* enum: Request packets with force flag set delayed due to the scheduler - * acknowledgement - */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_FORCE_HOLD_DELAY_REQ 0x101d -/* enum: Response packets with force flag set delayed due to the scheduler - * acknowledgement - */ -#define IFOE_TELEM_ID_IFOE_WENG_EVICTION_FORCE_HOLD_DELAY_RES 0x101e -/* enum: Number of Read Engine scheduled read requests */ -#define IFOE_TELEM_ID_IFOE_RENG_READ_SCH_IN 0x101f -/* enum: Number of Read Engine output packets sent to Encapsulation */ -#define IFOE_TELEM_ID_IFOE_RENG_READ_PKT_OUT 0x1020 -/* enum: Number of Read Engine scheduled free requests */ -#define IFOE_TELEM_ID_IFOE_RENG_FREE_SCH_IN 0x1021 -/* enum: Number of Read Engine freed head blocks, or freed packets */ -#define IFOE_TELEM_ID_IFOE_RENG_FREE_PKT_OUT 0x1022 -/* enum: Number of Read Engine freed blocks */ -#define IFOE_TELEM_ID_IFOE_RENG_FREE_BLK_OUT 0x1023 -/* enum: Count of the number of xrsec egress packets for network port 0 */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_PKT_EGRESS_XRSEC_NPORT_0 0x2001 -/* enum: Count of the number of xrsec egress packets for network port 1 */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_PKT_EGRESS_XRSEC_NPORT_1 0x2002 -/* enum: Count of the number of xrsec egress packets for network port 2 */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_PKT_EGRESS_XRSEC_NPORT_2 0x2003 -/* enum: Count of the number of xrsec egress packets for network port 3 */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_PKT_EGRESS_XRSEC_NPORT_3 0x2004 -/* enum: Count of the payload in 8B granules sent on xrsec egress network port - * 0 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_PAYL_LEN_EGRESS_XRSEC_NPORT_0 0x2005 -/* enum: Count of the payload in 8B granules sent on xrsec egress network port - * 1 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_PAYL_LEN_EGRESS_XRSEC_NPORT_1 0x2006 -/* enum: Count of the payload in 8B granules sent on xrsec egress network port - * 2 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_PAYL_LEN_EGRESS_XRSEC_NPORT_2 0x2007 -/* enum: Count of the payload in 8B granules sent on xrsec egress network port - * 3 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_PAYL_LEN_EGRESS_XRSEC_NPORT_3 0x2008 -/* enum: Count of the header (inc. metadata) in bytes sent on xrsec egress - * network port 0 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_HDR_LEN_EGRESS_XRSEC_NPORT_0 0x2009 -/* enum: Count of the header (inc. metadata) in bytes sent on xrsec egress - * network port 1 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_HDR_LEN_EGRESS_XRSEC_NPORT_1 0x200a -/* enum: Count of the header (inc. metadata) in bytes sent on xrsec egress - * network port 2 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_HDR_LEN_EGRESS_XRSEC_NPORT_2 0x200b -/* enum: Count of the header (inc. metadata) in bytes sent on xrsec egress - * network port 3 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_HDR_LEN_EGRESS_XRSEC_NPORT_3 0x200c -/* enum: Count of the number of xrsec egress valid cycles (valid=1 && ready=1) - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_VALID_EGRESS_XRSEC 0x200d -/* enum: Count of the number of xrsec egress stalled cycles (valid=1 && - * ready=0) - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_STALL_EGRESS_XRSEC 0x200e -/* enum: Count of the ingress packets from TX2 Read Engine */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_PKT_INGRESS 0x200f -/* enum: Count of the ingress valid cycles from TX2 Read Engine (valid=1 && - * ready=0) - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_VALID_INGRESS 0x2010 -/* enum: Count of the ingress stalled cycles from TX2 Read Engine (valid=1 && - * ready=0) - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_STALL_INGRESS 0x2011 -/* enum: Count of the context ingress valid cycles from TX Scheduler for - * network port 0 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_VALID_CNTXT_INGRESS_NPORT_0 0x2012 -/* enum: Count of the context ingress valid cycles from TX Scheduler for - * network port 1 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_VALID_CNTXT_INGRESS_NPORT_1 0x2013 -/* enum: Count of the context ingress valid cycles from TX Scheduler for - * network port 2 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_VALID_CNTXT_INGRESS_NPORT_2 0x2014 -/* enum: Count of the context ingress valid cycles from TX Scheduler for - * network port 3 - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_VALID_CNTXT_INGRESS_NPORT_3 0x2015 -/* enum: Count of the context ingress stalled cycles from TX Scheduler (valid=1 - * && ready=0) - */ -#define IFOE_TELEM_ID_IFOE_TX_ENCAP_STALL_CNTXT_INGRESS 0x2016 -/* enum: Number of streams in INACTIVE state */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_INACTIVE_STREAMS 0x3001 -/* enum: Number of streams in ACTIVE state */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_ACTIVE_STREAMS 0x3002 -/* enum: Number of streams in PAUSED state */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_PAUSED_STREAMS 0x3003 -/* enum: Number of streams with boosted priority */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_BOOSTED_PRI_STREAMS 0x3004 -/* enum: Number of streams with empty send + replay queues */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_EMPTY_QUEUE_STREAMS 0x3005 -/* enum: Number of streams with empty send queues */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_EMPTY_SEND_QUEUE_STREAMS 0x3006 -/* enum: Number of request packets in the scheduler */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_REQ_PKTS 0x3007 -/* enum: Number of response packets in the scheduler */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_RES_PKTS 0x3008 -/* enum: Number of low priority packets in the network port 0 Request queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_LOW_PRI_REQ_PKTS_NPORT_0 0x3009 -/* enum: Number of high priority packets in the network port 0 Request queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_HIGH_PRI_REQ_PKTS_NPORT_0 0x300a -/* enum: Number of low priority packets in the network port 0 Response queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_LOW_PRI_RES_PKTS_NPORT_0 0x300b -/* enum: Number of high priority packets in the network port 0 Response queue - */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_HIGH_PRI_RES_PKTS_NPORT_0 0x300c -/* enum: Number of low priority packets in the network port 1 Request queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_LOW_PRI_REQ_PKTS_NPORT_1 0x300d -/* enum: Number of high priority packets in the network port 1 Request queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_HIGH_PRI_REQ_PKTS_NPORT_1 0x300e -/* enum: Number of low priority packets in the network port 1 Response queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_LOW_PRI_RES_PKTS_NPORT_1 0x300f -/* enum: Number of high priority packets in the network port 1 Response queue - */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_HIGH_PRI_RES_PKTS_NPORT_1 0x3010 -/* enum: Number of low priority packets in the network port 2 Request queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_LOW_PRI_REQ_PKTS_NPORT_2 0x3011 -/* enum: Number of high priority packets in the network port 2 Request queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_HIGH_PRI_REQ_PKTS_NPORT_2 0x3012 -/* enum: Number of low priority packets in the network port 2 Response queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_LOW_PRI_RES_PKTS_NPORT_2 0x3013 -/* enum: Number of high priority packets in the network port 2 Response queue - */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_HIGH_PRI_RES_PKTS_NPORT_2 0x3014 -/* enum: Number of low priority packets in the network port 3 Request queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_LOW_PRI_REQ_PKTS_NPORT_3 0x3015 -/* enum: Number of high priority packets in the network port 3 Request queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_HIGH_PRI_REQ_PKTS_NPORT_3 0x3016 -/* enum: Number of low priority packets in the network port 3 Response queue */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_LOW_PRI_RES_PKTS_NPORT_3 0x3017 -/* enum: Number of high priority packets in the network port 3 Response queue - */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_HIGH_PRI_RES_PKTS_NPORT_3 0x3018 -/* enum: Number of active TXACK response streams */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_ACTIVE_TX_ACK_RES_STREAMS 0x3019 -/* enum: Number of active RXACK packets */ -#define IFOE_TELEM_ID_IFOE_TX_SCHED_ACTIVE_RX_ACK_PKTS 0x301a -/* enum: Count of the number of XRSEC ingress packets for network port 0 */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_XRSEC_INGRESS_NPORT_0 0x4001 -/* enum: Count of the number of XRSEC ingress packets for network port 1 */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_XRSEC_INGRESS_NPORT_1 0x4002 -/* enum: Count of the number of XRSEC ingress packets for network port 2 */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_XRSEC_INGRESS_NPORT_2 0x4003 -/* enum: Count of the number of XRSEC ingress packets for network port 3 */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_XRSEC_INGRESS_NPORT_3 0x4004 -/* enum: Count of the packet length in bytes of XRSEC ingress packets from - * network port 0 - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_LEN_XRSEC_INGRESS_NPORT_0 0x4005 -/* enum: Count of the packet length in bytes of XRSEC ingress packets from - * network port 1 - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_LEN_XRSEC_INGRESS_NPORT_1 0x4006 -/* enum: Count of the packet length in bytes of XRSEC ingress packets from - * network port 2 - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_LEN_XRSEC_INGRESS_NPORT_2 0x4007 -/* enum: Count of the packet length in bytes of XRSEC ingress packets from - * network port 3 - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_LEN_XRSEC_INGRESS_NPORT_3 0x4008 -/* enum: Count of the payload in 8B granules of XRSEC ingress packets from - * network port 0 - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PAYL_LEN_XRSEC_INGRESS_NPORT_0 0x4009 -/* enum: Count of the payload in 8B granules of XRSEC ingress packets from - * network port 1 - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PAYL_LEN_XRSEC_INGRESS_NPORT_1 0x400a -/* enum: Count of the payload in 8B granules of XRSEC ingress packets from - * network port 2 - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PAYL_LEN_XRSEC_INGRESS_NPORT_2 0x400b -/* enum: Count of the payload in 8B granules of XRSEC ingress packets from - * network port 3 - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PAYL_LEN_XRSEC_INGRESS_NPORT_3 0x400c -/* enum: Count of the number of xrsec ingress valid cycles (valid=1 && ready=1) - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_VALID_INGRESS_XRSEC 0x400d -/* enum: Count of the number of xrsec ingress stalled cycles (valid=1 && - * ready=0) - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_STALL_INGRESS_XRSEC 0x400e -/* enum: Count of the number of egress packets for requests sent to RX Unpack - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_EGRESS_REQ 0x400f -/* enum: Count of the number of egress packets for responses sent to RX Unpack - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_PKT_EGRESS_RSP 0x4010 -/* enum: Count of the number of packet egress valid cycles sent to RX Unpack */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_VALID_EGRESS 0x4011 -/* enum: Count of the number of egress credit info for requests sent to RX - * Unpack - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_CRDT_EGRESS_REQ 0x4012 -/* enum: Count of the number of egress credit info for responses sent to RX - * Unpack - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_CRDT_EGRESS_RSP 0x4013 -/* enum: Count of the number of egress TX ACKs for requests sent to TX - * Scheduler - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_TX_ACK_EGRESS_REQ 0x4014 -/* enum: Count of the number of egress TX ACKs for responses sent to TX - * Scheduler - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_TX_ACK_EGRESS_RSP 0x4015 -/* enum: Count of the number of egress TX NAKs for requests sent to TX - * Scheduler - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_TX_NAK_EGRESS_REQ 0x4016 -/* enum: Count of the number of egress TX NAKs for responses sent to TX - * Scheduler - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_TX_NAK_EGRESS_RSP 0x4017 -/* enum: Count of the number of egress RX ACKs for requests sent to TX - * Scheduler - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_RX_ACK_EGRESS_REQ 0x4018 -/* enum: Count of the number of egress RX ACKs for responses sent to TX - * Scheduler - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_RX_ACK_EGRESS_RSP 0x4019 -/* enum: Count of the number of egress RX NAKs for requests sent to TX - * Scheduler - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_RX_NAK_EGRESS_REQ 0x401a -/* enum: Count of the number of egress RX NAKs for responses sent to TX - * Scheduler - */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_RX_NAK_EGRESS_RSP 0x401b -/* enum: Count of dropped packets */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_DROPPED_PKTS 0x401c -/* enum: Init busy signal for sequence number RAM */ -#define IFOE_TELEM_ID_IFOE_RX_DECAP_INIT_BUSY 0x401d -/* enum: Live count of total network Request credits consumed. This is an - * accumulation of the payload credits plus overhead based on packets received - * by RX1. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_REQ_TOTAL_CREDITS_CONSUMED 0x5001 -/* enum: Live count of total network Request credits returned on credit - * interface. This is an accumulation of the payload credits returned due to - * parcels being read from the parcel buffer. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_REQ_PAYLOAD_CREDITS_RETURNED 0x5002 -/* enum: Live count of total network Request excess credits returned on credit - * interface. This is an accumulation of any credits returned due to packets - * being dropped or packet overheads. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_REQ_EXCESS_CREDITS_RETURNED 0x5003 -/* enum: Live count of total network Response credits consumed. This is an - * accumulation of the payload credits plus overhead based on packets received - * by RX1. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_RSP_TOTAL_CREDITS_CONSUMED 0x5004 -/* enum: Live count of total network Response credits returned on credit - * interface. This is an accumulation of the payload credits returned due to - * parcels being read from the parcel buffer. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_RSP_PAYLOAD_CREDITS_RETURNED 0x5005 -/* enum: Live count of total network Response excess credits returned on credit - * interface. This is an accumulation of any credits returned due to packets - * being dropped or packet overheads. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_RSP_EXCESS_CREDITS_RETURNED 0x5006 -/* enum: Live count of number of OrigReq beats written into the OrigReq SDP - * output buffer - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_REQ_CREDITS_CONSUMED 0x5007 -/* enum: Live count of credits returned for the OrigReq SDP interface */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_REQ_CREDITS_RETURNED 0x5008 -/* enum: Live count of number of Origdata beats written into the OrigData SDP - * output buffer - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_ORIGDATA_CREDITS_CONSUMED 0x5009 -/* enum: Live count of credits returned for the OrigData SDP interface */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_ORIGDATA_CREDITS_RETURNED 0x500a -/* enum: Live count of number of WrRsp beats written into the WrRsp SDP output - * buffer - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_WRRSP_CREDITS_CONSUMED 0x500b -/* enum: Live count of credits returned for the WrRsp SDP interface */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_WRRSP_CREDITS_RETURNED 0x500c -/* enum: Live count of number of RdRsp beats written into the RdRsp SDP output - * buffer - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_RDRSP_CREDITS_CONSUMED 0x500d -/* enum: Live count of credits returned for the RdRsp SDP interface */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_RDRSP_CREDITS_RETURNED 0x500e -/* enum: Count of number of cycles for which the input request buffer read is - * stalled. This can be due to credit starvation on SDP or time to process - * parcels. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_REQ_CYCLES_STALLED 0x500f -/* enum: Count of number of cycles for which the input response buffer read is - * stalled. This can be due to credit starvation on SDP or time to process - * parcels. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_RSP_CYCLES_STALLED 0x5010 -/* enum: Count of number of cycles for which Requests parcels are held due to - * credit starvation on OrigReq or OrigData SDP interface or running out of - * retags. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_REQ_CYCLES_STALLED_CNT 0x5011 -/* enum: Count of number of cycles for which Response parcels are held due to - * credit starvation on RdRsp or WrRsp SDP interface or running out of retags. - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_RSP_CYCLES_STALLED_CNT 0x5012 -/* enum: Count of number of retags used- expect one per each Request parcel - * processed - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_RETAG_USED 0x5013 -/* enum: Count of number of retags freed due to all expected responses for a - * request being received - */ -#define IFOE_TELEM_ID_IFOE_SDP_RX_UNPACK_RETAG_FREED 0x5014 -#define IFOE_TELEM_ID_IFOE_LBN 0 -#define IFOE_TELEM_ID_IFOE_WIDTH 32 -/* Telemetry IDs for the EX switch */ -#define IFOE_TELEM_ID_SWITCH_OFST 0 -#define IFOE_TELEM_ID_SWITCH_LEN 4 -/* enum property: index */ -/* enum: Count of non-IFoE packets read by firmware */ -#define IFOE_TELEM_ID_SWITCH_RX_NONIFOE_PKTS 0x1 -/* enum: Count of bytes of non-IFoE traffic read by firmware */ -#define IFOE_TELEM_ID_SWITCH_RX_NONIFOE_BYTES 0x2 -/* enum: Count of packets received from the network and dropped due to - * insufficient free space in the switch - */ -#define IFOE_TELEM_ID_SWITCH_RX_DROPPED_PKTS 0x3 -/* enum: Count of bytes received from the network and dropped due to - * insufficient free space in the switch - */ -#define IFOE_TELEM_ID_SWITCH_RX_DROPPED_BYTES 0x4 -/* enum: Count of non-IFoE packets written by firmware */ -#define IFOE_TELEM_ID_SWITCH_TX_NONIFOE_PKTS 0x5 -/* enum: Count of bytes of non-IFoE traffic written by firmware */ -#define IFOE_TELEM_ID_SWITCH_TX_NONIFOE_BYTES 0x6 -#define IFOE_TELEM_ID_SWITCH_LBN 0 -#define IFOE_TELEM_ID_SWITCH_WIDTH 32 -/* Telemetry IDs for the encrypt/decrypt hardware */ -#define IFOE_TELEM_ID_CRYPTO_OFST 0 -#define IFOE_TELEM_ID_CRYPTO_LEN 4 -/* enum property: index */ -/* enum: Flag indicating that initialization of the TX crypto core is complete - */ -#define IFOE_TELEM_ID_CRYPTO_TX_CORE_INIT_DONE 0x1 -/* enum: Flag indicating that initialization of the RX crypto core is complete - */ -#define IFOE_TELEM_ID_CRYPTO_RX_CORE_INIT_DONE 0x2 -/* enum: Count of all bytes into ingress of TX encryption core */ -#define IFOE_TELEM_ID_CRYPTO_TX_INGRESS_TOTAL_BYTES 0x3 -/* enum: Count of all packets into ingress of TX encryption core */ -#define IFOE_TELEM_ID_CRYPTO_TX_INGRESS_TOTAL_PKTS 0x4 -/* enum: Count of all bytes out of egress of TX encryption core */ -#define IFOE_TELEM_ID_CRYPTO_TX_EGRESS_TOTAL_BYTES 0x5 -/* enum: Count of all packets out of egress of TX encryption core */ -#define IFOE_TELEM_ID_CRYPTO_TX_EGRESS_TOTAL_PKTS 0x6 -/* enum: Count of all bytes into ingress of RX decryption core */ -#define IFOE_TELEM_ID_CRYPTO_RX_INGRESS_TOTAL_BYTES 0x7 -/* enum: Count of all packets into ingress of RX decryption core */ -#define IFOE_TELEM_ID_CRYPTO_RX_INGRESS_TOTAL_PKTS 0x8 -/* enum: Count of all bytes out of egress of RX encryption core */ -#define IFOE_TELEM_ID_CRYPTO_RX_EGRESS_TOTAL_BYTES 0x9 -/* enum: Count of all packets out of egress of RX encryption core */ -#define IFOE_TELEM_ID_CRYPTO_RX_EGRESS_TOTAL_PKTS 0xa -/* enum: Total payload bytes of all IFoE packets encrypted */ -#define IFOE_TELEM_ID_CRYPTO_TX_TOTAL_ENCRYPTED_BYTES 0x1001 -/* enum: Total number of good IFoE packets encrypted */ -#define IFOE_TELEM_ID_CRYPTO_TX_TOTAL_ENCRYPTED_PKTS 0x1002 -/* enum: Total number of IFoE packets processed containing an EOP error */ -#define IFOE_TELEM_ID_CRYPTO_TX_TOTAL_ERROR_PKTS 0x1003 -/* enum: Total payload bytes of all IFoE packets decrypted */ -#define IFOE_TELEM_ID_CRYPTO_RX_TOTAL_DECRYPTED_BYTES 0x1004 -/* enum: Total number of good IFoE packets decrypted */ -#define IFOE_TELEM_ID_CRYPTO_RX_TOTAL_DECRYPTED_PKTS 0x1005 -/* enum: Total number of IFoE packets processed that failed validation due to - * either an ICV check failure, a framing error or an EOP error - */ -#define IFOE_TELEM_ID_CRYPTO_RX_TOTAL_BAD_PKTS 0x1006 -/* enum: Total number of IFoE packets processed containing a framing or EOP - * error. - */ -#define IFOE_TELEM_ID_CRYPTO_RX_TOTAL_ERROR_PKTS 0x1007 -#define IFOE_TELEM_ID_CRYPTO_LBN 0 -#define IFOE_TELEM_ID_CRYPTO_WIDTH 32 -/* Telemetry IDs for the priority flow control block */ -#define IFOE_TELEM_ID_PFC_OFST 0 -#define IFOE_TELEM_ID_PFC_LEN 4 -/* enum property: index */ -/* enum: Total number of Global Pause packets transmitted */ -#define IFOE_TELEM_ID_PFC_TX_PAUSE_PACKETS_SENT 0x1 -/* enum: Total number of packets transmitted with PFC priority 0 */ -#define IFOE_TELEM_ID_PFC_TX_PFC_PRIO0_PACKETS_SENT 0x2 -/* enum: Total number of packets transmitted with PFC priority 1 */ -#define IFOE_TELEM_ID_PFC_TX_PFC_PRIO1_PACKETS_SENT 0x3 -/* enum: Total number of packets transmitted with PFC priority 2 */ -#define IFOE_TELEM_ID_PFC_TX_PFC_PRIO2_PACKETS_SENT 0x4 -/* enum: Total number of packets transmitted with PFC priority 3 */ -#define IFOE_TELEM_ID_PFC_TX_PFC_PRIO3_PACKETS_SENT 0x5 -/* enum: Total number of packets transmitted with PFC priority 4 */ -#define IFOE_TELEM_ID_PFC_TX_PFC_PRIO4_PACKETS_SENT 0x6 -/* enum: Total number of packets transmitted with PFC priority 5 */ -#define IFOE_TELEM_ID_PFC_TX_PFC_PRIO5_PACKETS_SENT 0x7 -/* enum: Total number of packets transmitted with PFC priority 6 */ -#define IFOE_TELEM_ID_PFC_TX_PFC_PRIO6_PACKETS_SENT 0x8 -/* enum: Total number of packets transmitted with PFC priority 7 */ -#define IFOE_TELEM_ID_PFC_TX_PFC_PRIO7_PACKETS_SENT 0x9 -/* enum: Total number of Global Pause packets received */ -#define IFOE_TELEM_ID_PFC_RX_PAUSE_PACKETS_RCVD 0x1001 -/* enum: Total number of packets received with PFC priority 0 */ -#define IFOE_TELEM_ID_PFC_RX_PFC_PRIO0_PACKETS_RCVD 0x1002 -/* enum: Total number of packets received with PFC priority 1 */ -#define IFOE_TELEM_ID_PFC_RX_PFC_PRIO1_PACKETS_RCVD 0x1003 -/* enum: Total number of packets received with PFC priority 2 */ -#define IFOE_TELEM_ID_PFC_RX_PFC_PRIO2_PACKETS_RCVD 0x1004 -/* enum: Total number of packets received with PFC priority 3 */ -#define IFOE_TELEM_ID_PFC_RX_PFC_PRIO3_PACKETS_RCVD 0x1005 -/* enum: Total number of packets received with PFC priority 4 */ -#define IFOE_TELEM_ID_PFC_RX_PFC_PRIO4_PACKETS_RCVD 0x1006 -/* enum: Total number of packets received with PFC priority 5 */ -#define IFOE_TELEM_ID_PFC_RX_PFC_PRIO5_PACKETS_RCVD 0x1007 -/* enum: Total number of packets received with PFC priority 6 */ -#define IFOE_TELEM_ID_PFC_RX_PFC_PRIO6_PACKETS_RCVD 0x1008 -/* enum: Total number of packets received with PFC priority 7 */ -#define IFOE_TELEM_ID_PFC_RX_PFC_PRIO7_PACKETS_RCVD 0x1009 -/* enum: Total number of bytes sent for IFoE Request TX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_TX_TOTAL_BYTES 0x2001 -/* enum: Total number of packets sent for IFoE Request TX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_TX_TOTAL_PACKETS 0x2002 -/* enum: Count of time XOFF was applied for IFoE Request TX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_TX_XOFF_TOTAL 0x2003 -/* enum: Amount of time a packet transmission was delayed due to XOFF for IFoE - * Request TX queue - */ -#define IFOE_TELEM_ID_PFC_REQ_Q_TX_DELAY_TOTAL 0x2004 -/* enum: Number of memory pages occupied by the IFoE Request TX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_TX_FLV 0x2005 -/* enum: Time duration between XON -> XOFF and a subsequent XOFF -> XON for - * IFoE Request TX queue - */ -#define IFOE_TELEM_ID_PFC_REQ_Q_TX_XOFF_PERIOD 0x2006 -/* enum: Flag indicating that a packet stopped in the middle when reading from - * packet buffer for IFoE Request TX queue - */ -#define IFOE_TELEM_ID_PFC_REQ_Q_TX_UNF 0x2007 -/* enum: Boolean value indicating that the IFoE Request TX queue is empty */ -#define IFOE_TELEM_ID_PFC_REQ_Q_TX_QUEUE_EMPTY 0x2008 -/* enum: Total number of bytes sent for IFoE Response TX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_TX_TOTAL_BYTES 0x2101 -/* enum: Total number of packets sent for IFoE Response TX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_TX_TOTAL_PACKETS 0x2102 -/* enum: Count of time XOFF was applied for IFoE Response TX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_TX_XOFF_TOTAL 0x2103 -/* enum: Amount of time a packet transmission was delayed due to XOFF for IFoE - * Response TX queue - */ -#define IFOE_TELEM_ID_PFC_RES_Q_TX_DELAY_TOTAL 0x2104 -/* enum: Number of memory pages occupied by the IFoE Response TX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_TX_FLV 0x2105 -/* enum: Time duration between XON -> XOFF and a subsequent XOFF -> XON for - * IFoE Response TX queue - */ -#define IFOE_TELEM_ID_PFC_RES_Q_TX_XOFF_PERIOD 0x2106 -/* enum: Flag indicating that a packet stopped in the middle when reading from - * packet buffer for IFoE Response TX queue - */ -#define IFOE_TELEM_ID_PFC_RES_Q_TX_UNF 0x2107 -/* enum: Boolean value indicating that the IFoE Response TX queue is empty */ -#define IFOE_TELEM_ID_PFC_RES_Q_TX_QUEUE_EMPTY 0x2108 -/* enum: Total number of bytes sent for non-IFoE traffic TX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_TX_TOTAL_BYTES 0x2201 -/* enum: Total number of packets sent for non-IFoE traffic TX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_TX_TOTAL_PACKETS 0x2202 -/* enum: Count of time XOFF was applied for non-IFoE traffic TX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_TX_XOFF_TOTAL 0x2203 -/* enum: Amount of time a packet transmission was delayed due to XOFF for non- - * IFoE traffic TX queue - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_TX_DELAY_TOTAL 0x2204 -/* enum: Number of memory pages occupied by the non-IFoE traffic TX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_TX_FLV 0x2205 -/* enum: Time duration between XON -> XOFF and a subsequent XOFF -> XON for - * non-IFoE traffic TX queue - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_TX_XOFF_PERIOD 0x2206 -/* enum: Flag indicating that a packet stopped in the middle when reading from - * packet buffer for the non-IFoE traffic TX queue - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_TX_UNF 0x2207 -/* enum: Boolean value indicating that the non-IFoE traffic TX queue is empty - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_TX_QUEUE_EMPTY 0x2208 -/* enum: Total number of bytes received for IFoE Request RX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_TOTAL_BYTES 0x3001 -/* enum: Number of bytes dropped for IFoE Request RX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_DROPPED_BYTES 0x3002 -/* enum: Total number of packets received for IFoE Request RX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_TOTAL_PACKETS 0x3003 -/* enum: Number of packets dropped for IFoE Request RX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_DROPPED_PACKETS 0x3004 -/* enum: Total number of truncated packets received for IFoE Request RX queue - */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_TRUNCATED_PACKETS 0x3005 -/* enum: Count of time XOFF was applied for IFoE Request RX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_XOFF_TOTAL 0x3006 -/* enum: Number of memory pages occupied by the IFoE Request RX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_FLV 0x3007 -/* enum: Flag indicating that a packet stopped in the middle when reading from - * packet buffer for IFoE Request RX queue - */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_UTF 0x3008 -/* enum: Time duration between XON -> XOFF and a subsequent XOFF -> XON for - * IFoE Request RX queue - */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_XOFF_PERIOD 0x3009 -/* enum: Instantaneous number of credits available for IFoE Request RX queue */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_CREDIT_INT 0x300a -/* enum: Flags indicating that a credit error has occurred for IFoE Request RX - * queue - */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_CREDIT_ERR 0x300b -/* enum: Boolean value indicating that the IFoE Request TX queue is empty */ -#define IFOE_TELEM_ID_PFC_REQ_Q_RX_QUEUE_EMPTY 0x300c -/* enum: Total number of bytes received for IFoE Response RX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_TOTAL_BYTES 0x3101 -/* enum: Number of bytes dropped for IFoE Response RX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_DROPPED_BYTES 0x3102 -/* enum: Total number of packets received for IFoE Response RX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_TOTAL_PACKETS 0x3103 -/* enum: Number of packets dropped for IFoE Response RX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_DROPPED_PACKETS 0x3104 -/* enum: Total number of truncated packets received for IFoE Response RX queue - */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_TRUNCATED_PACKETS 0x3105 -/* enum: Count of time XOFF was applied for IFoE Response RX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_XOFF_TOTAL 0x3106 -/* enum: Number of memory pages occupied by the IFoE Response RX queue */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_FLV 0x3107 -/* enum: Flag indicating that a packet stopped in the middle when reading from - * packet buffer for IFoE Response RX queue - */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_UTF 0x3108 -/* enum: Time duration between XON -> XOFF and a subsequent XOFF -> XON for - * IFoE Response RX queue - */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_XOFF_PERIOD 0x3109 -/* enum: Instantaneous number of credits available for IFoE Response RX queue - */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_CREDIT_INT 0x310a -/* enum: Flags indicating that a credit error has occurred for IFoE Response RX - * queue - */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_CREDIT_ERR 0x310b -/* enum: Boolean value indicating that the IFoE Response TX queue is empty */ -#define IFOE_TELEM_ID_PFC_RES_Q_RX_QUEUE_EMPTY 0x310c -/* enum: Total number of bytes received for the non-IFoE traffic RX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_TOTAL_BYTES 0x3201 -/* enum: Number of bytes dropped for the non-IFoE traffic RX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_DROPPED_BYTES 0x3202 -/* enum: Total number of packets received for the non-IFoE traffic RX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_TOTAL_PACKETS 0x3203 -/* enum: Number of packets dropped for the non-IFoE traffic RX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_DROPPED_PACKETS 0x3204 -/* enum: Total number of truncated packets received for the non-IFoE traffic RX - * queue - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_TRUNCATED_PACKETS 0x3205 -/* enum: Count of time XOFF was applied for the non-IFoE traffic RX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_XOFF_TOTAL 0x3206 -/* enum: Number of memory pages occupied by the non-IFoE traffic RX queue */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_FLV 0x3207 -/* enum: Flag indicating that a packet stopped in the middle when reading from - * packet buffer for the non-IFoE traffic RX queue - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_UTF 0x3208 -/* enum: Time duration between XON -> XOFF and a subsequent XOFF -> XON for the - * non-IFoE traffic RX queue - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_XOFF_PERIOD 0x3209 -/* enum: Instantaneous number of credits available for the non-IFoE traffic RX - * queue - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_CREDIT_INT 0x320a -/* enum: Flags indicating that a credit error has occurred for the non-IFoE - * traffic RX queue - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_CREDIT_ERR 0x320b -/* enum: Boolean value indicating that the non-IFoE traffic TX queue is empty - */ -#define IFOE_TELEM_ID_PFC_NONIFOE_Q_RX_QUEUE_EMPTY 0x320c -/* enum: Total number of bytes received for the discard RX queue */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_TOTAL_BYTES 0x3301 -/* enum: Number of bytes dropped for the discard RX queue */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_DROPPED_BYTES 0x3302 -/* enum: Total number of packets received for the discard RX queue */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_TOTAL_PACKETS 0x3303 -/* enum: Number of packets dropped for the discard RX queue */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_DROPPED_PACKETS 0x3304 -/* enum: Total number of truncated packets received for the discard RX queue */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_TRUNCATED_PACKETS 0x3305 -/* enum: Count of time XOFF was applied for the discard RX queue */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_XOFF_TOTAL 0x3306 -/* enum: Number of memory pages occupied by the discard RX queue */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_FLV 0x3307 -/* enum: Flag indicating that a packet stopped in the middle when reading from - * packet buffer for the discard RX queue - */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_UTF 0x3308 -/* enum: Time duration between XON -> XOFF and a subsequent XOFF -> XON for the - * discard RX queue - */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_XOFF_PERIOD 0x3309 -/* enum: Instantaneous number of credits available for the discard RX queue */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_CREDIT_INT 0x330a -/* enum: Flags indicating that a credit error has occurred for the discard RX - * queue - */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_CREDIT_ERR 0x330b -/* enum: Boolean value indicating that the discard TX queue is empty */ -#define IFOE_TELEM_ID_PFC_DISCARD_Q_RX_QUEUE_EMPTY 0x330c -#define IFOE_TELEM_ID_PFC_LBN 0 -#define IFOE_TELEM_ID_PFC_WIDTH 32 -/* Telemetry IDs for the ethernet network ports */ -#define IFOE_TELEM_ID_NETPORT_OFST 0 -#define IFOE_TELEM_ID_NETPORT_LEN 4 -/* enum property: index */ -/* enum: Total number of bytes transmitted */ -#define IFOE_TELEM_ID_NETPORT_TX_TOTAL_BYTES 0x1 -/* enum: Total number of good bytes transmitted. This value is only incremented - * when a packet is transmitted completely and contains no errors. - */ -#define IFOE_TELEM_ID_NETPORT_TX_TOTAL_GOOD_BYTES 0x2 -/* enum: Total number of bad bytes transmitted. This value is only incremented - * when a packet is not transmitted completely or contains errors. - */ -#define IFOE_TELEM_ID_NETPORT_TX_TOTAL_ERR_BYTES 0x3 -/* enum: Total number of packets transmitted. */ -#define IFOE_TELEM_ID_NETPORT_TX_TOTAL_PACKETS 0x4 -/* enum: Total number of good bytes transmitted. This value is only incremented - * when a packet is transmitted completely and contains no errors. - */ -#define IFOE_TELEM_ID_NETPORT_TX_TOTAL_GOOD_PACKETS 0x5 -/* enum: Number of packets with tx_errin set to 1 to indicate an End of Packet - * (EOP) abort. - */ -#define IFOE_TELEM_ID_NETPORT_TX_FRAME_ERROR 0x6 -/* enum: Total number of packets greater than 64 bytes that have FCS errors */ -#define IFOE_TELEM_ID_NETPORT_TX_BAD_FCS 0x7 -/* enum: Total number of good and bad 64-byte packets transmitted */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_64_BYTES 0x8 -/* enum: Total number of good and bad packets between 65 and 127 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_65_127_BYTES 0x9 -/* enum: Total number of good and bad packets between 128 and 255 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_128_255_BYTES 0xa -/* enum: Total number of good and bad packets between 256 and 511 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_256_511_BYTES 0xb -/* enum: Total number of good and bad packets between 512 and 1023 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_512_1023_BYTES 0xc -/* enum: Total number of good and bad packets between 1024 and 1518 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_1024_1518_BYTES 0xd -/* enum: Total number of good and bad packets between 1519 and 1522 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_1519_1522_BYTES 0xe -/* enum: Total number of good and bad packets between 1523 and 1548 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_1523_1548_BYTES 0xf -/* enum: Total number of good and bad packets between 1549 and 2047 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_1549_2047_BYTES 0x10 -/* enum: Total number of good and bad packets between 2048 and 4095 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_2048_4095_BYTES 0x11 -/* enum: Total number of good and bad packets between 4096 and 8191 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_4096_8191_BYTES 0x12 -/* enum: Total number of good and bad packets between 8192 and 9215 bytes - * transmitted - */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_8192_9215_BYTES 0x13 -/* enum: Total number of packets that are over 9215 bytes long */ -#define IFOE_TELEM_ID_NETPORT_TX_PACKET_LARGE 0x14 -/* enum: Total number of good unicast packets */ -#define IFOE_TELEM_ID_NETPORT_TX_UNICAST 0x15 -/* enum: Total number of good multicast packets */ -#define IFOE_TELEM_ID_NETPORT_TX_MULTICAST 0x16 -/* enum: Total number of good broadcast packets */ -#define IFOE_TELEM_ID_NETPORT_TX_BROADCAST 0x17 -/* enum: Total number of good 802.1Q tagged VLAN packets */ -#define IFOE_TELEM_ID_NETPORT_TX_VLAN 0x18 -/* enum: Total number of 802.3x MAC Pause packets with good FCS */ -#define IFOE_TELEM_ID_NETPORT_TX_PAUSE 0x19 -/* enum: Total number of priority based pause packets with good FCS */ -#define IFOE_TELEM_ID_NETPORT_TX_USER_PAUSE 0x1a -/* enum: Total number of padding bytes added to packets */ -#define IFOE_TELEM_ID_NETPORT_TX_TOTAL_PAD_BYTES 0x1b -/* enum: Total number of packets that were padded */ -#define IFOE_TELEM_ID_NETPORT_TX_TOTAL_PAD_PACKETS 0x1c -/* enum: Total number of bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_TOTAL_BYTES 0x1001 -/* enum: Total number of bytes received in good (error-free) packets */ -#define IFOE_TELEM_ID_NETPORT_RX_TOTAL_GOOD_BYTES 0x1002 -/* enum: Total number of bytes received in bad (errored) packets */ -#define IFOE_TELEM_ID_NETPORT_RX_TOTAL_ERR_BYTES 0x1003 -/* enum: Total number of packets received */ -#define IFOE_TELEM_ID_NETPORT_RX_TOTAL_PACKETS 0x1004 -/* enum: Total number of good (error-free) packets received */ -#define IFOE_TELEM_ID_NETPORT_RX_TOTAL_GOOD_PACKETS 0x1005 -/* enum: Total number of small (less than 64 bytes) packets received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_SMALL 0x1006 -/* enum: Total number of dropped packets */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_DROPPED 0x1007 -/* enum: Count of 64B/66B code violations observed in the MAC */ -#define IFOE_TELEM_ID_NETPORT_RX_BAD_CODE_COUNT 0x1008 -/* enum: Total number of packets received with bad (but not stomped) FCS. A - * stomped FCS is defined as the bitwise inverse of a good FCS. - */ -#define IFOE_TELEM_ID_NETPORT_RX_BAD_FCS 0x1009 -/* enum: Total number of packets between 64 and rx_max_packet_len bytes that - * have FCS errors - */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_BAD_FCS 0x100a -/* enum: Total number of packets received with stomped FCS. A stomped FCS is - * defined as the bitwise inverse of a good FCS. - */ -#define IFOE_TELEM_ID_NETPORT_RX_STOMPED_FCS 0x100b -/* enum: Total number of frames that were truncated due to their length - * exceeding the defined maximum length - */ -#define IFOE_TELEM_ID_NETPORT_RX_TRUNCATED 0x100c -/* enum: Total number of 64 byte packets received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_64_BYTES 0x100d -/* enum: Total number of packets between 65 and 127 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_65_127_BYTES 0x100e -/* enum: Total number of packets between 128 and 255 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_128_255_BYTES 0x100f -/* enum: Total number of packets between 256 and 511 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_256_511_BYTES 0x1010 -/* enum: Total number of packets between 512 and 1023 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_512_1023_BYTES 0x1011 -/* enum: Total number of packets between 1024 and 1518 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_1024_1518_BYTES 0x1012 -/* enum: Total number of packets between 1519 and 1522 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_1519_1522_BYTES 0x1013 -/* enum: Total number of packets between 1523 and 1548 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_1523_1548_BYTES 0x1014 -/* enum: Total number of packets between 1549 and 2047 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_1549_2047_BYTES 0x1015 -/* enum: Total number of packets between 2048 and 4095 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_2048_4095_BYTES 0x1016 -/* enum: Total number of packets between 4096 and 8191 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_4096_8191_BYTES 0x1017 -/* enum: Total number of packets between 8192 and 9215 bytes received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_8192_9215_BYTES 0x1018 -/* enum: Total number of packets longer than rx_max_packet_len with either good - * or bad FCS - */ -#define IFOE_TELEM_ID_NETPORT_RX_TOOLONG 0x1019 -/* enum: Total number of large (greater than 9215 bytes) packets received */ -#define IFOE_TELEM_ID_NETPORT_RX_PACKET_LARGE 0x101a -/* enum: Total number of packets longer than rx_max_packet_len with bad FCS */ -#define IFOE_TELEM_ID_NETPORT_RX_JABBER 0x101b -/* enum: Total number of packets longer than rx_max_packet_len with good FCS */ -#define IFOE_TELEM_ID_NETPORT_RX_OVERSIZE 0x101c -/* enum: Total number of received unicast packets */ -#define IFOE_TELEM_ID_NETPORT_RX_UNICAST 0x101d -/* enum: Total number of received multicast packets */ -#define IFOE_TELEM_ID_NETPORT_RX_MULTICAST 0x101e -/* enum: Total number of received broadcast packets */ -#define IFOE_TELEM_ID_NETPORT_RX_BROADCAST 0x101f -/* enum: Total number of received VLAN-tagged packets */ -#define IFOE_TELEM_ID_NETPORT_RX_VLAN 0x1020 -/* enum: Total number of received 802.3x Pause packets with good FCS */ -#define IFOE_TELEM_ID_NETPORT_RX_PAUSE 0x1021 -/* enum: Total number of received priority-based pause packets with good FCS */ -#define IFOE_TELEM_ID_NETPORT_RX_USER_PAUSE 0x1022 -/* enum: Total number of received frames with in-range length errors */ -#define IFOE_TELEM_ID_NETPORT_RX_INRANGEERR 0x1023 -/* enum: Count of FEC processed codewords */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_CW 0x2001 -/* enum: Count of FEC corrected codewords */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_CORRECTED_CW 0x2002 -/* enum: Count of FEC uncorrected codewords */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_UNCORRECTED_CW 0x2003 -/* enum: Count of FEC codeword B for interleaved FEC modes */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_CWB 0x2004 -/* enum: Count of FEC corrected codeword B for interleaved FEC modes */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_CORRECTED_CWB 0x2005 -/* enum: Count of FEC uncorrected codeword B for interleaved FEC modes */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_UNCORRECTED_CWB 0x2006 -/* enum: Number of bits corrected from 0 to 1 by RX FEC on lane 0 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_BIT_ERR_0TO1_L0 0x2007 -/* enum: Number of bits corrected from 0 to 1 by RX FEC on lane 1 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_BIT_ERR_0TO1_L1 0x2008 -/* enum: Number of bits corrected from 0 to 1 by RX FEC on lane 2 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_BIT_ERR_0TO1_L2 0x2009 -/* enum: Number of bits corrected from 0 to 1 by RX FEC on lane 3 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_BIT_ERR_0TO1_L3 0x200a -/* enum: Number of bits corrected from 1 to 0 by RX FEC on lane 0 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_BIT_ERR_1TO0_L0_LSB 0x200b -/* enum: Number of bits corrected from 1 to 0 by RX FEC on lane 1 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_BIT_ERR_1TO0_L1_LSB 0x200c -/* enum: Number of bits corrected from 1 to 0 by RX FEC on lane 2 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_BIT_ERR_1TO0_L2_LSB 0x200d -/* enum: Number of bits corrected from 1 to 0 by RX FEC on lane 3 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_BIT_ERR_1TO0_L3_LSB 0x200e -/* enum: Count of FEC symbol errors corrected on FEC lane 0 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_ERR_COUNT_L0_LSB 0x200f -/* enum: Count of FEC symbol errors corrected on FEC lane 1 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_ERR_COUNT_L1_LSB 0x2010 -/* enum: Count of FEC symbol errors corrected on FEC lane 2 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_ERR_COUNT_L2_LSB 0x2011 -/* enum: Count of FEC symbol errors corrected on FEC lane 3 */ -#define IFOE_TELEM_ID_NETPORT_RX_FEC_ERR_COUNT_L3_LSB 0x2012 -/* enum: The sequence number acknowledged in the most recent successfully - * received LLR_ACK or LLR_NACK. Range of 0 to 1,048,575 - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_ACKED_SEQ 0x3001 -/* enum: Live value of the timer which tracks how long packets have been - * sitting in the replay buffer without any acknowledgement - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_DATA_AGE_TIMER 0x3002 -/* enum: Current value of the total amount of data (in bytes) for - * unacknowledged frames - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_OUTSTANDING_DATA 0x3003 -/* enum: Live value of the number of unacknowledged frames that have been - * transmitted. Range 0 to 524,288 - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_OUTSTANDING_SEQ 0x3004 -/* enum: Live value of the timer which tracks how long PCS_Status is FALSE. - * Units are pairs of tx_core_clk cycles. - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_PCS_LOST_STATUS_TIMER 0x3005 -/* enum: Live value of the counter which tracks how many replay operations have - * been performed without receiving an LLR_ACK - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_REPLAY_CT 0x3006 -/* enum: Live value of the timer which tracks the number of tx_core_clk cycles - * since receiving an LLR_ACK - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_REPLAY_TIMER 0x3007 -/* enum: Sequence number that will be used for the next transmitted LLR- - * eligible frame. Range 0 to 1,048,575 - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_TX_SEQ 0x3008 -/* enum: Latest round-trip latency estimate in ts_clk cycles. 0 indicates that - * no round-trip estimate calculation has yet completed. - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_RTT_ESTIMATE 0x3009 -/* enum: Number of transmitted LLR_ACK CtlOS */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_ACK_CTLOS 0x300a -/* enum: Number of transmitted LLR_NACK CtlOS */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_NACK_CTLOS 0x300b -/* enum: Number of transmitted LLR_INIT CtlOS */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_INIT_CTLOS 0x300c -/* enum: Number of transmitted LLR_INIT_ECHO CtlOS */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_INIT_ECHO_CTLOS 0x300d -/* enum: Number of LLR_ACK/LLR_NACK CtlOS that contain a sequence number that - * implies a sequence number error - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_RCVD_ACK_NACK_SEQ_ERROR 0x300e -/* enum: Number of times the LLR TX FSM exited the REPLAY state */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_REPLAYS_COMPLETED 0x300f -/* enum: Number of transmit frames discarded while the LLR TX is in the FLUSH - * state - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_FLUSH_DISCARDED_PACKETS 0x3010 -/* enum: Number of transmit frames discarded while the LLR TX is in the INIT - * state - */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_INIT_DISCARDED_PACKETS 0x3011 -/* enum: Number of LLR-eligible frames transmitted with a good FCS */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_OK_PACKETS 0x3012 -/* enum: Number of LLR-eligible frames transmitted with a poisoned FCS */ -#define IFOE_TELEM_ID_NETPORT_TX_LLR_POISONED_PACKETS 0x3013 -/* enum: Expected sequence number of the next LLR-eligible frame to be received - */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_NEXT_RX_SEQ 0x4001 -/* enum: Number of received LLR_ACK CtlOS */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_ACK_CTLOS 0x4002 -/* enum: Number of received LLR_NACK CtlOS */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_NACK_CTLOS 0x4003 -/* enum: Number of received LLR_INIT CtlOS */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_INIT_CTLOS 0x4004 -/* enum: Number of received LLR_INIT_ECHO CtlOS */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_INIT_ECHO_CTLOS 0x4005 -/* enum: Number of times the RX detected the start of a replay */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_REPLAYS_DETECTED 0x4006 -/* enum: Number of LLR-eligible frames received with a bad FCS */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_BAD_PACKETS 0x4007 -/* enum: Number of LLR-eligible frames received with a sequence number - * indicating that the frame has already been successfully received - */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_DUPL_SEQ_PACKETS 0x4008 -/* enum: Number of LLR-eligible frames received with the expected sequence - * number and with a bad FCS - */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_EXP_SEQ_BAD_PACKETS 0x4009 -/* enum: Number of LLR-eligible frames received with the expected sequence - * number and a good FCS - */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_EXP_SEQ_GOOD_PACKETS 0x400a -/* enum: Number of LLR-eligible frames received with the expected sequence - * number and a poisoned FCS - */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_EXP_SEQ_POISONED_PACKETS 0x400b -/* enum: Number of LLR-eligible frames received with a sequence number - * indicating that a frame has been lost - */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_MISS_SEQ_PACKETS 0x400c -/* enum: Number of LLR-eligible frames received with a good FCS */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_OK_PACKETS 0x400d -/* enum: Number of LLR-eligible frames received with a poisoned FCS */ -#define IFOE_TELEM_ID_NETPORT_RX_LLR_POISONED_PACKETS 0x400e -#define IFOE_TELEM_ID_NETPORT_LBN 0 -#define IFOE_TELEM_ID_NETPORT_WIDTH 32 -/* Telemetry IDs for the derived / SW constructed telemetry per-IFOE station */ -#define IFOE_TELEM_ID_DERIVED_IFOE_OFST 0 -#define IFOE_TELEM_ID_DERIVED_IFOE_LEN 4 -/* enum property: index */ -/* enum: Bitmask of flags indicating the status of the IFoE logical link. A - * value of 0 means the link is fully up with no issues detected. Refer to - * IFOE_TELEM_LINK_STATUS for the definition of each flag. - */ -#define IFOE_TELEM_ID_IFOE_LOGICAL_LINK_STATUS 0x1 -/* enum: Current bandwidth of IFoE logical link in Gbit/s. If the logical link - * is degraded due to an issue with one of the underlying network ports this - * bandwidth will be reduced. - */ -#define IFOE_TELEM_ID_IFOE_LOGICAL_LINK_BW 0x2 -/* enum: Count of number of IFoE Request packets transmitted */ -#define IFOE_TELEM_ID_IFOE_TX_REQUEST_PKT_COUNT 0x3 -/* enum: Count of number of IFoE Response packets transmitted */ -#define IFOE_TELEM_ID_IFOE_TX_RESPONSE_PKT_COUNT 0x4 -/* enum: Count of number of IFoE Request packets received */ -#define IFOE_TELEM_ID_IFOE_RX_REQUEST_PKT_COUNT 0x5 -/* enum: Count of number of IFoE Response packets received */ -#define IFOE_TELEM_ID_IFOE_RX_RESPONSE_PKT_COUNT 0x6 -/* enum: Count of the total number of streams that have been remapped due to a - * retransmission timeout. - */ -#define IFOE_TELEM_ID_IFOE_STREAM_REMAPS_TOTAL 0x7 -/* enum: Count of the number of streams that have been remapped due to a - * retransmission timeout on Network Port 0 - */ -#define IFOE_TELEM_ID_IFOE_STREAM_REMAPS_NPORT_0 0x8 -/* enum: Count of the number of streams that have been remapped due to a - * retransmission timeout on Network Port 1 - */ -#define IFOE_TELEM_ID_IFOE_STREAM_REMAPS_NPORT_1 0x9 -/* enum: Count of the number of streams that have been remapped due to a - * retransmission timeout on Network Port 2 - */ -#define IFOE_TELEM_ID_IFOE_STREAM_REMAPS_NPORT_2 0xa -/* enum: Count of the number of streams that have been remapped due to a - * retransmission timeout on Network Port 3 - */ -#define IFOE_TELEM_ID_IFOE_STREAM_REMAPS_NPORT_3 0xb -/* enum: Live number of IFoE streams paused due to retransmission timeouts */ -#define IFOE_TELEM_ID_IFOE_PAUSED_STREAMS_COUNT 0xc -/* enum: Count of the number of times the encryption key was updated for - * Security Association 0. - */ -#define IFOE_TELEM_ID_IFOE_CRYPTO_TX_KEY_UPDATES_SA0 0x1001 -/* enum: Count of the number of times decryption key 0 was updated for Security - * Association 0. - */ -#define IFOE_TELEM_ID_IFOE_CRYPTO_RX_KEY0_UPDATES_SA0 0x1002 -/* enum: Count of the number of times decryption key 1 was updated for Security - * Association 0. - */ -#define IFOE_TELEM_ID_IFOE_CRYPTO_RX_KEY1_UPDATES_SA0 0x1003 -/* enum: Count of number of times a decryption key was disabled for Security - * Association 0. - */ -#define IFOE_TELEM_ID_IFOE_CRYPTO_RX_KEY_DISABLES_SA0 0x1004 -/* enum: Count of the number of times the encryption key was updated for - * Security Association 1. - */ -#define IFOE_TELEM_ID_IFOE_CRYPTO_TX_KEY_UPDATES_SA1 0x2001 -/* enum: Count of the number of times decryption key 0 was updated for Security - * Association 1. - */ -#define IFOE_TELEM_ID_IFOE_CRYPTO_RX_KEY0_UPDATES_SA1 0x2002 -/* enum: Count of the number of times decryption key 1 was updated for Security - * Association 1. - */ -#define IFOE_TELEM_ID_IFOE_CRYPTO_RX_KEY1_UPDATES_SA1 0x2003 -/* enum: Count of number of times a decryption key was disabled for Security - * Association 0. - */ -#define IFOE_TELEM_ID_IFOE_CRYPTO_RX_KEY_DISABLES_SA1 0x2004 -#define IFOE_TELEM_ID_DERIVED_IFOE_LBN 0 -#define IFOE_TELEM_ID_DERIVED_IFOE_WIDTH 32 -/* Telemetry IDs for the derived / SW constructed telemetry per Network Port */ -#define IFOE_TELEM_ID_DERIVED_NETPORT_OFST 0 -#define IFOE_TELEM_ID_DERIVED_NETPORT_LEN 4 -/* enum property: index */ -/* enum: Bitmask of flags indicating the status of the Network Port. A value of - * 0 means the link is fully up with no issues detected. Refer to - * IFOE_TELEM_NETPORT_STATUS for the definition of each flag. - */ -#define IFOE_TELEM_ID_NETPORT_LINK_STATUS 0x1 -/* enum: Indicates the auto-negotiated link speed in Gbits/s. Note that this - * field can read a non-zero value even if the link is down. - */ -#define IFOE_TELEM_ID_NETPORT_LINK_SPEED 0x2 -/* enum: Current Bit Error Rate reported by the network port expressed as - * errors per 10^12 bits - */ -#define IFOE_TELEM_ID_NETPORT_BIT_ERROR_RATE 0x3 -/* enum: Time taken to complete link training for most recent link up in ms */ -#define IFOE_TELEM_ID_NETPORT_LAST_LINK_TRAINING_DURATION 0x4 -/* enum: Average time taken to complete link training in ms */ -#define IFOE_TELEM_ID_NETPORT_AVERAGE_LINK_TRAINING_TIME 0x5 -/* enum: Number of times that the network link has come up */ -#define IFOE_TELEM_ID_NETPORT_LINK_UP_COUNT 0x6 -/* enum: Total time that the network link has been up in ms */ -#define IFOE_TELEM_ID_NETPORT_LINK_UP_TIME 0x7 -/* enum: Total time that the network link has been down in ms */ -#define IFOE_TELEM_ID_NETPORT_LINK_DOWN_TIME 0x8 -/* enum: Count of number of FEC codewords with no symbol errors. To support - * creation of a FEC histogram, telemetry is provided of the number of symbol - * errors in each codeword. The values reported at the number of symbol errors - * between snapshots. Host software can accumulate the data over longer periods - * of time as required. - */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_0 0x1001 -/* enum: Count of number of FEC codewords with 1 symbol error */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_1 0x1002 -/* enum: Count of number of FEC codewords with 2 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_2 0x1003 -/* enum: Count of number of FEC codewords with 3 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_3 0x1004 -/* enum: Count of number of FEC codewords with 4 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_4 0x1005 -/* enum: Count of number of FEC codewords with 5 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_5 0x1006 -/* enum: Count of number of FEC codewords with 6 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_6 0x1007 -/* enum: Count of number of FEC codewords with 7 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_7 0x1008 -/* enum: Count of number of FEC codewords with 8 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_8 0x1009 -/* enum: Count of number of FEC codewords with 9 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_9 0x100a -/* enum: Count of number of FEC codewords with 10 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_10 0x100b -/* enum: Count of number of FEC codewords with 11 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_11 0x100c -/* enum: Count of number of FEC codewords with 12 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_12 0x100d -/* enum: Count of number of FEC codewords with 13 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_13 0x100e -/* enum: Count of number of FEC codewords with 14 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_14 0x100f -/* enum: Count of number of FEC codewords with 15 symbol errors */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_15 0x1010 -/* enum: Count of number of FEC codewords with an uncorrectable number of - * symbol errors (>15) - */ -#define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_UNCORRECTABLE 0x1011 -#define IFOE_TELEM_ID_DERIVED_NETPORT_LBN 0 -#define IFOE_TELEM_ID_DERIVED_NETPORT_WIDTH 32 - /* IFOE_TELEM_TAG structuredef: Defines the tags for the various IFoE Telemetry * TLVs */ @@ -1460,13 +29,24 @@ #define IFOE_TELEM_TAG_TAG_ID_OFST 7 #define IFOE_TELEM_TAG_TAG_ID_LEN 1 /* enum property: index */ -#define IFOE_TELEM_TAG_HEADER 0x1 /* enum */ -#define IFOE_TELEM_TAG_DESC_LOCATOR 0x2 /* enum */ -#define IFOE_TELEM_TAG_DATASET_LOCATOR 0x3 /* enum */ -#define IFOE_TELEM_TAG_DESC 0x4 /* enum */ -#define IFOE_TELEM_TAG_DATASET_HDR 0x5 /* enum */ -#define IFOE_TELEM_TAG_DATA 0x6 /* enum */ -#define IFOE_TELEM_TAG_DATASET_FTR 0x7 /* enum */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TAG_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TAG_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TAG_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TAG_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TAG_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TAG_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TAG_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TAG_DATASET_FTR 0x7 #define IFOE_TELEM_TAG_TAG_ID_LBN 56 #define IFOE_TELEM_TAG_TAG_ID_WIDTH 8 /* Telemetry category */ @@ -1489,6 +69,9 @@ #define IFOE_TELEM_TAG_NETPORT_REL_IDX_OFST 0 #define IFOE_TELEM_TAG_NETPORT_REL_IDX_LBN 32 #define IFOE_TELEM_TAG_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TAG_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TAG_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TAG_PHY_LANE_REL_IDX_WIDTH 4 #define IFOE_TELEM_TAG_INSTANCE_LBN 0 #define IFOE_TELEM_TAG_INSTANCE_WIDTH 48 /* For IFoE telemetry, identifies the IFoE Station handle that the telemetry @@ -1498,8 +81,8 @@ #define IFOE_TELEM_TAG_STATION_HANDLE_LEN 4 #define IFOE_TELEM_TAG_STATION_HANDLE_LBN 0 #define IFOE_TELEM_TAG_STATION_HANDLE_WIDTH 32 -/* For Network Port telemetry, identifies the Network Port handle that the - * telemetry data applies to. This handle is unique within a device. +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. */ #define IFOE_TELEM_TAG_NETPORT_HANDLE_OFST 0 #define IFOE_TELEM_TAG_NETPORT_HANDLE_LEN 4 @@ -1517,13 +100,24 @@ #define IFOE_TELEM_TLV_TAG_ID_OFST 7 #define IFOE_TELEM_TLV_TAG_ID_LEN 1 /* enum property: index */ -#define IFOE_TELEM_TLV_HEADER 0x1 /* enum */ -#define IFOE_TELEM_TLV_DESC_LOCATOR 0x2 /* enum */ -#define IFOE_TELEM_TLV_DATASET_LOCATOR 0x3 /* enum */ -#define IFOE_TELEM_TLV_DESC 0x4 /* enum */ -#define IFOE_TELEM_TLV_DATASET_HDR 0x5 /* enum */ -#define IFOE_TELEM_TLV_DATA 0x6 /* enum */ -#define IFOE_TELEM_TLV_DATASET_FTR 0x7 /* enum */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TLV_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TLV_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TLV_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TLV_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TLV_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TLV_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TLV_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TLV_DATASET_FTR 0x7 #define IFOE_TELEM_TLV_TAG_ID_LBN 56 #define IFOE_TELEM_TLV_TAG_ID_WIDTH 8 /* Telemetry category */ @@ -1546,6 +140,9 @@ #define IFOE_TELEM_TLV_NETPORT_REL_IDX_OFST 0 #define IFOE_TELEM_TLV_NETPORT_REL_IDX_LBN 32 #define IFOE_TELEM_TLV_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_PHY_LANE_REL_IDX_WIDTH 4 #define IFOE_TELEM_TLV_INSTANCE_LBN 0 #define IFOE_TELEM_TLV_INSTANCE_WIDTH 48 /* For IFoE telemetry, identifies the IFoE Station handle that the telemetry @@ -1555,8 +152,8 @@ #define IFOE_TELEM_TLV_STATION_HANDLE_LEN 4 #define IFOE_TELEM_TLV_STATION_HANDLE_LBN 0 #define IFOE_TELEM_TLV_STATION_HANDLE_WIDTH 32 -/* For Network Port telemetry, identifies the Network Port handle that the - * telemetry data applies to. This handle is unique within a device. +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. */ #define IFOE_TELEM_TLV_NETPORT_HANDLE_OFST 0 #define IFOE_TELEM_TLV_NETPORT_HANDLE_LEN 4 @@ -1592,6 +189,109 @@ #define IFOE_TELEM_TLV_VALUES_LBN 128 #define IFOE_TELEM_TLV_VALUES_WIDTH 64 +/* IFOE_TELEM_TLV_NULL structuredef: Definition of a null TLV. The VALUES field + * in null TLVs does not contain any valid data so should be ignored by + * clients. In all other respects handling of the TLV is exactly the same as + * other types i.e. the LEN field provides the size of the (invalid) data in + * the VALUES fields and thus provides the position of the next TLV. + */ +#define IFOE_TELEM_TLV_NULL_LENMIN 16 +#define IFOE_TELEM_TLV_NULL_LENMAX 248 +#define IFOE_TELEM_TLV_NULL_LENMAX_MCDI2 1016 +#define IFOE_TELEM_TLV_NULL_LEN(num) (16 + 8 * (num)) +#define IFOE_TELEM_TLV_NULL_VALUES_NUM(len) (((len) - 16) / 8) +#define IFOE_TELEM_TLV_NULL_TAG_ID_OFST 7 +#define IFOE_TELEM_TLV_NULL_TAG_ID_LEN 1 +/* enum property: index */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TLV_NULL_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TLV_NULL_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TLV_NULL_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TLV_NULL_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TLV_NULL_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TLV_NULL_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TLV_NULL_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TLV_NULL_DATASET_FTR 0x7 +#define IFOE_TELEM_TLV_NULL_TAG_ID_LBN 56 +#define IFOE_TELEM_TLV_NULL_TAG_ID_WIDTH 8 +/* Telemetry category */ +#define IFOE_TELEM_TLV_NULL_CATEGORY_OFST 6 +#define IFOE_TELEM_TLV_NULL_CATEGORY_LEN 1 +/* enum property: index */ +/* Enum values, see field(s): */ +/* IFOE_TELEM_CAT */ +#define IFOE_TELEM_TLV_NULL_CATEGORY_LBN 48 +#define IFOE_TELEM_TLV_NULL_CATEGORY_WIDTH 8 +/* Field used to define which instance of a telemetry TLV structure applies to. + * This field can be subdivided as needed for each TLV type that has multiple + * instances. + */ +#define IFOE_TELEM_TLV_NULL_INSTANCE_OFST 0 +#define IFOE_TELEM_TLV_NULL_INSTANCE_LEN 6 +#define IFOE_TELEM_TLV_NULL_STATION_IDX_OFST 0 +#define IFOE_TELEM_TLV_NULL_STATION_IDX_LBN 36 +#define IFOE_TELEM_TLV_NULL_STATION_IDX_WIDTH 12 +#define IFOE_TELEM_TLV_NULL_NETPORT_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_NULL_NETPORT_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_NULL_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_NULL_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_NULL_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_NULL_PHY_LANE_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_NULL_INSTANCE_LBN 0 +#define IFOE_TELEM_TLV_NULL_INSTANCE_WIDTH 48 +/* For IFoE telemetry, identifies the IFoE Station handle that the telemetry + * data applies to. This handle is unique within a device. + */ +#define IFOE_TELEM_TLV_NULL_STATION_HANDLE_OFST 0 +#define IFOE_TELEM_TLV_NULL_STATION_HANDLE_LEN 4 +#define IFOE_TELEM_TLV_NULL_STATION_HANDLE_LBN 0 +#define IFOE_TELEM_TLV_NULL_STATION_HANDLE_WIDTH 32 +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. + */ +#define IFOE_TELEM_TLV_NULL_NETPORT_HANDLE_OFST 0 +#define IFOE_TELEM_TLV_NULL_NETPORT_HANDLE_LEN 4 +#define IFOE_TELEM_TLV_NULL_NETPORT_HANDLE_LBN 0 +#define IFOE_TELEM_TLV_NULL_NETPORT_HANDLE_WIDTH 32 +/* Size of the data following this field i.e. not including the Tag or Length + */ +#define IFOE_TELEM_TLV_NULL_LEN_OFST 8 +#define IFOE_TELEM_TLV_NULL_LEN_LEN 8 +#define IFOE_TELEM_TLV_NULL_LEN_LO_OFST 8 +#define IFOE_TELEM_TLV_NULL_LEN_LO_LEN 4 +#define IFOE_TELEM_TLV_NULL_LEN_LO_LBN 64 +#define IFOE_TELEM_TLV_NULL_LEN_LO_WIDTH 32 +#define IFOE_TELEM_TLV_NULL_LEN_HI_OFST 12 +#define IFOE_TELEM_TLV_NULL_LEN_HI_LEN 4 +#define IFOE_TELEM_TLV_NULL_LEN_HI_LBN 96 +#define IFOE_TELEM_TLV_NULL_LEN_HI_WIDTH 32 +#define IFOE_TELEM_TLV_NULL_LEN_LBN 64 +#define IFOE_TELEM_TLV_NULL_LEN_WIDTH 64 +#define IFOE_TELEM_TLV_NULL_VALUES_OFST 16 +#define IFOE_TELEM_TLV_NULL_VALUES_LEN 8 +#define IFOE_TELEM_TLV_NULL_VALUES_LO_OFST 16 +#define IFOE_TELEM_TLV_NULL_VALUES_LO_LEN 4 +#define IFOE_TELEM_TLV_NULL_VALUES_LO_LBN 128 +#define IFOE_TELEM_TLV_NULL_VALUES_LO_WIDTH 32 +#define IFOE_TELEM_TLV_NULL_VALUES_HI_OFST 20 +#define IFOE_TELEM_TLV_NULL_VALUES_HI_LEN 4 +#define IFOE_TELEM_TLV_NULL_VALUES_HI_LBN 160 +#define IFOE_TELEM_TLV_NULL_VALUES_HI_WIDTH 32 +#define IFOE_TELEM_TLV_NULL_VALUES_MINNUM 0 +#define IFOE_TELEM_TLV_NULL_VALUES_MAXNUM 29 +#define IFOE_TELEM_TLV_NULL_VALUES_MAXNUM_MCDI2 125 +#define IFOE_TELEM_TLV_NULL_VALUES_LBN 128 +#define IFOE_TELEM_TLV_NULL_VALUES_WIDTH 64 + /* IFOE_TELEM_TLV_HDR structuredef: Definition of the top-level header TLV */ #define IFOE_TELEM_TLV_HDR_LENMIN 40 #define IFOE_TELEM_TLV_HDR_LENMAX 248 @@ -1601,13 +301,24 @@ #define IFOE_TELEM_TLV_HDR_TAG_ID_OFST 7 #define IFOE_TELEM_TLV_HDR_TAG_ID_LEN 1 /* enum property: index */ -#define IFOE_TELEM_TLV_HDR_HEADER 0x1 /* enum */ -#define IFOE_TELEM_TLV_HDR_DESC_LOCATOR 0x2 /* enum */ -#define IFOE_TELEM_TLV_HDR_DATASET_LOCATOR 0x3 /* enum */ -#define IFOE_TELEM_TLV_HDR_DESC 0x4 /* enum */ -#define IFOE_TELEM_TLV_HDR_DATASET_HDR 0x5 /* enum */ -#define IFOE_TELEM_TLV_HDR_DATA 0x6 /* enum */ -#define IFOE_TELEM_TLV_HDR_DATASET_FTR 0x7 /* enum */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TLV_HDR_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TLV_HDR_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TLV_HDR_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TLV_HDR_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TLV_HDR_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TLV_HDR_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TLV_HDR_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TLV_HDR_DATASET_FTR 0x7 #define IFOE_TELEM_TLV_HDR_TAG_ID_LBN 56 #define IFOE_TELEM_TLV_HDR_TAG_ID_WIDTH 8 /* Telemetry category */ @@ -1630,6 +341,9 @@ #define IFOE_TELEM_TLV_HDR_NETPORT_REL_IDX_OFST 0 #define IFOE_TELEM_TLV_HDR_NETPORT_REL_IDX_LBN 32 #define IFOE_TELEM_TLV_HDR_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_HDR_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_HDR_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_HDR_PHY_LANE_REL_IDX_WIDTH 4 #define IFOE_TELEM_TLV_HDR_INSTANCE_LBN 0 #define IFOE_TELEM_TLV_HDR_INSTANCE_WIDTH 48 /* For IFoE telemetry, identifies the IFoE Station handle that the telemetry @@ -1639,8 +353,8 @@ #define IFOE_TELEM_TLV_HDR_STATION_HANDLE_LEN 4 #define IFOE_TELEM_TLV_HDR_STATION_HANDLE_LBN 0 #define IFOE_TELEM_TLV_HDR_STATION_HANDLE_WIDTH 32 -/* For Network Port telemetry, identifies the Network Port handle that the - * telemetry data applies to. This handle is unique within a device. +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. */ #define IFOE_TELEM_TLV_HDR_NETPORT_HANDLE_OFST 0 #define IFOE_TELEM_TLV_HDR_NETPORT_HANDLE_LEN 4 @@ -1738,13 +452,24 @@ #define IFOE_TELEM_TLV_DESC_LOCATOR_TAG_ID_OFST 7 #define IFOE_TELEM_TLV_DESC_LOCATOR_TAG_ID_LEN 1 /* enum property: index */ -#define IFOE_TELEM_TLV_DESC_LOCATOR_HEADER 0x1 /* enum */ -#define IFOE_TELEM_TLV_DESC_LOCATOR_DESC_LOCATOR 0x2 /* enum */ -#define IFOE_TELEM_TLV_DESC_LOCATOR_DATASET_LOCATOR 0x3 /* enum */ -#define IFOE_TELEM_TLV_DESC_LOCATOR_DESC 0x4 /* enum */ -#define IFOE_TELEM_TLV_DESC_LOCATOR_DATASET_HDR 0x5 /* enum */ -#define IFOE_TELEM_TLV_DESC_LOCATOR_DATA 0x6 /* enum */ -#define IFOE_TELEM_TLV_DESC_LOCATOR_DATASET_FTR 0x7 /* enum */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TLV_DESC_LOCATOR_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TLV_DESC_LOCATOR_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TLV_DESC_LOCATOR_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TLV_DESC_LOCATOR_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TLV_DESC_LOCATOR_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TLV_DESC_LOCATOR_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TLV_DESC_LOCATOR_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TLV_DESC_LOCATOR_DATASET_FTR 0x7 #define IFOE_TELEM_TLV_DESC_LOCATOR_TAG_ID_LBN 56 #define IFOE_TELEM_TLV_DESC_LOCATOR_TAG_ID_WIDTH 8 /* Telemetry category */ @@ -1767,6 +492,9 @@ #define IFOE_TELEM_TLV_DESC_LOCATOR_NETPORT_REL_IDX_OFST 0 #define IFOE_TELEM_TLV_DESC_LOCATOR_NETPORT_REL_IDX_LBN 32 #define IFOE_TELEM_TLV_DESC_LOCATOR_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_DESC_LOCATOR_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_DESC_LOCATOR_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_DESC_LOCATOR_PHY_LANE_REL_IDX_WIDTH 4 #define IFOE_TELEM_TLV_DESC_LOCATOR_INSTANCE_LBN 0 #define IFOE_TELEM_TLV_DESC_LOCATOR_INSTANCE_WIDTH 48 /* For IFoE telemetry, identifies the IFoE Station handle that the telemetry @@ -1776,8 +504,8 @@ #define IFOE_TELEM_TLV_DESC_LOCATOR_STATION_HANDLE_LEN 4 #define IFOE_TELEM_TLV_DESC_LOCATOR_STATION_HANDLE_LBN 0 #define IFOE_TELEM_TLV_DESC_LOCATOR_STATION_HANDLE_WIDTH 32 -/* For Network Port telemetry, identifies the Network Port handle that the - * telemetry data applies to. This handle is unique within a device. +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. */ #define IFOE_TELEM_TLV_DESC_LOCATOR_NETPORT_HANDLE_OFST 0 #define IFOE_TELEM_TLV_DESC_LOCATOR_NETPORT_HANDLE_LEN 4 @@ -1843,13 +571,24 @@ #define IFOE_TELEM_TLV_DATASET_LOCATOR_TAG_ID_OFST 7 #define IFOE_TELEM_TLV_DATASET_LOCATOR_TAG_ID_LEN 1 /* enum property: index */ -#define IFOE_TELEM_TLV_DATASET_LOCATOR_HEADER 0x1 /* enum */ -#define IFOE_TELEM_TLV_DATASET_LOCATOR_DESC_LOCATOR 0x2 /* enum */ -#define IFOE_TELEM_TLV_DATASET_LOCATOR_DATASET_LOCATOR 0x3 /* enum */ -#define IFOE_TELEM_TLV_DATASET_LOCATOR_DESC 0x4 /* enum */ -#define IFOE_TELEM_TLV_DATASET_LOCATOR_DATASET_HDR 0x5 /* enum */ -#define IFOE_TELEM_TLV_DATASET_LOCATOR_DATA 0x6 /* enum */ -#define IFOE_TELEM_TLV_DATASET_LOCATOR_DATASET_FTR 0x7 /* enum */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TLV_DATASET_LOCATOR_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TLV_DATASET_LOCATOR_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TLV_DATASET_LOCATOR_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TLV_DATASET_LOCATOR_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TLV_DATASET_LOCATOR_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TLV_DATASET_LOCATOR_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TLV_DATASET_LOCATOR_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TLV_DATASET_LOCATOR_DATASET_FTR 0x7 #define IFOE_TELEM_TLV_DATASET_LOCATOR_TAG_ID_LBN 56 #define IFOE_TELEM_TLV_DATASET_LOCATOR_TAG_ID_WIDTH 8 /* Telemetry category */ @@ -1872,6 +611,9 @@ #define IFOE_TELEM_TLV_DATASET_LOCATOR_NETPORT_REL_IDX_OFST 0 #define IFOE_TELEM_TLV_DATASET_LOCATOR_NETPORT_REL_IDX_LBN 32 #define IFOE_TELEM_TLV_DATASET_LOCATOR_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_DATASET_LOCATOR_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_DATASET_LOCATOR_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_DATASET_LOCATOR_PHY_LANE_REL_IDX_WIDTH 4 #define IFOE_TELEM_TLV_DATASET_LOCATOR_INSTANCE_LBN 0 #define IFOE_TELEM_TLV_DATASET_LOCATOR_INSTANCE_WIDTH 48 /* For IFoE telemetry, identifies the IFoE Station handle that the telemetry @@ -1881,8 +623,8 @@ #define IFOE_TELEM_TLV_DATASET_LOCATOR_STATION_HANDLE_LEN 4 #define IFOE_TELEM_TLV_DATASET_LOCATOR_STATION_HANDLE_LBN 0 #define IFOE_TELEM_TLV_DATASET_LOCATOR_STATION_HANDLE_WIDTH 32 -/* For Network Port telemetry, identifies the Network Port handle that the - * telemetry data applies to. This handle is unique within a device. +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. */ #define IFOE_TELEM_TLV_DATASET_LOCATOR_NETPORT_HANDLE_OFST 0 #define IFOE_TELEM_TLV_DATASET_LOCATOR_NETPORT_HANDLE_LEN 4 @@ -1948,13 +690,24 @@ #define IFOE_TELEM_TLV_DESC_TAG_ID_OFST 7 #define IFOE_TELEM_TLV_DESC_TAG_ID_LEN 1 /* enum property: index */ -#define IFOE_TELEM_TLV_DESC_HEADER 0x1 /* enum */ -#define IFOE_TELEM_TLV_DESC_DESC_LOCATOR 0x2 /* enum */ -#define IFOE_TELEM_TLV_DESC_DATASET_LOCATOR 0x3 /* enum */ -#define IFOE_TELEM_TLV_DESC_DESC 0x4 /* enum */ -#define IFOE_TELEM_TLV_DESC_DATASET_HDR 0x5 /* enum */ -#define IFOE_TELEM_TLV_DESC_DATA 0x6 /* enum */ -#define IFOE_TELEM_TLV_DESC_DATASET_FTR 0x7 /* enum */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TLV_DESC_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TLV_DESC_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TLV_DESC_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TLV_DESC_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TLV_DESC_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TLV_DESC_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TLV_DESC_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TLV_DESC_DATASET_FTR 0x7 #define IFOE_TELEM_TLV_DESC_TAG_ID_LBN 56 #define IFOE_TELEM_TLV_DESC_TAG_ID_WIDTH 8 /* Telemetry category */ @@ -1977,6 +730,9 @@ #define IFOE_TELEM_TLV_DESC_NETPORT_REL_IDX_OFST 0 #define IFOE_TELEM_TLV_DESC_NETPORT_REL_IDX_LBN 32 #define IFOE_TELEM_TLV_DESC_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_DESC_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_DESC_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_DESC_PHY_LANE_REL_IDX_WIDTH 4 #define IFOE_TELEM_TLV_DESC_INSTANCE_LBN 0 #define IFOE_TELEM_TLV_DESC_INSTANCE_WIDTH 48 /* For IFoE telemetry, identifies the IFoE Station handle that the telemetry @@ -1986,8 +742,8 @@ #define IFOE_TELEM_TLV_DESC_STATION_HANDLE_LEN 4 #define IFOE_TELEM_TLV_DESC_STATION_HANDLE_LBN 0 #define IFOE_TELEM_TLV_DESC_STATION_HANDLE_WIDTH 32 -/* For Network Port telemetry, identifies the Network Port handle that the - * telemetry data applies to. This handle is unique within a device. +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. */ #define IFOE_TELEM_TLV_DESC_NETPORT_HANDLE_OFST 0 #define IFOE_TELEM_TLV_DESC_NETPORT_HANDLE_LEN 4 @@ -2051,13 +807,24 @@ #define IFOE_TELEM_TLV_DATASET_HDR_TAG_ID_OFST 7 #define IFOE_TELEM_TLV_DATASET_HDR_TAG_ID_LEN 1 /* enum property: index */ -#define IFOE_TELEM_TLV_DATASET_HDR_HEADER 0x1 /* enum */ -#define IFOE_TELEM_TLV_DATASET_HDR_DESC_LOCATOR 0x2 /* enum */ -#define IFOE_TELEM_TLV_DATASET_HDR_DATASET_LOCATOR 0x3 /* enum */ -#define IFOE_TELEM_TLV_DATASET_HDR_DESC 0x4 /* enum */ -#define IFOE_TELEM_TLV_DATASET_HDR_DATASET_HDR 0x5 /* enum */ -#define IFOE_TELEM_TLV_DATASET_HDR_DATA 0x6 /* enum */ -#define IFOE_TELEM_TLV_DATASET_HDR_DATASET_FTR 0x7 /* enum */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TLV_DATASET_HDR_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TLV_DATASET_HDR_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TLV_DATASET_HDR_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TLV_DATASET_HDR_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TLV_DATASET_HDR_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TLV_DATASET_HDR_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TLV_DATASET_HDR_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TLV_DATASET_HDR_DATASET_FTR 0x7 #define IFOE_TELEM_TLV_DATASET_HDR_TAG_ID_LBN 56 #define IFOE_TELEM_TLV_DATASET_HDR_TAG_ID_WIDTH 8 /* Telemetry category */ @@ -2080,6 +847,9 @@ #define IFOE_TELEM_TLV_DATASET_HDR_NETPORT_REL_IDX_OFST 0 #define IFOE_TELEM_TLV_DATASET_HDR_NETPORT_REL_IDX_LBN 32 #define IFOE_TELEM_TLV_DATASET_HDR_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_DATASET_HDR_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_DATASET_HDR_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_DATASET_HDR_PHY_LANE_REL_IDX_WIDTH 4 #define IFOE_TELEM_TLV_DATASET_HDR_INSTANCE_LBN 0 #define IFOE_TELEM_TLV_DATASET_HDR_INSTANCE_WIDTH 48 /* For IFoE telemetry, identifies the IFoE Station handle that the telemetry @@ -2089,8 +859,8 @@ #define IFOE_TELEM_TLV_DATASET_HDR_STATION_HANDLE_LEN 4 #define IFOE_TELEM_TLV_DATASET_HDR_STATION_HANDLE_LBN 0 #define IFOE_TELEM_TLV_DATASET_HDR_STATION_HANDLE_WIDTH 32 -/* For Network Port telemetry, identifies the Network Port handle that the - * telemetry data applies to. This handle is unique within a device. +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. */ #define IFOE_TELEM_TLV_DATASET_HDR_NETPORT_HANDLE_OFST 0 #define IFOE_TELEM_TLV_DATASET_HDR_NETPORT_HANDLE_LEN 4 @@ -2168,13 +938,24 @@ #define IFOE_TELEM_TLV_DATA_TAG_ID_OFST 7 #define IFOE_TELEM_TLV_DATA_TAG_ID_LEN 1 /* enum property: index */ -#define IFOE_TELEM_TLV_DATA_HEADER 0x1 /* enum */ -#define IFOE_TELEM_TLV_DATA_DESC_LOCATOR 0x2 /* enum */ -#define IFOE_TELEM_TLV_DATA_DATASET_LOCATOR 0x3 /* enum */ -#define IFOE_TELEM_TLV_DATA_DESC 0x4 /* enum */ -#define IFOE_TELEM_TLV_DATA_DATASET_HDR 0x5 /* enum */ -#define IFOE_TELEM_TLV_DATA_DATA 0x6 /* enum */ -#define IFOE_TELEM_TLV_DATA_DATASET_FTR 0x7 /* enum */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TLV_DATA_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TLV_DATA_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TLV_DATA_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TLV_DATA_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TLV_DATA_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TLV_DATA_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TLV_DATA_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TLV_DATA_DATASET_FTR 0x7 #define IFOE_TELEM_TLV_DATA_TAG_ID_LBN 56 #define IFOE_TELEM_TLV_DATA_TAG_ID_WIDTH 8 /* Telemetry category */ @@ -2197,6 +978,9 @@ #define IFOE_TELEM_TLV_DATA_NETPORT_REL_IDX_OFST 0 #define IFOE_TELEM_TLV_DATA_NETPORT_REL_IDX_LBN 32 #define IFOE_TELEM_TLV_DATA_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_DATA_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_DATA_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_DATA_PHY_LANE_REL_IDX_WIDTH 4 #define IFOE_TELEM_TLV_DATA_INSTANCE_LBN 0 #define IFOE_TELEM_TLV_DATA_INSTANCE_WIDTH 48 /* For IFoE telemetry, identifies the IFoE Station handle that the telemetry @@ -2206,8 +990,8 @@ #define IFOE_TELEM_TLV_DATA_STATION_HANDLE_LEN 4 #define IFOE_TELEM_TLV_DATA_STATION_HANDLE_LBN 0 #define IFOE_TELEM_TLV_DATA_STATION_HANDLE_WIDTH 32 -/* For Network Port telemetry, identifies the Network Port handle that the - * telemetry data applies to. This handle is unique within a device. +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. */ #define IFOE_TELEM_TLV_DATA_NETPORT_HANDLE_OFST 0 #define IFOE_TELEM_TLV_DATA_NETPORT_HANDLE_LEN 4 @@ -2256,13 +1040,24 @@ #define IFOE_TELEM_TLV_DATASET_FTR_TAG_ID_OFST 7 #define IFOE_TELEM_TLV_DATASET_FTR_TAG_ID_LEN 1 /* enum property: index */ -#define IFOE_TELEM_TLV_DATASET_FTR_HEADER 0x1 /* enum */ -#define IFOE_TELEM_TLV_DATASET_FTR_DESC_LOCATOR 0x2 /* enum */ -#define IFOE_TELEM_TLV_DATASET_FTR_DATASET_LOCATOR 0x3 /* enum */ -#define IFOE_TELEM_TLV_DATASET_FTR_DESC 0x4 /* enum */ -#define IFOE_TELEM_TLV_DATASET_FTR_DATASET_HDR 0x5 /* enum */ -#define IFOE_TELEM_TLV_DATASET_FTR_DATA 0x6 /* enum */ -#define IFOE_TELEM_TLV_DATASET_FTR_DATASET_FTR 0x7 /* enum */ +/* enum: Indicates that the TLV is null and all other fields in the + * IFOE_TELEM_TAG should be ignored by the consumer. + */ +#define IFOE_TELEM_TLV_DATASET_FTR_NULL 0x0 +/* enum: Indicates that this is top-level telemetry header TLV tag. */ +#define IFOE_TELEM_TLV_DATASET_FTR_HEADER 0x1 +/* enum: Indicates that this is a telemetry description locator TLV */ +#define IFOE_TELEM_TLV_DATASET_FTR_DESC_LOCATOR 0x2 +/* enum: Indicates that this is a telemetry dataset locator TLV */ +#define IFOE_TELEM_TLV_DATASET_FTR_DATASET_LOCATOR 0x3 +/* enum: Indicates that this is a telemetry description TLV */ +#define IFOE_TELEM_TLV_DATASET_FTR_DESC 0x4 +/* enum: Indicates that this is a dataset header TLV */ +#define IFOE_TELEM_TLV_DATASET_FTR_DATASET_HDR 0x5 +/* enum: Indicates that this is a data instance TLV */ +#define IFOE_TELEM_TLV_DATASET_FTR_DATA 0x6 +/* enum: Indicates that this is a dataset footer TLV */ +#define IFOE_TELEM_TLV_DATASET_FTR_DATASET_FTR 0x7 #define IFOE_TELEM_TLV_DATASET_FTR_TAG_ID_LBN 56 #define IFOE_TELEM_TLV_DATASET_FTR_TAG_ID_WIDTH 8 /* Telemetry category */ @@ -2285,6 +1080,9 @@ #define IFOE_TELEM_TLV_DATASET_FTR_NETPORT_REL_IDX_OFST 0 #define IFOE_TELEM_TLV_DATASET_FTR_NETPORT_REL_IDX_LBN 32 #define IFOE_TELEM_TLV_DATASET_FTR_NETPORT_REL_IDX_WIDTH 4 +#define IFOE_TELEM_TLV_DATASET_FTR_PHY_LANE_REL_IDX_OFST 0 +#define IFOE_TELEM_TLV_DATASET_FTR_PHY_LANE_REL_IDX_LBN 32 +#define IFOE_TELEM_TLV_DATASET_FTR_PHY_LANE_REL_IDX_WIDTH 4 #define IFOE_TELEM_TLV_DATASET_FTR_INSTANCE_LBN 0 #define IFOE_TELEM_TLV_DATASET_FTR_INSTANCE_WIDTH 48 /* For IFoE telemetry, identifies the IFoE Station handle that the telemetry @@ -2294,8 +1092,8 @@ #define IFOE_TELEM_TLV_DATASET_FTR_STATION_HANDLE_LEN 4 #define IFOE_TELEM_TLV_DATASET_FTR_STATION_HANDLE_LBN 0 #define IFOE_TELEM_TLV_DATASET_FTR_STATION_HANDLE_WIDTH 32 -/* For Network Port telemetry, identifies the Network Port handle that the - * telemetry data applies to. This handle is unique within a device. +/* For Network Port, PFC and PHY telemetry, identifies the Network Port handle + * that the telemetry data applies to. This handle is unique within a device. */ #define IFOE_TELEM_TLV_DATASET_FTR_NETPORT_HANDLE_OFST 0 #define IFOE_TELEM_TLV_DATASET_FTR_NETPORT_HANDLE_LEN 4 diff --git a/projects/amdsmi/include/ualoe_lib/ifoe_telemetry_hostapp.h b/projects/amdsmi/include/ualoe_lib/ifoe_telemetry_hostapp.h index 40366b25b3cd..8df23764a009 100644 --- a/projects/amdsmi/include/ualoe_lib/ifoe_telemetry_hostapp.h +++ b/projects/amdsmi/include/ualoe_lib/ifoe_telemetry_hostapp.h @@ -58,6 +58,14 @@ * Port instance, for example the Network Port status */ #define IFOE_TELEM_CAT_DERIVED_NETPORT 0x6 +/* enum: Debug telemetry associated with the IFoE data path. Telemetry in this + * category is defined per IFoE Station. + */ +#define IFOE_TELEM_CAT_IFOE_DEBUG 0x7 +/* enum: Telemetry associated with the ethernet PHYs. Telemetry in this + * category is defined as a dataset per Serdes lane. + */ +#define IFOE_TELEM_CAT_PHY 0x8 /* IFOE_TELEM_LINK_STATUS structuredef: Flags indicating the IFoE logical link * status. The flags defined here apply to the telemetry data for @@ -1403,9 +1411,9 @@ #define IFOE_TELEM_ID_NETPORT_LINK_DOWN_TIME 0x6000008 /* enum: Count of number of FEC codewords with no symbol errors. To support * creation of a FEC histogram, telemetry is provided of the number of symbol - * errors in each codeword. The values reported at the number of symbol errors - * between snapshots. Host software can accumulate the data over longer periods - * of time as required. + * errors in each codeword. The reported number of codewords are accumulated + * values. Host could compare with previous readings to determine the number of + * codewords with a given number of symbol errors during a time interval. */ #define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_0 0x6001001 /* enum: Count of number of FEC codewords with 1 symbol error */ @@ -1442,5 +1450,470 @@ * symbol errors (>15) */ #define IFOE_TELEM_ID_NETPORT_FEC_CW_SYMBOL_ERRS_UNCORRECTABLE 0x6001011 +/* enum: Total count of packets that were received from the network but + * silently dropped (by firmware). This is the sum of all drop counters below. + */ +#define IFOE_TELEM_ID_NETPORT_RX_DROP_TOTAL 0x6002001 +/* enum: Count of packets dropped due to a mismatch between the destination MAC + * address and the local accelerator MAC. Excluding broadcast or multicast + * addresses. + */ +#define IFOE_TELEM_ID_NETPORT_RX_DROP_MAC_FILTERED 0x6002002 +/* enum: Count of packets dropped due to no available host RX descriptor to + * deliver the packet into. + */ +#define IFOE_TELEM_ID_NETPORT_RX_DROP_NO_DESCRIPTOR 0x6002003 +/* enum: Count of packets dropped due to the DMA transfer of the packet to host + * memory failing. + */ +#define IFOE_TELEM_ID_NETPORT_RX_DROP_DMA_ERROR 0x6002004 +/* enum: Count of control packets (e.g. IFoE ping) dropped by firmware because + * they were malformed, unaddressed to this accelerator or otherwise failed + * validation. + */ +#define IFOE_TELEM_ID_NETPORT_RX_DROP_INVALID 0x6002005 +/* enum: *** Telemetry IDs for the IFoE debug datapath *** Number of packets + * queued by perfmon instance 0 + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_PACKETS_QUEUED 0x7001001 +/* enum: Number of packets sent by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_PACKETS_SENT 0x7001002 +/* enum: Number of packets resent by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_PACKETS_RESENT 0x7001003 +/* enum: Number of packets freed by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_PACKETS_FREED 0x7001004 +/* enum: Number of granules queued by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_GRANULES_QUEUED 0x7001005 +/* enum: Number of granules sent by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_GRANULES_SENT 0x7001006 +/* enum: Number of granules resent by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_GRANULES_RESENT 0x7001007 +/* enum: Number of granules freed by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_GRANULES_FREED 0x7001008 +/* enum: Number of pure ACK packets sent by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_PACKETS_PURE_ACK 0x7001009 +/* enum: Number of TXNAKs observed by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_TXNAKS 0x700100a +/* enum: Number of TXACK timer elapses observed by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_TXACK_ELAPSES 0x700100b +/* enum: Number of RXNAKs observed by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_RXNAKS 0x700100c +/* enum: Number of RXACK timer elapses observed by perfmon instance 0 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_RXACK_ELAPSES 0x700100d +/* enum: Mean number of packets in-flight measured by perfmon instance 0, in + * fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_MEAN_PACKETS_INFLIGHT 0x700100e +/* enum: Mean number of granules in-flight measured by perfmon instance 0, in + * fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_MEAN_GRANULES_INFLIGHT 0x700100f +/* enum: Mean send latency in cycles measured by perfmon instance 0, in fixed- + * point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_MEAN_SEND_LATENCY 0x7001010 +/* enum: Mean absolute deviation of send latency in cycles measured by perfmon + * instance 0, in fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_MAD_SEND_LATENCY 0x7001011 +/* enum: Mean free latency in cycles measured by perfmon instance 0, in fixed- + * point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_MEAN_FREE_LATENCY 0x7001012 +/* enum: Mean absolute deviation of free latency in cycles measured by perfmon + * instance 0, in fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON0_MAD_FREE_LATENCY 0x7001013 +/* enum: Number of packets queued by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_PACKETS_QUEUED 0x7002001 +/* enum: Number of packets sent by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_PACKETS_SENT 0x7002002 +/* enum: Number of packets resent by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_PACKETS_RESENT 0x7002003 +/* enum: Number of packets freed by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_PACKETS_FREED 0x7002004 +/* enum: Number of granules queued by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_GRANULES_QUEUED 0x7002005 +/* enum: Number of granules sent by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_GRANULES_SENT 0x7002006 +/* enum: Number of granules resent by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_GRANULES_RESENT 0x7002007 +/* enum: Number of granules freed by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_GRANULES_FREED 0x7002008 +/* enum: Number of pure ACK packets sent by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_PACKETS_PURE_ACK 0x7002009 +/* enum: Number of TXNAKs observed by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_TXNAKS 0x700200a +/* enum: Number of TXACK timer elapses observed by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_TXACK_ELAPSES 0x700200b +/* enum: Number of RXNAKs observed by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_RXNAKS 0x700200c +/* enum: Number of RXACK timer elapses observed by perfmon instance 1 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_RXACK_ELAPSES 0x700200d +/* enum: Mean number of packets in-flight measured by perfmon instance 1, in + * fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_MEAN_PACKETS_INFLIGHT 0x700200e +/* enum: Mean number of granules in-flight measured by perfmon instance 1, in + * fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_MEAN_GRANULES_INFLIGHT 0x700200f +/* enum: Mean send latency in cycles measured by perfmon instance 1, in fixed- + * point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_MEAN_SEND_LATENCY 0x7002010 +/* enum: Mean absolute deviation of send latency in cycles measured by perfmon + * instance 1, in fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_MAD_SEND_LATENCY 0x7002011 +/* enum: Mean free latency in cycles measured by perfmon instance 1, in fixed- + * point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_MEAN_FREE_LATENCY 0x7002012 +/* enum: Mean absolute deviation of free latency in cycles measured by perfmon + * instance 1, in fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON1_MAD_FREE_LATENCY 0x7002013 +/* enum: Number of packets queued by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_PACKETS_QUEUED 0x7003001 +/* enum: Number of packets sent by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_PACKETS_SENT 0x7003002 +/* enum: Number of packets resent by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_PACKETS_RESENT 0x7003003 +/* enum: Number of packets freed by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_PACKETS_FREED 0x7003004 +/* enum: Number of granules queued by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_GRANULES_QUEUED 0x7003005 +/* enum: Number of granules sent by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_GRANULES_SENT 0x7003006 +/* enum: Number of granules resent by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_GRANULES_RESENT 0x7003007 +/* enum: Number of granules freed by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_GRANULES_FREED 0x7003008 +/* enum: Number of pure ACK packets sent by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_PACKETS_PURE_ACK 0x7003009 +/* enum: Number of TXNAKs observed by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_TXNAKS 0x700300a +/* enum: Number of TXACK timer elapses observed by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_TXACK_ELAPSES 0x700300b +/* enum: Number of RXNAKs observed by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_RXNAKS 0x700300c +/* enum: Number of RXACK timer elapses observed by perfmon instance 2 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_RXACK_ELAPSES 0x700300d +/* enum: Mean number of packets in-flight measured by perfmon instance 2, in + * fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_MEAN_PACKETS_INFLIGHT 0x700300e +/* enum: Mean number of granules in-flight measured by perfmon instance 2, in + * fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_MEAN_GRANULES_INFLIGHT 0x700300f +/* enum: Mean send latency in cycles measured by perfmon instance 2, in fixed- + * point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_MEAN_SEND_LATENCY 0x7003010 +/* enum: Mean absolute deviation of send latency in cycles measured by perfmon + * instance 2, in fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_MAD_SEND_LATENCY 0x7003011 +/* enum: Mean free latency in cycles measured by perfmon instance 2, in fixed- + * point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_MEAN_FREE_LATENCY 0x7003012 +/* enum: Mean absolute deviation of free latency in cycles measured by perfmon + * instance 2, in fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON2_MAD_FREE_LATENCY 0x7003013 +/* enum: Number of packets queued by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_PACKETS_QUEUED 0x7004001 +/* enum: Number of packets sent by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_PACKETS_SENT 0x7004002 +/* enum: Number of packets resent by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_PACKETS_RESENT 0x7004003 +/* enum: Number of packets freed by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_PACKETS_FREED 0x7004004 +/* enum: Number of granules queued by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_GRANULES_QUEUED 0x7004005 +/* enum: Number of granules sent by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_GRANULES_SENT 0x7004006 +/* enum: Number of granules resent by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_GRANULES_RESENT 0x7004007 +/* enum: Number of granules freed by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_GRANULES_FREED 0x7004008 +/* enum: Number of pure ACK packets sent by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_PACKETS_PURE_ACK 0x7004009 +/* enum: Number of TXNAKs observed by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_TXNAKS 0x700400a +/* enum: Number of TXACK timer elapses observed by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_TXACK_ELAPSES 0x700400b +/* enum: Number of RXNAKs observed by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_RXNAKS 0x700400c +/* enum: Number of RXACK timer elapses observed by perfmon instance 3 */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_RXACK_ELAPSES 0x700400d +/* enum: Mean number of packets in-flight measured by perfmon instance 3, in + * fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_MEAN_PACKETS_INFLIGHT 0x700400e +/* enum: Mean number of granules in-flight measured by perfmon instance 3, in + * fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_MEAN_GRANULES_INFLIGHT 0x700400f +/* enum: Mean send latency in cycles measured by perfmon instance 3, in fixed- + * point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_MEAN_SEND_LATENCY 0x7004010 +/* enum: Mean absolute deviation of send latency in cycles measured by perfmon + * instance 3, in fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_MAD_SEND_LATENCY 0x7004011 +/* enum: Mean free latency in cycles measured by perfmon instance 3, in fixed- + * point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_MEAN_FREE_LATENCY 0x7004012 +/* enum: Mean absolute deviation of free latency in cycles measured by perfmon + * instance 3, in fixed-point format with 8 fractional bits + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PERFMON3_MAD_FREE_LATENCY 0x7004013 +/* enum: *** RX SOP error flags and SEEN counters *** Raw SOP error flags + * register. Each bit corresponds to a sticky error condition detected at SOP. + * Bit definitions match STA_RX_DECAP_SOP_ERROR_FLAGS in the hardware register + * map. + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_SOP_ERROR_FLAGS 0x7005001 +/* enum: Count of times firmware has observed the bad IPv4 protocol field + * sticky bit set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_IPV4_PROTOCOL_SEEN 0x7005002 +/* enum: Count of times firmware has observed the bad IPv4 IHL field sticky bit + * set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_IPV4_IHL_SEEN 0x7005003 +/* enum: Count of times firmware has observed the bad sequence number sticky + * bit set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_SEQ_NUM_SEEN 0x7005004 +/* enum: Count of times firmware has observed the bad destination address + * sticky bit set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_DST_ADDR_SEEN 0x7005005 +/* enum: Count of times firmware has observed the zero length payload with no + * ACKs sticky bit set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_LEN_ZERO_NO_ACKS_SEEN 0x7005006 +/* enum: Count of times firmware has observed the request packet carrying ACKs + * sticky bit set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_REQ_HAS_ACKS_SEEN 0x7005007 +/* enum: Count of times firmware has observed the packet length above threshold + * sticky bit set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_LEN_ABOVE_THRESH_SEEN 0x7005008 +/* enum: Count of times firmware has observed the bad destination ID sticky bit + * set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_DEST_ID_SEEN 0x7005009 +/* enum: Count of times firmware has observed the bad stream ID sticky bit set + * at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_STRM_ID_SEEN 0x700500a +/* enum: Count of times firmware has observed the bad security status sticky + * bit set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_SEC_SOP_STATUS_SEEN 0x700500b +/* enum: Count of times firmware has observed the bad VLAN ID sticky bit set at + * SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_VID_SEEN 0x700500c +/* enum: Count of times firmware has observed the bad EtherType sticky bit set + * at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_ETH_TYPE_SEEN 0x700500d +/* enum: Count of times firmware has observed the disabled stream ID sticky bit + * set at SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_STRM_ID_DISABLED_SEEN 0x700500e +/* enum: Count of times firmware has observed the RX disabled sticky bit set at + * SOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_RX_DISABLED_SEEN 0x700500f +/* enum: *** RX EOP error flags and SEEN counters *** Raw EOP error flags + * register. Each bit corresponds to a sticky error condition detected at EOP. + * Bit definitions match STA_RX_DECAP_EOP_ERROR_FLAGS in the hardware register + * map. + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_EOP_ERROR_FLAGS 0x7006001 +/* enum: Count of times firmware has observed the bad CRC sticky bit set at EOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_EOP_BAD_CRC_SEEN 0x7006002 +/* enum: Count of times firmware has observed the bad EOP status sticky bit set + * at EOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_EOP_BAD_EOP_STATUS_SEEN 0x7006003 +/* enum: Count of times firmware has observed the EOP error flag sticky bit set + * at EOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_EOP_ERROR_FLAG_SEEN 0x7006004 +/* enum: Count of times firmware has observed the loss detection sticky bit set + * at EOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_LOSS_DETECTION_SEEN 0x7006005 +/* enum: Count of times firmware has observed the padding bytes error sticky + * bit set at EOP + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PADDING_BYTES_ERROR_SEEN 0x7006006 +/* enum: Count of packets dropped due to configuration errors */ +#define IFOE_TELEM_ID_IFOE_DEBUG_PKT_CFG_ERRORS 0x7007001 +/* enum: Count of IFoE header errors detected */ +#define IFOE_TELEM_ID_IFOE_DEBUG_IFOE_HDR_ERRORS 0x7007002 +/* enum: Count of SOP security errors detected */ +#define IFOE_TELEM_ID_IFOE_DEBUG_SOP_SEC_ERRORS 0x7007003 +/* enum: Count of EOP security errors detected */ +#define IFOE_TELEM_ID_IFOE_DEBUG_EOP_SEC_ERRORS 0x7007004 +/* enum: Count of destination address errors detected */ +#define IFOE_TELEM_ID_IFOE_DEBUG_DST_ADDR_ERRORS 0x7007005 +/* enum: Count of sequence number errors detected */ +#define IFOE_TELEM_ID_IFOE_DEBUG_SEQ_NUM_ERRORS 0x7007006 +/* enum: Count of loss detection events reported */ +#define IFOE_TELEM_ID_IFOE_DEBUG_LOSS_DETECTION_COUNT 0x7007007 +/* enum: Count of CRC errors detected */ +#define IFOE_TELEM_ID_IFOE_DEBUG_CRC_ERRORS 0x7007008 +/* enum: *** Bad packet capture telemetry IDs *** Snapshot of the most recent + * packet that latched one of the IFOE_DEBUG_SOP_ERROR_FLAGS / + * IFOE_DEBUG_EOP_ERROR_FLAGS sticky bits above. Config error flag captured + * from the most recent bad packet + */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_CONFIG_ERROR 0x7008001 +/* enum: Metadata fields captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_METADATA 0x7008002 +/* enum: Ethernet header word 0 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_ETH_HDR_0 0x7008003 +/* enum: Ethernet header word 1 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_ETH_HDR_1 0x7008004 +/* enum: Ethernet header word 2 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_ETH_HDR_2 0x7008005 +/* enum: Ethernet header word 3 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_ETH_HDR_3 0x7008006 +/* enum: VLAN fields captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_VLAN 0x7008007 +/* enum: IPv4 header word 0 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_IPV4_HDR_0 0x7008008 +/* enum: IPv4 header word 1 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_IPV4_HDR_1 0x7008009 +/* enum: IPv4 header word 2 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_IPV4_HDR_2 0x700800a +/* enum: IPv4 header word 3 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_IPV4_HDR_3 0x700800b +/* enum: IPv4 header word 4 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_IPV4_HDR_4 0x700800c +/* enum: IFoE header word 0 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_IFOE_HDR_0 0x700800d +/* enum: IFoE header word 1 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_IFOE_HDR_1 0x700800e +/* enum: IFoE header word 2 captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_IFOE_HDR_2 0x700800f +/* enum: ICV LSB captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_ICV_LSB 0x7008010 +/* enum: ICV MSB captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_ICV_MSB 0x7008011 +/* enum: CRC LSB captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_CRC_LSB 0x7008012 +/* enum: CRC MSB captured from the most recent bad packet */ +#define IFOE_TELEM_ID_IFOE_DEBUG_BAD_PKT_CRC_MSB 0x7008013 +/* enum: Sticky bit set when a TX configuration error is detected */ +#define IFOE_TELEM_ID_IFOE_DEBUG_TX_CONFIG_ERROR 0x7009001 +/* enum: Count of TX packet headers generated */ +#define IFOE_TELEM_ID_IFOE_DEBUG_TX_HDR 0x7009002 +/* enum: Count of TX packet CRCs generated */ +#define IFOE_TELEM_ID_IFOE_DEBUG_TX_CRC 0x7009003 +/* enum: TX differential amplitude control (txdiffctrl_sa) */ +#define IFOE_TELEM_ID_PHY_TXDIFFCTRL_SA 0x8000001 +/* enum: TX pre-emphasis pre-cursor tap 1 (txemppre_sa) */ +#define IFOE_TELEM_ID_PHY_TXEMPPRE_SA 0x8000002 +/* enum: TX main cursor amplitude (txempmain_sa) */ +#define IFOE_TELEM_ID_PHY_TXEMPMAIN_SA 0x8000003 +/* enum: TX post-cursor tap amplitude (txemppos_sa) */ +#define IFOE_TELEM_ID_PHY_TXEMPPOS_SA 0x8000004 +/* enum: TX pre-emphasis pre-cursor tap 2 (txemppre2_sa) */ +#define IFOE_TELEM_ID_PHY_TXEMPPRE2_SA 0x8000005 +/* enum: TX pre-emphasis pre-cursor tap 3 (txemppre3_sa) */ +#define IFOE_TELEM_ID_PHY_TXEMPPRE3_SA 0x8000006 +/* enum: RX FFE pre-tap 8 (hm08_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_PRE_TAP_08_DAC 0x8000007 +/* enum: RX FFE pre-tap 7 (hm07_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_PRE_TAP_07_DAC 0x8000008 +/* enum: RX FFE pre-tap 6 (hm06_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_PRE_TAP_06_DAC 0x8000009 +/* enum: RX FFE pre-tap 5 (hm05_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_PRE_TAP_05_DAC 0x800000a +/* enum: RX FFE pre-tap 4 (hm04_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_PRE_TAP_04_DAC 0x800000b +/* enum: RX FFE pre-tap 3 (hm03_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_PRE_TAP_03_DAC 0x800000c +/* enum: RX FFE pre-tap 2 (hm02_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_PRE_TAP_02_DAC 0x800000d +/* enum: RX FFE pre-tap 1 (hm01_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_PRE_TAP_01_DAC 0x800000e +/* enum: RX DFE H1 DAC value */ +#define IFOE_TELEM_ID_PHY_H1_DAC 0x800000f +/* enum: RX FFE post-tap 1 (hp01_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_01_DAC 0x8000010 +/* enum: RX FFE post-tap 2 (hp02_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_02_DAC 0x8000011 +/* enum: RX FFE post-tap 3 (hp03_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_03_DAC 0x8000012 +/* enum: RX FFE post-tap 4 (hp04_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_04_DAC 0x8000013 +/* enum: RX FFE post-tap 5 (hp05_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_05_DAC 0x8000014 +/* enum: RX FFE post-tap 6 (hp06_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_06_DAC 0x8000015 +/* enum: RX FFE post-tap 7 (hp07_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_07_DAC 0x8000016 +/* enum: RX FFE post-tap 8 (hp08_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_08_DAC 0x8000017 +/* enum: RX FFE post-tap 9 (hp09_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_09_DAC 0x8000018 +/* enum: RX FFE post-tap 10 (hp10_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_10_DAC 0x8000019 +/* enum: RX FFE post-tap 11 (hp11_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_11_DAC 0x800001a +/* enum: RX FFE post-tap 12 (hp12_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_12_DAC 0x800001b +/* enum: RX FFE post-tap 13 (hp13_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_13_DAC 0x800001c +/* enum: RX FFE post-tap 14 (hp14_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_14_DAC 0x800001d +/* enum: RX FFE post-tap 15 (hp15_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_POST_TAP_15_DAC 0x800001e +/* enum: RX FFE floating tap 1 (hf01_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_01_DAC 0x800001f +/* enum: RX FFE floating tap 2 (hf02_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_02_DAC 0x8000020 +/* enum: RX FFE floating tap 3 (hf03_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_03_DAC 0x8000021 +/* enum: RX FFE floating tap 4 (hf04_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_04_DAC 0x8000022 +/* enum: RX FFE floating tap 5 (hf05_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_05_DAC 0x8000023 +/* enum: RX FFE floating tap 6 (hf06_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_06_DAC 0x8000024 +/* enum: RX FFE floating tap 7 (hf07_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_07_DAC 0x8000025 +/* enum: RX FFE floating tap 8 (hf08_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_08_DAC 0x8000026 +/* enum: RX FFE floating tap 9 (hf09_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_09_DAC 0x8000027 +/* enum: RX FFE floating tap 10 (hf10_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_10_DAC 0x8000028 +/* enum: RX FFE floating tap 11 (hf11_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_11_DAC 0x8000029 +/* enum: RX FFE floating tap 12 (hf12_dac) */ +#define IFOE_TELEM_ID_PHY_FFE_FLOAT_TAP_12_DAC 0x800002a +/* enum: RX CTLE low-frequency peak (kl_dac) */ +#define IFOE_TELEM_ID_PHY_LO_PEAK 0x800002b +/* enum: RX CTLE high-frequency peak (kh_dac) */ +#define IFOE_TELEM_ID_PHY_HI_PEAK 0x800002c +/* enum: RX CTLE automatic gain control (agc_dac) */ +#define IFOE_TELEM_ID_PHY_GC_DAC 0x800002d #define IFOE_TELEM_ID_ID_LBN 0 #define IFOE_TELEM_ID_ID_WIDTH 64 diff --git a/projects/amdsmi/include/ualoe_lib/telemetry_dataset.h b/projects/amdsmi/include/ualoe_lib/telemetry_dataset.h new file mode 100644 index 000000000000..effad9fdbfab --- /dev/null +++ b/projects/amdsmi/include/ualoe_lib/telemetry_dataset.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include + +#include "ifoe_telemetry.h" + +/* C11 requires a message argument; C23 made it optional. Use #expr so the + * assertion text is preserved as the message on all compiler versions. */ +#define STATIC_ASSERT(expr) _Static_assert(expr, #expr) + +/* Number of telemetry categories currently supported */ +#define TELEMETRY_SRC_CATEGORY_COUNT (8) + +/* ID Count for each category */ +#define IFOE_TELEMETRY_ID_COUNT (167) +#define SWITCH_TELEMETRY_ID_COUNT (6) +#define CRYPTO_TELEMETRY_ID_COUNT (17) +#define PFC_TELEMETRY_ID_COUNT (90) +#define NETPORT_TELEMETRY_ID_COUNT (114) +#define IFOE_DERIVED_TELEMETRY_ID_COUNT (20) +#define NETPORT_DERIVED_TELEMETRY_ID_COUNT (25) + +/* Definition of the fundamental Tag-Length-Value format used to organize + * the telemetry + */ +typedef struct ifoe_telem_tlv_s { + uint64_t tag; + /* Size of the data following this field i.e. not including the Tag or Length */ + uint64_t len; +} ifoe_telem_tlv_t; + +STATIC_ASSERT(offsetof(ifoe_telem_tlv_t, tag) == IFOE_TELEM_TLV_INSTANCE_OFST); +STATIC_ASSERT(offsetof(ifoe_telem_tlv_t, len) == IFOE_TELEM_TLV_LEN_OFST); +STATIC_ASSERT(sizeof(ifoe_telem_tlv_t) == IFOE_TELEM_TLV_LENMIN); + +/* Definition of the top-level header TLV */ +typedef struct ifoe_telem_tlv_hdr_s { + ifoe_telem_tlv_t tlv; + /* Magic value, must be 0x1F0E5CA1AB1EDA7A */ + uint64_t magic; + /* Telemetry Version in format Major.Minor.Patch */ + uint64_t version; + /* The total size of the top-level telemetry TLVs (including tags/lengths) */ + uint64_t total_length; +} ifoe_telem_tlv_hdr_t; + +STATIC_ASSERT(offsetof(ifoe_telem_tlv_hdr_t, magic) == IFOE_TELEM_TLV_HDR_MAGIC_OFST); +STATIC_ASSERT(offsetof(ifoe_telem_tlv_hdr_t, version) == IFOE_TELEM_TLV_HDR_VERSION_OFST); +STATIC_ASSERT(offsetof(ifoe_telem_tlv_hdr_t, total_length) == IFOE_TELEM_TLV_HDR_TOTAL_LENGTH_OFST); +STATIC_ASSERT(sizeof(ifoe_telem_tlv_hdr_t) == IFOE_TELEM_TLV_HDR_LENMIN); + +/* Describes the telemetry data for a Telemetry Category */ +typedef struct ifoe_telem_tlv_desc_s { + ifoe_telem_tlv_t tlv; + /* List of Telemetry IDs in the order that they will appear in the + * corresponding Telemetry Data TLV + */ + uint64_t ids[]; +} ifoe_telem_tlv_desc_t; + +STATIC_ASSERT(offsetof(ifoe_telem_tlv_desc_t, ids) == IFOE_TELEM_TLV_DESC_IDS_OFST); +STATIC_ASSERT(sizeof(ifoe_telem_tlv_desc_t) == IFOE_TELEM_TLV_DESC_LENMIN); + +/* TLV containing the Telemetry Data for an instance of Telemetry Category */ +typedef struct ifoe_telem_tlv_data_s { + ifoe_telem_tlv_t tlv; + /* Telemetry data values in the order defined in the corresponding + * Telemetry Description. + */ + uint64_t values[]; +} ifoe_telem_tlv_data_t; + +STATIC_ASSERT(offsetof(ifoe_telem_tlv_data_t, values) == IFOE_TELEM_TLV_DATA_VALUES_OFST); +STATIC_ASSERT(sizeof(ifoe_telem_tlv_data_t) == IFOE_TELEM_TLV_DATA_LENMIN); + +/* TLV containing the location of each Telemetry Description */ +typedef struct ifoe_telem_tlv_desc_locator_s { + ifoe_telem_tlv_t tlv; + /* Array of offsets (from the start of the telemetry memory) to the + * Telemetry Description (ifoe_telem_tlv_desc_t) for each category + * The value 0 is defined as null and means there is no + * description for the category. Indexed by category number + * The telemetry memory may span multiple pages in GPU memory, the offset is + * calculated as if the telemetry memory were a single contiguous buffer + */ + uint64_t descs[TELEMETRY_SRC_CATEGORY_COUNT]; +} ifoe_telem_tlv_desc_locator_t; + +STATIC_ASSERT(offsetof(ifoe_telem_tlv_desc_locator_t, descs) == + IFOE_TELEM_TLV_DESC_LOCATOR_DESCS_OFST); +STATIC_ASSERT(sizeof(ifoe_telem_tlv_desc_locator_t) == + IFOE_TELEM_TLV_DESC_LOCATOR_LEN(TELEMETRY_SRC_CATEGORY_COUNT)); + +/* TLV containing the location of each Telemetry Dataset */ +typedef struct ifoe_telem_tlv_dataset_locator_s { + ifoe_telem_tlv_t tlv; + /* Array of offsets (from the start of the telemetry memory) to the + * Telemetry Dataset (ifoe_telem_tlv_dataset_hdr_t) for each category + * The value 0 is defined as null and means there is no data for the + * category. Indexed by category number + * The telemetry memory may span multiple pages in GPU memory, the offset is + * calculated as if the telemetry memory were a single contiguous buffer + */ + uint64_t datasets[TELEMETRY_SRC_CATEGORY_COUNT]; +} ifoe_telem_tlv_dataset_locator_t; + +STATIC_ASSERT(offsetof(ifoe_telem_tlv_dataset_locator_t, datasets) == + IFOE_TELEM_TLV_DATASET_LOCATOR_DATASETS_OFST); +STATIC_ASSERT(sizeof(ifoe_telem_tlv_dataset_locator_t) == + IFOE_TELEM_TLV_DATASET_LOCATOR_LEN(TELEMETRY_SRC_CATEGORY_COUNT)); + +/* Header TLV for a Telemetry Dataset */ +typedef struct ifoe_telem_tlv_dataset_hdr_s { + ifoe_telem_tlv_t tlv; + /* Sequence number incremented each time that the telemetry data is + * written. The header generation count is always written before the + * telemetry data + */ + uint64_t gen_count; + /* Timestamp of the point in time at which the telemetry was captured + * Note that this is an up-time for the IFoE firmware in milliseconds, not + * a time-of-day/UTC value + */ + uint64_t timestamp; +} ifoe_telem_tlv_dataset_hdr_t; + +STATIC_ASSERT(offsetof(ifoe_telem_tlv_dataset_hdr_t, gen_count) == + IFOE_TELEM_TLV_DATASET_HDR_GEN_COUNT_OFST); +STATIC_ASSERT(offsetof(ifoe_telem_tlv_dataset_hdr_t, timestamp) == + IFOE_TELEM_TLV_DATASET_HDR_TIMESTAMP_OFST); +STATIC_ASSERT(sizeof(ifoe_telem_tlv_dataset_hdr_t) == IFOE_TELEM_TLV_DATASET_HDR_LENMIN); + +/* Footer TLV for a Telemetry Dataset */ +typedef struct ifoe_telem_tlv_dataset_ftr_s { + ifoe_telem_tlv_t tlv; + /* Sequence number incremented each time that the telemetry data is + * written. The footer generation count is always written after the + * telemetry data + */ + uint64_t gen_count; +} ifoe_telem_tlv_dataset_ftr_t; + +STATIC_ASSERT(offsetof(ifoe_telem_tlv_dataset_ftr_t, gen_count) == + IFOE_TELEM_TLV_DATASET_FTR_GEN_COUNT_OFST); +STATIC_ASSERT(sizeof(ifoe_telem_tlv_dataset_ftr_t) == IFOE_TELEM_TLV_DATASET_FTR_LENMIN); diff --git a/projects/amdsmi/include/ualoe_lib/ualoe_cb.h b/projects/amdsmi/include/ualoe_lib/ualoe_cb.h index 359726ed52af..6ef139cc97ec 100644 --- a/projects/amdsmi/include/ualoe_lib/ualoe_cb.h +++ b/projects/amdsmi/include/ualoe_lib/ualoe_cb.h @@ -26,6 +26,7 @@ #include "ualoe_lib.h" void ualoe_cb_fini(ualoe_handle_t handle); -int ualoe_cb_init(ualoe_handle_t handle, int dev_id, ualoe_event_callback_t cb, void* user_ctx); +int ualoe_cb_init(ualoe_handle_t handle, int dev_id, ualoe_handle_t cdev_fd, + ualoe_event_callback_t cb, void* user_ctx); #endif /* UALOE_CB_H */ diff --git a/projects/amdsmi/include/ualoe_lib/ualoe_cdev.h b/projects/amdsmi/include/ualoe_lib/ualoe_cdev.h index dde0920f4c82..81b43dc452b0 100644 --- a/projects/amdsmi/include/ualoe_lib/ualoe_cdev.h +++ b/projects/amdsmi/include/ualoe_lib/ualoe_cdev.h @@ -77,6 +77,7 @@ int ualoe_cdev_telemetry_alloc(ualoe_handle_t handle, unsigned category_mask, ualoe_telemetry_t** telemetry); int ualoe_cdev_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry); int ualoe_cdev_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetry); +bool ualoe_cdev_is_telem_allocated(ualoe_handle_t handle); int ualoe_cdev_l2ping_start(ualoe_handle_t handle, ualoe_ping_spec_t* spec, ualoe_ping_t** ping); int ualoe_cdev_l2ping_update(ualoe_handle_t handle, ualoe_ping_t* ping); int ualoe_cdev_l2ping_fini(ualoe_handle_t handle, ualoe_ping_t* ping); diff --git a/projects/amdsmi/include/ualoe_lib/ualoe_lib.h b/projects/amdsmi/include/ualoe_lib/ualoe_lib.h index f6fde18b79a9..27449587a4c0 100644 --- a/projects/amdsmi/include/ualoe_lib/ualoe_lib.h +++ b/projects/amdsmi/include/ualoe_lib/ualoe_lib.h @@ -19,7 +19,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - #ifndef UALOE_LIB_H #define UALOE_LIB_H @@ -30,50 +29,44 @@ #include "ifoe_telemetry_hostapp.h" #include "ualoe_mcdi_defs.h" -/* UALoE library source compatibility version. This is incremented - * whenever a definition is added, removed or changed such that a - * client might need to guard its use with a compile-time check. - */ -#define UALOE_LIB_VERSION_MAJOR 0 -#define UALOE_LIB_VERSION_MINOR 1 -#define UALOE_LIB_VERSION_PATCH 0 - -/* ----------------- */ -/* Types and Defines */ -/* ----------------- */ - -/** Handle of an UALoE driver instance */ -typedef int ualoe_handle_t; - -/** Size of an IFoE textual label */ -#define UALOE_LABEL_SIZE (32) - -/** Maximum number of Network Ports per IFoE Station */ -#define UALOE_MAX_NETPORTS_PER_IFOE_STATION (4) - -/** Defines size of a crypto key */ -#define UALOE_CRYPTO_KEY_SIZE (8) - -/** Size of a MAC address */ -#define UALOE_MAC_ADDRESS_SIZE (6) - -/** Maximum number of pings supported per path for the L2Ping mechanism */ -#define UALOE_L2PING_MAX_PINGS (255) - -/** Enum defining different configuration phases for UALoE. Note that UALoE - * enforces a strict order of phases - * - * System -> Provider -> Tenant -> Showtime - * \ - * \-> Diagnostics - * - * The only transitions permitted are to the next phase via an explicit - * call to ualoe_next_config_phase() or by an entity reset which will - * reset back to the Provider or Tenant configuration phase, depending - * on whether a handle to the PF or VF is being used - * +/** + * Infinity Fabric over Ethernet (IFoE) provides Scale-Up network connectivity + * within AMD GPU clusters. AMD GPU chipsets contain multiple instances of the + * IFoE datapath and GPU remote memory transactions are hashed to spread traffic + * the different instances of IFoE to maximize bandwidth. Within each IFoE + * datapath,there is an IFoE Station which handles the encapsulation of + * Infinity Fabric into ethernet frames and also a series of Ethernet Network + * Ports. Traffic is spread between Network Ports within each IFoE Station + * using another hashing algorithm. + * + * @section IFoE Configuration Phases + * + * Configuration of the IFoE datapath takes place in phases where traffic flow + * is only enabled after the completion of the configuration. The following + * phases are defined: + * - System. Pre-OS configuration info from BIOS/APCP tokens + * - Provider. IFoE Datapath configuration carried out by the datacentre provider + * - Tenant. IFoE datapath configuration carried out by the datacentre tenant + * - Showtime. IFoE datapath active, GPU traffic flowing + * - Diagnostics. IFoE datapath not operational. Used to support diagnostics + * operations such as PRBS testing. + * + * Configuration phase transitions follow a restricted state transition + * diagram: + * + * /----------------------\ + * v | | | + * System -> Provider -> Tenant -> Showtime + * ^ ^ | | + * | \----------/ + * v + * Diagnostics + * + * Clients transition between phases via a call to ualoe_next_config_phase() + * or a call to ualoe_reset(), which will reset back to the Provider or Tenant + * configuration phase, depending on the role of the client. * Additionally a diagnostics mode is supported to allow offline diagnostics - * tests to be carried out e.g. Network Port PRBS. A PF FLR or entity reset + * tests to be carried out e.g. Network Port PRBS. A PF FLR or ualoe_reset() * will reset back to the Provider configuration phase. * * System @@ -100,7 +93,7 @@ typedef int ualoe_handle_t; * ------ * After the core Provider configuration is complete, the firmware enters this * state waiting to receive the Tenant configuration. Configuration that the - * Tenant should perform via the VF in virtualized mode of via the PF in Bare + * Tenant should perform via the VF in virtualized mode or via the PF in Bare * Metal mode... * ualoe_config_crypto() * ualoe_enable_accelerators() @@ -110,9 +103,166 @@ typedef int ualoe_handle_t; * Configuration is complete and the UALoE datapath is active. * * Diagnostics - * ----- + * ----------- * Offline diagnostics mode + * + * @section IFoE Client Roles + * + * IFoE can be deployed in different configurations depending on whether + * virtualization is being used and whether the customer is managing IFoE + * through the PCI interface or via the IFoE network itself. To support + * this API introduces the concept of Roles. The following Roles are + * defined: + * - Provider. Role of datacentre provider. A client with this Role is + * responsible for configuration of the IFoE datapath including the + * local accelerator ID, the set of accelerators active within the + * GPU cluster, the MAC address tables etc. + * - Tenant. Role of datacentre tenant. A client with this Role is + * responsible for configuration of datapath encryption, validation + * of the configuration put in place by the Provider and carrying + * out the final step of enabling the IFoE datapath for traffic + * flow. + * IFoE client (PCI PF and VF) typically have different roles depending on + * the way the GPU cluster is being managed. For example: + * - In a virtualized environment where cluster management is over PCI, + * the PF has the role of Provider and the VF has the role of Tenant. + * - In a bare-metal environment where cluster management is over PCI, + * the PF has the roles of Provider and Tenant. + * - Where cluster management is in-band over the IFoE network, no + * PCI client will have the Provider role and the Tenant role may be + * the PF or VF depending on the whether virtualization is in use. + * + * @section IFoE Station Administration + * + * IFoE Stations have the following administrative states defined: + * - Disabled. IFoE datapath in reset / low-power state + * - Stopped. IFoE datapath not in use for IFoE traffic + * - Active. Configured and usable for IFoE traffic + * + * The state of an IFoE Station can only be changed administratively during + * the Provider phase by clients who have the role of datacentre Provider. + * + * @section Network Port Administration + * + * Network ports have the following administrative states defined: + * - Enabled. Port is enabled and link may be up depending on the link + * partner and link settings + * - Link Disabled. Network Port in idle state, powered on but with the + * link administratively down + * - Power Off. Link is down and network port hardware is in lower power state + * + * Network port states can be changed in any configuration phase (with the + * exception of System) by clients who have the role of datacentre Provider. + * + * @section Default States + * + * After the pre-OS phase, where the set of configured IFoE stations and the + * network port mode is configured via APCB tokens and the configuration phase + * transitions to Provider, the default states are: + * - All configured IFoE Stations: Active + * - All configured Network Ports: Enabled + * + * @section IFoE Configuration Phase Transitions + * + * The following table shows how IFoE Config Phase transitions affect IFoE + * station and Netport state. In the table below, changes only apply to those + * instances that are configured during the boot / pre-OS phase. Stations and + * associated Network Ports not enabled for the platform will remain disabled + * and powered down at all times and are not visible to the user via the API below. + * + * ----------------------------------------------------------------------------------- + * | Config Phase | Config Phase | Station State | Netport State | Notes | + * | From | To | Effect | Effect | | + * |---------------------------------------------------------------------------------| + * | System | Provider | -> Active | -> Enabled | Only happens once | + * | | | | | on system boot | + * |---------------------------------------------------------------------------------| + * | Provider | Tenant | no change | no change | | + * |---------------------------------------------------------------------------------| + * | Tenant | Showtime | no change | no change | | + * |---------------------------------------------------------------------------------| + * | Provider, | Provider | -> Active | no change | Provider config | + * | Tenant, | | | | reset | + * | Showtime, | | | | | + * | Diagnostics | | | | | + * |---------------------------------------------------------------------------------| + * | Tenant, | Tenant | no change | no change | Tenant config | + * | Showtime | | | | reset | + * |---------------------------------------------------------------------------------| + * | Provider | Diagnostics | no change | no change | | + * ----------------------------------------------------------------------------------- + * + * @section PCI Function Level Reset (FLR) + * + * FLR operations are equivalent to IFOE Configuration Reset operations i.e. the + * behaviour depends on the Role of the PCI function. For example in a virtualized + * scenario where the PF has the role of Provider and the VF has the role of Tenant: + * - PF FLR is equivalent to a Provider Configuration Reset + * - VF FLR is equivalent to a Tenant Configuration Reset + * In the case where a client has both Provider and Tenant roles, a configuration + * reset or FLR will perform an Provider Configuration Reset. + * + * @section IFoE Station State Changes + * + * The state of individual IFoE stations can only be changed in the Provider + * configuration phase by a client with the Provider role. + * + * IFoE Station State change events are sent in the following scenarios + * - Network Port state change i.e. one of the network ports used by the IFoE + * station is administratively enabled/disabled or the link status changes + * - The IFoE administrative state changes i.e. the station is enabled or + * disabled + * - There is a fault with an IFoE datastream i.e. one of the streams failed + * over (or was paused if failover was not possible) + * - There is a fault causing the IFoE datapath to go into DX isolation + * (disconnection from SDP switch). + * + * @section Network Port State Changes + * + * The state of Network Ports can be changed in any configuration phase + * (except the System pre-OS phase). Only clients with Provider role are + * permitted to change the state. Note that disabling a Network Port during + * showtime while GPU traffic is flowing is dangerous and could result in a + * GPU remote memory access timing out. + * + * Network Port state change events are sent in the following scenarios: + * - Network Port administrative state change i.e. a network port is + * disabled or powered off or + * - The link status of a network port changes i.e. a network cable is + * unplugged or a link comes up. */ + +/** UALoE library source compatibility version. This is incremented + * whenever a definition is added, removed or changed such that a + * client might need to guard its use with a compile-time check. + */ +#define UALOE_LIB_VERSION_MAJOR 0 +#define UALOE_LIB_VERSION_MINOR 2 +#define UALOE_LIB_VERSION_PATCH 0 + +/* ----------------- */ +/* Types and Defines */ +/* ----------------- */ + +/** Handle of an UALoE driver instance */ +typedef int ualoe_handle_t; + +/** Size of an IFoE textual label */ +#define UALOE_LABEL_SIZE (32) + +/** Maximum number of Network Ports per IFoE Station */ +#define UALOE_MAX_NETPORTS_PER_IFOE_STATION (4) + +/** Defines size of a crypto key */ +#define UALOE_CRYPTO_KEY_SIZE (8) + +/** Size of a MAC address */ +#define UALOE_MAC_ADDRESS_SIZE (6) + +/** Maximum number of pings supported per path for the L2Ping mechanism */ +#define UALOE_L2PING_MAX_PINGS (255) + +/** Enum defining the different Configuration Phases for IFoE */ typedef enum ualoe_config_phase { UALOE_CONFIG_PHASE_SYSTEM, UALOE_CONFIG_PHASE_PROVIDER, @@ -188,8 +338,8 @@ typedef enum ualoe_crypto_key_id { /** Enum defining the state of an IFoE Station */ typedef enum ifoe_station_state { - /** In this state a station is disabled and Network Ports owned by the IFoE - * station will be powered off */ + /** In this state an IFoE station is disabled and the datapath hardware + * logic placed into reset */ IFOE_STATION_DISABLED, /** In this state, the IFoE station is in a state where the datapath is not * not active and traffic originating from both SDP and the network will be @@ -229,9 +379,16 @@ typedef struct ualoe_capabilities_s { unsigned num_configured_stations; /** Number of accelerators supported by the device */ unsigned max_accelerators; - /** Number of Network Ports configured for each IFoE Station */ + /** Number of Network Ports per configured IFoE station. Note that this gives + * the maximum number of network ports. Certain GPU cluster configurations + * have some IFoE stations with fewer functional network ports. + */ unsigned num_netports_per_station; - /** Number of IFoE Paths configured for each IFoE station */ + /** Number of IFoE paths per configured IFoE station. Note that this gives + * the maximum number of paths available. Where an IFoE station has a reduced + * number of functional network ports, the number of paths will also be + * reduced and will equal the number of ports. + */ unsigned num_paths_per_station; } ualoe_capabilities_t; @@ -301,7 +458,6 @@ typedef struct ifoe_station_desc_s { * each IFoE Station at the start of the Provider phase is as follows: * .state = IFOE_STATION_ACTIVE * .dx_isolated = FALSE - * .netports[].fault = FALSE * .netports[].streams_failover = 0 * .netports[].streams_paused = 0 * The value of other fields depends on the station instance and the state of @@ -327,7 +483,8 @@ typedef struct ifoe_station_state_s { unsigned logical_idx; /** Physical index of the IFoE Station within the device */ unsigned physical_idx; - /** Number of Network Port structures populated */ + /** Number of Network Ports configured for the IFoE station. Note that this + * will be greater than 0. */ unsigned netport_count; /** Array of Network Port information */ struct { @@ -379,7 +536,7 @@ typedef struct ifoe_netport_desc_s { * The set of Network Ports is configured in the BIOS based on the port mode * and the number of configured IFoE stations and will be set before IFoE * transitions to the Provider configuration phase. The initial state of each - * Network Port at the start of the Provider phase is as follows: + * Network Port after boot is as follows: * .state = IFOE_NETPORT_ENABLED * .autoneg_enabled = TRUE * .parallel_detect_enabled = TRUE @@ -410,6 +567,121 @@ typedef struct ifoe_netport_state_s { uint8_t permanent_mac_addr[UALOE_MAC_ADDRESS_SIZE]; } ifoe_netport_state_t; +/** Structure containing the IFCP per-netport state. + * + * The peer_* fields below (peer_device_id, peer_port_id, peer_enabled, + * peer_in_error, peer_encrypt_mode, peer_mac_addr, peer_mtu) are only + * valid when the local link is up (i.e. local_link_up == true). When + * local_link_up is false the peer fields are not populated by firmware + * and should be considered invalid. + */ +typedef struct ifoe_ifcp_netport_state_s { + /** Local IFCP port id (logical netport index used in IFCP Discovery) */ + uint32_t local_port_id; + /** Local physical link is up. This value is derived from the Network Port + * state (see ifoe_netport_state_t) — the IFCP layer reports the link as up + * only when the underlying netport reports the link as up. */ + bool local_link_up; + /** Local IFCP port reports an error */ + bool local_in_error; + /** Local IFCP link-level (LL) protocol is up. Only meaningful when + * local_link_up is true: the LL protocol cannot come up while the + * underlying physical link is down. */ + bool local_ll_up; + /** Source MAC used in IFCP packets transmitted on this port. This is the + * same MAC address as ifoe_netport_state_t::ifoe_mac_addr — the IFCP layer + * uses the IFoE source MAC configured via ifoe_netport_set_addr() as the + * source address for IFCP discovery and link-level traffic. */ + uint8_t local_mac_addr[UALOE_MAC_ADDRESS_SIZE]; + /** Peer device identity received in IFCP Discovery. + * Only valid when local_link_up is true. */ + uint64_t peer_device_id; + /** Peer port id received in IFCP Discovery. + * Only valid when local_link_up is true. */ + uint32_t peer_port_id; + /** Peer reports port enabled in IFCP Discovery. + * Only valid when local_link_up is true. */ + bool peer_enabled; + /** Peer reports an error in IFCP Discovery. + * Only valid when local_link_up is true. */ + bool peer_in_error; + /** Peer encryption mode reported in IFCP Discovery. + * Only valid when local_link_up is true. */ + ualoe_crypto_mode_e peer_encrypt_mode; + /** Peer port MAC address received in IFCP Discovery. This is the MAC + * address of the switch port that is directly connected to this netport. + * Only valid when local_link_up is true. */ + uint8_t peer_mac_addr[UALOE_MAC_ADDRESS_SIZE]; + /** Peer port maximum MTU received in IFCP Discovery. + * Only valid when local_link_up is true. */ + uint32_t peer_mtu; +} ifoe_ifcp_netport_state_t; + +/** Structure containing IFCP per-netport packet statistics. */ +typedef struct ifoe_ifcp_netport_stats_s { + /** Number of IFCP packets received on this port */ + uint64_t rx_count; + /** Number of IFCP packets transmitted on this port */ + uint64_t tx_count; + /** Number of IFCP packet transmit errors */ + uint64_t tx_errors; + /** Number of received IFCP packets dropped */ + uint64_t rx_dropped; +} ifoe_ifcp_netport_stats_t; + +/** Size in bytes of the scale-up fabric physical pod identity. */ +#define UALOE_SCALEUP_FABRIC_POD_ID_SIZE 16 +/** Maximum number of local accelerators in ualoe_scaleup_fabric_config_t. + * Matches the MCDI2 protocol maximum (MAXNUM_MCDI2) the driver emits. + */ +#define UALOE_SCALEUP_FABRIC_MAX_LOCAL_ACCELERATORS 250 + +/** Structure containing GPU scale-up fabric pod parameters. */ +typedef struct ualoe_scaleup_fabric_config_s { + /** Identity of the scale-up fabric pod to which this device belongs */ + uint8_t physical_pod_id[UALOE_SCALEUP_FABRIC_POD_ID_SIZE]; + /** Maximum number of accelerators in the scale-up fabric pod */ + uint32_t physical_pod_size; + /** Number of valid entries in local_accelerators */ + uint32_t num_local_accelerators; + /** Accelerator IDs that are local to the host on which this device resides */ + uint32_t local_accelerators[UALOE_SCALEUP_FABRIC_MAX_LOCAL_ACCELERATORS]; +} ualoe_scaleup_fabric_config_t; + +/** Structure containing GPU scale-up fabric virtual pod parameters. */ +typedef struct ualoe_scaleup_fabric_vpod_config_s { + /** Identity of the virtual pod to which this device belongs */ + uint32_t virtual_pod_id; + /** GPU Network physical addressing mode */ + uint32_t npa_address_mode; +} ualoe_scaleup_fabric_vpod_config_t; + +/** Maximum number of stations in ualoe_scaleup_fabric_station_info_t. + * Matches the MCDI2 protocol maximum (MAXNUM_MCDI2) the driver emits. + */ +#define UALOE_SCALEUP_FABRIC_MAX_STATIONS 1016 + +/** Structure containing GPU scale-up fabric station info. */ +typedef struct ualoe_scaleup_fabric_station_info_s { + /** Number of valid entries in station_bandwidth */ + uint32_t num_stations; + /** Scale-up fabric bandwidth of each station in Gbit/s, indexed by station + * logical index (0 .. num_stations-1). */ + uint8_t station_bandwidth[UALOE_SCALEUP_FABRIC_MAX_STATIONS]; +} ualoe_scaleup_fabric_station_info_t; + +/** Structure containing GPU identity parameters. */ +typedef struct ualoe_gpu_identity_s { + /** Physical ID of the GPU */ + uint32_t phys_id; + /** Number of GPUs in the compute tray */ + uint32_t num_gpus; + /** Compute tray type */ + ualoe_compute_tray_type_e tray_type; + /** Per-tray logical ID of the GPU */ + uint32_t oam_id; +} ualoe_gpu_identity_t; + /** Enum defining the type of used network address */ typedef enum ifoe_network_addr_type { IFOE_NETWORK_ADDR_TYPE_MAC, @@ -423,7 +695,7 @@ typedef struct ifoe_accelerator_addr_map_s { unsigned accelerator_id; /** MAC address */ uint8_t mac_addr[UALOE_MAC_ADDRESS_SIZE]; - /** IP address (in Network byte order) */ + /** IP address (in host byte order) */ uint32_t ip_addr; } ifoe_accelerator_addr_map_t; @@ -436,6 +708,8 @@ typedef enum ualoe_telemetry_category { UALOE_TELEMETRY_CATEGORY_NETPORT, UALOE_TELEMETRY_CATEGORY_DERIVED_IFOE, UALOE_TELEMETRY_CATEGORY_DERIVED_NETPORT, + UALOE_TELEMETRY_CATEGORY_IFOE_DEBUG, + UALOE_TELEMETRY_CATEGORY_PHY, UALOE_TELEMETRY_CATEGORY_MAX } ualoe_telemetry_category_e; @@ -519,6 +793,40 @@ typedef struct ualoe_telemetry_s { ualoe_telemetry_dataset_t* datasets[UALOE_TELEMETRY_CATEGORY_MAX]; } ualoe_telemetry_t; +/** CPER severity levels */ +typedef enum ualoe_cper_severity { + /** Non-fatal uncorrected error */ + UALOE_CPER_SEV_NON_FATAL_UNCORRECTED = 0, + /** Fatal error */ + UALOE_CPER_SEV_FATAL = 1, + /** Non-fatal corrected error */ + UALOE_CPER_SEV_NON_FATAL_CORRECTED = 2, + /** Number of valid severity levels */ + UALOE_CPER_SEV_NUM = 3, +} ualoe_cper_severity_e; + +/** Construct a severity bitmask for ualoe_get_ifoe_cper_entries() */ +#define UALOE_CPER_SEV_MASK(sev) (1U << (sev)) + +/** CPER (Common Platform Error Record) entry header for IFoE. Each CPER record + * in the cper_data buffer returned by ualoe_get_ifoe_cper_entries() begins with + * this header. The record_length field gives the total size of the record + * including this header, which allows the buffer to be walked entry by entry. + * + * Alignment: Each record in cper_data is aligned to alignof(ualoe_cper_hdr_t). + * The driver pads record_length to a multiple of this alignment so that + * successive headers are always correctly aligned when the caller provides a + * suitably aligned cper_data buffer (e.g. allocated via malloc). + */ +typedef struct ualoe_cper_hdr_s { + /** UTC timestamp at which the error was recorded */ + struct timespec timestamp; + /** Severity level of this CPER entry (one of ualoe_cper_severity_e) */ + ualoe_cper_severity_e severity; + /** Total length of this CPER record in bytes, including this header */ + uint32_t record_length; +} ualoe_cper_hdr_t; + /** Type for an L2Ping handle. */ typedef unsigned ualoe_ping_handle_t; @@ -545,6 +853,10 @@ typedef struct ualoe_ping_spec_s { unsigned num_pings; } ualoe_ping_spec_t; +/** Set in ualoe_ping_netport_result_t.flags when the netport result does not + * reflect a real test and must be ignored (e.g. netport not bonded). */ +#define UALOE_PING_NETPORT_INVALID_RESULT (1U << 0) + /** Structure holding a single ping result for a specific accelerator and * netport. */ typedef struct ualoe_ping_netport_results_s { @@ -554,9 +866,11 @@ typedef struct ualoe_ping_netport_results_s { /** Count of ping failures on the IFoE Response PFC channel. A value of 0 * indicates all pings completed successfully. */ uint8_t resp_failures; - /** Count of non-IFOE failures on the non-IFoE traffic PFC channel. A value + /** Count of non-IFoE failures on the non-IFoE traffic PFC channel. A value * of 0 indicates all pings completed successfully. */ uint8_t non_ifoe_failures; + /** Result flags (see UALOE_PING_NETPORT_*). */ + uint8_t flags; } ualoe_ping_netport_result_t; /** Structure holding a set of ping results for a specific accelerator. This @@ -603,6 +917,9 @@ typedef enum { UALOE_EVENT_CONFIG_PHASE_CHANGE, /** Notification that the current L2 ping test is complete */ UALOE_EVENT_L2PING_COMPLETE, + /** Notification that a new telemetry snapshot is ready. TELEMETRY_READY + * events are only expected when telemetry is allocated. */ + UALOE_EVENT_TELEMETRY_READY, } ualoe_event_id_e; /** Structure defining an UALoE event. This is passed to the caller @@ -666,6 +983,12 @@ typedef struct ualoe_event_s { /** Handle associated with the ping test */ ualoe_ping_handle_t handle; } l2ping_complete; + + /** Data associated with the event UALOE_EVENT_TELEMETRY_READY */ + struct { + /** Telemetry generation count */ + uint64_t generation_count; + } telemetry_ready; } u; } ualoe_event_t; @@ -824,6 +1147,10 @@ int ualoe_get_ifoe_config(ualoe_handle_t handle, ifoe_config_t* config, unsigned * this does not match the strict ordering enforced by the firmware, the * request will fail with ERANGE. See the UALoE configuration phases definition * above for notes on the transition order. + * This function can be used to return from the current to an earlier + * configuration phase. Performing such a transition is equivalent to performing + * a configuration reset ualoe_reset() i.e. transitioning backwards will result + * in the configuration being reset. * * @param handle UALoE driver handle * @param next_phase Configuration phase to transition to @@ -973,20 +1300,22 @@ int ifoe_station_get_state(ualoe_handle_t handle, unsigned station_idx, * @brief Set the Path to Port mapping for the IFoE datapath. This can be done * globally, per IFoE Station and per Accelerator ID, depending on the selected * flags. - * This command is permitted in the Provider, Tenant and Showtime phases. + * This operation is only permitted for clients with the Provider role and is + * only permitted in the Showtime phase. * * @param handle UALoE driver handle * @param specify_station Boolean indicating if the mapping should be set for a - * specific IFoE Station + * specific IFoE Station. Note that support to set the path to port map for all + * stations is not supportable so this field must always be set to true. * @param specify_accelerator Boolean indicating if the mapping should be set * for a specific Accelerator. * @param reenable_streams Boolean indicating that any disabled streams * affected by this mapping request should be re-enabled. * @param station_idx Logical index of IFoE station * @param accelerator_id Accelerator ID - * @param path_count Number of entries in paths array provided by the - * caller. This must match the number IFoE Paths as returned by - * ualoe_get_capabilities(). + * @param path_count Number of entries in map array provided by the + * caller. This must be equal to the number of network ports connected to the + * specified IFoE station as reported by ifoe_station_get_state(). * @param map Array of Network Port logical indices, indexed by the IFoE Path. * @return 0 on success. errno on failure */ @@ -997,14 +1326,15 @@ int ifoe_set_path_to_port_map(ualoe_handle_t handle, bool specify_station, bool /** * @brief Get the Path to Port mapping for a specified IFoE Station and * Accelerator. - * This command is permitted in the Provider, Tenant and Showtime phases. + * This operation is permitted for all clients, but only in the Showtime + * phase. * * @param handle UALoE driver handle * @param station_idx Logical index of IFoE station * @param accelerator_id Accelerator ID - * @param path_count Number of entries in paths array provided by the - * caller. This must match the number IFoE Paths as returned by - * ualoe_get_capabilities(). + * @param path_count Number of entries in map array provided by the + * caller. This must be equal to the number of network ports connected to the + * specified IFoE station as reported by ifoe_station_get_state(). * @param map Array of Network Port logical indices, indexed by IFoE Path. * @return 0 on success. errno on failure */ @@ -1025,27 +1355,53 @@ int ifoe_get_netport_properties(ualoe_handle_t handle, ualoe_netport_properties_ /** * @brief Get a set of descriptors for the Network Ports associated with the - * IFoE device. Each descriptor contain information about the location network - * port i.e. the IFoE station that it belongs to and it's station-relative - * index. + * IFoE device. Each descriptor contain information about a network port i.e. + * the IFoE station that it belongs to and its station-relative index. * This command is permitted in the Provider, Tenant, Showtime and Diagnostics * phases. * * @param handle UALoE driver handle * @param desc_count Number of entries in descriptor array provided by the - * caller. This should match the number of configured network ports- refer to - * ualoe_get_capabilities(). + * caller. This should match the number of configured network ports otherwise + * the call will fail. For most platforms this is the number of stations + * multiplied by the max ports per station (see ualoe_get_capabilities()). + * However, this is not true for all platforms and therefore a version 2 of + * the API is defined below which is more user friendly. * @param descs Array of descriptors. This memory should be allocated by the * caller and will be populated by this function. * @return 0 on success. errno on failure */ int ifoe_get_netport_list(ualoe_handle_t handle, unsigned desc_count, ifoe_netport_desc_t descs[]); +/** + * @brief Get a set of descriptors for the Network Ports associated with the + * IFoE device. Each descriptor contains information about a network port i.e. + * the IFoE station that it belongs to and its station-relative index. This + * is version 2 of the function which is modified to support a product variant + * where the number of network ports is reduced for some IFoE stations. + * This command is permitted in the Provider, Tenant, Showtime and Diagnostics + * phases. + * + * @param handle UALoE driver handle + * @param desc_count Pointer to variable specifying the number of entries in + * the descriptor array descs[]. This should be large enough to hold the + * maximum number of the Network Ports (refer to ualoe_get_capabilities()) + * otherwise the function will fail with ENOSPC. As a result of the call + * desc_count will be updated with total number of configured network ports. + * This also provides the number of descriptors populated. + * @param descs Array of descriptors. This memory should be allocated by the + * caller and will be populated by this function. + * @return 0 on success. errno on failure + */ +int ifoe_get_netport_list_v2(ualoe_handle_t handle, unsigned* desc_count, + ifoe_netport_desc_t descs[]); + /** * @brief Function to control a Network Port. This can be used to disable a * Network Port and remove it as a part of the logical link of the associated * IFoE Station. - * This command is only permitted in the Provider configuration phase. + * This command is permitted in the Provider, Tenant, Showtime and Diagnostics + * phases. This operation is only permitted for clients with the Provider role. * * @param handle UALoE driver handle * @param netport_idx Logical index of the Network Port @@ -1061,8 +1417,8 @@ int ifoe_netport_ctrl(ualoe_handle_t handle, unsigned netport_idx, ifoe_netport_ * negotiated depending on the link parter's capabilities. With AN enabled, * parallel detect can used in which case the local link will attempt to * determine the link configuration being used by the partner. - * This command is only permitted in the Provider and Diagnostics configuration - * phases. + * This command is permitted in the Provider, Tenant, Showtime and Diagnostics + * phases. This operation is only permitted for clients with the Provider role. * * @param handle UALoE driver handle * @param netport_idx Logical index of the Network Port @@ -1079,8 +1435,8 @@ int ifoe_netport_config_link_auto(ualoe_handle_t handle, unsigned netport_idx, * @brief Function to configure a Network Port link with Auto-Negotiation * disabled and a fixed link configuration. The caller should specify the * ethernet technology, FEC mode and the loopback mode (can be none). - * This command is only permitted in the Provider and Diagnostics configuration - * phases. + * This command is permitted in the Provider, Tenant, Showtime and Diagnostics + * phases. This operation is only permitted for clients with the Provider role. * * @param handle UALoE driver handle * @param netport_idx Logical index of the Network Port @@ -1106,7 +1462,7 @@ int ifoe_netport_config_link_manual(ualoe_handle_t handle, unsigned netport_idx, * @param netport_idx Logical index of the Network Port * @param addr_type The type of network address to use for IFoE traffic * @param mac_addr The MAC address to use for IFoE traffic - * @param ip_addr The IP address to use for IFoE traffic in Network byte order + * @param ip_addr The IP address to use for IFoE traffic (in host byte order) * @return 0 on success. errno on failure * * @note addr_type must match the configured encapsulation mode: @@ -1142,6 +1498,20 @@ int ifoe_netport_set_accelerator_addr_map(ualoe_handle_t handle, unsigned netpor ifoe_network_addr_type_e map_addr_type, unsigned map_count, ifoe_accelerator_addr_map_t map[]); +/** + * @brief Function to get the Accelerator to destination address mapping for a + * Network Port. + * This command is permitted in the Provider, Tenant and Showtime configuration + * phases. + * + * @param handle UALoE driver handle + * @param netport_idx Logical index of the Network Port + * @param map_count Number of mapping entries provided + * @param map Array of accelerator to address mappings to be populated + */ +int ifoe_netport_get_accelerator_addr_map(ualoe_handle_t handle, unsigned netport_idx, + unsigned map_count, ifoe_accelerator_addr_map_t map[]); + /** * @brief Function to get IFoE-specific state of a Network Port. * This command is permitted in the Provider, Tenant, Showtime and Diagnostics @@ -1155,6 +1525,120 @@ int ifoe_netport_set_accelerator_addr_map(ualoe_handle_t handle, unsigned netpor int ifoe_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, ifoe_netport_state_t* state); +/** + * @brief Function to get the IFCP per-netport state for the specified network + * port, returning the local and peer IFCP state. + * This command is permitted in the Provider, Tenant, Showtime and + * Diagnostics phases, and is accessible to both the PF (Provider) and the + * VF (Tenant). + * + * @param handle UALoE driver handle + * @param netport_idx Logical index of the Network Port + * @param state Pointer to structure to store the IFCP per-port state + * @return 0 on success. errno on failure + */ +int ifoe_ifcp_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, + ifoe_ifcp_netport_state_t* state); + +/** + * @brief Function to get the IFCP per-netport packet statistics for the + * specified network port, returning the IFCP packet RX/TX counters and + * error/drop counters. + * This command is permitted in the Provider, Tenant, Showtime and + * Diagnostics phases, and is accessible to both the PF (Provider) and the + * VF (Tenant). + * + * @param handle UALoE driver handle + * @param netport_idx Logical index of the Network Port + * @param stats Pointer to structure to store the IFCP per-port statistics + * @return 0 on success. errno on failure + */ +int ifoe_ifcp_netport_get_stats(ualoe_handle_t handle, unsigned netport_idx, + ifoe_ifcp_netport_stats_t* stats); + +/** + * @brief Get the GPU scale-up fabric parameters for this device. + * + * @param handle UALoE driver handle + * @param config Pointer to structure to store the scale-up fabric config + * @return 0 on success. errno on failure + */ +int ualoe_get_scaleup_fabric_config(ualoe_handle_t handle, ualoe_scaleup_fabric_config_t* config); + +/** + * @brief Get the GPU scale-up fabric virtual pod parameters for this device. + * + * @param handle UALoE driver handle + * @param config Pointer to structure to store the scale-up fabric vpod config + * @return 0 on success. errno on failure + */ +int ualoe_get_scaleup_fabric_vpod_config(ualoe_handle_t handle, + ualoe_scaleup_fabric_vpod_config_t* config); + +/** + * @brief Get the GPU scale-up fabric station info for this device. + * + * @param handle UALoE driver handle + * @param info Pointer to structure to store the scale-up fabric station info + * @return 0 on success. errno on failure + */ +int ualoe_get_scaleup_fabric_station_info(ualoe_handle_t handle, + ualoe_scaleup_fabric_station_info_t* info); + +/** + * @brief Set the GPU scale-up fabric parameters for this device. + * + * Programs the physical pod identity, the pod size and the list of + * accelerators local to this host. + * + * @param handle UALoE driver handle + * @param config Pointer to the scale-up fabric config to program + * @return 0 on success. errno on failure + */ +int ualoe_set_scaleup_fabric_config(ualoe_handle_t handle, + const ualoe_scaleup_fabric_config_t* config); + +/** + * @brief Set the GPU scale-up fabric virtual pod parameters for this device. + * + * Programs the virtual pod identity and the GPU network physical + * addressing mode. + * + * @param handle UALoE driver handle + * @param config Pointer to the scale-up fabric vpod config to program + * @return 0 on success. errno on failure + */ +int ualoe_set_scaleup_fabric_vpod_config(ualoe_handle_t handle, + const ualoe_scaleup_fabric_vpod_config_t* config); + +/** + * @brief Set the GPU scale-up fabric station info for this device. + * + * Programs the station count and the per-station scale-up bandwidth, + * indexed by station logical index. + * + * @param handle UALoE driver handle + * @param info Pointer to the scale-up fabric station info to program + * @return 0 on success. errno on failure + */ +int ualoe_set_scaleup_fabric_station_info(ualoe_handle_t handle, + const ualoe_scaleup_fabric_station_info_t* info); + +/** + * @brief Get the GPU identity for this device. + * + * Returns the physical ID, number of GPUs, tray type and OAM ID + * of the GPU to which this device is attached. + * This command is permitted in the Provider, Tenant, Showtime and + * Diagnostics phases, and is accessible to both the PF (Provider) and the + * VF (Tenant). + * + * @param handle UALoE driver handle + * @param identity Pointer to structure to store the GPU identity + * @return 0 on success. errno on failure + */ +int ualoe_get_gpu_identity(ualoe_handle_t handle, ualoe_gpu_identity_t* identity); + /** * @brief Allocate storage for Telemetry. This is called specify a set of * telemetry categories for which telemetry should be retrieved and the call @@ -1199,6 +1683,17 @@ int ualoe_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry); */ int ualoe_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetry); +/** + * @brief Query the telemetry categories available + * This command is permitted in Provider, Tenant, Showtime and Diagnostics + * phases. + * + * @param handle UALoE driver handle + * @param category_mask Pointer to receive the supported category bitmask + * @return 0 on success. errno on failure + */ +int ualoe_telemetry_get_category_mask(ualoe_handle_t handle, unsigned* category_mask); + /** * @brief Configure an L2 Ping test, allocate the context for the test and * memory required to hold the results before starting the test. The test will @@ -1206,9 +1701,9 @@ int ualoe_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetry); * the notification UALOE_EVENT_L2PING_COMPLETE will be sent. * ualoe_l2ping_update() can be called during the ping test to get an update * on progress and to retrieve the full results at the end of the test. - * ualoe_l2ping_free() must be called at the end of the test to free the + * ualoe_l2ping_fini() must be called at the end of the test to free the * allocated resources. - * This command is only permitted in Showtime and Diagnostics phases. + * This command is only permitted in the Showtime phase. * * @param handle UALoE driver handle * @param spec Specification for the ping test @@ -1221,7 +1716,7 @@ int ualoe_l2ping_start(ualoe_handle_t handle, ualoe_ping_spec_t* spec, ualoe_pin * @brief Update the ping context with the status and progress. If the ping * test is complete the context will be marked as such and the full results * populated. - * This command is only permitted in Showtime and Diagnostics phases. + * This command is only permitted in the Showtime phase. * * @param handle UALoE driver handle * @param ping Pointer to the context for the ping currently in progress @@ -1232,7 +1727,7 @@ int ualoe_l2ping_update(ualoe_handle_t handle, ualoe_ping_t* ping); /** * @brief Stop the current ping test if not already finished and free the * resources allocated for the test. - * This command is allowed in all phases. + * This command is only permitted in the Showtime phase. * * @param handle UALoE driver handle * @param ping Pointer to the ping context to be freed @@ -1369,4 +1864,47 @@ int ualoe_diag_config_prbs_rx(ualoe_handle_t handle, unsigned netport_idx, unsig int ualoe_diag_get_prbs_results(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, ualoe_prbs_results_t* results); +/** + * @brief Retrieve CPER entries cached in the IFoE driver. + * + * The user passes pre-allocated buffers to hold the raw CPER data and an array + * of pointers to hold parsed CPER headers. The library fills cper_data with + * raw records matching severity_mask and fills cper_hdrs with pointers into + * cper_data, one per record. A cursor is returned for paginated retrieval. + * + * If all available entries fit in the supplied buffers the function returns 0 + * and cursor is set to 0. If more entries remain (buf_size or entry_count was + * the limiting factor), the function returns ENOBUFS and cursor is set to a + * non-zero value; the caller should call the function again with that cursor + * to retrieve subsequent entries. If the buffers are too small to hold even a + * single entry, the function returns ENOSPC. + * + * A call using a non-zero cursor may return entry_count == 0 if the driver + * cache contains no further entries matching severity_mask; in that case 0 is + * returned so the caller knows iteration is complete. + * + * @param handle UALoE driver handle + * @param severity_mask Bitmask of CPER severity levels to retrieve + * @param cper_data Caller-allocated buffer to receive raw CPER records. Must be + * aligned to at least alignof(ualoe_cper_hdr_t) (satisfied by + * malloc). Records are padded so that each header is naturally + * aligned within the buffer + * @param buf_size On input, size of cper_data in bytes; on return, number of + * bytes written to cper_data + * @param cper_hdrs Array of pointers to ualoe_cper_hdr_t. The caller must + * allocate the array of pointers. The library fills the array + * with pointers to the parsed headers within cper_data. Each + * pointer is guaranteed to be correctly aligned + * @param entry_count On input, length of the cper_hdrs array; on return, number + * of entries written + * @param cursor On input, cursor from the previous call (0 for the first call); + * on return, cursor for the next call (0 means no more data) + * @return 0 on success. ENOBUFS if more entries are available (call again with + * the returned cursor). ENOSPC if the buffers are too small for one + * entry. errno on other failure + */ +int ualoe_get_ifoe_cper_entries(ualoe_handle_t handle, uint32_t severity_mask, char* cper_data, + uint64_t* buf_size, ualoe_cper_hdr_t** cper_hdrs, + uint64_t* entry_count, uint64_t* cursor); + #endif // UALOE_LIB_H diff --git a/projects/amdsmi/include/ualoe_lib/ualoe_mcdi_defs.h b/projects/amdsmi/include/ualoe_lib/ualoe_mcdi_defs.h index f72adb7e575b..9735cf04ee68 100644 --- a/projects/amdsmi/include/ualoe_lib/ualoe_mcdi_defs.h +++ b/projects/amdsmi/include/ualoe_lib/ualoe_mcdi_defs.h @@ -19,7 +19,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - #ifndef UALOE_MCDI_DEFS_H #define UALOE_MCDI_DEFS_H @@ -139,7 +138,8 @@ typedef enum ualoe_eth_tech { UALOE_ETH_TECH_200GBASE_DR1 = MC_CMD_ETH_TECH_200GBASE_DR1, UALOE_ETH_TECH_400GBASE_KR2 = MC_CMD_ETH_TECH_400GBASE_KR2, UALOE_ETH_TECH_400GBASE_CR2 = MC_CMD_ETH_TECH_400GBASE_CR2, - UALOE_ETH_TECH_400GBASE_DR2 = MC_CMD_ETH_TECH_400GBASE_DR2 + UALOE_ETH_TECH_400GBASE_DR2 = MC_CMD_ETH_TECH_400GBASE_DR2, + UALOE_ETH_TECH_NONE = MC_CMD_ETH_TECH_NONE } ualoe_eth_tech_e; /** Macro to generate a mask from ualoe_eth_tech_e enums */ @@ -224,6 +224,12 @@ typedef enum ualoe_netport_loopback_mode { UALOE_NETPORT_LOOPBACK_POST_PRE_MAC = MC_CMD_LOOPBACK_V2_PRE_MAC } ualoe_netport_loopback_mode_e; +typedef enum ualoe_compute_tray_type { + UALOE_COMPUTE_TRAY_TYPE_HELIOS_P = IFOE_COMPUTE_TRAY_TYPE_HELIOS_P, + UALOE_COMPUTE_TRAY_TYPE_HELIOS_R = IFOE_COMPUTE_TRAY_TYPE_HELIOS_R, + UALOE_COMPUTE_TRAY_TYPE_TITAN = IFOE_COMPUTE_TRAY_TYPE_TITAN +} ualoe_compute_tray_type_e; + /** Macro to generate a mask from ualoe_netport_loopback_mode_e enums */ #define UALOE_NETPORT_LOOPBACK_MASK(mode) (1 << (UALOE_NETPORT_LOOPBACK_##mode)) diff --git a/projects/amdsmi/include/ualoe_lib/ualoe_nl.h b/projects/amdsmi/include/ualoe_lib/ualoe_nl.h index 92acad4dfef4..b689444bffb6 100644 --- a/projects/amdsmi/include/ualoe_lib/ualoe_nl.h +++ b/projects/amdsmi/include/ualoe_lib/ualoe_nl.h @@ -65,10 +65,14 @@ int ifoe_nl_get_path_to_port_map(ualoe_handle_t handle, unsigned station_idx, unsigned accelerator_id, unsigned path_count, unsigned map[]); int ifoe_nl_get_netport_list(ualoe_handle_t handle, unsigned desc_count, ifoe_netport_desc_t descs[]); +int ifoe_nl_get_netport_list_v2(ualoe_handle_t handle, unsigned* desc_count, + ifoe_netport_desc_t descs[]); int ifoe_nl_netport_ctrl(ualoe_handle_t handle, unsigned netport_idx, ifoe_netport_state_e state); int ifoe_nl_netport_set_accelerator_addr_map(ualoe_handle_t handle, unsigned netport_idx, ifoe_network_addr_type_e map_addr_type, unsigned map_count, ifoe_accelerator_addr_map_t map[]); +int ifoe_nl_netport_get_accelerator_addr_map(ualoe_handle_t handle, unsigned netport_idx, + unsigned map_count, ifoe_accelerator_addr_map_t map[]); int ifoe_nl_netport_set_addr(ualoe_handle_t handle, unsigned netport_idx, ifoe_network_addr_type_e addr_type, uint8_t mac_addr[], uint32_t ip_addr); @@ -80,14 +84,45 @@ int ifoe_nl_netport_config_link_manual(ualoe_handle_t handle, unsigned netport_i ualoe_netport_loopback_mode_e loopback_mode); int ifoe_nl_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, ifoe_netport_state_t* state); +int ifoe_nl_ifcp_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, + ifoe_ifcp_netport_state_t* state); +int ifoe_nl_ifcp_netport_get_stats(ualoe_handle_t handle, unsigned netport_idx, + ifoe_ifcp_netport_stats_t* stats); int ifoe_nl_get_netport_properties(ualoe_handle_t handle, ualoe_netport_properties_t* properties); +int ualoe_nl_get_scaleup_fabric_config(ualoe_handle_t handle, + ualoe_scaleup_fabric_config_t* config); +int ualoe_nl_get_scaleup_fabric_vpod_config(ualoe_handle_t handle, + ualoe_scaleup_fabric_vpod_config_t* config); +int ualoe_nl_get_scaleup_fabric_station_info(ualoe_handle_t handle, + ualoe_scaleup_fabric_station_info_t* info); +int ualoe_nl_set_scaleup_fabric_config(ualoe_handle_t handle, + const ualoe_scaleup_fabric_config_t* config); +int ualoe_nl_set_scaleup_fabric_vpod_config(ualoe_handle_t handle, + const ualoe_scaleup_fabric_vpod_config_t* config); +int ualoe_nl_set_scaleup_fabric_station_info(ualoe_handle_t handle, + const ualoe_scaleup_fabric_station_info_t* info); +int ualoe_nl_get_gpu_identity(ualoe_handle_t handle, ualoe_gpu_identity_t* identity); int ualoe_nl_telemetry_alloc(ualoe_handle_t handle, unsigned category_mask, ualoe_telemetry_t** telemetry); int ualoe_nl_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry); int ualoe_nl_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetry); +int ualoe_nl_telemetry_get_category_mask(ualoe_handle_t handle, unsigned* category_mask); int ualoe_nl_l2ping_start(ualoe_handle_t handle, ualoe_ping_spec_t* spec, ualoe_ping_t** ping); int ualoe_nl_l2ping_update(ualoe_handle_t handle, ualoe_ping_t* ping); int ualoe_nl_l2ping_fini(ualoe_handle_t handle, ualoe_ping_t* ping); int ualoe_nl_register_event_callback(ualoe_handle_t handle, ualoe_event_callback_t callback, void* user_data); +int ualoe_nl_diag_config_pma_lane(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, + bool enable, ualoe_pma_rate_e pma_rate, + ualoe_netport_loopback_mode_e loopback_mode, + ualoe_pma_polarity_e tx_polarity, + ualoe_pma_polarity_e rx_polarity); +int ualoe_nl_diag_config_prbs_tx(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, + bool enable, ualoe_prbs_pattern_e pattern, + __uint128_t user_pattern); +int ualoe_nl_diag_config_prbs_rx(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, + bool enable, bool resync, ualoe_prbs_pattern_e pattern, + __uint128_t user_pattern); +int ualoe_nl_diag_get_prbs_results(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, + ualoe_prbs_results_t* results); #endif /* UALOE_NL_H */ diff --git a/projects/amdsmi/include/ualoe_lib/ualoe_telem.h b/projects/amdsmi/include/ualoe_lib/ualoe_telem.h new file mode 100644 index 000000000000..ac089e49683a --- /dev/null +++ b/projects/amdsmi/include/ualoe_lib/ualoe_telem.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef UALOE_TELEM_H +#define UALOE_TELEM_H + +#include "ualoe_lib.h" + +#ifdef __GNUC__ +#define ADD_OVERFLOW(a, b, res) __builtin_add_overflow((a), (b), (res)) +#else +#define ADD_OVERFLOW(a, b, res) (*(res) = (a) + (b), (*(res) < (a) || *(res) < (b))) +#endif + +long ualoe_get_page_size(void); +int ualoe_telem_parse(const void* mmap_buf, size_t buf_size, unsigned category_mask, + ualoe_telemetry_t* telemetry); + +#endif /* UALOE_TELEM_H */ diff --git a/projects/amdsmi/src/amd_smi/amd_smi_ualoe.cc b/projects/amdsmi/src/amd_smi/amd_smi_ualoe.cc index 99e362b35c27..44882fc90eb2 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi_ualoe.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi_ualoe.cc @@ -604,6 +604,19 @@ static amdsmi_status_t convert_errno_to_amdsmi_status(int errno_val) { } } +// The reinterpret_cast in amdsmi_alloc_fabric_telemetry() below aliases the UALoE +// telemetry allocation onto the amdsmi structs. These guards fail the build if a +// UALoE re-sync diverges the element layouts or drops below amd-smi's category count. +static_assert(static_cast(AMDSMI_FABRIC_TELEMETRY_CATEGORY_MAX) <= + static_cast(UALOE_TELEMETRY_CATEGORY_MAX), + "amdsmi fabric telemetry categories must not exceed UALoE categories"); +static_assert(sizeof(amdsmi_fabric_telemetry_item_t) == sizeof(ualoe_telemetry_item_t), + "amdsmi/UALoE telemetry item layout diverged"); +static_assert(sizeof(amdsmi_fabric_telemetry_instance_t) == sizeof(ualoe_telemetry_instance_t), + "amdsmi/UALoE telemetry instance layout diverged"); +static_assert(sizeof(amdsmi_fabric_telemetry_dataset_t) == sizeof(ualoe_telemetry_dataset_t), + "amdsmi/UALoE telemetry dataset layout diverged"); + amdsmi_status_t amdsmi_alloc_fabric_telemetry(amdsmi_processor_handle processor_handle, uint32_t category_mask, amdsmi_fabric_telemetry_t** telemetry) { @@ -641,7 +654,9 @@ amdsmi_status_t amdsmi_alloc_fabric_telemetry(amdsmi_processor_handle processor_ return convert_errno_to_amdsmi_status(ret); } - // Cast UALoE telemetry directly to AMDSMI telemetry since structures are now binary compatible + // Element layouts match (see the static_asserts above) and UALoE owns the + // allocation; amd-smi reads only categories [0, AMDSMI_FABRIC_TELEMETRY_CATEGORY_MAX), + // so aliasing the larger UALoE struct onto the amdsmi struct is safe. *telemetry = reinterpret_cast(ualoe_tel); return AMDSMI_STATUS_SUCCESS; diff --git a/projects/amdsmi/src/ualoe_lib/CMakeLists.txt b/projects/amdsmi/src/ualoe_lib/CMakeLists.txt index 8789f45a75c3..703d27afe33c 100644 --- a/projects/amdsmi/src/ualoe_lib/CMakeLists.txt +++ b/projects/amdsmi/src/ualoe_lib/CMakeLists.txt @@ -8,7 +8,13 @@ # when the libs live outside the default linker path (e.g. rocm_sysdeps). # Define source files for ualoe library -set(UALOE_SRC_LIST ualoe_lib.c ualoe_cdev.c ualoe_cb.c ualoe_nl.c) +set(UALOE_SRC_LIST + ualoe_lib.c + ualoe_cdev.c + ualoe_cb.c + ualoe_nl.c + ualoe_telem.c +) # Convert relative paths to absolute paths set(UALOE_ABS_SRC_LIST) diff --git a/projects/amdsmi/src/ualoe_lib/ualoe_cb.c b/projects/amdsmi/src/ualoe_lib/ualoe_cb.c index 22cf4291a620..5333b0312d11 100644 --- a/projects/amdsmi/src/ualoe_lib/ualoe_cb.c +++ b/projects/amdsmi/src/ualoe_lib/ualoe_cb.c @@ -35,12 +35,16 @@ #include #include +#include "ualoe_cdev.h" #include "ualoe_log.h" +#define UALOE_CB_NL_RCVBUF_SIZE (1024 * 1024) + struct cfg_cb_ctx { struct nl_sock* sk; ualoe_event_callback_t callback; ualoe_handle_t handle; + ualoe_handle_t cdev_fd; int dev_id; void* user_context; uint32_t seq; @@ -55,7 +59,8 @@ LIST_HEAD(cb_threads, cfg_cb_ctx); static struct cb_threads registered_cbs = LIST_HEAD_INITIALIZER(cb_threads); static pthread_mutex_t cb_lock = PTHREAD_MUTEX_INITIALIZER; -static const struct nla_policy cfg_timestamp_policy[] = { +/* non-const: older libnl3 (e.g. Debian 10) omits const on nla_parse_nested() policy arg */ +static struct nla_policy cfg_timestamp_policy[] = { [CFG_EVT_ATTR_TS_SECS] = {.type = NLA_U64}, [CFG_EVT_ATTR_TS_NSECS] = {.type = NLA_U64}, }; @@ -95,6 +100,12 @@ static struct nla_policy cfg_netport_link_event_policy[] = { [CFG_EVT_ATTR_DEV_ID] = {.type = NLA_S32}, }; +static struct nla_policy cfg_telemetry_ready_event_policy[] = { + [CFG_EVT_ATTR_TS] = {.type = NLA_NESTED}, + [CFG_EVT_ATTR_DEV_ID] = {.type = NLA_S32}, + [CFG_EVT_ATTR_GEN_COUNT] = {.type = NLA_U64}, +}; + static int ualoe_cb_parse_ts(struct nlattr* attr, struct timespec* ts) { struct nlattr* attrs[CFG_EVT_ATTR_TS_MAX + 1]; int rc; @@ -316,6 +327,46 @@ static int ualoe_cb_process_netport_link_event(struct nl_msg* msg, void* arg) { return NL_OK; } +static int ualoe_cb_process_telemetry_ready_event(struct nl_msg* msg, void* arg) { + struct nlattr* attrs[CFG_EVT_ATTR_MAX + 1]; + struct nlmsghdr* nlh = nlmsg_hdr(msg); + struct genlmsghdr* genlh = nlmsg_data(nlh); + struct cfg_cb_ctx* cb_ctx = arg; + ualoe_event_t event; + int dev_id, rc; + + rc = nla_parse(attrs, CFG_EVT_ATTR_MAX, genlmsg_attrdata(genlh, 0), genlmsg_attrlen(genlh, 0), + cfg_telemetry_ready_event_policy); + if (rc) return NL_OK; + + if (!attrs[CFG_EVT_ATTR_DEV_ID]) { + ualoe_log_error("No DEV_ID attribute found in telemetry ready event\n"); + return NL_OK; + } + + dev_id = nla_get_s32(attrs[CFG_EVT_ATTR_DEV_ID]); + if (dev_id != cb_ctx->dev_id) { + return NL_OK; + } + + if (!ualoe_cdev_is_telem_allocated(cb_ctx->cdev_fd)) return NL_OK; + + if (!attrs[CFG_EVT_ATTR_TS] || !attrs[CFG_EVT_ATTR_GEN_COUNT]) { + ualoe_log_error("Missing attribute in telemetry ready event\n"); + return NL_OK; + } + + event.id = UALOE_EVENT_TELEMETRY_READY; + + rc = ualoe_cb_parse_ts(attrs[CFG_EVT_ATTR_TS], &event.timestamp); + if (rc) return NL_OK; + + event.u.telemetry_ready.generation_count = nla_get_u64(attrs[CFG_EVT_ATTR_GEN_COUNT]); + + if (cb_ctx->callback) cb_ctx->callback(cb_ctx->user_context, cb_ctx->handle, event); + return NL_OK; +} + static int ualoe_cb_process_event(struct nl_msg* msg, void* arg) { struct nlmsghdr* nlh = nlmsg_hdr(msg); struct genlmsghdr* genlh = nlmsg_data(nlh); @@ -327,16 +378,21 @@ static int ualoe_cb_process_event(struct nl_msg* msg, void* arg) { return ualoe_cb_process_ifoe_link_event(msg, arg); case CFG_EVT_CMD_NETPORT_LINK_EVENT: return ualoe_cb_process_netport_link_event(msg, arg); + case CFG_EVT_CMD_TELEMETRY_READY_EVENT: + return ualoe_cb_process_telemetry_ready_event(msg, arg); default: - ualoe_log_error("Unknown cmd in event message: %d\n", genlh->cmd); return NL_SKIP; } } +#define EVENT_POLLER_BACKOFF_INIT_MS 10 +#define EVENT_POLLER_BACKOFF_MAX_MS 1000 + static void* ualoe_cb_event_poller(void* arg) { /* Callers must never hold cb_lock */ struct cfg_cb_ctx* cb_ctx = arg; struct pollfd fds[2]; + int backoff_ms = 0; int rc; fds[0].fd = nl_socket_get_fd(cb_ctx->sk); @@ -359,8 +415,24 @@ static void* ualoe_cb_event_poller(void* arg) { rc = nl_recvmsgs_default(cb_ctx->sk); if (rc < 0) { ualoe_log_error("nl_recvmsgs_default failed: %d\n", rc); - break; + /* + * Transient errors (e.g. NLE_NOMEM during event + * bursts) should not kill the poller -- the socket + * is still valid, so keep polling. Use exponential + * backoff to avoid spinning if the error persists. + */ + if (backoff_ms == 0) + backoff_ms = EVENT_POLLER_BACKOFF_INIT_MS; + else if (backoff_ms < EVENT_POLLER_BACKOFF_MAX_MS) + backoff_ms *= 2; + + /* Sleep but remain responsive to shutdown */ + rc = poll(&fds[1], 1, backoff_ms); + if (rc > 0 && (fds[1].revents & POLLIN)) break; + continue; } + /* Successful receive -- reset backoff */ + backoff_ms = 0; } } @@ -368,20 +440,22 @@ static void* ualoe_cb_event_poller(void* arg) { } static void ualoe_cb_ctx_init(struct cfg_cb_ctx* cb_ctx, ualoe_handle_t handle, int dev_id, - ualoe_event_callback_t callback, void* user_context) { + ualoe_handle_t cdev_fd, ualoe_event_callback_t callback, + void* user_context) { cb_ctx->seq = 0; cb_ctx->family_id = 0; cb_ctx->mcast_grp = 0; cb_ctx->dev_id = dev_id; cb_ctx->callback = callback; cb_ctx->handle = handle; + cb_ctx->cdev_fd = cdev_fd; cb_ctx->user_context = user_context; cb_ctx->tid = 0; cb_ctx->shutdown_fd = -1; } -int ualoe_cb_init(ualoe_handle_t handle, int dev_id, ualoe_event_callback_t callback, - void* user_context) { +int ualoe_cb_init(ualoe_handle_t handle, int dev_id, ualoe_handle_t cdev_fd, + ualoe_event_callback_t callback, void* user_context) { struct cfg_cb_ctx *cb_ctx, *iter; pthread_t tid; int rc; @@ -389,7 +463,7 @@ int ualoe_cb_init(ualoe_handle_t handle, int dev_id, ualoe_event_callback_t call cb_ctx = malloc(sizeof(*cb_ctx)); if (!cb_ctx) return ENOMEM; - ualoe_cb_ctx_init(cb_ctx, handle, dev_id, callback, user_context); + ualoe_cb_ctx_init(cb_ctx, handle, dev_id, cdev_fd, callback, user_context); cb_ctx->shutdown_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (cb_ctx->shutdown_fd < 0) { @@ -409,6 +483,10 @@ int ualoe_cb_init(ualoe_handle_t handle, int dev_id, ualoe_event_callback_t call goto free_nl_sock; } + /* Increase receive buffer to avoid drops during event bursts */ + rc = nl_socket_set_buffer_size(cb_ctx->sk, UALOE_CB_NL_RCVBUF_SIZE, 0); + if (rc < 0) ualoe_log_error("Failed to set NL rx buffer size: %d\n", rc); + cb_ctx->family_id = genl_ctrl_resolve(cb_ctx->sk, CFG_FAMILY_NAME); if (cb_ctx->family_id < 0) { rc = -cb_ctx->family_id; @@ -485,10 +563,10 @@ static void ualoe_cb_unreg(struct cfg_cb_ctx* cb_ctx) { ualoe_log_error("Failed to write to shutdown eventfd: %d\n", errno); rc = pthread_join(cb_ctx->tid, &res); - if (rc) ualoe_log_error("Failed to join cb thread rc=%d\n", rc); - - if (res != PTHREAD_CANCELED) - ualoe_log_error("Handle %d's cb thread not canceled\n", cb_ctx->handle); + if (rc) + ualoe_log_error("Failed to join cb thread rc=%d\n", rc); + else if (res != NULL) + ualoe_log_error("Handle %d's cb thread exited abnormally\n", cb_ctx->handle); LIST_REMOVE(cb_ctx, lentry); nl_close(cb_ctx->sk); diff --git a/projects/amdsmi/src/ualoe_lib/ualoe_cdev.c b/projects/amdsmi/src/ualoe_lib/ualoe_cdev.c index 938e0dd38789..e9d05b641add 100644 --- a/projects/amdsmi/src/ualoe_lib/ualoe_cdev.c +++ b/projects/amdsmi/src/ualoe_lib/ualoe_cdev.c @@ -23,8 +23,10 @@ #include "ualoe_cdev.h" #include +#include #include #include +#include #include #include #include @@ -32,16 +34,22 @@ #include #include #include +#include #include #include #include "ualoe_cb.h" #include "ualoe_lib.h" #include "ualoe_log.h" +#include "ualoe_telem.h" struct ualoe_cdev_handle { int fd; int dev_id; + bool use_mmap; + bool telem_allocated; + unsigned category_mask; + size_t snap_size; LIST_ENTRY(ualoe_cdev_handle) lentry; }; @@ -90,6 +98,12 @@ _Static_assert(offsetof(struct cfg_l2ping_netport_result, resp_failures) == _Static_assert(offsetof(struct cfg_l2ping_netport_result, non_ifoe_failures) == offsetof(ualoe_ping_netport_result_t, non_ifoe_failures), "non_ifoe_failures field offset mismatch"); +_Static_assert(offsetof(struct cfg_l2ping_netport_result, flags) == + offsetof(ualoe_ping_netport_result_t, flags), + "flags field offset mismatch"); +_Static_assert(CFG_L2PING_NETPORT_INVALID_RESULT == UALOE_PING_NETPORT_INVALID_RESULT, + "INVALID_RESULT flag value mismatch between kernel UAPI and " + "library headers"); /* Validate that cfg_l2ping_accel_result and ualoe_ping_accel_result_t * have the same memory layout so we can cast between them */ @@ -103,29 +117,70 @@ _Static_assert(offsetof(struct cfg_l2ping_accel_result, netports) == offsetof(ualoe_ping_accel_result_t, netports), "netports field offset mismatch"); -static int ualoe_cdev_find(const char* pci_addr, char** cdev_name) { - /* TODO: define proper method of mapping from GPU UUID to char device - * name. For testing just guess name. - */ - *cdev_name = "/dev/cbl-cfg-ifoe.cfg.0"; - return 0; +/** + * ualoe_cdev_find_any - Find any cbl-cfg misc device path + * + * Scans /sys/class/misc/ for the first entry matching "cbl-cfg-*" and + * returns its /dev path. This device is used temporarily to issue a + * CFG_CONNECT ioctl and discover the dev_id for a given PCI address. + * + * On success, *cdev_name points into a thread-local static buffer that is + * valid until the next call to this function on the same thread. + * + * Returns ENODEV if sysfs is unavailable or no matching device is found. + */ +static int ualoe_cdev_find_any(char** cdev_name) { + static __thread char devpath[PATH_MAX]; + struct dirent* ent; + DIR* dir; + + dir = opendir("/sys/class/misc"); + if (!dir) return ENODEV; + + while ((ent = readdir(dir)) != NULL) { + if (strncmp(ent->d_name, "cbl-cfg-", 8) != 0) continue; + + snprintf(devpath, sizeof(devpath), "/dev/%s", ent->d_name); + closedir(dir); + *cdev_name = devpath; + return 0; + } + closedir(dir); + return ENODEV; } int ualoe_cdev_open(const char* pci_addr, ualoe_handle_t* handle) { struct ualoe_cdev_handle* cdev_handle; - char* cdev_name; - int rc; + int ctrl_fd, dev_id, rc; + char devpath[PATH_MAX]; + char* ctrl_cdev; - cdev_handle = malloc(sizeof(*cdev_handle)); + cdev_handle = calloc(1, sizeof(*cdev_handle)); if (!cdev_handle) return ENOMEM; - rc = ualoe_cdev_find(pci_addr, &cdev_name); + /* Open any cbl-cfg cdev to issue CFG_CONNECT and discover dev_id */ + rc = ualoe_cdev_find_any(&ctrl_cdev); if (rc) { free(cdev_handle); - return ENOENT; + return ENODEV; } - rc = open(cdev_name, O_RDWR); + ctrl_fd = open(ctrl_cdev, O_RDWR); + if (ctrl_fd == -1) { + free(cdev_handle); + return errno; + } + + rc = ualoe_cdev_connect(ctrl_fd, pci_addr, &dev_id); + close(ctrl_fd); + if (rc) { + free(cdev_handle); + return rc; + } + + snprintf(devpath, sizeof(devpath), "/dev/cbl-cfg-ifoe.cfg.%d", dev_id); + + rc = open(devpath, O_RDWR); if (rc == -1) { free(cdev_handle); return errno; @@ -440,17 +495,24 @@ int ifoe_cdev_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, return 0; } +_Static_assert((int)UALOE_TELEMETRY_CATEGORY_MAX >= (int)CFG_TELEMETRY_CATEGORY_MAX, + "UALOE_TELEMETRY_CATEGORY_MAX must be >= CFG_TELEMETRY_CATEGORY_MAX"); + int ualoe_cdev_telemetry_alloc(ualoe_handle_t handle, unsigned category_mask, ualoe_telemetry_t** telemetry) { struct ualoe_cdev_handle* cdev_handle; ualoe_telemetry_dataset_t* dset; ualoe_telemetry_instance_t* instance; struct cfg_set_telemetry cfg_set_tele; + long page_size; int i, j, rc; + void* probe; rc = ualoe_cdev_find_handle(handle, &cdev_handle); if (rc) return rc; + if (cdev_handle->use_mmap && cdev_handle->category_mask != 0) return EINVAL; + /* 1) allocate ualoe_telemetry_*t */ *telemetry = calloc(1, sizeof(ualoe_telemetry_t)); if (!*telemetry) return ENOMEM; @@ -484,7 +546,6 @@ int ualoe_cdev_telemetry_alloc(ualoe_handle_t handle, unsigned category_mask, } } - /* 2) call driver to 'select' and 'dma_cfg' */ cfg_set_tele.dev_id = cdev_handle->dev_id; cfg_set_tele.category_mask = category_mask; rc = ioctl(handle, CFG_SET_TELEMETRY, &cfg_set_tele); @@ -493,6 +554,43 @@ int ualoe_cdev_telemetry_alloc(ualoe_handle_t handle, unsigned category_mask, goto free_dsets; } + /* Probe mmap to decide whether mmap is supported. */ + page_size = ualoe_get_page_size(); + probe = mmap(NULL, page_size, PROT_READ, MAP_SHARED, handle, 0); + if (probe != MAP_FAILED) { + /* mmap path: read snapshot header to learn full size */ + const struct cfg_telem_snapshot_hdr* snap_hdr = probe; + size_t const_end, dyn_end, total; + + if (ADD_OVERFLOW((size_t)snap_hdr->const_offset, (size_t)snap_hdr->const_size, &const_end) || + ADD_OVERFLOW((size_t)snap_hdr->dyn_offset, (size_t)snap_hdr->dyn_size, &dyn_end)) { + munmap(probe, page_size); + ualoe_log_error("mmap probe: snapshot header offsets overflow\n"); + rc = EIO; + goto free_dsets; + } + + total = const_end > dyn_end ? const_end : dyn_end; + + /* PAGE_ALIGN: round up to page boundary */ + total = (total + page_size - 1) & ~(page_size - 1); + + munmap(probe, page_size); + + if (total == 0) { + ualoe_log_error("mmap probe: snapshot header has zero size\n"); + rc = EIO; + goto free_dsets; + } + + cdev_handle->use_mmap = true; + cdev_handle->category_mask = category_mask; + cdev_handle->snap_size = total; + } else { + cdev_handle->use_mmap = false; + } + + cdev_handle->telem_allocated = true; return 0; free_dsets: @@ -506,18 +604,36 @@ int ualoe_cdev_telemetry_alloc(ualoe_handle_t handle, unsigned category_mask, } } free(*telemetry); + /* clear the out-parameter so callers that key cleanup off a non-NULL + * telemetry pointer (e.g. `if (telemetry != NULL) ualoe_telemetry_free()`) + * do not invoke free on this just-freed allocation and walk freed memory. + */ + *telemetry = NULL; return rc; } -int ualoe_cdev_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry) { - struct ualoe_cdev_handle* cdev_handle; - struct cfg_telemetry cfg_tele; // TODO how to specify number of categories? - int i, j, rc; +static int ualoe_cdev_telemetry_mmap_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry, + struct ualoe_cdev_handle* cdev_handle) { + void* buf; + int rc; - rc = ualoe_cdev_find_handle(handle, &cdev_handle); - if (rc) return rc; + /* Telemetry has not been allocated beforehand */ + if (cdev_handle->category_mask == 0 || cdev_handle->snap_size == 0) return EINVAL; + + buf = mmap(NULL, cdev_handle->snap_size, PROT_READ, MAP_SHARED, handle, 0); + if (buf == MAP_FAILED) return errno; - cfg_tele.datasets = calloc(UALOE_TELEMETRY_CATEGORY_MAX, sizeof(struct cfg_telemetry_dataset)); + rc = ualoe_telem_parse(buf, cdev_handle->snap_size, cdev_handle->category_mask, telemetry); + munmap(buf, cdev_handle->snap_size); + return rc; +} + +static int ualoe_cdev_telemetry_ioctl_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry, + struct ualoe_cdev_handle* cdev_handle) { + struct cfg_telemetry cfg_tele; + int i, j, rc; + + cfg_tele.datasets = calloc(CFG_TELEMETRY_CATEGORY_MAX, sizeof(struct cfg_telemetry_dataset)); if (!cfg_tele.datasets) return ENOMEM; for (i = 0; i < CFG_TELEMETRY_CATEGORY_MAX; i++) { @@ -546,7 +662,7 @@ int ualoe_cdev_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry } /* Validate telemetry structure matches driver response */ - for (i = 0; i < UALOE_TELEMETRY_CATEGORY_MAX; i++) { + for (i = 0; i < CFG_TELEMETRY_CATEGORY_MAX; i++) { /* Check if firmware returned unrequested category */ if (cfg_tele.datasets[i].instance_count > 0 && telemetry->datasets[i] == NULL) { ualoe_log_error( @@ -569,7 +685,7 @@ int ualoe_cdev_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry } /* copy driver cfg_tele into userspace telemetry */ - for (i = 0; i < UALOE_TELEMETRY_CATEGORY_MAX; i++) { + for (i = 0; i < CFG_TELEMETRY_CATEGORY_MAX; i++) { /* Skip NULL datasets (filtered categories) */ if (telemetry->datasets[i] == NULL) continue; @@ -601,14 +717,30 @@ int ualoe_cdev_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry out_free_instances: for (i = 0; i < CFG_TELEMETRY_CATEGORY_MAX; i++) { - for (j = 0; j < CFG_TELEMETRY_MAX_INSTANCES; j++) free(cfg_tele.datasets[i].instances[j].items); - free(cfg_tele.datasets[i].instances); + if (cfg_tele.datasets[i].instances != NULL) { + for (j = 0; j < CFG_TELEMETRY_MAX_INSTANCES; j++) + free(cfg_tele.datasets[i].instances[j].items); + free(cfg_tele.datasets[i].instances); + } } free(cfg_tele.datasets); return rc; } +int ualoe_cdev_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry) { + struct ualoe_cdev_handle* cdev_handle; + int rc; + + rc = ualoe_cdev_find_handle(handle, &cdev_handle); + if (rc) return rc; + + if (cdev_handle->use_mmap) + return ualoe_cdev_telemetry_mmap_get(handle, telemetry, cdev_handle); + else + return ualoe_cdev_telemetry_ioctl_get(handle, telemetry, cdev_handle); +} + int ualoe_cdev_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetry) { struct ualoe_cdev_handle* cdev_handle; int rc; @@ -617,8 +749,16 @@ int ualoe_cdev_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetr rc = ualoe_cdev_find_handle(handle, &cdev_handle); if (rc) return rc; - rc = ioctl(handle, CFG_FREE_TELEMETRY, &cdev_handle->dev_id); - if (rc == -1) return errno; + if (cdev_handle->use_mmap) { + if (cdev_handle->category_mask == 0) return EINVAL; + cdev_handle->category_mask = 0; + } else { + /* ioctl fallback: tell driver to free DMA resources */ + rc = ioctl(handle, CFG_FREE_TELEMETRY, &cdev_handle->dev_id); + if (rc == -1) return errno; + } + + cdev_handle->telem_allocated = false; for (i = UALOE_TELEMETRY_CATEGORY_MAX - 1; i >= 0; i--) { /* Skip NULL datasets (filtered categories) */ @@ -633,6 +773,13 @@ int ualoe_cdev_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetr return 0; } +bool ualoe_cdev_is_telem_allocated(ualoe_handle_t handle) { + struct ualoe_cdev_handle* cdev_handle; + + if (ualoe_cdev_find_handle(handle, &cdev_handle)) return false; + return cdev_handle->telem_allocated; +} + int ualoe_cdev_l2ping_start(ualoe_handle_t handle, ualoe_ping_spec_t* spec, ualoe_ping_t** ping) { struct ualoe_cdev_handle* cdev_handle; struct cfg_l2ping_config cfg_config; @@ -817,5 +964,5 @@ int ualoe_cdev_register_event_callback(ualoe_handle_t handle, ualoe_event_callba rc = ualoe_cdev_find_handle(handle, &cdev_handle); if (rc) return rc; - return ualoe_cb_init(handle, cdev_handle->dev_id, callback, user_context); + return ualoe_cb_init(handle, cdev_handle->dev_id, handle, callback, user_context); } diff --git a/projects/amdsmi/src/ualoe_lib/ualoe_lib.c b/projects/amdsmi/src/ualoe_lib/ualoe_lib.c index eb0c230315ed..3ea93e928415 100644 --- a/projects/amdsmi/src/ualoe_lib/ualoe_lib.c +++ b/projects/amdsmi/src/ualoe_lib/ualoe_lib.c @@ -623,6 +623,30 @@ int ifoe_get_netport_list(ualoe_handle_t handle, unsigned desc_count, ifoe_netpo #endif /* UALOE_NETLINK */ } +int ifoe_get_netport_list_v2(ualoe_handle_t handle, unsigned* desc_count, + ifoe_netport_desc_t descs[]) { + if (desc_count == NULL) { + ualoe_log_error("%s: desc_count cannot be NULL\n", __func__); + return EINVAL; + } + + if (*desc_count == 0) { + ualoe_log_error("%s: *desc_count must be greater than 0\n", __func__); + return EINVAL; + } + + if (descs == NULL) { + ualoe_log_error("%s: descs cannot be NULL\n", __func__); + return EINVAL; + } + +#ifdef UALOE_NETLINK + return ifoe_nl_get_netport_list_v2(handle, desc_count, descs); +#else + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + int ifoe_netport_ctrl(ualoe_handle_t handle, unsigned netport_idx, ifoe_netport_state_e state) { int rc; @@ -704,6 +728,26 @@ int ifoe_netport_set_accelerator_addr_map(ualoe_handle_t handle, unsigned netpor #endif /* UALOE_NETLINK */ } +int ifoe_netport_get_accelerator_addr_map(ualoe_handle_t handle, unsigned netport_idx, + unsigned map_count, ifoe_accelerator_addr_map_t map[]) { + if (map_count == 0 || map_count > UALOE_MAX_ACCELERATORS) { + ualoe_log_error("%s: map_count (%u) must be in range [1, %u]\n", __func__, map_count, + UALOE_MAX_ACCELERATORS); + return EINVAL; + } + + if (map == NULL) { + ualoe_log_error("%s: map cannot be NULL\n", __func__); + return EINVAL; + } + +#ifdef UALOE_NETLINK + return ifoe_nl_netport_get_accelerator_addr_map(handle, netport_idx, map_count, map); +#else + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + int ifoe_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, ifoe_netport_state_t* state) { if (state == NULL) { @@ -718,6 +762,170 @@ int ifoe_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, #endif /* UALOE_NETLINK */ } +int ifoe_ifcp_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, + ifoe_ifcp_netport_state_t* state) { + if (state == NULL) { + ualoe_log_error("%s: state cannot be equal to NULL\n", __func__); + return EINVAL; + } + +#ifdef UALOE_NETLINK + return ifoe_nl_ifcp_netport_get_state(handle, netport_idx, state); +#else + /* No cdev fallback for IFCP commands; available only over netlink */ + (void)handle; + (void)netport_idx; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + +int ifoe_ifcp_netport_get_stats(ualoe_handle_t handle, unsigned netport_idx, + ifoe_ifcp_netport_stats_t* stats) { + if (stats == NULL) { + ualoe_log_error("%s: stats cannot be equal to NULL\n", __func__); + return EINVAL; + } + +#ifdef UALOE_NETLINK + return ifoe_nl_ifcp_netport_get_stats(handle, netport_idx, stats); +#else + /* No cdev fallback for IFCP commands; available only over netlink */ + (void)handle; + (void)netport_idx; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + +int ualoe_get_scaleup_fabric_config(ualoe_handle_t handle, ualoe_scaleup_fabric_config_t* config) { + if (config == NULL) { + ualoe_log_error("%s: config cannot be equal to NULL\n", __func__); + return EINVAL; + } + + memset(config, 0, sizeof(*config)); + +#ifdef UALOE_NETLINK + return ualoe_nl_get_scaleup_fabric_config(handle, config); +#else + /* No cdev fallback for scaleup fabric commands; netlink only */ + (void)handle; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + +int ualoe_get_scaleup_fabric_vpod_config(ualoe_handle_t handle, + ualoe_scaleup_fabric_vpod_config_t* config) { + if (config == NULL) { + ualoe_log_error("%s: config cannot be equal to NULL\n", __func__); + return EINVAL; + } + + memset(config, 0, sizeof(*config)); + +#ifdef UALOE_NETLINK + return ualoe_nl_get_scaleup_fabric_vpod_config(handle, config); +#else + /* No cdev fallback for scaleup fabric commands; netlink only */ + (void)handle; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + +int ualoe_get_scaleup_fabric_station_info(ualoe_handle_t handle, + ualoe_scaleup_fabric_station_info_t* info) { + if (info == NULL) { + ualoe_log_error("%s: info cannot be NULL\n", __func__); + return EINVAL; + } + + memset(info, 0, sizeof(*info)); + +#ifdef UALOE_NETLINK + return ualoe_nl_get_scaleup_fabric_station_info(handle, info); +#else + /* No cdev fallback for scaleup fabric commands; netlink only */ + (void)handle; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + +int ualoe_set_scaleup_fabric_config(ualoe_handle_t handle, + const ualoe_scaleup_fabric_config_t* config) { + if (config == NULL) { + ualoe_log_error("%s: config cannot be equal to NULL\n", __func__); + return EINVAL; + } + + if (config->num_local_accelerators > UALOE_SCALEUP_FABRIC_MAX_LOCAL_ACCELERATORS) { + ualoe_log_error("%s: num_local_accelerators %u exceeds maximum %u\n", __func__, + config->num_local_accelerators, UALOE_SCALEUP_FABRIC_MAX_LOCAL_ACCELERATORS); + return EINVAL; + } + +#ifdef UALOE_NETLINK + return ualoe_nl_set_scaleup_fabric_config(handle, config); +#else + /* No cdev fallback for scaleup fabric commands; netlink only */ + (void)handle; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + +int ualoe_set_scaleup_fabric_vpod_config(ualoe_handle_t handle, + const ualoe_scaleup_fabric_vpod_config_t* config) { + if (config == NULL) { + ualoe_log_error("%s: config cannot be equal to NULL\n", __func__); + return EINVAL; + } + +#ifdef UALOE_NETLINK + return ualoe_nl_set_scaleup_fabric_vpod_config(handle, config); +#else + /* No cdev fallback for scaleup fabric commands; netlink only */ + (void)handle; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + +int ualoe_set_scaleup_fabric_station_info(ualoe_handle_t handle, + const ualoe_scaleup_fabric_station_info_t* info) { + if (info == NULL) { + ualoe_log_error("%s: info cannot be NULL\n", __func__); + return EINVAL; + } + + if (info->num_stations > UALOE_SCALEUP_FABRIC_MAX_STATIONS) { + ualoe_log_error("%s: num_stations %u exceeds maximum %u\n", __func__, info->num_stations, + UALOE_SCALEUP_FABRIC_MAX_STATIONS); + return EINVAL; + } + +#ifdef UALOE_NETLINK + return ualoe_nl_set_scaleup_fabric_station_info(handle, info); +#else + /* No cdev fallback for scaleup fabric commands; netlink only */ + (void)handle; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + +int ualoe_get_gpu_identity(ualoe_handle_t handle, ualoe_gpu_identity_t* identity) { + if (identity == NULL) { + ualoe_log_error("%s: identity cannot be NULL\n", __func__); + return EINVAL; + } + + memset(identity, 0, sizeof(*identity)); + +#ifdef UALOE_NETLINK + return ualoe_nl_get_gpu_identity(handle, identity); +#else + /* No cdev fallback for GPU identity command; netlink only */ + (void)handle; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + int ualoe_telemetry_alloc(ualoe_handle_t handle, unsigned category_mask, ualoe_telemetry_t** telemetry) { if (category_mask >= (1U << UALOE_TELEMETRY_CATEGORY_MAX)) { @@ -763,6 +971,21 @@ int ualoe_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetry) { #endif /* UALOE_NETLINK */ } +int ualoe_telemetry_get_category_mask(ualoe_handle_t handle, unsigned* category_mask) { + if (category_mask == NULL) { + ualoe_log_error("%s: category_mask cannot be NULL\n", __func__); + return EINVAL; + } + +#ifdef UALOE_NETLINK + return ualoe_nl_telemetry_get_category_mask(handle, category_mask); +#else + /* No cdev fallback; netlink only */ + (void)handle; + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + int ualoe_l2ping_start(ualoe_handle_t handle, ualoe_ping_spec_t* spec, ualoe_ping_t** ping) { if (spec == NULL) { ualoe_log_error("%s: spec parameter is NULL\n", __func__); @@ -824,21 +1047,70 @@ int ualoe_diag_config_pma_lane(ualoe_handle_t handle, unsigned netport_idx, unsi bool enable, ualoe_pma_rate_e pma_rate, ualoe_netport_loopback_mode_e loopback_mode, ualoe_pma_polarity_e tx_polarity, ualoe_pma_polarity_e rx_polarity) { +#ifdef UALOE_NETLINK + return ualoe_nl_diag_config_pma_lane(handle, netport_idx, lane_idx, enable, pma_rate, + loopback_mode, tx_polarity, rx_polarity); +#else return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ } int ualoe_diag_config_prbs_tx(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, bool enable, ualoe_prbs_pattern_e pattern, __uint128_t user_pattern) { +#ifdef UALOE_NETLINK + return ualoe_nl_diag_config_prbs_tx(handle, netport_idx, lane_idx, enable, pattern, user_pattern); +#else return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ } int ualoe_diag_config_prbs_rx(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, bool enable, bool resync, ualoe_prbs_pattern_e pattern, __uint128_t user_pattern) { +#ifdef UALOE_NETLINK + return ualoe_nl_diag_config_prbs_rx(handle, netport_idx, lane_idx, enable, resync, pattern, + user_pattern); +#else return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ } int ualoe_diag_get_prbs_results(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, ualoe_prbs_results_t* results) { + if (results == NULL) { + ualoe_log_error("%s: results cannot be NULL\n", __func__); + return EINVAL; + } +#ifdef UALOE_NETLINK + return ualoe_nl_diag_get_prbs_results(handle, netport_idx, lane_idx, results); +#else + return EOPNOTSUPP; +#endif /* UALOE_NETLINK */ +} + +int ualoe_get_ifoe_cper_entries(ualoe_handle_t handle, uint32_t severity_mask, char* cper_data, + uint64_t* buf_size, ualoe_cper_hdr_t** cper_hdrs, + uint64_t* entry_count, uint64_t* cursor) { + if (cper_data == NULL) { + ualoe_log_error("%s: cper_data cannot be NULL\n", __func__); + return EINVAL; + } + if (buf_size == NULL) { + ualoe_log_error("%s: buf_size cannot be NULL\n", __func__); + return EINVAL; + } + if (cper_hdrs == NULL) { + ualoe_log_error("%s: cper_hdrs cannot be NULL\n", __func__); + return EINVAL; + } + if (entry_count == NULL) { + ualoe_log_error("%s: entry_count cannot be NULL\n", __func__); + return EINVAL; + } + if (cursor == NULL) { + ualoe_log_error("%s: cursor cannot be NULL\n", __func__); + return EINVAL; + } + return EOPNOTSUPP; } diff --git a/projects/amdsmi/src/ualoe_lib/ualoe_nl.c b/projects/amdsmi/src/ualoe_lib/ualoe_nl.c index 508d55f06322..e058eb9cee31 100644 --- a/projects/amdsmi/src/ualoe_lib/ualoe_nl.c +++ b/projects/amdsmi/src/ualoe_lib/ualoe_nl.c @@ -19,7 +19,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - #include "ualoe_nl.h" #include @@ -47,6 +46,7 @@ struct ualoe_nl_handle { int port_id; int seq; int cdev_fd; + pthread_mutex_t request_lock; LIST_ENTRY(ualoe_nl_handle) lentry; }; @@ -59,80 +59,116 @@ static void ualoe_nl_init_msg(struct ualoe_nl_handle* handle, struct nlmsghdr** *nlh = mnl_nlmsg_put_header(buf); (*nlh)->nlmsg_type = type; (*nlh)->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - (*nlh)->nlmsg_seq = ++handle->seq; + (*nlh)->nlmsg_seq = 0; (*nlh)->nlmsg_pid = handle->port_id; *genlh = mnl_nlmsg_put_extra_header(*nlh, sizeof(**genlh)); (*genlh)->cmd = cmd; (*genlh)->version = vers; } -static int ualoe_nl_get_family_attrs(const struct nlattr* attr, void* data) { - struct ualoe_nl_handle* nl_handle = data; - int type = mnl_attr_get_type(attr); - - if (type != CTRL_ATTR_FAMILY_ID) return MNL_CB_OK; - - nl_handle->family_id = mnl_attr_get_u16(attr); - return MNL_CB_OK; +static void ualoe_nl_request_lock(struct ualoe_nl_handle* nl_handle, struct nlmsghdr* nlh) { + pthread_mutex_lock(&nl_handle->request_lock); + nlh->nlmsg_seq = ++nl_handle->seq; } -static int ualoe_nl_get_family_cb(const struct nlmsghdr* nlh, void* data) { - return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_get_family_attrs, data); +static void ualoe_nl_request_unlock(struct ualoe_nl_handle* nl_handle) { + pthread_mutex_unlock(&nl_handle->request_lock); } -static int ualoe_nl_get_family_id(struct ualoe_nl_handle* nl_handle) { - char buf[MNL_SOCKET_BUFFER_SIZE]; - struct genlmsghdr* genlh; - struct nlmsghdr* nlh; +struct ualoe_nl_response_ctx { + mnl_cb_t cb; + void* data; + int callback_error; + bool skip_payloads; +}; + +static int ualoe_nl_response_cb(const struct nlmsghdr* nlh, void* data) { + struct ualoe_nl_response_ctx* ctx = data; int rc; - ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CTRL_CMD_GETFAMILY, GENL_ID_CTRL, 2); + if (ctx->skip_payloads) return MNL_CB_OK; - mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, CFG_FAMILY_NAME); + errno = 0; + rc = ctx->cb ? ctx->cb(nlh, ctx->data) : MNL_CB_OK; + if (rc == MNL_CB_ERROR) { + ctx->callback_error = errno ? errno : EPROTO; + ctx->skip_payloads = true; + } else if (rc == MNL_CB_STOP) { + ctx->skip_payloads = true; + } + + /* Continue until mnl_cb_run consumes the terminal ACK or NLMSG_DONE. */ + return MNL_CB_OK; +} + +static int ualoe_nl_send_recv(struct ualoe_nl_handle* nl_handle, char* buf, size_t buf_size, + struct nlmsghdr* nlh, mnl_cb_t cb, void* cb_data) { + struct ualoe_nl_response_ctx ctx = { + .cb = cb, + .data = cb_data, + }; + unsigned int exp_seq, exp_pid; + int rc; + + ualoe_nl_request_lock(nl_handle, nlh); if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { rc = errno; ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; + goto unlock; } - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); + exp_seq = nlh->nlmsg_seq; + exp_pid = nlh->nlmsg_pid; + + rc = mnl_socket_recvfrom(nl_handle->sk, buf, buf_size); while (rc > 0) { - rc = mnl_cb_run(buf, rc, nl_handle->seq, nl_handle->port_id, ualoe_nl_get_family_cb, nl_handle); + rc = mnl_cb_run(buf, rc, exp_seq, exp_pid, ualoe_nl_response_cb, &ctx); if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); + rc = mnl_socket_recvfrom(nl_handle->sk, buf, buf_size); } - if (rc == -1) { + + if (ctx.callback_error) { + rc = ctx.callback_error; + } else if (rc == -1) { rc = errno; - ualoe_log_error("Failed to receive message rc=%d\n", rc); - return rc; + } else { + rc = 0; } - return 0; +unlock: + ualoe_nl_request_unlock(nl_handle); + return rc; } -/* Context structure for ualoe_nl_connect callbacks */ -struct ualoe_nl_connect_ctx { - struct ualoe_nl_handle* nl_handle; - int error_code; -}; +static int ualoe_nl_get_family_attrs(const struct nlattr* attr, void* data) { + struct ualoe_nl_handle* nl_handle = data; + int type = mnl_attr_get_type(attr); -static int ualoe_nl_connect_err_cb(const struct nlmsghdr* nlh, void* data) { - const struct nlmsgerr* err = mnl_nlmsg_get_payload(nlh); - struct ualoe_nl_connect_ctx* ctx = data; + if (type != CTRL_ATTR_FAMILY_ID) return MNL_CB_OK; - /* Extract the actual error code from the NLMSG_ERROR payload - * The kernel error is stored as negative value in err->error - * We want to return positive errno value - */ - ctx->error_code = -err->error; + nl_handle->family_id = mnl_attr_get_u16(attr); + return MNL_CB_OK; +} + +static int ualoe_nl_get_family_cb(const struct nlmsghdr* nlh, void* data) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_get_family_attrs, data); +} + +static int ualoe_nl_get_family_id(struct ualoe_nl_handle* nl_handle) { + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CTRL_CMD_GETFAMILY, GENL_ID_CTRL, 2); - return MNL_CB_ERROR; + mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, CFG_FAMILY_NAME); + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_get_family_cb, nl_handle); } -static int ualoe_nl_connect_attrs_ctx(const struct nlattr* attr, void* data) { - struct ualoe_nl_connect_ctx* ctx = data; - struct ualoe_nl_handle* nl_handle = ctx->nl_handle; +static int ualoe_nl_connect_attrs(const struct nlattr* attr, void* data) { + struct ualoe_nl_handle* nl_handle = data; int type = mnl_attr_get_type(attr); switch (type) { @@ -145,8 +181,8 @@ static int ualoe_nl_connect_attrs_ctx(const struct nlattr* attr, void* data) { return MNL_CB_OK; } -static int ualoe_nl_connect_cb_ctx(const struct nlmsghdr* nlh, void* data) { - return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_connect_attrs_ctx, data); +static int ualoe_nl_connect_cb(const struct nlmsghdr* nlh, void* data) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_connect_attrs, data); } static int ualoe_nl_connect(struct ualoe_nl_handle* nl_handle, const char* addr) { @@ -154,52 +190,20 @@ static int ualoe_nl_connect(struct ualoe_nl_handle* nl_handle, const char* addr) struct genlmsghdr* genlh; struct nlmsghdr* nlh; int rc; - struct ualoe_nl_connect_ctx ctx = { - .nl_handle = nl_handle, - .error_code = 0, - }; - mnl_cb_t cb_ctl_array[NLMSG_MIN_TYPE] = {NULL}; - - /* Register error callback for NLMSG_ERROR messages */ - cb_ctl_array[NLMSG_ERROR] = ualoe_nl_connect_err_cb; ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_CONNECT, nl_handle->family_id, 1); mnl_attr_put_strz(nlh, CFG_ATTR_PCI_ADDR, addr); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - int rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - - while (rc > 0) { - /* Use mnl_cb_run2 to provide custom error callback that extracts - * the actual kernel error code from NLMSG_ERROR messages - */ - rc = mnl_cb_run2(buf, rc, nl_handle->seq, nl_handle->port_id, ualoe_nl_connect_cb_ctx, &ctx, - cb_ctl_array, NLMSG_MIN_TYPE); - - if (rc <= MNL_CB_STOP) break; + rc = ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_connect_cb, nl_handle); + if (rc) return rc; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); + if (nl_handle->dev_id < 0) { + ualoe_log_error("Device %s did not return a device ID\n", addr); + return ENODEV; } - /* Check if we successfully received the device ID. - * If dev_id was set (>= 0), the connection succeeded even if we got an ACK. - * If rc == -1 and dev_id is still -1, then an actual error occurred. - */ - if (nl_handle->dev_id >= 0) return 0; - - /* If we get here, connection failed. ctx.error_code contains the error - * from NLMSG_ERROR, or we fall back to ENODEV if no error was reported. - */ - rc = ctx.error_code ? ctx.error_code : ENODEV; - printf("Device %s not found (error=%d)\n", addr, rc); - nl_handle->dev_id = -1; - return rc; + return 0; } int ualoe_nl_open(const char* name, ualoe_handle_t* handle) { @@ -209,10 +213,14 @@ int ualoe_nl_open(const char* name, ualoe_handle_t* handle) { nl_handle = malloc(sizeof(*nl_handle)); if (!nl_handle) return ENOMEM; + rc = pthread_mutex_init(&nl_handle->request_lock, NULL); + if (rc) goto free_handle; + + nl_handle->seq = 0; nl_handle->sk = mnl_socket_open(NETLINK_GENERIC); if (!nl_handle->sk) { rc = errno; - goto free_handle; + goto destroy_mutex; } if (mnl_socket_bind(nl_handle->sk, 0, MNL_SOCKET_AUTOPID) < 0) { @@ -230,10 +238,6 @@ int ualoe_nl_open(const char* name, ualoe_handle_t* handle) { rc = ualoe_nl_connect(nl_handle, name); if (rc) goto free_socket; - pthread_mutex_lock(&handle_lock); - LIST_INSERT_HEAD(&open_handles, nl_handle, lentry); - pthread_mutex_unlock(&handle_lock); - /** * For now, keep cdev fd for ioctl calls until netlink support is * added for all operations. @@ -241,12 +245,18 @@ int ualoe_nl_open(const char* name, ualoe_handle_t* handle) { rc = ualoe_cdev_open(name, &nl_handle->cdev_fd); if (rc) goto free_socket; + pthread_mutex_lock(&handle_lock); + LIST_INSERT_HEAD(&open_handles, nl_handle, lentry); + pthread_mutex_unlock(&handle_lock); + *handle = nl_handle->fd; return 0; free_socket: mnl_socket_close(nl_handle->sk); +destroy_mutex: + pthread_mutex_destroy(&nl_handle->request_lock); free_handle: free(nl_handle); return rc; @@ -271,9 +281,12 @@ int ualoe_nl_close(ualoe_handle_t handle) { * operations. */ ualoe_cb_fini(handle); - ualoe_cdev_close(nl_handle->cdev_fd); + pthread_mutex_lock(&nl_handle->request_lock); + ualoe_cdev_close(nl_handle->cdev_fd); mnl_socket_close(nl_handle->sk); + pthread_mutex_unlock(&nl_handle->request_lock); + pthread_mutex_destroy(&nl_handle->request_lock); free(nl_handle); return 0; @@ -367,22 +380,7 @@ int ualoe_nl_get_version(ualoe_handle_t handle, ualoe_version_t* lib_version, mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - /* Receive and parse response */ - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, ualoe_nl_get_version_handler, &ctx); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_get_version_handler, &ctx); } int ualoe_nl_reset(ualoe_handle_t handle) { @@ -398,21 +396,7 @@ int ualoe_nl_reset(ualoe_handle_t handle) { ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_RESET, nl_handle->family_id, 1); mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } static int ualoe_nl_parse_get_caps_nested(const struct nlattr* attr, void* arg) { @@ -466,21 +450,7 @@ int ualoe_nl_get_capabilities(ualoe_handle_t handle, ualoe_capabilities_t* caps) mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, ualoe_nl_get_caps_handler, caps); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_get_caps_handler, caps); } int ualoe_nl_set_identity(ualoe_handle_t handle, uint32_t accelerator_id) { @@ -499,21 +469,7 @@ int ualoe_nl_set_identity(ualoe_handle_t handle, uint32_t accelerator_id) { mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_ACCELERATOR_ID, accelerator_id); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } int ualoe_nl_set_accelerator_config(ualoe_handle_t handle, unsigned bitmask_size, @@ -551,21 +507,7 @@ int ualoe_nl_set_accelerator_config(ualoe_handle_t handle, unsigned bitmask_size } mnl_attr_nest_end(nlh, nest); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } int ualoe_nl_set_config_phase(ualoe_handle_t handle, ualoe_config_phase_e next_phase) { @@ -584,21 +526,7 @@ int ualoe_nl_set_config_phase(ualoe_handle_t handle, ualoe_config_phase_e next_p mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_CONFIG_PHASE, next_phase); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } static int ualoe_nl_parse_get_current_config_phase_nested(const struct nlattr* attr, void* arg) { @@ -644,22 +572,8 @@ int ualoe_nl_get_current_config_phase(ualoe_handle_t handle, ualoe_config_phase_ mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, - ualoe_nl_get_current_config_phase_handler, phase); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, + ualoe_nl_get_current_config_phase_handler, phase); } int ualoe_nl_set_ifoe_config(ualoe_handle_t handle, ifoe_virt_mode_e virt_mode, @@ -683,21 +597,7 @@ int ualoe_nl_set_ifoe_config(ualoe_handle_t handle, ifoe_virt_mode_e virt_mode, mnl_attr_put_u32(nlh, CFG_ATTR_IFOE_CONFIG_FAILOVER_MODE, failover_mode); mnl_attr_put_u32(nlh, CFG_ATTR_IFOE_CONFIG_LOOPBACK_MODE, loopback_mode); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } struct ualoe_nl_ifoe_cfg { @@ -867,22 +767,8 @@ int ualoe_nl_get_ifoe_config(ualoe_handle_t handle, ifoe_config_t* config, unsig .bitmask_size = bitmask_size, }; - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, ualoe_nl_get_ifoe_config_handler, - &cb_ctx); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_get_ifoe_config_handler, + &cb_ctx); } int ualoe_nl_enable_accelerators(ualoe_handle_t handle, unsigned bitmask_size, @@ -905,21 +791,7 @@ int ualoe_nl_enable_accelerators(ualoe_handle_t handle, unsigned bitmask_size, if (bitmask_size > 0 && enabled_accelerator_bitmask) mnl_attr_put(nlh, CFG_ATTR_ENABLED_ACCEL, bitmask_size, enabled_accelerator_bitmask); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } int ualoe_nl_config_crypto(ualoe_handle_t handle, ualoe_crypto_mode_e mode) { @@ -937,20 +809,7 @@ int ualoe_nl_config_crypto(ualoe_handle_t handle, ualoe_crypto_mode_e mode) { mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_CRYPTO_MODE, mode); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } int ualoe_nl_set_tx_crypto_key(ualoe_handle_t handle, ualoe_crypto_key_id_e key_id, @@ -972,21 +831,7 @@ int ualoe_nl_set_tx_crypto_key(ualoe_handle_t handle, ualoe_crypto_key_id_e key_ mnl_attr_put_u32(nlh, CFG_ATTR_CRYPTO_KEY_LEN, UALOE_CRYPTO_KEY_SIZE); mnl_attr_put(nlh, CFG_ATTR_CRYPTO_KEY, UALOE_CRYPTO_KEY_SIZE * sizeof(uint32_t), key); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } int ualoe_nl_disable_rx_crypto_key(ualoe_handle_t handle, ualoe_crypto_key_id_e key_id) { @@ -1005,21 +850,7 @@ int ualoe_nl_disable_rx_crypto_key(ualoe_handle_t handle, ualoe_crypto_key_id_e mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_CRYPTO_KEY_ID, key_id); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } int ualoe_nl_set_rx_crypto_key(ualoe_handle_t handle, ualoe_crypto_key_id_e key_id, @@ -1041,21 +872,7 @@ int ualoe_nl_set_rx_crypto_key(ualoe_handle_t handle, ualoe_crypto_key_id_e key_ mnl_attr_put_u32(nlh, CFG_ATTR_CRYPTO_KEY_LEN, UALOE_CRYPTO_KEY_SIZE); mnl_attr_put(nlh, CFG_ATTR_CRYPTO_KEY, UALOE_CRYPTO_KEY_SIZE * sizeof(uint32_t), key); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } static int ifoe_nl_parse_station_desc(const struct nlattr* attr, void* data) { @@ -1086,17 +903,33 @@ static int ifoe_nl_parse_station_desc(const struct nlattr* attr, void* data) { return MNL_CB_OK; } +struct ifoe_nl_station_list_ctx { + ifoe_station_desc_t* descs; + unsigned desc_count; + unsigned received; +}; + static int ifoe_nl_get_station_list_handler(const struct nlmsghdr* nlh, void* data) { - return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ifoe_nl_parse_station_desc, data); + struct ifoe_nl_station_list_ctx* ctx = data; + ifoe_station_desc_t* desc = ctx->received < ctx->desc_count ? &ctx->descs[ctx->received] : NULL; + int rc; + + rc = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ifoe_nl_parse_station_desc, desc); + if (rc > MNL_CB_STOP) ctx->received++; + return rc; } int ifoe_nl_get_station_list(ualoe_handle_t handle, unsigned desc_count, ifoe_station_desc_t descs[]) { + struct ifoe_nl_station_list_ctx ctx = { + .descs = descs, + .desc_count = desc_count, + }; struct ualoe_nl_handle* nl_handle; char buf[MNL_SOCKET_BUFFER_SIZE]; struct genlmsghdr* genlh; struct nlmsghdr* nlh; - int rc, i; + int rc; rc = ualoe_nl_find_handle(handle, &nl_handle); if (rc) return rc; @@ -1105,28 +938,10 @@ int ifoe_nl_get_station_list(ualoe_handle_t handle, unsigned desc_count, 1); mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_DESC_COUNT, desc_count); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - i = 0; - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - ifoe_station_desc_t* desc = i < desc_count ? &descs[i] : NULL; - - rc = - mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, ifoe_nl_get_station_list_handler, desc); - if (rc <= MNL_CB_STOP) break; - i++; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - if (i != desc_count) return ERANGE; - return 0; + rc = ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ifoe_nl_get_station_list_handler, &ctx); + if (rc) return rc; + return ctx.received == desc_count ? 0 : ERANGE; } int ifoe_nl_station_ctrl(ualoe_handle_t handle, unsigned station_idx, ifoe_station_state_e state) { @@ -1143,21 +958,7 @@ int ifoe_nl_station_ctrl(ualoe_handle_t handle, unsigned station_idx, ifoe_stati mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_STATION_LOGICAL_IDX, station_idx); mnl_attr_put_u32(nlh, CFG_ATTR_STATION_STATE, state); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } struct ualoe_nl_netport_cb_ctx { @@ -1293,23 +1094,9 @@ int ifoe_nl_station_get_state(ualoe_handle_t handle, unsigned station_idx, 1); mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_STATION_LOGICAL_IDX, station_idx); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, ifoe_nl_station_get_state_handler, - state); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; -} + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ifoe_nl_station_get_state_handler, + state); +} int ifoe_nl_set_path_to_port_map(ualoe_handle_t handle, bool specify_station, bool specify_accelerator, bool reenable_streams, @@ -1339,21 +1126,7 @@ int ifoe_nl_set_path_to_port_map(ualoe_handle_t handle, bool specify_station, if (specify_station) mnl_attr_put_u32(nlh, CFG_ATTR_STATION_LOGICAL_IDX, station_idx); if (specify_accelerator) mnl_attr_put_u32(nlh, CFG_ATTR_ACCELERATOR_ID, accelerator_id); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } struct ifoe_nl_path_to_port_map_cb_ctx { @@ -1413,22 +1186,8 @@ int ifoe_nl_get_path_to_port_map(ualoe_handle_t handle, unsigned station_idx, .map = map, }; - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, ifoe_nl_get_path_to_port_map_cb, - &cb_ctx); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ifoe_nl_get_path_to_port_map_cb, + &cb_ctx); } static int ifoe_nl_parse_netport_properties(const struct nlattr* attr, void* data) { @@ -1484,22 +1243,8 @@ int ifoe_nl_get_netport_properties(ualoe_handle_t handle, ualoe_netport_properti nl_handle->family_id, 1); mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, ifoe_nl_get_netport_properties_handler, - properties); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, + ifoe_nl_get_netport_properties_handler, properties); } static int ifoe_nl_parse_netport_desc(const struct nlattr* attr, void* data) { @@ -1538,16 +1283,32 @@ static int ifoe_nl_parse_netport_desc(const struct nlattr* attr, void* data) { return MNL_CB_OK; } +struct ifoe_nl_netport_list_ctx { + ifoe_netport_desc_t* descs; + unsigned desc_count; + unsigned received; +}; + static int ifoe_nl_get_netport_list_handler(const struct nlmsghdr* nlh, void* data) { - return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ifoe_nl_parse_netport_desc, data); + struct ifoe_nl_netport_list_ctx* ctx = data; + ifoe_netport_desc_t* desc = ctx->received < ctx->desc_count ? &ctx->descs[ctx->received] : NULL; + int rc; + + rc = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ifoe_nl_parse_netport_desc, desc); + if (rc > MNL_CB_STOP) ctx->received++; + return rc; } int ifoe_nl_get_netport_list(ualoe_handle_t handle, unsigned desc_count, ifoe_netport_desc_t descs[]) { + struct ifoe_nl_netport_list_ctx ctx = { + .descs = descs, + .desc_count = desc_count, + }; struct ualoe_nl_handle* nl_handle; char buf[MNL_SOCKET_BUFFER_SIZE]; struct genlmsghdr* genlh; struct nlmsghdr* nlh; - int rc, i; + int rc; rc = ualoe_nl_find_handle(handle, &nl_handle); if (rc) return rc; @@ -1556,27 +1317,106 @@ int ifoe_nl_get_netport_list(ualoe_handle_t handle, unsigned desc_count, 1); mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_DESC_COUNT, desc_count); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; + + rc = ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ifoe_nl_get_netport_list_handler, &ctx); + if (rc == ENOSPC) /* Preserve the legacy v1 behavior when descs is too small. */ + return EINVAL; + if (rc) return rc; + return ctx.received == desc_count ? 0 : ERANGE; +} + +/** Context for parsing netport list responses which include the + * total netport count alongside each descriptor. + */ +struct netport_list_v2_ctx { + ifoe_netport_desc_t* descs; + ifoe_netport_desc_t* desc; + unsigned max_count; + unsigned received; + unsigned total_count; +}; + +static int ifoe_nl_parse_netport_desc_v2(const struct nlattr* attr, void* data) { + struct netport_list_v2_ctx* ctx = data; + + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_NETPORT_LOGICAL_IDX: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + if (ctx->desc) ctx->desc->logical_idx = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_NETPORT_REL_IDX: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + if (ctx->desc) ctx->desc->station_rel_netport_idx = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_NETPORT_LABEL: + if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) return MNL_CB_ERROR; + if (ctx->desc) + snprintf(ctx->desc->name.text, UALOE_LABEL_SIZE, "%s", (char*)mnl_attr_get_str(attr)); + break; + case CFG_ATTR_STATION_LOGICAL_IDX: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + if (ctx->desc) ctx->desc->station_idx = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_STATION_LABEL: + if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) return MNL_CB_ERROR; + if (ctx->desc) + snprintf(ctx->desc->station_name.text, UALOE_LABEL_SIZE, "%s", + (char*)mnl_attr_get_str(attr)); + break; + case CFG_ATTR_NETPORT_TOTAL_COUNT: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + ctx->total_count = mnl_attr_get_u32(attr); + break; + default: + break; } + return MNL_CB_OK; +} - i = 0; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - ifoe_netport_desc_t* desc = i < desc_count ? &descs[i] : NULL; +static int ifoe_nl_get_netport_list_v2_handler(const struct nlmsghdr* nlh, void* data) { + struct netport_list_v2_ctx* ctx = data; + int rc; - rc = - mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, ifoe_nl_get_netport_list_handler, desc); - if (rc <= MNL_CB_STOP) break; - i++; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); + ctx->desc = ctx->received < ctx->max_count ? &ctx->descs[ctx->received] : NULL; + rc = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ifoe_nl_parse_netport_desc_v2, ctx); + if (rc > MNL_CB_STOP) ctx->received++; + return rc; +} + +int ifoe_nl_get_netport_list_v2(ualoe_handle_t handle, unsigned* desc_count, + ifoe_netport_desc_t descs[]) { + struct netport_list_v2_ctx ctx = { + .descs = descs, + .max_count = *desc_count, + }; + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + /* Omit CFG_ATTR_DESC_COUNT so the driver returns all configured + * netports and includes CFG_ATTR_NETPORT_TOTAL_COUNT in responses. + */ + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_GET_NETPORT_LIST, nl_handle->family_id, + 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + + rc = ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ifoe_nl_get_netport_list_v2_handler, + &ctx); + if (rc) return rc; + + if (ctx.total_count && ctx.received != ctx.total_count) { + ualoe_log_error("Expected %u netports but received %u\n", ctx.total_count, ctx.received); + return EIO; } - if (rc == -1) return errno; - if (i != desc_count) return ERANGE; - return 0; + *desc_count = ctx.received; + + return ctx.received > ctx.max_count ? ENOSPC : 0; } int ifoe_nl_netport_ctrl(ualoe_handle_t handle, unsigned netport_idx, ifoe_netport_state_e state) { @@ -1593,21 +1433,7 @@ int ifoe_nl_netport_ctrl(ualoe_handle_t handle, unsigned netport_idx, ifoe_netpo mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOGICAL_IDX, netport_idx); mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_STATE, state); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } int ifoe_nl_netport_config_link_auto(ualoe_handle_t handle, unsigned netport_idx, @@ -1634,21 +1460,7 @@ int ifoe_nl_netport_config_link_auto(ualoe_handle_t handle, unsigned netport_idx return ENOMEM; } - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } int ifoe_nl_netport_config_link_manual(ualoe_handle_t handle, unsigned netport_idx, @@ -1671,21 +1483,7 @@ int ifoe_nl_netport_config_link_manual(ualoe_handle_t handle, unsigned netport_i mnl_attr_put_u8(nlh, CFG_ATTR_NETPORT_FEC_MODE, fec_mode); mnl_attr_put_u8(nlh, CFG_ATTR_NETPORT_LOOPBACK_MODE, loopback_mode); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } _Static_assert((sizeof(ifoe_accelerator_addr_map_t) == @@ -1711,7 +1509,7 @@ _Static_assert((sizeof(ifoe_accelerator_addr_map_t) == #define NETPORT_SET_ACCELERATOR_ADDR_MAP_U32_ATTRS 25 #define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define NETPORT_SET_ACCELERATOR_ADDR_MAP_BUF_SIZE \ +#define NETPORT_ACCELERATOR_ADDR_MAP_BUF_SIZE \ MAX(MNL_SOCKET_BUFFER_SIZE, MNL_NLMSG_HDRLEN + \ NETPORT_SET_ACCELERATOR_ADDR_MAP_U32_ATTRS * sizeof(uint32_t) + \ UALOE_MAX_ACCELERATORS * sizeof(ifoe_accelerator_addr_map_t)) @@ -1738,7 +1536,7 @@ int ifoe_nl_netport_set_accelerator_addr_map(ualoe_handle_t handle, unsigned net ifoe_accelerator_addr_map_t map[]) { struct ualoe_nl_handle* nl_handle; enum cfg_network_addr_type cfg_map_addr_type; - char buf[NETPORT_SET_ACCELERATOR_ADDR_MAP_BUF_SIZE]; + char buf[NETPORT_ACCELERATOR_ADDR_MAP_BUF_SIZE]; struct genlmsghdr* genlh; struct nlmsghdr* nlh; int rc; @@ -1763,21 +1561,70 @@ int ifoe_nl_netport_set_accelerator_addr_map(ualoe_handle_t handle, unsigned net return ENOMEM; } - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); +} - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); +struct get_accelerator_addr_map_cb_ctx { + unsigned map_count; + ifoe_accelerator_addr_map_t* map; +}; + +static int ifoe_nl_parse_netport_accel_addr_map(const struct nlattr* attr, void* data) { + struct get_accelerator_addr_map_cb_ctx* cb_ctx = data; + + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_NETPORT_ACCELERATOR_ADDR_MAP: + if (mnl_attr_get_payload_len(attr) != + cb_ctx->map_count * sizeof(ifoe_accelerator_addr_map_t)) { + errno = ERANGE; + return MNL_CB_ERROR; + } + memcpy(cb_ctx->map, mnl_attr_get_payload(attr), + cb_ctx->map_count * sizeof(ifoe_accelerator_addr_map_t)); + break; + case CFG_ATTR_DESC_COUNT: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + if (mnl_attr_get_u32(attr) != cb_ctx->map_count) { + errno = ERANGE; + return MNL_CB_ERROR; + } + break; + default: + errno = EINVAL; + return MNL_CB_ERROR; } + return MNL_CB_OK; +} - if (rc == -1) return errno; - return 0; +static int ifoe_nl_get_accel_addr_map_cb(const struct nlmsghdr* nlh, void* data) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ifoe_nl_parse_netport_accel_addr_map, data); +} + +int ifoe_nl_netport_get_accelerator_addr_map(ualoe_handle_t handle, unsigned netport_idx, + unsigned map_count, + ifoe_accelerator_addr_map_t map[]) { + char buf[NETPORT_ACCELERATOR_ADDR_MAP_BUF_SIZE]; + struct ualoe_nl_handle* nl_handle; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_NETPORT_GET_ACCELERATOR_ADDR_MAP, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOGICAL_IDX, netport_idx); + mnl_attr_put_u32(nlh, CFG_ATTR_DESC_COUNT, map_count); + + struct get_accelerator_addr_map_cb_ctx cb_ctx = { + .map_count = map_count, + .map = map, + }; + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ifoe_nl_get_accel_addr_map_cb, + &cb_ctx); } int ifoe_nl_netport_set_addr(ualoe_handle_t handle, unsigned netport_idx, @@ -1807,21 +1654,7 @@ int ifoe_nl_netport_set_addr(ualoe_handle_t handle, unsigned netport_idx, mnl_attr_put(nlh, CFG_ATTR_NETPORT_IFOE_MAC_ADDR, UALOE_MAC_ADDRESS_SIZE, mac_addr); } mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_IFOE_IP_ADDR, ip_addr); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, NULL, NULL); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); } static int ifoe_nl_parse_netport_state(const struct nlattr* attr, void* data) { @@ -1888,62 +1721,531 @@ int ifoe_nl_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, 1); mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOGICAL_IDX, netport_idx); - if (mnl_socket_sendto(nl_handle->sk, buf, nlh->nlmsg_len) < 0) { - rc = errno; - ualoe_log_error("Failed to send message rc=%d\n", rc); - return rc; - } - - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - while (rc > 0) { - rc = mnl_cb_run(buf, rc, nlh->nlmsg_seq, nlh->nlmsg_pid, ualoe_nl_netport_state_handler, state); - if (rc <= MNL_CB_STOP) break; - rc = mnl_socket_recvfrom(nl_handle->sk, buf, sizeof(buf)); - } - - if (rc == -1) return errno; - return 0; + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_netport_state_handler, + state); } -int ualoe_nl_telemetry_alloc(ualoe_handle_t handle, unsigned category_mask, - ualoe_telemetry_t** telemetry) { - struct ualoe_nl_handle* nl_handle; - int rc; - - rc = ualoe_nl_find_handle(handle, &nl_handle); - if (rc) return rc; +static int ifoe_nl_parse_ifcp_netport_state(const struct nlattr* attr, void* data) { + ifoe_ifcp_netport_state_t* state = data; - return ualoe_cdev_telemetry_alloc(nl_handle->cdev_fd, category_mask, telemetry); + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_IFCP_LOCAL_PORT_ID: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + state->local_port_id = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_IFCP_LOCAL_LINK_UP: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + state->local_link_up = mnl_attr_get_u8(attr); + break; + case CFG_ATTR_IFCP_LOCAL_IN_ERROR: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + state->local_in_error = mnl_attr_get_u8(attr); + break; + case CFG_ATTR_IFCP_LOCAL_LL_UP: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + state->local_ll_up = mnl_attr_get_u8(attr); + break; + case CFG_ATTR_IFCP_LOCAL_MAC_ADDR: + if (mnl_attr_get_payload_len(attr) != UALOE_MAC_ADDRESS_SIZE) { + errno = ERANGE; + return MNL_CB_ERROR; + } + memcpy(state->local_mac_addr, mnl_attr_get_payload(attr), UALOE_MAC_ADDRESS_SIZE); + break; + case CFG_ATTR_IFCP_PEER_DEVICE_ID: + if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) return MNL_CB_ERROR; + state->peer_device_id = mnl_attr_get_u64(attr); + break; + case CFG_ATTR_IFCP_PEER_PORT_ID: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + state->peer_port_id = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_IFCP_PEER_ENABLED: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + state->peer_enabled = mnl_attr_get_u8(attr); + break; + case CFG_ATTR_IFCP_PEER_IN_ERROR: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + state->peer_in_error = mnl_attr_get_u8(attr); + break; + case CFG_ATTR_IFCP_PEER_ENCRYPT_MODE: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + state->peer_encrypt_mode = (ualoe_crypto_mode_e)mnl_attr_get_u8(attr); + break; + case CFG_ATTR_IFCP_PEER_MAC_ADDR: + if (mnl_attr_get_payload_len(attr) != UALOE_MAC_ADDRESS_SIZE) { + errno = ERANGE; + return MNL_CB_ERROR; + } + memcpy(state->peer_mac_addr, mnl_attr_get_payload(attr), UALOE_MAC_ADDRESS_SIZE); + break; + case CFG_ATTR_IFCP_PEER_MTU: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + state->peer_mtu = mnl_attr_get_u32(attr); + break; + default: + errno = EINVAL; + return MNL_CB_ERROR; + } + return MNL_CB_OK; } -int ualoe_nl_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry) { - struct ualoe_nl_handle* nl_handle; - int rc; - - rc = ualoe_nl_find_handle(handle, &nl_handle); - if (rc) return rc; - - return ualoe_cdev_telemetry_get(nl_handle->cdev_fd, telemetry); +static int ualoe_nl_ifcp_netport_state_handler(const struct nlmsghdr* nlh, void* data) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ifoe_nl_parse_ifcp_netport_state, data); } -int ualoe_nl_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetry) { +int ifoe_nl_ifcp_netport_get_state(ualoe_handle_t handle, unsigned netport_idx, + ifoe_ifcp_netport_state_t* state) { struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; int rc; rc = ualoe_nl_find_handle(handle, &nl_handle); if (rc) return rc; - return ualoe_cdev_telemetry_free(nl_handle->cdev_fd, telemetry); + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_IFCP_GET_NETPORT_STATE, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOGICAL_IDX, netport_idx); + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_ifcp_netport_state_handler, + state); } -int ualoe_nl_l2ping_start(ualoe_handle_t handle, ualoe_ping_spec_t* spec, ualoe_ping_t** ping) { - struct ualoe_nl_handle* nl_handle; +static int ifoe_nl_parse_ifcp_netport_stats(const struct nlattr* attr, void* data) { + ifoe_ifcp_netport_stats_t* stats = data; + + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_IFCP_STATS_RX_COUNT: + if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) return MNL_CB_ERROR; + stats->rx_count = mnl_attr_get_u64(attr); + break; + case CFG_ATTR_IFCP_STATS_TX_COUNT: + if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) return MNL_CB_ERROR; + stats->tx_count = mnl_attr_get_u64(attr); + break; + case CFG_ATTR_IFCP_STATS_TX_ERRORS: + if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) return MNL_CB_ERROR; + stats->tx_errors = mnl_attr_get_u64(attr); + break; + case CFG_ATTR_IFCP_STATS_RX_DROPPED: + if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) return MNL_CB_ERROR; + stats->rx_dropped = mnl_attr_get_u64(attr); + break; + default: + errno = EINVAL; + return MNL_CB_ERROR; + } + return MNL_CB_OK; +} + +static int ualoe_nl_ifcp_netport_stats_handler(const struct nlmsghdr* nlh, void* data) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ifoe_nl_parse_ifcp_netport_stats, data); +} + +int ifoe_nl_ifcp_netport_get_stats(ualoe_handle_t handle, unsigned netport_idx, + ifoe_ifcp_netport_stats_t* stats) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_IFCP_GET_NETPORT_STATS, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOGICAL_IDX, netport_idx); + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_ifcp_netport_stats_handler, + stats); +} + +static int ualoe_nl_parse_scaleup_fabric_config(const struct nlattr* attr, void* arg) { + ualoe_scaleup_fabric_config_t* config = arg; + unsigned payload_len, count; + + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_SCALEUP_PHYSICAL_POD_ID: + if (mnl_attr_get_payload_len(attr) != UALOE_SCALEUP_FABRIC_POD_ID_SIZE) { + errno = ERANGE; + return MNL_CB_ERROR; + } + memcpy(config->physical_pod_id, mnl_attr_get_payload(attr), UALOE_SCALEUP_FABRIC_POD_ID_SIZE); + break; + case CFG_ATTR_SCALEUP_PHYSICAL_POD_SIZE: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + config->physical_pod_size = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_SCALEUP_LOCAL_ACCELERATORS: + payload_len = mnl_attr_get_payload_len(attr); + if (payload_len % sizeof(uint32_t) != 0) { + errno = ERANGE; + return MNL_CB_ERROR; + } + count = payload_len / sizeof(uint32_t); + if (count > UALOE_SCALEUP_FABRIC_MAX_LOCAL_ACCELERATORS) { + errno = ERANGE; + return MNL_CB_ERROR; + } + memcpy(config->local_accelerators, mnl_attr_get_payload(attr), payload_len); + config->num_local_accelerators = count; + break; + default: + break; + } + return MNL_CB_OK; +} + +static int ualoe_nl_get_scaleup_fabric_config_handler(const struct nlmsghdr* nlh, void* arg) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_parse_scaleup_fabric_config, arg); +} + +int ualoe_nl_get_scaleup_fabric_config(ualoe_handle_t handle, + ualoe_scaleup_fabric_config_t* config) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_GET_SCALEUP_FABRIC_CONFIG, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, + ualoe_nl_get_scaleup_fabric_config_handler, config); +} + +int ualoe_nl_set_scaleup_fabric_config(ualoe_handle_t handle, + const ualoe_scaleup_fabric_config_t* config) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_SET_SCALEUP_FABRIC_CONFIG, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + if (!mnl_attr_put_check(nlh, sizeof(buf), CFG_ATTR_SCALEUP_PHYSICAL_POD_ID, + sizeof(config->physical_pod_id), config->physical_pod_id)) { + ualoe_log_error("%s: Failed to put physical_pod_id to buffer\n", __func__); + return ENOMEM; + } + mnl_attr_put_u32(nlh, CFG_ATTR_SCALEUP_PHYSICAL_POD_SIZE, config->physical_pod_size); + if (!mnl_attr_put_check(nlh, sizeof(buf), CFG_ATTR_SCALEUP_LOCAL_ACCELERATORS, + config->num_local_accelerators * sizeof(uint32_t), + config->local_accelerators)) { + ualoe_log_error("%s: Failed to put local_accelerators to buffer\n", __func__); + return ENOMEM; + } + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); +} + +int ualoe_nl_set_scaleup_fabric_vpod_config(ualoe_handle_t handle, + const ualoe_scaleup_fabric_vpod_config_t* config) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_SET_SCALEUP_FABRIC_VPOD_CONFIG, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + mnl_attr_put_u32(nlh, CFG_ATTR_SCALEUP_VIRTUAL_POD_ID, config->virtual_pod_id); + mnl_attr_put_u32(nlh, CFG_ATTR_SCALEUP_NPA_ADDRESS_MODE, config->npa_address_mode); + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); +} + +int ualoe_nl_set_scaleup_fabric_station_info(ualoe_handle_t handle, + const ualoe_scaleup_fabric_station_info_t* info) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_SET_SCALEUP_FABRIC_STATION_INFO, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + mnl_attr_put_u32(nlh, CFG_ATTR_SCALEUP_STATION_COUNT, info->num_stations); + if (!mnl_attr_put_check(nlh, sizeof(buf), CFG_ATTR_SCALEUP_STATION_BANDWIDTH, info->num_stations, + info->station_bandwidth)) { + ualoe_log_error("%s: Failed to put station_bandwidth to buffer\n", __func__); + return ENOMEM; + } + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); +} + +static int ualoe_nl_parse_scaleup_fabric_vpod_config(const struct nlattr* attr, void* arg) { + ualoe_scaleup_fabric_vpod_config_t* config = arg; + + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_SCALEUP_VIRTUAL_POD_ID: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + config->virtual_pod_id = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_SCALEUP_NPA_ADDRESS_MODE: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + config->npa_address_mode = mnl_attr_get_u32(attr); + break; + default: + break; + } + return MNL_CB_OK; +} + +static int ualoe_nl_get_scaleup_fabric_vpod_config_handler(const struct nlmsghdr* nlh, void* arg) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_parse_scaleup_fabric_vpod_config, + arg); +} + +int ualoe_nl_get_scaleup_fabric_vpod_config(ualoe_handle_t handle, + ualoe_scaleup_fabric_vpod_config_t* config) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_GET_SCALEUP_FABRIC_VPOD_CONFIG, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, + ualoe_nl_get_scaleup_fabric_vpod_config_handler, config); +} + +struct ualoe_nl_scaleup_station_ctx { + ualoe_scaleup_fabric_station_info_t* info; + uint32_t reported_count; + unsigned bandwidth_len; +}; + +static int ualoe_nl_parse_scaleup_fabric_station_info(const struct nlattr* attr, void* arg) { + struct ualoe_nl_scaleup_station_ctx* ctx = arg; + + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_SCALEUP_STATION_COUNT: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + ctx->reported_count = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_SCALEUP_STATION_BANDWIDTH: + ctx->bandwidth_len = mnl_attr_get_payload_len(attr); + if (ctx->bandwidth_len > sizeof(ctx->info->station_bandwidth)) { + errno = ERANGE; + return MNL_CB_ERROR; + } + memcpy(ctx->info->station_bandwidth, mnl_attr_get_payload(attr), ctx->bandwidth_len); + break; + default: + break; + } + return MNL_CB_OK; +} + +static int ualoe_nl_get_scaleup_fabric_station_info_handler(const struct nlmsghdr* nlh, void* arg) { + struct ualoe_nl_scaleup_station_ctx* ctx = arg; + + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_parse_scaleup_fabric_station_info, + ctx); +} + +int ualoe_nl_get_scaleup_fabric_station_info(ualoe_handle_t handle, + ualoe_scaleup_fabric_station_info_t* info) { + struct ualoe_nl_scaleup_station_ctx ctx = { + .info = info, + .reported_count = 0, + .bandwidth_len = 0, + }; + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_GET_SCALEUP_FABRIC_STATION_INFO, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + + rc = ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, + ualoe_nl_get_scaleup_fabric_station_info_handler, &ctx); + if (rc) return rc; + + /* Enforce the invariant that the reported station count equals the + * bandwidth payload length in bytes (one byte per station); a response + * that violates it is rejected. An all-zero result (no stations) is a + * valid empty set. + */ + if (ctx.reported_count != ctx.bandwidth_len) return EINVAL; + + info->num_stations = ctx.reported_count; + return 0; +} + +static int ualoe_nl_parse_gpu_identity(const struct nlattr* attr, void* arg) { + ualoe_gpu_identity_t* identity = arg; + + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_GPU_PHYS_ID: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + identity->phys_id = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_GPU_NUM_GPUS: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + identity->num_gpus = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_GPU_TRAY_TYPE: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + identity->tray_type = mnl_attr_get_u32(attr); + break; + case CFG_ATTR_GPU_OAM_ID: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + identity->oam_id = mnl_attr_get_u32(attr); + break; + default: + break; + } + return MNL_CB_OK; +} + +static int ualoe_nl_get_gpu_identity_handler(const struct nlmsghdr* nlh, void* arg) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_parse_gpu_identity, arg); +} + +int ualoe_nl_get_gpu_identity(ualoe_handle_t handle, ualoe_gpu_identity_t* identity) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; int rc; rc = ualoe_nl_find_handle(handle, &nl_handle); if (rc) return rc; - return ualoe_cdev_l2ping_start(nl_handle->cdev_fd, spec, ping); + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_GET_GPU_IDENTITY, nl_handle->family_id, + 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_get_gpu_identity_handler, + identity); +} + +static int ualoe_nl_parse_telemetry_category_mask(const struct nlattr* attr, void* arg) { + unsigned* category_mask = arg; + + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_CATEGORY_MASK: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) return MNL_CB_ERROR; + *category_mask = mnl_attr_get_u32(attr); + break; + default: + break; + } + return MNL_CB_OK; +} + +static int ualoe_nl_telemetry_get_category_mask_handler(const struct nlmsghdr* nlh, void* arg) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_parse_telemetry_category_mask, + arg); +} + +int ualoe_nl_telemetry_get_category_mask(ualoe_handle_t handle, unsigned* category_mask) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + *category_mask = 0; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_GET_TELEMETRY_CATEGORY_MASK, + nl_handle->family_id, 1); + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, + ualoe_nl_telemetry_get_category_mask_handler, category_mask); +} + +int ualoe_nl_telemetry_alloc(ualoe_handle_t handle, unsigned category_mask, + ualoe_telemetry_t** telemetry) { + struct ualoe_nl_handle* nl_handle; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + pthread_mutex_lock(&nl_handle->request_lock); + rc = ualoe_cdev_telemetry_alloc(nl_handle->cdev_fd, category_mask, telemetry); + pthread_mutex_unlock(&nl_handle->request_lock); + return rc; +} + +int ualoe_nl_telemetry_get(ualoe_handle_t handle, ualoe_telemetry_t* telemetry) { + struct ualoe_nl_handle* nl_handle; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + pthread_mutex_lock(&nl_handle->request_lock); + rc = ualoe_cdev_telemetry_get(nl_handle->cdev_fd, telemetry); + pthread_mutex_unlock(&nl_handle->request_lock); + return rc; +} + +int ualoe_nl_telemetry_free(ualoe_handle_t handle, ualoe_telemetry_t* telemetry) { + struct ualoe_nl_handle* nl_handle; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + pthread_mutex_lock(&nl_handle->request_lock); + rc = ualoe_cdev_telemetry_free(nl_handle->cdev_fd, telemetry); + pthread_mutex_unlock(&nl_handle->request_lock); + return rc; +} + +int ualoe_nl_l2ping_start(ualoe_handle_t handle, ualoe_ping_spec_t* spec, ualoe_ping_t** ping) { + struct ualoe_nl_handle* nl_handle; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + pthread_mutex_lock(&nl_handle->request_lock); + rc = ualoe_cdev_l2ping_start(nl_handle->cdev_fd, spec, ping); + pthread_mutex_unlock(&nl_handle->request_lock); + return rc; } int ualoe_nl_l2ping_update(ualoe_handle_t handle, ualoe_ping_t* ping) { @@ -1953,7 +2255,10 @@ int ualoe_nl_l2ping_update(ualoe_handle_t handle, ualoe_ping_t* ping) { rc = ualoe_nl_find_handle(handle, &nl_handle); if (rc) return rc; - return ualoe_cdev_l2ping_update(nl_handle->cdev_fd, ping); + pthread_mutex_lock(&nl_handle->request_lock); + rc = ualoe_cdev_l2ping_update(nl_handle->cdev_fd, ping); + pthread_mutex_unlock(&nl_handle->request_lock); + return rc; } int ualoe_nl_l2ping_fini(ualoe_handle_t handle, ualoe_ping_t* ping) { @@ -1963,7 +2268,10 @@ int ualoe_nl_l2ping_fini(ualoe_handle_t handle, ualoe_ping_t* ping) { rc = ualoe_nl_find_handle(handle, &nl_handle); if (rc) return rc; - return ualoe_cdev_l2ping_fini(nl_handle->cdev_fd, ping); + pthread_mutex_lock(&nl_handle->request_lock); + rc = ualoe_cdev_l2ping_fini(nl_handle->cdev_fd, ping); + pthread_mutex_unlock(&nl_handle->request_lock); + return rc; } int ualoe_nl_register_event_callback(ualoe_handle_t handle, ualoe_event_callback_t callback, @@ -1974,5 +2282,168 @@ int ualoe_nl_register_event_callback(ualoe_handle_t handle, ualoe_event_callback rc = ualoe_nl_find_handle(handle, &nl_handle); if (rc) return rc; - return ualoe_cb_init(handle, nl_handle->dev_id, callback, user_context); + return ualoe_cb_init(handle, nl_handle->dev_id, nl_handle->cdev_fd, callback, user_context); +} + +/*---------- PMA lane and PRBS diagnostic netlink functions ----------*/ + +int ualoe_nl_diag_config_pma_lane(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, + bool enable, ualoe_pma_rate_e pma_rate, + ualoe_netport_loopback_mode_e loopback_mode, + ualoe_pma_polarity_e tx_polarity, + ualoe_pma_polarity_e rx_polarity) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_DIAG_CONFIG_PMA_LANE, + nl_handle->family_id, 1); + + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOGICAL_IDX, netport_idx); + mnl_attr_put_u32(nlh, CFG_ATTR_LANE_IDX, lane_idx); + mnl_attr_put_u8(nlh, CFG_ATTR_ENABLE, (uint8_t)enable); + mnl_attr_put_u32(nlh, CFG_ATTR_PMA_RATE, (uint32_t)pma_rate); + mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOOPBACK_MODE, (uint32_t)loopback_mode); + mnl_attr_put_u32(nlh, CFG_ATTR_TX_POLARITY, (uint32_t)tx_polarity); + mnl_attr_put_u32(nlh, CFG_ATTR_RX_POLARITY, (uint32_t)rx_polarity); + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); +} + +int ualoe_nl_diag_config_prbs_tx(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, + bool enable, ualoe_prbs_pattern_e pattern, + __uint128_t user_pattern) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_DIAG_CONFIG_PRBS_TX, nl_handle->family_id, + 1); + + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOGICAL_IDX, netport_idx); + mnl_attr_put_u32(nlh, CFG_ATTR_LANE_IDX, lane_idx); + mnl_attr_put_u8(nlh, CFG_ATTR_ENABLE, (uint8_t)enable); + mnl_attr_put_u32(nlh, CFG_ATTR_PRBS_PATTERN, (uint32_t)pattern); + if (!mnl_attr_put_check(nlh, sizeof(buf), CFG_ATTR_USER_PATTERN, sizeof(user_pattern), + &user_pattern)) { + ualoe_log_error("%s: Failed to put user_pattern to buffer\n", __func__); + return ENOMEM; + } + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); +} + +int ualoe_nl_diag_config_prbs_rx(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, + bool enable, bool resync, ualoe_prbs_pattern_e pattern, + __uint128_t user_pattern) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_DIAG_CONFIG_PRBS_RX, nl_handle->family_id, + 1); + + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOGICAL_IDX, netport_idx); + mnl_attr_put_u32(nlh, CFG_ATTR_LANE_IDX, lane_idx); + mnl_attr_put_u8(nlh, CFG_ATTR_ENABLE, (uint8_t)enable); + mnl_attr_put_u8(nlh, CFG_ATTR_RESYNC, (uint8_t)resync); + mnl_attr_put_u32(nlh, CFG_ATTR_PRBS_PATTERN, (uint32_t)pattern); + if (!mnl_attr_put_check(nlh, sizeof(buf), CFG_ATTR_USER_PATTERN, sizeof(user_pattern), + &user_pattern)) { + ualoe_log_error("%s: Failed to put user_pattern to buffer\n", __func__); + return ENOMEM; + } + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, NULL, NULL); +} + +static int ualoe_nl_parse_prbs_results_nested(const struct nlattr* attr, void* arg) { + ualoe_prbs_results_t* results = arg; + uint64_t elapsed_us; + + switch (mnl_attr_get_type(attr)) { + case CFG_ATTR_PRBS_RESULTS_VALID: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + results->valid = !!mnl_attr_get_u8(attr); + break; + case CFG_ATTR_PRBS_RESULTS_RXEQ_SUCCESS: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + results->rxeq_success = !!mnl_attr_get_u8(attr); + break; + case CFG_ATTR_PRBS_RESULTS_CDR_LOCK: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + results->cdr_lock = !!mnl_attr_get_u8(attr); + break; + case CFG_ATTR_PRBS_RESULTS_PATTERN_LOCK: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + results->pattern_lock = !!mnl_attr_get_u8(attr); + break; + case CFG_ATTR_PRBS_RESULTS_OVERFLOW: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) return MNL_CB_ERROR; + results->overflow = !!mnl_attr_get_u8(attr); + break; + case CFG_ATTR_PRBS_RESULTS_ELAPSED_US: + if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) return MNL_CB_ERROR; + elapsed_us = mnl_attr_get_u64(attr); + results->interval.tv_sec = (time_t)(elapsed_us / 1000000ULL); + results->interval.tv_nsec = (long)((elapsed_us % 1000000ULL) * 1000ULL); + break; + case CFG_ATTR_PRBS_RESULTS_ERROR_COUNT: + if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) return MNL_CB_ERROR; + results->error_count = mnl_attr_get_u64(attr); + break; + default: + break; + } + return MNL_CB_OK; +} + +static int ualoe_nl_parse_prbs_results(const struct nlattr* attr, void* arg) { + if (mnl_attr_get_type(attr) == CFG_ATTR_PRBS_RESULTS) + return mnl_attr_parse_nested(attr, ualoe_nl_parse_prbs_results_nested, arg); + return MNL_CB_OK; +} + +static int ualoe_nl_get_prbs_results_handler(const struct nlmsghdr* nlh, void* arg) { + return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), ualoe_nl_parse_prbs_results, arg); +} + +int ualoe_nl_diag_get_prbs_results(ualoe_handle_t handle, unsigned netport_idx, unsigned lane_idx, + ualoe_prbs_results_t* results) { + struct ualoe_nl_handle* nl_handle; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct genlmsghdr* genlh; + struct nlmsghdr* nlh; + int rc; + + rc = ualoe_nl_find_handle(handle, &nl_handle); + if (rc) return rc; + + ualoe_nl_init_msg(nl_handle, &nlh, &genlh, buf, CFG_CMD_DIAG_GET_PRBS_RESULTS, + nl_handle->family_id, 1); + + mnl_attr_put_u32(nlh, CFG_ATTR_DEV_ID, nl_handle->dev_id); + mnl_attr_put_u32(nlh, CFG_ATTR_NETPORT_LOGICAL_IDX, netport_idx); + mnl_attr_put_u32(nlh, CFG_ATTR_LANE_IDX, lane_idx); + + return ualoe_nl_send_recv(nl_handle, buf, sizeof(buf), nlh, ualoe_nl_get_prbs_results_handler, + results); } diff --git a/projects/amdsmi/src/ualoe_lib/ualoe_telem.c b/projects/amdsmi/src/ualoe_lib/ualoe_telem.c new file mode 100644 index 000000000000..586c5d569698 --- /dev/null +++ b/projects/amdsmi/src/ualoe_lib/ualoe_telem.c @@ -0,0 +1,425 @@ +/* + * Copyright (c) Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "ualoe_telem.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ifoe_telemetry.h" +#include "telemetry_dataset.h" +#include "ualoe_log.h" + +_Static_assert((int)CFG_TELEMETRY_CATEGORY_MAX >= (int)TELEMETRY_SRC_CATEGORY_COUNT, + "CFG_TELEMETRY_CATEGORY_MAX must be >= TELEMETRY_SRC_CATEGORY_COUNT"); + +#define EXTRACT_FIELD(value, field) (((value) >> field##_LBN) & ((1ULL << field##_WIDTH) - 1)) + +/* + * Overflow-safe bounds check: returns true if [_start, _start + _len) + * exceeds _buf_size. All arguments must be integer quantities (offsets + * or sizes), never pointers. + */ +#ifdef __GNUC__ +#define CHECK_BOUNDS(_start, _len, _buf_size) \ + ({ \ + size_t _end; \ + __builtin_add_overflow((size_t)(_start), (size_t)(_len), &_end) || _end > (_buf_size); \ + }) +#else +#define CHECK_BOUNDS(_start, _len, _buf_size) \ + ((size_t)(_len) > (_buf_size) || (size_t)(_start) > (_buf_size) - (size_t)(_len)) +#endif + +#define TELEM_TAG_ID(id) ((uint64_t)(id) << IFOE_TELEM_TAG_TAG_ID_LBN) + +struct telem_regions { + const char* const_base; + const char* const_end; + const char* dyn_base; + const char* dyn_end; + long page_size; +}; + +long ualoe_get_page_size(void) { + static long page_size; + + if (!page_size) { + page_size = sysconf(_SC_PAGESIZE); + if (page_size <= 0) page_size = 4096; + } + + return page_size; +} + +static void set_instance_ids(ualoe_telemetry_instance_t* instance, uint64_t tlv_tag, + bool netport_based, uint32_t netports_per_station) { + uint32_t station_idx; + + station_idx = EXTRACT_FIELD(tlv_tag, IFOE_TELEM_TAG_STATION_IDX); + + if (!netport_based) { + instance->logical_idx = station_idx; + snprintf(instance->name.text, sizeof(instance->name.text), CFG_STATION_LABEL_FMT, station_idx); + } else { + uint32_t netport_rel_idx; + uint32_t netport_logical_idx; + + netport_rel_idx = EXTRACT_FIELD(tlv_tag, IFOE_TELEM_TAG_NETPORT_REL_IDX); + netport_logical_idx = + CFG_NETPORT_LOGICAL_IDX(station_idx, netports_per_station, netport_rel_idx); + + instance->logical_idx = netport_logical_idx; + snprintf(instance->name.text, sizeof(instance->name.text), CFG_NETPORT_LABEL_FMT, + netport_logical_idx); + } +} + +static const ifoe_telem_tlv_data_t* tlv_next(const ifoe_telem_tlv_data_t* data, const char* end) { + size_t remaining, advance; + + remaining = (size_t)(end - (const char*)data); + if (ADD_OVERFLOW(sizeof(ifoe_telem_tlv_t), (size_t)data->tlv.len, &advance)) return NULL; + if (advance > remaining || remaining - advance < sizeof(ifoe_telem_tlv_t)) return NULL; + + return (const ifoe_telem_tlv_data_t*)((const char*)data + advance); +} + +static int ualoe_telem_parse_snapshot_hdr(const void* mmap_buf, size_t buf_size, + struct telem_regions* rgn) { + const struct cfg_telem_snapshot_hdr* snap_hdr; + + if (buf_size < sizeof(struct cfg_telem_snapshot_hdr)) { + ualoe_log_error("telemetry_parse: buffer too small for snapshot header\n"); + return EIO; + } + + snap_hdr = (const struct cfg_telem_snapshot_hdr*)mmap_buf; + + if (CHECK_BOUNDS(snap_hdr->const_offset, snap_hdr->const_size, buf_size) || + CHECK_BOUNDS(snap_hdr->dyn_offset, snap_hdr->dyn_size, buf_size)) { + ualoe_log_error("telemetry_parse: snapshot header offsets exceed buffer\n"); + return EIO; + } + + rgn->const_base = (const char*)mmap_buf + snap_hdr->const_offset; + rgn->const_end = rgn->const_base + snap_hdr->const_size; + rgn->dyn_base = (const char*)mmap_buf + snap_hdr->dyn_offset; + rgn->dyn_end = rgn->dyn_base + snap_hdr->dyn_size; + + return 0; +} + +static int ualoe_telem_validate_hdr(const struct telem_regions* rgn, + const ifoe_telem_tlv_hdr_t** hdr) { + *hdr = (const ifoe_telem_tlv_hdr_t*)(rgn->const_base + rgn->page_size); + + if ((const char*)(*hdr) + sizeof(**hdr) > rgn->const_end) { + ualoe_log_error("telemetry_parse: header TLV outside const region\n"); + return EIO; + } + + if ((*hdr)->magic != IFOE_TELEM_TLV_HDR_MAGIC_VALUE || + (*hdr)->tlv.tag != TELEM_TAG_ID(IFOE_TELEM_TAG_HEADER)) { + ualoe_log_error("telemetry_parse: invalid header TLV magic or tag\n"); + return EIO; + } + + return 0; +} + +static int ualoe_telem_validate_locators(const ifoe_telem_tlv_hdr_t* hdr, const char* const_end, + const ifoe_telem_tlv_desc_locator_t** desc_locator, + const ifoe_telem_tlv_dataset_locator_t** dataset_locator) { + size_t remaining, advance; + + *desc_locator = + (const ifoe_telem_tlv_desc_locator_t*)((const char*)hdr + sizeof(ifoe_telem_tlv_hdr_t)); + + if ((const char*)(*desc_locator) + sizeof(**desc_locator) > const_end) { + ualoe_log_error("telemetry_parse: desc_locator outside const region\n"); + return EIO; + } + + if ((*desc_locator)->tlv.tag != TELEM_TAG_ID(IFOE_TELEM_TAG_DESC_LOCATOR)) { + ualoe_log_error("telemetry_parse: invalid desc_locator tag\n"); + return EIO; + } + + remaining = (size_t)(const_end - (const char*)(*desc_locator)); + if (ADD_OVERFLOW(sizeof(ifoe_telem_tlv_t), (size_t)(*desc_locator)->tlv.len, &advance) || + advance > remaining || remaining - advance < sizeof(ifoe_telem_tlv_t)) { + ualoe_log_error("telemetry_parse: dataset_locator outside const region\n"); + return EIO; + } + *dataset_locator = + (const ifoe_telem_tlv_dataset_locator_t*)((const char*)(*desc_locator) + advance); + + if ((*dataset_locator)->tlv.tag != TELEM_TAG_ID(IFOE_TELEM_TAG_DATASET_LOCATOR)) { + ualoe_log_error("telemetry_parse: invalid dataset_locator tag\n"); + return EIO; + } + + return 0; +} + +static int count_data_tlvs(const struct telem_regions* rgn, + const ifoe_telem_tlv_dataset_hdr_t* data_hdr, unsigned cat, + bool netport_based, unsigned* instance_count, + uint32_t* netports_per_station) { + uint32_t max_netport_rel_idx = 0; + const ifoe_telem_tlv_data_t* data; + unsigned inst_idx = 0; + + data = + (const ifoe_telem_tlv_data_t*)((const char*)data_hdr + sizeof(ifoe_telem_tlv_dataset_hdr_t)); + while (inst_idx < CFG_TELEMETRY_MAX_INSTANCES && + (const char*)data + sizeof(ifoe_telem_tlv_t) <= rgn->dyn_end) { + uint8_t tag_id = EXTRACT_FIELD(data->tlv.tag, IFOE_TELEM_TAG_TAG_ID); + + if (tag_id == IFOE_TELEM_TAG_NULL) { + data = tlv_next(data, rgn->dyn_end); + if (!data) { + ualoe_log_error( + "telemetry_parse: category %u: " + "TLV walk exceeded dyn region in count pass\n", + cat); + return EIO; + } + continue; + } + if (tag_id != IFOE_TELEM_TAG_DATA) break; + if (netport_based) { + uint32_t nri = EXTRACT_FIELD(data->tlv.tag, IFOE_TELEM_TAG_NETPORT_REL_IDX); + if (nri > max_netport_rel_idx) max_netport_rel_idx = nri; + } + inst_idx++; + data = tlv_next(data, rgn->dyn_end); + if (!data) { + ualoe_log_error( + "telemetry_parse: category %u: " + "TLV walk exceeded dyn region in count pass\n", + cat); + return EIO; + } + } + + *instance_count = inst_idx; + *netports_per_station = netport_based ? (max_netport_rel_idx + 1) : 1; + return 0; +} + +static int populate_instances(ualoe_telemetry_dataset_t* dataset, const struct telem_regions* rgn, + const ifoe_telem_tlv_dataset_hdr_t* data_hdr, + const ifoe_telem_tlv_desc_t* desc, unsigned cat, bool netport_based, + unsigned item_count, uint32_t netports_per_station) { + const ifoe_telem_tlv_data_t* data; + unsigned inst_idx; + + data = + (const ifoe_telem_tlv_data_t*)((const char*)data_hdr + sizeof(ifoe_telem_tlv_dataset_hdr_t)); + for (inst_idx = 0; inst_idx < dataset->instance_count; inst_idx++) { + ualoe_telemetry_instance_t* instance; + unsigned int k; + + /* Skip any NULL TLVs between DATA TLVs */ + while ((const char*)data + sizeof(ifoe_telem_tlv_t) <= rgn->dyn_end && + EXTRACT_FIELD(data->tlv.tag, IFOE_TELEM_TAG_TAG_ID) == IFOE_TELEM_TAG_NULL) { + data = tlv_next(data, rgn->dyn_end); + if (!data) { + ualoe_log_error( + "telemetry_parse: category %u: " + "TLV walk exceeded dyn region in data pass\n", + cat); + return EIO; + } + } + + if ((const char*)data + sizeof(ifoe_telem_tlv_t) > rgn->dyn_end || + EXTRACT_FIELD(data->tlv.tag, IFOE_TELEM_TAG_TAG_ID) != IFOE_TELEM_TAG_DATA) { + ualoe_log_error( + "telemetry_parse: category %u: " + "unexpected tag in data pass\n", + cat); + return EIO; + } + + if (data->tlv.len < item_count * sizeof(uint64_t)) { + ualoe_log_error( + "telemetry_parse: category %u: " + "DATA TLV too short for %u items\n", + cat, item_count); + return EIO; + } + + if ((const char*)&data->values[item_count] > rgn->dyn_end) { + ualoe_log_error( + "telemetry_parse: category %u: " + "data values exceed dyn region\n", + cat); + return EIO; + } + + instance = &dataset->instances[inst_idx]; + set_instance_ids(instance, data->tlv.tag, netport_based, netports_per_station); + instance->item_count = item_count; + + for (k = 0; k < IFOE_TELEMETRY_ID_COUNT && k < item_count; k++) { + instance->items[k].id = desc->ids[k]; + instance->items[k].value = data->values[k]; + } + + data = tlv_next(data, rgn->dyn_end); + if (!data && inst_idx + 1 < dataset->instance_count) { + ualoe_log_error( + "telemetry_parse: category %u: " + "TLV walk exceeded dyn region in data pass\n", + cat); + return EIO; + } + } + + return 0; +} + +static int parse_category(const struct telem_regions* rgn, unsigned cat, + const ifoe_telem_tlv_desc_locator_t* desc_locator, + const ifoe_telem_tlv_dataset_locator_t* dataset_locator, + ualoe_telemetry_dataset_t* dataset) { + size_t const_size, dyn_size, offset; + uint32_t netports_per_station; + const ifoe_telem_tlv_dataset_hdr_t* data_hdr; + const ifoe_telem_tlv_desc_t* desc; + unsigned item_count; + bool netport_based; + int rc; + + /* Find desc TLV in const region */ + const_size = (size_t)(rgn->const_end - rgn->const_base); + if (ADD_OVERFLOW((size_t)rgn->page_size, (size_t)desc_locator->descs[cat], &offset) || + offset > const_size || const_size - offset < sizeof(*desc)) { + ualoe_log_error("telemetry_parse: category %u: desc outside const region\n", cat); + return EIO; + } + desc = (const ifoe_telem_tlv_desc_t*)(rgn->const_base + offset); + + if (EXTRACT_FIELD(desc->tlv.tag, IFOE_TELEM_TAG_TAG_ID) != IFOE_TELEM_TAG_DESC) { + ualoe_log_error("telemetry_parse: category %u: invalid desc tag\n", cat); + return EIO; + } + + dataset->category = EXTRACT_FIELD(desc->tlv.tag, IFOE_TELEM_TAG_CATEGORY); + item_count = desc->tlv.len / sizeof(uint64_t); + if (item_count > IFOE_TELEMETRY_ID_COUNT) item_count = IFOE_TELEMETRY_ID_COUNT; + + if ((const char*)&desc->ids[item_count] > rgn->const_end) { + ualoe_log_error("telemetry_parse: category %u: desc ids exceed const region\n", cat); + return EIO; + } + + /* Find dataset header TLV in dyn region */ + dyn_size = (size_t)(rgn->dyn_end - rgn->dyn_base); + if (ADD_OVERFLOW((size_t)rgn->page_size, (size_t)dataset_locator->datasets[cat], &offset) || + offset > dyn_size || dyn_size - offset < sizeof(*data_hdr)) { + ualoe_log_error("telemetry_parse: category %u: dataset_hdr outside dyn region\n", cat); + return EIO; + } + data_hdr = (const ifoe_telem_tlv_dataset_hdr_t*)(rgn->dyn_base + offset); + + if (EXTRACT_FIELD(data_hdr->tlv.tag, IFOE_TELEM_TAG_TAG_ID) != IFOE_TELEM_TAG_DATASET_HDR) { + ualoe_log_error("telemetry_parse: category %u: invalid dataset_hdr tag\n", cat); + return EIO; + } + + netport_based = (cat == CFG_TELEMETRY_CATEGORY_PFC || cat == CFG_TELEMETRY_CATEGORY_NETPORT || + cat == CFG_TELEMETRY_CATEGORY_DERIVED_NETPORT); + + rc = count_data_tlvs(rgn, data_hdr, cat, netport_based, &dataset->instance_count, + &netports_per_station); + if (rc) return rc; + + dataset->generation_count = data_hdr->gen_count; + dataset->timestamp.tv_sec = data_hdr->timestamp / 1000; + dataset->timestamp.tv_nsec = (data_hdr->timestamp % 1000) * 1000000; + + rc = populate_instances(dataset, rgn, data_hdr, desc, cat, netport_based, item_count, + netports_per_station); + if (rc) return rc; + + return 0; +} + +int ualoe_telem_parse(const void* mmap_buf, size_t buf_size, unsigned category_mask, + ualoe_telemetry_t* telemetry) { + const ifoe_telem_tlv_dataset_locator_t* dataset_locator; + const ifoe_telem_tlv_desc_locator_t* desc_locator; + const ifoe_telem_tlv_hdr_t* hdr; + struct telem_regions rgn; + unsigned cat; + int rc; + + rgn.page_size = ualoe_get_page_size(); + + rc = ualoe_telem_parse_snapshot_hdr(mmap_buf, buf_size, &rgn); + if (rc) return rc; + + rc = ualoe_telem_validate_hdr(&rgn, &hdr); + if (rc) return rc; + + rc = ualoe_telem_validate_locators(hdr, rgn.const_end, &desc_locator, &dataset_locator); + if (rc) return rc; + + for (cat = 0; cat < TELEMETRY_SRC_CATEGORY_COUNT && cat < UALOE_TELEMETRY_CATEGORY_MAX; cat++) { + if (category_mask & (1U << cat)) { + if (telemetry->datasets[cat] == NULL) { + ualoe_log_error("No dataset allocated for category %d\n", cat); + return EINVAL; + } else if (desc_locator->descs[cat] == 0) { + ualoe_log_error( + "Firmware has not provided data for " + "category %d\n", + cat); + return EINVAL; + } else if (dataset_locator->datasets[cat] == 0) { + ualoe_log_error( + "Firmware has not provided dataset for " + "category %d\n", + cat); + return EINVAL; + } + } else { + if (telemetry->datasets[cat]) telemetry->datasets[cat]->instance_count = 0; + continue; + } + + rc = parse_category(&rgn, cat, desc_locator, dataset_locator, telemetry->datasets[cat]); + if (rc) return rc; + } + + return 0; +} diff --git a/projects/amdsmi/tests/amd_smi_test/functional/ifoe/fabric/fabric_read_test.cc b/projects/amdsmi/tests/amd_smi_test/functional/ifoe/fabric/fabric_read_test.cc index c9873d4c9288..13bf3a7a267c 100644 --- a/projects/amdsmi/tests/amd_smi_test/functional/ifoe/fabric/fabric_read_test.cc +++ b/projects/amdsmi/tests/amd_smi_test/functional/ifoe/fabric/fabric_read_test.cc @@ -271,3 +271,38 @@ void TestFabricRead::Run(void) { ASSERT_EQ(err, AMDSMI_STATUS_INVAL); } } + +// amdsmi_fabric_telem_id_to_string() is a pure lookup over a static id->name +// table generated from the vendored IFOE_TELEM_ID_* headers, so these run +// without a device and catch id->name drift when the headers are re-synced. + +// Literals (independent of the vendored macros) spanning the table — first, +// mid-table, and last entry — so a reorder or drop anywhere is caught. +static constexpr uint64_t kFirstTelemId = 0x1; +static constexpr uint64_t kMidTelemId = 0x6000001; +static constexpr uint64_t kLastTelemId = 0x6001011; + +TEST(IfoeFunctionalReadOnly, FabricTelemIdToStringMapsKnownIds) { + const char* name = nullptr; + + ASSERT_EQ(amdsmi_fabric_telem_id_to_string(kFirstTelemId, &name), AMDSMI_STATUS_SUCCESS); + ASSERT_STREQ(name, "IFOE_SDP_TX_PACK_WR_REQ"); + + ASSERT_EQ(amdsmi_fabric_telem_id_to_string(kMidTelemId, &name), AMDSMI_STATUS_SUCCESS); + ASSERT_STREQ(name, "NETPORT_LINK_STATUS"); + + ASSERT_EQ(amdsmi_fabric_telem_id_to_string(kLastTelemId, &name), AMDSMI_STATUS_SUCCESS); + ASSERT_STREQ(name, "NETPORT_FEC_CW_SYMBOL_ERRS_UNCORRECTABLE"); +} + +TEST(IfoeFunctionalReadOnly, FabricTelemIdToStringRejectsNullName) { + amdsmi_status_t err = amdsmi_fabric_telem_id_to_string(kFirstTelemId, nullptr); + ASSERT_EQ(err, AMDSMI_STATUS_INVAL); +} + +TEST(IfoeFunctionalReadOnly, FabricTelemIdToStringUnknownIdReportsUnknown) { + const char* name = nullptr; + amdsmi_status_t err = amdsmi_fabric_telem_id_to_string(UINT64_MAX, &name); + ASSERT_EQ(err, AMDSMI_STATUS_NOT_FOUND); + ASSERT_STREQ(name, "UNKNOWN"); +}