diff --git a/packages/platforms/accton/x86-64/as9726-32d/modules/builds/src/x86-64-accton-as9726-32d-cpld.c b/packages/platforms/accton/x86-64/as9726-32d/modules/builds/src/x86-64-accton-as9726-32d-cpld.c index 3aed8f66c..bd1f9f6e3 100644 --- a/packages/platforms/accton/x86-64/as9726-32d/modules/builds/src/x86-64-accton-as9726-32d-cpld.c +++ b/packages/platforms/accton/x86-64/as9726-32d/modules/builds/src/x86-64-accton-as9726-32d-cpld.c @@ -37,6 +37,8 @@ #define I2C_RW_RETRY_COUNT 10 #define I2C_RW_RETRY_INTERVAL 60 /* ms */ +#define MAC_PCIE_RESET_DELAY 100 /* ms */ + static LIST_HEAD(cpld_client_list); static struct mutex list_lock; @@ -76,7 +78,8 @@ MODULE_DEVICE_TABLE(i2c, as9726_32d_cpld_id); enum as9726_32d_cpld_sysfs_attributes { CPLD_VERSION, - BIOS_FLASH_ID, + BIOS_FLASH_ID, + RESET_MAC, ACCESS, MODULE_PRESENT_ALL, MODULE_RXLOS_ALL, @@ -210,6 +213,10 @@ static ssize_t show_bios_flash_id(struct device *dev, struct device_attribute *d static int as9726_32d_cpld_read_internal(struct i2c_client *client, u8 reg); static int as9726_32d_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); +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); /* transceiver attributes */ #define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \ @@ -247,6 +254,8 @@ static int as9726_32d_cpld_write_internal(struct i2c_client *client, u8 reg, static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); static SENSOR_DEVICE_ATTR(bios_flash_id, S_IRUGO, show_bios_flash_id, NULL, BIOS_FLASH_ID); static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); +static SENSOR_DEVICE_ATTR(reset_mac, S_IRUGO | S_IWUSR, \ + get_reset, set_reset, RESET_MAC); static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, \ NULL, MODULE_PRESENT_ALL); @@ -293,6 +302,7 @@ DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34); static struct attribute *as9726_32d_fpga_attributes[] = { &sensor_dev_attr_version.dev_attr.attr, &sensor_dev_attr_access.dev_attr.attr, + &sensor_dev_attr_reset_mac.dev_attr.attr, NULL }; @@ -836,6 +846,113 @@ static ssize_t show_bios_flash_id(struct device *dev, struct device_attribute *a return sprintf(buf, "%d\n", ( ((val >> 2) & 0x1) == 1 ) ? 1 : 2); /*1: master, 2: slave*/ } +static ssize_t get_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as9726_32d_cpld_data *data = i2c_get_clientdata(client); + + int status = 0, val = 0; + u8 reg = 0, mask_mac = 0x80, mask_pcie = 0x10, mask = 0; + + switch (attr->index) { + case RESET_MAC: + reg = 0x8; + mask = mask_mac | mask_pcie; + break; + default: + return 0; + } + + mutex_lock(&data->update_lock); + status = as9726_32d_cpld_read_internal(client, reg); + + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + val = ((status & mask) == 0x0) ? 1 : 0; + return sprintf(buf, "%d\n", val); + +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) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as9726_32d_cpld_data *data = i2c_get_clientdata(client); + long value; + int status; + u8 reg = 0, mask_mac, mask_pcie = 0; + + status = kstrtol(buf, 10, &value); + + if (status) + return status; + + if (value != 1) + return -EINVAL; + + switch (attr->index) { + case RESET_MAC: + reg = 0x8; + mask_mac = 0x80; + mask_pcie = 0x10; + + mutex_lock(&data->update_lock); + + /* put mac & pcie to low */ + status = as9726_32d_cpld_read_internal(client, reg); + if (unlikely(status < 0)) + goto exit; + + status &= ~(mask_mac | mask_pcie); + status = as9726_32d_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) + goto exit; + + /* put mac to high */ + status = as9726_32d_cpld_read_internal(client, reg); + if (unlikely(status < 0)) + goto exit; + + status |= mask_mac; + status = as9726_32d_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) + goto exit; + + msleep(MAC_PCIE_RESET_DELAY); + + /* put pcie to high */ + status = as9726_32d_cpld_read_internal(client, reg); + if (unlikely(status < 0)) + goto exit; + + status |= mask_pcie; + status = as9726_32d_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) + goto exit; + + mutex_unlock(&data->update_lock); + break; + + default: + return -EINVAL; + } + + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + /* * I2C init/probing/exit functions */ diff --git a/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/platform_lib.c b/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/platform_lib.c index 546d303c9..049e97d6e 100644 --- a/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/platform_lib.c +++ b/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/platform_lib.c @@ -205,3 +205,32 @@ enum onlp_fan_dir onlp_get_fan_dir(void) return dir; } + +/** + * @brief warm reset for mac + * @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 ret = ONLP_STATUS_OK; + char *device_id[] = { NULL, "mac" }; + char buf[4] = "1"; + + if (unit_id != 0 || reset_dev >= WARM_RESET_MAX) { + return ONLP_STATUS_E_PARAM; + } + + if (reset_dev == 0) { + return ONLP_STATUS_E_UNSUPPORTED; + } + + /* Reset device */ + ret = onlp_file_write_str(buf, WARM_RESET_FORMAT, device_id[reset_dev]); + if (ret < 0) { + AIM_LOG_ERROR("Reset device-%d:(%s) failed.", reset_dev, device_id[reset_dev]); + } + + return ret; +} diff --git a/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/platform_lib.h b/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/platform_lib.h index c5a535281..78b0884b2 100644 --- a/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/platform_lib.h +++ b/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/platform_lib.h @@ -60,6 +60,7 @@ #define FAN_NODE(node) FAN_BOARD_PATH#node #define IDPROM_PATH "/sys/bus/i2c/devices/13-0056/eeprom" +#define WARM_RESET_FORMAT "/sys/bus/i2c/devices/1-0060/reset_mac" enum onlp_thermal_id { @@ -96,6 +97,11 @@ enum onlp_fan_dir { FAN_DIR_COUNT, }; +enum reset_dev_type { + WARM_RESET_MAC = 1, + WARM_RESET_MAX +}; + enum onlp_fan_dir onlp_get_fan_dir(void); psu_type_t get_psu_type(int id, char* modelname, int modelname_len);