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

Platform APIs for SmartSwitch #454

Merged
merged 16 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
53 changes: 51 additions & 2 deletions sonic_platform_base/chassis_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ def is_modular_chassis(self):
A bool value, should return False by default or for fixed-platforms.
Should return True for supervisor-cards, line-cards etc running as part
of modular-chassis.
For SmartSwitch platforms this should return True even if they are
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
fixed-platforms, as they are treated like a modular chassis as the
DPU cards are treated like line-cards of a modular-chassis.
"""
return False

Expand Down Expand Up @@ -218,6 +221,7 @@ def get_component(self, index):
def get_num_modules(self):
"""
Retrieves the number of modules available on this chassis
On a SmarSwitch chassis this includes the number of DPUs.

Returns:
An integer, the number of modules available on this chassis
Expand All @@ -226,7 +230,8 @@ def get_num_modules(self):

def get_all_modules(self):
"""
Retrieves all modules available on this chassis
Retrieves all modules available on this chassis. On a SmartSwitch
chassis this includes the DPUs.

Returns:
A list of objects derived from ModuleBase representing all
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -237,13 +242,15 @@ def get_all_modules(self):
def get_module(self, index):
"""
Retrieves module represented by (0-based) index <index>
On a SmartSwitch index:0 is not used, index:1 will fetch
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
DPU0 and so on

Args:
index: An integer, the index (0-based) of the module to
retrieve

Returns:
An object dervied from ModuleBase representing the specified
An object derived from ModuleBase representing the specified
module
"""
module = None
Expand All @@ -263,12 +270,54 @@ def get_module_index(self, module_name):
Args:
module_name: A string, prefixed by SUPERVISOR, LINE-CARD or FABRIC-CARD
Ex. SUPERVISOR0, LINE-CARD1, FABRIC-CARD5
SmartSwitch Example: DPU0, DPU1, DPU2 ... DPUX

Returns:
An integer, the index of the ModuleBase object in the module_list
"""
raise NotImplementedError

##############################################
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
# SmartSwitch methods
##############################################

def get_dpu_id(self, name):
"""
Retrieves the DPU ID for the given dpu-module name.
Returns None for non-smartswitch chassis.

Returns:
An integer, indicating the DPU ID Ex: name:DPU0 return value 1,
name:DPU1 return value 2, name:DPUX return value X+1
"""
raise NotImplementedError

def is_smartswitch(self):
"""
Retrieves whether the sonic instance is part of smartswitch

Returns:
Returns:True for SmartSwitch and False for other platforms
"""
return False

def get_module_dpu_data_port(self, index):
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
"""
Retrieves the DPU data port NPU-DPU association represented for
the DPU index. Platforms that need to overwrite the platform.json
file will use this API. This is valid only on the Switch and not on DPUs

Args:
index: An integer, the index of the module to retrieve

Returns:
A string giving the NPU-DPU port association:
Ex: For index: 1 will return the dup0 port association which is
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
"Ethernet192: Ethernet0" where the string left of ":" (Ethernet192)
is the NPU port and the string right of ":" (Ethernet0) is the DPU port
"""
raise NotImplementedError

##############################################
# Fan methods
##############################################
Expand Down
81 changes: 77 additions & 4 deletions sonic_platform_base/module_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,25 @@ class ModuleBase(device_base.DeviceBase):
# Device type definition. Note, this is a constant.
DEVICE_TYPE = "module"

# Possible reboot causes
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
REBOOT_CAUSE_POWER_LOSS = "Power Loss"
REBOOT_CAUSE_THERMAL_OVERLOAD_CPU = "Thermal Overload: CPU"
REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC = "Thermal Overload: ASIC"
REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER = "Thermal Overload: Other"
REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED = "Insufficient Fan Speed"
REBOOT_CAUSE_WATCHDOG = "Watchdog"
REBOOT_CAUSE_HARDWARE_OTHER = "Hardware - Other"
REBOOT_CAUSE_HARDWARE_BIOS = "BIOS"
REBOOT_CAUSE_HARDWARE_CPU = "CPU"
REBOOT_CAUSE_HARDWARE_BUTTON = "Push button"
REBOOT_CAUSE_HARDWARE_RESET_FROM_ASIC = "Reset from ASIC"
REBOOT_CAUSE_NON_HARDWARE = "Non-Hardware"

# Possible card types for modular chassis
MODULE_TYPE_SUPERVISOR = "SUPERVISOR"
MODULE_TYPE_LINE = "LINE-CARD"
MODULE_TYPE_FABRIC = "FABRIC-CARD"
MODULE_TYPE_DPU = "DPU"

# Possible card status for modular chassis
# Module state is Empty if no module is inserted in the slot
Expand Down Expand Up @@ -104,15 +119,17 @@ def get_system_eeprom_info(self):
def get_name(self):
"""
Retrieves the name of the module prefixed by SUPERVISOR, LINE-CARD,
FABRIC-CARD
FABRIC-CARD, DPU0, DPUX

Returns:
A string, the module name prefixed by one of MODULE_TYPE_SUPERVISOR,
MODULE_TYPE_LINE or MODULE_TYPE_FABRIC and followed by a 0-based index
MODULE_TYPE_LINE or MODULE_TYPE_FABRIC or MODULE_TYPE_DPU and followed
by a 0-based index.

Ex. A Chassis having 1 supervisor, 4 line-cards and 6 fabric-cards
can provide names SUPERVISOR0, LINE-CARD0 to LINE-CARD3,
FABRIC-CARD0 to FABRIC-CARD5
FABRIC-CARD0 to FABRIC-CARD5.
A SmartSwitch having 4 DPUs names DPU0 to DPU3
"""
raise NotImplementedError

Expand Down Expand Up @@ -141,6 +158,7 @@ def get_type(self):
Returns:
A string, the module-type from one of the predefined types:
MODULE_TYPE_SUPERVISOR, MODULE_TYPE_LINE or MODULE_TYPE_FABRIC
or MODULE_TYPE_DPU
"""
raise NotImplementedError

Expand All @@ -152,6 +170,11 @@ def get_oper_status(self):
A string, the operational status of the module from one of the
predefined status values: MODULE_STATUS_EMPTY, MODULE_STATUS_OFFLINE,
MODULE_STATUS_FAULT, MODULE_STATUS_PRESENT or MODULE_STATUS_ONLINE
The SmartSwitch platforms will have these additional status
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
MODULE_STATUS_MIDPLANE_OFFLINE, MODULE_STATUS_MIDPLANE_ONLINE,
MODULE_STATUS_CONTROLPLANE_OFFLINE, MODULE_STATUS_CONTROLPLANE_ONLINE,
MODULE_STATUS_CONTROLPLANE_PARTIAL_ONLINE, MODULE_STATUS_DATAPLANE_OFFLINE,
MODULE_STATUS_DATAPLANE_ONLINE, MODULE_STATUS_DATAPLANE_PARTIAL_ONLINE
"""
raise NotImplementedError

Expand All @@ -175,7 +198,7 @@ def set_admin_state(self, up):
The down state will power down the module and the status should show
MODULE_STATUS_OFFLINE.
The up state will take the module to MODULE_STATUS_FAULT or
MODULE_STAUS_ONLINE states.
MODULE_STATUS_ONLINE states.

Args:
up: A boolean, True to set the admin-state to UP. False to set the
Expand All @@ -196,6 +219,54 @@ def get_maximum_consumed_power(self):
"""
raise NotImplementedError

##############################################
# SmartSwitch methods
##############################################

def get_dpu_id(self):
"""
Retrieves the DPU ID. Returns None for non-smartswitch chassis.

Returns:
An integer, indicating the DPU ID. DPU0 returns 1, DPUX returns X+1
"""
raise NotImplementedError

def get_reboot_cause(self):
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
"""
Retrieves the cause of the previous reboot of the DPU module

Returns:
A tuple (string, string) where the first element is a string
containing the cause of the previous reboot. This string must
be one of the predefined strings in this class. If the first
string is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be
used to pass a description of the reboot cause.

"""
raise NotImplementedError

def get_state_info(self):
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
"""
Retrieves the dpu state object having the detailed dpu state progression.
Fetched from ChassisStateDB.

Returns:
An object instance of the DPU_STATE (see DB schema)
Returns None on switch module
"""
raise NotImplementedError

def get_health_info(self):
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
"""
Retrieves the dpu health object having the detailed dpu health.
Fetched from the DPUs.

Returns:
An object instance of the dpu health.
"""
raise NotImplementedError

##############################################
# Component methods
##############################################
Expand Down Expand Up @@ -541,6 +612,8 @@ def get_midplane_ip(self):
line-card and return the midplane IP-address of the line-card.
When called from the line-card, the module will represent the
Supervisor and return its midplane IP-address.
When called from the DPU, returns the midplane IP-address of the dpu-card.
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
When called from the Switch returns the midplane IP-address of Switch.
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved

Returns:
A string, the IP-address of the module reachable over the midplane
Expand Down
6 changes: 6 additions & 0 deletions tests/chassis_base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def test_chassis_base(self):
not_implemented_methods = [
[chassis.get_uid_led],
[chassis.set_uid_led, "COLOR"],
[chassis.get_dpu_id, "DPU0"],
[chassis.get_module_dpu_data_port, 0],
]

for method in not_implemented_methods:
Expand All @@ -35,6 +37,10 @@ def test_chassis_base(self):

assert exception_raised

def test_smartswitch(self):
chassis = ChassisBase()
assert(chassis.is_smartswitch() == False)

def test_sensors(self):
chassis = ChassisBase()
assert(chassis.get_num_voltage_sensors() == 0)
Expand Down
20 changes: 20 additions & 0 deletions tests/module_base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@

class TestModuleBase:

def test_module_base(self):
module = ModuleBase()
not_implemented_methods = [
[module.get_dpu_id],
[module.get_reboot_cause],
[module.get_state_info],
[module.get_health_info],
]

for method in not_implemented_methods:
exception_raised = False
try:
func = method[0]
args = method[1:]
func(*args)
except NotImplementedError:
exception_raised = True

assert exception_raised

def test_sensors(self):
module = ModuleBase()
assert(module.get_num_voltage_sensors() == 0)
Expand Down
Loading