AMI - API Description¶
The following is a brief overview of the AMI API.
Public API Return Codes¶
Code | Description |
---|---|
AMI_STATUS_OK | Success |
AMI_STATUS_ERROR | Failure |
AMI Device Functions¶
The ami_device struct is defined as an opaque declaration (not exposed via API) and is used to represent a single PCI device instance.
It is used in various API’s to identify which device the operation should be performed with.
/* Opaque declaration of `struct ami_device`. */
typedef struct ami_device ami_device;
/**
* struct amc_version - structure to hold AMC version information
* @major: Major software version
* @minor: Minor software version
* @patch: Patch number (if applicable)
* @local_changes: 0 for no changes, 1 for changes
* @dev_commits: Number of development commits since the version was released
*/
struct amc_version {
uint8_t major;
uint8_t minor;
uint8_t patch;
uint8_t local_changes;
uint16_t dev_commits;
};
/**
* enum ami_amc_debug_level - AMC debug verbosity levels
* @AMI_AMC_DEBUG_LEVEL_LOG: used for printing to the log (dmesg)
* @AMI_AMC_DEBUG_LEVEL_INFO: used when printing is part of the behaviour
* @AMI_AMC_DEBUG_LEVEL_ERROR: used for errors
* @AMI_AMC_DEBUG_LEVEL_WARNING: used for warnings
* @AMI_AMC_DEBUG_LEVEL_DEBUG: used for debug prints
*
* Note that these log levels only apply to what AMC puts into dmesg.
* Debug levels are "up to and including". The default log level is
* `AMI_AMC_DEBUG_LEVEL_LOG`.
*/
enum ami_amc_debug_level {
AMI_AMC_DEBUG_LEVEL_LOG = 0,
AMI_AMC_DEBUG_LEVEL_INFO,
AMI_AMC_DEBUG_LEVEL_ERROR,
AMI_AMC_DEBUG_LEVEL_WARNING,
AMI_AMC_DEBUG_LEVEL_DEBUG,
};
Function | Description |
---|---|
int ami_dev_find_next(ami_device **dev, int b, int d, int f, ami_device *prev); | Find the next device that matches the specified criteria |
int ami_dev_find(const char *bdf, ami_device **dev); | Wrapper around `ami_dev_find_next` |
int ami_dev_bringup(const char *bdf, ami_device **dev); | Find a device and perform additional setup logic on it |
void ami_dev_delete(ami_device **dev); | Free the memory held by a device struct |
int ami_dev_request_access(ami_device *dev); | Request elevated device permissions |
int ami_dev_pci_reload(ami_device **dev, const char *bdf); | Remove a device from the PCI tree and rescan the bus |
int ami_dev_hot_reset(ami_device **dev); | Trigger a PCI hot reset for this device |
int ami_dev_set_amc_debug_level(ami_device *dev, enum ami_amc_debug_level level); | Set the AMC debug level. |
int ami_dev_read_uuid(ami_device *dev, char buf[AMI_LOGIC_UUID_SIZE]); | Read the logic uuid sysfs node |
int ami_dev_get_num_devices(uint16_t *num); | Get the number of devices attached to the driver |
int ami_dev_get_pci_link_speed(ami_device *dev, uint8_t *current, uint8_t *max); | Get the PCI link speed. |
int ami_dev_get_pci_link_width(ami_device *dev, uint8_t *current, uint8_t *max); | Get the PCI link width |
int ami_dev_get_pci_vendor(ami_device *dev, uint16_t *vendor); | Get the PCI vendor ID |
int ami_dev_get_pci_device(ami_device *dev, uint16_t *device); | Get the PCI device ID |
int ami_dev_get_pci_numa_node(ami_device *dev, uint8_t *node); | Get the PCI device NUMA node. |
int ami_dev_get_pci_cpulist(ami_device *dev, char buf[AMI_PCI_CPULIST_SIZE]); | Get the PCI CPU affinity |
int ami_dev_get_state(ami_device *dev, char buf[AMI_DEV_STATE_SIZE]); | Get the device state |
int ami_dev_get_name(ami_device *dev, char buf[AMI_DEV_NAME_SIZE]); | Get the device name |
int ami_dev_get_amc_version(ami_device *dev, struct amc_version *amc_version); | Get AMC version info if available |
int ami_dev_get_pci_port(ami_device *dev, char buf[AMI_DEV_PCI_PORT_SIZE]); | Get the BDF of the PCI port for the given device |
int ami_dev_get_pci_bdf(ami_device *dev, uint16_t *bdf); | Get PCI BDF for this device |
int ami_dev_get_cdev_num(ami_device *dev, int *num); | Get the character device number for this device |
int ami_dev_get_hwmon_num(ami_device *dev, int *num); | Get the HWMON number for this device |
Versioning Functions¶
The versioning API’s for the API & driver, the AMC version is available via the Device API if available.
/**
* struct ami_version - structure to hold AMI version information
* @major: Major software version
* @minor: Minor software version
* @patch: Patch number (if applicable)
* @dev_commits: Number of development commits since the version was released
* @status: 0 if unmodified, 1 if there are unversioned modifications
*/
struct ami_version {
uint8_t major;
uint8_t minor;
uint8_t patch;
uint8_t dev_commits;
uint8_t status;
};
Function | Description |
---|---|
int ami_get_driver_version(struct ami_version *ami_version); | Get AMI Driver version info |
int ami_get_api_version(struct ami_version *ami_version); | Get AMI API version info |
Utility Functions¶
The general utility functions to return the last error and convert BDF string into a u16.
Function | Description |
---|---|
const char *ami_get_last_error(void); | Get a human readable string of the last error code |
uint16_t ami_parse_bdf(const char *bdf); | Parse a BDF string into a uint16 representation |
Event Handling¶
Some API functions can accept an event handler which will receive AMI driver events.
This can be useful, for example, for tracking the progress of long running commands such as PDI programming.
/**
* enum ami_event_status - list of driver event status codes
* @AMI_EVENT_STATUS_OK: poll was ok and valid data was read back
* @AMI_EVENT_STATUS_READ_ERROR: poll was ok but the read failed
* @AMI_EVENT_STATUS_TIMEOUT: poll timed out (no event)
*/
enum ami_event_status {
AMI_EVENT_STATUS_OK = 0,
AMI_EVENT_STATUS_READ_ERROR,
AMI_EVENT_STATUS_TIMEOUT,
};
Function Prototype | Description |
---|---|
typedef void (*ami_event_handler)(enum ami_event_status status, uint64_t ctr, void *data) | Receive a single driver event - will run in a separate thread |
Program Functions¶
These functions allow programming of a PDI image to a particular partition, copying one partition to another and setting the boot partition.
There is also functionality within this API to return the FPT header and each FPT entry.
/**
* struct ami_fpt_header - The FPT header.
* @version: FPT version.
* @hdr_size: The size of the header in bytes.
* @entry_size: The entry size in bytes.
* @num_entries: The number of partitions.
*/
struct ami_fpt_header {
uint8_t version;
uint8_t hdr_size;
uint8_t entry_size;
uint8_t num_entries;
};
/**
* enum ami_fpt_type - Different FPT partition types.
* @AMI_FPT_TYPE_FPT: File partition table.
* @AMI_FPT_TYPE_RECOVERY_FPT: Recovery file partition table.
* @AMI_FPT_TYPE_EXTENSION_FPT: Extension file partition table.
* @AMI_FPT_TYPE_PDI_BOOT: PDI boot.
* @AMI_FPT_TYPE_PDI_BOOT_BACKUP: PDI boot backup.
* @AMI_FPT_TYPE_PDI_XSABIN_META: XSABIN metadata.
* @AMI_FPT_TYPE_PDI_GOLDEN: PDI golden image.
* @AMI_FPT_TYPE_PDI_SYS_DTB: SYS DTB.
* @AMI_FPT_TYPE_PDI_META: PDI metadata.
* @AMI_FPT_TYPE_PDI_META_BACKUP: PDI metadata backup.
* @AMI_FPT_TYPE_SC_FW: SC FW.
*/
enum ami_fpt_type {
AMI_FPT_TYPE_FPT = 0xFFFF,
AMI_FPT_TYPE_RECOVERY_FPT = 0xFFFE,
AMI_FPT_TYPE_EXTENSION_FPT = 0xFFFD,
AMI_FPT_TYPE_PDI_BOOT = 0x0E00,
AMI_FPT_TYPE_PDI_BOOT_BACKUP = 0x0E01,
AMI_FPT_TYPE_PDI_XSABIN_META = 0x0E02,
AMI_FPT_TYPE_PDI_GOLDEN = 0x0E03,
AMI_FPT_TYPE_PDI_SYS_DTB = 0x0E04,
AMI_FPT_TYPE_PDI_META = 0x0E05,
AMI_FPT_TYPE_PDI_META_BACKUP = 0x0E06,
AMI_FPT_TYPE_SC_FW = 0x0C00,
};
/**
* struct ami_fpt_partition - The individual partition information.
* @type: Partition type.
* @base_addr: Partition base address.
* @size: Partition size.
*/
struct ami_fpt_partition {
enum ami_fpt_type type;
uint32_t base_addr;
uint32_t size;
};
/**
* struct ami_pdi_progress - Data struct for PDI download progress handlers
* @bytes_to_write: Total number of bytes to write as part of the procedure
* @bytes_written: Number of bytes written so far - this must be updated by
* the progress handler (initially set to 0)
* @reserved: Generic field which can be used by the handler implementation
*/
struct ami_pdi_progress {
uint32_t bytes_to_write;
uint32_t bytes_written;
uint64_t reserved;
};
/**
* enum ami_boot_devices - list of available boot devices
* @AMI_BOOT_DEVICES_PRIMARY: primary boot device
* @AMI_BOOT_DEVICES_SECONDARY: secondary boot device
* @AMI_BOOT_DEVICES_MAX: max boot device
*/
enum ami_boot_devices {
AMI_BOOT_DEVICES_PRIMARY = 0,
AMI_BOOT_DEVICES_SECONDARY,
AMI_BOOT_DEVICES_MAX,
};
Function | Description |
---|---|
int ami_prog_download_pdi(ami_device *dev, const char *path, uint8_t boot_device, uint32_t partition, ami_event_handler progress_handler); | Program a PDI bitstream onto a device |
int ami_prog_update_fpt(ami_device *dev, const char *path, uint8_t boot_device, ami_event_handler progress_handler); | Program a PDI bitstream containing an FPT |
int ami_prog_device_boot(struct ami_device **dev, uint32_t partition); | Set the device boot partition |
int ami_prog_copy_partition(ami_device *dev, uint32_t src_device, uint32_t src_part, uint32_t dest_device, uint32_t dest_part, ami_event_handler progress_handler); | Copy one device partition to another |
int ami_prog_get_fpt_header(ami_device *dev, uint8_t boot_device, struct ami_fpt_header *header); | Get the FPT header information |
int ami_prog_get_fpt_partition(ami_device *dev, uint32_t num, struct ami_fpt_partition *partition); | Get FPT partition information |
Manufacturer Info Functions¶
The manufacturing info is returned as below, note only certain fields are applicable depending on EEPROM version programmed on the AMC.
/**
* enum ami_mfg_field - List of device EEPROM fields.
* @AMI_MFG_FIELD_MIN: Min enum value to allow iteration.
* @AMI_MFG_EEPROM_VERSION: The EEPROM version.
* @AMI_MFG_PRODUCT_NAME: the product name.
* @AMI_MFG_BOARD_REV: the board revision.
* @AMI_MFG_BOARD_SERIAL: the board serial number.
* @AMI_MFG_MEMORY_SIZE: Coveys the max memory (in GB).
* @AMI_MFG_PART_NUM: Board part number.
* @AMI_MFG_M_PART_NUM: Manufacturer part number.
* @AMI_MFG_MAC_ADDR_C: Number of MAC IDs.
* @AMI_MFG_MAC_ADDR: Primary MAC ID.
* @AMI_MFG_MAC_ADDR_N: Number of MAC IDs.
* @AMI_MFG_ACTIVE_STATE: Active/Passive.
* @AMI_MFG_CONFIG_MODE: 07: Master SPI x4 (QSPIx4), 08: OSPI.
* @AMI_MFG_M_DATE: Manufacturing Date.
* @AMI_MFG_UUID: Used to uniquely ID the product.
* @AMI_MFG_PCIE_ID: Vendor ID, Device ID, SubVendor ID, SubDevice ID.
* @AMI_MFG_POWER_MODE: Max power mode.
* @AMI_MFG_OEM_ID: OEM ID.
* @AMI_MFG_CAPABILITY: Capability word.
* @AMI_MFG_FIELD_MAX: Max enum value to allow iteration.
*/
enum ami_mfg_field {
AMI_MFG_FIELD_MIN,
AMI_MFG_EEPROM_VERSION,
AMI_MFG_PRODUCT_NAME,
AMI_MFG_BOARD_REV,
AMI_MFG_BOARD_SERIAL,
AMI_MFG_MEMORY_SIZE,
AMI_MFG_PART_NUM,
AMI_MFG_M_PART_NUM,
AMI_MFG_MAC_ADDR_C,
AMI_MFG_MAC_ADDR,
AMI_MFG_MAC_ADDR_N,
AMI_MFG_ACTIVE_STATE,
AMI_MFG_CONFIG_MODE,
AMI_MFG_M_DATE,
AMI_MFG_UUID,
AMI_MFG_PCIE_ID,
AMI_MFG_POWER_MODE,
AMI_MFG_OEM_ID,
AMI_MFG_CAPABILITY,
AMI_MFG_FIELD_MAX,
};
Function | Description |
---|---|
int ami_mfg_get_info(ami_device *dev, enum ami_mfg_field field, char buf[AMI_MFG_INFO_MAX_STR]); | Get manufacturing board information |
Memory Access Functions¶
These functions allow reading/writing to a particular PCI bar, one of multiple u32 values at a time.
Function | Description |
---|---|
int ami_mem_bar_read(ami_device *dev, uint8_t idx, uint64_t offset, uint32_t *val); | Read a PCI bar register |
int ami_mem_bar_write(ami_device *dev, uint8_t idx, uint64_t offset, uint32_t val); | Write to a PCI bar register |
int ami_mem_bar_read_range(ami_device *dev, uint8_t idx, uint64_t offset, uint32_t num, uint32_t *val); | Read block of data from a PCI bar register |
int ami_mem_bar_write_range(ami_device *dev, uint8_t idx, uint64_t offset, uint32_t num, uint32_t *val); | Write block of data to a PCI bar register |
EEPROM Read/Write Functions¶
These functions allow reading/writing one or more bytes to the EEPROM on the AMC.
Note: On future versions of the AMC the first 128 bytes will be read only.
Function | Description |
---|---|
int ami_eeprom_read(ami_device *dev, uint8_t offset, uint8_t num, uint8_t *val); | Read one or more bytes of data from the EEPROM |
int ami_eeprom_write(ami_device *dev, uint8_t offset, uint8_t num, uint8_t *val); | Write one or more bytes of data to the EEPROM |
Module Read/Write Functions¶
These functions allow reading/writing one or more bytes to/from QSFP modules.
Function | Description |
---|---|
int ami_module_read(ami_device *dev, uint8_t device_id, uint8_t page, uint8_t offset, uint8_t num, uint8_t *val); | Read one or more bytes of data from a QSFP module |
int ami_module_write(ami_device *dev, uint8_t device_id, uint8_t page, uint8_t offset, uint8_t num, uint8_t *val); | Write one or more bytes of data to a QSFP module |
Sensor Functions¶
The sensor functions are defined below and allow:
Initial discovery
Set or get the sensor refresh rate.
Accessors to get information of type/number of sensors on each device.
Accessors to get status, value, average value, max value and unit byte modifier per sensor name.
/**
* enum ami_sensor_type - list of AMI sensor types
* @AMI_SENSOR_TYPE_TEMP: temperature sensor
* @AMI_SENSOR_TYPE_CURRENT: current sensor
* @AMI_SENSOR_TYPE_VOLTAGE: voltage sensor
* @AMI_SENSOR_TYPE_POWER: power sensor
* @AMI_SENSOR_TYPE_INVALID: invalid sensor type
*/
enum ami_sensor_type {
AMI_SENSOR_TYPE_TEMP = (uint32_t)(1 << 0),
AMI_SENSOR_TYPE_CURRENT = (uint32_t)(1 << 1),
AMI_SENSOR_TYPE_VOLTAGE = (uint32_t)(1 << 2),
AMI_SENSOR_TYPE_POWER = (uint32_t)(1 << 3),
AMI_SENSOR_TYPE_INVALID = (uint32_t)0,
};
/**
* enum ami_sensor_status - list of sensor status codes
* @AMI_SENSOR_STATUS_INVALID: Generic invalid code to be used as a placeholder.
* @AMI_SENSOR_STATUS_NOT_PRESENT: Sensor not present.
* @AMI_SENSOR_STATUS_OK: Sensor present and valid.
* @AMI_SENSOR_STATUS_NO_DATA: Data not available.
* @AMI_SENSOR_STATUS_OK_CACHED: Value is OK but not fresh.
* @AMI_SENSOR_STATUS_NA: Not applicable or default value.
*/
enum ami_sensor_status {
AMI_SENSOR_STATUS_INVALID = -1,
AMI_SENSOR_STATUS_NOT_PRESENT = 0x00,
AMI_SENSOR_STATUS_OK = 0x01,
AMI_SENSOR_STATUS_NO_DATA = 0x02,
AMI_SENSOR_STATUS_OK_CACHED = 0x03, /* Not from ASDM */
/* 0x04 - 0x7E Reserved */
AMI_SENSOR_STATUS_NA = 0x7F,
/* 0x80 - 0xFF Reserved */
};
/**
* enum ami_sensor_unit_mod - base unit modifiers for sensor readings
* @AMI_SENSOR_UNIT_MOD_MEGA: 10^6 modifier
* @AMI_SENSOR_UNIT_MOD_KILO: 10^3 modifier
* @AMI_SENSOR_UNIT_MOD_NONE: 10^0 modifier (none)
* @AMI_SENSOR_UNIT_MOD_MILLI: 10^-3 modifier
* @AMI_SENSOR_UNIT_MOD_MICRO: 10^-6 modifier
*
* Note that no enum is defined for the type of unit used as this can be
* inferred from the getter function being called. For reference, the units used
* are as follows:
*
* Temp - Degrees Celsius
* Power - Watts
* Voltage - Volts
* Current - Amperes
*/
enum ami_sensor_unit_mod {
AMI_SENSOR_UNIT_MOD_MEGA = 6,
AMI_SENSOR_UNIT_MOD_KILO = 3,
AMI_SENSOR_UNIT_MOD_NONE = 0,
AMI_SENSOR_UNIT_MOD_MILLI = -3,
AMI_SENSOR_UNIT_MOD_MICRO = -6
};
/**
* enum ami_sensor_limit - list of supported sensor limits/thresholds
* @AMI_SENSOR_LIMIT_WARN: Warning threshold
* @AMI_SENSOR_LIMIT_CRIT: Critical threshold
* @AMI_SENSOR_LIMIT_FATAL: Fatal threshold
*/
enum ami_sensor_limit {
AMI_SENSOR_LIMIT_WARN,
AMI_SENSOR_LIMIT_CRIT,
AMI_SENSOR_LIMIT_FATAL,
};
/* Opaque declaration of sensor private data. */
typedef struct ami_sensor_internal ami_sensor_internal;
/**
* struct ami_sensor() - Represents a top-level sensor struct.
* @name: Sensor name.
* @next: Pointer to next sensor.
* @sensor_data: Private sensor data. Not to be used by user.
*/
struct ami_sensor {
char name[AMI_SENSOR_MAX_STR];
struct ami_sensor *next;
ami_sensor_internal *sensor_data;
};
Function | Description |
---|---|
int ami_sensor_discover(ami_device *dev); | Find all sensors supported by a specific device |
int ami_sensor_set_refresh(ami_device *dev, uint16_t val); | Set the sensor update interval |
int ami_sensor_get_refresh(ami_device *dev, uint16_t *val); | Get the current sensor update interval |
int ami_sensor_get_type(ami_device *dev, const char *sensor_name, uint32_t *type); | Get a bitmask describing the sensor types |
int ami_sensor_get_sensors(ami_device *dev, struct ami_sensor **sensors, int *num); | Get the list of sensors belonging to a device |
int ami_sensor_get_num_total(ami_device *dev, int *num); | Get the total number of sensors for a device |
int ami_sensor_get_temp_status(ami_device *dev, const char *sensor_name, enum ami_sensor_status *val); | Get the status string of a temperature sensor |
int ami_sensor_get_voltage_status(ami_device *dev, const char *sensor_name, enum ami_sensor_status *val); | Get the status string of a voltage sensor |
int ami_sensor_get_current_status(ami_device *dev, const char *sensor_name, enum ami_sensor_status *val); | Get the status string of a current sensor |
int ami_sensor_get_power_status(ami_device *dev, const char *sensor_name, enum ami_sensor_status *val); | Get the status string of a power sensor |
int ami_sensor_get_temp_value(ami_device *dev, const char *sensor_name, long *val, enum ami_sensor_status *sensor_status); | Get the value of a temperature sensor |
int ami_sensor_get_voltage_value(ami_device *dev, const char *sensor_name, long *val, enum ami_sensor_status *sensor_status); | Get the value of a voltage sensor |
int ami_sensor_get_current_value(ami_device *dev, const char *sensor_name, long *val, enum ami_sensor_status *sensor_status); | Get the value of a current sensor |
int ami_sensor_get_power_value(ami_device *dev, const char *sensor_name, long *val, enum ami_sensor_status *sensor_status); | Get the value of a power sensor |
int ami_sensor_get_temp_uptime_max(ami_device *dev, const char *sensor_name, long *val); | Get the max value of a temperature sensor |
int ami_sensor_get_voltage_uptime_max(ami_device *dev, const char *sensor_name, long *val); | Get the max value of a voltage sensor |
int ami_sensor_get_current_uptime_max(ami_device *dev, const char *sensor_name, long *val); | Get the max value of a current sensor |
int ami_sensor_get_power_uptime_max(ami_device *dev, const char *sensor_name, long *val); | Get the max value of a power sensor |
int ami_sensor_get_temp_uptime_average(ami_device *dev, const char *sensor_name, long *val); | Get the average value of a temperature sensor |
int ami_sensor_get_voltage_uptime_average(ami_device *dev, const char *sensor_name, long *val); | Get the average value of a voltage sensor |
int ami_sensor_get_current_uptime_average(ami_device *dev, const char *sensor_name, long *val); | Get the average value of a current sensor |
int ami_sensor_get_power_uptime_average(ami_device *dev, const char *sensor_name, long *val); | Get the average value of a power sensor |
int ami_sensor_get_temp_unit_mod(ami_device *dev, const char *sensor_name, enum ami_sensor_unit_mod *mod); | Get the unit modifier of a temperature sensor |
int ami_sensor_get_voltage_unit_mod(ami_device *dev, const char *sensor_name, enum ami_sensor_unit_mod *mod); | Get the unit modifier of a voltage sensor |
int ami_sensor_get_current_unit_mod(ami_device *dev, const char *sensor_name, enum ami_sensor_unit_mod *mod); | Get the unit modifier of a current sensor |
int ami_sensor_get_power_unit_mod(ami_device *dev, const char *sensor_name, enum ami_sensor_unit_mod *mod); | Get the unit modifier of a power sensor. |
int ami_sensor_get_temp_limit(ami_device *dev, const char *sensor_name, enum ami_sensor_limit limit_type, long *val) | Get the limits of a temperature sensor. |
int ami_sensor_get_voltage_limit(ami_device *dev, const char *sensor_name, enum ami_sensor_limit limit_type, long *val) | Get the limits of a voltage sensor. |
int ami_sensor_get_current_limit(ami_device *dev, const char *sensor_name, enum ami_sensor_limit limit_type, long *val) | Get the limits of a current sensor. |
int ami_sensor_get_power_limit(ami_device *dev, const char *sensor_name, enum ami_sensor_limit limit_type, long *val) | Get the limits of a power sensor. |
Page Revision: v. 24