From b67df2def1559e3c48b64ad2da2093f21e838f0f Mon Sep 17 00:00:00 2001 From: brandonchuang Date: Thu, 7 Jun 2018 10:42:13 +0800 Subject: [PATCH 1/2] Add new accton platform, AS5916-26XB. --- .../src/python/onl/platform/base.py | 4 + .../configs/x86_64-all/x86_64-all.config | 13 +- .../x86-64-accton-as5916-26xb/.gitignore | 2 + .../x86-64/x86-64-accton-as5916-26xb/Makefile | 1 + .../modules/Makefile | 1 + .../x86-64-accton-as5916-26xb/modules/PKG.yml | 1 + .../modules/builds/.gitignore | 1 + .../modules/builds/Makefile | 6 + .../builds/x86-64-accton-as5916-26xb-fan.c | 457 +++++++ .../builds/x86-64-accton-as5916-26xb-led.c | 465 +++++++ .../builds/x86-64-accton-as5916-26xb-psu.c | 547 ++++++++ .../builds/x86-64-accton-as5916-26xb-sfp.c | 1169 +++++++++++++++++ .../builds/x86-64-accton-as5916-26xb-sys.c | 368 ++++++ .../x86-64-accton-as5916-26xb-thermal.c | 358 +++++ .../x86-64-accton-as5916-26xb/onlp/Makefile | 1 + .../x86-64-accton-as5916-26xb/onlp/PKG.yml | 1 + .../onlp/builds/Makefile | 2 + .../onlp/builds/lib/Makefile | 45 + .../onlp/builds/onlpdump/Makefile | 46 + .../onlp/builds/src/.gitignore | 1 + .../onlp/builds/src/.module | 1 + .../onlp/builds/src/Makefile | 9 + .../onlp/builds/src/README | 6 + .../module/auto/x86_64_accton_as5916_26xb.yml | 50 + .../x86_64_accton_as5916_26xb.x | 14 + .../x86_64_accton_as5916_26xb_config.h | 137 ++ .../x86_64_accton_as5916_26xb_dox.h | 26 + .../x86_64_accton_as5916_26xb_porting.h | 107 ++ .../onlp/builds/src/module/src/Makefile | 9 + .../onlp/builds/src/module/src/fani.c | 232 ++++ .../onlp/builds/src/module/src/ledi.c | 248 ++++ .../onlp/builds/src/module/src/platform_lib.h | 70 + .../onlp/builds/src/module/src/psui.c | 154 +++ .../onlp/builds/src/module/src/sfpi.c | 287 ++++ .../onlp/builds/src/module/src/sysi.c | 103 ++ .../onlp/builds/src/module/src/thermali.c | 138 ++ .../src/x86_64_accton_as5916_26xb_config.c | 80 ++ .../src/x86_64_accton_as5916_26xb_enums.c | 10 + .../src/x86_64_accton_as5916_26xb_int.h | 12 + .../src/x86_64_accton_as5916_26xb_log.c | 18 + .../src/x86_64_accton_as5916_26xb_log.h | 12 + .../src/x86_64_accton_as5916_26xb_module.c | 24 + .../src/x86_64_accton_as5916_26xb_ucli.c | 50 + .../platform-config/Makefile | 1 + .../platform-config/r0/Makefile | 1 + .../platform-config/r0/PKG.yml | 1 + .../src/lib/x86-64-accton-as5916-26xb-r0.yml | 33 + .../x86_64_accton_as5916_26xb_r0/__init__.py | 13 + 48 files changed, 5334 insertions(+), 1 deletion(-) create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/.gitignore create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/PKG.yml create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/.gitignore create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-fan.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-led.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-psu.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-sfp.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-sys.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-thermal.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/PKG.yml create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/lib/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/onlpdump/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.gitignore create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/README create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/auto/x86_64_accton_as5916_26xb.yml create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb.x create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_config.h create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_dox.h create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_porting.h create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/fani.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/ledi.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/platform_lib.h create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/psui.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/sfpi.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/sysi.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/thermali.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_config.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_enums.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_int.h create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_log.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_log.h create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_module.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_ucli.c create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/PKG.yml create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/src/lib/x86-64-accton-as5916-26xb-r0.yml create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/src/python/x86_64_accton_as5916_26xb_r0/__init__.py diff --git a/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py b/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py index 4e5ce87a..f2790225 100755 --- a/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py @@ -535,3 +535,7 @@ class OnlPlatformPortConfig_48x10_6x100(object): class OnlPlatformPortConfig_12x10_3x100(object): PORT_COUNT=15 PORT_CONFIG="12x10 + 3x100" + +class OnlPlatformPortConfig_24x10_2x100(object): + PORT_COUNT=26 + PORT_CONFIG="24x10 + 2x100" diff --git a/packages/base/any/kernels/4.14-lts/configs/x86_64-all/x86_64-all.config b/packages/base/any/kernels/4.14-lts/configs/x86_64-all/x86_64-all.config index d05cf88b..f16bb336 100755 --- a/packages/base/any/kernels/4.14-lts/configs/x86_64-all/x86_64-all.config +++ b/packages/base/any/kernels/4.14-lts/configs/x86_64-all/x86_64-all.config @@ -654,6 +654,7 @@ CONFIG_ACPI_PROCESSOR_CSTATE=y CONFIG_ACPI_PROCESSOR_IDLE=y CONFIG_ACPI_CPPC_LIB=y CONFIG_ACPI_PROCESSOR=y +# CONFIG_ACPI_IPMI is not set CONFIG_ACPI_HOTPLUG_CPU=y # CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set CONFIG_ACPI_THERMAL=y @@ -2413,7 +2414,15 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_TTY_PRINTK is not set CONFIG_HVC_DRIVER=y CONFIG_VIRTIO_CONSOLE=y -# CONFIG_IPMI_HANDLER is not set +CONFIG_IPMI_HANDLER=y +CONFIG_IPMI_DMI_DECODE=y +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=y +CONFIG_IPMI_SI=y +CONFIG_IPMI_SI_PROBE_DEFAULTS=y +# CONFIG_IPMI_SSIF is not set +CONFIG_IPMI_WATCHDOG=y +CONFIG_IPMI_POWEROFF=y CONFIG_HW_RANDOM=y # CONFIG_HW_RANDOM_TIMERIOMEM is not set # CONFIG_HW_RANDOM_INTEL is not set @@ -2715,6 +2724,8 @@ CONFIG_HWMON=y # CONFIG_SENSORS_G762 is not set # CONFIG_SENSORS_GPIO_FAN is not set # CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IBMAEM is not set +# CONFIG_SENSORS_IBMPEX is not set # CONFIG_SENSORS_I5500 is not set CONFIG_SENSORS_CORETEMP=y # CONFIG_SENSORS_IT87 is not set diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/.gitignore b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/.gitignore new file mode 100644 index 00000000..dbe9025a --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/.gitignore @@ -0,0 +1,2 @@ +*x86*64*accton*as5916*26xb*.mk +onlpdump.mk diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/PKG.yml b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/PKG.yml new file mode 100644 index 00000000..32003db8 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/PKG.yml @@ -0,0 +1 @@ +!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5916-26xb ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64" diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/.gitignore b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/.gitignore new file mode 100644 index 00000000..a65b4177 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/.gitignore @@ -0,0 +1 @@ +lib diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/Makefile new file mode 100644 index 00000000..61dd5817 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/Makefile @@ -0,0 +1,6 @@ +KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64 +KMODULES := $(wildcard *.c) +VENDOR := accton +BASENAME := x86-64-accton-as5916-26xb +ARCH := x86_64 +include $(ONL)/make/kmodule.mk diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-fan.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-fan.c new file mode 100644 index 00000000..b54660c1 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-fan.c @@ -0,0 +1,457 @@ +/* + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as5916_54x CPLD1/CPLD2 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as5916_26xb_fan" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_FAN_READ_CMD 0x14 +#define IPMI_FAN_WRITE_CMD 0x15 +#define IPMI_TIMEOUT (5 * HZ) + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static ssize_t set_fan(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_fan(struct device *dev, struct device_attribute *attr, char *buf); +static int as5916_26xb_fan_probe(struct platform_device *pdev); +static int as5916_26xb_fan_remove(struct platform_device *pdev); + +enum fan_id { + FAN_1, + FAN_2, + FAN_3, + FAN_4, + FAN_5, + NUM_OF_FAN +}; + +enum fan_data_index { + FAN_PRESENT, + FAN_PWM, + FAN_SPEED0, + FAN_SPEED1, + FAN_DATA_COUNT +}; + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + ipmi_user_t user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct as5916_26xb_fan_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned char ipmi_resp[20]; + struct ipmi_data ipmi; + unsigned char ipmi_tx_data[3]; /* 0: FAN id, 1: 0x02, 2: PWM */ +}; + +struct as5916_26xb_fan_data *data = NULL; + +static struct platform_driver as5916_26xb_fan_driver = { + .probe = as5916_26xb_fan_probe, + .remove = as5916_26xb_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +#define FAN_PRESENT_ATTR_ID(index) FAN##index##_PRESENT +#define FAN_PWM_ATTR_ID(index) FAN##index##_PWM +#define FAN_RPM_ATTR_ID(index) FAN##index##_INPUT + +#define FAN_ATTR(fan_id) \ + FAN_PRESENT_ATTR_ID(fan_id), \ + FAN_PWM_ATTR_ID(fan_id), \ + FAN_RPM_ATTR_ID(fan_id) + +enum as5916_54x_fan_sysfs_attrs { + FAN_ATTR(1), + FAN_ATTR(2), + FAN_ATTR(3), + FAN_ATTR(4), + FAN_ATTR(5), + NUM_OF_FAN_ATTR, + NUM_OF_PER_FAN_ATTR = (NUM_OF_FAN_ATTR/NUM_OF_FAN) +}; + +/* fan attributes */ +#define DECLARE_FAN_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, show_fan, NULL, FAN##index##_PRESENT); \ + static SENSOR_DEVICE_ATTR(fan##index##_pwm, S_IWUSR | S_IRUGO, show_fan, set_fan, FAN##index##_PWM); \ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, show_fan, NULL, FAN##index##_INPUT) +#define DECLARE_FAN_ATTR(index) \ + &sensor_dev_attr_fan##index##_present.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_pwm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr + +DECLARE_FAN_SENSOR_DEVICE_ATTR(1); +DECLARE_FAN_SENSOR_DEVICE_ATTR(2); +DECLARE_FAN_SENSOR_DEVICE_ATTR(3); +DECLARE_FAN_SENSOR_DEVICE_ATTR(4); +DECLARE_FAN_SENSOR_DEVICE_ATTR(5); + +static struct attribute *as5916_26xb_fan_attributes[] = { + /* fan attributes */ + DECLARE_FAN_ATTR(1), + DECLARE_FAN_ATTR(2), + DECLARE_FAN_ATTR(3), + DECLARE_FAN_ATTR(4), + DECLARE_FAN_ATTR(5), + NULL +}; + +static const struct attribute_group as5916_26xb_fan_group = { + .attrs = as5916_26xb_fan_attributes, +}; + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static struct as5916_26xb_fan_data *as5916_26xb_fan_update_device(void) +{ + int status = 0; + + if (time_before(jiffies, data->last_updated + HZ * 5) && data->valid) { + return data; + } + + mutex_lock(&data->update_lock); + + data->valid = 0; + status = ipmi_send_message(&data->ipmi, IPMI_FAN_READ_CMD, NULL, 0, + data->ipmi_resp, sizeof(data->ipmi_resp)); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_fan(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char fid = attr->index / NUM_OF_PER_FAN_ATTR; + struct as5916_26xb_fan_data *data = NULL; + int value = 0; + int index = 0; + int present = 0; + + data = as5916_26xb_fan_update_device(); + if (!data->valid) { + return -EIO; + } + + index = fid * FAN_DATA_COUNT; /* base index */ + present = !data->ipmi_resp[index + FAN_PRESENT]; + + switch (attr->index) { + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + value = !data->ipmi_resp[index + FAN_PRESENT]; + break; + case FAN1_PWM: + case FAN2_PWM: + case FAN3_PWM: + case FAN4_PWM: + case FAN5_PWM: + value = (data->ipmi_resp[index + FAN_PWM] + 1) * 625 / 100; + break; + case FAN1_INPUT: + case FAN2_INPUT: + case FAN3_INPUT: + case FAN4_INPUT: + case FAN5_INPUT: + value = (int)data->ipmi_resp[index + FAN_SPEED0] | + (int)data->ipmi_resp[index + FAN_SPEED1] << 8; + break; + default: + return -EINVAL; + } + + return sprintf(buf, "%d\n", present ? value : 0); +} + +static ssize_t set_fan(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long pwm; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char fid = attr->index / NUM_OF_PER_FAN_ATTR; + + status = kstrtol(buf, 10, &pwm); + if (status) { + return status; + } + + pwm = (pwm * 100) / 625 - 1; /* Convert pwm to register value */ + + /* Send IPMI write command */ + data->ipmi_tx_data[0] = fid + 1; /* FAN ID base id for ipmi start from 1 */ + data->ipmi_tx_data[1] = 0x02; + data->ipmi_tx_data[2] = pwm; + status = ipmi_send_message(&data->ipmi, IPMI_FAN_WRITE_CMD, + data->ipmi_tx_data, sizeof(data->ipmi_tx_data), NULL, 0); + if (unlikely(status != 0)) { + return status; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + return -EIO; + } + + /* Update pwm to ipmi_resp buffer to prevent from the impact of lazy update */ + data->ipmi_resp[fid * FAN_DATA_COUNT + FAN_PWM] = pwm; + + return count; +} + +static int as5916_26xb_fan_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &as5916_26xb_fan_group); + if (status) { + goto exit; + } + + dev_info(&pdev->dev, "device created\n"); + + return 0; + +exit: + return status; +} + +static int as5916_26xb_fan_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &as5916_26xb_fan_group); + + return 0; +} + +static int __init as5916_26xb_fan_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as5916_26xb_fan_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + data->valid = 0; + + ret = platform_driver_register(&as5916_26xb_fan_driver); + if (ret < 0) { + goto dri_reg_err; + } + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) + goto ipmi_err; + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as5916_26xb_fan_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as5916_26xb_fan_exit(void) +{ + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + platform_driver_unregister(&as5916_26xb_fan_driver); + kfree(data); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("AS5916 26XB fan driver"); +MODULE_LICENSE("GPL"); + +module_init(as5916_26xb_fan_init); +module_exit(as5916_26xb_fan_exit); + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-led.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-led.c new file mode 100644 index 00000000..c89bed39 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-led.c @@ -0,0 +1,465 @@ +/* + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as5916_54x CPLD1/CPLD2 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as5916_26xb_led" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_LED_READ_CMD 0x1A +#define IPMI_LED_WRITE_CMD 0x1B +#define IPMI_TIMEOUT (5 * HZ) + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static ssize_t set_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_led(struct device *dev, struct device_attribute *attr, char *buf); +static int as5916_26xb_led_probe(struct platform_device *pdev); +static int as5916_26xb_led_remove(struct platform_device *pdev); + +enum led_data_index { + LOC_INDEX, + DIAG_RED_INDEX, + DIAG_GREEN_INDEX +}; + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + ipmi_user_t user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct as5916_26xb_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned char ipmi_resp[3]; /* 0: LOC LED, 1: DIAG Red LED, 2: DIAG Green LED */ + struct ipmi_data ipmi; +}; + +struct as5916_26xb_led_data *data = NULL; + +static struct platform_driver as5916_26xb_led_driver = { + .probe = as5916_26xb_led_probe, + .remove = as5916_26xb_led_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +enum led_light_mode { + LED_MODE_OFF, + LED_MODE_RED = 10, + LED_MODE_RED_BLINKING = 11, + LED_MODE_ORANGE = 12, + LED_MODE_ORANGE_BLINKING = 13, + LED_MODE_YELLOW = 14, + LED_MODE_YELLOW_BLINKING = 15, + LED_MODE_GREEN = 16, + LED_MODE_GREEN_BLINKING = 17, + LED_MODE_BLUE = 18, + LED_MODE_BLUE_BLINKING = 19, + LED_MODE_PURPLE = 20, + LED_MODE_PURPLE_BLINKING = 21, + LED_MODE_AUTO = 22, + LED_MODE_AUTO_BLINKING = 23, + LED_MODE_WHITE = 24, + LED_MODE_WHITE_BLINKING = 25, + LED_MODE_CYAN = 26, + LED_MODE_CYAN_BLINKING = 27, + LED_MODE_UNKNOWN = 99 +}; + +enum as5916_54x_led_sysfs_attrs { + LED_LOC, + LED_DIAG, + LED_PSU1, + LED_PSU2, + LED_FAN +}; + +static SENSOR_DEVICE_ATTR(led_loc, S_IWUSR | S_IRUGO, show_led, set_led, LED_LOC); +static SENSOR_DEVICE_ATTR(led_diag, S_IWUSR | S_IRUGO, show_led, set_led, LED_DIAG); +static SENSOR_DEVICE_ATTR(led_psu1, S_IWUSR | S_IRUGO, show_led, set_led, LED_PSU1); +static SENSOR_DEVICE_ATTR(led_psu2, S_IWUSR | S_IRUGO, show_led, set_led, LED_PSU2); +static SENSOR_DEVICE_ATTR(led_fan, S_IWUSR | S_IRUGO, show_led, set_led, LED_FAN); + +static struct attribute *as5916_26xb_led_attributes[] = { + &sensor_dev_attr_led_loc.dev_attr.attr, + &sensor_dev_attr_led_diag.dev_attr.attr, + &sensor_dev_attr_led_psu1.dev_attr.attr, + &sensor_dev_attr_led_psu2.dev_attr.attr, + &sensor_dev_attr_led_fan.dev_attr.attr, + NULL +}; + +static const struct attribute_group as5916_26xb_led_group = { + .attrs = as5916_26xb_led_attributes, +}; + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static struct as5916_26xb_led_data *as5916_26xb_led_update_device(void) +{ + int status = 0; + + if (time_before(jiffies, data->last_updated + HZ * 5) && data->valid) { + return data; + } + + mutex_lock(&data->update_lock); + + data->valid = 0; + status = ipmi_send_message(&data->ipmi, IPMI_LED_READ_CMD, NULL, 0, + data->ipmi_resp, sizeof(data->ipmi_resp)); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_led(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as5916_26xb_led_data *data = NULL; + int value; + + data = as5916_26xb_led_update_device(); + if (!data->valid) { + return -EIO; + } + + switch (attr->index) { + case LED_LOC: + value = data->ipmi_resp[LOC_INDEX] ? LED_MODE_ORANGE_BLINKING : LED_MODE_OFF; + break; + case LED_DIAG: + { + if (data->ipmi_resp[DIAG_GREEN_INDEX] && data->ipmi_resp[DIAG_RED_INDEX]) + value = LED_MODE_OFF; + else if (!data->ipmi_resp[DIAG_GREEN_INDEX] && !data->ipmi_resp[DIAG_RED_INDEX]) + value = LED_MODE_OFF; + else if (data->ipmi_resp[DIAG_RED_INDEX]) + value = LED_MODE_ORANGE; + else if (data->ipmi_resp[DIAG_GREEN_INDEX] == 1) + value = LED_MODE_GREEN_BLINKING; + else + value = LED_MODE_GREEN; + break; + } + case LED_PSU1: + case LED_PSU2: + case LED_FAN: + value = LED_MODE_AUTO; + break; + default: + return -EINVAL; + } + + return sprintf(buf, "%d\n", value); +} + +static ssize_t set_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long mode; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = kstrtol(buf, 10, &mode); + if (status) { + return status; + } + + data = as5916_26xb_led_update_device(); + if (!data->valid) { + return -EIO; + } + + switch (attr->index) { + case LED_LOC: + data->ipmi_resp[LOC_INDEX] = !!mode; + break; + case LED_DIAG: + { + if (mode == LED_MODE_GREEN_BLINKING) { + data->ipmi_resp[DIAG_GREEN_INDEX] = 1; + data->ipmi_resp[DIAG_RED_INDEX] = 0; + } + else if (mode == LED_MODE_GREEN) { + data->ipmi_resp[DIAG_GREEN_INDEX] = 2; + data->ipmi_resp[DIAG_RED_INDEX] = 0; + } + else if (mode == LED_MODE_ORANGE) { + data->ipmi_resp[DIAG_GREEN_INDEX] = 0; + data->ipmi_resp[DIAG_RED_INDEX] = 1; + } + else { /* OFF */ + data->ipmi_resp[DIAG_GREEN_INDEX] = 0; + data->ipmi_resp[DIAG_RED_INDEX] = 0; + } + + break; + } + default: + return -EINVAL; + } + + /* Send IPMI write command */ + status = ipmi_send_message(&data->ipmi, IPMI_LED_WRITE_CMD, + data->ipmi_resp, sizeof(data->ipmi_resp), NULL, 0); + if (unlikely(status != 0)) { + return status; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + return -EIO; + } + + return count; +} + +static int as5916_26xb_led_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &as5916_26xb_led_group); + if (status) { + goto exit; + } + + dev_info(&pdev->dev, "device created\n"); + + return 0; + +exit: + return status; +} + +static int as5916_26xb_led_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &as5916_26xb_led_group); + + return 0; +} + +static int __init as5916_26xb_led_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as5916_26xb_led_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + data->valid = 0; + + ret = platform_driver_register(&as5916_26xb_led_driver); + if (ret < 0) { + goto dri_reg_err; + } + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) + goto ipmi_err; + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as5916_26xb_led_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as5916_26xb_led_exit(void) +{ + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + platform_driver_unregister(&as5916_26xb_led_driver); + kfree(data); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("AS5916 26XB led driver"); +MODULE_LICENSE("GPL"); + +module_init(as5916_26xb_led_init); +module_exit(as5916_26xb_led_exit); + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-psu.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-psu.c new file mode 100644 index 00000000..ba71289b --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-psu.c @@ -0,0 +1,547 @@ +/* + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as5916_54x CPLD1/CPLD2 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as5916_26xb_psu" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_PSU_READ_CMD 0x16 +#define IPMI_PSU_MODEL_NAME_CMD 0x10 +#define IPMI_PSU_SERIAL_NUM_CMD 0x11 +#define IPMI_TIMEOUT (5 * HZ) + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static ssize_t show_psu(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t show_string(struct device *dev, struct device_attribute *attr, char *buf); +static int as5916_26xb_psu_probe(struct platform_device *pdev); +static int as5916_26xb_psu_remove(struct platform_device *pdev); + +enum psu_id { + PSU_1, + PSU_2, + NUM_OF_PSU +}; + +enum psu_data_index { + PSU_PRESENT = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD_CPLD, + PSU_POWER_GOOD_PMBUS, + PSU_OVER_VOLTAGE, + PSU_OVER_CURRENT, + PSU_POWER_ON, + PSU_VIN0, + PSU_VIN1, + PSU_VOUT0, + PSU_VOUT1, + PSU_IOUT0, + PSU_IOUT1, + PSU_TEMP0, + PSU_TEMP1, + PSU_FAN0, + PSU_FAN1, + PSU_POUT0, + PSU_POUT1, + PSU_STATUS_COUNT, + PSU_MODEL = 0, + PSU_SERIAL = 0 +}; + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + ipmi_user_t user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct ipmi_psu_resp_data { + char status[19]; + char serial[20]; + char model[9]; +}; + +struct as5916_26xb_psu_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid[2]; /* != 0 if registers are valid, 0: PSU1, 1: PSU2 */ + unsigned long last_updated[2]; /* In jiffies, 0: PSU1, 1: PSU2 */ + struct ipmi_data ipmi; + struct ipmi_psu_resp_data ipmi_resp[2]; /* 0: PSU1, 1: PSU2 */ + unsigned char ipmi_tx_data[2]; +}; + +struct as5916_26xb_psu_data *data = NULL; + +static struct platform_driver as5916_26xb_psu_driver = { + .probe = as5916_26xb_psu_probe, + .remove = as5916_26xb_psu_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +#define PSU_PRESENT_ATTR_ID(index) PSU##index##_PRESENT +#define PSU_POWERGOOD_ATTR_ID(index) PSU##index##_POWER_GOOD +#define PSU_VIN_ATTR_ID(index) PSU##index##_VIN +#define PSU_VOUT_ATTR_ID(index) PSU##index##_VOUT +#define PSU_IOUT_ATTR_ID(index) PSU##index##_IOUT +#define PSU_POUT_ATTR_ID(index) PSU##index##_POUT +#define PSU_MODEL_ATTR_ID(index) PSU##index##_MODEL +#define PSU_SERIAL_ATTR_ID(index) PSU##index##_SERIAL +#define PSU_TEMP_INPUT_ATTR_ID(index) PSU##index##_TEMP_INPUT +#define PSU_FAN_INPUT_ATTR_ID(index) PSU##index##_FAN_INPUT + +#define PSU_ATTR(psu_id) \ + PSU_PRESENT_ATTR_ID(psu_id), \ + PSU_POWERGOOD_ATTR_ID(psu_id), \ + PSU_VIN_ATTR_ID(psu_id), \ + PSU_VOUT_ATTR_ID(psu_id), \ + PSU_IOUT_ATTR_ID(psu_id), \ + PSU_POUT_ATTR_ID(psu_id), \ + PSU_MODEL_ATTR_ID(psu_id), \ + PSU_SERIAL_ATTR_ID(psu_id), \ + PSU_TEMP_INPUT_ATTR_ID(psu_id), \ + PSU_FAN_INPUT_ATTR_ID(psu_id) + +enum as5916_54x_psu_sysfs_attrs { + /* psu attributes */ + PSU_ATTR(1), + PSU_ATTR(2), + NUM_OF_PSU_ATTR, + NUM_OF_PER_PSU_ATTR = (NUM_OF_PSU_ATTR/NUM_OF_PSU) +}; + +/* psu attributes */ +#define DECLARE_PSU_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(psu##index##_present, S_IRUGO, show_psu, NULL, PSU##index##_PRESENT); \ + static SENSOR_DEVICE_ATTR(psu##index##_power_good, S_IRUGO, show_psu, NULL, PSU##index##_POWER_GOOD); \ + static SENSOR_DEVICE_ATTR(psu##index##_vin, S_IRUGO, show_psu, NULL, PSU##index##_VIN); \ + static SENSOR_DEVICE_ATTR(psu##index##_vout, S_IRUGO, show_psu, NULL, PSU##index##_VOUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_iout, S_IRUGO, show_psu, NULL, PSU##index##_IOUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_pout, S_IRUGO, show_psu, NULL, PSU##index##_POUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_model, S_IRUGO, show_string, NULL, PSU##index##_MODEL); \ + static SENSOR_DEVICE_ATTR(psu##index##_serial, S_IRUGO, show_string, NULL, PSU##index##_SERIAL);\ + static SENSOR_DEVICE_ATTR(psu##index##_temp1_input, S_IRUGO, show_psu, NULL, PSU##index##_TEMP_INPUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_fan1_input, S_IRUGO, show_psu, NULL, PSU##index##_FAN_INPUT) +#define DECLARE_PSU_ATTR(index) \ + &sensor_dev_attr_psu##index##_present.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_power_good.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_vin.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_vout.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_iout.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_pout.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_model.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_serial.dev_attr.attr,\ + &sensor_dev_attr_psu##index##_temp1_input.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_fan1_input.dev_attr.attr + +DECLARE_PSU_SENSOR_DEVICE_ATTR(1); +DECLARE_PSU_SENSOR_DEVICE_ATTR(2); + +static struct attribute *as5916_26xb_psu_attributes[] = { + /* psu attributes */ + DECLARE_PSU_ATTR(1), + DECLARE_PSU_ATTR(2), + NULL +}; + +static const struct attribute_group as5916_26xb_psu_group = { + .attrs = as5916_26xb_psu_attributes, +}; + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static struct as5916_26xb_psu_data *as5916_26xb_psu_update_device(struct device_attribute *da) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR; + int status = 0; + + if (time_before(jiffies, data->last_updated[pid] + HZ * 5) && data->valid[pid]) { + return data; + } + + mutex_lock(&data->update_lock); + + data->valid[pid] = 0; + + /* Get status from ipmi */ + data->ipmi_tx_data[0] = pid + 1; /* PSU ID base id for ipmi start from 1 */ + status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, data->ipmi_tx_data, 1, + data->ipmi_resp[pid].status, sizeof(data->ipmi_resp[pid].status)); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + /* Get model name from ipmi */ + data->ipmi_tx_data[1] = 0x10; + status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, data->ipmi_tx_data, 2, + data->ipmi_resp[pid].model, sizeof(data->ipmi_resp[pid].model) - 1); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + /* Get serial number from ipmi */ + data->ipmi_tx_data[1] = 0x11; + status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, data->ipmi_tx_data, 2, + data->ipmi_resp[pid].serial, sizeof(data->ipmi_resp[pid].serial) - 1); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->last_updated[pid] = jiffies; + data->valid[pid] = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +#define VALIDATE_PRESENT_RETURN(id) \ +{ \ + if (data->ipmi_resp[id].status[PSU_PRESENT] != 0) { \ + return -ENXIO; \ + } \ +} + +static ssize_t show_psu(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR; + struct as5916_26xb_psu_data *data = NULL; + int value = 0; + + data = as5916_26xb_psu_update_device(da); + if (!data->valid[pid]) { + return -EIO; + } + + switch (attr->index) { + case PSU1_PRESENT: + case PSU2_PRESENT: + value = !(data->ipmi_resp[pid].status[PSU_PRESENT]); + break; + case PSU1_POWER_GOOD: + case PSU2_POWER_GOOD: + VALIDATE_PRESENT_RETURN(pid); + value = data->ipmi_resp[pid].status[PSU_POWER_GOOD_CPLD]; + break; + case PSU1_VIN: + case PSU2_VIN: + VALIDATE_PRESENT_RETURN(pid); + value = ((int)data->ipmi_resp[pid].status[PSU_VIN0] | + (int)data->ipmi_resp[pid].status[PSU_VIN1] << 8) * 1000; + break; + case PSU1_VOUT: + case PSU2_VOUT: + VALIDATE_PRESENT_RETURN(pid); + value = ((int)data->ipmi_resp[pid].status[PSU_VOUT0] | + (int)data->ipmi_resp[pid].status[PSU_VOUT1] << 8) * 1000; + break; + case PSU1_IOUT: + case PSU2_IOUT: + VALIDATE_PRESENT_RETURN(pid); + value = ((int)data->ipmi_resp[pid].status[PSU_IOUT0] | + (int)data->ipmi_resp[pid].status[PSU_IOUT1] << 8) * 1000; + break; + case PSU1_POUT: + case PSU2_POUT: + VALIDATE_PRESENT_RETURN(pid); + value = ((int)data->ipmi_resp[pid].status[PSU_POUT0] | + (int)data->ipmi_resp[pid].status[PSU_POUT1] << 8) * 1000; + break; + case PSU1_TEMP_INPUT: + case PSU2_TEMP_INPUT: + VALIDATE_PRESENT_RETURN(pid); + value = ((int)data->ipmi_resp[pid].status[PSU_TEMP0] | + (int)data->ipmi_resp[pid].status[PSU_TEMP1] << 8) * 1000; + break; + case PSU1_FAN_INPUT: + case PSU2_FAN_INPUT: + VALIDATE_PRESENT_RETURN(pid); + value = ((int)data->ipmi_resp[pid].status[PSU_FAN0] | + (int)data->ipmi_resp[pid].status[PSU_FAN1] << 8); + break; + default: + return -EINVAL; + } + + return sprintf(buf, "%d\n", value); +} + +static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR; + struct as5916_26xb_psu_data *data; + char *str = NULL; + + data = as5916_26xb_psu_update_device(da); + if (!data->valid[pid]) { + return -EIO; + } + + switch (attr->index) { + case PSU1_MODEL: + case PSU2_MODEL: + VALIDATE_PRESENT_RETURN(pid); + str = data->ipmi_resp[pid].model; + break; + case PSU1_SERIAL: + case PSU2_SERIAL: + VALIDATE_PRESENT_RETURN(pid); + str = data->ipmi_resp[pid].serial; + break; + default: + return -EINVAL; + } + + return sprintf(buf, "%s\n", str); +} + +static int as5916_26xb_psu_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &as5916_26xb_psu_group); + if (status) { + goto exit; + } + + + dev_info(&pdev->dev, "device created\n"); + + return 0; + +exit: + return status; +} + +static int as5916_26xb_psu_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &as5916_26xb_psu_group); + return 0; +} + +static int __init as5916_26xb_psu_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as5916_26xb_psu_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + + ret = platform_driver_register(&as5916_26xb_psu_driver); + if (ret < 0) { + goto dri_reg_err; + } + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) + goto ipmi_err; + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as5916_26xb_psu_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as5916_26xb_psu_exit(void) +{ + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + platform_driver_unregister(&as5916_26xb_psu_driver); + kfree(data); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("AS5916 26XB PSU driver"); +MODULE_LICENSE("GPL"); + +module_init(as5916_26xb_psu_init); +module_exit(as5916_26xb_psu_exit); + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-sfp.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-sfp.c new file mode 100644 index 00000000..20e28815 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-sfp.c @@ -0,0 +1,1169 @@ +/* + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as5916_54x CPLD1/CPLD2 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as5916_26xb_sfp" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_QSFP_READ_CMD 0x10 +#define IPMI_QSFP_WRITE_CMD 0x11 +#define IPMI_SFP_READ_CMD 0x1C +#define IPMI_SFP_WRITE_CMD 0x1D +#define IPMI_TIMEOUT (5 * HZ) +#define IPMI_READ_MAX_LEN 128 + +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +#define NUM_OF_SFP 24 +#define NUM_OF_QSFP 2 + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static ssize_t set_sfp(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_sfp(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_sfp_eeprom(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_qsfp_txdisable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_qsfp_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_qsfp(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_qsfp_eeprom(struct device *dev, struct device_attribute *da, char *buf); +static int as5916_26xb_sfp_probe(struct platform_device *pdev); +static int as5916_26xb_sfp_remove(struct platform_device *pdev); +static ssize_t show_all(struct device *dev, struct device_attribute *da, char *buf); +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_present(void); +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_txdisable(void); +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_txfault(void); +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_rxlos(void); +static struct as5916_26xb_sfp_data *as5916_26xb_qsfp_update_present(void); +static struct as5916_26xb_sfp_data *as5916_26xb_qsfp_update_txdisable(void); +static struct as5916_26xb_sfp_data *as5916_26xb_qsfp_update_reset(void); +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_eeprom(int port); + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + ipmi_user_t user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +enum module_status { + SFP_PRESENT = 0, + SFP_TXDISABLE, + SFP_TXFAULT, + SFP_RXLOS, + NUM_OF_SFP_STATUS, + + QSFP_PRESENT = 0, + QSFP_TXDISABLE, + QSFP_RESET, + NUM_OF_QSFP_STATUS, + + PRESENT_ALL = 0, + RXLOS_ALL +}; + +struct ipmi_sfp_resp_data { + unsigned char eeprom[EEPROM_SIZE]; + char eeprom_valid; + + char sfp_valid[NUM_OF_SFP_STATUS]; /* != 0 if registers are valid */ + unsigned long sfp_last_updated[NUM_OF_SFP_STATUS]; /* In jiffies */ + unsigned char sfp_resp[NUM_OF_SFP_STATUS][NUM_OF_SFP]; /* 0: present, 1: tx-disable + 2: tx-fault, 3: rx-los */ + char qsfp_valid[NUM_OF_QSFP_STATUS]; /* != 0 if registers are valid */ + unsigned long qsfp_last_updated[NUM_OF_SFP_STATUS]; /* In jiffies */ + unsigned char qsfp_resp[NUM_OF_QSFP_STATUS][NUM_OF_QSFP]; /* 0: present, 1: tx-disable, 2: reset */ +}; + +struct as5916_26xb_sfp_data { + struct platform_device *pdev; + struct mutex update_lock; + struct ipmi_data ipmi; + struct ipmi_sfp_resp_data ipmi_resp; + unsigned char ipmi_tx_data[3]; +}; + +struct as5916_26xb_sfp_data *data = NULL; + +static struct platform_driver as5916_26xb_sfp_driver = { + .probe = as5916_26xb_sfp_probe, + .remove = as5916_26xb_sfp_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +#define SFP_PRESENT_ATTR_ID(port) SFP##port##_PRESENT +#define SFP_TXDISABLE_ATTR_ID(port) SFP##port##_TXDISABLE +#define SFP_TXFAULT_ATTR_ID(port) SFP##port##_TXFAULT +#define SFP_RXLOS_ATTR_ID(port) SFP##port##_RXLOS +#define SFP_EEPROM_ATTR_ID(port) SFP##port##_EEPROM + +#define SFP_ATTR(port) \ + SFP_PRESENT_ATTR_ID(port), \ + SFP_TXDISABLE_ATTR_ID(port), \ + SFP_TXFAULT_ATTR_ID(port), \ + SFP_RXLOS_ATTR_ID(port), \ + SFP_EEPROM_ATTR_ID(port) + +#define QSFP_PRESENT_ATTR_ID(port) QSFP##port##_PRESENT +#define QSFP_TXDISABLE_ATTR_ID(port) QSFP##port##_TXDISABLE +#define QSFP_RESET_ATTR_ID(port) QSFP##port##_RESET +#define QSFP_EEPROM_ATTR_ID(port) QSFP##port##_EEPROM + +#define QSFP_ATTR(port) \ + QSFP_PRESENT_ATTR_ID(port), \ + QSFP_TXDISABLE_ATTR_ID(port), \ + QSFP_RESET_ATTR_ID(port), \ + QSFP_EEPROM_ATTR_ID(port) + +enum as5916_54x_sfp_sysfs_attrs { + SFP_ATTR(1), + SFP_ATTR(2), + SFP_ATTR(3), + SFP_ATTR(4), + SFP_ATTR(5), + SFP_ATTR(6), + SFP_ATTR(7), + SFP_ATTR(8), + SFP_ATTR(9), + SFP_ATTR(10), + SFP_ATTR(11), + SFP_ATTR(12), + SFP_ATTR(13), + SFP_ATTR(14), + SFP_ATTR(15), + SFP_ATTR(16), + SFP_ATTR(17), + SFP_ATTR(18), + SFP_ATTR(19), + SFP_ATTR(20), + SFP_ATTR(21), + SFP_ATTR(22), + SFP_ATTR(23), + SFP_ATTR(24), + NUM_OF_SFP_ATTR, + NUM_OF_PER_SFP_ATTR = (NUM_OF_SFP_ATTR/NUM_OF_SFP), +}; + +enum as5916_54x_qsfp_sysfs_attrs { + QSFP_ATTR(25), + QSFP_ATTR(26), + NUM_OF_QSFP_ATTR, + NUM_OF_PER_QSFP_ATTR = (NUM_OF_QSFP_ATTR/NUM_OF_QSFP), +}; + +/* sfp attributes */ +#define DECLARE_SFP_SENSOR_DEVICE_ATTR(port) \ + static SENSOR_DEVICE_ATTR(module_present_##port, S_IRUGO, show_sfp, NULL, SFP##port##_PRESENT); \ + static SENSOR_DEVICE_ATTR(module_tx_disable_##port, S_IWUSR | S_IRUGO, show_sfp, set_sfp, SFP##port##_TXDISABLE); \ + static SENSOR_DEVICE_ATTR(module_tx_fault_##port, S_IRUGO, show_sfp, NULL, SFP##port##_TXFAULT); \ + static SENSOR_DEVICE_ATTR(module_rx_los_##port, S_IRUGO, show_sfp, NULL, SFP##port##_RXLOS); \ + static SENSOR_DEVICE_ATTR(module_eeprom_##port, S_IRUGO, show_sfp_eeprom, NULL, SFP##port##_EEPROM) +#define DECLARE_SFP_ATTR(port) \ + &sensor_dev_attr_module_present_##port.dev_attr.attr, \ + &sensor_dev_attr_module_tx_disable_##port.dev_attr.attr, \ + &sensor_dev_attr_module_tx_fault_##port.dev_attr.attr, \ + &sensor_dev_attr_module_rx_los_##port.dev_attr.attr, \ + &sensor_dev_attr_module_eeprom_##port.dev_attr.attr + +/* qsfp attributes */ +#define DECLARE_QSFP_SENSOR_DEVICE_ATTR(port) \ + static SENSOR_DEVICE_ATTR(module_present_##port, S_IRUGO, show_qsfp, NULL, QSFP##port##_PRESENT); \ + static SENSOR_DEVICE_ATTR(module_tx_disable_##port, S_IWUSR | S_IRUGO, show_qsfp, set_qsfp_txdisable, QSFP##port##_TXDISABLE); \ + static SENSOR_DEVICE_ATTR(module_reset_##port, S_IWUSR | S_IRUGO, show_qsfp, set_qsfp_reset, QSFP##port##_RESET); \ + static SENSOR_DEVICE_ATTR(module_eeprom_##port, S_IRUGO, show_qsfp_eeprom, NULL, QSFP##port##_EEPROM) +#define DECLARE_QSFP_ATTR(port) \ + &sensor_dev_attr_module_present_##port.dev_attr.attr, \ + &sensor_dev_attr_module_tx_disable_##port.dev_attr.attr, \ + &sensor_dev_attr_module_reset_##port.dev_attr.attr, \ + &sensor_dev_attr_module_eeprom_##port.dev_attr.attr + +static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_all, NULL, PRESENT_ALL); \ +static SENSOR_DEVICE_ATTR(module_rxlos_all, S_IRUGO, show_all, NULL, RXLOS_ALL); \ + +DECLARE_SFP_SENSOR_DEVICE_ATTR(1); +DECLARE_SFP_SENSOR_DEVICE_ATTR(2); +DECLARE_SFP_SENSOR_DEVICE_ATTR(3); +DECLARE_SFP_SENSOR_DEVICE_ATTR(4); +DECLARE_SFP_SENSOR_DEVICE_ATTR(5); +DECLARE_SFP_SENSOR_DEVICE_ATTR(6); +DECLARE_SFP_SENSOR_DEVICE_ATTR(7); +DECLARE_SFP_SENSOR_DEVICE_ATTR(8); +DECLARE_SFP_SENSOR_DEVICE_ATTR(9); +DECLARE_SFP_SENSOR_DEVICE_ATTR(10); +DECLARE_SFP_SENSOR_DEVICE_ATTR(11); +DECLARE_SFP_SENSOR_DEVICE_ATTR(12); +DECLARE_SFP_SENSOR_DEVICE_ATTR(13); +DECLARE_SFP_SENSOR_DEVICE_ATTR(14); +DECLARE_SFP_SENSOR_DEVICE_ATTR(15); +DECLARE_SFP_SENSOR_DEVICE_ATTR(16); +DECLARE_SFP_SENSOR_DEVICE_ATTR(17); +DECLARE_SFP_SENSOR_DEVICE_ATTR(18); +DECLARE_SFP_SENSOR_DEVICE_ATTR(19); +DECLARE_SFP_SENSOR_DEVICE_ATTR(20); +DECLARE_SFP_SENSOR_DEVICE_ATTR(21); +DECLARE_SFP_SENSOR_DEVICE_ATTR(22); +DECLARE_SFP_SENSOR_DEVICE_ATTR(23); +DECLARE_SFP_SENSOR_DEVICE_ATTR(24); +DECLARE_QSFP_SENSOR_DEVICE_ATTR(25); +DECLARE_QSFP_SENSOR_DEVICE_ATTR(26); + +static struct attribute *as5916_26xb_sfp_attributes[] = { + /* sfp attributes */ + DECLARE_SFP_ATTR(1), + DECLARE_SFP_ATTR(2), + DECLARE_SFP_ATTR(3), + DECLARE_SFP_ATTR(4), + DECLARE_SFP_ATTR(5), + DECLARE_SFP_ATTR(6), + DECLARE_SFP_ATTR(7), + DECLARE_SFP_ATTR(8), + DECLARE_SFP_ATTR(9), + DECLARE_SFP_ATTR(10), + DECLARE_SFP_ATTR(11), + DECLARE_SFP_ATTR(12), + DECLARE_SFP_ATTR(13), + DECLARE_SFP_ATTR(14), + DECLARE_SFP_ATTR(15), + DECLARE_SFP_ATTR(16), + DECLARE_SFP_ATTR(17), + DECLARE_SFP_ATTR(18), + DECLARE_SFP_ATTR(19), + DECLARE_SFP_ATTR(20), + DECLARE_SFP_ATTR(21), + DECLARE_SFP_ATTR(22), + DECLARE_SFP_ATTR(23), + DECLARE_SFP_ATTR(24), + DECLARE_QSFP_ATTR(25), + DECLARE_QSFP_ATTR(26), + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rxlos_all.dev_attr.attr, + NULL +}; + +static const struct attribute_group as5916_26xb_sfp_group = { + .attrs = as5916_26xb_sfp_attributes, +}; + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_present(void) +{ + int status = 0; + + if (time_before(jiffies, data->ipmi_resp.sfp_last_updated[SFP_PRESENT] + HZ) && + data->ipmi_resp.sfp_valid[SFP_PRESENT]) { + return data; + } + + mutex_lock(&data->update_lock); + + data->ipmi_resp.sfp_valid[SFP_PRESENT] = 0; + + /* Get status from ipmi */ + data->ipmi_tx_data[0] = 0x10; + status = ipmi_send_message(&data->ipmi, IPMI_SFP_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp.sfp_resp[SFP_PRESENT], + sizeof(data->ipmi_resp.sfp_resp[SFP_PRESENT])); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->ipmi_resp.sfp_last_updated[SFP_PRESENT] = jiffies; + data->ipmi_resp.sfp_valid[SFP_PRESENT] = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_txdisable(void) +{ + int status = 0; + + if (time_before(jiffies, data->ipmi_resp.sfp_last_updated[SFP_TXDISABLE] + HZ * 5) && + data->ipmi_resp.sfp_valid[SFP_TXDISABLE]) { + return data; + } + + mutex_lock(&data->update_lock); + + data->ipmi_resp.sfp_valid[SFP_TXDISABLE] = 0; + + /* Get status from ipmi */ + data->ipmi_tx_data[0] = 0x01; + status = ipmi_send_message(&data->ipmi, IPMI_SFP_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp.sfp_resp[SFP_TXDISABLE], + sizeof(data->ipmi_resp.sfp_resp[SFP_TXDISABLE])); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->ipmi_resp.sfp_last_updated[SFP_TXDISABLE] = jiffies; + data->ipmi_resp.sfp_valid[SFP_TXDISABLE] = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_txfault(void) +{ + int status = 0; + + if (time_before(jiffies, data->ipmi_resp.sfp_last_updated[SFP_TXFAULT] + HZ * 5) && + data->ipmi_resp.sfp_valid[SFP_TXFAULT]) { + return data; + } + + mutex_lock(&data->update_lock); + + data->ipmi_resp.sfp_valid[SFP_TXFAULT] = 0; + + /* Get status from ipmi */ + data->ipmi_tx_data[0] = 0x12; + status = ipmi_send_message(&data->ipmi, IPMI_SFP_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp.sfp_resp[SFP_TXFAULT], + sizeof(data->ipmi_resp.sfp_resp[SFP_TXFAULT])); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->ipmi_resp.sfp_last_updated[SFP_TXFAULT] = jiffies; + data->ipmi_resp.sfp_valid[SFP_TXFAULT] = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_rxlos(void) +{ + int status = 0; + + if (time_before(jiffies, data->ipmi_resp.sfp_last_updated[SFP_RXLOS] + HZ * 5) && + data->ipmi_resp.sfp_valid[SFP_RXLOS]) { + return data; + } + + mutex_lock(&data->update_lock); + + data->ipmi_resp.sfp_valid[SFP_RXLOS] = 0; + + /* Get status from ipmi */ + data->ipmi_tx_data[0] = 0x13; + status = ipmi_send_message(&data->ipmi, IPMI_SFP_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp.sfp_resp[SFP_RXLOS], + sizeof(data->ipmi_resp.sfp_resp[SFP_RXLOS])); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->ipmi_resp.sfp_last_updated[SFP_RXLOS] = jiffies; + data->ipmi_resp.sfp_valid[SFP_RXLOS] = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct as5916_26xb_sfp_data *as5916_26xb_qsfp_update_present(void) +{ + int status = 0; + + if (time_before(jiffies, data->ipmi_resp.qsfp_last_updated[QSFP_PRESENT] + HZ) && + data->ipmi_resp.qsfp_valid[QSFP_PRESENT]) { + return data; + } + + mutex_lock(&data->update_lock); + + data->ipmi_resp.qsfp_valid[QSFP_PRESENT] = 0; + + /* Get status from ipmi */ + data->ipmi_tx_data[0] = 0x10; + status = ipmi_send_message(&data->ipmi, IPMI_QSFP_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp.qsfp_resp[QSFP_PRESENT], + sizeof(data->ipmi_resp.qsfp_resp[QSFP_PRESENT])); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->ipmi_resp.qsfp_last_updated[QSFP_PRESENT] = jiffies; + data->ipmi_resp.qsfp_valid[QSFP_PRESENT] = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct as5916_26xb_sfp_data *as5916_26xb_qsfp_update_txdisable(void) +{ + int status = 0; + + if (time_before(jiffies, data->ipmi_resp.qsfp_last_updated[QSFP_TXDISABLE] + HZ * 5) && + data->ipmi_resp.qsfp_valid[QSFP_TXDISABLE]) { + return data; + } + + mutex_lock(&data->update_lock); + + data->ipmi_resp.qsfp_valid[QSFP_TXDISABLE] = 0; + + /* Get status from ipmi */ + data->ipmi_tx_data[0] = 0x01; + status = ipmi_send_message(&data->ipmi, IPMI_QSFP_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp.qsfp_resp[QSFP_TXDISABLE], + sizeof(data->ipmi_resp.qsfp_resp[QSFP_TXDISABLE])); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->ipmi_resp.qsfp_last_updated[QSFP_TXDISABLE] = jiffies; + data->ipmi_resp.qsfp_valid[QSFP_TXDISABLE] = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct as5916_26xb_sfp_data *as5916_26xb_qsfp_update_reset(void) +{ + int status = 0; + + if (time_before(jiffies, data->ipmi_resp.qsfp_last_updated[QSFP_RESET] + HZ * 5) && + data->ipmi_resp.qsfp_valid[QSFP_RESET]) { + return data; + } + + mutex_lock(&data->update_lock); + + data->ipmi_resp.qsfp_valid[QSFP_RESET] = 0; + + /* Get status from ipmi */ + data->ipmi_tx_data[0] = 0x11; + status = ipmi_send_message(&data->ipmi, IPMI_QSFP_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp.qsfp_resp[QSFP_RESET], + sizeof(data->ipmi_resp.qsfp_resp[QSFP_RESET])); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->ipmi_resp.qsfp_last_updated[QSFP_RESET] = jiffies; + data->ipmi_resp.qsfp_valid[QSFP_RESET] = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct as5916_26xb_sfp_data *as5916_26xb_sfp_update_eeprom(int port) +{ + int status = 0, i = 0; + unsigned char cmd = (port <= NUM_OF_SFP) ? IPMI_SFP_READ_CMD : IPMI_QSFP_READ_CMD; + unsigned char ipmi_port_id = (port <= NUM_OF_SFP) ? port : (port - NUM_OF_SFP); + + mutex_lock(&data->update_lock); + + data->ipmi_resp.eeprom_valid = 0; + + for (i = 0; i <= 1; i++) { + data->ipmi_tx_data[0] = ipmi_port_id; + data->ipmi_tx_data[1] = i; /* 0: Get eeprom byte (0~127) from ipmi + 1: Get eeprom byte (128~255) from ipmi */ + status = ipmi_send_message(&data->ipmi, cmd, data->ipmi_tx_data, 2, + data->ipmi_resp.eeprom + i*128, 128); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + } + + data->ipmi_resp.eeprom_valid = 1; + +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_all(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as5916_26xb_sfp_data *data = NULL; + u32 values = 0; + int i; + + switch (attr->index) { + case PRESENT_ALL: + { + data = as5916_26xb_sfp_update_present(); + if (!data->ipmi_resp.sfp_valid[SFP_PRESENT]) { + return -EIO; + } + + data = as5916_26xb_qsfp_update_present(); + if (!data->ipmi_resp.qsfp_valid[QSFP_PRESENT]) { + return -EIO; + } + + /* Update qsfp present status */ + for (i = (NUM_OF_QSFP-1); i >= 0; i--) { + values <<= 1; + values |= (data->ipmi_resp.qsfp_resp[QSFP_PRESENT][i] & 0x1); + } + + /* Update sfp present status */ + for (i = (NUM_OF_SFP-1); i >= 0; i--) { + values <<= 1; + values |= (data->ipmi_resp.sfp_resp[SFP_PRESENT][i] & 0x1); + } + + /* Return values 1 -> 26 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x\n", + 0xFF & values, + 0xFF & (values >> 8), + 0xFF & (values >> 16), + 0x3 & (values >> 24)); + } + case RXLOS_ALL: + { + data = as5916_26xb_sfp_update_rxlos(); + if (!data->ipmi_resp.sfp_valid[SFP_RXLOS]) { + return -EIO; + } + + /* Update sfp rxlos status */ + for (i = (NUM_OF_SFP-1); i >= 0; i--) { + values <<= 1; + values |= !(data->ipmi_resp.sfp_resp[SFP_RXLOS][i] & 0x1); + } + + /* Return values 1 -> 26 in order */ + return sprintf(buf, "%.2x %.2x %.2x\n", + 0xFF & values, + 0xFF & (values >> 8), + 0xFF & (values >> 16)); + } + default: + break; + } + + return 0; +} + +static ssize_t show_sfp(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_SFP_ATTR; /* port id, 0 based */ + struct as5916_26xb_sfp_data *data = NULL; + int value = 0; + + switch (attr->index) { + case SFP1_PRESENT: + case SFP2_PRESENT: + case SFP3_PRESENT: + case SFP4_PRESENT: + case SFP5_PRESENT: + case SFP6_PRESENT: + case SFP7_PRESENT: + case SFP8_PRESENT: + case SFP9_PRESENT: + case SFP10_PRESENT: + case SFP11_PRESENT: + case SFP12_PRESENT: + case SFP13_PRESENT: + case SFP14_PRESENT: + case SFP15_PRESENT: + case SFP16_PRESENT: + case SFP17_PRESENT: + case SFP18_PRESENT: + case SFP19_PRESENT: + case SFP20_PRESENT: + case SFP21_PRESENT: + case SFP22_PRESENT: + case SFP23_PRESENT: + case SFP24_PRESENT: + { + data = as5916_26xb_sfp_update_present(); + if (!data->ipmi_resp.sfp_valid[SFP_PRESENT]) { + return -EIO; + } + + value = data->ipmi_resp.sfp_resp[SFP_PRESENT][pid]; + break; + } + case SFP1_TXDISABLE: + case SFP2_TXDISABLE: + case SFP3_TXDISABLE: + case SFP4_TXDISABLE: + case SFP5_TXDISABLE: + case SFP6_TXDISABLE: + case SFP7_TXDISABLE: + case SFP8_TXDISABLE: + case SFP9_TXDISABLE: + case SFP10_TXDISABLE: + case SFP11_TXDISABLE: + case SFP12_TXDISABLE: + case SFP13_TXDISABLE: + case SFP14_TXDISABLE: + case SFP15_TXDISABLE: + case SFP16_TXDISABLE: + case SFP17_TXDISABLE: + case SFP18_TXDISABLE: + case SFP19_TXDISABLE: + case SFP20_TXDISABLE: + case SFP21_TXDISABLE: + case SFP22_TXDISABLE: + case SFP23_TXDISABLE: + case SFP24_TXDISABLE: + { + data = as5916_26xb_sfp_update_txdisable(); + if (!data->ipmi_resp.sfp_valid[SFP_TXDISABLE]) { + return -EIO; + } + + value = !data->ipmi_resp.sfp_resp[SFP_TXDISABLE][pid]; + break; + } + case SFP1_TXFAULT: + case SFP2_TXFAULT: + case SFP3_TXFAULT: + case SFP4_TXFAULT: + case SFP5_TXFAULT: + case SFP6_TXFAULT: + case SFP7_TXFAULT: + case SFP8_TXFAULT: + case SFP9_TXFAULT: + case SFP10_TXFAULT: + case SFP11_TXFAULT: + case SFP12_TXFAULT: + case SFP13_TXFAULT: + case SFP14_TXFAULT: + case SFP15_TXFAULT: + case SFP16_TXFAULT: + case SFP17_TXFAULT: + case SFP18_TXFAULT: + case SFP19_TXFAULT: + case SFP20_TXFAULT: + case SFP21_TXFAULT: + case SFP22_TXFAULT: + case SFP23_TXFAULT: + case SFP24_TXFAULT: + { + data = as5916_26xb_sfp_update_txfault(); + if (!data->ipmi_resp.sfp_valid[SFP_TXFAULT]) { + return -EIO; + } + + value = data->ipmi_resp.sfp_resp[SFP_TXFAULT][pid]; + break; + } + case SFP1_RXLOS: + case SFP2_RXLOS: + case SFP3_RXLOS: + case SFP4_RXLOS: + case SFP5_RXLOS: + case SFP6_RXLOS: + case SFP7_RXLOS: + case SFP8_RXLOS: + case SFP9_RXLOS: + case SFP10_RXLOS: + case SFP11_RXLOS: + case SFP12_RXLOS: + case SFP13_RXLOS: + case SFP14_RXLOS: + case SFP15_RXLOS: + case SFP16_RXLOS: + case SFP17_RXLOS: + case SFP18_RXLOS: + case SFP19_RXLOS: + case SFP20_RXLOS: + case SFP21_RXLOS: + case SFP22_RXLOS: + case SFP23_RXLOS: + case SFP24_RXLOS: + { + data = as5916_26xb_sfp_update_rxlos(); + if (!data->ipmi_resp.sfp_valid[SFP_RXLOS]) { + return -EIO; + } + + value = !data->ipmi_resp.sfp_resp[SFP_RXLOS][pid]; + break; + } + default: + return -EINVAL; + } + + return sprintf(buf, "%d\n", value); +} + +static ssize_t show_sfp_eeprom(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_SFP_ATTR; /* port id, 0 based */ + struct as5916_26xb_sfp_data *data = NULL; + + data = as5916_26xb_sfp_update_eeprom(pid + 1); + if (!data->ipmi_resp.eeprom_valid) { + return -EIO; + } + + memcpy(buf, data->ipmi_resp.eeprom, sizeof(data->ipmi_resp.eeprom)); + return sizeof(data->ipmi_resp.eeprom); +} + +static ssize_t set_sfp(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_SFP_ATTR; /* port id, 0 based */ + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + disable = !disable; /* the IPMI cmd is 0 for tx-disable and 1 for tx-enable */ + + /* Send IPMI write command */ + data->ipmi_tx_data[0] = pid + 1; /* FAN ID base id for ipmi start from 1 */ + data->ipmi_tx_data[1] = 0x01; + data->ipmi_tx_data[2] = disable; + status = ipmi_send_message(&data->ipmi, IPMI_SFP_WRITE_CMD, + data->ipmi_tx_data, sizeof(data->ipmi_tx_data), NULL, 0); + if (unlikely(status != 0)) { + return status; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + return -EIO; + } + + /* Update to ipmi_resp buffer to prevent from the impact of lazy update */ + data->ipmi_resp.sfp_resp[SFP_TXDISABLE][pid] = disable; + + return count; +} + +static ssize_t show_qsfp(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_QSFP_ATTR; /* port id, 0 based */ + struct as5916_26xb_sfp_data *data = NULL; + int value = 0; + + switch (attr->index) { + case QSFP25_PRESENT: + case QSFP26_PRESENT: + { + data = as5916_26xb_qsfp_update_present(); + if (!data->ipmi_resp.qsfp_valid[QSFP_PRESENT]) { + return -EIO; + } + + value = data->ipmi_resp.qsfp_resp[QSFP_PRESENT][pid]; + break; + } + case QSFP25_TXDISABLE: + case QSFP26_TXDISABLE: + { + data = as5916_26xb_qsfp_update_txdisable(); + if (!data->ipmi_resp.qsfp_valid[QSFP_TXDISABLE]) { + return -EIO; + } + + value = !!data->ipmi_resp.qsfp_resp[QSFP_TXDISABLE][pid]; + break; + } + case QSFP25_RESET: + case QSFP26_RESET: + { + data = as5916_26xb_qsfp_update_reset(); + if (!data->ipmi_resp.qsfp_valid[QSFP_RESET]) { + return -EIO; + } + + value = !data->ipmi_resp.qsfp_resp[QSFP_RESET][pid]; + break; + } + default: + return -EINVAL; + } + + return sprintf(buf, "%d\n", value); +} + +static ssize_t set_qsfp_txdisable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_QSFP_ATTR; /* port id, 0 based */ + struct as5916_26xb_sfp_data *data = NULL; + + data = as5916_26xb_qsfp_update_present(); + if (!data->ipmi_resp.qsfp_valid[QSFP_PRESENT]) { + return -EIO; + } + + if (!data->ipmi_resp.qsfp_resp[QSFP_PRESENT][pid]) { + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + /* Send IPMI write command */ + data->ipmi_tx_data[0] = pid + 1; /* FAN ID base id for ipmi start from 1 */ + data->ipmi_tx_data[1] = 0x01; + data->ipmi_tx_data[2] = disable ? 0xf : 0; + status = ipmi_send_message(&data->ipmi, IPMI_QSFP_WRITE_CMD, + data->ipmi_tx_data, sizeof(data->ipmi_tx_data), NULL, 0); + if (unlikely(status != 0)) { + return status; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + return -EIO; + } + + /* Update to ipmi_resp buffer to prevent from the impact of lazy update */ + data->ipmi_resp.qsfp_resp[QSFP_TXDISABLE][pid] = disable; + + return count; +} + +static ssize_t set_qsfp_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long reset; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_QSFP_ATTR; /* port id, 0 based */ + + status = kstrtol(buf, 10, &reset); + if (status) { + return status; + } + + reset = !reset; /* the IPMI cmd is 0 for reset and 1 for out of reset */ + + /* Send IPMI write command */ + data->ipmi_tx_data[0] = pid + 1; /* FAN ID base id for ipmi start from 1 */ + data->ipmi_tx_data[1] = 0x11; + data->ipmi_tx_data[2] = reset; + status = ipmi_send_message(&data->ipmi, IPMI_QSFP_WRITE_CMD, + data->ipmi_tx_data, sizeof(data->ipmi_tx_data), NULL, 0); + if (unlikely(status != 0)) { + return status; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + return -EIO; + } + + /* Update to ipmi_resp buffer to prevent from the impact of lazy update */ + data->ipmi_resp.qsfp_resp[QSFP_RESET][pid] = reset; + + return count; +} + +static ssize_t show_qsfp_eeprom(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_QSFP_ATTR; /* port id, 0 based */ + struct as5916_26xb_sfp_data *data = NULL; + + data = as5916_26xb_sfp_update_eeprom(pid + 1 + NUM_OF_SFP); + if (!data->ipmi_resp.eeprom_valid) { + return -EIO; + } + + memcpy(buf, data->ipmi_resp.eeprom, sizeof(data->ipmi_resp.eeprom)); + return sizeof(data->ipmi_resp.eeprom); +} + +static int as5916_26xb_sfp_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &as5916_26xb_sfp_group); + if (status) { + goto exit; + } + + dev_info(&pdev->dev, "device created\n"); + + return 0; + +exit: + return status; +} + +static int as5916_26xb_sfp_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &as5916_26xb_sfp_group); + return 0; +} + +static int __init as5916_26xb_sfp_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as5916_26xb_sfp_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + + ret = platform_driver_register(&as5916_26xb_sfp_driver); + if (ret < 0) { + goto dri_reg_err; + } + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) + goto ipmi_err; + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as5916_26xb_sfp_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as5916_26xb_sfp_exit(void) +{ + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + platform_driver_unregister(&as5916_26xb_sfp_driver); + kfree(data); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("AS5916 26XB sfp driver"); +MODULE_LICENSE("GPL"); + +module_init(as5916_26xb_sfp_init); +module_exit(as5916_26xb_sfp_exit); + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-sys.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-sys.c new file mode 100644 index 00000000..e89c962f --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-sys.c @@ -0,0 +1,368 @@ +/* + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as5916_54x CPLD1/CPLD2 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as5916_26xb_sys" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_SYSEEPROM_READ_CMD 0x18 +#define IPMI_TIMEOUT (5 * HZ) +#define IPMI_READ_MAX_LEN 128 + +#define EEPROM_NAME "eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static int as5916_26xb_sys_probe(struct platform_device *pdev); +static int as5916_26xb_sys_remove(struct platform_device *pdev); + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + ipmi_user_t user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct as5916_26xb_sys_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned char ipmi_resp[256]; + struct ipmi_data ipmi; + unsigned char ipmi_tx_data[2]; + struct bin_attribute eeprom; /* eeprom data */ +}; + +struct as5916_26xb_sys_data *data = NULL; + +static struct platform_driver as5916_26xb_sys_driver = { + .probe = as5916_26xb_sys_probe, + .remove = as5916_26xb_sys_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static ssize_t sys_eeprom_read(loff_t off, char *buf, size_t count) +{ + int status = 0; + + if ((off + count) > EEPROM_SIZE) { + return -EINVAL; + } + + data->ipmi_tx_data[0] = off; + data->ipmi_tx_data[1] = (count >= IPMI_READ_MAX_LEN) ? IPMI_READ_MAX_LEN : count; + data->ipmi.rx_msg_data = data->ipmi_resp + off; + data->ipmi.rx_msg_len = data->ipmi_tx_data[1]; + + status = ipmi_send_message(&data->ipmi, IPMI_SYSEEPROM_READ_CMD, data->ipmi_tx_data, sizeof(data->ipmi_tx_data), + data->ipmi_resp + off, data->ipmi_tx_data[1]); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + status = data->ipmi_tx_data[1]; + memcpy(buf, data->ipmi_resp + off, data->ipmi_tx_data[1]); + +exit: + return status; +} + +static ssize_t sysfs_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sys_eeprom_read(off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static int sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IRUGO; + eeprom->read = sysfs_bin_read; + eeprom->write = NULL; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + return sysfs_create_bin_file(kobj, eeprom); +} + +static int sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static int as5916_26xb_sys_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_eeprom_init(&pdev->dev.kobj, &data->eeprom); + if (status) { + goto exit; + } + + dev_info(&pdev->dev, "device created\n"); + + return 0; + +exit: + return status; +} + +static int as5916_26xb_sys_remove(struct platform_device *pdev) +{ + sysfs_eeprom_cleanup(&pdev->dev.kobj, &data->eeprom); + + return 0; +} + +static int __init as5916_26xb_sys_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as5916_26xb_sys_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + data->valid = 0; + + ret = platform_driver_register(&as5916_26xb_sys_driver); + if (ret < 0) { + goto dri_reg_err; + } + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) + goto ipmi_err; + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as5916_26xb_sys_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as5916_26xb_sys_exit(void) +{ + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + platform_driver_unregister(&as5916_26xb_sys_driver); + kfree(data); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("AS5916 26XB System driver"); +MODULE_LICENSE("GPL"); + +module_init(as5916_26xb_sys_init); +module_exit(as5916_26xb_sys_exit); + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-thermal.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-thermal.c new file mode 100644 index 00000000..5557242f --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/modules/builds/x86-64-accton-as5916-26xb-thermal.c @@ -0,0 +1,358 @@ +/* + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as5916_54x CPLD1/CPLD2 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as5916_26xb_thermal" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_THERMAL_READ_CMD 0x12 +#define IPMI_TIMEOUT (5 * HZ) + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf); +static int as5916_26xb_thermal_probe(struct platform_device *pdev); +static int as5916_26xb_thermal_remove(struct platform_device *pdev); + +enum temp_data_index { + TEMP_ADDR, + TEMP_FAULT, + TEMP_INPUT, + TEMP_DATA_COUNT +}; + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + ipmi_user_t user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct as5916_26xb_thermal_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + char ipmi_resp[18]; + struct ipmi_data ipmi; +}; + +struct as5916_26xb_thermal_data *data = NULL; + +static struct platform_driver as5916_26xb_thermal_driver = { + .probe = as5916_26xb_thermal_probe, + .remove = as5916_26xb_thermal_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +enum as5916_54x_thermal_sysfs_attrs { + TEMP1_INPUT, + TEMP2_INPUT, + TEMP3_INPUT, + TEMP4_INPUT, + TEMP5_INPUT, + TEMP6_INPUT +}; + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, TEMP4_INPUT); +static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, TEMP5_INPUT); +static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp, NULL, TEMP6_INPUT); + +static struct attribute *as5916_26xb_thermal_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp6_input.dev_attr.attr, + NULL +}; + +static const struct attribute_group as5916_26xb_thermal_group = { + .attrs = as5916_26xb_thermal_attributes, +}; + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = 0; + int index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ * 5) || !data->valid) { + data->valid = 0; + + status = ipmi_send_message(&data->ipmi, IPMI_THERMAL_READ_CMD, NULL, 0, + data->ipmi_resp, sizeof(data->ipmi_resp)); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + /* Get temp fault status */ + index = attr->index * TEMP_DATA_COUNT + TEMP_FAULT; + if (unlikely(data->ipmi_resp[index] == 0)) { + status = -EIO; + goto exit; + } + + /* Get temperature in degree celsius */ + index = attr->index * TEMP_DATA_COUNT + TEMP_INPUT; + status = data->ipmi_resp[index] * 1000; + + return sprintf(buf, "%d\n", status); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static int as5916_26xb_thermal_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &as5916_26xb_thermal_group); + if (status) { + goto exit; + } + + dev_info(&pdev->dev, "device created\n"); + + return 0; + +exit: + return status; +} + +static int as5916_26xb_thermal_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &as5916_26xb_thermal_group); + + return 0; +} + +static int __init as5916_26xb_thermal_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as5916_26xb_thermal_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + data->valid = 0; + + ret = platform_driver_register(&as5916_26xb_thermal_driver); + if (ret < 0) { + goto dri_reg_err; + } + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) + goto ipmi_err; + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as5916_26xb_thermal_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as5916_26xb_thermal_exit(void) +{ + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + platform_driver_unregister(&as5916_26xb_thermal_driver); + kfree(data); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("AS5916 26XB Thermal driver"); +MODULE_LICENSE("GPL"); + +module_init(as5916_26xb_thermal_init); +module_exit(as5916_26xb_thermal_exit); + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/PKG.yml b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/PKG.yml new file mode 100644 index 00000000..b96bf432 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/PKG.yml @@ -0,0 +1 @@ +!include $ONL_TEMPLATES/onlp-platform-any.yml PLATFORM=x86-64-accton-as5916-26xb ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/Makefile new file mode 100644 index 00000000..e7437cb2 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/Makefile @@ -0,0 +1,2 @@ +FILTER=src +include $(ONL)/make/subdirs.mk diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/lib/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/lib/Makefile new file mode 100644 index 00000000..32b55bb7 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/lib/Makefile @@ -0,0 +1,45 @@ +############################################################ +# +# +# Copyright 2014 BigSwitch Networks, Inc. +# +# 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. +# +# +############################################################ +# +# +############################################################ +include $(ONL)/make/config.amd64.mk + +MODULE := libonlp-x86-64-accton-as5916-26xb +include $(BUILDER)/standardinit.mk + +DEPENDMODULES := AIM IOF x86_64_accton_as5916_26xb onlplib +DEPENDMODULE_HEADERS := sff + +include $(BUILDER)/dependmodules.mk + +SHAREDLIB := libonlp-x86-64-accton-as5916-26xb.so +$(SHAREDLIB)_TARGETS := $(ALL_TARGETS) +include $(BUILDER)/so.mk +.DEFAULT_GOAL := $(SHAREDLIB) + +GLOBAL_CFLAGS += -I$(onlp_BASEDIR)/module/inc +GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1 +GLOBAL_CFLAGS += -fPIC +GLOBAL_LINK_LIBS += -lpthread + +include $(BUILDER)/targets.mk + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/onlpdump/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/onlpdump/Makefile new file mode 100644 index 00000000..40aae7b3 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/onlpdump/Makefile @@ -0,0 +1,46 @@ +############################################################ +# +# +# Copyright 2014 BigSwitch Networks, Inc. +# +# 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. +# +# +############################################################ +# +# +# +############################################################ +include $(ONL)/make/config.amd64.mk + +.DEFAULT_GOAL := onlpdump + +MODULE := onlpdump +include $(BUILDER)/standardinit.mk + +DEPENDMODULES := AIM IOF onlp x86_64_accton_as5916_26xb onlplib onlp_platform_defaults sff cjson cjson_util timer_wheel OS + +include $(BUILDER)/dependmodules.mk + +BINARY := onlpdump +$(BINARY)_LIBRARIES := $(LIBRARY_TARGETS) +include $(BUILDER)/bin.mk + +GLOBAL_CFLAGS += -DAIM_CONFIG_AIM_MAIN_FUNCTION=onlpdump_main +GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1 +GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MAIN=1 +GLOBAL_LINK_LIBS += -lpthread -lm + +include $(BUILDER)/targets.mk + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.gitignore b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.gitignore new file mode 100644 index 00000000..c81d16be --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.gitignore @@ -0,0 +1 @@ +*.mk diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.module new file mode 100644 index 00000000..588f0566 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as5916_26xb diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/Makefile new file mode 100644 index 00000000..ac46bc42 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/Makefile @@ -0,0 +1,9 @@ +############################################################################### +# +# +# +############################################################################### +include $(ONL)/make/config.mk +MODULE := x86_64_accton_as5916_26xb +AUTOMODULE := x86_64_accton_as5916_26xb +include $(BUILDER)/definemodule.mk diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/README b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/README new file mode 100644 index 00000000..0ad083e7 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/README @@ -0,0 +1,6 @@ +############################################################################### +# +# x86_64_accton_as5916_26xb README +# +############################################################################### + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/auto/x86_64_accton_as5916_26xb.yml b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/auto/x86_64_accton_as5916_26xb.yml new file mode 100644 index 00000000..0896dd45 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/auto/x86_64_accton_as5916_26xb.yml @@ -0,0 +1,50 @@ +############################################################################### +# +# x86_64_accton_as5916_26xb Autogeneration Definitions. +# +############################################################################### + +cdefs: &cdefs +- X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_LOGGING: + doc: "Include or exclude logging." + default: 1 +- X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_OPTIONS_DEFAULT: + doc: "Default enabled log options." + default: AIM_LOG_OPTIONS_DEFAULT +- X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_BITS_DEFAULT: + doc: "Default enabled log bits." + default: AIM_LOG_BITS_DEFAULT +- X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_CUSTOM_BITS_DEFAULT: + doc: "Default enabled custom log bits." + default: 0 +- X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB: + doc: "Default all porting macros to use the C standard libraries." + default: 1 +- X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS: + doc: "Include standard library headers for stdlib porting macros." + default: X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB +- X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_UCLI: + doc: "Include generic uCli support." + default: 0 +- X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION: + doc: "Assume chassis fan direction is the same as the PSU fan direction." + default: 0 + + +definitions: + cdefs: + X86_64_ACCTON_AS5916_26xb_CONFIG_HEADER: + defs: *cdefs + basename: x86_64_accton_as5916_26xb_config + + portingmacro: + x86_64_accton_as5916_26xb: + macros: + - malloc + - free + - memset + - memcpy + - strncpy + - vsnprintf + - snprintf + - strlen diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb.x b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb.x new file mode 100644 index 00000000..42078eff --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb.x @@ -0,0 +1,14 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +/* <--auto.start.xmacro(ALL).define> */ +/* */ + +/* <--auto.start.xenum(ALL).define> */ +/* */ + + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_config.h b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_config.h new file mode 100644 index 00000000..1dfcfbdb --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_config.h @@ -0,0 +1,137 @@ +/**************************************************************************//** + * + * @file + * @brief x86_64_accton_as5916_26xb Configuration Header + * + * @addtogroup x86_64_accton_as5916_26xb-config + * @{ + * + *****************************************************************************/ +#ifndef __X86_64_ACCTON_AS5916_26XB_CONFIG_H__ +#define __X86_64_ACCTON_AS5916_26XB_CONFIG_H__ + +#ifdef GLOBAL_INCLUDE_CUSTOM_CONFIG +#include +#endif +#ifdef X86_64_ACCTON_AS5916_26XB_INCLUDE_CUSTOM_CONFIG +#include +#endif + +/* */ +#include +/** + * X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_LOGGING + * + * Include or exclude logging. */ + + +#ifndef X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_LOGGING +#define X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_LOGGING 1 +#endif + +/** + * X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_OPTIONS_DEFAULT + * + * Default enabled log options. */ + + +#ifndef X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_OPTIONS_DEFAULT +#define X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_OPTIONS_DEFAULT AIM_LOG_OPTIONS_DEFAULT +#endif + +/** + * X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_BITS_DEFAULT + * + * Default enabled log bits. */ + + +#ifndef X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_BITS_DEFAULT +#define X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_BITS_DEFAULT AIM_LOG_BITS_DEFAULT +#endif + +/** + * X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_CUSTOM_BITS_DEFAULT + * + * Default enabled custom log bits. */ + + +#ifndef X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_CUSTOM_BITS_DEFAULT +#define X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_CUSTOM_BITS_DEFAULT 0 +#endif + +/** + * X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB + * + * Default all porting macros to use the C standard libraries. */ + + +#ifndef X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB +#define X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB 1 +#endif + +/** + * X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS + * + * Include standard library headers for stdlib porting macros. */ + + +#ifndef X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS +#define X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB +#endif + +/** + * X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_UCLI + * + * Include generic uCli support. */ + + +#ifndef X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_UCLI +#define X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_UCLI 0 +#endif + +/** + * X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION + * + * Assume chassis fan direction is the same as the PSU fan direction. */ + + +#ifndef X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION +#define X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION 0 +#endif + + + +/** + * All compile time options can be queried or displayed + */ + +/** Configuration settings structure. */ +typedef struct x86_64_accton_as5916_26xb_config_settings_s { + /** name */ + const char* name; + /** value */ + const char* value; +} x86_64_accton_as5916_26xb_config_settings_t; + +/** Configuration settings table. */ +/** x86_64_accton_as5916_26xb_config_settings table. */ +extern x86_64_accton_as5916_26xb_config_settings_t x86_64_accton_as5916_26xb_config_settings[]; + +/** + * @brief Lookup a configuration setting. + * @param setting The name of the configuration option to lookup. + */ +const char* x86_64_accton_as5916_26xb_config_lookup(const char* setting); + +/** + * @brief Show the compile-time configuration. + * @param pvs The output stream. + */ +int x86_64_accton_as5916_26xb_config_show(struct aim_pvs_s* pvs); + +/* */ + +#include "x86_64_accton_as5916_26xb_porting.h" + +#endif /* __X86_64_ACCTON_AS5916_26XB_CONFIG_H__ */ +/* @} */ diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_dox.h b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_dox.h new file mode 100644 index 00000000..1c8901e0 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_dox.h @@ -0,0 +1,26 @@ +/**************************************************************************//** + * + * x86_64_accton_as5916_26xb Doxygen Header + * + *****************************************************************************/ +#ifndef __X86_64_ACCTON_AS5916_26XB_DOX_H__ +#define __X86_64_ACCTON_AS5916_26XB_DOX_H__ + +/** + * @defgroup x86_64_accton_as5916_26xb x86_64_accton_as5916_26xb - x86_64_accton_as5916_26xb Description + * + +The documentation overview for this module should go here. + + * + * @{ + * + * @defgroup x86_64_accton_as5916_26xb-x86_64_accton_as5916_26xb Public Interface + * @defgroup x86_64_accton_as5916_26xb-config Compile Time Configuration + * @defgroup x86_64_accton_as5916_26xb-porting Porting Macros + * + * @} + * + */ + +#endif /* __X86_64_ACCTON_AS5916_26XB_DOX_H__ */ diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_porting.h b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_porting.h new file mode 100644 index 00000000..ba711cd1 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/inc/x86_64_accton_as5916_26xb/x86_64_accton_as5916_26xb_porting.h @@ -0,0 +1,107 @@ +/**************************************************************************//** + * + * @file + * @brief x86_64_accton_as5916_26xb Porting Macros. + * + * @addtogroup x86_64_accton_as5916_26xb-porting + * @{ + * + *****************************************************************************/ +#ifndef __X86_64_ACCTON_AS5916_26XB_PORTING_H__ +#define __X86_64_ACCTON_AS5916_26XB_PORTING_H__ + + +/* */ +#if X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS == 1 +#include +#include +#include +#include +#include +#endif + +#ifndef X86_64_ACCTON_AS5916_26XB_MALLOC + #if defined(GLOBAL_MALLOC) + #define X86_64_ACCTON_AS5916_26XB_MALLOC GLOBAL_MALLOC + #elif X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ACCTON_AS5916_26XB_MALLOC malloc + #else + #error The macro X86_64_ACCTON_AS5916_26XB_MALLOC is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ACCTON_AS5916_26XB_FREE + #if defined(GLOBAL_FREE) + #define X86_64_ACCTON_AS5916_26XB_FREE GLOBAL_FREE + #elif X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ACCTON_AS5916_26XB_FREE free + #else + #error The macro X86_64_ACCTON_AS5916_26XB_FREE is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ACCTON_AS5916_26XB_MEMSET + #if defined(GLOBAL_MEMSET) + #define X86_64_ACCTON_AS5916_26XB_MEMSET GLOBAL_MEMSET + #elif X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ACCTON_AS5916_26XB_MEMSET memset + #else + #error The macro X86_64_ACCTON_AS5916_26XB_MEMSET is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ACCTON_AS5916_26XB_MEMCPY + #if defined(GLOBAL_MEMCPY) + #define X86_64_ACCTON_AS5916_26XB_MEMCPY GLOBAL_MEMCPY + #elif X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ACCTON_AS5916_26XB_MEMCPY memcpy + #else + #error The macro X86_64_ACCTON_AS5916_26XB_MEMCPY is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ACCTON_AS5916_26XB_STRNCPY + #if defined(GLOBAL_STRNCPY) + #define X86_64_ACCTON_AS5916_26XB_STRNCPY GLOBAL_STRNCPY + #elif X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ACCTON_AS5916_26XB_STRNCPY strncpy + #else + #error The macro X86_64_ACCTON_AS5916_26XB_STRNCPY is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ACCTON_AS5916_26XB_VSNPRINTF + #if defined(GLOBAL_VSNPRINTF) + #define X86_64_ACCTON_AS5916_26XB_VSNPRINTF GLOBAL_VSNPRINTF + #elif X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ACCTON_AS5916_26XB_VSNPRINTF vsnprintf + #else + #error The macro X86_64_ACCTON_AS5916_26XB_VSNPRINTF is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ACCTON_AS5916_26XB_SNPRINTF + #if defined(GLOBAL_SNPRINTF) + #define X86_64_ACCTON_AS5916_26XB_SNPRINTF GLOBAL_SNPRINTF + #elif X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ACCTON_AS5916_26XB_SNPRINTF snprintf + #else + #error The macro X86_64_ACCTON_AS5916_26XB_SNPRINTF is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ACCTON_AS5916_26XB_STRLEN + #if defined(GLOBAL_STRLEN) + #define X86_64_ACCTON_AS5916_26XB_STRLEN GLOBAL_STRLEN + #elif X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ACCTON_AS5916_26XB_STRLEN strlen + #else + #error The macro X86_64_ACCTON_AS5916_26XB_STRLEN is required but cannot be defined. + #endif +#endif + +/* */ + + +#endif /* __X86_64_ACCTON_AS5916_26XB_PORTING_H__ */ +/* @} */ diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/Makefile new file mode 100644 index 00000000..a7e74bb5 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/Makefile @@ -0,0 +1,9 @@ +############################################################################### +# +# Local source generation targets. +# +############################################################################### + +ucli: + @../../../../tools/uclihandlers.py x86_64_accton_as5916_26xb_ucli.c + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/fani.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/fani.c new file mode 100644 index 00000000..bcd6b60e --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/fani.c @@ -0,0 +1,232 @@ +/************************************************************ + * + * + * 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. + * + * + ************************************************************ + * + * Fan Platform Implementation Defaults. + * + ***********************************************************/ +#include +#include +#include "platform_lib.h" + +enum fan_id { + FAN_1_ON_FAN_BOARD = 1, + FAN_2_ON_FAN_BOARD, + FAN_3_ON_FAN_BOARD, + FAN_4_ON_FAN_BOARD, + FAN_5_ON_FAN_BOARD, + FAN_1_ON_PSU_1, + FAN_1_ON_PSU_2, +}; + +#define MAX_FAN_SPEED 25500 +#define MAX_PSU_FAN_SPEED 25500 + +#define CHASSIS_FAN_INFO(fid) \ + { \ + { ONLP_FAN_ID_CREATE(FAN_##fid##_ON_FAN_BOARD), "Chassis Fan - "#fid, 0 },\ + 0x0,\ + ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE,\ + 0,\ + 0,\ + ONLP_FAN_MODE_INVALID,\ + } + +#define PSU_FAN_INFO(pid, fid) \ + { \ + { ONLP_FAN_ID_CREATE(FAN_##fid##_ON_PSU_##pid), "PSU "#pid" - Fan "#fid, 0 },\ + 0x0,\ + ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE,\ + 0,\ + 0,\ + ONLP_FAN_MODE_INVALID,\ + } + +/* Static fan information */ +onlp_fan_info_t finfo[] = { + { }, /* Not used */ + CHASSIS_FAN_INFO(1), + CHASSIS_FAN_INFO(2), + CHASSIS_FAN_INFO(3), + CHASSIS_FAN_INFO(4), + CHASSIS_FAN_INFO(5), + PSU_FAN_INFO(1, 1), + PSU_FAN_INFO(2, 1) +}; + +#define VALIDATE(_id) \ + do { \ + if(!ONLP_OID_IS_FAN(_id)) { \ + return ONLP_STATUS_E_INVALID; \ + } \ + } while(0) + +static int +_onlp_fani_info_get_fan(int fid, onlp_fan_info_t* info) +{ + int value, ret; + + /* get fan present status + */ + ret = onlp_file_read_int(&value, "%s""fan%d_present", FAN_BOARD_PATH, fid); + if (ret < 0) { + AIM_LOG_ERROR("Unable to read status from (%s)\r\n", FAN_BOARD_PATH); + return ONLP_STATUS_E_INTERNAL; + } + + if (value == 0) { + return ONLP_STATUS_OK; /* fan is not present */ + } + info->status |= ONLP_FAN_STATUS_PRESENT; + + + /* get fan direction + */ + info->status |= ONLP_FAN_STATUS_F2B; + + + /* get fan speed + */ + ret = onlp_file_read_int(&value, "%s""fan%d_input", FAN_BOARD_PATH, fid); + if (ret < 0) { + AIM_LOG_ERROR("Unable to read status from (%s)\r\n", FAN_BOARD_PATH); + return ONLP_STATUS_E_INTERNAL; + } + info->rpm = value; + info->percentage = (info->rpm * 100)/MAX_FAN_SPEED; + + + /* get fan fault status + */ + if (!info->rpm) { + info->status |= ONLP_FAN_STATUS_FAILED; + } + + return ONLP_STATUS_OK; +} + +static int +_onlp_fani_info_get_fan_on_psu(int pid, onlp_fan_info_t* info) +{ + int value, ret; + + info->status |= ONLP_FAN_STATUS_PRESENT; + + /* get fan direction + */ + info->status |= ONLP_FAN_STATUS_F2B; + + /* get fan speed + */ + ret = onlp_file_read_int(&value, "%s""psu%d_fan1_input", PSU_SYSFS_PATH, pid); + if (ret < 0) { + AIM_LOG_ERROR("Unable to read status from (%s)\r\n", PSU_SYSFS_PATH); + return ONLP_STATUS_E_INTERNAL; + } + + info->rpm = value; + info->percentage = (info->rpm * 100)/MAX_PSU_FAN_SPEED; + + /* get fan fault status + */ + if (!info->rpm) { + info->status |= ONLP_FAN_STATUS_FAILED; + } + + return ONLP_STATUS_OK; +} + +/* + * This function will be called prior to all of onlp_fani_* functions. + */ +int +onlp_fani_init(void) +{ + return ONLP_STATUS_OK; +} + +int +onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info) +{ + int rc = 0; + int fid; + VALIDATE(id); + + fid = ONLP_OID_ID_GET(id); + *info = finfo[fid]; + + switch (fid) + { + case FAN_1_ON_PSU_1: + rc = _onlp_fani_info_get_fan_on_psu(PSU1_ID, info); + break; + case FAN_1_ON_PSU_2: + rc = _onlp_fani_info_get_fan_on_psu(PSU2_ID, info); + break; + case FAN_1_ON_FAN_BOARD: + case FAN_2_ON_FAN_BOARD: + case FAN_3_ON_FAN_BOARD: + case FAN_4_ON_FAN_BOARD: + case FAN_5_ON_FAN_BOARD: + rc =_onlp_fani_info_get_fan(fid, info); + break; + default: + rc = ONLP_STATUS_E_INVALID; + break; + } + + return rc; +} + +/* + * This function sets the fan speed of the given OID as a percentage. + * + * This will only be called if the OID has the PERCENTAGE_SET + * capability. + * + * It is optional if you have no fans at all with this feature. + */ +int +onlp_fani_percentage_set(onlp_oid_t id, int p) +{ + int fid; + + VALIDATE(id); + + fid = ONLP_OID_ID_GET(id); + + /* reject p=0 (p=0, stop fan) */ + if (p == 0){ + return ONLP_STATUS_E_INVALID; + } + + if (fid < FAN_1_ON_FAN_BOARD || fid > FAN_5_ON_FAN_BOARD) { + return ONLP_STATUS_E_INVALID; + } + + if (onlp_file_write_int(p, "%s""fan%d_pwm", FAN_BOARD_PATH, fid) < 0) { + AIM_LOG_ERROR("Unable to write data to file %s""fan%d_pwm", FAN_BOARD_PATH, fid); + return ONLP_STATUS_E_INTERNAL; + } + + return ONLP_STATUS_OK; +} + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/ledi.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/ledi.c new file mode 100644 index 00000000..e3480a6d --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/ledi.c @@ -0,0 +1,248 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright 2013 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. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#include +#include +#include "platform_lib.h" + +#define LED_FORMAT "/sys/devices/platform/as5916_26xb_led/%s" + +#define VALIDATE(_id) \ + do { \ + if(!ONLP_OID_IS_LED(_id)) { \ + return ONLP_STATUS_E_INVALID; \ + } \ + } while(0) + +/* LED related data + */ +enum onlp_led_id +{ + LED_RESERVED = 0, + LED_LOC, + LED_DIAG, + LED_PSU1, + LED_PSU2, + LED_FAN, +}; + +enum led_light_mode { + LED_MODE_OFF, + LED_MODE_RED = 10, + LED_MODE_RED_BLINKING = 11, + LED_MODE_ORANGE = 12, + LED_MODE_ORANGE_BLINKING = 13, + LED_MODE_YELLOW = 14, + LED_MODE_YELLOW_BLINKING = 15, + LED_MODE_GREEN = 16, + LED_MODE_GREEN_BLINKING = 17, + LED_MODE_BLUE = 18, + LED_MODE_BLUE_BLINKING = 19, + LED_MODE_PURPLE = 20, + LED_MODE_PURPLE_BLINKING = 21, + LED_MODE_AUTO = 22, + LED_MODE_AUTO_BLINKING = 23, + LED_MODE_WHITE = 24, + LED_MODE_WHITE_BLINKING = 25, + LED_MODE_CYAN = 26, + LED_MODE_CYAN_BLINKING = 27, + LED_MODE_UNKNOWN = 99 +}; + +typedef struct led_light_mode_map { + enum onlp_led_id id; + enum led_light_mode driver_led_mode; + enum onlp_led_mode_e onlp_led_mode; +} led_light_mode_map_t; + +led_light_mode_map_t led_map[] = { +{LED_LOC, LED_MODE_OFF, ONLP_LED_MODE_OFF}, +{LED_LOC, LED_MODE_ORANGE_BLINKING, ONLP_LED_MODE_ORANGE_BLINKING}, +{LED_DIAG, LED_MODE_OFF, ONLP_LED_MODE_OFF}, +{LED_DIAG, LED_MODE_GREEN, ONLP_LED_MODE_GREEN}, +{LED_DIAG, LED_MODE_GREEN_BLINKING, ONLP_LED_MODE_GREEN_BLINKING}, +{LED_DIAG, LED_MODE_ORANGE, ONLP_LED_MODE_ORANGE}, +{LED_FAN, LED_MODE_AUTO, ONLP_LED_MODE_AUTO}, +{LED_PSU1, LED_MODE_AUTO, ONLP_LED_MODE_AUTO}, +{LED_PSU2, LED_MODE_AUTO, ONLP_LED_MODE_AUTO} +}; + +static char *leds[] = /* must map with onlp_led_id */ +{ + NULL, + "led_loc", + "led_diag", + "led_psu1", + "led_psu2", + "led_fan" +}; + +/* + * Get the information for the given LED OID. + */ +static onlp_led_info_t linfo[] = +{ + { }, /* Not used */ + { + { ONLP_LED_ID_CREATE(LED_LOC), "Chassis LED 1 (LOC LED)", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_ORANGE_BLINKING, + }, + { + { ONLP_LED_ID_CREATE(LED_DIAG), "Chassis LED 2 (DIAG LED)", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_GREEN_BLINKING, + }, + { + { ONLP_LED_ID_CREATE(LED_PSU1), "Chassis LED 3 (PSU1 LED)", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_AUTO, + }, + { + { ONLP_LED_ID_CREATE(LED_PSU2), "Chassis LED 4 (PSU2 LED)", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_AUTO, + }, + { + { ONLP_LED_ID_CREATE(LED_FAN), "Chassis LED 5 (FAN LED)", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_AUTO, + }, +}; + +static int driver_to_onlp_led_mode(enum onlp_led_id id, enum led_light_mode driver_led_mode) +{ + int i, nsize = sizeof(led_map)/sizeof(led_map[0]); + + for (i = 0; i < nsize; i++) + { + if (id == led_map[i].id && driver_led_mode == led_map[i].driver_led_mode) + { + return led_map[i].onlp_led_mode; + } + } + + return 0; +} + +static int onlp_to_driver_led_mode(enum onlp_led_id id, onlp_led_mode_t onlp_led_mode) +{ + int i, nsize = sizeof(led_map)/sizeof(led_map[0]); + + for(i = 0; i < nsize; i++) + { + if (id == led_map[i].id && onlp_led_mode == led_map[i].onlp_led_mode) + { + return led_map[i].driver_led_mode; + } + } + + return 0; +} + +/* + * This function will be called prior to any other onlp_ledi_* functions. + */ +int +onlp_ledi_init(void) +{ + /* + * Turn off the LOCATION and DIAG LEDs at startup + */ + onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_DIAG), ONLP_LED_MODE_OFF); + onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_LOC), ONLP_LED_MODE_OFF); + + return ONLP_STATUS_OK; +} + +int +onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info) +{ + int lid, value; + + VALIDATE(id); + + lid = ONLP_OID_ID_GET(id); + + /* Set the onlp_oid_hdr_t and capabilities */ + *info = linfo[ONLP_OID_ID_GET(id)]; + + /* Get LED mode */ + if (onlp_file_read_int(&value, LED_FORMAT, leds[lid]) < 0) { + DEBUG_PRINT("Unable to read status from file "LED_FORMAT, leds[lid]); + return ONLP_STATUS_E_INTERNAL; + } + + info->mode = driver_to_onlp_led_mode(lid, value); + + /* Set the on/off status */ + if (info->mode != ONLP_LED_MODE_OFF) { + info->status |= ONLP_LED_STATUS_ON; + } + + return ONLP_STATUS_OK; +} + +/* + * Turn an LED on or off. + * + * This function will only be called if the LED OID supports the ONOFF + * capability. + * + * What 'on' means in terms of colors or modes for multimode LEDs is + * up to the platform to decide. This is intended as baseline toggle mechanism. + */ +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; +} + +/* + * This function puts the LED into the given mode. It is a more functional + * interface for multimode LEDs. + * + * Only modes reported in the LED's capabilities will be attempted. + */ +int +onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode) +{ + int lid; + VALIDATE(id); + + lid = ONLP_OID_ID_GET(id); + if (onlp_file_write_int(onlp_to_driver_led_mode(lid , mode), LED_FORMAT, leds[lid]) < 0) { + return ONLP_STATUS_E_INTERNAL; + } + + return ONLP_STATUS_OK; +} + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/platform_lib.h b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/platform_lib.h new file mode 100644 index 00000000..f6144470 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/platform_lib.h @@ -0,0 +1,70 @@ +/************************************************************ + * + * + * 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. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#ifndef __PLATFORM_LIB_H__ +#define __PLATFORM_LIB_H__ + +#include "x86_64_accton_as5916_26xb_log.h" + +#define CHASSIS_FAN_COUNT 5 +#define CHASSIS_THERMAL_COUNT 7 +#define CHASSIS_LED_COUNT 5 +#define CHASSIS_PSU_COUNT 2 + +#define PSU1_ID 1 +#define PSU2_ID 2 + +#define PSU_SYSFS_PATH "/sys/devices/platform/as5916_26xb_psu/" + +#define FAN_BOARD_PATH "/sys/devices/platform/as5916_26xb_fan/" +#define FAN_NODE(node) FAN_BOARD_PATH#node + +#define IDPROM_PATH "/sys/devices/platform/as5916_26xb_sys/eeprom" + +enum onlp_thermal_id +{ + THERMAL_RESERVED = 0, + THERMAL_CPU_CORE, + THERMAL_1_ON_MAIN_BROAD, + THERMAL_2_ON_MAIN_BROAD, + THERMAL_3_ON_MAIN_BROAD, + THERMAL_4_ON_MAIN_BROAD, + THERMAL_5_ON_MAIN_BROAD, + THERMAL_6_ON_MAIN_BROAD, + THERMAL_1_ON_PSU1, + THERMAL_1_ON_PSU2, +}; + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printf("%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#endif /* __PLATFORM_LIB_H__ */ + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/psui.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/psui.c new file mode 100644 index 00000000..156f9bdb --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/psui.c @@ -0,0 +1,154 @@ +/************************************************************ + * + * + * 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. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#include +#include +#include "platform_lib.h" + +#define PSU_STATUS_PRESENT 1 +#define PSU_STATUS_POWER_GOOD 1 + +#define VALIDATE(_id) \ + do { \ + if(!ONLP_OID_IS_PSU(_id)) { \ + return ONLP_STATUS_E_INVALID; \ + } \ + } while(0) + +int +onlp_psui_init(void) +{ + return ONLP_STATUS_OK; +} + +/* + * Get all information about the given PSU oid. + */ +static onlp_psu_info_t pinfo[] = +{ + { }, /* Not used */ + { + { ONLP_PSU_ID_CREATE(PSU1_ID), "PSU-1", 0 }, + }, + { + { ONLP_PSU_ID_CREATE(PSU2_ID), "PSU-2", 0 }, + } +}; + +int +onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) +{ + int val = 0; + int ret = ONLP_STATUS_OK; + int pid = ONLP_OID_ID_GET(id); + + VALIDATE(id); + + memset(info, 0, sizeof(onlp_psu_info_t)); + *info = pinfo[pid]; /* Set the onlp_oid_hdr_t */ + + /* Get the present state */ + ret = onlp_file_read_int(&val, "%s""psu%d_present", PSU_SYSFS_PATH, pid); + if (ret < 0) { + AIM_LOG_ERROR("Unable to read status from (%s""psu%d_present)\r\n", PSU_SYSFS_PATH, pid); + return ONLP_STATUS_E_INTERNAL; + } + + if (val != PSU_STATUS_PRESENT) { + info->status &= ~ONLP_PSU_STATUS_PRESENT; + return ONLP_STATUS_OK; + } + info->status |= ONLP_PSU_STATUS_PRESENT; + + + /* Get power good status */ + ret = onlp_file_read_int(&val, "%s""psu%d_power_good", PSU_SYSFS_PATH, pid); + if (ret < 0) { + AIM_LOG_ERROR("Unable to read status from (%s""psu%d_power_good)\r\n", PSU_SYSFS_PATH, pid); + return ONLP_STATUS_E_INTERNAL; + } + + if (val != PSU_STATUS_POWER_GOOD) { + info->status |= ONLP_PSU_STATUS_FAILED; + } + + if (info->status & ONLP_PSU_STATUS_FAILED) { + return ONLP_STATUS_OK; + } + + /* Read voltage, current and power */ + val = 0; + if (onlp_file_read_int(&val, "%s""psu%d_vin", PSU_SYSFS_PATH, pid) == 0 && val) { + info->mvin = val; + info->caps |= ONLP_PSU_CAPS_VIN; + } + + val = 0; + if (onlp_file_read_int(&val, "%s""psu%d_vout", PSU_SYSFS_PATH, pid) == 0 && val) { + info->mvout = val; + info->caps |= ONLP_PSU_CAPS_VOUT; + } + + val = 0; + if (onlp_file_read_int(&val, "%s""psu%d_iout", PSU_SYSFS_PATH, pid) == 0 && val) { + info->miout = val; + info->caps |= ONLP_PSU_CAPS_IOUT; + } + + val = 0; + if (onlp_file_read_int(&val, "%s""psu%d_pout", PSU_SYSFS_PATH, pid) == 0 && val) { + info->mpout = val; + info->caps |= ONLP_PSU_CAPS_POUT; + } + + /* Set the associated oid_table */ + val = 0; + if (onlp_file_read_int(&val, "%s""psu%d_fan1_input", PSU_SYSFS_PATH, pid) == 0 && val) { + info->hdr.coids[0] = ONLP_FAN_ID_CREATE(pid + CHASSIS_FAN_COUNT); + } + + val = 0; + if (onlp_file_read_int(&val, "%s""psu%d_temp1_input", PSU_SYSFS_PATH, pid) == 0 && val) { + info->hdr.coids[1] = ONLP_THERMAL_ID_CREATE(pid + CHASSIS_THERMAL_COUNT); + } + + /* Read model */ + char *string = NULL; + int len = onlp_file_read_str(&string, "%s""psu%d_model", PSU_SYSFS_PATH, pid); + if (string && len) { + strncpy(info->model, string, len); + aim_free(string); + } + + /* Read serial */ + len = onlp_file_read_str(&string, "%s""psu%d_serial", PSU_SYSFS_PATH, pid); + if (string && len) { + strncpy(info->serial, string, len); + aim_free(string); + } + + return ret; +} + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/sfpi.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/sfpi.c new file mode 100644 index 00000000..29a02a12 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/sfpi.c @@ -0,0 +1,287 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright 2017 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. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#include +#include +#include +#include "x86_64_accton_as5916_26xb_int.h" +#include "x86_64_accton_as5916_26xb_log.h" + +#define PORT_EEPROM_FORMAT "/sys/devices/platform/as5916_26xb_sfp/module_eeprom_%d" +#define MODULE_PRESENT_FORMAT "/sys/devices/platform/as5916_26xb_sfp/module_present_%d" +#define MODULE_RXLOS_FORMAT "/sys/devices/platform/as5916_26xb_sfp/module_rx_los_%d" +#define MODULE_TXFAULT_FORMAT "/sys/devices/platform/as5916_26xb_sfp/module_tx_fault_%d" +#define MODULE_TXDISABLE_FORMAT "/sys/devices/platform/as5916_26xb_sfp/module_tx_disable_%d" +#define MODULE_PRESENT_ALL_ATTR "/sys/devices/platform/as5916_26xb_sfp/module_present_all" +#define MODULE_RXLOS_ALL_ATTR "/sys/devices/platform/as5916_26xb_sfp/module_rxlos_all" + +/************************************************************ + * + * SFPI Entry Points + * + ***********************************************************/ +int +onlp_sfpi_init(void) +{ + /* Called at initialization time */ + return ONLP_STATUS_OK; +} + +int +onlp_sfpi_bitmap_get(onlp_sfp_bitmap_t* bmap) +{ + /* + * Ports {0, 54} + */ + int p; + + for(p = 0; p < 26; p++) { + AIM_BITMAP_SET(bmap, p); + } + + 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; + + if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, (port+1)) < 0) { + AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + + return present; +} + +int +onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) +{ + uint32_t bytes[4]; + FILE* fp; + + /* Read present status of port 0~25 */ + int count = 0; + + fp = fopen(MODULE_PRESENT_ALL_ATTR, "r"); + if(fp == NULL) { + AIM_LOG_ERROR("Unable to open the module_present_all device file from (%s).", MODULE_PRESENT_ALL_ATTR); + return ONLP_STATUS_E_INTERNAL; + } + + count = fscanf(fp, "%x %x %x %x", bytes+0, bytes+1, bytes+2, bytes+3); + fclose(fp); + if(count != 4) { + /* Likely a CPLD read timeout. */ + AIM_LOG_ERROR("Unable to read all fields the module_present_all device file from(%s).", MODULE_PRESENT_ALL_ATTR); + return ONLP_STATUS_E_INTERNAL; + } + + /* Mask out non-existant QSFP ports */ + bytes[3] &= 0x3; + + /* Convert to 64 bit integer in port order */ + int i = 0; + uint64_t presence_all = 0 ; + for(i = AIM_ARRAYSIZE(bytes)-1; i >= 0; i--) { + presence_all <<= 8; + presence_all |= bytes[i]; + } + + /* Populate bitmap */ + for(i = 0; presence_all; i++) { + AIM_BITMAP_MOD(dst, i, (presence_all & 1)); + presence_all >>= 1; + } + + return ONLP_STATUS_OK; +} + +int +onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) +{ + uint32_t bytes[3]; + FILE* fp; + + /* Read present status of port 0~25 */ + int count = 0; + + fp = fopen(MODULE_RXLOS_ALL_ATTR, "r"); + if(fp == NULL) { + AIM_LOG_ERROR("Unable to open the module_rxlos_all device file from (%s).", MODULE_RXLOS_ALL_ATTR); + return ONLP_STATUS_E_INTERNAL; + } + + count = fscanf(fp, "%x %x %x", bytes+0, bytes+1, bytes+2); + fclose(fp); + if(count != 3) { + /* Likely a CPLD read timeout. */ + AIM_LOG_ERROR("Unable to read all fields the module_rxlos_all device file from(%s).", MODULE_RXLOS_ALL_ATTR); + return ONLP_STATUS_E_INTERNAL; + } + + /* Convert to 64 bit integer in port order */ + int i = 0; + uint64_t rx_los_all = 0 ; + for(i = AIM_ARRAYSIZE(bytes)-1; i >= 0; i--) { + rx_los_all <<= 8; + rx_los_all |= bytes[i]; + } + + /* Populate bitmap */ + for(i = 0; rx_los_all; i++) { + AIM_BITMAP_MOD(dst, i, (rx_los_all & 1)); + rx_los_all >>= 1; + } + + return ONLP_STATUS_OK; +} + +int +onlp_sfpi_eeprom_read(int port, uint8_t data[256]) +{ + /* + * Read the SFP eeprom into data[] + * + * Return MISSING if SFP is missing. + * Return OK if eeprom is read + */ + int size = 0; + memset(data, 0, 256); + + if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, (port+1)) != 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 is different!\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + + return ONLP_STATUS_OK; +} + +int +onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) +{ + int rv; + + switch(control) + { + case ONLP_SFP_CONTROL_TX_DISABLE: + { + if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, (port+1)) < 0) { + AIM_LOG_ERROR("Unable to set tx_disable status to port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + break; + } + + default: + rv = ONLP_STATUS_E_UNSUPPORTED; + break; + } + + return rv; +} + +int +onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) +{ + int rv; + + if (port < 0) { + return ONLP_STATUS_E_UNSUPPORTED; + } + + switch(control) + { + case ONLP_SFP_CONTROL_RX_LOS: + { + if (port >= 24) { + return ONLP_STATUS_E_UNSUPPORTED; + } + + if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, (port+1)) < 0) { + AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + break; + } + + case ONLP_SFP_CONTROL_TX_FAULT: + { + if (port >= 24) { + return ONLP_STATUS_E_UNSUPPORTED; + } + + if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, (port+1)) < 0) { + AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + break; + } + + case ONLP_SFP_CONTROL_TX_DISABLE: + { + if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, (port+1)) < 0) { + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + break; + } + + default: + rv = ONLP_STATUS_E_UNSUPPORTED; + } + + return rv; +} + +int +onlp_sfpi_denit(void) +{ + return ONLP_STATUS_OK; +} + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/sysi.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/sysi.c new file mode 100644 index 00000000..d8c9f10d --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/sysi.c @@ -0,0 +1,103 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright 2017 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. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#include +#include + +#include +#include +#include +#include +#include +#include +#include "platform_lib.h" + +#include "x86_64_accton_as5916_26xb_int.h" +#include "x86_64_accton_as5916_26xb_log.h" + +const char* +onlp_sysi_platform_get(void) +{ + return "x86-64-accton-as5916-26xb-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)); + + /* 5 Thermal sensors on the chassis */ + for (i = 1; i <= CHASSIS_THERMAL_COUNT; i++) { + *e++ = ONLP_THERMAL_ID_CREATE(i); + } + + /* 5 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); + } + + /* 6 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) +{ + aim_free(pi->cpld_versions); +} + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/thermali.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/thermali.c new file mode 100644 index 00000000..35afa1aa --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/thermali.c @@ -0,0 +1,138 @@ +/************************************************************ + * + * + * 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. + * + * + ************************************************************ + * + * Thermal Sensor Platform Implementation. + * + ***********************************************************/ +#include +#include +#include "platform_lib.h" + +#define VALIDATE(_id) \ + do { \ + if(!ONLP_OID_IS_THERMAL(_id)) { \ + return ONLP_STATUS_E_INVALID; \ + } \ + } while(0) + +static char* devfiles__[] = /* must map with onlp_thermal_id */ +{ + NULL, + NULL, /* CPU_CORE files */ + "/sys/devices/platform/as5916_26xb_thermal/temp1_input", + "/sys/devices/platform/as5916_26xb_thermal/temp2_input", + "/sys/devices/platform/as5916_26xb_thermal/temp3_input", + "/sys/devices/platform/as5916_26xb_thermal/temp4_input", + "/sys/devices/platform/as5916_26xb_thermal/temp5_input", + "/sys/devices/platform/as5916_26xb_thermal/temp6_input", + "/sys/devices/platform/as5916_26xb_psu/psu1_temp1_input", + "/sys/devices/platform/as5916_26xb_psu/psu2_temp1_input", +}; + +static char* cpu_coretemp_files[] = + { + "/sys/devices/platform/coretemp.0*temp2_input", + "/sys/devices/platform/coretemp.0*temp3_input", + "/sys/devices/platform/coretemp.0*temp4_input", + "/sys/devices/platform/coretemp.0*temp5_input", + NULL, + }; + +/* 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), "LM75-1", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_2_ON_MAIN_BROAD), "LM75-2", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_3_ON_MAIN_BROAD), "LM75-3", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_4_ON_MAIN_BROAD), "LM75-4", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_5_ON_MAIN_BROAD), "LM75-5", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_6_ON_MAIN_BROAD), "LM75-6", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_PSU1), "PSU-1 Thermal Sensor 1", ONLP_PSU_ID_CREATE(PSU1_ID)}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_PSU2), "PSU-2 Thermal Sensor 1", ONLP_PSU_ID_CREATE(PSU2_ID)}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + } +}; + +/* + * This will be called to intiialize the thermali subsystem. + */ +int +onlp_thermali_init(void) +{ + return ONLP_STATUS_OK; +} + +/* + * Retrieve the information structure for the given thermal OID. + * + * If the OID is invalid, return ONLP_E_STATUS_INVALID. + * If an unexpected error occurs, return ONLP_E_STATUS_INTERNAL. + * Otherwise, return ONLP_STATUS_OK with the OID's information. + * + * Note -- it is expected that you fill out the information + * structure even if the sensor described by the OID is not present. + */ +int +onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info) +{ + int tid; + VALIDATE(id); + + tid = ONLP_OID_ID_GET(id); + + /* Set the onlp_oid_hdr_t and capabilities */ + *info = linfo[tid]; + + if(tid == THERMAL_CPU_CORE) { + int rv = onlp_file_read_int_max(&info->mcelsius, cpu_coretemp_files); + return rv; + } + + return onlp_file_read_int(&info->mcelsius, devfiles__[tid]); +} + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_config.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_config.c new file mode 100644 index 00000000..e5cadc0a --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_config.c @@ -0,0 +1,80 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +/* */ +#define __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(_x) #_x +#define __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE(_x) __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(_x) +x86_64_accton_as5916_26xb_config_settings_t x86_64_accton_as5916_26xb_config_settings[] = +{ +#ifdef X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_LOGGING + { __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_LOGGING), __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE(X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_LOGGING) }, +#else +{ X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_LOGGING(__x86_64_accton_as5916_26xb_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_OPTIONS_DEFAULT + { __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_OPTIONS_DEFAULT), __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE(X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_OPTIONS_DEFAULT) }, +#else +{ X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_OPTIONS_DEFAULT(__x86_64_accton_as5916_26xb_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_BITS_DEFAULT + { __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_BITS_DEFAULT), __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE(X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_BITS_DEFAULT) }, +#else +{ X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_BITS_DEFAULT(__x86_64_accton_as5916_26xb_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_CUSTOM_BITS_DEFAULT + { __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_CUSTOM_BITS_DEFAULT), __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE(X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_CUSTOM_BITS_DEFAULT) }, +#else +{ X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_CUSTOM_BITS_DEFAULT(__x86_64_accton_as5916_26xb_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB + { __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB), __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE(X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB) }, +#else +{ X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_STDLIB(__x86_64_accton_as5916_26xb_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS + { __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS), __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE(X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS) }, +#else +{ X86_64_ACCTON_AS5916_26XB_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS(__x86_64_accton_as5916_26xb_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_UCLI + { __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_UCLI), __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE(X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_UCLI) }, +#else +{ X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_UCLI(__x86_64_accton_as5916_26xb_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION + { __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME(X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION), __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE(X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION) }, +#else +{ X86_64_ACCTON_AS5916_26XB_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION(__x86_64_accton_as5916_26xb_config_STRINGIFY_NAME), "__undefined__" }, +#endif + { NULL, NULL } +}; +#undef __x86_64_accton_as5916_26xb_config_STRINGIFY_VALUE +#undef __x86_64_accton_as5916_26xb_config_STRINGIFY_NAME + +const char* +x86_64_accton_as5916_26xb_config_lookup(const char* setting) +{ + int i; + for(i = 0; x86_64_accton_as5916_26xb_config_settings[i].name; i++) { + if(!strcmp(x86_64_accton_as5916_26xb_config_settings[i].name, setting)) { + return x86_64_accton_as5916_26xb_config_settings[i].value; + } + } + return NULL; +} + +int +x86_64_accton_as5916_26xb_config_show(struct aim_pvs_s* pvs) +{ + int i; + for(i = 0; x86_64_accton_as5916_26xb_config_settings[i].name; i++) { + aim_printf(pvs, "%s = %s\n", x86_64_accton_as5916_26xb_config_settings[i].name, x86_64_accton_as5916_26xb_config_settings[i].value); + } + return i; +} + +/* */ diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_enums.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_enums.c new file mode 100644 index 00000000..9d03c510 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_enums.c @@ -0,0 +1,10 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +/* <--auto.start.enum(ALL).source> */ +/* */ + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_int.h b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_int.h new file mode 100644 index 00000000..639fe6ea --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_int.h @@ -0,0 +1,12 @@ +/**************************************************************************//** + * + * x86_64_accton_as5916_26xb Internal Header + * + *****************************************************************************/ +#ifndef __x86_64_accton_as5916_26xb_INT_H__ +#define __x86_64_accton_as5916_26xb_INT_H__ + +#include + + +#endif /* __x86_64_accton_as5916_26xb_INT_H__ */ \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_log.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_log.c new file mode 100644 index 00000000..b2de8434 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_log.c @@ -0,0 +1,18 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#include "x86_64_accton_as5916_26xb_log.h" +/* + * x86_64_accton_as5916_26xb log struct. + */ +AIM_LOG_STRUCT_DEFINE( + X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_OPTIONS_DEFAULT, + X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_BITS_DEFAULT, + NULL, /* Custom log map */ + X86_64_ACCTON_AS5916_26XB_CONFIG_LOG_CUSTOM_BITS_DEFAULT + ); + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_log.h b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_log.h new file mode 100644 index 00000000..6ba6a5a3 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_log.h @@ -0,0 +1,12 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#ifndef __x86_64_accton_as5916_26xb_LOG_H__ +#define __x86_64_accton_as5916_26xb_LOG_H__ + +#define AIM_LOG_MODULE_NAME x86_64_accton_as5916_26xb +#include + +#endif /* __x86_64_accton_as5916_26xb_LOG_H__ */ \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_module.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_module.c new file mode 100644 index 00000000..6c69173d --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_module.c @@ -0,0 +1,24 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#include "x86_64_accton_as5916_26xb_log.h" + +static int +datatypes_init__(void) +{ +#define x86_64_accton_as5916_26xb_ENUMERATION_ENTRY(_enum_name, _desc) AIM_DATATYPE_MAP_REGISTER(_enum_name, _enum_name##_map, _desc, AIM_LOG_INTERNAL); +#include + return 0; +} + +void __x86_64_accton_as5916_26xb_module_init__(void) +{ + AIM_LOG_STRUCT_REGISTER(); + datatypes_init__(); +} + +int __onlp_platform_version__ = 1; \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_ucli.c b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_ucli.c new file mode 100644 index 00000000..d627a0dc --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/x86_64_accton_as5916_26xb_ucli.c @@ -0,0 +1,50 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#if x86_64_accton_as5916_26xb_CONFIG_INCLUDE_UCLI == 1 + +#include +#include +#include + +static ucli_status_t +x86_64_accton_as5916_26xb_ucli_ucli__config__(ucli_context_t* uc) +{ + UCLI_HANDLER_MACRO_MODULE_CONFIG(x86_64_accton_as5916_26xb) +} + +/* */ +/* */ + +static ucli_module_t +x86_64_accton_as5916_26xb_ucli_module__ = + { + "x86_64_accton_as5916_26xb_ucli", + NULL, + x86_64_accton_as5916_26xb_ucli_ucli_handlers__, + NULL, + NULL, + }; + +ucli_node_t* +x86_64_accton_as5916_26xb_ucli_node_create(void) +{ + ucli_node_t* n; + ucli_module_init(&x86_64_accton_as5916_26xb_ucli_module__); + n = ucli_node_create("x86_64_accton_as5916_26xb", NULL, &x86_64_accton_as5916_26xb_ucli_module__); + ucli_node_subnode_add(n, ucli_module_log_node_create("x86_64_accton_as5916_26xb")); + return n; +} + +#else +void* +x86_64_accton_as5916_26xb_ucli_node_create(void) +{ + return NULL; +} +#endif + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/PKG.yml b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/PKG.yml new file mode 100644 index 00000000..bcd1c338 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/PKG.yml @@ -0,0 +1 @@ +!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=accton BASENAME=x86-64-accton-as5916-26xb REVISION=r0 diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/src/lib/x86-64-accton-as5916-26xb-r0.yml b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/src/lib/x86-64-accton-as5916-26xb-r0.yml new file mode 100644 index 00000000..bcd34404 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/src/lib/x86-64-accton-as5916-26xb-r0.yml @@ -0,0 +1,33 @@ +--- + +###################################################################### +# +# platform-config for AS5916 +# +###################################################################### + +x86-64-accton-as5916-26xb-r0: + + grub: + + serial: >- + --port=0x3f8 + --speed=115200 + --word=8 + --parity=no + --stop=1 + + kernel: + <<: *kernel-4-14 + + args: >- + nopat + console=ttyS0,115200n8 + tg3.short_preamble=1 + tg3.bcm5718s_reset=1 + + ##network: + ## interfaces: + ## ma1: + ## name: ~ + ## syspath: pci0000:00/0000:00:1c.0/0000:0a:00.0 diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/src/python/x86_64_accton_as5916_26xb_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/src/python/x86_64_accton_as5916_26xb_r0/__init__.py new file mode 100644 index 00000000..b7f0fec0 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/platform-config/r0/src/python/x86_64_accton_as5916_26xb_r0/__init__.py @@ -0,0 +1,13 @@ +from onl.platform.base import * +from onl.platform.accton import * + +class OnlPlatform_x86_64_accton_as5916_26xb_r0(OnlPlatformAccton, + OnlPlatformPortConfig_24x10_2x100): + PLATFORM='x86-64-accton-as5916-26xb-r0' + MODEL="AS5916-26XB" + SYS_OBJECT_ID=".5916.26" + + def baseconfig(self): + self.insmod_platform() + return True + From 7e83b99d2e5e74be7520bf92127c42fcb2134743 Mon Sep 17 00:00:00 2001 From: brandonchuang Date: Tue, 3 Jul 2018 09:14:14 +0800 Subject: [PATCH 2/2] [as5916-26xb] Add make.mk to fix the build failure --- .../onlp/builds/src/.gitignore | 2 +- .../onlp/builds/src/module/auto/make.mk | 9 +++++++++ .../onlp/builds/src/module/make.mk | 10 ++++++++++ .../onlp/builds/src/module/src/make.mk | 9 +++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/auto/make.mk create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/make.mk create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/make.mk diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.gitignore b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.gitignore index c81d16be..8b137891 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.gitignore +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/.gitignore @@ -1 +1 @@ -*.mk + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/auto/make.mk b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/auto/make.mk new file mode 100644 index 00000000..9db4a259 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/auto/make.mk @@ -0,0 +1,9 @@ +############################################################################### +# +# x86_64_accton_as5916_54x Autogeneration +# +############################################################################### +x86_64_accton_as5916_54x_AUTO_DEFS := module/auto/x86_64_accton_as5916_54x.yml +x86_64_accton_as5916_54x_AUTO_DIRS := module/inc/x86_64_accton_as5916_54x module/src +include $(BUILDER)/auto.mk + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/make.mk b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/make.mk new file mode 100644 index 00000000..ea9d2db7 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/make.mk @@ -0,0 +1,10 @@ +############################################################################### +# +# +# +############################################################################### +THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +x86_64_accton_as5916_26xb_INCLUDES := -I $(THIS_DIR)inc +x86_64_accton_as5916_26xb_INTERNAL_INCLUDES := -I $(THIS_DIR)src +x86_64_accton_as5916_26xb_DEPENDMODULE_ENTRIES := init:x86_64_accton_as5916_26xb ucli:x86_64_accton_as5916_26xb + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/make.mk b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/make.mk new file mode 100644 index 00000000..b376dc5b --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5916-26xb/onlp/builds/src/module/src/make.mk @@ -0,0 +1,9 @@ +############################################################################### +# +# +# +############################################################################### + +LIBRARY := x86_64_accton_as5916_26xb +$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(BUILDER)/lib.mk