From cb969fc843b7a2aab5516c0090d241122e2053e5 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 16 May 2017 08:07:47 -0700 Subject: [PATCH] [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 --- .../x86_64-arista_7050_qx32/plugins/eeprom.py | 219 +----------------- .../Arista-7050-QX32S/port_config.ini | 33 +++ .../Arista-7050-QX32S/sai.profile | 1 + .../plugins/eeprom.py | 13 ++ .../plugins/sfputil.py | 30 +++ .../x86_64-arista_7050_qx32s/sensors.conf | 49 ++++ .../plugins/eeprom.py | 13 ++ .../plugins/sfputil.py | 28 +++ dockers/docker-orchagent/orchagent.sh | 2 + .../broadcom/sonic-platform-modules-arista | 2 +- 10 files changed, 176 insertions(+), 214 deletions(-) create mode 100644 device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX32S/port_config.ini create mode 100644 device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX32S/sai.profile create mode 100644 device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py create mode 100644 device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py create mode 100644 device/arista/x86_64-arista_7050_qx32s/sensors.conf create mode 100644 device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py create mode 100644 device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py diff --git a/device/arista/x86_64-arista_7050_qx32/plugins/eeprom.py b/device/arista/x86_64-arista_7050_qx32/plugins/eeprom.py index f8a3515d924f..9da54dbf1b90 100644 --- a/device/arista/x86_64-arista_7050_qx32/plugins/eeprom.py +++ b/device/arista/x86_64-arista_7050_qx32/plugins/eeprom.py @@ -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() diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX32S/port_config.ini b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX32S/port_config.ini new file mode 100644 index 000000000000..b56d958499d4 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX32S/port_config.ini @@ -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 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX32S/sai.profile b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX32S/sai.profile new file mode 100644 index 000000000000..e06f3ba3a4b1 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX32S/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/etc/bcm/td2-a7050-qx32s-32x40G.config.bcm diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py b/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py new file mode 100644 index 000000000000..d1c6212219d4 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py @@ -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() diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py b/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py new file mode 100644 index 000000000000..18472c44c55b --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py @@ -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) diff --git a/device/arista/x86_64-arista_7050_qx32s/sensors.conf b/device/arista/x86_64-arista_7050_qx32s/sensors.conf new file mode 100644 index 000000000000..fc5f5c8c3e8e --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/sensors.conf @@ -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" + diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py b/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py new file mode 100644 index 000000000000..0cfe5109a300 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py @@ -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() diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py b/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py new file mode 100644 index 000000000000..0f7f0d2cac85 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py @@ -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) diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index cdf9ea16627a..15eb2c7e17ac 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -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 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index a1ca8013e952..43ed7b2330f2 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit a1ca8013e952d1cc0d555c24fe6eb2bf016ab694 +Subproject commit 43ed7b2330f2c7928f8098ca6c78bd9533b918c5