-
Notifications
You must be signed in to change notification settings - Fork 237
[CPO] Extend ChassisBase to support CPO ports #700
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
Changes from all commits
05a2534
ff568f1
29ee0ac
5d8929c
83d4b24
2f9a227
aaceb83
ab18bf2
30f8627
9b8f961
fc51057
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| """ | ||
|
|
||
| import sys | ||
| from sonic_py_common import device_info | ||
| from . import device_base | ||
| from . import sfp_base | ||
|
|
||
|
|
@@ -62,9 +63,18 @@ def __init__(self): | |
| self._current_sensor_list = [] | ||
|
|
||
| # List of SfpBase-derived objects representing all sfps | ||
| # available on the chassis | ||
| # available on the chassis, indexed by physical port. | ||
| self._sfp_list = [] | ||
|
|
||
| # List of CpoBase-derived objects representing all CPO ports | ||
| # available on the chassis, indexed by physical port. | ||
| self._cpo_list = [] | ||
|
bgallagher-nexthop marked this conversation as resolved.
|
||
|
|
||
| # Set once the port lists have been checked for consistency. The check | ||
| # is deferred until the lists are first accessed, since subclasses | ||
| # populate them after ChassisBase.__init__ has returned. | ||
| self._port_lists_validated = False | ||
|
|
||
| # Object derived from WatchdogBase for interacting with hardware watchdog | ||
| self._watchdog = None | ||
|
|
||
|
|
@@ -80,6 +90,12 @@ def __init__(self): | |
| # SED (Self-Encrypting Drive) password management | ||
| self._sed_mgmt = None | ||
|
|
||
| # On platforms that provide a cpo.json file, populate self._cpo_list | ||
| # based on the device topology described in that file | ||
| cpo_data = device_info.get_cpo_data() | ||
|
prgeor marked this conversation as resolved.
|
||
| if cpo_data: | ||
| self.construct_cpo_devices(cpo_data) | ||
|
bgallagher-nexthop marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is the construct_cpo_devices responsible also to add the "None" for the sfps?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct, the intention is that the implementation of this method should add None for any non-CPO ports |
||
|
|
||
| def get_base_mac(self): | ||
| """ | ||
| Retrieves the base MAC address for the chassis | ||
|
|
@@ -701,14 +717,61 @@ def get_current_sensor(self, index): | |
| # SFP methods | ||
| ############################################## | ||
|
|
||
| def construct_cpo_devices(self, cpo_data): | ||
| """ | ||
| Construct objects representing the devices driving traffic through | ||
| a front panel port on the chassis based on topology data in | ||
| cpo.json | ||
|
|
||
| Subclasses should implement this method on platforms that provide | ||
| a cpo.json file. | ||
|
|
||
| Args: | ||
| cpo_data: device topology data parsed from cpo.json | ||
| """ | ||
| raise NotImplementedError | ||
|
|
||
| def _validate_port_lists(self): | ||
| """ | ||
| Check that _sfp_list and _cpo_list follow the indexing convention: | ||
| both are indexed by physical front panel port, with None at the | ||
| indices driven by the other technology. A platform which has only one | ||
| kind of port need only populate the corresponding list. | ||
| """ | ||
| if self._port_lists_validated: | ||
| return | ||
|
|
||
| if not self._sfp_list or not self._cpo_list: | ||
| # This is a platform that only has one type of transceiver technology. | ||
| # We do not need to perform validation against both lists, because only | ||
| # one will be used. | ||
| return | ||
|
|
||
| if len(self._sfp_list) != len(self._cpo_list): | ||
| raise RuntimeError( | ||
| "_sfp_list (length {}) and _cpo_list (length {}) must be the " | ||
| "same length: both are indexed by physical front panel port, " | ||
| "with None at the indices driven by the other technology".format( | ||
| len(self._sfp_list), len(self._cpo_list))) | ||
|
|
||
| for index, (sfp, cpo) in enumerate(zip(self._sfp_list, self._cpo_list)): | ||
| if sfp is not None and cpo is not None: | ||
| raise RuntimeError( | ||
| "Physical port {} has both an SFP and a CPO object; each " | ||
| "port must appear in exactly one of _sfp_list and " | ||
| "_cpo_list".format(index)) | ||
|
|
||
| self._port_lists_validated = True | ||
|
|
||
| def get_num_sfps(self): | ||
| """ | ||
| Retrieves the number of sfps available on this chassis | ||
|
|
||
| Returns: | ||
| An integer, the number of sfps available on this chassis | ||
| """ | ||
| return len(self._sfp_list) | ||
| self._validate_port_lists() | ||
| return sum(1 for sfp in self._sfp_list if sfp is not None) | ||
|
|
||
| def get_all_sfps(self): | ||
| """ | ||
|
|
@@ -718,6 +781,7 @@ def get_all_sfps(self): | |
| A list of objects derived from SfpBase representing all sfps | ||
| available on this chassis | ||
| """ | ||
| self._validate_port_lists() | ||
| return [ sfp for sfp in self._sfp_list if sfp is not None ] | ||
|
|
||
| def get_sfp(self, index): | ||
|
|
@@ -732,10 +796,12 @@ def get_sfp(self, index): | |
| 0 for Ethernet0, 1 for Ethernet4 and so on for another platform. | ||
|
|
||
| Returns: | ||
| An object dervied from SfpBase representing the specified sfp | ||
| An object dervied from SfpBase representing the specified sfp, | ||
| or None if the port is not an SFP port | ||
| """ | ||
| sfp = None | ||
|
|
||
| self._validate_port_lists() | ||
| try: | ||
| sfp = self._sfp_list[index] | ||
| except IndexError: | ||
|
|
@@ -744,6 +810,48 @@ def get_sfp(self, index): | |
|
|
||
| return sfp | ||
|
|
||
| def get_num_cpos(self): | ||
| """ | ||
| Retrieves the number of CPO ports available on this chassis | ||
|
|
||
| Returns: | ||
| An integer, the number of CPO ports available on this chassis | ||
| """ | ||
| self._validate_port_lists() | ||
| return sum(1 for cpo in self._cpo_list if cpo is not None) | ||
|
|
||
| def get_all_cpos(self): | ||
| """ | ||
| Retrieves all CPO ports available on this chassis | ||
|
|
||
| Returns: | ||
| A list of objects derived from CpoBase representing all CPO ports | ||
| available on this chassis | ||
| """ | ||
| self._validate_port_lists() | ||
| return [cpo for cpo in self._cpo_list if cpo is not None] | ||
|
|
||
| def get_cpo(self, index): | ||
| """ | ||
| Retrieves the CPO port corresponding to physical port <index>, if | ||
| that port is driven by CPO devices. | ||
|
|
||
| Args: | ||
| index: An integer (>=0), the physical port index (same indexing as | ||
| get_sfp()). | ||
|
|
||
| Returns: | ||
| An object derived from CpoBase representing the specified CPO port, | ||
| or None if the port is not a CPO port. | ||
| """ | ||
| cpo = None | ||
| self._validate_port_lists() | ||
| try: | ||
| cpo = self._cpo_list[index] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we want to return an error in case the entry in specific index is "None"?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have copied the behaviour of So for the two scenarios where an incorrect access occurs, we return
|
||
| except IndexError: | ||
| sys.stderr.write("CPO index {} out of range (0-{})\n".format( | ||
| index, len(self._cpo_list)-1)) | ||
| return cpo | ||
|
|
||
| def get_port_or_cage_type(self, index): | ||
| """ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.