enhance get data performance

1. old method: open UART and close UART whenever we need to get information from BMC.
       new method: open UART at beginning, then we use the UART(TTY) device directly.
    2. old method: use onlp_i2c_readw() to get all QSFP/SFP's eeprom data, it spends 128 times i2c access time.
       new method: use OOM's sysfs
                   we also correct the port mapping
    3. reduce the UART(TTY) retry time and timeout time
    4. add PSU's serial number information
This commit is contained in:
Aken Liu
2018-10-24 16:41:27 +08:00
parent c5cfb37aa2
commit fbf6f2adac
5 changed files with 282 additions and 174 deletions

View File

@@ -31,9 +31,9 @@
#define TTY_DEVICE "/dev/ttyACM0"
#define TTY_PROMPT "@bmc:"
#define TTY_I2C_TIMEOUT 800000
#define TTY_I2C_TIMEOUT 55000
#define TTY_BMC_LOGIN_TIMEOUT 1000000
#define TTY_RETRY 10
#define TTY_RETRY 3
#define MAXIMUM_TTY_BUFFER_LENGTH 1024
#define MAXIMUM_TTY_STRING_LENGTH (MAXIMUM_TTY_BUFFER_LENGTH - 1)
@@ -86,6 +86,7 @@ static int tty_exec_buf(unsigned long udelay, const char *str)
write(tty_fd, tty_buf, strlen(tty_buf)+1);
usleep(udelay);
memset(tty_buf, 0, MAXIMUM_TTY_BUFFER_LENGTH);
read(tty_fd, tty_buf, MAXIMUM_TTY_BUFFER_LENGTH);
return (strstr(tty_buf, str) != NULL) ? 0 : -1;
}
@@ -118,26 +119,51 @@ static int tty_login(void)
return -1;
}
int bmc_tty_init(void)
{
int i;
if (tty_fd >= 0){
return 0;
}
for (i = 1; i <= TTY_RETRY; i++) {
if (tty_open() != 0) {
AIM_LOG_ERROR("ERROR: Cannot open TTY device\n");
continue;
}
if (tty_login() != 0) {
AIM_LOG_ERROR("ERROR: Cannot login TTY device\n");
tty_close();
continue;
}
return 0;
}
AIM_LOG_ERROR("Unable to init bmc tty\r\n");
return -1;
}
int bmc_tty_deinit(void)
{
if( tty_fd != -1 ){
tty_close();
}
else{
AIM_LOG_ERROR("ERROR: TTY not open\n");
}
return 0;
}
int bmc_send_command(char *cmd)
{
int i, ret = 0;
for (i = 1; i <= TTY_RETRY; i++) {
if (tty_open() != 0) {
printf("ERROR: Cannot open TTY device\n");
continue;
}
if (tty_login() != 0) {
//printf("ERROR: Cannot login TTY device\n");
tty_close();
continue;
}
snprintf(tty_buf, MAXIMUM_TTY_BUFFER_LENGTH, "%s", cmd);
ret = tty_exec_buf(TTY_I2C_TIMEOUT * i, TTY_PROMPT);
tty_close();
snprintf(tty_buf, MAXIMUM_TTY_BUFFER_LENGTH, "%s", cmd);
ret = tty_exec_buf(TTY_I2C_TIMEOUT, TTY_PROMPT);
if (ret != 0) {
printf("ERROR: bmc_send_command timed out\n");
// AIM_LOG_ERROR("ERROR: bmc_send_command(%s) timed out\n", cmd);
continue;
}
@@ -148,6 +174,63 @@ int bmc_send_command(char *cmd)
return -1;
}
int chk_numeric_char(char *data, int base)
{
int len, i, orig = 0;
if( *data == '\0' ){
return 0;
}
len = (int) strlen(data);
if( base == 10 ){
for( i=0; i<len; i++ ){
if( i && ( *(data+i) == 0xd ) ){
break;
}
if( i && ( *(data+i) == 0xa ) ){
break;
}
if( *(data+i) < '0' ){
return 0;
}
if( *(data+i) > '9' ){
return 0;
}
}
return 1;
}
else if( base == 16 ){
if( !memcmp(data, "0x", 2) ){
if( len <= 2 ){
return 0;
}
orig = 2;
}
else if( !memcmp(data, "0X", 2) ){
if( len <= 2 ){
return 0;
}
orig = 2;
}
for( i=orig; i<len; i++ ){
if( (i > orig) && ( *(data+i) == 0xd ) ){
break;
}
if( (i > orig) && ( *(data+i) == 0xa ) ){
break;
}
if( !( ( (*(data+i) >= '0') && (*(data+i) <= '9') ) ||
( (*(data+i) >= 'A') && (*(data+i) <= 'F') ) ||
( (*(data+i) >= 'a') && (*(data+i) <= 'f') )
)
){
return 0;
}
}
return 1;
}
return 0;
}
int
bmc_command_read_int(int* value, char *cmd, int base)
{
@@ -166,6 +249,9 @@ bmc_command_read_int(int* value, char *cmd, int base)
for (i = 1; i <= TTY_RETRY; i++) {
current_str = strstr(prev_str + len, cmd);
if(current_str == NULL) {
if( !chk_numeric_char(prev_str + len, base) ){
return -1;
}
*value = strtoul(prev_str + len, NULL, base);
break;
}else {

View File

@@ -64,6 +64,9 @@ 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);
int bmc_i2c_readraw(uint8_t bus, uint8_t devaddr, uint8_t addr, char* data, int data_size);
int bmc_tty_init(void);
int bmc_tty_deinit(void);
#endif /* __PLATFORM_LIB_H__ */

View File

@@ -24,6 +24,7 @@
*
***********************************************************/
#include <onlplib/i2c.h>
#include <unistd.h>
#include <onlplib/file.h>
#include <onlp/platformi/psui.h>
#include "platform_lib.h"
@@ -121,6 +122,7 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
if (bmc_i2c_writeb(7, 0x70, 0, value) < 0) {
return ONLP_STATUS_E_INTERNAL;
}
usleep(1200);
/* Read vin */
addr = (pid == PSU1_ID) ? 0x59 : 0x5a;
@@ -164,7 +166,10 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
}
/* Get model name */
return bmc_i2c_readraw(7, addr, 0x9a, info->model, sizeof(info->model));
bmc_i2c_readraw(7, addr, 0x9a, info->model, sizeof(info->model));
/* Get serial number */
return bmc_i2c_readraw(7, addr, 0x9e, info->serial, sizeof(info->serial));
}
int

View File

@@ -32,15 +32,17 @@
#define BIT(i) (1 << (i))
#define NUM_OF_SFP_PORT 64
#define PORT_EEPROM_FORMAT "/sys/bus/i2c/devices/%d-0050/eeprom"
static const int sfp_bus_index[] = {
4, 3, 6, 5, 8, 7, 10, 9,
12, 11, 14, 13, 16, 15, 18, 17,
20, 19, 22, 21, 24, 23, 26, 25,
28, 27, 30, 29, 32, 31, 34, 33,
44, 43, 46, 45, 48, 47, 50, 49,
52, 51, 54, 53, 56, 55, 58, 57,
60, 59, 62, 61, 64, 63, 66, 65,
68, 67, 70, 69, 72, 71, 74, 73,
4, 3, 6, 5, 8, 7, 10, 9,
12, 11, 14, 13, 16, 15, 18, 17,
20, 19, 22, 21, 24, 23, 26, 25,
28, 27, 30, 29, 32, 31, 34, 33,
};
/************************************************************
@@ -103,13 +105,13 @@ onlp_sfpi_is_present(int port)
int offset;
if(port < 16) {
bus = 37;
}else if(port >=16 && port < 32){
bus = 38;
}else if(port >=32 && port < 48){
bus = 77;
}else if(port >=48 && port <= 63){
}else if(port >=16 && port < 32){
bus = 78;
}else if(port >=32 && port < 48){
bus = 37;
}else if(port >=48 && port <= 63){
bus = 38;
}
if ((port < 8) || (port >= 16 && port <= 23) || (port >= 32 && port <= 39) \
@@ -144,19 +146,19 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
{
case 0:
case 1:
bus = 37;
bus = 77;
break;
case 2:
case 3:
bus = 38;
bus = 78;
break;
case 4:
case 5:
bus = 77;
bus = 37;
break;
case 6:
case 7:
bus = 78;
bus = 38;
break;
default:
break;
@@ -193,44 +195,55 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)
return ONLP_STATUS_OK;
}
static int
sfpi_eeprom_read(int port, uint8_t devaddr, uint8_t data[256])
{
int i;
/*
* Read the SFP eeprom into data[]
*
* Return MISSING if SFP is missing.
* Return OK if eeprom is read
*/
memset(data, 0, 256);
for (i = 0; i < 128; i++) {
int bus = sfp_bus_index[port];
int val = onlp_i2c_readw(bus, devaddr, i*2, ONLP_I2C_F_FORCE);
if (val < 0) {
return ONLP_STATUS_E_INTERNAL;
}
data[i*2] = val & 0xff;
data[(i*2)+1] = (val >> 8) & 0xff;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
{
return sfpi_eeprom_read(port, 0x50, data);
int size = 0;
if(port <0 || port >= NUM_OF_SFP_PORT)
return ONLP_STATUS_E_INTERNAL;
memset(data, 0, 256);
if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, sfp_bus_index[port]) != ONLP_STATUS_OK) {
AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
if (size != 256) {
AIM_LOG_ERROR("Unable to read eeprom from port(%d), size(%d) is different!\r\n", port, size);
return ONLP_STATUS_E_INTERNAL;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_dom_read(int port, uint8_t data[256])
{
return sfpi_eeprom_read(port, 0x51, data);
FILE* fp;
char file[64] = {0};
sprintf(file, PORT_EEPROM_FORMAT, sfp_bus_index[port]);
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;
}
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;
}
int 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 ONLP_STATUS_OK;
}
int

View File

@@ -1,114 +1,115 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <unistd.h>
#include <fcntl.h>
#include <onlplib/file.h>
#include <onlp/platformi/sysi.h>
#include <onlp/platformi/ledi.h>
#include <onlp/platformi/thermali.h>
#include <onlp/platformi/fani.h>
#include <onlp/platformi/psui.h>
#include "platform_lib.h"
#include "x86_64_accton_wedge100bf_65x_int.h"
#include "x86_64_accton_wedge100bf_65x_log.h"
const char*
onlp_sysi_platform_get(void)
{
return "x86-64-accton-wedge100bf-65x-r0";
}
int
onlp_sysi_onie_data_get(uint8_t** data, int* size)
{
uint8_t* rdata = aim_zmalloc(256);
if(onlp_file_read(rdata, 256, size, IDPROM_PATH) == ONLP_STATUS_OK) {
if(*size == 256) {
*data = rdata;
return ONLP_STATUS_OK;
}
}
aim_free(rdata);
*size = 0;
return ONLP_STATUS_E_INTERNAL;
}
int
onlp_sysi_oids_get(onlp_oid_t* table, int max)
{
int i;
onlp_oid_t* e = table;
memset(table, 0, max*sizeof(onlp_oid_t));
/* 8 Thermal sensors on the chassis */
for (i = 1; i <= CHASSIS_THERMAL_COUNT; i++) {
*e++ = ONLP_THERMAL_ID_CREATE(i);
}
/* 2 LEDs on the chassis */
for (i = 1; i <= CHASSIS_LED_COUNT; i++) {
*e++ = ONLP_LED_ID_CREATE(i);
}
/* 2 PSUs on the chassis */
for (i = 1; i <= CHASSIS_PSU_COUNT; i++) {
*e++ = ONLP_PSU_ID_CREATE(i);
}
/* 5 Fans on the chassis */
for (i = 1; i <= CHASSIS_FAN_COUNT; i++) {
*e++ = ONLP_FAN_ID_CREATE(i);
}
return 0;
}
int
onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
{
return ONLP_STATUS_OK;
}
void
onlp_sysi_platform_info_free(onlp_platform_info_t* pi)
{
}
int
onlp_sysi_platform_manage_fans(void)
{
return ONLP_STATUS_OK;
}
int
onlp_sysi_platform_manage_leds(void)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <unistd.h>
#include <fcntl.h>
#include <onlplib/file.h>
#include <onlp/platformi/sysi.h>
#include <onlp/platformi/ledi.h>
#include <onlp/platformi/thermali.h>
#include <onlp/platformi/fani.h>
#include <onlp/platformi/psui.h>
#include "platform_lib.h"
#include "x86_64_accton_wedge100bf_65x_int.h"
#include "x86_64_accton_wedge100bf_65x_log.h"
const char*
onlp_sysi_platform_get(void)
{
return "x86-64-accton-wedge100bf-65x-r0";
}
int
onlp_sysi_onie_data_get(uint8_t** data, int* size)
{
uint8_t* rdata = aim_zmalloc(256);
if(onlp_file_read(rdata, 256, size, IDPROM_PATH) == ONLP_STATUS_OK) {
if(*size == 256) {
*data = rdata;
return ONLP_STATUS_OK;
}
}
aim_free(rdata);
*size = 0;
return ONLP_STATUS_E_INTERNAL;
}
int
onlp_sysi_oids_get(onlp_oid_t* table, int max)
{
int i;
onlp_oid_t* e = table;
memset(table, 0, max*sizeof(onlp_oid_t));
/* 8 Thermal sensors on the chassis */
for (i = 1; i <= CHASSIS_THERMAL_COUNT; i++) {
*e++ = ONLP_THERMAL_ID_CREATE(i);
}
/* 2 LEDs on the chassis */
for (i = 1; i <= CHASSIS_LED_COUNT; i++) {
*e++ = ONLP_LED_ID_CREATE(i);
}
/* 2 PSUs on the chassis */
for (i = 1; i <= CHASSIS_PSU_COUNT; i++) {
*e++ = ONLP_PSU_ID_CREATE(i);
}
/* 5 Fans on the chassis */
for (i = 1; i <= CHASSIS_FAN_COUNT; i++) {
*e++ = ONLP_FAN_ID_CREATE(i);
}
bmc_tty_init();
return 0;
}
int
onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
{
return ONLP_STATUS_OK;
}
void
onlp_sysi_platform_info_free(onlp_platform_info_t* pi)
{
}
int
onlp_sysi_platform_manage_fans(void)
{
return ONLP_STATUS_OK;
}
int
onlp_sysi_platform_manage_leds(void)
{
return ONLP_STATUS_E_UNSUPPORTED;
}