-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[Dell] S6000 I2C not responding to certain optics #8736
Changes from all commits
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 |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
import re | ||
import struct | ||
import time | ||
import fcntl | ||
from sonic_platform_base.sfp_base import SfpBase | ||
from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId | ||
from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom | ||
|
@@ -154,6 +155,15 @@ def _get_eeprom_data(self, eeprom_key): | |
if (self.sfpInfo is None): | ||
return None | ||
|
||
SFP_LOCK_FILE="/etc/sonic/sfp_lock" | ||
prgeor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
try: | ||
fd = open(SFP_LOCK_FILE, "r") | ||
except IOError as e: | ||
print("Error: unable to open file: %s" % str(e)) | ||
return None | ||
fcntl.flock(fd, fcntl.LOCK_EX) | ||
self.set_modsel() | ||
|
||
page_offset = sff8436_parser[eeprom_key][PAGE_OFFSET] | ||
eeprom_data_raw = self._read_eeprom_bytes( | ||
self.eeprom_path, | ||
|
@@ -172,6 +182,7 @@ def _get_eeprom_data(self, eeprom_key): | |
self.sfpDomInfo, sff8436_parser[eeprom_key][FUNC_NAME])( | ||
eeprom_data_raw, 0) | ||
|
||
fcntl.flock(fd, fcntl.LOCK_UN) | ||
return eeprom_data | ||
|
||
def _strip_unit_from_str(self, value_str): | ||
|
@@ -423,6 +434,16 @@ def get_presence(self): | |
Retrieves the presence of the sfp | ||
""" | ||
presence_ctrl = self.sfp_control + 'qsfp_modprs' | ||
SFP_LOCK_FILE="/etc/sonic/sfp_lock" | ||
|
||
try: | ||
fd = open(SFP_LOCK_FILE, "r") | ||
except IOError as e: | ||
print("Error: unable to open file: %s" % str(e)) | ||
return False | ||
fcntl.flock(fd, fcntl.LOCK_EX) | ||
self.set_modsel() | ||
|
||
try: | ||
reg_file = open(presence_ctrl) | ||
except IOError as e: | ||
|
@@ -437,12 +458,69 @@ def get_presence(self): | |
# Mask off the bit corresponding to our port | ||
mask = (1 << self.sfp_ctrl_idx) | ||
|
||
fcntl.flock(fd, fcntl.LOCK_UN) | ||
|
||
# ModPrsL is active low | ||
if ((reg_value & mask) == 0): | ||
return True | ||
|
||
return False | ||
|
||
def get_modsel(self): | ||
modsel_ctrl = self.sfp_control + 'qsfp_modsel' | ||
try: | ||
reg_file = open(modsel_ctrl, "r+") | ||
except IOError as e: | ||
return False | ||
|
||
reg_hex = reg_file.readline().rstrip() | ||
|
||
# content is a string containing the hex | ||
# representation of the register | ||
reg_value = int(reg_hex, 16) | ||
|
||
# Mask off the bit corresponding to our port | ||
index = self.sfp_ctrl_idx | ||
|
||
mask = (1 << index) | ||
|
||
if ((reg_value & mask) == 1): | ||
modsel_state = False | ||
else: | ||
modsel_state = True | ||
|
||
return modsel_state | ||
|
||
def set_modsel(self): | ||
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. If you bring the lock inside set_modsel(), then you don't have to lock/unlock every place where set_modsel() is called, keeps code changes to minimum. 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. The lock is based on set_modsel() but we cant introduce it here.
|
||
modsel_ctrl = self.sfp_control + 'qsfp_modsel' | ||
try: | ||
reg_file = open(modsel_ctrl, "r+") | ||
except IOError as e: | ||
return False | ||
|
||
reg_hex = reg_file.readline().rstrip() | ||
|
||
# content is a string containing the hex | ||
# representation of the register | ||
reg_value = int(reg_hex, 16) | ||
|
||
# Mask off the bit corresponding to our port | ||
index = self.sfp_ctrl_idx | ||
|
||
reg_value = reg_value | int("0xffffffff", 16) | ||
mask = (1 << index) | ||
|
||
reg_value = (reg_value & ~mask) | ||
|
||
# Convert our register value back to a hex string and write back | ||
content = hex(reg_value) | ||
|
||
reg_file.seek(0) | ||
reg_file.write(content) | ||
reg_file.close() | ||
|
||
return True | ||
|
||
def get_model(self): | ||
""" | ||
Retrieves the model number (or part number) of the sfp | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is qsfp_modprs pin access needs a lock? Reading of sysfs entry shouldn't need lock. I see this https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c#L286 already thread safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lock is provided for writing qsfp_modsel register.
When multiple ports are enabled via qsfp_modsel register, we observed that qsfp_modprs values are being wrong. At a time only one port should be enabled in qsfp_modsel.