diff --git a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/ledi.c b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/ledi.c index ebb5820f..48acc1d8 100755 --- a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/ledi.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/ledi.c @@ -45,6 +45,23 @@ enum onlp_led_id LED_ACT }; +typedef struct { + bool valid; + time_t last_poll; + uint8_t reg_val; +} led_status_t; + +typedef struct { + led_status_t ls[1]; /*2 LEDs but Only 1 reg*/ + sem_t mutex; +} ledi_status_t; + + +#define POLL_INTERVAL (5) /*in seconds*/ +#define SEM_LOCK do {sem_wait(&global_ledi_st->mutex);} while(0) +#define SEM_UNLOCK do {sem_post(&global_ledi_st->mutex);} while(0) + + typedef struct led_address_s { enum onlp_led_id id; uint8_t bus; @@ -57,7 +74,7 @@ typedef struct led_mode_info_s { uint8_t regval; } led_mode_info_t; -static led_address_t led_addr[] = +static led_address_t led_addr[] = { { }, /* Not used */ {LED_SYS, 50, 0x20, 3}, @@ -105,7 +122,7 @@ static onlp_led_info_t linfo[] = ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_PURPLE | ONLP_LED_CAPS_RED | ONLP_LED_CAPS_YELLOW | - ONLP_LED_CAPS_BLUE + ONLP_LED_CAPS_BLUE }, { { ONLP_LED_ID_CREATE(LED_ACT), "SIM LED 2 (ACT LED)", 0 }, @@ -113,16 +130,42 @@ static onlp_led_info_t linfo[] = ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_PURPLE | ONLP_LED_CAPS_RED | ONLP_LED_CAPS_YELLOW | - ONLP_LED_CAPS_BLUE + ONLP_LED_CAPS_BLUE }, }; +ledi_status_t *global_ledi_st = NULL; + + +/*--------------------------------------------------------*/ +static int _create_shm(key_t id) { + int rv; + + if (global_ledi_st == NULL) { + rv = onlp_shmem_create(id, sizeof(led_status_t), + (void**)&global_ledi_st); + if (rv >= 0) { + if(pltfm_create_sem(&global_ledi_st->mutex) != 0) { + AIM_DIE("%s(): mutex_init failed\n", __func__); + return ONLP_STATUS_E_INTERNAL; + } + } + else { + AIM_DIE("Global %s created failed.", __func__); + } + } + return ONLP_STATUS_OK; +} /* * This function will be called prior to any other onlp_ledi_* functions. */ int onlp_ledi_init(void) { + if (_create_shm(ONLP_LEDI_SHM_KEY) < 0) { + AIM_DIE("%s::_create_shm created failed.", __func__); + return ONLP_STATUS_E_INTERNAL; + } return ONLP_STATUS_OK; } @@ -145,7 +188,7 @@ static int reg_value_to_onlp_led_mode(enum onlp_led_id type, uint8_t reg_val) { } static uint8_t onlp_led_mode_to_reg_value(enum onlp_led_id type, - onlp_led_mode_t mode, uint8_t reg_val) { + onlp_led_mode_t mode, uint8_t reg_val) { int i; for (i = 0; i < AIM_ARRAYSIZE(led_type_mode_data); i++) { @@ -163,23 +206,74 @@ static uint8_t onlp_led_mode_to_reg_value(enum onlp_led_id type, return reg_val; } +static int ledi_read_reg(int lid, uint8_t* data) +{ + time_t cur, elapse; + led_status_t *ps; + int value; + + if (data == NULL) + return ONLP_STATUS_E_PARAM; + + cur = time (NULL); + SEM_LOCK; + ps = &global_ledi_st->ls[0]; /*2 LED share same REG. Not take lid here.*/ + elapse = cur - ps->last_poll; + if (!ps->valid || (elapse > POLL_INTERVAL)) { + value = bmc_i2c_readb(led_addr[lid].bus, led_addr[lid].devaddr, led_addr[lid].offset); + if (value < 0) { + ps->valid = false; + SEM_UNLOCK; + return ONLP_STATUS_E_INTERNAL; + } + ps->reg_val = value; + ps->valid = true; + ps->last_poll = time (NULL); + } else { + DEBUG_PRINT("Cached PID:%d @%lu for LED:%d\n", getpid(), cur, lid); + } + *data = ps->reg_val; + SEM_UNLOCK; + return ONLP_STATUS_OK; +} + +static int ledi_write_reg(int lid, uint8_t data) +{ + led_status_t *ps; + + SEM_LOCK; + ps = &global_ledi_st->ls[0]; /*2LED shares same REG. Not take lid here.*/ + if (bmc_i2c_writeb(led_addr[lid].bus, led_addr[lid].devaddr, + led_addr[lid].offset, data) < 0) { + SEM_UNLOCK; + return ONLP_STATUS_E_INTERNAL; + } else { + ps->reg_val = data; + ps->valid = true; + ps->last_poll = time (NULL); + SEM_UNLOCK; + return ONLP_STATUS_OK; + } + SEM_UNLOCK; + return ONLP_STATUS_OK; +} + int onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info) { - int lid, value; + int lid; + uint8_t value; VALIDATE(id); lid = ONLP_OID_ID_GET(id); - - /* Set the onlp_oid_hdr_t and capabilities */ - *info = linfo[ONLP_OID_ID_GET(id)]; - - value = bmc_i2c_readb(led_addr[lid].bus, led_addr[lid].devaddr, led_addr[lid].offset); - if (value < 0) { + if (ledi_read_reg(lid, &value) != ONLP_STATUS_OK) + { return ONLP_STATUS_E_INTERNAL; } + /* Set the onlp_oid_hdr_t and capabilities */ + *info = linfo[ONLP_OID_ID_GET(id)]; info->mode = reg_value_to_onlp_led_mode(lid, value); /* Set the on/off status */ if (info->mode != ONLP_LED_MODE_OFF) { @@ -202,11 +296,9 @@ int onlp_ledi_set(onlp_oid_t id, int on_or_off) { VALIDATE(id); - if (!on_or_off) { return onlp_ledi_mode_set(id, ONLP_LED_MODE_OFF); } - return ONLP_STATUS_E_UNSUPPORTED; } @@ -219,28 +311,25 @@ onlp_ledi_set(onlp_oid_t id, int on_or_off) int onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode) { - int lid, value, i; + int lid, i; + uint8_t value; VALIDATE(id); lid = ONLP_OID_ID_GET(id); - - for (i = 1; i <= PLATFOTM_H_TTY_RETRY; i++) { - value = bmc_i2c_readb(led_addr[lid].bus, led_addr[lid].devaddr, - led_addr[lid].offset); - if (value < 0) { + for (i = 0; i < PLATFOTM_H_TTY_RETRY; i++) { + if (ledi_read_reg(lid, &value) != ONLP_STATUS_OK) + { continue; } value = onlp_led_mode_to_reg_value(lid, mode, value); - if (bmc_i2c_writeb(led_addr[lid].bus, led_addr[lid].devaddr, - led_addr[lid].offset, value) < 0) { + + if (ledi_write_reg(lid, value) != ONLP_STATUS_OK) + { continue; - } else { - return ONLP_STATUS_OK; } } return ONLP_STATUS_E_INTERNAL; - } /* diff --git a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/platform_lib.c b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/platform_lib.c index 0d875423..4a2ddf5f 100755 --- a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/platform_lib.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/platform_lib.c @@ -23,9 +23,7 @@ * ***********************************************************/ #include -#include #include -#include #include #include #include @@ -34,11 +32,15 @@ #define TTY_DEVICE "/dev/ttyACM0" #define TTY_PROMPT "@bmc-oob:" #define TTY_USER "root" -#define TTY_I2C_TIMEOUT 100000 +#define TTY_I2C_WAIT_REPLY 200000 #define TTY_BMC_LOGIN_TIMEOUT 1000000 -#define TTY_LOGIN_RETRY (8) +#define TTY_BMC_LOGIN_INTERVAL 50000 +#define TTY_LOGIN_RETRY (20) +#define TTY_RETRY_INTERVAL 100000 #define TTY_RETRY PLATFOTM_H_TTY_RETRY +static bool global_logged_in = false; + static int tty_open(int *fd) { int ret; @@ -70,9 +72,7 @@ static int tty_open(int *fd) return ONLP_STATUS_OK; } } - i--; - usleep(100000); } while (i > 0); return ONLP_STATUS_E_GENERIC; } @@ -89,47 +89,37 @@ static int tty_close(int *fd) } static int tty_clear_rxbuf(int fd, char* buf, int max_size) { - int ret; + int ret, i; - if (!buf) { + if (!buf || fd < 0) { return ONLP_STATUS_E_PARAM; } - - if (fd < 0) { - return -1; - } - do { - usleep(100000); ret = read(fd, buf, max_size); - if (ret > 0) - DEBUG_PRINT("clear %d bytes, \"%s\"\n", ret, buf); - memset(buf, 0, max_size); - } while (ret > 0); - + i++; + } while (ret > 0 && i < TTY_RETRY); return ret; } static int tty_write_and_read( int fd, const char *cmd, - unsigned long udelay, char *buf, int buf_size) + uint32_t udelay, char *buf, int buf_size) { int ret, len, retry; + if (fd < 0 || !cmd) { return ONLP_STATUS_E_PARAM; } - tty_clear_rxbuf(fd, buf, buf_size); + len = strlen(cmd) + 1; retry = 0; - len = strlen(cmd)+1; do { ret = write(fd, cmd, len); retry++ ; - } while(ret != len && retry<5 && usleep(100000*retry)); + } while(ret != len && retry < TTY_RETRY && usleep(TTY_RETRY_INTERVAL*retry)); DEBUG_PRINT("sent cmd:%s\n",cmd); usleep(udelay); - usleep(100000); memset(buf, 0, buf_size); ret = read(fd, buf, buf_size); DEBUG_PRINT("Read %d bytes, \"%s\", \n", ret, buf); @@ -137,7 +127,7 @@ static int tty_write_and_read( int fd, const char *cmd, } static int tty_access_and_match( int fd, const char *cmd, - unsigned long udelay, const char *keywd) + uint32_t udelay, const char *keywd) { int num; char resp[256] = {0}; @@ -153,29 +143,38 @@ static int tty_access_and_match( int fd, const char *cmd, static bool is_logged_in(int fd, char *resp, int max_size) { int num; + char *p; - num = tty_write_and_read(fd, "\r\r", TTY_I2C_TIMEOUT, resp, sizeof(resp)); - if (num <= 0) { - return ONLP_STATUS_E_GENERIC; + if (global_logged_in == true) { + return true; + } + + num = tty_write_and_read(fd, "\r\r", TTY_BMC_LOGIN_TIMEOUT, resp, max_size); + if (num <= 0) { + return false; + } + p = strstr(resp, TTY_PROMPT); + if (p != NULL ) { + global_logged_in = true; + return true; + } else { + return false; } - return (strstr(resp, TTY_PROMPT) != NULL) ? - ONLP_STATUS_OK : ONLP_STATUS_E_GENERIC; } -static int tty_login(int fd) +static int tty_login(int fd, char *buf, int buf_size) { int i; - char resp[256]; for (i = 0; i < TTY_LOGIN_RETRY; i++) { - if (is_logged_in(fd, resp, sizeof(resp))) { + if (is_logged_in(fd, buf, buf_size)) { DEBUG_PRINT("Been logged in!\n"); return ONLP_STATUS_OK; } - DEBUG_PRINT("Try to login!\n"); - if (strstr(resp, "bmc") != NULL && - (strstr(resp, "login:") != NULL)) + DEBUG_PRINT("Try to login, @%d!\n", i); + if (strstr(buf, "bmc") != NULL && + (strstr(buf, "login:") != NULL)) { if (!tty_access_and_match(fd, TTY_USER"\r",TTY_BMC_LOGIN_TIMEOUT, "Password:")) { if (!tty_access_and_match(fd, "0penBmc\r", TTY_BMC_LOGIN_TIMEOUT, TTY_PROMPT)) { @@ -184,14 +183,15 @@ static int tty_login(int fd) } } - usleep(50000*i); + usleep(TTY_BMC_LOGIN_INTERVAL*i); } + return ONLP_STATUS_E_GENERIC; } -static int tty_transaction(const char *cmd, unsigned long udelay, char *resp, int max_size) +static int +tty_transaction(const char *cmd, uint32_t udelay, char *resp, int max_size) { - int i; char *buf; int tty_fd = -1; int num, ret = ONLP_STATUS_OK; @@ -205,22 +205,17 @@ static int tty_transaction(const char *cmd, unsigned long udelay, char *resp, in return ONLP_STATUS_E_GENERIC; } - /*Tried to login.*/ - for (i = 0; i < TTY_RETRY; i++) { - if (tty_login(tty_fd) == ONLP_STATUS_OK) { - break; - } - } - if(i == TTY_RETRY) { - AIM_LOG_ERROR("ERROR: Cannot login TTY device\n"); - return ONLP_STATUS_E_GENERIC; - } buf = (char *)calloc(buf_size, sizeof(char)); if (buf == NULL) { AIM_LOG_ERROR("ERROR: Cannot allocate memory\n"); goto exit; } + ret = tty_login(tty_fd, buf, buf_size); + if (ret != ONLP_STATUS_OK) { + AIM_LOG_ERROR("ERROR: Cannot login TTY device\n"); + goto exit; + } num = tty_write_and_read(tty_fd, cmd, udelay, buf, buf_size); if (num <= 0) { @@ -228,7 +223,6 @@ static int tty_transaction(const char *cmd, unsigned long udelay, char *resp, in goto exit; } strncpy(resp, buf, max_size); - DEBUG_PRINT("Resp:\"%s\", \n", resp); exit: free(buf); tty_close(&tty_fd); @@ -304,7 +298,7 @@ static int strip_off_prompt(char *buf, int max_size) return ONLP_STATUS_OK; } -int bmc_reply_pure(char *cmd, unsigned long udelay, char *resp, int max_size) +int bmc_reply_pure(char *cmd, uint32_t udelay, char *resp, int max_size) { int i, ret = 0; char *p; @@ -324,7 +318,7 @@ int bmc_reply_pure(char *cmd, unsigned long udelay, char *resp, int max_size) /*Find if cmd is inside the response.*/ p = strstr(resp, cmd); if (p != NULL) { - memcpy(resp, p+strlen(cmd), max_size); + memcpy(resp, p+strlen(cmdr), max_size); return ONLP_STATUS_OK; } DEBUG_PRINT("Resp: [%s]\n", resp); @@ -338,7 +332,7 @@ int bmc_reply(char *cmd, char *resp, int max_size) int i, ret = 0; for (i = 1; i <= TTY_RETRY; i++) { - ret = tty_transaction(cmd, TTY_I2C_TIMEOUT, resp, max_size); + ret = tty_transaction(cmd, TTY_I2C_WAIT_REPLY, resp, max_size); if (ret != ONLP_STATUS_OK) { continue; } @@ -347,12 +341,12 @@ int bmc_reply(char *cmd, char *resp, int max_size) } return ONLP_STATUS_OK; } - AIM_LOG_ERROR("Unable to send command to bmc(%s)\r\n", cmd); + DEBUG_PRINT("Unable to send command to bmc(%s)\r\n", cmd); return ONLP_STATUS_E_GENERIC; } int -bmc_command_read_int(int* value, char *cmd, int base) +bmc_command_read_int(int *value, char *cmd, int base) { int len; int i; @@ -360,7 +354,7 @@ bmc_command_read_int(int* value, char *cmd, int base) char *prev_str = NULL; char *current_str= NULL; - if (bmc_reply(cmd, resp, sizeof(resp)) < 0) { + if (bmc_reply(cmd, resp, sizeof(resp)) != ONLP_STATUS_OK) { return ONLP_STATUS_E_INTERNAL; } @@ -467,3 +461,15 @@ bmc_i2c_readraw(uint8_t bus, uint8_t devaddr, uint8_t addr, char* data, int data return 0; } +uint32_t pltfm_create_sem (sem_t *mutex) +{ + int rc; + + rc = sem_init(mutex, 1, 1); + if (rc != 0) { + AIM_DIE("%s failed, errno %d.", __func__, errno); + return ONLP_STATUS_E_INTERNAL; + } + return ONLP_STATUS_OK; +} + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/platform_lib.h b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/platform_lib.h index cb022b6e..eb65ccc7 100755 --- a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/platform_lib.h +++ b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/platform_lib.h @@ -25,6 +25,13 @@ ***********************************************************/ #ifndef __PLATFORM_LIB_H__ #define __PLATFORM_LIB_H__ +#include +#include +#include +#include +#include +#include +#include #include "x86_64_accton_minipack_log.h" @@ -44,7 +51,7 @@ #define CHASSIS_LED_COUNT 2 #define CHASSIS_PSU_COUNT 4 -#define IDPROM_PATH "/sys/bus/i2c/devices/1-0057/eeprom" + #define PLATFOTM_H_TTY_RETRY (5) #define MAXIMUM_TTY_BUFFER_LENGTH 1024 @@ -63,13 +70,20 @@ enum onlp_thermal_id THERMAL_7_ON_MAIN_BROAD, }; -int bmc_reply_pure(char *cmd, unsigned long udelay, char *resp, int max_size); +#define ONLP_PSUI_SHM_KEY (0xF001100 | ONLP_OID_TYPE_PSU) +#define ONLP_SFPI_SHM_KEY (0xF001100 | ONLP_OID_TYPE_MODULE) +#define ONLP_LEDI_SHM_KEY (0xF001100 | ONLP_OID_TYPE_LED) + + +int bmc_reply_pure(char *cmd, uint32_t udelay, char *resp, int max_size); int bmc_reply(char *cmd, char *resp, int max_size); int bmc_file_read_int(int* value, char *file, int base); int bmc_i2c_readb(uint8_t bus, uint8_t devaddr, uint8_t addr); int bmc_i2c_writeb(uint8_t bus, uint8_t devaddr, uint8_t addr, uint8_t value); int bmc_i2c_readw(uint8_t bus, uint8_t devaddr, uint8_t addr, uint16_t *data); int bmc_i2c_readraw(uint8_t bus, uint8_t devaddr, uint8_t addr, char* data, int data_size); +uint32_t pltfm_create_sem (sem_t *mutex); + #endif /* __PLATFORM_LIB_H__ */ diff --git a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/psui.c b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/psui.c old mode 100644 new mode 100755 index 84ca6a81..a635dcb3 --- a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/psui.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/psui.c @@ -43,6 +43,28 @@ enum { PSU4_ID, /*At the right-lower of the front view.*/ }; +typedef struct { + bool valid; + time_t last_poll; + uint32_t present; + char model[ONLP_CONFIG_INFO_STR_MAX]; + char serial[ONLP_CONFIG_INFO_STR_MAX]; + uint32_t status; + uint32_t caps; +} psu_status_t; + +typedef struct { + psu_status_t info[CHASSIS_PSU_COUNT]; + sem_t mutex; +} psus_status_t; + + +#define PMBUS_PATH_STR "/sys/bus/platform/devices/minipack_psensor/%s%d_input" +#define TTY_INTERVAL (300000) /*in useconds*/ +#define PSU_POLL_INTERVAL (24) /*in seconds*/ +#define SEM_LOCK do {sem_wait(&global_psui_st->mutex);} while(0) +#define SEM_UNLOCK do {sem_post(&global_psui_st->mutex);} while(0) + /* * Get all information about the given PSU oid. */ @@ -54,15 +76,38 @@ static onlp_psu_info_t pinfo[] = { {ONLP_PSU_ID_CREATE(PSU3_ID), "PSU-3", 0}, }, { {ONLP_PSU_ID_CREATE(PSU4_ID), "PSU-4", 0}, }, }; +psus_status_t *global_psui_st = NULL; + +/*---------------------------------------------------------*/ +static int psui_create_shm(key_t id) { + int rv; + + if (global_psui_st == NULL) { + rv = onlp_shmem_create(id, sizeof(psus_status_t), + (void**)&global_psui_st); + if (rv >= 0) { + if(pltfm_create_sem(&global_psui_st->mutex) != 0) { + AIM_DIE("%s(): mutex_init failed\n", __func__); + return ONLP_STATUS_E_INTERNAL; + } + } + else { + AIM_DIE("Global %s created failed.", __func__); + } + } + return ONLP_STATUS_OK; +} int onlp_psui_init(void) { + if (psui_create_shm(ONLP_PSUI_SHM_KEY) < 0) { + AIM_DIE("%s::psui_create_shm created failed.", __func__); + return ONLP_STATUS_E_INTERNAL; + } return ONLP_STATUS_OK; } -#define PMBUS_PATH_FORMAT "/sys/bus/platform/devices/minipack_psensor/%s%d_input" - static int onlp_psui_rm_special_char(char* in, char* out, int max) { @@ -85,7 +130,6 @@ onlp_psui_rm_special_char(char* in, char* out, int max) return j; } - static int onlp_psui_get_BMC_info(int pid, onlp_psu_info_t* info) { @@ -105,8 +149,8 @@ onlp_psui_get_BMC_info(int pid, onlp_psu_info_t* info) offset = model; sprintf(cmd, bcmd, bus, addr, offset); memset(info->model, 0, sizeof(info->model)); - if (bmc_reply_pure(cmd, 200000, resp, sizeof(resp)) < 0) { - AIM_LOG_ERROR("Unable to send command to bmc(%s)\r\n", cmd); + if (bmc_reply_pure(cmd, TTY_INTERVAL, resp, sizeof(resp)) < 0) { + DEBUG_PRINT("Unable to send command to bmc(%s)\r\n", cmd); info->status &= ~ONLP_PSU_STATUS_PRESENT; return ONLP_STATUS_OK; } @@ -124,8 +168,8 @@ onlp_psui_get_BMC_info(int pid, onlp_psu_info_t* info) offset = serial; sprintf(cmd, bcmd, bus, addr, offset); memset(info->serial, 0, sizeof(info->serial)); - if (bmc_reply_pure(cmd, 200000, resp, sizeof(resp)) < 0) { - AIM_LOG_ERROR("Unable to send command to bmc(%s)\r\n", cmd); + if (bmc_reply_pure(cmd, TTY_INTERVAL, resp, sizeof(resp)) < 0) { + DEBUG_PRINT("Unable to send command to bmc(%s)\r\n", cmd); info->status &= ~ONLP_PSU_STATUS_PRESENT; return ONLP_STATUS_OK; } @@ -133,6 +177,43 @@ onlp_psui_get_BMC_info(int pid, onlp_psu_info_t* info) return ONLP_STATUS_OK; } +static int +onlp_psui_get_string(int pid, onlp_psu_info_t* info) +{ + time_t cur, elapse; + psu_status_t *ps; + + /*Sanity check*/ + if (info == NULL) + return ONLP_STATUS_E_PARAM; + + cur = time (NULL); + SEM_LOCK; + ps = &global_psui_st->info[pid-1]; + elapse = cur - ps->last_poll; + if (!ps->valid || (elapse > PSU_POLL_INTERVAL)) { + if (onlp_psui_get_BMC_info(pid, info) != ONLP_STATUS_OK) + { + ps->valid = false; + SEM_UNLOCK; + return ONLP_STATUS_E_INTERNAL; + } + strncpy(ps->model, info->model, sizeof(ps->model)); + strncpy(ps->serial, info->serial, sizeof(ps->serial)); + ps->status = info->status; + ps->caps = info->caps; + ps->valid = true; + ps->last_poll = time (NULL); + } else { + strncpy(info->model, ps->model, sizeof(info->model)); + strncpy(info->serial, ps->serial, sizeof(info->serial)); + info->status = ps->status; + info->caps = ps->caps; + } + SEM_UNLOCK; + return ONLP_STATUS_OK; +} + int onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) { @@ -145,8 +226,7 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) /* Get the present status */ - - if (onlp_psui_get_BMC_info(pid, info) != ONLP_STATUS_OK) + if (onlp_psui_get_string(pid, info) != ONLP_STATUS_OK) { return ONLP_STATUS_E_INTERNAL; } @@ -159,10 +239,10 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) DEBUG_PRINT("in%d_input: for pid:%d\n",pid_in, pid); /* Read vin */ - sprintf(path, PMBUS_PATH_FORMAT, "in", pid_in); + sprintf(path, PMBUS_PATH_STR, "in", pid_in); if (onlp_file_read_int(&value, path) < 0) { - AIM_LOG_ERROR("Unable to read status from file (%s)\r\n", path); - return ONLP_STATUS_E_INTERNAL; + DEBUG_PRINT("Unable to read status from file (%s)\r\n", path); + value = 0; } if (value >= 1000) { @@ -171,10 +251,10 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) } /* Read iin */ - sprintf(path, PMBUS_PATH_FORMAT, "curr", pid_in); + sprintf(path, PMBUS_PATH_STR, "curr", pid_in); if (onlp_file_read_int(&value, path) < 0) { - AIM_LOG_ERROR("Unable to read status from file (%s)\r\n", path); - return ONLP_STATUS_E_INTERNAL; + DEBUG_PRINT("Unable to read status from file (%s)\r\n", path); + value = 0; } if (value >= 0) { info->miin = value; @@ -182,20 +262,20 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) } /* Get pin */ - sprintf(path, PMBUS_PATH_FORMAT, "power", pid_in); + sprintf(path, PMBUS_PATH_STR, "power", pid_in); if (onlp_file_read_int(&value, path) < 0) { - AIM_LOG_ERROR("Unable to read status from file (%s)\r\n", path); - return ONLP_STATUS_E_INTERNAL; + DEBUG_PRINT("Unable to read status from file (%s)\r\n", path); + value = 0; } if (value >= 0) { info->mpin = value / 1000; /*power is in unit of microWatts.*/ info->caps |= ONLP_PSU_CAPS_PIN; } /* Get vout */ - sprintf(path, PMBUS_PATH_FORMAT, "in", pid_out); + sprintf(path, PMBUS_PATH_STR, "in", pid_out); if (onlp_file_read_int(&value, path) < 0) { - AIM_LOG_ERROR("Unable to read status from file (%s)\r\n", path); - return ONLP_STATUS_E_INTERNAL; + DEBUG_PRINT("Unable to read status from file (%s)\r\n", path); + value = 0; } if (value >= 0) { info->mvout = value; @@ -203,10 +283,10 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) } /* Read iout */ - sprintf(path, PMBUS_PATH_FORMAT, "curr", pid_out); + sprintf(path, PMBUS_PATH_STR, "curr", pid_out); if (onlp_file_read_int(&value, path) < 0) { - AIM_LOG_ERROR("Unable to read status from file (%s)\r\n", path); - return ONLP_STATUS_E_INTERNAL; + DEBUG_PRINT("Unable to read status from file (%s)\r\n", path); + value = 0; } if (value >= 0) { info->miout = value; @@ -214,16 +294,16 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) } /* Read pout */ - sprintf(path, PMBUS_PATH_FORMAT, "power", pid_out); + sprintf(path, PMBUS_PATH_STR, "power", pid_out); if (onlp_file_read_int(&value, path) < 0) { - AIM_LOG_ERROR("Unable to read status from file (%s)\r\n", path); - return ONLP_STATUS_E_INTERNAL; + DEBUG_PRINT("Unable to read status from file (%s)\r\n", path); + value = 0; } if (value >= 0) { info->mpout = value/1000; /*power is in unit of microWatts.*/; info->caps |= ONLP_PSU_CAPS_POUT; } - return 0; + return ONLP_STATUS_OK; } int diff --git a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/sfpi.c b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/sfpi.c old mode 100755 new mode 100644 index 9065186b..29deb3ff --- a/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/sfpi.c @@ -26,24 +26,23 @@ #include #include #include -#include +#include +#include #include "platform_lib.h" #include "x86_64_accton_minipack_log.h" -#define NUM_OF_PIM (8) -#define TYPES_OF_PIM (2) -#define NUM_OF_SFP_PORT (128) -#define SFP_PORT_PER_PIM (NUM_OF_SFP_PORT/NUM_OF_PIM) -#define PORT_EEPROM_FORMAT "/sys/bus/i2c/devices/%d-0050/eeprom" - /* PIM stands for "Port Interface Module". * For minipack, there are hot-pluggable 8 PIMs. * Each PIM can have 16*16Q or 4*4DD ports. */ +#define NUM_OF_PIM (8) +#define TYPES_OF_PIM (2) +#define NUM_OF_SFP_PORT (128) +#define SFP_PORT_PER_PIM (NUM_OF_SFP_PORT/NUM_OF_PIM) #define I2C_BUS (1) -#define PIM_POLL_INTERVAL (8) /*in seconds*/ -#define PORT_POLL_INTERVAL (5) /*per PIM, in seconds*/ - +#define PIM_POLL_INTERVAL (5) /*in seconds*/ +#define PORT_POLL_INTERVAL (8) /*per PIM, in seconds*/ +#define PORT_EEPROM_FORMAT "/sys/bus/i2c/devices/%d-0050/eeprom" typedef struct { bool valid; @@ -54,32 +53,67 @@ typedef struct { typedef struct { present_status_t pim; present_status_t port_at_pim[NUM_OF_SFP_PORT/NUM_OF_PIM]; -} port_status_t; -static port_status_t ps; + sem_t mutex; +} sfpi_port_status_t; + +static int sfpi_eeprom_close_all_channels(void); +static int onlp_read_pim_present(uint32_t *bmap); + +#define SEM_LOCK do {sem_wait(&global_sfpi_st->mutex);} while(0) +#define SEM_UNLOCK do {sem_post(&global_sfpi_st->mutex);} while(0) + +sfpi_port_status_t *global_sfpi_st = NULL; + /************************************************************ * * SFPI Entry Points * ***********************************************************/ -static int -sfpi_eeprom_close_all_channels(void); +static int sfpi_create_shm(key_t id) { + int rv; -int -onlp_sfpi_init(void) + if (global_sfpi_st == NULL) { + rv = onlp_shmem_create(id, sizeof(sfpi_port_status_t), + (void**)&global_sfpi_st); + if (rv >= 0) { + if(pltfm_create_sem(&global_sfpi_st->mutex) != 0) { + AIM_DIE("onlpi_create_sem(): mutex_init failed\n"); + return ONLP_STATUS_E_INTERNAL; + } + } + else { + AIM_DIE("Global %s created failed.", __func__); + } + } + return ONLP_STATUS_OK; +} + +static int update_ports(int pim, bool valid, uint32_t present) { + present_status_t *ports; + + SEM_LOCK; + ports = &global_sfpi_st->port_at_pim[pim]; + ports->valid = valid; + ports->present = present; + ports->last_poll = time (NULL); + + SEM_UNLOCK; + return ONLP_STATUS_OK; +} + +int onlp_sfpi_init(void) { - /* Called at initialization time */ - memset(&ps, 0, sizeof(ps)); + if (sfpi_create_shm(ONLP_SFPI_SHM_KEY) < 0) { + AIM_DIE("onlp_sfpi_init::sfpi_create_shm created failed."); + return ONLP_STATUS_E_INTERNAL; + } sfpi_eeprom_close_all_channels(); return ONLP_STATUS_OK; } -int -onlp_sfpi_bitmap_get(onlp_sfp_bitmap_t* bmap) +int onlp_sfpi_bitmap_get(onlp_sfp_bitmap_t* bmap) { - /* - * Ports {0, 32} - */ int p; AIM_BITMAP_CLR_ALL(bmap); @@ -102,7 +136,7 @@ onlp_sfpi_bitmap_get(onlp_sfp_bitmap_t* bmap) ... same order for port 8-15. */ static uint32_t -onlp_sfpi_reg_val_to_port_sequence(uint32_t value, int revert) +_sfpi_port_present_remap_reg(uint32_t value) { int i, j; uint32_t ret = 0; @@ -117,11 +151,27 @@ onlp_sfpi_reg_val_to_port_sequence(uint32_t value, int revert) ret |= (!!(value & BIT(j)) << i); } - return revert ? ~ret : ret; + return ret; } +static int +onlp_read_pim_present(uint32_t *bmap) +{ + uint32_t present; + int bus = 12; + int addr = 0x3e; + int offset = 0x32; -/* "PIM" stands for "Port Interface Module". + present = bmc_i2c_readb(bus, addr, offset); + if (present < 0) { + *bmap = 0; + return ONLP_STATUS_E_INTERNAL; + } + *bmap = ~present; + return ONLP_STATUS_OK; +} + +/* "PIM" stands for "Port Interface Module". They are hot-pluggable. * A pim can have 16 QSFP ports of 100Gbps, or 4 DD ports of 400 Gbps. * * Return 1 if present. @@ -133,40 +183,36 @@ onlp_pim_is_present(int pim) { time_t cur, elapse; uint32_t present; - int bus = 12; - int addr = 0x3e; - int offset = 0x32; + int ret; + sfpi_port_status_t *ps; + SEM_LOCK; + ps = global_sfpi_st; cur = time (NULL); - elapse = cur - ps.pim.last_poll; - - if (!ps.pim.valid || (elapse > PIM_POLL_INTERVAL)) { - present = bmc_i2c_readb(bus, addr, offset); - if (present < 0) { - ps.pim.valid = 0; - ps.pim.present = 0xff; /*1 means absent*/ - present = 0xff; + elapse = cur - ps->pim.last_poll; + if (!ps->pim.valid || (elapse > PIM_POLL_INTERVAL)) { + ret = onlp_read_pim_present(&present); + if (ret < 0) { + ps->pim.valid = false; + ps->pim.present = 0; + present = 0; + SEM_UNLOCK; return ONLP_STATUS_E_INTERNAL; + } else { + ps->pim.valid = true; + ps->pim.present = present; + ps->pim.last_poll = time (NULL); } - ps.pim.valid = 1; - ps.pim.present = present; - ps.pim.last_poll = time (NULL); } else { - present = ps.pim.present; + present = ps->pim.present; } - - return !(present & BIT(pim % NUM_OF_PIM)); -} - -static int update_ports(present_status_t *ports, uint32_t present) { - ports->valid = 1; - ports->present = present; - ports->last_poll = time (NULL); - return ONLP_STATUS_OK; + SEM_UNLOCK; + return !!(present & BIT(pim % NUM_OF_PIM)); } -/*bit_array is the present bitmap of a PIM, not all ports of PIMs.*/ + +/*bit_array is the present bitmap of a PIM, not all ports on this machine.*/ static int get_pim_port_present_bmap(int port, uint32_t *bit_array) { @@ -179,136 +225,40 @@ get_pim_port_present_bmap(int port, uint32_t *bit_array) int offset = 0x12; pim = port/SFP_PORT_PER_PIM; - ports = &ps.port_at_pim[pim]; - /*If PIM not present, set all 1's to pbmap.*/ + /*If PIM not present, set all 0's to pbmap.*/ if(onlp_pim_is_present(pim) == 0) { - update_ports(ports, 0xffff); - *bit_array = onlp_sfpi_reg_val_to_port_sequence(ports->present, 0); + present = 0; + update_ports(pim, 0, present); + *bit_array = _sfpi_port_present_remap_reg(present); return ONLP_STATUS_OK; } + ports = &global_sfpi_st->port_at_pim[pim]; cur = time (NULL); elapse = cur - ports->last_poll; + if (!ports->valid || (elapse > PORT_POLL_INTERVAL)) { ret = bmc_i2c_readw(bus[pim], addr[0], offset, (uint16_t*)&present); if (ret < 0) { - ports->valid = 0; - ports->present = 0xffff; /*No needs to flip in port order.*/ - *bit_array = 0xffff; /*No needs to flip in port order.*/ + present = 0; + update_ports(pim, 0, present); + *bit_array = present; /*No needs for remmaped.*/ return ONLP_STATUS_E_INTERNAL; + } else { + present = ~present; + update_ports(pim, 1, present); } - update_ports(ports, present); } else { present = ports->present; } - - *bit_array = onlp_sfpi_reg_val_to_port_sequence(present, 0); + *bit_array = _sfpi_port_present_remap_reg(present); return ONLP_STATUS_OK; } -int -onlp_sfpi_is_present(int port) -{ - /* - * Return 1 if present. - * Return 0 if not present. - * Return < 0 if error. - */ - int present, pim, ret; - uint32_t bit_array; - - pim = port/SFP_PORT_PER_PIM; - present = onlp_pim_is_present(pim); - if (present < 0) { - return present; - } - if (!present) { - update_ports(&ps.port_at_pim[pim], 0xff); - return 0; - } - - ret = get_pim_port_present_bmap(port, &bit_array); - if (ret < 0) { - return ret; - } - - return !(bit_array & BIT(port % SFP_PORT_PER_PIM)); -} - - -int -onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) -{ - int i, port, ret; - uint32_t bmp; - uint32_t bmap_pim[NUM_OF_PIM] = {0}; - - /*Get present bitmap per PIM.*/ - for (i = 0; i < NUM_OF_PIM; i++) { - port = i*SFP_PORT_PER_PIM; - ret = get_pim_port_present_bmap(port, &bmap_pim[i]); - if (ret < 0) - return ret; - } - - for (i = 0; i < NUM_OF_SFP_PORT; i++) { - AIM_BITMAP_CLR(dst, i); - } - for (i = 0; i < NUM_OF_SFP_PORT; i++) { - bmp = bmap_pim[i/SFP_PORT_PER_PIM]; - if (!(bmp & BIT(i%SFP_PORT_PER_PIM))) { - AIM_BITMAP_SET(dst, i); - } - } - - return ONLP_STATUS_OK; -} - -int -onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) -{ - return ONLP_STATUS_OK; -} - -static int -sfpi_eeprom_close_all_channels(void) -{ - int i, k; - int value = 0 ; - int mux_1st = 0x70; - int mux_2st[] = {0x72, 0x71}; - int offset = 0; - int channels = 8; - - for (i = 0; i < channels; i++) { - if (onlp_pim_is_present(i) != 1) - continue; - - value = 1<