Skip to content

Commit

Permalink
[Mellanox] Support new platform API get_port_or_cage_type for RJ45 po…
Browse files Browse the repository at this point in the history
…rts (#11336)

- Why I did it
Support get_port_or_cage_type for RJ45 ports

- How I did it
Implement the new platform API get_port_or_cage_type
Fix the issue: unable to import SFP when chassis object is destructed

- How to verify it
Manually test and regression test

Signed-off-by: Stephen Sun <stephens@nvidia.com>
  • Loading branch information
stephenxs authored Jul 14, 2022
1 parent cf7a8f8 commit 81600fa
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 14 deletions.
58 changes: 44 additions & 14 deletions platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
from .utils import extract_RJ45_ports_index
from . import utils
from .device_data import DeviceDataManager
from .sfp import SFP, RJ45Port, deinitialize_sdk_handle
except ImportError as e:
raise ImportError (str(e) + "- required module not found")

Expand Down Expand Up @@ -110,6 +109,8 @@ def __init__(self):
self.sfp_event = None
self.reboot_cause_initialized = False

self.sfp_module = None

# Build the RJ45 port list from platform.json and hwsku.json
self._RJ45_port_inited = False
self._RJ45_port_list = None
Expand All @@ -121,9 +122,8 @@ def __del__(self):
self.sfp_event.deinitialize()

if self._sfp_list:
from .sfp import SFP, deinitialize_sdk_handle
if SFP.shared_sdk_handle:
deinitialize_sdk_handle(SFP.shared_sdk_handle)
if self.sfp_module.SFP.shared_sdk_handle:
self.sfp_module.deinitialize_sdk_handle(sfp_module.SFP.shared_sdk_handle)

@property
def RJ45_port_list(self):
Expand Down Expand Up @@ -249,39 +249,45 @@ def get_fan_drawer(self, index):
# SFP methods
##############################################

def _import_sfp_module(self):
if not self.sfp_module:
from . import sfp as sfp_module
self.sfp_module = sfp_module
return self.sfp_module

def initialize_single_sfp(self, index):
sfp_count = self.get_num_sfps()
if index < sfp_count:
if not self._sfp_list:
self._sfp_list = [None] * sfp_count

if not self._sfp_list[index]:
from .sfp import SFP
sfp_module = self._import_sfp_module()
if self.RJ45_port_list and index in self.RJ45_port_list:
self._sfp_list[index] = RJ45Port(index)
self._sfp_list[index] = sfp_module.RJ45Port(index)
else:
self._sfp_list[index] = SFP(index)
self._sfp_list[index] = sfp_module.SFP(index)
self.sfp_initialized_count += 1

def initialize_sfp(self):
if not self._sfp_list:
from .sfp import SFP
sfp_module = self._import_sfp_module()
sfp_count = self.get_num_sfps()
for index in range(sfp_count):
if self.RJ45_port_list and index in self.RJ45_port_list:
sfp_module = RJ45Port(index)
sfp_object = sfp_module.RJ45Port(index)
else:
sfp_module = SFP(index)
self._sfp_list.append(sfp_module)
sfp_object = sfp_module.SFP(index)
self._sfp_list.append(sfp_object)
self.sfp_initialized_count = sfp_count
elif self.sfp_initialized_count != len(self._sfp_list):
from .sfp import SFP
sfp_module = self._import_sfp_module()
for index in range(len(self._sfp_list)):
if self._sfp_list[index] is None:
if self.RJ45_port_list and index in self.RJ45_port_list:
self._sfp_list[index] = RJ45Port(index)
self._sfp_list[index] = sfp_module.RJ45Port(index)
else:
self._sfp_list[index] = SFP(index)
self._sfp_list[index] = sfp_module.SFP(index)
self.sfp_initialized_count = len(self._sfp_list)

def get_num_sfps(self):
Expand Down Expand Up @@ -321,6 +327,30 @@ def get_sfp(self, index):
self.initialize_single_sfp(index)
return super(Chassis, self).get_sfp(index)

def get_port_or_cage_type(self, index):
"""
Retrieves sfp port or cage type corresponding to physical port <index>
Args:
index: An integer (>=0), the index of the sfp to retrieve.
The index should correspond to the physical port in a chassis.
For example:-
1 for Ethernet0, 2 for Ethernet4 and so on for one platform.
0 for Ethernet0, 1 for Ethernet4 and so on for another platform.
Returns:
The masks of all types of port or cage that can be supported on the port
Types are defined in sfp_base.py
Eg.
Both SFP and SFP+ are supported on the port, the return value should be 0x0a
which is 0x02 | 0x08
"""
index = index - 1
if self.RJ45_port_list and index in self.RJ45_port_list:
from sonic_platform_base.sfp_base import SfpBase
return SfpBase.SFP_PORT_TYPE_BIT_RJ45
raise NotImplementedError

def get_change_event(self, timeout=0):
"""
Returns a nested dictionary containing all devices which have
Expand Down
14 changes: 14 additions & 0 deletions platform/mellanox/mlnx-platform-api/tests/test_chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
sys.path.insert(0, modules_path)

import sonic_platform.chassis
from sonic_platform_base.sfp_base import SfpBase
from sonic_platform.chassis import Chassis
from sonic_platform.device_data import DeviceDataManager

Expand Down Expand Up @@ -282,3 +283,16 @@ def test_revision_permission(self):
sonic_platform.chassis.DMI_FILE = old_dmi_file
os.system("rm -f " + new_dmi_file)
assert rev == "N/A"

def test_get_port_or_cage_type(self):
chassis = Chassis()
chassis.RJ45_port_list = [0]
assert SfpBase.SFP_PORT_TYPE_BIT_RJ45 == chassis.get_port_or_cage_type(1)

exceptionRaised = False
try:
chassis.get_port_or_cage_type(2)
except NotImplementedError:
exceptionRaised = True

assert exceptionRaised

0 comments on commit 81600fa

Please sign in to comment.