Skip to content

Commit

Permalink
BFN platform API 2.0 support (#4766)
Browse files Browse the repository at this point in the history
Added barefoot platform api 2.0 support

Signed-off-by: Volodymyr Boyko <[email protected]>
  • Loading branch information
vboykox authored Oct 3, 2020
1 parent e92061c commit dbea3bb
Show file tree
Hide file tree
Showing 19 changed files with 4,722 additions and 5 deletions.
21 changes: 16 additions & 5 deletions platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
#!/usr/bin/make -f

PLATFORM = x86_64-accton_wedge100bf_32x-r0
PACKAGE_NAME := sonic-platform-modules-bfn-montara
SCRIPT_SRC := $(shell pwd)/scripts
CONFIGS_SRC := $(shell pwd)/configs
BUILD_DIR := $(shell pwd)/build
WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel
PLUGINS_DIR := $(shell pwd)/plugins

%:
dh $@

override_dh_auto_build:
set -e
python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR)
python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR)
set +e

override_dh_auto_install:
dh_installdirs -p$(PACKAGE_NAME) usr/local/bin
cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin
dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/
cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/
dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/x86_64-accton_wedge100bf_32x-r0/plugins
cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/x86_64-accton_wedge100bf_32x-r0/plugins/
dh_installdirs -p$(PACKAGE_NAME) /usr/share/sonic/device/${PLATFORM}/
cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/
dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/${PLATFORM}/plugins
cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/plugins/

override_dh_usrlocal:

override_dh_pysupport:

override_dh_clean:
rm -fr $(WHEEL_BUILD_DIR)
rm -fr *.egg-info
rm -fr $(BUILD)
dh_clean

31 changes: 31 additions & 0 deletions platform/barefoot/sonic-platform-modules-bfn-montara/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from setuptools import setup

setup(
name='sonic-platform',
version='1.0',
description='SONiC platform API implementation',
license='Apache 2.0',
author='SONiC Team',
author_email='',
url='https://github.com/Azure/sonic-buildimage',
maintainer='Barefoot',
maintainer_email='',
packages=[
'sonic_platform',
'sonic_platform/pltfm_mgr_rpc'
],
package_data = {'sonic_platform':['logging.conf']},
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',
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp']
import platform
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env python

try:
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.sfp import Sfp
from sonic_platform.psu import Psu
from eeprom import Eeprom
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

class Chassis(ChassisBase):
"""
Platform-specific Chassis class
"""
def __init__(self):
ChassisBase.__init__(self)
SFP_PORT_END = Sfp.port_end()
PORTS_IN_BLOCK = (SFP_PORT_END + 1)
MAX_PSU = Psu.get_num_psus()

self._eeprom = Eeprom()

for index in range(0, PORTS_IN_BLOCK):
sfp_node = Sfp(index)
self._sfp_list.append(sfp_node)

for i in range(MAX_PSU):
psu = Psu(i)
self._psu_list.append(psu)

def get_name(self):
"""
Retrieves the name of the chassis
Returns:
string: The name of the chassis
"""
return self._eeprom.modelstr()

def get_presence(self):
"""
Retrieves the presence of the chassis
Returns:
bool: True if chassis is present, False if not
"""
return True

def get_model(self):
"""
Retrieves the model number (or part number) of the chassis
Returns:
string: Model/part number of chassis
"""
return self._eeprom.part_number_str()

def get_serial(self):
"""
Retrieves the serial number of the chassis (Service tag)
Returns:
string: Serial number of chassis
"""
return self._eeprom.serial_str()

def get_sfp(self, index):
"""
Retrieves sfp represented by (1-based) index <index>
Args:
index: An integer, the index (1-based) of the sfp to retrieve.
The index should be the sequence of a physical port in a chassis,
starting from 1.
For example, 0 for Ethernet0, 1 for Ethernet4 and so on.
Returns:
An object dervied from SfpBase representing the specified sfp
"""
sfp = None

try:
sfp = self._sfp_list[index-1]
except IndexError:
sys.stderr.write("SFP index {} out of range (1-{})\n".format(
index, len(self._sfp_list)-1))
return sfp

def get_status(self):
"""
Retrieves the operational status of the chassis
Returns:
bool: A boolean value, True if chassis is operating properly
False if not
"""
return True

def get_base_mac(self):
"""
Retrieves the base MAC address for the chassis
Returns:
A string containing the MAC address in the format
'XX:XX:XX:XX:XX:XX'
"""
return self._eeprom.base_mac_addr()

def get_serial_number(self):
"""
Retrieves the hardware serial number for the chassis
Returns:
A string containing the hardware serial number for this chassis.
"""
return self._eeprom.serial_number_str()

def get_system_eeprom_info(self):
"""
Retrieves the full content of system EEPROM information for the chassis
Returns:
A dictionary where keys are the type code defined in
OCP ONIE TlvInfo EEPROM format and values are their corresponding
values.
"""
return self._eeprom.system_eeprom_info()

def get_change_event(self, timeout=0):
ready, event_sfp = Sfp.get_transceiver_change_event(timeout)
return ready, { 'sfp': event_sfp } if ready else {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/usr/bin/python


try:
import time
import os
import sys
import errno
import datetime
import logging
import logging.config
import yaml

sys.path.append(os.path.dirname(__file__))

from cStringIO import StringIO
from sonic_eeprom import eeprom_base
from sonic_eeprom import eeprom_tlvinfo

from .platform_thrift_client import ThriftClient
except ImportError, e:
raise ImportError (str(e) + "- required module not found")


eeprom_default_dict = {
"prod_name" : ("Product Name", "0x21", 12),
"odm_pcba_part_num" : ("Part Number", "0x22", 13),
"prod_ser_num" : ("Serial Number", "0x23", 12),
"ext_mac_addr" : ("Extended MAC Address Base", "0x24", 12),
"sys_mfg_date" : ("System Manufacturing Date", "0x25", 4),
"prod_ver" : ("Product Version", "0x26", 1),
"ext_mac_addr_size" : ("Extende MAC Address Size", "0x2A", 2),
"sys_mfger" : ("Manufacturer", "0x2B", 8)
}

eeprom_dict = { "version" : ("Version", None, 0),
"pcb_mfger" : ("PCB Manufacturer", "0x01", 8),
"prod_ser_num" : ("Serial Number", "0x23", 12),
"bfn_pcba_part_num" : ("Switch PCBA Part Number", "0x02", 12),
"odm_pcba_part_num" : ("Part Number", "0x22", 13),
"bfn_pcbb_part_num" : ("Switch PCBB Part Number", "0x04", 12),
"sys_asm_part_num" : ("System Assembly Part Number", "0x05", 12),
"prod_state" : ("Product Production State", "0x06", 1),
"location" : ("EEPROM Location of Fabric", "0x07", 8),
"ext_mac_addr_size" : ("Extende MAC Address Size", "0x08", 2),
"sys_mfg_date" : ("System Manufacturing Date", "0x25", 4),
"prod_name" : ("Product Name", "0x21", 12),
"prod_ver" : ("Product Version", "0x26", 1),
"prod_part_num" : ("Product Part Number", "0x09", 8),
"sys_mfger" : ("Manufacturer", "0x2B", 8),
"assembled_at" : ("Assembled at", "0x08", 8),
"prod_ast_tag" : ("Product Asset Tag", "0x09", 12),
"loc_mac_addr" : ("Local MAC address", "0x0A", 12),
"odm_pcba_ser_num" : ("ODM PBCA Serial Number", "0x0B", 12),
"ext_mac_addr" : ("Extended MAC Address Base", "0x0C", 12),
"prod_sub_ver" : ("Product Sub Version", "0x0D", 1)
}

product_dict = { "Montara" : "Wedge100BF-32X-O-AC-F-BF",
"Lower MAV" : "Wedge100BF-65X-O-AC-F-BF",
"Upper MAV" : "Wedge100BF-65X-O-AC-F-BF"
}

EEPROM_SYMLINK = "/var/run/platform/eeprom/syseeprom"
EEPROM_STATUS = "/var/run/platform/eeprom/status"

class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
RETRIES = 35

def __init__(self):

with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f:
config_dict = yaml.load(f, yaml.SafeLoader)
logging.config.dictConfig(config_dict)

if not os.path.exists(os.path.dirname(EEPROM_SYMLINK)):
try:
os.makedirs(os.path.dirname(EEPROM_SYMLINK))
except OSError as e:
if e.errno != errno.EEXIST:
raise

open(EEPROM_SYMLINK, 'a').close()
f = open(EEPROM_STATUS, 'w')
f.write("initializing..")
f.close()

self.eeprom_path = EEPROM_SYMLINK
super(Eeprom, self).__init__(self.eeprom_path, 0, EEPROM_STATUS, True)

for attempt in range(self.RETRIES):
if self.eeprom_init():
break
if attempt + 1 == self.RETRIES:
raise RuntimeError("eeprom.py: Initialization failed")
time.sleep(1)

def eeprom_init(self):
try:
with ThriftClient() as client:
self.eeprom = client.pltfm_mgr.pltfm_mgr_sys_eeprom_get()
except Exception:
return False

f = open(EEPROM_STATUS, 'w')
f.write("ok")
f.close()

eeprom_params = ""
for attr, val in self.eeprom.__dict__.iteritems():
if val is None:
continue

elem = eeprom_default_dict.get(attr)
if elem is None:
continue

if isinstance(val, basestring):
value = val.replace('\0', '')
else:
value = str(val)

if attr == "sys_mfg_date":
value = datetime.datetime.strptime(value, '%m-%d-%y').strftime('%m/%d/%Y 00:00:00')

product = product_dict.get(value)
if product is not None:
value = product
if len(eeprom_params) > 0:
eeprom_params += ","
eeprom_params += "{0:s}={1:s}".format(elem[1], value)

orig_stdout = sys.stdout
sys.stdout = StringIO()
new_e = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params])
sys.stdout = orig_stdout
eeprom_base.EepromDecoder.write_eeprom(self, new_e)

return True

def serial_number_str(self):
return self.eeprom.prod_ser_num

def system_eeprom_info(self):
return self.eeprom.__dict__

def get_base_mac(self):
return self.eeprom.ext_mac_addr

def part_number_str(self):
return self.eeprom.prod_part_num
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env python

#############################################################################
#
# Module contains an implementation of SONiC Platform Base API and
# provides the platform information
#
#############################################################################

try:
from sonic_platform_base.platform_base import PlatformBase
from sonic_platform.chassis import Chassis
except ImportError as e:
raise ImportError(str(e) + "- required module not found")


class Platform(PlatformBase):

def __init__(self):
PlatformBase.__init__(self)
self._chassis = Chassis()
Loading

0 comments on commit dbea3bb

Please sign in to comment.