diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/x86-64-accton-as7926-40xfb-sys.c b/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/x86-64-accton-as7926-40xfb-sys.c
index fe909e7d7..e860d05a2 100644
--- a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/x86-64-accton-as7926-40xfb-sys.c
+++ b/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/x86-64-accton-as7926-40xfb-sys.c
@@ -42,6 +42,8 @@
#define IPMI_TIMEOUT (5 * HZ)
#define IPMI_ERR_RETRY_TIMES 1
#define IPMI_READ_MAX_LEN 128
+#define IPMI_RESET_CMD 0x65
+#define IPMI_RESET_CMD_LENGTH 6
#define EEPROM_NAME "eeprom"
#define EEPROM_SIZE 256 /* 256 byte eeprom */
@@ -49,6 +51,10 @@
static int as7926_40xfb_sys_probe(struct platform_device *pdev);
static int as7926_40xfb_sys_remove(struct platform_device *pdev);
static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
+static ssize_t get_reset(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t set_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
struct ipmi_data {
struct completion read_complete;
@@ -75,6 +81,8 @@ struct as7926_40xfb_sys_data {
struct ipmi_data ipmi;
unsigned char ipmi_resp_eeprom[EEPROM_SIZE];
unsigned char ipmi_tx_data[2];
+ unsigned char ipmi_resp_rst[2];
+ unsigned char ipmi_tx_data_rst[IPMI_RESET_CMD_LENGTH];
struct bin_attribute eeprom; /* eeprom data */
};
@@ -89,6 +97,45 @@ static struct platform_driver as7926_40xfb_sys_driver = {
},
};
+/* sysfs attributes */
+enum as7926_40xfb_sysfs_attrs {
+ RESET_MUX,
+ RESET_MAC,
+ RESET_JR2,
+ RESET_OP2,
+ RESET_GEARBOX
+};
+
+#define DECLARE_RESET_SENSOR_DEVICE_ATTR() \
+ static SENSOR_DEVICE_ATTR(reset_mac, S_IWUSR | S_IRUGO, \
+ get_reset, set_reset, RESET_MAC); \
+ static SENSOR_DEVICE_ATTR(reset_jr2, S_IWUSR | S_IRUGO, \
+ get_reset, set_reset, RESET_JR2); \
+ static SENSOR_DEVICE_ATTR(reset_op2, S_IWUSR | S_IRUGO, \
+ get_reset, set_reset, RESET_OP2); \
+ static SENSOR_DEVICE_ATTR(reset_gb, S_IWUSR | S_IRUGO, \
+ get_reset, set_reset, RESET_GEARBOX); \
+ static SENSOR_DEVICE_ATTR(reset_mux, S_IWUSR | S_IRUGO, \
+ get_reset, set_reset, RESET_MUX)
+#define DECLARE_RESET_ATTR() \
+ &sensor_dev_attr_reset_mac.dev_attr.attr, \
+ &sensor_dev_attr_reset_jr2.dev_attr.attr, \
+ &sensor_dev_attr_reset_op2.dev_attr.attr, \
+ &sensor_dev_attr_reset_gb.dev_attr.attr, \
+ &sensor_dev_attr_reset_mux.dev_attr.attr
+
+DECLARE_RESET_SENSOR_DEVICE_ATTR();
+
+static struct attribute *as7926_40xfb_sys_attributes[] = {
+ /* sysfs attributes */
+ DECLARE_RESET_ATTR(),
+ NULL
+};
+
+static const struct attribute_group as7926_40xfb_sys_group = {
+ .attrs = as7926_40xfb_sys_attributes,
+};
+
/* Functions to talk to the IPMI layer */
/* Initialize IPMI address, message buffers and user data */
@@ -225,6 +272,71 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
complete(&ipmi->read_complete);
}
+static ssize_t get_reset(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ int status = 0;
+
+ mutex_lock(&data->update_lock);
+ status = ipmi_send_message(&data->ipmi, IPMI_RESET_CMD, NULL, 0,
+ data->ipmi_resp_rst, sizeof(data->ipmi_resp_rst));
+ if (unlikely(status != 0))
+ goto exit;
+
+ if (unlikely(data->ipmi.rx_result != 0)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return sprintf(buf, "0x%x 0x%x", data->ipmi_resp_rst[0], data->ipmi_resp_rst[1]);
+
+ exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static ssize_t set_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ u32 magic[2];
+ int status;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+
+ if (sscanf(buf, "0x%x 0x%x", &magic[0], &magic[1]) != 2)
+ return -EINVAL;
+
+ if (magic[0] > 0xFF || magic[1] > 0xFF)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+
+ /* Send IPMI write command */
+ data->ipmi_tx_data_rst[0] = 0;
+ data->ipmi_tx_data_rst[1] = 0;
+ data->ipmi_tx_data_rst[2] = (attr->index == RESET_MUX) ? 0 : (attr->index);
+ data->ipmi_tx_data_rst[3] = (attr->index == RESET_MUX) ? 2 : 1;
+ data->ipmi_tx_data_rst[4] = magic[0];
+ data->ipmi_tx_data_rst[5] = magic[1];
+
+ status = ipmi_send_message(&data->ipmi, IPMI_RESET_CMD,
+ data->ipmi_tx_data_rst,
+ sizeof(data->ipmi_tx_data_rst), NULL, 0);
+ if (unlikely(status != 0))
+ goto exit;
+
+ if (unlikely(data->ipmi.rx_result != 0)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ status = count;
+
+ exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
static ssize_t sys_eeprom_read(loff_t off, char *buf, size_t count)
{
int status = 0;
@@ -322,19 +434,27 @@ static int as7926_40xfb_sys_probe(struct platform_device *pdev)
/* Register sysfs hooks */
status = sysfs_eeprom_init(&pdev->dev.kobj, &data->eeprom);
if (status) {
- goto exit;
+ goto exit_eeprom;
+ }
+
+ status = sysfs_create_group(&pdev->dev.kobj, &as7926_40xfb_sys_group);
+ if (status) {
+ goto exit_sysfs;
}
dev_info(&pdev->dev, "device created\n");
return 0;
- exit:
+exit_sysfs:
+ sysfs_eeprom_cleanup(&pdev->dev.kobj, &data->eeprom);
+ exit_eeprom:
return status;
}
static int as7926_40xfb_sys_remove(struct platform_device *pdev)
{
+ sysfs_remove_group(&pdev->dev.kobj, &as7926_40xfb_sys_group);
sysfs_eeprom_cleanup(&pdev->dev.kobj, &data->eeprom);
return 0;
diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/fani.c b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/fani.c
index afa1efc26..d1efce68c 100644
--- a/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/fani.c
+++ b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/fani.c
@@ -64,15 +64,6 @@ enum fan_id {
{ 0 },\
}
-#define AIM_FREE_IF_PTR(p) \
- do \
- { \
- if (p) { \
- aim_free(p); \
- p = NULL; \
- } \
- } while (0)
-
/* Static fan information */
onlp_fan_info_t finfo[] = {
{ }, /* Not used */
diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/platform_lib.c b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/platform_lib.c
new file mode 100644
index 000000000..24798e21f
--- /dev/null
+++ b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/platform_lib.c
@@ -0,0 +1,65 @@
+/************************************************************
+ *
+ *
+ * Copyright 2014 Big Switch 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.
+ *
+ *
+ ************************************************************
+ *
+ * Platform Library
+ *
+ ***********************************************************/
+#include
+#include
+#include
+#include "platform_lib.h"
+
+#define WARM_RESET_FORMAT "/sys/devices/platform/as7926_40xfb_sys/reset_%s"
+
+/**
+ * @brief warm reset for mac, mux, op2, gb and jr2
+ * @param unit_id The warm reset device unit id, should be 0
+ * @param reset_dev The warm reset device id, should be 1 ~ (WARM_RESET_MAX-1)
+ * @param ret return value.
+ */
+int onlp_data_path_reset(uint8_t unit_id, uint8_t reset_dev)
+{
+ int len = 0;
+ int ret = ONLP_STATUS_OK;
+ char *magic_num = NULL;
+ char *device_id[] = { NULL, "mac", NULL, "mux", "op2", "gb", "jr2" };
+
+ if (unit_id != 0 || reset_dev >= WARM_RESET_MAX)
+ return ONLP_STATUS_E_PARAM;
+
+ if (reset_dev == 0 || reset_dev == WARM_RESET_PHY)
+ return ONLP_STATUS_E_UNSUPPORTED;
+
+ /* Reset device */
+ len = onlp_file_read_str(&magic_num, WARM_RESET_FORMAT, device_id[reset_dev]);
+ if (magic_num && len) {
+ ret = onlp_file_write_str(magic_num, WARM_RESET_FORMAT, device_id[reset_dev]);
+ if (ret < 0) {
+ AIM_LOG_ERROR("Reset device-%d:(%s) failed.", reset_dev, device_id[reset_dev]);
+ }
+ }
+ else {
+ ret = ONLP_STATUS_E_INTERNAL;
+ }
+
+ AIM_FREE_IF_PTR(magic_num);
+ return ret;
+}
diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/platform_lib.h b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/platform_lib.h
index 194bda08e..4ed9a3d82 100644
--- a/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/platform_lib.h
+++ b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/platform_lib.h
@@ -41,6 +41,15 @@
#define FAN_BOARD_PATH "/sys/devices/platform/as7926_40xfb_fan/"
#define IDPROM_PATH "/sys/devices/platform/as7926_40xfb_sys/eeprom"
+#define AIM_FREE_IF_PTR(p) \
+ do \
+ { \
+ if (p) { \
+ aim_free(p); \
+ p = NULL; \
+ } \
+ } while (0)
+
enum onlp_led_id
{
LED_RESERVED = 0,
@@ -68,4 +77,14 @@ enum onlp_thermal_id {
THERMAL_1_ON_PSU2,
};
+enum reset_dev_type {
+ WARM_RESET_MAC = 1,
+ WARM_RESET_PHY, /* Not supported */
+ WARM_RESET_MUX,
+ WARM_RESET_OP2,
+ WARM_RESET_GB,
+ WARM_RESET_JR2,
+ WARM_RESET_MAX
+};
+
#endif /* __PLATFORM_LIB_H__ */
diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/psui.c b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/psui.c
index 58a55d9be..24fb4337a 100644
--- a/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/psui.c
+++ b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/psui.c
@@ -37,15 +37,6 @@
} \
} while(0)
-#define AIM_FREE_IF_PTR(p) \
- do \
- { \
- if (p) { \
- aim_free(p); \
- p = NULL; \
- } \
- } while (0)
-
int
onlp_psui_init(void)
{