diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py index 330d30b879d..0292e2d52e1 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py @@ -219,8 +219,30 @@ def set_low_power_mode(self, port_num, lpmode): time.sleep(0.01) def reset(self, port_num): - raise NotImplementedError + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + cpld_i = self.get_cpld_num(port_num) + cpld_ps = self._cpld_mapping[cpld_i] + path = "/sys/bus/i2c/devices/{0}/module_reset_{1}" + port_ps = path.format(cpld_ps, port_num) + + self.__port_to_mod_rst = port_ps + try: + reg_file = open(self.__port_to_mod_rst, 'r+', buffering=0) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + + return True @property def _get_present_bitmap(self): nodes = [] diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c index a4ff19fea54..70d9a66affd 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c @@ -285,6 +285,14 @@ enum as7326_56x_cpld_sysfs_attributes { TRANSCEIVER_TXFAULT_ATTR_ID(48), TRANSCEIVER_TXFAULT_ATTR_ID(57), TRANSCEIVER_TXFAULT_ATTR_ID(58), + TRANSCEIVER_RESET_ATTR_ID(49), + TRANSCEIVER_RESET_ATTR_ID(50), + TRANSCEIVER_RESET_ATTR_ID(51), + TRANSCEIVER_RESET_ATTR_ID(52), + TRANSCEIVER_RESET_ATTR_ID(53), + TRANSCEIVER_RESET_ATTR_ID(54), + TRANSCEIVER_RESET_ATTR_ID(55), + TRANSCEIVER_RESET_ATTR_ID(56), }; /* sysfs attributes for hwmon @@ -297,6 +305,8 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t set_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); static ssize_t access(struct device *dev, struct device_attribute *da, const char *buf, size_t count); static ssize_t show_version(struct device *dev, struct device_attribute *da, @@ -437,6 +447,15 @@ DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(57); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(58); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(49); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(50); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(51); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(52); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(53); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(54); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(55); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(56); + static struct attribute *as7326_56x_cpld3_attributes[] = { &sensor_dev_attr_version.dev_attr.attr, &sensor_dev_attr_access.dev_attr.attr, @@ -507,7 +526,7 @@ static struct attribute *as7326_56x_cpld2_attributes[] = { DECLARE_SFP_TRANSCEIVER_ATTR(22), DECLARE_SFP_TRANSCEIVER_ATTR(23), DECLARE_SFP_TRANSCEIVER_ATTR(24), - DECLARE_SFP_TRANSCEIVER_ATTR(25), + DECLARE_SFP_TRANSCEIVER_ATTR(25), DECLARE_SFP_TRANSCEIVER_ATTR(26), DECLARE_SFP_TRANSCEIVER_ATTR(27), DECLARE_SFP_TRANSCEIVER_ATTR(28), @@ -574,6 +593,14 @@ static struct attribute *as7326_56x_cpld1_attributes[] = { DECLARE_SFP_TRANSCEIVER_ATTR(48), DECLARE_SFP_TRANSCEIVER_ATTR(57), DECLARE_SFP_TRANSCEIVER_ATTR(58), + DECLARE_TRANSCEIVER_RESET_ATTR(49), + DECLARE_TRANSCEIVER_RESET_ATTR(50), + DECLARE_TRANSCEIVER_RESET_ATTR(51), + DECLARE_TRANSCEIVER_RESET_ATTR(52), + DECLARE_TRANSCEIVER_RESET_ATTR(53), + DECLARE_TRANSCEIVER_RESET_ATTR(54), + DECLARE_TRANSCEIVER_RESET_ATTR(55), + DECLARE_TRANSCEIVER_RESET_ATTR(56), NULL }; @@ -724,6 +751,11 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, reg = 0x19; mask = 0x1 << (( attr->index - MODULE_RXLOS_57)+2); break; + case MODULE_RESET_49 ... MODULE_RESET_56: + reg = 0x4; + mask = 0x1 << (attr->index - MODULE_RESET_49); + revert = 1; + break; default: return 0; } @@ -806,6 +838,59 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, 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 as7326_56x_cpld_data *data = i2c_get_clientdata(client); + long reset; + int status; + u8 reg = 0, mask = 0; + + status = kstrtol(buf, 10, &reset); + if (status) { + return status; + } + + switch (attr->index) + { + case MODULE_RESET_49 ... MODULE_RESET_56: + reg = 0x4; + mask = 0x1 << (attr->index - MODULE_RESET_49); + break; + default: + return 0; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as7326_56x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update reset status */ + if (!reset) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as7326_56x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + static ssize_t access(struct device *dev, struct device_attribute *da, const char *buf, size_t count) {