Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DellEMC S6100 : Platform2.0 API implementation [Module, Thermal] #3363

Merged
merged 5 commits into from
Sep 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__all__ = ["platform", "chassis", "fan", "psu", "sfp"]
__all__ = ["platform", "chassis", "module", "fan", "psu", "sfp", "thermal"]
from sonic_platform import *

Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@
from sonic_platform.sfp import Sfp
from sonic_platform.psu import Psu
from sonic_platform.fan import Fan
from sonic_platform.module import Module
from sonic_platform.thermal import Thermal
from eeprom import Eeprom
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

MAX_S6100_MODULE = 4
MAX_S6100_FAN = 4
MAX_S6100_PSU = 2
MAX_S6100_THERMAL = 10


class Chassis(ChassisBase):
Expand All @@ -38,39 +42,6 @@ class Chassis(ChassisBase):
HWMON_NODE = os.listdir(HWMON_DIR)[0]
MAILBOX_DIR = HWMON_DIR + HWMON_NODE

PORT_START = 0
PORT_END = 63
PORTS_IN_BLOCK = (PORT_END + 1)
IOM1_PORT_START = 0
IOM2_PORT_START = 16
IOM3_PORT_START = 32
IOM4_PORT_START = 48

PORT_I2C_MAPPING = {}
# 0th Index = i2cLine, 1st Index = EepromIdx in i2cLine
EEPROM_I2C_MAPPING = {
# IOM 1
0: [6, 66], 1: [6, 67], 2: [6, 68], 3: [6, 69],
4: [6, 70], 5: [6, 71], 6: [6, 72], 7: [6, 73],
8: [6, 74], 9: [6, 75], 10: [6, 76], 11: [6, 77],
12: [6, 78], 13: [6, 79], 14: [6, 80], 15: [6, 81],
# IOM 2
16: [8, 34], 17: [8, 35], 18: [8, 36], 19: [8, 37],
20: [8, 38], 21: [8, 39], 22: [8, 40], 23: [8, 41],
24: [8, 42], 25: [8, 43], 26: [8, 44], 27: [8, 45],
28: [8, 46], 29: [8, 47], 30: [8, 48], 31: [8, 49],
# IOM 3
32: [7, 50], 33: [7, 51], 34: [7, 52], 35: [7, 53],
36: [7, 54], 37: [7, 55], 38: [7, 56], 39: [7, 57],
40: [7, 58], 41: [7, 59], 42: [7, 60], 43: [7, 61],
44: [7, 62], 45: [7, 63], 46: [7, 64], 47: [7, 65],
# IOM 4
48: [9, 18], 49: [9, 19], 50: [9, 20], 51: [9, 21],
52: [9, 22], 53: [9, 23], 54: [9, 24], 55: [9, 25],
56: [9, 26], 57: [9, 27], 58: [9, 28], 59: [9, 29],
60: [9, 30], 61: [9, 31], 62: [9, 32], 63: [9, 33]
}

reset_reason_dict = {}
reset_reason_dict[11] = ChassisBase.REBOOT_CAUSE_POWER_LOSS
reset_reason_dict[33] = ChassisBase.REBOOT_CAUSE_WATCHDOG
Expand All @@ -90,6 +61,10 @@ def __init__(self):
ChassisBase.__init__(self)
# Initialize EEPROM
self.sys_eeprom = Eeprom()
for i in range(MAX_S6100_MODULE):
module = Module(i)
self._module_list.append(module)

for i in range(MAX_S6100_FAN):
fan = Fan(i)
self._fan_list.append(fan)
Expand All @@ -98,38 +73,9 @@ def __init__(self):
psu = Psu(i)
self._psu_list.append(psu)

self._populate_port_i2c_mapping()

# sfp.py will read eeprom contents and retrive the eeprom data.
# It will also provide support sfp controls like reset and setting
# low power mode.
# We pass the eeprom path and sfp control path from chassis.py
# So that sfp.py implementation can be generic to all platforms
eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/i2c-{1}/{1}-0050/eeprom"
sfp_ctrl_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-003e/"
for index in range(0, self.PORTS_IN_BLOCK):
eeprom_path = eeprom_base.format(self.EEPROM_I2C_MAPPING[index][0],
self.EEPROM_I2C_MAPPING[index][1])
sfp_control = sfp_ctrl_base.format(self.PORT_I2C_MAPPING[index])
sfp_node = Sfp(index, 'QSFP', eeprom_path, sfp_control, index)
self._sfp_list.append(sfp_node)

def _populate_port_i2c_mapping(self):
# port_num and i2c match
for port_num in range(0, self.PORTS_IN_BLOCK):
if((port_num >= self.IOM1_PORT_START) and
(port_num < self.IOM2_PORT_START)):
i2c_line = 14
elif((port_num >= self.IOM2_PORT_START) and
(port_num < self.IOM3_PORT_START)):
i2c_line = 16
elif((port_num >= self.IOM3_PORT_START) and
(port_num <self.IOM4_PORT_START)):
i2c_line = 15
elif((port_num >= self.IOM4_PORT_START) and
(port_num < self.PORTS_IN_BLOCK)):
i2c_line = 17
self.PORT_I2C_MAPPING[port_num] = i2c_line
for i in range(MAX_S6100_THERMAL):
thermal = Thermal(i)
self._thermal_list.append(thermal)

def _get_pmc_register(self, reg_name):
# On successful read, returns the value read from given
Expand Down Expand Up @@ -222,6 +168,7 @@ def get_system_eeprom_info(self):
OCP ONIE TlvInfo EEPROM format and values are their corresponding
values.
"""
return self.sys_eeprom.system_eeprom_info()

def get_reboot_cause(self):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,42 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
def __init__(self):
self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom"
super(Eeprom, self).__init__(self.eeprom_path, 0, '', True)
self.eeprom_tlv_dict = dict()
try:
self.eeprom_data = self.read_eeprom()
except:
self.eeprom_data = "N/A"
raise RuntimeError("Eeprom is not Programmed")
else:
eeprom = self.eeprom_data

if not self.is_valid_tlvinfo_header(eeprom):
return

total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10])
tlv_index = self._TLV_INFO_HDR_LEN
tlv_end = self._TLV_INFO_HDR_LEN + total_length

while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end:
if not self.is_valid_tlv(eeprom[tlv_index:]):
break

tlv = eeprom[tlv_index:tlv_index + 2
+ ord(eeprom[tlv_index + 1])]
code = "0x%02X" % (ord(tlv[0]))

if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT:
value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) |
(ord(tlv[4]) << 8) | ord(tlv[5]))
value += str(tlv[6:6 + ord(tlv[1])])
else:
name, value = self.decoder(None, tlv)

self.eeprom_tlv_dict[code] = value
if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32:
break

tlv_index += ord(eeprom[tlv_index+1]) + 2


def serial_number_str(self):
Expand Down Expand Up @@ -76,3 +107,10 @@ def revision_str(self):

return results[2]

def system_eeprom_info(self):
"""
Returns a dictionary, where keys are the type code defined in
ONIE EEPROM format and values are their corresponding values
found in the system EEPROM.
"""
return self.eeprom_tlv_dict
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Fan(FanBase):
HWMON_NODE = os.listdir(HWMON_DIR)[0]
MAILBOX_DIR = HWMON_DIR + HWMON_NODE

def __init__(self, fantray_index, fan_index=1, psu_fan=False):
def __init__(self, fantray_index=1, fan_index=1, psu_fan=False):
self.is_psu_fan = psu_fan
if not self.is_psu_fan:
# API index is starting from 0, DellEMC platform index is starting
Expand Down Expand Up @@ -74,7 +74,7 @@ def get_name(self):
return "FanTray{}-Fan{}".format(
self.fantrayindex, self.fanindex - 1)
else:
return "PSU{} Fan".format(self.index - 10)
return "PSU{} Fan".format(self.fanindex - 10)

def get_model(self):
"""
Expand Down Expand Up @@ -209,7 +209,7 @@ def set_status_led(self, color):
status = False
return status

def get_target_speed(self):
def get_target_speed(self):
"""
Retrieves the target (expected) speed of the fan
Returns:
Expand Down
Loading