diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/minigraph.xml b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/minigraph.xml index e2d151e6ec47..803ae39d22c2 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/minigraph.xml +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/minigraph.xml @@ -93,7 +93,7 @@ - 40000 + 100000 DeviceInterfaceLink OCPSCH0104001MS Ethernet24 @@ -101,7 +101,7 @@ Ethernet0 - 40000 + 100000 DeviceInterfaceLink OCPSCH0104002MS Ethernet24 diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/sensors.conf b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/sensors.conf index eb5a5b4b69f3..eb991d771d15 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/sensors.conf +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/sensors.conf @@ -40,9 +40,9 @@ chip "w83795adg-*" label in0 "0.9V" set in0_max 0.927 set in0_min 0.873 - label in1 "0.86V" - set in1_max 0.877 - set in1_min 0.843 + label in1 "VDD" + set in1_max 0.962 + set in1_min 0.717 ignore in2 ignore in3 ignore in4 diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/port_config.ini b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/port_config.ini new file mode 100644 index 000000000000..749f9f484a3d --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/port_config.ini @@ -0,0 +1,65 @@ +# name lanes alias speed autoneg fec index +Ethernet0 0,1,2,3 Ethernet0 100000 0 0 0 +Ethernet4 4,5,6,7 Ethernet4 100000 0 0 1 +Ethernet8 8,9,10,11 Ethernet8 100000 0 0 2 +Ethernet12 12,13,14,15 Ethernet12 100000 0 0 3 +Ethernet16 16,17,18,19 Ethernet16 100000 0 0 4 +Ethernet20 20,21,22,23 Ethernet20 100000 0 0 5 +Ethernet24 24,25,26,27 Ethernet24 100000 0 0 6 +Ethernet28 28,29,30,31 Ethernet28 100000 0 0 7 +Ethernet32 32,33,34,35 Ethernet32 100000 0 0 8 +Ethernet36 36,37,38,39 Ethernet36 100000 0 0 9 +Ethernet40 40,41,42,43 Ethernet40 100000 0 0 10 +Ethernet44 44,45,46,47 Ethernet44 100000 0 0 11 +Ethernet48 48,49,50,51 Ethernet48 100000 0 0 12 +Ethernet52 52,53,54,55 Ethernet52 100000 0 0 13 +Ethernet56 56,57,58,59 Ethernet56 100000 0 0 14 +Ethernet60 60,61,62,63 Ethernet60 100000 0 0 15 +Ethernet64 64,65,66,67 Ethernet64 100000 0 0 16 +Ethernet68 68,69,70,71 Ethernet68 100000 0 0 17 +Ethernet72 72,73,74,75 Ethernet72 100000 0 0 18 +Ethernet76 76,77,78,79 Ethernet76 100000 0 0 19 +Ethernet80 80,81,82,83 Ethernet80 100000 0 0 20 +Ethernet84 84,85,86,87 Ethernet84 100000 0 0 21 +Ethernet88 88,89,90,91 Ethernet88 100000 0 0 22 +Ethernet92 92,93,94,95 Ethernet92 100000 0 0 23 +Ethernet96 96,97,98,99 Ethernet96 100000 0 0 24 +Ethernet100 100,101,102,103 Ethernet100 100000 0 0 25 +Ethernet104 104,105,106,107 Ethernet104 100000 0 0 26 +Ethernet108 108,109,110,111 Ethernet108 100000 0 0 27 +Ethernet112 112,113,114,115 Ethernet112 100000 0 0 28 +Ethernet116 116,117,118,119 Ethernet116 100000 0 0 29 +Ethernet120 120,121,122,123 Ethernet120 100000 0 0 30 +Ethernet124 124,125,126,127 Ethernet124 100000 0 0 31 +Ethernet128 128,129,130,131 Ethernet128 100000 0 0 32 +Ethernet132 132,133,134,135 Ethernet132 100000 0 0 33 +Ethernet136 136,137,138,139 Ethernet136 100000 0 0 34 +Ethernet140 140,141,142,143 Ethernet140 100000 0 0 35 +Ethernet144 144,145,146,147 Ethernet144 100000 0 0 36 +Ethernet148 148,149,150,151 Ethernet148 100000 0 0 37 +Ethernet152 152,153,154,155 Ethernet152 100000 0 0 38 +Ethernet156 156,157,158,159 Ethernet156 100000 0 0 39 +Ethernet160 160,161,162,163 Ethernet160 100000 0 0 40 +Ethernet164 164,165,166,167 Ethernet164 100000 0 0 41 +Ethernet168 168,169,170,171 Ethernet168 100000 0 0 42 +Ethernet172 172,173,174,175 Ethernet172 100000 0 0 43 +Ethernet176 176,177,178,179 Ethernet176 100000 0 0 44 +Ethernet180 180,181,182,183 Ethernet180 100000 0 0 45 +Ethernet184 184,185,186,187 Ethernet184 100000 0 0 46 +Ethernet188 188,189,190,191 Ethernet188 100000 0 0 47 +Ethernet192 192,193,194,195 Ethernet192 100000 0 0 48 +Ethernet196 196,197,198,199 Ethernet196 100000 0 0 49 +Ethernet200 200,201,202,203 Ethernet200 100000 0 0 50 +Ethernet204 204,205,206,207 Ethernet204 100000 0 0 51 +Ethernet208 208,209,210,211 Ethernet208 100000 0 0 52 +Ethernet212 212,213,214,215 Ethernet212 100000 0 0 53 +Ethernet216 216,217,218,219 Ethernet216 100000 0 0 54 +Ethernet220 220,221,222,223 Ethernet220 100000 0 0 55 +Ethernet224 224,225,226,227 Ethernet224 100000 0 0 56 +Ethernet228 228,229,230,231 Ethernet228 100000 0 0 57 +Ethernet232 232,233,234,235 Ethernet232 100000 0 0 58 +Ethernet236 236,237,238,239 Ethernet236 100000 0 0 59 +Ethernet240 240,241,242,243 Ethernet240 100000 0 0 60 +Ethernet244 244,245,246,247 Ethernet244 100000 0 0 61 +Ethernet248 248,249,250,251 Ethernet248 100000 0 0 62 +Ethernet252 252,253,254,255 Ethernet252 100000 0 0 63 diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf new file mode 100644 index 000000000000..224d1fc58b18 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "switchsai": "lib/libswitchsai.so", + "agent0": "lib/platform/x86_64-ingrasys_s9280_64x-r0/libpltfm_mgr.so", + "switchapi_port_add": false + } + ] +} diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/fancontrol b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/fancontrol new file mode 100644 index 000000000000..c131df9df32c --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/fancontrol @@ -0,0 +1,9 @@ +INTERVAL=10 +DEVPATH=hwmon1=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-16/16-002f hwmon3=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-6/6-004e +DEVNAME=hwmon1=w83795adg +FCTEMPS=hwmon1/device/pwm2=hwmon3/temp1_input +FCFANS=hwmon1/device/pwm2=hwmon1/device/fan7_input hwmon1/device/pwm2=hwmon1/device/fan5_input hwmon1/device/pwm2=hwmon1/device/fan3_input hwmon1/device/pwm2=hwmon1/device/fan1_input +MINTEMP=hwmon1/device/pwm2=20 +MAXTEMP=hwmon1/device/pwm2=60 +MINSTART=hwmon1/device/pwm2=75 +MINSTOP=hwmon1/device/pwm2=22 diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/installer.conf b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/minigraph.xml b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/minigraph.xml new file mode 100644 index 000000000000..ffc71df148e5 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/minigraph.xml @@ -0,0 +1,151 @@ + + + + + + OCPSCH0104001MS + 10.10.1.26 + OCPSCH01040GGLF + 10.10.1.25 + 1 + 10 + 3 + + + OCPSCH0104002MS + 10.10.2.26 + OCPSCH01040GGLF + 10.10.2.25 + 1 + 10 + 3 + + + + + 64536 + OCPSCH01040GGLF + + +
10.10.1.26
+ + +
+ +
10.10.2.26
+ + +
+
+ +
+ + 64542 + OCPSCH0104001MS + + + + 64543 + OCPSCH0104002MS + + +
+
+ + + + + + HostIP + Loopback0 + + 100.0.0.9/32 + + 100.0.0.9/32 + + + + + + + + OCPSCH01040GGLF + + + + + + Ethernet0 + 10.10.1.25/30 + + + + Ethernet4 + 10.10.2.25/30 + + + + + + + + + + + + 100000 + DeviceInterfaceLink + OCPSCH0104001MS + Ethernet24 + OCPSCH01040GGLF + Ethernet0 + + + 100000 + DeviceInterfaceLink + OCPSCH0104002MS + Ethernet24 + OCPSCH01040GGLF + Ethernet4 + + + + + OCPSCH01040GGLF + INGRASYS-S9280-64X + + + + + + + OCPSCH01040GGLF + + + DhcpResources + + + + + NtpResources + + 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org + + + SyslogResources + + + + + ErspanDestinationIpv4 + + 2.2.2.2 + + + + + + + OCPSCH01040GGLF + INGRASYS-S9280-64X +
diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/eeprom.py new file mode 100644 index 000000000000..ecf171539843 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# Ingrasys S9280-64X +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0051/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/psuutil.py new file mode 100644 index 000000000000..c4b78c943e81 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/psuutil.py @@ -0,0 +1,93 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + # TODO: need to check if the patch mapping correct + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/i2c-18/18-0050", + "/sys/bus/i2c/devices/i2c-17/17-0050"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip('\r\n') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file = 'psu_pg' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absent = 0 + attr_file ='psu_abs' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU presence + if (attr_value == 0): + status = 1 + + return status + diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/sfputil.py new file mode 100644 index 000000000000..d9ef84c331c5 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/sfputil.py @@ -0,0 +1,300 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 63 + PORTS_IN_BLOCK = 64 + EEPROM_OFFSET = 41 + CPLD1_PORTS = 12 + CPLDx_PORTS = 13 + #TODO: check init sequence for CPLD i2c bus + CPLD_OFFSET = 1 + CPLD_PRES_BIT = 1 + CPLD_RESET_BIT = 0 + CPLD_LPMOD_BIT = 2 + CPLDx_I2C_ADDR = "33" + EEPROM_I2C_ADDR = "50" + CPLD_PORT_STATUS_KEY = "cpld_qsfp_port_status" + CPLD_PORT_CONFIG_KEY = "cpld_qsfp_port_config" + CPLD_REG_PATH = "/sys/bus/i2c/devices/{0}-00{1}/{2}_{3}" + + _port_to_eeprom_mapping = {} + + #TODO: check the fp port to phy port mapping + _fp2phy_port_mapping = { + 0: 0, + 1: 1, + 2: 4, + 3: 5, + 4: 8, + 5: 9, + 6: 12, + 7: 13, + 8: 16, + 9: 17, + 10: 20, + 11: 21, + 12: 24, + 13: 25, + 14: 28, + 15: 29, + 16: 32, + 17: 33, + 18: 36, + 19: 37, + 20: 40, + 21: 41, + 22: 44, + 23: 45, + 24: 48, + 25: 49, + 26: 52, + 27: 53, + 28: 56, + 29: 57, + 30: 60, + 31: 61, + 32: 2, + 33: 3, + 34: 6, + 35: 7, + 36: 10, + 37: 11, + 38: 14, + 39: 15, + 40: 18, + 41: 19, + 42: 22, + 43: 23, + 44: 26, + 45: 27, + 46: 30, + 47: 31, + 48: 34, + 49: 35, + 50: 38, + 51: 39, + 52: 42, + 53: 43, + 54: 46, + 55: 47, + 56: 50, + 57: 51, + 58: 54, + 59: 55, + 60: 58, + 61: 59, + 62: 62, + 63: 63 + } + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(0, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + + def __init__(self): + # Override port_to_eeprom_mapping for class initialization + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-00{1}/eeprom" + for x in range(self.port_start, self.port_end + 1): + phy_port = self.fp2phy_port_num(x) + port_eeprom_path = eeprom_path.format(phy_port + self.EEPROM_OFFSET, self.EEPROM_I2C_ADDR) + self.port_to_eeprom_mapping[x] = port_eeprom_path + + SfpUtilBase.__init__(self) + + def qsfp_to_cpld_index(self, port_num): + if port_num < self.CPLD1_PORTS: + cpld_id = 0 + cpld_port_index = port_num + 1 + else: + cpld_id = 1 + (port_num - self.CPLD1_PORTS) / self.CPLDx_PORTS + cpld_port_index = ((port_num - self.CPLD1_PORTS) % self.CPLDx_PORTS) + 1 + return cpld_id, cpld_port_index + + def fp2phy_port_num(self, fp_port_num): + + phy_port_num = self._fp2phy_port_mapping[fp_port_num] + return phy_port_num + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # logic port to physical port mapping + port_num = self.fp2phy_port_num(port_num) + + cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) + i2c_id = self.CPLD_OFFSET + cpld_id + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ + self.CPLD_PORT_STATUS_KEY, cpld_port_index) + + try: + reg_file = open(reg_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # content is a string containing the status register value + content = reg_file.readline().rstrip() + reg_file.close() + + reg_value = int(content, 16) + # mask for presence bit (bit 1) + mask = (1 << self.CPLD_PRES_BIT) + + # 0 - presence, 1 - absence + if reg_value & mask == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # logic port to physical port mapping + port_num = self.fp2phy_port_num(port_num) + + cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) + i2c_id = self.CPLD_OFFSET + cpld_id + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ + self.CPLD_PORT_CONFIG_KEY, cpld_port_index) + + try: + reg_file = open(reg_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # content is a string containing the status register value + content = reg_file.readline().rstrip() + reg_file.close() + + reg_value = int(content, 16) + # mask for lp_mod bit (bit 2) + mask = (1 << self.CPLD_LPMOD_BIT) + + # 0 - disable, 1 - low power mode + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # logic port to physical port mapping + port_num = self.fp2phy_port_num(port_num) + + cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) + i2c_id = self.CPLD_OFFSET + cpld_id + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ + self.CPLD_PORT_CONFIG_KEY, cpld_port_index) + + try: + reg_file = open(reg_path, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # content is a string containing the status register value + content = reg_file.readline().rstrip() + reg_value = int(content, 16) + # mask for lp_mod bit (bit 2) + mask = (1 << self.CPLD_LPMOD_BIT) + + # 1 - low power mode, 0 - high power mode + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # convert value to hex string + content = hex(reg_value) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # logic port to physical port mapping + port_num = self.fp2phy_port_num(port_num) + + cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) + i2c_id = self.CPLD_OFFSET + cpld_id + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ + self.CPLD_PORT_CONFIG_KEY, cpld_port_index) + + # reset the port + try: + reg_file = open(reg_path, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # content is a string containing the status register value + content = reg_file.readline().rstrip() + reg_value = int(content, 16) + # mask for reset bit (bit 0) + mask = (1 << self.CPLD_RESET_BIT) + + # 1 - out of reset, 0 - reset + reg_value = reg_value & ~mask + + reg_file.seek(0) + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 1 second to reset done + time.sleep(1) + + # take the port out of reset + try: + reg_file = open(reg_path, "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = reg_value | mask + + reg_file.seek(0) + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/sensors.conf b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/sensors.conf new file mode 100644 index 000000000000..ddc04a5f4ad6 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/sensors.conf @@ -0,0 +1,85 @@ +# libsensors configuration file +chip "i350bb-*" + ignore loc1 + +chip "jc42-*" + +bus "i2c-16" "i2c-mux-1 (chan_id 7)" +chip "w83795adg-*" + ignore in0 + label in1 "VDD_CORE" + set in1_min 0.717 + set in1_max 0.962 + ignore in2 + ignore in3 + label in4 "3.3V" + compute in4 @/(0.3052), (0.3052)*@ + set in4_min 3.3 * 0.95 + set in4_max 3.3 * 1.05 + label in5 "0.9V" + set in5_min 0.90 * 0.98 + set in5_max 0.90 * 1.02 + ignore in6 + ignore in7 + ignore in8 + ignore in9 + ignore in10 + ignore in11 + ignore in12 + ignore in13 + ignore in14 + ignore in15 + ignore in16 + ignore in17 + ignore in18 + ignore in19 + label fan1 "FANTRAY 1" + ignore fan2 + label fan3 "FANTRAY 2" + ignore fan4 + label fan5 "FANTRAY 3" + ignore fan6 + label fan7 "FANTRAY 4" + ignore fan8 + ignore temp1 + ignore temp2 + ignore temp3 + ignore temp4 + ignore temp5 + ignore temp6 + ignore intrusion0 + +chip "tmp75-i2c-*-4A" + label temp1 "BMC Board Temp" + set temp1_max 50 + set temp1_max_hyst 45 + +bus "i2c-0" "SMBus I801 adapter at f000" +chip "tmp75-i2c-*-4F" + label temp1 "x86 CPU Board Temp" + set temp1_max 50 + set temp1_max_hyst 45 + +bus "i2c-6" "i2c-0-mux (chan_id 5)" +chip "lm75-i2c-6-4D" + label temp1 "Rear Panel Temp" + set temp1_max 50 + set temp1_max_hyst 45 +chip "lm75-i2c-6-4E" + label temp1 "Rear MAC Temp" + set temp1_max 50 + set temp1_max_hyst 45 +chip "lm86-i2c-6-4C" + label temp1 "MB Temp" + set temp1_max 50 + label temp2 "MAC Temp" + set temp2_max 70 +bus "i2c-7" "i2c-0-mux (chan_id 6)" +chip "lm75-i2c-7-4D" + label temp1 "Front Panel Temp" + set temp1_max 50 + set temp1_max_hyst 45 +chip "lm75-i2c-7-4E" + label temp1 "Front MAC Temp" + set temp1_max 50 + set temp1_max_hyst 45 diff --git a/platform/barefoot/bfn-platform-ingrasys.mk b/platform/barefoot/bfn-platform-ingrasys.mk index a85d69baab79..7f3ba4746572 100644 --- a/platform/barefoot/bfn-platform-ingrasys.mk +++ b/platform/barefoot/bfn-platform-ingrasys.mk @@ -1,5 +1,5 @@ -BFN_INGRASYS_PLATFORM = bfnplatform-ingrasys_1.0.0_amd64.deb -$(BFN_INGRASYS_PLATFORM)_URL = "https://github.com/Ingrasys-sonic/packages/raw/master/lib/bfnplatform-ingrasys_1.0.0_amd64.deb" +BFN_INGRASYS_PLATFORM = bfnplatform-ingrasys_8.2.0_amd64.deb +$(BFN_INGRASYS_PLATFORM)_URL = "https://github.com/Ingrasys-sonic/packages/raw/master/lib/bfnplatform-ingrasys_8.2.0_amd64.deb" SONIC_ONLINE_DEBS += $(BFN_INGRASYS_PLATFORM) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_INGRASYS_PLATFORM) diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index a7b5d009516d..490712f6818e 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -7,5 +7,6 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9280_64X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/barefoot/platform-modules-ingrasys.mk b/platform/barefoot/platform-modules-ingrasys.mk index 7204adb7e02d..5145dcbc5ffa 100644 --- a/platform/barefoot/platform-modules-ingrasys.mk +++ b/platform/barefoot/platform-modules-ingrasys.mk @@ -1,11 +1,18 @@ # Ingrasys S9180-32X Platform modules INGRASYS_S9180_32X_PLATFORM_MODULE_VERSION = 1.1.0 +INGRASYS_S9280_64X_PLATFORM_MODULE_VERSION = 1.1.0 export INGRASYS_S9180_32X_PLATFORM_MODULE_VERSION +export INGRASYS_S9280_64X_PLATFORM_MODULE_VERSION INGRASYS_S9180_32X_PLATFORM_MODULE = sonic-platform-ingrasys-s9180-32x_$(INGRASYS_S9180_32X_PLATFORM_MODULE_VERSION)_amd64.deb $(INGRASYS_S9180_32X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-ingrasys $(INGRASYS_S9180_32X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(INGRASYS_S9180_32X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9180_32x-r0 SONIC_DPKG_DEBS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) + +INGRASYS_S9280_64X_PLATFORM_MODULE = sonic-platform-ingrasys-s9280-64x_$(INGRASYS_S9280_64X_PLATFORM_MODULE_VERSION)_amd64.deb +$(INGRASYS_S9280_64X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9280_64x-r0 + +$(eval $(call add_extra_package,$(INGRASYS_S9180_32X_PLATFORM_MODULE),$(INGRASYS_S9280_64X_PLATFORM_MODULE))) diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/changelog b/platform/barefoot/sonic-platform-modules-ingrasys/debian/changelog index f5c70c166031..cfbeb17d018a 100644 --- a/platform/barefoot/sonic-platform-modules-ingrasys/debian/changelog +++ b/platform/barefoot/sonic-platform-modules-ingrasys/debian/changelog @@ -1,15 +1,9 @@ platform-driver (1.1.0) unstable; urgency=low - * Add support for s9180-32x + * Add support for s9180-32x s9280-64x -- developer Fri, 26 May 2017 11:00:00 +0800 -platform-driver (1.1.0) unstable; urgency=low - - * Add support for s8900 series - - -- developer Wed, 29 Mar 2017 11:00:00 +0800 - platform-driver (1.0.0) unstable; urgency=low * Initial release (Closes: #nnnn) diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/control b/platform/barefoot/sonic-platform-modules-ingrasys/debian/control index ec2c1f20c0f7..a912ed8ace2e 100644 --- a/platform/barefoot/sonic-platform-modules-ingrasys/debian/control +++ b/platform/barefoot/sonic-platform-modules-ingrasys/debian/control @@ -8,3 +8,7 @@ Standards-Version: 1.0.0 Package: sonic-platform-ingrasys-s9180-32x Architecture: amd64 Description: This package contains S9180-32X platform driver utility for SONiC project. + +Package: sonic-platform-ingrasys-s9280-64x +Architecture: amd64 +Description: This package contains S9280-64X platform driver utility for SONiC project. diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/rules b/platform/barefoot/sonic-platform-modules-ingrasys/debian/rules index 3ac0d3de6049..428b4731eb75 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/debian/rules +++ b/platform/barefoot/sonic-platform-modules-ingrasys/debian/rules @@ -1,13 +1,4 @@ #!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 export INSTALL_MOD_DIR:=extra @@ -15,7 +6,7 @@ PACKAGE_PRE_NAME := sonic-platform-ingrasys KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= s9180-32x +MODULE_DIRS:= s9180-32x s9280-64x MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service @@ -24,58 +15,28 @@ CONF_DIR := conf %: dh $@ --with systemd -clean: - dh_testdir - dh_testroot - dh_clean - -build: - #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) +override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ done) -binary: binary-arch binary-indep - # Nothing to do - -binary-arch: - # Nothing to do - -#install: build - #dh_testdir - #dh_testroot - #dh_clean -k - #dh_installdirs - -binary-indep: - dh_testdir - dh_installdirs +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko \ + debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/sbin; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.sh \ + debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/sbin; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} lib/systemd/system; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service \ + debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \ + done) - # Custom package commands +override_dh_clean: + dh_clean (for mod in $(MODULE_DIRS); do \ - mkdir debian/tmp/usr/sbin -p; \ - mkdir debian/tmp/lib/systemd/system -p; \ - mkdir debian/tmp/etc/init.d -p; \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.sh debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/sbin/; \ - cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/bfn debian/$(PACKAGE_PRE_NAME)-$${mod}/etc/init\.d/; \ - cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ done) - # Resuming debhelper scripts - dh_testroot - dh_install - dh_installchangelogs - dh_installdocs - dh_systemd_enable - dh_installinit - dh_systemd_start - dh_link - dh_fixperms - dh_compress - dh_strip - dh_installdeb - dh_gencontrol - dh_md5sums - dh_builddeb -.PHONY: build binary binary-arch binary-indep clean + diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.dirs b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.dirs deleted file mode 100644 index 401d79eb79b8..000000000000 --- a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.dirs +++ /dev/null @@ -1,4 +0,0 @@ -usr/sbin -lib/systemd/system -etc/ -etc/init.d/ \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.init b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.init new file mode 100644 index 000000000000..9479fa354949 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.init @@ -0,0 +1,41 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup S9180-32X board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + depmod -a + + echo "done." + ;; + +stop) + + i2c_utils.sh i2c_deinit + + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/sonic-platform-ingrasys-s9180-32x.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.install b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.install deleted file mode 100644 index 99bda5d123ae..000000000000 --- a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.install +++ /dev/null @@ -1,4 +0,0 @@ -lib/systemd/ -usr/sbin/ -etc/ -etc/init.d/ diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.postinst b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.postinst deleted file mode 100644 index 38e5cac148c4..000000000000 --- a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.postinst +++ /dev/null @@ -1,57 +0,0 @@ -# Automatically added by dh_systemd_enable -# This will only remove masks created by d-s-h on package removal. -deb-systemd-helper unmask s9180-32x-monitor.service >/dev/null || true -deb-systemd-helper unmask bfn.service >/dev/null || true -deb-systemd-helper unmask qsfp-monitor.service >/dev/null || true -# Generate kernel modules.dep and map files for add eeprom_mb. -depmod -a || true -# was-enabled defaults to true, so new installations run enable. -if deb-systemd-helper --quiet was-enabled s9180-32x-monitor.service; then - # Enables the unit on first installation, creates new - # symlinks on upgrades if the unit file has changed. - deb-systemd-helper enable s9180-32x-monitor.service >/dev/null || true -else - # Update the statefile to add new symlinks (if any), which need to be - # cleaned up on purge. Also remove old symlinks. - deb-systemd-helper update-state s9180-32x-monitor.service >/dev/null || true -fi -if deb-systemd-helper --quiet was-enabled bfn.service; then - # Enables the unit on first installation, creates new - # symlinks on upgrades if the unit file has changed. - deb-systemd-helper enable bfn.service >/dev/null || true -else - # Update the statefile to add new symlinks (if any), which need to be - # cleaned up on purge. Also remove old symlinks. - deb-systemd-helper update-state bfn.service >/dev/null || true -fi -if deb-systemd-helper --quiet was-enabled qsfp-monitor.service; then - # Enables the unit on first installation, creates new - # symlinks on upgrades if the unit file has changed. - deb-systemd-helper enable qsfp-monitor.service >/dev/null || true -else - # Update the statefile to add new symlinks (if any), which need to be - # cleaned up on purge. Also remove old symlinks. - deb-systemd-helper update-state qsfp-monitor.service >/dev/null || true -fi -# End automatically added section -# Automatically added by dh_installinit -if [ -x "/etc/init.d/s9180-32x-monitor" ]; then - update-rc.d s9180-32x-monitor defaults >/dev/null - invoke-rc.d s9180-32x-monitor start || exit $? -fi -if [ -x "/etc/init.d/qsfp-monitor" ]; then - update-rc.d qsfp-monitor defaults >/dev/null - invoke-rc.d qsfp-monitor start || exit $? -fi -if [ -x "/etc/init.d/bfn" ]; then - invoke-rc.d bfn start || exit $? -fi -# End automatically added section -# Automatically added by dh_systemd_start -if [ -d /run/systemd/system ]; then - systemctl --system daemon-reload >/dev/null || true - deb-systemd-invoke start s9180-32x-monitor.service >/dev/null || true - deb-systemd-invoke start qsfp-monitor.service >/dev/null || true - deb-systemd-invoke start bfn.service >/dev/null || true -fi -# End automatically added section diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.postrm b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.postrm deleted file mode 100644 index 19c6bcb2945f..000000000000 --- a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.postrm +++ /dev/null @@ -1,42 +0,0 @@ -# Automatically added by dh_systemd_start -if [ -d /run/systemd/system ]; then - systemctl --system daemon-reload >/dev/null || true - fi -# End automatically added section -# Automatically added by dh_installinit -if [ "$1" = "purge" ] ; then - update-rc.d s9180-32x-monitor remove >/dev/null - update-rc.d bfn remove >/dev/null - update-rc.d qsfp-monitor remove >/dev/null -fi - - -# In case this system is running systemd, we make systemd reload the unit files -# to pick up changes. -if [ -d /run/systemd/system ] ; then - systemctl --system daemon-reload >/dev/null || true -fi -# End automatically added section -# Automatically added by dh_systemd_enable -if [ "$1" = "remove" ]; then - if [ -x "/usr/bin/deb-systemd-helper" ]; then - deb-systemd-helper mask s9180-32x-monitor.service >/dev/null - deb-systemd-helper mask bfn.service >/dev/null - deb-systemd-helper mask qsfp-monitor.service >/dev/null - fi -fi - -if [ "$1" = "purge" ]; then - if [ -x "/usr/bin/deb-systemd-helper" ]; then - deb-systemd-helper purge s9180-32x-monitor.service >/dev/null - deb-systemd-helper unmask s9180-32x-monitor.service >/dev/null - deb-systemd-helper purge bfn.service >/dev/null - deb-systemd-helper unmask bfn.service >/dev/null - deb-systemd-helper purge qsfp-monitor.service >/dev/null - deb-systemd-helper unmask qsfp-monitor.service >/dev/null - fi -fi -# Generate kernel modules.dep and map files for remove eeprom_mb. -depmod -a || true -# End automatically added section - diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.prerm b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.prerm deleted file mode 100644 index 76533bfe6889..000000000000 --- a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.prerm +++ /dev/null @@ -1,21 +0,0 @@ -# Automatically added by dh_systemd_start -if [ -d /run/systemd/system ]; then - deb-systemd-invoke stop s9180-32x-monitor.service >/dev/null - deb-systemd-invoke stop bfn.service >/dev/null - deb-systemd-invoke stop qsfp-monitor.service >/dev/null -fi -# End automatically added section -# Automatically added by dh_installinit -if [ -x "/etc/init.d/s9180-32x-monitor" ]; then - invoke-rc.d s9180-32x-monitor stop || exit $? -fi -if [ -x "/etc/init.d/bfn" ]; then - invoke-rc.d bfn stop || exit $? -fi -if [ -x "/etc/init.d/qsfp-monitor" ]; then - invoke-rc.d qsfp-monitor stop || exit $? -fi -# Driver deinit -/usr/sbin/i2c_utils.sh i2c_deinit -# End automatically added section - diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.upstart b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.upstart deleted file mode 100644 index 2c8d2ebec6d7..000000000000 --- a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9180-32x.upstart +++ /dev/null @@ -1,7 +0,0 @@ -description "SONiC platform service" - -respawn - -exec /usr/sbin/s9180_32x_monitor.sh -exec /usr/sbin/qsfp_monitor.sh -exec /etc/init.d/bfn start diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9280-64x.init b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9280-64x.init new file mode 100644 index 000000000000..545ec8e9987a --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9280-64x.init @@ -0,0 +1,41 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup S9280-64X board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + depmod -a + + echo "done." + ;; + +stop) + + i2c_utils i2c_deinit + + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/sonic-platform-ingrasys-s9280-64x.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/modules/Makefile b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/modules/Makefile index 3edb8690475e..df7bfd3e770e 100644 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/modules/Makefile +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/modules/Makefile @@ -1 +1,3 @@ obj-m := eeprom_mb.o +obj-m+= cpld_wdt.o + diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/modules/cpld_wdt.c b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/modules/cpld_wdt.c new file mode 100644 index 000000000000..4cf70b4b80ab --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/modules/cpld_wdt.c @@ -0,0 +1,296 @@ +/* + * CPLD Watchdog Driver + * + * Copyright (c) 2018 Ingrasys Corp. + * + * Author: Wade He + * + * This program 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, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* + * Includes, defines, variables, module parameters, ... + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +/* Module and version information */ +#define DRV_NAME "cpld_wdt" +#define DRV_VERSION "1.0" + +/* Includes */ +#include /* For module specific items */ +#include /* For new moduleparam's */ +#include /* For standard types (like size_t) */ +#include /* For the -ENODEV/... values */ +#include /* For printk/panic/... */ +#include /* For the watchdog specific items */ +#include /* For __init/__exit/... */ +#include /* For file operations */ +#include /* For platform_driver framework */ +#include /* For pci functions */ +#include /* For io-port access */ +#include /* For spin_lock/spin_unlock/... */ +#include /* For copy_to_user/put_user/... */ +#include /* For inb/outb/... */ +#include +#include +#include +#include + + +/* Address definitions for the CPLD */ +/* CPLD base address */ +#define TCOBASE 0x600 +/* SMI Control and Enable Register */ + +#define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */ +#define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */ +#define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */ +#define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */ +#define TCO1_STS (TCOBASE + 0x04) /* Control Watchdog Register */ +#define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */ +#define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */ +#define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */ +#define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */ + +#define DEBUG +#ifdef DEBUG + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s[%d]: " fmt "\r\n", \ + __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define ERROR_MSG(fmt, args...) \ + printk(KERN_ERR "%s[%d]: " fmt "\r\n", \ + __FUNCTION__, __LINE__, ##args) + + + +/* internal variables */ +static struct { /* this is private data for the cpld_wdt device */ + /* the lock for io operations */ + spinlock_t io_lock; + struct platform_device *dev; +} cpld_wdt_private; + +static struct task_struct *cpld_wdt_tsk; +static int data; + +static void device_release(struct device *dev) +{ + return; +} + +static struct platform_device cpld_wdt = { + .name = DRV_NAME, + .id = 0, + .dev = { + .platform_data = NULL, + .release = device_release + }, +}; + +/* module parameters */ +#define WATCHDOG_TIMEOUT 15 /* 15 sec default heartbeat */ +static int heartbeat = WATCHDOG_TIMEOUT; /* in seconds */ +module_param(heartbeat, int, 0); +MODULE_PARM_DESC(heartbeat, "Watchdog ping period in seconds. " + "5..20, default=" + __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, + "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + + +static int cpld_wdt_check_timeout_range(unsigned int tmrval) +{ + if (tmrval < 5 || tmrval > 20) { + DEBUG_PRINT("heartbeat out of range, using default=%d\n", WATCHDOG_TIMEOUT); + heartbeat = WATCHDOG_TIMEOUT; + } else { + DEBUG_PRINT("heartbeat using %d seconds\n", heartbeat); + } + + return 0; +} + +/* + * Some TCO specific functions + */ + +static int cpld_wdt_stop(void *arg) +{ + + spin_lock(&cpld_wdt_private.io_lock); + + outb(0x1, TCO1_STS); + + DEBUG_PRINT("cpld_wdt_stop done"); + + spin_unlock(&cpld_wdt_private.io_lock); + + return 0; +} + +static int cpld_wdt_ping(void *arg) +{ + spin_lock(&cpld_wdt_private.io_lock); + + /* Reload the timer by writing to the TCO Timer Counter register */ + outb(0x1, TCO1_STS); /* write 1 to clear bit */ + udelay(100); + outb(0x3, TCO1_STS); + + DEBUG_PRINT("cpld_wdt_ping done"); + + spin_unlock(&cpld_wdt_private.io_lock); + return 0; +} + +static int kthread_wdt_ping_loop(void *arg) +{ + int i; + + set_current_state(TASK_INTERRUPTIBLE); + + while(!kthread_should_stop()) { + DEBUG_PRINT("ping start"); + cpld_wdt_ping(NULL); + set_current_state(TASK_INTERRUPTIBLE); + for (i=0;i"); +MODULE_DESCRIPTION("CPLD Watchdog Timer Kernel Driver"); +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/service/bfn.service b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/service/bfn.service deleted file mode 100644 index 6c8c2fb71517..000000000000 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/service/bfn.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Barefoot Kernel Module -After=local-fs.target -Before=docker.service - -[Service] -Type=oneshot -ExecStart=-/etc/init.d/bfn start -ExecStop=-/etc/init.d/bfn stop -RemainAfterExit=yes - -[Install] -WantedBy=multi-user.target diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/bfn b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/bfn deleted file mode 100755 index c52b1fab4ea1..000000000000 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/bfn +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# This script load/unload Barefoot kernel modules - -### BEGIN INIT INFO -# Provides: -# Required-Start: -# Required-Stop: -# Should-Start: -# Should-Stop: -# Default-Start: S -# Default-Stop: 0 6 -# Short-Description: Load Barefoot kernel modules -### END INIT INFO - -case "$1" in -start) - echo -n "Load Barefoot kernel modules... " - - modprobe bf_kdrv - modprobe bf_tun - - echo "done." - ;; - -stop) - echo -n "Unload Barefoot kernel modules... " - - rmmod bf_tun - rmmod bf_kdrv - - echo "done." - ;; - -force-reload|restart) - echo "Not supported" - ;; - -*) - echo "Usage: /etc/init.d/bfn {start|stop}" - exit 1 - ;; -esac - -exit 0 diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/i2c_utils.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/i2c_utils.sh index e765ed1da6a9..969ba09f84cb 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/i2c_utils.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/i2c_utils.sh @@ -72,6 +72,7 @@ NUM_FRU_MUX_CHAN2_DEVICE=$(( ${NUM_FRU_MUX_CHAN0_DEVICE} + 2 )) # FAN NUM_CPLD_DEVICE=$(( ${NUM_MUX7_CHAN0_DEVICE} + 3 )) # CPLD NUM_SFP1_DEVICE=$(( ${NUM_MUX7_CHAN0_DEVICE} + 4 )) # CPLD NUM_SFP2_DEVICE=$(( ${NUM_MUX7_CHAN0_DEVICE} + 5 )) # CPLD +NUM_ROV_DEVICE=${NUM_MAIN_MUX_CHAN6_DEVICE} PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon" @@ -89,12 +90,20 @@ PATH_MUX_CHAN7_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN7_DEVICE}" PATH_MUX7_CHAN0_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX7_CHAN0_DEVICE}" PATH_MAIN_MUX_CHAN0_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MAIN_MUX_CHAN0_DEVICE}" +# i2c address for deviecs +CPLD_I2C_ADDR=0x33 +ROV_I2C_ADDR=0x22 + #Power Supply Status PSU_DC_ON=1 PSU_DC_OFF=0 PSU_EXIST=1 PSU_NOT_EXIST=0 +# vdd value for mac +rov_val_array=( 0.85 0.82 0.77 0.87 0.74 0.84 0.79 0.89 ) +rov_reg_array=( 0x24 0x21 0x1c 0x26 0x19 0x23 0x1e 0x28 ) + # Help usage function function _help { echo "=========================================================" @@ -159,6 +168,7 @@ function _i2c_init { modprobe i2c_i801 modprobe i2c_dev modprobe i2c_mux_pca954x force_deselect_on_exit=1 + #modprobe cpld_wdt if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN0_DEVICE}" ]; then _retry "echo 'pca9548 0x70' > ${PATH_I801_DEVICE}/new_device" @@ -227,9 +237,35 @@ function _i2c_init { _i2c_led_fan_status_set _i2c_led_fan_tray_status_set + # rov for mac init + _mac_vdd_init + #SYS LED set green COLOR_SYS_LED="green" _i2c_sys_led + +} + +function _mac_vdd_init { + # read mac vid register value from CPLD + val=`i2cget -y ${NUM_CPLD_DEVICE} ${CPLD_I2C_ADDR} 0x42 2>/dev/null` + + # get vid form register value [0:2] + vid=$(($val & 0x7)) + + # get rov val and reg according to vid + rov_val=${rov_val_array[$vid]} + rov_reg=${rov_reg_array[$vid]} + echo "vid=${vid}, rov_val=${rov_val}, rov_reg=${rov_reg}" + + # write the rov reg to rov + i2cset -y -r ${NUM_ROV_DEVICE} ${ROV_I2C_ADDR} 0x21 ${rov_reg} w + + if [ $? -eq 0 ]; then + echo "set ROV for mac vdd done" + else + echo "set ROV for mac vdd fail" + fi } #I2C Deinit @@ -290,7 +326,7 @@ function _i2c_io_exp_init { i2cset -y -r ${NUM_I801_DEVICE} 0x26 5 0x00 i2cset -y -r ${NUM_I801_DEVICE} 0x26 2 0x3F i2cset -y -r ${NUM_I801_DEVICE} 0x26 3 0x1F - i2cset -y -r ${NUM_I801_DEVICE} 0x26 6 0xC0 + i2cset -y -r ${NUM_I801_DEVICE} 0x26 6 0xD0 i2cset -y -r ${NUM_I801_DEVICE} 0x26 7 0x00 #CPU Baord @@ -914,7 +950,7 @@ function _i2c_qsfp_eeprom_init { if [ "${action}" == "new" ] && \ ! [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then - echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/new_device + echo "optoe1 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/new_device elif [ "${action}" == "delete" ] && \ [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/delete_device @@ -1006,7 +1042,7 @@ function _i2c_sfp_eeprom_init { return fi - #Init 1-32 ports EEPROM + #Init 33-34 ports EEPROM if [ "${action}" == "new" ] && \ ! [ -L ${PATH_SYS_I2C_DEVICES}/${NUM_SFP1_DEVICE}-0050 ] && \ ! [ -L ${PATH_SYS_I2C_DEVICES}/${NUM_SFP2_DEVICE}-0050 ]; then diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/s9180_32x_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/s9180_32x_monitor.sh index c110bdeaaf04..eedf685b290b 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/s9180_32x_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/s9180_32x_monitor.sh @@ -21,6 +21,7 @@ I2C_UTILS="/usr/sbin/i2c_utils.sh" # TBD: LED status monitor function _led_monitor { ${I2C_UTILS} i2c_led_fan_status_set >/dev/null + ${I2C_UTILS} i2c_led_psu_status_set >/dev/null ${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null } @@ -38,4 +39,4 @@ function _main { done } -_main \ No newline at end of file +_main diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/README.md b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/README.md new file mode 100644 index 000000000000..7411603ba608 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/README.md @@ -0,0 +1,175 @@ +# Ingrasys S9280-64X Platform Driver for SONiC + +Copyright (C) 2016 Ingrasys, Inc. + +This program 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, either version 3 of the License, or +(at your option) any later version. + +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. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + + +## Licensing terms + +The Licensing terms of the files within this project is split 2 parts. +The Linux kernel is released under the GNU General Public License version 2. +All other code is released under the GNU General Public License version 3. +Please see the LICENSE file for copies of both licenses. + +## Contents of this package + + - service/ + > Service config files for platform initialization and monitoring + - utils/ + > Scripts useful during platform bringup and sysfs function + - conf/ + > Platform configure files. + +## Kernel modules and drivers + +The driver for interacting with Ingrasys S9280-64X is contained in the I2C +kernel module and initialization script. The initialization script loads +the modules in the correct order. It has been built and tested against +the Linux 3.16 kernel. + +The initialization script will modprobe the needed modules, navigate to the +module's device directory in sysfs, and write configuration data to +the kernel module. + +### IGB + +This is OOB Ports on front panel for management plane. + +The IGB module must be loaded first on Ingrasys S9280-64X platform. + +### I2C i801 + +The I2C i801 on Ingrasys S9280-64X can be found in +`/sys/bus/i2c/devices/i2c-0/` + +This is I2C bus for Clock Gen, DIMM channel and digital potentiometers. + +The i801 module must be loaded second on Ingrasys S9280-64X. + +### I2C PCA9548 +The PCA9548 module on S9280-64X can be found in +`/sys/bus/i2c/devices/i2c-0/` , `/sys/bus/i2c/devices/i2c-17/`, +`/sys/bus/i2c/devices/i2c-18/` , `/sys/bus/i2c/devices/i2c-19/`, +`/sys/bus/i2c/devices/i2c-20/`, `/sys/bus/i2c/devices/i2c-21/`, +`/sys/bus/i2c/devices/i2c-22/`, `/sys/bus/i2c/devices/i2c-23/`, +`/sys/bus/i2c/devices/i2c-24/`. + +The pca9548 module for zQSFP module get/set functions, PSU information, +fan status and EEPROM. + +## Hardware components + +The hardware components are initialized in the init script on S9280-64X. +The following describes manual initialization as well as interaction. +The examples below are just for Ingrasys S9280-64X platform. + +### Hardware initialization + +When the sonic-platform-ingrasys-s9280 package is installed on the S9280-64X, +it is automatically initialized. If you want to manual initialization, the +utility command usage as follows: +``` + i2c_utils.sh i2c_init +``` + +### EEPROM + +The EEPROM is including the board SKU, model name, vendor name, serial number, +and other information can be accessed with the specific eeprom kernel module. +After using `modprobe eeprom_mb` to detect the eeprom, it will show up in sysfs. + +The hexdump utility can be used to decode the raw output of the EEPROM. +For example, +``` + bash# echo "mb_eeprom 0x55" > /sys/bus/i2c/devices/i2c-0/new_device + bash# cat /sys/bus/i2c/drivers/mb_eeprom/0-0055/eeprom | hexdump -C +``` + +### Front panel LEDs + +LEDs can be setup on/off by using i2c utility `/usr/sbin/i2c_utils.sh`. +Utility function command usage as follows: + +``` +Status LED: + i2c_utils.sh i2c_sys_led green|amber on|off + +Fan status LED: + i2c_utils.sh i2c_fan_led green|amber on|off + +PSU1 status LED: + i2c_utils.sh i2c_psu1_led green|amber on|off + +PSU2 status LED: + i2c_utils.sh i2c_psu2_led green|amber on|off + +``` +QSFP Module Port LEDs control by ASIC library. + + +### Fan speed + +Fan speed are controlled by the w83795 kernel module. +It can be found in `/sys/class/hwmon/hwmon2/device/`. +If they were compiled as modules, you will need to modprobe w83795 for +their sysfs entries to show up. Each fan has an `fan_input` file +for reading the fan speed. And `pwm1` setting fan1 to fan4, +`pwm2` setting fan5 to fan8. + +There is docker-platform-monitor container installed fancontrol package that can +automatic control platform fan speed. + + +### Temperature sensors + +Temperature sensors are controlled by the w83795 kernel +module. It can be found in `/sys/class/hwmon/hwmon3/device/`. +If they were compiled as modules, then you will need to modprobe w83795 for +their sysfs entries to show up. +`temp1_input` is front MAC temperature sensor. `temp2_input` is rear MAC +temperature sensor. + +There is docker-platform-monitor container installed lm-sensors package that can +monitor platform temperature. And `sensors` command can show each +temperature sensors status. + +### Power supplies + +Power supplies status and its EEPROM info can be used i2c utility +`/usr/sbin/i2c_utils.sh` to get. +The usage as follows: +``` +PSU EEPROM: + i2c_utils.sh i2c_psu_eeprom_get + +PSU Status: + i2c_utils.sh i2c_psu_status +``` + +### QSFPs +QSFP modules are managed by the pca9548 kernel driver. +The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and +module EEPROM informations. +The usage as follows: +``` +QSFP EEPROM: + i2c_utils.sh i2c_qsfp_eeprom_get [1-64] + +QSFP Insert Event: + i2c_utils.sh i2c_qsfp_status_get [1-64] + 0 => not insert + 1 => inserted +``` + diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/Makefile b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/Makefile new file mode 100644 index 000000000000..af1a5abe1d12 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/Makefile @@ -0,0 +1,3 @@ +obj-m := eeprom_mb.o +obj-m += ingrasys_s9280_64x_i2c_cpld.o +obj-m += ingrasys_s9280_64x_psu.o diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/eeprom_mb.c b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/eeprom_mb.c new file mode 100644 index 000000000000..528864d93382 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/eeprom_mb.c @@ -0,0 +1,267 @@ +/* + * Copyright (C) 1998, 1999 Frodo Looijaard and + * Philip Edelbrock + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Jean Delvare + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +/* enable dev_dbg print out */ +//#define DEBUG + +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { /*0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57,*/ I2C_CLIENT_END }; + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 512 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void mb_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, (u8)((addr >> 8) & 0xFF), (u8)(addr & 0xFF)); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t mb_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + mb_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static ssize_t mb_eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + int ret; + int i; + u8 cmd; + u16 value16; + + dev_dbg(&client->dev, "mb_eeprom_write off=%d, count=%d\n", (int)off, (int)count); + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + mutex_lock(&data->update_lock); + + for(i=0; i < count; i++) { + /* write command */ + cmd = (off >> 8) & 0xff; + value16 = off & 0xff; + value16 |= buf[i] << 8; + ret = i2c_smbus_write_word_data(client, cmd, value16); + + if (ret < 0) { + dev_err(&client->dev, "write address failed at %d \n", (int)off); + goto exit; + } + + off++; + + /* need to wait for write complete */ + udelay(10000); + } +exit: + mutex_unlock(&data->update_lock); + /* force to update client when reading */ + for(i=0; i < SLICE_NUM; i++) { + data->last_updated[i] = 0; + } + + return count; +} + +static struct bin_attribute mb_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUSR, + }, + .size = EEPROM_SIZE, + .read = mb_eeprom_read, + .write = mb_eeprom_write, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int mb_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x51 and 0x55. So decline + attaching to addresses >= 0x56 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x56) { + return -ENODEV; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + return -ENODEV; + } + + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int mb_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &mb_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int mb_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &mb_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id mb_eeprom_id[] = { + { "mb_eeprom", 0 }, + { } +}; + +static struct i2c_driver mb_eeprom_driver = { + .driver = { + .name = "mb_eeprom", + }, + .probe = mb_eeprom_probe, + .remove = mb_eeprom_remove, + .id_table = mb_eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = mb_eeprom_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(mb_eeprom_driver); + +MODULE_AUTHOR("Wade "); +MODULE_DESCRIPTION("Ingrasys Mother Borad EEPROM driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_i2c_cpld.c b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_i2c_cpld.c new file mode 100644 index 000000000000..912060cc93e5 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_i2c_cpld.c @@ -0,0 +1,1618 @@ +/* + * A i2c cpld driver for the ingrasys_s9280_64x + * + * Copyright (C) 2017 Ingrasys Technology Corporation. + * Leo Lin + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ingrasys_s9280_64x_i2c_cpld.h" + +#ifdef DEBUG +#define DEBUG_PRINT(fmt, args...) \ + printk(KERN_INFO "%s:%s[%d]: " fmt "\r\n", \ + __FILE__, __func__, __LINE__, ##args) +#else +#define DEBUG_PRINT(fmt, args...) +#endif + +#define I2C_READ_BYTE_DATA(ret, lock, i2c_client, reg) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_read_byte_data(i2c_client, reg); \ + mutex_unlock(lock); \ +} +#define I2C_WRITE_BYTE_DATA(ret, lock, i2c_client, reg, val) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_write_byte_data(i2c_client, reg, val); \ + mutex_unlock(lock); \ +} + +/* CPLD sysfs attributes index */ +enum s9280_64x_cpld_sysfs_attributes { + CPLD_ACCESS_REG, + CPLD_REGISTER_VAL, + CPLD_PORT_START, + CPLD_PORTS, + CPLD_VERSION, + CPLD_ID, + CPLD_BOARD_TYPE, + CPLD_EXT_BOARD_TYPE, + CPLD_QSFP_PORT_STATUS_1, + CPLD_QSFP_PORT_STATUS_2, + CPLD_QSFP_PORT_STATUS_3, + CPLD_QSFP_PORT_STATUS_4, + CPLD_QSFP_PORT_STATUS_5, + CPLD_QSFP_PORT_STATUS_6, + CPLD_QSFP_PORT_STATUS_7, + CPLD_QSFP_PORT_STATUS_8, + CPLD_QSFP_PORT_STATUS_9, + CPLD_QSFP_PORT_STATUS_10, + CPLD_QSFP_PORT_STATUS_11, + CPLD_QSFP_PORT_STATUS_12, + CPLD_QSFP_PORT_STATUS_13, + CPLD_QSFP_PORT_CONFIG_1, + CPLD_QSFP_PORT_CONFIG_2, + CPLD_QSFP_PORT_CONFIG_3, + CPLD_QSFP_PORT_CONFIG_4, + CPLD_QSFP_PORT_CONFIG_5, + CPLD_QSFP_PORT_CONFIG_6, + CPLD_QSFP_PORT_CONFIG_7, + CPLD_QSFP_PORT_CONFIG_8, + CPLD_QSFP_PORT_CONFIG_9, + CPLD_QSFP_PORT_CONFIG_10, + CPLD_QSFP_PORT_CONFIG_11, + CPLD_QSFP_PORT_CONFIG_12, + CPLD_QSFP_PORT_CONFIG_13, + CPLD_QSFP_PORT_INTERRUPT, + CPLD_SFP_PORT_STATUS, + CPLD_SFP_PORT_CONFIG, + CPLD_10GMUX_CONFIG, + CPLD_BMC_STATUS, + CPLD_BMC_WATCHDOG, + CPLD_USB_STATUS, + CPLD_RESET_CONTROL, + CPLD_SFP_LED, + CPLD_SFP_LED_BLINK, + CPLD_QSFP_LED_1, + CPLD_QSFP_LED_2, + CPLD_QSFP_LED_3, + CPLD_QSFP_LED_4, + CPLD_QSFP_LED_5, + CPLD_QSFP_LED_6, + CPLD_QSFP_LED_7, + CPLD_QSFP_LED_8, + CPLD_QSFP_LED_9, + CPLD_QSFP_LED_10, + CPLD_QSFP_LED_11, + CPLD_QSFP_LED_12, + CPLD_QSFP_LED_13, + CPLD_QSFP_LED_14, + CPLD_QSFP_LED_15, + CPLD_QSFP_LED_16, + CPLD_QSFP_LED_BLINK, + CPLD_RTMR_RESET, + CPLD_ROV_STATUS, + +}; + +/* CPLD sysfs attributes hook functions */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t get_qsfp_port_start(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t get_qsfp_ports(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_cpld_id(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_qsfp_port_status(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_qsfp_port_config(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_qsfp_port_config(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_qsfp_port_interrupt(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_sfp_port_status(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_sfp_port_config(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_sfp_port_config(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_10gmux_config(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_10gmux_config(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_bmc_status(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_bmc_watchdog(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_bmc_watchdog(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_usb_status(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_reset_control(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_reset_control(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_sfp_led(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_sfp_led(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_sfp_led_blink(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_sfp_led_blink(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_qsfp_led(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_qsfp_led(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_qsfp_led_blink(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_qsfp_led_blink(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_rtmr_reset(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_rtmr_reset(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_rov_status(struct device *dev, + struct device_attribute *da, char *buf); + +static LIST_HEAD(cpld_client_list); /* client list for cpld */ +static struct mutex list_lock; /* mutex for client list */ + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +struct cpld_data { + int index; /* CPLD index */ + struct mutex access_lock; /* mutex for cpld access */ + u8 access_reg; /* register to access */ +}; + +/* CPLD device id and data */ +static const struct i2c_device_id ingrasys_i2c_cpld_id[] = { + { "ingrasys_cpld1", cpld1 }, + { "ingrasys_cpld2", cpld2 }, + { "ingrasys_cpld3", cpld3 }, + { "ingrasys_cpld4", cpld4 }, + { "ingrasys_cpld5", cpld5 }, + {} +}; + +/* Addresses scanned for ingrasys_i2c_cpld */ +static const unsigned short cpld_i2c_addr[] = { 0x33, I2C_CLIENT_END }; + +/* define all support register access of cpld in attribute */ +static SENSOR_DEVICE_ATTR(cpld_access_register, S_IWUSR | S_IRUGO, + read_access_register, write_access_register, CPLD_ACCESS_REG); +static SENSOR_DEVICE_ATTR(cpld_register_value, S_IWUSR | S_IRUGO, + read_register_value, write_register_value, CPLD_REGISTER_VAL); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_start, S_IRUGO, + get_qsfp_port_start, NULL, CPLD_PORT_START); +static SENSOR_DEVICE_ATTR(cpld_qsfp_ports, S_IRUGO, + get_qsfp_ports, NULL, CPLD_PORTS); +static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, + read_cpld_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(cpld_id, S_IRUGO, read_cpld_id, NULL, CPLD_ID); +static SENSOR_DEVICE_ATTR(cpld_board_type, S_IRUGO, + read_board_type, NULL, CPLD_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_ext_board_type, S_IRUGO, + read_ext_board_type, NULL, CPLD_EXT_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_1, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_1); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_2, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_2); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_3, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_3); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_4, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_4); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_5, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_5); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_6, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_6); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_7, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_7); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_8, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_8); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_9, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_9); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_10, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_10); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_11, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_11); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_12, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_12); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_13, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_13); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_1, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_1); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_2, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_2); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_3, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_3); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_4, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_4); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_5, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_5); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_6, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_6); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_7, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_7); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_8, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_8); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_9, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_9); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_10, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_10); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_11, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_11); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_12, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_12); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_13, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_13); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_interrupt, S_IRUGO, + read_qsfp_port_interrupt, NULL, CPLD_QSFP_PORT_INTERRUPT); +static SENSOR_DEVICE_ATTR(cpld_sfp_port_status, S_IRUGO, + read_sfp_port_status, NULL, CPLD_SFP_PORT_STATUS); +static SENSOR_DEVICE_ATTR(cpld_sfp_port_config, S_IWUSR | S_IRUGO, + read_sfp_port_config, write_sfp_port_config, CPLD_SFP_PORT_CONFIG); +static SENSOR_DEVICE_ATTR(cpld_10gmux_config, S_IWUSR | S_IRUGO, + read_10gmux_config, write_10gmux_config, + CPLD_10GMUX_CONFIG); +static SENSOR_DEVICE_ATTR(cpld_bmc_status, S_IRUGO, + read_bmc_status, NULL, CPLD_BMC_STATUS); +static SENSOR_DEVICE_ATTR(cpld_bmc_watchdog, S_IWUSR | S_IRUGO, + read_bmc_watchdog, write_bmc_watchdog, + CPLD_BMC_WATCHDOG); +static SENSOR_DEVICE_ATTR(cpld_usb_status, S_IRUGO, + read_usb_status, NULL, CPLD_USB_STATUS); +static SENSOR_DEVICE_ATTR(cpld_reset_control, S_IWUSR | S_IRUGO, + read_reset_control, write_reset_control, + CPLD_BMC_WATCHDOG); +static SENSOR_DEVICE_ATTR(cpld_sfp_led, S_IWUSR | S_IRUGO, + read_sfp_led, write_sfp_led, CPLD_SFP_LED); +static SENSOR_DEVICE_ATTR(cpld_sfp_led_blink, S_IWUSR | S_IRUGO, + read_sfp_led_blink, write_sfp_led_blink, CPLD_SFP_LED_BLINK); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_1, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_1); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_2, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_2); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_3, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_3); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_4, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_4); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_5, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_5); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_6, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_6); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_7, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_7); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_8, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_8); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_9, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_9); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_10, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_10); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_11, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_11); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_12, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_12); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_13, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_13); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_14, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_14); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_15, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_15); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_16, S_IWUSR | S_IRUGO, + read_qsfp_led, write_qsfp_led, CPLD_QSFP_LED_16); +static SENSOR_DEVICE_ATTR(cpld_qsfp_led_blink, S_IWUSR | S_IRUGO, + read_qsfp_led_blink, write_qsfp_led_blink, CPLD_QSFP_LED_BLINK); +static SENSOR_DEVICE_ATTR(cpld_rtmr_reset, S_IWUSR | S_IRUGO, + read_rtmr_reset, write_rtmr_reset, CPLD_RTMR_RESET); +static SENSOR_DEVICE_ATTR(cpld_rov_status, S_IRUGO, + read_rov_status, NULL, CPLD_ROV_STATUS); + +/* define support attributes of cpldx , total 5 */ +/* cpld 1 */ +static struct attribute *s9280_64x_cpld1_attributes[] = { + &sensor_dev_attr_cpld_access_register.dev_attr.attr, + &sensor_dev_attr_cpld_register_value.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_start.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_ports.dev_attr.attr, + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_cpld_id.dev_attr.attr, + &sensor_dev_attr_cpld_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_ext_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_interrupt.dev_attr.attr, + &sensor_dev_attr_cpld_sfp_port_status.dev_attr.attr, + &sensor_dev_attr_cpld_sfp_port_config.dev_attr.attr, + &sensor_dev_attr_cpld_10gmux_config.dev_attr.attr, + &sensor_dev_attr_cpld_bmc_status.dev_attr.attr, + &sensor_dev_attr_cpld_bmc_watchdog.dev_attr.attr, + &sensor_dev_attr_cpld_usb_status.dev_attr.attr, + &sensor_dev_attr_cpld_reset_control.dev_attr.attr, + &sensor_dev_attr_cpld_sfp_led.dev_attr.attr, + &sensor_dev_attr_cpld_sfp_led_blink.dev_attr.attr, + &sensor_dev_attr_cpld_rtmr_reset.dev_attr.attr, + &sensor_dev_attr_cpld_rov_status.dev_attr.attr, + NULL +}; + +/* cpld 2 / cpld 3 / cpld 4 / cpld 5 */ +static struct attribute *s9280_64x_cpld2345_attributes[] = { +&sensor_dev_attr_cpld_access_register.dev_attr.attr, + &sensor_dev_attr_cpld_register_value.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_start.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_ports.dev_attr.attr, + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_cpld_id.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_13.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_13.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_interrupt.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_13.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_14.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_15.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_16.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_led_blink.dev_attr.attr, + NULL +}; + +/* cpld 1 attributes group */ +static const struct attribute_group s9280_64x_cpld1_group = { + .attrs = s9280_64x_cpld1_attributes, +}; +/* cpld 2/3/4/5 attributes group */ +static const struct attribute_group s9280_64x_cpld2345_group = { + .attrs = s9280_64x_cpld2345_attributes, +}; + +/* read access register from cpld data */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + + return sprintf(buf, "0x%x\n", reg); +} + +/* write access register to cpld data */ +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + + if (kstrtou8(buf, 0, ®) < 0) + return -EINVAL; + + data->access_reg = reg; + return count; +} + +/* read the value of access register in cpld data */ +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + int reg_val; + + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + + if (reg_val < 0) + return -1; + + return sprintf(buf, "0x%x\n", reg_val); +} + +/* wrtie the value to access register in cpld data */ +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + int ret = -EIO; + u8 reg = data->access_reg; + u8 reg_val; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, client, reg, reg_val); + + return count; +} + +/* get qsfp port start number of the cpld device */ +/* the start number use to tranlate qsfp port to cpld port */ +/* the cpld port use to access the qsfp port register in cpld */ +static ssize_t get_qsfp_port_start(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + int port_base_num; + + if (attr->index == CPLD_PORT_START) { + if (data->index == cpld1) { + port_base_num = 1; + } else { + port_base_num = CPLD_1_PORT_NUM + + CPLD_2_PORT_NUM*(data->index - 1) + 1; + } + return sprintf(buf, "%d\n", port_base_num); + } + return -1; +} + +/* get total qsfp port which contain register in the cpld device */ +static ssize_t get_qsfp_ports(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + int ports; + + if (attr->index == CPLD_PORTS) { + if (data->index == cpld1) + ports = CPLD_1_PORT_NUM; + else + ports = CPLD_2_PORT_NUM; + return sprintf(buf, "%d\n", ports); + } + return -1; +} + +/* get cpdl version register value */ +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_VERSION) { + reg = CPLD_VERSION_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get cpdl id register value */ +static ssize_t read_cpld_id(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_ID) { + reg = CPLD_ID_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get board type register value */ +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_BOARD_TYPE) { + reg = CPLD_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_EXT_BOARD_TYPE) { + reg = CPLD_EXT_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get qsfp port status register value */ +static ssize_t read_qsfp_port_status(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index >= CPLD_QSFP_PORT_STATUS_1 && + attr->index <= CPLD_QSFP_PORT_STATUS_13) { + reg = CPLD_QSFP_PORT_STATUS_BASE_REG + + (attr->index - CPLD_QSFP_PORT_STATUS_1); + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get qsfp port config register value */ +static ssize_t read_qsfp_port_config(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index >= CPLD_QSFP_PORT_CONFIG_1 && + attr->index <= CPLD_QSFP_PORT_CONFIG_13) { + reg = CPLD_QSFP_PORT_CONFIG_BASE_REG + + (attr->index - CPLD_QSFP_PORT_CONFIG_1); + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to qsfp port config register */ +static ssize_t write_qsfp_port_config(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index >= CPLD_QSFP_PORT_CONFIG_1 && + attr->index <= CPLD_QSFP_PORT_CONFIG_13) { + reg = CPLD_QSFP_PORT_CONFIG_BASE_REG + + (attr->index - CPLD_QSFP_PORT_CONFIG_1); + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get qsfp port interrupt register value */ +static ssize_t read_qsfp_port_interrupt(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_QSFP_PORT_INTERRUPT) { + reg = CPLD_QSFP_PORT_INTERRUPT_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get sfp port status register value */ +static ssize_t read_sfp_port_status(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_SFP_PORT_STATUS) { + reg = CPLD_SFP_PORT_STATUS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get sfp port config register value */ +static ssize_t read_sfp_port_config(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_SFP_PORT_CONFIG) { + reg = CPLD_SFP_PORT_CONFIG_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to sfp port config register */ +static ssize_t write_sfp_port_config(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_SFP_PORT_CONFIG) { + reg = CPLD_SFP_PORT_CONFIG_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get 10g mux config register value */ +static ssize_t read_10gmux_config(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_10GMUX_CONFIG) { + reg = CPLD_10GMUX_CONFIG_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to 10g mux config register */ +static ssize_t write_10gmux_config(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_10GMUX_CONFIG) { + reg = CPLD_10GMUX_CONFIG_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get bmc status register value */ +static ssize_t read_bmc_status(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_BMC_STATUS) { + reg = CPLD_BMC_STATUS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get bmc watchdog register value */ +static ssize_t read_bmc_watchdog(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_BMC_WATCHDOG) { + reg = CPLD_BMC_WATCHDOG_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to bmc watchdog register */ +static ssize_t write_bmc_watchdog(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_BMC_WATCHDOG) { + reg = CPLD_BMC_WATCHDOG_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get usb status register value */ +static ssize_t read_usb_status(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_USB_STATUS) { + reg = CPLD_USB_STATUS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get reset control register value */ +static ssize_t read_reset_control(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_RESET_CONTROL) { + reg = CPLD_RESET_CONTROL_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to reset control register */ +static ssize_t write_reset_control(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_RESET_CONTROL) { + reg = CPLD_RESET_CONTROL_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get sfp port 0/1 led register */ +static ssize_t read_sfp_led(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_SFP_LED) { + reg = CPLD_SFP_LED_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to sfp 0/1 port led register */ +static ssize_t write_sfp_led(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_SFP_LED) { + reg = CPLD_SFP_LED_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get sfp port 0/1 led blink register */ +static ssize_t read_sfp_led_blink(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_SFP_LED_BLINK) { + reg = CPLD_SFP_LED_BLINK_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to sfp port 0/1 led blink register */ +static ssize_t write_sfp_led_blink(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_SFP_LED_BLINK) { + reg = CPLD_SFP_LED_BLINK_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get qsfp port led register */ +static ssize_t read_qsfp_led(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index >= CPLD_QSFP_LED_1 && + attr->index <= CPLD_QSFP_LED_16) { + reg = CPLD_QSFP_LED_BASE_REG + (attr->index - CPLD_QSFP_LED_1); + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to qsfp port led register */ +static ssize_t write_qsfp_led(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index >= CPLD_QSFP_LED_1 && + attr->index <= CPLD_QSFP_LED_16) { + reg = CPLD_QSFP_LED_BASE_REG + (attr->index - CPLD_QSFP_LED_1); + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get qsfp 16 port led blink register value in 64 bit map */ +/* + each register for 2 port, each port has 4 channel for led blink + bit 64 56 48 40 32 24 16 8 0 + port 16/15 14/13 12/11 10/9 8/7 6/5 4/3 2/1 + */ +static ssize_t read_qsfp_led_blink(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val, i; + u64 bitmap = 0; + + if (attr->index == CPLD_QSFP_LED_BLINK) { + for (i = 0; i <= 7; i++) { + reg = CPLD_QSFP_LED_BLINK_BASE_REG + i; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + reg_val = reg_val & 0xff; + bitmap = bitmap | (reg_val<<(i*8)); + } + return sprintf(buf, "0x%llx\n", bitmap); + } + return -1; +} + +/* set 64 bit map value to qsfp port led blink register */ +/* + each register for 2 port, each port has 4 channel for led blink + bit 63 56 48 40 32 24 16 8 0 + port 16/15 14/13 12/11 10/9 8/7 6/5 4/3 2/1 + */ +static ssize_t write_qsfp_led_blink(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val, i; + int ret; + u64 bitmap = 0; + + if (kstrtou64(buf, 0, &bitmap) < 0) + return -EINVAL; + + if (attr->index == CPLD_QSFP_LED_BLINK) { + for (i = 0; i <= 7; i++) { + reg = CPLD_QSFP_LED_BLINK_BASE_REG + i; + reg_val = (u8)((bitmap >> i*8) & 0xFF); + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + } + return count; +} + +/* get retimer reset register */ +static ssize_t read_rtmr_reset(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_RTMR_RESET) { + reg = CPLD_RTMR_RESET_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to retimer reset register */ +static ssize_t write_rtmr_reset(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_RTMR_RESET) { + reg = CPLD_RTMR_RESET_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get rov status register */ +static ssize_t read_rov_status(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_ROV_STATUS) { + reg = CPLD_ROV_STATUS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* add valid cpld client to list */ +static void ingrasys_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = NULL; + + node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + if (!node) { + dev_info(&client->dev, + "Can't allocate cpld_client_node for index %d\n", + client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +/* remove exist cpld client in list */ +static void ingrasys_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, + struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + mutex_unlock(&list_lock); +} + +/* cpld drvier probe */ +static int ingrasys_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct cpld_data *data = NULL; + int ret = -EPERM; + int idx; + + data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* init cpld data for client */ + i2c_set_clientdata(client, data); + mutex_init(&data->access_lock); + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_info(&client->dev, + "i2c_check_functionality failed (0x%x)\n", + client->addr); + status = -EIO; + goto exit; + } + + /* get cpld id from device */ + ret = i2c_smbus_read_byte_data(client, CPLD_ID_REG); + + if (ret < 0) { + dev_info(&client->dev, + "fail to get cpld id (0x%x) at addr (0x%x)\n", + CPLD_ID_REG, client->addr); + status = -EIO; + goto exit; + } + + CPLD_ID_ID_GET(ret, idx); + + if (INVALID(idx, cpld1, cpld5)) { + dev_info(&client->dev, + "cpld id %d(device) not valid\n", idx); + //status = -EPERM; + //goto exit; + } + +#if 0 + /* change client name for each cpld with index */ + snprintf(client->name, sizeof(client->name), "%s_%d", client->name, + data->index); +#endif + + data->index = dev_id->driver_data; + + /* register sysfs hooks for different cpld group */ + dev_info(&client->dev, "probe cpld with index %d\n", data->index); + switch (data->index) { + case cpld1: + status = sysfs_create_group(&client->dev.kobj, + &s9280_64x_cpld1_group); + break; + case cpld2: + case cpld3: + case cpld4: + case cpld5: + status = sysfs_create_group(&client->dev.kobj, + &s9280_64x_cpld2345_group); + break; + default: + status = -EINVAL; + } + + if (status) + goto exit; + + dev_info(&client->dev, "chip found\n"); + + /* add probe chip to client list */ + ingrasys_i2c_cpld_add_client(client); + + return 0; +exit: + sysfs_remove_group(&client->dev.kobj, &s9280_64x_cpld2345_group); + return status; +} + +/* cpld drvier remove */ +static int ingrasys_i2c_cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + + switch (data->index) { + case cpld1: + sysfs_remove_group(&client->dev.kobj, &s9280_64x_cpld1_group); + break; + case cpld2: + case cpld3: + case cpld4: + case cpld5: + sysfs_remove_group(&client->dev.kobj, + &s9280_64x_cpld2345_group); + break; + } + + ingrasys_i2c_cpld_remove_client(client); + return 0; +} + +MODULE_DEVICE_TABLE(i2c, ingrasys_i2c_cpld_id); + +static struct i2c_driver ingrasys_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ingrasys_i2c_cpld", + }, + .probe = ingrasys_i2c_cpld_probe, + .remove = ingrasys_i2c_cpld_remove, + .id_table = ingrasys_i2c_cpld_id, + .address_list = cpld_i2c_addr, +}; + +/* provid cpld register read */ +/* cpld_idx indicate the index of cpld device */ +int ingrasys_i2c_cpld_read(u8 cpld_idx, + u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + struct cpld_data *data; + + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, + struct cpld_client_node, list); + data = i2c_get_clientdata(cpld_node->client); + if (data->index == cpld_idx) { + DEBUG_PRINT("cpld_idx=%d, read reg 0x%02x", + cpld_idx, reg); + I2C_READ_BYTE_DATA(ret, &data->access_lock, + cpld_node->client, reg); + DEBUG_PRINT("cpld_idx=%d, read reg 0x%02x = 0x%02x", + cpld_idx, reg, ret); + break; + } + } + + return ret; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_read); + +/* provid cpld register write */ +/* cpld_idx indicate the index of cpld device */ +int ingrasys_i2c_cpld_write(u8 cpld_idx, + u8 reg, + u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + struct cpld_data *data; + + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, + struct cpld_client_node, list); + data = i2c_get_clientdata(cpld_node->client); + + if (data->index == cpld_idx) { + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + cpld_node->client, + reg, value); + DEBUG_PRINT("cpld_idx=%d, write reg 0x%02x val 0x%02x, ret=%d", + cpld_idx, reg, value, ret); + break; + } + } + + return ret; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_write); + +/* provid qsfp port status register read */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_get_qsfp_port_status_val(u8 port_num) +{ + u8 cpld_idx, cpld_port, reg; + int reg_val; + + if (INVALID(port_num, QSFP_MIN_PORT_NUM, QSFP_MAX_PORT_NUM)) { + DEBUG_PRINT("invalid input value %d", port_num); + return -1; + } + QSFP_TO_CPLD_IDX(port_num, cpld_idx, cpld_port); + reg = QSFP_PORT_STATUS_REG(cpld_port); + DEBUG_PRINT("port_num=%d, cpld_idx=%d, cpld_port=%d, reg=0x%x", + port_num, cpld_idx, cpld_port, reg); + reg_val = ingrasys_i2c_cpld_read(cpld_idx, reg); + return reg_val; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_get_qsfp_port_status_val); + +/* provid qsfp port config register read */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_get_qsfp_port_config_val(u8 port_num) +{ + u8 cpld_idx, cpld_port, reg; + int reg_val; + + if (INVALID(port_num, QSFP_MIN_PORT_NUM, QSFP_MAX_PORT_NUM)) { + DEBUG_PRINT("invalid input value %d", port_num); + return -1; + } + QSFP_TO_CPLD_IDX(port_num, cpld_idx, cpld_port); + reg = QSFP_PORT_CONFIG_REG(cpld_port); + DEBUG_PRINT("port_num=%d, cpld_idx=%d, cpld_port=%d, reg=0x%x", + port_num, cpld_idx, cpld_port, reg); + reg_val = ingrasys_i2c_cpld_read(cpld_idx, reg); + return reg_val; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_get_qsfp_port_config_val); + +/* provid qsfp port config register write */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_set_qsfp_port_config_val(u8 port_num, + u8 reg_val) +{ + u8 cpld_idx, cpld_port, reg, ret; + + if (INVALID(port_num, QSFP_MIN_PORT_NUM, QSFP_MAX_PORT_NUM)) { + DEBUG_PRINT("invalid input value %d", port_num); + return -1; + } + QSFP_TO_CPLD_IDX(port_num, cpld_idx, cpld_port); + reg = QSFP_PORT_CONFIG_REG(cpld_port); + DEBUG_PRINT("port_num=%d, cpld_idx=%d, cpld_port=%d, reg=0x%x", + port_num, cpld_idx, cpld_port, reg); + ret = ingrasys_i2c_cpld_write(cpld_idx, reg, reg_val); + return ret; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_set_qsfp_port_config_val); + +/* provid sfp port 0/1 status register read */ +int ingrasys_i2c_cpld_get_sfp_port_status_val(void) +{ + u8 cpld_idx, reg; + int reg_val; + + cpld_idx = cpld1; + reg = CPLD_SFP_PORT_STATUS_REG; + DEBUG_PRINT("cpld_idx=%d, reg=0x%x", + cpld_idx, reg); + reg_val = ingrasys_i2c_cpld_read(cpld_idx, reg); + return reg_val; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_get_sfp_port_status_val); + +/* provid qsfp port config register read */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_get_sfp_port_config_val(void) +{ + u8 cpld_idx, reg; + int reg_val; + + cpld_idx = cpld1; + reg = CPLD_SFP_PORT_CONFIG_REG; + DEBUG_PRINT("cpld_idx=%d, reg=0x%x", + cpld_idx, reg); + reg_val = ingrasys_i2c_cpld_read(cpld_idx, reg); + return reg_val; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_get_sfp_port_config_val); + +/* provid qsfp port config register write */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_set_sfp_port_config_val(u8 reg_val) +{ + u8 cpld_idx, reg, ret; + + cpld_idx = cpld1; + reg = CPLD_SFP_PORT_CONFIG_REG; + DEBUG_PRINT("cpld_idx=%d, reg=0x%x", + cpld_idx, reg); + ret = ingrasys_i2c_cpld_write(cpld_idx, reg, reg_val); + return ret; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_set_sfp_port_config_val); + +static int __init ingrasys_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&ingrasys_i2c_cpld_driver); +} + +static void __exit ingrasys_i2c_cpld_exit(void) +{ + i2c_del_driver(&ingrasys_i2c_cpld_driver); +} + +MODULE_AUTHOR("Leo Lin "); +MODULE_DESCRIPTION("ingrasys_i2c_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(ingrasys_i2c_cpld_init); +module_exit(ingrasys_i2c_cpld_exit); + diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_i2c_cpld.h b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_i2c_cpld.h new file mode 100644 index 000000000000..8d1df5dee49d --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_i2c_cpld.h @@ -0,0 +1,338 @@ +/* header file for i2c cpld driver of ingrasys_s9280_64x + * + * Copyright (C) 2017 Ingrasys Technology Corporation. + * Leo Lin + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef INGRASYS_S9280_64X_I2C_CPLD_H +#define INGRASYS_S9280_64X_I2C_CPLD_H + +/* CPLD device index value */ +enum cpld_id { + cpld1, + cpld2, + cpld3, + cpld4, + cpld5 +}; + +enum LED_BLINK { + BLINK, + NOBLINK, +}; + +enum LED_YELLOW { + YELLOW_OFF, + YELLOW_ON, +}; + +enum LED_GREEN { + GREEN_OFF, + GREEN_ON, +}; + +/* port number on CPLD */ +#define CPLD_1_PORT_NUM 12 +#define CPLD_2_PORT_NUM 13 + +/* QSFP port number */ +#define QSFP_MAX_PORT_NUM 64 +#define QSFP_MIN_PORT_NUM 1 + +/* SFP+ port number */ +#define SFP_MAX_PORT_NUM 2 +#define SFP_MIN_PORT_NUM 1 + + +/* CPLD registers */ +#define CPLD_BOARD_TYPE_REG 0x0 +#define CPLD_EXT_BOARD_TYPE_REG 0x7 +#define CPLD_VERSION_REG 0x1 +#define CPLD_ID_REG 0x2 +#define CPLD_QSFP_PORT_STATUS_BASE_REG 0x20 +#define CPLD_QSFP_PORT_CONFIG_BASE_REG 0x30 +#define CPLD_QSFP_PORT_INTERRUPT_REG 0x40 +#define CPLD_SFP_PORT_STATUS_REG 0x2F +#define CPLD_SFP_PORT_CONFIG_REG 0x3F +#define CPLD_QSFP_PORT_INTERRUPT_REG 0x40 +#define CPLD_10GMUX_CONFIG_REG 0x41 +#define CPLD_BMC_STATUS_REG 0x42 +#define CPLD_BMC_WATCHDOG_REG 0x43 +#define CPLD_USB_STATUS_REG 0x44 +#define CPLD_RESET_CONTROL_REG 0x4A +#define CPLD_SFP_LED_REG 0x80 +#define CPLD_SFP_LED_BLINK_REG 0x90 +#define CPLD_QSFP_LED_BASE_REG 0x80 +#define CPLD_QSFP_LED_BLINK_BASE_REG 0x90 +#define CPLD_RTMR_RESET_REG 0x4B +#define CPLD_ROV_STATUS_REG 0x4C + +/* bit definition for register value */ +enum CPLD_QSFP_PORT_STATUS_BITS { + CPLD_QSFP_PORT_STATUS_INT_BIT, + CPLD_QSFP_PORT_STATUS_ABS_BIT, +}; +enum CPLD_QSFP_PORT_CONFIG_BITS { + CPLD_QSFP_PORT_CONFIG_RESET_BIT, + CPLD_QSFP_PORT_CONFIG_RESERVE_BIT, + CPLD_QSFP_PORT_CONFIG_LPMODE_BIT, +}; +enum CPLD_SFP_PORT_STATUS_BITS { + CPLD_SFP0_PORT_STATUS_PRESENT_BIT, + CPLD_SFP0_PORT_STATUS_TXFAULT_BIT, + CPLD_SFP0_PORT_STATUS_RXLOS_BIT, + CPLD_SFP_PORT_STATUS_DUMMY, + CPLD_SFP1_PORT_STATUS_PRESENT_BIT, + CPLD_SFP1_PORT_STATUS_TXFAULT_BIT, + CPLD_SFP1_PORT_STATUS_RXLOS_BIT, +}; +enum CPLD_SFP_PORT_CONFIG_BITS { + CPLD_SFP0_PORT_CONFIG_TXDIS_BIT, + CPLD_SFP0_PORT_CONFIG_RS_BIT, + CPLD_SFP0_PORT_CONFIG_TS_BIT, + CPLD_SFP_PORT_CONFIG_DUMMY, + CPLD_SFP1_PORT_CONFIG_TXDIS_BIT, + CPLD_SFP1_PORT_CONFIG_RS_BIT, + CPLD_SFP1_PORT_CONFIG_TS_BIT, + +}; +enum CPLD_10GMUX_CONFIG_BITS { + CPLD_10GMUX_CONFIG_ENSMB_BIT, + CPLD_10GMUX_CONFIG_ENINPUT_BIT, + CPLD_10GMUX_CONFIG_SEL1_BIT, + CPLD_10GMUX_CONFIG_SEL0_BIT, +}; +enum CPLD_BMC_WATCHDOG_BITS { + CPLD_10GMUX_CONFIG_ENTIMER_BIT, + CPLD_10GMUX_CONFIG_TIMEOUT_BIT, +}; +enum CPLD_RESET_CONTROL_BITS { + CPLD_RESET_CONTROL_SWRST_BIT, + CPLD_RESET_CONTROL_CP2104RST_BIT, + CPLD_RESET_CONTROL_82P33814RST_BIT, + CPLD_RESET_CONTROL_BMCRST_BIT, +}; +enum CPLD_SFP_LED_BITS { + CPLD_SFP_LED_SFP0_GREEN_BIT, + CPLD_SFP_LED_SFP0_YELLOW_BIT, + CPLD_SFP_LED_SFP1_GREEN_BIT, + CPLD_SFP_LED_SFP1_YELLOW_BIT, +}; +enum CPLD_SFP_LED_BLINK_BITS { + CPLD_SFP_LED_BLINK_SFP0_BIT, + CPLD_SFP_LED_BLINK_SFP1_BIT, +}; +enum CPLD_QSFP_LED_BITS { + CPLD_QSFP_LED_CHAN_0_GREEN_BIT, + CPLD_QSFP_LED_CHAN_0_YELLOW_BIT, + CPLD_QSFP_LED_CHAN_1_GREEN_BIT, + CPLD_QSFP_LED_CHAN_1_YELLOW_BIT, + CPLD_QSFP_LED_CHAN_2_GREEN_BIT, + CPLD_QSFP_LED_CHAN_2_YELLOW_BIT, + CPLD_QSFP_LED_CHAN_3_GREEN_BIT, + CPLD_QSFP_LED_CHAN_3_YELLOW_BIT, + +}; +enum CPLD_QSFP_LED_BLINK_BITS { + CPLD_QSFP_LED_BLINK_X_CHAN0_BIT, + CPLD_QSFP_LED_BLINK_X_CHAN1_BIT, + CPLD_QSFP_LED_BLINK_X_CHAN2_BIT, + CPLD_QSFP_LED_BLINK_X_CHAN3_BIT, + CPLD_QSFP_LED_BLINK_XPLUS_CHAN0_BIT, + CPLD_QSFP_LED_BLINK_XPLUS_CHAN1_BIT, + CPLD_QSFP_LED_BLINK_XPLUS_CHAN2_BIT, + CPLD_QSFP_LED_BLINK_XPLUS_CHAN3_BIT, +}; + +/* bit field structure for register value */ +struct cpld_reg_board_type_t { + u8 build_rev:2; + u8 hw_rev:2; + u8 board_id:4; +}; + +struct cpld_reg_version_t { + u8 revision:6; + u8 release:1; + u8 reserve:1; +}; + +struct cpld_reg_id_t { + u8 id:3; + u8 release:5; +}; + +/* common manipulation */ +#define INVALID(i, min, max) ((i < min) || (i > max) ? 1u : 0u) +#define READ_BIT(val, bit) ((0u == (val & (1<bf_name) +#define READ_BF_1(bf_struct, val, bf_name, bf_value) \ + bf_struct bf; \ + bf.data = val; \ + bf_value = bf.bf_name +#define BOARD_TYPE_BUILD_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, build_rev, res) +#define BOARD_TYPE_HW_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, hw_rev, res) +#define BOARD_TYPE_BOARD_ID_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, board_id, res) +#define CPLD_VERSION_REV_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, revision, res) +#define CPLD_VERSION_REL_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, release, res) +#define CPLD_ID_ID_GET(val, res) \ + READ_BF(cpld_reg_id_t, val, id, res) +#define CPLD_ID_REL_GET(val, res) \ + READ_BF(cpld_reg_id_t, val, release, res) +/* SFP/QSFP port led registers manipulation */ +#define SFP_LED_TO_CPLD_IDX(sfp_port) cpld1 +#define SFP_LED_REG(sfp_port) CPLD_SFP_LED_REG +#define SFP_LED_BLINK_REG(sfp_port) CPLD_SFP_LED_BLINK_REG +#define QSFP_LED_TO_CPLD_IDX(qsfp_port) \ + ((qsfp_port - 1) / 16 + 2) +#define QSFP_LED_REG(qsfp_port) \ + ((qsfp_port - 1) % 16 + CPLD_QSFP_LED_BASE_REG) +#define QSFP_LED_BLINK_REG(qsfp_port) \ + (((qsfp_port - 1) % 16) / 2 + CPLD_QSFP_LED_BLINK_BASE_REG) +/* QSFP/SFP port status registers manipulation */ +#define QSFP_TO_CPLD_IDX(qsfp_port, cpld_index, cpld_port) \ +{ \ + if (QSFP_MIN_PORT_NUM <= qsfp_port && qsfp_port <= CPLD_1_PORT_NUM) { \ + cpld_index = cpld1; \ + cpld_port = qsfp_port - 1; \ + } else if (CPLD_1_PORT_NUM < qsfp_port \ + && qsfp_port <= QSFP_MAX_PORT_NUM) { \ + cpld_index = cpld2 + (qsfp_port - 1 - CPLD_1_PORT_NUM) \ + / CPLD_2_PORT_NUM; \ + cpld_port = (qsfp_port - 1 - CPLD_1_PORT_NUM) % \ + CPLD_2_PORT_NUM; \ + } else { \ + cpld_index = 0; \ + cpld_port = 0; \ + } \ +} +#define QSFP_PORT_STATUS_REG(cpld_port) \ + (CPLD_QSFP_PORT_STATUS_BASE_REG + cpld_port) +#define QSFP_PORT_CONFIG_REG(cpld_port) \ + (CPLD_QSFP_PORT_CONFIG_BASE_REG + cpld_port) +#define QSFP_PORT_INT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_INT_BIT) +#define QSFP_PORT_ABS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_ABS_BIT) +#define QSFP_PORT_RESET_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_RESET_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_RESET_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_LPMODE_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define SFP_PORT_PRESENT_BIT_GET(sfp_port, port_status_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + READ_BIT(port_status_value, CPLD_SFP0_PORT_STATUS_PRESENT_BIT); \ + } else { \ + READ_BIT(port_status_value, CPLD_SFP1_PORT_STATUS_PRESENT_BIT); \ + } +#define SFP_PORT_TXFAULT_BIT_GET(sfp_port, port_status_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + READ_BIT(port_status_value, CPLD_SFP0_PORT_STATUS_TXFAULT_BIT); \ + } else { \ + READ_BIT(port_status_value, CPLD_SFP1_PORT_STATUS_TXFAULT_BIT); \ + } +#define SFP_PORT_RXLOS_BIT_GET(sfp_port, port_status_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + READ_BIT(port_status_value, CPLD_SFP0_PORT_STATUS_RXLOS_BIT); \ + } else { \ + READ_BIT(port_status_value, CPLD_SFP1_PORT_STATUS_RXLOS_BIT); \ + } +#define SFP_PORT_TXDIS_BIT_GET(sfp_port, port_config_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + READ_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TXDIS_BIT); \ + } else { \ + READ_BIT(port_config_value, CPLD_SFP1_PORT_STATUS_RXLOS_BIT); \ + } +#define SFP_PORT_RS_BIT_GET(sfp_port, port_config_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + READ_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_RS_BIT); \ + } else { \ + READ_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_RS_BIT); \ + } +#define SFP_PORT_TS_BIT_GET(sfp_port, port_config_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + READ_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TS_BIT); \ + } else { \ + READ_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TS_BIT); \ + } +#define SFP_PORT_TXDIS_BIT_SET(sfp_port, port_config_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + SET_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TXDIS_BIT); \ + } else { \ + SET_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_TXDIS_BIT); \ + } +#define SFP_PORT_TXDIS_BIT_CLEAR(sfp_port, port_config_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + CLEAR_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TXDIS_BIT); \ + } else { \ + CLEAR_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_TXDIS_BIT); \ + } +#define SFP_PORT_RS_BIT_SET(sfp_port, port_config_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + SET_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_RS_BIT); \ + } else { \ + SET_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_RS_BIT); \ + } +#define SFP_PORT_RS_BIT_CLEAR(sfp_port, port_config_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + CLEAR_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_RS_BIT); \ + } else { \ + CLEAR_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_RS_BIT); \ + } +#define SFP_PORT_TS_BIT_SET(sfp_port, port_config_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + SET_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TS_BIT); \ + } else { \ + SET_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_TS_BIT); \ + } +#define SFP_PORT_TS_BIT_CLEAR(sfp_port, port_config_value) \ + if (sfp_port == SFP_MIN_PORT_NUM) { \ + CLEAR_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TS_BIT); \ + } else { \ + CLEAR_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_TS_BIT); \ + } + +/* CPLD access functions */ +extern int ingrasys_i2c_cpld_get_qsfp_port_status_val(u8 port_num); +extern int ingrasys_i2c_cpld_get_qsfp_port_config_val(u8 port_num); +extern int ingrasys_i2c_cpld_set_qsfp_port_config_val(u8 port_num, u8 reg_val); +extern int ingrasys_i2c_cpld_get_sfp_port_status_val(void); +extern int ingrasys_i2c_cpld_get_sfp_port_config_val(void); +extern int ingrasys_i2c_cpld_set_sfp_port_config_val(u8 reg_val); +extern u8 fp_port_to_phy_port(u8 fp_port); +#endif + diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_platform.h b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_platform.h new file mode 100644 index 000000000000..08f14c0bd96b --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_platform.h @@ -0,0 +1,158 @@ +#ifndef _S9230_64X_PLATFORM_H +#define _S9230_64X_PLATFORM_H + +#include + +// remove debug before release +#define DEBUG + +enum bus_order { + I2C_BUS_MAIN, + MUX_9548_0_CH0, + MUX_9548_0_CH1, + MUX_9548_0_CH2, + MUX_9548_0_CH3, + MUX_9548_0_CH4, + MUX_9548_0_CH5, + MUX_9548_0_CH6, + MUX_9548_0_CH7, + MUX_9548_1_CH0, + MUX_9548_1_CH1, + MUX_9548_1_CH2, + MUX_9548_1_CH3, + MUX_9548_1_CH4, + MUX_9548_1_CH5, + MUX_9548_1_CH6, + MUX_9548_1_CH7, + MUX_9548_2_CH0, + MUX_9548_2_CH1, + MUX_9548_2_CH2, + MUX_9548_2_CH3, + MUX_9548_2_CH4, + MUX_9548_2_CH5, + MUX_9548_2_CH6, + MUX_9548_2_CH7, + MUX_9546_0_CH0, + MUX_9546_0_CH1, + MUX_9546_0_CH2, + MUX_9546_0_CH3, + MUX_9546_1_CH0, + MUX_9546_1_CH1, + MUX_9546_1_CH2, + MUX_9546_1_CH3, + MUX_9548_11_CH0, + MUX_9548_11_CH1, + MUX_9548_11_CH2, + MUX_9548_11_CH3, + MUX_9548_11_CH4, + MUX_9548_11_CH5, + MUX_9548_11_CH6, + MUX_9548_11_CH7, + MUX_9548_3_CH0, + MUX_9548_3_CH1, + MUX_9548_3_CH2, + MUX_9548_3_CH3, + MUX_9548_3_CH4, + MUX_9548_3_CH5, + MUX_9548_3_CH6, + MUX_9548_3_CH7, + MUX_9548_4_CH0, + MUX_9548_4_CH1, + MUX_9548_4_CH2, + MUX_9548_4_CH3, + MUX_9548_4_CH4, + MUX_9548_4_CH5, + MUX_9548_4_CH6, + MUX_9548_4_CH7, + MUX_9548_5_CH0, + MUX_9548_5_CH1, + MUX_9548_5_CH2, + MUX_9548_5_CH3, + MUX_9548_5_CH4, + MUX_9548_5_CH5, + MUX_9548_5_CH6, + MUX_9548_5_CH7, + MUX_9548_6_CH0, + MUX_9548_6_CH1, + MUX_9548_6_CH2, + MUX_9548_6_CH3, + MUX_9548_6_CH4, + MUX_9548_6_CH5, + MUX_9548_6_CH6, + MUX_9548_6_CH7, + MUX_9548_7_CH0, + MUX_9548_7_CH1, + MUX_9548_7_CH2, + MUX_9548_7_CH3, + MUX_9548_7_CH4, + MUX_9548_7_CH5, + MUX_9548_7_CH6, + MUX_9548_7_CH7, + MUX_9548_8_CH0, + MUX_9548_8_CH1, + MUX_9548_8_CH2, + MUX_9548_8_CH3, + MUX_9548_8_CH4, + MUX_9548_8_CH5, + MUX_9548_8_CH6, + MUX_9548_8_CH7, + MUX_9548_9_CH0, + MUX_9548_9_CH1, + MUX_9548_9_CH2, + MUX_9548_9_CH3, + MUX_9548_9_CH4, + MUX_9548_9_CH5, + MUX_9548_9_CH6, + MUX_9548_9_CH7, + MUX_9548_10_CH0, + MUX_9548_10_CH1, + MUX_9548_10_CH2, + MUX_9548_10_CH3, + MUX_9548_10_CH4, + MUX_9548_10_CH5, + MUX_9548_10_CH6, + MUX_9548_10_CH7, +}; + +#define I2C_ADDR_MUX_9555_0 (0x20) +#define I2C_ADDR_MUX_9555_1 (0x24) +#define I2C_ADDR_MUX_9555_2 (0x25) +#define I2C_ADDR_MUX_9555_3 (0x26) +#define I2C_ADDR_MUX_9539_0 (0x76) +#define I2C_ADDR_MUX_9539_1 (0x76) +#define I2C_BUS_FAN_STATUS (I2C_BUS_MAIN) +#define I2C_BUS_SYS_LED (MUX_9548_1_CH1) +#define I2C_BUS_PSU_STATUS (I2C_BUS_MAIN) +#define I2C_ADDR_PSU_STATUS (I2C_ADDR_MUX_9555_2) + +#define NUM_OF_I2C_MUX (11) +#define NUM_OF_CPLD (5) +#define NUM_OF_QSFP_PORT (64) +#define NUM_OF_SFP_PORT (2) +#define QSFP_EEPROM_I2C_ADDR (0x50) + +enum gpio_reg { + REG_PORT0_IN, + REG_PORT1_IN, + REG_PORT0_OUT, + REG_PORT1_OUT, + REG_PORT0_POL, + REG_PORT1_POL, + REG_PORT0_DIR, + REG_PORT1_DIR, +}; + +struct ing_i2c_board_info { + int ch; + int size; + struct i2c_board_info *board_info; +}; + +struct i2c_init_data { + __u16 ch; + __u16 addr; + __u8 reg; + __u8 value; +}; + +#endif diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_psu.c b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_psu.c new file mode 100644 index 000000000000..c2537bf40858 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/modules/ingrasys_s9280_64x_psu.c @@ -0,0 +1,394 @@ +/* + * S9280-64x PSU driver + * + * Copyright (C) 2017 Ingrasys, Inc. + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ingrasys_s9280_64x_platform.h" + +static ssize_t show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf); +static struct s9280_psu_data *s9280_psu_update_status(struct device *dev); +static struct s9280_psu_data *s9280_psu_update_eeprom(struct device *dev); +static int s9280_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len); + + +#define DRIVER_NAME "psu" + +// Addresses scanned +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* PSU EEPROM SIZE */ +#define EEPROM_SZ 256 +#define READ_EEPROM 1 +#define NREAD_EEPROM 0 + +static struct i2c_client pca9555_client; + +/* pca9555 gpio pin mapping */ +#define PSU2_PWROK 0 +#define PSU2_PRSNT_L 1 +#define PSU2_PWRON_L 2 +#define PSU1_PWROK 3 +#define PSU1_PRSNT_L 4 +#define PSU1_PWRON_L 5 +#define TMP_75_INT_L 6 + +/* Driver Private Data */ +struct s9280_psu_data { + struct mutex lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + s32 status; /* IO expander value */ + char eeprom[EEPROM_SZ]; /* psu eeprom data */ + char psuABS; /* PSU absent */ + char psuPG; /* PSU power good */ +}; + +enum psu_index +{ + s9280_psu1, + s9280_psu2 +}; + +/* + * display power good attribute + */ +static ssize_t +show_psu_pg(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s9280_psu_data *data = s9280_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuPG; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + +/* + * display power absent attribute + */ +static ssize_t +show_psu_abs(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s9280_psu_data *data = s9280_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuABS; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + + +/* + * sysfs attributes for psu + */ +static DEVICE_ATTR(psu_pg, S_IRUGO, show_psu_pg, NULL); +static DEVICE_ATTR(psu_abs, S_IRUGO, show_psu_abs, NULL); +static DEVICE_ATTR(psu_eeprom, S_IRUGO, show_psu_eeprom, NULL); + +static struct attribute *s9280_psu_attributes[] = { + &dev_attr_psu_pg.attr, + &dev_attr_psu_abs.attr, + &dev_attr_psu_eeprom.attr, + NULL +}; + +/* + * display psu eeprom content + */ +static ssize_t +show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct s9280_psu_data *data = s9280_psu_update_eeprom(dev); + + memcpy(buf, (char *)data->eeprom, EEPROM_SZ); + return EEPROM_SZ; +} + +static const struct attribute_group s9280_psu_group = { + .attrs = s9280_psu_attributes, +}; + +/* + * check gpio expander is accessible + */ +static int +pca9555_detect(struct i2c_client *client) +{ + if (i2c_smbus_read_byte_data(client, REG_PORT0_DIR) < 0) { + return -ENODEV; + } + + return 0; +} + +/* + * client init + */ +static void +i2c_devices_client_address_init(struct i2c_client *client) +{ + pca9555_client = *client; + + /* get i2c adapter for the target */ + pca9555_client.adapter = i2c_get_adapter(I2C_BUS_PSU_STATUS); + + /* get the i2c addr for the target */ + pca9555_client.addr = I2C_ADDR_PSU_STATUS; +} + +static int +s9280_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct s9280_psu_data *data; + int status, err; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct s9280_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + memset(data, 0, sizeof(struct s9280_psu_data)); + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->lock); + + i2c_devices_client_address_init(client); + + err = pca9555_detect(&pca9555_client); + if (err) { + return err; + } + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &s9280_psu_group); + if (status) { + goto exit_free; + } + + return 0; + +exit_free: + kfree(data); +exit: + + return status; +} + +static int +s9280_psu_remove(struct i2c_client *client) +{ + struct s9280_psu_data *data = i2c_get_clientdata(client); + + sysfs_remove_group(&client->dev.kobj, &s9280_psu_group); + kfree(data); + + /* free i2c adapter */ + i2c_put_adapter(pca9555_client.adapter); + + return 0; +} + + +/* + * psu eeprom read utility + */ +static int +s9280_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len) +{ + int i=0, ret=0; + int blk_max = 32; //max block read size + + /* read eeprom, 32 * 8 = 256 bytes */ + for (i=0; i < EEPROM_SZ/blk_max; i++) { + ret = i2c_smbus_read_i2c_block_data(client, (i*blk_max), blk_max, + data + (i*blk_max)); + if (ret < 0) { + return ret; + } + } + return ret; +} + +/* + * update eeprom content + */ +static struct s9280_psu_data +*s9280_psu_update_eeprom(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s9280_psu_data *data = i2c_get_clientdata(client); + s32 status = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + if (time_after(jiffies, data->last_updated + 300 * HZ) + || !data->valid) { + + /* Read psu status */ + + status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN); + data->status = status; + + /*read psu status from io expander*/ + + if (data->index == s9280_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (status >> psu_pwrok) & 0x1; + data->psuABS = (status >> psu_prsnt_l) & 0x1; + + /* Read eeprom */ + if (!data->psuABS) { + //clear local eeprom data + memset(data->eeprom, 0, EEPROM_SZ); + + //read eeprom + status = s9280_psu_read_block(client, 0, data->eeprom, + ARRAY_SIZE(data->eeprom)); + + if (status < 0) { + memset(data->eeprom, 0, EEPROM_SZ); + dev_err(&client->dev, "Read eeprom failed, status=(%d)\n", status); + } else { + data->valid = 1; + } + } else { + memset(data->eeprom, 0, EEPROM_SZ); + } + data->last_updated = jiffies; + } + + mutex_unlock(&data->lock); + + return data; +} + +/* + * update psu status + */ +static struct s9280_psu_data +*s9280_psu_update_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s9280_psu_data *data = i2c_get_clientdata(client); + s32 status = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + /* Read psu status */ + + status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN); + data->status = status; + + /*read psu status from io expander*/ + + if (data->index == s9280_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (status >> psu_pwrok) & 0x1; + data->psuABS = (status >> psu_prsnt_l) & 0x1; + + mutex_unlock(&data->lock); + + return data; +} + +static const struct i2c_device_id s9280_psu_id[] = { + { "psu1", s9280_psu1 }, + { "psu2", s9280_psu2 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, s9280_psu_id); + +static struct i2c_driver s9280_psu_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = s9280_psu_probe, + .remove = s9280_psu_remove, + .id_table = s9280_psu_id, + .address_list = normal_i2c, +}; + +static int __init s9280_psu_init(void) +{ + return i2c_add_driver(&s9280_psu_driver); +} + +static void __exit s9280_psu_exit(void) +{ + i2c_del_driver(&s9280_psu_driver); +} + +module_init(s9280_psu_init); +module_exit(s9280_psu_exit); + +MODULE_AUTHOR("Leo Lin "); +MODULE_DESCRIPTION("S9280-64X psu driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/service/qsfp-monitor.service b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/service/qsfp-monitor.service new file mode 100644 index 000000000000..c801ad68966d --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/service/qsfp-monitor.service @@ -0,0 +1,15 @@ +[Unit] +Description= This QSFP Monitor service is to setup QSFP SI. +Requires=s9280-64x-monitor.service +After=s9280-64x-monitor.service + +[Service] +ExecStart=/usr/sbin/qsfp_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/service/s9280-64x-monitor.service b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/service/s9280-64x-monitor.service new file mode 100644 index 000000000000..5f22b6164dd0 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/service/s9280-64x-monitor.service @@ -0,0 +1,19 @@ +[Unit] +Description= This Platform Monitor service is to initialize platform and monitor platform. +Before=platform-monitor.service +After=sysinit.target +Wants=fancontrol.service +Wants=qsfp-monitor.service +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/sbin/i2c_utils.sh i2c_init +ExecStart=/usr/sbin/s9280_64x_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/i2c_utils.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/i2c_utils.sh new file mode 100755 index 000000000000..fcb7b6372efa --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/i2c_utils.sh @@ -0,0 +1,1844 @@ +#!/bin/bash + +# Copyright (C) 2016 Ingrasys, Inc. +# +# This program 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# trun on for more debug output +#DEBUG="on" + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +EXEC_FUNC=${1} +COLOR_LED=${2} +QSFP_PORT=${2} +SFP_PORT=${2} +QSFP_ACTION=${2} +SFP_ACTION=${2} +MB_EEPROM_ACTION=${2} +ONOFF_LED=${3} +FAN_TRAY=${4} + +############################################################ +# Distributor ID: Debian +# Description: Debian GNU/Linux 8.6 (jessie) +# Release: 8.6 +# Codename: jessie +# Linux debian 3.16.0-4-amd64 #1 +# SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux +############################################################ + +# Color Definition +COLOR_TITLE="\e[1;32m" ### Green ### +COLOR_WARNING="\e[1;33m" ### Yellow ### +COLOR_ERROR="\e[1;31m" ### Red ### +COLOR_END="\e[0m" ### END ### + +NUM_I801_DEVICE=0 + +# PCA9548#0 0x70 +NUM_MUX_9548_0_CH0=$(( ${NUM_I801_DEVICE} + 1 )) # CPLD1 +NUM_MUX_9548_0_CH1=$(( ${NUM_I801_DEVICE} + 2 )) # CPLD2 +NUM_MUX_9548_0_CH2=$(( ${NUM_I801_DEVICE} + 3 )) # CPLD3 +NUM_MUX_9548_0_CH3=$(( ${NUM_I801_DEVICE} + 4 )) # CPLD4 +NUM_MUX_9548_0_CH4=$(( ${NUM_I801_DEVICE} + 5 )) # CPLD5 +NUM_MUX_9548_0_CH5=$(( ${NUM_I801_DEVICE} + 6 )) # LM75_1 LM75_2 LM86 +NUM_MUX_9548_0_CH6=$(( ${NUM_I801_DEVICE} + 7 )) # LM75_3 LM75_4 + +# PCA9548#1 0x73 +NUM_MUX_9548_1_CH0=$(( ${NUM_I801_DEVICE} + 9 )) # UCD9090 +NUM_MUX_9548_1_CH1=$(( ${NUM_I801_DEVICE} + 10 )) # PCA9539#0 0x76 for FP LED & HW ID +NUM_MUX_9548_1_CH2=$(( ${NUM_I801_DEVICE} + 11 )) # NONE +NUM_MUX_9548_1_CH3=$(( ${NUM_I801_DEVICE} + 12 )) # EEPROM for debug 0x57 +#NUM_MUX_9548_1_CH4=$(( ${NUM_I801_DEVICE} + 13 )) # NONE +NUM_MUX_9548_1_CH5=$(( ${NUM_I801_DEVICE} + 14 )) # CLK gen +NUM_MUX_9548_1_CH6=$(( ${NUM_I801_DEVICE} + 15 )) # ROV +NUM_MUX_9548_1_CH7=$(( ${NUM_I801_DEVICE} + 16 )) # HWM on BMC + +# PCA9546#0 0X72 +NUM_MUX_9546_0_CH0=$(( ${NUM_I801_DEVICE} + 17 )) # PSU1 0x58 +NUM_MUX_9546_0_CH1=$(( ${NUM_I801_DEVICE} + 18 )) # PSU2 0x58 +NUM_MUX_9546_0_CH2=$(( ${NUM_I801_DEVICE} + 19 )) # NONE +NUM_MUX_9546_0_CH3=$(( ${NUM_I801_DEVICE} + 20 )) # NONE + +# PCA9548#2 0X71 +NUM_MUX_9548_2_CH0=$(( ${NUM_I801_DEVICE} + 21 )) # PCA9548#3 0x74 +NUM_MUX_9548_2_CH1=$(( ${NUM_I801_DEVICE} + 22 )) # PCA9548#4 0x74 +NUM_MUX_9548_2_CH2=$(( ${NUM_I801_DEVICE} + 23 )) # PCA9548#5 0x74 +NUM_MUX_9548_2_CH3=$(( ${NUM_I801_DEVICE} + 24 )) # PCA9548#6 0x74 +NUM_MUX_9548_2_CH4=$(( ${NUM_I801_DEVICE} + 25 )) # PCA9548#7 0x74 +NUM_MUX_9548_2_CH5=$(( ${NUM_I801_DEVICE} + 26 )) # PCA9548#8 0x74 +NUM_MUX_9548_2_CH6=$(( ${NUM_I801_DEVICE} + 27 )) # PCA9548#9 0x74 +NUM_MUX_9548_2_CH7=$(( ${NUM_I801_DEVICE} + 28 )) # PCA9548#10 0x74 + + + +# PCA9546#1 0X77 +NUM_MUX_9546_1_CH0=$(( ${NUM_I801_DEVICE} + 29 )) # SFP0 EEPROM 0x50 +NUM_MUX_9546_1_CH1=$(( ${NUM_I801_DEVICE} + 30 )) # SFP1 EEPROM 0x50 +NUM_MUX_9546_1_CH2=$(( ${NUM_I801_DEVICE} + 31 )) # NONE +NUM_MUX_9546_1_CH3=$(( ${NUM_I801_DEVICE} + 32 )) # PCA9539#1 0x76 for sys control + +# PCA9548#11 0X75 +NUM_MUX_9548_11_CH0=$(( ${NUM_I801_DEVICE} + 33 )) # SW upgrade for CPLD1 +NUM_MUX_9548_11_CH1=$(( ${NUM_I801_DEVICE} + 34 )) # SW upgrade for CPLD2 +NUM_MUX_9548_11_CH2=$(( ${NUM_I801_DEVICE} + 35 )) # SW upgrade for CPLD3 +NUM_MUX_9548_11_CH3=$(( ${NUM_I801_DEVICE} + 36 )) # SW upgrade for CPLD4 +NUM_MUX_9548_11_CH4=$(( ${NUM_I801_DEVICE} + 37 )) # SW upgrade for CPLD5 +NUM_MUX_9548_11_CH5=$(( ${NUM_I801_DEVICE} + 38 )) # EEPROM for debug 0x57 +NUM_MUX_9548_11_CH6=$(( ${NUM_I801_DEVICE} + 39 )) # Retimer#0~3 +NUM_MUX_9548_11_CH7=$(( ${NUM_I801_DEVICE} + 40 )) # Retimer#4~7 + +# PCA9548#3~10 0X74 +NUM_MUX_9548_3_CH0=$(( ${NUM_I801_DEVICE} + 41 )) # QSFP 0 EEPROM +NUM_MUX_9548_4_CH0=$(( ${NUM_I801_DEVICE} + 49 )) # QSFP 8 EEPROM +NUM_MUX_9548_5_CH0=$(( ${NUM_I801_DEVICE} + 57 )) # QSFP 16 EEPROM +NUM_MUX_9548_6_CH0=$(( ${NUM_I801_DEVICE} + 65 )) # QSFP 24 EEPROM +NUM_MUX_9548_7_CH0=$(( ${NUM_I801_DEVICE} + 73 )) # QSFP 32 EEPROM +NUM_MUX_9548_8_CH0=$(( ${NUM_I801_DEVICE} + 81 )) # QSFP 40 EEPROM +NUM_MUX_9548_9_CH0=$(( ${NUM_I801_DEVICE} + 89 )) # QSFP 48 EEPROM +NUM_MUX_9548_10_CH0=$(( ${NUM_I801_DEVICE} + 97 )) # QSFP 56 EEPROM + +# MUX Alias +I2C_BUS_MAIN=${NUM_I801_DEVICE} +I2C_BUS_HWM=${NUM_MUX_9548_1_CH7} +I2C_BUS_FAN_STATUS=${I2C_BUS_MAIN} +I2C_BUS_SYS_LED=${NUM_MUX_9548_1_CH1} +I2C_BUS_HW_ID=${NUM_MUX_9548_1_CH1} +I2C_BUS_BMC_HW_ID=${I2C_BUS_MAIN} +I2C_BUS_PSU_STAT=${I2C_BUS_MAIN} +I2C_BUS_FANTRAY_LED=${I2C_BUS_MAIN} +I2C_BUS_MB_EEPROM=${I2C_BUS_MAIN} +I2C_BUS_CB_EEPROM=${I2C_BUS_MAIN} +# TODO: check i2c channel of PSU1/PSU2, it swap in s9230 +I2C_BUS_PSU1_EEPROM=${NUM_MUX_9546_0_CH1} +I2C_BUS_PSU2_EEPROM=${NUM_MUX_9546_0_CH0} +I2C_BUS_CPLD1=${NUM_MUX_9548_0_CH0} +I2C_BUS_CPLD2=${NUM_MUX_9548_0_CH1} +I2C_BUS_CPLD3=${NUM_MUX_9548_0_CH2} +I2C_BUS_CPLD4=${NUM_MUX_9548_0_CH3} +I2C_BUS_CPLD5=${NUM_MUX_9548_0_CH4} +I2C_BUS_ROV=${NUM_MUX_9548_1_CH6} + +# I2C BUS path +PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" +PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon" +# TODO: need to verify HWM deivce path after board ready +PATH_HWMON_W83795_DEVICE="${PATH_HWMON_ROOT_DEVICES}/hwmon1" +PATH_I801_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}" +PATH_MUX_9548_0_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH0}" +PATH_MUX_9548_0_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH1}" +PATH_MUX_9548_0_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH2}" +PATH_MUX_9548_0_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH3}" +PATH_MUX_9548_0_CH4="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH4}" +PATH_MUX_9548_0_CH5="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH5}" +PATH_MUX_9548_0_CH6="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH6}" +PATH_MUX_9548_0_CH7="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH7}" +PATH_MUX_9548_1_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH0}" +PATH_MUX_9548_1_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH1}" +PATH_MUX_9548_1_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH2}" +PATH_MUX_9548_1_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH3}" +PATH_MUX_9548_1_CH4="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH4}" +PATH_MUX_9548_1_CH5="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH5}" +PATH_MUX_9548_1_CH6="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH6}" +PATH_MUX_9548_1_CH7="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH7}" +PATH_MUX_9548_2_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH0}" +PATH_MUX_9548_2_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH1}" +PATH_MUX_9548_2_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH2}" +PATH_MUX_9548_2_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH3}" +PATH_MUX_9548_2_CH4="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH4}" +PATH_MUX_9548_2_CH5="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH5}" +PATH_MUX_9548_2_CH6="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH6}" +PATH_MUX_9548_2_CH7="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH7}" +PATH_MUX_9546_0_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_0_CH0}" +PATH_MUX_9546_0_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_0_CH1}" +PATH_MUX_9546_0_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_0_CH2}" +PATH_MUX_9546_0_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_0_CH3}" +PATH_MUX_9546_1_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_1_CH0}" +PATH_MUX_9546_1_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_1_CH1}" +PATH_MUX_9546_1_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_1_CH2}" +PATH_MUX_9546_1_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_1_CH3}" +PATH_MUX_9548_11_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_11_CH0}" +PATH_MUX_9548_3_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_3_CH0}" +PATH_MUX_9548_4_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_4_CH0}" +PATH_MUX_9548_5_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_5_CH0}" +PATH_MUX_9548_6_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_6_CH0}" +PATH_MUX_9548_7_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_7_CH0}" +PATH_MUX_9548_8_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_8_CH0}" +PATH_MUX_9548_9_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_9_CH0}" +PATH_MUX_9548_10_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_10_CH0}" +PATH_CPLD1_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD1}" +PATH_CPLD2_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD2}" +PATH_CPLD3_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD3}" +PATH_CPLD4_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD4}" +PATH_CPLD5_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD5}" + + +# I2C Address +### I2C MUX +I2C_ADDR_MUX_9548_0=0x70 +I2C_ADDR_MUX_9548_1=0x73 +I2C_ADDR_MUX_9548_2=0x71 +I2C_ADDR_MUX_9546_0=0x72 +I2C_ADDR_MUX_9546_1=0x71 +I2C_ADDR_MUX_9548_11=0x75 +I2C_ADDR_MUX_9548_3=0x74 +I2C_ADDR_MUX_9548_4=0x74 +I2C_ADDR_MUX_9548_5=0x74 +I2C_ADDR_MUX_9548_6=0x74 +I2C_ADDR_MUX_9548_7=0x74 +I2C_ADDR_MUX_9548_8=0x74 +I2C_ADDR_MUX_9548_9=0x74 +I2C_ADDR_MUX_9548_10=0x74 + +### GPIO Expander +I2C_ADDR_MUX_9539_0=0x76 # LED & HW ID +I2C_ADDR_MUX_9539_1=0x76 # SYS config +I2C_ADDR_MUX_9539_2=0x76 # on CPU board, STATUS and ERR from CPLD +I2C_ADDR_MUX_9555_0=0x20 # on FAN board, fan status and led config +I2C_ADDR_MUX_9555_1=0x24 # on BMC board, INT and HW ID +I2C_ADDR_MUX_9555_2=0x25 # on BMC board, PSU status +I2C_ADDR_MUX_9555_3=0x26 # on BMC board, RST and SEL + + +### peripheral +I2C_ADDR_MB_EEPROM=0x55 # on main board +I2C_ADDR_CB_EEPROM=0x51 # on cpu board +I2C_ADDR_UCD9090=0x34 +I2C_ADDR_W83795=0x2F +I2C_ADDR_PSU1_EEPROM=0x50 +I2C_ADDR_PSU2_EEPROM=0x50 +I2C_ADDR_LM75_1=0x4D # Rear Panel +I2C_ADDR_LM75_2=0x4E # Rear MAC +I2C_ADDR_LM86=0x4C # TBD +I2C_ADDR_LM75_3=0x4D # Front Panel +I2C_ADDR_LM75_4=0x4E # Front MAC +I2C_ADDR_TMP75_CB=0x4F # on cpu board +I2C_ADDR_TMP75_BB=0x4A # on bmc board +I2C_ADDR_QSFP_EEPROM=0x50 +I2C_ADDR_SFP_EEPROM=0x50 +I2C_ADDR_CPLD=0x33 +I2C_ADDR_ROV=0x76 + +#sysfs +PATH_SYSFS_PSU1="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU1_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU1_EEPROM)" +PATH_SYSFS_PSU2="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU2_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU2_EEPROM)" + +#ACTIVE LOW enable flag +ACTIVE_LOW_EN=1 +ACTIVE_HIGH_EN=0 +#GPIO Direction In/Out +DIR_IN=in +DIR_OUT=out + +#Power Supply Status +PSU_DC_ON=1 +PSU_DC_OFF=0 +PSU_EXIST=1 +PSU_NOT_EXIST=0 + +# IO expander register +# direction +REG_PORT0_DIR=6 +REG_PORT1_DIR=7 +# polarity +REG_PORT0_POL=4 +REG_PORT1_POL=5 +# output +REG_PORT0_OUT=2 +REG_PORT1_OUT=3 +# input +REG_PORT0_IN=0 +REG_PORT1_IN=1 + +# qsfp port number range +MIN_QSFP_PORT_NUM=1 +MAX_QSFP_PORT_NUM=64 + +# sfp+ port number range +MIN_SFP_PORT_NUM=1 +MAX_SFP_PORT_NUM=2 + +# CPLD access +# ROV status +CPLD_ROV_STATUS_KEY=cpld_rov_status +# port status +CPLD_QSFP_STATUS_KEY=cpld_qsfp_port_status +CPLD_SFP_STATUS_KEY=cpld_sfp_port_status +# bit define +CPLD_QSFP_STATUS_ABS_BIT=1 +CPLD_SFP0_STATUS_PRES_BIT=0 +CPLD_SFP1_STATUS_PRES_BIT=4 + +# fp port to phy port mapping +fp2phy_array=( 0 1 4 5 8 9 12 13 16 17 20 21 24 25 28 29 + 32 33 36 37 40 41 44 45 48 49 52 53 56 57 60 61 + 2 3 6 7 10 11 14 15 18 19 22 23 26 27 30 31 + 34 35 38 39 42 43 46 47 50 51 54 55 58 59 62 63) +# fp port to led port mapping +fp2led_array=( 1 2 5 6 9 10 13 14 1 2 5 6 9 10 13 14 + 1 2 5 6 9 10 13 14 1 2 5 6 9 10 13 14 + 3 4 7 8 11 12 15 16 3 4 7 8 11 12 15 16 + 3 4 7 8 11 12 15 16 3 4 7 8 11 12 15 16) +# vdd value for mac +rov_val_array=( 0.85 0.82 0.77 0.87 0.74 0.84 0.79 0.89 ) +rov_reg_array=( 0x79 0x73 0x69 0x7D 0x63 0x77 0x6D 0x81 ) + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} i2c_init" + echo " : ${0} i2c_deinit" + echo " : ${0} i2c_fan_speed_init" + echo " : ${0} i2c_io_exp_init" + echo " : ${0} i2c_led_test" + echo " : ${0} i2c_psu_eeprom_get" + echo " : ${0} i2c_mb_eeprom_get" + echo " : ${0} i2c_cb_eeprom_get" + echo " : ${0} i2c_qsfp_eeprom_get [${MIN_QSFP_PORT_NUM}-${MAX_QSFP_PORT_NUM}]" + echo " : ${0} i2c_sfp_eeprom_get [${MIN_SFP_PORT_NUM}-${MAX_SFP_PORT_NUM}]" + echo " : ${0} i2c_qsfp_eeprom_init new|delete" + echo " : ${0} i2c_sfp_eeprom_init new|delete" + echo " : ${0} i2c_mb_eeprom_init new|delete" + echo " : ${0} i2c_cb_eeprom_init new|delete" + echo " : ${0} i2c_qsfp_status_get [${MIN_QSFP_PORT_NUM}-${MAX_QSFP_PORT_NUM}]" + echo " : ${0} i2c_sfp_status_get [${MIN_SFP_PORT_NUM}-${MAX_SFP_PORT_NUM}]" + echo " : ${0} i2c_qsfp_type_get [${MIN_QSFP_PORT_NUM}-${MAX_QSFP_PORT_NUM}]" + echo " : ${0} i2c_sfp_type_get [${MIN_SFP_PORT_NUM}-${MAX_SFP_PORT_NUM}]" + echo " : ${0} i2c_board_type_get" + echo " : ${0} i2c_bmc_board_type_get" + echo " : ${0} i2c_cpld_version" + echo " : ${0} i2c_psu_status" + echo " : ${0} i2c_led_psu_status_set" + echo " : ${0} i2c_led_fan_status_set" + echo " : ${0} i2c_led_fan_tray_status_set" + echo " : ${0} i2c_test_all" + echo " : ${0} i2c_sys_led green|amber" + echo " : ${0} i2c_fan_led green|amber|off" + echo " : ${0} i2c_psu1_led green|amber|off" + echo " : ${0} i2c_psu2_led green|amber|off" + echo " : ${0} i2c_fan_tray_led green|amber on|off [1-4]" + echo "----------------------------------------------------" +} + +#Pause function +function _pause { + read -p "$*" +} + +#Retry command function +function _retry { + local i + for i in {1..5}; + do + echo "${*}" + eval "${*}" && break || echo "retry"; sleep 1; + done +} + +# front panel port to physical port mapping +function _port_fp2phy { + + local fp_port=$1 + local phy_port=0 + local index=$((${fp_port} - 1)) + # change to 1 base index for internal use + phy_port=$((${fp2phy_array[$index]} + 1)) + #phy_port=${fp2phy_array[$index]} + + echo $phy_port +} + +#front panel port to led port mapping +function _port_fp2led { + + local logic_port=$1 + local led_port=0 + led_port=${fp2led_array[$logic_port]} + + echo $led_port +} + +#I2C Init +function _i2c_init { + echo "=========================================================" + echo "# Description: I2C Init" + echo "=========================================================" + + #remove optoe module + rmmod optoe + + #rmmod i2c_ismt + _util_rmmod i2c_i801 + modprobe i2c_i801 + modprobe i2c_dev + modprobe i2c_mux_pca954x force_deselect_on_exit=1 + + # add MUX PCA9548#0 on I801, assume to be i2c-1~8 + if [ ! -e ${PATH_MUX_9548_0_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_0}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_0} already init." + fi + + # add MUX PCA9548#1 on I801, assume to be i2c-9~16 + if [ ! -e ${PATH_MUX_9548_1_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_1}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_1} already init." + fi + + # add MUX PCA9546#0 on I801, assume to be i2c-17~20 + if [ ! -e ${PATH_MUX_9546_0_CH0} ]; then + _retry "echo 'pca9546 ${I2C_ADDR_MUX_9546_0}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9546 ${I2C_ADDR_MUX_9546_0} already init." + fi + + # add MUX PCA9548#2 on I801, assume to be i2c-21~28 + if [ ! -e ${PATH_MUX_9548_2_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_2}' > ${PATH_MUX_9546_0_CH2}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_2} already init." + fi + + # add MUX PCA9546#1 on I801, assume to be i2c-29~32 + if [ ! -e ${PATH_MUX_9546_1_CH0} ]; then + _retry "echo 'pca9546 ${I2C_ADDR_MUX_9546_1}' > ${PATH_MUX_9546_0_CH3}/new_device" + else + echo "pca9546 ${I2C_ADDR_MUX_9546_1} already init." + fi + + # add MUX PCA9548#11 on I801, assume to be i2c-33~40 + if [ ! -e ${PATH_MUX_9548_11_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_11}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_11} already init." + fi + + # add MUX PCA9548#3 on PCA9548#2 CH0, assume to be i2c-41~48 + if [ ! -e ${PATH_MUX_9548_3_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_3}' > ${PATH_MUX_9548_2_CH0}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_4} already init." + fi + + # add MUX PCA9548#4 on PCA9548#2 CH1, assume to be i2c-49~56 + if [ ! -e ${PATH_MUX_9548_4_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_4}' > ${PATH_MUX_9548_2_CH1}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_4} already init." + fi + + # add MUX PCA9548#5 on PCA9548#2 CH2, assume to be i2c-57~64 + if [ ! -e ${PATH_MUX_9548_5_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_5}' > ${PATH_MUX_9548_2_CH2}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_5} already init." + fi + + # add MUX PCA9548#6 on PCA9548#2 CH3, assume to be i2c-65~72 + if [ ! -e ${PATH_MUX_9548_6_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_6}' > ${PATH_MUX_9548_2_CH3}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_6} already init." + fi + + # add MUX PCA9548#7 on PCA9548#2 CH4, assume to be i2c-73~80 + if [ ! -e ${PATH_MUX_9548_7_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_7}' > ${PATH_MUX_9548_2_CH4}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_7} already init." + fi + + # add MUX PCA9548#8 on PCA9548#2 CH5, assume to be i2c-81~88 + if [ ! -e ${PATH_MUX_9548_8_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_8}' > ${PATH_MUX_9548_2_CH5}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_8} already init." + fi + + # add MUX PCA9548#9 on PCA9548#2 CH6, assume to be i2c-89~96 + if [ ! -e ${PATH_MUX_9548_9_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_9}' > ${PATH_MUX_9548_2_CH6}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_9} already init." + fi + + # add MUX PCA9548#10 on PCA9548#2 CH7, assume to be i2c-97~104 + if [ ! -e ${PATH_MUX_9548_10_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_10}' > ${PATH_MUX_9548_2_CH7}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_10} already init." + fi + + _i2c_hwm_init + _util_rmmod eeprom + modprobe eeprom_mb + modprobe gpio-pca953x + _i2c_io_exp_init + _i2c_sensors_init + _i2c_cpld_init + _i2c_psu_init + + _i2c_qsfp_eeprom_init "new" + _i2c_sfp_eeprom_init "new" + _i2c_mb_eeprom_init "new" + _i2c_cb_eeprom_init "new" + _i2c_fan_speed_init + _i2c_led_psu_status_set + _i2c_led_fan_status_set + + # clear port led + _util_port_led_clear + + # rov for mac init + _mac_vdd_init + + # trun on sys led + echo "led_sys setup..." + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + + _config_rmem +} + +function _mac_vdd_init { + # read mac vid register value from CPLD + cpld_index=1 + _i2c_cpld_reg_read ${cpld_index} ${CPLD_ROV_STATUS_KEY} + # get vid form register value [0:2] + vid=$(($cpld_reg_val & 0x7)) + # get rov val and reg according to vid + rov_val=${rov_val_array[$vid]} + rov_reg=${rov_reg_array[$vid]} + echo "vid=${vid}, rov_val=${rov_val}, rov_reg=${rov_reg}" + + # write the rov reg to rov + i2cset -y -r ${I2C_BUS_ROV} ${I2C_ADDR_ROV} 0x21 ${rov_reg} w + + if [ $? -eq 0 ]; then + echo "set ROV for mac vdd done" + else + echo "set ROV for mac vdd fail" + fi +} + +#I2C Deinit +function _i2c_deinit { + echo "i2c deinit..." + for mod in coretemp jc42 w83795 ingrasys_s9280_64x_psu ingrasys_s9280_64x_i2c_cpld eeprom eeprom_mb gpio-pca953x i2c_mux_pca954x i2c_i801; + do + _util_rmmod $mod + done + echo "Done" +} + +function _i2c_cpld_init { + echo "CPLD init..." + _util_rmmod ingrasys_s9280_64x_i2c_cpld + modprobe ingrasys_s9280_64x_i2c_cpld + + # add cpld 1~5 to sysfs + for i in {1..5}; + do + local cpld_bus="I2C_BUS_CPLD${i}" + local cpld_path="PATH_CPLD${i}_DEVICE" + dev_path="${PATH_SYS_I2C_DEVICES}/${!cpld_bus}-$(printf "%04x" ${I2C_ADDR_CPLD})" + if ! [ -L ${dev_path} ]; then + echo "ingrasys_cpld${i} ${I2C_ADDR_CPLD}" > ${!cpld_path}/new_device + else + echo "${dev_path} already exist" + fi + done + + echo "Done" +} + +function _i2c_sensors_init { + echo "SENSORS init..." + local dev_path + # to make sure hwmon index in sysfs as expected, + # need to remove kernel module and then probe them in expected order + # remove all sensors kernel module + _util_rmmod coretemp + _util_rmmod jc42 + _util_rmmod w83795 + # probe coretemp kernel module + modprobe coretemp #hwmon0 + # probe hwmon kernel module + modprobe w83795 + # add w83795 to sysfs + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_1_CH7}-$(printf "%04x" ${I2C_ADDR_W83795})" + if ! [ -L ${dev_path} ]; then + echo "w83795adg ${I2C_ADDR_W83795}" > ${PATH_MUX_9548_1_CH7}/new_device #hwmon1 + sleep 0.1 + else + echo "${dev_path} already exist" + fi + # add lm75/lm86 to sysfs + ####Main board thermal + ####lm75_1 + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH5}-$(printf "%04x" ${I2C_ADDR_LM75_1})" + if ! [ -L ${dev_path} ]; then + echo "lm75 ${I2C_ADDR_LM75_1}" > ${PATH_MUX_9548_0_CH5}/new_device # hwmon2 + sleep 0.1 + else + echo "${dev_path} already exist" + fi + ####lm75_2 + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH5}-$(printf "%04x" ${I2C_ADDR_LM75_2})" + if ! [ -L ${dev_path} ]; then + echo "lm75 ${I2C_ADDR_LM75_2}" > ${PATH_MUX_9548_0_CH5}/new_device #hwmon3 + sleep 0.1 + else + echo "${dev_path} already exist" + fi + ####lm86 + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH5}-$(printf "%04x" ${I2C_ADDR_LM86})" + if ! [ -L ${dev_path} ]; then + echo "lm86 ${I2C_ADDR_LM86}" > ${PATH_MUX_9548_0_CH5}/new_device #hwmon4 + sleep 0.1 + else + echo "${dev_path} already exist" + fi + ####lm75_3 + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH6}-$(printf "%04x" ${I2C_ADDR_LM75_3})" + if ! [ -L ${dev_path} ]; then + echo "lm75 ${I2C_ADDR_LM75_3}" > ${PATH_MUX_9548_0_CH6}/new_device # hwmon5 + sleep 0.1 + else + echo "${dev_path} already exist" + fi + ####lm75_4 + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH6}-$(printf "%04x" ${I2C_ADDR_LM75_4})" + if ! [ -L ${dev_path} ]; then + echo "lm75 ${I2C_ADDR_LM75_4}" > ${PATH_MUX_9548_0_CH6}/new_device #hwmon6 + sleep 0.1 + else + echo "${dev_path} already exist" + fi + ####BMC board thermal + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_1_CH7}-$(printf "%04x" ${I2C_ADDR_TMP75_BB})" + if ! [ -L ${dev_path} ]; then + echo "tmp75 ${I2C_ADDR_TMP75_BB}" > ${PATH_MUX_9548_1_CH7}/new_device #hwmon7 + sleep 0.1 + else + echo "${dev_path} already exist" + fi + ####CPU board thermal + dev_path="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MAIN}-$(printf "%04x" ${I2C_ADDR_TMP75_CB})" + if ! [ -L ${dev_path} ]; then + echo "tmp75 ${I2C_ADDR_TMP75_CB}" > ${PATH_I801_DEVICE}/new_device #hwmon8 + sleep 0.1 + else + echo "${dev_path} already exist" + fi + + # probe jc42 kernel module + modprobe jc42 #hwmon9 + + echo "Done" +} + +#FAN Speed Init +function _i2c_fan_speed_init { + echo -n "FAN SPEED INIT..." + if [ -e "${PATH_HWMON_W83795_DEVICE}" ]; then + # init fan speed + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm2 + echo "SUCCESS" + else + echo "FAIL" + fi +} + +# HWM init +function _i2c_hwm_init { + echo "HWM INIT..." + # select bank0 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x80 + # SW reset, Disable monitor + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x01 0x9C + # disable TR5/TR6 DTS + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x04 0x0 + # enable FANIN1~8 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x06 0xFF + # disable FANIN9~14 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x07 0x00 + # CLKIN clock frequency set as 48Mhz + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x01 0x1C + # select bank 2 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x82 + # set PWM mode in FOMC + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x0F 0x00 + # set 25KHz fan output frequency in F1OPFP&F2OPFP + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x18 0x84 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x19 0x84 +} + +#IO Expander Init +function _i2c_io_exp_init { + echo "=========================================================" + echo "# Description: I2C IO Expender Init" + echo "=========================================================" + + # need to init BMC io expander first due to some io expander are reset default + echo "Init BMC INT & HW ID IO Expander" + # all input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_1} ${REG_PORT0_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_1} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_1} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_1} ${REG_PORT1_POL} 0x00 + + echo "Init BMC PSU status IO Expander" + # PWRON default 0 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT0_OUT} 0x00 + # default 0 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT1_OUT} 0x00 + # I/O 0.2 0.5 output(PWRON), rest input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT0_DIR} 0xDB + # I/O 1.0~1.1 input, 1.2~1.4 output (1.5~1.7 not enable) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT1_DIR} 0xE3 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT1_POL} 0x00 + + echo "Init BMC RST and SEL IO Expander" + # RST default is 1 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT0_OUT} 0x3F + # SEL default is 0 (HOST), EN default is 1 (ACTIVE_HIGH) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT1_OUT} 0x1F + # I/O 0.0~0.5 output, 0.6~0.7 not use + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT0_DIR} 0xD0 + # all output + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT1_DIR} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT1_POL} 0x00 + + echo "Init System LED & HW ID IO Expander" + # I/O_0.x for System LED default 0, I/O_1.x for HW ID + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT0_OUT} 0x00 + # System LED => all output + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT0_DIR} 0x00 + # HW ID => all input + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT1_POL} 0x00 + + echo "Init FAN Board Status IO Expander" + # LED_G_H set to 1, LED_Y_G set to 0 (ACTIVE_HIGH) + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT0_OUT} 0x11 + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT1_OUT} 0x11 + # DIR/ABS is input, LED_Y/LED_G is output + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT0_DIR} 0xCC + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT1_DIR} 0xCC + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT1_POL} 0x00 + + echo "Init System SEL and RST IO Expander" + # default 0 (ACTIVE high) + # 0.4~0.5 SEL set to value 0 (host) + # 0.2 LED_CLR set to 0 will clear all switch LED bitmap, set to 1 here + _util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_OUT} 0x04 + # RST 1.6~1.7 default 1 (ACTIVE low), INT 1.0~1.4 default 1 (ACTIVE low) + _util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_OUT} 0xDF + # all output, but ISO_TF_CORE_RST_N 0.0 need to set as input to prevent reboot issue + _util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_DIR} 0x09 + # RST 1.6~1.7 output, rest are input + _util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_DIR} 0x3F + _util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_POL} 0x00 + + echo "Init CPU CPLD IO Expander (FIXME)" + # all input + #echo "NUM_MUX_9546_1_CH3=${NUM_MUX_9546_1_CH3}, I2C_ADDR_MUX_9539_2=${I2C_ADDR_MUX_9539_2}" + #_util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_DIR} 0xFF + # all input + #_util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_DIR} 0xFF + #_util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_POL} 0x00 + #_util_i2cset -y -r ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_POL} 0x00 +} + +#Set FAN Tray LED +function _i2c_led_fan_tray_status_set { + echo "FAN Tray Status Setup" + #FAN Status get + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + + # check if io expander for fan tray exist + result=`i2cget -y ${I2C_BUS_FANTRAY_LED} ${I2C_ADDR_MUX_9555_0} ${REG_PORT0_IN} 2>/dev/null` + err_code=$? + if [ "$err_code" != "0" ]; then + echo "fan tray not exist!" + return + fi + + for FAN_TRAY in {1..4}; + do + FAN_ALARM="FAN${FAN_TRAY}_ALARM" + if [ "${!FAN_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="off" + _i2c_fan_tray_led + + echo "set [FAN TRAY ${FAN_TRAY}] [Green]=on [Amber]=off" + else + COLOR_LED="green" + ONOFF_LED="off" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_fan_tray_led + + echo "set [FAN TRAY ${FAN_TRAY}] [Green]=off [Amber]=on" + fi + done +} + +#Set FAN LED +function _i2c_led_fan_status_set { + echo "FAN Status Setup" + #PSU Status set + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + + echo "led_fan setup..." + # all fan ok + if [ "${FAN1_ALARM}" == "0" ] \ + && [ "${FAN3_ALARM}" == "0" ] \ + && [ "${FAN5_ALARM}" == "0" ] \ + && [ "${FAN7_ALARM}" == "0" ]; then + COLOR_LED="green" + echo "${COLOR_LED}" + _i2c_fan_led + # all fan fail + elif [ "${FAN1_ALARM}" == "1" ] \ + && [ "${FAN3_ALARM}" == "1" ] \ + && [ "${FAN5_ALARM}" == "1" ] \ + && [ "${FAN7_ALARM}" == "1" ] ; then + COLOR_LED="amber" + echo "${COLOR_LED}" + _i2c_fan_led + # partial fan fail + else + COLOR_LED="amber" + echo "${COLOR_LED}" + _i2c_fan_led + fi + # if fan not present, no led need to be set +} + +#Set Power Supply LED +function _i2c_led_psu_status_set { + echo "PSU LED Status Setup" + + #PSU Status set + _i2c_psu_status + + #PSU1 Status + echo "led_psu1 setup..." + if [ "${psu1Exist}" == ${PSU_EXIST} ]; then + if [ "${psu1PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + echo "${COLOR_LED}" + _i2c_psu1_led + else + COLOR_LED="amber" + echo "${COLOR_LED}" + _i2c_psu1_led + fi + else + COLOR_LED="off" + echo "${COLOR_LED}" + _i2c_psu1_led + fi + + #PSU2 Status + echo "led_psu2 setup..." + if [ "${psu2Exist}" == ${PSU_EXIST} ]; then + if [ "${psu2PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + echo "${COLOR_LED}" + _i2c_psu2_led + else + COLOR_LED="amber" + echo "${COLOR_LED}" + _i2c_psu2_led + fi + else + COLOR_LED="off" + echo "${COLOR_LED}" + _i2c_psu2_led + fi +} + +#LED Test +function _i2c_led_test { + echo "=========================================================" + echo "# Description: I2C SYSTEM LED TEST..." + echo "=========================================================" + + #sys led (green) + COLOR_LED="green" + _i2c_sys_led + _pause 'Check SYS LED green light and Press [Enter] key to continue...' + #sys led (amber) + COLOR_LED="amber" + _i2c_sys_led + _pause 'Check SYS LED amber light and Press [Enter] key to continue...' + + #FAN led (green) + COLOR_LED="green" + _i2c_fan_led + _pause 'Check FAN LED green light and Press [Enter] key to continue...' + #FAN led (amber) + COLOR_LED="amber" + _i2c_fan_led + _pause 'Check FAN LED amber light and Press [Enter] key to continue...' + + #PSU1 led (green) + COLOR_LED="green" + _i2c_psu1_led + _pause 'Check PSU1 LED green light and Press [Enter] key to continue...' + #PSU1 led (amber) + COLOR_LED="amber" + _i2c_psu1_led + _pause 'Check PSU1 LED amber light and Press [Enter] key to continue...' + + #PSU2 led (green) + COLOR_LED="green" + _i2c_psu2_led + _pause 'Check PSU2 LED green light and Press [Enter] key to continue...' + #PSU2 led (amber) + COLOR_LED="amber" + _i2c_psu2_led + _pause 'Check PSU2 LED amber light and Press [Enter] key to continue...' + + #Turn OFF All LED (can't trun off system led) + COLOR_LED="off" + _i2c_sys_led + _i2c_fan_led + _i2c_psu1_led + _i2c_psu2_led + _pause 'Check turn off all LEDs (exclude SYS LED) and Press [Enter] key to continue...' + + # restore sys led + COLOR_LED="green" + _i2c_sys_led +} + +#Set QSFP Port cpld variable +function _qsfp_cpld_var_set { + local port=$1 + local reg_port_base + local reg_port_shift + + echo "_qsfp_cpld_var_set port=$port" + if [[ $1 -le 12 && $1 -ge 1 ]]; then + cpld_index=1 + reg_port_base=0 + elif [[ $1 -le 25 && $1 -ge 13 ]]; then + cpld_index=2 + reg_port_base=12 + elif [[ $1 -le 38 && $1 -ge 26 ]]; then + cpld_index=3 + reg_port_base=25 + elif [[ $1 -le 51 && $1 -ge 39 ]]; then + cpld_index=4 + reg_port_base=38 + elif [[ $1 -le 64 && $1 -ge 52 ]]; then + cpld_index=5 + reg_port_base=51 + else + echo "invalid port number" + fi + + cpld_port_index=$(( $port - $reg_port_base )) +} + +#Set QSFP Port eeporm variable +function _qsfp_eeprom_var_set { + local port=$1 + local eeprombusbase + local eeprombusshift + # port 1 => zqsfp0 + # port 2 => zqsfp1 + # ... + local port_group=$(( ($port - 1) / 8 )) + + case ${port_group} in + 0) + eeprombusbase=${NUM_MUX_9548_3_CH0} + ;; + 1) + eeprombusbase=${NUM_MUX_9548_4_CH0} + ;; + 2) + eeprombusbase=${NUM_MUX_9548_5_CH0} + ;; + 3) + eeprombusbase=${NUM_MUX_9548_6_CH0} + ;; + 4) + eeprombusbase=${NUM_MUX_9548_7_CH0} + ;; + 5) + eeprombusbase=${NUM_MUX_9548_8_CH0} + ;; + 6) + eeprombusbase=${NUM_MUX_9548_9_CH0} + ;; + 7) + eeprombusbase=${NUM_MUX_9548_10_CH0} + ;; + *) + ;; + esac + + eeprombusshift=$(( (${port} - 1) % 8)) + eepromBus=$(( ${eeprombusbase} + ${eeprombusshift} )) + eepromAddr=${I2C_ADDR_QSFP_EEPROM} +} + + +#Set SFP Port cpld variable +function _sfp_cpld_var_set { + local port=$1 + case ${port} in + 1) + cpld_index=1 + ;; + 2) + cpld_index=1 + ;; + *) + ;; + esac +} + +#Set QSFP Port eeporm variable +function _sfp_eeprom_var_set { + local port=$1 + + case ${port} in + 1) + eepromBus=${NUM_MUX_9546_1_CH0} + ;; + 2) + eepromBus=${NUM_MUX_9546_1_CH1} + ;; + *) + ;; + esac + + eepromAddr=${I2C_ADDR_SFP_EEPROM} +} + +#Get QSFP EEPROM Information +function _i2c_qsfp_eeprom_get { + local phy_port=0 + + # input parameter validation + _util_input_check ${QSFP_PORT} ${MIN_QSFP_PORT_NUM} ${MAX_QSFP_PORT_NUM} + + #get physical port + phy_port=$(_port_fp2phy $QSFP_PORT) + + _qsfp_eeprom_var_set ${phy_port} + + _util_get_qsfp_abs + + if [ $status = 0 ]; then + exit + fi + + # debug + echo "${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf '%04x' $eepromAddr)/eeprom | hexdump -C" + cat ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C +} + +#Init QSFP EEPROM +function _i2c_qsfp_eeprom_init { + echo "QSFP EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init 1-64 ports EEPROM + local i + for i in {1..64}; + do + + #get physical port + phy_port=$(_port_fp2phy $i) + + _qsfp_eeprom_var_set ${phy_port} + + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr) ]; then + echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/new_device + #echo "optoe1 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr) ]; then + echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/delete_device + fi + done + echo "Done" +} + +#Get SFP EEPROM Information +function _i2c_sfp_eeprom_get { + + # input parameter validation + _util_input_check ${SFP_PORT} ${MIN_SFP_PORT_NUM} ${MAX_SFP_PORT_NUM} + _util_get_sfp_pres + + if [ $status = 0 ]; then + exit + fi + + _sfp_eeprom_var_set ${SFP_PORT} + + cat ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C +} + +#Init SFP EEPROM +function _i2c_sfp_eeprom_init { + echo "SFP EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init 1-2 sfp+ EEPROM + local i + for i in {1..2}; + do + _sfp_eeprom_var_set ${i} + + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr) ]; then + echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/new_device + #echo "optoe1 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr) ]; then + echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/delete_device + fi + done + echo "Done" +} + +#Init Main Board EEPROM +function _i2c_mb_eeprom_init { + echo -n "Main Board EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init mb EEPROM + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM) ]; then + echo "mb_eeprom ${I2C_ADDR_MB_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_MB_EEPROM}/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM) ]; then + echo "$I2C_ADDR_MB_EEPROM" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_MB_EEPROM}/delete_device + fi + echo "Done" +} + +#Init CPU Board EEPROM +function _i2c_cb_eeprom_init { + echo -n "CPU Board EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init cpu EEPROM + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM) ]; then + echo "mb_eeprom ${I2C_ADDR_CB_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CB_EEPROM}/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM) ]; then + echo "$I2C_ADDR_CB_EEPROM" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CB_EEPROM}/delete_device + fi + echo "Done" +} + +#Init PSU Kernel Module +function _i2c_psu_init { + echo "=========================================================" + echo "# Description: I2C PSU Init" + echo "=========================================================" + modprobe ingrasys_s9280_64x_psu + + echo "psu1 ${I2C_ADDR_PSU1_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU1_EEPROM}/new_device + echo "psu2 ${I2C_ADDR_PSU2_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU2_EEPROM}/new_device +} + +#Deinit PSU Kernel Module +function _i2c_psu_deinit { + echo "${I2C_ADDR_PSU1_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU1_EEPROM}/delete_device + echo "${I2C_ADDR_PSU2_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU2_EEPROM}/delete_device + _util_rmmod ingrasys_s9280_64x_psu +} + +#get QSFP Status +function _i2c_qsfp_status_get { + + # input parameter validation + _util_input_check ${QSFP_PORT} ${MIN_QSFP_PORT_NUM} ${MAX_QSFP_PORT_NUM} + + local stat + _util_get_qsfp_abs + echo "status=$status" +} + +#get QSFP Type +function _i2c_qsfp_type_get { + local phy_port=0 + + phy_port=$(_port_fp2phy ${QSFP_PORT}) + + # input parameter validation + _util_input_check ${QSFP_PORT} ${MIN_QSFP_PORT_NUM} ${MAX_QSFP_PORT_NUM} + + _qsfp_eeprom_var_set ${phy_port} + + #Get QSFP EEPROM info + qsfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr)/eeprom) + + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + + echo "identifier=$identifier" + echo "connector=$connector" + echo "transceiver=$transceiver" +} + +function _i2c_sfp_status_get { + + # input parameter validation + _util_input_check ${SFP_PORT} ${MIN_SFP_PORT_NUM} ${MAX_SFP_PORT_NUM} + + local stat + _util_get_sfp_pres + #status: 0 -> Down, 1 -> Up + if [ $status = 0 ]; then + stat="down" + else + stat="up" + fi + echo "status is $stat" +} + +#get SFP Type +function _i2c_sfp_type_get { + + # input parameter validation + _util_input_check ${SFP_PORT} ${MIN_SFP_PORT_NUM} ${MAX_SFP_PORT_NUM} + + _sfp_eeprom_var_set ${SFP_PORT} + + #Get QSFP EEPROM info + sfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr)/eeprom) + + identifier=$(echo $sfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $sfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $sfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + + echo "identifier=$identifier" + echo "connector=$connector" + echo "transceiver=$transceiver" +} + +#Get PSU EEPROM Information +function _i2c_psu_eeprom_get { + local eeprom_psu1="" + local eeprom_psu2="" + + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Get..." + echo "=========================================================" + + eeprom_psu1="${PATH_SYSFS_PSU1}/psu_eeprom" + cat ${eeprom_psu1} | hexdump -C + + eeprom_psu2="${PATH_SYSFS_PSU2}/psu_eeprom" + cat ${eeprom_psu2} | hexdump -C +} + +#Get Main Board EEPROM Information +function _i2c_mb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C MB EEPROM Get..." + echo "=========================================================" + _i2c_sys_eeprom_get mb +} + +#Get CPU Board EEPROM Information +function _i2c_cb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C CB EEPROM Get..." + echo "=========================================================" + _i2c_sys_eeprom_get cb +} + +#Get system EEPROM Information +##input: "cb" for cpu board, "mb" for main board +function _i2c_sys_eeprom_get { + local eeprom_dev + + if [ "$1" == "cb" ]; then + eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM)/eeprom" + elif [ "$1" == "mb" ]; then + eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM)/eeprom" + else + echo "wrong eeprom type" + return + fi + + # check if eeprom device exist in sysfs + if [ ! -f ${eeprom_dev} ]; then + echo "eeprom device not init" + return + fi + + cat ${eeprom_dev} | hexdump -C + echo "Done" +} + +#sync eeprom content between mb and cb eeprom +function _i2c_eeprom_sync { + echo "=========================================================" + echo "# Description: EEPROM sync..." + echo "=========================================================" + + local mb_eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM)/eeprom" + local cb_eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM)/eeprom" + + # check if eeprom device exist in sysfs + if [[ ! -f ${mb_eeprom_dev} || ! -f ${cb_eeprom_dev} ]]; then + echo "eeprom device not init" + return + fi + + ## check if MB eeprom is empty + if [ ! -z "$(cat ${mb_eeprom_dev} | hexdump -n2 | grep ffff)" ]; then + echo "copy cb eeprom to mb eeprom..." + cat ${cb_eeprom_dev} > ${mb_eeprom_dev} + else + echo "no need to sync" + fi + + echo "Done" +} + +#Set System Status LED +function _i2c_sys_led { + # only green/amber, on/off can't control + if [ "${COLOR_LED}" == "green" ]; then + # set sys_led_g (0.7) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x80 + value=0x80 + elif [ "${COLOR_LED}" == "amber" ]; then + # set sys_led_g (0.7) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x80 + value=0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set FAN LED +function _i2c_fan_led { + if [ "${COLOR_LED}" == "green" ]; then + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x40 + elif [ "${COLOR_LED}" == "amber" ]; then + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x60 + elif [ "${COLOR_LED}" == "off" ]; then + # set fan_led_en (0.6) = 0 & fan_led_y (0.5) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set PSU1 LED +function _i2c_psu1_led { + if [ "${COLOR_LED}" == "green" ]; then + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x18 + elif [ "${COLOR_LED}" == "off" ]; then + # set psu1_pwr_ok_oe (0.4) = 0 & psu1_led_y (0.3) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set PSU2 LED +function _i2c_psu2_led { + if [ "${COLOR_LED}" == "green" ]; then + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x04 + elif [ "${COLOR_LED}" == "amber" ]; then + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x06 + elif [ "${COLOR_LED}" == "off" ]; then + # set psu0_pwr_ok_oe (0.2) = 0 & psu0_led_y (0.1) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set FAN Tray LED +function _i2c_fan_tray_led { + + i2cAddr=${I2C_ADDR_MUX_9555_0} + output_reg=${REG_PORT0_OUT} + + case ${FAN_TRAY} in + 1) + output_reg=${REG_PORT0_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 2) + output_reg=${REG_PORT0_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + 3) + output_reg=${REG_PORT1_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 4) + output_reg=${REG_PORT1_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + *) + echo "Please input 1~4" + exit + ;; + esac + + # LED PIN value is ACTIVE HIGH + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0xff + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0xff + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "Done" +} + +#Get Board Version and Type +function _i2c_board_type_get { + # read input port 1 value from io expander + input_reg=${REG_PORT1_IN} + boardType=`i2cget -y ${I2C_BUS_HW_ID} ${I2C_ADDR_MUX_9539_0} ${input_reg}` + boardBuildRev=$((($boardType) & 0x03)) + boardHwRev=$((($boardType) >> 2 & 0x03)) + boardId=$((($boardType) >> 4)) + printf "MAIN_BOARD BOARD_ID is 0x%02x, HW Rev 0x%02x, Build Rev 0x%02x\n" $boardId $boardHwRev $boardBuildRev +} + +#Get BMC Board Version and Type +function _i2c_bmc_board_type_get { + # read input port 1 value from io expander + input_reg=${REG_PORT1_IN} + boardType=`i2cget -y ${I2C_BUS_BMC_HW_ID} ${I2C_ADDR_MUX_9555_1} ${input_reg}` + boardBuildRev=$((($boardType) & 0x03)) + boardHwRev=$((($boardType) >> 2 & 0x03)) + boardId=$((($boardType) >> 4)) + printf "BMC_BOARD BOARD_ID is 0x%02x, HW Rev 0x%02x, Build Rev 0x%02x\n" $boardId $boardHwRev $boardBuildRev +} + +#Get CPLD Version +function _i2c_cpld_version { + echo "=========================================================" + echo "# Description: CPLD Version" + echo "=========================================================" + + for i in {1..5}; + do + local cpld_bus="I2C_BUS_CPLD${i}" + local cpld_path="PATH_CPLD${i}_DEVICE" + local file_path="${PATH_SYS_I2C_DEVICES}/${!cpld_bus}-$(printf "%04x" ${I2C_ADDR_CPLD})/cpld_version" + printf "[CPLD %d] %s\n" ${i} $(cat ${file_path}) + done +} + +#Get PSU Status +function _i2c_psu_status { + local psu_abs="" + + psu1PwGood=`cat ${PATH_SYSFS_PSU1}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU1}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu1Exist=1 + else + psu1Exist=0 + fi + + psu2PwGood=`cat ${PATH_SYSFS_PSU2}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU2}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu2Exist=1 + else + psu2Exist=0 + fi + + printf "PSU1 Exist:%x PSU1 PW Good:%d\n" $psu1Exist $psu1PwGood + printf "PSU2 Exist:%d PSU2 PW Good:%d\n" $psu2Exist $psu2PwGood +} + +#Get register value from CPLD +function _i2c_cpld_reg_read { + local idx=$1 + local file_name=$2 + local cpld_i2c_addr=${I2C_ADDR_CPLD} + local reg_file_path + + case ${idx} in + 1) + cpld_i2c_bus=${I2C_BUS_CPLD1} + ;; + 2) + cpld_i2c_bus=${I2C_BUS_CPLD2} + ;; + 3) + cpld_i2c_bus=${I2C_BUS_CPLD3} + ;; + 4) + cpld_i2c_bus=${I2C_BUS_CPLD4} + ;; + 5) + cpld_i2c_bus=${I2C_BUS_CPLD5} + ;; + *) + echo "invalid cpld index" + exit + ;; + esac + + reg_file_path="${PATH_SYS_I2C_DEVICES}/${cpld_i2c_bus}-$(printf "%04x" ${cpld_i2c_addr})/${file_name}" + cpld_reg_val=`cat ${reg_file_path}` + # TODO: debug + echo "cat ${reg_file_path} => ${cpld_reg_val}" +} + +#util functions +function _util_i2cset { + if [ "$DEBUG" == "on" ]; then + i2cset $@ + else + i2cset $@ 1>/dev/null + fi +} + +function _i2c_set { + local i2c_bus=$1 + local i2c_addr=$2 + local reg=$3 + local mask=$4 + local value=$5 + + echo `i2cset -m $mask -y -r ${i2c_bus} ${i2c_addr} ${reg} ${value}` +} + +function _util_rmmod { + local mod=$1 + [ "$(lsmod | grep "^$mod ")" != "" ] && rmmod $mod +} + +# get qsfp presence +function _util_get_qsfp_abs { + local phy_port=0 + + #get physical port + phy_port=$(_port_fp2phy $QSFP_PORT) + + echo "fp port $QSFP_PORT => phy port $phy_port" + # read status from cpld + _qsfp_cpld_var_set ${phy_port} + cpld_reg_file_name="${CPLD_QSFP_STATUS_KEY}_${cpld_port_index}" + _i2c_cpld_reg_read ${cpld_index} ${cpld_reg_file_name} + #status: 0 -> Down, 1 -> Up (ACTIVE_LOW in ABS_BIT) + status=$(( $(( $((${cpld_reg_val})) & (1 << ($CPLD_QSFP_STATUS_ABS_BIT)) ))?0:1 )) +} + +# get sfp presence +function _util_get_sfp_pres { + local pres_bit + # read status from cpld + _sfp_cpld_var_set ${SFP_PORT} + cpld_reg_file_name="${CPLD_SFP_STATUS_KEY}" + _i2c_cpld_reg_read ${cpld_index} ${cpld_reg_file_name} + if [ "${SFP_PORT}" == "1" ]; then + pres_bit=${CPLD_SFP0_STATUS_PRES_BIT} + else + pres_bit=${CPLD_SFP1_STATUS_PRES_BIT} + fi + #status: 0 -> Down, 1 -> Up (ACTIVE_LOW in PRES_BIT) + status=$(( $(( $((${cpld_reg_val})) & (1 << ($pres_bit)) ))?0:1 )) +} + +# valid input number +function _util_input_check { + # input parameter validation + if [[ $1 -lt $2 || $1 -gt $3 ]]; then + echo "Please input number $2~$3" + exit + fi +} + +# clear all switch port led bitmap +function _util_port_led_clear { + echo "port led clear..." + # gpio pin on GPIO MUX PCA9539#1 I/O 0.2 + # pull low to reset bitamp + output_reg=${REG_PORT0_OUT} + mask=0x04 + value=0x00 + _util_i2cset -m ${mask} -y ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_1} ${output_reg} ${value} + sleep 1 + # pull high to out of reset + value=0xFF + _util_i2cset -m ${mask} -y ${NUM_MUX_9546_1_CH3} ${I2C_ADDR_MUX_9539_1} ${output_reg} ${value} + echo "Done" +} + +#Increase read socket buffer for CoPP Test +function _config_rmem { + echo "109430400" > /proc/sys/net/core/rmem_max +} + +#Main Function +function _main { + tart_time_str=`date` + start_time_sec=$(date +%s) + + if [ "${EXEC_FUNC}" == "help" ]; then + _help + elif [ "${EXEC_FUNC}" == "i2c_init" ]; then + _i2c_init + elif [ "${EXEC_FUNC}" == "i2c_deinit" ]; then + _i2c_deinit + elif [ "${EXEC_FUNC}" == "i2c_fan_speed_init" ]; then + _i2c_fan_speed_init + elif [ "${EXEC_FUNC}" == "i2c_io_exp_init" ]; then + _i2c_io_exp_init + elif [ "${EXEC_FUNC}" == "i2c_led_test" ]; then + _i2c_led_test + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_get" ]; then + _i2c_mb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_cb_eeprom_get" ]; then + _i2c_cb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_eeprom_sync" ]; then + _i2c_eeprom_sync + elif [ "${EXEC_FUNC}" == "i2c_psu_eeprom_get" ]; then + _i2c_psu_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_get" ]; then + _i2c_qsfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_sfp_eeprom_get" ]; then + _i2c_sfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_init" ]; then + _i2c_qsfp_eeprom_init ${QSFP_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_sfp_eeprom_init" ]; then + _i2c_sfp_eeprom_init ${SFP_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_init" ]; then + _i2c_mb_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_cb_eeprom_init" ]; then + _i2c_cb_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_qsfp_status_get" ]; then + _i2c_qsfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_sfp_status_get" ]; then + _i2c_sfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_type_get" ]; then + _i2c_qsfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_sfp_type_get" ]; then + _i2c_sfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_led_psu_status_set" ]; then + _i2c_led_psu_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_status_set" ]; then + _i2c_led_fan_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_status_set" ]; then + _i2c_led_fan_tray_status_set + elif [ "${EXEC_FUNC}" == "i2c_sys_led" ]; then + _i2c_sys_led + elif [ "${EXEC_FUNC}" == "i2c_fan_led" ]; then + _i2c_fan_led + elif [ "${EXEC_FUNC}" == "i2c_fan_tray_led" ]; then + _i2c_fan_tray_led + elif [ "${EXEC_FUNC}" == "i2c_psu1_led" ]; then + _i2c_psu1_led + elif [ "${EXEC_FUNC}" == "i2c_psu2_led" ]; then + _i2c_psu2_led + elif [ "${EXEC_FUNC}" == "i2c_board_type_get" ]; then + _i2c_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_bmc_board_type_get" ]; then + _i2c_bmc_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_cpld_version" ]; then + _i2c_cpld_version + elif [ "${EXEC_FUNC}" == "i2c_psu_status" ]; then + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_test_all" ]; then + _i2c_init + _i2c_led_test + _i2c_psu_eeprom_get + _i2c_mb_eeprom_get + _i2c_cb_eeprom_get + _i2c_board_type_get + _i2c_bmc_board_type_get + _i2c_cpld_version + _i2c_psu_status + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + if [ "$DEBUG" == "on" ]; then + echo "-----------------------------------------------------" + end_time_str=`date` + end_time_sec=$(date +%s) + diff_time=$[ ${end_time_sec} - ${start_time_sec} ] + echo "Start Time: ${start_time_str} (${start_time_sec})" + echo "End Time : ${end_time_str} (${end_time_sec})" + echo "Total Execution Time: ${diff_time} sec" + + echo "done!!!" + fi +} + +_main diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh new file mode 100755 index 000000000000..23a3fd066bee --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh @@ -0,0 +1,105 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, Inc. +# +# This program 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +INTERVAL=3 +I2C_UTILS="/usr/sbin/i2c_utils.sh" +QSFP_SI_SCRIPT="/usr/sbin/qsfp_si_cfg.sh" +QSFP_ARRAY=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \ + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +#QSFP SI monitor +function _qsfp_si_monitor { + local i + local status + for i in {0..63}; + do + status=`${I2C_UTILS} i2c_qsfp_status_get $(expr $i + 1) | egrep '^status=.*$' | sed -e 's/status=//g'` + if [ "${status}" == "1" ]; then + _qsfp_type_check $i + fi + done +} + +#QSFP type +function _qsfp_type_check { + local port=$1 + local qsfp_type=`${I2C_UTILS} i2c_qsfp_type_get $(expr $port + 1)` + local identifier=`echo "$qsfp_type" | grep '^identifier=.*$' | sed -e 's/identifier=//g'` + if [ "${identifier}" == "11" ]; then + connector=`echo "$qsfp_type" | grep '^connector=.*$' | sed -e 's/connector=//g'` + case ${connector} in + 21|23) + #DAC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to DAC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} dac $port >/dev/null + fi + ;; + *) + #Optical + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to Optical" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} optical $port >/dev/null + fi + ;; + esac + fi +} + +#Docker exist check +function _docker_swss_check { + while true + do + # Check if syncd starts + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + if [ "$result" == "3" ]; then + return + fi + sleep $INTERVAL + done +} + +#Docker exist check +function _qsfp_si_cfg_script_check { + + if [ -f ${QSFP_SI_SCRIPT} ] && [ -x ${QSFP_SI_SCRIPT} ]; then + echo "SI Script exists. Start monitor." + return + else + echo "SI Script not exist. Exit monitor." + exit + fi +} + +# main function +function _main { + #Check SI Script + _qsfp_si_cfg_script_check + #Check docker swss is running + _docker_swss_check + while true + do + _qsfp_si_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main + diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/s9280_64x_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/s9280_64x_monitor.sh new file mode 100755 index 000000000000..eedf685b290b --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/s9280_64x_monitor.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Copyright (C) 2016 Ingrasys, Inc. +# +# This program 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +INTERVAL=5 +I2C_UTILS="/usr/sbin/i2c_utils.sh" + + +# TBD: LED status monitor +function _led_monitor { + ${I2C_UTILS} i2c_led_fan_status_set >/dev/null + ${I2C_UTILS} i2c_led_psu_status_set >/dev/null + ${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null +} + +# main function +function _main { + while true + do + #PSU controlled by dummy board, + #but fan LED and fan tray LED must controlled by this service + _led_monitor + + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main