Skip to content

Commit

Permalink
[platform] Add Arista DCS-7050QX-32S and missing plugins (#597)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Staphylo authored and lguohan committed May 16, 2017
1 parent 8af03fd commit cb969fc
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 214 deletions.
219 changes: 6 additions & 213 deletions device/arista/x86_64-arista_7050_qx32/plugins/eeprom.py
Original file line number Diff line number Diff line change
@@ -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()
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SAI_INIT_CONFIG_FILE=/etc/bcm/td2-a7050-qx32s-32x40G.config.bcm
13 changes: 13 additions & 0 deletions device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py
Original file line number Diff line number Diff line change
@@ -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()
30 changes: 30 additions & 0 deletions device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py
Original file line number Diff line number Diff line change
@@ -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)
49 changes: 49 additions & 0 deletions device/arista/x86_64-arista_7050_qx32s/sensors.conf
Original file line number Diff line number Diff line change
@@ -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"

13 changes: 13 additions & 0 deletions device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py
Original file line number Diff line number Diff line change
@@ -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()
Loading

0 comments on commit cb969fc

Please sign in to comment.