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) {