From e3ca171b63915aafca95a722fe2ace0a885ac83f Mon Sep 17 00:00:00 2001 From: Jostar Yang Date: Thu, 12 Aug 2021 17:35:38 +0800 Subject: [PATCH] [AS4630-54PE] Add SFP reset and lpmode sysfs Signed-off-by: Jostar Yang --- .../plugins/sfputil.py | 22 +++- .../modules/x86-64-accton-as4630-54pe-cpld.c | 105 +++++++++++++++--- 2 files changed, 109 insertions(+), 18 deletions(-) diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py index fd660ccdc245..e46722974fba 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py @@ -50,7 +50,7 @@ def port_end(self): @property def qsfp_ports(self): - return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) + return list(range(self.QSFP_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -147,7 +147,25 @@ def set_low_power_mode(self, port_num, lpmode): time.sleep(0.01) def reset(self, port_num): - raise NotImplementedError + if not port_num in self.qsfp_ports: + return False + + path = self.BASE_CPLD_PATH + "module_reset_" + str(port_num) + self.__port_to_mod_rst = path + 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_presence_bitmap(self): diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c index d1205516ef53..f7a438feed7f 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c @@ -96,14 +96,16 @@ static const struct i2c_device_id as4630_54pe_cpld_id[] = { }; MODULE_DEVICE_TABLE(i2c, as4630_54pe_cpld_id); -#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index +#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index +#define TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index +#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index #define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index -#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index -#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index +#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index +#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index #define FAN_SPEED_RPM_ATTR_ID(index) FAN_SPEED_RPM_##index -#define FAN_DIRECTION_ID(index) FAN_DIRECTION_##index +#define FAN_DIRECTION_ID(index) FAN_DIRECTION_##index #define FAN_PRESENT_ATTR_ID(index) FAN_PRESENT_##index -#define FAN_FAULT_ATTR_ID(index) FAN_FAULT_##index +#define FAN_FAULT_ATTR_ID(index) FAN_FAULT_##index enum as4630_54pe_cpld_sysfs_attributes { CPLD_VERSION, @@ -123,6 +125,10 @@ enum as4630_54pe_cpld_sysfs_attributes { TRANSCEIVER_PRESENT_ATTR_ID(52), TRANSCEIVER_PRESENT_ATTR_ID(53), TRANSCEIVER_PRESENT_ATTR_ID(54), + TRANSCEIVER_RESET_ATTR_ID(53), + TRANSCEIVER_RESET_ATTR_ID(54), + TRANSCEIVER_LPMODE_ATTR_ID(53), + TRANSCEIVER_LPMODE_ATTR_ID(54), TRANSCEIVER_TXDISABLE_ATTR_ID(49), TRANSCEIVER_TXDISABLE_ATTR_ID(50), TRANSCEIVER_TXDISABLE_ATTR_ID(51), @@ -148,6 +154,8 @@ static ssize_t show_status(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_qsfp(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, @@ -161,10 +169,6 @@ static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, c static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, char *buf); -//static ssize_t show_power(struct device *dev, struct device_attribute *da, - // char *buf); - - /* transceiver attributes */ #define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ @@ -178,11 +182,15 @@ static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, cha &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr - + #define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_lpmode_##index, S_IRUGO | S_IWUSR, show_status, set_qsfp, MODULE_LPMODE_##index); \ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO | S_IWUSR, show_status, set_qsfp, MODULE_RESET_##index); \ static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index); #define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_lpmode_##index.dev_attr.attr, \ + &sensor_dev_attr_module_reset_##index.dev_attr.attr, \ &sensor_dev_attr_module_present_##index.dev_attr.attr @@ -273,7 +281,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, break; case MODULE_TXDISABLE_49 ... MODULE_TXDISABLE_50: reg=0x5; - mask=0x1 << (attr->index==MODULE_TXFAULT_49?7:3); + mask=0x1 << (attr->index==MODULE_TXDISABLE_49?7:3); break; case MODULE_RXLOS_51 ... MODULE_RXLOS_52: @@ -290,12 +298,22 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, break; case MODULE_TXDISABLE_51 ... MODULE_TXDISABLE_52: reg=0x6; - mask=0x1 << (attr->index==MODULE_TXFAULT_51?7:3); + mask=0x1 << (attr->index==MODULE_TXDISABLE_51?7:3); break; case MODULE_PRESENT_53 ... MODULE_PRESENT_54: reg=0x21; mask=0x1 << (attr->index==MODULE_PRESENT_53?0:4); break; + case MODULE_RESET_53 ... MODULE_RESET_54: + reg=0x21; + mask=0x1 << (attr->index==MODULE_RESET_53?3:7); + revert = 1; + break; + case MODULE_LPMODE_53 ... MODULE_LPMODE_54: + reg = 0x21; + mask = 0x1 << (attr->index==MODULE_LPMODE_53?2:6); + revert = 0; + break; default: return 0; } @@ -319,6 +337,61 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, return status; } +static ssize_t set_qsfp(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 as4630_54pe_cpld_data *data = i2c_get_clientdata(client); + long disable; + int status; + u8 reg = 0, mask = 0, revert = 0; + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + reg = 0x21; + switch (attr->index) + { + case MODULE_RESET_53 ... MODULE_RESET_54: + mask=0x1 << (attr->index==MODULE_RESET_53?3:7); + revert = 1; + break; + case MODULE_LPMODE_53 ... MODULE_LPMODE_54: + mask=0x1 << (attr->index==MODULE_LPMODE_53?2:6); + revert = 0; + break; + default: + return 0; + } + + disable = revert ? disable : !disable; + /* Read current status */ + mutex_lock(&data->update_lock); + status = as4630_54pe_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + if (disable) { + status &= ~mask; + } + else { + status |= mask; + } + status = as4630_54pe_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 set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { @@ -338,11 +411,11 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, { case MODULE_TXDISABLE_49 ... MODULE_TXDISABLE_50: reg=0x5; - mask=0x1 << (attr->index==MODULE_TXFAULT_49?7:3); + mask=0x1 << (attr->index==MODULE_TXDISABLE_49?7:3); break; case MODULE_TXDISABLE_51 ... MODULE_TXDISABLE_52: reg=0x6; - mask=0x1 << (attr->index==MODULE_TXFAULT_51?7:3); + mask=0x1 << (attr->index==MODULE_TXDISABLE_51?7:3); break; default: @@ -357,10 +430,10 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, } /* Update tx_disable status */ if (disable) { - status &= ~mask; + status |= mask; } else { - status |= mask; + status &= ~mask; } status = as4630_54pe_cpld_write_internal(client, reg, status); if (unlikely(status < 0)) {