Skip to content

Commit ddf40cb

Browse files
authored
[201911] Dell S6000 I2C not responding to certain optics - porting (#8855)
1 parent 384fff7 commit ddf40cb

File tree

4 files changed

+204
-2
lines changed

4 files changed

+204
-2
lines changed

device/dell/x86_64-dell_s6000_s1220-r0/plugins/sfputil.py

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
try:
77
import time
8+
import fcntl
89
import datetime
910
from sonic_sfp.sfputilbase import SfpUtilBase
1011
except ImportError as e:
@@ -19,6 +20,7 @@ class SfpUtil(SfpUtilBase):
1920
PORTS_IN_BLOCK = 32
2021

2122
EEPROM_OFFSET = 20
23+
SFP_LOCK_FILE="/etc/sonic/sfp_lock"
2224

2325
_port_to_eeprom_mapping = {}
2426
port_dict = {}
@@ -73,10 +75,19 @@ def get_presence(self, port_num):
7375
if port_num < self.port_start or port_num > self.port_end:
7476
return False
7577

78+
try:
79+
fd = open(self.SFP_LOCK_FILE, "r")
80+
except IOError as e:
81+
print("Error: unable to open file: "+ str(e))
82+
return False
83+
fcntl.flock(fd, fcntl.LOCK_EX)
84+
self.set_modsel(port_num)
85+
7686
try:
7787
reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_modprs")
7888
except IOError as e:
7989
print "Error: unable to open file: %s" % str(e)
90+
fcntl.flock(fd, fcntl.LOCK_UN)
8091
return False
8192

8293
content = reg_file.readline().rstrip()
@@ -86,13 +97,103 @@ def get_presence(self, port_num):
8697

8798
# Mask off the bit corresponding to our port
8899
mask = (1 << port_num)
89-
100+
fcntl.flock(fd, fcntl.LOCK_UN)
90101
# ModPrsL is active low
91102
if reg_value & mask == 0:
92103
return True
93104

94105
return False
95106

107+
def get_modsel(self, port_num):
108+
# Check for invalid port_num
109+
if port_num < self.port_start or port_num > self.port_end:
110+
return False
111+
112+
try:
113+
reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_modsel")
114+
except IOError as e:
115+
print("Error: unable to open file: %s" % str(e))
116+
return False
117+
118+
content = reg_file.readline().rstrip()
119+
120+
# content is a string containing the hex representation of the register
121+
reg_value = int(content, 16)
122+
123+
# Mask off the bit corresponding to our port
124+
mask = (1 << port_num)
125+
126+
if reg_value & mask == 1:
127+
return False
128+
129+
return True
130+
131+
def set_modsel(self, port_num):
132+
# Check for invalid port_num
133+
if port_num < self.port_start or port_num > self.port_end:
134+
return False
135+
136+
try:
137+
reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_modsel", "r+")
138+
except IOError as e:
139+
print("Error: unable to open file: %s" % str(e))
140+
return False
141+
142+
content = reg_file.readline().rstrip()
143+
144+
# content is a string containing the hex representation of the register
145+
reg_value = int(content, 16)
146+
147+
# Mask off the bit corresponding to our port
148+
mask = (1 << port_num)
149+
reg_value = reg_value | int("0xffffffff", 16)
150+
reg_value = reg_value & ~mask
151+
152+
# Convert our register value back to a hex string and write back
153+
content = hex(reg_value)
154+
155+
reg_file.seek(0)
156+
reg_file.write(content)
157+
reg_file.close()
158+
159+
return True
160+
161+
def get_eeprom_raw(self, port_num, num_bytes=256):
162+
# Read interface id EEPROM at addr 0x50
163+
try:
164+
fd = open(self.SFP_LOCK_FILE, "r")
165+
except IOError as e:
166+
print("Error: unable to open file: %s" % str(e))
167+
return None
168+
fcntl.flock(fd, fcntl.LOCK_EX)
169+
self.set_modsel(port_num)
170+
eeprom_bytes = self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 0, num_bytes)
171+
fcntl.flock(fd, fcntl.LOCK_UN)
172+
return eeprom_bytes
173+
174+
def get_eeprom_dom_raw(self, port_num):
175+
if port_num in self.osfp_ports:
176+
return None
177+
if port_num in self.qsfp_ports:
178+
# QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw
179+
return None
180+
else:
181+
# Read dom eeprom at addr 0x51
182+
if not self.get_modsel(port_num):
183+
try:
184+
fd = open(self.SFP_LOCK_FILE, "r")
185+
except IOError as e:
186+
print("Error: unable to open file: %s" % str(e))
187+
return None
188+
fcntl.flock(fd, fcntl.LOCK_EX)
189+
self.set_modsel(port_num)
190+
eeprom_bytes = self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 0)
191+
fcntl.flock(fd, fcntl.LOCK_UN)
192+
return eeprom_bytes
193+
else:
194+
return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 0)
195+
196+
96197
def get_low_power_mode(self, port_num):
97198
# Check for invalid port_num
98199
if port_num < self.port_start or port_num > self.port_end:

platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,25 @@ static ssize_t get_modsel(struct device *dev, struct device_attribute *devattr,
312312
return sprintf(buf, "0x%08x\n", data);
313313
}
314314

315+
static ssize_t set_modsel(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
316+
{
317+
int err;
318+
unsigned long data = 0;
319+
struct cpld_platform_data *pdata = dev->platform_data;
320+
321+
err = kstrtoul(buf, 16, &data);
322+
if (err)
323+
return err;
324+
325+
dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x0, (u8)(data & 0xff));
326+
dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x1, (u8)((data >> 8) & 0xff));
327+
dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xa, (u8)((data >> 16) & 0xff));
328+
dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xb, (u8)((data >> 24) & 0xff));
329+
330+
msleep(2); // As per HW spec
331+
return count;
332+
}
333+
315334
static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, char *buf)
316335
{
317336
int ret;
@@ -1128,7 +1147,7 @@ static ssize_t get_reboot_reason(struct device *dev,
11281147
return sprintf(buf, "0x%x\n", data);
11291148
}
11301149

1131-
static DEVICE_ATTR(qsfp_modsel, S_IRUGO, get_modsel, NULL);
1150+
static DEVICE_ATTR(qsfp_modsel, S_IRUGO | S_IWUSR, get_modsel, set_modsel);
11321151
static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL);
11331152
static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode);
11341153
static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset);

platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ remove_python_api_package() {
9393
# read SONiC immutable variables
9494
[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment
9595

96+
if [ ! -e /etc/sonic/sfp_lock ]; then
97+
touch /etc/sonic/sfp_lock
98+
fi
99+
96100
if [[ "$1" == "init" ]]; then
97101
depmod -a
98102
modprobe nvram

platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
try:
1212
import os
13+
import fcntl
1314
import time
1415
from sonic_platform_base.chassis_base import ChassisBase
1516
from sonic_platform_base.sfp_base import SfpBase
@@ -149,6 +150,15 @@ def _get_eeprom_data(self, eeprom_key):
149150
if (self.sfpInfo is None):
150151
return None
151152

153+
SFP_LOCK_FILE="/etc/sonic/sfp_lock"
154+
try:
155+
fd = open(SFP_LOCK_FILE, "r")
156+
except IOError as e:
157+
print("Error: unable to open file: %s" % str(e))
158+
return None
159+
fcntl.flock(fd, fcntl.LOCK_EX)
160+
self.set_modsel()
161+
152162
page_offset = sff8436_parser[eeprom_key][PAGE_OFFSET]
153163
eeprom_data_raw = self._read_eeprom_bytes(
154164
self.eeprom_path,
@@ -167,6 +177,7 @@ def _get_eeprom_data(self, eeprom_key):
167177
self.sfpDomInfo, sff8436_parser[eeprom_key][FUNC_NAME])(
168178
eeprom_data_raw, 0)
169179

180+
fcntl.flock(fd, fcntl.LOCK_UN)
170181
return eeprom_data
171182

172183

@@ -410,6 +421,16 @@ def get_presence(self):
410421
Retrieves the presence of the sfp
411422
"""
412423
presence_ctrl = self.sfp_control + 'qsfp_modprs'
424+
SFP_LOCK_FILE="/etc/sonic/sfp_lock"
425+
426+
try:
427+
fd = open(SFP_LOCK_FILE, "r")
428+
except IOError as e:
429+
print("Error: unable to open file: %s" % str(e))
430+
return False
431+
fcntl.flock(fd, fcntl.LOCK_EX)
432+
self.set_modsel()
433+
413434
try:
414435
reg_file = open(presence_ctrl)
415436
except IOError as e:
@@ -424,12 +445,69 @@ def get_presence(self):
424445
# Mask off the bit corresponding to our port
425446
mask = (1 << self.sfp_ctrl_idx)
426447

448+
fcntl.flock(fd, fcntl.LOCK_UN)
449+
427450
# ModPrsL is active low
428451
if ((reg_value & mask) == 0):
429452
return True
430453

431454
return False
432455

456+
def get_modsel(self):
457+
modsel_ctrl = self.sfp_control + 'qsfp_modsel'
458+
try:
459+
reg_file = open(modsel_ctrl, "r+")
460+
except IOError as e:
461+
return False
462+
463+
reg_hex = reg_file.readline().rstrip()
464+
465+
# content is a string containing the hex
466+
# representation of the register
467+
reg_value = int(reg_hex, 16)
468+
469+
# Mask off the bit corresponding to our port
470+
index = self.sfp_ctrl_idx
471+
472+
mask = (1 << index)
473+
474+
if ((reg_value & mask) == 1):
475+
modsel_state = False
476+
else:
477+
modsel_state = True
478+
479+
return modsel_state
480+
481+
def set_modsel(self):
482+
modsel_ctrl = self.sfp_control + 'qsfp_modsel'
483+
try:
484+
reg_file = open(modsel_ctrl, "r+")
485+
except IOError as e:
486+
return False
487+
488+
reg_hex = reg_file.readline().rstrip()
489+
490+
# content is a string containing the hex
491+
# representation of the register
492+
reg_value = int(reg_hex, 16)
493+
494+
# Mask off the bit corresponding to our port
495+
index = self.sfp_ctrl_idx
496+
497+
reg_value = reg_value | int("0xffffffff", 16)
498+
mask = (1 << index)
499+
500+
reg_value = (reg_value & ~mask)
501+
502+
# Convert our register value back to a hex string and write back
503+
content = hex(reg_value)
504+
505+
reg_file.seek(0)
506+
reg_file.write(content)
507+
reg_file.close()
508+
509+
return True
510+
433511
def get_model(self):
434512
"""
435513
Retrieves the model number (or part number) of the sfp

0 commit comments

Comments
 (0)