Merge branch 'master' into platform2.0_s6100
This commit is contained in:
commit
4bad5eabb6
@ -227,18 +227,24 @@ init :
|
|||||||
@git submodule update --init --recursive
|
@git submodule update --init --recursive
|
||||||
@git submodule foreach --recursive '[ -f .git ] && echo "gitdir: $$(realpath --relative-to=. $$(cut -d" " -f2 .git))" > .git'
|
@git submodule foreach --recursive '[ -f .git ] && echo "gitdir: $$(realpath --relative-to=. $$(cut -d" " -f2 .git))" > .git'
|
||||||
|
|
||||||
|
.ONESHELL : reset
|
||||||
reset :
|
reset :
|
||||||
@echo && echo -n "Warning! All local changes will be lost. Proceed? [y/N]: "
|
@echo && echo -n "Warning! All local changes will be lost. Proceed? [y/N]: "
|
||||||
@read ans && \
|
@read ans && (
|
||||||
if [ $$ans == y ]; then \
|
if [ $$ans == y ]; then
|
||||||
echo "Resetting local repository. Please wait..."; \
|
echo "Resetting local repository. Please wait...";
|
||||||
$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) sudo rm -rf fsroot; \
|
$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) sudo rm -rf fsroot;
|
||||||
git clean -xfdf; \
|
if [[ "$(CONFIGURED_ARCH)" == "armhf" || "$(CONFIGURED_ARCH)" == "arm64" ]]; then
|
||||||
git reset --hard; \
|
echo "Stopping march $(CONFIGURED_ARCH) docker"
|
||||||
git submodule foreach --recursive git clean -xfdf; \
|
sudo kill -9 `sudo cat /var/run/march/docker.pid` || true
|
||||||
git submodule foreach --recursive git reset --hard; \
|
sudo rm -f /var/run/march/docker.pid || true
|
||||||
git submodule update --init --recursive; \
|
fi
|
||||||
echo "Reset complete!"; \
|
git clean -xfdf;
|
||||||
else \
|
git reset --hard;
|
||||||
echo "Reset aborted"; \
|
git submodule foreach --recursive git clean -xfdf;
|
||||||
fi
|
git submodule foreach --recursive git reset --hard;
|
||||||
|
git submodule update --init --recursive;
|
||||||
|
echo "Reset complete!";
|
||||||
|
else
|
||||||
|
echo "Reset aborted";
|
||||||
|
fi )
|
||||||
|
@ -51,6 +51,11 @@ Install pip and jinja in host build machine, execute below commands if j2/j2cli
|
|||||||
sudo pip install --force-reinstall --upgrade jinja2>=2.10
|
sudo pip install --force-reinstall --upgrade jinja2>=2.10
|
||||||
sudo pip install j2cli
|
sudo pip install j2cli
|
||||||
|
|
||||||
|
Configure your system to allow running the 'docker' command without 'sudo':
|
||||||
|
Add current user to the docker group
|
||||||
|
`sudo gpasswd -a ${USER} docker`
|
||||||
|
Log out and log back in so that your group membership is re-evaluated
|
||||||
|
|
||||||
## SAI Version
|
## SAI Version
|
||||||
Please refer to [SONiC roadmap](https://github.com/Azure/SONiC/wiki/Sonic-Roadmap-Planning) on the SAI version for each SONiC release.
|
Please refer to [SONiC roadmap](https://github.com/Azure/SONiC/wiki/Sonic-Roadmap-Planning) on the SAI version for each SONiC release.
|
||||||
|
|
||||||
|
@ -31,7 +31,12 @@ set -x -e
|
|||||||
CONFIGURED_ARCH=$([ -f .arch ] && cat .arch || echo amd64)
|
CONFIGURED_ARCH=$([ -f .arch ] && cat .arch || echo amd64)
|
||||||
|
|
||||||
## docker engine version (with platform)
|
## docker engine version (with platform)
|
||||||
DOCKER_VERSION=5:18.09.8~3-0~debian-stretch
|
if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then
|
||||||
|
# Version name differs between ARCH, copying same version as in sonic-slave docker
|
||||||
|
DOCKER_VERSION=18.06.3~ce~3-0~debian
|
||||||
|
else
|
||||||
|
DOCKER_VERSION=5:18.09.8~3-0~debian-stretch
|
||||||
|
fi
|
||||||
LINUX_KERNEL_VERSION=4.9.0-9-2
|
LINUX_KERNEL_VERSION=4.9.0-9-2
|
||||||
|
|
||||||
## Working directory to prepare the file system
|
## Working directory to prepare the file system
|
||||||
@ -458,6 +463,14 @@ build_number: ${BUILD_NUMBER:-0}
|
|||||||
built_by: $USER@$BUILD_HOSTNAME
|
built_by: $USER@$BUILD_HOSTNAME
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
## Copy ASIC config checksum
|
||||||
|
python files/build_scripts/generate_asic_config_checksum.py
|
||||||
|
if [[ ! -f './asic_config_checksum' ]]; then
|
||||||
|
echo 'asic_config_checksum not found'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sudo cp ./asic_config_checksum $FILESYSTEM_ROOT/etc/sonic/asic_config_checksum
|
||||||
|
|
||||||
if [ -f sonic_debian_extension.sh ]; then
|
if [ -f sonic_debian_extension.sh ]; then
|
||||||
./sonic_debian_extension.sh $FILESYSTEM_ROOT $PLATFORM_DIR
|
./sonic_debian_extension.sh $FILESYSTEM_ROOT $PLATFORM_DIR
|
||||||
fi
|
fi
|
||||||
@ -488,10 +501,7 @@ then
|
|||||||
sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo '/debug is mounted in each docker' >> /etc/motd"
|
sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo '/debug is mounted in each docker' >> /etc/motd"
|
||||||
|
|
||||||
sudo mkdir -p $FILESYSTEM_ROOT/src
|
sudo mkdir -p $FILESYSTEM_ROOT/src
|
||||||
pushd src
|
sudo cp $DEBUG_SRC_ARCHIVE_FILE $FILESYSTEM_ROOT/src/
|
||||||
../scripts/dbg_files.sh | sudo tar -cvzf ../$FILESYSTEM_ROOT/src/sonic_src.tar.gz -T -
|
|
||||||
popd
|
|
||||||
|
|
||||||
sudo mkdir -p $FILESYSTEM_ROOT/debug
|
sudo mkdir -p $FILESYSTEM_ROOT/debug
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
# name lanes alias index speed
|
||||||
|
Ethernet0 73,74,75,76,77,78,79,80 fourHundredGigE1 0 400000
|
||||||
|
Ethernet4 65,66,67,68,69,70,71,72 fourHundredGigE2 1 400000
|
||||||
|
Ethernet8 81,82,83,84,85,86,87,88 fourHundredGigE3 2 400000
|
||||||
|
Ethernet12 89,90,91,92,93,94,95,96 fourHundredGigE4 3 400000
|
||||||
|
Ethernet16 97,98,99,100,101,102,103,104 fourHundredGigE5 4 400000
|
||||||
|
Ethernet20 105,106,107,108,109,110,111,112 fourHundredGigE6 5 400000
|
||||||
|
Ethernet24 113,114,115,116,117,118,119,120 fourHundredGigE7 6 400000
|
||||||
|
Ethernet28 121,122,123,124,125,126,127,128 fourHundredGigE8 7 400000
|
||||||
|
Ethernet32 41,42,43,44,45,46,47,48 fourHundredGigE9 8 400000
|
||||||
|
Ethernet36 33,34,35,36,37,38,39,40 fourHundredGigE10 9 400000
|
||||||
|
Ethernet40 49,50,51,52,53,54,55,56 fourHundredGigE11 10 400000
|
||||||
|
Ethernet44 57,58,59,60,61,62,63,64 fourHundredGigE12 11 400000
|
||||||
|
Ethernet48 129,130,131,132,133,134,135,136 fourHundredGigE13 12 400000
|
||||||
|
Ethernet52 137,138,139,140,141,142,143,144 fourHundredGigE14 13 400000
|
||||||
|
Ethernet56 145,146,147,148,149,150,151,152 fourHundredGigE15 14 400000
|
||||||
|
Ethernet60 153,154,155,156,157,158,159,160 fourHundredGigE16 15 400000
|
||||||
|
Ethernet64 169,170,171,172,173,174,175,176 fourHundredGigE17 16 400000
|
||||||
|
Ethernet68 161,162,163,164,165,166,167,168 fourHundredGigE18 17 400000
|
||||||
|
Ethernet72 177,178,179,180,181,182,183,184 fourHundredGigE19 18 400000
|
||||||
|
Ethernet76 185,186,187,188,189,190,191,192 fourHundredGigE20 19 400000
|
||||||
|
Ethernet80 1,2,3,4,5,6,7,8 fourHundredGigE21 20 400000
|
||||||
|
Ethernet84 9,10,11,12,13,14,15,16 fourHundredGigE22 21 400000
|
||||||
|
Ethernet88 17,18,19,20,21,22,23,24 fourHundredGigE23 22 400000
|
||||||
|
Ethernet92 25,26,27,28,29,30,31,32 fourHundredGigE24 23 400000
|
||||||
|
Ethernet96 201,202,203,204,205,206,207,208 fourHundredGigE25 24 400000
|
||||||
|
Ethernet100 193,194,195,196,197,198,199,200 fourHundredGigE26 25 400000
|
||||||
|
Ethernet104 217,218,219,220,221,222,223,224 fourHundredGigE27 26 400000
|
||||||
|
Ethernet108 209,210,211,212,213,214,215,216 fourHundredGigE28 27 400000
|
||||||
|
Ethernet112 233,234,235,236,237,238,239,240 fourHundredGigE29 28 400000
|
||||||
|
Ethernet116 225,226,227,228,229,230,231,232 fourHundredGigE30 29 400000
|
||||||
|
Ethernet120 249,250,251,252,253,254,255,256 fourHundredGigE31 30 400000
|
||||||
|
Ethernet124 241,242,243,244,245,246,247,248 fourHundredGigE32 31 400000
|
@ -0,0 +1 @@
|
|||||||
|
SAI_INIT_CONFIG_FILE=/etc/bcm/th3-as9716-32x400G.config.bcm
|
1
device/accton/x86_64-accton_as9716_32d-r0/default_sku
Normal file
1
device/accton/x86_64-accton_as9716_32d-r0/default_sku
Normal file
@ -0,0 +1 @@
|
|||||||
|
Accton-AS9716-32D t1
|
4
device/accton/x86_64-accton_as9716_32d-r0/installer.conf
Normal file
4
device/accton/x86_64-accton_as9716_32d-r0/installer.conf
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CONSOLE_PORT=0x3f8
|
||||||
|
CONSOLE_DEV=0
|
||||||
|
CONSOLE_SPEED=115200
|
||||||
|
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pcie_aspm=off"
|
21
device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py
Normal file
21
device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
try:
|
||||||
|
import exceptions
|
||||||
|
import binascii
|
||||||
|
import time
|
||||||
|
import optparse
|
||||||
|
import warnings
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from sonic_eeprom import eeprom_base
|
||||||
|
from sonic_eeprom import eeprom_tlvinfo
|
||||||
|
import subprocess
|
||||||
|
except ImportError, e:
|
||||||
|
raise ImportError (str(e) + "- required module not found")
|
||||||
|
|
||||||
|
class board(eeprom_tlvinfo.TlvInfoDecoder):
|
||||||
|
_TLV_INFO_MAX_LEN = 256
|
||||||
|
def __init__(self, name, path, cpld_root, ro):
|
||||||
|
self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom"
|
||||||
|
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
61
device/accton/x86_64-accton_as9716_32d-r0/plugins/psuutil.py
Normal file
61
device/accton/x86_64-accton_as9716_32d-r0/plugins/psuutil.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Accton
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC PSU Base API and
|
||||||
|
# provides the PSUs status which are available in the platform
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_psu.psu_base import PsuBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError (str(e) + "- required module not found")
|
||||||
|
|
||||||
|
class PsuUtil(PsuBase):
|
||||||
|
"""Platform-specific PSUutil class"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
PsuBase.__init__(self)
|
||||||
|
|
||||||
|
self.psu_path = "/sys/bus/i2c/devices/"
|
||||||
|
self.psu_presence = "/psu_present"
|
||||||
|
self.psu_oper_status = "/psu_power_good"
|
||||||
|
self.psu_mapping = {
|
||||||
|
2: "10-0051",
|
||||||
|
1: "9-0050",
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_num_psus(self):
|
||||||
|
return len(self.psu_mapping)
|
||||||
|
|
||||||
|
def get_psu_status(self, index):
|
||||||
|
if index is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
status = 0
|
||||||
|
node = self.psu_path + self.psu_mapping[index]+self.psu_oper_status
|
||||||
|
try:
|
||||||
|
with open(node, 'r') as power_status:
|
||||||
|
status = int(power_status.read())
|
||||||
|
except IOError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return status == 1
|
||||||
|
|
||||||
|
def get_psu_presence(self, index):
|
||||||
|
if index is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
status = 0
|
||||||
|
node = self.psu_path + self.psu_mapping[index] + self.psu_presence
|
||||||
|
try:
|
||||||
|
with open(node, 'r') as presence_status:
|
||||||
|
status = int(presence_status.read())
|
||||||
|
except IOError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return status == 1
|
150
device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py
Normal file
150
device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
# sfputil.py
|
||||||
|
#
|
||||||
|
# Platform-specific SFP transceiver interface for SONiC
|
||||||
|
#
|
||||||
|
|
||||||
|
try:
|
||||||
|
import time
|
||||||
|
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError("%s - required module not found" % str(e))
|
||||||
|
|
||||||
|
|
||||||
|
class SfpUtil(SfpUtilBase):
|
||||||
|
"""Platform-specific SfpUtil class"""
|
||||||
|
|
||||||
|
PORT_START = 0
|
||||||
|
PORT_END = 33
|
||||||
|
PORTS_IN_BLOCK = 34
|
||||||
|
|
||||||
|
BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/"
|
||||||
|
BASE_CPLD1_PATH = "/sys/bus/i2c/devices/20-0061/"
|
||||||
|
BASE_CPLD2_PATH = "/sys/bus/i2c/devices/21-0062/"
|
||||||
|
|
||||||
|
_port_to_is_present = {}
|
||||||
|
_port_to_lp_mode = {}
|
||||||
|
|
||||||
|
_port_to_eeprom_mapping = {}
|
||||||
|
_port_to_i2c_mapping = {
|
||||||
|
0: [1, 25],
|
||||||
|
1: [2, 26],
|
||||||
|
2: [3, 27],
|
||||||
|
3: [4, 28],
|
||||||
|
4: [5, 29],
|
||||||
|
5: [6, 30],
|
||||||
|
6: [7, 31],
|
||||||
|
7: [8, 32],
|
||||||
|
8: [9, 33],
|
||||||
|
9: [10, 34],
|
||||||
|
10: [11, 35],
|
||||||
|
11: [12, 36],
|
||||||
|
12: [13, 37],
|
||||||
|
13: [14, 38],
|
||||||
|
14: [15, 39],
|
||||||
|
15: [16, 40],
|
||||||
|
16: [17, 41],
|
||||||
|
17: [18, 42],
|
||||||
|
18: [19, 43],
|
||||||
|
19: [20, 44],
|
||||||
|
20: [21, 45],
|
||||||
|
21: [22, 46],
|
||||||
|
22: [23, 47],
|
||||||
|
23: [24, 48],
|
||||||
|
24: [25, 49],
|
||||||
|
25: [26, 50],
|
||||||
|
26: [27, 51],
|
||||||
|
27: [28, 52],
|
||||||
|
28: [29, 53],
|
||||||
|
29: [30, 54],
|
||||||
|
30: [31, 55],
|
||||||
|
31: [32, 56],
|
||||||
|
32: [33, 57],
|
||||||
|
33: [34, 58],
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_start(self):
|
||||||
|
return self.PORT_START
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_end(self):
|
||||||
|
return self.PORT_END
|
||||||
|
|
||||||
|
@property
|
||||||
|
def qsfp_ports(self):
|
||||||
|
return range(self.PORT_START, self.PORTS_IN_BLOCK + 1)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_to_eeprom_mapping(self):
|
||||||
|
return self._port_to_eeprom_mapping
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
eeprom_path = self.BASE_OOM_PATH + "eeprom"
|
||||||
|
|
||||||
|
for x in range(0, self.port_end+1):
|
||||||
|
self.port_to_eeprom_mapping[x] = eeprom_path.format(
|
||||||
|
self._port_to_i2c_mapping[x][1]
|
||||||
|
)
|
||||||
|
|
||||||
|
SfpUtilBase.__init__(self)
|
||||||
|
|
||||||
|
def get_presence(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
if port_num < 16 :
|
||||||
|
present_path = self.BASE_CPLD1_PATH + "module_present_" + str(port_num+1)
|
||||||
|
else:
|
||||||
|
present_path = self.BASE_CPLD2_PATH + "module_present_" + str(port_num+1)
|
||||||
|
self.__port_to_is_present = present_path
|
||||||
|
|
||||||
|
try:
|
||||||
|
val_file = open(self.__port_to_is_present)
|
||||||
|
except IOError as e:
|
||||||
|
print "Error: unable to open file: %s" % str(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
content = val_file.readline().rstrip()
|
||||||
|
val_file.close()
|
||||||
|
|
||||||
|
if content == "1":
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_low_power_mode(self, port_num):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def set_low_power_mode(self, port_num, lpmode):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def reset(self, port_num):
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if port_num < 16 :
|
||||||
|
mod_rst_path = self.BASE_CPLD1_PATH + "module_reset_" + str(port_num+1)
|
||||||
|
else:
|
||||||
|
mod_rst_path = self.BASE_CPLD2_PATH + "module_reset_" + str(port_num+1)
|
||||||
|
|
||||||
|
self.__port_to_mod_rst = mod_rst_path
|
||||||
|
try:
|
||||||
|
reg_file = open(self.__port_to_mod_rst, 'r+')
|
||||||
|
except IOError as e:
|
||||||
|
print "Error: unable to open file: %s" % str(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
reg_value = '1'
|
||||||
|
|
||||||
|
reg_file.write(reg_value)
|
||||||
|
reg_file.close()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_transceiver_change_event(self):
|
||||||
|
"""
|
||||||
|
TODO: This function need to be implemented
|
||||||
|
when decide to support monitoring SFP(Xcvrd)
|
||||||
|
on this platform.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"skip_ledd": true
|
||||||
|
}
|
||||||
|
|
@ -815,3 +815,37 @@ serdes_core_tx_polarity_flip_physical{233}=0x36
|
|||||||
serdes_core_tx_polarity_flip_physical{241}=0xc6
|
serdes_core_tx_polarity_flip_physical{241}=0xc6
|
||||||
serdes_core_tx_polarity_flip_physical{249}=0xc3
|
serdes_core_tx_polarity_flip_physical{249}=0xc3
|
||||||
serdes_core_tx_polarity_flip_physical{257}=0x0
|
serdes_core_tx_polarity_flip_physical{257}=0x0
|
||||||
|
serdes_tx_taps_cd0=pam4:-28:124:-12:4:0:0
|
||||||
|
serdes_tx_taps_cd1=pam4:-28:124:-12:4:0:0
|
||||||
|
serdes_tx_taps_cd2=pam4:-28:124:-12:4:0:0
|
||||||
|
serdes_tx_taps_cd3=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd4=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd5=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd6=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd7=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd8=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd9=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd10=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd11=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd12=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd13=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd14=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd15=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd16=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd17=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd18=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd19=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd20=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd21=pam4:-28:124:0:4:0:0
|
||||||
|
serdes_tx_taps_cd22=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd23=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd24=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd25=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd26=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd27=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd28=pam4:-28:120:-4:4:0:0
|
||||||
|
serdes_tx_taps_cd29=pam4:-28:124:-12:4:0:0
|
||||||
|
serdes_tx_taps_cd30=pam4:-28:124:-12:4:0:0
|
||||||
|
serdes_tx_taps_cd31=pam4:-28:124:-12:4:0:0
|
||||||
|
serdes_tx_taps_cd32=pam4:1:34:9:0:0:0
|
||||||
|
serdes_tx_taps_cd33=pam4:1:34:9:0:0:0
|
||||||
|
@ -22,13 +22,13 @@
|
|||||||
"p4_pipelines": [
|
"p4_pipelines": [
|
||||||
{
|
{
|
||||||
"p4_pipeline_name": "pipe",
|
"p4_pipeline_name": "pipe",
|
||||||
"config": "share/tofinopd/switch/pipe/tofino.bin",
|
"config": "share/switch/pipe/tofino.bin",
|
||||||
"context": "share/tofinopd/switch/pipe/context.json"
|
"context": "share/switch/pipe/context.json"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"program-name": "switch",
|
"program-name": "switch",
|
||||||
"switchsai": "lib/libswitchsai.so",
|
"switchsai": "lib/libswitchsai.so",
|
||||||
"bfrt-config": "share/tofinopd/switch/bf-rt.json",
|
"bfrt-config": "share/switch/bf-rt.json",
|
||||||
"model_json_path" : "share/switch/aug_model.json",
|
"model_json_path" : "share/switch/aug_model.json",
|
||||||
"switchapi_port_add": false,
|
"switchapi_port_add": false,
|
||||||
"non_default_port_ppgs": 5
|
"non_default_port_ppgs": 5
|
||||||
|
@ -22,13 +22,13 @@
|
|||||||
"p4_pipelines": [
|
"p4_pipelines": [
|
||||||
{
|
{
|
||||||
"p4_pipeline_name": "pipe",
|
"p4_pipeline_name": "pipe",
|
||||||
"config": "share/tofinopd/switch/pipe/tofino.bin",
|
"config": "share/switch/pipe/tofino.bin",
|
||||||
"context": "share/tofinopd/switch/pipe/context.json"
|
"context": "share/switch/pipe/context.json"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"program-name": "switch",
|
"program-name": "switch",
|
||||||
"switchsai": "lib/libswitchsai.so",
|
"switchsai": "lib/libswitchsai.so",
|
||||||
"bfrt-config": "share/tofinopd/switch/bf-rt.json",
|
"bfrt-config": "share/switch/bf-rt.json",
|
||||||
"model_json_path" : "share/switch/aug_model.json",
|
"model_json_path" : "share/switch/aug_model.json",
|
||||||
"switchapi_port_add": false,
|
"switchapi_port_add": false,
|
||||||
"non_default_port_ppgs": 5
|
"non_default_port_ppgs": 5
|
||||||
|
@ -23,13 +23,13 @@
|
|||||||
"p4_pipelines": [
|
"p4_pipelines": [
|
||||||
{
|
{
|
||||||
"p4_pipeline_name": "pipe",
|
"p4_pipeline_name": "pipe",
|
||||||
"config": "share/tofinopd/switch/pipe/tofino.bin",
|
"config": "share/switch/pipe/tofino.bin",
|
||||||
"context": "share/tofinopd/switch/pipe/context.json"
|
"context": "share/switch/pipe/context.json"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"program-name": "switch",
|
"program-name": "switch",
|
||||||
"switchsai": "lib/libswitchsai.so",
|
"switchsai": "lib/libswitchsai.so",
|
||||||
"bfrt-config": "share/tofinopd/switch/bf-rt.json",
|
"bfrt-config": "share/switch/bf-rt.json",
|
||||||
"model_json_path" : "share/switch/aug_model.json",
|
"model_json_path" : "share/switch/aug_model.json",
|
||||||
"switchapi_port_add": false,
|
"switchapi_port_add": false,
|
||||||
"non_default_port_ppgs": 5
|
"non_default_port_ppgs": 5
|
||||||
|
@ -9,6 +9,9 @@ try:
|
|||||||
import sys
|
import sys
|
||||||
import errno
|
import errno
|
||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
|
import logging.config
|
||||||
|
import yaml
|
||||||
|
|
||||||
sys.path.append(os.path.dirname(__file__))
|
sys.path.append(os.path.dirname(__file__))
|
||||||
import pltfm_mgr_rpc
|
import pltfm_mgr_rpc
|
||||||
@ -71,13 +74,17 @@ transport = None
|
|||||||
pltfm_mgr = None
|
pltfm_mgr = None
|
||||||
|
|
||||||
EEPROM_SYMLINK = "/var/run/platform/eeprom/syseeprom"
|
EEPROM_SYMLINK = "/var/run/platform/eeprom/syseeprom"
|
||||||
|
EEPROM_STATUS = "/var/run/platform/eeprom/status"
|
||||||
|
|
||||||
class board(eeprom_tlvinfo.TlvInfoDecoder):
|
class board(eeprom_tlvinfo.TlvInfoDecoder):
|
||||||
RETRIES = 30
|
RETRIES = 3
|
||||||
|
|
||||||
def __init__(self, name, path, cpld_root, ro):
|
def __init__(self, name, path, cpld_root, ro):
|
||||||
|
|
||||||
|
with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f:
|
||||||
|
config_dict = yaml.load(f)
|
||||||
|
logging.config.dictConfig(config_dict)
|
||||||
|
|
||||||
if not os.path.exists(os.path.dirname(EEPROM_SYMLINK)):
|
if not os.path.exists(os.path.dirname(EEPROM_SYMLINK)):
|
||||||
try:
|
try:
|
||||||
os.makedirs(os.path.dirname(EEPROM_SYMLINK))
|
os.makedirs(os.path.dirname(EEPROM_SYMLINK))
|
||||||
@ -86,19 +93,17 @@ class board(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
open(EEPROM_SYMLINK, 'a').close()
|
open(EEPROM_SYMLINK, 'a').close()
|
||||||
|
f = open(EEPROM_STATUS, 'w')
|
||||||
|
f.write("initializing..")
|
||||||
|
f.close()
|
||||||
|
|
||||||
self.eeprom_path = EEPROM_SYMLINK
|
self.eeprom_path = EEPROM_SYMLINK
|
||||||
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
super(board, self).__init__(self.eeprom_path, 0, EEPROM_STATUS, True)
|
||||||
|
|
||||||
for attempt in range(self.RETRIES + 1):
|
for attempt in range(self.RETRIES):
|
||||||
if not self.eeprom_init():
|
if self.eeprom_init() or (attempt + 1 >= self.RETRIES):
|
||||||
time.sleep(1)
|
|
||||||
else:
|
|
||||||
break
|
break
|
||||||
|
time.sleep(1)
|
||||||
if attempt == self.RETRIES:
|
|
||||||
raise RuntimeError("Could not initialize syseeprom")
|
|
||||||
|
|
||||||
|
|
||||||
def thrift_setup(self):
|
def thrift_setup(self):
|
||||||
global thrift_server, transport, pltfm_mgr
|
global thrift_server, transport, pltfm_mgr
|
||||||
@ -119,13 +124,18 @@ class board(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
|
|
||||||
def eeprom_init(self):
|
def eeprom_init(self):
|
||||||
global pltfm_mgr
|
global pltfm_mgr
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.thrift_setup()
|
self.thrift_setup()
|
||||||
eeprom = pltfm_mgr.pltfm_mgr_sys_eeprom_get()
|
eeprom = pltfm_mgr.pltfm_mgr_sys_eeprom_get()
|
||||||
self.thrift_teardown()
|
self.thrift_teardown()
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
f = open(EEPROM_STATUS, 'w')
|
||||||
|
f.write("ok")
|
||||||
|
f.close()
|
||||||
|
|
||||||
eeprom_params = ""
|
eeprom_params = ""
|
||||||
for attr, val in eeprom.__dict__.iteritems():
|
for attr, val in eeprom.__dict__.iteritems():
|
||||||
if val is None:
|
if val is None:
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
version: 1
|
||||||
|
disable_existing_loggers: False
|
||||||
|
|
||||||
|
formatters:
|
||||||
|
simple:
|
||||||
|
format: '%(asctime)s %(name)-30s %(levelname)-7s %(message)s'
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
file:
|
||||||
|
class: logging.handlers.RotatingFileHandler
|
||||||
|
formatter: simple
|
||||||
|
filename: /var/log/platform.log
|
||||||
|
|
||||||
|
root:
|
||||||
|
level: ERROR
|
||||||
|
handlers:
|
||||||
|
- file
|
@ -34,6 +34,7 @@ class SfpUtil(SfpUtilBase):
|
|||||||
QSFP_PORT_START = 1
|
QSFP_PORT_START = 1
|
||||||
QSFP_PORT_END = 0
|
QSFP_PORT_END = 0
|
||||||
EEPROM_OFFSET = 0
|
EEPROM_OFFSET = 0
|
||||||
|
QSFP_CHECK_INTERVAL = 4
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port_start(self):
|
def port_start(self):
|
||||||
@ -56,6 +57,11 @@ class SfpUtil(SfpUtilBase):
|
|||||||
raise Exception()
|
raise Exception()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.ready = False
|
||||||
|
self.phy_port_dict = {'-1': 'system_not_ready'}
|
||||||
|
self.phy_port_cur_state = {}
|
||||||
|
self.qsfp_interval = self.QSFP_CHECK_INTERVAL
|
||||||
|
|
||||||
if not os.path.exists(os.path.dirname(SFP_EEPROM_CACHE)):
|
if not os.path.exists(os.path.dirname(SFP_EEPROM_CACHE)):
|
||||||
try:
|
try:
|
||||||
os.makedirs(os.path.dirname(SFP_EEPROM_CACHE))
|
os.makedirs(os.path.dirname(SFP_EEPROM_CACHE))
|
||||||
@ -142,12 +148,76 @@ class SfpUtil(SfpUtilBase):
|
|||||||
self.thrift_teardown()
|
self.thrift_teardown()
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
def check_transceiver_change(self):
|
||||||
|
if not self.ready:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.phy_port_dict = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.thrift_setup()
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get presence of each SFP
|
||||||
|
for port in range(self.port_start, self.port_end + 1):
|
||||||
|
try:
|
||||||
|
sfp_resent = pltfm_mgr.pltfm_mgr_qsfp_presence_get(port)
|
||||||
|
except:
|
||||||
|
sfp_resent = False
|
||||||
|
sfp_state = '1' if sfp_resent else '0'
|
||||||
|
|
||||||
|
if port in self.phy_port_cur_state:
|
||||||
|
if self.phy_port_cur_state[port] != sfp_state:
|
||||||
|
self.phy_port_dict[port] = sfp_state
|
||||||
|
else:
|
||||||
|
self.phy_port_dict[port] = sfp_state
|
||||||
|
|
||||||
|
# Update port current state
|
||||||
|
self.phy_port_cur_state[port] = sfp_state
|
||||||
|
|
||||||
|
self.thrift_teardown()
|
||||||
|
|
||||||
def get_transceiver_change_event(self, timeout=0):
|
def get_transceiver_change_event(self, timeout=0):
|
||||||
phy_port_dict = {}
|
forever = False
|
||||||
status = True
|
if timeout == 0:
|
||||||
# TODO: Process transceiver plug-in/out event
|
forever = True
|
||||||
time.sleep(1)
|
elif timeout > 0:
|
||||||
return status, phy_port_dict
|
timeout = timeout / float(1000) # Convert to secs
|
||||||
|
else:
|
||||||
|
print "get_transceiver_change_event:Invalid timeout value", timeout
|
||||||
|
return False, {}
|
||||||
|
|
||||||
|
while forever or timeout > 0:
|
||||||
|
if not self.ready:
|
||||||
|
try:
|
||||||
|
self.thrift_setup()
|
||||||
|
self.thrift_teardown()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.ready = True
|
||||||
|
self.phy_port_dict = {}
|
||||||
|
break
|
||||||
|
elif self.qsfp_interval == 0:
|
||||||
|
self.qsfp_interval = self.QSFP_CHECK_INTERVAL
|
||||||
|
|
||||||
|
# Process transceiver plug-in/out event
|
||||||
|
self.check_transceiver_change()
|
||||||
|
|
||||||
|
# Break if tranceiver state has changed
|
||||||
|
if bool(self.phy_port_dict):
|
||||||
|
break
|
||||||
|
|
||||||
|
if timeout:
|
||||||
|
timeout -= 1
|
||||||
|
|
||||||
|
if self.qsfp_interval:
|
||||||
|
self.qsfp_interval -= 1
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
return self.ready, self.phy_port_dict
|
||||||
|
|
||||||
def _get_port_eeprom_path(self, port_num, devid):
|
def _get_port_eeprom_path(self, port_num, devid):
|
||||||
eeprom_path = None
|
eeprom_path = None
|
||||||
|
@ -23,13 +23,13 @@
|
|||||||
"p4_pipelines": [
|
"p4_pipelines": [
|
||||||
{
|
{
|
||||||
"p4_pipeline_name": "pipe",
|
"p4_pipeline_name": "pipe",
|
||||||
"config": "share/tofinopd/switch/pipe/tofino.bin",
|
"config": "share/switch/pipe/tofino.bin",
|
||||||
"context": "share/tofinopd/switch/pipe/context.json"
|
"context": "share/switch/pipe/context.json"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"program-name": "switch",
|
"program-name": "switch",
|
||||||
"switchsai": "lib/libswitchsai.so",
|
"switchsai": "lib/libswitchsai.so",
|
||||||
"bfrt-config": "share/tofinopd/switch/bf-rt.json",
|
"bfrt-config": "share/switch/bf-rt.json",
|
||||||
"model_json_path" : "share/switch/aug_model.json",
|
"model_json_path" : "share/switch/aug_model.json",
|
||||||
"switchapi_port_add": false,
|
"switchapi_port_add": false,
|
||||||
"non_default_port_ppgs": 5
|
"non_default_port_ppgs": 5
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Configuration file generated by pwmconfig, changes will be lost
|
# Configuration file generated by pwmconfig, changes will be lost
|
||||||
INTERVAL=2
|
INTERVAL=2
|
||||||
DEVPATH=hwmon3=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-23/23-004d hwmon2=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-11/11-001a
|
DEVPATH=hwmon3=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-23/23-004d hwmon2=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-11/11-001a
|
||||||
DEVNAME=hwmon3=emc2305 hwmon2=max6697
|
DEVNAME=hwmon3=emc2305 hwmon2=max6699
|
||||||
FCTEMPS=hwmon3/device/pwm1=hwmon2/temp1_input hwmon3/device/pwm2=hwmon2/temp1_input hwmon3/device/pwm4=hwmon2/temp1_input
|
FCTEMPS=hwmon3/device/pwm1=hwmon2/temp1_input hwmon3/device/pwm2=hwmon2/temp1_input hwmon3/device/pwm4=hwmon2/temp1_input
|
||||||
FCFANS=hwmon3/device/pwm1=hwmon3/device/fan1_input hwmon3/device/pwm2=hwmon3/device/fan2_input hwmon3/device/pwm4=hwmon3/device/fan4_input
|
FCFANS=hwmon3/device/pwm1=hwmon3/device/fan1_input hwmon3/device/pwm2=hwmon3/device/fan2_input hwmon3/device/pwm4=hwmon3/device/fan4_input
|
||||||
MINTEMP=hwmon3/device/pwm1=27 hwmon3/device/pwm2=27 hwmon3/device/pwm4=27
|
MINTEMP=hwmon3/device/pwm1=27 hwmon3/device/pwm2=27 hwmon3/device/pwm4=27
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
__all__ = ["platform", "chassis"]
|
||||||
|
from sonic_platform import *
|
@ -26,13 +26,16 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
NUM_FAN = 3
|
NUM_FAN_TRAY = 3
|
||||||
|
NUM_FAN = 1
|
||||||
NUM_PSU = 2
|
NUM_PSU = 2
|
||||||
NUM_THERMAL = 7
|
NUM_THERMAL = 7
|
||||||
NUM_SFP = 52
|
NUM_SFP = 52
|
||||||
RESET_REGISTER = "0x112"
|
RESET_REGISTER = "0x112"
|
||||||
REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt"
|
HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt"
|
||||||
|
PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/previous-reboot-cause.txt"
|
||||||
COMPONENT_NAME_LIST = ["SMC_CPLD", "MMC_CPLD", "BIOS"]
|
COMPONENT_NAME_LIST = ["SMC_CPLD", "MMC_CPLD", "BIOS"]
|
||||||
|
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
||||||
|
|
||||||
|
|
||||||
class Chassis(ChassisBase):
|
class Chassis(ChassisBase):
|
||||||
@ -40,9 +43,10 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.config_data = {}
|
self.config_data = {}
|
||||||
for index in range(0, NUM_FAN):
|
for fant_index in range(0, NUM_FAN_TRAY):
|
||||||
fan = Fan(index)
|
for fan_index in range(0, NUM_FAN):
|
||||||
self._fan_list.append(fan)
|
fan = Fan(fant_index, fan_index)
|
||||||
|
self._fan_list.append(fan)
|
||||||
for index in range(0, NUM_PSU):
|
for index in range(0, NUM_PSU):
|
||||||
psu = Psu(index)
|
psu = Psu(index)
|
||||||
self._psu_list.append(psu)
|
self._psu_list.append(psu)
|
||||||
@ -53,17 +57,23 @@ class Chassis(ChassisBase):
|
|||||||
sfp = Sfp(index)
|
sfp = Sfp(index)
|
||||||
self._sfp_list.append(sfp)
|
self._sfp_list.append(sfp)
|
||||||
ChassisBase.__init__(self)
|
ChassisBase.__init__(self)
|
||||||
|
self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host(
|
||||||
|
) else PMON_REBOOT_CAUSE_PATH
|
||||||
self._component_name_list = COMPONENT_NAME_LIST
|
self._component_name_list = COMPONENT_NAME_LIST
|
||||||
self._watchdog = Watchdog()
|
self._watchdog = Watchdog()
|
||||||
self._eeprom = Tlv()
|
self._eeprom = Tlv()
|
||||||
|
|
||||||
|
def __is_host(self):
|
||||||
|
return os.system(HOST_CHK_CMD) == 0
|
||||||
|
|
||||||
def __read_txt_file(self, file_path):
|
def __read_txt_file(self, file_path):
|
||||||
try:
|
try:
|
||||||
with open(file_path, 'r') as fd:
|
with open(file_path, 'r') as fd:
|
||||||
data = fd.read()
|
data = fd.read()
|
||||||
return data.strip()
|
return data.strip()
|
||||||
except IOError:
|
except IOError:
|
||||||
raise IOError("Unable to open %s file !" % file_path)
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
def get_base_mac(self):
|
def get_base_mac(self):
|
||||||
"""
|
"""
|
||||||
@ -137,14 +147,15 @@ class Chassis(ChassisBase):
|
|||||||
description = 'None'
|
description = 'None'
|
||||||
reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
|
reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
|
||||||
hw_reboot_cause = self.component.get_register_value(RESET_REGISTER)
|
hw_reboot_cause = self.component.get_register_value(RESET_REGISTER)
|
||||||
sw_reboot_cause = self.__read_txt_file(REBOOT_CAUSE_PATH)
|
sw_reboot_cause = self.__read_txt_file(
|
||||||
|
self._reboot_cause_path) or "Unknown"
|
||||||
|
|
||||||
if sw_reboot_cause != "Unexpected reboot":
|
if hw_reboot_cause == "0x55":
|
||||||
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
|
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
|
||||||
description = sw_reboot_cause
|
description = sw_reboot_cause
|
||||||
elif hw_reboot_cause == "0x11":
|
elif hw_reboot_cause == "0x11":
|
||||||
reboot_cause = self.REBOOT_CAUSE_POWER_LOSS
|
reboot_cause = self.REBOOT_CAUSE_POWER_LOSS
|
||||||
elif hw_reboot_cause == "0x33" or hw_reboot_cause == "0x55":
|
elif hw_reboot_cause == "0x33":
|
||||||
reboot_cause = self.REBOOT_CAUSE_WATCHDOG
|
reboot_cause = self.REBOOT_CAUSE_WATCHDOG
|
||||||
else:
|
else:
|
||||||
reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
|
reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
|
||||||
|
@ -17,34 +17,50 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
EMC2305_FAN_PATH = "/sys/bus/i2c/drivers/emc2305/"
|
EMC2305_PATH = "/sys/bus/i2c/drivers/emc2305/"
|
||||||
FAN_PATH = "/sys/devices/platform/e1031.smc/"
|
FAN_PATH = "/sys/devices/platform/e1031.smc/"
|
||||||
SYS_GPIO_DIR = "/sys/class/gpio"
|
|
||||||
EMC2305_MAX_PWM = 255
|
EMC2305_MAX_PWM = 255
|
||||||
EMC2305_FAN_PWM = "pwm{}"
|
EMC2305_FAN_PWM = "pwm{}"
|
||||||
EMC2305_FAN_TARGET = "fan{}_target"
|
EMC2305_FAN_TARGET = "fan{}_target"
|
||||||
EMC2305_FAN_INPUT = "pwm{}"
|
EMC2305_FAN_INPUT = "pwm{}"
|
||||||
FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3"]
|
FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3"]
|
||||||
|
PSU_FAN_MAX_RPM = 11000
|
||||||
|
PSU_HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
||||||
|
PSU_I2C_MAPPING = {
|
||||||
|
0: {
|
||||||
|
"num": 13,
|
||||||
|
"addr": "5b"
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
"num": 12,
|
||||||
|
"addr": "5a"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Fan(FanBase):
|
class Fan(FanBase):
|
||||||
"""Platform-specific Fan class"""
|
"""Platform-specific Fan class"""
|
||||||
|
|
||||||
def __init__(self, fan_index):
|
def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
|
||||||
self.index = fan_index
|
self.fan_index = fan_index
|
||||||
self.config_data = {}
|
self.fan_tray_index = fan_tray_index
|
||||||
self.fan_speed = 0
|
self.is_psu_fan = is_psu_fan
|
||||||
|
if self.is_psu_fan:
|
||||||
|
self.psu_index = psu_index
|
||||||
|
self.psu_i2c_num = PSU_I2C_MAPPING[self.psu_index]["num"]
|
||||||
|
self.psu_i2c_addr = PSU_I2C_MAPPING[self.psu_index]["addr"]
|
||||||
|
self.psu_hwmon_path = PSU_HWMON_PATH.format(
|
||||||
|
self.psu_i2c_num, self.psu_i2c_addr)
|
||||||
|
|
||||||
# e1031 fan attributes
|
# e1031 fan attributes
|
||||||
# Single emc2305 chip located at i2c-23-4d
|
# Single emc2305 chip located at i2c-23-4d
|
||||||
# to control a fan module
|
# to control a fan module
|
||||||
self.e1031_emc2305_chip = [
|
self.emc2305_chip_mapping = [
|
||||||
{
|
{
|
||||||
'device': "23-004d",
|
'device': "23-004d",
|
||||||
'index_map': [1, 2, 4]
|
'index_map': [1, 2, 4]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
self.fan_e1031_presence = "fan{}_prs"
|
self.fan_e1031_presence = "fan{}_prs"
|
||||||
self.fan_e1031_direction = "fan{}_dir"
|
self.fan_e1031_direction = "fan{}_dir"
|
||||||
self.fan_e1031_led = "fan{}_led"
|
self.fan_e1031_led = "fan{}_led"
|
||||||
@ -55,84 +71,103 @@ class Fan(FanBase):
|
|||||||
}
|
}
|
||||||
FanBase.__init__(self)
|
FanBase.__init__(self)
|
||||||
|
|
||||||
def get_direction(self):
|
def __read_txt_file(self, file_path):
|
||||||
|
|
||||||
direction = self.FAN_DIRECTION_INTAKE
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fan_direction_file = (FAN_PATH +
|
with open(file_path, 'r') as fd:
|
||||||
self.fan_e1031_direction.format(self.index+1))
|
data = fd.read()
|
||||||
with open(fan_direction_file, 'r') as file:
|
return data.strip()
|
||||||
raw = file.read().strip('\r\n')
|
|
||||||
if str(raw).upper() == "F2B":
|
|
||||||
direction = self.FAN_DIRECTION_INTAKE
|
|
||||||
else:
|
|
||||||
direction = self.FAN_DIRECTION_EXHAUST
|
|
||||||
except IOError:
|
except IOError:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def __write_txt_file(self, file_path, value):
|
||||||
|
try:
|
||||||
|
with open(file_path, 'w') as fd:
|
||||||
|
fd.write(str(value))
|
||||||
|
except:
|
||||||
return False
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __search_file_by_name(self, directory, file_name):
|
||||||
|
for dirpath, dirnames, files in os.walk(directory):
|
||||||
|
for name in files:
|
||||||
|
file_path = os.path.join(dirpath, name)
|
||||||
|
if name in file_name:
|
||||||
|
return file_path
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_direction(self):
|
||||||
|
"""
|
||||||
|
Retrieves the direction of fan
|
||||||
|
Returns:
|
||||||
|
A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST
|
||||||
|
depending on fan direction
|
||||||
|
"""
|
||||||
|
direction = self.FAN_DIRECTION_EXHAUST
|
||||||
|
if not self.is_psu_fan:
|
||||||
|
fan_direction_file = (FAN_PATH +
|
||||||
|
self.fan_e1031_direction.format(self.fan_tray_index+1))
|
||||||
|
raw = self.__read_txt_file(fan_direction_file).strip('\r\n')
|
||||||
|
direction = self.FAN_DIRECTION_INTAKE if str(
|
||||||
|
raw).upper() == "F2B" else self.FAN_DIRECTION_EXHAUST
|
||||||
|
|
||||||
return direction
|
return direction
|
||||||
|
|
||||||
def get_speed(self):
|
def get_speed(self):
|
||||||
"""
|
"""
|
||||||
E1031 platform specific data:
|
Retrieves the speed of fan as a percentage of full speed
|
||||||
|
Returns:
|
||||||
|
An integer, the percentage of full fan speed, in the range 0 (off)
|
||||||
|
to 100 (full speed)
|
||||||
|
|
||||||
|
Note:
|
||||||
speed = pwm_in/255*100
|
speed = pwm_in/255*100
|
||||||
"""
|
"""
|
||||||
# TODO: Seperate PSU's fan and main fan class
|
speed = 0
|
||||||
if self.fan_speed != 0:
|
if self.is_psu_fan:
|
||||||
return self.fan_speed
|
fan_speed_sysfs_name = "fan{}_input".format(self.fan_index+1)
|
||||||
else:
|
fan_speed_sysfs_path = self.__search_file_by_name(
|
||||||
speed = 0
|
self.psu_hwmon_path, fan_speed_sysfs_name)
|
||||||
pwm = []
|
fan_speed_rpm = self.__read_txt_file(fan_speed_sysfs_path) or 0
|
||||||
emc2305_chips = self.e1031_emc2305_chip
|
fan_speed_raw = float(fan_speed_rpm)/PSU_FAN_MAX_RPM * 100
|
||||||
|
speed = math.ceil(float(fan_speed_rpm) * 100 / PSU_FAN_MAX_RPM)
|
||||||
|
elif self.get_presence():
|
||||||
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
|
device = chip['device']
|
||||||
|
fan_index = chip['index_map']
|
||||||
|
sysfs_path = "%s%s/%s" % (
|
||||||
|
EMC2305_PATH, device, EMC2305_FAN_INPUT)
|
||||||
|
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
||||||
|
raw = self.__read_txt_file(sysfs_path).strip('\r\n')
|
||||||
|
pwm = int(raw, 10) if raw else 0
|
||||||
|
speed = math.ceil(float(pwm * 100 / EMC2305_MAX_PWM))
|
||||||
|
|
||||||
for chip in emc2305_chips:
|
return int(speed)
|
||||||
device = chip['device']
|
|
||||||
fan_index = chip['index_map']
|
|
||||||
sysfs_path = "%s%s/%s" % (
|
|
||||||
EMC2305_FAN_PATH, device, EMC2305_FAN_INPUT)
|
|
||||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
|
||||||
try:
|
|
||||||
with open(sysfs_path, 'r') as file:
|
|
||||||
raw = file.read().strip('\r\n')
|
|
||||||
pwm.append(int(raw, 10))
|
|
||||||
except IOError:
|
|
||||||
raise IOError("Unable to open " + sysfs_path)
|
|
||||||
|
|
||||||
speed = math.ceil(
|
|
||||||
float(pwm[0]) * 100 / EMC2305_MAX_PWM)
|
|
||||||
|
|
||||||
return int(speed)
|
|
||||||
|
|
||||||
def get_target_speed(self):
|
def get_target_speed(self):
|
||||||
"""
|
"""
|
||||||
E1031 platform specific data:
|
Retrieves the target (expected) speed of the fan
|
||||||
|
Returns:
|
||||||
|
An integer, the percentage of full fan speed, in the range 0 (off)
|
||||||
|
to 100 (full speed)
|
||||||
|
|
||||||
|
Note:
|
||||||
speed_pc = pwm_target/255*100
|
speed_pc = pwm_target/255*100
|
||||||
|
|
||||||
0 : when PWM mode is use
|
0 : when PWM mode is use
|
||||||
pwm : when pwm mode is not use
|
pwm : when pwm mode is not use
|
||||||
|
|
||||||
"""
|
"""
|
||||||
target = 0
|
target = 0
|
||||||
pwm = []
|
if not self.is_psu_fan:
|
||||||
emc2305_chips = self.e1031_emc2305_chip
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
|
|
||||||
for chip in emc2305_chips:
|
|
||||||
device = chip['device']
|
device = chip['device']
|
||||||
fan_index = chip['index_map']
|
fan_index = chip['index_map']
|
||||||
sysfs_path = "%s%s/%s" % (
|
sysfs_path = "%s%s/%s" % (
|
||||||
EMC2305_FAN_PATH, device, EMC2305_FAN_TARGET)
|
EMC2305_PATH, device, EMC2305_FAN_TARGET)
|
||||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
||||||
try:
|
raw = self.__read_txt_file(sysfs_path).strip('\r\n')
|
||||||
with open(sysfs_path, 'r') as file:
|
pwm = int(raw, 10) if raw else 0
|
||||||
raw = file.read().strip('\r\n')
|
target = math.ceil(float(pwm) * 100 / EMC2305_MAX_PWM)
|
||||||
pwm.append(int(raw, 10))
|
|
||||||
except IOError:
|
|
||||||
raise IOError("Unable to open " + sysfs_path)
|
|
||||||
|
|
||||||
target = pwm[0] * 100 / EMC2305_MAX_PWM
|
|
||||||
|
|
||||||
return target
|
return target
|
||||||
|
|
||||||
@ -147,40 +182,50 @@ class Fan(FanBase):
|
|||||||
|
|
||||||
def set_speed(self, speed):
|
def set_speed(self, speed):
|
||||||
"""
|
"""
|
||||||
Depends on pwm or target mode is selected:
|
Sets the fan speed
|
||||||
|
Args:
|
||||||
|
speed: An integer, the percentage of full fan speed to set fan to,
|
||||||
|
in the range 0 (off) to 100 (full speed)
|
||||||
|
Returns:
|
||||||
|
A boolean, True if speed is set successfully, False if not
|
||||||
|
|
||||||
|
Note:
|
||||||
|
Depends on pwm or target mode is selected:
|
||||||
1) pwm = speed_pc * 255 <-- Currently use this mode.
|
1) pwm = speed_pc * 255 <-- Currently use this mode.
|
||||||
2) target_pwm = speed_pc * 100 / 255
|
2) target_pwm = speed_pc * 100 / 255
|
||||||
2.1) set pwm{}_enable to 3
|
2.1) set pwm{}_enable to 3
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pwm = speed * 255 / 100
|
pwm = speed * 255 / 100
|
||||||
emc2305_chips = self.e1031_emc2305_chip
|
if not self.is_psu_fan and self.get_presence():
|
||||||
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
for chip in emc2305_chips:
|
|
||||||
device = chip['device']
|
device = chip['device']
|
||||||
fan_index = chip['index_map']
|
fan_index = chip['index_map']
|
||||||
sysfs_path = "%s%s/%s" % (
|
sysfs_path = "%s%s/%s" % (
|
||||||
EMC2305_FAN_PATH, device, EMC2305_FAN_PWM)
|
EMC2305_PATH, device, EMC2305_FAN_PWM)
|
||||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
||||||
try:
|
return self.__write_txt_file(sysfs_path, int(pwm))
|
||||||
with open(sysfs_path, 'w') as file:
|
|
||||||
file.write(str(int(pwm)))
|
|
||||||
except IOError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
return False
|
||||||
|
|
||||||
def set_status_led(self, color):
|
def set_status_led(self, color):
|
||||||
|
"""
|
||||||
try:
|
Sets the state of the fan module status LED
|
||||||
|
Args:
|
||||||
|
color: A string representing the color with which to set the
|
||||||
|
fan module status LED
|
||||||
|
Returns:
|
||||||
|
bool: True if status LED state is set successfully, False if not
|
||||||
|
"""
|
||||||
|
set_status_led = False
|
||||||
|
if not self.is_psu_fan:
|
||||||
fan_led_file = (FAN_PATH +
|
fan_led_file = (FAN_PATH +
|
||||||
self.fan_e1031_led.format(self.index+1))
|
self.fan_e1031_led.format(self.fan_tray_index+1))
|
||||||
with open(fan_led_file, 'r') as file:
|
|
||||||
file.write(self.fan_e1031_led_col_map[color])
|
|
||||||
except IOError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
set_status_led = self.__write_txt_file(
|
||||||
|
fan_led_file, self.fan_e1031_led_col_map[color]) if self.get_presence() else False
|
||||||
|
|
||||||
|
return set_status_led
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
@ -188,7 +233,10 @@ class Fan(FanBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: The name of the device
|
string: The name of the device
|
||||||
"""
|
"""
|
||||||
return FAN_NAME_LIST[self.index]
|
fan_name = FAN_NAME_LIST[self.fan_tray_index] if not self.is_psu_fan else "PSU-{} FAN-{}".format(
|
||||||
|
self.psu_index+1, self.fan_index+1)
|
||||||
|
|
||||||
|
return fan_name
|
||||||
|
|
||||||
def get_presence(self):
|
def get_presence(self):
|
||||||
"""
|
"""
|
||||||
@ -196,13 +244,8 @@ class Fan(FanBase):
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if PSU is present, False if not
|
bool: True if PSU is present, False if not
|
||||||
"""
|
"""
|
||||||
|
fan_direction_file = (FAN_PATH +
|
||||||
|
self.fan_e1031_presence.format(self.fan_tray_index+1))
|
||||||
|
present_str = self.__read_txt_file(fan_direction_file) or '1'
|
||||||
|
|
||||||
try:
|
return int(present_str) == 0 if not self.is_psu_fan else True
|
||||||
fan_direction_file = (FAN_PATH +
|
|
||||||
self.fan_e1031_presence.format(self.index+1))
|
|
||||||
with open(fan_direction_file, 'r') as file:
|
|
||||||
present = int(file.read().strip('\r\n'))
|
|
||||||
except IOError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return present == 0
|
|
||||||
|
@ -18,8 +18,20 @@ except ImportError as e:
|
|||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
FAN_E1031_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input"
|
FAN_E1031_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input"
|
||||||
|
HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
||||||
FAN_MAX_RPM = 11000
|
FAN_MAX_RPM = 11000
|
||||||
PSU_NAME_LIST = ["PSU-R", "PSU-L"]
|
PSU_NAME_LIST = ["PSU-R", "PSU-L"]
|
||||||
|
PSU_NUM_FAN = [1, 1]
|
||||||
|
PSU_I2C_MAPPING = {
|
||||||
|
0: {
|
||||||
|
"num": 13,
|
||||||
|
"addr": "5b"
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
"num": 12,
|
||||||
|
"addr": "5a"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Psu(PsuBase):
|
class Psu(PsuBase):
|
||||||
@ -31,26 +43,109 @@ class Psu(PsuBase):
|
|||||||
self.psu_path = "/sys/devices/platform/e1031.smc/"
|
self.psu_path = "/sys/devices/platform/e1031.smc/"
|
||||||
self.psu_presence = "psu{}_prs"
|
self.psu_presence = "psu{}_prs"
|
||||||
self.psu_oper_status = "psu{}_status"
|
self.psu_oper_status = "psu{}_status"
|
||||||
|
self.i2c_num = PSU_I2C_MAPPING[self.index]["num"]
|
||||||
|
self.i2c_addr = PSU_I2C_MAPPING[self.index]["addr"]
|
||||||
|
self.hwmon_path = HWMON_PATH.format(self.i2c_num, self.i2c_addr)
|
||||||
|
for fan_index in range(0, PSU_NUM_FAN[self.index]):
|
||||||
|
fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index)
|
||||||
|
self._fan_list.append(fan)
|
||||||
|
PsuBase.__init__(self)
|
||||||
|
|
||||||
def get_fan(self):
|
def __read_txt_file(self, file_path):
|
||||||
"""
|
|
||||||
Retrieves object representing the fan module contained in this PSU
|
|
||||||
Returns:
|
|
||||||
An object dervied from FanBase representing the fan module
|
|
||||||
contained in this PSU
|
|
||||||
"""
|
|
||||||
fan_speed_path = FAN_E1031_SPEED_PATH.format(
|
|
||||||
str(self.index+3))
|
|
||||||
try:
|
try:
|
||||||
with open(fan_speed_path) as fan_speed_file:
|
with open(file_path, 'r') as fd:
|
||||||
fan_speed_rpm = int(fan_speed_file.read())
|
data = fd.read()
|
||||||
|
return data.strip()
|
||||||
except IOError:
|
except IOError:
|
||||||
fan_speed = 0
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
fan_speed = float(fan_speed_rpm)/FAN_MAX_RPM * 100
|
def __search_file_by_contain(self, directory, search_str, file_start):
|
||||||
fan = Fan(0)
|
for dirpath, dirnames, files in os.walk(directory):
|
||||||
fan.fan_speed = int(fan_speed) if int(fan_speed) <= 100 else 100
|
for name in files:
|
||||||
return fan
|
file_path = os.path.join(dirpath, name)
|
||||||
|
if name.startswith(file_start) and search_str in self.__read_txt_file(file_path):
|
||||||
|
return file_path
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_voltage(self):
|
||||||
|
"""
|
||||||
|
Retrieves current PSU voltage output
|
||||||
|
Returns:
|
||||||
|
A float number, the output voltage in volts,
|
||||||
|
e.g. 12.1
|
||||||
|
"""
|
||||||
|
psu_voltage = 0.0
|
||||||
|
voltage_name = "in{}_input"
|
||||||
|
voltage_label = "vout1"
|
||||||
|
|
||||||
|
vout_label_path = self.__search_file_by_contain(
|
||||||
|
self.hwmon_path, voltage_label, "in")
|
||||||
|
if vout_label_path:
|
||||||
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
|
basename = os.path.basename(vout_label_path)
|
||||||
|
in_num = filter(str.isdigit, basename)
|
||||||
|
vout_path = os.path.join(
|
||||||
|
dir_name, voltage_name.format(in_num))
|
||||||
|
vout_val = self.__read_txt_file(vout_path)
|
||||||
|
psu_voltage = float(vout_val) / 1000
|
||||||
|
|
||||||
|
return psu_voltage
|
||||||
|
|
||||||
|
def get_current(self):
|
||||||
|
"""
|
||||||
|
Retrieves present electric current supplied by PSU
|
||||||
|
Returns:
|
||||||
|
A float number, the electric current in amperes, e.g 15.4
|
||||||
|
"""
|
||||||
|
psu_current = 0.0
|
||||||
|
current_name = "curr{}_input"
|
||||||
|
current_label = "iout1"
|
||||||
|
|
||||||
|
curr_label_path = self.__search_file_by_contain(
|
||||||
|
self.hwmon_path, current_label, "cur")
|
||||||
|
if curr_label_path:
|
||||||
|
dir_name = os.path.dirname(curr_label_path)
|
||||||
|
basename = os.path.basename(curr_label_path)
|
||||||
|
cur_num = filter(str.isdigit, basename)
|
||||||
|
cur_path = os.path.join(
|
||||||
|
dir_name, current_name.format(cur_num))
|
||||||
|
cur_val = self.__read_txt_file(cur_path)
|
||||||
|
psu_current = float(cur_val) / 1000
|
||||||
|
|
||||||
|
return psu_current
|
||||||
|
|
||||||
|
def get_power(self):
|
||||||
|
"""
|
||||||
|
Retrieves current energy supplied by PSU
|
||||||
|
Returns:
|
||||||
|
A float number, the power in watts, e.g. 302.6
|
||||||
|
"""
|
||||||
|
psu_power = 0.0
|
||||||
|
current_name = "power{}_input"
|
||||||
|
current_label = "pout1"
|
||||||
|
|
||||||
|
pw_label_path = self.__search_file_by_contain(
|
||||||
|
self.hwmon_path, current_label, "power")
|
||||||
|
if pw_label_path:
|
||||||
|
dir_name = os.path.dirname(pw_label_path)
|
||||||
|
basename = os.path.basename(pw_label_path)
|
||||||
|
pw_num = filter(str.isdigit, basename)
|
||||||
|
pw_path = os.path.join(
|
||||||
|
dir_name, current_name.format(pw_num))
|
||||||
|
pw_val = self.__read_txt_file(pw_path)
|
||||||
|
psu_power = float(pw_val) / 1000000
|
||||||
|
|
||||||
|
return psu_power
|
||||||
|
|
||||||
|
def get_powergood_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the powergood status of PSU
|
||||||
|
Returns:
|
||||||
|
A boolean, True if PSU has stablized its output voltages and passed all
|
||||||
|
its internal self-tests, False if not.
|
||||||
|
"""
|
||||||
|
return self.get_status()
|
||||||
|
|
||||||
def set_status_led(self, color):
|
def set_status_led(self, color):
|
||||||
"""
|
"""
|
||||||
@ -64,6 +159,15 @@ class Psu(PsuBase):
|
|||||||
# Hardware not supported
|
# Hardware not supported
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_status_led(self):
|
||||||
|
"""
|
||||||
|
Gets the state of the PSU status LED
|
||||||
|
Returns:
|
||||||
|
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||||
|
"""
|
||||||
|
# Hardware not supported
|
||||||
|
return self.STATUS_LED_COLOR_OFF
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the device
|
Retrieves the name of the device
|
||||||
@ -79,14 +183,10 @@ class Psu(PsuBase):
|
|||||||
bool: True if PSU is present, False if not
|
bool: True if PSU is present, False if not
|
||||||
"""
|
"""
|
||||||
psu_location = ["R", "L"]
|
psu_location = ["R", "L"]
|
||||||
status = 0
|
presences_status = self.__read_txt_file(
|
||||||
try:
|
self.psu_path + self.psu_presence.format(psu_location[self.index])) or 0
|
||||||
with open(self.psu_path + self.psu_presence.format(psu_location[self.index]), 'r') as psu_prs:
|
|
||||||
status = int(psu_prs.read())
|
|
||||||
except IOError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return status == 1
|
return int(presences_status) == 1
|
||||||
|
|
||||||
def get_status(self):
|
def get_status(self):
|
||||||
"""
|
"""
|
||||||
@ -95,11 +195,7 @@ class Psu(PsuBase):
|
|||||||
A boolean value, True if device is operating properly, False if not
|
A boolean value, True if device is operating properly, False if not
|
||||||
"""
|
"""
|
||||||
psu_location = ["R", "L"]
|
psu_location = ["R", "L"]
|
||||||
status = 0
|
power_status = self.__read_txt_file(
|
||||||
try:
|
self.psu_path + self.psu_oper_status.format(psu_location[self.index])) or 0
|
||||||
with open(self.psu_path + self.psu_oper_status.format(psu_location[self.index]), 'r') as power_status:
|
|
||||||
status = int(power_status.read())
|
|
||||||
except IOError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return status == 1
|
return int(power_status) == 1
|
||||||
|
@ -15,16 +15,65 @@ import sonic_device_util
|
|||||||
from ctypes import create_string_buffer
|
from ctypes import create_string_buffer
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from swsssdk import ConfigDBConnector
|
|
||||||
from sonic_platform_base.sfp_base import SfpBase
|
from sonic_platform_base.sfp_base import SfpBase
|
||||||
from sonic_platform_base.sonic_sfp.sfputilbase import SfpUtilBase
|
from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
|
||||||
|
from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
|
||||||
|
from sonic_platform_base.sonic_sfp.sff8472 import sffbase
|
||||||
|
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
INFO_OFFSET = 0
|
||||||
|
DOM_OFFSET = 256
|
||||||
|
|
||||||
class Sfp(SfpBase, SfpUtilBase):
|
XCVR_INTFACE_BULK_OFFSET = 0
|
||||||
|
XCVR_INTFACE_BULK_WIDTH_SFP = 21
|
||||||
|
XCVR_VENDOR_NAME_OFFSET = 20
|
||||||
|
XCVR_VENDOR_NAME_WIDTH = 16
|
||||||
|
XCVR_VENDOR_OUI_OFFSET = 37
|
||||||
|
XCVR_VENDOR_OUI_WIDTH = 3
|
||||||
|
XCVR_VENDOR_PN_OFFSET = 40
|
||||||
|
XCVR_VENDOR_PN_WIDTH = 16
|
||||||
|
XCVR_HW_REV_OFFSET = 56
|
||||||
|
XCVR_HW_REV_WIDTH_SFP = 4
|
||||||
|
XCVR_VENDOR_SN_OFFSET = 68
|
||||||
|
XCVR_VENDOR_SN_WIDTH = 16
|
||||||
|
XCVR_VENDOR_DATE_OFFSET = 84
|
||||||
|
XCVR_VENDOR_DATE_WIDTH = 8
|
||||||
|
XCVR_DOM_CAPABILITY_OFFSET = 92
|
||||||
|
XCVR_DOM_CAPABILITY_WIDTH = 1
|
||||||
|
|
||||||
|
# Offset for values in SFP eeprom
|
||||||
|
SFP_TEMPE_OFFSET = 96
|
||||||
|
SFP_TEMPE_WIDTH = 2
|
||||||
|
SFP_VOLT_OFFSET = 98
|
||||||
|
SFP_VOLT_WIDTH = 2
|
||||||
|
SFP_CHANNL_MON_OFFSET = 100
|
||||||
|
SFP_CHANNL_MON_WIDTH = 6
|
||||||
|
SFP_MODULE_THRESHOLD_OFFSET = 0
|
||||||
|
SFP_MODULE_THRESHOLD_WIDTH = 40
|
||||||
|
SFP_CHANNL_THRESHOLD_OFFSET = 112
|
||||||
|
SFP_CHANNL_THRESHOLD_WIDTH = 2
|
||||||
|
SFP_STATUS_CONTROL_OFFSET = 110
|
||||||
|
SFP_STATUS_CONTROL_WIDTH = 1
|
||||||
|
SFP_TX_DISABLE_HARD_BIT = 7
|
||||||
|
SFP_TX_DISABLE_SOFT_BIT = 6
|
||||||
|
|
||||||
|
sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
|
||||||
|
'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
|
||||||
|
'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)')
|
||||||
|
|
||||||
|
sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode',
|
||||||
|
'ESCONComplianceCodes', 'SONETComplianceCodes',
|
||||||
|
'EthernetComplianceCodes', 'FibreChannelLinkLength',
|
||||||
|
'FibreChannelTechnology', 'SFP+CableTechnology',
|
||||||
|
'FibreChannelTransmissionMedia', 'FibreChannelSpeed')
|
||||||
|
|
||||||
|
|
||||||
|
class Sfp(SfpBase):
|
||||||
"""Platform-specific Sfp class"""
|
"""Platform-specific Sfp class"""
|
||||||
|
|
||||||
|
# Port number
|
||||||
PORT_START = 1
|
PORT_START = 1
|
||||||
PORT_END = 52
|
PORT_END = 52
|
||||||
port_to_i2c_mapping = {
|
port_to_i2c_mapping = {
|
||||||
@ -33,50 +82,39 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
51: 17,
|
51: 17,
|
||||||
52: 16
|
52: 16
|
||||||
}
|
}
|
||||||
|
_sfp_port = range(49, PORT_END + 1)
|
||||||
PRS_PATH = "/sys/devices/platform/e1031.smc/SFP/sfp_modabs"
|
PRS_PATH = "/sys/devices/platform/e1031.smc/SFP/sfp_modabs"
|
||||||
PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
|
PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
|
||||||
SFP_STATUS_CONTROL_OFFSET = 110
|
PMON_HWSKU_PATH = '/usr/share/sonic/hwsku'
|
||||||
SFP_STATUS_CONTROL_WIDTH = 1
|
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
||||||
|
|
||||||
_port_to_eeprom_mapping = {}
|
PLATFORM = "x86_64-cel_e1031-r0"
|
||||||
_sfp_port = range(49, PORT_END + 1)
|
HWSKU = "Celestica-E1031-T48S4"
|
||||||
|
|
||||||
SFP_EEPROM_TYPE_KEY = "TypeOfTransceiver"
|
def __init__(self, sfp_index):
|
||||||
SFP_EEPROM_HW_REV_KEY = "VendorRev"
|
# Init index
|
||||||
SFP_EEPROM_MF_NAME_KEY = "VendorName"
|
self.index = sfp_index
|
||||||
SFP_EEPROM_MODEL_NAME_KEY = "VendorPN"
|
self.port_num = self.index + 1
|
||||||
SFP_EEPROM_SERIAL_KEY = "VendorSN"
|
|
||||||
SFP_EEPROM_CONNECTOR_KEY = "Connector"
|
|
||||||
SFP_EEPROM_ENCODE_KEY = "EncodingCodes"
|
|
||||||
SFP_EEPROM_EXT_IDENT_KEY = "ExtIdentOfTypeOfTransceiver"
|
|
||||||
SFP_EEPROM_CABLE_KEY = "LengthCable(UnitsOfm)"
|
|
||||||
SFP_EEPROM_BIT_RATE_KEY = "NominalSignallingRate(UnitsOf100Mbd)"
|
|
||||||
SFP_EEPROM_SPEC_COM_KEY = "Specification compliance"
|
|
||||||
SFP_EEPROM_DATE_KEY = "VendorDataCode(YYYY-MM-DD Lot)"
|
|
||||||
SFP_EEPROM_OUI_KEY = "VendorOUI"
|
|
||||||
SFP_EEPROM_MON_DATA_KEY = "MonitorData"
|
|
||||||
SFP_EEPROM_TEMP_KEY = "Temperature"
|
|
||||||
SFP_EEPROM_VCC_KEY = "Vcc"
|
|
||||||
SFP_EEPROM_RX_PWR_KEY = "RXPower"
|
|
||||||
SFP_EEPROM_TX_PWR_KEY = "TXPower"
|
|
||||||
SFP_EEPROM_TX_BS_KEY = "TXBias"
|
|
||||||
SFP_EEPROM_STATUS_CON_KEY = "StatusControl"
|
|
||||||
|
|
||||||
@property
|
# Init eeprom path
|
||||||
def port_start(self):
|
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
|
||||||
return self.PORT_START
|
self.port_to_eeprom_mapping = {}
|
||||||
|
for x in range(self.PORT_START, self.PORT_END + 1):
|
||||||
|
if x not in self._sfp_port:
|
||||||
|
self.port_to_i2c_mapping[x] = None
|
||||||
|
self.port_to_eeprom_mapping[x] = eeprom_path.format(
|
||||||
|
self.port_to_i2c_mapping[x])
|
||||||
|
|
||||||
@property
|
self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier',
|
||||||
def port_end(self):
|
'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui']
|
||||||
return self.PORT_END
|
|
||||||
|
|
||||||
@property
|
self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage',
|
||||||
def qsfp_ports(self):
|
'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power']
|
||||||
return []
|
|
||||||
|
|
||||||
@property
|
self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning',
|
||||||
def port_to_eeprom_mapping(self):
|
'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
|
||||||
return self._port_to_eeprom_mapping
|
|
||||||
|
SfpBase.__init__(self)
|
||||||
|
|
||||||
def _convert_string_to_num(self, value_str):
|
def _convert_string_to_num(self, value_str):
|
||||||
if "-inf" in value_str:
|
if "-inf" in value_str:
|
||||||
@ -98,64 +136,45 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
else:
|
else:
|
||||||
return 'N/A'
|
return 'N/A'
|
||||||
|
|
||||||
def get_low_power_mode(self, port_num):
|
def __read_txt_file(self, file_path):
|
||||||
raise NotImplementedError
|
try:
|
||||||
|
with open(file_path, 'r') as fd:
|
||||||
|
data = fd.read()
|
||||||
|
return data.strip()
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
def set_low_power_mode(self, port_num, lpmode):
|
def __is_host(self):
|
||||||
raise NotImplementedError
|
return os.system(self.HOST_CHK_CMD) == 0
|
||||||
|
|
||||||
def get_transceiver_change_event(self, timeout=0):
|
def __get_path_to_port_config_file(self):
|
||||||
raise NotImplementedError
|
platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM])
|
||||||
|
hwsku_path = "/".join([platform_path, self.HWSKU]
|
||||||
|
) if self.__is_host() else self.PMON_HWSKU_PATH
|
||||||
|
return "/".join([hwsku_path, "port_config.ini"])
|
||||||
|
|
||||||
def __init__(self, sfp_index):
|
def __read_eeprom_specific_bytes(self, offset, num_bytes):
|
||||||
# Init SfpUtilBase
|
|
||||||
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
|
|
||||||
for x in range(self.PORT_START, self.PORT_END + 1):
|
|
||||||
if x not in self._sfp_port:
|
|
||||||
self.port_to_i2c_mapping[x] = None
|
|
||||||
self.port_to_eeprom_mapping[x] = eeprom_path.format(
|
|
||||||
self.port_to_i2c_mapping[x])
|
|
||||||
self.read_porttab_mappings(self.__get_path_to_port_config_file())
|
|
||||||
SfpUtilBase.__init__(self)
|
|
||||||
|
|
||||||
# Init index
|
|
||||||
self.index = sfp_index
|
|
||||||
self.port_num = self.index + 1
|
|
||||||
|
|
||||||
def __get_sysfsfile_eeprom(self):
|
|
||||||
sysfsfile_eeprom = None
|
sysfsfile_eeprom = None
|
||||||
|
eeprom_raw = []
|
||||||
|
for i in range(0, num_bytes):
|
||||||
|
eeprom_raw.append("0x00")
|
||||||
|
|
||||||
sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num]
|
sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num]
|
||||||
try:
|
try:
|
||||||
sysfsfile_eeprom = open(
|
sysfsfile_eeprom = open(
|
||||||
sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0)
|
sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0)
|
||||||
except IOError:
|
sysfsfile_eeprom.seek(offset)
|
||||||
print("Error: reading sysfs file %s" %
|
raw = sysfsfile_eeprom.read(num_bytes)
|
||||||
sysfs_sfp_i2c_client_eeprom_path)
|
for n in range(0, num_bytes):
|
||||||
return sysfsfile_eeprom
|
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
if sysfsfile_eeprom:
|
||||||
|
sysfsfile_eeprom.close()
|
||||||
|
|
||||||
def __get_path_to_port_config_file(self):
|
return eeprom_raw
|
||||||
# Get platform and hwsku
|
|
||||||
machine_info = sonic_device_util.get_machine_info()
|
|
||||||
platform = sonic_device_util.get_platform_info(machine_info)
|
|
||||||
config_db = ConfigDBConnector()
|
|
||||||
config_db.connect()
|
|
||||||
data = config_db.get_table('DEVICE_METADATA')
|
|
||||||
try:
|
|
||||||
hwsku = data['localhost']['hwsku']
|
|
||||||
except KeyError:
|
|
||||||
hwsku = "Unknown"
|
|
||||||
|
|
||||||
# Load platform module from source
|
|
||||||
platform_path = "/".join([self.PLATFORM_ROOT_PATH, platform])
|
|
||||||
hwsku_path = "/".join([platform_path, hwsku])
|
|
||||||
|
|
||||||
# First check for the presence of the new 'port_config.ini' file
|
|
||||||
port_config_file_path = "/".join([hwsku_path, "port_config.ini"])
|
|
||||||
if not os.path.isfile(port_config_file_path):
|
|
||||||
# port_config.ini doesn't exist. Try loading the legacy 'portmap.ini' file
|
|
||||||
port_config_file_path = "/".join([hwsku_path, "portmap.ini"])
|
|
||||||
|
|
||||||
return port_config_file_path
|
|
||||||
|
|
||||||
def get_transceiver_info(self):
|
def get_transceiver_info(self):
|
||||||
"""
|
"""
|
||||||
@ -181,44 +200,84 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
vendor_oui |1*255VCHAR |vendor OUI
|
vendor_oui |1*255VCHAR |vendor OUI
|
||||||
========================================================================
|
========================================================================
|
||||||
"""
|
"""
|
||||||
transceiver_info_dict = dict()
|
# check present status
|
||||||
# get eeprom data
|
sfpi_obj = sff8472InterfaceId()
|
||||||
self.eeprom_dict = self.get_eeprom_dict(self.port_num)
|
if not self.get_presence() or not sfpi_obj:
|
||||||
if self.eeprom_dict and self.eeprom_dict.get('interface'):
|
return {}
|
||||||
transceiver_info_data = self.eeprom_dict['interface'].get('data')
|
|
||||||
|
|
||||||
# set specification_compliance
|
offset = INFO_OFFSET
|
||||||
spec_com = transceiver_info_data.get(
|
|
||||||
self.SFP_EEPROM_SPEC_COM_KEY, {})
|
|
||||||
spec_com_str = "/".join(list(spec_com.values()))
|
|
||||||
|
|
||||||
# set normal transceiver info
|
sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(
|
||||||
transceiver_info_dict['type'] = transceiver_info_data.get(
|
(offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_SFP)
|
||||||
self.SFP_EEPROM_TYPE_KEY, 'N/A')
|
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(
|
||||||
transceiver_info_dict['hardwarerev'] = transceiver_info_data.get(
|
sfp_interface_bulk_raw, 0)
|
||||||
self.SFP_EEPROM_HW_REV_KEY, 'N/A')
|
|
||||||
transceiver_info_dict['manufacturename'] = transceiver_info_data.get(
|
sfp_vendor_name_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.SFP_EEPROM_MF_NAME_KEY, 'N/A')
|
(offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
|
||||||
transceiver_info_dict['modelname'] = transceiver_info_data.get(
|
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
|
||||||
self.SFP_EEPROM_MODEL_NAME_KEY, 'N/A')
|
sfp_vendor_name_raw, 0)
|
||||||
transceiver_info_dict['serialnum'] = transceiver_info_data.get(
|
|
||||||
self.SFP_EEPROM_SERIAL_KEY, 'N/A')
|
sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
|
||||||
transceiver_info_dict['Connector'] = transceiver_info_data.get(
|
(offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
|
||||||
self.SFP_EEPROM_CONNECTOR_KEY, 'N/A')
|
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
|
||||||
transceiver_info_dict['encoding'] = transceiver_info_data.get(
|
sfp_vendor_pn_raw, 0)
|
||||||
self.SFP_EEPROM_ENCODE_KEY, 'N/A')
|
|
||||||
transceiver_info_dict['ext_identifier'] = transceiver_info_data.get(
|
sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.SFP_EEPROM_EXT_IDENT_KEY, 'N/A')
|
(offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_SFP)
|
||||||
transceiver_info_dict['cable_length'] = transceiver_info_data.get(
|
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
|
||||||
self.SFP_EEPROM_CABLE_KEY, 'N/A')
|
sfp_vendor_rev_raw, 0)
|
||||||
transceiver_info_dict['nominal_bit_rate'] = transceiver_info_data.get(
|
|
||||||
self.SFP_EEPROM_BIT_RATE_KEY, 'N/A')
|
sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
|
||||||
transceiver_info_dict['vendor_date'] = transceiver_info_data.get(
|
(offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
|
||||||
self.SFP_EEPROM_DATE_KEY, 'N/A')
|
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
|
||||||
transceiver_info_dict['vendor_oui'] = transceiver_info_data.get(
|
sfp_vendor_sn_raw, 0)
|
||||||
self.SFP_EEPROM_OUI_KEY, 'N/A')
|
|
||||||
transceiver_info_dict['ext_rateselect_compliance'] = "N/A"
|
sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes(
|
||||||
transceiver_info_dict['specification_compliance'] = spec_com_str or "N/A"
|
(offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
|
||||||
|
if sfp_vendor_oui_raw is not None:
|
||||||
|
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(
|
||||||
|
sfp_vendor_oui_raw, 0)
|
||||||
|
|
||||||
|
sfp_vendor_date_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
|
||||||
|
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(
|
||||||
|
sfp_vendor_date_raw, 0)
|
||||||
|
|
||||||
|
transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A')
|
||||||
|
compliance_code_dict = dict()
|
||||||
|
|
||||||
|
if sfp_interface_bulk_data:
|
||||||
|
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
|
||||||
|
transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value']
|
||||||
|
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
|
||||||
|
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
|
||||||
|
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
|
||||||
|
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
|
||||||
|
|
||||||
|
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[
|
||||||
|
'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A'
|
||||||
|
transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
|
||||||
|
transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A'
|
||||||
|
transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
|
||||||
|
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A'
|
||||||
|
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[
|
||||||
|
'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A'
|
||||||
|
transceiver_info_dict['cable_type'] = "Unknown"
|
||||||
|
transceiver_info_dict['cable_length'] = "Unknown"
|
||||||
|
|
||||||
|
for key in sfp_cable_length_tup:
|
||||||
|
if key in sfp_interface_bulk_data['data']:
|
||||||
|
transceiver_info_dict['cable_type'] = key
|
||||||
|
transceiver_info_dict['cable_length'] = str(
|
||||||
|
sfp_interface_bulk_data['data'][key]['value'])
|
||||||
|
|
||||||
|
for key in sfp_compliance_code_tup:
|
||||||
|
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
|
||||||
|
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
|
||||||
|
transceiver_info_dict['specification_compliance'] = str(
|
||||||
|
compliance_code_dict)
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = str(
|
||||||
|
sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
|
||||||
|
|
||||||
return transceiver_info_dict
|
return transceiver_info_dict
|
||||||
|
|
||||||
@ -230,60 +289,146 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
========================================================================
|
========================================================================
|
||||||
keys |Value Format |Information
|
keys |Value Format |Information
|
||||||
---------------------------|---------------|----------------------------
|
---------------------------|---------------|----------------------------
|
||||||
RX LOS |BOOLEAN |RX lost-of-signal status,
|
rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not.
|
||||||
| |True if has RX los, False if not.
|
tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not.
|
||||||
TX FAULT |BOOLEAN |TX fault status,
|
reset_status |BOOLEAN |reset status, True if SFP in reset, False if not.
|
||||||
| |True if has TX fault, False if not.
|
lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not.
|
||||||
Reset status |BOOLEAN |reset status,
|
tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not.
|
||||||
| |True if SFP in reset, False if not.
|
tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0
|
||||||
LP mode |BOOLEAN |low power mode status,
|
|
||||||
| |True in lp mode, False if not.
|
|
||||||
TX disable |BOOLEAN |TX disable status,
|
|
||||||
| |True TX disabled, False if not.
|
|
||||||
TX disabled channel |HEX |disabled TX channles in hex,
|
|
||||||
| |bits 0 to 3 represent channel 0
|
|
||||||
| |to channel 3.
|
| |to channel 3.
|
||||||
Temperature |INT |module temperature in Celsius
|
temperature |INT |module temperature in Celsius
|
||||||
Voltage |INT |supply voltage in mV
|
voltage |INT |supply voltage in mV
|
||||||
TX bias |INT |TX Bias Current in mA
|
tx<n>bias |INT |TX Bias Current in mA, n is the channel number,
|
||||||
RX power |INT |received optical power in mW
|
| |for example, tx2bias stands for tx bias of channel 2.
|
||||||
TX power |INT |TX output power in mW
|
rx<n>power |INT |received optical power in mW, n is the channel number,
|
||||||
|
| |for example, rx2power stands for rx power of channel 2.
|
||||||
|
tx<n>power |INT |TX output power in mW, n is the channel number,
|
||||||
|
| |for example, tx2power stands for tx power of channel 2.
|
||||||
========================================================================
|
========================================================================
|
||||||
"""
|
"""
|
||||||
transceiver_bulk_status_dict = dict()
|
# check present status
|
||||||
# get eeprom data
|
sfpd_obj = sff8472Dom()
|
||||||
self.eeprom_dict = self.get_eeprom_dict(self.port_num)
|
if not self.get_presence() or not sfpd_obj:
|
||||||
if self.eeprom_dict and self.eeprom_dict.get('dom'):
|
return {}
|
||||||
transceiver_dom_data = self.eeprom_dict['dom'].get('data', {})
|
|
||||||
transceiver_dom_data_mmv = transceiver_dom_data.get(
|
|
||||||
self.SFP_EEPROM_MON_DATA_KEY)
|
|
||||||
|
|
||||||
# set normal transceiver bulk status
|
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
|
||||||
transceiver_bulk_status_dict['temperature'] = transceiver_dom_data_mmv.get(
|
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
|
||||||
self.SFP_EEPROM_TEMP_KEY, 'N/A')
|
cal_type = sfpi_obj.get_calibration_type()
|
||||||
transceiver_bulk_status_dict['voltage'] = transceiver_dom_data_mmv.get(
|
sfpd_obj._calibration_type = cal_type
|
||||||
self.SFP_EEPROM_VCC_KEY, 'N/A')
|
|
||||||
transceiver_bulk_status_dict['rx1power'] = transceiver_dom_data_mmv.get(
|
|
||||||
self.SFP_EEPROM_RX_PWR_KEY, 'N/A')
|
|
||||||
transceiver_bulk_status_dict['rx2power'] = "N/A"
|
|
||||||
transceiver_bulk_status_dict['rx3power'] = "N/A"
|
|
||||||
transceiver_bulk_status_dict['rx4power'] = "N/A"
|
|
||||||
transceiver_bulk_status_dict['tx1bias'] = transceiver_dom_data_mmv.get(
|
|
||||||
self.SFP_EEPROM_TX_BS_KEY, 'N/A')
|
|
||||||
transceiver_bulk_status_dict['tx2bias'] = "N/A"
|
|
||||||
transceiver_bulk_status_dict['tx3bias'] = "N/A"
|
|
||||||
transceiver_bulk_status_dict['tx4bias'] = "N/A"
|
|
||||||
transceiver_bulk_status_dict['tx1power'] = transceiver_dom_data_mmv.get(
|
|
||||||
self.SFP_EEPROM_TX_PWR_KEY, 'N/A')
|
|
||||||
transceiver_bulk_status_dict['tx2power'] = "N/A"
|
|
||||||
transceiver_bulk_status_dict['tx3power'] = "N/A"
|
|
||||||
transceiver_bulk_status_dict['tx4power'] = "N/A"
|
|
||||||
|
|
||||||
for key in transceiver_bulk_status_dict:
|
offset = DOM_OFFSET
|
||||||
transceiver_bulk_status_dict[key] = self._convert_string_to_num(
|
transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A')
|
||||||
transceiver_bulk_status_dict[key])
|
dom_temperature_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
|
||||||
|
|
||||||
return transceiver_bulk_status_dict
|
if dom_temperature_raw is not None:
|
||||||
|
dom_temperature_data = sfpd_obj.parse_temperature(
|
||||||
|
dom_temperature_raw, 0)
|
||||||
|
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
|
||||||
|
|
||||||
|
dom_voltage_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH)
|
||||||
|
if dom_voltage_raw is not None:
|
||||||
|
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
|
||||||
|
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
|
||||||
|
|
||||||
|
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
dom_voltage_data = sfpd_obj.parse_channel_monitor_params(
|
||||||
|
dom_channel_monitor_raw, 0)
|
||||||
|
transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value']
|
||||||
|
transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value']
|
||||||
|
transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value']
|
||||||
|
|
||||||
|
for key in transceiver_dom_info_dict:
|
||||||
|
transceiver_dom_info_dict[key] = self._convert_string_to_num(
|
||||||
|
transceiver_dom_info_dict[key])
|
||||||
|
|
||||||
|
transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
|
||||||
|
transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
|
||||||
|
transceiver_dom_info_dict['reset_status'] = self.get_reset_status()
|
||||||
|
transceiver_dom_info_dict['lp_mode'] = self.get_lpmode()
|
||||||
|
|
||||||
|
return transceiver_dom_info_dict
|
||||||
|
|
||||||
|
def get_transceiver_threshold_info(self):
|
||||||
|
"""
|
||||||
|
Retrieves transceiver threshold info of this SFP
|
||||||
|
Returns:
|
||||||
|
A dict which contains following keys/values :
|
||||||
|
========================================================================
|
||||||
|
keys |Value Format |Information
|
||||||
|
---------------------------|---------------|----------------------------
|
||||||
|
temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius.
|
||||||
|
templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius.
|
||||||
|
temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius.
|
||||||
|
templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius.
|
||||||
|
vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV.
|
||||||
|
vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV.
|
||||||
|
vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV.
|
||||||
|
vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV.
|
||||||
|
rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm.
|
||||||
|
rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm.
|
||||||
|
rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm.
|
||||||
|
rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm.
|
||||||
|
txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm.
|
||||||
|
txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm.
|
||||||
|
txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm.
|
||||||
|
txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm.
|
||||||
|
txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA.
|
||||||
|
txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA.
|
||||||
|
txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA.
|
||||||
|
txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA.
|
||||||
|
========================================================================
|
||||||
|
"""
|
||||||
|
# check present status
|
||||||
|
sfpd_obj = sff8472Dom()
|
||||||
|
|
||||||
|
if not self.get_presence() and not sfpd_obj:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
|
||||||
|
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
|
||||||
|
cal_type = sfpi_obj.get_calibration_type()
|
||||||
|
sfpd_obj._calibration_type = cal_type
|
||||||
|
|
||||||
|
offset = DOM_OFFSET
|
||||||
|
transceiver_dom_threshold_info_dict = dict.fromkeys(
|
||||||
|
self.threshold_dict_keys, 'N/A')
|
||||||
|
dom_module_threshold_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH)
|
||||||
|
if dom_module_threshold_raw is not None:
|
||||||
|
dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(
|
||||||
|
dom_module_threshold_raw, 0)
|
||||||
|
|
||||||
|
transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[
|
||||||
|
'data']['VoltageHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value']
|
||||||
|
|
||||||
|
for key in transceiver_dom_threshold_info_dict:
|
||||||
|
transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num(
|
||||||
|
transceiver_dom_threshold_info_dict[key])
|
||||||
|
|
||||||
|
return transceiver_dom_threshold_info_dict
|
||||||
|
|
||||||
def get_reset_status(self):
|
def get_reset_status(self):
|
||||||
"""
|
"""
|
||||||
@ -292,7 +437,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
A Boolean, True if reset enabled, False if disabled
|
A Boolean, True if reset enabled, False if disabled
|
||||||
"""
|
"""
|
||||||
# SFP doesn't support this feature
|
# SFP doesn't support this feature
|
||||||
return NotImplementedError
|
return False
|
||||||
|
|
||||||
def get_rx_los(self):
|
def get_rx_los(self):
|
||||||
"""
|
"""
|
||||||
@ -302,14 +447,12 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Note : RX LOS status is latched until a call to get_rx_los or a reset.
|
Note : RX LOS status is latched until a call to get_rx_los or a reset.
|
||||||
"""
|
"""
|
||||||
rx_los = False
|
rx_los = False
|
||||||
rx_los_key = "RXLOSState"
|
status_control_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.eeprom_dict = self.get_eeprom_dict(self.port_num)
|
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
||||||
if self.eeprom_dict and self.eeprom_dict.get('dom'):
|
if status_control_raw:
|
||||||
transceiver_dom_data = self.eeprom_dict['dom'].get('data', {})
|
data = int(status_control_raw[0], 16)
|
||||||
transceiver_dom_data_sc = transceiver_dom_data.get(
|
rx_los = (sffbase().test_bit(data, 1) != 0)
|
||||||
self.SFP_EEPROM_STATUS_CON_KEY)
|
|
||||||
state = transceiver_dom_data_sc.get(rx_los_key)
|
|
||||||
rx_los = True if 'off' not in state.lower() else False
|
|
||||||
return rx_los
|
return rx_los
|
||||||
|
|
||||||
def get_tx_fault(self):
|
def get_tx_fault(self):
|
||||||
@ -320,14 +463,12 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Note : TX fault status is lached until a call to get_tx_fault or a reset.
|
Note : TX fault status is lached until a call to get_tx_fault or a reset.
|
||||||
"""
|
"""
|
||||||
tx_fault = False
|
tx_fault = False
|
||||||
tx_fault_key = "TXFaultState"
|
status_control_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.eeprom_dict = self.get_eeprom_dict(self.port_num)
|
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
||||||
if self.eeprom_dict and self.eeprom_dict.get('dom'):
|
if status_control_raw:
|
||||||
transceiver_dom_data = self.eeprom_dict['dom'].get('data', {})
|
data = int(status_control_raw[0], 16)
|
||||||
transceiver_dom_data_sc = transceiver_dom_data.get(
|
tx_fault = (sffbase().test_bit(data, 2) != 0)
|
||||||
self.SFP_EEPROM_STATUS_CON_KEY)
|
|
||||||
state = transceiver_dom_data_sc.get(tx_fault_key)
|
|
||||||
tx_fault = True if 'off' not in state.lower() else False
|
|
||||||
return tx_fault
|
return tx_fault
|
||||||
|
|
||||||
def get_tx_disable(self):
|
def get_tx_disable(self):
|
||||||
@ -337,14 +478,17 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
A Boolean, True if tx_disable is enabled, False if disabled
|
A Boolean, True if tx_disable is enabled, False if disabled
|
||||||
"""
|
"""
|
||||||
tx_disable = False
|
tx_disable = False
|
||||||
tx_disable_key = "TXDisableState"
|
tx_fault = False
|
||||||
self.eeprom_dict = self.get_eeprom_dict(self.port_num)
|
status_control_raw = self.__read_eeprom_specific_bytes(
|
||||||
if self.eeprom_dict and self.eeprom_dict.get('dom'):
|
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
||||||
transceiver_dom_data = self.eeprom_dict['dom'].get('data', {})
|
if status_control_raw:
|
||||||
transceiver_dom_data_sc = transceiver_dom_data.get(
|
data = int(status_control_raw[0], 16)
|
||||||
self.SFP_EEPROM_STATUS_CON_KEY)
|
tx_disable_hard = (sffbase().test_bit(
|
||||||
state = transceiver_dom_data_sc.get(tx_disable_key)
|
data, SFP_TX_DISABLE_HARD_BIT) != 0)
|
||||||
tx_disable = True if 'off' not in state.lower() else False
|
tx_disable_soft = (sffbase().test_bit(
|
||||||
|
data, SFP_TX_DISABLE_SOFT_BIT) != 0)
|
||||||
|
tx_disable = tx_disable_hard | tx_disable_soft
|
||||||
|
|
||||||
return tx_disable
|
return tx_disable
|
||||||
|
|
||||||
def get_tx_disable_channel(self):
|
def get_tx_disable_channel(self):
|
||||||
@ -357,7 +501,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
and channel 2 have been disabled.
|
and channel 2 have been disabled.
|
||||||
"""
|
"""
|
||||||
# SFP doesn't support this feature
|
# SFP doesn't support this feature
|
||||||
return NotImplementedError
|
return 0
|
||||||
|
|
||||||
def get_lpmode(self):
|
def get_lpmode(self):
|
||||||
"""
|
"""
|
||||||
@ -366,7 +510,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
A Boolean, True if lpmode is enabled, False if disabled
|
A Boolean, True if lpmode is enabled, False if disabled
|
||||||
"""
|
"""
|
||||||
# SFP doesn't support this feature
|
# SFP doesn't support this feature
|
||||||
return self.get_low_power_mode(self.port_num)
|
return False
|
||||||
|
|
||||||
def get_power_override(self):
|
def get_power_override(self):
|
||||||
"""
|
"""
|
||||||
@ -375,7 +519,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
A Boolean, True if power-override is enabled, False if disabled
|
A Boolean, True if power-override is enabled, False if disabled
|
||||||
"""
|
"""
|
||||||
# SFP doesn't support this feature
|
# SFP doesn't support this feature
|
||||||
return NotImplementedError
|
return False
|
||||||
|
|
||||||
def get_temperature(self):
|
def get_temperature(self):
|
||||||
"""
|
"""
|
||||||
@ -405,7 +549,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||||
tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A")
|
tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A")
|
||||||
return [tx1_bs, "N/A", "N/A", "N/A"]
|
return [tx1_bs, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else []
|
||||||
|
|
||||||
def get_rx_power(self):
|
def get_rx_power(self):
|
||||||
"""
|
"""
|
||||||
@ -417,7 +561,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||||
rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A")
|
rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A")
|
||||||
return [rx1_pw, "N/A", "N/A", "N/A"]
|
return [rx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else []
|
||||||
|
|
||||||
def get_tx_power(self):
|
def get_tx_power(self):
|
||||||
"""
|
"""
|
||||||
@ -429,7 +573,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||||
tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A")
|
tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A")
|
||||||
return [tx1_pw, "N/A", "N/A", "N/A"]
|
return [tx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else []
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
@ -438,7 +582,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
A boolean, True if successful, False if not
|
A boolean, True if successful, False if not
|
||||||
"""
|
"""
|
||||||
# SFP doesn't support this feature
|
# SFP doesn't support this feature
|
||||||
return NotImplementedError
|
return False
|
||||||
|
|
||||||
def tx_disable(self, tx_disable):
|
def tx_disable(self, tx_disable):
|
||||||
"""
|
"""
|
||||||
@ -449,26 +593,29 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
A boolean, True if tx_disable is set successfully, False if not
|
A boolean, True if tx_disable is set successfully, False if not
|
||||||
"""
|
"""
|
||||||
|
sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num]
|
||||||
sysfsfile_eeprom = self.__get_sysfsfile_eeprom()
|
status_control_raw = self.__read_eeprom_specific_bytes(
|
||||||
status_control_raw = self._read_eeprom_specific_bytes(
|
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
||||||
sysfsfile_eeprom, self.SFP_STATUS_CONTROL_OFFSET, self.SFP_STATUS_CONTROL_WIDTH)
|
|
||||||
if status_control_raw is not None:
|
if status_control_raw is not None:
|
||||||
tx_disable_bit = 0x80 if tx_disable else 0x7f
|
# Set bit 6 for Soft TX Disable Select
|
||||||
|
# 01000000 = 64 and 10111111 = 191
|
||||||
|
tx_disable_bit = 64 if tx_disable else 191
|
||||||
status_control = int(status_control_raw[0], 16)
|
status_control = int(status_control_raw[0], 16)
|
||||||
tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else (
|
tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else (
|
||||||
status_control & tx_disable_bit)
|
status_control & tx_disable_bit)
|
||||||
try:
|
try:
|
||||||
|
sysfsfile_eeprom = open(
|
||||||
|
sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0)
|
||||||
buffer = create_string_buffer(1)
|
buffer = create_string_buffer(1)
|
||||||
buffer[0] = chr(tx_disable_ctl)
|
buffer[0] = chr(tx_disable_ctl)
|
||||||
# Write to eeprom
|
# Write to eeprom
|
||||||
sysfsfile_eeprom.seek(self.SFP_STATUS_CONTROL_OFFSET)
|
sysfsfile_eeprom.seek(SFP_STATUS_CONTROL_OFFSET)
|
||||||
sysfsfile_eeprom.write(buffer[0])
|
sysfsfile_eeprom.write(buffer[0])
|
||||||
except IOError as e:
|
except:
|
||||||
print "Error: unable to open file: %s" % str(e)
|
#print("Error: unable to open file: %s" % str(e))
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
if sysfsfile_eeprom is not None:
|
if sysfsfile_eeprom:
|
||||||
sysfsfile_eeprom.close()
|
sysfsfile_eeprom.close()
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
return True
|
return True
|
||||||
@ -486,7 +633,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
A boolean, True if successful, False if not
|
A boolean, True if successful, False if not
|
||||||
"""
|
"""
|
||||||
# SFP doesn't support this feature
|
# SFP doesn't support this feature
|
||||||
return NotImplementedError
|
return False
|
||||||
|
|
||||||
def set_lpmode(self, lpmode):
|
def set_lpmode(self, lpmode):
|
||||||
"""
|
"""
|
||||||
@ -497,7 +644,8 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
A boolean, True if lpmode is set successfully, False if not
|
A boolean, True if lpmode is set successfully, False if not
|
||||||
"""
|
"""
|
||||||
return self.set_low_power_mode(self.port_num, lpmode)
|
# SFP doesn't support this feature
|
||||||
|
return False
|
||||||
|
|
||||||
def set_power_override(self, power_override, power_set):
|
def set_power_override(self, power_override, power_set):
|
||||||
"""
|
"""
|
||||||
@ -516,7 +664,8 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
A boolean, True if power-override and power_set are set successfully,
|
A boolean, True if power-override and power_set are set successfully,
|
||||||
False if not
|
False if not
|
||||||
"""
|
"""
|
||||||
return NotImplementedError
|
# SFP doesn't support this feature
|
||||||
|
return False
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
@ -524,7 +673,11 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: The name of the device
|
string: The name of the device
|
||||||
"""
|
"""
|
||||||
return self.logical[self.index]
|
sfputil_helper = SfpUtilHelper()
|
||||||
|
sfputil_helper.read_porttab_mappings(
|
||||||
|
self.__get_path_to_port_config_file())
|
||||||
|
name = sfputil_helper.logical[self.index] or "Unknown"
|
||||||
|
return name
|
||||||
|
|
||||||
def get_presence(self):
|
def get_presence(self):
|
||||||
"""
|
"""
|
||||||
@ -551,7 +704,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: Model/part number of device
|
string: Model/part number of device
|
||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
transceiver_dom_info_dict = self.get_transceiver_info()
|
||||||
return transceiver_dom_info_dict.get("modelname", "N/A")
|
return transceiver_dom_info_dict.get("modelname", "N/A")
|
||||||
|
|
||||||
def get_serial(self):
|
def get_serial(self):
|
||||||
@ -560,5 +713,5 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: Serial number of device
|
string: Serial number of device
|
||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
transceiver_dom_info_dict = self.get_transceiver_info()
|
||||||
return transceiver_dom_info_dict.get("serialnum", "N/A")
|
return transceiver_dom_info_dict.get("serialnum", "N/A")
|
||||||
|
@ -22,8 +22,8 @@ class Thermal(ThermalBase):
|
|||||||
"""Platform-specific Thermal class"""
|
"""Platform-specific Thermal class"""
|
||||||
|
|
||||||
THERMAL_NAME_LIST = []
|
THERMAL_NAME_LIST = []
|
||||||
MAINBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-11/11-001a/hwmon/"
|
MAINBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-11/11-001a/hwmon/hwmon2"
|
||||||
CPUBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-3/3-001a/hwmon/"
|
CPUBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-3/3-001a/hwmon/hwmon1"
|
||||||
SS_CONFIG_PATH = "/usr/share/sonic/device/x86_64-cel_e1031-r0/sensors.conf"
|
SS_CONFIG_PATH = "/usr/share/sonic/device/x86_64-cel_e1031-r0/sensors.conf"
|
||||||
|
|
||||||
def __init__(self, thermal_index):
|
def __init__(self, thermal_index):
|
||||||
@ -41,10 +41,8 @@ class Thermal(ThermalBase):
|
|||||||
self.THERMAL_NAME_LIST.append("CPU board temperature sensor : 2")
|
self.THERMAL_NAME_LIST.append("CPU board temperature sensor : 2")
|
||||||
|
|
||||||
# Set hwmon path
|
# Set hwmon path
|
||||||
self.ss_index, self.ss_path = self.__get_ss_info(self.index)
|
self.ss_index, self.hwmon_path = self.__get_ss_info(self.index)
|
||||||
self.ss_key = self.THERMAL_NAME_LIST[self.index]
|
self.ss_key = self.THERMAL_NAME_LIST[self.index]
|
||||||
self.hwmon_name = os.listdir(self.ss_path)[0]
|
|
||||||
self.hwmon_path = os.path.join(self.ss_path, self.hwmon_name)
|
|
||||||
|
|
||||||
def __get_ss_info(self, index):
|
def __get_ss_info(self, index):
|
||||||
if self.index <= 4:
|
if self.index <= 4:
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
__all__ = ["platform", "chassis"]
|
||||||
|
from sonic_platform import *
|
@ -26,13 +26,18 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
NUM_FAN = 5
|
NUM_FAN_TRAY = 5
|
||||||
|
NUM_FAN = 2
|
||||||
NUM_PSU = 2
|
NUM_PSU = 2
|
||||||
NUM_THERMAL = 5
|
NUM_THERMAL = 5
|
||||||
NUM_SFP = 32
|
NUM_SFP = 32
|
||||||
RESET_REGISTER = "0x103"
|
RESET_REGISTER = "0x103"
|
||||||
REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt"
|
HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/"
|
||||||
|
PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/"
|
||||||
|
REBOOT_CAUSE_FILE = "reboot-cause.txt"
|
||||||
|
PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt"
|
||||||
COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"]
|
COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"]
|
||||||
|
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
||||||
|
|
||||||
|
|
||||||
class Chassis(ChassisBase):
|
class Chassis(ChassisBase):
|
||||||
@ -40,9 +45,10 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.config_data = {}
|
self.config_data = {}
|
||||||
for index in range(0, NUM_FAN):
|
for fant_index in range(0, NUM_FAN_TRAY):
|
||||||
fan = Fan(index)
|
for fan_index in range(0, NUM_FAN):
|
||||||
self._fan_list.append(fan)
|
fan = Fan(fant_index, fan_index)
|
||||||
|
self._fan_list.append(fan)
|
||||||
for index in range(0, NUM_PSU):
|
for index in range(0, NUM_PSU):
|
||||||
psu = Psu(index)
|
psu = Psu(index)
|
||||||
self._psu_list.append(psu)
|
self._psu_list.append(psu)
|
||||||
@ -53,17 +59,22 @@ class Chassis(ChassisBase):
|
|||||||
sfp = Sfp(index)
|
sfp = Sfp(index)
|
||||||
self._sfp_list.append(sfp)
|
self._sfp_list.append(sfp)
|
||||||
ChassisBase.__init__(self)
|
ChassisBase.__init__(self)
|
||||||
|
|
||||||
self._component_name_list = COMPONENT_NAME_LIST
|
self._component_name_list = COMPONENT_NAME_LIST
|
||||||
self._watchdog = Watchdog()
|
self._watchdog = Watchdog()
|
||||||
self._eeprom = Tlv()
|
self._eeprom = Tlv()
|
||||||
|
|
||||||
|
def __is_host(self):
|
||||||
|
return os.system(HOST_CHK_CMD) == 0
|
||||||
|
|
||||||
def __read_txt_file(self, file_path):
|
def __read_txt_file(self, file_path):
|
||||||
try:
|
try:
|
||||||
with open(file_path, 'r') as fd:
|
with open(file_path, 'r') as fd:
|
||||||
data = fd.read()
|
data = fd.read()
|
||||||
return data.strip()
|
return data.strip()
|
||||||
except IOError:
|
except IOError:
|
||||||
raise IOError("Unable to open %s file !" % file_path)
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
def get_base_mac(self):
|
def get_base_mac(self):
|
||||||
"""
|
"""
|
||||||
@ -136,14 +147,27 @@ class Chassis(ChassisBase):
|
|||||||
self.component = Component("CPLD1")
|
self.component = Component("CPLD1")
|
||||||
description = 'None'
|
description = 'None'
|
||||||
reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
|
reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
|
||||||
hw_reboot_cause = self.component.get_register_value(RESET_REGISTER)
|
|
||||||
sw_reboot_cause = self.__read_txt_file(REBOOT_CAUSE_PATH)
|
|
||||||
|
|
||||||
if sw_reboot_cause != "Unexpected reboot":
|
reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.__is_host(
|
||||||
|
) else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE
|
||||||
|
prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.__is_host(
|
||||||
|
) else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE
|
||||||
|
|
||||||
|
hw_reboot_cause = self.component.get_register_value(RESET_REGISTER)
|
||||||
|
|
||||||
|
sw_reboot_cause = self.__read_txt_file(
|
||||||
|
reboot_cause_path) or "Unknown"
|
||||||
|
prev_sw_reboot_cause = self.__read_txt_file(
|
||||||
|
prev_reboot_cause_path) or "Unknown"
|
||||||
|
|
||||||
|
if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS) and hw_reboot_cause == "0x11":
|
||||||
|
reboot_cause = self.REBOOT_CAUSE_POWER_LOSS
|
||||||
|
elif sw_reboot_cause != "Unknown" and hw_reboot_cause == "0x11":
|
||||||
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
|
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
|
||||||
description = sw_reboot_cause
|
description = sw_reboot_cause
|
||||||
elif hw_reboot_cause == "0x11":
|
elif prev_reboot_cause_path != "Unknown" and hw_reboot_cause == "0x11":
|
||||||
reboot_cause = self.REBOOT_CAUSE_POWER_LOSS
|
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
|
||||||
|
description = prev_sw_reboot_cause
|
||||||
elif hw_reboot_cause == "0x22":
|
elif hw_reboot_cause == "0x22":
|
||||||
reboot_cause = self.REBOOT_CAUSE_WATCHDOG,
|
reboot_cause = self.REBOOT_CAUSE_WATCHDOG,
|
||||||
else:
|
else:
|
||||||
|
@ -17,29 +17,47 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
CONFIG_DB_PATH = "/etc/sonic/config_db.json"
|
|
||||||
EMC2305_PATH = "/sys/bus/i2c/drivers/emc2305/"
|
EMC2305_PATH = "/sys/bus/i2c/drivers/emc2305/"
|
||||||
SYS_GPIO_DIR = "/sys/class/gpio"
|
GPIO_DIR = "/sys/class/gpio"
|
||||||
|
GPIO_LABEL = "pca9505"
|
||||||
EMC2305_MAX_PWM = 255
|
EMC2305_MAX_PWM = 255
|
||||||
EMC2305_FAN_PWM = "pwm{}"
|
EMC2305_FAN_PWM = "pwm{}"
|
||||||
EMC2305_FAN_TARGET = "fan{}_target"
|
EMC2305_FAN_TARGET = "fan{}_target"
|
||||||
EMC2305_FAN_INPUT = "pwm{}"
|
EMC2305_FAN_INPUT = "pwm{}"
|
||||||
FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3", "FAN-4", "FAN-5"]
|
FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R",
|
||||||
|
"FAN-3F", "FAN-3R", "FAN-4F", "FAN-4R", "FAN-5F", "FAN-5R"]
|
||||||
|
PSU_FAN_MAX_RPM = 11000
|
||||||
|
PSU_HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
||||||
|
PSU_I2C_MAPPING = {
|
||||||
|
0: {
|
||||||
|
"num": 10,
|
||||||
|
"addr": "5a"
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
"num": 11,
|
||||||
|
"addr": "5b"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Fan(FanBase):
|
class Fan(FanBase):
|
||||||
"""Platform-specific Fan class"""
|
"""Platform-specific Fan class"""
|
||||||
|
|
||||||
def __init__(self, fan_index):
|
def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
|
||||||
self.index = fan_index
|
self.fan_index = fan_index
|
||||||
self.config_data = {}
|
self.fan_tray_index = fan_tray_index
|
||||||
self.fan_speed = 0
|
self.is_psu_fan = is_psu_fan
|
||||||
FanBase.__init__(self)
|
if self.is_psu_fan:
|
||||||
|
self.psu_index = psu_index
|
||||||
|
self.psu_i2c_num = PSU_I2C_MAPPING[self.psu_index]["num"]
|
||||||
|
self.psu_i2c_addr = PSU_I2C_MAPPING[self.psu_index]["addr"]
|
||||||
|
self.psu_hwmon_path = PSU_HWMON_PATH.format(
|
||||||
|
self.psu_i2c_num, self.psu_i2c_addr)
|
||||||
|
|
||||||
# dx010 fan attributes
|
# dx010 fan attributes
|
||||||
# Two EMC2305s located at i2c-13-4d and i2c-13-2e
|
# Two EMC2305s located at i2c-13-4d and i2c-13-2e
|
||||||
# to control a dual-fan module.
|
# to control a dual-fan module.
|
||||||
self.dx010_emc2305_chip = [
|
self.emc2305_chip_mapping = [
|
||||||
{
|
{
|
||||||
'device': "13-002e",
|
'device': "13-002e",
|
||||||
'index_map': [2, 1, 4, 5, 3]
|
'index_map': [2, 1, 4, 5, 3]
|
||||||
@ -49,121 +67,133 @@ class Fan(FanBase):
|
|||||||
'index_map': [2, 4, 5, 3, 1]
|
'index_map': [2, 4, 5, 3, 1]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
self.dx010_fan_gpio = [
|
self.dx010_fan_gpio = [
|
||||||
{'base': self.get_gpio_base()},
|
{'base': self.__get_gpio_base()},
|
||||||
{'prs': 10, 'dir': 15, 'color': {'red': 31, 'green': 32}},
|
{'prs': 11, 'dir': 16, 'color': {'red': 31, 'green': 32}}, # 1
|
||||||
{'prs': 11, 'dir': 16, 'color': {'red': 29, 'green': 30}},
|
{'prs': 10, 'dir': 15, 'color': {'red': 29, 'green': 30}}, # 2
|
||||||
{'prs': 12, 'dir': 17, 'color': {'red': 35, 'green': 36}},
|
{'prs': 13, 'dir': 18, 'color': {'red': 35, 'green': 36}}, # 3
|
||||||
{'prs': 13, 'dir': 18, 'color': {'red': 37, 'green': 38}},
|
{'prs': 14, 'dir': 19, 'color': {'red': 37, 'green': 38}}, # 4
|
||||||
{'prs': 14, 'dir': 19, 'color': {'red': 33, 'green': 34}},
|
{'prs': 12, 'dir': 17, 'color': {'red': 33, 'green': 34}}, # 5
|
||||||
]
|
]
|
||||||
|
FanBase.__init__(self)
|
||||||
|
|
||||||
def get_gpio_base(self):
|
def __read_txt_file(self, file_path):
|
||||||
for r in os.listdir(SYS_GPIO_DIR):
|
try:
|
||||||
if "gpiochip" in r:
|
with open(file_path, 'r') as fd:
|
||||||
|
data = fd.read()
|
||||||
|
return data.strip()
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def __write_txt_file(self, file_path, value):
|
||||||
|
try:
|
||||||
|
with open(file_path, 'w') as fd:
|
||||||
|
fd.write(str(value))
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __search_file_by_name(self, directory, file_name):
|
||||||
|
for dirpath, dirnames, files in os.walk(directory):
|
||||||
|
for name in files:
|
||||||
|
file_path = os.path.join(dirpath, name)
|
||||||
|
if name in file_name:
|
||||||
|
return file_path
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __get_gpio_base(self):
|
||||||
|
for r in os.listdir(GPIO_DIR):
|
||||||
|
label_path = os.path.join(GPIO_DIR, r, "label")
|
||||||
|
if "gpiochip" in r and GPIO_LABEL in self.__read_txt_file(label_path):
|
||||||
return int(r[8:], 10)
|
return int(r[8:], 10)
|
||||||
return 216 # Reserve
|
return 216 # Reserve
|
||||||
|
|
||||||
def get_gpio_value(self, pinnum):
|
def __get_gpio_value(self, pinnum):
|
||||||
gpio_base = self.dx010_fan_gpio[0]['base']
|
gpio_base = self.dx010_fan_gpio[0]['base']
|
||||||
|
gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
|
||||||
gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
|
|
||||||
gpio_file = gpio_dir + "/value"
|
gpio_file = gpio_dir + "/value"
|
||||||
|
retval = self.__read_txt_file(gpio_file)
|
||||||
|
return retval.rstrip('\r\n')
|
||||||
|
|
||||||
try:
|
def __set_gpio_value(self, pinnum, value=0):
|
||||||
with open(gpio_file, 'r') as fd:
|
|
||||||
retval = fd.read()
|
|
||||||
except IOError:
|
|
||||||
raise IOError("Unable to open " + gpio_file + "file !")
|
|
||||||
|
|
||||||
retval = retval.rstrip('\r\n')
|
|
||||||
return retval
|
|
||||||
|
|
||||||
def set_gpio_value(self, pinnum, value=0):
|
|
||||||
gpio_base = self.dx010_fan_gpio[0]['base']
|
gpio_base = self.dx010_fan_gpio[0]['base']
|
||||||
|
gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
|
||||||
gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
|
|
||||||
gpio_file = gpio_dir + "/value"
|
gpio_file = gpio_dir + "/value"
|
||||||
|
return self.__write_txt_file(gpio_file, value)
|
||||||
try:
|
|
||||||
with open(gpio_file, 'w') as fd:
|
|
||||||
retval = fd.write(str(value))
|
|
||||||
except IOError:
|
|
||||||
raise IOError("Unable to open " + gpio_file + "file !")
|
|
||||||
|
|
||||||
def get_direction(self):
|
def get_direction(self):
|
||||||
|
"""
|
||||||
|
Retrieves the direction of fan
|
||||||
|
Returns:
|
||||||
|
A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST
|
||||||
|
depending on fan direction
|
||||||
|
"""
|
||||||
|
direction = self.FAN_DIRECTION_EXHAUST
|
||||||
|
if not self.is_psu_fan:
|
||||||
|
raw = self.__get_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['dir'])
|
||||||
|
|
||||||
direction = self.FAN_DIRECTION_INTAKE
|
direction = self.FAN_DIRECTION_INTAKE if int(
|
||||||
raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['dir'])
|
raw, 10) == 0 else self.FAN_DIRECTION_EXHAUST
|
||||||
|
|
||||||
if int(raw, 10) == 0:
|
|
||||||
direction = self.FAN_DIRECTION_INTAKE
|
|
||||||
else:
|
|
||||||
direction = self.FAN_DIRECTION_EXHAUST
|
|
||||||
|
|
||||||
return direction
|
return direction
|
||||||
|
|
||||||
def get_speed(self):
|
def get_speed(self):
|
||||||
"""
|
"""
|
||||||
DX010 platform specific data:
|
Retrieves the speed of fan as a percentage of full speed
|
||||||
|
Returns:
|
||||||
|
An integer, the percentage of full fan speed, in the range 0 (off)
|
||||||
|
to 100 (full speed)
|
||||||
|
|
||||||
|
Note:
|
||||||
speed = pwm_in/255*100
|
speed = pwm_in/255*100
|
||||||
"""
|
"""
|
||||||
# TODO: Seperate PSU's fan and main fan class
|
speed = 0
|
||||||
if self.fan_speed != 0:
|
if self.is_psu_fan:
|
||||||
return self.fan_speed
|
fan_speed_sysfs_name = "fan{}_input".format(self.fan_index+1)
|
||||||
else:
|
fan_speed_sysfs_path = self.__search_file_by_name(
|
||||||
speed = 0
|
self.psu_hwmon_path, fan_speed_sysfs_name)
|
||||||
pwm = []
|
fan_speed_rpm = self.__read_txt_file(fan_speed_sysfs_path) or 0
|
||||||
emc2305_chips = self.dx010_emc2305_chip
|
fan_speed_raw = float(fan_speed_rpm)/PSU_FAN_MAX_RPM * 100
|
||||||
|
speed = math.ceil(float(fan_speed_rpm) * 100 / PSU_FAN_MAX_RPM)
|
||||||
|
elif self.get_presence():
|
||||||
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
|
device = chip['device']
|
||||||
|
fan_index = chip['index_map']
|
||||||
|
sysfs_path = "%s%s/%s" % (
|
||||||
|
EMC2305_PATH, device, EMC2305_FAN_INPUT)
|
||||||
|
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
||||||
|
raw = self.__read_txt_file(sysfs_path).strip('\r\n')
|
||||||
|
pwm = int(raw, 10) if raw else 0
|
||||||
|
speed = math.ceil(float(pwm * 100 / EMC2305_MAX_PWM))
|
||||||
|
|
||||||
for chip in emc2305_chips:
|
return int(speed)
|
||||||
device = chip['device']
|
|
||||||
fan_index = chip['index_map']
|
|
||||||
sysfs_path = "%s%s/%s" % (
|
|
||||||
EMC2305_PATH, device, EMC2305_FAN_INPUT)
|
|
||||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
|
||||||
try:
|
|
||||||
with open(sysfs_path, 'r') as file:
|
|
||||||
raw = file.read().strip('\r\n')
|
|
||||||
pwm.append(int(raw, 10))
|
|
||||||
except IOError:
|
|
||||||
raise IOError("Unable to open " + sysfs_path)
|
|
||||||
|
|
||||||
speed = math.ceil(
|
|
||||||
float(pwm[0]) * 100 / EMC2305_MAX_PWM)
|
|
||||||
|
|
||||||
return int(speed)
|
|
||||||
|
|
||||||
def get_target_speed(self):
|
def get_target_speed(self):
|
||||||
"""
|
"""
|
||||||
DX010 platform specific data:
|
Retrieves the target (expected) speed of the fan
|
||||||
|
Returns:
|
||||||
|
An integer, the percentage of full fan speed, in the range 0 (off)
|
||||||
|
to 100 (full speed)
|
||||||
|
|
||||||
|
Note:
|
||||||
speed_pc = pwm_target/255*100
|
speed_pc = pwm_target/255*100
|
||||||
|
|
||||||
0 : when PWM mode is use
|
0 : when PWM mode is use
|
||||||
pwm : when pwm mode is not use
|
pwm : when pwm mode is not use
|
||||||
|
|
||||||
"""
|
"""
|
||||||
target = 0
|
target = 0
|
||||||
pwm = []
|
if not self.is_psu_fan:
|
||||||
emc2305_chips = self.dx010_emc2305_chip
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
|
|
||||||
for chip in emc2305_chips:
|
|
||||||
device = chip['device']
|
device = chip['device']
|
||||||
fan_index = chip['index_map']
|
fan_index = chip['index_map']
|
||||||
sysfs_path = "%s%s/%s" % (
|
sysfs_path = "%s%s/%s" % (
|
||||||
EMC2305_PATH, device, EMC2305_FAN_TARGET)
|
EMC2305_PATH, device, EMC2305_FAN_TARGET)
|
||||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
||||||
try:
|
raw = self.__read_txt_file(sysfs_path).strip('\r\n')
|
||||||
with open(sysfs_path, 'r') as file:
|
pwm = int(raw, 10) if raw else 0
|
||||||
raw = file.read().strip('\r\n')
|
target = math.ceil(float(pwm) * 100 / EMC2305_MAX_PWM)
|
||||||
pwm.append(int(raw, 10))
|
|
||||||
except IOError:
|
|
||||||
raise IOError("Unable to open " + sysfs_path)
|
|
||||||
|
|
||||||
target = pwm[0] * 100 / EMC2305_MAX_PWM
|
|
||||||
|
|
||||||
return target
|
return target
|
||||||
|
|
||||||
@ -178,55 +208,68 @@ class Fan(FanBase):
|
|||||||
|
|
||||||
def set_speed(self, speed):
|
def set_speed(self, speed):
|
||||||
"""
|
"""
|
||||||
Depends on pwm or target mode is selected:
|
Sets the fan speed
|
||||||
|
Args:
|
||||||
|
speed: An integer, the percentage of full fan speed to set fan to,
|
||||||
|
in the range 0 (off) to 100 (full speed)
|
||||||
|
Returns:
|
||||||
|
A boolean, True if speed is set successfully, False if not
|
||||||
|
|
||||||
|
Note:
|
||||||
|
Depends on pwm or target mode is selected:
|
||||||
1) pwm = speed_pc * 255 <-- Currently use this mode.
|
1) pwm = speed_pc * 255 <-- Currently use this mode.
|
||||||
2) target_pwm = speed_pc * 100 / 255
|
2) target_pwm = speed_pc * 100 / 255
|
||||||
2.1) set pwm{}_enable to 3
|
2.1) set pwm{}_enable to 3
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pwm = speed * 255 / 100
|
pwm = speed * 255 / 100
|
||||||
emc2305_chips = self.dx010_emc2305_chip
|
if not self.is_psu_fan and self.get_presence():
|
||||||
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
for chip in emc2305_chips:
|
|
||||||
device = chip['device']
|
device = chip['device']
|
||||||
fan_index = chip['index_map']
|
fan_index = chip['index_map']
|
||||||
sysfs_path = "%s%s/%s" % (
|
sysfs_path = "%s%s/%s" % (
|
||||||
EMC2305_PATH, device, EMC2305_FAN_PWM)
|
EMC2305_PATH, device, EMC2305_FAN_PWM)
|
||||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
||||||
|
return self.__write_txt_file(sysfs_path, int(pwm))
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_status_led(self, color):
|
||||||
|
"""
|
||||||
|
Sets the state of the fan module status LED
|
||||||
|
Args:
|
||||||
|
color: A string representing the color with which to set the
|
||||||
|
fan module status LED
|
||||||
|
Returns:
|
||||||
|
bool: True if status LED state is set successfully, False if not
|
||||||
|
"""
|
||||||
|
set_status_led = False
|
||||||
|
if not self.is_psu_fan:
|
||||||
|
s1, s2 = False, False
|
||||||
try:
|
try:
|
||||||
with open(sysfs_path, 'w') as file:
|
if color == self.STATUS_LED_COLOR_GREEN:
|
||||||
file.write(str(int(pwm)))
|
s1 = self.__set_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'], 1)
|
||||||
|
s2 = self.__set_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'], 0)
|
||||||
|
|
||||||
|
elif color == self.STATUS_LED_COLOR_RED:
|
||||||
|
s1 = self.__set_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'], 0)
|
||||||
|
s2 = self.__set_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'], 1)
|
||||||
|
|
||||||
|
elif color == self.STATUS_LED_COLOR_OFF:
|
||||||
|
s1 = self.__set_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'], 1)
|
||||||
|
s2 = self.__set_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'], 1)
|
||||||
|
set_status_led = s1 and s2
|
||||||
|
return set_status_led
|
||||||
except IOError:
|
except IOError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return set_status_led
|
||||||
|
|
||||||
def set_status_led(self, color):
|
|
||||||
try:
|
|
||||||
if color == self.STATUS_LED_COLOR_GREEN:
|
|
||||||
self.set_gpio_value(
|
|
||||||
self.dx010_fan_gpio[self.index+1]['color']['red'], 1)
|
|
||||||
self.set_gpio_value(
|
|
||||||
self.dx010_fan_gpio[self.index+1]['color']['green'], 0)
|
|
||||||
|
|
||||||
elif color == self.STATUS_LED_COLOR_RED:
|
|
||||||
self.set_gpio_value(
|
|
||||||
self.dx010_fan_gpio[self.index+1]['color']['red'], 0)
|
|
||||||
self.set_gpio_value(
|
|
||||||
self.dx010_fan_gpio[self.index+1]['color']['green'], 1)
|
|
||||||
|
|
||||||
elif color == self.STATUS_LED_COLOR_OFF:
|
|
||||||
self.set_gpio_value(
|
|
||||||
self.dx010_fan_gpio[self.index+1]['color']['red'], 1)
|
|
||||||
self.set_gpio_value(
|
|
||||||
self.dx010_fan_gpio[self.index+1]['color']['green'], 1)
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
except IOError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
@ -234,7 +277,10 @@ class Fan(FanBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: The name of the device
|
string: The name of the device
|
||||||
"""
|
"""
|
||||||
return FAN_NAME_LIST[self.index]
|
fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] if not self.is_psu_fan else "PSU-{} FAN-{}".format(
|
||||||
|
self.psu_index+1, self.fan_index+1)
|
||||||
|
|
||||||
|
return fan_name
|
||||||
|
|
||||||
def get_presence(self):
|
def get_presence(self):
|
||||||
"""
|
"""
|
||||||
@ -242,6 +288,7 @@ class Fan(FanBase):
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if PSU is present, False if not
|
bool: True if PSU is present, False if not
|
||||||
"""
|
"""
|
||||||
raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['prs'])
|
present_str = self.__get_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['prs'])
|
||||||
|
|
||||||
return int(raw, 10) == 0
|
return int(present_str, 10) == 0 if not self.is_psu_fan else True
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
import os.path
|
import os
|
||||||
import sonic_platform
|
import sonic_platform
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -17,66 +17,152 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
FAN_DX010_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input"
|
|
||||||
GREEN_LED_PATH = "/sys/devices/platform/leds_dx010/leds/dx010:green:p-{}/brightness"
|
GREEN_LED_PATH = "/sys/devices/platform/leds_dx010/leds/dx010:green:p-{}/brightness"
|
||||||
FAN_MAX_RPM = 11000
|
HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
||||||
SYS_GPIO_DIR = "/sys/class/gpio"
|
GPIO_DIR = "/sys/class/gpio"
|
||||||
|
GPIO_LABEL = "pca9505"
|
||||||
PSU_NAME_LIST = ["PSU-1", "PSU-2"]
|
PSU_NAME_LIST = ["PSU-1", "PSU-2"]
|
||||||
|
PSU_NUM_FAN = [1, 1]
|
||||||
|
PSU_I2C_MAPPING = {
|
||||||
|
0: {
|
||||||
|
"num": 10,
|
||||||
|
"addr": "5a"
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
"num": 11,
|
||||||
|
"addr": "5b"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Psu(PsuBase):
|
class Psu(PsuBase):
|
||||||
"""Platform-specific Psu class"""
|
"""Platform-specific Psu class"""
|
||||||
|
|
||||||
def __init__(self, psu_index):
|
def __init__(self, psu_index):
|
||||||
PsuBase.__init__(self)
|
|
||||||
self.index = psu_index
|
self.index = psu_index
|
||||||
self.green_led_path = GREEN_LED_PATH.format(self.index+1)
|
self.green_led_path = GREEN_LED_PATH.format(self.index+1)
|
||||||
self.dx010_psu_gpio = [
|
self.dx010_psu_gpio = [
|
||||||
{'base': self.get_gpio_base()},
|
{'base': self.__get_gpio_base()},
|
||||||
{'prs': 27, 'status': 22},
|
{'prs': 27, 'status': 22},
|
||||||
{'prs': 28, 'status': 25}
|
{'prs': 28, 'status': 25}
|
||||||
]
|
]
|
||||||
|
self.i2c_num = PSU_I2C_MAPPING[self.index]["num"]
|
||||||
|
self.i2c_addr = PSU_I2C_MAPPING[self.index]["addr"]
|
||||||
|
self.hwmon_path = HWMON_PATH.format(self.i2c_num, self.i2c_addr)
|
||||||
|
for fan_index in range(0, PSU_NUM_FAN[self.index]):
|
||||||
|
fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index)
|
||||||
|
self._fan_list.append(fan)
|
||||||
|
PsuBase.__init__(self)
|
||||||
|
|
||||||
def get_gpio_base(self):
|
def __read_txt_file(self, file_path):
|
||||||
for r in os.listdir(SYS_GPIO_DIR):
|
try:
|
||||||
if "gpiochip" in r:
|
with open(file_path, 'r') as fd:
|
||||||
|
data = fd.read()
|
||||||
|
return data.strip()
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def __search_file_by_contain(self, directory, search_str, file_start):
|
||||||
|
for dirpath, dirnames, files in os.walk(directory):
|
||||||
|
for name in files:
|
||||||
|
file_path = os.path.join(dirpath, name)
|
||||||
|
if name.startswith(file_start) and search_str in self.__read_txt_file(file_path):
|
||||||
|
return file_path
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __get_gpio_base(self):
|
||||||
|
for r in os.listdir(GPIO_DIR):
|
||||||
|
label_path = os.path.join(GPIO_DIR, r, "label")
|
||||||
|
if "gpiochip" in r and GPIO_LABEL in self.__read_txt_file(label_path):
|
||||||
return int(r[8:], 10)
|
return int(r[8:], 10)
|
||||||
return 216 # Reserve
|
return 216 # Reserve
|
||||||
|
|
||||||
def get_gpio_value(self, pinnum):
|
def __get_gpio_value(self, pinnum):
|
||||||
gpio_base = self.dx010_psu_gpio[0]['base']
|
gpio_base = self.dx010_psu_gpio[0]['base']
|
||||||
gpio_file = "{}/gpio{}/value".format(SYS_GPIO_DIR,
|
gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
|
||||||
str(gpio_base+pinnum))
|
gpio_file = gpio_dir + "/value"
|
||||||
|
retval = self.__read_txt_file(gpio_file)
|
||||||
|
return retval.rstrip('\r\n')
|
||||||
|
|
||||||
try:
|
def get_voltage(self):
|
||||||
with open(gpio_file, 'r') as fd:
|
|
||||||
retval = fd.read()
|
|
||||||
except IOError:
|
|
||||||
raise IOError("Unable to open " + gpio_file + "file !")
|
|
||||||
|
|
||||||
retval = retval.rstrip('\r\n')
|
|
||||||
return retval
|
|
||||||
|
|
||||||
def get_fan(self):
|
|
||||||
"""
|
"""
|
||||||
Retrieves object representing the fan module contained in this PSU
|
Retrieves current PSU voltage output
|
||||||
Returns:
|
Returns:
|
||||||
An object dervied from FanBase representing the fan module
|
A float number, the output voltage in volts,
|
||||||
contained in this PSU
|
e.g. 12.1
|
||||||
"""
|
"""
|
||||||
|
psu_voltage = 0.0
|
||||||
|
voltage_name = "in{}_input"
|
||||||
|
voltage_label = "vout1"
|
||||||
|
|
||||||
fan_speed_path = FAN_DX010_SPEED_PATH.format(
|
vout_label_path = self.__search_file_by_contain(
|
||||||
str(self.index+8))
|
self.hwmon_path, voltage_label, "in")
|
||||||
try:
|
if vout_label_path:
|
||||||
with open(fan_speed_path) as fan_speed_file:
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
fan_speed_rpm = int(fan_speed_file.read())
|
basename = os.path.basename(vout_label_path)
|
||||||
except IOError:
|
in_num = filter(str.isdigit, basename)
|
||||||
fan_speed = 0
|
vout_path = os.path.join(
|
||||||
|
dir_name, voltage_name.format(in_num))
|
||||||
|
vout_val = self.__read_txt_file(vout_path)
|
||||||
|
psu_voltage = float(vout_val) / 1000
|
||||||
|
|
||||||
fan_speed = float(fan_speed_rpm)/FAN_MAX_RPM * 100
|
return psu_voltage
|
||||||
fan = Fan(0)
|
|
||||||
fan.fan_speed = int(fan_speed) if int(fan_speed) <= 100 else 100
|
def get_current(self):
|
||||||
return fan
|
"""
|
||||||
|
Retrieves present electric current supplied by PSU
|
||||||
|
Returns:
|
||||||
|
A float number, the electric current in amperes, e.g 15.4
|
||||||
|
"""
|
||||||
|
psu_current = 0.0
|
||||||
|
current_name = "curr{}_input"
|
||||||
|
current_label = "iout1"
|
||||||
|
|
||||||
|
curr_label_path = self.__search_file_by_contain(
|
||||||
|
self.hwmon_path, current_label, "cur")
|
||||||
|
if curr_label_path:
|
||||||
|
dir_name = os.path.dirname(curr_label_path)
|
||||||
|
basename = os.path.basename(curr_label_path)
|
||||||
|
cur_num = filter(str.isdigit, basename)
|
||||||
|
cur_path = os.path.join(
|
||||||
|
dir_name, current_name.format(cur_num))
|
||||||
|
cur_val = self.__read_txt_file(cur_path)
|
||||||
|
psu_current = float(cur_val) / 1000
|
||||||
|
|
||||||
|
return psu_current
|
||||||
|
|
||||||
|
def get_power(self):
|
||||||
|
"""
|
||||||
|
Retrieves current energy supplied by PSU
|
||||||
|
Returns:
|
||||||
|
A float number, the power in watts, e.g. 302.6
|
||||||
|
"""
|
||||||
|
psu_power = 0.0
|
||||||
|
current_name = "power{}_input"
|
||||||
|
current_label = "pout1"
|
||||||
|
|
||||||
|
pw_label_path = self.__search_file_by_contain(
|
||||||
|
self.hwmon_path, current_label, "power")
|
||||||
|
if pw_label_path:
|
||||||
|
dir_name = os.path.dirname(pw_label_path)
|
||||||
|
basename = os.path.basename(pw_label_path)
|
||||||
|
pw_num = filter(str.isdigit, basename)
|
||||||
|
pw_path = os.path.join(
|
||||||
|
dir_name, current_name.format(pw_num))
|
||||||
|
pw_val = self.__read_txt_file(pw_path)
|
||||||
|
psu_power = float(pw_val) / 1000000
|
||||||
|
|
||||||
|
return psu_power
|
||||||
|
|
||||||
|
def get_powergood_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the powergood status of PSU
|
||||||
|
Returns:
|
||||||
|
A boolean, True if PSU has stablized its output voltages and passed all
|
||||||
|
its internal self-tests, False if not.
|
||||||
|
"""
|
||||||
|
return self.get_status()
|
||||||
|
|
||||||
def set_status_led(self, color):
|
def set_status_led(self, color):
|
||||||
"""
|
"""
|
||||||
@ -104,6 +190,20 @@ class Psu(PsuBase):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_status_led(self):
|
||||||
|
"""
|
||||||
|
Gets the state of the PSU status LED
|
||||||
|
Returns:
|
||||||
|
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||||
|
"""
|
||||||
|
status = self.__read_txt_file(self.green_led_path)
|
||||||
|
status_str = {
|
||||||
|
'255': self.STATUS_LED_COLOR_GREEN,
|
||||||
|
'0': self.STATUS_LED_COLOR_OFF
|
||||||
|
}.get(status, None)
|
||||||
|
|
||||||
|
return status_str
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the device
|
Retrieves the name of the device
|
||||||
@ -118,7 +218,7 @@ class Psu(PsuBase):
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if PSU is present, False if not
|
bool: True if PSU is present, False if not
|
||||||
"""
|
"""
|
||||||
raw = self.get_gpio_value(self.dx010_psu_gpio[self.index+1]['prs'])
|
raw = self.__get_gpio_value(self.dx010_psu_gpio[self.index+1]['prs'])
|
||||||
return int(raw, 10) == 0
|
return int(raw, 10) == 0
|
||||||
|
|
||||||
def get_status(self):
|
def get_status(self):
|
||||||
@ -127,5 +227,6 @@ class Psu(PsuBase):
|
|||||||
Returns:
|
Returns:
|
||||||
A boolean value, True if device is operating properly, False if not
|
A boolean value, True if device is operating properly, False if not
|
||||||
"""
|
"""
|
||||||
raw = self.get_gpio_value(self.dx010_psu_gpio[self.index+1]['status'])
|
raw = self.__get_gpio_value(
|
||||||
|
self.dx010_psu_gpio[self.index+1]['status'])
|
||||||
return int(raw, 10) == 1
|
return int(raw, 10) == 1
|
||||||
|
@ -15,71 +15,110 @@ import sonic_device_util
|
|||||||
from ctypes import create_string_buffer
|
from ctypes import create_string_buffer
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from swsssdk import ConfigDBConnector
|
|
||||||
from sonic_platform_base.sfp_base import SfpBase
|
from sonic_platform_base.sfp_base import SfpBase
|
||||||
from sonic_platform_base.sonic_sfp.sfputilbase import SfpUtilBase
|
from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
|
||||||
from sonic_platform_base.sonic_sfp.sfputilbase import sff8436Dom
|
from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
|
||||||
|
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
INFO_OFFSET = 128
|
||||||
|
DOM_OFFSET = 0
|
||||||
|
|
||||||
class Sfp(SfpBase, SfpUtilBase):
|
XCVR_INTFACE_BULK_OFFSET = 0
|
||||||
|
XCVR_INTFACE_BULK_WIDTH_QSFP = 20
|
||||||
|
XCVR_HW_REV_WIDTH_QSFP = 2
|
||||||
|
XCVR_CABLE_LENGTH_WIDTH_QSFP = 5
|
||||||
|
XCVR_VENDOR_NAME_OFFSET = 20
|
||||||
|
XCVR_VENDOR_NAME_WIDTH = 16
|
||||||
|
XCVR_VENDOR_OUI_OFFSET = 37
|
||||||
|
XCVR_VENDOR_OUI_WIDTH = 3
|
||||||
|
XCVR_VENDOR_PN_OFFSET = 40
|
||||||
|
XCVR_VENDOR_PN_WIDTH = 16
|
||||||
|
XCVR_HW_REV_OFFSET = 56
|
||||||
|
XCVR_HW_REV_WIDTH_OSFP = 2
|
||||||
|
XCVR_HW_REV_WIDTH_SFP = 4
|
||||||
|
XCVR_VENDOR_SN_OFFSET = 68
|
||||||
|
XCVR_VENDOR_SN_WIDTH = 16
|
||||||
|
XCVR_VENDOR_DATE_OFFSET = 84
|
||||||
|
XCVR_VENDOR_DATE_WIDTH = 8
|
||||||
|
XCVR_DOM_CAPABILITY_OFFSET = 92
|
||||||
|
XCVR_DOM_CAPABILITY_WIDTH = 1
|
||||||
|
|
||||||
|
# Offset for values in QSFP eeprom
|
||||||
|
QSFP_DOM_REV_OFFSET = 1
|
||||||
|
QSFP_DOM_REV_WIDTH = 1
|
||||||
|
QSFP_TEMPE_OFFSET = 22
|
||||||
|
QSFP_TEMPE_WIDTH = 2
|
||||||
|
QSFP_VOLT_OFFSET = 26
|
||||||
|
QSFP_VOLT_WIDTH = 2
|
||||||
|
QSFP_CHANNL_MON_OFFSET = 34
|
||||||
|
QSFP_CHANNL_MON_WIDTH = 16
|
||||||
|
QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24
|
||||||
|
QSFP_CONTROL_OFFSET = 86
|
||||||
|
QSFP_CONTROL_WIDTH = 8
|
||||||
|
QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3
|
||||||
|
QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1
|
||||||
|
QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4
|
||||||
|
QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1
|
||||||
|
QSFP_POWEROVERRIDE_OFFSET = 93
|
||||||
|
QSFP_POWEROVERRIDE_WIDTH = 1
|
||||||
|
QSFP_MODULE_THRESHOLD_OFFSET = 128
|
||||||
|
QSFP_MODULE_THRESHOLD_WIDTH = 24
|
||||||
|
QSFP_CHANNEL_THRESHOLD_OFFSET = 176
|
||||||
|
QSFP_CHANNEL_THRESHOLD_WIDTH = 16
|
||||||
|
|
||||||
|
qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)',
|
||||||
|
'Length OM2(m)', 'Length OM1(m)',
|
||||||
|
'Length Cable Assembly(m)')
|
||||||
|
|
||||||
|
qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes',
|
||||||
|
'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes',
|
||||||
|
'Fibre Channel link length/Transmitter Technology',
|
||||||
|
'Fibre Channel transmission media', 'Fibre Channel Speed')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Sfp(SfpBase):
|
||||||
"""Platform-specific Sfp class"""
|
"""Platform-specific Sfp class"""
|
||||||
|
|
||||||
# Port number
|
# Port number
|
||||||
PORT_START = 1
|
PORT_START = 1
|
||||||
PORT_END = 32
|
PORT_END = 32
|
||||||
PORTS_IN_BLOCK = 32
|
|
||||||
|
|
||||||
# Offset for values in QSFP info eeprom
|
|
||||||
QSFP_CONTROL_OFFSET = 86
|
|
||||||
QSFP_CONTROL_WIDTH = 8
|
|
||||||
QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3
|
|
||||||
QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1
|
|
||||||
QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4
|
|
||||||
QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1
|
|
||||||
QSFP_POWEROVERRIDE_OFFSET = 93
|
|
||||||
QSFP_POWEROVERRIDE_WIDTH = 1
|
|
||||||
|
|
||||||
# Key for values in QSFP eeprom dict
|
|
||||||
QSFP_EEPROM_TYPE_KEY = "Identifier"
|
|
||||||
QSFP_EEPROM_HW_REV_KEY = "Vendor Rev"
|
|
||||||
QSFP_EEPROM_MF_NAME_KEY = "Vendor Name"
|
|
||||||
QSFP_EEPROM_MODEL_NAME_KEY = "Vendor PN"
|
|
||||||
QSFP_EEPROM_SERIAL_KEY = "Vendor SN"
|
|
||||||
QSFP_EEPROM_CONNECTOR_KEY = "Connector"
|
|
||||||
QSFP_EEPROM_ENCODE_KEY = "Encoding"
|
|
||||||
QSFP_EEPROM_EXT_IDENT_KEY = "Extended Identifier"
|
|
||||||
QSFP_EEPROM_EXT_RATE_KEY = "Extended RateSelect Compliance"
|
|
||||||
QSFP_EEPROM_CABLE_KEY = "Length(km)"
|
|
||||||
QSFP_EEPROM_BIT_RATE_KEY = "Nominal Bit Rate(100Mbs)"
|
|
||||||
QSFP_EEPROM_SPEC_COM_KEY = "Specification compliance"
|
|
||||||
QSFP_EEPROM_DATE_KEY = "Vendor Date Code(YYYY-MM-DD Lot)"
|
|
||||||
QSFP_EEPROM_OUI_KEY = "Vendor OUI"
|
|
||||||
|
|
||||||
# Path to QSFP sysfs
|
# Path to QSFP sysfs
|
||||||
RESET_PATH = "/sys/devices/platform/dx010_cpld/qsfp_reset"
|
RESET_PATH = "/sys/devices/platform/dx010_cpld/qsfp_reset"
|
||||||
LP_PATH = "/sys/devices/platform/dx010_cpld/qsfp_lpmode"
|
LP_PATH = "/sys/devices/platform/dx010_cpld/qsfp_lpmode"
|
||||||
PRS_PATH = "/sys/devices/platform/dx010_cpld/qsfp_modprs"
|
PRS_PATH = "/sys/devices/platform/dx010_cpld/qsfp_modprs"
|
||||||
PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
|
PLATFORM_ROOT_PATH = "/usr/share/sonic/device"
|
||||||
|
PMON_HWSKU_PATH = "/usr/share/sonic/hwsku"
|
||||||
|
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
||||||
|
|
||||||
_port_to_eeprom_mapping = {}
|
PLATFORM = "x86_64-cel_seastone-r0"
|
||||||
|
HWSKU = "Seastone-DX010"
|
||||||
|
|
||||||
@property
|
def __init__(self, sfp_index):
|
||||||
def port_start(self):
|
# Init index
|
||||||
return self.PORT_START
|
self.index = sfp_index
|
||||||
|
self.port_num = self.index + 1 if self.PORT_START == 1 else index
|
||||||
|
|
||||||
@property
|
# Init eeprom path
|
||||||
def port_end(self):
|
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
|
||||||
return self.PORT_END
|
self.port_to_eeprom_mapping = {}
|
||||||
|
for x in range(self.PORT_START, self.PORT_END + 1):
|
||||||
|
p_num = x - 1 if self.PORT_START == 1 else x
|
||||||
|
self.port_to_eeprom_mapping[x] = eeprom_path.format(p_num + 26)
|
||||||
|
|
||||||
@property
|
self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier',
|
||||||
def qsfp_ports(self):
|
'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui']
|
||||||
return range(self.PORT_START, self.PORTS_IN_BLOCK + 1)
|
|
||||||
|
|
||||||
@property
|
self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage',
|
||||||
def port_to_eeprom_mapping(self):
|
'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power']
|
||||||
return self._port_to_eeprom_mapping
|
|
||||||
|
self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning',
|
||||||
|
'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
|
||||||
|
|
||||||
|
SfpBase.__init__(self)
|
||||||
|
|
||||||
def _convert_string_to_num(self, value_str):
|
def _convert_string_to_num(self, value_str):
|
||||||
if "-inf" in value_str:
|
if "-inf" in value_str:
|
||||||
@ -101,122 +140,44 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
else:
|
else:
|
||||||
return 'N/A'
|
return 'N/A'
|
||||||
|
|
||||||
def get_low_power_mode(self, port_num):
|
def __read_txt_file(self, file_path):
|
||||||
# Check for invalid port_num
|
|
||||||
if port_num < self.port_start or port_num > self.port_end:
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
reg_file = open(self.LP_PATH, "r")
|
with open(file_path, 'r') as fd:
|
||||||
content = reg_file.readline().rstrip()
|
data = fd.read()
|
||||||
except IOError as e:
|
return data.strip()
|
||||||
print("Error: unable to open file: %s" % str(e))
|
except IOError:
|
||||||
return False
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
# content is a string containing the hex representation of the register
|
def __is_host(self):
|
||||||
reg_value = int(content, 16)
|
return os.system(self.HOST_CHK_CMD) == 0
|
||||||
|
|
||||||
# Determind if port_num start from 1 or 0
|
|
||||||
bit_index = port_num - 1 if self.port_start == 1 else port_num
|
|
||||||
|
|
||||||
# Mask off the bit corresponding to our port
|
|
||||||
mask = (1 << bit_index)
|
|
||||||
|
|
||||||
# LPMode is active high
|
|
||||||
if reg_value & mask == 0:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def set_low_power_mode(self, port_num, lpmode):
|
|
||||||
try:
|
|
||||||
reg_file = open(self.LP_PATH, "r+")
|
|
||||||
except IOError as e:
|
|
||||||
print("Error: unable to open file: %s" % str(e))
|
|
||||||
return False
|
|
||||||
|
|
||||||
content = reg_file.readline().rstrip()
|
|
||||||
|
|
||||||
# content is a string containing the hex representation of the register
|
|
||||||
reg_value = int(content, 16)
|
|
||||||
|
|
||||||
# Determind if port_num start from 1 or 0
|
|
||||||
bit_index = port_num - 1 if self.port_start == 1 else port_num
|
|
||||||
|
|
||||||
# Mask off the bit corresponding to our port
|
|
||||||
mask = (1 << bit_index)
|
|
||||||
# LPMode is active high; set or clear the bit accordingly
|
|
||||||
reg_value = reg_value | mask if lpmode else reg_value & ~mask
|
|
||||||
|
|
||||||
# Convert our register value back to a hex string and write back
|
|
||||||
content = hex(reg_value).strip('L')
|
|
||||||
|
|
||||||
reg_file.seek(0)
|
|
||||||
reg_file.write(content)
|
|
||||||
reg_file.close()
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_transceiver_change_event(self, timeout=0):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def __init__(self, sfp_index):
|
|
||||||
# Init SfpUtilBase
|
|
||||||
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
|
|
||||||
|
|
||||||
for x in range(self.PORT_START, self.PORT_END + 1):
|
|
||||||
if self.port_start == 1:
|
|
||||||
self._port_to_eeprom_mapping[x] = eeprom_path.format(
|
|
||||||
(x - 1) + 26)
|
|
||||||
else:
|
|
||||||
self._port_to_eeprom_mapping[x] = eeprom_path.format(x + 26)
|
|
||||||
self.read_porttab_mappings(self.__get_path_to_port_config_file())
|
|
||||||
SfpUtilBase.__init__(self)
|
|
||||||
|
|
||||||
# Init index
|
|
||||||
self.index = sfp_index
|
|
||||||
self.port_num = self.index + 1
|
|
||||||
|
|
||||||
def __get_path_to_port_config_file(self):
|
def __get_path_to_port_config_file(self):
|
||||||
# Get platform and hwsku
|
platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM])
|
||||||
machine_info = sonic_device_util.get_machine_info()
|
hwsku_path = "/".join([platform_path, self.HWSKU]
|
||||||
platform = sonic_device_util.get_platform_info(machine_info)
|
) if self.__is_host() else self.PMON_HWSKU_PATH
|
||||||
config_db = ConfigDBConnector()
|
return "/".join([hwsku_path, "port_config.ini"])
|
||||||
config_db.connect()
|
|
||||||
data = config_db.get_table('DEVICE_METADATA')
|
|
||||||
|
|
||||||
try:
|
|
||||||
hwsku = data['localhost']['hwsku']
|
|
||||||
except KeyError:
|
|
||||||
hwsku = "Unknown"
|
|
||||||
|
|
||||||
# Load platform module from source
|
|
||||||
platform_path = "/".join([self.PLATFORM_ROOT_PATH, platform])
|
|
||||||
hwsku_path = "/".join([platform_path, hwsku])
|
|
||||||
|
|
||||||
# First check for the presence of the new 'port_config.ini' file
|
|
||||||
port_config_file_path = "/".join([hwsku_path, "port_config.ini"])
|
|
||||||
if not os.path.isfile(port_config_file_path):
|
|
||||||
# port_config.ini doesn't exist. Try loading the legacy 'portmap.ini' file
|
|
||||||
port_config_file_path = "/".join([hwsku_path, "portmap.ini"])
|
|
||||||
|
|
||||||
return port_config_file_path
|
|
||||||
|
|
||||||
def __read_eeprom_specific_bytes(self, offset, num_bytes):
|
def __read_eeprom_specific_bytes(self, offset, num_bytes):
|
||||||
sysfsfile_eeprom = None
|
sysfsfile_eeprom = None
|
||||||
eeprom_raw = None
|
eeprom_raw = []
|
||||||
|
for i in range(0, num_bytes):
|
||||||
|
eeprom_raw.append("0x00")
|
||||||
|
|
||||||
sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num]
|
sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num]
|
||||||
try:
|
try:
|
||||||
sysfsfile_eeprom = open(
|
sysfsfile_eeprom = open(
|
||||||
sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0)
|
sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0)
|
||||||
except IOError:
|
sysfsfile_eeprom.seek(offset)
|
||||||
print("Error: reading sysfs file %s" %
|
raw = sysfsfile_eeprom.read(num_bytes)
|
||||||
sysfs_sfp_i2c_client_eeprom_path)
|
for n in range(0, num_bytes):
|
||||||
|
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
finally:
|
finally:
|
||||||
if sysfsfile_eeprom:
|
if sysfsfile_eeprom:
|
||||||
eeprom_raw = self._read_eeprom_specific_bytes(
|
|
||||||
sysfsfile_eeprom, offset, num_bytes)
|
|
||||||
sysfsfile_eeprom.close()
|
sysfsfile_eeprom.close()
|
||||||
|
|
||||||
return eeprom_raw
|
return eeprom_raw
|
||||||
|
|
||||||
def get_transceiver_info(self):
|
def get_transceiver_info(self):
|
||||||
@ -243,45 +204,84 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
vendor_oui |1*255VCHAR |vendor OUI
|
vendor_oui |1*255VCHAR |vendor OUI
|
||||||
========================================================================
|
========================================================================
|
||||||
"""
|
"""
|
||||||
transceiver_info_dict = dict()
|
# check present status
|
||||||
# get eeprom data
|
sfpi_obj = sff8436InterfaceId()
|
||||||
self.eeprom_dict = self.get_eeprom_dict(self.port_num)
|
if not self.get_presence() or not sfpi_obj:
|
||||||
if self.eeprom_dict and self.eeprom_dict.get('interface'):
|
return {}
|
||||||
transceiver_info_data = self.eeprom_dict['interface'].get('data')
|
|
||||||
|
|
||||||
# set specification_compliance
|
offset = INFO_OFFSET
|
||||||
spec_com = transceiver_info_data.get(
|
|
||||||
self.QSFP_EEPROM_SPEC_COM_KEY, {})
|
|
||||||
spec_com_str = "/".join(list(spec_com.values()))
|
|
||||||
|
|
||||||
# set normal transceiver info
|
sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(
|
||||||
transceiver_info_dict['type'] = transceiver_info_data.get(
|
(offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP)
|
||||||
self.QSFP_EEPROM_TYPE_KEY, 'N/A')
|
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(
|
||||||
transceiver_info_dict['hardwarerev'] = transceiver_info_data.get(
|
sfp_interface_bulk_raw, 0)
|
||||||
self.QSFP_EEPROM_HW_REV_KEY, 'N/A')
|
|
||||||
transceiver_info_dict['manufacturename'] = transceiver_info_data.get(
|
sfp_vendor_name_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.QSFP_EEPROM_MF_NAME_KEY, 'N/A')
|
(offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
|
||||||
transceiver_info_dict['modelname'] = transceiver_info_data.get(
|
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
|
||||||
self.QSFP_EEPROM_MODEL_NAME_KEY, 'N/A')
|
sfp_vendor_name_raw, 0)
|
||||||
transceiver_info_dict['serialnum'] = transceiver_info_data.get(
|
|
||||||
self.QSFP_EEPROM_SERIAL_KEY, 'N/A')
|
sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
|
||||||
transceiver_info_dict['Connector'] = transceiver_info_data.get(
|
(offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
|
||||||
self.QSFP_EEPROM_CONNECTOR_KEY, 'N/A')
|
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
|
||||||
transceiver_info_dict['encoding'] = transceiver_info_data.get(
|
sfp_vendor_pn_raw, 0)
|
||||||
self.QSFP_EEPROM_ENCODE_KEY, 'N/A')
|
|
||||||
transceiver_info_dict['ext_identifier'] = transceiver_info_data.get(
|
sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.QSFP_EEPROM_EXT_IDENT_KEY, 'N/A')
|
(offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP)
|
||||||
transceiver_info_dict['ext_rateselect_compliance'] = transceiver_info_data.get(
|
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
|
||||||
self.QSFP_EEPROM_EXT_RATE_KEY, 'N/A')
|
sfp_vendor_rev_raw, 0)
|
||||||
transceiver_info_dict['cable_length'] = transceiver_info_data.get(
|
|
||||||
self.QSFP_EEPROM_CABLE_KEY, 'N/A')
|
sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
|
||||||
transceiver_info_dict['vendor_date'] = transceiver_info_data.get(
|
(offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
|
||||||
self.QSFP_EEPROM_DATE_KEY, 'N/A')
|
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
|
||||||
transceiver_info_dict['vendor_oui'] = transceiver_info_data.get(
|
sfp_vendor_sn_raw, 0)
|
||||||
self.QSFP_EEPROM_OUI_KEY, 'N/A')
|
|
||||||
transceiver_info_dict['nominal_bit_rate'] = transceiver_info_data.get(
|
sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.QSFP_EEPROM_BIT_RATE_KEY, 'N/A')
|
(offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
|
||||||
transceiver_info_dict['specification_compliance'] = spec_com_str or "N/A"
|
if sfp_vendor_oui_raw is not None:
|
||||||
|
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(
|
||||||
|
sfp_vendor_oui_raw, 0)
|
||||||
|
|
||||||
|
sfp_vendor_date_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
|
||||||
|
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(
|
||||||
|
sfp_vendor_date_raw, 0)
|
||||||
|
|
||||||
|
transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A')
|
||||||
|
compliance_code_dict = dict()
|
||||||
|
|
||||||
|
if sfp_interface_bulk_data:
|
||||||
|
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
|
||||||
|
transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value']
|
||||||
|
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
|
||||||
|
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
|
||||||
|
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
|
||||||
|
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
|
||||||
|
|
||||||
|
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[
|
||||||
|
'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A'
|
||||||
|
transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
|
||||||
|
transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A'
|
||||||
|
transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
|
||||||
|
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A'
|
||||||
|
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[
|
||||||
|
'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A'
|
||||||
|
transceiver_info_dict['cable_type'] = "Unknown"
|
||||||
|
transceiver_info_dict['cable_length'] = "Unknown"
|
||||||
|
|
||||||
|
for key in qsfp_cable_length_tup:
|
||||||
|
if key in sfp_interface_bulk_data['data']:
|
||||||
|
transceiver_info_dict['cable_type'] = key
|
||||||
|
transceiver_info_dict['cable_length'] = str(
|
||||||
|
sfp_interface_bulk_data['data'][key]['value'])
|
||||||
|
|
||||||
|
for key in qsfp_compliance_code_tup:
|
||||||
|
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
|
||||||
|
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
|
||||||
|
transceiver_info_dict['specification_compliance'] = str(
|
||||||
|
compliance_code_dict)
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = str(
|
||||||
|
sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value'])
|
||||||
|
|
||||||
return transceiver_info_dict
|
return transceiver_info_dict
|
||||||
|
|
||||||
@ -293,83 +293,200 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
========================================================================
|
========================================================================
|
||||||
keys |Value Format |Information
|
keys |Value Format |Information
|
||||||
---------------------------|---------------|----------------------------
|
---------------------------|---------------|----------------------------
|
||||||
RX LOS |BOOLEAN |RX lost-of-signal status,
|
rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not.
|
||||||
| |True if has RX los, False if not.
|
tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not.
|
||||||
TX FAULT |BOOLEAN |TX fault status,
|
reset_status |BOOLEAN |reset status, True if SFP in reset, False if not.
|
||||||
| |True if has TX fault, False if not.
|
lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not.
|
||||||
Reset status |BOOLEAN |reset status,
|
tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not.
|
||||||
| |True if SFP in reset, False if not.
|
tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0
|
||||||
LP mode |BOOLEAN |low power mode status,
|
|
||||||
| |True in lp mode, False if not.
|
|
||||||
TX disable |BOOLEAN |TX disable status,
|
|
||||||
| |True TX disabled, False if not.
|
|
||||||
TX disabled channel |HEX |disabled TX channles in hex,
|
|
||||||
| |bits 0 to 3 represent channel 0
|
|
||||||
| |to channel 3.
|
| |to channel 3.
|
||||||
Temperature |INT |module temperature in Celsius
|
temperature |INT |module temperature in Celsius
|
||||||
Voltage |INT |supply voltage in mV
|
voltage |INT |supply voltage in mV
|
||||||
TX bias |INT |TX Bias Current in mA
|
tx<n>bias |INT |TX Bias Current in mA, n is the channel number,
|
||||||
RX power |INT |received optical power in mW
|
| |for example, tx2bias stands for tx bias of channel 2.
|
||||||
TX power |INT |TX output power in mW
|
rx<n>power |INT |received optical power in mW, n is the channel number,
|
||||||
|
| |for example, rx2power stands for rx power of channel 2.
|
||||||
|
tx<n>power |INT |TX output power in mW, n is the channel number,
|
||||||
|
| |for example, tx2power stands for tx power of channel 2.
|
||||||
========================================================================
|
========================================================================
|
||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = dict()
|
# check present status
|
||||||
self.eeprom_dict = self.get_eeprom_dict(self.port_num)
|
sfpd_obj = sff8436Dom()
|
||||||
if self.eeprom_dict and self.eeprom_dict.get('dom'):
|
sfpi_obj = sff8436InterfaceId()
|
||||||
transceiver_dom_data = self.eeprom_dict['dom'].get('data', {})
|
|
||||||
transceiver_dom_data_mmv = transceiver_dom_data.get(
|
if not self.get_presence() or not sfpi_obj or not sfpd_obj:
|
||||||
"ModuleMonitorValues")
|
return {}
|
||||||
transceiver_dom_data_cmv = transceiver_dom_data.get(
|
|
||||||
"ChannelMonitorValues")
|
transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A')
|
||||||
transceiver_dom_info_dict['temperature'] = transceiver_dom_data_mmv.get(
|
offset = DOM_OFFSET
|
||||||
'Temperature', 'N/A')
|
offset_xcvr = INFO_OFFSET
|
||||||
transceiver_dom_info_dict['voltage'] = transceiver_dom_data_mmv.get(
|
|
||||||
'Vcc', 'N/A')
|
# QSFP capability byte parse, through this byte can know whether it support tx_power or not.
|
||||||
transceiver_dom_info_dict['rx1power'] = transceiver_dom_data_cmv.get(
|
# TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
|
||||||
'RX1Power', 'N/A')
|
# need to add more code for determining the capability and version compliance
|
||||||
transceiver_dom_info_dict['rx2power'] = transceiver_dom_data_cmv.get(
|
# in SFF-8636 dom capability definitions evolving with the versions.
|
||||||
'RX2Power', 'N/A')
|
qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes(
|
||||||
transceiver_dom_info_dict['rx3power'] = transceiver_dom_data_cmv.get(
|
(offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH)
|
||||||
'RX3Power', 'N/A')
|
if qsfp_dom_capability_raw is not None:
|
||||||
transceiver_dom_info_dict['rx4power'] = transceiver_dom_data_cmv.get(
|
qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(
|
||||||
'RX4Power', 'N/A')
|
qsfp_dom_capability_raw, 0)
|
||||||
transceiver_dom_info_dict['tx1bias'] = transceiver_dom_data_cmv.get(
|
else:
|
||||||
'TX1Bias', 'N/A')
|
return None
|
||||||
transceiver_dom_info_dict['tx2bias'] = transceiver_dom_data_cmv.get(
|
|
||||||
'TX2Bias', 'N/A')
|
dom_temperature_raw = self.__read_eeprom_specific_bytes(
|
||||||
transceiver_dom_info_dict['tx3bias'] = transceiver_dom_data_cmv.get(
|
(offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH)
|
||||||
'TX3Bias', 'N/A')
|
if dom_temperature_raw is not None:
|
||||||
transceiver_dom_info_dict['tx4bias'] = transceiver_dom_data_cmv.get(
|
dom_temperature_data = sfpd_obj.parse_temperature(
|
||||||
'TX4Bias', 'N/A')
|
dom_temperature_raw, 0)
|
||||||
transceiver_dom_info_dict['tx1power'] = transceiver_dom_data_cmv.get(
|
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
|
||||||
'TX1Power', 'N/A')
|
|
||||||
transceiver_dom_info_dict['tx2power'] = transceiver_dom_data_cmv.get(
|
dom_voltage_raw = self.__read_eeprom_specific_bytes(
|
||||||
'TX2Power', 'N/A')
|
(offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH)
|
||||||
transceiver_dom_info_dict['tx3power'] = transceiver_dom_data_cmv.get(
|
if dom_voltage_raw is not None:
|
||||||
'TX3Power', 'N/A')
|
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
|
||||||
transceiver_dom_info_dict['tx4power'] = transceiver_dom_data_cmv.get(
|
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
|
||||||
'TX4Power', 'N/A')
|
|
||||||
|
qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH)
|
||||||
|
if qsfp_dom_rev_raw is not None:
|
||||||
|
qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0)
|
||||||
|
qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value']
|
||||||
|
|
||||||
|
# The tx_power monitoring is only available on QSFP which compliant with SFF-8636
|
||||||
|
# and claimed that it support tx_power with one indicator bit.
|
||||||
|
dom_channel_monitor_data = {}
|
||||||
|
dom_channel_monitor_raw = None
|
||||||
|
qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value']
|
||||||
|
if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')):
|
||||||
|
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(
|
||||||
|
dom_channel_monitor_raw, 0)
|
||||||
|
|
||||||
|
else:
|
||||||
|
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(
|
||||||
|
dom_channel_monitor_raw, 0)
|
||||||
|
transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value']
|
||||||
|
transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value']
|
||||||
|
transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value']
|
||||||
|
transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value']
|
||||||
|
|
||||||
|
if dom_channel_monitor_raw:
|
||||||
|
transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value']
|
||||||
|
transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value']
|
||||||
|
transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value']
|
||||||
|
transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value']
|
||||||
|
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value']
|
||||||
|
transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value']
|
||||||
|
transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value']
|
||||||
|
transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value']
|
||||||
|
|
||||||
for key in transceiver_dom_info_dict:
|
for key in transceiver_dom_info_dict:
|
||||||
transceiver_dom_info_dict[key] = self._convert_string_to_num(
|
transceiver_dom_info_dict[key] = self._convert_string_to_num(
|
||||||
transceiver_dom_info_dict[key])
|
transceiver_dom_info_dict[key])
|
||||||
|
|
||||||
|
transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
|
||||||
|
transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
|
||||||
|
transceiver_dom_info_dict['reset_status'] = self.get_reset_status()
|
||||||
|
transceiver_dom_info_dict['lp_mode'] = self.get_lpmode()
|
||||||
|
|
||||||
return transceiver_dom_info_dict
|
return transceiver_dom_info_dict
|
||||||
|
|
||||||
|
def get_transceiver_threshold_info(self):
|
||||||
|
"""
|
||||||
|
Retrieves transceiver threshold info of this SFP
|
||||||
|
Returns:
|
||||||
|
A dict which contains following keys/values :
|
||||||
|
========================================================================
|
||||||
|
keys |Value Format |Information
|
||||||
|
---------------------------|---------------|----------------------------
|
||||||
|
temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius.
|
||||||
|
templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius.
|
||||||
|
temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius.
|
||||||
|
templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius.
|
||||||
|
vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV.
|
||||||
|
vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV.
|
||||||
|
vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV.
|
||||||
|
vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV.
|
||||||
|
rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm.
|
||||||
|
rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm.
|
||||||
|
rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm.
|
||||||
|
rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm.
|
||||||
|
txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm.
|
||||||
|
txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm.
|
||||||
|
txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm.
|
||||||
|
txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm.
|
||||||
|
txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA.
|
||||||
|
txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA.
|
||||||
|
txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA.
|
||||||
|
txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA.
|
||||||
|
========================================================================
|
||||||
|
"""
|
||||||
|
# check present status
|
||||||
|
sfpd_obj = sff8436Dom()
|
||||||
|
|
||||||
|
if not self.get_presence() or not sfpd_obj:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
transceiver_dom_threshold_dict = dict.fromkeys(
|
||||||
|
self.threshold_dict_keys, 'N/A')
|
||||||
|
dom_thres_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None
|
||||||
|
|
||||||
|
if dom_thres_raw:
|
||||||
|
module_threshold_values = sfpd_obj.parse_module_threshold_values(
|
||||||
|
dom_thres_raw, 0)
|
||||||
|
module_threshold_data = module_threshold_values.get('data')
|
||||||
|
if module_threshold_data:
|
||||||
|
transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value']
|
||||||
|
transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value']
|
||||||
|
|
||||||
|
dom_thres_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None
|
||||||
|
channel_threshold_values = sfpd_obj.parse_channel_threshold_values(
|
||||||
|
dom_thres_raw, 0)
|
||||||
|
channel_threshold_data = channel_threshold_values.get('data')
|
||||||
|
if channel_threshold_data:
|
||||||
|
transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value']
|
||||||
|
transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm"
|
||||||
|
transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm"
|
||||||
|
transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm"
|
||||||
|
transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm"
|
||||||
|
transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value']
|
||||||
|
|
||||||
|
for key in transceiver_dom_threshold_dict:
|
||||||
|
transceiver_dom_threshold_dict[key] = self._convert_string_to_num(
|
||||||
|
transceiver_dom_threshold_dict[key])
|
||||||
|
|
||||||
|
return transceiver_dom_threshold_dict
|
||||||
|
|
||||||
def get_reset_status(self):
|
def get_reset_status(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the reset status of SFP
|
Retrieves the reset status of SFP
|
||||||
Returns:
|
Returns:
|
||||||
A Boolean, True if reset enabled, False if disabled
|
A Boolean, True if reset enabled, False if disabled
|
||||||
"""
|
"""
|
||||||
try:
|
reset_status_raw = self.__read_txt_file(self.RESET_PATH).rstrip()
|
||||||
reg_file = open(self.RESET_PATH, "r")
|
if not reset_status_raw:
|
||||||
except IOError as e:
|
|
||||||
print("Error: unable to open file: %s" % str(e))
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
content = reg_file.readline().rstrip()
|
reg_value = int(reset_status_raw, 16)
|
||||||
reg_value = int(content, 16)
|
|
||||||
bin_format = bin(reg_value)[2:].zfill(32)
|
bin_format = bin(reg_value)[2:].zfill(32)
|
||||||
return bin_format[::-1][self.index] == '0'
|
return bin_format[::-1][self.index] == '0'
|
||||||
|
|
||||||
@ -380,16 +497,18 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
A Boolean, True if SFP has RX LOS, False if not.
|
A Boolean, True if SFP has RX LOS, False if not.
|
||||||
Note : RX LOS status is latched until a call to get_rx_los or a reset.
|
Note : RX LOS status is latched until a call to get_rx_los or a reset.
|
||||||
"""
|
"""
|
||||||
|
rx_los = False
|
||||||
rx_los_list = []
|
rx_los_list = []
|
||||||
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.QSFP_CHANNL_RX_LOS_STATUS_OFFSET, self.QSFP_CHANNL_RX_LOS_STATUS_WIDTH)
|
QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None
|
||||||
if dom_channel_monitor_raw is not None:
|
if dom_channel_monitor_raw is not None:
|
||||||
rx_los_data = int(dom_channel_monitor_raw[0], 16)
|
rx_los_data = int(dom_channel_monitor_raw[0], 16)
|
||||||
rx_los_list.append(rx_los_data & 0x01 != 0)
|
rx_los_list.append(rx_los_data & 0x01 != 0)
|
||||||
rx_los_list.append(rx_los_data & 0x02 != 0)
|
rx_los_list.append(rx_los_data & 0x02 != 0)
|
||||||
rx_los_list.append(rx_los_data & 0x04 != 0)
|
rx_los_list.append(rx_los_data & 0x04 != 0)
|
||||||
rx_los_list.append(rx_los_data & 0x08 != 0)
|
rx_los_list.append(rx_los_data & 0x08 != 0)
|
||||||
return rx_los_list
|
rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3]
|
||||||
|
return rx_los
|
||||||
|
|
||||||
def get_tx_fault(self):
|
def get_tx_fault(self):
|
||||||
"""
|
"""
|
||||||
@ -398,16 +517,19 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
A Boolean, True if SFP has TX fault, False if not
|
A Boolean, True if SFP has TX fault, False if not
|
||||||
Note : TX fault status is lached until a call to get_tx_fault or a reset.
|
Note : TX fault status is lached until a call to get_tx_fault or a reset.
|
||||||
"""
|
"""
|
||||||
|
tx_fault = False
|
||||||
tx_fault_list = []
|
tx_fault_list = []
|
||||||
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, self.QSFP_CHANNL_TX_FAULT_STATUS_WIDTH)
|
QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None
|
||||||
if dom_channel_monitor_raw is not None:
|
if dom_channel_monitor_raw is not None:
|
||||||
tx_fault_data = int(dom_channel_monitor_raw[0], 16)
|
tx_fault_data = int(dom_channel_monitor_raw[0], 16)
|
||||||
tx_fault_list.append(tx_fault_data & 0x01 != 0)
|
tx_fault_list.append(tx_fault_data & 0x01 != 0)
|
||||||
tx_fault_list.append(tx_fault_data & 0x02 != 0)
|
tx_fault_list.append(tx_fault_data & 0x02 != 0)
|
||||||
tx_fault_list.append(tx_fault_data & 0x04 != 0)
|
tx_fault_list.append(tx_fault_data & 0x04 != 0)
|
||||||
tx_fault_list.append(tx_fault_data & 0x08 != 0)
|
tx_fault_list.append(tx_fault_data & 0x08 != 0)
|
||||||
return tx_fault_list
|
tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3]
|
||||||
|
|
||||||
|
return tx_fault
|
||||||
|
|
||||||
def get_tx_disable(self):
|
def get_tx_disable(self):
|
||||||
"""
|
"""
|
||||||
@ -422,7 +544,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
dom_control_raw = self.__read_eeprom_specific_bytes(
|
dom_control_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.QSFP_CONTROL_OFFSET, self.QSFP_CONTROL_WIDTH)
|
QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None
|
||||||
if dom_control_raw is not None:
|
if dom_control_raw is not None:
|
||||||
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
|
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
|
||||||
tx_disable_list.append(
|
tx_disable_list.append(
|
||||||
@ -460,7 +582,27 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
A Boolean, True if lpmode is enabled, False if disabled
|
A Boolean, True if lpmode is enabled, False if disabled
|
||||||
"""
|
"""
|
||||||
return self.get_low_power_mode(self.port_num)
|
try:
|
||||||
|
reg_file = open(self.LP_PATH, "r")
|
||||||
|
content = reg_file.readline().rstrip()
|
||||||
|
except IOError as e:
|
||||||
|
print("Error: unable to open file: %s" % str(e))
|
||||||
|
return False
|
||||||
|
|
||||||
|
# content is a string containing the hex representation of the register
|
||||||
|
reg_value = int(content, 16)
|
||||||
|
|
||||||
|
# Determind if port_num start from 1 or 0
|
||||||
|
bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num
|
||||||
|
|
||||||
|
# Mask off the bit corresponding to our port
|
||||||
|
mask = (1 << bit_index)
|
||||||
|
|
||||||
|
# LPMode is active high
|
||||||
|
if reg_value & mask == 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def get_power_override(self):
|
def get_power_override(self):
|
||||||
"""
|
"""
|
||||||
@ -476,7 +618,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
dom_control_raw = self.__read_eeprom_specific_bytes(
|
dom_control_raw = self.__read_eeprom_specific_bytes(
|
||||||
self.QSFP_CONTROL_OFFSET, self.QSFP_CONTROL_WIDTH)
|
QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None
|
||||||
if dom_control_raw is not None:
|
if dom_control_raw is not None:
|
||||||
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
|
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
|
||||||
power_override = (
|
power_override = (
|
||||||
@ -515,7 +657,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A")
|
tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A")
|
||||||
tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A")
|
tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A")
|
||||||
tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A")
|
tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A")
|
||||||
return [tx1_bs, tx2_bs, tx3_bs, tx4_bs]
|
return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else []
|
||||||
|
|
||||||
def get_rx_power(self):
|
def get_rx_power(self):
|
||||||
"""
|
"""
|
||||||
@ -530,7 +672,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A")
|
rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A")
|
||||||
rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A")
|
rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A")
|
||||||
rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A")
|
rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A")
|
||||||
return [rx1_pw, rx2_pw, rx3_pw, rx4_pw]
|
return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else []
|
||||||
|
|
||||||
def get_tx_power(self):
|
def get_tx_power(self):
|
||||||
"""
|
"""
|
||||||
@ -568,7 +710,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
reg_value = int(content, 16)
|
reg_value = int(content, 16)
|
||||||
|
|
||||||
# Determind if port_num start from 1 or 0
|
# Determind if port_num start from 1 or 0
|
||||||
bit_index = self.port_num - 1 if self.port_start == 1 else self.port_num
|
bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num
|
||||||
|
|
||||||
# Mask off the bit corresponding to our port
|
# Mask off the bit corresponding to our port
|
||||||
mask = (1 << bit_index)
|
mask = (1 << bit_index)
|
||||||
@ -615,7 +757,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
# Write to eeprom
|
# Write to eeprom
|
||||||
sysfsfile_eeprom = open(
|
sysfsfile_eeprom = open(
|
||||||
self.port_to_eeprom_mapping[self.port_num], "r+b")
|
self.port_to_eeprom_mapping[self.port_num], "r+b")
|
||||||
sysfsfile_eeprom.seek(self.QSFP_CONTROL_OFFSET)
|
sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
|
||||||
sysfsfile_eeprom.write(buffer[0])
|
sysfsfile_eeprom.write(buffer[0])
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
print "Error: unable to open file: %s" % str(e)
|
print "Error: unable to open file: %s" % str(e)
|
||||||
@ -649,7 +791,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
# Write to eeprom
|
# Write to eeprom
|
||||||
sysfsfile_eeprom = open(
|
sysfsfile_eeprom = open(
|
||||||
self.port_to_eeprom_mapping[self.port_num], "r+b")
|
self.port_to_eeprom_mapping[self.port_num], "r+b")
|
||||||
sysfsfile_eeprom.seek(self.QSFP_CONTROL_OFFSET)
|
sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
|
||||||
sysfsfile_eeprom.write(buffer[0])
|
sysfsfile_eeprom.write(buffer[0])
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
print "Error: unable to open file: %s" % str(e)
|
print "Error: unable to open file: %s" % str(e)
|
||||||
@ -669,7 +811,33 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
A boolean, True if lpmode is set successfully, False if not
|
A boolean, True if lpmode is set successfully, False if not
|
||||||
"""
|
"""
|
||||||
return self.set_low_power_mode(self.port_num, lpmode)
|
try:
|
||||||
|
reg_file = open(self.LP_PATH, "r+")
|
||||||
|
except IOError as e:
|
||||||
|
print("Error: unable to open file: %s" % str(e))
|
||||||
|
return False
|
||||||
|
|
||||||
|
content = reg_file.readline().rstrip()
|
||||||
|
|
||||||
|
# content is a string containing the hex representation of the register
|
||||||
|
reg_value = int(content, 16)
|
||||||
|
|
||||||
|
# Determind if port_num start from 1 or 0
|
||||||
|
bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num
|
||||||
|
|
||||||
|
# Mask off the bit corresponding to our port
|
||||||
|
mask = (1 << bit_index)
|
||||||
|
# LPMode is active high; set or clear the bit accordingly
|
||||||
|
reg_value = reg_value | mask if lpmode else reg_value & ~mask
|
||||||
|
|
||||||
|
# Convert our register value back to a hex string and write back
|
||||||
|
content = hex(reg_value).strip('L')
|
||||||
|
|
||||||
|
reg_file.seek(0)
|
||||||
|
reg_file.write(content)
|
||||||
|
reg_file.close()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def set_power_override(self, power_override, power_set):
|
def set_power_override(self, power_override, power_set):
|
||||||
"""
|
"""
|
||||||
@ -702,7 +870,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
# Write to eeprom
|
# Write to eeprom
|
||||||
sysfsfile_eeprom = open(
|
sysfsfile_eeprom = open(
|
||||||
self.port_to_eeprom_mapping[self.port_num], "r+b")
|
self.port_to_eeprom_mapping[self.port_num], "r+b")
|
||||||
sysfsfile_eeprom.seek(self.QSFP_POWEROVERRIDE_OFFSET)
|
sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET)
|
||||||
sysfsfile_eeprom.write(buffer[0])
|
sysfsfile_eeprom.write(buffer[0])
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
print "Error: unable to open file: %s" % str(e)
|
print "Error: unable to open file: %s" % str(e)
|
||||||
@ -719,7 +887,11 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: The name of the device
|
string: The name of the device
|
||||||
"""
|
"""
|
||||||
return self.logical[self.index]
|
sfputil_helper = SfpUtilHelper()
|
||||||
|
sfputil_helper.read_porttab_mappings(
|
||||||
|
self.__get_path_to_port_config_file())
|
||||||
|
name = sfputil_helper.logical[self.index] or "Unknown"
|
||||||
|
return name
|
||||||
|
|
||||||
def get_presence(self):
|
def get_presence(self):
|
||||||
"""
|
"""
|
||||||
@ -727,17 +899,15 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if PSU is present, False if not
|
bool: True if PSU is present, False if not
|
||||||
"""
|
"""
|
||||||
try:
|
presence_status_raw = self.__read_txt_file(self.PRS_PATH).rstrip()
|
||||||
reg_file = open(self.PRS_PATH, "r")
|
if not presence_status_raw:
|
||||||
except IOError as e:
|
|
||||||
print("Error: unable to open file: %s" % str(e))
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
content = reg_file.readline().rstrip()
|
content = presence_status_raw.rstrip()
|
||||||
reg_value = int(content, 16)
|
reg_value = int(content, 16)
|
||||||
|
|
||||||
# Determind if port_num start from 1 or 0
|
# Determind if port_num start from 1 or 0
|
||||||
bit_index = self.port_num - 1 if self.port_start == 1 else self.port_num
|
bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num
|
||||||
|
|
||||||
# Mask off the bit corresponding to our port
|
# Mask off the bit corresponding to our port
|
||||||
mask = (1 << bit_index)
|
mask = (1 << bit_index)
|
||||||
@ -754,7 +924,7 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: Model/part number of device
|
string: Model/part number of device
|
||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
transceiver_dom_info_dict = self.get_transceiver_info()
|
||||||
return transceiver_dom_info_dict.get("modelname", "N/A")
|
return transceiver_dom_info_dict.get("modelname", "N/A")
|
||||||
|
|
||||||
def get_serial(self):
|
def get_serial(self):
|
||||||
@ -763,5 +933,13 @@ class Sfp(SfpBase, SfpUtilBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: Serial number of device
|
string: Serial number of device
|
||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
transceiver_dom_info_dict = self.get_transceiver_info()
|
||||||
return transceiver_dom_info_dict.get("serialnum", "N/A")
|
return transceiver_dom_info_dict.get("serialnum", "N/A")
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the device
|
||||||
|
Returns:
|
||||||
|
A boolean value, True if device is operating properly, False if not
|
||||||
|
"""
|
||||||
|
return self.get_presence() and self.get_transceiver_bulk_status()
|
||||||
|
@ -37,18 +37,16 @@ class Thermal(ThermalBase):
|
|||||||
|
|
||||||
# Set hwmon path
|
# Set hwmon path
|
||||||
i2c_path = {
|
i2c_path = {
|
||||||
0: "i2c-5/5-0048", # u4 system-inlet
|
0: "i2c-5/5-0048/hwmon/hwmon1", # u4 system-inlet
|
||||||
1: "i2c-6/6-0049", # u2 system-inlet
|
1: "i2c-6/6-0049/hwmon/hwmon2", # u2 system-inlet
|
||||||
2: "i2c-7/7-004a", # u44 bmc56960-on-board
|
2: "i2c-7/7-004a/hwmon/hwmon3", # u44 bmc56960-on-board
|
||||||
3: "i2c-14/14-0048", # u9200 cpu-on-board
|
3: "i2c-14/14-0048/hwmon/hwmon4", # u9200 cpu-on-board
|
||||||
4: "i2c-15/15-004e" # u9201 system-outlet
|
4: "i2c-15/15-004e/hwmon/hwmon5" # u9201 system-outlet
|
||||||
}.get(self.index, None)
|
}.get(self.index, None)
|
||||||
|
|
||||||
self.ss_path = "{}/{}/hwmon".format(self.I2C_ADAPTER_PATH, i2c_path)
|
self.hwmon_path = "{}/{}".format(self.I2C_ADAPTER_PATH, i2c_path)
|
||||||
self.ss_key = self.THERMAL_NAME_LIST[self.index]
|
self.ss_key = self.THERMAL_NAME_LIST[self.index]
|
||||||
self.ss_index = 1
|
self.ss_index = 1
|
||||||
self.hwmon_name = os.listdir(self.ss_path)[0]
|
|
||||||
self.hwmon_path = os.path.join(self.ss_path, self.hwmon_name)
|
|
||||||
|
|
||||||
def __read_txt_file(self, file_path):
|
def __read_txt_file(self, file_path):
|
||||||
try:
|
try:
|
||||||
@ -56,7 +54,7 @@ class Thermal(ThermalBase):
|
|||||||
data = fd.read()
|
data = fd.read()
|
||||||
return data.strip()
|
return data.strip()
|
||||||
except IOError:
|
except IOError:
|
||||||
raise IOError("Unable to open %s file !" % file_path)
|
pass
|
||||||
|
|
||||||
def __get_temp(self, temp_file):
|
def __get_temp(self, temp_file):
|
||||||
temp_file_path = os.path.join(self.hwmon_path, temp_file)
|
temp_file_path = os.path.join(self.hwmon_path, temp_file)
|
||||||
|
Binary file not shown.
@ -23,13 +23,13 @@
|
|||||||
"p4_pipelines": [
|
"p4_pipelines": [
|
||||||
{
|
{
|
||||||
"p4_pipeline_name": "pipe",
|
"p4_pipeline_name": "pipe",
|
||||||
"config": "share/tofinopd/switch/pipe/tofino.bin",
|
"config": "share/switch/pipe/tofino.bin",
|
||||||
"context": "share/tofinopd/switch/pipe/context.json"
|
"context": "share/switch/pipe/context.json"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"program-name": "switch",
|
"program-name": "switch",
|
||||||
"switchsai": "lib/libswitchsai.so",
|
"switchsai": "lib/libswitchsai.so",
|
||||||
"bfrt-config": "share/tofinopd/switch/bf-rt.json",
|
"bfrt-config": "share/switch/bf-rt.json",
|
||||||
"model_json_path" : "share/switch/aug_model.json",
|
"model_json_path" : "share/switch/aug_model.json",
|
||||||
"switchapi_port_add": false,
|
"switchapi_port_add": false,
|
||||||
"non_default_port_ppgs": 5
|
"non_default_port_ppgs": 5
|
||||||
|
@ -23,13 +23,13 @@
|
|||||||
"p4_pipelines": [
|
"p4_pipelines": [
|
||||||
{
|
{
|
||||||
"p4_pipeline_name": "pipe",
|
"p4_pipeline_name": "pipe",
|
||||||
"config": "share/tofinopd/switch/pipe/tofino.bin",
|
"config": "share/switch/pipe/tofino.bin",
|
||||||
"context": "share/tofinopd/switch/pipe/context.json"
|
"context": "share/switch/pipe/context.json"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"program-name": "switch",
|
"program-name": "switch",
|
||||||
"switchsai": "lib/libswitchsai.so",
|
"switchsai": "lib/libswitchsai.so",
|
||||||
"bfrt-config": "share/tofinopd/switch/bf-rt.json",
|
"bfrt-config": "share/switch/bf-rt.json",
|
||||||
"model_json_path" : "share/switch/aug_model.json",
|
"model_json_path" : "share/switch/aug_model.json",
|
||||||
"switchapi_port_add": false,
|
"switchapi_port_add": false,
|
||||||
"non_default_port_ppgs": 5
|
"non_default_port_ppgs": 5
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
# name lanes alias
|
||||||
|
Ethernet0 73,74,75,76 hundredGigE1
|
||||||
|
Ethernet4 65,66,67,68 hundredGigE2
|
||||||
|
Ethernet8 81,82,83,84 hundredGigE3
|
||||||
|
Ethernet12 89,90,91,92 hundredGigE4
|
||||||
|
Ethernet16 105,106,107,108 hundredGigE5
|
||||||
|
Ethernet20 97,98,99,100 hundredGigE6
|
||||||
|
Ethernet24 113,114,115,116 hundredGigE7
|
||||||
|
Ethernet28 121,122,123,124 hundredGigE8
|
||||||
|
Ethernet32 41,42,43,44 hundredGigE9
|
||||||
|
Ethernet36 33,34,35,36 hundredGigE10
|
||||||
|
Ethernet40 49,50,51,52 hundredGigE11
|
||||||
|
Ethernet44 57,58,59,60 hundredGigE12
|
||||||
|
Ethernet48 137,138,139,140 hundredGigE13
|
||||||
|
Ethernet52 129,130,131,132 hundredGigE14
|
||||||
|
Ethernet56 145,146,147,148 hundredGigE15
|
||||||
|
Ethernet60 153,154,155,156 hundredGigE16
|
||||||
|
Ethernet64 173,174,175,176 hundredGigE17
|
||||||
|
Ethernet68 165,166,167,168 hundredGigE18
|
||||||
|
Ethernet72 181,182,183,184 hundredGigE19
|
||||||
|
Ethernet76 189,190,191,192 hundredGigE20
|
||||||
|
Ethernet80 13,14,15,16 hundredGigE21
|
||||||
|
Ethernet84 5,6,7,8 hundredGigE22
|
||||||
|
Ethernet88 29,30,31,32 hundredGigE23
|
||||||
|
Ethernet92 21,22,23,24 hundredGigE24
|
||||||
|
Ethernet96 205,206,207,208 hundredGigE25
|
||||||
|
Ethernet100 197,198,199,200 hundredGigE26
|
||||||
|
Ethernet104 213,214,215,216 hundredGigE27
|
||||||
|
Ethernet108 221,222,223,224 hundredGigE28
|
||||||
|
Ethernet112 229,230,231,232 hundredGigE29
|
||||||
|
Ethernet116 237,238,239,240 hundredGigE30
|
||||||
|
Ethernet120 245,246,247,248 hundredGigE31
|
||||||
|
Ethernet124 253,254,255,256 hundredGigE32
|
||||||
|
Ethernet128 69,70,71,72 hundredGigE33
|
||||||
|
Ethernet132 77,78,79,80 hundredGigE34
|
||||||
|
Ethernet136 93,94,95,96 hundredGigE35
|
||||||
|
Ethernet140 85,86,87,88 hundredGigE36
|
||||||
|
Ethernet144 101,102,103,104 hundredGigE37
|
||||||
|
Ethernet148 109,110,111,112 hundredGigE38
|
||||||
|
Ethernet152 125,126,127,128 hundredGigE39
|
||||||
|
Ethernet156 117,118,119,120 hundredGigE40
|
||||||
|
Ethernet160 37,38,39,40 hundredGigE41
|
||||||
|
Ethernet164 45,46,47,48 hundredGigE42
|
||||||
|
Ethernet168 61,62,63,64 hundredGigE43
|
||||||
|
Ethernet172 53,54,55,56 hundredGigE44
|
||||||
|
Ethernet176 133,134,135,136 hundredGigE45
|
||||||
|
Ethernet180 141,142,143,144 hundredGigE46
|
||||||
|
Ethernet184 157,158,159,160 hundredGigE47
|
||||||
|
Ethernet188 149,150,151,152 hundredGigE48
|
||||||
|
Ethernet192 161,162,163,164 hundredGigE49
|
||||||
|
Ethernet196 169,170,171,172 hundredGigE50
|
||||||
|
Ethernet200 185,186,187,188 hundredGigE51
|
||||||
|
Ethernet204 177,178,179,180 hundredGigE52
|
||||||
|
Ethernet208 1,2,3,4 hundredGigE53
|
||||||
|
Ethernet212 9,10,11,12 hundredGigE54
|
||||||
|
Ethernet216 25,26,27,28 hundredGigE55
|
||||||
|
Ethernet220 17,18,19,20 hundredGigE56
|
||||||
|
Ethernet224 193,194,195,196 hundredGigE57
|
||||||
|
Ethernet228 201,202,203,204 hundredGigE58
|
||||||
|
Ethernet232 217,218,219,220 hundredGigE59
|
||||||
|
Ethernet236 209,210,211,212 hundredGigE60
|
||||||
|
Ethernet240 225,226,227,228 hundredGigE61
|
||||||
|
Ethernet244 233,234,235,236 hundredGigE62
|
||||||
|
Ethernet248 249,250,251,252 hundredGigE63
|
||||||
|
Ethernet252 241,242,243,244 hundredGigE64
|
@ -0,0 +1 @@
|
|||||||
|
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-qfx5210-64x100G.config.bcm
|
@ -0,0 +1,875 @@
|
|||||||
|
# Broadcom Tomahawk SDK configuration
|
||||||
|
os=unix
|
||||||
|
schan_intr_enable=0
|
||||||
|
l2_mem_entries=40960
|
||||||
|
l2xmsg_mode=1
|
||||||
|
l3_mem_entries=40960
|
||||||
|
parity_correction=0
|
||||||
|
parity_enable=0
|
||||||
|
mmu_lossless=1
|
||||||
|
|
||||||
|
pbmp_xport_xe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
pbmp_oversubscribe=0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
|
||||||
|
# platform specific setting
|
||||||
|
arl_clean_timeout_usec=15000000
|
||||||
|
asf_mem_profile=2
|
||||||
|
bcm_num_cos=8
|
||||||
|
bcm_stat_flags=1
|
||||||
|
bcm_stat_jumbo=9236
|
||||||
|
cdma_timeout_usec=15000000
|
||||||
|
dma_desc_timeout_usec=15000000
|
||||||
|
ipv6_lpm_128b_enable=1
|
||||||
|
l3_alpm_enable=2
|
||||||
|
lpm_scaling_enable=0
|
||||||
|
max_vp_lags=0
|
||||||
|
miim_intr_enable=0
|
||||||
|
module_64ports=1
|
||||||
|
oversubscribe_mode=1
|
||||||
|
|
||||||
|
#add loopback port
|
||||||
|
# port 33 is the first loopback port
|
||||||
|
portmap_33=260:10
|
||||||
|
# port 66 is the first management port
|
||||||
|
portmap_66=257:10
|
||||||
|
# port 67 is the second loopback port
|
||||||
|
portmap_67=261:10
|
||||||
|
# port 100 is the second management port
|
||||||
|
portmap_100=259:10
|
||||||
|
# port 101 is the third loopback port
|
||||||
|
portmap_101=262:10
|
||||||
|
# port 135 is the fourth loopback port
|
||||||
|
portmap_135=263:10
|
||||||
|
|
||||||
|
#Port0
|
||||||
|
#FC18
|
||||||
|
portmap_36=73:100
|
||||||
|
phy_chain_rx_lane_map_physical{73.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{73.0}=0x3021
|
||||||
|
phy_chain_rx_polarity_flip_physical{73.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{74.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{75.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{76.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{73.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{74.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{75.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{76.0}=0x0
|
||||||
|
#Port1
|
||||||
|
#FC16
|
||||||
|
portmap_34=65:100
|
||||||
|
phy_chain_rx_lane_map_physical{65.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{65.0}=0x3210
|
||||||
|
phy_chain_rx_polarity_flip_physical{65.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{66.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{67.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{68.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{65.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{66.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{67.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{68.0}=0x0
|
||||||
|
#Port2
|
||||||
|
#FC20
|
||||||
|
portmap_38=81:100
|
||||||
|
phy_chain_rx_lane_map_physical{81.0}=0x1230
|
||||||
|
phy_chain_tx_lane_map_physical{81.0}=0x1032
|
||||||
|
phy_chain_rx_polarity_flip_physical{81.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{82.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{83.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{84.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{81.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{82.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{83.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{84.0}=0x0
|
||||||
|
#Port3
|
||||||
|
#FC22
|
||||||
|
portmap_40=89:100
|
||||||
|
phy_chain_rx_lane_map_physical{89.0}=0x0132
|
||||||
|
phy_chain_tx_lane_map_physical{89.0}=0x1203
|
||||||
|
phy_chain_rx_polarity_flip_physical{89.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{90.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{91.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{92.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{89.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{90.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{91.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{92.0}=0x1
|
||||||
|
#Port4
|
||||||
|
#FC26
|
||||||
|
portmap_44=105:100
|
||||||
|
phy_chain_rx_lane_map_physical{105.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{105.0}=0x0231
|
||||||
|
phy_chain_rx_polarity_flip_physical{105.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{106.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{107.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{108.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{105.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{106.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{107.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{108.0}=0x1
|
||||||
|
#Port5
|
||||||
|
#FC24
|
||||||
|
portmap_42=97:100
|
||||||
|
phy_chain_rx_lane_map_physical{97.0}=0x0213
|
||||||
|
phy_chain_tx_lane_map_physical{97.0}=0x3210
|
||||||
|
phy_chain_rx_polarity_flip_physical{97.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{98.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{99.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{100.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{97.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{98.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{99.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{100.0}=0x0
|
||||||
|
#Port6
|
||||||
|
#FC 28
|
||||||
|
portmap_46=113:100
|
||||||
|
phy_chain_rx_lane_map_physical{113.0}=0x3021
|
||||||
|
phy_chain_tx_lane_map_physical{113.0}=0x0312
|
||||||
|
phy_chain_rx_polarity_flip_physical{113.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{114.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{115.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{116.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{113.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{114.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{115.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{116.0}=0x1
|
||||||
|
#Port7
|
||||||
|
#FC30
|
||||||
|
portmap_48=121:100
|
||||||
|
phy_chain_rx_lane_map_physical{121.0}=0x3021
|
||||||
|
phy_chain_tx_lane_map_physical{121.0}=0x2130
|
||||||
|
phy_chain_rx_polarity_flip_physical{121.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{122.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{123.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{124.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{121.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{122.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{123.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{124.0}=0x0
|
||||||
|
#Port8
|
||||||
|
#FC10
|
||||||
|
portmap_11=41:100
|
||||||
|
phy_chain_rx_lane_map_physical{41.0}=0x0132
|
||||||
|
phy_chain_tx_lane_map_physical{41.0}=0x1302
|
||||||
|
phy_chain_rx_polarity_flip_physical{41.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{42.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{43.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{44.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{41.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{42.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{43.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{44.0}=0x0
|
||||||
|
#Port9
|
||||||
|
#FC8
|
||||||
|
portmap_9=33:100
|
||||||
|
phy_chain_rx_lane_map_physical{33.0}=0x2310
|
||||||
|
phy_chain_tx_lane_map_physical{33.0}=0x0213
|
||||||
|
phy_chain_rx_polarity_flip_physical{33.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{34.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{35.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{36.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{33.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{34.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{35.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{36.0}=0x0
|
||||||
|
#Port10
|
||||||
|
#FC12
|
||||||
|
portmap_13=49:100
|
||||||
|
phy_chain_rx_lane_map_physical{49.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{49.0}=0x3102
|
||||||
|
phy_chain_rx_polarity_flip_physical{49.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{50.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{51.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{52.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{49.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{50.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{51.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{52.0}=0x1
|
||||||
|
#Port11
|
||||||
|
#FC14
|
||||||
|
portmap_15=57:100
|
||||||
|
phy_chain_rx_lane_map_physical{57.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{57.0}=0x1302
|
||||||
|
phy_chain_rx_polarity_flip_physical{57.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{58.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{59.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{60.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{57.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{58.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{59.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{60.0}=0x1
|
||||||
|
#Port12
|
||||||
|
#FC34
|
||||||
|
portmap_70=137:100
|
||||||
|
phy_chain_rx_lane_map_physical{137.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{137.0}=0x0213
|
||||||
|
phy_chain_rx_polarity_flip_physical{137.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{138.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{139.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{140.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{137.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{138.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{139.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{140.0}=0x0
|
||||||
|
#Port13
|
||||||
|
#FC32
|
||||||
|
portmap_68=129:100
|
||||||
|
phy_chain_rx_lane_map_physical{129.0}=0x3021
|
||||||
|
phy_chain_tx_lane_map_physical{129.0}=0x1203
|
||||||
|
phy_chain_rx_polarity_flip_physical{129.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{130.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{131.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{132.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{129.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{130.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{131.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{132.0}=0x1
|
||||||
|
#Port14
|
||||||
|
#FC36
|
||||||
|
portmap_72=145:100
|
||||||
|
phy_chain_rx_lane_map_physical{145.0}=0x0213
|
||||||
|
phy_chain_tx_lane_map_physical{145.0}=0x2301
|
||||||
|
phy_chain_rx_polarity_flip_physical{145.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{146.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{147.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{148.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{145.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{146.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{147.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{148.0}=0x1
|
||||||
|
#Port15
|
||||||
|
#FC38
|
||||||
|
portmap_74=153:100
|
||||||
|
phy_chain_rx_lane_map_physical{153.0}=0x0213
|
||||||
|
phy_chain_tx_lane_map_physical{153.0}=0x1302
|
||||||
|
phy_chain_rx_polarity_flip_physical{153.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{154.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{155.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{156.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{153.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{154.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{155.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{156.0}=0x0
|
||||||
|
#Port16
|
||||||
|
#FC43
|
||||||
|
portmap_79=173:100
|
||||||
|
phy_chain_rx_lane_map_physical{173.0}=0x1032
|
||||||
|
phy_chain_tx_lane_map_physical{173.0}=0x1203
|
||||||
|
phy_chain_rx_polarity_flip_physical{173.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{174.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{175.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{176.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{173.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{174.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{175.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{176.0}=0x1
|
||||||
|
#Port17
|
||||||
|
#FC41
|
||||||
|
portmap_77=165:100
|
||||||
|
phy_chain_rx_lane_map_physical{165.0}=0x1230
|
||||||
|
phy_chain_tx_lane_map_physical{165.0}=0x2130
|
||||||
|
phy_chain_rx_polarity_flip_physical{165.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{166.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{167.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{168.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{165.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{166.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{167.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{168.0}=0x0
|
||||||
|
#Port18
|
||||||
|
#FC45
|
||||||
|
portmap_81=181:100
|
||||||
|
phy_chain_rx_lane_map_physical{181.0}=0x0312
|
||||||
|
phy_chain_tx_lane_map_physical{181.0}=0x3120
|
||||||
|
phy_chain_rx_polarity_flip_physical{181.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{182.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{183.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{184.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{181.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{182.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{183.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{184.0}=0x0
|
||||||
|
#Port19
|
||||||
|
#FC47
|
||||||
|
portmap_83=189:100
|
||||||
|
phy_chain_rx_lane_map_physical{189.0}=0x0132
|
||||||
|
phy_chain_tx_lane_map_physical{189.0}=0x3210
|
||||||
|
phy_chain_rx_polarity_flip_physical{189.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{190.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{191.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{192.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{189.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{190.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{191.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{192.0}=0x0
|
||||||
|
#Port20
|
||||||
|
#FC3
|
||||||
|
portmap_4=13:100
|
||||||
|
phy_chain_rx_lane_map_physical{13.0}=0x3120
|
||||||
|
phy_chain_tx_lane_map_physical{13.0}=0x3210
|
||||||
|
phy_chain_rx_polarity_flip_physical{13.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{14.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{15.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{16.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{13.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{14.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{15.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{16.0}=0x1
|
||||||
|
#Port21
|
||||||
|
#FC1
|
||||||
|
portmap_2=5:100
|
||||||
|
phy_chain_rx_lane_map_physical{5.0}=0x0213
|
||||||
|
phy_chain_tx_lane_map_physical{5.0}=0x0321
|
||||||
|
phy_chain_rx_polarity_flip_physical{5.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{6.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{7.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{8.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{5.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{6.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{7.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{8.0}=0x1
|
||||||
|
#Port22
|
||||||
|
#FC7
|
||||||
|
portmap_8=29:100
|
||||||
|
phy_chain_rx_lane_map_physical{29.0}=0x3021
|
||||||
|
phy_chain_tx_lane_map_physical{29.0}=0x2130
|
||||||
|
phy_chain_rx_polarity_flip_physical{29.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{30.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{31.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{32.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{29.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{30.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{31.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{32.0}=0x0
|
||||||
|
#Port23
|
||||||
|
#FC5
|
||||||
|
portmap_6=21:100
|
||||||
|
phy_chain_rx_lane_map_physical{21.0}=0x0321
|
||||||
|
phy_chain_tx_lane_map_physical{21.0}=0x0123
|
||||||
|
phy_chain_rx_polarity_flip_physical{21.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{22.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{23.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{24.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{21.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{22.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{23.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{24.0}=0x1
|
||||||
|
#Port24
|
||||||
|
#FC51
|
||||||
|
portmap_105=205:100
|
||||||
|
phy_chain_rx_lane_map_physical{205.0}=0x0132
|
||||||
|
phy_chain_tx_lane_map_physical{205.0}=0x1230
|
||||||
|
phy_chain_rx_polarity_flip_physical{205.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{206.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{207.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{208.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{205.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{206.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{207.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{208.0}=0x1
|
||||||
|
#Port25
|
||||||
|
#FC49
|
||||||
|
portmap_103=197:100
|
||||||
|
phy_chain_rx_lane_map_physical{197.0}=0x1230
|
||||||
|
phy_chain_tx_lane_map_physical{197.0}=0x3021
|
||||||
|
phy_chain_rx_polarity_flip_physical{197.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{198.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{199.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{200.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{197.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{198.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{199.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{200.0}=0x0
|
||||||
|
#Port26
|
||||||
|
#FC53
|
||||||
|
portmap_107=213:100
|
||||||
|
phy_chain_rx_lane_map_physical{213.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{213.0}=0x1230
|
||||||
|
phy_chain_rx_polarity_flip_physical{213.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{214.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{215.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{216.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{213.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{214.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{215.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{216.0}=0x1
|
||||||
|
#Port27
|
||||||
|
#FC55
|
||||||
|
portmap_109=221:100
|
||||||
|
phy_chain_rx_lane_map_physical{221.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{221.0}=0x3210
|
||||||
|
phy_chain_rx_polarity_flip_physical{221.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{222.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{223.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{224.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{221.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{222.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{223.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{224.0}=0x0
|
||||||
|
#Port28
|
||||||
|
#FC57
|
||||||
|
portmap_111=229:100
|
||||||
|
phy_chain_rx_lane_map_physical{229.0}=0x2301
|
||||||
|
phy_chain_tx_lane_map_physical{229.0}=0x3210
|
||||||
|
phy_chain_rx_polarity_flip_physical{229.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{230.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{231.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{232.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{229.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{230.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{231.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{232.0}=0x0
|
||||||
|
#Port29
|
||||||
|
#FC59
|
||||||
|
portmap_113=237:100
|
||||||
|
phy_chain_rx_lane_map_physical{237.0}=0x0123
|
||||||
|
phy_chain_tx_lane_map_physical{237.0}=0x3210
|
||||||
|
phy_chain_rx_polarity_flip_physical{237.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{238.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{239.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{240.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{237.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{238.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{239.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{240.0}=0x0
|
||||||
|
#Port30
|
||||||
|
#FC61
|
||||||
|
portmap_115=245:100
|
||||||
|
phy_chain_rx_lane_map_physical{245.0}=0x0213
|
||||||
|
phy_chain_tx_lane_map_physical{245.0}=0x3210
|
||||||
|
phy_chain_rx_polarity_flip_physical{245.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{246.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{247.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{248.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{245.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{246.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{247.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{248.0}=0x0
|
||||||
|
#Port31
|
||||||
|
#FC63
|
||||||
|
portmap_117=253:100
|
||||||
|
phy_chain_rx_lane_map_physical{253.0}=0x0213
|
||||||
|
phy_chain_tx_lane_map_physical{253.0}=0x0312
|
||||||
|
phy_chain_rx_polarity_flip_physical{253.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{254.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{255.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{256.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{253.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{254.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{255.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{256.0}=0x0
|
||||||
|
#Port32
|
||||||
|
#FC17
|
||||||
|
portmap_35=69:100
|
||||||
|
phy_chain_rx_lane_map_physical{69.0}=0x1032
|
||||||
|
phy_chain_tx_lane_map_physical{69.0}=0x3102
|
||||||
|
phy_chain_rx_polarity_flip_physical{69.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{70.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{71.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{72.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{69.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{70.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{71.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{72.0}=0x1
|
||||||
|
#Port33
|
||||||
|
#FC19
|
||||||
|
portmap_37=77:100
|
||||||
|
phy_chain_rx_lane_map_physical{77.0}=0x1230
|
||||||
|
phy_chain_tx_lane_map_physical{77.0}=0x3021
|
||||||
|
phy_chain_rx_polarity_flip_physical{77.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{78.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{79.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{80.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{77.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{78.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{79.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{80.0}=0x0
|
||||||
|
#Port34
|
||||||
|
#FC23
|
||||||
|
portmap_41=93:100
|
||||||
|
phy_chain_rx_lane_map_physical{93.0}=0x1032
|
||||||
|
phy_chain_tx_lane_map_physical{93.0}=0x0231
|
||||||
|
phy_chain_rx_polarity_flip_physical{93.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{94.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{95.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{96.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{93.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{94.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{95.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{96.0}=0x1
|
||||||
|
#Port35
|
||||||
|
#FC21
|
||||||
|
portmap_39=85:100
|
||||||
|
phy_chain_rx_lane_map_physical{85.0}=0x0312
|
||||||
|
phy_chain_tx_lane_map_physical{85.0}=0x1230
|
||||||
|
phy_chain_rx_polarity_flip_physical{85.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{86.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{87.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{88.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{85.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{86.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{87.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{88.0}=0x0
|
||||||
|
#Port36
|
||||||
|
#FC25
|
||||||
|
portmap_43=101:100
|
||||||
|
phy_chain_rx_lane_map_physical{101.0}=0x1302
|
||||||
|
phy_chain_tx_lane_map_physical{101.0}=0x0213
|
||||||
|
phy_chain_rx_polarity_flip_physical{101.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{102.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{103.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{104.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{101.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{102.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{103.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{104.0}=0x1
|
||||||
|
#Port37
|
||||||
|
#FC27
|
||||||
|
portmap_45=109:100
|
||||||
|
phy_chain_rx_lane_map_physical{109.0}=0x0213
|
||||||
|
phy_chain_tx_lane_map_physical{109.0}=0x1032
|
||||||
|
phy_chain_rx_polarity_flip_physical{109.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{110.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{111.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{112.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{109.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{110.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{111.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{112.0}=0x1
|
||||||
|
#Port38
|
||||||
|
#FC31
|
||||||
|
portmap_49=125:100
|
||||||
|
phy_chain_rx_lane_map_physical{125.0}=0x2130
|
||||||
|
phy_chain_tx_lane_map_physical{125.0}=0x1203
|
||||||
|
phy_chain_rx_polarity_flip_physical{125.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{126.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{127.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{128.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{125.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{126.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{127.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{128.0}=0x1
|
||||||
|
#Port39
|
||||||
|
#FC29
|
||||||
|
portmap_47=117:100
|
||||||
|
phy_chain_rx_lane_map_physical{117.0}=0x3102
|
||||||
|
phy_chain_tx_lane_map_physical{117.0}=0x2310
|
||||||
|
phy_chain_rx_polarity_flip_physical{117.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{118.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{119.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{120.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{117.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{118.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{119.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{120.0}=0x0
|
||||||
|
#Port40
|
||||||
|
#FC9
|
||||||
|
portmap_10=37:100
|
||||||
|
phy_chain_rx_lane_map_physical{37.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{37.0}=0x1302
|
||||||
|
phy_chain_rx_polarity_flip_physical{37.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{38.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{39.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{40.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{37.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{38.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{39.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{40.0}=0x1
|
||||||
|
#Port41
|
||||||
|
#FC11
|
||||||
|
portmap_12=45:100
|
||||||
|
phy_chain_rx_lane_map_physical{45.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{45.0}=0x0123
|
||||||
|
phy_chain_rx_polarity_flip_physical{45.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{46.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{47.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{48.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{45.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{46.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{47.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{48.0}=0x1
|
||||||
|
#Port42
|
||||||
|
#FC15
|
||||||
|
portmap_16=61:100
|
||||||
|
phy_chain_rx_lane_map_physical{61.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{61.0}=0x1230
|
||||||
|
phy_chain_rx_polarity_flip_physical{61.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{62.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{63.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{64.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{61.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{62.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{63.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{64.0}=0x0
|
||||||
|
#Port43
|
||||||
|
#FC13
|
||||||
|
portmap_14=53:100
|
||||||
|
phy_chain_rx_lane_map_physical{53.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{53.0}=0x3210
|
||||||
|
phy_chain_rx_polarity_flip_physical{53.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{54.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{55.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{56.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{53.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{54.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{55.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{56.0}=0x0
|
||||||
|
#Port44
|
||||||
|
#FC33
|
||||||
|
portmap_69=133:100
|
||||||
|
phy_chain_rx_lane_map_physical{133.0}=0x0312
|
||||||
|
phy_chain_tx_lane_map_physical{133.0}=0x2310
|
||||||
|
phy_chain_rx_polarity_flip_physical{133.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{134.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{135.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{136.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{133.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{134.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{135.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{136.0}=0x1
|
||||||
|
#Port45
|
||||||
|
#FC35
|
||||||
|
portmap_71=141:100
|
||||||
|
phy_chain_rx_lane_map_physical{141.0}=0x3012
|
||||||
|
phy_chain_tx_lane_map_physical{141.0}=0x0123
|
||||||
|
phy_chain_rx_polarity_flip_physical{141.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{142.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{143.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{144.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{141.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{142.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{143.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{144.0}=0x0
|
||||||
|
#Port46
|
||||||
|
#FC39
|
||||||
|
portmap_75=157:100
|
||||||
|
phy_chain_rx_lane_map_physical{157.0}=0x2103
|
||||||
|
phy_chain_tx_lane_map_physical{157.0}=0x0231
|
||||||
|
phy_chain_rx_polarity_flip_physical{157.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{158.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{159.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{160.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{157.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{158.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{159.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{160.0}=0x0
|
||||||
|
#Port47
|
||||||
|
#FC37
|
||||||
|
portmap_73=149:100
|
||||||
|
phy_chain_rx_lane_map_physical{149.0}=0x3120
|
||||||
|
phy_chain_tx_lane_map_physical{149.0}=0x1023
|
||||||
|
phy_chain_rx_polarity_flip_physical{149.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{150.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{151.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{152.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{149.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{150.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{151.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{152.0}=0x1
|
||||||
|
#Port48
|
||||||
|
#FC40
|
||||||
|
portmap_76=161:100
|
||||||
|
phy_chain_rx_lane_map_physical{161.0}=0x3012
|
||||||
|
phy_chain_tx_lane_map_physical{161.0}=0x1023
|
||||||
|
phy_chain_rx_polarity_flip_physical{161.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{162.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{163.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{164.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{161.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{162.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{163.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{164.0}=0x0
|
||||||
|
#Port49
|
||||||
|
#FC42
|
||||||
|
portmap_78=169:100
|
||||||
|
phy_chain_rx_lane_map_physical{169.0}=0x3210
|
||||||
|
phy_chain_tx_lane_map_physical{169.0}=0x2031
|
||||||
|
phy_chain_rx_polarity_flip_physical{169.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{170.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{171.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{172.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{169.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{170.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{171.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{172.0}=0x0
|
||||||
|
#Port50
|
||||||
|
#FC46
|
||||||
|
portmap_82=185:100
|
||||||
|
phy_chain_rx_lane_map_physical{185.0}=0x2310
|
||||||
|
phy_chain_tx_lane_map_physical{185.0}=0x3021
|
||||||
|
phy_chain_rx_polarity_flip_physical{185.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{186.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{187.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{188.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{185.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{186.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{187.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{188.0}=0x0
|
||||||
|
#Port51
|
||||||
|
#FC44
|
||||||
|
portmap_80=177:100
|
||||||
|
phy_chain_rx_lane_map_physical{177.0}=0x1032
|
||||||
|
phy_chain_tx_lane_map_physical{177.0}=0x2301
|
||||||
|
phy_chain_rx_polarity_flip_physical{177.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{178.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{179.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{180.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{177.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{178.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{179.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{180.0}=0x0
|
||||||
|
#Port52
|
||||||
|
#FC6
|
||||||
|
portmap_7=25:100
|
||||||
|
phy_chain_rx_lane_map_physical{25.0}=0x3102
|
||||||
|
phy_chain_tx_lane_map_physical{25.0}=0x0132
|
||||||
|
phy_chain_rx_polarity_flip_physical{25.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{26.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{27.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{28.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{25.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{26.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{27.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{28.0}=0x1
|
||||||
|
#Port53
|
||||||
|
#FC4
|
||||||
|
portmap_5=17:100
|
||||||
|
phy_chain_rx_lane_map_physical{17.0}=0x3120
|
||||||
|
phy_chain_tx_lane_map_physical{17.0}=0x3021
|
||||||
|
phy_chain_rx_polarity_flip_physical{17.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{18.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{19.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{20.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{17.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{18.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{19.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{20.0}=0x0
|
||||||
|
#Port54
|
||||||
|
#FC0
|
||||||
|
portmap_1=1:100
|
||||||
|
phy_chain_rx_lane_map_physical{1.0}=0x2130
|
||||||
|
phy_chain_tx_lane_map_physical{1.0}=0x1203
|
||||||
|
phy_chain_rx_polarity_flip_physical{1.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{2.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{3.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{4.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{1.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{2.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{3.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{4.0}=0x1
|
||||||
|
#Port55
|
||||||
|
#FC2
|
||||||
|
portmap_3=9:100
|
||||||
|
phy_chain_rx_lane_map_physical{9.0}=0x1203
|
||||||
|
phy_chain_tx_lane_map_physical{9.0}=0x1230
|
||||||
|
phy_chain_rx_polarity_flip_physical{9.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{10.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{11.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{12.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{9.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{10.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{11.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{12.0}=0x0
|
||||||
|
#Port56
|
||||||
|
#FC48
|
||||||
|
portmap_102=193:100
|
||||||
|
phy_chain_rx_lane_map_physical{193.0}=0x2103
|
||||||
|
phy_chain_tx_lane_map_physical{193.0}=0x1230
|
||||||
|
phy_chain_rx_polarity_flip_physical{193.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{194.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{195.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{196.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{193.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{194.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{195.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{196.0}=0x0
|
||||||
|
#Port57
|
||||||
|
#FC50
|
||||||
|
portmap_104=201:100
|
||||||
|
phy_chain_rx_lane_map_physical{201.0}=0x0321
|
||||||
|
phy_chain_tx_lane_map_physical{201.0}=0x3021
|
||||||
|
phy_chain_rx_polarity_flip_physical{201.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{202.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{203.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{204.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{201.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{202.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{203.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{204.0}=0x1
|
||||||
|
#Port58
|
||||||
|
#FC54
|
||||||
|
portmap_108=217:100
|
||||||
|
phy_chain_rx_lane_map_physical{217.0}=0x1203
|
||||||
|
phy_chain_tx_lane_map_physical{217.0}=0x2031
|
||||||
|
phy_chain_rx_polarity_flip_physical{217.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{218.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{219.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{220.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{217.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{218.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{219.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{220.0}=0x0
|
||||||
|
#Port59
|
||||||
|
#FC52
|
||||||
|
portmap_106=209:100
|
||||||
|
phy_chain_rx_lane_map_physical{209.0}=0x0321
|
||||||
|
phy_chain_tx_lane_map_physical{209.0}=0x3102
|
||||||
|
phy_chain_rx_polarity_flip_physical{209.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{210.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{211.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{212.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{209.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{210.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{211.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{212.0}=0x0
|
||||||
|
#Port60
|
||||||
|
#FC56
|
||||||
|
portmap_110=225:100
|
||||||
|
phy_chain_rx_lane_map_physical{225.0}=0x2103
|
||||||
|
phy_chain_tx_lane_map_physical{225.0}=0x2031
|
||||||
|
phy_chain_rx_polarity_flip_physical{225.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{226.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{227.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{228.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{225.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{226.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{227.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{228.0}=0x1
|
||||||
|
#Port61
|
||||||
|
#FC58
|
||||||
|
portmap_112=233:100
|
||||||
|
phy_chain_rx_lane_map_physical{233.0}=0x2130
|
||||||
|
phy_chain_tx_lane_map_physical{233.0}=0x0312
|
||||||
|
phy_chain_rx_polarity_flip_physical{233.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{234.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{235.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{236.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{233.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{234.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{235.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{236.0}=0x0
|
||||||
|
#Port62
|
||||||
|
#FC62
|
||||||
|
portmap_116=249:100
|
||||||
|
phy_chain_rx_lane_map_physical{249.0}=0x1302
|
||||||
|
phy_chain_tx_lane_map_physical{249.0}=0x1302
|
||||||
|
phy_chain_rx_polarity_flip_physical{249.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{250.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{251.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{252.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{249.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{250.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{251.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{252.0}=0x1
|
||||||
|
#Port63
|
||||||
|
#FC60
|
||||||
|
portmap_114=241:100
|
||||||
|
phy_chain_rx_lane_map_physical{241.0}=0x3012
|
||||||
|
phy_chain_tx_lane_map_physical{241.0}=0x2301
|
||||||
|
phy_chain_rx_polarity_flip_physical{241.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{242.0}=0x1
|
||||||
|
phy_chain_rx_polarity_flip_physical{243.0}=0x0
|
||||||
|
phy_chain_rx_polarity_flip_physical{244.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{241.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{242.0}=0x0
|
||||||
|
phy_chain_tx_polarity_flip_physical{243.0}=0x1
|
||||||
|
phy_chain_tx_polarity_flip_physical{244.0}=0x0
|
1
device/juniper/x86_64-juniper_qfx5210-r0/default_sku
Normal file
1
device/juniper/x86_64-juniper_qfx5210-r0/default_sku
Normal file
@ -0,0 +1 @@
|
|||||||
|
Juniper-QFX5210-64C t1
|
2
device/juniper/x86_64-juniper_qfx5210-r0/installer.conf
Normal file
2
device/juniper/x86_64-juniper_qfx5210-r0/installer.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
CONSOLE_SPEED=9600
|
||||||
|
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="tg3.short_preamble=1 tg3.bcm5718s_reset=1"
|
155
device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc
Executable file
155
device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc
Executable file
@ -0,0 +1,155 @@
|
|||||||
|
m CMIC_LEDUP0_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000
|
||||||
|
m CMIC_LEDUP1_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000
|
||||||
|
m CMIC_LEDUP2_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000
|
||||||
|
m CMIC_LEDUP3_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000
|
||||||
|
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=63 REMAP_PORT_1=62 REMAP_PORT_2=61 REMAP_PORT_3=60
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=59 REMAP_PORT_5=58 REMAP_PORT_6=57 REMAP_PORT_7=56
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=55 REMAP_PORT_9=54 REMAP_PORT_10=53 REMAP_PORT_11=52
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=51 REMAP_PORT_13=50 REMAP_PORT_14=49 REMAP_PORT_15=48
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 REMAP_PORT_17=46 REMAP_PORT_18=45 REMAP_PORT_19=44
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 REMAP_PORT_21=42 REMAP_PORT_22=41 REMAP_PORT_23=40
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 REMAP_PORT_25=38 REMAP_PORT_26=37 REMAP_PORT_27=36
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 REMAP_PORT_29=34 REMAP_PORT_30=33 REMAP_PORT_31=32
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=31 REMAP_PORT_33=30 REMAP_PORT_34=29 REMAP_PORT_35=28
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=27 REMAP_PORT_37=26 REMAP_PORT_38=25 REMAP_PORT_39=24
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=23 REMAP_PORT_41=22 REMAP_PORT_42=21 REMAP_PORT_43=20
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=19 REMAP_PORT_45=18 REMAP_PORT_46=17 REMAP_PORT_47=16
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 REMAP_PORT_49=14 REMAP_PORT_50=13 REMAP_PORT_51=12
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 REMAP_PORT_53=10 REMAP_PORT_54=9 REMAP_PORT_55=8
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 REMAP_PORT_57=6 REMAP_PORT_58=5 REMAP_PORT_59=4
|
||||||
|
m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 REMAP_PORT_61=2 REMAP_PORT_62=1 REMAP_PORT_63=0
|
||||||
|
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=3 REMAP_PORT_1=2 REMAP_PORT_2=1 REMAP_PORT_3=0
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=7 REMAP_PORT_5=6 REMAP_PORT_6=5 REMAP_PORT_7=4
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=11 REMAP_PORT_9=10 REMAP_PORT_10=9 REMAP_PORT_11=8
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=15 REMAP_PORT_13=14 REMAP_PORT_14=13 REMAP_PORT_15=12
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=19 REMAP_PORT_17=18 REMAP_PORT_18=17 REMAP_PORT_19=16
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=23 REMAP_PORT_21=22 REMAP_PORT_22=21 REMAP_PORT_23=20
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=27 REMAP_PORT_25=26 REMAP_PORT_26=25 REMAP_PORT_27=24
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=31 REMAP_PORT_29=30 REMAP_PORT_30=29 REMAP_PORT_31=28
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=35 REMAP_PORT_33=34 REMAP_PORT_34=33 REMAP_PORT_35=32
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=39 REMAP_PORT_37=38 REMAP_PORT_38=37 REMAP_PORT_39=36
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=43 REMAP_PORT_41=42 REMAP_PORT_42=41 REMAP_PORT_43=40
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=47 REMAP_PORT_45=46 REMAP_PORT_46=45 REMAP_PORT_47=44
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=51 REMAP_PORT_49=50 REMAP_PORT_50=49 REMAP_PORT_51=48
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=55 REMAP_PORT_53=54 REMAP_PORT_54=53 REMAP_PORT_55=52
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=59 REMAP_PORT_57=58 REMAP_PORT_58=57 REMAP_PORT_59=56
|
||||||
|
m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60
|
||||||
|
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=63 REMAP_PORT_1=62 REMAP_PORT_2=61 REMAP_PORT_3=60
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=59 REMAP_PORT_5=58 REMAP_PORT_6=57 REMAP_PORT_7=56
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=55 REMAP_PORT_9=54 REMAP_PORT_10=53 REMAP_PORT_11=52
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=51 REMAP_PORT_13=50 REMAP_PORT_14=49 REMAP_PORT_15=48
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 REMAP_PORT_17=46 REMAP_PORT_18=45 REMAP_PORT_19=44
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 REMAP_PORT_21=42 REMAP_PORT_22=41 REMAP_PORT_23=40
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 REMAP_PORT_25=38 REMAP_PORT_26=37 REMAP_PORT_27=36
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 REMAP_PORT_29=34 REMAP_PORT_30=33 REMAP_PORT_31=32
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=31 REMAP_PORT_33=30 REMAP_PORT_34=29 REMAP_PORT_35=28
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=27 REMAP_PORT_37=26 REMAP_PORT_38=25 REMAP_PORT_39=24
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=23 REMAP_PORT_41=22 REMAP_PORT_42=21 REMAP_PORT_43=20
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=19 REMAP_PORT_45=18 REMAP_PORT_46=17 REMAP_PORT_47=16
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 REMAP_PORT_49=14 REMAP_PORT_50=13 REMAP_PORT_51=12
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 REMAP_PORT_53=10 REMAP_PORT_54=9 REMAP_PORT_55=8
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 REMAP_PORT_57=6 REMAP_PORT_58=5 REMAP_PORT_59=4
|
||||||
|
m CMIC_LEDUP2_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 REMAP_PORT_61=2 REMAP_PORT_62=1 REMAP_PORT_63=0
|
||||||
|
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=3 REMAP_PORT_1=2 REMAP_PORT_2=1 REMAP_PORT_3=0
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=7 REMAP_PORT_5=6 REMAP_PORT_6=5 REMAP_PORT_7=4
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=11 REMAP_PORT_9=10 REMAP_PORT_10=9 REMAP_PORT_11=8
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=15 REMAP_PORT_13=14 REMAP_PORT_14=13 REMAP_PORT_15=12
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=19 REMAP_PORT_17=18 REMAP_PORT_18=17 REMAP_PORT_19=16
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=23 REMAP_PORT_21=22 REMAP_PORT_22=21 REMAP_PORT_23=20
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=27 REMAP_PORT_25=26 REMAP_PORT_26=25 REMAP_PORT_27=24
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=31 REMAP_PORT_29=30 REMAP_PORT_30=29 REMAP_PORT_31=28
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=35 REMAP_PORT_33=34 REMAP_PORT_34=33 REMAP_PORT_35=32
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=39 REMAP_PORT_37=38 REMAP_PORT_38=37 REMAP_PORT_39=36
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=43 REMAP_PORT_41=42 REMAP_PORT_42=41 REMAP_PORT_43=40
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=47 REMAP_PORT_45=46 REMAP_PORT_46=45 REMAP_PORT_47=44
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=51 REMAP_PORT_49=50 REMAP_PORT_50=49 REMAP_PORT_51=48
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=55 REMAP_PORT_53=54 REMAP_PORT_54=53 REMAP_PORT_55=52
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=59 REMAP_PORT_57=58 REMAP_PORT_58=57 REMAP_PORT_59=56
|
||||||
|
m CMIC_LEDUP3_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60
|
||||||
|
|
||||||
|
led 0 stop
|
||||||
|
led 0 prog \
|
||||||
|
02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \
|
||||||
|
02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \
|
||||||
|
67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \
|
||||||
|
86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \
|
||||||
|
3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \
|
||||||
|
98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \
|
||||||
|
4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \
|
||||||
|
F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \
|
||||||
|
71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \
|
||||||
|
52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \
|
||||||
|
74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \
|
||||||
|
98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \
|
||||||
|
88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \
|
||||||
|
88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \
|
||||||
|
84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
|
||||||
|
|
||||||
|
led 1 stop
|
||||||
|
led 1 prog \
|
||||||
|
02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \
|
||||||
|
02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \
|
||||||
|
67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \
|
||||||
|
86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \
|
||||||
|
3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \
|
||||||
|
98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \
|
||||||
|
4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \
|
||||||
|
F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \
|
||||||
|
71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \
|
||||||
|
52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \
|
||||||
|
74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \
|
||||||
|
98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \
|
||||||
|
88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \
|
||||||
|
88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \
|
||||||
|
84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
|
||||||
|
led 2 stop
|
||||||
|
led 2 prog \
|
||||||
|
02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \
|
||||||
|
02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \
|
||||||
|
67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \
|
||||||
|
86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \
|
||||||
|
3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \
|
||||||
|
98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \
|
||||||
|
4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \
|
||||||
|
F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \
|
||||||
|
71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \
|
||||||
|
52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \
|
||||||
|
74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \
|
||||||
|
98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \
|
||||||
|
88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \
|
||||||
|
88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \
|
||||||
|
84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
|
||||||
|
led 3 stop
|
||||||
|
led 3 prog \
|
||||||
|
02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \
|
||||||
|
02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \
|
||||||
|
67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \
|
||||||
|
86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \
|
||||||
|
3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \
|
||||||
|
98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \
|
||||||
|
4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \
|
||||||
|
F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \
|
||||||
|
71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \
|
||||||
|
52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \
|
||||||
|
74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \
|
||||||
|
98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \
|
||||||
|
88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \
|
||||||
|
88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \
|
||||||
|
84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
|
||||||
|
led auto on
|
||||||
|
led 0 start
|
||||||
|
led 1 start
|
||||||
|
led 2 start
|
||||||
|
led 3 start
|
2823
device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json
Normal file
2823
device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json
Normal file
File diff suppressed because it is too large
Load Diff
40
device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py
Normal file
40
device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
try:
|
||||||
|
import exceptions
|
||||||
|
import binascii
|
||||||
|
import time
|
||||||
|
import optparse
|
||||||
|
import warnings
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from sonic_eeprom import eeprom_base
|
||||||
|
from sonic_eeprom import eeprom_tlvinfo
|
||||||
|
import subprocess
|
||||||
|
import syslog
|
||||||
|
from struct import *
|
||||||
|
from array import *
|
||||||
|
|
||||||
|
except ImportError, e:
|
||||||
|
raise ImportError (str(e) + "- required module not found")
|
||||||
|
|
||||||
|
SYSLOG_IDENTIFIER = "eeprom.py"
|
||||||
|
EEPROM_PATH = "/sys/bus/i2c/devices/0-0056/eeprom"
|
||||||
|
|
||||||
|
def log_error(msg):
|
||||||
|
syslog.openlog(SYSLOG_IDENTIFIER)
|
||||||
|
syslog.syslog(syslog.LOG_ERR, msg)
|
||||||
|
syslog.closelog()
|
||||||
|
|
||||||
|
class board(eeprom_tlvinfo.TlvInfoDecoder):
|
||||||
|
_TLV_INFO_MAX_LEN = 256
|
||||||
|
|
||||||
|
def __init__(self, name, path, cpld_root, ro):
|
||||||
|
|
||||||
|
if not os.path.exists(EEPROM_PATH):
|
||||||
|
log_error("Cannot find system eeprom")
|
||||||
|
raise RuntimeError("No syseeprom found")
|
||||||
|
|
||||||
|
self.eeprom_path = EEPROM_PATH
|
||||||
|
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
||||||
|
|
61
device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py
Executable file
61
device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Accton
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC PSU Base API and
|
||||||
|
# provides the PSUs status which are available in the platform
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_psu.psu_base import PsuBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError (str(e) + "- required module not found")
|
||||||
|
|
||||||
|
class PsuUtil(PsuBase):
|
||||||
|
"""Platform-specific PSUutil class"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
PsuBase.__init__(self)
|
||||||
|
|
||||||
|
self.psu_path = "/sys/bus/i2c/devices/"
|
||||||
|
self.psu_presence = "/psu_present"
|
||||||
|
self.psu_oper_status = "/psu_power_good"
|
||||||
|
self.psu_mapping = {
|
||||||
|
1: "10-0053",
|
||||||
|
2: "9-0050",
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_num_psus(self):
|
||||||
|
return len(self.psu_mapping)
|
||||||
|
|
||||||
|
def get_psu_status(self, index):
|
||||||
|
if index is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
status = 0
|
||||||
|
node = self.psu_path + self.psu_mapping[index]+self.psu_oper_status
|
||||||
|
try:
|
||||||
|
with open(node, 'r') as power_status:
|
||||||
|
status = int(power_status.read())
|
||||||
|
except IOError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return status == 1
|
||||||
|
|
||||||
|
def get_psu_presence(self, index):
|
||||||
|
if index is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
status = 0
|
||||||
|
node = self.psu_path + self.psu_mapping[index] + self.psu_presence
|
||||||
|
try:
|
||||||
|
with open(node, 'r') as presence_status:
|
||||||
|
status = int(presence_status.read())
|
||||||
|
except IOError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return status == 1
|
761
device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py
Normal file
761
device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py
Normal file
@ -0,0 +1,761 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
try:
|
||||||
|
import time
|
||||||
|
from sonic_sfp.sfputilbase import *
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
from ctypes import create_string_buffer
|
||||||
|
# sys.path.append('/usr/local/bin')
|
||||||
|
# import sfp_detect
|
||||||
|
except ImportError, e:
|
||||||
|
raise ImportError (str(e) + "- required module not found")
|
||||||
|
|
||||||
|
|
||||||
|
qfx5210_qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)',
|
||||||
|
'Length OM2(m)', 'Length OM1(m)',
|
||||||
|
'Length Cable Assembly(m)')
|
||||||
|
|
||||||
|
qfx5210_sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
|
||||||
|
'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
|
||||||
|
'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)')
|
||||||
|
|
||||||
|
qfx5210_sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode',
|
||||||
|
'ESCONComplianceCodes', 'SONETComplianceCodes',
|
||||||
|
'EthernetComplianceCodes','FibreChannelLinkLength',
|
||||||
|
'FibreChannelTechnology', 'SFP+CableTechnology',
|
||||||
|
'FibreChannelTransmissionMedia','FibreChannelSpeed')
|
||||||
|
|
||||||
|
qfx5210_qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes',
|
||||||
|
'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes',
|
||||||
|
'Fibre Channel link length/Transmitter Technology',
|
||||||
|
'Fibre Channel transmission media', 'Fibre Channel Speed')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SfpUtil(SfpUtilBase):
|
||||||
|
"""Platform specific SfpUtill class"""
|
||||||
|
|
||||||
|
_port_start = 0
|
||||||
|
_port_end = 63
|
||||||
|
ports_in_block = 64
|
||||||
|
cmd = '/var/run/sfppresence'
|
||||||
|
_port_to_eeprom_mapping = {}
|
||||||
|
port_to_i2c_mapping = {
|
||||||
|
61 : 25,
|
||||||
|
62 : 26,
|
||||||
|
63 : 27,
|
||||||
|
64 : 28,
|
||||||
|
55 : 29,
|
||||||
|
56 : 30,
|
||||||
|
53 : 31,
|
||||||
|
54 : 32,
|
||||||
|
9 : 33,
|
||||||
|
10 : 34,
|
||||||
|
11 : 35,
|
||||||
|
12 : 36,
|
||||||
|
1 : 37,
|
||||||
|
2 : 38,
|
||||||
|
3 : 39,
|
||||||
|
4 : 40,
|
||||||
|
6 : 41,
|
||||||
|
5 : 42,
|
||||||
|
8 : 43,
|
||||||
|
7 : 44,
|
||||||
|
13 : 45,
|
||||||
|
14 : 46,
|
||||||
|
15 : 47,
|
||||||
|
16 : 48,
|
||||||
|
17 : 49,
|
||||||
|
18 : 50,
|
||||||
|
19 : 51,
|
||||||
|
20 : 52,
|
||||||
|
25 : 53,
|
||||||
|
26 : 54,
|
||||||
|
27 : 55,
|
||||||
|
28 : 56,
|
||||||
|
29 : 57,
|
||||||
|
30 : 58,
|
||||||
|
31 : 59,
|
||||||
|
32 : 60,
|
||||||
|
21 : 61,
|
||||||
|
22 : 62,
|
||||||
|
23 : 63,
|
||||||
|
24 : 64,
|
||||||
|
41 : 65,
|
||||||
|
42 : 66,
|
||||||
|
43 : 67,
|
||||||
|
44 : 68,
|
||||||
|
33 : 69,
|
||||||
|
34 : 70,
|
||||||
|
35 : 71,
|
||||||
|
36 : 72,
|
||||||
|
45 : 73,
|
||||||
|
46 : 74,
|
||||||
|
47 : 75,
|
||||||
|
48 : 76,
|
||||||
|
37 : 77,
|
||||||
|
38 : 78,
|
||||||
|
39 : 79,
|
||||||
|
40 : 80,
|
||||||
|
57 : 81,
|
||||||
|
58 : 82,
|
||||||
|
59 : 83,
|
||||||
|
60 : 84,
|
||||||
|
49 : 85,
|
||||||
|
50 : 86,
|
||||||
|
51 : 87,
|
||||||
|
52 : 88,}
|
||||||
|
|
||||||
|
port_to_sysfs_map = [
|
||||||
|
'/sys/bus/i2c/devices/37-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/38-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/39-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/40-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/42-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/41-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/44-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/43-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/33-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/34-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/35-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/36-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/45-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/46-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/47-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/48-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/49-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/50-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/51-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/52-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/61-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/62-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/63-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/64-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/53-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/54-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/55-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/56-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/57-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/58-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/59-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/60-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/69-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/70-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/71-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/72-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/77-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/78-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/79-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/80-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/65-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/66-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/67-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/68-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/73-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/74-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/75-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/76-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/85-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/86-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/87-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/88-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/31-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/32-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/29-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/30-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/81-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/82-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/83-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/84-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/25-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/26-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/27-0050/sfp_is_present',
|
||||||
|
'/sys/bus/i2c/devices/28-0050/sfp_is_present'
|
||||||
|
|
||||||
|
]
|
||||||
|
# sys.path.append('/usr/local/bin')
|
||||||
|
_qsfp_ports = range(0, ports_in_block + 1)
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom'
|
||||||
|
for x in range(0, self._port_end + 1):
|
||||||
|
port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x+1])
|
||||||
|
self._port_to_eeprom_mapping[x] = port_eeprom_path
|
||||||
|
SfpUtilBase.__init__(self)
|
||||||
|
|
||||||
|
def reset(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self._port_start or port_num > self._port_end:
|
||||||
|
return False
|
||||||
|
path = "/sys/bus/i2c/devices/19-0060/module_reset_{0}"
|
||||||
|
port_ps = path.format(port_num+1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
reg_file = open(port_ps, 'w')
|
||||||
|
except IOError as e:
|
||||||
|
print "Error: unable to open file: %s" % str(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
#HW will clear reset after set.
|
||||||
|
reg_file.seek(0)
|
||||||
|
reg_file.write('1')
|
||||||
|
reg_file.close()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_presence(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self._port_start or port_num > self._port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present"
|
||||||
|
port_ps = path.format(self.port_to_i2c_mapping[port_num+1])
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
reg_file = open(port_ps)
|
||||||
|
except IOError as e:
|
||||||
|
print "Error: unable to open file: %s" % str(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
reg_value = reg_file.readline().rstrip()
|
||||||
|
if reg_value == '1':
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_start(self):
|
||||||
|
return self._port_start
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_end(self):
|
||||||
|
return self._port_end
|
||||||
|
|
||||||
|
@property
|
||||||
|
def qsfp_ports(self):
|
||||||
|
return range(0, self.ports_in_block + 1)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_to_eeprom_mapping(self):
|
||||||
|
return self._port_to_eeprom_mapping
|
||||||
|
|
||||||
|
# Writing to a file from a list
|
||||||
|
def write_to_file(self, file_name, from_list):
|
||||||
|
try:
|
||||||
|
fp1 = open(file_name, 'w')
|
||||||
|
except IOError as e:
|
||||||
|
print "Error: unable to open file: %s" % str(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
for i in from_list:
|
||||||
|
fp1.write(i)
|
||||||
|
fp1.write('\n')
|
||||||
|
|
||||||
|
fp1.close()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# Reading from a file to a list
|
||||||
|
def read_from_file(self, file_name):
|
||||||
|
try:
|
||||||
|
fp = open(file_name, 'r')
|
||||||
|
except IOError as e:
|
||||||
|
print "Error: unable to open file: %s" % str(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
to_list = fp.readlines()
|
||||||
|
to_list = [x.rstrip() for x in to_list]
|
||||||
|
fp.close()
|
||||||
|
return to_list
|
||||||
|
|
||||||
|
def sfp_detect(self):
|
||||||
|
x = 0
|
||||||
|
ret_dict = {}
|
||||||
|
defl_dict = {}
|
||||||
|
current_sfp_values = [0] * 64
|
||||||
|
previous_sfp_values = [0] * 64
|
||||||
|
|
||||||
|
if not os.path.isfile(self.cmd):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if (self.read_from_file(self.cmd) == False):
|
||||||
|
return False, defl_dict
|
||||||
|
else:
|
||||||
|
previous_sfp_values = self.read_from_file(self.cmd)
|
||||||
|
|
||||||
|
# Read the current values from sysfs
|
||||||
|
for x in range(len(self.port_to_sysfs_map)):
|
||||||
|
try:
|
||||||
|
reg_file = open(self.port_to_sysfs_map[x], 'r')
|
||||||
|
except IOError as e:
|
||||||
|
print "Error: unable to open file: %s" % str(e)
|
||||||
|
return False, defl_dict
|
||||||
|
|
||||||
|
sfp_present = reg_file.readline().rstrip()
|
||||||
|
reg_file.close()
|
||||||
|
current_sfp_values[x] = sfp_present
|
||||||
|
if (current_sfp_values[x] != previous_sfp_values[x]):
|
||||||
|
ret_dict.update({x:current_sfp_values[x]})
|
||||||
|
|
||||||
|
if(self.write_to_file(self.cmd, current_sfp_values) == True):
|
||||||
|
return True, ret_dict
|
||||||
|
else:
|
||||||
|
return False, defl_dict
|
||||||
|
|
||||||
|
def get_transceiver_change_event(self):
|
||||||
|
time.sleep(3)
|
||||||
|
return self.sfp_detect()
|
||||||
|
|
||||||
|
def get_low_power_mode(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self._port_start or port_num > self._port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
eeprom = None
|
||||||
|
|
||||||
|
if not self.get_presence(port_num):
|
||||||
|
return False
|
||||||
|
|
||||||
|
eeprom = open(self.port_to_eeprom_mapping[port_num], "rb")
|
||||||
|
eeprom.seek(93)
|
||||||
|
lpmode = ord(eeprom.read(1))
|
||||||
|
|
||||||
|
if ((lpmode & 0x3) == 0x3):
|
||||||
|
return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1
|
||||||
|
else:
|
||||||
|
return False # High Power Mode if one of the following conditions is matched:
|
||||||
|
# 1. "Power override" bit is 0
|
||||||
|
# 2. "Power override" bit is 1 and "Power set" bit is 0
|
||||||
|
except IOError as e:
|
||||||
|
print "Error: unable to open file: %s" % str(e)
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
if eeprom is not None:
|
||||||
|
eeprom.close()
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
def set_low_power_mode(self, port_num, lpmode):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self._port_start or port_num > self._port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
eeprom = None
|
||||||
|
|
||||||
|
if not self.get_presence(port_num):
|
||||||
|
return False # Port is not present, unable to set the eeprom
|
||||||
|
|
||||||
|
# Fill in write buffer
|
||||||
|
regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode
|
||||||
|
buffer = create_string_buffer(1)
|
||||||
|
buffer[0] = chr(regval)
|
||||||
|
|
||||||
|
# Write to eeprom
|
||||||
|
eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b")
|
||||||
|
eeprom.seek(93)
|
||||||
|
eeprom.write(buffer[0])
|
||||||
|
return True
|
||||||
|
except IOError as e:
|
||||||
|
print "Error: unable to open file: %s" % str(e)
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
if eeprom is not None:
|
||||||
|
eeprom.close()
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
# Read out SFP type, vendor name, PN, REV, SN from eeprom.
|
||||||
|
def get_transceiver_info_dict(self, port_num):
|
||||||
|
transceiver_info_dict = {}
|
||||||
|
compliance_code_dict = {}
|
||||||
|
|
||||||
|
# ToDo: OSFP tranceiver info parsing not fully supported.
|
||||||
|
# in inf8628.py lack of some memory map definition
|
||||||
|
# will be implemented when the inf8628 memory map ready
|
||||||
|
if port_num in self.osfp_ports:
|
||||||
|
offset = 0
|
||||||
|
vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP
|
||||||
|
|
||||||
|
sfpi_obj = inf8628InterfaceId()
|
||||||
|
if sfpi_obj is None:
|
||||||
|
print("Error: sfp_object open failed")
|
||||||
|
return None
|
||||||
|
|
||||||
|
file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR)
|
||||||
|
if not self._sfp_eeprom_present(file_path, 0):
|
||||||
|
print("Error, file not exist %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
sysfsfile_eeprom = open(file_path, mode="rb", buffering=0)
|
||||||
|
except IOError:
|
||||||
|
print("Error: reading sysfs file %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_type_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH)
|
||||||
|
if sfp_type_raw is not None:
|
||||||
|
sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_name_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
|
||||||
|
if sfp_vendor_name_raw is not None:
|
||||||
|
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_pn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
|
||||||
|
if sfp_vendor_pn_raw is not None:
|
||||||
|
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_HW_REV_OFFSET), vendor_rev_width)
|
||||||
|
if sfp_vendor_rev_raw is not None:
|
||||||
|
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_sn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
|
||||||
|
if sfp_vendor_sn_raw is not None:
|
||||||
|
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
sysfsfile_eeprom.close()
|
||||||
|
except IOError:
|
||||||
|
print("Error: closing sysfs file %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_info_dict['type'] = sfp_type_data['data']['type']['value']
|
||||||
|
transceiver_info_dict['type_abbrv_name'] = sfp_type_data['data']['type_abbrv_name']['value']
|
||||||
|
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value']
|
||||||
|
transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
|
||||||
|
transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
|
||||||
|
transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
|
||||||
|
# Below part is added to avoid fail the xcvrd, shall be implemented later
|
||||||
|
transceiver_info_dict['vendor_oui'] = 'N/A'
|
||||||
|
transceiver_info_dict['vendor_date'] = 'N/A'
|
||||||
|
transceiver_info_dict['Connector'] = 'N/A'
|
||||||
|
transceiver_info_dict['encoding'] = 'N/A'
|
||||||
|
transceiver_info_dict['ext_identifier'] = 'N/A'
|
||||||
|
transceiver_info_dict['ext_rateselect_compliance'] = 'N/A'
|
||||||
|
transceiver_info_dict['cable_type'] = 'N/A'
|
||||||
|
transceiver_info_dict['cable_length'] = 'N/A'
|
||||||
|
transceiver_info_dict['specification_compliance'] = 'N/A'
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = 'N/A'
|
||||||
|
|
||||||
|
else:
|
||||||
|
if port_num in self.qsfp_ports:
|
||||||
|
offset = 128
|
||||||
|
vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP
|
||||||
|
cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP
|
||||||
|
interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP
|
||||||
|
sfp_type = 'QSFP'
|
||||||
|
|
||||||
|
sfpi_obj = sff8436InterfaceId()
|
||||||
|
if sfpi_obj is None:
|
||||||
|
print("Error: sfp_object open failed")
|
||||||
|
return None
|
||||||
|
|
||||||
|
else:
|
||||||
|
offset = 0
|
||||||
|
vendor_rev_width = XCVR_HW_REV_WIDTH_SFP
|
||||||
|
cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP
|
||||||
|
interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP
|
||||||
|
sfp_type = 'SFP'
|
||||||
|
|
||||||
|
sfpi_obj = sff8472InterfaceId()
|
||||||
|
if sfpi_obj is None:
|
||||||
|
print("Error: sfp_object open failed")
|
||||||
|
return None
|
||||||
|
|
||||||
|
file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR)
|
||||||
|
if not self._sfp_eeprom_present(file_path, 0):
|
||||||
|
print("Error, file not exist %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
sysfsfile_eeprom = open(file_path, mode="rb", buffering=0)
|
||||||
|
except IOError:
|
||||||
|
print("Error: reading sysfs file %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_interface_bulk_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width)
|
||||||
|
if sfp_interface_bulk_raw is not None:
|
||||||
|
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_name_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
|
||||||
|
if sfp_vendor_name_raw is not None:
|
||||||
|
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_pn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
|
||||||
|
if sfp_vendor_pn_raw is not None:
|
||||||
|
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_HW_REV_OFFSET), vendor_rev_width)
|
||||||
|
if sfp_vendor_rev_raw is not None:
|
||||||
|
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_sn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
|
||||||
|
if sfp_vendor_sn_raw is not None:
|
||||||
|
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_oui_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
|
||||||
|
if sfp_vendor_oui_raw is not None:
|
||||||
|
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfp_vendor_date_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
|
||||||
|
if sfp_vendor_date_raw is not None:
|
||||||
|
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
sysfsfile_eeprom.close()
|
||||||
|
except IOError:
|
||||||
|
print("Error: closing sysfs file %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
|
||||||
|
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
|
||||||
|
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value']
|
||||||
|
transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
|
||||||
|
transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
|
||||||
|
transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
|
||||||
|
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value']
|
||||||
|
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']
|
||||||
|
transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value']
|
||||||
|
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
|
||||||
|
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
|
||||||
|
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
|
||||||
|
if sfp_type == 'QSFP':
|
||||||
|
for key in qfx5210_qsfp_cable_length_tup:
|
||||||
|
if key in sfp_interface_bulk_data['data']:
|
||||||
|
transceiver_info_dict['cable_type'] = key
|
||||||
|
transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value'])
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
transceiver_info_dict['cable_type'] = key
|
||||||
|
transceiver_info_dict['cable_length'] = 'N/A'
|
||||||
|
|
||||||
|
for key in qfx5210_qsfp_compliance_code_tup:
|
||||||
|
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
|
||||||
|
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
|
||||||
|
transceiver_info_dict['specification_compliance'] = str(compliance_code_dict)
|
||||||
|
|
||||||
|
if sfp_interface_bulk_data['data'].has_key('Nominal Bit Rate(100Mbs)'):
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value'])
|
||||||
|
else:
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = 'N/A'
|
||||||
|
else:
|
||||||
|
for key in qfx5210_sfp_cable_length_tup:
|
||||||
|
if key in sfp_interface_bulk_data['data']:
|
||||||
|
transceiver_info_dict['cable_type'] = key
|
||||||
|
transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value'])
|
||||||
|
else:
|
||||||
|
transceiver_info_dict['cable_type'] = key
|
||||||
|
transceiver_info_dict['cable_length'] = 'N/A'
|
||||||
|
|
||||||
|
for key in qfx5210_sfp_compliance_code_tup:
|
||||||
|
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
|
||||||
|
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
|
||||||
|
transceiver_info_dict['specification_compliance'] = str(compliance_code_dict)
|
||||||
|
|
||||||
|
if sfp_interface_bulk_data['data'].has_key('NominalSignallingRate(UnitsOf100Mbd)'):
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
|
||||||
|
else:
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = 'N/A'
|
||||||
|
#transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
|
||||||
|
|
||||||
|
return transceiver_info_dict
|
||||||
|
|
||||||
|
def get_transceiver_dom_info_dict(self, port_num):
|
||||||
|
transceiver_dom_info_dict = {}
|
||||||
|
|
||||||
|
if port_num in self.osfp_ports:
|
||||||
|
# Below part is added to avoid fail xcvrd, shall be implemented later
|
||||||
|
transceiver_dom_info_dict['temperature'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['voltage'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['rx1power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['rx2power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['rx3power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['rx4power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx1bias'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx2bias'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx3bias'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx4bias'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx1power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx2power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx3power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx4power'] = 'N/A'
|
||||||
|
|
||||||
|
elif port_num in self.qsfp_ports:
|
||||||
|
offset = 0
|
||||||
|
offset_xcvr = 128
|
||||||
|
file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR)
|
||||||
|
if not self._sfp_eeprom_present(file_path, 0):
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
sysfsfile_eeprom = open(file_path, mode="rb", buffering=0)
|
||||||
|
except IOError:
|
||||||
|
print("Error: reading sysfs file %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfpd_obj = sff8436Dom()
|
||||||
|
if sfpd_obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfpi_obj = sff8436InterfaceId()
|
||||||
|
if sfpi_obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# QSFP capability byte parse, through this byte can know whether it support tx_power or not.
|
||||||
|
# TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
|
||||||
|
# need to add more code for determining the capability and version compliance
|
||||||
|
# in SFF-8636 dom capability definitions evolving with the versions.
|
||||||
|
qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH)
|
||||||
|
if qsfp_dom_capability_raw is not None:
|
||||||
|
qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH)
|
||||||
|
if dom_temperature_raw is not None:
|
||||||
|
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH)
|
||||||
|
if dom_voltage_raw is not None:
|
||||||
|
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH)
|
||||||
|
if qsfp_dom_rev_raw is not None:
|
||||||
|
qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
|
||||||
|
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
|
||||||
|
|
||||||
|
# The tx_power monitoring is only available on QSFP which compliant with SFF-8636
|
||||||
|
# and claimed that it support tx_power with one indicator bit.
|
||||||
|
dom_channel_monitor_data = {}
|
||||||
|
qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value']
|
||||||
|
qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value']
|
||||||
|
if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')):
|
||||||
|
dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_dom_info_dict['tx1power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx2power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx3power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx4power'] = 'N/A'
|
||||||
|
else:
|
||||||
|
dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value']
|
||||||
|
transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value']
|
||||||
|
transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value']
|
||||||
|
transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value']
|
||||||
|
|
||||||
|
try:
|
||||||
|
sysfsfile_eeprom.close()
|
||||||
|
except IOError:
|
||||||
|
print("Error: closing sysfs file %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
|
||||||
|
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
|
||||||
|
transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value']
|
||||||
|
transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value']
|
||||||
|
transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value']
|
||||||
|
transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value']
|
||||||
|
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value']
|
||||||
|
transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value']
|
||||||
|
transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value']
|
||||||
|
transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value']
|
||||||
|
|
||||||
|
else:
|
||||||
|
offset = 256
|
||||||
|
file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR)
|
||||||
|
if not self._sfp_eeprom_present(file_path, 0):
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
sysfsfile_eeprom = open(file_path, mode="rb", buffering=0)
|
||||||
|
except IOError:
|
||||||
|
print("Error: reading sysfs file %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
sfpd_obj = sff8472Dom()
|
||||||
|
if sfpd_obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
|
||||||
|
if dom_temperature_raw is not None:
|
||||||
|
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH)
|
||||||
|
if dom_voltage_raw is not None:
|
||||||
|
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
sysfsfile_eeprom.close()
|
||||||
|
except IOError:
|
||||||
|
print("Error: closing sysfs file %s" % file_path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
|
||||||
|
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
|
||||||
|
transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value']
|
||||||
|
transceiver_dom_info_dict['rx2power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['rx3power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['rx4power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value']
|
||||||
|
transceiver_dom_info_dict['tx2bias'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx3bias'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx4bias'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value']
|
||||||
|
transceiver_dom_info_dict['tx2power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx3power'] = 'N/A'
|
||||||
|
transceiver_dom_info_dict['tx4power'] = 'N/A'
|
||||||
|
|
||||||
|
return transceiver_dom_info_dict
|
@ -4,6 +4,7 @@ declare -r EXIT_SUCCESS="0"
|
|||||||
declare -r EXIT_ERROR="1"
|
declare -r EXIT_ERROR="1"
|
||||||
|
|
||||||
declare -r FW_UPGRADE_SCRIPT="/usr/bin/mlnx-fw-upgrade.sh"
|
declare -r FW_UPGRADE_SCRIPT="/usr/bin/mlnx-fw-upgrade.sh"
|
||||||
|
declare -r SYSFS_PWR_CYCLE="/sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/pwr_cycle"
|
||||||
|
|
||||||
FORCE_REBOOT="no"
|
FORCE_REBOOT="no"
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ function ParseArguments() {
|
|||||||
|
|
||||||
ParseArguments "$@"
|
ParseArguments "$@"
|
||||||
|
|
||||||
${FW_UPGRADE_SCRIPT} --upgrade
|
${FW_UPGRADE_SCRIPT} --upgrade --verbose
|
||||||
EXIT_CODE="$?"
|
EXIT_CODE="$?"
|
||||||
if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then
|
if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then
|
||||||
echo "Failed to burn MLNX FW: errno=${EXIT_CODE}"
|
echo "Failed to burn MLNX FW: errno=${EXIT_CODE}"
|
||||||
@ -31,4 +32,7 @@ if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec /sbin/reboot $@
|
# perform "hardware" reboot
|
||||||
|
echo 1 > $SYSFS_PWR_CYCLE
|
||||||
|
sleep 3
|
||||||
|
echo 0 > $SYSFS_PWR_CYCLE
|
||||||
|
@ -1 +0,0 @@
|
|||||||
../x86_64-mlnx_msn2700-r0/platform_reboot
|
|
21
device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_reboot
Executable file
21
device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_reboot
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
declare -r EXIT_SUCCESS="0"
|
||||||
|
declare -r EXIT_ERROR="1"
|
||||||
|
|
||||||
|
FORCE_REBOOT="no"
|
||||||
|
|
||||||
|
function ParseArguments() {
|
||||||
|
while [ $# -ge 1 ]; do
|
||||||
|
case "$1" in
|
||||||
|
-f|--force)
|
||||||
|
FORCE_REBOOT="yes"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseArguments "$@"
|
||||||
|
|
||||||
|
exec /sbin/reboot $@
|
@ -1 +0,0 @@
|
|||||||
../x86_64-mlnx_msn2700-r0/platform_wait
|
|
@ -1 +1 @@
|
|||||||
../x86_64-mlnx_msn3700-r0/platform_reboot
|
../x86_64-mlnx_msn2700_simx-r0/platform_reboot
|
@ -1 +0,0 @@
|
|||||||
../x86_64-mlnx_msn3700-r0/platform_wait
|
|
@ -23,13 +23,13 @@
|
|||||||
"p4_pipelines": [
|
"p4_pipelines": [
|
||||||
{
|
{
|
||||||
"p4_pipeline_name": "pipe",
|
"p4_pipeline_name": "pipe",
|
||||||
"config": "share/tofinopd/switch/pipe/tofino.bin",
|
"config": "share/switch/pipe/tofino.bin",
|
||||||
"context": "share/tofinopd/switch/pipe/context.json"
|
"context": "share/switch/pipe/context.json"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"program-name": "switch",
|
"program-name": "switch",
|
||||||
"switchsai": "lib/libswitchsai.so",
|
"switchsai": "lib/libswitchsai.so",
|
||||||
"bfrt-config": "share/tofinopd/switch/bf-rt.json",
|
"bfrt-config": "share/switch/bf-rt.json",
|
||||||
"model_json_path" : "share/switch/aug_model.json",
|
"model_json_path" : "share/switch/aug_model.json",
|
||||||
"switchapi_port_add": false,
|
"switchapi_port_add": false,
|
||||||
"non_default_port_ppgs": 5
|
"non_default_port_ppgs": 5
|
||||||
|
@ -32,6 +32,9 @@ RUN apt-get clean -y && \
|
|||||||
s/^client-output-buffer-limit pubsub [0-9]+mb [0-9]+mb [0-9]+/client-output-buffer-limit pubsub 0 0 0/ \
|
s/^client-output-buffer-limit pubsub [0-9]+mb [0-9]+mb [0-9]+/client-output-buffer-limit pubsub 0 0 0/ \
|
||||||
' /etc/redis/redis.conf
|
' /etc/redis/redis.conf
|
||||||
|
|
||||||
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
|
COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"]
|
||||||
|
COPY ["docker-database-init.sh", "/usr/local/bin/"]
|
||||||
|
COPY ["ping_pong_db_insts", "/usr/local/bin/"]
|
||||||
|
COPY ["database_config.json", "/etc/default/sonic-db/"]
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/bin/supervisord"]
|
ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"]
|
||||||
|
43
dockers/docker-database/database_config.json
Normal file
43
dockers/docker-database/database_config.json
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"INSTANCES": {
|
||||||
|
"redis":{
|
||||||
|
"port": 6379,
|
||||||
|
"socket": "/var/run/redis/redis.sock"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"DATABASES" : {
|
||||||
|
"APPL_DB" : {
|
||||||
|
"id" : 0,
|
||||||
|
"instance" : "redis"
|
||||||
|
},
|
||||||
|
"ASIC_DB" : {
|
||||||
|
"id" : 1,
|
||||||
|
"instance" : "redis"
|
||||||
|
},
|
||||||
|
"COUNTERS_DB" : {
|
||||||
|
"id" : 2,
|
||||||
|
"instance" : "redis"
|
||||||
|
},
|
||||||
|
"LOGLEVEL_DB" : {
|
||||||
|
"id" : 3,
|
||||||
|
"instance" : "redis"
|
||||||
|
},
|
||||||
|
"CONFIG_DB" : {
|
||||||
|
"id" : 4,
|
||||||
|
"instance" : "redis"
|
||||||
|
},
|
||||||
|
"PFC_WD_DB" : {
|
||||||
|
"id" : 5,
|
||||||
|
"instance" : "redis"
|
||||||
|
},
|
||||||
|
"FLEX_COUNTER_DB" : {
|
||||||
|
"id" : 5,
|
||||||
|
"instance" : "redis"
|
||||||
|
},
|
||||||
|
"STATE_DB" : {
|
||||||
|
"id" : 6,
|
||||||
|
"instance" : "redis"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"VERSION" : "1.0"
|
||||||
|
}
|
14
dockers/docker-database/docker-database-init.sh
Executable file
14
dockers/docker-database/docker-database-init.sh
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
mkdir -p /var/run/redis/sonic-db
|
||||||
|
if [ -f /etc/sonic/database_config.json ]; then
|
||||||
|
cp /etc/sonic/database_config.json /var/run/redis/sonic-db
|
||||||
|
else
|
||||||
|
cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p /etc/supervisor/conf.d/
|
||||||
|
# generate all redis server supervisord configuration file
|
||||||
|
sonic-cfggen -j /var/run/redis/sonic-db/database_config.json -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf
|
||||||
|
|
||||||
|
exec /usr/bin/supervisord
|
40
dockers/docker-database/ping_pong_db_insts
Executable file
40
dockers/docker-database/ping_pong_db_insts
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
import syslog
|
||||||
|
|
||||||
|
def ping_redis(cmd):
|
||||||
|
output = ''
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(cmd, shell=True)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
syslog.syslog(syslog.LOG_ERR, 'ping redis failed, cmd : {}'.format(cmd))
|
||||||
|
|
||||||
|
if 'PONG' in output:
|
||||||
|
break
|
||||||
|
syslog.syslog(syslog.LOG_ERR, 'ping response : {}'.format(output))
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
database_config_file = "/var/run/redis/sonic-db/database_config.json"
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
while True:
|
||||||
|
if os.path.isfile(database_config_file):
|
||||||
|
with open(database_config_file, "r") as read_file:
|
||||||
|
data = json.load(read_file)
|
||||||
|
break
|
||||||
|
time.sleep(1)
|
||||||
|
syslog.syslog(syslog.LOG_ERR, 'config file {} does not exist right now'.format(database_config_file))
|
||||||
|
|
||||||
|
while True:
|
||||||
|
if 'INSTANCES' in data:
|
||||||
|
for inst in data["INSTANCES"]:
|
||||||
|
port = data["INSTANCES"][inst]["port"]
|
||||||
|
cmd = "redis-cli -p " + str(port) + " ping"
|
||||||
|
ping_redis(cmd)
|
||||||
|
break
|
||||||
|
time.sleep(1)
|
||||||
|
syslog.syslog(syslog.LOG_ERR, 'config file {} does not have INSTANCES'.format(database_config_file))
|
@ -1,21 +0,0 @@
|
|||||||
[supervisord]
|
|
||||||
logfile_maxbytes=1MB
|
|
||||||
logfile_backups=2
|
|
||||||
nodaemon=true
|
|
||||||
|
|
||||||
[program:rsyslogd]
|
|
||||||
command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n"
|
|
||||||
priority=1
|
|
||||||
autostart=true
|
|
||||||
autorestart=false
|
|
||||||
stdout_logfile=syslog
|
|
||||||
stderr_logfile=syslog
|
|
||||||
|
|
||||||
[program:redis-server]
|
|
||||||
command=/bin/bash -c "{ [[ -s /var/lib/redis/dump.rdb ]] || rm -f /var/lib/redis/dump.rdb; } && exec /usr/bin/redis-server /etc/redis/redis.conf"
|
|
||||||
priority=2
|
|
||||||
autostart=true
|
|
||||||
autorestart=false
|
|
||||||
stdout_logfile=syslog
|
|
||||||
stderr_logfile=syslog
|
|
||||||
|
|
24
dockers/docker-database/supervisord.conf.j2
Normal file
24
dockers/docker-database/supervisord.conf.j2
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[supervisord]
|
||||||
|
logfile_maxbytes=1MB
|
||||||
|
logfile_backups=2
|
||||||
|
nodaemon=true
|
||||||
|
|
||||||
|
[program:rsyslogd]
|
||||||
|
command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n"
|
||||||
|
priority=1
|
||||||
|
autostart=true
|
||||||
|
autorestart=false
|
||||||
|
stdout_logfile=syslog
|
||||||
|
stderr_logfile=syslog
|
||||||
|
|
||||||
|
{% if INSTANCES %}
|
||||||
|
{% for redis_inst, redis_items in INSTANCES.iteritems() %}
|
||||||
|
[program: {{ redis_inst }}]
|
||||||
|
command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --port {{ redis_items['port'] }} --unixsocket {{ redis_items['socket'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}"
|
||||||
|
priority=2
|
||||||
|
autostart=true
|
||||||
|
autorestart=false
|
||||||
|
stdout_logfile=syslog
|
||||||
|
stderr_logfile=syslog
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
@ -43,8 +43,16 @@ isc-dhcp-relay-{{ vlan_name }}
|
|||||||
|
|
||||||
|
|
||||||
{# Create a program entry for each DHCP relay agent instance #}
|
{# Create a program entry for each DHCP relay agent instance #}
|
||||||
|
{% set relay_for_ipv4 = { 'flag': False } %}
|
||||||
{% for vlan_name in VLAN %}
|
{% for vlan_name in VLAN %}
|
||||||
{% if VLAN[vlan_name]['dhcp_servers'] %}
|
{% if VLAN[vlan_name]['dhcp_servers'] %}
|
||||||
|
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
|
||||||
|
{% if dhcp_server | ipv4 %}
|
||||||
|
{% set _dummy = relay_for_ipv4.update({'flag': True}) %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if relay_for_ipv4.flag %}
|
||||||
|
{% set _dummy = relay_for_ipv4.update({'flag': False}) %}
|
||||||
[program:isc-dhcp-relay-{{ vlan_name }}]
|
[program:isc-dhcp-relay-{{ vlan_name }}]
|
||||||
{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
|
{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
|
||||||
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id {{ vlan_name }}
|
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id {{ vlan_name }}
|
||||||
@ -58,7 +66,9 @@ command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /t
|
|||||||
{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
|
{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
|
||||||
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
|
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} {{ dhcp_server }}{% endfor %}
|
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
|
||||||
|
{%- if dhcp_server | ipv4 %} {{ dhcp_server }}{% endif -%}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
priority=3
|
priority=3
|
||||||
autostart=false
|
autostart=false
|
||||||
@ -66,6 +76,7 @@ autorestart=false
|
|||||||
stdout_logfile=syslog
|
stdout_logfile=syslog
|
||||||
stderr_logfile=syslog
|
stderr_logfile=syslog
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -1,65 +1,124 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import copy
|
||||||
|
import Queue
|
||||||
import redis
|
import redis
|
||||||
import subprocess
|
import subprocess
|
||||||
import syslog
|
import syslog
|
||||||
from swsssdk import ConfigDBConnector
|
import os
|
||||||
|
from swsscommon import swsscommon
|
||||||
|
|
||||||
class BGPConfigDaemon:
|
|
||||||
|
def run_command(command):
|
||||||
|
syslog.syslog(syslog.LOG_DEBUG, "execute command {}.".format(command))
|
||||||
|
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
|
||||||
|
stdout = p.communicate()[0]
|
||||||
|
p.wait()
|
||||||
|
if p.returncode != 0:
|
||||||
|
syslog.syslog(syslog.LOG_ERR, 'command execution returned {}. Command: "{}", stdout: "{}"'.format(p.returncode, command, stdout))
|
||||||
|
|
||||||
|
|
||||||
|
class BGPConfigManager(object):
|
||||||
|
def __init__(self, daemon):
|
||||||
|
self.daemon = daemon
|
||||||
|
self.bgp_asn = None
|
||||||
|
self.bgp_message = Queue.Queue(0)
|
||||||
|
daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, self.__metadata_handler)
|
||||||
|
daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, self.__bgp_handler)
|
||||||
|
|
||||||
|
def __metadata_handler(self, key, op, data):
|
||||||
|
if key != "localhost" \
|
||||||
|
or "bgp_asn" not in data \
|
||||||
|
or self.bgp_asn == data["bgp_asn"]:
|
||||||
|
return
|
||||||
|
|
||||||
|
# TODO add ASN update commands
|
||||||
|
|
||||||
|
self.bgp_asn = data["bgp_asn"]
|
||||||
|
self.__update_bgp()
|
||||||
|
|
||||||
|
def __update_bgp(self):
|
||||||
|
while not self.bgp_message.empty():
|
||||||
|
key, op, data = self.bgp_message.get()
|
||||||
|
syslog.syslog(syslog.LOG_INFO, 'value for {} changed to {}'.format(key, data))
|
||||||
|
if op == swsscommon.SET_COMMAND:
|
||||||
|
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} remote-as {}'".format(self.bgp_asn, key, data['asn'])
|
||||||
|
run_command(command)
|
||||||
|
if "name" in data:
|
||||||
|
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} description {}'".format(self.bgp_asn, key, data['name'])
|
||||||
|
run_command(command)
|
||||||
|
if "admin_status" in data:
|
||||||
|
command_mod = "no " if data["admin_status"] == "up" else ""
|
||||||
|
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(self.bgp_asn, command_mod, key)
|
||||||
|
run_command(command)
|
||||||
|
elif op == swsscommon.DEL_COMMAND:
|
||||||
|
# Neighbor is deleted
|
||||||
|
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'no neighbor {}'".format(self.bgp_asn, key)
|
||||||
|
run_command(command)
|
||||||
|
|
||||||
|
def __bgp_handler(self, key, op, data):
|
||||||
|
self.bgp_message.put((key, op, data))
|
||||||
|
# If ASN is not set, we just cache this message until the ASN is set.
|
||||||
|
if self.bgp_asn == None:
|
||||||
|
return
|
||||||
|
self.__update_bgp()
|
||||||
|
|
||||||
|
|
||||||
|
class Daemon(object):
|
||||||
|
|
||||||
|
SELECT_TIMEOUT = 1000
|
||||||
|
SUPPORT_DATABASE_LIST = (swsscommon.APPL_DB, swsscommon.CONFIG_DB)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.config_db = ConfigDBConnector()
|
self.appl_db = swsscommon.DBConnector(swsscommon.APPL_DB, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0)
|
||||||
self.config_db.connect()
|
self.conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0)
|
||||||
self.bgp_asn = self.config_db.get_entry('DEVICE_METADATA', 'localhost')['bgp_asn']
|
self.selector = swsscommon.Select()
|
||||||
self.bgp_neighbor = self.config_db.get_table('BGP_NEIGHBOR')
|
self.db_connectors = {}
|
||||||
|
self.callbacks = {}
|
||||||
|
self.subscribers = set()
|
||||||
|
|
||||||
def __run_command(self, command):
|
def get_db_connector(self, db):
|
||||||
# print command
|
if db not in Daemon.SUPPORT_DATABASE_LIST:
|
||||||
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
|
raise ValueError("database {} not Daemon support list {}.".format(db, SUPPORT_DATABASE_LIST))
|
||||||
stdout = p.communicate()[0]
|
# if this database connector has been initialized
|
||||||
p.wait()
|
if db not in self.db_connectors:
|
||||||
if p.returncode != 0:
|
self.db_connectors[db] = swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0)
|
||||||
syslog.syslog(syslog.LOG_ERR, '[bgp cfgd] command execution returned {}. Command: "{}", stdout: "{}"'.format(p.returncode, command, stdout))
|
return self.db_connectors[db]
|
||||||
|
|
||||||
def metadata_handler(self, key, data):
|
def add_manager(self, db, table_name, callback):
|
||||||
if key == 'localhost' and data.has_key('bgp_asn'):
|
if db not in self.callbacks:
|
||||||
if data['bgp_asn'] != self.bgp_asn:
|
self.callbacks[db] = {}
|
||||||
syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] ASN changed to {} from {}, restart BGP...'.format(data['bgp_asn'], self.bgp_asn))
|
if table_name not in self.callbacks[db]:
|
||||||
self.__run_command("supervisorctl restart start.sh")
|
self.callbacks[db][table_name] = []
|
||||||
self.__run_command("service quagga restart")
|
conn = self.get_db_connector(db)
|
||||||
self.bgp_asn = data['bgp_asn']
|
subscriber = swsscommon.SubscriberStateTable(conn, table_name)
|
||||||
|
self.subscribers.add(subscriber)
|
||||||
def bgp_handler(self, key, data):
|
self.selector.addSelectable(subscriber)
|
||||||
syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] value for {} changed to {}'.format(key, data))
|
self.callbacks[db][table_name].append(callback)
|
||||||
if not data:
|
|
||||||
# Neighbor is deleted
|
|
||||||
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'no neighbor {}'".format(self.bgp_asn, key)
|
|
||||||
self.__run_command(command)
|
|
||||||
self.bgp_neighbor.pop(key)
|
|
||||||
else:
|
|
||||||
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} remote-as {}'".format(self.bgp_asn, key, data['asn'])
|
|
||||||
self.__run_command(command)
|
|
||||||
if data.has_key('name'):
|
|
||||||
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} description {}'".format(self.bgp_asn, key, data['name'])
|
|
||||||
self.__run_command(command)
|
|
||||||
if data.has_key('admin_status'):
|
|
||||||
command_mod = 'no ' if data['admin_status'] == 'up' else ''
|
|
||||||
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(self.bgp_asn, command_mod, key)
|
|
||||||
self.__run_command(command)
|
|
||||||
self.bgp_neighbor[key] = data
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.config_db.subscribe('BGP_NEIGHBOR',
|
while True:
|
||||||
lambda table, key, data: self.bgp_handler(key, data))
|
state, selectable = self.selector.select(Daemon.SELECT_TIMEOUT)
|
||||||
self.config_db.subscribe('DEVICE_METADATA',
|
if not selectable:
|
||||||
lambda table, key, data: self.metadata_handler(key, data))
|
continue
|
||||||
self.config_db.listen()
|
for subscriber in self.subscribers:
|
||||||
|
key, op, fvs = subscriber.pop()
|
||||||
|
# if no new message
|
||||||
|
if not key:
|
||||||
|
continue
|
||||||
|
data = dict(fvs)
|
||||||
|
syslog.syslog(syslog.LOG_DEBUG, "Receive message : {}".format((key, op, fvs)))
|
||||||
|
for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]:
|
||||||
|
callback(key, op, data)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
daemon = BGPConfigDaemon()
|
syslog.openlog("bgpcfgd")
|
||||||
|
daemon = Daemon()
|
||||||
|
bgp_manager = BGPConfigManager(daemon)
|
||||||
daemon.start()
|
daemon.start()
|
||||||
|
syslog.closelog()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
{% set hash_seed = 0 %}
|
{% set hash_seed = 0 %}
|
||||||
{% elif DEVICE_METADATA.localhost.type == "LeafRouter" %}
|
{% elif DEVICE_METADATA.localhost.type == "LeafRouter" %}
|
||||||
{% set hash_seed = 10 %}
|
{% set hash_seed = 10 %}
|
||||||
|
{% elif DEVICE_METADATA.localhost.type == "SpineRouter" %}
|
||||||
|
{% set hash_seed = 15 %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
[
|
[
|
||||||
|
67
files/build_scripts/generate_asic_config_checksum.py
Normal file
67
files/build_scripts/generate_asic_config_checksum.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import syslog
|
||||||
|
import os
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
SYSLOG_IDENTIFIER = 'asic_config_checksum'
|
||||||
|
|
||||||
|
CHUNK_SIZE = 8192
|
||||||
|
|
||||||
|
CONFIG_FILES = {
|
||||||
|
os.path.abspath('./src/sonic-swss/swssconfig/sample/'): ['netbouncer.json', '00-copp.config.json']
|
||||||
|
}
|
||||||
|
|
||||||
|
OUTPUT_FILE = os.path.abspath('./asic_config_checksum')
|
||||||
|
|
||||||
|
def log_info(msg):
|
||||||
|
syslog.openlog(SYSLOG_IDENTIFIER)
|
||||||
|
syslog.syslog(syslog.LOG_INFO, msg)
|
||||||
|
syslog.closelog()
|
||||||
|
|
||||||
|
def log_error(msg):
|
||||||
|
syslog.openlog(SYSLOG_IDENTIFIER)
|
||||||
|
syslog.syslog(syslog.LOG_ERR, msg)
|
||||||
|
syslog.closelog()
|
||||||
|
|
||||||
|
def get_config_files(config_file_map):
|
||||||
|
'''
|
||||||
|
Generates a list of absolute paths to ASIC config files.
|
||||||
|
'''
|
||||||
|
config_files = []
|
||||||
|
for path, files in config_file_map.items():
|
||||||
|
for config_file in files:
|
||||||
|
config_files.append(os.path.join(path, config_file))
|
||||||
|
return config_files
|
||||||
|
|
||||||
|
def generate_checksum(checksum_files):
|
||||||
|
'''
|
||||||
|
Generates a checksum for a given list of files. Returns None if an error
|
||||||
|
occurs while reading the files.
|
||||||
|
|
||||||
|
NOTE: The checksum is performed in the order provided. This function does
|
||||||
|
NOT do any re-ordering of the files before creating the checksum.
|
||||||
|
'''
|
||||||
|
checksum = hashlib.sha1()
|
||||||
|
for checksum_file in checksum_files:
|
||||||
|
try:
|
||||||
|
with open(checksum_file, 'r') as f:
|
||||||
|
for chunk in iter(lambda: f.read(CHUNK_SIZE), b""):
|
||||||
|
checksum.update(chunk)
|
||||||
|
except IOError as e:
|
||||||
|
log_error('Error processing ASIC config file ' + checksum_file + ':' + e.strerror)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return checksum.hexdigest()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
config_files = sorted(get_config_files(CONFIG_FILES))
|
||||||
|
checksum = generate_checksum(config_files)
|
||||||
|
if checksum == None:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
with open(OUTPUT_FILE, 'w') as output:
|
||||||
|
output.write(checksum + '\n')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -2,6 +2,7 @@
|
|||||||
Description=Database container
|
Description=Database container
|
||||||
Requires=docker.service
|
Requires=docker.service
|
||||||
After=docker.service
|
After=docker.service
|
||||||
|
After=rc-local.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
User=root
|
User=root
|
||||||
|
@ -71,10 +71,7 @@ function postStartAction()
|
|||||||
{
|
{
|
||||||
{%- if docker_container_name == "database" %}
|
{%- if docker_container_name == "database" %}
|
||||||
# Wait until redis starts
|
# Wait until redis starts
|
||||||
REDIS_SOCK="/var/run/redis/redis.sock"
|
/usr/bin/docker exec database ping_pong_db_insts
|
||||||
until [[ $(/usr/bin/docker exec database redis-cli -s $REDIS_SOCK ping | grep -c PONG) -gt 0 ]]; do
|
|
||||||
sleep 1;
|
|
||||||
done
|
|
||||||
if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then
|
if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then
|
||||||
rm -f $WARM_DIR/dump.rdb
|
rm -f $WARM_DIR/dump.rdb
|
||||||
else
|
else
|
||||||
@ -163,6 +160,11 @@ start() {
|
|||||||
|
|
||||||
{%- if docker_container_name == "database" %}
|
{%- if docker_container_name == "database" %}
|
||||||
echo "Creating new {{docker_container_name}} container"
|
echo "Creating new {{docker_container_name}} container"
|
||||||
|
# if database_config exists in old_config, use it; otherwise use the default one in new image
|
||||||
|
if [ -f /etc/sonic/old_config/database_config.json ]; then
|
||||||
|
echo "Use database_config.json from old system..."
|
||||||
|
mv /etc/sonic/old_config/database_config.json /etc/sonic/
|
||||||
|
fi
|
||||||
{%- else %}
|
{%- else %}
|
||||||
echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU"
|
echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU"
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%}
|
{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%}
|
||||||
|
{%- set backend_device_types = ['BackEndToRRouter', 'BackEndLeafRouter'] -%}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -72,6 +73,20 @@
|
|||||||
"7": "7"
|
"7": "7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{% if DEVICE_METADATA['localhost']['type'] in backend_device_types %}
|
||||||
|
"DOT1P_TO_TC_MAP": {
|
||||||
|
"AZURE": {
|
||||||
|
"0": "0",
|
||||||
|
"1": "1",
|
||||||
|
"2": "2",
|
||||||
|
"3": "3",
|
||||||
|
"4": "4",
|
||||||
|
"5": "5",
|
||||||
|
"6": "6",
|
||||||
|
"7": "7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{% else %}
|
||||||
"DSCP_TO_TC_MAP": {
|
"DSCP_TO_TC_MAP": {
|
||||||
"AZURE": {
|
"AZURE": {
|
||||||
"0" : "1",
|
"0" : "1",
|
||||||
@ -140,6 +155,7 @@
|
|||||||
"63": "1"
|
"63": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{% endif %}
|
||||||
"SCHEDULER": {
|
"SCHEDULER": {
|
||||||
"scheduler.0": {
|
"scheduler.0": {
|
||||||
"type" : "DWRR",
|
"type" : "DWRR",
|
||||||
@ -160,7 +176,11 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
"PORT_QOS_MAP": {
|
"PORT_QOS_MAP": {
|
||||||
"{{ port_names_active }}": {
|
"{{ port_names_active }}": {
|
||||||
|
{% if DEVICE_METADATA['localhost']['type'] in backend_device_types %}
|
||||||
|
"dot1p_to_tc_map" : "[DOT1P_TO_TC_MAP|AZURE]",
|
||||||
|
{% else %}
|
||||||
"dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
|
"dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
|
||||||
|
{% endif %}
|
||||||
"tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
|
"tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
|
||||||
"tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
|
"tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
|
||||||
"pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
|
"pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
|
||||||
|
@ -64,7 +64,7 @@ function getBootType()
|
|||||||
TYPE='fastfast'
|
TYPE='fastfast'
|
||||||
;;
|
;;
|
||||||
*SONIC_BOOT_TYPE=fast*|*fast-reboot*)
|
*SONIC_BOOT_TYPE=fast*|*fast-reboot*)
|
||||||
TYPE='fast'
|
TYPE=$(awk '{ if ($1 <= 180) print "fast"; else print "cold" }' /proc/uptime)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
TYPE='cold'
|
TYPE='cold'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
BFN_PLATFORM = bfnplatform_8_9_1.x.ab1e16f.deb
|
BFN_PLATFORM = bfnplatform_9.0.0.cc6ccbe_pr_deb9.deb
|
||||||
$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9_1/bfnplatform_8_9_1.x.ab1e16f.deb"
|
$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_0/bfnplatform_9.0.0.cc6ccbe_pr_deb9.deb"
|
||||||
|
|
||||||
SONIC_ONLINE_DEBS += $(BFN_PLATFORM) # $(BFN_SAI_DEV)
|
SONIC_ONLINE_DEBS += $(BFN_PLATFORM)
|
||||||
$(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM)
|
$(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
BFN_SAI = bfnsdk_8_9_1.x.ab1e16f.deb
|
BFN_SAI = bfnsdk_9.0.0.cc6ccbe_pr_deb9.deb
|
||||||
$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9_1/bfnsdk_8_9_1.x.ab1e16f.deb"
|
$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_0/bfnsdk_9.0.0.cc6ccbe_pr_deb9.deb"
|
||||||
|
|
||||||
SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV)
|
SONIC_ONLINE_DEBS += $(BFN_SAI)
|
||||||
$(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI)
|
$(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI)
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 8c45a8e111534f9d4337d3552eaf08881fb19d30
|
Subproject commit 7b39cf3400dd728494b91810db9cc82542a22584
|
@ -20,5 +20,6 @@ endif
|
|||||||
$(DOCKER_SYNCD_BRCM_RPC)_CONTAINER_NAME = syncd
|
$(DOCKER_SYNCD_BRCM_RPC)_CONTAINER_NAME = syncd
|
||||||
$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += --net=host --privileged -t
|
$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += --net=host --privileged -t
|
||||||
$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf
|
$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf
|
||||||
|
$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot
|
||||||
$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd
|
$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd
|
||||||
$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
|
$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
|
||||||
|
@ -51,7 +51,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
|
|||||||
$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \
|
$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \
|
||||||
$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \
|
$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \
|
||||||
$(BRCM_XLR_GTS_PLATFORM_MODULE) \
|
$(BRCM_XLR_GTS_PLATFORM_MODULE) \
|
||||||
$(DELTA_AG9032V2A_PLATFORM_MODULE)
|
$(DELTA_AG9032V2A_PLATFORM_MODULE) \
|
||||||
|
$(JUNIPER_QFX5210_PLATFORM_MODULE)
|
||||||
ifeq ($(INSTALL_DEBUG_TOOLS),y)
|
ifeq ($(INSTALL_DEBUG_TOOLS),y)
|
||||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
|
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
|
||||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
|
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
|
||||||
|
@ -36,3 +36,6 @@ $(DELL_S5232F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5232f_c3538-r0
|
|||||||
$(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5232F_PLATFORM_MODULE)))
|
$(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5232F_PLATFORM_MODULE)))
|
||||||
|
|
||||||
SONIC_STRETCH_DEBS += $(DELL_Z9100_PLATFORM_MODULE)
|
SONIC_STRETCH_DEBS += $(DELL_Z9100_PLATFORM_MODULE)
|
||||||
|
|
||||||
|
#flashrom tool
|
||||||
|
$(shell ./$(PLATFORM_PATH)/sonic-platform-modules-dell/tools/flashrom.sh > /dev/null 2>&1)
|
||||||
|
13
platform/broadcom/platform-modules-juniper.mk
Executable file
13
platform/broadcom/platform-modules-juniper.mk
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
# Juniper Platform modules
|
||||||
|
|
||||||
|
JUNIPER_QFX5210_PLATFORM_MODULE_VERSION = 1.1
|
||||||
|
|
||||||
|
export JUNIPER_QFX5210_PLATFORM_MODULE_VERSION
|
||||||
|
|
||||||
|
JUNIPER_QFX5210_PLATFORM_MODULE = sonic-platform-juniper-qfx5210_$(JUNIPER_QFX5210_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||||
|
$(JUNIPER_QFX5210_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-juniper
|
||||||
|
$(JUNIPER_QFX5210_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
|
||||||
|
$(JUNIPER_QFX5210_PLATFORM_MODULE)_PLATFORM = x86_64-juniper_qfx5210-r0
|
||||||
|
SONIC_DPKG_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE)
|
||||||
|
|
||||||
|
SONIC_STRETCH_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE)
|
@ -10,6 +10,7 @@ include $(PLATFORM_PATH)/platform-modules-cel.mk
|
|||||||
include $(PLATFORM_PATH)/platform-modules-delta.mk
|
include $(PLATFORM_PATH)/platform-modules-delta.mk
|
||||||
include $(PLATFORM_PATH)/platform-modules-quanta.mk
|
include $(PLATFORM_PATH)/platform-modules-quanta.mk
|
||||||
#include $(PLATFORM_PATH)/platform-modules-mitac.mk
|
#include $(PLATFORM_PATH)/platform-modules-mitac.mk
|
||||||
|
include $(PLATFORM_PATH)/platform-modules-juniper.mk
|
||||||
include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk
|
include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk
|
||||||
include $(PLATFORM_PATH)/docker-syncd-brcm.mk
|
include $(PLATFORM_PATH)/docker-syncd-brcm.mk
|
||||||
include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk
|
include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk
|
||||||
|
@ -1,26 +1,22 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# Copyright (c) 2019 Edgecore Networks Corporation
|
||||||
#
|
#
|
||||||
# Copyright (C) 2017 Accton Technology Corporation
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||||
# it under the terms of the GNU General Public License as published by
|
# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS
|
||||||
# (at your option) any later version.
|
# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# See the Apache Version 2.0 License for specific language governing
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# permissions and limitations under the License.
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
#
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# HISTORY:
|
# HISTORY:
|
||||||
# mm/dd/yyyy (A.D.)
|
# mm/dd/yyyy (A.D.)
|
||||||
# 11/13/2017: Polly Hsu, Create
|
# 8/27/2019:Jostar craete for as9716_32d
|
||||||
# 1/10/2018: Jostar modify for as7716_32
|
|
||||||
# 12/03/2018: Jostar modify for as7726_32
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -46,8 +42,8 @@ class FanUtil(object):
|
|||||||
FAN_NODE_FAULT_IDX_OF_MAP = 1
|
FAN_NODE_FAULT_IDX_OF_MAP = 1
|
||||||
FAN_NODE_DIR_IDX_OF_MAP = 2
|
FAN_NODE_DIR_IDX_OF_MAP = 2
|
||||||
|
|
||||||
BASE_VAL_PATH = '/sys/bus/i2c/devices/54-0066/{0}'
|
BASE_VAL_PATH = '/sys/bus/i2c/devices/17-0066/{0}'
|
||||||
FAN_DUTY_PATH = '/sys/bus/i2c/devices/54-0066/fan_duty_cycle_percentage'
|
FAN_DUTY_PATH = '/sys/bus/i2c/devices/17-0066/fan_duty_cycle_percentage'
|
||||||
|
|
||||||
#logfile = ''
|
#logfile = ''
|
||||||
#loglevel = logging.INFO
|
#loglevel = logging.INFO
|
||||||
@ -56,14 +52,14 @@ class FanUtil(object):
|
|||||||
key1 = fan id index (integer) starting from 1
|
key1 = fan id index (integer) starting from 1
|
||||||
key2 = fan node index (interger) starting from 1
|
key2 = fan node index (interger) starting from 1
|
||||||
value = path to fan device file (string) """
|
value = path to fan device file (string) """
|
||||||
_fan_to_device_path_mapping = {}
|
_fan_device_path_mapping = {}
|
||||||
|
|
||||||
#fan1_direction
|
#fan1_direction
|
||||||
#fan1_fault
|
#fan1_fault
|
||||||
#fan1_present
|
#fan1_present
|
||||||
|
|
||||||
#(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage',
|
#(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage',
|
||||||
_fan_to_device_node_mapping = {
|
_fan_device_node_mapping = {
|
||||||
(FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault',
|
(FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault',
|
||||||
(FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction',
|
(FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction',
|
||||||
|
|
||||||
@ -83,8 +79,8 @@ class FanUtil(object):
|
|||||||
(FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction',
|
(FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction',
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_fan_to_device_node(self, fan_num, node_num):
|
def _get_fan_device_node(self, fan_num, node_num):
|
||||||
return self._fan_to_device_node_mapping[(fan_num, node_num)]
|
return self._fan_device_node_mapping[(fan_num, node_num)]
|
||||||
|
|
||||||
def _get_fan_node_val(self, fan_num, node_num):
|
def _get_fan_node_val(self, fan_num, node_num):
|
||||||
if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
|
if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
|
||||||
@ -95,7 +91,7 @@ class FanUtil(object):
|
|||||||
logging.debug('GET. Parameter error. node_num:%d', node_num)
|
logging.debug('GET. Parameter error. node_num:%d', node_num)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
device_path = self.get_fan_to_device_path(fan_num, node_num)
|
device_path = self.get_fan_device_path(fan_num, node_num)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
val_file = open(device_path, 'r')
|
val_file = open(device_path, 'r')
|
||||||
@ -131,7 +127,7 @@ class FanUtil(object):
|
|||||||
logging.debug('GET. content is NULL. device_path:%s', device_path)
|
logging.debug('GET. content is NULL. device_path:%s', device_path)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
device_path = self.get_fan_to_device_path(fan_num, node_num)
|
device_path = self.get_fan_device_path(fan_num, node_num)
|
||||||
try:
|
try:
|
||||||
val_file = open(device_path, 'w')
|
val_file = open(device_path, 'w')
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
@ -153,8 +149,8 @@ class FanUtil(object):
|
|||||||
|
|
||||||
for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1):
|
for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1):
|
||||||
for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1):
|
for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1):
|
||||||
self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format(
|
self._fan_device_path_mapping[(fan_num, node_num)] = fan_path.format(
|
||||||
self._fan_to_device_node_mapping[(fan_num, node_num)])
|
self._fan_device_node_mapping[(fan_num, node_num)])
|
||||||
|
|
||||||
def get_num_fans(self):
|
def get_num_fans(self):
|
||||||
return self.FAN_NUM_ON_MAIN_BROAD
|
return self.FAN_NUM_ON_MAIN_BROAD
|
||||||
@ -169,20 +165,17 @@ class FanUtil(object):
|
|||||||
return self.FAN_NODE_FAULT_IDX_OF_MAP
|
return self.FAN_NODE_FAULT_IDX_OF_MAP
|
||||||
|
|
||||||
def get_size_node_map(self):
|
def get_size_node_map(self):
|
||||||
return len(self._fan_to_device_node_mapping)
|
return len(self._fan_device_node_mapping)
|
||||||
|
|
||||||
def get_size_path_map(self):
|
def get_size_path_map(self):
|
||||||
return len(self._fan_to_device_path_mapping)
|
return len(self._fan_device_path_mapping)
|
||||||
|
|
||||||
def get_fan_to_device_path(self, fan_num, node_num):
|
def get_fan_device_path(self, fan_num, node_num):
|
||||||
return self._fan_to_device_path_mapping[(fan_num, node_num)]
|
return self._fan_device_path_mapping[(fan_num, node_num)]
|
||||||
|
|
||||||
def get_fan_fault(self, fan_num):
|
def get_fan_fault(self, fan_num):
|
||||||
return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP)
|
return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP)
|
||||||
|
|
||||||
#def get_fan_speed(self, fan_num):
|
|
||||||
# return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP)
|
|
||||||
|
|
||||||
def get_fan_dir(self, fan_num):
|
def get_fan_dir(self, fan_num):
|
||||||
return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP)
|
return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP)
|
||||||
|
|
||||||
@ -198,28 +191,18 @@ class FanUtil(object):
|
|||||||
val_file.close()
|
val_file.close()
|
||||||
|
|
||||||
return int(content)
|
return int(content)
|
||||||
#self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP)
|
|
||||||
#static u32 reg_val_to_duty_cycle(u8 reg_val)
|
|
||||||
#{
|
|
||||||
# reg_val &= FAN_DUTY_CYCLE_REG_MASK;
|
|
||||||
# return ((u32)(reg_val+1) * 625 + 75)/ 100;
|
|
||||||
#}
|
|
||||||
#
|
|
||||||
def set_fan_duty_cycle(self, val):
|
def set_fan_duty_cycle(self, val):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fan_file = open(self.FAN_DUTY_PATH, 'r+')
|
fan_file = open(self.FAN_DUTY_PATH, 'r+')
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
print "Error: unable to open file: %s" % str(e)
|
print "Error: unable to open file: %s" % str(e)
|
||||||
return False
|
return False
|
||||||
#val = ((val + 1 ) * 625 +75 ) / 100
|
|
||||||
fan_file.write(str(val))
|
fan_file.write(str(val))
|
||||||
fan_file.close()
|
fan_file.close()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
#def get_fanr_fault(self, fan_num):
|
|
||||||
# return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP)
|
|
||||||
|
|
||||||
def get_fanr_speed(self, fan_num):
|
def get_fanr_speed(self, fan_num):
|
||||||
return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP)
|
return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP)
|
||||||
|
|
||||||
@ -232,20 +215,4 @@ class FanUtil(object):
|
|||||||
logging.debug('GET. FAN fault. fan_num, %d', fan_num)
|
logging.debug('GET. FAN fault. fan_num, %d', fan_num)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
#if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0:
|
|
||||||
# logging.debug('GET. FANR fault. fan_num, %d', fan_num)
|
|
||||||
# return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
#def main():
|
|
||||||
# fan = FanUtil()
|
|
||||||
#
|
|
||||||
# print 'get_size_node_map : %d' % fan.get_size_node_map()
|
|
||||||
# print 'get_size_path_map : %d' % fan.get_size_path_map()
|
|
||||||
# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1):
|
|
||||||
# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1):
|
|
||||||
# print fan.get_fan_to_device_path(x, y)
|
|
||||||
#
|
|
||||||
#if __name__ == '__main__':
|
|
||||||
# main()
|
|
||||||
|
@ -1,24 +1,22 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# Copyright (c) 2019 Edgecore Networks Corporation
|
||||||
#
|
#
|
||||||
# Copyright (C) 2017 Accton Technology Corporation
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||||
# it under the terms of the GNU General Public License as published by
|
# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS
|
||||||
# (at your option) any later version.
|
# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# See the Apache Version 2.0 License for specific language governing
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# permissions and limitations under the License.
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
#
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# HISTORY:
|
# HISTORY:
|
||||||
# mm/dd/yyyy (A.D.)
|
# mm/dd/yyyy (A.D.)
|
||||||
# 12/18/2018:Jostar craete for as9716_32d
|
# 8/27/2019:Jostar craete for as9716_32d
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -34,38 +32,29 @@ except ImportError as e:
|
|||||||
class ThermalUtil(object):
|
class ThermalUtil(object):
|
||||||
"""Platform-specific ThermalUtil class"""
|
"""Platform-specific ThermalUtil class"""
|
||||||
THERMAL_NUM_MAX = 8
|
THERMAL_NUM_MAX = 8
|
||||||
THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD. LM75
|
THERMAL_NUM_1_IDX = 1 # 1~7 are mainboard thermal sensors
|
||||||
THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD. LM75
|
THERMAL_NUM_2_IDX = 2
|
||||||
THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD. LM75
|
THERMAL_NUM_3_IDX = 3
|
||||||
THERMAL_NUM_4_IDX = 4 # 4_ON_MAIN_BROAD. LM75
|
THERMAL_NUM_4_IDX = 4
|
||||||
THERMAL_NUM_5_IDX = 5 # 5_ON_MAIN_BROAD. LM75
|
THERMAL_NUM_5_IDX = 5
|
||||||
THERMAL_NUM_6_IDX = 6 # 6_ON_MAIN_BROAD. LM75
|
THERMAL_NUM_6_IDX = 6
|
||||||
THERMAL_NUM_7_IDX = 7 # 7_ON_MAIN_BROAD. LM75
|
THERMAL_NUM_7_IDX = 7 # CPU core
|
||||||
THERMAL_NUM_8_IDX = 8 # 8_ON_MAIN_BROAD. LM75
|
THERMAL_NUM_8_IDX = 8
|
||||||
|
|
||||||
""" Dictionary where
|
""" Dictionary where
|
||||||
key1 = thermal id index (integer) starting from 1
|
key1 = thermal id index (integer) starting from 1
|
||||||
value = path to fan device file (string) """
|
value = path to fan device file (string) """
|
||||||
#_thermal_to_device_path_mapping = {}
|
#_thermal_to_device_path_mapping = {}
|
||||||
|
|
||||||
_thermal_to_device_node_mapping = {
|
|
||||||
THERMAL_NUM_1_IDX: ['18', '48'],
|
|
||||||
THERMAL_NUM_2_IDX: ['18', '49'],
|
|
||||||
THERMAL_NUM_3_IDX: ['18', '4a'],
|
|
||||||
THERMAL_NUM_4_IDX: ['18', '4b'],
|
|
||||||
THERMAL_NUM_5_IDX: ['18', '4c'],
|
|
||||||
THERMAL_NUM_6_IDX: ['18', '4e'],
|
|
||||||
THERMAL_NUM_7_IDX: ['18', '4f'],
|
|
||||||
}
|
|
||||||
thermal_sysfspath ={
|
thermal_sysfspath ={
|
||||||
THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/18-0048/hwmon/hwmon*/temp1_input"],
|
THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/18-0048/hwmon/hwmon*/temp1_input"],
|
||||||
THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/18-0049/hwmon/hwmon*/temp1_input"],
|
THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/18-0049/hwmon/hwmon*/temp1_input"],
|
||||||
THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/18-004a/hwmon/hwmon*/temp1_input"],
|
THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/18-004a/hwmon/hwmon*/temp1_input"],
|
||||||
THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/18-004b/hwmon/hwmon*/temp1_input"],
|
THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/18-004c/hwmon/hwmon*/temp1_input"],
|
||||||
THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/18-004c/hwmon/hwmon*/temp1_input"],
|
THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/18-004e/hwmon/hwmon*/temp1_input"],
|
||||||
THERMAL_NUM_6_IDX: ["/sys/bus/i2c/devices/18-004e/hwmon/hwmon*/temp1_input"],
|
THERMAL_NUM_6_IDX: ["/sys/bus/i2c/devices/18-004f/hwmon/hwmon*/temp1_input"],
|
||||||
THERMAL_NUM_7_IDX: ["/sys/bus/i2c/devices/18-004f/hwmon/hwmon*/temp1_input"],
|
THERMAL_NUM_7_IDX: ["/sys/class/hwmon/hwmon0/temp1_input"],
|
||||||
THERMAL_NUM_8_IDX: ["/sys/class/hwmon/hwmon0/temp1_input"],
|
THERMAL_NUM_8_IDX: ["/sys/bus/i2c/devices/18-004b/hwmon/hwmon*/temp1_input"],
|
||||||
}
|
}
|
||||||
|
|
||||||
#def __init__(self):
|
#def __init__(self):
|
||||||
@ -75,7 +64,7 @@ class ThermalUtil(object):
|
|||||||
logging.debug('GET. Parameter error. thermal_num, %d', thermal_num)
|
logging.debug('GET. Parameter error. thermal_num, %d', thermal_num)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
device_path = self.get_thermal_to_device_path(thermal_num)
|
device_path = self.get_thermal_path(thermal_num)
|
||||||
for filename in glob.glob(device_path):
|
for filename in glob.glob(device_path):
|
||||||
try:
|
try:
|
||||||
val_file = open(filename, 'r')
|
val_file = open(filename, 'r')
|
||||||
@ -97,39 +86,17 @@ class ThermalUtil(object):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
def get_num_thermals(self):
|
def get_num_thermals(self):
|
||||||
return self.THERMAL_NUM_MAX
|
return self.THERMAL_NUM_MAX
|
||||||
|
|
||||||
def get_idx_thermal_start(self):
|
|
||||||
return self.THERMAL_NUM_1_IDX
|
|
||||||
|
|
||||||
def get_size_node_map(self):
|
|
||||||
return len(self._thermal_to_device_node_mapping)
|
|
||||||
|
|
||||||
def get_size_path_map(self):
|
def get_size_path_map(self):
|
||||||
return len(self.thermal_sysfspath)
|
return len(self.thermal_sysfspath)
|
||||||
|
|
||||||
def get_thermal_to_device_path(self, thermal_num):
|
def get_thermal_path(self, thermal_num):
|
||||||
return self.thermal_sysfspath[thermal_num][0]
|
return self.thermal_sysfspath[thermal_num][0]
|
||||||
|
|
||||||
def get_thermal_temp(self):
|
|
||||||
return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX))
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
thermal = ThermalUtil()
|
thermal = ThermalUtil()
|
||||||
print "termal1=%d" %thermal._get_thermal_val(1)
|
|
||||||
print "termal2=%d" %thermal._get_thermal_val(2)
|
|
||||||
print "termal3=%d" %thermal._get_thermal_val(3)
|
|
||||||
print "termal4=%d" %thermal._get_thermal_val(4)
|
|
||||||
print "termal5=%d" %thermal._get_thermal_val(5)
|
|
||||||
print "termal7=%d" %thermal._get_thermal_val(6)
|
|
||||||
print "termal8=%d" %thermal._get_thermal_val(7)
|
|
||||||
print "termal9=%d" %thermal._get_thermal_val(8)
|
|
||||||
|
|
||||||
#
|
|
||||||
# print 'get_size_node_map : %d' % thermal.get_size_node_map()
|
|
||||||
# print 'get_size_path_map : %d' % thermal.get_size_path_map()
|
|
||||||
# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1):
|
|
||||||
# print thermal.get_thermal_to_device_path(x)
|
|
||||||
#
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
@ -1,28 +1,27 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*
|
||||||
|
# Copyright (c) 2019 Edgecore Networks Corporation
|
||||||
#
|
#
|
||||||
# Copyright (C) 2017 Accton Technology Corporation
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||||
# it under the terms of the GNU General Public License as published by
|
# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS
|
||||||
# (at your option) any later version.
|
# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# See the Apache Version 2.0 License for specific language governing
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# permissions and limitations under the License.
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
#
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
# HISTORY:
|
# HISTORY:
|
||||||
# mm/dd/yyyy (A.D.)#
|
# mm/dd/yyyy (A.D.)#
|
||||||
# 12/19/2018:Jostar create for as9716_32d thermal plan
|
# 8/27/2019:Jostar create for as9716_32d thermal plan
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import os
|
import os
|
||||||
|
import commands
|
||||||
import sys, getopt
|
import sys, getopt
|
||||||
import subprocess
|
import subprocess
|
||||||
import click
|
import click
|
||||||
@ -41,31 +40,11 @@ except ImportError as e:
|
|||||||
|
|
||||||
# Deafults
|
# Deafults
|
||||||
VERSION = '1.0'
|
VERSION = '1.0'
|
||||||
FUNCTION_NAME = '/usr/local/bin/accton_as9716_32x_monitor'
|
FUNCTION_NAME = '/usr/local/bin/accton_as9716_32d_monitor'
|
||||||
|
|
||||||
global log_file
|
global log_file
|
||||||
global log_level
|
global log_level
|
||||||
|
|
||||||
|
|
||||||
# Air Flow Front to Back :
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=38C : Keep 37.5%(0x04) Fan speed
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 38C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08)
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 46C : Change Fan speed from 62.5%(0x08) to 100%(0x0E)
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 58C : Send alarm message
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 66C : Shut down system
|
|
||||||
# One Fan fail : Change Fan speed to 100%(0x0E)
|
|
||||||
|
|
||||||
|
|
||||||
# Air Flow Back to Front :
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=34C : Keep 37.5%(0x04) Fan speed
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 34C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08)
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 44C : Change Fan speed from 62.5%(0x08) to 100%(0x0E)
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 59C : Send alarm message
|
|
||||||
# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 67C : Shut down system
|
|
||||||
# One Fan fail: Change Fan speed to 100%(0x0E)
|
|
||||||
# sensor_LM75_CPU == sensor_LM75_4B
|
|
||||||
|
|
||||||
|
|
||||||
class switch(object):
|
class switch(object):
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
self.value = value
|
self.value = value
|
||||||
@ -87,20 +66,217 @@ class switch(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
fan_policy_state=1
|
|
||||||
|
# Read fanN_direction=1: The air flow of Fan6 is “AFI-Back to Front”
|
||||||
|
# 0: The air flow of Fan6 is “AFO-Front to back”
|
||||||
|
#
|
||||||
|
# Thermal policy:
|
||||||
|
# a.Defaut fan duty_cycle=100%
|
||||||
|
# b.One fan fail, set to fan duty_cycle=100%
|
||||||
|
# 1.For AFI:
|
||||||
|
# Default fan duty_cycle will be 100%(fan_policy_state=LEVEL_FAN_MAX).
|
||||||
|
# If all below case meet with, set to 75%(LEVEL_FAN_MID).
|
||||||
|
# MB board
|
||||||
|
# LM75-1(0X48)<=57
|
||||||
|
# LM75-2(0X49)<=47.3
|
||||||
|
# LM75-3(0X4A)<=45
|
||||||
|
# LM75-4(0X4C)<=45.1
|
||||||
|
# LM75-5(0X4E)<=40.75
|
||||||
|
# LM75-6(0X4F)<=42.1
|
||||||
|
# CPU board
|
||||||
|
# Core<=44
|
||||||
|
# LM75-1(0X4B)<=35
|
||||||
|
|
||||||
|
# When fan_policy_state=LEVEL_FAN_MID, meet with below case, Fan duty_cycle will be 100%(LEVEL_FAN_DAX)
|
||||||
|
# (MB board)
|
||||||
|
# LM75-1(0X48)>=61.5
|
||||||
|
# LM75-2(0X49)>=51.5
|
||||||
|
# LM75-3(0X4A)>=49.4
|
||||||
|
# LM75-4(0X4C)>=49.4
|
||||||
|
# LM75-5(0X4E)>=45.1
|
||||||
|
# LM75-6(0X4F)>=46.75
|
||||||
|
# (CPU board)
|
||||||
|
# Core>=48
|
||||||
|
# LM75-1(0X4B)>=38.5
|
||||||
|
|
||||||
|
# 2. For AFO:
|
||||||
|
# At default, FAN duty_cycle was 100%(LEVEL_FAN_MAX). If all below case meet with, set to 75%(LEVEL_FAN_MID).
|
||||||
|
# (MB board)
|
||||||
|
# LM75-1(0X48)<=59
|
||||||
|
# LM75-2(0X49)<=53.5
|
||||||
|
# LM75-3(0X4A)<=55.3
|
||||||
|
# LM75-4(0X4C)<=50.3
|
||||||
|
# LM75-5(0X4E)<=50
|
||||||
|
# LM75-6(0X4F)<=52.5
|
||||||
|
# (CPU board)
|
||||||
|
# Core<=59
|
||||||
|
# LM75-1(0X4B)<=41.1
|
||||||
|
|
||||||
|
# When FAN duty_cycle was 75%(LEVEL_FAN_MID). If all below case meet with, set to 50%(LEVEL_FAN_DEF).
|
||||||
|
# (MB board)
|
||||||
|
# LM75-1(0X48)<=55.8
|
||||||
|
# LM75-2(0X49)<=50.5
|
||||||
|
# LM75-3(0X4A)<=51.1
|
||||||
|
# LM75-4(0X4C)<=47.6
|
||||||
|
# LM75-5(0X4E)<=45.75
|
||||||
|
# LM75-6(0X4F)<=50.1
|
||||||
|
# (CPU board)
|
||||||
|
# Core<=57
|
||||||
|
# LM75-1(0X4B)<=36.6
|
||||||
|
|
||||||
|
# When fan_speed 50%(LEVEL_FAN_DEF).
|
||||||
|
# Meet with below case, Fan duty_cycle will be 75%(LEVEL_FAN_MID)
|
||||||
|
# (MB board)
|
||||||
|
# LM75-1(0X48)>=70
|
||||||
|
# LM75-2(0X49)>=66
|
||||||
|
# LM75-3(0X4A)>=68
|
||||||
|
# LM75-4(0X4C)>=62
|
||||||
|
# LM75-5(0X4E)>=62
|
||||||
|
# LM75-6(0X4F)>=67
|
||||||
|
# (CPU board)
|
||||||
|
# Core>=77
|
||||||
|
# LM75-1(0X4B)>=50
|
||||||
|
|
||||||
|
# When FAN duty_cycle was 75%(LEVEL_FAN_MID). If all below case meet with, set to 100%(LEVEL_FAN_MAX).
|
||||||
|
# (MB board)
|
||||||
|
# LM75-1(0X48)>=67
|
||||||
|
# LM75-2(0X49)>=62.5
|
||||||
|
# LM75-3(0X4A)>=65
|
||||||
|
# LM75-4(0X4C)>=59
|
||||||
|
# LM75-5(0X4E)>=58.5
|
||||||
|
# LM75-6(0X4F)>=63
|
||||||
|
|
||||||
|
# (CPU board)
|
||||||
|
# Core >=69
|
||||||
|
# LM75-1(0X4B)>=49
|
||||||
|
|
||||||
|
|
||||||
|
#Yellow Alarm
|
||||||
|
#MB board
|
||||||
|
#LM75-1(0X48)>=68
|
||||||
|
#LM75-2(0X49)>=64
|
||||||
|
#LM75-3(0X4A)>=65
|
||||||
|
#LM75-4(0X4C)>=61
|
||||||
|
#LM75-5(0X4E)>=60
|
||||||
|
#LM75-6(0X4F)>=64
|
||||||
|
#CPU Board
|
||||||
|
#Core>=70
|
||||||
|
#LM75-1(0X4B)>=68
|
||||||
|
|
||||||
|
#Red Alarm
|
||||||
|
#MB board
|
||||||
|
#LM75-1(0X48)>=72
|
||||||
|
#LM75-2(0X49)>=68
|
||||||
|
#LM75-3(0X4A)>=69
|
||||||
|
#LM75-4(0X4C)>=65
|
||||||
|
#LM75-5(0X4E)>=64
|
||||||
|
#LM75-6(0X4F)>=68
|
||||||
|
#CPU Board
|
||||||
|
#Core>=74
|
||||||
|
#LM75-1(0X4B)>=72
|
||||||
|
|
||||||
|
#Shut down
|
||||||
|
#MB board
|
||||||
|
#LM75-1(0X48)>=77
|
||||||
|
#LM75-2(0X49)>=73
|
||||||
|
#LM75-3(0X4A)>=74
|
||||||
|
#LM75-4(0X4C)>=70
|
||||||
|
#LM75-5(0X4E)>=69
|
||||||
|
#LM75-6(0X4F)>=73
|
||||||
|
#CPU Board
|
||||||
|
#Core>=79
|
||||||
|
#LM75-1(0X4B)>=77
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def power_off_dut():
|
||||||
|
cmd_str="i2cset -y -f 19 0x60 0x60 0x10"
|
||||||
|
status, output = commands.getstatusoutput(cmd_str)
|
||||||
|
return status
|
||||||
|
|
||||||
|
#If only one PSU insert(or one of PSU pwoer fail), and watt >800w. Must let DUT fan pwm >= 75% in AFO.
|
||||||
|
#Because the psu temp is high.
|
||||||
|
# Return 1: full load
|
||||||
|
# Return 0: Not full load
|
||||||
|
def check_psu_loading():
|
||||||
|
psu_power_status=[1, 1]
|
||||||
|
|
||||||
|
psu_power_good = {
|
||||||
|
2: "/sys/bus/i2c/devices/10-0051/psu_power_good",
|
||||||
|
1: "/sys/bus/i2c/devices/9-0050/psu_power_good",
|
||||||
|
}
|
||||||
|
psu_power_in = {
|
||||||
|
2: "/sys/bus/i2c/devices/10-0059/psu_p_in",
|
||||||
|
1: "/sys/bus/i2c/devices/9-0058/psu_p_in",
|
||||||
|
}
|
||||||
|
psu_power_out = {
|
||||||
|
2: "/sys/bus/i2c/devices/10-0059/psu_p_out",
|
||||||
|
1: "/sys/bus/i2c/devices/9-0058/psu_p_out",
|
||||||
|
}
|
||||||
|
|
||||||
|
check_psu_watt=0
|
||||||
|
for i in range(1,3):
|
||||||
|
node = psu_power_good[i]
|
||||||
|
try:
|
||||||
|
with open(node, 'r') as power_status:
|
||||||
|
status = int(power_status.read())
|
||||||
|
except IOError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
psu_power_status[i-1]=int(status)
|
||||||
|
if status==0:
|
||||||
|
check_psu_watt=1
|
||||||
|
|
||||||
|
if check_psu_watt:
|
||||||
|
for i in range(1,3):
|
||||||
|
if psu_power_status[i-1]==1:
|
||||||
|
#check watt
|
||||||
|
node = psu_power_in[i]
|
||||||
|
try:
|
||||||
|
with open(node, 'r') as power_status:
|
||||||
|
status = int(power_status.read())
|
||||||
|
except IOError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
psu_p_in= int(status)
|
||||||
|
if psu_p_in/1000 > 800:
|
||||||
|
return True
|
||||||
|
|
||||||
|
node = psu_power_out[i]
|
||||||
|
try:
|
||||||
|
with open(node, 'r') as power_status:
|
||||||
|
status = int(power_status.read())
|
||||||
|
except IOError:
|
||||||
|
return None
|
||||||
|
psu_p_out= int(status)
|
||||||
|
if psu_p_out/1000 > 800:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
fan_policy_state=0
|
||||||
|
fan_policy_alarm=0
|
||||||
|
send_yellow_alarm=0
|
||||||
|
send_red_alarm=0
|
||||||
fan_fail=0
|
fan_fail=0
|
||||||
alarm_state = 0 #0->default or clear, 1-->alarm detect
|
count_check=0
|
||||||
|
|
||||||
test_temp = 0
|
test_temp = 0
|
||||||
test_temp_list = [0, 0, 0, 0, 0, 0]
|
test_temp_list = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
temp_test_data=0
|
temp_test_data=0
|
||||||
|
test_temp_revert=0
|
||||||
|
|
||||||
# Make a class we can use to capture stdout and sterr in the log
|
# Make a class we can use to capture stdout and sterr in the log
|
||||||
class device_monitor(object):
|
class device_monitor(object):
|
||||||
# static temp var
|
# static temp var
|
||||||
temp = 0
|
temp = 0
|
||||||
new_pwm = 0
|
new_duty_cycle = 0
|
||||||
pwm=0
|
duty_cycle=0
|
||||||
ori_pwm = 0
|
ori_duty_cycle = 0
|
||||||
default_pwm=0x4
|
|
||||||
|
|
||||||
def __init__(self, log_file, log_level):
|
def __init__(self, log_file, log_level):
|
||||||
"""Needs a logger and a logger level."""
|
"""Needs a logger and a logger level."""
|
||||||
@ -123,179 +299,197 @@ class device_monitor(object):
|
|||||||
sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log')
|
sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log')
|
||||||
sys_handler.setLevel(logging.WARNING)
|
sys_handler.setLevel(logging.WARNING)
|
||||||
logging.getLogger('').addHandler(sys_handler)
|
logging.getLogger('').addHandler(sys_handler)
|
||||||
|
|
||||||
#logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level)
|
#logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level)
|
||||||
|
|
||||||
def get_state_from_fan_policy(self, temp, policy):
|
|
||||||
state=0
|
|
||||||
|
|
||||||
logging.debug('temp=%d', temp)
|
|
||||||
for i in range(0, len(policy)):
|
|
||||||
#logging.debug('policy[%d][0]=%d, policy[%d][1]=%d, policy[%d][2]=%d', i,policy[i][0],i, policy[i][1], i, policy[i][2])
|
|
||||||
if temp > policy[i][2]:
|
|
||||||
if temp <= policy[i][3]:
|
|
||||||
state =i
|
|
||||||
logging.debug ('temp=%d >= policy[%d][2]=%d, temp=%d < policy[%d][3]=%d' , temp, i, policy[i][2], temp, i, policy[i][3])
|
|
||||||
logging.debug ('fan_state=%d', state)
|
|
||||||
break
|
|
||||||
|
|
||||||
return state
|
|
||||||
|
|
||||||
|
|
||||||
def manage_fans(self):
|
def manage_fans(self):
|
||||||
|
|
||||||
global fan_policy_state
|
global fan_policy_state
|
||||||
|
global fan_policy_alarm
|
||||||
|
global send_yellow_alarm
|
||||||
|
global send_red_alarm
|
||||||
global fan_fail
|
global fan_fail
|
||||||
|
global count_check
|
||||||
global test_temp
|
global test_temp
|
||||||
global test_temp_list
|
global test_temp_list
|
||||||
global alarm_state
|
|
||||||
global temp_test_data
|
global temp_test_data
|
||||||
|
global test_temp_revert
|
||||||
LEVEL_FAN_DEF=0
|
|
||||||
LEVEL_FAN_MID=1
|
CHECK_TIMES=3
|
||||||
LEVEL_FAN_MAX=2
|
|
||||||
LEVEL_TEMP_HIGH=3
|
LEVEL_FAN_INIT=0
|
||||||
LEVEL_TEMP_CRITICAL=4
|
LEVEL_FAN_MIN=1
|
||||||
|
LEVEL_FAN_MID=2
|
||||||
|
LEVEL_FAN_MAX=3
|
||||||
fan_policy_f2b = {
|
LEVEL_FAN_DEF=LEVEL_FAN_MAX
|
||||||
LEVEL_FAN_DEF: [38, 0x4, 0, 38000],
|
LEVEL_FAN_YELLOW_ALARM=4
|
||||||
LEVEL_FAN_MID: [63, 0x6, 38000, 46000],
|
LEVEL_FAN_RED_ALARM=5
|
||||||
LEVEL_FAN_MAX: [100, 0xE, 46000, 58000],
|
LEVEL_FAN_SHUTDOWN=6
|
||||||
LEVEL_TEMP_HIGH: [100, 0xE, 58000, 66000],
|
|
||||||
LEVEL_TEMP_CRITICAL: [100, 0xE, 58000, 200000],
|
fan_policy_f2b = { #AFO
|
||||||
|
LEVEL_FAN_MIN: [50, 0x7],
|
||||||
|
LEVEL_FAN_MID: [75, 0xb],
|
||||||
|
LEVEL_FAN_MAX: [100, 0xf]
|
||||||
}
|
}
|
||||||
fan_policy_b2f = {
|
fan_policy_b2f = { #AFI
|
||||||
LEVEL_FAN_DEF: [38, 0x4, 0, 34000],
|
LEVEL_FAN_MID: [75, 0xb],
|
||||||
LEVEL_FAN_MID: [63, 0x8, 34000, 44000],
|
LEVEL_FAN_MAX: [100, 0xf]
|
||||||
LEVEL_FAN_MAX: [100, 0xE, 44000, 59000],
|
|
||||||
LEVEL_TEMP_HIGH: [100, 0xE, 59000, 67000],
|
|
||||||
LEVEL_TEMP_CRITICAL: [100, 0xE, 59000, 200000],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
afi_thermal_spec={
|
||||||
|
"mid_to_max_temp":[61500, 51500, 49400, 49400, 45100, 46750, 48000, 38500],
|
||||||
|
"max_to_mid_temp":[57000, 47300, 45000, 45100, 40750, 42100, 44000, 35000]
|
||||||
|
}
|
||||||
|
afo_thermal_spec={
|
||||||
|
"min_to_mid_temp": [70000, 66000, 68000, 62000, 62000, 67000, 77000, 50000],
|
||||||
|
"mid_to_max_temp": [67000, 62000, 65000, 59000, 58500, 63000, 69000, 49000],
|
||||||
|
"max_to_mid_temp": [59000, 53500, 55300, 50300, 50000, 52500, 59000, 41100],
|
||||||
|
"mid_to_min_temp": [55800, 50500, 51100, 47600, 45750, 50100, 57000, 36600],
|
||||||
|
"max_to_yellow_alarm": [68000, 64000, 65000, 61000, 60000, 64000, 70000, 68000],
|
||||||
|
"yellow_to_red_alarm": [72000, 68000, 69000, 65000, 64000, 68000, 74000, 72000],
|
||||||
|
"red_alarm_to_shutdown": [77000, 73000, 74000, 70000, 69000, 73000, 79000, 77000]
|
||||||
|
}
|
||||||
|
|
||||||
|
thermal_val=[0,0,0,0,0,0,0,0]
|
||||||
|
max_to_mid=0
|
||||||
|
mid_to_min=0
|
||||||
|
|
||||||
fan_policy = fan_policy_f2b
|
fan = FanUtil()
|
||||||
|
if fan_policy_state==LEVEL_FAN_INIT:
|
||||||
|
fan_policy_state=LEVEL_FAN_MAX #This is default state
|
||||||
|
logging.debug("fan_policy_state=LEVEL_FAN_MAX")
|
||||||
|
return
|
||||||
|
|
||||||
|
count_check=count_check+1
|
||||||
|
if count_check < CHECK_TIMES:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
count_check=0
|
||||||
|
|
||||||
thermal = ThermalUtil()
|
thermal = ThermalUtil()
|
||||||
fan = FanUtil()
|
fan_dir=1
|
||||||
fan_dir=fan.get_fan_dir(1)
|
fan_dir=fan.get_fan_dir(1)
|
||||||
if fan_dir == 1:
|
|
||||||
fan_dri=1 #something wrong, set fan_dir to default val
|
if fan_dir==1: # AFI
|
||||||
|
fan_thermal_spec = afi_thermal_spec
|
||||||
|
fan_policy=fan_policy_b2f
|
||||||
|
elif fan_dir==0: # AFO
|
||||||
|
fan_thermal_spec = afo_thermal_spec
|
||||||
|
fan_policy=fan_policy_f2b
|
||||||
else:
|
else:
|
||||||
fan_policy = fan_policy_b2f
|
logging.debug( "NULL case")
|
||||||
|
|
||||||
ori_pwm=fan.get_fan_duty_cycle()
|
ori_duty_cycle=fan.get_fan_duty_cycle()
|
||||||
new_pwm=0
|
new_duty_cycle=0
|
||||||
logging.debug('fan_dir=%d, ori_pwm=%d', fan_dir, ori_pwm)
|
|
||||||
logging.debug('test_temp=%d', test_temp)
|
if test_temp_revert==0:
|
||||||
if test_temp==0:
|
temp_test_data=temp_test_data+2000
|
||||||
temp1 = thermal._get_thermal_val(1)
|
else:
|
||||||
temp2 = thermal._get_thermal_val(2)
|
temp_test_data=temp_test_data-2000
|
||||||
temp3 = thermal._get_thermal_val(3)
|
|
||||||
temp4 = thermal._get_thermal_val(4)
|
if test_temp==0:
|
||||||
temp5 = thermal._get_thermal_val(5)
|
for i in range (thermal.THERMAL_NUM_1_IDX, thermal.THERMAL_NUM_MAX+1):
|
||||||
|
thermal_val[i-1]=thermal._get_thermal_val(i)
|
||||||
else:
|
else:
|
||||||
temp1 = test_temp_list[0]
|
for i in range (thermal.THERMAL_NUM_1_IDX, thermal.THERMAL_NUM_MAX+1):
|
||||||
temp2 = test_temp_list[1]
|
thermal_val[i-1]=test_temp_list[i-1]
|
||||||
temp3 = test_temp_list[2]
|
thermal_val[i-1]= thermal_val[i-1] + temp_test_data
|
||||||
temp4 = test_temp_list[3]
|
|
||||||
temp5 = test_temp_list[4]
|
|
||||||
fan_fail=0
|
fan_fail=0
|
||||||
|
|
||||||
if temp3==0:
|
ori_state=fan_policy_state;
|
||||||
temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75%
|
current_state=fan_policy_state;
|
||||||
logging.debug('lm75_49 detect fail, so set temp_get=50000, let fan to 75%')
|
|
||||||
elif temp4==0:
|
if fan_dir==1: #AFI
|
||||||
temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75%
|
for i in range (0, thermal.THERMAL_NUM_MAX):
|
||||||
logging.debug('lm75_4b detect fail, so set temp_get=50000, let fan to 75%')
|
if ori_state==LEVEL_FAN_MID:
|
||||||
else:
|
if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]:
|
||||||
temp_get= (temp3 + temp4)/2 # Use (sensor_LM75_4a + sensor_LM75_4b) /2
|
current_state=LEVEL_FAN_MAX
|
||||||
ori_state=fan_policy_state
|
logging.debug("current_state=LEVEL_FAN_MAX")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if (thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i]):
|
||||||
|
max_to_mid=max_to_mid+1
|
||||||
|
|
||||||
#temp_test_data=temp_test_data+1000
|
if max_to_mid==thermal.THERMAL_NUM_MAX and fan_policy_state==LEVEL_FAN_MAX:
|
||||||
#temp_get = temp_get + temp_test_data
|
current_state=LEVEL_FAN_MID
|
||||||
#print "Unit test:temp_get=%d"%temp_get
|
logging.debug("current_state=LEVEL_FAN_MID")
|
||||||
|
else: #AFO
|
||||||
fan_policy_state=self.get_state_from_fan_policy(temp_get, fan_policy)
|
psu_full_load=check_psu_loading()
|
||||||
#print "temp3=%d"%temp3
|
for i in range (0, thermal.THERMAL_NUM_MAX):
|
||||||
#print "temp4=%d"%temp4
|
if ori_state==LEVEL_FAN_MID:
|
||||||
#print "temp_get=%d"%temp_get
|
if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]:
|
||||||
|
current_state=LEVEL_FAN_MAX
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if psu_full_load!=True and thermal_val[i] <= fan_thermal_spec["mid_to_min_temp"][i]:
|
||||||
|
mid_to_min=mid_to_min+1
|
||||||
|
elif ori_state==LEVEL_FAN_MIN:
|
||||||
|
if psu_full_load==True:
|
||||||
|
current_state=LEVEL_FAN_MID
|
||||||
|
logging.debug("psu_full_load, set current_state=LEVEL_FAN_MID")
|
||||||
|
if thermal_val[i] >= fan_thermal_spec["min_to_mid_temp"][i]:
|
||||||
|
current_state=LEVEL_FAN_MID
|
||||||
|
|
||||||
|
else:
|
||||||
|
if thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i] :
|
||||||
|
max_to_mid=max_to_mid+1
|
||||||
|
if fan_policy_alarm==0:
|
||||||
|
if thermal_val[i] >= fan_thermal_spec["max_to_yellow_alarm"][i]:
|
||||||
|
if send_yellow_alarm==0:
|
||||||
|
logging.warning('Alarm-Yellow for temperature high is detected')
|
||||||
|
fan_policy_alarm=LEVEL_FAN_YELLOW_ALARM
|
||||||
|
send_yellow_alarm=1
|
||||||
|
elif fan_policy_alarm==LEVEL_FAN_YELLOW_ALARM:
|
||||||
|
if thermal_val[i] >= fan_thermal_spec["yellow_to_red_alarm"][i]:
|
||||||
|
if send_red_alarm==0:
|
||||||
|
logging.warning('Alarm-Red for temperature high is detected')
|
||||||
|
fan_policy_alarm=LEVEL_FAN_RED_ALARM
|
||||||
|
send_red_alarm=1
|
||||||
|
elif fan_policy_alarm==LEVEL_FAN_RED_ALARM:
|
||||||
|
if thermal_val[i] >= fan_thermal_spec["red_alarm_to_shutdown"][i]:
|
||||||
|
logging.critical('Alarm-Critical for temperature high is detected, shutdown DUT')
|
||||||
|
fan_policy_alarm=LEVEL_FAN_SHUTDOWN
|
||||||
|
time.sleep(2)
|
||||||
|
power_off_dut()
|
||||||
|
|
||||||
logging.debug('lm75_48=%d, lm75_49=%d, lm75_4a=%d, lm_4b=%d, lm_4b=%d', temp1,temp2,temp3,temp4,temp5)
|
if max_to_mid==thermal.THERMAL_NUM_MAX and ori_state==LEVEL_FAN_MAX:
|
||||||
logging.debug('ori_state=%d, fan_policy_state=%d', ori_state, fan_policy_state)
|
current_state=LEVEL_FAN_MID
|
||||||
new_pwm = fan_policy[fan_policy_state][0]
|
if fan_policy_alarm!=0:
|
||||||
if fan_fail==0:
|
logging.warning('Alarm for temperature high is cleared')
|
||||||
logging.debug('new_fan_cycle=%d', new_pwm)
|
fan_policy_alarm=0
|
||||||
|
send_yellow_alarm=0
|
||||||
if fan_fail==0:
|
send_red_alarm=0
|
||||||
if new_pwm!=ori_pwm:
|
test_temp_revert=0
|
||||||
fan.set_fan_duty_cycle(new_pwm)
|
logging.debug("current_state=LEVEL_FAN_MID")
|
||||||
logging.info('Set fan speed from %d to %d', ori_pwm, new_pwm)
|
|
||||||
|
if mid_to_min==thermal.THERMAL_NUM_MAX and ori_state==LEVEL_FAN_MID:
|
||||||
|
if psu_full_load==0:
|
||||||
|
current_state=LEVEL_FAN_MIN
|
||||||
|
logging.debug("current_state=LEVEL_FAN_MIN")
|
||||||
|
|
||||||
#Check Fan status
|
#Check Fan status
|
||||||
for i in range (fan.FAN_NUM_1_IDX, fan.FAN_NUM_ON_MAIN_BROAD+1):
|
for i in range (fan.FAN_NUM_1_IDX, fan.FAN_NUM_ON_MAIN_BROAD+1):
|
||||||
if fan.get_fan_status(i)==0:
|
if fan.get_fan_status(i)==0:
|
||||||
new_pwm=100
|
new_duty_cycle=100
|
||||||
logging.debug('fan_%d fail, set pwm to 100',i)
|
logging.debug('fan_%d fail, set duty_cycle to 100',i)
|
||||||
if test_temp==0:
|
if test_temp==0:
|
||||||
fan_fail=1
|
fan_fail=1
|
||||||
fan.set_fan_duty_cycle(new_pwm)
|
fan.set_fan_duty_cycle(new_duty_cycle)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
fan_fail=0
|
fan_fail=0
|
||||||
|
|
||||||
#if fan_policy_state == ori_state:
|
if current_state!=ori_state:
|
||||||
# return True
|
fan_policy_state=current_state
|
||||||
#else:
|
new_duty_cycle=fan_policy[current_state][0]
|
||||||
new_state = fan_policy_state
|
logging.debug("fan_policy_state=%d, new_duty_cycle=%d", fan_policy_state, new_duty_cycle)
|
||||||
|
if new_duty_cycle!=ori_duty_cycle and fan_fail==0:
|
||||||
#logging.warning('Temperature high alarm testing')
|
fan.set_fan_duty_cycle(new_duty_cycle)
|
||||||
if ori_state==LEVEL_FAN_DEF:
|
return True
|
||||||
if new_state==LEVEL_TEMP_HIGH:
|
if new_duty_cycle==0 and fan_fail==0:
|
||||||
if alarm_state==0:
|
fan.set_fan_duty_cycle(FAN_DUTY_CYCLE_MAX)
|
||||||
logging.warning('Alarm for temperature high is detected')
|
|
||||||
alarm_state=1
|
|
||||||
if new_state==LEVEL_TEMP_CRITICAL:
|
|
||||||
logging.critical('Alarm for temperature critical is detected, reboot DUT')
|
|
||||||
time.sleep(2)
|
|
||||||
os.system('reboot')
|
|
||||||
if ori_state==LEVEL_FAN_MID:
|
|
||||||
if new_state==LEVEL_TEMP_HIGH:
|
|
||||||
if alarm_state==0:
|
|
||||||
logging.warning('Alarm for temperature high is detected')
|
|
||||||
alarm_state=1
|
|
||||||
if new_state==LEVEL_TEMP_CRITICAL:
|
|
||||||
logging.critical('Alarm for temperature critical is detected')
|
|
||||||
time.sleep(2)
|
|
||||||
os.system('reboot')
|
|
||||||
if ori_state==LEVEL_FAN_MAX:
|
|
||||||
if new_state==LEVEL_TEMP_HIGH:
|
|
||||||
if alarm_state==0:
|
|
||||||
logging.warning('Alarm for temperature high is detected')
|
|
||||||
alarm_state=1
|
|
||||||
if new_state==LEVEL_TEMP_CRITICAL:
|
|
||||||
logging.critical('Alarm for temperature critical is detected')
|
|
||||||
time.sleep(2)
|
|
||||||
os.system('reboot')
|
|
||||||
if alarm_state==1:
|
|
||||||
if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm
|
|
||||||
logging.warning('Alarm for temperature high is cleared')
|
|
||||||
alarm_state=0
|
|
||||||
if ori_state==LEVEL_TEMP_HIGH:
|
|
||||||
if new_state==LEVEL_TEMP_CRITICAL:
|
|
||||||
logging.critical('Alarm for temperature critical is detected')
|
|
||||||
time.sleep(2)
|
|
||||||
os.system('reboot')
|
|
||||||
if new_state <= LEVEL_FAN_MID:
|
|
||||||
logging.warning('Alarm for temperature high is cleared')
|
|
||||||
alarm_state=0
|
|
||||||
if new_state <= LEVEL_FAN_MAX:
|
|
||||||
if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm
|
|
||||||
logging.warning('Alarm for temperature high is cleared')
|
|
||||||
alarm_state=0
|
|
||||||
if ori_state==LEVEL_TEMP_CRITICAL:
|
|
||||||
if new_state <= LEVEL_FAN_MAX:
|
|
||||||
logging.warning('Alarm for temperature critical is cleared')
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
@ -318,26 +512,25 @@ def main(argv):
|
|||||||
log_file = arg
|
log_file = arg
|
||||||
|
|
||||||
if sys.argv[1]== '-t':
|
if sys.argv[1]== '-t':
|
||||||
if len(sys.argv)!=7:
|
if len(sys.argv)!=10:
|
||||||
print "temp test, need input six temp"
|
print "temp test, need input 8 temp"
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
i=0
|
i=0
|
||||||
for x in range(2, 7):
|
for x in range(2, 10):
|
||||||
test_temp_list[i]= int(sys.argv[x])*1000
|
test_temp_list[i]= int(sys.argv[x])*1000
|
||||||
i=i+1
|
i=i+1
|
||||||
test_temp = 1
|
test_temp = 1
|
||||||
log_level = logging.DEBUG
|
log_level = logging.DEBUG
|
||||||
print test_temp_list
|
print test_temp_list
|
||||||
|
|
||||||
fan = FanUtil()
|
fan = FanUtil()
|
||||||
fan.set_fan_duty_cycle(38)
|
fan.set_fan_duty_cycle(100)
|
||||||
print "set default fan speed to 37.5%"
|
|
||||||
monitor = device_monitor(log_file, log_level)
|
monitor = device_monitor(log_file, log_level)
|
||||||
# Loop forever, doing something useful hopefully:
|
# Loop forever, doing something useful hopefully:
|
||||||
while True:
|
while True:
|
||||||
#monitor.manage_fans()
|
monitor.manage_fans()
|
||||||
time.sleep(5)
|
time.sleep(10)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main(sys.argv[1:])
|
main(sys.argv[1:])
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 8c45a8e111534f9d4337d3552eaf08881fb19d30
|
Subproject commit 7b39cf3400dd728494b91810db9cc82542a22584
|
@ -141,6 +141,8 @@ start)
|
|||||||
sleep 0.1
|
sleep 0.1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
/bin/sh /usr/local/bin/platform_api_mgnt.sh init
|
||||||
|
|
||||||
echo "done."
|
echo "done."
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
dx010/scripts/dx010_check_qsfp.sh usr/local/bin
|
dx010/scripts/dx010_check_qsfp.sh usr/local/bin
|
||||||
dx010/cfg/dx010-modules.conf etc/modules-load.d
|
dx010/cfg/dx010-modules.conf etc/modules-load.d
|
||||||
dx010/systemd/platform-modules-dx010.service lib/systemd/system
|
dx010/systemd/platform-modules-dx010.service lib/systemd/system
|
||||||
|
dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0
|
||||||
|
services/platform_api/platform_api_mgnt.sh usr/local/bin
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
depmod -a
|
depmod -a
|
||||||
systemctl enable platform-modules-dx010.service
|
systemctl enable platform-modules-dx010.service
|
||||||
systemctl start platform-modules-dx010.service
|
systemctl start platform-modules-dx010.service
|
||||||
|
|
||||||
|
/usr/local/bin/platform_api_mgnt.sh install
|
||||||
|
|
||||||
|
@ -69,6 +69,8 @@ start)
|
|||||||
echo "both" > /sys/devices/platform/e1031.smc/SFP/modabs_trig
|
echo "both" > /sys/devices/platform/e1031.smc/SFP/modabs_trig
|
||||||
echo 0 > /sys/devices/platform/e1031.smc/SFP/modabs_mask
|
echo 0 > /sys/devices/platform/e1031.smc/SFP/modabs_mask
|
||||||
|
|
||||||
|
/bin/sh /usr/local/bin/platform_api_mgnt.sh init
|
||||||
|
|
||||||
echo "done."
|
echo "done."
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
@ -3,3 +3,5 @@ haliburton/systemd/platform-modules-haliburton.service lib/systemd/system
|
|||||||
haliburton/script/fancontrol.sh etc/init.d
|
haliburton/script/fancontrol.sh etc/init.d
|
||||||
services/fancontrol/fancontrol.service lib/systemd/system
|
services/fancontrol/fancontrol.service lib/systemd/system
|
||||||
services/fancontrol/fancontrol usr/local/bin
|
services/fancontrol/fancontrol usr/local/bin
|
||||||
|
haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0
|
||||||
|
services/platform_api/platform_api_mgnt.sh usr/local/bin
|
||||||
|
@ -3,4 +3,6 @@ systemctl enable platform-modules-haliburton.service
|
|||||||
systemctl enable fancontrol.service
|
systemctl enable fancontrol.service
|
||||||
|
|
||||||
systemctl start platform-modules-haliburton.service
|
systemctl start platform-modules-haliburton.service
|
||||||
systemctl start fancontrol.service
|
systemctl start fancontrol.service
|
||||||
|
|
||||||
|
/usr/local/bin/platform_api_mgnt.sh install
|
||||||
|
@ -13,6 +13,9 @@ MODULE_DIRS:= dx010 haliburton
|
|||||||
override_dh_auto_build:
|
override_dh_auto_build:
|
||||||
(for mod in $(MODULE_DIRS); do \
|
(for mod in $(MODULE_DIRS); do \
|
||||||
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
|
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
|
||||||
|
cd $(MOD_SRC_DIR)/$${mod}; \
|
||||||
|
python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \
|
||||||
|
cd $(MOD_SRC_DIR); \
|
||||||
done)
|
done)
|
||||||
|
|
||||||
override_dh_auto_install:
|
override_dh_auto_install:
|
||||||
|
34
platform/broadcom/sonic-platform-modules-cel/dx010/setup.py
Normal file
34
platform/broadcom/sonic-platform-modules-cel/dx010/setup.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
DEVICE_NAME = 'celestica'
|
||||||
|
HW_SKU = 'x86_64-cel_seastone-r0'
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='sonic-platform',
|
||||||
|
version='1.0',
|
||||||
|
description='SONiC platform API implementation on Celestica Platforms',
|
||||||
|
license='Apache 2.0',
|
||||||
|
author='SONiC Team',
|
||||||
|
author_email='linuxnetdev@microsoft.com',
|
||||||
|
url='https://github.com/Azure/sonic-buildimage',
|
||||||
|
maintainer='Wirut Getbamrung',
|
||||||
|
maintainer_email='wgetbumr@celestica.com',
|
||||||
|
packages=[
|
||||||
|
'sonic_platform',
|
||||||
|
],
|
||||||
|
package_dir={
|
||||||
|
'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)},
|
||||||
|
classifiers=[
|
||||||
|
'Development Status :: 3 - Alpha',
|
||||||
|
'Environment :: Plugins',
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'Intended Audience :: Information Technology',
|
||||||
|
'Intended Audience :: System Administrators',
|
||||||
|
'License :: OSI Approved :: Apache Software License',
|
||||||
|
'Natural Language :: English',
|
||||||
|
'Operating System :: POSIX :: Linux',
|
||||||
|
'Programming Language :: Python :: 2.7',
|
||||||
|
'Topic :: Utilities',
|
||||||
|
],
|
||||||
|
keywords='sonic SONiC platform PLATFORM',
|
||||||
|
)
|
@ -0,0 +1,34 @@
|
|||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
DEVICE_NAME = 'celestica'
|
||||||
|
HW_SKU = 'x86_64-cel_e1031-r0'
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='sonic-platform',
|
||||||
|
version='1.0',
|
||||||
|
description='SONiC platform API implementation on Celestica Platforms',
|
||||||
|
license='Apache 2.0',
|
||||||
|
author='SONiC Team',
|
||||||
|
author_email='linuxnetdev@microsoft.com',
|
||||||
|
url='https://github.com/Azure/sonic-buildimage',
|
||||||
|
maintainer='Wirut Getbamrung',
|
||||||
|
maintainer_email='wgetbumr@celestica.com',
|
||||||
|
packages=[
|
||||||
|
'sonic_platform',
|
||||||
|
],
|
||||||
|
package_dir={
|
||||||
|
'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)},
|
||||||
|
classifiers=[
|
||||||
|
'Development Status :: 3 - Alpha',
|
||||||
|
'Environment :: Plugins',
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'Intended Audience :: Information Technology',
|
||||||
|
'Intended Audience :: System Administrators',
|
||||||
|
'License :: OSI Approved :: Apache Software License',
|
||||||
|
'Natural Language :: English',
|
||||||
|
'Operating System :: POSIX :: Linux',
|
||||||
|
'Programming Language :: Python :: 2.7',
|
||||||
|
'Topic :: Utilities',
|
||||||
|
],
|
||||||
|
keywords='sonic SONiC platform PLATFORM',
|
||||||
|
)
|
@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
PREV_REBOOT_CAUSE="/host/reboot-cause/"
|
||||||
|
DEVICE="/usr/share/sonic/device"
|
||||||
|
PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
|
||||||
|
FILES=$DEVICE/$PLATFORM/api_files
|
||||||
|
|
||||||
|
install() {
|
||||||
|
# Install sonic-platform package
|
||||||
|
if [ -e $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl ]; then
|
||||||
|
pip install $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
# mount needed files for sonic-platform package
|
||||||
|
mkdir -p $FILES
|
||||||
|
|
||||||
|
mkdir -p $FILES/reboot-cause
|
||||||
|
mount -B $PREV_REBOOT_CAUSE $FILES/reboot-cause
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit() {
|
||||||
|
# deinit sonic-platform package
|
||||||
|
umount -f $PREV_REBOOT_CAUSE $FILES/reboot-cause >/dev/null 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall() {
|
||||||
|
# Uninstall sonic-platform package
|
||||||
|
pip uninstall -y sonic-platform >/dev/null 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
install | uninstall | init | deinit)
|
||||||
|
$1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {install|uninstall|init|deinit}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
@ -12,3 +12,4 @@ s6100/scripts/platform_watchdog_disable.sh usr/local/bin
|
|||||||
s6100/scripts/sensors usr/bin
|
s6100/scripts/sensors usr/bin
|
||||||
s6100/systemd/platform-modules-s6100.service etc/systemd/system
|
s6100/systemd/platform-modules-s6100.service etc/systemd/system
|
||||||
s6100/systemd/s6100-lpc-monitor.service etc/systemd/system
|
s6100/systemd/s6100-lpc-monitor.service etc/systemd/system
|
||||||
|
tools/flashrom/flashrom usr/local/bin/
|
||||||
|
@ -22,7 +22,7 @@ start)
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
stop)
|
stop)
|
||||||
/usr/local/bin/z9100_platform.sh deinit
|
/usr/local/bin/z9264f_platform.sh deinit
|
||||||
echo "done."
|
echo "done."
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
import datetime
|
||||||
from sonic_platform_base.chassis_base import ChassisBase
|
from sonic_platform_base.chassis_base import ChassisBase
|
||||||
from sonic_platform.sfp import Sfp
|
from sonic_platform.sfp import Sfp
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
@ -22,16 +24,19 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
MAILBOX_DIR = "/sys/devices/platform/dell-s6000-cpld.0"
|
MAILBOX_DIR = "/sys/devices/platform/dell-s6000-cpld.0"
|
||||||
|
|
||||||
|
sfp_control = ""
|
||||||
|
PORT_START = 0
|
||||||
|
PORT_END = 0
|
||||||
reset_reason_dict = {}
|
reset_reason_dict = {}
|
||||||
reset_reason_dict[0xe] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE
|
reset_reason_dict[0xe] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE
|
||||||
reset_reason_dict[0x6] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE
|
reset_reason_dict[0x6] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Initialize SFP list
|
# Initialize SFP list
|
||||||
PORT_START = 0
|
self.PORT_START = 0
|
||||||
PORT_END = 31
|
self.PORT_END = 31
|
||||||
EEPROM_OFFSET = 20
|
EEPROM_OFFSET = 20
|
||||||
PORTS_IN_BLOCK = (PORT_END + 1)
|
PORTS_IN_BLOCK = (self.PORT_END + 1)
|
||||||
|
|
||||||
# sfp.py will read eeprom contents and retrive the eeprom data.
|
# sfp.py will read eeprom contents and retrive the eeprom data.
|
||||||
# It will also provide support sfp controls like reset and setting
|
# It will also provide support sfp controls like reset and setting
|
||||||
@ -39,12 +44,16 @@ class Chassis(ChassisBase):
|
|||||||
# We pass the eeprom path and sfp control path from chassis.py
|
# We pass the eeprom path and sfp control path from chassis.py
|
||||||
# So that sfp.py implementation can be generic to all platforms
|
# So that sfp.py implementation can be generic to all platforms
|
||||||
eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom"
|
eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom"
|
||||||
sfp_control = "/sys/devices/platform/dell-s6000-cpld.0/"
|
self.sfp_control = "/sys/devices/platform/dell-s6000-cpld.0/"
|
||||||
|
|
||||||
for index in range(0, PORTS_IN_BLOCK):
|
for index in range(0, PORTS_IN_BLOCK):
|
||||||
eeprom_path = eeprom_base.format(index + EEPROM_OFFSET)
|
eeprom_path = eeprom_base.format(index + EEPROM_OFFSET)
|
||||||
sfp_node = Sfp(index, 'QSFP', eeprom_path, sfp_control, index)
|
sfp_node = Sfp(index, 'QSFP', eeprom_path, self.sfp_control, index)
|
||||||
self._sfp_list.append(sfp_node)
|
self._sfp_list.append(sfp_node)
|
||||||
|
|
||||||
|
# Get Transceiver status
|
||||||
|
self.modprs_register = self._get_transceiver_status()
|
||||||
|
|
||||||
def get_register(self, reg_name):
|
def get_register(self, reg_name):
|
||||||
rv = 'ERR'
|
rv = 'ERR'
|
||||||
mb_reg_file = self.MAILBOX_DIR+'/'+reg_name
|
mb_reg_file = self.MAILBOX_DIR+'/'+reg_name
|
||||||
@ -76,3 +85,69 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
||||||
|
|
||||||
|
def _get_transceiver_status(self):
|
||||||
|
presence_ctrl = self.sfp_control + 'qsfp_modprs'
|
||||||
|
try:
|
||||||
|
reg_file = open(presence_ctrl)
|
||||||
|
|
||||||
|
except IOError as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
content = reg_file.readline().rstrip()
|
||||||
|
reg_file.close()
|
||||||
|
|
||||||
|
return int(content, 16)
|
||||||
|
|
||||||
|
def get_transceiver_change_event(self, timeout=0):
|
||||||
|
"""
|
||||||
|
Returns a dictionary containing sfp changes which have
|
||||||
|
experienced a change at chassis level
|
||||||
|
"""
|
||||||
|
start_time = time.time()
|
||||||
|
port_dict = {}
|
||||||
|
port = self.PORT_START
|
||||||
|
forever = False
|
||||||
|
|
||||||
|
if timeout == 0:
|
||||||
|
forever = True
|
||||||
|
elif timeout > 0:
|
||||||
|
timeout = timeout / float(1000) # Convert to secs
|
||||||
|
else:
|
||||||
|
return False, {}
|
||||||
|
end_time = start_time + timeout
|
||||||
|
|
||||||
|
if (start_time > end_time):
|
||||||
|
return False, {} # Time wrap or possibly incorrect timeout
|
||||||
|
|
||||||
|
while (timeout >= 0):
|
||||||
|
# Check for OIR events and return updated port_dict
|
||||||
|
reg_value = self._get_transceiver_status()
|
||||||
|
if (reg_value != self.modprs_register):
|
||||||
|
changed_ports = (self.modprs_register ^ reg_value)
|
||||||
|
while (port >= self.PORT_START and port <= self.PORT_END):
|
||||||
|
# Mask off the bit corresponding to our port
|
||||||
|
mask = (1 << port)
|
||||||
|
if (changed_ports & mask):
|
||||||
|
# ModPrsL is active low
|
||||||
|
if reg_value & mask == 0:
|
||||||
|
port_dict[port] = '1'
|
||||||
|
else:
|
||||||
|
port_dict[port] = '0'
|
||||||
|
port += 1
|
||||||
|
|
||||||
|
# Update reg value
|
||||||
|
self.modprs_register = reg_value
|
||||||
|
return True, port_dict
|
||||||
|
|
||||||
|
if forever:
|
||||||
|
time.sleep(1)
|
||||||
|
else:
|
||||||
|
timeout = end_time - time.time()
|
||||||
|
if timeout >= 1:
|
||||||
|
time.sleep(1) # We poll at 1 second granularity
|
||||||
|
else:
|
||||||
|
if timeout > 0:
|
||||||
|
time.sleep(timeout)
|
||||||
|
return True, {}
|
||||||
|
return False, {}
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
../../s6100/sonic_platform/sfp.py
|
|
@ -0,0 +1,876 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# DELLEMC
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC Platform Base API and
|
||||||
|
# provides the platform information
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
from sonic_platform_base.chassis_base import ChassisBase
|
||||||
|
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
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
|
||||||
|
PAGE_OFFSET = 0
|
||||||
|
KEY_OFFSET = 1
|
||||||
|
KEY_WIDTH = 2
|
||||||
|
FUNC_NAME = 3
|
||||||
|
|
||||||
|
INFO_OFFSET = 128
|
||||||
|
DOM_OFFSET = 0
|
||||||
|
DOM_OFFSET1 = 384
|
||||||
|
|
||||||
|
cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)',
|
||||||
|
'Length OM1(m)', 'Length Cable Assembly(m)')
|
||||||
|
|
||||||
|
compliance_code_tup = (
|
||||||
|
'10/40G Ethernet Compliance Code',
|
||||||
|
'SONET Compliance codes',
|
||||||
|
'SAS/SATA compliance codes',
|
||||||
|
'Gigabit Ethernet Compliant codes',
|
||||||
|
'Fibre Channel link length/Transmitter Technology',
|
||||||
|
'Fibre Channel transmission media',
|
||||||
|
'Fibre Channel Speed')
|
||||||
|
|
||||||
|
info_dict_keys = ['type', 'hardwarerev', 'serialnum',
|
||||||
|
'manufacturename', 'modelname', 'Connector',
|
||||||
|
'encoding', 'ext_identifier', 'ext_rateselect_compliance',
|
||||||
|
'cable_type', 'cable_length', 'nominal_bit_rate',
|
||||||
|
'specification_compliance', 'vendor_date', 'vendor_oui']
|
||||||
|
|
||||||
|
dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status',
|
||||||
|
'power_lpmode', 'tx_disable', 'tx_disable_channel',
|
||||||
|
'temperature', 'voltage', 'rx1power',
|
||||||
|
'rx2power', 'rx3power', 'rx4power',
|
||||||
|
'tx1bias', 'tx2bias', 'tx3bias',
|
||||||
|
'tx4bias', 'tx1power', 'tx2power',
|
||||||
|
'tx3power', 'tx4power']
|
||||||
|
|
||||||
|
threshold_dict_keys = ['temphighalarm', 'temphighwarning',
|
||||||
|
'templowalarm', 'templowwarning',
|
||||||
|
'vcchighalarm', 'vcchighwarning',
|
||||||
|
'vcclowalarm', 'vcclowwarning',
|
||||||
|
'rxpowerhighalarm', 'rxpowerhighwarning',
|
||||||
|
'rxpowerlowalarm', 'rxpowerlowwarning',
|
||||||
|
'txpowerhighalarm', 'txpowerhighwarning',
|
||||||
|
'txpowerlowalarm', 'txpowerlowwarning',
|
||||||
|
'txbiashighalarm', 'txbiashighwarning',
|
||||||
|
'txbiaslowalarm', 'txbiaslowwarning']
|
||||||
|
|
||||||
|
sff8436_parser = {
|
||||||
|
'reset_status': [DOM_OFFSET, 2, 1, 'parse_dom_status_indicator'],
|
||||||
|
'rx_los': [DOM_OFFSET, 3, 1, 'parse_dom_tx_rx_los'],
|
||||||
|
'tx_fault': [DOM_OFFSET, 4, 1, 'parse_dom_tx_fault'],
|
||||||
|
'tx_disable': [DOM_OFFSET, 86, 1, 'parse_dom_tx_disable'],
|
||||||
|
'power_lpmode': [DOM_OFFSET, 93, 1, 'parse_dom_power_control'],
|
||||||
|
'power_override': [DOM_OFFSET, 93, 1, 'parse_dom_power_control'],
|
||||||
|
'Temperature': [DOM_OFFSET, 22, 2, 'parse_temperature'],
|
||||||
|
'Voltage': [DOM_OFFSET, 26, 2, 'parse_voltage'],
|
||||||
|
'ChannelMonitor': [DOM_OFFSET, 34, 16, 'parse_channel_monitor_params'],
|
||||||
|
|
||||||
|
'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'],
|
||||||
|
'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'],
|
||||||
|
'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'ext_rateselect_compliance':
|
||||||
|
[INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'specification_compliance':
|
||||||
|
[INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'],
|
||||||
|
'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'],
|
||||||
|
'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'],
|
||||||
|
'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'],
|
||||||
|
'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'],
|
||||||
|
'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'],
|
||||||
|
'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'],
|
||||||
|
'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Sfp(SfpBase):
|
||||||
|
"""
|
||||||
|
DELLEMC Platform-specific Sfp class
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, index, sfp_type, eeprom_path,
|
||||||
|
sfp_control, sfp_ctrl_idx):
|
||||||
|
SfpBase.__init__(self)
|
||||||
|
self.sfp_type = sfp_type
|
||||||
|
self.index = index
|
||||||
|
self.eeprom_path = eeprom_path
|
||||||
|
self.sfp_control = sfp_control
|
||||||
|
self.sfp_ctrl_idx = sfp_ctrl_idx
|
||||||
|
self.sfpInfo = sff8436InterfaceId()
|
||||||
|
self.sfpDomInfo = sff8436Dom()
|
||||||
|
|
||||||
|
def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes):
|
||||||
|
eeprom_raw = []
|
||||||
|
try:
|
||||||
|
eeprom = open(eeprom_path, mode="rb", buffering=0)
|
||||||
|
except IOError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for i in range(0, num_bytes):
|
||||||
|
eeprom_raw.append("0x00")
|
||||||
|
|
||||||
|
try:
|
||||||
|
eeprom.seek(offset)
|
||||||
|
raw = eeprom.read(num_bytes)
|
||||||
|
except IOError:
|
||||||
|
eeprom.close()
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
for n in range(0, num_bytes):
|
||||||
|
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
|
||||||
|
except BaseException:
|
||||||
|
eeprom.close()
|
||||||
|
return None
|
||||||
|
|
||||||
|
eeprom.close()
|
||||||
|
return eeprom_raw
|
||||||
|
|
||||||
|
def _get_eeprom_data(self, eeprom_key):
|
||||||
|
eeprom_data = None
|
||||||
|
page_offset = None
|
||||||
|
|
||||||
|
if (self.sfpInfo is None):
|
||||||
|
return None
|
||||||
|
|
||||||
|
page_offset = sff8436_parser[eeprom_key][PAGE_OFFSET]
|
||||||
|
eeprom_data_raw = self._read_eeprom_bytes(
|
||||||
|
self.eeprom_path,
|
||||||
|
(sff8436_parser[eeprom_key][PAGE_OFFSET] +
|
||||||
|
sff8436_parser[eeprom_key][KEY_OFFSET]),
|
||||||
|
sff8436_parser[eeprom_key][KEY_WIDTH])
|
||||||
|
if (eeprom_data_raw is not None):
|
||||||
|
# Offset 128 is used to retrieve sff8436InterfaceId Info
|
||||||
|
# Offset 0 is used to retrieve sff8436Dom Info
|
||||||
|
if (page_offset == 128):
|
||||||
|
eeprom_data = getattr(
|
||||||
|
self.sfpInfo, sff8436_parser[eeprom_key][FUNC_NAME])(
|
||||||
|
eeprom_data_raw, 0)
|
||||||
|
else:
|
||||||
|
eeprom_data = getattr(
|
||||||
|
self.sfpDomInfo, sff8436_parser[eeprom_key][FUNC_NAME])(
|
||||||
|
eeprom_data_raw, 0)
|
||||||
|
|
||||||
|
return eeprom_data
|
||||||
|
|
||||||
|
def get_transceiver_info(self):
|
||||||
|
"""
|
||||||
|
Retrieves transceiver info of this SFP
|
||||||
|
"""
|
||||||
|
transceiver_info_dict = {}
|
||||||
|
compliance_code_dict = {}
|
||||||
|
transceiver_info_dict = dict.fromkeys(info_dict_keys, 'N/A')
|
||||||
|
|
||||||
|
# BaseInformation
|
||||||
|
iface_data = self._get_eeprom_data('type')
|
||||||
|
if (iface_data is not None):
|
||||||
|
connector = iface_data['data']['Connector']['value']
|
||||||
|
encoding = iface_data['data']['EncodingCodes']['value']
|
||||||
|
ext_id = iface_data['data']['Extended Identifier']['value']
|
||||||
|
rate_identifier = iface_data['data']['RateIdentifier']['value']
|
||||||
|
identifier = iface_data['data']['type']['value']
|
||||||
|
bit_rate = str(
|
||||||
|
iface_data['data']['Nominal Bit Rate(100Mbs)']['value'])
|
||||||
|
|
||||||
|
for key in compliance_code_tup:
|
||||||
|
if key in iface_data['data']['Specification compliance']['value']:
|
||||||
|
compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value']
|
||||||
|
for key in cable_length_tup:
|
||||||
|
if key in iface_data['data']:
|
||||||
|
cable_type = key
|
||||||
|
cable_length = str(iface_data['data'][key]['value'])
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor Date
|
||||||
|
vendor_date_data = self._get_eeprom_data('vendor_date')
|
||||||
|
if (vendor_date_data is not None):
|
||||||
|
vendor_date = vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor Name
|
||||||
|
vendor_name_data = self._get_eeprom_data('manufacturename')
|
||||||
|
if (vendor_name_data is not None):
|
||||||
|
vendor_name = vendor_name_data['data']['Vendor Name']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor OUI
|
||||||
|
vendor_oui_data = self._get_eeprom_data('vendor_oui')
|
||||||
|
if (vendor_oui_data is not None):
|
||||||
|
vendor_oui = vendor_oui_data['data']['Vendor OUI']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor PN
|
||||||
|
vendor_pn_data = self._get_eeprom_data('modelname')
|
||||||
|
if (vendor_pn_data is not None):
|
||||||
|
vendor_pn = vendor_pn_data['data']['Vendor PN']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor Revision
|
||||||
|
vendor_rev_data = self._get_eeprom_data('hardwarerev')
|
||||||
|
if (vendor_rev_data is not None):
|
||||||
|
vendor_rev = vendor_rev_data['data']['Vendor Rev']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor Serial Number
|
||||||
|
vendor_sn_data = self._get_eeprom_data('serialnum')
|
||||||
|
if (vendor_sn_data is not None):
|
||||||
|
vendor_sn = vendor_sn_data['data']['Vendor SN']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Fill The Dictionary and return
|
||||||
|
transceiver_info_dict['type'] = identifier
|
||||||
|
transceiver_info_dict['hardwarerev'] = vendor_rev
|
||||||
|
transceiver_info_dict['serialnum'] = vendor_sn
|
||||||
|
transceiver_info_dict['manufacturename'] = vendor_name
|
||||||
|
transceiver_info_dict['modelname'] = vendor_pn
|
||||||
|
transceiver_info_dict['Connector'] = connector
|
||||||
|
transceiver_info_dict['encoding'] = encoding
|
||||||
|
transceiver_info_dict['ext_identifier'] = ext_id
|
||||||
|
transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier
|
||||||
|
transceiver_info_dict['cable_type'] = cable_type
|
||||||
|
transceiver_info_dict['cable_length'] = cable_length
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = bit_rate
|
||||||
|
transceiver_info_dict['specification_compliance'] = str(
|
||||||
|
compliance_code_dict)
|
||||||
|
transceiver_info_dict['vendor_date'] = vendor_date
|
||||||
|
transceiver_info_dict['vendor_oui'] = vendor_oui
|
||||||
|
|
||||||
|
return transceiver_info_dict
|
||||||
|
|
||||||
|
def get_transceiver_threshold_info(self):
|
||||||
|
"""
|
||||||
|
Retrieves transceiver threshold info of this SFP
|
||||||
|
"""
|
||||||
|
transceiver_dom_threshold_dict = {}
|
||||||
|
transceiver_dom_threshold_dict = dict.fromkeys(
|
||||||
|
threshold_dict_keys, 'N/A')
|
||||||
|
|
||||||
|
# Module Threshold
|
||||||
|
module_threshold_data = self._get_eeprom_data('ModuleThreshold')
|
||||||
|
if (module_threshold_data is not None):
|
||||||
|
tempHighAlarm = module_threshold_data['data']['TempHighAlarm']['value']
|
||||||
|
tempLowAlarm = module_threshold_data['data']['TempLowAlarm']['value']
|
||||||
|
tempHighWarn = module_threshold_data['data']['TempHighWarning']['value']
|
||||||
|
tempLowWarn = module_threshold_data['data']['TempLowWarning']['value']
|
||||||
|
vccHighAlarm = module_threshold_data['data']['VccHighAlarm']['value']
|
||||||
|
vccLowAlarm = module_threshold_data['data']['VccLowAlarm']['value']
|
||||||
|
vccHighWarn = module_threshold_data['data']['VccHighWarning']['value']
|
||||||
|
vccLowWarn = module_threshold_data['data']['VccLowWarning']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Channel Threshold
|
||||||
|
channel_threshold_data = self._get_eeprom_data('ChannelThreshold')
|
||||||
|
if (channel_threshold_data is not None):
|
||||||
|
rxPowerHighAlarm = channel_threshold_data['data']['RxPowerHighAlarm']['value']
|
||||||
|
rxPowerLowAlarm = channel_threshold_data['data']['RxPowerLowAlarm']['value']
|
||||||
|
rxPowerHighWarn = channel_threshold_data['data']['RxPowerHighWarning']['value']
|
||||||
|
rxPowerLowWarn = channel_threshold_data['data']['RxPowerLowWarning']['value']
|
||||||
|
txBiasHighAlarm = channel_threshold_data['data']['TxBiasHighAlarm']['value']
|
||||||
|
txBiasLowAlarm = channel_threshold_data['data']['TxBiasLowAlarm']['value']
|
||||||
|
txBiasHighWarn = channel_threshold_data['data']['TxBiasHighWarning']['value']
|
||||||
|
txBiasLowWarn = channel_threshold_data['data']['TxBiasLowWarning']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_dom_threshold_dict['temphighalarm'] = tempHighAlarm
|
||||||
|
transceiver_dom_threshold_dict['templowalarm'] = tempLowAlarm
|
||||||
|
transceiver_dom_threshold_dict['temphighwarning'] = tempHighWarn
|
||||||
|
transceiver_dom_threshold_dict['templowwarning'] = tempLowWarn
|
||||||
|
transceiver_dom_threshold_dict['vcchighalarm'] = vccHighAlarm
|
||||||
|
transceiver_dom_threshold_dict['vcclowalarm'] = vccLowAlarm
|
||||||
|
transceiver_dom_threshold_dict['vcchighwarning'] = vccHighWarn
|
||||||
|
transceiver_dom_threshold_dict['vcclowwarning'] = vccLowWarn
|
||||||
|
transceiver_dom_threshold_dict['rxpowerhighalarm'] = rxPowerHighAlarm
|
||||||
|
transceiver_dom_threshold_dict['rxpowerlowalarm'] = rxPowerLowAlarm
|
||||||
|
transceiver_dom_threshold_dict['rxpowerhighwarning'] = rxPowerHighWarn
|
||||||
|
transceiver_dom_threshold_dict['rxpowerlowwarning'] = rxPowerLowWarn
|
||||||
|
transceiver_dom_threshold_dict['txbiashighalarm'] = txBiasHighAlarm
|
||||||
|
transceiver_dom_threshold_dict['txbiaslowalarm'] = txBiasLowAlarm
|
||||||
|
transceiver_dom_threshold_dict['txbiashighwarning'] = txBiasHighWarn
|
||||||
|
transceiver_dom_threshold_dict['txbiaslowwarning'] = txBiasLowWarn
|
||||||
|
|
||||||
|
return transceiver_dom_threshold_dict
|
||||||
|
|
||||||
|
def get_transceiver_bulk_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves transceiver bulk status of this SFP
|
||||||
|
"""
|
||||||
|
tx_bias_list = []
|
||||||
|
rx_power_list = []
|
||||||
|
transceiver_dom_dict = {}
|
||||||
|
transceiver_dom_dict = dict.fromkeys(dom_dict_keys, 'N/A')
|
||||||
|
|
||||||
|
# RxLos
|
||||||
|
rx_los = self.get_rx_los()
|
||||||
|
|
||||||
|
# TxFault
|
||||||
|
tx_fault = self.get_tx_fault()
|
||||||
|
|
||||||
|
# ResetStatus
|
||||||
|
reset_state = self.get_reset_status()
|
||||||
|
|
||||||
|
# LowPower Mode
|
||||||
|
lp_mode = self.get_lpmode()
|
||||||
|
|
||||||
|
# TxDisable
|
||||||
|
tx_disable = self.get_tx_disable()
|
||||||
|
|
||||||
|
# TxDisable Channel
|
||||||
|
tx_disable_channel = self.get_tx_disable_channel()
|
||||||
|
|
||||||
|
# Temperature
|
||||||
|
temperature = self.get_temperature()
|
||||||
|
|
||||||
|
# Voltage
|
||||||
|
voltage = self.get_voltage()
|
||||||
|
|
||||||
|
# Channel Monitor
|
||||||
|
channel_monitor_data = self._get_eeprom_data('ChannelMonitor')
|
||||||
|
if (channel_monitor_data is not None):
|
||||||
|
tx_bias = channel_monitor_data['data']['TX1Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = channel_monitor_data['data']['TX2Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = channel_monitor_data['data']['TX3Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = channel_monitor_data['data']['TX4Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
rx_power = channel_monitor_data['data']['RX1Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = channel_monitor_data['data']['RX2Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = channel_monitor_data['data']['RX3Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = channel_monitor_data['data']['RX4Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_dom_dict['rx_los'] = rx_los
|
||||||
|
transceiver_dom_dict['tx_fault'] = tx_fault
|
||||||
|
transceiver_dom_dict['reset_status'] = reset_state
|
||||||
|
transceiver_dom_dict['power_lpmode'] = lp_mode
|
||||||
|
transceiver_dom_dict['tx_disable'] = tx_disable
|
||||||
|
transceiver_dom_dict['tx_disable_channel'] = tx_disable_channel
|
||||||
|
transceiver_dom_dict['temperature'] = temperature
|
||||||
|
transceiver_dom_dict['voltage'] = voltage
|
||||||
|
transceiver_dom_dict['tx1bias'] = tx_bias_list[0]
|
||||||
|
transceiver_dom_dict['tx2bias'] = tx_bias_list[1]
|
||||||
|
transceiver_dom_dict['tx3bias'] = tx_bias_list[2]
|
||||||
|
transceiver_dom_dict['tx4bias'] = tx_bias_list[3]
|
||||||
|
transceiver_dom_dict['rx1power'] = rx_power_list[0]
|
||||||
|
transceiver_dom_dict['rx2power'] = rx_power_list[1]
|
||||||
|
transceiver_dom_dict['rx3power'] = rx_power_list[2]
|
||||||
|
transceiver_dom_dict['rx4power'] = rx_power_list[3]
|
||||||
|
|
||||||
|
return transceiver_dom_dict
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the name of the sfp
|
||||||
|
Returns : QSFP or QSFP+ or QSFP28
|
||||||
|
"""
|
||||||
|
iface_data = self._get_eeprom_data('type')
|
||||||
|
if (iface_data is not None):
|
||||||
|
identifier = iface_data['data']['type']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return identifier
|
||||||
|
|
||||||
|
def get_presence(self):
|
||||||
|
"""
|
||||||
|
Retrieves the presence of the sfp
|
||||||
|
"""
|
||||||
|
presence_ctrl = self.sfp_control + 'qsfp_modprs'
|
||||||
|
try:
|
||||||
|
reg_file = open(presence_ctrl)
|
||||||
|
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
|
||||||
|
mask = (1 << self.sfp_ctrl_idx)
|
||||||
|
|
||||||
|
# ModPrsL is active low
|
||||||
|
if ((reg_value & mask) == 0):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the sfp
|
||||||
|
"""
|
||||||
|
vendor_pn_data = self._get_eeprom_data('modelname')
|
||||||
|
if (vendor_pn_data is not None):
|
||||||
|
vendor_pn = vendor_pn_data['data']['Vendor PN']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return vendor_pn
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the sfp
|
||||||
|
"""
|
||||||
|
vendor_sn_data = self._get_eeprom_data('serialnum')
|
||||||
|
if (vendor_sn_data is not None):
|
||||||
|
vendor_sn = vendor_sn_data['data']['Vendor SN']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return vendor_sn
|
||||||
|
|
||||||
|
def get_reset_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the reset status of SFP
|
||||||
|
"""
|
||||||
|
reset_status = None
|
||||||
|
reset_ctrl = self.sfp_control + 'qsfp_reset'
|
||||||
|
try:
|
||||||
|
reg_file = open(reset_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) == 0):
|
||||||
|
reset_status = True
|
||||||
|
else:
|
||||||
|
reset_status = False
|
||||||
|
|
||||||
|
return reset_status
|
||||||
|
|
||||||
|
def get_rx_los(self):
|
||||||
|
"""
|
||||||
|
Retrieves the RX LOS (lost-of-signal) status of SFP
|
||||||
|
"""
|
||||||
|
rx_los = None
|
||||||
|
rx_los_list = []
|
||||||
|
|
||||||
|
rx_los_data = self._get_eeprom_data('rx_los')
|
||||||
|
if (rx_los_data is not None):
|
||||||
|
rx_los = rx_los_data['data']['Rx1LOS']['value']
|
||||||
|
if (rx_los is 'On'):
|
||||||
|
rx_los_list.append(True)
|
||||||
|
else:
|
||||||
|
rx_los_list.append(False)
|
||||||
|
rx_los = rx_los_data['data']['Rx2LOS']['value']
|
||||||
|
if (rx_los is 'On'):
|
||||||
|
rx_los_list.append(True)
|
||||||
|
else:
|
||||||
|
rx_los_list.append(False)
|
||||||
|
rx_los = rx_los_data['data']['Rx3LOS']['value']
|
||||||
|
if (rx_los is 'On'):
|
||||||
|
rx_los_list.append(True)
|
||||||
|
else:
|
||||||
|
rx_los_list.append(False)
|
||||||
|
rx_los = rx_los_data['data']['Rx4LOS']['value']
|
||||||
|
if (rx_los is 'On'):
|
||||||
|
rx_los_list.append(True)
|
||||||
|
else:
|
||||||
|
rx_los_list.append(False)
|
||||||
|
|
||||||
|
if (rx_los_list[0] and rx_los_list[1]
|
||||||
|
and rx_los_list[2] and rx_los_list[3]):
|
||||||
|
rx_los = True
|
||||||
|
else:
|
||||||
|
rx_los = False
|
||||||
|
|
||||||
|
return rx_los
|
||||||
|
|
||||||
|
def get_tx_fault(self):
|
||||||
|
"""
|
||||||
|
Retrieves the TX fault status of SFP
|
||||||
|
"""
|
||||||
|
tx_fault = None
|
||||||
|
tx_fault_list = []
|
||||||
|
|
||||||
|
tx_fault_data = self._get_eeprom_data('tx_fault')
|
||||||
|
if (tx_fault_data is not None):
|
||||||
|
tx_fault = tx_fault_data['data']['Tx1Fault']['value']
|
||||||
|
if (tx_fault is 'On'):
|
||||||
|
tx_fault_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_fault_list.append(False)
|
||||||
|
tx_fault = tx_fault_data['data']['Tx2Fault']['value']
|
||||||
|
if (tx_fault is 'On'):
|
||||||
|
tx_fault_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_fault_list.append(False)
|
||||||
|
tx_fault = tx_fault_data['data']['Tx3Fault']['value']
|
||||||
|
if (tx_fault is 'On'):
|
||||||
|
tx_fault_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_fault_list.append(False)
|
||||||
|
tx_fault = tx_fault_data['data']['Tx4Fault']['value']
|
||||||
|
if (tx_fault is 'On'):
|
||||||
|
tx_fault_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_fault_list.append(False)
|
||||||
|
|
||||||
|
if (tx_fault_list[0] and tx_fault_list[1]
|
||||||
|
and tx_fault_list[2] and tx_fault_list[3]):
|
||||||
|
tx_fault = True
|
||||||
|
else:
|
||||||
|
tx_fault = False
|
||||||
|
|
||||||
|
return tx_fault
|
||||||
|
|
||||||
|
def get_tx_disable(self):
|
||||||
|
"""
|
||||||
|
Retrieves the tx_disable status of this SFP
|
||||||
|
"""
|
||||||
|
tx_disable = None
|
||||||
|
tx_disable_list = []
|
||||||
|
|
||||||
|
tx_disable_data = self._get_eeprom_data('tx_disable')
|
||||||
|
if (tx_disable_data is not None):
|
||||||
|
tx_disable = tx_disable_data['data']['Tx1Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(False)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx2Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(False)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx3Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(False)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx4Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(False)
|
||||||
|
|
||||||
|
if (tx_disable_list[0] and tx_disable_list[1]
|
||||||
|
and tx_disable_list[2] and tx_disable_list[3]):
|
||||||
|
tx_disable = True
|
||||||
|
else:
|
||||||
|
tx_disable = False
|
||||||
|
|
||||||
|
return tx_disable
|
||||||
|
|
||||||
|
def get_tx_disable_channel(self):
|
||||||
|
"""
|
||||||
|
Retrieves the TX disabled channels in this SFP
|
||||||
|
"""
|
||||||
|
tx_disable = None
|
||||||
|
tx_disable_list = []
|
||||||
|
|
||||||
|
tx_disable_data = self._get_eeprom_data('tx_disable')
|
||||||
|
if (tx_disable_data is not None):
|
||||||
|
tx_disable = tx_disable_data['data']['Tx1Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(1)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(0)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx2Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(1)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(0)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx3Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(1)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(0)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx4Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(1)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(0)
|
||||||
|
|
||||||
|
bit4 = int(tx_disable_list[3]) * 8
|
||||||
|
bit3 = int(tx_disable_list[2]) * 4
|
||||||
|
bit2 = int(tx_disable_list[1]) * 2
|
||||||
|
bit1 = int(tx_disable_list[0]) * 1
|
||||||
|
|
||||||
|
tx_disable_channel = hex(bit4 + bit3 + bit2 + bit1)
|
||||||
|
|
||||||
|
return tx_disable_channel
|
||||||
|
|
||||||
|
def get_lpmode(self):
|
||||||
|
"""
|
||||||
|
Retrieves the lpmode (low power mode) status of this SFP
|
||||||
|
"""
|
||||||
|
lpmode_ctrl = self.sfp_control + 'qsfp_lpmode'
|
||||||
|
try:
|
||||||
|
reg_file = open(lpmode_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) == 0):
|
||||||
|
lpmode_state = False
|
||||||
|
else:
|
||||||
|
lpmode_state = True
|
||||||
|
|
||||||
|
return lpmode_state
|
||||||
|
|
||||||
|
def get_power_override(self):
|
||||||
|
"""
|
||||||
|
Retrieves the power-override status of this SFP
|
||||||
|
"""
|
||||||
|
power_override_state = None
|
||||||
|
|
||||||
|
# Reset Status
|
||||||
|
power_override_data = self._get_eeprom_data('power_override')
|
||||||
|
if (power_override_data is not None):
|
||||||
|
power_override = power_override_data['data']['PowerOverRide']['value']
|
||||||
|
if (power_override is 'On'):
|
||||||
|
power_override_state = True
|
||||||
|
else:
|
||||||
|
power_override_state = False
|
||||||
|
|
||||||
|
return power_override_state
|
||||||
|
|
||||||
|
def get_temperature(self):
|
||||||
|
"""
|
||||||
|
Retrieves the temperature of this SFP
|
||||||
|
"""
|
||||||
|
temperature = None
|
||||||
|
|
||||||
|
temperature_data = self._get_eeprom_data('Temperature')
|
||||||
|
if (temperature_data is not None):
|
||||||
|
temperature = temperature_data['data']['Temperature']['value']
|
||||||
|
|
||||||
|
return temperature
|
||||||
|
|
||||||
|
def get_voltage(self):
|
||||||
|
"""
|
||||||
|
Retrieves the supply voltage of this SFP
|
||||||
|
"""
|
||||||
|
voltage = None
|
||||||
|
|
||||||
|
voltage_data = self._get_eeprom_data('Voltage')
|
||||||
|
if (voltage_data is not None):
|
||||||
|
voltage = voltage_data['data']['Vcc']['value']
|
||||||
|
|
||||||
|
return voltage
|
||||||
|
|
||||||
|
def get_tx_bias(self):
|
||||||
|
"""
|
||||||
|
Retrieves the TX bias current of this SFP
|
||||||
|
"""
|
||||||
|
tx_bias = None
|
||||||
|
tx_bias_list = []
|
||||||
|
|
||||||
|
tx_bias_data = self._get_eeprom_data('ChannelMonitor')
|
||||||
|
if (tx_bias_data is not None):
|
||||||
|
tx_bias = tx_bias_data['data']['TX1Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = tx_bias_data['data']['TX2Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = tx_bias_data['data']['TX3Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = tx_bias_data['data']['TX4Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
|
||||||
|
return tx_bias_list
|
||||||
|
|
||||||
|
def get_rx_power(self):
|
||||||
|
"""
|
||||||
|
Retrieves the received optical power for this SFP
|
||||||
|
"""
|
||||||
|
rx_power = None
|
||||||
|
rx_power_list = []
|
||||||
|
|
||||||
|
rx_power_data = self._get_eeprom_data('ChannelMonitor')
|
||||||
|
if (rx_power_data is not None):
|
||||||
|
rx_power = rx_power_data['data']['RX1Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = rx_power_data['data']['RX2Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = rx_power_data['data']['RX3Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = rx_power_data['data']['RX4Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
|
||||||
|
return rx_power_list
|
||||||
|
|
||||||
|
|
||||||
|
def get_tx_power(self):
|
||||||
|
"""
|
||||||
|
Retrieves the TX power of this SFP
|
||||||
|
"""
|
||||||
|
tx_power = None
|
||||||
|
tx_power_list = []
|
||||||
|
|
||||||
|
tx_power_list.append('-infdBm')
|
||||||
|
tx_power_list.append('-infdBm')
|
||||||
|
tx_power_list.append('-infdBm')
|
||||||
|
tx_power_list.append('-infdBm')
|
||||||
|
|
||||||
|
return tx_power_list
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
"""
|
||||||
|
Reset SFP and return all user module settings to their default srate.
|
||||||
|
"""
|
||||||
|
reset_ctrl = self.sfp_control + 'qsfp_reset'
|
||||||
|
try:
|
||||||
|
# Open reset_ctrl in both read & write mode
|
||||||
|
reg_file = open(reset_ctrl, "r+")
|
||||||
|
except IOError as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
reg_hex = reg_file.readline().rstrip()
|
||||||
|
reg_value = int(reg_hex, 16)
|
||||||
|
|
||||||
|
# Mask off the bit corresponding to our port
|
||||||
|
index = self.sfp_ctrl_idx
|
||||||
|
|
||||||
|
# Mask off the bit corresponding to our port
|
||||||
|
mask = (1 << index)
|
||||||
|
|
||||||
|
# ResetL is active low
|
||||||
|
reg_value = (reg_value & ~mask)
|
||||||
|
|
||||||
|
# Convert our register value back to a
|
||||||
|
# hex string and write back
|
||||||
|
reg_file.seek(0)
|
||||||
|
reg_file.write(hex(reg_value))
|
||||||
|
reg_file.close()
|
||||||
|
|
||||||
|
# Sleep 1 second to allow it to settle
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Flip the bit back high and write back to the
|
||||||
|
# register to take port out of reset
|
||||||
|
try:
|
||||||
|
reg_file = open(reset_ctrl, "w")
|
||||||
|
except IOError as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
reg_value = reg_value | mask
|
||||||
|
reg_file.seek(0)
|
||||||
|
reg_file.write(hex(reg_value))
|
||||||
|
reg_file.close()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def set_lpmode(self, lpmode):
|
||||||
|
"""
|
||||||
|
Sets the lpmode (low power mode) of SFP
|
||||||
|
"""
|
||||||
|
lpmode_ctrl = self.sfp_control + 'qsfp_lpmode'
|
||||||
|
try:
|
||||||
|
reg_file = open(lpmode_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)
|
||||||
|
|
||||||
|
# LPMode is active high; set or clear the bit accordingly
|
||||||
|
if lpmode is True:
|
||||||
|
reg_value = (reg_value | mask)
|
||||||
|
else:
|
||||||
|
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 tx_disable(self, tx_disable):
|
||||||
|
"""
|
||||||
|
Disable SFP TX for all channels
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def tx_disable_channel(self, channel, disable):
|
||||||
|
"""
|
||||||
|
Sets the tx_disable for specified SFP channels
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def tx_disable_channel(self, channel, disable):
|
||||||
|
"""
|
||||||
|
Sets the tx_disable for specified SFP channels
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_power_override(self, power_override, power_set):
|
||||||
|
"""
|
||||||
|
Sets SFP power level using power_override and power_set
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the device
|
||||||
|
"""
|
||||||
|
reset = self.get_reset_status()
|
||||||
|
|
||||||
|
if (reset == True):
|
||||||
|
status = False
|
||||||
|
else:
|
||||||
|
status = True
|
||||||
|
|
||||||
|
return status
|
@ -10,6 +10,13 @@
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import click
|
||||||
|
import subprocess
|
||||||
|
import glob
|
||||||
|
import sonic_device_util
|
||||||
|
from commands import getstatusoutput
|
||||||
|
from sonic_platform_base.platform_base import PlatformBase
|
||||||
from sonic_platform_base.chassis_base import ChassisBase
|
from sonic_platform_base.chassis_base import ChassisBase
|
||||||
from sonic_platform.sfp import Sfp
|
from sonic_platform.sfp import Sfp
|
||||||
from sonic_platform.psu import Psu
|
from sonic_platform.psu import Psu
|
||||||
@ -47,6 +54,8 @@ class Chassis(ChassisBase):
|
|||||||
power_reason_dict[33] = ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC
|
power_reason_dict[33] = ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC
|
||||||
power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED
|
power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED
|
||||||
|
|
||||||
|
_component_name_list = ["BIOS", "CPLD1", "CPLD2", "FPGA"]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
ChassisBase.__init__(self)
|
ChassisBase.__init__(self)
|
||||||
@ -87,6 +96,19 @@ class Chassis(ChassisBase):
|
|||||||
rv = rv.lstrip(" ")
|
rv = rv.lstrip(" ")
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
# Run bash command and print output to stdout
|
||||||
|
def run_command(self, command):
|
||||||
|
click.echo(click.style("Command: ", fg='cyan') +
|
||||||
|
click.style(command, fg='green'))
|
||||||
|
|
||||||
|
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
|
||||||
|
(out, err) = proc.communicate()
|
||||||
|
|
||||||
|
click.echo(out)
|
||||||
|
|
||||||
|
if proc.returncode != 0:
|
||||||
|
sys.exit(proc.returncode)
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the device
|
Retrieves the name of the device
|
||||||
@ -177,3 +199,127 @@ class Chassis(ChassisBase):
|
|||||||
return (self.reset_reason_dict[reset_reason], None)
|
return (self.reset_reason_dict[reset_reason], None)
|
||||||
|
|
||||||
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
||||||
|
|
||||||
|
def get_component_name_list(self):
|
||||||
|
"""
|
||||||
|
Retrieves chassis components list such as BIOS, CPLD, FPGA, etc.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A list containing component name.
|
||||||
|
"""
|
||||||
|
return self._component_name_list
|
||||||
|
|
||||||
|
def get_firmware_version(self, component_name):
|
||||||
|
|
||||||
|
version = None
|
||||||
|
|
||||||
|
if component_name in self._component_name_list:
|
||||||
|
|
||||||
|
if component_name == self._component_name_list[0]: # BIOS
|
||||||
|
status, version = getstatusoutput(
|
||||||
|
"dmidecode -s system-version")
|
||||||
|
|
||||||
|
elif component_name == self._component_name_list[1]: # CPLD1
|
||||||
|
version = None
|
||||||
|
|
||||||
|
elif component_name == self._component_name_list[2]: # CPLD2
|
||||||
|
version = None
|
||||||
|
|
||||||
|
elif component_name == self._component_name_list[3]: # SMF
|
||||||
|
version = None
|
||||||
|
|
||||||
|
return version
|
||||||
|
|
||||||
|
def install_component_firmware(self, component_name, image_path):
|
||||||
|
|
||||||
|
bios_image = None
|
||||||
|
bios_version = "3.25.0."
|
||||||
|
bios_file_name = "S6100*BIOS*"
|
||||||
|
flashrom = "/usr/local/bin/flashrom"
|
||||||
|
PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
|
||||||
|
machine_info = sonic_device_util.get_machine_info()
|
||||||
|
platform = sonic_device_util.get_platform_info(machine_info)
|
||||||
|
platform_path = "/".join([PLATFORM_ROOT_PATH, platform, "bin"])
|
||||||
|
|
||||||
|
warning = """
|
||||||
|
********************************************************************
|
||||||
|
* Warning - Upgrading BIOS is inherently risky and should only be *
|
||||||
|
* attempted when necessary. A failure at this upgrade may cause *
|
||||||
|
* a board RMA. Proceed with caution ! *
|
||||||
|
********************************************************************
|
||||||
|
"""
|
||||||
|
|
||||||
|
if component_name in self._component_name_list:
|
||||||
|
if component_name == self._component_name_list[0]: # BIOS
|
||||||
|
|
||||||
|
# current BIOS version
|
||||||
|
current_bios_version = self.get_firmware_version("BIOS")
|
||||||
|
|
||||||
|
# Construct BIOS image path
|
||||||
|
if image_path is not None:
|
||||||
|
image_path = image_path + platform_path
|
||||||
|
for name in glob.glob(
|
||||||
|
os.path.join(image_path, bios_file_name)):
|
||||||
|
bios_image = image_path = name
|
||||||
|
|
||||||
|
if not bios_image:
|
||||||
|
print "BIOS image file not found:", image_path
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Extract BIOS image version
|
||||||
|
bios_image = os.path.basename(bios_image)
|
||||||
|
bios_image = bios_image.strip('S6100-BIOS-')
|
||||||
|
bios_image_version = bios_image.strip('.bin')
|
||||||
|
|
||||||
|
if bios_image_version.startswith(bios_version):
|
||||||
|
bios_image_minor = bios_image_version.replace(
|
||||||
|
bios_image_version[:7], '')
|
||||||
|
if bios_image_minor.startswith("2"):
|
||||||
|
bios_image_minor = bios_image_minor.split("-")[1]
|
||||||
|
|
||||||
|
if current_bios_version.startswith(bios_version):
|
||||||
|
current_bios_minor = current_bios_version.replace(
|
||||||
|
current_bios_version[:7], '')
|
||||||
|
if current_bios_minor.startswith("2"):
|
||||||
|
current_bios_minor = current_bios_minor.split("-")[1]
|
||||||
|
|
||||||
|
# BIOS version check
|
||||||
|
if bios_image_minor > current_bios_minor:
|
||||||
|
|
||||||
|
print warning
|
||||||
|
prompt_text = "New BIOS image " + bios_image_version + \
|
||||||
|
" available to install, continue?"
|
||||||
|
yes = click.confirm(prompt_text)
|
||||||
|
|
||||||
|
elif current_bios_minor > bios_image_minor:
|
||||||
|
|
||||||
|
print warning
|
||||||
|
prompt_text = "Do you want to downgrade BIOS image from " \
|
||||||
|
+ current_bios_version + " to " + \
|
||||||
|
bios_image_version + " continue?"
|
||||||
|
|
||||||
|
yes = click.confirm(prompt_text)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("BIOS is already with {} latest version".format(
|
||||||
|
current_bios_version))
|
||||||
|
return True
|
||||||
|
|
||||||
|
if yes:
|
||||||
|
command = flashrom + " -p" + " internal" + " -w " + \
|
||||||
|
image_path
|
||||||
|
self.run_command(command)
|
||||||
|
|
||||||
|
elif component_name == self._component_name_list[1]: # CPLD1
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif component_name == self._component_name_list[2]: # CPLD2
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif component_name == self._component_name_list[3]: # SMF
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print "Invalid component Name:", component_name
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
@ -418,7 +418,13 @@ class Sfp(SfpBase):
|
|||||||
reg_value = int(reg_hex, 16)
|
reg_value = int(reg_hex, 16)
|
||||||
|
|
||||||
# Mask off the bit corresponding to our port
|
# Mask off the bit corresponding to our port
|
||||||
mask = (1 << self.sfp_ctrl_idx)
|
if (self.sfp_ctrl_idx > 15):
|
||||||
|
index = self.sfp_ctrl_idx % 16
|
||||||
|
else:
|
||||||
|
index = self.sfp_ctrl_idx
|
||||||
|
|
||||||
|
# Mask off the bit corresponding to our port
|
||||||
|
mask = (1 << index)
|
||||||
|
|
||||||
# ModPrsL is active low
|
# ModPrsL is active low
|
||||||
if ((reg_value & mask) == 0):
|
if ((reg_value & mask) == 0):
|
||||||
@ -849,3 +855,40 @@ class Sfp(SfpBase):
|
|||||||
reg_file.close()
|
reg_file.close()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def tx_disable(self, tx_disable):
|
||||||
|
"""
|
||||||
|
Disable SFP TX for all channels
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def tx_disable_channel(self, channel, disable):
|
||||||
|
"""
|
||||||
|
Sets the tx_disable for specified SFP channels
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def tx_disable_channel(self, channel, disable):
|
||||||
|
"""
|
||||||
|
Sets the tx_disable for specified SFP channels
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_power_override(self, power_override, power_set):
|
||||||
|
"""
|
||||||
|
Sets SFP power level using power_override and power_set
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the device
|
||||||
|
"""
|
||||||
|
reset = self.get_reset_status()
|
||||||
|
|
||||||
|
if (reset == True):
|
||||||
|
status = False
|
||||||
|
else:
|
||||||
|
status = True
|
||||||
|
|
||||||
|
return status
|
||||||
|
File diff suppressed because it is too large
Load Diff
10
platform/broadcom/sonic-platform-modules-dell/tools/flashrom.sh
Executable file
10
platform/broadcom/sonic-platform-modules-dell/tools/flashrom.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
export DELL_TOOLS_DIR="platform/broadcom/sonic-platform-modules-dell/tools"
|
||||||
|
|
||||||
|
cd $DELL_TOOLS_DIR
|
||||||
|
rm -rf $DELL_TOOLS_DIR/flashrom
|
||||||
|
git clone https://github.com/flashrom/flashrom.git
|
||||||
|
cd flashrom
|
||||||
|
git checkout tags/0.9.7
|
||||||
|
git apply ../0002-Flashrom-support-for-Intel-Rangeley-and-Denverton-CP.patch
|
||||||
|
make
|
@ -1 +0,0 @@
|
|||||||
../../s6100/sonic_platform/sfp.py
|
|
@ -0,0 +1,879 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# DELLEMC
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC Platform Base API and
|
||||||
|
# provides the platform information
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
from sonic_platform_base.chassis_base import ChassisBase
|
||||||
|
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
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
|
||||||
|
PAGE_OFFSET = 0
|
||||||
|
KEY_OFFSET = 1
|
||||||
|
KEY_WIDTH = 2
|
||||||
|
FUNC_NAME = 3
|
||||||
|
|
||||||
|
INFO_OFFSET = 128
|
||||||
|
DOM_OFFSET = 0
|
||||||
|
DOM_OFFSET1 = 384
|
||||||
|
|
||||||
|
cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)',
|
||||||
|
'Length OM1(m)', 'Length Cable Assembly(m)')
|
||||||
|
|
||||||
|
compliance_code_tup = (
|
||||||
|
'10/40G Ethernet Compliance Code',
|
||||||
|
'SONET Compliance codes',
|
||||||
|
'SAS/SATA compliance codes',
|
||||||
|
'Gigabit Ethernet Compliant codes',
|
||||||
|
'Fibre Channel link length/Transmitter Technology',
|
||||||
|
'Fibre Channel transmission media',
|
||||||
|
'Fibre Channel Speed')
|
||||||
|
|
||||||
|
info_dict_keys = ['type', 'hardwarerev', 'serialnum',
|
||||||
|
'manufacturename', 'modelname', 'Connector',
|
||||||
|
'encoding', 'ext_identifier', 'ext_rateselect_compliance',
|
||||||
|
'cable_type', 'cable_length', 'nominal_bit_rate',
|
||||||
|
'specification_compliance', 'vendor_date', 'vendor_oui']
|
||||||
|
|
||||||
|
dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status',
|
||||||
|
'power_lpmode', 'tx_disable', 'tx_disable_channel',
|
||||||
|
'temperature', 'voltage', 'rx1power',
|
||||||
|
'rx2power', 'rx3power', 'rx4power',
|
||||||
|
'tx1bias', 'tx2bias', 'tx3bias',
|
||||||
|
'tx4bias', 'tx1power', 'tx2power',
|
||||||
|
'tx3power', 'tx4power']
|
||||||
|
|
||||||
|
threshold_dict_keys = ['temphighalarm', 'temphighwarning',
|
||||||
|
'templowalarm', 'templowwarning',
|
||||||
|
'vcchighalarm', 'vcchighwarning',
|
||||||
|
'vcclowalarm', 'vcclowwarning',
|
||||||
|
'rxpowerhighalarm', 'rxpowerhighwarning',
|
||||||
|
'rxpowerlowalarm', 'rxpowerlowwarning',
|
||||||
|
'txpowerhighalarm', 'txpowerhighwarning',
|
||||||
|
'txpowerlowalarm', 'txpowerlowwarning',
|
||||||
|
'txbiashighalarm', 'txbiashighwarning',
|
||||||
|
'txbiaslowalarm', 'txbiaslowwarning']
|
||||||
|
|
||||||
|
sff8436_parser = {
|
||||||
|
'reset_status': [DOM_OFFSET, 2, 1, 'parse_dom_status_indicator'],
|
||||||
|
'rx_los': [DOM_OFFSET, 3, 1, 'parse_dom_tx_rx_los'],
|
||||||
|
'tx_fault': [DOM_OFFSET, 4, 1, 'parse_dom_tx_fault'],
|
||||||
|
'tx_disable': [DOM_OFFSET, 86, 1, 'parse_dom_tx_disable'],
|
||||||
|
'power_lpmode': [DOM_OFFSET, 93, 1, 'parse_dom_power_control'],
|
||||||
|
'power_override': [DOM_OFFSET, 93, 1, 'parse_dom_power_control'],
|
||||||
|
'Temperature': [DOM_OFFSET, 22, 2, 'parse_temperature'],
|
||||||
|
'Voltage': [DOM_OFFSET, 26, 2, 'parse_voltage'],
|
||||||
|
'ChannelMonitor': [DOM_OFFSET, 34, 16, 'parse_channel_monitor_params'],
|
||||||
|
|
||||||
|
'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'],
|
||||||
|
'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'],
|
||||||
|
'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'ext_rateselect_compliance':
|
||||||
|
[INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'specification_compliance':
|
||||||
|
[INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'],
|
||||||
|
'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'],
|
||||||
|
'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'],
|
||||||
|
'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'],
|
||||||
|
'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'],
|
||||||
|
'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'],
|
||||||
|
'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'],
|
||||||
|
'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'],
|
||||||
|
'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Sfp(SfpBase):
|
||||||
|
"""
|
||||||
|
DELLEMC Platform-specific Sfp class
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, index, sfp_type, eeprom_path,
|
||||||
|
sfp_control, sfp_ctrl_idx):
|
||||||
|
SfpBase.__init__(self)
|
||||||
|
self.sfp_type = sfp_type
|
||||||
|
self.index = index
|
||||||
|
self.eeprom_path = eeprom_path
|
||||||
|
self.sfp_control = sfp_control
|
||||||
|
self.sfp_ctrl_idx = sfp_ctrl_idx
|
||||||
|
self.sfpInfo = sff8436InterfaceId()
|
||||||
|
self.sfpDomInfo = sff8436Dom()
|
||||||
|
|
||||||
|
def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes):
|
||||||
|
eeprom_raw = []
|
||||||
|
try:
|
||||||
|
eeprom = open(eeprom_path, mode="rb", buffering=0)
|
||||||
|
except IOError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for i in range(0, num_bytes):
|
||||||
|
eeprom_raw.append("0x00")
|
||||||
|
|
||||||
|
try:
|
||||||
|
eeprom.seek(offset)
|
||||||
|
raw = eeprom.read(num_bytes)
|
||||||
|
except IOError:
|
||||||
|
eeprom.close()
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
for n in range(0, num_bytes):
|
||||||
|
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
|
||||||
|
except BaseException:
|
||||||
|
eeprom.close()
|
||||||
|
return None
|
||||||
|
|
||||||
|
eeprom.close()
|
||||||
|
return eeprom_raw
|
||||||
|
|
||||||
|
def _get_eeprom_data(self, eeprom_key):
|
||||||
|
eeprom_data = None
|
||||||
|
page_offset = None
|
||||||
|
|
||||||
|
if (self.sfpInfo is None):
|
||||||
|
return None
|
||||||
|
|
||||||
|
page_offset = sff8436_parser[eeprom_key][PAGE_OFFSET]
|
||||||
|
eeprom_data_raw = self._read_eeprom_bytes(
|
||||||
|
self.eeprom_path,
|
||||||
|
(sff8436_parser[eeprom_key][PAGE_OFFSET] +
|
||||||
|
sff8436_parser[eeprom_key][KEY_OFFSET]),
|
||||||
|
sff8436_parser[eeprom_key][KEY_WIDTH])
|
||||||
|
if (eeprom_data_raw is not None):
|
||||||
|
# Offset 128 is used to retrieve sff8436InterfaceId Info
|
||||||
|
# Offset 0 is used to retrieve sff8436Dom Info
|
||||||
|
if (page_offset == 128):
|
||||||
|
eeprom_data = getattr(
|
||||||
|
self.sfpInfo, sff8436_parser[eeprom_key][FUNC_NAME])(
|
||||||
|
eeprom_data_raw, 0)
|
||||||
|
else:
|
||||||
|
eeprom_data = getattr(
|
||||||
|
self.sfpDomInfo, sff8436_parser[eeprom_key][FUNC_NAME])(
|
||||||
|
eeprom_data_raw, 0)
|
||||||
|
|
||||||
|
return eeprom_data
|
||||||
|
|
||||||
|
def get_transceiver_info(self):
|
||||||
|
"""
|
||||||
|
Retrieves transceiver info of this SFP
|
||||||
|
"""
|
||||||
|
transceiver_info_dict = {}
|
||||||
|
compliance_code_dict = {}
|
||||||
|
transceiver_info_dict = dict.fromkeys(info_dict_keys, 'N/A')
|
||||||
|
|
||||||
|
# BaseInformation
|
||||||
|
iface_data = self._get_eeprom_data('type')
|
||||||
|
if (iface_data is not None):
|
||||||
|
connector = iface_data['data']['Connector']['value']
|
||||||
|
encoding = iface_data['data']['EncodingCodes']['value']
|
||||||
|
ext_id = iface_data['data']['Extended Identifier']['value']
|
||||||
|
rate_identifier = iface_data['data']['RateIdentifier']['value']
|
||||||
|
identifier = iface_data['data']['type']['value']
|
||||||
|
bit_rate = str(
|
||||||
|
iface_data['data']['Nominal Bit Rate(100Mbs)']['value'])
|
||||||
|
|
||||||
|
for key in compliance_code_tup:
|
||||||
|
if key in iface_data['data']['Specification compliance']['value']:
|
||||||
|
compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value']
|
||||||
|
for key in cable_length_tup:
|
||||||
|
if key in iface_data['data']:
|
||||||
|
cable_type = key
|
||||||
|
cable_length = str(iface_data['data'][key]['value'])
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor Date
|
||||||
|
vendor_date_data = self._get_eeprom_data('vendor_date')
|
||||||
|
if (vendor_date_data is not None):
|
||||||
|
vendor_date = vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor Name
|
||||||
|
vendor_name_data = self._get_eeprom_data('manufacturename')
|
||||||
|
if (vendor_name_data is not None):
|
||||||
|
vendor_name = vendor_name_data['data']['Vendor Name']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor OUI
|
||||||
|
vendor_oui_data = self._get_eeprom_data('vendor_oui')
|
||||||
|
if (vendor_oui_data is not None):
|
||||||
|
vendor_oui = vendor_oui_data['data']['Vendor OUI']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor PN
|
||||||
|
vendor_pn_data = self._get_eeprom_data('modelname')
|
||||||
|
if (vendor_pn_data is not None):
|
||||||
|
vendor_pn = vendor_pn_data['data']['Vendor PN']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor Revision
|
||||||
|
vendor_rev_data = self._get_eeprom_data('hardwarerev')
|
||||||
|
if (vendor_rev_data is not None):
|
||||||
|
vendor_rev = vendor_rev_data['data']['Vendor Rev']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Vendor Serial Number
|
||||||
|
vendor_sn_data = self._get_eeprom_data('serialnum')
|
||||||
|
if (vendor_sn_data is not None):
|
||||||
|
vendor_sn = vendor_sn_data['data']['Vendor SN']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Fill The Dictionary and return
|
||||||
|
transceiver_info_dict['type'] = identifier
|
||||||
|
transceiver_info_dict['hardwarerev'] = vendor_rev
|
||||||
|
transceiver_info_dict['serialnum'] = vendor_sn
|
||||||
|
transceiver_info_dict['manufacturename'] = vendor_name
|
||||||
|
transceiver_info_dict['modelname'] = vendor_pn
|
||||||
|
transceiver_info_dict['Connector'] = connector
|
||||||
|
transceiver_info_dict['encoding'] = encoding
|
||||||
|
transceiver_info_dict['ext_identifier'] = ext_id
|
||||||
|
transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier
|
||||||
|
transceiver_info_dict['cable_type'] = cable_type
|
||||||
|
transceiver_info_dict['cable_length'] = cable_length
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = bit_rate
|
||||||
|
transceiver_info_dict['specification_compliance'] = str(
|
||||||
|
compliance_code_dict)
|
||||||
|
transceiver_info_dict['vendor_date'] = vendor_date
|
||||||
|
transceiver_info_dict['vendor_oui'] = vendor_oui
|
||||||
|
|
||||||
|
return transceiver_info_dict
|
||||||
|
|
||||||
|
def get_transceiver_threshold_info(self):
|
||||||
|
"""
|
||||||
|
Retrieves transceiver threshold info of this SFP
|
||||||
|
"""
|
||||||
|
transceiver_dom_threshold_dict = {}
|
||||||
|
transceiver_dom_threshold_dict = dict.fromkeys(
|
||||||
|
threshold_dict_keys, 'N/A')
|
||||||
|
|
||||||
|
# Module Threshold
|
||||||
|
module_threshold_data = self._get_eeprom_data('ModuleThreshold')
|
||||||
|
if (module_threshold_data is not None):
|
||||||
|
tempHighAlarm = module_threshold_data['data']['TempHighAlarm']['value']
|
||||||
|
tempLowAlarm = module_threshold_data['data']['TempLowAlarm']['value']
|
||||||
|
tempHighWarn = module_threshold_data['data']['TempHighWarning']['value']
|
||||||
|
tempLowWarn = module_threshold_data['data']['TempLowWarning']['value']
|
||||||
|
vccHighAlarm = module_threshold_data['data']['VccHighAlarm']['value']
|
||||||
|
vccLowAlarm = module_threshold_data['data']['VccLowAlarm']['value']
|
||||||
|
vccHighWarn = module_threshold_data['data']['VccHighWarning']['value']
|
||||||
|
vccLowWarn = module_threshold_data['data']['VccLowWarning']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Channel Threshold
|
||||||
|
channel_threshold_data = self._get_eeprom_data('ChannelThreshold')
|
||||||
|
if (channel_threshold_data is not None):
|
||||||
|
rxPowerHighAlarm = channel_threshold_data['data']['RxPowerHighAlarm']['value']
|
||||||
|
rxPowerLowAlarm = channel_threshold_data['data']['RxPowerLowAlarm']['value']
|
||||||
|
rxPowerHighWarn = channel_threshold_data['data']['RxPowerHighWarning']['value']
|
||||||
|
rxPowerLowWarn = channel_threshold_data['data']['RxPowerLowWarning']['value']
|
||||||
|
txBiasHighAlarm = channel_threshold_data['data']['TxBiasHighAlarm']['value']
|
||||||
|
txBiasLowAlarm = channel_threshold_data['data']['TxBiasLowAlarm']['value']
|
||||||
|
txBiasHighWarn = channel_threshold_data['data']['TxBiasHighWarning']['value']
|
||||||
|
txBiasLowWarn = channel_threshold_data['data']['TxBiasLowWarning']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_dom_threshold_dict['temphighalarm'] = tempHighAlarm
|
||||||
|
transceiver_dom_threshold_dict['templowalarm'] = tempLowAlarm
|
||||||
|
transceiver_dom_threshold_dict['temphighwarning'] = tempHighWarn
|
||||||
|
transceiver_dom_threshold_dict['templowwarning'] = tempLowWarn
|
||||||
|
transceiver_dom_threshold_dict['vcchighalarm'] = vccHighAlarm
|
||||||
|
transceiver_dom_threshold_dict['vcclowalarm'] = vccLowAlarm
|
||||||
|
transceiver_dom_threshold_dict['vcchighwarning'] = vccHighWarn
|
||||||
|
transceiver_dom_threshold_dict['vcclowwarning'] = vccLowWarn
|
||||||
|
transceiver_dom_threshold_dict['rxpowerhighalarm'] = rxPowerHighAlarm
|
||||||
|
transceiver_dom_threshold_dict['rxpowerlowalarm'] = rxPowerLowAlarm
|
||||||
|
transceiver_dom_threshold_dict['rxpowerhighwarning'] = rxPowerHighWarn
|
||||||
|
transceiver_dom_threshold_dict['rxpowerlowwarning'] = rxPowerLowWarn
|
||||||
|
transceiver_dom_threshold_dict['txbiashighalarm'] = txBiasHighAlarm
|
||||||
|
transceiver_dom_threshold_dict['txbiaslowalarm'] = txBiasLowAlarm
|
||||||
|
transceiver_dom_threshold_dict['txbiashighwarning'] = txBiasHighWarn
|
||||||
|
transceiver_dom_threshold_dict['txbiaslowwarning'] = txBiasLowWarn
|
||||||
|
|
||||||
|
return transceiver_dom_threshold_dict
|
||||||
|
|
||||||
|
def get_transceiver_bulk_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves transceiver bulk status of this SFP
|
||||||
|
"""
|
||||||
|
tx_bias_list = []
|
||||||
|
rx_power_list = []
|
||||||
|
transceiver_dom_dict = {}
|
||||||
|
transceiver_dom_dict = dict.fromkeys(dom_dict_keys, 'N/A')
|
||||||
|
|
||||||
|
# RxLos
|
||||||
|
rx_los = self.get_rx_los()
|
||||||
|
|
||||||
|
# TxFault
|
||||||
|
tx_fault = self.get_tx_fault()
|
||||||
|
|
||||||
|
# ResetStatus
|
||||||
|
reset_state = self.get_reset_status()
|
||||||
|
|
||||||
|
# LowPower Mode
|
||||||
|
lp_mode = self.get_lpmode()
|
||||||
|
|
||||||
|
# TxDisable
|
||||||
|
tx_disable = self.get_tx_disable()
|
||||||
|
|
||||||
|
# TxDisable Channel
|
||||||
|
tx_disable_channel = self.get_tx_disable_channel()
|
||||||
|
|
||||||
|
# Temperature
|
||||||
|
temperature = self.get_temperature()
|
||||||
|
|
||||||
|
# Voltage
|
||||||
|
voltage = self.get_voltage()
|
||||||
|
|
||||||
|
# Channel Monitor
|
||||||
|
channel_monitor_data = self._get_eeprom_data('ChannelMonitor')
|
||||||
|
if (channel_monitor_data is not None):
|
||||||
|
tx_bias = channel_monitor_data['data']['TX1Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = channel_monitor_data['data']['TX2Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = channel_monitor_data['data']['TX3Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = channel_monitor_data['data']['TX4Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
rx_power = channel_monitor_data['data']['RX1Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = channel_monitor_data['data']['RX2Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = channel_monitor_data['data']['RX3Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = channel_monitor_data['data']['RX4Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
transceiver_dom_dict['rx_los'] = rx_los
|
||||||
|
transceiver_dom_dict['tx_fault'] = tx_fault
|
||||||
|
transceiver_dom_dict['reset_status'] = reset_state
|
||||||
|
transceiver_dom_dict['power_lpmode'] = lp_mode
|
||||||
|
transceiver_dom_dict['tx_disable'] = tx_disable
|
||||||
|
transceiver_dom_dict['tx_disable_channel'] = tx_disable_channel
|
||||||
|
transceiver_dom_dict['temperature'] = temperature
|
||||||
|
transceiver_dom_dict['voltage'] = voltage
|
||||||
|
transceiver_dom_dict['tx1bias'] = tx_bias_list[0]
|
||||||
|
transceiver_dom_dict['tx2bias'] = tx_bias_list[1]
|
||||||
|
transceiver_dom_dict['tx3bias'] = tx_bias_list[2]
|
||||||
|
transceiver_dom_dict['tx4bias'] = tx_bias_list[3]
|
||||||
|
transceiver_dom_dict['rx1power'] = rx_power_list[0]
|
||||||
|
transceiver_dom_dict['rx2power'] = rx_power_list[1]
|
||||||
|
transceiver_dom_dict['rx3power'] = rx_power_list[2]
|
||||||
|
transceiver_dom_dict['rx4power'] = rx_power_list[3]
|
||||||
|
|
||||||
|
return transceiver_dom_dict
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the name of the sfp
|
||||||
|
Returns : QSFP or QSFP+ or QSFP28
|
||||||
|
"""
|
||||||
|
iface_data = self._get_eeprom_data('type')
|
||||||
|
if (iface_data is not None):
|
||||||
|
identifier = iface_data['data']['type']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return identifier
|
||||||
|
|
||||||
|
def get_presence(self):
|
||||||
|
"""
|
||||||
|
Retrieves the presence of the sfp
|
||||||
|
"""
|
||||||
|
presence_ctrl = self.sfp_control + 'qsfp_modprs'
|
||||||
|
try:
|
||||||
|
reg_file = open(presence_ctrl)
|
||||||
|
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 off the bit corresponding to our port
|
||||||
|
mask = (1 << index)
|
||||||
|
|
||||||
|
# ModPrsL is active low
|
||||||
|
if ((reg_value & mask) == 0):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the sfp
|
||||||
|
"""
|
||||||
|
vendor_pn_data = self._get_eeprom_data('modelname')
|
||||||
|
if (vendor_pn_data is not None):
|
||||||
|
vendor_pn = vendor_pn_data['data']['Vendor PN']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return vendor_pn
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the sfp
|
||||||
|
"""
|
||||||
|
vendor_sn_data = self._get_eeprom_data('serialnum')
|
||||||
|
if (vendor_sn_data is not None):
|
||||||
|
vendor_sn = vendor_sn_data['data']['Vendor SN']['value']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return vendor_sn
|
||||||
|
|
||||||
|
def get_reset_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the reset status of SFP
|
||||||
|
"""
|
||||||
|
reset_status = None
|
||||||
|
reset_ctrl = self.sfp_control + 'qsfp_reset'
|
||||||
|
try:
|
||||||
|
reg_file = open(reset_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) == 0):
|
||||||
|
reset_status = True
|
||||||
|
else:
|
||||||
|
reset_status = False
|
||||||
|
|
||||||
|
return reset_status
|
||||||
|
|
||||||
|
def get_rx_los(self):
|
||||||
|
"""
|
||||||
|
Retrieves the RX LOS (lost-of-signal) status of SFP
|
||||||
|
"""
|
||||||
|
rx_los = None
|
||||||
|
rx_los_list = []
|
||||||
|
|
||||||
|
rx_los_data = self._get_eeprom_data('rx_los')
|
||||||
|
if (rx_los_data is not None):
|
||||||
|
rx_los = rx_los_data['data']['Rx1LOS']['value']
|
||||||
|
if (rx_los is 'On'):
|
||||||
|
rx_los_list.append(True)
|
||||||
|
else:
|
||||||
|
rx_los_list.append(False)
|
||||||
|
rx_los = rx_los_data['data']['Rx2LOS']['value']
|
||||||
|
if (rx_los is 'On'):
|
||||||
|
rx_los_list.append(True)
|
||||||
|
else:
|
||||||
|
rx_los_list.append(False)
|
||||||
|
rx_los = rx_los_data['data']['Rx3LOS']['value']
|
||||||
|
if (rx_los is 'On'):
|
||||||
|
rx_los_list.append(True)
|
||||||
|
else:
|
||||||
|
rx_los_list.append(False)
|
||||||
|
rx_los = rx_los_data['data']['Rx4LOS']['value']
|
||||||
|
if (rx_los is 'On'):
|
||||||
|
rx_los_list.append(True)
|
||||||
|
else:
|
||||||
|
rx_los_list.append(False)
|
||||||
|
|
||||||
|
if (rx_los_list[0] and rx_los_list[1]
|
||||||
|
and rx_los_list[2] and rx_los_list[3]):
|
||||||
|
rx_los = True
|
||||||
|
else:
|
||||||
|
rx_los = False
|
||||||
|
|
||||||
|
return rx_los
|
||||||
|
|
||||||
|
def get_tx_fault(self):
|
||||||
|
"""
|
||||||
|
Retrieves the TX fault status of SFP
|
||||||
|
"""
|
||||||
|
tx_fault = None
|
||||||
|
tx_fault_list = []
|
||||||
|
|
||||||
|
tx_fault_data = self._get_eeprom_data('tx_fault')
|
||||||
|
if (tx_fault_data is not None):
|
||||||
|
tx_fault = tx_fault_data['data']['Tx1Fault']['value']
|
||||||
|
if (tx_fault is 'On'):
|
||||||
|
tx_fault_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_fault_list.append(False)
|
||||||
|
tx_fault = tx_fault_data['data']['Tx2Fault']['value']
|
||||||
|
if (tx_fault is 'On'):
|
||||||
|
tx_fault_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_fault_list.append(False)
|
||||||
|
tx_fault = tx_fault_data['data']['Tx3Fault']['value']
|
||||||
|
if (tx_fault is 'On'):
|
||||||
|
tx_fault_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_fault_list.append(False)
|
||||||
|
tx_fault = tx_fault_data['data']['Tx4Fault']['value']
|
||||||
|
if (tx_fault is 'On'):
|
||||||
|
tx_fault_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_fault_list.append(False)
|
||||||
|
|
||||||
|
if (tx_fault_list[0] and tx_fault_list[1]
|
||||||
|
and tx_fault_list[2] and tx_fault_list[3]):
|
||||||
|
tx_fault = True
|
||||||
|
else:
|
||||||
|
tx_fault = False
|
||||||
|
|
||||||
|
return tx_fault
|
||||||
|
|
||||||
|
def get_tx_disable(self):
|
||||||
|
"""
|
||||||
|
Retrieves the tx_disable status of this SFP
|
||||||
|
"""
|
||||||
|
tx_disable = None
|
||||||
|
tx_disable_list = []
|
||||||
|
|
||||||
|
tx_disable_data = self._get_eeprom_data('tx_disable')
|
||||||
|
if (tx_disable_data is not None):
|
||||||
|
tx_disable = tx_disable_data['data']['Tx1Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(False)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx2Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(False)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx3Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(False)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx4Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(True)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(False)
|
||||||
|
|
||||||
|
if (tx_disable_list[0] and tx_disable_list[1]
|
||||||
|
and tx_disable_list[2] and tx_disable_list[3]):
|
||||||
|
tx_disable = True
|
||||||
|
else:
|
||||||
|
tx_disable = False
|
||||||
|
|
||||||
|
return tx_disable
|
||||||
|
|
||||||
|
def get_tx_disable_channel(self):
|
||||||
|
"""
|
||||||
|
Retrieves the TX disabled channels in this SFP
|
||||||
|
"""
|
||||||
|
tx_disable = None
|
||||||
|
tx_disable_list = []
|
||||||
|
|
||||||
|
tx_disable_data = self._get_eeprom_data('tx_disable')
|
||||||
|
if (tx_disable_data is not None):
|
||||||
|
tx_disable = tx_disable_data['data']['Tx1Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(1)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(0)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx2Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(1)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(0)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx3Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(1)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(0)
|
||||||
|
tx_disable = tx_disable_data['data']['Tx4Disable']['value']
|
||||||
|
if (tx_disable is 'On'):
|
||||||
|
tx_disable_list.append(1)
|
||||||
|
else:
|
||||||
|
tx_disable_list.append(0)
|
||||||
|
|
||||||
|
bit4 = int(tx_disable_list[3]) * 8
|
||||||
|
bit3 = int(tx_disable_list[2]) * 4
|
||||||
|
bit2 = int(tx_disable_list[1]) * 2
|
||||||
|
bit1 = int(tx_disable_list[0]) * 1
|
||||||
|
|
||||||
|
tx_disable_channel = hex(bit4 + bit3 + bit2 + bit1)
|
||||||
|
|
||||||
|
return tx_disable_channel
|
||||||
|
|
||||||
|
def get_lpmode(self):
|
||||||
|
"""
|
||||||
|
Retrieves the lpmode (low power mode) status of this SFP
|
||||||
|
"""
|
||||||
|
lpmode_ctrl = self.sfp_control + 'qsfp_lpmode'
|
||||||
|
try:
|
||||||
|
reg_file = open(lpmode_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) == 0):
|
||||||
|
lpmode_state = False
|
||||||
|
else:
|
||||||
|
lpmode_state = True
|
||||||
|
|
||||||
|
return lpmode_state
|
||||||
|
|
||||||
|
def get_power_override(self):
|
||||||
|
"""
|
||||||
|
Retrieves the power-override status of this SFP
|
||||||
|
"""
|
||||||
|
power_override_state = None
|
||||||
|
|
||||||
|
# Reset Status
|
||||||
|
power_override_data = self._get_eeprom_data('power_override')
|
||||||
|
if (power_override_data is not None):
|
||||||
|
power_override = power_override_data['data']['PowerOverRide']['value']
|
||||||
|
if (power_override is 'On'):
|
||||||
|
power_override_state = True
|
||||||
|
else:
|
||||||
|
power_override_state = False
|
||||||
|
|
||||||
|
return power_override_state
|
||||||
|
|
||||||
|
def get_temperature(self):
|
||||||
|
"""
|
||||||
|
Retrieves the temperature of this SFP
|
||||||
|
"""
|
||||||
|
temperature = None
|
||||||
|
|
||||||
|
temperature_data = self._get_eeprom_data('Temperature')
|
||||||
|
if (temperature_data is not None):
|
||||||
|
temperature = temperature_data['data']['Temperature']['value']
|
||||||
|
|
||||||
|
return temperature
|
||||||
|
|
||||||
|
def get_voltage(self):
|
||||||
|
"""
|
||||||
|
Retrieves the supply voltage of this SFP
|
||||||
|
"""
|
||||||
|
voltage = None
|
||||||
|
|
||||||
|
voltage_data = self._get_eeprom_data('Voltage')
|
||||||
|
if (voltage_data is not None):
|
||||||
|
voltage = voltage_data['data']['Vcc']['value']
|
||||||
|
|
||||||
|
return voltage
|
||||||
|
|
||||||
|
def get_tx_bias(self):
|
||||||
|
"""
|
||||||
|
Retrieves the TX bias current of this SFP
|
||||||
|
"""
|
||||||
|
tx_bias = None
|
||||||
|
tx_bias_list = []
|
||||||
|
|
||||||
|
tx_bias_data = self._get_eeprom_data('ChannelMonitor')
|
||||||
|
if (tx_bias_data is not None):
|
||||||
|
tx_bias = tx_bias_data['data']['TX1Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = tx_bias_data['data']['TX2Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = tx_bias_data['data']['TX3Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
tx_bias = tx_bias_data['data']['TX4Bias']['value']
|
||||||
|
tx_bias_list.append(tx_bias)
|
||||||
|
|
||||||
|
return tx_bias_list
|
||||||
|
|
||||||
|
def get_rx_power(self):
|
||||||
|
"""
|
||||||
|
Retrieves the received optical power for this SFP
|
||||||
|
"""
|
||||||
|
rx_power = None
|
||||||
|
rx_power_list = []
|
||||||
|
|
||||||
|
rx_power_data = self._get_eeprom_data('ChannelMonitor')
|
||||||
|
if (rx_power_data is not None):
|
||||||
|
rx_power = rx_power_data['data']['RX1Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = rx_power_data['data']['RX2Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = rx_power_data['data']['RX3Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
rx_power = rx_power_data['data']['RX4Power']['value']
|
||||||
|
rx_power_list.append(rx_power)
|
||||||
|
|
||||||
|
return rx_power_list
|
||||||
|
|
||||||
|
|
||||||
|
def get_tx_power(self):
|
||||||
|
"""
|
||||||
|
Retrieves the TX power of this SFP
|
||||||
|
"""
|
||||||
|
tx_power = None
|
||||||
|
tx_power_list = []
|
||||||
|
|
||||||
|
tx_power_list.append('-infdBm')
|
||||||
|
tx_power_list.append('-infdBm')
|
||||||
|
tx_power_list.append('-infdBm')
|
||||||
|
tx_power_list.append('-infdBm')
|
||||||
|
|
||||||
|
return tx_power_list
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
"""
|
||||||
|
Reset SFP and return all user module settings to their default srate.
|
||||||
|
"""
|
||||||
|
reset_ctrl = self.sfp_control + 'qsfp_reset'
|
||||||
|
try:
|
||||||
|
# Open reset_ctrl in both read & write mode
|
||||||
|
reg_file = open(reset_ctrl, "r+")
|
||||||
|
except IOError as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
reg_hex = reg_file.readline().rstrip()
|
||||||
|
reg_value = int(reg_hex, 16)
|
||||||
|
|
||||||
|
# Mask off the bit corresponding to our port
|
||||||
|
index = self.sfp_ctrl_idx
|
||||||
|
|
||||||
|
# Mask off the bit corresponding to our port
|
||||||
|
mask = (1 << index)
|
||||||
|
|
||||||
|
# ResetL is active low
|
||||||
|
reg_value = (reg_value & ~mask)
|
||||||
|
|
||||||
|
# Convert our register value back to a
|
||||||
|
# hex string and write back
|
||||||
|
reg_file.seek(0)
|
||||||
|
reg_file.write(hex(reg_value))
|
||||||
|
reg_file.close()
|
||||||
|
|
||||||
|
# Sleep 1 second to allow it to settle
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Flip the bit back high and write back to the
|
||||||
|
# register to take port out of reset
|
||||||
|
try:
|
||||||
|
reg_file = open(reset_ctrl, "w")
|
||||||
|
except IOError as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
reg_value = reg_value | mask
|
||||||
|
reg_file.seek(0)
|
||||||
|
reg_file.write(hex(reg_value))
|
||||||
|
reg_file.close()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def set_lpmode(self, lpmode):
|
||||||
|
"""
|
||||||
|
Sets the lpmode (low power mode) of SFP
|
||||||
|
"""
|
||||||
|
lpmode_ctrl = self.sfp_control + 'qsfp_lpmode'
|
||||||
|
try:
|
||||||
|
reg_file = open(lpmode_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)
|
||||||
|
|
||||||
|
# LPMode is active high; set or clear the bit accordingly
|
||||||
|
if lpmode is True:
|
||||||
|
reg_value = (reg_value | mask)
|
||||||
|
else:
|
||||||
|
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 tx_disable(self, tx_disable):
|
||||||
|
"""
|
||||||
|
Disable SFP TX for all channels
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def tx_disable_channel(self, channel, disable):
|
||||||
|
"""
|
||||||
|
Sets the tx_disable for specified SFP channels
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def tx_disable_channel(self, channel, disable):
|
||||||
|
"""
|
||||||
|
Sets the tx_disable for specified SFP channels
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_power_override(self, power_override, power_set):
|
||||||
|
"""
|
||||||
|
Sets SFP power level using power_override and power_set
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the device
|
||||||
|
"""
|
||||||
|
reset = self.get_reset_status()
|
||||||
|
|
||||||
|
if (reset == True):
|
||||||
|
status = False
|
||||||
|
else:
|
||||||
|
status = True
|
||||||
|
|
||||||
|
return status
|
@ -85,6 +85,22 @@ switch_board_modsel() {
|
|||||||
python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1
|
python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Copy led_proc_init.soc file according to the HWSKU
|
||||||
|
init_switch_port_led() {
|
||||||
|
device="/usr/share/sonic/device"
|
||||||
|
platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
|
||||||
|
hwsku=$(cat /etc/sonic/config_db.json | grep "hwsku" | cut -d ":" -f2 | sed 's/"//g' | sed 's/,//g'| xargs )
|
||||||
|
|
||||||
|
led_proc_init="$device/$platform/$hwsku/led_proc_init.soc"
|
||||||
|
# Remove old HWSKU LED file..
|
||||||
|
rm -rf $device/$platform/led_proc_init.soc
|
||||||
|
|
||||||
|
if [ -e $led_proc_init ] && [ ! -e $device/$platform/led_proc_init.soc ]; then
|
||||||
|
cp $led_proc_init $device/$platform/
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
init_devnum
|
init_devnum
|
||||||
|
|
||||||
if [ "$1" == "init" ]; then
|
if [ "$1" == "init" ]; then
|
||||||
@ -98,6 +114,7 @@ if [ "$1" == "init" ]; then
|
|||||||
switch_board_qsfp_mux "new_device"
|
switch_board_qsfp_mux "new_device"
|
||||||
switch_board_qsfp "new_device"
|
switch_board_qsfp "new_device"
|
||||||
switch_board_modsel
|
switch_board_modsel
|
||||||
|
init_switch_port_led
|
||||||
python /usr/bin/qsfp_irq_enable.py
|
python /usr/bin/qsfp_irq_enable.py
|
||||||
|
|
||||||
elif [ "$1" == "deinit" ]; then
|
elif [ "$1" == "deinit" ]; then
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user