mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-12-24 16:57:02 +00:00
To shorten the response time, few changes are made.
1. reducing waiting time. 2. use shared memory and caching data. 3. only check if logged in at 1st time. Signed-off-by: roy_lee <roy_lee@accton.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -23,9 +23,7 @@
|
||||
*
|
||||
***********************************************************/
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/file.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <onlplib/file.h>
|
||||
#include <onlp/onlp.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,13 @@
|
||||
***********************************************************/
|
||||
#ifndef __PLATFORM_LIB_H__
|
||||
#define __PLATFORM_LIB_H__
|
||||
#include <unistd.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <onlp/onlp.h>
|
||||
#include <onlp/oids.h>
|
||||
#include <onlplib/file.h>
|
||||
#include <onlplib/shlocks.h>
|
||||
|
||||
#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__ */
|
||||
|
||||
|
||||
|
||||
136
packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/psui.c
Normal file → Executable file
136
packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/psui.c
Normal file → Executable file
@@ -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
|
||||
|
||||
429
packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/sfpi.c
Executable file → Normal file
429
packages/platforms/accton/x86-64/x86-64-accton-minipack/onlp/builds/src/module/src/sfpi.c
Executable file → Normal file
@@ -26,24 +26,23 @@
|
||||
#include <time.h>
|
||||
#include <onlplib/i2c.h>
|
||||
#include <onlp/platformi/sfpi.h>
|
||||
#include <onlplib/file.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#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<<i;
|
||||
/*Open only 1 channel of level-1 mux*/
|
||||
if (onlp_i2c_writeb(I2C_BUS, mux_1st, offset, value, ONLP_I2C_F_FORCE) < 0) {
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
/*Close mux on each PIM.*/
|
||||
for (k = 0; k < AIM_ARRAYSIZE(mux_2st); k++) {
|
||||
if (onlp_i2c_writeb(I2C_BUS, mux_2st[k], offset, 0, ONLP_I2C_F_FORCE) < 0) {
|
||||
; /*return ONLP_STATUS_E_INTERNAL;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*close level-1 mux*/
|
||||
if (onlp_i2c_writeb(I2C_BUS, mux_1st, offset, 0, ONLP_I2C_F_FORCE) < 0) {
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*Retrieve the channel order on a PIM.*/
|
||||
static int
|
||||
sfpi_get_channel_mapping(int port)
|
||||
sfpi_get_i2cmux_mapping(int port)
|
||||
{
|
||||
int pp = port % SFP_PORT_PER_PIM;
|
||||
int index, base;
|
||||
@@ -336,15 +286,14 @@ sfpi_eeprom_channel_open(int port)
|
||||
int offset = 0;
|
||||
|
||||
pim = port/SFP_PORT_PER_PIM;
|
||||
reg = 1 << pim;
|
||||
|
||||
reg = BIT(pim);
|
||||
/*Open only 1 channel of level-1 mux*/
|
||||
if (onlp_i2c_writeb(I2C_BUS, mux_1st, offset, reg, ONLP_I2C_F_FORCE) < 0) {
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
/*Open only 1 channel on that PIM.*/
|
||||
index = sfpi_get_channel_mapping(port);
|
||||
index = sfpi_get_i2cmux_mapping(port);
|
||||
for (i = 0; i < AIM_ARRAYSIZE(mux_2st); i++) {
|
||||
if ((index/8) != i) {
|
||||
reg = 0;
|
||||
@@ -358,35 +307,110 @@ sfpi_eeprom_channel_open(int port)
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Due to PIM can be hot swapped, here the eeprom driver is always at root bus.
|
||||
* To avoid multi-slave condition, only 1 channel is opened on reading.
|
||||
*/
|
||||
|
||||
/*---------------Public APIs------------------------*/
|
||||
int
|
||||
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
|
||||
onlp_sfpi_is_present(int port)
|
||||
{
|
||||
FILE* fp;
|
||||
int ret;
|
||||
char file[64] = {0};
|
||||
/*
|
||||
* Return 1 if present.
|
||||
* Return 0 if not present.
|
||||
* Return < 0 if error.
|
||||
*/
|
||||
int present, pim, ret;
|
||||
uint32_t bit_array;
|
||||
|
||||
ret = sfpi_eeprom_channel_open(port);
|
||||
pim = port/SFP_PORT_PER_PIM;
|
||||
present = onlp_pim_is_present(pim);
|
||||
if (present < 0) {
|
||||
return present;
|
||||
}
|
||||
if (!present) {
|
||||
update_ports(pim, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
ret = get_pim_port_present_bmap(port, &bit_array);
|
||||
if (ret < 0) {
|
||||
AIM_LOG_ERROR("Unable to set i2c channel for the module_eeprom of port(%d, %d)", port, ret);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
sprintf(file, PORT_EEPROM_FORMAT, I2C_BUS);
|
||||
fp = fopen(file, "r");
|
||||
if(fp == NULL) {
|
||||
AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
ret = fread(data, 1, 256, fp);
|
||||
fclose(fp);
|
||||
if (ret != 256) {
|
||||
AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d, %d)", port, ret);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
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)
|
||||
{
|
||||
AIM_BITMAP_CLR_ALL(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;
|
||||
uint32_t present;
|
||||
|
||||
SEM_LOCK;
|
||||
onlp_read_pim_present(&present);
|
||||
|
||||
for (i = 0; i < channels; i++) {
|
||||
if (!(present & BIT(i)))
|
||||
continue;
|
||||
|
||||
value = BIT(i);
|
||||
/*Open only 1 channel of level-1 mux*/
|
||||
if (onlp_i2c_writeb(I2C_BUS, mux_1st, offset, value, ONLP_I2C_F_FORCE) < 0) {
|
||||
SEM_UNLOCK;
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
/*Close mux on each PIM.*/
|
||||
for (k = 0; k < AIM_ARRAYSIZE(mux_2st); k++) {
|
||||
if (onlp_i2c_writeb(I2C_BUS, mux_2st[k], offset, 0, ONLP_I2C_F_FORCE) < 0) {
|
||||
DEBUG_PRINT("Unable to write to I2C slave(0x%x)", mux_2st[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*close level-1 mux*/
|
||||
if (onlp_i2c_writeb(I2C_BUS, mux_1st, offset, 0, ONLP_I2C_F_FORCE) < 0) {
|
||||
SEM_UNLOCK;
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
SEM_UNLOCK;
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
|
||||
@@ -394,38 +418,37 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256])
|
||||
* To avoid multi-slave condition, only 1 channel is opened on reading.
|
||||
*/
|
||||
int
|
||||
onlp_sfpi_dom_read(int port, uint8_t data[256])
|
||||
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
|
||||
{
|
||||
FILE* fp;
|
||||
int ret;
|
||||
int ret, bytes;
|
||||
char file[64] = {0};
|
||||
|
||||
bytes = 256;
|
||||
SEM_LOCK;
|
||||
ret = sfpi_eeprom_channel_open(port);
|
||||
if (ret < 0) {
|
||||
AIM_LOG_ERROR("Unable to set i2c channel for the module_eeprom of port(%d, %d)", port, ret);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
if (ret != ONLP_STATUS_OK) {
|
||||
DEBUG_PRINT("Unable to set i2c channel for the module_eeprom of port(%d, %d)", port, ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sprintf(file, PORT_EEPROM_FORMAT, I2C_BUS);
|
||||
fp = fopen(file, "r");
|
||||
if(fp == NULL) {
|
||||
AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
ret = ONLP_STATUS_E_INTERNAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (fseek(fp, 256, SEEK_CUR) != 0) {
|
||||
fclose(fp);
|
||||
AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
ret = fread(data, 1, 256, fp);
|
||||
ret = fread(data, 1, bytes, fp);
|
||||
fclose(fp);
|
||||
if (ret != 256) {
|
||||
AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d, %d)", port, ret);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
if (ret != bytes) {
|
||||
ret = ONLP_STATUS_E_INTERNAL;
|
||||
goto exit;
|
||||
}
|
||||
return ONLP_STATUS_OK;
|
||||
ret = ONLP_STATUS_OK;
|
||||
exit:
|
||||
SEM_UNLOCK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -37,22 +37,25 @@
|
||||
#include "x86_64_accton_minipack_int.h"
|
||||
#include "x86_64_accton_minipack_log.h"
|
||||
|
||||
#define IDPROM_PATH "/sys/bus/i2c/devices/1-0057/eeprom"
|
||||
|
||||
const char*
|
||||
onlp_sysi_platform_get(void)
|
||||
{
|
||||
return "x86-64-accton-minipack-r0";
|
||||
}
|
||||
|
||||
#define TLV_START_OFFSET (512)
|
||||
#define TLV_START_OFFSET 512
|
||||
#define TLV_DATA_LENGTH 256
|
||||
|
||||
int
|
||||
onlp_sysi_onie_data_get(uint8_t** data, int* size)
|
||||
{
|
||||
FILE* fp;
|
||||
uint8_t* rdata = aim_zmalloc(512);
|
||||
uint8_t* rdata = aim_zmalloc(TLV_DATA_LENGTH);
|
||||
|
||||
/* Temporary solution.
|
||||
* The very start part of eeprom is in FB format.
|
||||
* The very start part of eeprom is in other format.
|
||||
* Real TLV info locates at where else.
|
||||
*/
|
||||
fp = fopen(IDPROM_PATH, "r");
|
||||
@@ -67,9 +70,9 @@ onlp_sysi_onie_data_get(uint8_t** data, int* size)
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
*size = fread(rdata, 1, 256, fp);
|
||||
*size = fread(rdata, 1, TLV_DATA_LENGTH, fp);
|
||||
fclose(fp);
|
||||
if(*size == 256) {
|
||||
if(*size == TLV_DATA_LENGTH) {
|
||||
*data = rdata;
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
@@ -79,6 +82,17 @@ onlp_sysi_onie_data_get(uint8_t** data, int* size)
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
onlp_sysi_onie_data_free(uint8_t* data)
|
||||
{
|
||||
/*If onlp_sysi_onie_data_get() allocated, it has be freed here.*/
|
||||
if (data) {
|
||||
aim_free(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
onlp_sysi_oids_get(onlp_oid_t* table, int max)
|
||||
{
|
||||
|
||||
@@ -53,37 +53,37 @@ static char* directory[] = /* must map with onlp_thermal_id */
|
||||
/* Static values */
|
||||
static onlp_thermal_info_t linfo[] = {
|
||||
{ }, /* Not used */
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE), "CPU Core", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_MAIN_BROAD), "TMP75-1", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE), "CPU Core", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_2_ON_MAIN_BROAD), "TMP75-2", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_MAIN_BROAD), "TMP75-1", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_3_ON_MAIN_BROAD), "TMP75-3", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_2_ON_MAIN_BROAD), "TMP75-2", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_4_ON_MAIN_BROAD), "TMP75-4", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_3_ON_MAIN_BROAD), "TMP75-3", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_5_ON_MAIN_BROAD), "TMP75-5", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_4_ON_MAIN_BROAD), "TMP75-4", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_6_ON_MAIN_BROAD), "TMP75-6", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_5_ON_MAIN_BROAD), "TMP75-5", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_7_ON_MAIN_BROAD), "TMP75-7", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_6_ON_MAIN_BROAD), "TMP75-6", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(THERMAL_7_ON_MAIN_BROAD), "TMP75-7", 0},
|
||||
ONLP_THERMAL_STATUS_PRESENT,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
};
|
||||
|
||||
@@ -112,16 +112,16 @@ onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
|
||||
int tid;
|
||||
char path[64] = {0};
|
||||
VALIDATE(id);
|
||||
|
||||
|
||||
tid = ONLP_OID_ID_GET(id);
|
||||
|
||||
/* Set the onlp_oid_hdr_t and capabilities */
|
||||
|
||||
/* Set the onlp_oid_hdr_t and capabilities */
|
||||
*info = linfo[tid];
|
||||
|
||||
|
||||
/* get path */
|
||||
if (THERMAL_CPU_CORE == tid) {
|
||||
sprintf(path, THERMAL_CPU_CORE_PATH_FORMAT);
|
||||
}else {
|
||||
} else {
|
||||
sprintf(path, THERMAL_PATH_FORMAT, directory[tid]);
|
||||
}
|
||||
|
||||
@@ -130,5 +130,5 @@ onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
return ONLP_STATUS_OK;
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user