[platform] Add Arista DCS-7050QX-32S and missing plugins (#597)

* Update sonic-platform-modules-arista submodule

* Add sensors.conf for Arista DCS-7050QX-32S

* Add plugin/eeprom.py for Arista DCS-7050QX-32S

* Add plugin/sfputil.py for Arista DCS-7050QX-32S

* Add port_config.ini for Arista DCS-7050QX-32S

* Add plugin/sfputil.py for Arista DCS-7060CX-32S

* Add plugin/eeprom.py for Arista DCS-7060CX-32S

* Update plugin/eeprom.py for Arista DCS-7050QX-32
This commit is contained in:
Samuel Angebault 2017-05-16 08:07:47 -07:00 committed by lguohan
parent 8af03fd0f9
commit cb969fc843
10 changed files with 176 additions and 214 deletions

View File

@ -1,220 +1,13 @@
#!/usr/bin/env python
#############################################################################
# Arista 7050-QX32
#
# Platform and model specific eeprom subclass, inherits from the base class,
# and provides the followings:
# - the eeprom format definition
# - specific encoder/decoder if there is special need
#############################################################################
"""
Arista 7050QX-32 eeprom plugin
Uses the arista driver library to obtain the TlvInfoDecoder
"""
try:
import exceptions
import binascii
import time
import optparse
import warnings
import os
import sys
import subprocess
import re
import struct
import zlib
import StringIO
from sonic_eeprom import eeprom_base
from sonic_eeprom import eeprom_tlvinfo
import arista.utils.sonic_eeprom as arista_eeprom
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
def showMac( m ):
return ":".join([m[0:2], m[2:4], m[4:6], m[6:8], m[8:10], m[10:12]])
typeMap = {
"END" : ( "00", None, None, None, False ),
"SKU" : ( "03", None, None, None, False ),
"MAC" : ( "05", None, showMac, None, False ),
"SerialNumber" : ( "0E", None, None, None, False ),
}
idToNameMap = {}
for k, v in typeMap.iteritems():
idToNameMap[ v[0] ] = k
class board(eeprom_tlvinfo.TlvInfoDecoder):
_TLV_INFO_MAX_LEN = 256
_TLV_HDR_ENABLED = 0
pFdl = None
def __init__(self, name, path, cpld_root, ro):
self.eeprom_path = "/sys/bus/i2c/drivers/eeprom/1-0052/eeprom"
super(board, self).__init__(self.eeprom_path, 0, '', True)
def _decode_eeprom(self, e):
# For format 0002 and more recent fdls use the new Prefdl class
data = e[0:4]
if data in ("0002", "0003"):
fp = StringIO.StringIO(e[4:])
self.pFdl = PreFdl( fp, data, data )
def decode_eeprom(self, e):
self._decode_eeprom(e)
return self.pFdl.show()
def is_checksum_valid(self, e):
self._decode_eeprom(e)
return (True, self.pFdl.get_crc())
def serial_number_str(self, e):
self._decode_eeprom(e)
return self.pFdl.get_field('SerialNumber')
def mgmtaddrstr(self,e):
self._decode_eeprom(e)
return self.pFdl.get_field('MAC')
def crc32( data ):
return struct.unpack("I",struct.pack("i",zlib.crc32( data )))[0]
def validSerial( x ):
x = x.replace( " ", "" )
x = x.replace( "-", "" )
# All serial numbers are upper case
x = x.upper()
if re.compile( "[A-Z]{3}\d{4}[A-Z0-9]{4}$" ).match( x ):
return x
return None
class PreFdlField( ):
def __init__( self, name, valid, show, optionName, data=None, append=False ):
self.name = name
if valid:
self.valid = valid
else:
self.valid = lambda x: x
self.show = show
self.optionName = optionName
self.data = []
self.append = append
if data:
self.dataIs( data )
def dataIs( self, data ):
vd = self.valid( data )
if not vd:
raise InvalidPrefdlData( "Invalid %s: %s" % ( self.name, data ) )
if self.append:
self.data.append( vd )
else:
self.data = [ vd ]
class TlvField( PreFdlField ):
def __init__( self, name ):
args = typeMap.get( name )
valid = None
show = None
optionName = None
append = False
if args:
self.id, valid, show, optionName, append = args
PreFdlField.__init__( self, name, valid, show, optionName, append=append )
class PreFdl():
def __init__( self, fp=None, preFdlStr=None, version="0002" ):
# populate the required fields
self.requiredFields = []
self.mac = None
self.serial = None
if version == "0002":
preFdlStr, offset = self.initPreFdl2( fp, preFdlStr )
elif version == "0003":
preFdlStr, offset = self.initPreFdl3( fp, preFdlStr )
else:
raise NotImplementedError(
"Only Prefdl data format version 0002 or 0003 are supported" )
# populate the tlv fileds
self.tlvFields = {}
for k in typeMap.keys():
self.tlvFields[ k ] = TlvField( k )
# create the map option to field
self.optionMap = {}
for f in self.requiredFields + self.tlvFields.values():
# Do not add the option from TLV if already added by required fields
if f.optionName and f.optionName not in self.optionMap:
self.optionMap[ f.optionName ] = f
# save the current tlv fields
if fp:
while True:
tlv = fp.read( 6 )
( id, lengthStr ) = ( tlv[0:2], tlv[2:6] )
length = int( lengthStr, base=16 )
bytes = fp.read( length )
what = None if id not in idToNameMap.keys() else idToNameMap[ id ]
if what and what != "END":
self.tlvFields[ what ].dataIs( bytes )
preFdlStr += tlv + bytes
offset += 6 + length
if what == "END":
# End of the tlv list
break
self.crc = fp.read( 8 )
# Check the CRC
computed = crc32( preFdlStr )
if int( self.crc, 16 ) != computed:
raise Exception( "Invalid CRC -- saw %s expected %8X" %
( self.crc, computed ) )
# Initialize and parse fixed section for prefdl version 2. Return the offset
# to where the TLV section starts.
def initPreFdl2( self, fp, preFdlStr ):
# if we start with an existing file
if fp:
# if no preFdlStr is specified, read the fixed section, 30 bytes.
# Otherwise, only the 4 byte data version section was written and
# read the remaining 26 bytes from the fixed section.
if not preFdlStr:
preFdlStr = fp.read( 30 ).strip()
elif preFdlStr == "0002":
preFdlStr += fp.read( 26 ).strip()
else:
raise ValueError( "preFdlStr arg has invalid data format" )
if len( preFdlStr ) < 12:
fatal( "prefdl is too short exiting" )
data = None if not preFdlStr else preFdlStr[ 16:16 + 11 ]
self.requiredFields.append(
PreFdlField( "SerialNumber", validSerial, None, None, data ) )
return preFdlStr, 30
# Initialize and parse fixed section for prefdl version 3. Return the offset
# to where the TLV section starts.
def initPreFdl3( self, fp, preFdlStr ):
# if we start with an existing file
currPtr = 0
if fp and not preFdlStr:
preFdlStr = fp.read( 4 ).strip()
if len( preFdlStr ) < 4:
fatal( "prefdl is too short exiting" )
return preFdlStr, 4
def show( self ):
for f in self.requiredFields + self.tlvFields.values():
for d in f.data:
dStr = d if f.show is None else f.show( d )
print "%s: %s" % ( f.name, dStr )
def get_field( self, name ):
for f in self.requiredFields + self.tlvFields.values():
for d in f.data:
if f.name == name:
dStr = d if f.show is None else f.show( d )
return dStr
def get_crc( self ):
return self.crc
board = arista_eeprom.getTlvInfoDecoder()

View File

@ -0,0 +1,33 @@
# name lanes alias
Ethernet0 9,10,11,12 Ethernet5/1
Ethernet4 13,14,15,16 Ethernet6/1
Ethernet8 17,18,19,20 Ethernet7/1
Ethernet12 21,22,23,24 Ethernet8/1
Ethernet16 29,30,31,32 Ethernet9/1
Ethernet20 25,26,27,28 Ethernet10/1
Ethernet24 33,34,35,36 Ethernet11/1
Ethernet28 37,38,39,40 Ethernet12/1
Ethernet32 45,46,47,48 Ethernet13/1
Ethernet36 41,42,43,44 Ethernet14/1
Ethernet40 49,50,51,52 Ethernet15/1
Ethernet44 53,54,55,56 Ethernet16/1
Ethernet48 69,70,71,72 Ethernet17/1
Ethernet52 65,66,67,68 Ethernet18/1
Ethernet56 73,74,75,76 Ethernet19/1
Ethernet60 77,78,79,80 Ethernet20/1
Ethernet64 93,94,95,96 Ethernet21/1
Ethernet68 89,90,91,92 Ethernet22/1
Ethernet72 97,98,99,100 Ethernet23/1
Ethernet76 101,102,103,104 Ethernet24/1
Ethernet80 109,110,111,112 Ethernet25/1
Ethernet84 105,106,107,108 Ethernet26/1
Ethernet88 121,122,123,124 Ethernet27/1
Ethernet92 125,126,127,128 Ethernet28/1
Ethernet96 61,62,63,64 Ethernet29
Ethernet100 57,58,59,60 Ethernet30
Ethernet104 81,82,83,84 Ethernet31
Ethernet108 85,86,87,88 Ethernet32
Ethernet112 117,118,119,120 Ethernet33
Ethernet116 113,114,115,116 Ethernet34
Ethernet120 1,2,3,4 Ethernet35
Ethernet124 5,6,7,8 Ethernet36

View File

@ -0,0 +1 @@
SAI_INIT_CONFIG_FILE=/etc/bcm/td2-a7050-qx32s-32x40G.config.bcm

View File

@ -0,0 +1,13 @@
#!/usr/bin/env python
"""
Arista 7050QX-32S eeprom plugin
Uses the arista driver library to obtain the TlvInfoDecoder
"""
try:
import arista.utils.sonic_eeprom as arista_eeprom
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
board = arista_eeprom.getTlvInfoDecoder()

View File

@ -0,0 +1,30 @@
#!/usr/bin/env python
try:
from sonic_sfp.sfputilbase import sfputilbase
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
class sfputil(sfputilbase):
"""Platform specific sfputil class"""
port_start = 0
port_end = 31
ports_in_block = 32
eeprom_offset = 10
port_to_eeprom_mapping = {}
_qsfp_ports = range(0, ports_in_block + 1)
# also has sfp[1-4] ports handled by a mux to choose against qsfp5
# i2c-40 to i2c-43
def __init__(self, port_num):
# Override port_to_eeprom_mapping for class initialization
eeprom_path = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'
for x in range(0, self.port_end + 1):
self.port_to_eeprom_mapping[x] = eeprom_path.format(x + self.eeprom_offset)
sfputilbase.__init__(self, port_num)

View File

@ -0,0 +1,49 @@
# libsensors configuration file for DCS-7050QX-32S
# ------------------------------------------------
#
bus "i2c-2" "SCD SMBus master 0 bus 0"
bus "i2c-3" "SCD SMBus master 0 bus 1"
bus "i2c-5" "SCD SMBus master 0 bus 3"
bus "i2c-6" "SCD SMBus master 0 bus 4"
bus "i2c-7" "SCD SMBus master 0 bus 5"
chip "k10temp-pci-00c3"
label temp1 "Cpu temp sensor"
chip "max6658-i2c-2-4c"
label temp1 "Board temp sensor"
set temp1_max 55
set temp1_crit 70
label temp2 "Front panel temp sensor"
set temp2_max 65
set temp2_crit 75
chip "max6658-i2c-3-4c"
label temp1 "Cpu board temp sensor"
set temp1_max 75
set temp1_crit 80
label temp2 "Back panel temp sensor"
set temp2_max 75
set temp2_crit 80
chip "pmbus-i2c-3-4e"
label temp1 "Power controller 1 sensor 1"
label temp2 "Power controller 1 sensor 2"
chip "pmbus-i2c-7-4e"
label temp1 "Power controller 2 sensor 1"
label temp2 "Power controller 2 sensor 2"
chip "pmbus-i2c-6-58"
label temp1 "Power supply 1 hotspot sensor"
label temp2 "Power supply 1 inlet temp sensor"
label temp3 "Power supply 1 sensor"
chip "pmbus-i2c-5-58"
label temp1 "Power supply 2 hotspot sensor"
label temp2 "Power supply 2 inlet temp sensor"
label temp3 "Power supply 2 sensor"

View File

@ -0,0 +1,13 @@
#!/usr/bin/env python
"""
Arista 7060CX-32S eeprom plugin
Uses the arista driver library to obtain the TlvInfoDecoder
"""
try:
import arista.utils.sonic_eeprom as arista_eeprom
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
board = arista_eeprom.getTlvInfoDecoder()

View File

@ -0,0 +1,28 @@
#!/usr/bin/env python
try:
from sonic_sfp.sfputilbase import sfputilbase
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
class sfputil(sfputilbase):
"""Platform specific sfputil class"""
port_start = 0
port_end = 33
ports_in_block = 34
eeprom_offset = 18
port_to_eeprom_mapping = {}
_qsfp_ports = range(0, 32 + 1)
_sfp_ports = range(33, 34 + 1)
def __init__(self, port_num):
# Override port_to_eeprom_mapping for class initialization
eeprom_path = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'
for x in range(0, self.port_end + 1):
self.port_to_eeprom_mapping[x] = eeprom_path.format(x + self.eeprom_offset)
sfputilbase.__init__(self, port_num)

View File

@ -14,6 +14,8 @@ elif [ "$HWSKU" == "Force10-Z9100" ]; then
ORCHAGENT_ARGS+="-m $MAC_ADDRESS"
elif [ "$HWSKU" == "Arista-7050-QX32" ]; then
ORCHAGENT_ARGS+="-m $MAC_ADDRESS"
elif [ "$HWSKU" == "Arista-7050-QX32S" ]; then
ORCHAGENT_ARGS+="-m $MAC_ADDRESS"
elif [ "$HWSKU" == "Arista-7060-CX32S" ]; then
ORCHAGENT_ARGS+="-m $MAC_ADDRESS"
elif [ "$HWSKU" == "AS7512" ]; then

@ -1 +1 @@
Subproject commit a1ca8013e952d1cc0d555c24fe6eb2bf016ab694
Subproject commit 43ed7b2330f2c7928f8098ca6c78bd9533b918c5