Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions packages/platforms/accton/common/inc/log_ctrl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/************************************************************
* <bsn.cl fy=2026 v=onl>
*
* Copyright 2026 Accton Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0.
*
* </bsn.cl>
************************************************************
*
* Per-key syslog rate limiting shared by Accton ONLP driver
* modules (sfpi.c, fani.c, sysi.c, ...).
*
* Generic primitive:
* struct log_ctrl { int should_log; };
* void syslog_ctrl(struct log_ctrl *arr, int reason,
* const char *fmt, ...);
* void reset_log_ctrl(struct log_ctrl *arr, int count);
*
* Each domain (SFP, fan, ...) defines its own reason enum plus a
* bookkeeping struct bundling a last-known state value with a
* per-reason log_ctrl[] array. The SFP domain lives in this header
* to avoid an extra include; new domains (fan, PSU, ...) should be
* appended below in the same style.
*
* Typical driver-side declaration (SFP example):
*
* static struct sfp_log_mgmt log_mgmt[MAX_PORT + 1] = {
* [0 ... MAX_PORT] = {
* .present_rec = ONLP_STATUS_E_INTERNAL,
* .log_ctrl = {
* [0 ... SFP_LOG_REASON_COUNT - 1] = { .should_log = 1 }
* }
* }
* };
*
* syslog_ctrl(log_mgmt[port].log_ctrl, SFP_PRESENT_UNABLE_TO_GET_STATUS,
* "fmt %d", arg);
* reset_log_ctrl(log_mgmt[port].log_ctrl, SFP_LOG_REASON_COUNT);
*
***********************************************************/
#ifndef __ACCTON_COMMON_LOG_CTRL_H__
#define __ACCTON_COMMON_LOG_CTRL_H__

/* ---------------------------------------------------------------
* Generic throttling primitive
* --------------------------------------------------------------- */

struct log_ctrl {
int should_log;
};

/*
* Emit one syslog(LOG_ERR, ...) line for arr[reason] if its
* should_log flag is set, then clear the flag. Subsequent calls
* with the same (arr, reason) key are silent until reset_log_ctrl()
* re-arms them.
*
* The caller owns the array and must guarantee 0 <= reason < count,
* where count is the size passed to reset_log_ctrl() below.
*/
void syslog_ctrl(struct log_ctrl *arr, int reason, const char *fmt, ...)
__attribute__((format(printf, 3, 4)));

/*
* Re-arm every entry in arr[0..count-1] so the next syslog_ctrl()
* for each reason is emitted again.
*/
void reset_log_ctrl(struct log_ctrl *arr, int count);

/* ---------------------------------------------------------------
* SFP domain
* --------------------------------------------------------------- */

enum sfp_log_reason {
SFP_PRESENT_UNABLE_TO_GET_STATUS,
SFP_EEPROM_UNABLE_TO_GET_DATA,
SFP_EEPROM_UNABLE_TO_GET_DATA_SIZE_DIFF,
SFP_DOM_UNABLE_TO_OPEN_EEPROM_FILE,
SFP_DOM_UNABLE_TO_SET_FILE_POS_INDICATOR,
SFP_DOM_UNABLE_TO_GET_EEPROM_DATA,
SFP_TX_DIS_UNABLE_TO_SET_STATUS,
SFP_TX_DIS_UNABLE_TO_GET_IDENTIFIER,
SFP_TX_DIS_UNABLE_TO_GET_MEM_MODEL,
SFP_TX_DIS_UNABLE_TO_SET_EEPROM_PAGE,
SFP_TX_DIS_UNABLE_TO_GET_CONTROL,
SFP_TX_DIS_UNABLE_TO_SET_BANK,
SFP_TX_DIS_UNABLE_TO_GET_STATUS,
SFP_LP_MODE_UNABLE_TO_GET_IDENTIFIER,
SFP_LP_MODE_UNABLE_TO_SET_STATUS,
SFP_LP_MODE_UNABLE_TO_GET_STATUS,
SFP_RESET_UNABLE_TO_SET_STATUS,
SFP_RESET_UNABLE_TO_GET_STATUS,
SFP_RX_LOS_UNABLE_TO_GET_STATUS,
SFP_TX_FAULT_UNABLE_TO_GET_STATUS,
SFP_MULTIRATE_UNABLE_TO_SET_STATUS,

SFP_LOG_REASON_COUNT,
};

struct sfp_log_mgmt {
int present_rec;
struct log_ctrl log_ctrl[SFP_LOG_REASON_COUNT];
};

#endif /* __ACCTON_COMMON_LOG_CTRL_H__ */
40 changes: 40 additions & 0 deletions packages/platforms/accton/common/src/log_ctrl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/************************************************************
* <bsn.cl fy=2026 v=onl>
*
* Copyright 2026 Accton Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0.
*
* </bsn.cl>
***********************************************************/
#include <stdio.h>
#include <stdarg.h>
#include <syslog.h>

#include "log_ctrl.h"

void
syslog_ctrl(struct log_ctrl *arr, int reason, const char *fmt, ...)
{
char buf[256];
va_list ap;

va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);

if (arr[reason].should_log) {
syslog(LOG_ERR, "%s", buf);
arr[reason].should_log = 0;
}
}

void
reset_log_ctrl(struct log_ctrl *arr, int count)
{
int i;

for (i = 0; i < count; i++) {
arr[i].should_log = 1;
}
}
9 changes: 9 additions & 0 deletions packages/platforms/accton/common/src/make.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
###############################################################################
#
# Common library shared by Accton platform ONLP modules.
#
###############################################################################

LIBRARY := accton_common
$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST)))
include $(BUILDER)/lib.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
#
###############################################################################
THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
x86_64_accton_as4625_54t_INCLUDES := -I $(THIS_DIR)inc
x86_64_accton_as4625_54t_INTERNAL_INCLUDES := -I $(THIS_DIR)src
ACCTON_COMMON := $(THIS_DIR)../../../../../../common
x86_64_accton_as4625_54t_INCLUDES := -I $(THIS_DIR)inc -I $(ACCTON_COMMON)/inc
x86_64_accton_as4625_54t_INTERNAL_INCLUDES := -I $(THIS_DIR)src -I $(ACCTON_COMMON)/inc
x86_64_accton_as4625_54t_DEPENDMODULE_ENTRIES := init:x86_64_accton_as4625_54t ucli:x86_64_accton_as4625_54t

# Pull in the shared accton helper library (log throttling).
include $(ACCTON_COMMON)/src/make.mk
x86_64_accton_as4625_54t_LIBRARIES := accton_common
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <onlplib/file.h>
#include "x86_64_accton_as4625_54t_int.h"
#include "x86_64_accton_as4625_54t_log.h"
#include <syslog.h>
#include "log_ctrl.h"

#define PORT_EEPROM_FORMAT "/sys/bus/i2c/devices/%d-0050/eeprom"
#define MODULE_PRESENT_FORMAT_0 "/sys/bus/i2c/devices/0-0064/module_present_%d"
Expand All @@ -46,12 +48,22 @@
int port_bus_index[] = { 10, 11, 12, 13, 14, 15 };
#define PORT_BUS_INDEX(port) (port_bus_index[port-48])

#define MAX_PORT 53

#define VALIDATE_SFP(_port) \
do { \
if (_port < 48 || _port > 53) \
return ONLP_STATUS_E_UNSUPPORTED; \
} while(0)

static struct sfp_log_mgmt log_mgmt[MAX_PORT+1] = {
[0 ... MAX_PORT] = {
.present_rec = ONLP_STATUS_E_INTERNAL,
.log_ctrl = {
[0 ... SFP_LOG_REASON_COUNT - 1] = { .should_log = 1 }
}
}
};

/************************************************************
*
Expand Down Expand Up @@ -93,12 +105,22 @@ onlp_sfpi_is_present(int port)

if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT_0, port+1) < 0) {
if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT_1, port+1) < 0) {
AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n",
port);
if (log_mgmt[port].present_rec != ONLP_STATUS_E_INTERNAL) {
reset_log_ctrl(log_mgmt[port].log_ctrl, SFP_LOG_REASON_COUNT);
}
log_mgmt[port].present_rec = ONLP_STATUS_E_INTERNAL;

syslog_ctrl(log_mgmt[port].log_ctrl, SFP_PRESENT_UNABLE_TO_GET_STATUS,
"Unable to read present status from port(%d)", port);
return ONLP_STATUS_E_INTERNAL;
}
}

if (present == 1 && present != log_mgmt[port].present_rec) {
reset_log_ctrl(log_mgmt[port].log_ctrl, SFP_LOG_REASON_COUNT);
}
log_mgmt[port].present_rec = present;

return present;
}

Expand All @@ -115,7 +137,7 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
if(fp == NULL) {
fp = fopen(MODULE_PRESENT_ALL_ATTR_1, "r");
if(fp == NULL) {
AIM_LOG_ERROR("Unable to open the module_present_all device file");
syslog(LOG_ERR, "Unable to open the module_present_all device file");
return ONLP_STATUS_E_INTERNAL;
}
}
Expand All @@ -125,7 +147,7 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)

if(count != 1) {
/* Likely a CPLD read timeout. */
AIM_LOG_ERROR("Unable to read the module_present_all device file");
syslog(LOG_ERR, "Unable to read the module_present_all device file");
return ONLP_STATUS_E_INTERNAL;
}

Expand Down Expand Up @@ -166,7 +188,7 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)
if(fp == NULL) {
fp = fopen(MODULE_RXLOS_ALL_ATTR_1, "r");
if(fp == NULL){
AIM_LOG_ERROR("Unable to open the module_rx_los_all device file");
syslog(LOG_ERR, "Unable to open the module_rx_los_all device file");
return ONLP_STATUS_E_INTERNAL;
}
}
Expand All @@ -176,15 +198,15 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)

if(count != 1) {
/* Likely a CPLD read timeout. */
AIM_LOG_ERROR("Unable to read the module_rx_los_all device file");
syslog(LOG_ERR, "Unable to read the module_rx_los_all device file");
return ONLP_STATUS_E_INTERNAL;
}

fp1 = fopen(MODULE_PRESENT_ALL_ATTR_0, "r");
if(fp1 == NULL) {
fp1 = fopen(MODULE_PRESENT_ALL_ATTR_1, "r");
if(fp1 == NULL) {
AIM_LOG_ERROR("Unable to open the module_present_all device file");
syslog(LOG_ERR, "Unable to open the module_present_all device file");
return ONLP_STATUS_E_INTERNAL;
}
}
Expand All @@ -194,7 +216,7 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)

if(count1 != 1) {
/* Likely a CPLD read timeout. */
AIM_LOG_ERROR("Unable to read the module_present_all device file");
syslog(LOG_ERR, "Unable to read the module_present_all device file");
return ONLP_STATUS_E_INTERNAL;
}
/* Mask out non-existant SFP ports */
Expand Down Expand Up @@ -230,12 +252,14 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256])

if (onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT,
PORT_BUS_INDEX(port)) != ONLP_STATUS_OK) {
AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port);
syslog_ctrl(log_mgmt[port].log_ctrl, SFP_EEPROM_UNABLE_TO_GET_DATA,
"Unable to read eeprom from port(%d)", port);
return ONLP_STATUS_E_INTERNAL;
}

if (size != 256) {
AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n"
syslog_ctrl(log_mgmt[port].log_ctrl, SFP_EEPROM_UNABLE_TO_GET_DATA_SIZE_DIFF,
"Unable to read eeprom from port(%d), size is different!"
, port);
return ONLP_STATUS_E_INTERNAL;
}
Expand All @@ -254,22 +278,25 @@ onlp_sfpi_dom_read(int port, uint8_t data[256])
sprintf(file, PORT_EEPROM_FORMAT, PORT_BUS_INDEX(port));
fp = fopen(file, "r");
if(fp == NULL) {
AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)"
syslog_ctrl(log_mgmt[port].log_ctrl, SFP_DOM_UNABLE_TO_OPEN_EEPROM_FILE,
"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)"
syslog_ctrl(log_mgmt[port].log_ctrl, SFP_DOM_UNABLE_TO_SET_FILE_POS_INDICATOR,
"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)"
syslog_ctrl(log_mgmt[port].log_ctrl, SFP_DOM_UNABLE_TO_GET_EEPROM_DATA,
"Unable to read the module_eeprom device file of port(%d)"
, port);
return ONLP_STATUS_E_INTERNAL;
}
Expand All @@ -292,7 +319,8 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value)
, (port+1)) < 0) {
if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT_1
, (port+1)) < 0) {
AIM_LOG_ERROR("Unable to set tx_disable status to port(%d)\r\n"
syslog_ctrl(log_mgmt[port].log_ctrl, SFP_TX_DIS_UNABLE_TO_SET_STATUS,
"Unable to set tx_disable status to port(%d)"
, port);
return ONLP_STATUS_E_INTERNAL;
}
Expand Down Expand Up @@ -325,7 +353,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
< 0) {
if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT_1, (port+1))
< 0) {
AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n"
syslog_ctrl(log_mgmt[port].log_ctrl, SFP_RX_LOS_UNABLE_TO_GET_STATUS,
"Unable to read rx_loss status from port(%d)"
, port);
return ONLP_STATUS_E_INTERNAL;
}
Expand All @@ -340,7 +369,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
< 0) {
if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT_1, (port+1))
< 0) {
AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n"
syslog_ctrl(log_mgmt[port].log_ctrl, SFP_TX_FAULT_UNABLE_TO_GET_STATUS,
"Unable to read tx_fault status from port(%d)"
, port);
return ONLP_STATUS_E_INTERNAL;
}
Expand All @@ -358,7 +388,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
(port+1)) < 0) {
if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT_1,
(port+1)) < 0) {
AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n"
syslog_ctrl(log_mgmt[port].log_ctrl, SFP_TX_DIS_UNABLE_TO_GET_STATUS,
"Unable to read tx_disabled status from port(%d)"
, port);
return ONLP_STATUS_E_INTERNAL;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
#
###############################################################################
THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
x86_64_accton_as4630_54pe_INCLUDES := -I $(THIS_DIR)inc
x86_64_accton_as4630_54pe_INTERNAL_INCLUDES := -I $(THIS_DIR)src
ACCTON_COMMON := $(THIS_DIR)../../../../../../common
x86_64_accton_as4630_54pe_INCLUDES := -I $(THIS_DIR)inc -I $(ACCTON_COMMON)/inc
x86_64_accton_as4630_54pe_INTERNAL_INCLUDES := -I $(THIS_DIR)src -I $(ACCTON_COMMON)/inc
x86_64_accton_as4630_54pe_DEPENDMODULE_ENTRIES := init:x86_64_accton_as4630_54pe ucli:x86_64_accton_as4630_54pe

# Pull in the shared accton helper library (log throttling).
include $(ACCTON_COMMON)/src/make.mk
x86_64_accton_as4630_54pe_LIBRARIES := accton_common
Loading