AMI - API Description

The following is a brief overview of the AMI API.

Public API Return Codes

CodeDescription

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,
};
FunctionDescription

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;
};
FunctionDescription

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.

FunctionDescription

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,
};

FunctionDescription

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,
};
FunctionDescription

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.

FunctionDescription

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.

FunctionDescription

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.

FunctionDescription

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;
};

FunctionDescription

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