From 9b4a96cb1852f2252ebcd9c0f4c9acd4fe79d0d4 Mon Sep 17 00:00:00 2001
From: Wirut Getbamrung <wgetbum@icloud.com>
Date: Fri, 22 May 2020 17:50:43 +0700
Subject: [PATCH 1/3] [device/celestica]: DX010 platform API update (#4608)

- Fix fancontrol.service path
- Fix return temp format in thermal API
- Improve init time in chassis API
- Upgrade sfp API
---
 .../sonic_platform/chassis.py                 |  177 ++-
 .../sonic_platform/component.py               |   23 +-
 .../sonic_platform/fan.py                     |   73 +-
 .../sonic_platform/helper.py                  |  121 ++
 .../sonic_platform/psu.py                     |   25 +-
 .../sonic_platform/sfp.py                     | 1178 +++++++++++------
 .../sonic_platform/thermal.py                 |   14 +-
 .../debian/platform-modules-dx010.install     |    2 +-
 .../platform-modules-haliburton.install       |    2 +-
 .../dx010/scripts/fancontrol.service          |   12 +
 .../script}/fancontrol.service                |    0
 11 files changed, 1130 insertions(+), 497 deletions(-)
 create mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py
 create mode 100755 platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service
 rename platform/broadcom/sonic-platform-modules-cel/{services/fancontrol => haliburton/script}/fancontrol.service (100%)

diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py
index 91e3dc0bf464..421d03c82bb4 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py
@@ -8,20 +8,10 @@
 #
 #############################################################################
 
-import sys
-import re
-import os
-import subprocess
-import json
-
 try:
+    import sys
     from sonic_platform_base.chassis_base import ChassisBase
-    from sonic_platform.fan import Fan
-    from sonic_platform.psu import Psu
-    from sonic_platform.component import Component
-    from sonic_platform.thermal import Thermal
-    from sonic_platform.sfp import Sfp
-    from sonic_platform.eeprom import Tlv
+    from helper import APIHelper
 except ImportError as e:
     raise ImportError(str(e) + "- required module not found")
 
@@ -44,38 +34,53 @@ class Chassis(ChassisBase):
 
     def __init__(self):
         ChassisBase.__init__(self)
-        self.config_data = {}
+        self._api_helper = APIHelper()
+        self.sfp_module_initialized = False
+        self.__initialize_eeprom()
+        self.is_host = self._api_helper.is_host()
+
+        if not self.is_host:
+            self.__initialize_fan()
+            self.__initialize_psu()
+            self.__initialize_thermals()
+        else:
+            self.__initialize_components()
+
+    def __initialize_sfp(self):
+        from sonic_platform.sfp import Sfp
+        for index in range(0, NUM_SFP):
+            sfp = Sfp(index)
+            self._sfp_list.append(sfp)
+        self.sfp_module_initialized = True
+
+    def __initialize_psu(self):
+        from sonic_platform.psu import Psu
+        for index in range(0, NUM_PSU):
+            psu = Psu(index)
+            self._psu_list.append(psu)
+
+    def __initialize_fan(self):
+        from sonic_platform.fan import Fan
         for fant_index in range(0, NUM_FAN_TRAY):
             for fan_index in range(0, NUM_FAN):
                 fan = Fan(fant_index, fan_index)
                 self._fan_list.append(fan)
-        for index in range(0, NUM_PSU):
-            psu = Psu(index)
-            self._psu_list.append(psu)
+
+    def __initialize_thermals(self):
+        from sonic_platform.thermal import Thermal
         for index in range(0, NUM_THERMAL):
             thermal = Thermal(index)
             self._thermal_list.append(thermal)
-        # sfp index start from 1
-        for index in range(0, NUM_SFP):
-            sfp = Sfp(index)
-            self._sfp_list.append(sfp)
-        for index in range(0, NUM_COMPONENT):
-            component = Component(index)
-            self._component_list.append(component)
 
+    def __initialize_eeprom(self):
+        from sonic_platform.eeprom import Tlv
         self._eeprom = Tlv()
 
-    def __is_host(self):
-        return os.system(HOST_CHK_CMD) == 0
-
-    def __read_txt_file(self, file_path):
-        try:
-            with open(file_path, 'r') as fd:
-                data = fd.read()
-                return data.strip()
-        except IOError:
-            pass
-        return None
+    def __initialize_components(self):
+        from sonic_platform.component import Component
+        for index in range(0, NUM_COMPONENT):
+            component = Component(index)
+            self._component_list.append(component)
 
     def get_base_mac(self):
         """
@@ -107,7 +112,6 @@ def get_system_eeprom_info(self):
     def get_reboot_cause(self):
         """
         Retrieves the cause of the previous reboot
-
         Returns:
             A tuple (string, string) where the first element is a string
             containing the cause of the previous reboot. This string must be
@@ -118,16 +122,14 @@ def get_reboot_cause(self):
         description = 'None'
         reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
 
-        reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.__is_host(
-        ) else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE
-        prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.__is_host(
-        ) else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE
+        reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.is_host else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE
+        prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.is_host else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE
 
         hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER)
 
-        sw_reboot_cause = self.__read_txt_file(
+        sw_reboot_cause = self._api_helper.read_txt_file(
             reboot_cause_path) or "Unknown"
-        prev_sw_reboot_cause = self.__read_txt_file(
+        prev_sw_reboot_cause = self._api_helper.read_txt_file(
             prev_reboot_cause_path) or "Unknown"
 
         if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS) and hw_reboot_cause == "0x11":
@@ -146,18 +148,32 @@ def get_reboot_cause(self):
 
         return (reboot_cause, description)
 
-    def get_watchdog(self):
+    ##############################################################
+    ######################## SFP methods #########################
+    ##############################################################
+
+    def get_num_sfps(self):
         """
-        Retreives hardware watchdog device on this chassis
+        Retrieves the number of sfps available on this chassis
         Returns:
-            An object derived from WatchdogBase representing the hardware
-            watchdog device
+            An integer, the number of sfps available on this chassis
         """
-        if self._watchdog is None:
-            from sonic_platform.watchdog import Watchdog
-            self._watchdog = Watchdog()
+        if not self.sfp_module_initialized:
+            self.__initialize_sfp()
 
-        return self._watchdog
+        return len(self._sfp_list)
+
+    def get_all_sfps(self):
+        """
+        Retrieves all sfps available on this chassis
+        Returns:
+            A list of objects derived from SfpBase representing all sfps
+            available on this chassis
+        """
+        if not self.sfp_module_initialized:
+            self.__initialize_sfp()
+
+        return self._sfp_list
 
     def get_sfp(self, index):
         """
@@ -171,6 +187,8 @@ def get_sfp(self, index):
             An object dervied from SfpBase representing the specified sfp
         """
         sfp = None
+        if not self.sfp_module_initialized:
+            self.__initialize_sfp()
 
         try:
             # The index will start from 1
@@ -179,3 +197,64 @@ def get_sfp(self, index):
             sys.stderr.write("SFP index {} out of range (1-{})\n".format(
                              index, len(self._sfp_list)))
         return sfp
+
+    ##############################################################
+    ####################### Other methods ########################
+    ##############################################################
+
+    def get_watchdog(self):
+        """
+        Retreives hardware watchdog device on this chassis
+        Returns:
+            An object derived from WatchdogBase representing the hardware
+            watchdog device
+        """
+        if self._watchdog is None:
+            from sonic_platform.watchdog import Watchdog
+            self._watchdog = Watchdog()
+
+        return self._watchdog
+
+    ##############################################################
+    ###################### Device methods ########################
+    ##############################################################
+
+    def get_name(self):
+        """
+        Retrieves the name of the device
+            Returns:
+            string: The name of the device
+        """
+        return self._api_helper.hwsku
+
+    def get_presence(self):
+        """
+        Retrieves the presence of the PSU
+        Returns:
+            bool: True if PSU is present, False if not
+        """
+        return True
+
+    def get_model(self):
+        """
+        Retrieves the model number (or part number) of the device
+        Returns:
+            string: Model/part number of device
+        """
+        return self._eeprom.get_pn()
+
+    def get_serial(self):
+        """
+        Retrieves the serial number of the device
+        Returns:
+            string: Serial number of device
+        """
+        return self.get_serial_number()
+
+    def get_status(self):
+        """
+        Retrieves the operational status of the device
+        Returns:
+            A boolean value, True if device is operating properly, False if not
+        """
+        return True
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py
index d94a93474452..e51cd639a2ef 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py
@@ -8,14 +8,13 @@
 #
 #############################################################################
 
-import json
 import os.path
 import shutil
-import shlex
 import subprocess
 
 try:
     from sonic_platform_base.component_base import ComponentBase
+    from helper import APIHelper
 except ImportError as e:
     raise ImportError(str(e) + "- required module not found")
 
@@ -29,7 +28,8 @@
 GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg"
 BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version"
 COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"]
-COMPONENT_DES_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "Basic Input/Output System"]
+COMPONENT_DES_LIST = ["Used for managing the CPU",
+                      "Used for managing QSFP+ ports (1-10)", "Used for managing QSFP+ ports (11-20)", "Used for managing QSFP+ ports (22-32)", "Basic Input/Output System"]
 
 
 class Component(ComponentBase):
@@ -40,24 +40,9 @@ class Component(ComponentBase):
     def __init__(self, component_index):
         ComponentBase.__init__(self)
         self.index = component_index
+        self._api_helper = APIHelper()
         self.name = self.get_name()
 
-    def __run_command(self, command):
-        # Run bash command and print output to stdout
-        try:
-            process = subprocess.Popen(
-                shlex.split(command), stdout=subprocess.PIPE)
-            while True:
-                output = process.stdout.readline()
-                if output == '' and process.poll() is not None:
-                    break
-            rc = process.poll()
-            if rc != 0:
-                return False
-        except:
-            return False
-        return True
-
     def __get_bios_version(self):
         # Retrieves the BIOS firmware version
         try:
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py
index c0724e9bb688..c38b57f83cd9 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py
@@ -14,6 +14,7 @@
 
 try:
     from sonic_platform_base.fan_base import FanBase
+    from helper import APIHelper
 except ImportError as e:
     raise ImportError(str(e) + "- required module not found")
 
@@ -38,13 +39,16 @@
         "addr": "5b"
     },
 }
+NULL_VAL = "N/A"
 
 
 class Fan(FanBase):
     """Platform-specific Fan class"""
 
     def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
+        FanBase.__init__(self)
         self.fan_index = fan_index
+        self._api_helper = APIHelper()
         self.fan_tray_index = fan_tray_index
         self.is_psu_fan = is_psu_fan
         if self.is_psu_fan:
@@ -75,16 +79,6 @@ def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
             {'prs': 14, 'dir': 19, 'color': {'red': 37, 'green': 38}},  # 4
             {'prs': 12, 'dir': 17, 'color': {'red': 33, 'green': 34}},  # 5
         ]
-        FanBase.__init__(self)
-
-    def __read_txt_file(self, file_path):
-        try:
-            with open(file_path, 'r') as fd:
-                data = fd.read()
-                return data.strip()
-        except IOError:
-            pass
-        return ""
 
     def __write_txt_file(self, file_path, value):
         try:
@@ -105,7 +99,7 @@ def __search_file_by_name(self, directory, file_name):
     def __get_gpio_base(self):
         for r in os.listdir(GPIO_DIR):
             label_path = os.path.join(GPIO_DIR, r, "label")
-            if "gpiochip" in r and GPIO_LABEL in self.__read_txt_file(label_path):
+            if "gpiochip" in r and GPIO_LABEL in self._api_helper.read_txt_file(label_path):
                 return int(r[8:], 10)
         return 216  # Reserve
 
@@ -113,7 +107,7 @@ def __get_gpio_value(self, pinnum):
         gpio_base = self.dx010_fan_gpio[0]['base']
         gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
         gpio_file = gpio_dir + "/value"
-        retval = self.__read_txt_file(gpio_file)
+        retval = self._api_helper.read_txt_file(gpio_file)
         return retval.rstrip('\r\n')
 
     def __set_gpio_value(self, pinnum, value=0):
@@ -154,7 +148,8 @@ def get_speed(self):
             fan_speed_sysfs_name = "fan{}_input".format(self.fan_index+1)
             fan_speed_sysfs_path = self.__search_file_by_name(
                 self.psu_hwmon_path, fan_speed_sysfs_name)
-            fan_speed_rpm = self.__read_txt_file(fan_speed_sysfs_path) or 0
+            fan_speed_rpm = self._api_helper.read_txt_file(
+                fan_speed_sysfs_path) or 0
             fan_speed_raw = float(fan_speed_rpm)/PSU_FAN_MAX_RPM * 100
             speed = math.ceil(float(fan_speed_rpm) * 100 / PSU_FAN_MAX_RPM)
         elif self.get_presence():
@@ -164,7 +159,7 @@ def get_speed(self):
             sysfs_path = "%s%s/%s" % (
                 EMC2305_PATH, device, EMC2305_FAN_INPUT)
             sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
-            raw = self.__read_txt_file(sysfs_path).strip('\r\n')
+            raw = self._api_helper.read_txt_file(sysfs_path).strip('\r\n')
             pwm = int(raw, 10) if raw else 0
             speed = math.ceil(float(pwm * 100 / EMC2305_MAX_PWM))
 
@@ -183,19 +178,7 @@ def get_target_speed(self):
             0   : when PWM mode is use
             pwm : when pwm mode is not use
         """
-        target = 0
-        if not self.is_psu_fan:
-            chip = self.emc2305_chip_mapping[self.fan_index]
-            device = chip['device']
-            fan_index = chip['index_map']
-            sysfs_path = "%s%s/%s" % (
-                EMC2305_PATH, device, EMC2305_FAN_TARGET)
-            sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
-            raw = self.__read_txt_file(sysfs_path).strip('\r\n')
-            pwm = int(raw, 10) if raw else 0
-            target = math.ceil(float(pwm) * 100 / EMC2305_MAX_PWM)
-
-        return target
+        return 'N/A'
 
     def get_speed_tolerance(self):
         """
@@ -284,11 +267,43 @@ def get_name(self):
 
     def get_presence(self):
         """
-        Retrieves the presence of the PSU
+        Retrieves the presence of the FAN
         Returns:
-            bool: True if PSU is present, False if not
+            bool: True if FAN is present, False if not
         """
         present_str = self.__get_gpio_value(
             self.dx010_fan_gpio[self.fan_tray_index+1]['prs'])
 
         return int(present_str, 10) == 0 if not self.is_psu_fan else True
+
+    def get_model(self):
+        """
+        Retrieves the model number (or part number) of the device
+        Returns:
+            string: Model/part number of device
+        """
+        if self.is_psu_fan:
+            return NULL_VAL
+
+        model = NULL_VAL
+        return model
+
+    def get_serial(self):
+        """
+        Retrieves the serial number of the device
+        Returns:
+            string: Serial number of device
+        """
+        if self.is_psu_fan:
+            return NULL_VAL
+
+        serial = NULL_VAL
+        return serial
+
+    def get_status(self):
+        """
+        Retrieves the operational status of the device
+        Returns:
+            A boolean value, True if device is operating properly, False if not
+        """
+        return self.get_presence() and self.get_speed() > 0
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py
new file mode 100644
index 000000000000..86fc5ea726ef
--- /dev/null
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+
+import os
+import struct
+import subprocess
+from sonic_daemon_base.daemon_base import DaemonBase
+from mmap import *
+
+HOST_CHK_CMD = "docker > /dev/null 2>&1"
+EMPTY_STRING = ""
+
+
+class APIHelper():
+
+    def __init__(self):
+        (self.platform, self.hwsku) = DaemonBase().get_platform_and_hwsku()
+
+    def is_host(self):
+        return os.system(HOST_CHK_CMD) == 0
+
+    def pci_get_value(self, resource, offset):
+        status = True
+        result = ""
+        try:
+            fd = os.open(resource, os.O_RDWR)
+            mm = mmap(fd, 0)
+            mm.seek(int(offset))
+            read_data_stream = mm.read(4)
+            result = struct.unpack('I', read_data_stream)
+        except:
+            status = False
+        return status, result
+
+    def run_command(self, cmd):
+        status = True
+        result = ""
+        try:
+            p = subprocess.Popen(
+                cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            raw_data, err = p.communicate()
+            if err == '':
+                result = raw_data.strip()
+        except:
+            status = False
+        return status, result
+
+    def run_interactive_command(self, cmd):
+        try:
+            os.system(cmd)
+        except:
+            return False
+        return True
+
+    def read_txt_file(self, file_path):
+        try:
+            with open(file_path, 'r') as fd:
+                data = fd.read()
+                return data.strip()
+        except IOError:
+            pass
+        return None
+
+    def read_one_line_file(self, file_path):
+        try:
+            with open(file_path, 'r') as fd:
+                data = fd.readline()
+                return data.strip()
+        except IOError:
+            pass
+        return None
+
+    def ipmi_raw(self, netfn, cmd):
+        status = True
+        result = ""
+        try:
+            cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd))
+            p = subprocess.Popen(
+                cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            raw_data, err = p.communicate()
+            if err == '':
+                result = raw_data.strip()
+            else:
+                status = False
+        except:
+            status = False
+        return status, result
+
+    def ipmi_fru_id(self, id, key=None):
+        status = True
+        result = ""
+        try:
+            cmd = "ipmitool fru print {}".format(str(
+                id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key))
+
+            p = subprocess.Popen(
+                cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            raw_data, err = p.communicate()
+            if err == '':
+                result = raw_data.strip()
+            else:
+                status = False
+        except:
+            status = False
+        return status, result
+
+    def ipmi_set_ss_thres(self, id, threshold_key, value):
+        status = True
+        result = ""
+        try:
+            cmd = "ipmitool sensor thresh '{}' {} {}".format(
+                str(id), str(threshold_key), str(value))
+            p = subprocess.Popen(
+                cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            raw_data, err = p.communicate()
+            if err == '':
+                result = raw_data.strip()
+            else:
+                status = False
+        except:
+            status = False
+        return status, result
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py
index 8558b0b0cadd..d34c130dd4be 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py
@@ -14,6 +14,7 @@
 try:
     from sonic_platform_base.psu_base import PsuBase
     from sonic_platform.fan import Fan
+    from helper import APIHelper
 except ImportError as e:
     raise ImportError(str(e) + "- required module not found")
 
@@ -41,6 +42,7 @@ class Psu(PsuBase):
     def __init__(self, psu_index):
         PsuBase.__init__(self)
         self.index = psu_index
+        self._api_helper = APIHelper()
         self.green_led_path = GREEN_LED_PATH.format(self.index+1)
         self.dx010_psu_gpio = [
             {'base': self.__get_gpio_base()},
@@ -54,27 +56,18 @@ def __init__(self, psu_index):
             fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index)
             self._fan_list.append(fan)
 
-    def __read_txt_file(self, file_path):
-        try:
-            with open(file_path, 'r') as fd:
-                data = fd.read()
-                return data.strip()
-        except IOError:
-            pass
-        return ""
-
     def __search_file_by_contain(self, directory, search_str, file_start):
         for dirpath, dirnames, files in os.walk(directory):
             for name in files:
                 file_path = os.path.join(dirpath, name)
-                if name.startswith(file_start) and search_str in self.__read_txt_file(file_path):
+                if name.startswith(file_start) and search_str in self._api_helper.read_txt_file(file_path):
                     return file_path
         return None
 
     def __get_gpio_base(self):
         for r in os.listdir(GPIO_DIR):
             label_path = os.path.join(GPIO_DIR, r, "label")
-            if "gpiochip" in r and GPIO_LABEL in self.__read_txt_file(label_path):
+            if "gpiochip" in r and GPIO_LABEL in self._api_helper.read_txt_file(label_path):
                 return int(r[8:], 10)
         return 216  # Reserve
 
@@ -82,7 +75,7 @@ def __get_gpio_value(self, pinnum):
         gpio_base = self.dx010_psu_gpio[0]['base']
         gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
         gpio_file = gpio_dir + "/value"
-        retval = self.__read_txt_file(gpio_file)
+        retval = self._api_helper.read_txt_file(gpio_file)
         return retval.rstrip('\r\n')
 
     def get_voltage(self):
@@ -104,7 +97,7 @@ def get_voltage(self):
             in_num = filter(str.isdigit, basename)
             vout_path = os.path.join(
                 dir_name, voltage_name.format(in_num))
-            vout_val = self.__read_txt_file(vout_path)
+            vout_val = self._api_helper.read_txt_file(vout_path)
             psu_voltage = float(vout_val) / 1000
 
         return psu_voltage
@@ -127,7 +120,7 @@ def get_current(self):
             cur_num = filter(str.isdigit, basename)
             cur_path = os.path.join(
                 dir_name, current_name.format(cur_num))
-            cur_val = self.__read_txt_file(cur_path)
+            cur_val = self._api_helper.read_txt_file(cur_path)
             psu_current = float(cur_val) / 1000
 
         return psu_current
@@ -150,7 +143,7 @@ def get_power(self):
             pw_num = filter(str.isdigit, basename)
             pw_path = os.path.join(
                 dir_name, current_name.format(pw_num))
-            pw_val = self.__read_txt_file(pw_path)
+            pw_val = self._api_helper.read_txt_file(pw_path)
             psu_power = float(pw_val) / 1000000
 
         return psu_power
@@ -196,7 +189,7 @@ def get_status_led(self):
         Returns:
             A string, one of the predefined STATUS_LED_COLOR_* strings above
         """
-        status = self.__read_txt_file(self.green_led_path)
+        status = self._api_helper.read_txt_file(self.green_led_path)
         status_str = {
             '255': self.STATUS_LED_COLOR_GREEN,
             '0': self.STATUS_LED_COLOR_OFF
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py
index 09c965a9b925..9b447798dddd 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py
@@ -8,26 +8,46 @@
 #
 #############################################################################
 
-import os
 import time
 import subprocess
 from ctypes import create_string_buffer
 
 try:
     from sonic_platform_base.sfp_base import SfpBase
-    from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
+    from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
+    from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
     from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
+    from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
+    from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId
     from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
+    from helper import APIHelper
 except ImportError as e:
     raise ImportError(str(e) + "- required module not found")
 
 INFO_OFFSET = 128
 DOM_OFFSET = 0
 
+# definitions of the offset and width for values in XCVR info eeprom
 XCVR_INTFACE_BULK_OFFSET = 0
 XCVR_INTFACE_BULK_WIDTH_QSFP = 20
-XCVR_HW_REV_WIDTH_QSFP = 2
+XCVR_INTFACE_BULK_WIDTH_SFP = 21
+XCVR_TYPE_OFFSET = 0
+XCVR_TYPE_WIDTH = 1
+XCVR_EXT_TYPE_OFFSET = 1
+XCVR_EXT_TYPE_WIDTH = 1
+XCVR_CONNECTOR_OFFSET = 2
+XCVR_CONNECTOR_WIDTH = 1
+XCVR_COMPLIANCE_CODE_OFFSET = 3
+XCVR_COMPLIANCE_CODE_WIDTH = 8
+XCVR_ENCODING_OFFSET = 11
+XCVR_ENCODING_WIDTH = 1
+XCVR_NBR_OFFSET = 12
+XCVR_NBR_WIDTH = 1
+XCVR_EXT_RATE_SEL_OFFSET = 13
+XCVR_EXT_RATE_SEL_WIDTH = 1
+XCVR_CABLE_LENGTH_OFFSET = 14
 XCVR_CABLE_LENGTH_WIDTH_QSFP = 5
+XCVR_CABLE_LENGTH_WIDTH_SFP = 6
 XCVR_VENDOR_NAME_OFFSET = 20
 XCVR_VENDOR_NAME_WIDTH = 16
 XCVR_VENDOR_OUI_OFFSET = 37
@@ -36,13 +56,29 @@
 XCVR_VENDOR_PN_WIDTH = 16
 XCVR_HW_REV_OFFSET = 56
 XCVR_HW_REV_WIDTH_OSFP = 2
+XCVR_HW_REV_WIDTH_QSFP = 2
 XCVR_HW_REV_WIDTH_SFP = 4
 XCVR_VENDOR_SN_OFFSET = 68
 XCVR_VENDOR_SN_WIDTH = 16
 XCVR_VENDOR_DATE_OFFSET = 84
 XCVR_VENDOR_DATE_WIDTH = 8
 XCVR_DOM_CAPABILITY_OFFSET = 92
-XCVR_DOM_CAPABILITY_WIDTH = 1
+XCVR_DOM_CAPABILITY_WIDTH = 2
+
+XCVR_INTERFACE_DATA_START = 0
+XCVR_INTERFACE_DATA_SIZE = 92
+
+QSFP_DOM_BULK_DATA_START = 22
+QSFP_DOM_BULK_DATA_SIZE = 36
+SFP_DOM_BULK_DATA_START = 96
+SFP_DOM_BULK_DATA_SIZE = 10
+
+# definitions of the offset for values in OSFP info eeprom
+OSFP_TYPE_OFFSET = 0
+OSFP_VENDOR_NAME_OFFSET = 129
+OSFP_VENDOR_PN_OFFSET = 148
+OSFP_HW_REV_OFFSET = 164
+OSFP_VENDOR_SN_OFFSET = 166
 
 # Offset for values in QSFP eeprom
 QSFP_DOM_REV_OFFSET = 1
@@ -51,62 +87,110 @@
 QSFP_TEMPE_WIDTH = 2
 QSFP_VOLT_OFFSET = 26
 QSFP_VOLT_WIDTH = 2
+QSFP_VERSION_COMPLIANCE_OFFSET = 1
+QSFP_VERSION_COMPLIANCE_WIDTH = 2
 QSFP_CHANNL_MON_OFFSET = 34
 QSFP_CHANNL_MON_WIDTH = 16
 QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24
-QSFP_CONTROL_OFFSET = 86
-QSFP_CONTROL_WIDTH = 8
+QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86
+QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1
 QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3
 QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1
 QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4
 QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1
+QSFP_CONTROL_OFFSET = 86
+QSFP_CONTROL_WIDTH = 8
+QSFP_MODULE_MONITOR_OFFSET = 0
+QSFP_MODULE_MONITOR_WIDTH = 9
 QSFP_POWEROVERRIDE_OFFSET = 93
 QSFP_POWEROVERRIDE_WIDTH = 1
+QSFP_POWEROVERRIDE_BIT = 0
+QSFP_POWERSET_BIT = 1
+QSFP_OPTION_VALUE_OFFSET = 192
+QSFP_OPTION_VALUE_WIDTH = 4
+QSFP_MODULE_UPPER_PAGE3_START = 384
 QSFP_MODULE_THRESHOLD_OFFSET = 128
 QSFP_MODULE_THRESHOLD_WIDTH = 24
-QSFP_CHANNEL_THRESHOLD_OFFSET = 176
-QSFP_CHANNEL_THRESHOLD_WIDTH = 16
+QSFP_CHANNL_THRESHOLD_OFFSET = 176
+QSFP_CHANNL_THRESHOLD_WIDTH = 24
+
+SFP_MODULE_ADDRA2_OFFSET = 256
+SFP_MODULE_THRESHOLD_OFFSET = 0
+SFP_MODULE_THRESHOLD_WIDTH = 56
+SFP_CHANNL_THRESHOLD_OFFSET = 112
+SFP_CHANNL_THRESHOLD_WIDTH = 2
+
+SFP_TEMPE_OFFSET = 96
+SFP_TEMPE_WIDTH = 2
+SFP_VOLT_OFFSET = 98
+SFP_VOLT_WIDTH = 2
+SFP_CHANNL_MON_OFFSET = 100
+SFP_CHANNL_MON_WIDTH = 6
+SFP_CHANNL_STATUS_OFFSET = 110
+SFP_CHANNL_STATUS_WIDTH = 1
+
 
 qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)',
                          'Length OM2(m)', 'Length OM1(m)',
                          'Length Cable Assembly(m)')
 
+sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
+                        'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
+                        'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)')
+
+sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode',
+                           'ESCONComplianceCodes', 'SONETComplianceCodes',
+                           'EthernetComplianceCodes', 'FibreChannelLinkLength',
+                           'FibreChannelTechnology', 'SFP+CableTechnology',
+                           'FibreChannelTransmissionMedia', 'FibreChannelSpeed')
+
 qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes',
                             'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes',
                             'Fibre Channel link length/Transmitter Technology',
                             'Fibre Channel transmission media', 'Fibre Channel Speed')
 
+SFP_TYPE = "SFP"
+QSFP_TYPE = "QSFP"
+OSFP_TYPE = "OSFP"
+
+PORT_START = 1
+PORT_END = 56
+QSFP_PORT_START = 1
+QSFP_PORT_END = 32
+
+SFP_I2C_START = 26
 
 
 class Sfp(SfpBase):
     """Platform-specific Sfp class"""
 
-    # Port number
-    PORT_START = 1
-    PORT_END = 32
-
     # Path to QSFP sysfs
     RESET_PATH = "/sys/devices/platform/dx010_cpld/qsfp_reset"
     LP_PATH = "/sys/devices/platform/dx010_cpld/qsfp_lpmode"
     PRS_PATH = "/sys/devices/platform/dx010_cpld/qsfp_modprs"
     PLATFORM_ROOT_PATH = "/usr/share/sonic/device"
     PMON_HWSKU_PATH = "/usr/share/sonic/hwsku"
-    HOST_CHK_CMD = "docker > /dev/null 2>&1"
-
-    PLATFORM = "x86_64-cel_seastone-r0"
-    HWSKU = "Seastone-DX010"
 
     def __init__(self, sfp_index):
+        SfpBase.__init__(self)
         # Init index
         self.index = sfp_index
         self.port_num = self.index + 1
+        self.dom_supported = False
+        self.sfp_type, self.port_name = self.__get_sfp_info()
+        self._api_helper = APIHelper()
+        self.platform = self._api_helper.platform
+        self.hwsku = self._api_helper.hwsku
 
         # Init eeprom path
         eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
         self.port_to_eeprom_mapping = {}
-        for x in range(self.PORT_START, self.PORT_END + 1):
-            p_num = x - 1 if self.PORT_START == 1 else x
-            self.port_to_eeprom_mapping[x] = eeprom_path.format(p_num + 26)
+        self.port_to_i2c_mapping = {}
+
+        for x in range(PORT_START, PORT_END + 1):
+            self.port_to_i2c_mapping[x] = (SFP_I2C_START + x) - 1
+            port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x])
+            self.port_to_eeprom_mapping[x] = port_eeprom_path
 
         self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier',
                                'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui']
@@ -117,9 +201,21 @@ def __init__(self, sfp_index):
         self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning',
                                     'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
 
-        SfpBase.__init__(self)
+        self._dom_capability_detect()
+
+    def __get_sfp_info(self):
+        port_name = "Unknown"
+        sfp_type = "Unknown"
 
-    def _convert_string_to_num(self, value_str):
+        if self.port_num >= QSFP_PORT_START and self.port_num <= QSFP_TYPE:
+            sfp_type = QSFP_TYPE
+            port_name = "QSFP" + str(self.port_num - QSFP_PORT_START + 1)
+        elif self.port_num >= SFP_PORT_START and self.port_num <= SFP_PORT_END:
+            sfp_type = SFP_TYPE
+            port_name = "SFP" + str(self.port_num - SFP_PORT_START + 1)
+        return sfp_type, port_name
+
+    def __convert_string_to_num(self, value_str):
         if "-inf" in value_str:
             return 'N/A'
         elif "Unknown" in value_str:
@@ -139,22 +235,10 @@ def _convert_string_to_num(self, value_str):
         else:
             return 'N/A'
 
-    def __read_txt_file(self, file_path):
-        try:
-            with open(file_path, 'r') as fd:
-                data = fd.read()
-                return data.strip()
-        except IOError:
-            pass
-        return ""
-
-    def __is_host(self):
-        return os.system(self.HOST_CHK_CMD) == 0
-
     def __get_path_to_port_config_file(self):
-        platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM])
-        hwsku_path = "/".join([platform_path, self.HWSKU]
-                              ) if self.__is_host() else self.PMON_HWSKU_PATH
+        platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.platform])
+        hwsku_path = "/".join([platform_path, self.hwsku]
+                              ) if self._api_helper.is_host() else self.PMON_HWSKU_PATH
         return "/".join([hwsku_path, "port_config.ini"])
 
     def __read_eeprom_specific_bytes(self, offset, num_bytes):
@@ -179,6 +263,106 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes):
 
         return eeprom_raw
 
+    def _dom_capability_detect(self):
+        if not self.get_presence():
+            self.dom_supported = False
+            self.dom_temp_supported = False
+            self.dom_volt_supported = False
+            self.dom_rx_power_supported = False
+            self.dom_tx_power_supported = False
+            self.calibration = 0
+            return
+
+        if self.sfp_type == "QSFP":
+            self.calibration = 1
+            sfpi_obj = sff8436InterfaceId()
+            if sfpi_obj is None:
+                self.dom_supported = False
+            offset = 128
+
+            # QSFP capability byte parse, through this byte can know whether it support tx_power or not.
+            # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
+            # need to add more code for determining the capability and version compliance
+            # in SFF-8636 dom capability definitions evolving with the versions.
+            qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes(
+                (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH)
+            if qsfp_dom_capability_raw is not None:
+                qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes(
+                    QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH)
+                qsfp_version_compliance = int(
+                    qsfp_version_compliance_raw[0], 16)
+                dom_capability = sfpi_obj.parse_qsfp_dom_capability(
+                    qsfp_dom_capability_raw, 0)
+                if qsfp_version_compliance >= 0x08:
+                    self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On'
+                    self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On'
+                    self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On'
+                    self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On'
+                else:
+                    self.dom_temp_supported = True
+                    self.dom_volt_supported = True
+                    self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On'
+                    self.dom_tx_power_supported = True
+
+                self.dom_supported = True
+                self.calibration = 1
+                sfpd_obj = sff8436Dom()
+                if sfpd_obj is None:
+                    return None
+                qsfp_option_value_raw = self.__read_eeprom_specific_bytes(
+                    QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH)
+                if qsfp_option_value_raw is not None:
+                    optional_capability = sfpd_obj.parse_option_params(
+                        qsfp_option_value_raw, 0)
+                    self.dom_tx_disable_supported = optional_capability[
+                        'data']['TxDisable']['value'] == 'On'
+                dom_status_indicator = sfpd_obj.parse_dom_status_indicator(
+                    qsfp_version_compliance_raw, 1)
+                self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off'
+            else:
+                self.dom_supported = False
+                self.dom_temp_supported = False
+                self.dom_volt_supported = False
+                self.dom_rx_power_supported = False
+                self.dom_tx_power_supported = False
+                self.calibration = 0
+                self.qsfp_page3_available = False
+
+        elif self.sfp_type == "SFP":
+            sfpi_obj = sff8472InterfaceId()
+            if sfpi_obj is None:
+                return None
+            sfp_dom_capability_raw = self.__read_eeprom_specific_bytes(
+                XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH)
+            if sfp_dom_capability_raw is not None:
+                sfp_dom_capability = int(sfp_dom_capability_raw[0], 16)
+                self.dom_supported = (sfp_dom_capability & 0x40 != 0)
+                if self.dom_supported:
+                    self.dom_temp_supported = True
+                    self.dom_volt_supported = True
+                    self.dom_rx_power_supported = True
+                    self.dom_tx_power_supported = True
+                    if sfp_dom_capability & 0x20 != 0:
+                        self.calibration = 1
+                    elif sfp_dom_capability & 0x10 != 0:
+                        self.calibration = 2
+                    else:
+                        self.calibration = 0
+                else:
+                    self.dom_temp_supported = False
+                    self.dom_volt_supported = False
+                    self.dom_rx_power_supported = False
+                    self.dom_tx_power_supported = False
+                    self.calibration = 0
+                self.dom_tx_disable_supported = (
+                    int(sfp_dom_capability_raw[1], 16) & 0x40 != 0)
+        else:
+            self.dom_supported = False
+            self.dom_temp_supported = False
+            self.dom_volt_supported = False
+            self.dom_rx_power_supported = False
+            self.dom_tx_power_supported = False
+
     def get_transceiver_info(self):
         """
         Retrieves transceiver info of this SFP
@@ -202,85 +386,183 @@ def get_transceiver_info(self):
         vendor_date                |1*255VCHAR     |vendor date
         vendor_oui                 |1*255VCHAR     |vendor OUI
         ========================================================================
-        """
-        # check present status
-        sfpi_obj = sff8436InterfaceId()
-        if not self.get_presence() or not sfpi_obj:
-            return {}
-
-        offset = INFO_OFFSET
-
-        sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(
-            (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP)
-        sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(
-            sfp_interface_bulk_raw, 0)
-
-        sfp_vendor_name_raw = self.__read_eeprom_specific_bytes(
-            (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
-        sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
-            sfp_vendor_name_raw, 0)
-
-        sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
-            (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
-        sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
-            sfp_vendor_pn_raw, 0)
-
-        sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes(
-            (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP)
-        sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
-            sfp_vendor_rev_raw, 0)
-
-        sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
-            (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
-        sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
-            sfp_vendor_sn_raw, 0)
-
-        sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes(
-            (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
-        if sfp_vendor_oui_raw is not None:
-            sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(
-                sfp_vendor_oui_raw, 0)
-
-        sfp_vendor_date_raw = self.__read_eeprom_specific_bytes(
-            (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
-        sfp_vendor_date_data = sfpi_obj.parse_vendor_date(
-            sfp_vendor_date_raw, 0)
-
+         """
+        compliance_code_dict = {}
         transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A')
-        compliance_code_dict = dict()
+        if not self.get_presence():
+            return transceiver_info_dict
+
+        # ToDo: OSFP tranceiver info parsing not fully supported.
+        # in inf8628.py lack of some memory map definition
+        # will be implemented when the inf8628 memory map ready
+        if self.sfp_type == OSFP_TYPE:
+            offset = 0
+            vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP
+
+            sfpi_obj = inf8628InterfaceId()
+            if sfpi_obj is None:
+                return None
+
+            sfp_type_raw = self.__read_eeprom_specific_bytes(
+                (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH)
+            if sfp_type_raw is not None:
+                sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0)
+            else:
+                return None
+
+            sfp_vendor_name_raw = self.__read_eeprom_specific_bytes(
+                (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
+            if sfp_vendor_name_raw is not None:
+                sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
+                    sfp_vendor_name_raw, 0)
+            else:
+                return None
+
+            sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
+                (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
+            if sfp_vendor_pn_raw is not None:
+                sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
+                    sfp_vendor_pn_raw, 0)
+            else:
+                return None
+
+            sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes(
+                (offset + OSFP_HW_REV_OFFSET), vendor_rev_width)
+            if sfp_vendor_rev_raw is not None:
+                sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
+                    sfp_vendor_rev_raw, 0)
+            else:
+                return None
+
+            sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
+                (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
+            if sfp_vendor_sn_raw is not None:
+                sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
+                    sfp_vendor_sn_raw, 0)
+            else:
+                return None
+
+            transceiver_info_dict['type'] = sfp_type_data['data']['type']['value']
+            transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value']
+            transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
+            transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
+            transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
+            transceiver_info_dict['vendor_oui'] = 'N/A'
+            transceiver_info_dict['vendor_date'] = 'N/A'
+            transceiver_info_dict['Connector'] = 'N/A'
+            transceiver_info_dict['encoding'] = 'N/A'
+            transceiver_info_dict['ext_identifier'] = 'N/A'
+            transceiver_info_dict['ext_rateselect_compliance'] = 'N/A'
+            transceiver_info_dict['cable_type'] = 'N/A'
+            transceiver_info_dict['cable_length'] = 'N/A'
+            transceiver_info_dict['specification_compliance'] = '{}'
+            transceiver_info_dict['nominal_bit_rate'] = 'N/A'
 
-        if sfp_interface_bulk_data:
+        else:
+            if self.sfp_type == QSFP_TYPE:
+                offset = 128
+                vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP
+                # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP
+                interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP
+
+                sfpi_obj = sff8436InterfaceId()
+                if sfpi_obj is None:
+                    print("Error: sfp_object open failed")
+                    return None
+
+            else:
+                offset = 0
+                vendor_rev_width = XCVR_HW_REV_WIDTH_SFP
+                # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP
+                interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP
+
+                sfpi_obj = sff8472InterfaceId()
+                if sfpi_obj is None:
+                    print("Error: sfp_object open failed")
+                    return None
+            sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(
+                offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE)
+            if sfp_interface_bulk_raw is None:
+                return None
+
+            start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START
+            end = start + interface_info_bulk_width
+            sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(
+                sfp_interface_bulk_raw[start: end], 0)
+
+            start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START
+            end = start + XCVR_VENDOR_NAME_WIDTH
+            sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
+                sfp_interface_bulk_raw[start: end], 0)
+
+            start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START
+            end = start + XCVR_VENDOR_PN_WIDTH
+            sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
+                sfp_interface_bulk_raw[start: end], 0)
+
+            start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START
+            end = start + vendor_rev_width
+            sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
+                sfp_interface_bulk_raw[start: end], 0)
+
+            start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START
+            end = start + XCVR_VENDOR_SN_WIDTH
+            sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
+                sfp_interface_bulk_raw[start: end], 0)
+
+            start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START
+            end = start + XCVR_VENDOR_OUI_WIDTH
+            sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(
+                sfp_interface_bulk_raw[start: end], 0)
+
+            start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START
+            end = start + XCVR_VENDOR_DATE_WIDTH
+            sfp_vendor_date_data = sfpi_obj.parse_vendor_date(
+                sfp_interface_bulk_raw[start: end], 0)
             transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
-            transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value']
+            transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value']
+            transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
+            transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
+            transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
+            transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value']
+            transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[
+                'data']['VendorDataCode(YYYY-MM-DD Lot)']['value']
+            transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value']
             transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
             transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
             transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
-            transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
-
-        transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[
-            'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A'
-        transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
-        transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A'
-        transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
-        transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A'
-        transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[
-            'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A'
-        transceiver_info_dict['cable_type'] = "Unknown"
-        transceiver_info_dict['cable_length'] = "Unknown"
-
-        for key in qsfp_cable_length_tup:
-            if key in sfp_interface_bulk_data['data']:
-                transceiver_info_dict['cable_type'] = key
-                transceiver_info_dict['cable_length'] = str(
-                    sfp_interface_bulk_data['data'][key]['value'])
-
-        for key in qsfp_compliance_code_tup:
-            if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
-                compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
-        transceiver_info_dict['specification_compliance'] = str(
-            compliance_code_dict)
-        transceiver_info_dict['nominal_bit_rate'] = str(
-            sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value'])
+
+
+            if self.sfp_type == QSFP_TYPE:
+                for key in qsfp_cable_length_tup:
+                    if key in sfp_interface_bulk_data['data']:
+                        transceiver_info_dict['cable_type'] = key
+                        transceiver_info_dict['cable_length'] = str(
+                            sfp_interface_bulk_data['data'][key]['value'])
+
+                for key in qsfp_compliance_code_tup:
+                    if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
+                        compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
+                transceiver_info_dict['specification_compliance'] = str(
+                    compliance_code_dict)
+
+                transceiver_info_dict['nominal_bit_rate'] = str(
+                    sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value'])
+            else:
+                for key in sfp_cable_length_tup:
+                    if key in sfp_interface_bulk_data['data']:
+                        transceiver_info_dict['cable_type'] = key
+                        transceiver_info_dict['cable_length'] = str(
+                            sfp_interface_bulk_data['data'][key]['value'])
+
+                for key in sfp_compliance_code_tup:
+                    if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
+                        compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
+                transceiver_info_dict['specification_compliance'] = str(
+                    compliance_code_dict)
+
+                transceiver_info_dict['nominal_bit_rate'] = str(
+                    sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
 
         return transceiver_info_dict
 
@@ -309,84 +591,117 @@ def get_transceiver_bulk_status(self):
                                    |               |for example, tx2power stands for tx power of channel 2.
         ========================================================================
         """
-        # check present status
-        sfpd_obj = sff8436Dom()
-        sfpi_obj = sff8436InterfaceId()
+        transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A')
 
-        if not self.get_presence() or not sfpi_obj or not sfpd_obj:
-            return {}
+        if self.sfp_type == OSFP_TYPE:
+            pass
+
+        elif self.sfp_type == QSFP_TYPE:
+            if not self.dom_supported:
+                return transceiver_dom_info_dict
+
+            offset = 0
+            sfpd_obj = sff8436Dom()
+            if sfpd_obj is None:
+                return transceiver_dom_info_dict
+
+            dom_data_raw = self.__read_eeprom_specific_bytes(
+                (offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE)
+            if dom_data_raw is None:
+                return transceiver_dom_info_dict
+
+            if self.dom_temp_supported:
+                start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START
+                end = start + QSFP_TEMPE_WIDTH
+                dom_temperature_data = sfpd_obj.parse_temperature(
+                    dom_data_raw[start: end], 0)
+                temp = self.__convert_string_to_num(
+                    dom_temperature_data['data']['Temperature']['value'])
+                if temp is not None:
+                    transceiver_dom_info_dict['temperature'] = temp
+
+            if self.dom_volt_supported:
+                start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START
+                end = start + QSFP_VOLT_WIDTH
+                dom_voltage_data = sfpd_obj.parse_voltage(
+                    dom_data_raw[start: end], 0)
+                volt = self.__convert_string_to_num(
+                    dom_voltage_data['data']['Vcc']['value'])
+                if volt is not None:
+                    transceiver_dom_info_dict['voltage'] = volt
+
+            start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START
+            end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH
+            dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(
+                dom_data_raw[start: end], 0)
+
+            if self.dom_tx_power_supported:
+                transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num(
+                    dom_channel_monitor_data['data']['TX1Power']['value'])
+                transceiver_dom_info_dict['tx2power'] = self.__convert_string_to_num(
+                    dom_channel_monitor_data['data']['TX2Power']['value'])
+                transceiver_dom_info_dict['tx3power'] = self.__convert_string_to_num(
+                    dom_channel_monitor_data['data']['TX3Power']['value'])
+                transceiver_dom_info_dict['tx4power'] = self.__convert_string_to_num(
+                    dom_channel_monitor_data['data']['TX4Power']['value'])
+
+            if self.dom_rx_power_supported:
+                transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num(
+                    dom_channel_monitor_data['data']['RX1Power']['value'])
+                transceiver_dom_info_dict['rx2power'] = self.__convert_string_to_num(
+                    dom_channel_monitor_data['data']['RX2Power']['value'])
+                transceiver_dom_info_dict['rx3power'] = self.__convert_string_to_num(
+                    dom_channel_monitor_data['data']['RX3Power']['value'])
+                transceiver_dom_info_dict['rx4power'] = self.__convert_string_to_num(
+                    dom_channel_monitor_data['data']['RX4Power']['value'])
+
+            transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num(
+                dom_channel_monitor_data['data']['TX1Bias']['value'])
+            transceiver_dom_info_dict['tx2bias'] = self.__convert_string_to_num(
+                dom_channel_monitor_data['data']['TX2Bias']['value'])
+            transceiver_dom_info_dict['tx3bias'] = self.__convert_string_to_num(
+                dom_channel_monitor_data['data']['TX3Bias']['value'])
+            transceiver_dom_info_dict['tx4bias'] = self.__convert_string_to_num(
+                dom_channel_monitor_data['data']['TX4Bias']['value'])
 
-        transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A')
-        offset = DOM_OFFSET
-        offset_xcvr = INFO_OFFSET
-
-        # QSFP capability byte parse, through this byte can know whether it support tx_power or not.
-        # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
-        # need to add more code for determining the capability and version compliance
-        # in SFF-8636 dom capability definitions evolving with the versions.
-        qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes(
-            (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH)
-        if qsfp_dom_capability_raw is not None:
-            qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(
-                qsfp_dom_capability_raw, 0)
         else:
-            return None
+            if not self.dom_supported:
+                return transceiver_dom_info_dict
 
-        dom_temperature_raw = self.__read_eeprom_specific_bytes(
-            (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH)
-        if dom_temperature_raw is not None:
-            dom_temperature_data = sfpd_obj.parse_temperature(
-                dom_temperature_raw, 0)
-            transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
-
-        dom_voltage_raw = self.__read_eeprom_specific_bytes(
-            (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH)
-        if dom_voltage_raw is not None:
-            dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
-            transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
-
-        qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes(
-            (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH)
-        if qsfp_dom_rev_raw is not None:
-            qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0)
-            qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value']
-
-        # The tx_power monitoring is only available on QSFP which compliant with SFF-8636
-        # and claimed that it support tx_power with one indicator bit.
-        dom_channel_monitor_data = {}
-        dom_channel_monitor_raw = None
-        qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value']
-        if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')):
-            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
-                (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH)
-            if dom_channel_monitor_raw is not None:
-                dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(
-                    dom_channel_monitor_raw, 0)
+            offset = 256
+            sfpd_obj = sff8472Dom()
+            if sfpd_obj is None:
+                return transceiver_dom_info_dict
+            sfpd_obj._calibration_type = self.calibration
 
-        else:
-            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
-                (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH)
-            if dom_channel_monitor_raw is not None:
-                dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(
-                    dom_channel_monitor_raw, 0)
-                transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value']
-                transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value']
-                transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value']
-                transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value']
-
-        if dom_channel_monitor_raw:
-            transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value']
-            transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value']
-            transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value']
-            transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value']
-            transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value']
-            transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value']
-            transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value']
-            transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value']
-
-        for key in transceiver_dom_info_dict:
-            transceiver_dom_info_dict[key] = self._convert_string_to_num(
-                transceiver_dom_info_dict[key])
+            dom_data_raw = self.__read_eeprom_specific_bytes(
+                (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE)
+
+            start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START
+            end = start + SFP_TEMPE_WIDTH
+            dom_temperature_data = sfpd_obj.parse_temperature(
+                dom_data_raw[start: end], 0)
+
+            start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START
+            end = start + SFP_VOLT_WIDTH
+            dom_voltage_data = sfpd_obj.parse_voltage(
+                dom_data_raw[start: end], 0)
+
+            start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START
+            end = start + SFP_CHANNL_MON_WIDTH
+            dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(
+                dom_data_raw[start: end], 0)
+
+            transceiver_dom_info_dict['temperature'] = self.__convert_string_to_num(
+                dom_temperature_data['data']['Temperature']['value'])
+            transceiver_dom_info_dict['voltage'] = self.__convert_string_to_num(
+                dom_voltage_data['data']['Vcc']['value'])
+            transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num(
+                dom_channel_monitor_data['data']['RXPower']['value'])
+            transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num(
+                dom_channel_monitor_data['data']['TXBias']['value'])
+            transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num(
+                dom_channel_monitor_data['data']['TXPower']['value'])
 
         transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
         transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
@@ -425,55 +740,106 @@ def get_transceiver_threshold_info(self):
         txbiaslowwarning           |FLOAT          |Low Warning Threshold value of tx Bias Current in mA.
         ========================================================================
         """
-        # check present status
-        sfpd_obj = sff8436Dom()
+        transceiver_dom_threshold_info_dict = dict.fromkeys(
+            self.threshold_dict_keys, 'N/A')
 
-        if not self.get_presence() or not sfpd_obj:
-            return {}
+        if self.sfp_type == OSFP_TYPE:
+            pass
 
-        transceiver_dom_threshold_dict = dict.fromkeys(
-            self.threshold_dict_keys, 'N/A')
-        dom_thres_raw = self.__read_eeprom_specific_bytes(
-            QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None
-
-        if dom_thres_raw:
-            module_threshold_values = sfpd_obj.parse_module_threshold_values(
-                dom_thres_raw, 0)
-            module_threshold_data = module_threshold_values.get('data')
-            if module_threshold_data:
-                transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value']
-                transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value']
-                transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value']
-                transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value']
-                transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value']
-                transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value']
-                transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value']
-                transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value']
-
-        dom_thres_raw = self.__read_eeprom_specific_bytes(
-            QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None
-        channel_threshold_values = sfpd_obj.parse_channel_threshold_values(
-            dom_thres_raw, 0)
-        channel_threshold_data = channel_threshold_values.get('data')
-        if channel_threshold_data:
-            transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value']
-            transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value']
-            transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value']
-            transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value']
-            transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm"
-            transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm"
-            transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm"
-            transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm"
-            transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value']
-            transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value']
-            transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value']
-            transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value']
-
-        for key in transceiver_dom_threshold_dict:
-            transceiver_dom_threshold_dict[key] = self._convert_string_to_num(
-                transceiver_dom_threshold_dict[key])
-
-        return transceiver_dom_threshold_dict
+        elif self.sfp_type == QSFP_TYPE:
+            if not self.dom_supported or not self.qsfp_page3_available:
+                return transceiver_dom_threshold_info_dict
+
+            # Dom Threshold data starts from offset 384
+            # Revert offset back to 0 once data is retrieved
+            offset = QSFP_MODULE_UPPER_PAGE3_START
+            sfpd_obj = sff8436Dom()
+            if sfpd_obj is None:
+                return transceiver_dom_threshold_info_dict
+
+            dom_module_threshold_raw = self.__read_eeprom_specific_bytes(
+                (offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH)
+            if dom_module_threshold_raw is None:
+                return transceiver_dom_threshold_info_dict
+
+            dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(
+                dom_module_threshold_raw, 0)
+
+            dom_channel_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET),
+                                                                          QSFP_CHANNL_THRESHOLD_WIDTH)
+            if dom_channel_threshold_raw is None:
+                return transceiver_dom_threshold_info_dict
+            dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(
+                dom_channel_threshold_raw, 0)
+
+            # Threshold Data
+            transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
+            transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
+            transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value']
+            transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value']
+            transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value']
+            transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value']
+            transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value']
+            transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value']
+            transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value']
+            transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value']
+
+        else:
+            offset = SFP_MODULE_ADDRA2_OFFSET
+
+            if not self.dom_supported:
+                return transceiver_dom_threshold_info_dict
+
+            sfpd_obj = sff8472Dom(None, self.calibration)
+            if sfpd_obj is None:
+                return transceiver_dom_threshold_info_dict
+
+            dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET),
+                                                                         SFP_MODULE_THRESHOLD_WIDTH)
+            if dom_module_threshold_raw is not None:
+                dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(
+                    dom_module_threshold_raw, 0)
+            else:
+                return transceiver_dom_threshold_info_dict
+
+            # Threshold Data
+            transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
+            transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
+            transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[
+                'data']['VoltageHighWarning']['value']
+            transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value']
+            transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value']
+            transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value']
+            transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value']
+            transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value']
+            transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value']
+            transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value']
+            transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value']
+            transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value']
+
+        for key in transceiver_dom_threshold_info_dict:
+            transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(
+                transceiver_dom_threshold_info_dict[key])
+
+        return transceiver_dom_threshold_info_dict
 
     def get_reset_status(self):
         """
@@ -481,7 +847,7 @@ def get_reset_status(self):
         Returns:
             A Boolean, True if reset enabled, False if disabled
         """
-        reset_status_raw = self.__read_txt_file(self.RESET_PATH).rstrip()
+        reset_status_raw = self._api_helper.read_txt_file(self.RESET_PATH).rstrip()
         if not reset_status_raw:
             return False
 
@@ -497,16 +863,28 @@ def get_rx_los(self):
             Note : RX LOS status is latched until a call to get_rx_los or a reset.
         """
         rx_los = False
-        rx_los_list = []
-        dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
-            QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None
-        if dom_channel_monitor_raw is not None:
-            rx_los_data = int(dom_channel_monitor_raw[0], 16)
-            rx_los_list.append(rx_los_data & 0x01 != 0)
-            rx_los_list.append(rx_los_data & 0x02 != 0)
-            rx_los_list.append(rx_los_data & 0x04 != 0)
-            rx_los_list.append(rx_los_data & 0x08 != 0)
-            rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3]
+        if self.sfp_type == OSFP_TYPE:
+            return False
+
+        elif self.sfp_type == QSFP_TYPE:
+            offset = 0
+            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+                (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH)
+            if dom_channel_monitor_raw is not None:
+                rx_los_data = int(dom_channel_monitor_raw[0], 16)
+                rx1_los = (rx_los_data & 0x01 != 0)
+                rx2_los = (rx_los_data & 0x02 != 0)
+                rx3_los = (rx_los_data & 0x04 != 0)
+                rx4_los = (rx_los_data & 0x08 != 0)
+                rx_los = (rx1_los and rx2_los and rx3_los and rx4_los)
+        else:
+            offset = 256
+            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+                (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH)
+            if dom_channel_monitor_raw is not None:
+                rx_los_data = int(dom_channel_monitor_raw[0], 16)
+                rx_los = (rx_los_data & 0x02 != 0)
+
         return rx_los
 
     def get_tx_fault(self):
@@ -516,19 +894,32 @@ def get_tx_fault(self):
             A Boolean, True if SFP has TX fault, False if not
             Note : TX fault status is lached until a call to get_tx_fault or a reset.
         """
-        tx_fault = False
-        tx_fault_list = []
-        dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
-            QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None
-        if dom_channel_monitor_raw is not None:
-            tx_fault_data = int(dom_channel_monitor_raw[0], 16)
-            tx_fault_list.append(tx_fault_data & 0x01 != 0)
-            tx_fault_list.append(tx_fault_data & 0x02 != 0)
-            tx_fault_list.append(tx_fault_data & 0x04 != 0)
-            tx_fault_list.append(tx_fault_data & 0x08 != 0)
-            tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3]
+        tx4_fault = False
+
+        if self.sfp_type == OSFP_TYPE or not self.dom_supported:
+            return False
+
+        elif self.sfp_type == QSFP_TYPE:
+            offset = 0
+            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+                (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH)
+            if dom_channel_monitor_raw is not None:
+                tx_fault_data = int(dom_channel_monitor_raw[0], 16)
+                tx1_fault = (tx_fault_data & 0x01 != 0)
+                tx2_fault = (tx_fault_data & 0x02 != 0)
+                tx3_fault = (tx_fault_data & 0x04 != 0)
+                tx4_fault = (tx_fault_data & 0x08 != 0)
+                tx4_fault = (
+                    tx1_fault and tx2_fault and tx3_fault and tx4_fault)
+        else:
+            offset = 256
+            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+                (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH)
+            if dom_channel_monitor_raw is not None:
+                tx_fault_data = int(dom_channel_monitor_raw[0], 16)
+                tx4_fault = (tx_fault_data & 0x04 != 0)
 
-        return tx_fault
+        return tx4_fault
 
     def get_tx_disable(self):
         """
@@ -536,26 +927,33 @@ def get_tx_disable(self):
         Returns:
             A Boolean, True if tx_disable is enabled, False if disabled
         """
-        tx_disable_list = []
 
-        sfpd_obj = sff8436Dom()
-        if sfpd_obj is None:
+        tx_disable = False
+
+        if self.sfp_type == OSFP_TYPE and not self.dom_supported:
             return False
 
-        dom_control_raw = self.__read_eeprom_specific_bytes(
-            QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None
-        if dom_control_raw is not None:
-            dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
-            tx_disable_list.append(
-                'On' == dom_control_data['data']['TX1Disable']['value'])
-            tx_disable_list.append(
-                'On' == dom_control_data['data']['TX2Disable']['value'])
-            tx_disable_list.append(
-                'On' == dom_control_data['data']['TX3Disable']['value'])
-            tx_disable_list.append(
-                'On' == dom_control_data['data']['TX4Disable']['value'])
-
-        return tx_disable_list
+        elif self.sfp_type == QSFP_TYPE:
+            offset = 0
+            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+                (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH)
+            if dom_channel_monitor_raw is not None:
+                tx_disable_data = int(dom_channel_monitor_raw[0], 16)
+                tx1_disable = (tx_disable_data & 0x01 != 0)
+                tx2_disable = (tx_disable_data & 0x02 != 0)
+                tx3_disable = (tx_disable_data & 0x04 != 0)
+                tx4_disable = (tx_disable_data & 0x08 != 0)
+                tx_disable = (
+                    tx1_disable and tx2_disable and tx3_disable and tx4_disable)
+        else:
+            offset = 256
+            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+                (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH)
+            if dom_channel_monitor_raw is not None:
+                tx_disable_data = int(dom_channel_monitor_raw[0], 16)
+                tx_disable = (tx_disable_data & 0xC0 != 0)
+
+        return tx_disable
 
     def get_tx_disable_channel(self):
         """
@@ -566,9 +964,29 @@ def get_tx_disable_channel(self):
             As an example, a returned value of 0x5 indicates that channel 0
             and channel 2 have been disabled.
         """
-        tx_disable_list = self.get_tx_disable()
-        if tx_disable_list is None:
-            return 0
+        tx_disable_list = [False, False, False, False]
+
+        if self.sfp_type == OSFP_TYPE:
+            pass
+
+        elif self.sfp_type == QSFP_TYPE:
+            offset = 0
+            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+                (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH)
+            if dom_channel_monitor_raw is not None:
+                tx_disable_data = int(dom_channel_monitor_raw[0], 16)
+                tx_disable_list[0] = (tx_disable_data & 0x01 != 0)
+                tx_disable_list[1] = (tx_disable_data & 0x02 != 0)
+                tx_disable_list[2] = (tx_disable_data & 0x04 != 0)
+                tx_disable_list[3] = (tx_disable_data & 0x08 != 0)
+        else:
+            offset = 256
+            dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+                (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH)
+            if dom_channel_monitor_raw is not None:
+                tx_disable_data = int(dom_channel_monitor_raw[0], 16)
+                tx_disable_list[0] = (tx_disable_data & 0xC0 != 0)
+
         tx_disabled = 0
         for i in range(len(tx_disable_list)):
             if tx_disable_list[i]:
@@ -609,30 +1027,31 @@ def get_power_override(self):
         Returns:
             A Boolean, True if power-override is enabled, False if disabled
         """
-        power_override = False
-
-        offset = 0
-        sfpd_obj = sff8436Dom()
-        if sfpd_obj is None:
+        if self.sfp_type == QSFP_TYPE:
+            offset = 0
+            sfpd_obj = sff8436Dom()
+            if sfpd_obj is None:
+                return False
+
+            dom_control_raw = self.__read_eeprom_specific_bytes(
+                QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None
+            if dom_control_raw is not None:
+                dom_control_data = sfpd_obj.parse_control_bytes(
+                    dom_control_raw, 0)
+                power_override = (
+                    'On' == dom_control_data['data']['PowerOverride']['value'])
+                return power_override
+        else:
             return False
 
-        dom_control_raw = self.__read_eeprom_specific_bytes(
-            QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None
-        if dom_control_raw is not None:
-            dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
-            power_override = (
-                'On' == dom_control_data['data']['PowerOverride']['value'])
-
-        return power_override
-
     def get_temperature(self):
         """
         Retrieves the temperature of this SFP
         Returns:
             An integer number of current temperature in Celsius
         """
-        transceiver_dom_info_dict = self.get_transceiver_bulk_status()
-        return transceiver_dom_info_dict.get("temperature", "N/A")
+        transceiver_bulk_status = self.get_transceiver_bulk_status()
+        return transceiver_bulk_status.get("temperature", "N/A")
 
     def get_voltage(self):
         """
@@ -640,8 +1059,8 @@ def get_voltage(self):
         Returns:
             An integer number of supply voltage in mV
         """
-        transceiver_dom_info_dict = self.get_transceiver_bulk_status()
-        return transceiver_dom_info_dict.get("voltage", "N/A")
+        transceiver_bulk_status = self.get_transceiver_bulk_status()
+        return transceiver_bulk_status.get("voltage", "N/A")
 
     def get_tx_bias(self):
         """
@@ -651,12 +1070,13 @@ def get_tx_bias(self):
             for channel 0 to channel 4.
             Ex. ['110.09', '111.12', '108.21', '112.09']
         """
-        transceiver_dom_info_dict = self.get_transceiver_bulk_status()
-        tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A")
-        tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A")
-        tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A")
-        tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A")
-        return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else []
+        transceiver_bulk_status = self.get_transceiver_bulk_status()
+        tx1_bs = transceiver_bulk_status.get("tx1bias", "N/A")
+        tx2_bs = transceiver_bulk_status.get("tx2bias", "N/A")
+        tx3_bs = transceiver_bulk_status.get("tx3bias", "N/A")
+        tx4_bs = transceiver_bulk_status.get("tx4bias", "N/A")
+        tx_bias_list = [tx1_bs, tx2_bs, tx3_bs, tx4_bs]
+        return tx_bias_list
 
     def get_rx_power(self):
         """
@@ -666,12 +1086,14 @@ def get_rx_power(self):
             power in mW for channel 0 to channel 4.
             Ex. ['1.77', '1.71', '1.68', '1.70']
         """
-        transceiver_dom_info_dict = self.get_transceiver_bulk_status()
-        rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A")
-        rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A")
-        rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A")
-        rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A")
-        return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else []
+        rx_power_list = []
+        transceiver_bulk_status = self.get_transceiver_bulk_status()
+        rx1_p = transceiver_bulk_status.get("rx1power", "N/A")
+        rx2_p = transceiver_bulk_status.get("rx2power", "N/A")
+        rx3_p = transceiver_bulk_status.get("rx3power", "N/A")
+        rx4_p = transceiver_bulk_status.get("rx4power", "N/A")
+        rx_power_list = [rx1_p, rx2_p, rx3_p, rx4_p]
+        return rx_power_list
 
     def get_tx_power(self):
         """
@@ -681,12 +1103,14 @@ def get_tx_power(self):
             for channel 0 to channel 4.
             Ex. ['1.86', '1.86', '1.86', '1.86']
         """
-        transceiver_dom_info_dict = self.get_transceiver_bulk_status()
-        tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A")
-        tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A")
-        tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A")
-        tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A")
-        return [tx1_pw, tx2_pw, tx3_pw, tx4_pw]
+        tx_power_list = []
+        transceiver_bulk_status = self.get_transceiver_bulk_status()
+        tx1_p = transceiver_bulk_status.get("tx1power", "N/A")
+        tx2_p = transceiver_bulk_status.get("tx2power", "N/A")
+        tx3_p = transceiver_bulk_status.get("tx3power", "N/A")
+        tx4_p = transceiver_bulk_status.get("tx4power", "N/A")
+        tx_power_list = [tx1_p, tx2_p, tx3_p, tx4_p]
+        return tx_power_list
 
     def reset(self):
         """
@@ -748,24 +1172,26 @@ def tx_disable(self, tx_disable):
         Returns:
             A boolean, True if tx_disable is set successfully, False if not
         """
-        sysfsfile_eeprom = None
-        try:
-            tx_disable_ctl = 0xf if tx_disable else 0x0
-            buffer = create_string_buffer(1)
-            buffer[0] = chr(tx_disable_ctl)
-            # Write to eeprom
-            sysfsfile_eeprom = open(
-                self.port_to_eeprom_mapping[self.port_num], "r+b")
-            sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
-            sysfsfile_eeprom.write(buffer[0])
-        except IOError as e:
-            print "Error: unable to open file: %s" % str(e)
-            return False
-        finally:
-            if sysfsfile_eeprom is not None:
-                sysfsfile_eeprom.close()
-                time.sleep(0.01)
-        return True
+        if self.sfp_type == QSFP_TYPE:
+            sysfsfile_eeprom = None
+            try:
+                tx_disable_ctl = 0xf if tx_disable else 0x0
+                buffer = create_string_buffer(1)
+                buffer[0] = chr(tx_disable_ctl)
+                # Write to eeprom
+                sysfsfile_eeprom = open(
+                    self.port_to_eeprom_mapping[self.port_num], "r+b")
+                sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
+                sysfsfile_eeprom.write(buffer[0])
+            except IOError as e:
+                #print("Error: unable to open file: %s" % str(e))
+                return False
+            finally:
+                if sysfsfile_eeprom is not None:
+                    sysfsfile_eeprom.close()
+                    time.sleep(0.01)
+            return True
+        return False
 
     def tx_disable_channel(self, channel, disable):
         """
@@ -778,28 +1204,30 @@ def tx_disable_channel(self, channel, disable):
         Returns:
             A boolean, True if successful, False if not
         """
-        sysfsfile_eeprom = None
-        try:
-            channel_state = self.get_tx_disable_channel()
-            tx_enable_mask = [0xe, 0xd, 0xb, 0x7]
-            tx_disable_mask = [0x1, 0x3, 0x7, 0xf]
-            tx_disable_ctl = channel_state | tx_disable_mask[
-                channel] if disable else channel_state & tx_enable_mask[channel]
-            buffer = create_string_buffer(1)
-            buffer[0] = chr(tx_disable_ctl)
-            # Write to eeprom
-            sysfsfile_eeprom = open(
-                self.port_to_eeprom_mapping[self.port_num], "r+b")
-            sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
-            sysfsfile_eeprom.write(buffer[0])
-        except IOError as e:
-            print "Error: unable to open file: %s" % str(e)
-            return False
-        finally:
-            if sysfsfile_eeprom is not None:
-                sysfsfile_eeprom.close()
-                time.sleep(0.01)
-        return True
+        if self.sfp_type == QSFP_TYPE:
+            sysfsfile_eeprom = None
+            try:
+                channel_state = self.get_tx_disable_channel()
+                tx_enable_mask = [0xe, 0xd, 0xb, 0x7]
+                tx_disable_mask = [0x1, 0x3, 0x7, 0xf]
+                tx_disable_ctl = channel_state | tx_disable_mask[
+                    channel] if disable else channel_state & tx_enable_mask[channel]
+                buffer = create_string_buffer(1)
+                buffer[0] = chr(tx_disable_ctl)
+                # Write to eeprom
+                sysfsfile_eeprom = open(
+                    self.port_to_eeprom_mapping[self.port_num], "r+b")
+                sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
+                sysfsfile_eeprom.write(buffer[0])
+            except IOError as e:
+                #print("Error: unable to open file: %s" % str(e))
+                return False
+            finally:
+                if sysfsfile_eeprom is not None:
+                    sysfsfile_eeprom.close()
+                    time.sleep(0.01)
+            return True
+        return False
 
     def set_lpmode(self, lpmode):
         """
@@ -855,30 +1283,36 @@ def set_power_override(self, power_override, power_set):
             A boolean, True if power-override and power_set are set successfully,
             False if not
         """
-        try:
-            power_override_bit = 0
-            if power_override:
-                power_override_bit |= 1 << 0
-
-            power_set_bit = 0
-            if power_set:
-                power_set_bit |= 1 << 1
+        if self.sfp_type == QSFP_TYPE:
+            try:
+                power_override_bit = 0
+                if power_override:
+                    power_override_bit |= 1 << 0
+
+                power_set_bit = 0
+                if power_set:
+                    power_set_bit |= 1 << 1
+
+                buffer = create_string_buffer(1)
+                buffer[0] = chr(power_override_bit | power_set_bit)
+                # Write to eeprom
+                sysfsfile_eeprom = open(
+                    self.port_to_eeprom_mapping[self.port_num], "r+b")
+                sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET)
+                sysfsfile_eeprom.write(buffer[0])
+            except IOError as e:
+                #print("Error: unable to open file: %s" % str(e))
+                return False
+            finally:
+                if sysfsfile_eeprom is not None:
+                    sysfsfile_eeprom.close()
+                    time.sleep(0.01)
+            return True
+        return False
 
-            buffer = create_string_buffer(1)
-            buffer[0] = chr(power_override_bit | power_set_bit)
-            # Write to eeprom
-            sysfsfile_eeprom = open(
-                self.port_to_eeprom_mapping[self.port_num], "r+b")
-            sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET)
-            sysfsfile_eeprom.write(buffer[0])
-        except IOError as e:
-            print "Error: unable to open file: %s" % str(e)
-            return False
-        finally:
-            if sysfsfile_eeprom is not None:
-                sysfsfile_eeprom.close()
-                time.sleep(0.01)
-        return True
+    ##############################################################
+    ###################### Device methods ########################
+    ##############################################################
 
     def get_name(self):
         """
@@ -898,7 +1332,7 @@ def get_presence(self):
         Returns:
             bool: True if PSU is present, False if not
         """
-        presence_status_raw = self.__read_txt_file(self.PRS_PATH).rstrip()
+        presence_status_raw = self._api_helper.read_txt_file(self.PRS_PATH).rstrip()
         if not presence_status_raw:
             return False
 
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py
index 1e0a2c4b5645..18c2bd30c03e 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py
@@ -14,6 +14,7 @@
 
 try:
     from sonic_platform_base.thermal_base import ThermalBase
+    from helper import APIHelper
 except ImportError as e:
     raise ImportError(str(e) + "- required module not found")
 
@@ -27,6 +28,7 @@ class Thermal(ThermalBase):
 
     def __init__(self, thermal_index):
         self.index = thermal_index
+        self._api_helper = APIHelper()
 
         # Add thermal name
         self.THERMAL_NAME_LIST.append("Front-panel temp sensor 1")
@@ -48,19 +50,11 @@ def __init__(self, thermal_index):
         self.ss_key = self.THERMAL_NAME_LIST[self.index]
         self.ss_index = 1
 
-    def __read_txt_file(self, file_path):
-        try:
-            with open(file_path, 'r') as fd:
-                data = fd.read()
-                return data.strip()
-        except IOError:
-            pass
-
     def __get_temp(self, temp_file):
         temp_file_path = os.path.join(self.hwmon_path, temp_file)
-        raw_temp = self.__read_txt_file(temp_file_path)
+        raw_temp = self._api_helper.read_txt_file(temp_file_path)
         temp = float(raw_temp)/1000
-        return "{:.3f}".format(temp)
+        return float("{:.3f}".format(temp))
 
     def __set_threshold(self, file_name, temperature):
         temp_file_path = os.path.join(self.hwmon_path, file_name)
diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install
index 9b456a7c9112..a36e2cd1377c 100644
--- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install
+++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install
@@ -2,7 +2,7 @@ dx010/scripts/dx010_check_qsfp.sh usr/local/bin
 dx010/cfg/dx010-modules.conf etc/modules-load.d
 dx010/systemd/platform-modules-dx010.service lib/systemd/system
 dx010/scripts/fancontrol.sh etc/init.d
-services/fancontrol/fancontrol.service lib/systemd/system
+dx010/scripts/fancontrol.service lib/systemd/system
 services/fancontrol/fancontrol  usr/local/bin
 dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0
 services/platform_api/platform_api_mgnt.sh usr/local/bin
diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install
index df78b7a34ea4..4fdfd33f1ec3 100644
--- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install
+++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install
@@ -1,7 +1,7 @@
 haliburton/cfg/haliburton-modules.conf etc/modules-load.d
 haliburton/systemd/platform-modules-haliburton.service lib/systemd/system
 haliburton/script/fancontrol.sh etc/init.d
-services/fancontrol/fancontrol.service lib/systemd/system
+haliburton/script/fancontrol.service lib/systemd/system
 services/fancontrol/fancontrol  usr/local/bin
 haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0
 services/platform_api/platform_api_mgnt.sh usr/local/bin
diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service
new file mode 100755
index 000000000000..25b9f34df2d0
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=fan speed regulator
+After=platform-modules-dx010.service
+Before=pmon.service
+
+[Service]
+ExecStart=-/etc/init.d/fancontrol.sh start
+ExecStop=-/etc/init.d/fancontrol.sh stop
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
diff --git a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol.service b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/fancontrol.service
similarity index 100%
rename from platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol.service
rename to platform/broadcom/sonic-platform-modules-cel/haliburton/script/fancontrol.service

From 4389b9d34c27611c7c63100ea02be57bc29d3330 Mon Sep 17 00:00:00 2001
From: Wirut Getbamrung <wgetbum@icloud.com>
Date: Thu, 17 Sep 2020 22:56:52 +0700
Subject: [PATCH 2/3] [device/celestica]: Update DX010 reboot cause API (#4678)

- Add more cases support in DX010 reboot cause API
    - Add Thermal Overload reboot cause support
    - Add new Watchdog reboot cause support
---
 .../x86_64-cel_seastone-r0/fancontrol-B2F     |   4 +-
 .../x86_64-cel_seastone-r0/fancontrol-F2B     |   3 +-
 .../sonic_platform/__init__.py                |   4 +-
 .../sonic_platform/chassis.py                 |  57 +-
 .../sonic_platform/helper.py                  |  13 +
 .../sonic_platform/watchdog.py                | 172 ++--
 .../debian/platform-modules-dx010.install     |   1 +
 .../dx010/modules/dx010_cpld.c                | 379 ++++---
 .../dx010/scripts/thermal_overload_control.sh |  75 ++
 .../services/fancontrol/fancontrol            | 937 +++++++++---------
 10 files changed, 896 insertions(+), 749 deletions(-)
 create mode 100755 platform/broadcom/sonic-platform-modules-cel/dx010/scripts/thermal_overload_control.sh

diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F
index c2132d7f2806..61b1c386f3d8 100644
--- a/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F
+++ b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F
@@ -8,4 +8,6 @@ MINSTART=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e
 MINSTOP=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89
 MINPWM=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89
 MAXPWM=13-002e/pwm1=255 13-002e/pwm2=255 13-002e/pwm3=255 13-002e/pwm4=255 13-002e/pwm5=255 13-004d/pwm1=255 13-004d/pwm2=255 13-004d/pwm3=255 13-004d/pwm4=255 13-004d/pwm5=255
-THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3
\ No newline at end of file
+THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3
+MAXTEMPCRIT=/sys/bus/i2c/devices/7-004a/hwmon/hwmon*/temp1_input=65 /sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input=75
+MAXTEMPTYPE=/sys/bus/i2c/devices/7-004a/hwmon/hwmon*/temp1_input=ASIC /sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input=CPU
diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B b/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B
index dc67e2623cc2..b851d0a6d6ca 100644
--- a/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B
+++ b/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B
@@ -9,4 +9,5 @@ MINSTOP=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/
 MINPWM=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89
 MAXPWM=13-002e/pwm1=255 13-002e/pwm2=255 13-002e/pwm3=255 13-002e/pwm4=255 13-002e/pwm5=255 13-004d/pwm1=255 13-004d/pwm2=255 13-004d/pwm3=255 13-004d/pwm4=255 13-004d/pwm5=255
 THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3
-
+MAXTEMPCRIT=/sys/bus/i2c/devices/7-004a/hwmon/hwmon*/temp1_input=75 /sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input=75
+MAXTEMPTYPE=/sys/bus/i2c/devices/7-004a/hwmon/hwmon*/temp1_input=ASIC /sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input=CPU
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py
index d82f3749319c..7b86fa12b515 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py
@@ -1,2 +1,2 @@
-__all__ = ["platform", "chassis"]
-from sonic_platform import *
+import chassis
+import platform
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py
index 421d03c82bb4..18d57096b6d3 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py
@@ -23,9 +23,9 @@
 NUM_COMPONENT = 5
 RESET_REGISTER = "0x103"
 HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/"
-PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/"
 REBOOT_CAUSE_FILE = "reboot-cause.txt"
 PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt"
+GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg"
 HOST_CHK_CMD = "docker > /dev/null 2>&1"
 
 
@@ -118,35 +118,38 @@ def get_reboot_cause(self):
             one of the predefined strings in this class. If the first string
             is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
             to pass a description of the reboot cause.
-        """
-        description = 'None'
-        reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
-
-        reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.is_host else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE
-        prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.is_host else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE
 
-        hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER)
+            REBOOT_CAUSE_POWER_LOSS = "Power Loss"
+            REBOOT_CAUSE_THERMAL_OVERLOAD_CPU = "Thermal Overload: CPU"
+            REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC = "Thermal Overload: ASIC"
+            REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER = "Thermal Overload: Other"
+            REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED = "Insufficient Fan Speed"
+            REBOOT_CAUSE_WATCHDOG = "Watchdog"
+            REBOOT_CAUSE_HARDWARE_OTHER = "Hardware - Other"
+            REBOOT_CAUSE_NON_HARDWARE = "Non-Hardware"
 
+        """
+        reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE)
         sw_reboot_cause = self._api_helper.read_txt_file(
             reboot_cause_path) or "Unknown"
-        prev_sw_reboot_cause = self._api_helper.read_txt_file(
-            prev_reboot_cause_path) or "Unknown"
-
-        if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS) and hw_reboot_cause == "0x11":
-            reboot_cause = self.REBOOT_CAUSE_POWER_LOSS
-        elif sw_reboot_cause != "Unknown" and hw_reboot_cause == "0x11":
-            reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
-            description = sw_reboot_cause
-        elif prev_reboot_cause_path != "Unknown" and hw_reboot_cause == "0x11":
-            reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
-            description = prev_sw_reboot_cause
-        elif hw_reboot_cause == "0x22":
-            reboot_cause = self.REBOOT_CAUSE_WATCHDOG,
-        else:
-            reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
-            description = 'Unknown reason'
+        hw_reboot_cause = self._api_helper.get_cpld_reg_value(
+            GETREG_PATH, RESET_REGISTER)
+
+        prev_reboot_cause = {
+            '0x11': (self.REBOOT_CAUSE_POWER_LOSS, 'Power on reset'),
+            '0x22': (self.REBOOT_CAUSE_HARDWARE_OTHER, 'CPLD_WD_RESET'),
+            '0x33': (self.REBOOT_CAUSE_HARDWARE_OTHER, 'Power cycle reset triggered by CPU'),
+            '0x44': (self.REBOOT_CAUSE_HARDWARE_OTHER, 'Power cycle reset triggered by reset button'),
+            '0x55': (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, ''),
+            '0x66': (self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, ''),
+            '0x77': (self.REBOOT_CAUSE_WATCHDOG, '')
+        }.get(hw_reboot_cause, (self.REBOOT_CAUSE_HARDWARE_OTHER, 'Unknown reason'))
+
+        if sw_reboot_cause != 'Unknown' and hw_reboot_cause == '0x11':
+            prev_reboot_cause = (
+                self.REBOOT_CAUSE_NON_HARDWARE, sw_reboot_cause)
 
-        return (reboot_cause, description)
+        return prev_reboot_cause
 
     ##############################################################
     ######################## SFP methods #########################
@@ -229,9 +232,9 @@ def get_name(self):
 
     def get_presence(self):
         """
-        Retrieves the presence of the PSU
+        Retrieves the presence of the Chassis
         Returns:
-            bool: True if PSU is present, False if not
+            bool: True if Chassis is present, False if not
         """
         return True
 
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py
index 86fc5ea726ef..6566d4698e8d 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py
@@ -69,6 +69,19 @@ def read_one_line_file(self, file_path):
             pass
         return None
 
+    def write_txt_file(self, file_path, value):
+        try:
+            with open(file_path, 'w') as fd:
+                fd.write(str(value))
+        except Exception:
+            return False
+        return True
+
+    def get_cpld_reg_value(self, getreg_path, register):
+        cmd = "echo {1} > {0}; cat {0}".format(getreg_path, register)
+        status, result = self.run_command(cmd)
+        return result if status else None
+
     def ipmi_raw(self, netfn, cmd):
         status = True
         result = ""
diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py
index b539bc06f618..e410a940ee7e 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py
@@ -7,115 +7,79 @@
 #
 #############################################################################
 import ctypes
-import fcntl
 import os
 import subprocess
 import time
-import array
 
 try:
     from sonic_platform_base.watchdog_base import WatchdogBase
+    from helper import APIHelper
 except ImportError as e:
     raise ImportError(str(e) + "- required module not found")
 
-""" ioctl constants """
-IO_WRITE = 0x40000000
-IO_READ = 0x80000000
-IO_READ_WRITE = 0xC0000000
-IO_SIZE_INT = 0x00040000
-IO_SIZE_40 = 0x00280000
-IO_TYPE_WATCHDOG = ord('W') << 8
-
-WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG
-WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG
-WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG
-
-""" Watchdog ioctl commands """
-WDIOC_GETSUPPORT = 0 | WDR_40
-WDIOC_GETSTATUS = 1 | WDR_INT
-WDIOC_GETBOOTSTATUS = 2 | WDR_INT
-WDIOC_GETTEMP = 3 | WDR_INT
-WDIOC_SETOPTIONS = 4 | WDR_INT
-WDIOC_KEEPALIVE = 5 | WDR_INT
-WDIOC_SETTIMEOUT = 6 | WDWR_INT
-WDIOC_GETTIMEOUT = 7 | WDR_INT
-WDIOC_SETPRETIMEOUT = 8 | WDWR_INT
-WDIOC_GETPRETIMEOUT = 9 | WDR_INT
-WDIOC_GETTIMELEFT = 10 | WDR_INT
-
-""" Watchdog status constants """
-WDIOS_DISABLECARD = 0x0001
-WDIOS_ENABLECARD = 0x0002
-
+PLATFORM_CPLD_PATH = '/sys/devices/platform/dx010_cpld'
+GETREG_FILE = 'getreg'
+SETREG_FILE = 'setreg'
+WDT_ENABLE_REG = '0x141'
+WDT_TIMER_L_BIT_REG = '0x142'
+WDT_TIMER_M_BIT_REG = '0x143'
+WDT_TIMER_H_BIT_REG = '0x144'
+WDT_KEEP_ALVIVE_REG = '0x145'
+ENABLE_CMD = '0x1'
+DISABLE_CMD = '0x0'
 WDT_COMMON_ERROR = -1
-WD_MAIN_IDENTITY = "iTCO_wdt"
-WDT_SYSFS_PATH = "/sys/class/watchdog/"
 
 
 class Watchdog(WatchdogBase):
 
     def __init__(self):
+        # Init helper
+        self._api_helper = APIHelper()
+
+        # Init cpld reg path
+        self.setreg_path = os.path.join(PLATFORM_CPLD_PATH, SETREG_FILE)
+        self.getreg_path = os.path.join(PLATFORM_CPLD_PATH, GETREG_FILE)
 
-        self.watchdog, self.wdt_main_dev_name = self._get_wdt()
-        self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name
-        self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name
-        self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name
         # Set default value
         self._disable()
         self.armed = False
-        self.timeout = self._gettimeout(self.timeout_path)
-
-    def _is_wd_main(self, dev):
-        """
-        Checks watchdog identity
-        """
-        identity = self._read_file(
-            "{}/{}/identity".format(WDT_SYSFS_PATH, dev))
-        return identity == WD_MAIN_IDENTITY
-
-    def _get_wdt(self):
-        """
-        Retrieves watchdog device
-        """
-        wdt_main_dev_list = [dev for dev in os.listdir(
-            "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)]
-        if not wdt_main_dev_list:
-            return None
-        wdt_main_dev_name = wdt_main_dev_list[0]
-        watchdog_device_path = "/dev/{}".format(wdt_main_dev_name)
-        watchdog = os.open(watchdog_device_path, os.O_RDWR)
-        return watchdog, wdt_main_dev_name
-
-    def _read_file(self, file_path):
-        """
-        Read text file
-        """
-        try:
-            with open(file_path, "r") as fd:
-                txt = fd.read()
-        except IOError:
-            return WDT_COMMON_ERROR
-        return txt.strip()
+        self.timeout = self._gettimeout()
 
     def _enable(self):
         """
         Turn on the watchdog timer
         """
-        req = array.array('h', [WDIOS_ENABLECARD])
-        fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
+        # echo 0x141 0x1 > /sys/devices/platform/dx010_cpld/setreg
+        enable_val = '{} {}'.format(WDT_ENABLE_REG, ENABLE_CMD)
+        return self._api_helper.write_txt_file(self.setreg_path, enable_val)
 
     def _disable(self):
         """
         Turn off the watchdog timer
         """
-        req = array.array('h', [WDIOS_DISABLECARD])
-        fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
+        # echo 0x141 0x0 > /sys/devices/platform/dx010_cpld/setreg
+        disable_val = '{} {}'.format(WDT_ENABLE_REG, DISABLE_CMD)
+        return self._api_helper.write_txt_file(self.setreg_path, disable_val)
 
     def _keepalive(self):
         """
         Keep alive watchdog timer
         """
-        fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE)
+        # echo 0x145 0x1 > /sys/devices/platform/dx010_cpld/setreg
+        enable_val = '{} {}'.format(WDT_KEEP_ALVIVE_REG, ENABLE_CMD)
+        return self._api_helper.write_txt_file(self.setreg_path, enable_val)
+
+    def _get_level_hex(self, sub_hex):
+        sub_hex_str = sub_hex.replace("x", "0")
+        return hex(int(sub_hex_str, 16))
+
+    def _seconds_to_lmh_hex(self, seconds):
+        ms = seconds*1000  # calculate timeout in ms format
+        hex_str = hex(ms)
+        l = self._get_level_hex(hex_str[-2:])
+        m = self._get_level_hex(hex_str[-4:-2])
+        h = self._get_level_hex(hex_str[-6:-4])
+        return (l, m, h)
 
     def _settimeout(self, seconds):
         """
@@ -123,29 +87,35 @@ def _settimeout(self, seconds):
         @param seconds - timeout in seconds
         @return is the actual set timeout
         """
-        req = array.array('I', [seconds])
-        fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True)
-        return int(req[0])
+        # max = 0xffffff = 16777.215 seconds
+
+        (l, m, h) = self._seconds_to_lmh_hex(seconds)
+        set_h_val = '{} {}'.format(WDT_TIMER_H_BIT_REG, h)
+        set_m_val = '{} {}'.format(WDT_TIMER_M_BIT_REG, m)
+        set_l_val = '{} {}'.format(WDT_TIMER_L_BIT_REG, l)
+
+        self._api_helper.write_txt_file(self.setreg_path, set_h_val)
+        self._api_helper.write_txt_file(self.setreg_path, set_m_val)
+        self._api_helper.write_txt_file(self.setreg_path, set_l_val)
 
-    def _gettimeout(self, timeout_path):
+        return seconds
+
+    def _gettimeout(self):
         """
         Get watchdog timeout
         @return watchdog timeout
         """
-        req = array.array('I', [0])
-        fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True)
-
-        return int(req[0])
 
-    def _gettimeleft(self):
-        """
-        Get time left before watchdog timer expires
-        @return time left in seconds
-        """
-        req = array.array('I', [0])
-        fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True)
+        h_bit = self._api_helper.get_cpld_reg_value(
+            self.getreg_path, WDT_TIMER_H_BIT_REG)
+        m_bit = self._api_helper.get_cpld_reg_value(
+            self.getreg_path, WDT_TIMER_M_BIT_REG)
+        l_bit = self._api_helper.get_cpld_reg_value(
+            self.getreg_path, WDT_TIMER_L_BIT_REG)
 
-        return int(req[0])
+        hex_time = '0x{}{}{}'.format(h_bit[2:], m_bit[2:], l_bit[2:])
+        ms = int(hex_time, 16)
+        return int(float(ms)/1000)
 
     #################################################################
 
@@ -169,12 +139,15 @@ def arm(self, seconds):
         try:
             if self.timeout != seconds:
                 self.timeout = self._settimeout(seconds)
+
             if self.armed:
                 self._keepalive()
             else:
                 self._enable()
                 self.armed = True
+
             ret = self.timeout
+            self.arm_timestamp = time.time()
         except IOError as e:
             pass
 
@@ -215,19 +188,4 @@ def get_remaining_time(self):
             watchdog timer. If the watchdog is not armed, returns -1.
         """
 
-        timeleft = WDT_COMMON_ERROR
-
-        if self.armed:
-            try:
-                timeleft = self._gettimeleft()
-            except IOError:
-                pass
-
-        return timeleft
-
-    def __del__(self):
-        """
-        Close watchdog
-        """
-
-        os.close(self.watchdog)
+        return int(self.timeout - (time.time() - self.arm_timestamp)) if self.armed else WDT_COMMON_ERROR
diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install
index a36e2cd1377c..d7720cea90f4 100644
--- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install
+++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install
@@ -3,6 +3,7 @@ dx010/cfg/dx010-modules.conf etc/modules-load.d
 dx010/systemd/platform-modules-dx010.service lib/systemd/system
 dx010/scripts/fancontrol.sh etc/init.d
 dx010/scripts/fancontrol.service lib/systemd/system
+dx010/scripts/thermal_overload_control.sh usr/local/bin
 services/fancontrol/fancontrol  usr/local/bin
 dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0
 services/platform_api/platform_api_mgnt.sh usr/local/bin
diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c
index 7893220ff6d5..ead28807832d 100644
--- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c
+++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c
@@ -76,42 +76,52 @@
 #define PORT_SFPP1              33
 #define PORT_SFPP2              34
 
-#define PORT_ID_BANK1           0x210
-#define PORT_ID_BANK2           0x290
-#define PORT_ID_BANK3           0x390
 
-#define OPCODE_ID_BANK1         0x211
-#define OPCODE_ID_BANK2         0x291
-#define OPCODE_ID_BANK3         0x391
+#define CPLD_I2C_CLK_100Khz_BIT    BIT(6)
+#define CPLD_I2C_DATA_SZ_MASK      GENMASK(7,4)
+#define CPLD_I2C_CMD_SZ_MASK       GENMASK(1,0)
+#define CPLD_I2C_ERR               BIT(7)
+#define CPLD_I2C_BUSY              BIT(6)
+#define CPLD_I2C_RST_BIT           BIT(0)
+#define CPLD_I2C_RESET             0
+#define CPLD_I2C_UNRESET           1
+#define CPLD_I2C_DATA_SZ_MAX       8
+#define CPLD_I2C_CMD_SZ_MAX        3
+
+
+#define CPLD_I2C_BANK1_BASE     0x210
+#define CPLD_I2C_BANK2_BASE     0x290
+#define CPLD_I2C_BANK3_BASE     0x390
+
+#define I2C_PORT_ID        0x0
+#define I2C_OPCODE         0x1
+#define I2C_DEV_ADDR       0x2
+#define I2C_CMD_BYT0       0x3
+#define I2C_SSR            0x6
+#define I2C_WRITE_DATA     0x10
+#define I2C_READ_DATA      0x20
 
-#define DEVADDR_ID_BANK1        0x212
-#define DEVADDR_ID_BANK2        0x292
-#define DEVADDR_ID_BANK3        0x392
-
-#define CMDBYT_ID_BANK1         0x213
-#define CMDBYT_ID_BANK2         0x293
-#define CMDBYT_ID_BANK3         0x393
-
-#define WRITE_ID_BANK1          0x220
-#define WRITE_ID_BANK2          0x2A0
-#define WRITE_ID_BANK3          0x3A0
-
-#define READ_ID_BANK1           0x230
-#define READ_ID_BANK2           0x2B0
-#define READ_ID_BANK3           0x3B0
-
-#define SSRR_ID_BANK1           0x216
-#define SSRR_ID_BANK2           0x296
-#define SSRR_ID_BANK3           0x396
-
-#define HST_CNTL2_QUICK         0x00
-#define HST_CNTL2_BYTE          0x01
-#define HST_CNTL2_BYTE_DATA     0x02
-#define HST_CNTL2_WORD_DATA     0x03
-#define HST_CNTL2_BLOCK         0x05
+/*
+ * private data to send to I2C core
+ */
+struct current_xfer {
+    u8 addr;
+    u8 cmd[CPLD_I2C_CMD_SZ_MAX];
+    u8 cmd_len;
+    u8 data_len;
+    union i2c_smbus_data *data;
+};
 
+/*
+ * private data of I2C adapter
+ * base_addr: Base address of this I2C adapter core.
+ * port_id: The port ID, use to mux an i2c core to a font panel port.
+ * current_xfer: The struct carry current data setup of current smbus transfer.
+ */
 struct dx010_i2c_data {
+        int base_addr;
         int portid;
+        struct current_xfer curr_xfer;
 };
 
 struct dx010_cpld_data {
@@ -364,179 +374,210 @@ static struct platform_device cel_dx010_lpc_dev = {
         }
 };
 
+// TODO: Refactoring this function with helper functions.
+static s32 cpld_smbus_transfer(struct dx010_i2c_data *priv) {
 
-/**
- * Read eeprom of QSFP device.
- * @param  a        i2c adapter.
- * @param  addr     address to read.
- * @param  new_data QSFP port number struct.
- * @param  cmd      i2c command.
- * @return          0 if not error, else the error code.
- */
-static int i2c_read_eeprom(struct i2c_adapter *a, u16 addr,
-               struct dx010_i2c_data *new_data, u8 cmd, union i2c_smbus_data *data){
+        u8 val;
+        s32 error;
+        unsigned long ioBase;
+        short portid, opcode, devaddr, cmdbyte0, ssr, writedata, readdata;
+        union i2c_smbus_data *data;
 
-        u32 reg;
-        int ioBase=0;
-        char byte;
-        short temp;
-        short portid, opcode, devaddr, cmdbyte0, ssrr, writedata, readdata;
-        __u16 word_data;
-        int error = -EIO;
+        error = -EIO;
 
         mutex_lock(&cpld_data->cpld_lock);
 
-        if (((new_data->portid >= PORT_BANK1_START)
-                        && (new_data->portid <= PORT_BANK1_END))
-                        || (new_data->portid == PORT_SFPP1)
-                        || (new_data->portid == PORT_SFPP2))
-        {
-                portid = PORT_ID_BANK1;
-                opcode = OPCODE_ID_BANK1;
-                devaddr = DEVADDR_ID_BANK1;
-                cmdbyte0 = CMDBYT_ID_BANK1;
-                ssrr = SSRR_ID_BANK1;
-                writedata = WRITE_ID_BANK1;
-                readdata = READ_ID_BANK1;
-        }else if ((new_data->portid >= PORT_BANK2_START) && (new_data->portid <= PORT_BANK2_END)){
-                portid = PORT_ID_BANK2;
-                opcode = OPCODE_ID_BANK2;
-                devaddr = DEVADDR_ID_BANK2;
-                cmdbyte0 = CMDBYT_ID_BANK2;
-                ssrr = SSRR_ID_BANK2;
-                writedata = WRITE_ID_BANK2;
-                readdata = READ_ID_BANK2;
-        }else if ((new_data->portid  >= PORT_BANK3_START) && (new_data->portid  <= PORT_BANK3_END)){
-                portid = PORT_ID_BANK3;
-                opcode = OPCODE_ID_BANK3;
-                devaddr = DEVADDR_ID_BANK3;
-                cmdbyte0 = CMDBYT_ID_BANK3;
-                ssrr = SSRR_ID_BANK3;
-                writedata = WRITE_ID_BANK3;
-                readdata = READ_ID_BANK3;
-        }else{
-            /* Invalid parameter! */
-                error = -EINVAL;
-                goto exit;
+        ioBase = priv->base_addr;
+        data = priv->curr_xfer.data;
+
+        portid = ioBase + I2C_PORT_ID;
+        opcode = ioBase + I2C_OPCODE;
+        devaddr = ioBase + I2C_DEV_ADDR;
+        cmdbyte0 = ioBase + I2C_CMD_BYT0;
+        ssr = ioBase + I2C_SSR;
+        writedata = ioBase + I2C_WRITE_DATA;
+        readdata = ioBase + I2C_READ_DATA;
+
+        /* Wait for the core to be free */
+        pr_debug("CPLD_I2C Wait busy bit(6) to be cleared\n");
+        do {
+                val = inb(ssr);
+                if ((val & CPLD_I2C_BUSY) == 0)
+                        break;
+                udelay(100);
+        } while (true);  // Risky - add timeout
+
+        /*
+         * If any error happen here, we do soft-reset
+         * and check the BUSY/ERROR again.
+         */
+        pr_debug("CPLD_I2C Check error bit(7)\n");
+        if (val & CPLD_I2C_ERR) {
+                pr_debug("CPLD_I2C Error, try soft-reset\n");
+                outb(CPLD_I2C_RESET, ssr);
+                udelay(3000);
+                outb(CPLD_I2C_UNRESET, ssr);
+
+                val = inb(ssr);
+                if (val & (CPLD_I2C_BUSY | CPLD_I2C_ERR)) {
+                    pr_debug("CPLD_I2C Error, core busy after reset\n");
+                    error = -EIO;
+                    goto exit_unlock;
+                }
         }
 
-        while ((inb(ioBase + ssrr) & 0x40));
-        if ((inb(ioBase + ssrr) & 0x80) == 0x80) {
-                error = -EIO;
-                /* Read error reset the port */
-                outb(0x00, ioBase + ssrr);
-                udelay(3000);
-                outb(0x01, ioBase + ssrr);
-                goto exit;
+        /* Configure PortID */
+        val = priv->portid | CPLD_I2C_CLK_100Khz_BIT;
+        outb(val, portid);
+        pr_debug("CPLD_I2C Write PortID 0x%x\n", val);
+
+        /* Configure OP_Code */
+        val = (priv->curr_xfer.data_len << 4) &  CPLD_I2C_DATA_SZ_MASK;
+        val |= (priv->curr_xfer.cmd_len & CPLD_I2C_CMD_SZ_MASK);
+        outb(val, opcode);
+        pr_debug("CPLD_I2C Write OP_Code 0x%x\n", val);
+
+        /* Configure CMD_Byte */
+        outb(priv->curr_xfer.cmd[0], cmdbyte0);
+        pr_debug("CPLD_I2C Write CMD_Byte 0x%x\n", priv->curr_xfer.cmd[0]);
+
+        /* Configure write data buffer */
+        if ((priv->curr_xfer.addr & BIT(0)) == I2C_SMBUS_WRITE){
+                pr_debug("CPLD_I2C Write WR_DATA buffer\n");
+                switch(priv->curr_xfer.data_len){
+                case 1:
+                        outb(data->byte, writedata);
+                        break;
+                case 2:
+                        outb(data->block[0], writedata);
+                        outb(data->block[1], ++writedata);
+                        break;
+                }
         }
 
-        byte = 0x40 +new_data->portid;
-        reg = cmd;
-        outb(byte, ioBase + portid);
-        outb(reg,ioBase + cmdbyte0);
-        byte = 33;
-        outb(byte, ioBase + opcode);
-        addr = addr << 1;
-        addr |= 0x01;
-        outb(addr, ioBase + devaddr);
-        while ((inb(ioBase + ssrr) & 0x40))
-        {
+        /* Start transfer, write the device address register */
+        pr_debug("CPLD_I2C Write DEV_ADDR 0x%x\n", priv->curr_xfer.addr);
+        outb(priv->curr_xfer.addr, devaddr);
+
+        /* Wait for transfer finish */
+        pr_debug("CPLD_I2C Wait busy bit(6) to be cleared\n");
+        do {
+                val = inb(ssr);
+                if ((val & CPLD_I2C_BUSY) == 0)
+                        break;
                 udelay(100);
-        }
+        } while (true); // Risky - add timeout
 
-        if ((inb(ioBase + ssrr) & 0x80) == 0x80) {
-            /* Read error reset the port */
+        pr_debug("CPLD_I2C Check error bit(7)\n");
+        if (val & CPLD_I2C_ERR) {
                 error = -EIO;
-                outb(0x00, ioBase + ssrr);
-                udelay(3000);
-                outb(0x01, ioBase + ssrr);
-                goto exit;
+                goto exit_unlock;
         }
 
-        temp = ioBase + readdata;
-        word_data = inb(temp);
-        word_data |= (inb(++temp) << 8);
+        /* Get the data from buffer */
+        if ((priv->curr_xfer.addr & BIT(0)) == I2C_SMBUS_READ){
+                pr_debug("CPLD_I2C Read RD_DATA buffer\n");
+                switch (priv->curr_xfer.data_len) {
+                case 1:
+                        data->byte = inb(readdata);
+                        break;
+                case 2:
+                        data->block[0] = inb(readdata);
+                        data->block[1] = inb(++readdata);
+                        break;
+                }
+        }
 
-        mutex_unlock(&cpld_data->cpld_lock);
-        data->word = word_data;
-        return 0;
+        error = 0;
 
-exit:
+exit_unlock:
+        pr_debug("CPLD_I2C Exit with %d\n", error);
         mutex_unlock(&cpld_data->cpld_lock);
         return error;
+
 }
 
-static int dx010_i2c_access(struct i2c_adapter *a, u16 addr,
-              unsigned short flags, char rw, u8 cmd,
-              int size, union i2c_smbus_data *data)
-{
+/*
+ * dx010_smbus_xfer - execute LPC-SMBus transfer
+ * Returns a negative errno code else zero on success.
+ */
+static s32 dx010_smbus_xfer(struct i2c_adapter *adap, u16 addr,
+               unsigned short flags, char read_write,
+               u8 command, int size, union i2c_smbus_data *data) {
 
         int error = 0;
+        struct dx010_i2c_data *priv;
+
+        priv = i2c_get_adapdata(adap);
 
-        struct dx010_i2c_data *new_data;
+        pr_debug("smbus_xfer called RW:%x CMD:%x SIZE:0x%x",
+                 read_write, command, size);
 
-        /* Write the command register */
-        new_data = i2c_get_adapdata(a);
+        priv->curr_xfer.addr = (addr << 1) | read_write;
+        priv->curr_xfer.data = data;
 
         /* Map the size to what the chip understands */
         switch (size) {
-        case I2C_SMBUS_QUICK:
-                size = HST_CNTL2_QUICK;
-        break;
         case I2C_SMBUS_BYTE:
-                size = HST_CNTL2_BYTE;
-        break;
+                priv->curr_xfer.cmd_len = 0;
+                priv->curr_xfer.data_len = 1;
+                break;
         case I2C_SMBUS_BYTE_DATA:
-                size = HST_CNTL2_BYTE_DATA;
-        break;
+                priv->curr_xfer.cmd_len = 1;
+                priv->curr_xfer.data_len = 1;
+                priv->curr_xfer.cmd[0] = command;
+                break;
         case I2C_SMBUS_WORD_DATA:
-            	size = HST_CNTL2_WORD_DATA;
-        break;
-        case I2C_SMBUS_BLOCK_DATA:
-                size = HST_CNTL2_BLOCK;
-        break;
+                priv->curr_xfer.cmd_len = 1;
+                priv->curr_xfer.data_len = 2;
+                priv->curr_xfer.cmd[0] = command;
+                break;
         default:
-                dev_warn(&a->dev, "Unsupported transaction %d\n", size);
+                dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
                 error = -EOPNOTSUPP;
                 goto Done;
         }
 
-        switch (size) {
-        case HST_CNTL2_BYTE:    /* Result put in SMBHSTDAT0 */
-        break;
-        case HST_CNTL2_BYTE_DATA:
-        break;
-        case HST_CNTL2_WORD_DATA:
-                if( 0 == i2c_read_eeprom(a,addr,new_data,cmd,data)){
-                    error = 0;
-                }else{
-                    error = -EIO;
-                }
-        break;
-        }
+        error = cpld_smbus_transfer(priv);
 
 Done:
         return error;
 }
 
-static u32 dx010_i2c_func(struct i2c_adapter *a)
-{
-        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-                        I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
-                        I2C_FUNC_SMBUS_BLOCK_DATA;
+// TODO: Add support for I2C_FUNC_SMBUS_PROC_CALL and I2C_FUNC_SMBUS_I2C_BLOCK
+static u32 dx010_i2c_func(struct i2c_adapter *a) {
+        return  I2C_FUNC_SMBUS_READ_BYTE  |
+                I2C_FUNC_SMBUS_BYTE_DATA  |
+                I2C_FUNC_SMBUS_WORD_DATA;
 }
 
 static const struct i2c_algorithm dx010_i2c_algorithm = {
-        .smbus_xfer = dx010_i2c_access,
+        .smbus_xfer = dx010_smbus_xfer,
         .functionality  = dx010_i2c_func,
 };
 
-static struct i2c_adapter * cel_dx010_i2c_init(struct platform_device *pdev, int portid)
+static struct i2c_adapter *cel_dx010_i2c_init(struct platform_device *pdev, int portid)
 {
         int error;
-
+        int base_addr;
         struct i2c_adapter *new_adapter;
-        struct dx010_i2c_data *new_data;
+        struct dx010_i2c_data *priv;
+
+        switch (portid) {
+        case PORT_SFPP1 ... PORT_SFPP2:
+        case PORT_BANK1_START ... PORT_BANK1_END:
+                base_addr = CPLD_I2C_BANK1_BASE;
+                break;
+        case PORT_BANK2_START ... PORT_BANK2_END:
+                base_addr = CPLD_I2C_BANK2_BASE;
+                break;
+        case PORT_BANK3_START ... PORT_BANK3_END:
+                base_addr = CPLD_I2C_BANK3_BASE;
+                break;
+        default:
+                dev_err(&pdev->dev, "Invalid port adapter ID: %d\n", portid);
+                goto error_exit;
+        }
 
         new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL);
                 if (!new_adapter)
@@ -544,31 +585,39 @@ static struct i2c_adapter * cel_dx010_i2c_init(struct platform_device *pdev, int
 
         new_adapter->dev.parent = &pdev->dev;
         new_adapter->owner = THIS_MODULE;
-        new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+        new_adapter->class = I2C_CLASS_DEPRECATED;
         new_adapter->algo  = &dx010_i2c_algorithm;
 
         snprintf(new_adapter->name, sizeof(new_adapter->name),
-                        "SMBus dx010 i2c Adapter portid@%04x", portid);
-
-        new_data = kzalloc(sizeof(*new_data), GFP_KERNEL);
-        if (!new_data)
-                return NULL;
+                        "SMBus dx010 i2c Adapter port %d", portid);
 
-        new_data->portid = portid;
+        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+        if (!priv) {
+                goto free_adap;
+        }
 
-        i2c_set_adapdata(new_adapter,new_data);
+        priv->portid = portid;
+        priv->base_addr = base_addr;
 
+        i2c_set_adapdata(new_adapter, priv);
         error = i2c_add_adapter(new_adapter);
         if(error)
-                return NULL;
+                goto free_data;
 
         return new_adapter;
+
+free_adap:
+        kzfree(new_adapter);
+free_data:
+        kzfree(priv);
+error_exit:
+        return NULL;
 };
 
 static int cel_dx010_lpc_drv_probe(struct platform_device *pdev)
 {
         struct resource *res;
-        int ret =0;
+        int ret = 0;
         int portid_count;
 
         cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct dx010_cpld_data),
diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/thermal_overload_control.sh b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/thermal_overload_control.sh
new file mode 100755
index 000000000000..57fd851f9cfb
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/thermal_overload_control.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+#
+# Copyright 2020-present Celestica. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+#
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+SETREG_FILE=/sys/devices/platform/dx010_cpld/setreg
+TOVERREG=0x140
+CPUOVER=0xa1
+ASICOVER=0xa2
+
+prog="$0"
+command="$1"
+
+if [[ $EUID -ne 0 ]]; then
+    echo "This script must be run as root"
+    exit 1
+fi
+
+usage() {
+    echo "Usage: thermal_overload_control.sh [option] <command>"
+    echo
+    echo "Options:"
+    echo "  -h, --help          : to print this message."
+    echo
+    echo "Commands:"
+    echo
+    echo "  cpu:  To enabling CPU thermal overload handler"
+    echo
+    echo "  asic : To enabling ASIC thermal overload handler"
+    echo
+}
+
+cpu_overload() {
+	logger "Enable CPU thermal overload control"
+	set_reg=`echo ${TOVERREG} ${CPUOVER} > ${SETREG_FILE}`
+}
+
+asic_overload() {
+	logger "Enable ASIC thermal overload control"
+	set_reg=`echo ${TOVERREG} ${ASICOVER} > ${SETREG_FILE}`
+}
+
+if [ $# -lt 1 ]; then
+    usage
+    exit -1
+fi
+
+case "$command" in
+-h | --help)
+    usage
+    ;;
+cpu)
+	cpu_overload
+	;;
+asic)
+	asic_overload
+	;;
+*)
+	usage
+	exit -1
+	;;
+esac
+
+exit $?
diff --git a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol
index eb15598b0efa..cdd5005e3688 100755
--- a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol
+++ b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol
@@ -39,285 +39,327 @@
 #
 
 PIDFILE="/var/run/fancontrol.pid"
+THERMAL_OVERLOAD_CONTROL_FILE="/usr/local/bin/thermal_overload_control.sh"
 
 #DEBUG=1
 MAX=255
 
 function LoadConfig
 {
-	local fcvcount fcv
-
-	echo "Loading configuration from $1 ..."
-	if [ ! -r "$1" ]
-	then
-		echo "Error: Can't read configuration file" >&2
-		exit 1
-	fi
-
-	# grep configuration from file
-	INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'`
-	DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'`
-	DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'`
-	FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'`
-	MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'`
-	MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'`
-	MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'`
-	MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'`
-	# optional settings:
-	FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'`
-	MINPWM=`egrep '^MINPWM=.*$' $1 | sed -e 's/MINPWM=//g'`
-	MAXPWM=`egrep '^MAXPWM=.*$' $1 | sed -e 's/MAXPWM=//g'`
-	THYST=`egrep '^THYST=.*$' $1 | sed -e 's/THYST=//g'`
-	echo 
-	# Check whether all mandatory settings are set
-	if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]]
-	then
-		echo "Some mandatory settings missing, please check your config file!" >&2
-		exit 1
-	fi
-	if [ "$INTERVAL" -le 0 ]
-	then
-		echo "Error in configuration file:" >&2
-		echo "INTERVAL must be at least 1" >&2
-		exit 1
-	fi
-
-	# write settings to arrays for easier use and print them
-	echo
-	echo "Common settings:"
-	echo "  INTERVAL=$INTERVAL"
-
-	let fcvcount=0
-	for fcv in $FCTEMPS
-	do
-		if ! echo $fcv | egrep -q '='
-		then
-			echo "Error in configuration file:" >&2
-			echo "FCTEMPS value is improperly formatted" >&2
-			exit 1
-		fi
-
-		AFCPWM[$fcvcount]=`echo $fcv |cut -d'=' -f1`
-		AFCTEMP[$fcvcount]=`echo $fcv |cut -d'=' -f2`
-		AFCFAN[$fcvcount]=`echo $FCFANS |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
-		AFCFANFAULT[$fcvcount]=`echo "${AFCFAN[$fcvcount]}" |sed -e 's/input/fault/g'`
-		AFCMINTEMP[$fcvcount]=`echo $MINTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
-		AFCMAXTEMP[$fcvcount]=`echo $MAXTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
-		AFCMINSTART[$fcvcount]=`echo $MINSTART |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
-		AFCMINSTOP[$fcvcount]=`echo $MINSTOP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
-		AFCMINPWM[$fcvcount]=`echo $MINPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
-		[ -z "${AFCMINPWM[$fcvcount]}" ] && AFCMINPWM[$fcvcount]=0
-		AFCMAXPWM[$fcvcount]=`echo $MAXPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
-		[ -z "${AFCMAXPWM[$fcvcount]}" ] && AFCMAXPWM[$fcvcount]=255
-		AFCTHYST[$fcvcount]=`echo $THYST |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
-		[ -z "${AFCTHYST[$fcvcount]}" ] && AFCTHYST[$fcvcount]=0
-
-		# verify the validity of the settings
-		if [ "${AFCMINTEMP[$fcvcount]}" -ge "${AFCMAXTEMP[$fcvcount]}" ]
-		then
-			echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
-			echo "MINTEMP must be less than MAXTEMP" >&2
-			exit 1
-		fi
-		if [ "${AFCMAXPWM[$fcvcount]}" -gt 255 ]
-		then
-			echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
-			echo "MAXPWM must be at most 255" >&2
-			exit 1
-		fi
-		if [ "${AFCMINSTOP[$fcvcount]}" -ge "${AFCMAXPWM[$fcvcount]}" ]
-		then
-			echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
-			echo "MINSTOP must be less than MAXPWM" >&2
-			exit 1
-		fi
-		if [ "${AFCMINSTOP[$fcvcount]}" -lt "${AFCMINPWM[$fcvcount]}" ]
-		then
-			echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
-			echo "MINSTOP must be greater than or equal to MINPWM" >&2
-			exit 1
-		fi
-		if [ "${AFCMINPWM[$fcvcount]}" -lt 0 ]
-		then
-			echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
-			echo "MINPWM must be at least 0" >&2
-			exit 1
-		fi
-
-		echo
-		echo "Settings for ${AFCPWM[$fcvcount]}:"
-		echo "  Depends on ${AFCTEMP[$fcvcount]}"
-		echo "  Controls ${AFCFAN[$fcvcount]}"
-		echo "  MINTEMP=${AFCMINTEMP[$fcvcount]}"
-		echo "  MAXTEMP=${AFCMAXTEMP[$fcvcount]}"
-		echo "  MINSTART=${AFCMINSTART[$fcvcount]}"
-		echo "  MINSTOP=${AFCMINSTOP[$fcvcount]}"
-		echo "  MINPWM=${AFCMINPWM[$fcvcount]}"
-		echo "  MAXPWM=${AFCMAXPWM[$fcvcount]}"
-		echo "  THYST=${AFCTHYST[$fcvcount]}"
-		let fcvcount=fcvcount+1
-	done
-	echo
+    local fcvcount fcv
+
+    echo "Loading configuration from $1 ..."
+    if [ ! -r "$1" ]
+    then
+        echo "Error: Can't read configuration file" >&2
+        exit 1
+    fi
+
+    # grep configuration from file
+    INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'`
+    DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'`
+    DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'`
+    FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'`
+    MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'`
+    MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'`
+    MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'`
+    MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'`
+    # optional settings:
+    FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'`
+    MINPWM=`egrep '^MINPWM=.*$' $1 | sed -e 's/MINPWM=//g'`
+    MAXPWM=`egrep '^MAXPWM=.*$' $1 | sed -e 's/MAXPWM=//g'`
+    THYST=`egrep '^THYST=.*$' $1 | sed -e 's/THYST=//g'`
+    MAXTEMPCRIT=`egrep '^MAXTEMPCRIT=.*$' $1 | sed -e 's/MAXTEMPCRIT=//g'`
+    MAXTEMPTYPE=`egrep '^MAXTEMPTYPE=.*$' $1 | sed -e 's/MAXTEMPTYPE=//g'`
+    echo 
+    # Check whether all mandatory settings are set
+    if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]]
+    then
+        echo "Some mandatory settings missing, please check your config file!" >&2
+        exit 1
+    fi
+    if [ "$INTERVAL" -le 0 ]
+    then
+        echo "Error in configuration file:" >&2
+        echo "INTERVAL must be at least 1" >&2
+        exit 1
+    fi
+
+    # write settings to arrays for easier use and print them
+    echo
+    echo "Common settings:"
+    echo "  INTERVAL=$INTERVAL"
+
+    let fcvcount=0
+    for fcv in $FCTEMPS
+    do
+        if ! echo $fcv | egrep -q '='
+        then
+            echo "Error in configuration file:" >&2
+            echo "FCTEMPS value is improperly formatted" >&2
+            exit 1
+        fi
+
+        AFCPWM[$fcvcount]=`echo $fcv |cut -d'=' -f1`
+        AFCTEMP[$fcvcount]=`echo $fcv |cut -d'=' -f2`
+        AFCFAN[$fcvcount]=`echo $FCFANS |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
+        AFCFANFAULT[$fcvcount]=`echo "${AFCFAN[$fcvcount]}" |sed -e 's/input/fault/g'`
+        AFCMINTEMP[$fcvcount]=`echo $MINTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
+        AFCMAXTEMP[$fcvcount]=`echo $MAXTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
+        AFCMINSTART[$fcvcount]=`echo $MINSTART |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
+        AFCMINSTOP[$fcvcount]=`echo $MINSTOP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
+        AFCMINPWM[$fcvcount]=`echo $MINPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
+        [ -z "${AFCMINPWM[$fcvcount]}" ] && AFCMINPWM[$fcvcount]=0
+        AFCMAXPWM[$fcvcount]=`echo $MAXPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
+        [ -z "${AFCMAXPWM[$fcvcount]}" ] && AFCMAXPWM[$fcvcount]=255
+        AFCTHYST[$fcvcount]=`echo $THYST |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`
+        [ -z "${AFCTHYST[$fcvcount]}" ] && AFCTHYST[$fcvcount]=0
+
+        # verify the validity of the settings
+        if [ "${AFCMINTEMP[$fcvcount]}" -ge "${AFCMAXTEMP[$fcvcount]}" ]
+        then
+            echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
+            echo "MINTEMP must be less than MAXTEMP" >&2
+            exit 1
+        fi
+        if [ "${AFCMAXPWM[$fcvcount]}" -gt 255 ]
+        then
+            echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
+            echo "MAXPWM must be at most 255" >&2
+            exit 1
+        fi
+        if [ "${AFCMINSTOP[$fcvcount]}" -ge "${AFCMAXPWM[$fcvcount]}" ]
+        then
+            echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
+            echo "MINSTOP must be less than MAXPWM" >&2
+            exit 1
+        fi
+        if [ "${AFCMINSTOP[$fcvcount]}" -lt "${AFCMINPWM[$fcvcount]}" ]
+        then
+            echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
+            echo "MINSTOP must be greater than or equal to MINPWM" >&2
+            exit 1
+        fi
+        if [ "${AFCMINPWM[$fcvcount]}" -lt 0 ]
+        then
+            echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2
+            echo "MINPWM must be at least 0" >&2
+            exit 1
+        fi
+
+        echo
+        echo "Settings for ${AFCPWM[$fcvcount]}:"
+        echo "  Depends on ${AFCTEMP[$fcvcount]}"
+        echo "  Controls ${AFCFAN[$fcvcount]}"
+        echo "  MINTEMP=${AFCMINTEMP[$fcvcount]}"
+        echo "  MAXTEMP=${AFCMAXTEMP[$fcvcount]}"
+        echo "  MINSTART=${AFCMINSTART[$fcvcount]}"
+        echo "  MINSTOP=${AFCMINSTOP[$fcvcount]}"
+        echo "  MINPWM=${AFCMINPWM[$fcvcount]}"
+        echo "  MAXPWM=${AFCMAXPWM[$fcvcount]}"
+        echo "  THYST=${AFCTHYST[$fcvcount]}"
+        let fcvcount=fcvcount+1
+    done
+    echo
+
+
+    let tscount=0
+    for ts in $MAXTEMPCRIT
+    do
+        CSTEMP[$tscount]=`echo $ts | cut -d '=' -f1`
+        CSMAXTEMPCRIT[$tscount]=`echo $ts | cut -d '=' -f2`
+        CSMAXTEMPTYPE=($(echo $MAXTEMPTYPE |sed -e 's/ /\n/g'| cut -d'=' -f2))
+
+        echo
+        echo "Settings for ${CSMAXTEMPTYPE[$tscount]} temperature sensor:"
+        echo "  Depends on ${CSTEMP[$tscount]}"
+        echo "  MAXTEMPCRIT=${CSMAXTEMPCRIT[$tscount]}"
+        let tscount=tscount+1
+    done
+    echo
+
 }
 
 function CheckFanFault()
 {
-	let fancount=0
-	while (( $fancount < ${#AFCFANFAULT[@]} )) # go through all fan fault.
-	do
-		fault=`cat ${AFCFANFAULT[$fancount]}`
-		if [[ "$fault" == "1" ]]
-		then
-			return 1 # fan fault detected
-		fi
-		let fancount=$fancount+1
-	done
-	return 0
+    let fancount=0
+    while (( $fancount < ${#AFCFANFAULT[@]} )) # go through all fan fault.
+    do
+        fault=`cat ${AFCFANFAULT[$fancount]}`
+        if [[ "$fault" == "1" ]]
+        then
+            return 1 # fan fault detected
+        fi
+        let fancount=$fancount+1
+    done
+    return 0
+}
+
+function CheckTempOver()
+{
+    let tempcount=0
+    while (( $tempcount < ${#CSTEMP[@]} )) # go through all temp.
+    do
+        ctemp=`cat ${CSTEMP[$tempcount]}`
+        let maxcrit="${CSMAXTEMPCRIT[$tempcount]}*1000"
+        if [ $ctemp -ge $maxcrit ]
+        then
+            logger "Thermal overload : ${CSMAXTEMPTYPE[$tempcount]} temperature ${ctemp} > ${maxcrit}"
+            if [ -f "$THERMAL_OVERLOAD_CONTROL_FILE" ]
+            then
+                toc_cmd="${THERMAL_OVERLOAD_CONTROL_FILE} ${CSMAXTEMPTYPE[$tempcount],,}"
+                bash $toc_cmd
+                exit 1
+            fi
+        fi
+        let tempcount=$tempcount+1
+    done
+    return 0
 }
 
 function DevicePath()
 {
-	if [ -h "$1/device" ]
-	then
-		readlink -f "$1/device" | sed -e 's/^\/sys\///'
-	fi
+    if [ -h "$1/device" ]
+    then
+        readlink -f "$1/device" | sed -e 's/^\/sys\///'
+    fi
 }
 
 function DeviceName()
 {
-	if [ -r "$1/name" ]
-	then
-		cat "$1/name" | sed -e 's/[[:space:]=]/_/g'
-	elif [ -r "$1/device/name" ]
-	then
-		cat "$1/device/name" | sed -e 's/[[:space:]=]/_/g'
-	fi
+    if [ -r "$1/name" ]
+    then
+        cat "$1/name" | sed -e 's/[[:space:]=]/_/g'
+    elif [ -r "$1/device/name" ]
+    then
+        cat "$1/device/name" | sed -e 's/[[:space:]=]/_/g'
+    fi
 }
 
 function ValidateDevices()
 {
-	local OLD_DEVPATH="$1" OLD_DEVNAME="$2" outdated=0
-	local entry device name path
-
-	for entry in $OLD_DEVPATH
-	do
-		device=`echo "$entry" | sed -e 's/=[^=]*$//'`
-		path=`echo "$entry" | sed -e 's/^[^=]*=//'`
-
-		if [ "`DevicePath "$device"`" != "$path" ]
-		then
-			echo "Device path of $device has changed" >&2
-			outdated=1
-		fi
-	done
-
-	for entry in $OLD_DEVNAME
-	do
-		device=`echo "$entry" | sed -e 's/=[^=]*$//'`
-		name=`echo "$entry" | sed -e 's/^[^=]*=//'`
-
-		if [ "`DeviceName "$device"`" != "$name" ]
-		then
-			echo "Device name of $device has changed" >&2
-			outdated=1
-		fi
-	done
-
-	return $outdated
+    local OLD_DEVPATH="$1" OLD_DEVNAME="$2" outdated=0
+    local entry device name path
+
+    for entry in $OLD_DEVPATH
+    do
+        device=`echo "$entry" | sed -e 's/=[^=]*$//'`
+        path=`echo "$entry" | sed -e 's/^[^=]*=//'`
+
+        if [ "`DevicePath "$device"`" != "$path" ]
+        then
+            echo "Device path of $device has changed" >&2
+            outdated=1
+        fi
+    done
+
+    for entry in $OLD_DEVNAME
+    do
+        device=`echo "$entry" | sed -e 's/=[^=]*$//'`
+        name=`echo "$entry" | sed -e 's/^[^=]*=//'`
+
+        if [ "`DeviceName "$device"`" != "$name" ]
+        then
+            echo "Device name of $device has changed" >&2
+            outdated=1
+        fi
+    done
+
+    return $outdated
 }
 
 # Check that all referenced sysfs files exist
 function CheckFiles
 {
-	local outdated=0 fcvcount pwmo tsen fan
-
-	let fcvcount=0
-	while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs
-	do
-		pwmo=${AFCPWM[$fcvcount]}
-		if [ ! -w $pwmo ]
-		then
-			echo "Error: file $pwmo doesn't exist" >&2
-			outdated=1
-		fi
-		let fcvcount=$fcvcount+1
-	done
-
-	let fcvcount=0
-	while (( $fcvcount < ${#AFCTEMP[@]} )) # go through all temp inputs
-	do
-		tsen=${AFCTEMP[$fcvcount]}
-		if [ ! -r $tsen ]
-		then
-			echo "Error: file $tsen doesn't exist" >&2
-			outdated=1
-		fi
-		let fcvcount=$fcvcount+1
-	done
-
-	let fcvcount=0
-	while (( $fcvcount < ${#AFCFAN[@]} )) # go through all fan inputs
-	do
-		# A given PWM output can control several fans
-		for fan in $(echo ${AFCFAN[$fcvcount]} | sed -e 's/+/ /')
-		do
-			if [ ! -r $fan ]
-			then
-				echo "Error: file $fan doesn't exist" >&2
-				outdated=1
-			fi
-		done
-		let fcvcount=$fcvcount+1
-	done
-
-	if [ $outdated -eq 1 ]
-	then
-		echo >&2
-		echo "At least one referenced file is missing. Either some required kernel" >&2
-		echo "modules haven't been loaded, or your configuration file is outdated." >&2
-		echo "In the latter case, you should run pwmconfig again." >&2
-	fi
-
-	return $outdated
+    local outdated=0 fcvcount pwmo tsen fan
+
+    let fcvcount=0
+    while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs
+    do
+        pwmo=${AFCPWM[$fcvcount]}
+        if [ ! -w $pwmo ]
+        then
+            echo "Error: file $pwmo doesn't exist" >&2
+            outdated=1
+        fi
+        let fcvcount=$fcvcount+1
+    done
+
+    let fcvcount=0
+    while (( $fcvcount < ${#AFCTEMP[@]} )) # go through all temp inputs
+    do
+        tsen=${AFCTEMP[$fcvcount]}
+        if [ ! -r $tsen ]
+        then
+            echo "Error: file $tsen doesn't exist" >&2
+            outdated=1
+        fi
+        let fcvcount=$fcvcount+1
+    done
+
+    let fcvcount=0
+    while (( $fcvcount < ${#AFCFAN[@]} )) # go through all fan inputs
+    do
+        # A given PWM output can control several fans
+        for fan in $(echo ${AFCFAN[$fcvcount]} | sed -e 's/+/ /')
+        do
+            if [ ! -r $fan ]
+            then
+                echo "Error: file $fan doesn't exist" >&2
+                outdated=1
+            fi
+        done
+        let fcvcount=$fcvcount+1
+    done
+
+    if [ $outdated -eq 1 ]
+    then
+        echo >&2
+        echo "At least one referenced file is missing. Either some required kernel" >&2
+        echo "modules haven't been loaded, or your configuration file is outdated." >&2
+        echo "In the latter case, you should run pwmconfig again." >&2
+    fi
+
+    return $outdated
 }
 
 if [ "$1" == "--check" ]
 then
-	if [ -f "$2" ]
-	then
-		LoadConfig $2
-	else
-		LoadConfig /etc/fancontrol
-	fi
-	exit 0
+    if [ -f "$2" ]
+    then
+        LoadConfig $2
+    else
+        LoadConfig /etc/fancontrol
+    fi
+    exit 0
 fi
 
 if [ -f "$1" ]
 then
-	LoadConfig $1
+    LoadConfig $1
 else
-	LoadConfig /etc/fancontrol
+    LoadConfig /etc/fancontrol
 fi
 
 # Detect path to sensors
 if echo "${AFCPWM[0]}" | egrep -q '^/'
 then
-	DIR=/
+    DIR=/
 elif echo "${AFCPWM[0]}" | egrep -q '^hwmon[0-9]'
 then
-	DIR=/sys/class/hwmon
+    DIR=/sys/class/hwmon
 elif echo "${AFCPWM[0]}" | egrep -q '^[1-9]*[0-9]-[0-9abcdef]{4}'
 then
-	DIR=/sys/bus/i2c/devices
+    DIR=/sys/bus/i2c/devices
 else
-	echo "$0: Invalid path to sensors" >&2
-	exit 1
+    echo "$0: Invalid path to sensors" >&2
+    exit 1
 fi
 
 if [ ! -d $DIR ]
 then
-	echo $0: 'No sensors found! (did you load the necessary modules?)' >&2
-	exit 1
+    echo $0: 'No sensors found! (did you load the necessary modules?)' >&2
+    exit 1
 fi
 cd $DIR
 
@@ -325,94 +367,94 @@ cd $DIR
 # if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ]
 # then
 #    echo "Configuration is too old, please run pwmconfig again" >&2
-# 	 exit 1
+#      exit 1
 # fi
 
 if [ "$DIR" = "/" -a -n "$DEVPATH" ]
 then
-	echo "Unneeded DEVPATH with absolute device paths" >&2
-	exit 1
+    echo "Unneeded DEVPATH with absolute device paths" >&2
+    exit 1
 fi
 if ! ValidateDevices "$DEVPATH" "$DEVNAME"
 then
-	echo "Configuration appears to be outdated, please run pwmconfig again" >&2
-	exit 1
+    echo "Configuration appears to be outdated, please run pwmconfig again" >&2
+    exit 1
 fi
 CheckFiles || exit 1
 
 if [ -f "$PIDFILE" ]
 then
-	echo "File $PIDFILE exists, is fancontrol already running?" >&2
-	exit 1
+    echo "File $PIDFILE exists, is fancontrol already running?" >&2
+    exit 1
 fi
 echo $$ > "$PIDFILE"
 
 # $1 = pwm file name
 function pwmdisable()
 {
-	local ENABLE=${1}_enable
-
-	# No enable file? Just set to max
-	if [ ! -f $ENABLE ]
-	then
-		echo $MAX > $1
-		return 0
-	fi
-
-	# Try pwmN_enable=0
-	echo 0 > $ENABLE 2> /dev/null
-	if [ `cat $ENABLE` -eq 0 ]
-	then
-		# Success
-		echo $MAX > $1
-		return 0
-	fi
-
-	# It didn't work, try pwmN_enable=1 pwmN=255
-	echo 1 > $ENABLE 2> /dev/null
-	echo $MAX > $1
-	if [ `cat $ENABLE` -eq 1 -a `cat $1` -ge 190 ]
-	then
-		# Success
-		return 0
-	fi
-
-	# Nothing worked
-	echo "$ENABLE stuck to" `cat $ENABLE` >&2
-	return 1
+    local ENABLE=${1}_enable
+
+    # No enable file? Just set to max
+    if [ ! -f $ENABLE ]
+    then
+        echo $MAX > $1
+        return 0
+    fi
+
+    # Try pwmN_enable=0
+    echo 0 > $ENABLE 2> /dev/null
+    if [ `cat $ENABLE` -eq 0 ]
+    then
+        # Success
+        echo $MAX > $1
+        return 0
+    fi
+
+    # It didn't work, try pwmN_enable=1 pwmN=255
+    echo 1 > $ENABLE 2> /dev/null
+    echo $MAX > $1
+    if [ `cat $ENABLE` -eq 1 -a `cat $1` -ge 190 ]
+    then
+        # Success
+        return 0
+    fi
+
+    # Nothing worked
+    echo "$ENABLE stuck to" `cat $ENABLE` >&2
+    return 1
 }
 
 # $1 = pwm file name
 function pwmenable()
 {
-	local ENABLE=${1}_enable
-
-	if [ -f $ENABLE ]
-	then
-		echo 1 > $ENABLE 2> /dev/null
-		if [ $? -ne 0 ]
-		then
-			return 1
-		fi
-	fi
-	echo $MAX > $1
+    local ENABLE=${1}_enable
+
+    if [ -f $ENABLE ]
+    then
+        echo 1 > $ENABLE 2> /dev/null
+        if [ $? -ne 0 ]
+        then
+            return 1
+        fi
+    fi
+    echo $MAX > $1
 }
 
 function restorefans()
 {
-	local status=$1 fcvcount pwmo
-
-	echo 'Aborting, restoring fans...'
-	let fcvcount=0
-	while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs
-	do
-		pwmo=${AFCPWM[$fcvcount]}
-		pwmdisable $pwmo
-		let fcvcount=$fcvcount+1
-	done
-	echo 'Verify fans have returned to full speed'
-	rm -f "$PIDFILE"
-	exit $status
+    local status=$1 fcvcount pwmo
+
+    echo 'Aborting, restoring fans...'
+    let fcvcount=0
+    while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs
+    do
+        pwmo=${AFCPWM[$fcvcount]}
+        pwmdisable $pwmo
+        let fcvcount=$fcvcount+1
+    done
+    echo 'Verify fans have returned to full speed'
+    rm -f "$PIDFILE"
+    exit $status
 }
 
 trap 'restorefans 0' SIGQUIT SIGTERM
@@ -446,163 +488,166 @@ function lowerBound
 # main function
 function UpdateFanSpeeds
 {
-	local fcvcount
-	local pwmo tsens fan mint maxt minsa minso minpwm maxpwm tHyst
-	local tval pwmpval fanval min_fanval one_fan one_fanval
-	local -i pwmval
-
-	let fcvcount=0
-	while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs
-	do
-		#hopefully shorter vars will improve readability:
-		pwmo=${AFCPWM[$fcvcount]}
-		tsens=${AFCTEMP[$fcvcount]}
-		fan=${AFCFAN[$fcvcount]}
-		let mint="${AFCMINTEMP[$fcvcount]}*1000"
-		let maxt="${AFCMAXTEMP[$fcvcount]}*1000"
-		minsa=${AFCMINSTART[$fcvcount]}
-		minso=${AFCMINSTOP[$fcvcount]}
-		minpwm=${AFCMINPWM[$fcvcount]}
-		maxpwm=${AFCMAXPWM[$fcvcount]}
-		let tHyst="${AFCTHYST[$fcvcount]}*1000"
-
-		#if some fan fault detected all pwm=100%
-		CheckFanFault
-		if [ $? -ne 0 ]
-		then
-			echo $MAX > $pwmo
-			let fcvcount=$fcvcount+1
-			continue			
-		fi	
-
-		read tval < ${tsens}
-		if [ $? -ne 0 ]
-		then
-			echo "Error reading temperature from $DIR/$tsens"
-			restorefans 1
-		fi
-
-		read pwmpval < ${pwmo}
-		if [ $? -ne 0 ]
-		then
-			echo "Error reading PWM value from $DIR/$pwmo"
-			restorefans 1
-		fi
-
-		# If fanspeed-sensor output shall be used, do it
-		if [[ -n ${fan} ]]
-		then
-			min_fanval=100000
-			fanval=
-			# A given PWM output can control several fans
-			for one_fan in $(echo $fan | sed -e 's/+/ /')
-			do
-				read one_fanval < ${one_fan}
-				if [ $? -ne 0 ]
-				then
-					echo "Error reading Fan value from $DIR/$one_fan" >&2
-					restorefans 1
-				fi
-
-				# Remember the minimum, it only matters if it is 0
-				if [ $one_fanval -lt $min_fanval ]
-				then
-					min_fanval=$one_fanval
-				fi
-
-				if [ -z "$fanval" ]
-				then
-					fanval=$one_fanval
-				else
-					fanval="$fanval/$one_fanval"
-				fi
-			done
-		else
-			fanval=1  # set it to a non zero value, so the rest of the script still works
-		fi
-
-		# debug info
-		if [ "$DEBUG" != "" ]
-		then
-			echo "pwmo=$pwmo"
-			echo "tsens=$tsens"
-			echo "fan=$fan"
-			echo "mint=$mint"
-			echo "maxt=$maxt"
-			echo "minsa=$minsa"
-			echo "minso=$minso"
-			echo "minpwm=$minpwm"
-			echo "maxpwm=$maxpwm"
-			echo "tval=$tval"
-			echo "pwmpval=$pwmpval"
-			echo "fanval=$fanval"
-			echo "min_fanval=$min_fanval"
-			echo "tHyst=$tHyst"
-		fi
-		pwmval=$pwmpval
-		if (( $tval+$tHyst <= $mint ))
-			then pwmval=$minpwm # below min temp, use defined min pwm
-		elif (( $tval >= $maxt ))
-			then pwmval=$maxpwm # over max temp, use defined max pwm
-		elif (( $tval+$tHyst >= $maxt )) && (( $pwmpval == $maxpwm ))
-			then pwmval=$maxpwm
-		else
-			# calculate the new value from temperature and settings
-			# pwmval="(${tval}-${mint})*(${maxpwm}-${minso})/(${maxt}-${mint})+${minso}
-			lowerBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst}
-			lb=$lw_b
-			upperBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst}
-			ub=$up_b
-
-			if [ "$DEBUG" != "" ]
-			then
-				echo "old pwm=$pwmval lw_b=$lw_b up_b=$up_b"
-			fi
-
-			if [[ "$pwmval" -gt "$ub" ]]
-			then
-				pwmval=$ub
-			else
-				if [[ "$pwmval" -lt "$lb" ]]
-				then
-						pwmval=$lb
-				fi
-			fi
-
-			if [ $pwmpval -eq 0 -o $min_fanval -eq 0 ]
-			then # if fan was stopped start it using a safe value
-				echo $minsa > $pwmo
-				# Sleep while still handling signals
-				sleep 1 &
-				wait $!
-			fi
-		fi
-		echo $pwmval > $pwmo # write new value to pwm output
-		if [ $? -ne 0 ]
-		then
-			echo "Error writing PWM value to $DIR/$pwmo" >&2
-			restorefans 1
-		fi
-		if [ "$DEBUG" != "" ]
-		then
-			echo "new pwmval=$pwmval"
-		fi
-		let fcvcount=$fcvcount+1
-	done
+    local fcvcount
+    local pwmo tsens fan mint maxt minsa minso minpwm maxpwm tHyst
+    local tval pwmpval fanval min_fanval one_fan one_fanval
+    local -i pwmval
+
+    let fcvcount=0
+    while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs
+    do
+        #hopefully shorter vars will improve readability:
+        pwmo=${AFCPWM[$fcvcount]}
+        tsens=${AFCTEMP[$fcvcount]}
+        fan=${AFCFAN[$fcvcount]}
+        let mint="${AFCMINTEMP[$fcvcount]}*1000"
+        let maxt="${AFCMAXTEMP[$fcvcount]}*1000"
+        minsa=${AFCMINSTART[$fcvcount]}
+        minso=${AFCMINSTOP[$fcvcount]}
+        minpwm=${AFCMINPWM[$fcvcount]}
+        maxpwm=${AFCMAXPWM[$fcvcount]}
+        let tHyst="${AFCTHYST[$fcvcount]}*1000"
+
+        #if some fan fault detected all pwm=100%
+        CheckFanFault
+        if [ $? -ne 0 ]
+        then
+            echo $MAX > $pwmo
+            let fcvcount=$fcvcount+1
+            continue
+        fi
+
+		#check thermal overload
+        CheckTempOver
+
+        read tval < ${tsens}
+        if [ $? -ne 0 ]
+        then
+            echo "Error reading temperature from $DIR/$tsens"
+            restorefans 1
+        fi
+
+        read pwmpval < ${pwmo}
+        if [ $? -ne 0 ]
+        then
+            echo "Error reading PWM value from $DIR/$pwmo"
+            restorefans 1
+        fi
+
+        # If fanspeed-sensor output shall be used, do it
+        if [[ -n ${fan} ]]
+        then
+            min_fanval=100000
+            fanval=
+            # A given PWM output can control several fans
+            for one_fan in $(echo $fan | sed -e 's/+/ /')
+            do
+                read one_fanval < ${one_fan}
+                if [ $? -ne 0 ]
+                then
+                    echo "Error reading Fan value from $DIR/$one_fan" >&2
+                    restorefans 1
+                fi
+
+                # Remember the minimum, it only matters if it is 0
+                if [ $one_fanval -lt $min_fanval ]
+                then
+                    min_fanval=$one_fanval
+                fi
+
+                if [ -z "$fanval" ]
+                then
+                    fanval=$one_fanval
+                else
+                    fanval="$fanval/$one_fanval"
+                fi
+            done
+        else
+            fanval=1  # set it to a non zero value, so the rest of the script still works
+        fi
+
+        # debug info
+        if [ "$DEBUG" != "" ]
+        then
+            echo "pwmo=$pwmo"
+            echo "tsens=$tsens"
+            echo "fan=$fan"
+            echo "mint=$mint"
+            echo "maxt=$maxt"
+            echo "minsa=$minsa"
+            echo "minso=$minso"
+            echo "minpwm=$minpwm"
+            echo "maxpwm=$maxpwm"
+            echo "tval=$tval"
+            echo "pwmpval=$pwmpval"
+            echo "fanval=$fanval"
+            echo "min_fanval=$min_fanval"
+            echo "tHyst=$tHyst"
+        fi
+        pwmval=$pwmpval
+        if (( $tval+$tHyst <= $mint ))
+            then pwmval=$minpwm # below min temp, use defined min pwm
+        elif (( $tval >= $maxt ))
+            then pwmval=$maxpwm # over max temp, use defined max pwm
+        elif (( $tval+$tHyst >= $maxt )) && (( $pwmpval == $maxpwm ))
+            then pwmval=$maxpwm
+        else
+            # calculate the new value from temperature and settings
+            # pwmval="(${tval}-${mint})*(${maxpwm}-${minso})/(${maxt}-${mint})+${minso}
+            lowerBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst}
+            lb=$lw_b
+            upperBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst}
+            ub=$up_b
+
+            if [ "$DEBUG" != "" ]
+            then
+                echo "old pwm=$pwmval lw_b=$lw_b up_b=$up_b"
+            fi
+
+            if [[ "$pwmval" -gt "$ub" ]]
+            then
+                pwmval=$ub
+            else
+                if [[ "$pwmval" -lt "$lb" ]]
+                then
+                        pwmval=$lb
+                fi
+            fi
+
+            if [ $pwmpval -eq 0 -o $min_fanval -eq 0 ]
+            then # if fan was stopped start it using a safe value
+                echo $minsa > $pwmo
+                # Sleep while still handling signals
+                sleep 1 &
+                wait $!
+            fi
+        fi
+        echo $pwmval > $pwmo # write new value to pwm output
+        if [ $? -ne 0 ]
+        then
+            echo "Error writing PWM value to $DIR/$pwmo" >&2
+            restorefans 1
+        fi
+        if [ "$DEBUG" != "" ]
+        then
+            echo "new pwmval=$pwmval"
+        fi
+        let fcvcount=$fcvcount+1
+    done
 }
 
 echo 'Enabling PWM on fans...'
 let fcvcount=0
 while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs
 do
-	pwmo=${AFCPWM[$fcvcount]}
-	pwmenable $pwmo
-	if [ $? -ne 0 ]
-	then
-		echo "Error enabling PWM on $DIR/$pwmo" >&2
-		restorefans 1
-	fi
-	let fcvcount=$fcvcount+1
+    pwmo=${AFCPWM[$fcvcount]}
+    pwmenable $pwmo
+    if [ $? -ne 0 ]
+    then
+        echo "Error enabling PWM on $DIR/$pwmo" >&2
+        restorefans 1
+    fi
+    let fcvcount=$fcvcount+1
 done
 
 echo 'Starting automatic fan control...'
@@ -610,8 +655,8 @@ echo 'Starting automatic fan control...'
 # main loop calling the main function at specified intervals
 while true
 do
-	UpdateFanSpeeds
-	# Sleep while still handling signals
-	sleep $INTERVAL &
-	wait $!
-done
\ No newline at end of file
+    UpdateFanSpeeds
+    # Sleep while still handling signals
+    sleep $INTERVAL &
+    wait $!
+done

From e9148ee19962729733b6ff0b1562d7e9017cc609 Mon Sep 17 00:00:00 2001
From: Wirut Getbamrung <wgetbum@icloud.com>
Date: Wed, 23 Sep 2020 13:25:23 +0700
Subject: [PATCH 3/3] [device/celestica]: using sonic-py-common package

---
 .../celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py
index 6566d4698e8d..1f034be4a0b0 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py
+++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py
@@ -3,7 +3,7 @@
 import os
 import struct
 import subprocess
-from sonic_daemon_base.daemon_base import DaemonBase
+from sonic_py_common import device_info
 from mmap import *
 
 HOST_CHK_CMD = "docker > /dev/null 2>&1"
@@ -13,7 +13,7 @@
 class APIHelper():
 
     def __init__(self):
-        (self.platform, self.hwsku) = DaemonBase().get_platform_and_hwsku()
+        (self.platform, self.hwsku) = device_info.get_platform_and_hwsku()
 
     def is_host(self):
         return os.system(HOST_CHK_CMD) == 0