Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BFN platform API 2.0 support #4766

Merged
merged 9 commits into from
Oct 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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