common/ipmi/include/ipmb.h (137 lines of code) (raw):

#ifndef IPMB_H #define IPMB_H #include <devicetree.h> #include <stdio.h> #if DT_NODE_EXISTS(DT_NODELABEL(ipmb0)) #define DEV_IPMB_0 #endif #if DT_NODE_EXISTS(DT_NODELABEL(ipmb1)) #define DEV_IPMB_1 #endif #if DT_NODE_EXISTS(DT_NODELABEL(ipmb2)) #define DEV_IPMB_2 #endif #if DT_NODE_EXISTS(DT_NODELABEL(ipmb3)) #define DEV_IPMB_3 #endif #if DT_NODE_EXISTS(DT_NODELABEL(ipmb4)) #define DEV_IPMB_4 #endif #if DT_NODE_EXISTS(DT_NODELABEL(ipmb5)) #define DEV_IPMB_5 #endif #if DT_NODE_EXISTS(DT_NODELABEL(ipmb6)) #define DEV_IPMB_6 #endif #if DT_NODE_EXISTS(DT_NODELABEL(ipmb7)) #define DEV_IPMB_7 #endif #if DT_NODE_EXISTS(DT_NODELABEL(ipmb8)) #define DEV_IPMB_8 #endif #if DT_NODE_EXISTS(DT_NODELABEL(ipmb9)) #define DEV_IPMB_9 #endif #define DEBUG_IPMI 0 #define SEQ_NUM 64 #define MAX_DATA_QUENE 15 #define MAX_IPMB_IDX 5 #define IPMB_timeout_S 1 #define SELF_IPMB_IF 0x00 #define IPMI_DATA_MAX_LENGTH 520 #define IPMB_REQ_HEADER_LENGTH 6 #define IPMB_RESP_HEADER_LENGTH 7 #define IPMI_MSG_MAX_LENGTH (IPMI_DATA_MAX_LENGTH + IPMB_RESP_HEADER_LENGTH) #define IPMB_MAX_RETRIES 5 #define IPMB_TXQUEUE_LEN 1 #define IPMB_RXQUEUE_LEN 2 #define IPMB_TX_STACK_SIZE 1500 #define IPMB_RX_STACK_SIZE 2000 #define IPMI_HEADER_CHECKSUM_POSITION 2 #define IPMB_NETFN_MASK 0xFC #define IPMB_DEST_LUN_MASK 0x03 #define IPMB_SEQ_MASK 0xFC #define IPMB_SRC_LUN_MASK 0x03 #define CLIENT_NOTIFY_TIMEOUT 5 #define IPMB_RETRY_DELAY_ms 500 #define IPMB_MQUEUE_POLL_DELAY_ms 10 #define IPMB_SEQ_TIMEOUT_ms 1000 #define IPMB_SEQ_TIMEOUT_STACK_SIZE 500 #define IPMB_RESERVE_IDX 0xFF #define Enable 1 #define Disable 0 #define IS_RESPONSE(msg) (msg.netfn & 0x01) enum { Self_IFs = 0x0, ME_IPMB_IFs = 0x01, BMC_IPMB_IFs = 0x02, HOST_KCS_IFs = 0x03, SERVER_IPMB_IFs = 0x04, EXP1_IPMB_IFs = 0x05, SLOT1_BIC_IFs = 0x07, SLOT3_BIC_IFs = 0x08, BB_IPMB_IFs = 0x10, EXP2_IPMB_IFs = 0x15, PEER_BMC_IPMB_IFs = 0x1A, BMC_USB_IFs = 0x20, PLDM_IFs = 0x40, Reserve_IFs, }; enum { I2C_IF, I3C_IF, Reserve_IF, }; typedef struct IPMB_config { uint8_t index; uint8_t Inf; uint8_t Inf_source; uint8_t bus; uint8_t target_addr; bool EnStatus; uint8_t slave_addr; char *Rx_attr_name; char *Tx_attr_name; } IPMB_config; extern IPMB_config *IPMB_config_table; typedef enum ipmb_error { ipmb_error_success = 0, /**< Generic no-error flag */ ipmb_error_unknown, /**< Unknown error */ ipmb_error_failure, /**< Generic failure on IPMB */ ipmb_error_timeout, /**< Error raised when a message takes too long to be responded */ ipmb_error_invalid_req, /**< A invalid request was received */ ipmb_error_hdr_chksum, /**< Invalid header checksum from incoming message */ ipmb_error_msg_chksum, /**< Invalid message checksum from incoming message */ ipmb_error_queue_creation, /**< Client queue couldn't be created. Invalid pointer to handler was given */ ipmb_error_get_messageQueue, /**< Failure on getting queue message */ ipmb_error_mutex_lock, /**< Fail to lock mutex in time */ } ipmb_error; typedef struct ipmi_msg { uint8_t dest_addr; /**< Destination slave address */ uint8_t netfn; /**< Net Function */ uint8_t dest_LUN; /**< Destination LUN (Logical Unit Number) */ uint8_t hdr_chksum; /**< Connection Header Checksum */ uint8_t src_addr; /**< Source slave address */ uint8_t seq_source; /**< Source sequence Number */ uint8_t seq_target; /**< Target sequence Number */ uint8_t seq; /**< Sequence Number */ uint8_t InF_source; /**< Source bridge interface */ uint8_t InF_target; /**< Target bridge interface */ uint8_t src_LUN; /**< Source LUN (Logical Unit Number) */ uint8_t cmd; /**< Command */ uint8_t completion_code; /**< Completion Code*/ uint16_t data_len; /**< Amount of valid bytes in #data buffer */ uint8_t data[IPMI_MSG_MAX_LENGTH]; /**< Data buffer > * Data field has 24 bytes: * 32 (Max IPMI msg len) - 7 header bytes - 1 final chksum byte */ uint32_t timestamp; /**< Tick count at the beginning of the process */ uint8_t msg_chksum; /**< Message checksum */ } __packed __aligned(4) ipmi_msg; typedef struct ipmi_msg_cfg { ipmi_msg buffer; /**< IPMI Message */ uint8_t retries; /**< Current retry counter */ struct ipmi_msg_cfg *next; } __packed __aligned(4) ipmi_msg_cfg; void ipmb_init(void); ipmb_error ipmb_send_request(ipmi_msg *req, uint8_t bus); ipmb_error ipmb_send_response(ipmi_msg *resp, uint8_t bus); ipmb_error ipmb_read(ipmi_msg *msg, uint8_t bus); #endif