Skip to content

Commit

Permalink
[devices]: Add platform support for delta ag9032v2a (#3148)
Browse files Browse the repository at this point in the history
Add platform support for delta ag9032v2a
CPU: Broadwell-DE
ASIC: BMC56870 with <100Gx32 + 10Gx1>
BMC: AST2520:
- What I did
add the new platform of delta ag9032v2a
- How I did it
1.provide the QSFP and SWPLD attributes and create the virtual buses of I2C
2. provide the port configuration
- How to verify it
1. psuutil.py
2. sfputil.py
3. bcmcd

- Known issue
The port LED is not ready. We noticed that BCM chip had the M0 FW initialization issue while bringing up SDK with "BRCM SAI ver: [3.5.2.3], OCP SAI ver: [1.4], SDK ver: [6.5.14]" and here is the information :
root@sonic:/home/admin# bcmcmd "M0 status"
M0 status
0:soc_iproc_data_send_wait: No response for msg 2
M0 FW is NOT Running
M0 FW Version is 0.0
Host FW Version is 1.0
Host and M0 FW Versions do not match!!!

Signed-off-by: hans-tseng <hans.tseng@deltaww.com>
  • Loading branch information
hans-tseng authored and lguohan committed Aug 2, 2019
1 parent 11ea368 commit ca1534a
Show file tree
Hide file tree
Showing 19 changed files with 2,558 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# name lanes alias
Ethernet0 41,42,43,44 hundredGigE1/1
Ethernet4 45,46,47,48 hundredGigE1/2
Ethernet8 49,50,51,52 hundredGigE1/3
Ethernet12 37,38,39,40 hundredGigE1/4
Ethernet16 33,34,35,36 hundredGigE1/5
Ethernet20 53,54,55,56 hundredGigE1/6
Ethernet24 57,58,59,60 hundredGigE1/7
Ethernet28 61,62,63,64 hundredGigE1/8
Ethernet32 65,66,67,68 hundredGigE1/9
Ethernet36 69,70,71,72 hundredGigE1/10
Ethernet40 73,74,75,76 hundredGigE1/11
Ethernet44 77,78,79,80 hundredGigE1/12
Ethernet48 81,82,83,84 hundredGigE1/13
Ethernet52 85,86,87,88 hundredGigE1/14
Ethernet56 89,90,91,92 hundredGigE1/15
Ethernet60 93,94,95,96 hundredGigE1/16
Ethernet64 97,98,99,100 hundredGigE1/17
Ethernet68 101,102,103,104 hundredGigE1/18
Ethernet72 105,106,107,108 hundredGigE1/19
Ethernet76 109,110,111,112 hundredGigE1/20
Ethernet80 121,122,123,124 hundredGigE1/21
Ethernet84 113,114,115,116 hundredGigE1/22
Ethernet88 1,2,3,4 hundredGigE1/23
Ethernet92 117,118,119,120 hundredGigE1/24
Ethernet96 5,6,7,8 hundredGigE1/25
Ethernet100 125,126,127,128 hundredGigE1/26
Ethernet104 29,30,31,32 hundredGigE1/27
Ethernet108 9,10,11,12 hundredGigE1/28
Ethernet112 13,14,15,16 hundredGigE1/29
Ethernet116 25,26,27,28 hundredGigE1/30
Ethernet120 17,18,19,20 hundredGigE1/31
Ethernet124 21,22,23,24 hundredGigE1/32
Ethernet128 129 hundredGigE1/33
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ag9032v2a-32x100G+1x10G.config.bcm

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions device/delta/x86_64-delta_ag9032v2a-r0/installer.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONSOLE_PORT=0x3f8
CONSOLE_SPEED=115200
32 changes: 32 additions & 0 deletions device/delta/x86_64-delta_ag9032v2a-r0/plugins/eeprom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env python

#############################################################################
# Mellanox
#
# 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
#############################################################################

try:
import exceptions
import binascii
import time
import optparse
import warnings
import os
import sys
from sonic_eeprom import eeprom_base
from sonic_eeprom import eeprom_tlvinfo
import subprocess
except ImportError, e:
raise ImportError (str(e) + "- required module not found")

class board(eeprom_tlvinfo.TlvInfoDecoder):

_TLV_INFO_MAX_LEN = 256

def __init__(self, name, path, cpld_root, ro):
self.eeprom_path = "/sys/devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-1/1-0053/eeprom"
super(board, self).__init__(self.eeprom_path, 0, '', True)
85 changes: 85 additions & 0 deletions device/delta/x86_64-delta_ag9032v2a-r0/plugins/psuutil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#
# Module contains an implementation of SONiC PSU Base API and
# provides the PSUs status which are available in the platform
#

import os.path
import subprocess

try:
from sonic_psu.psu_base import PsuBase
except ImportError as e:
raise ImportError (str(e) + "- required module not found")

class PsuUtil(PsuBase):
"""Platform-specific PSUutil class"""

def __init__(self):
PsuBase.__init__(self)

def get_num_psus(self):
"""
Retrieves the number of PSUs available on the device
:return: An integer, the number of PSUs available on the device
"""
return 2

def get_psu_status(self, index):
"""
Retrieves the oprational status of power supply unit (PSU) defined
by 1-based index <index>
:param index: An integer, 1-based index of the PSU of which to query status
:return: Boolean, True if PSU is operating properly, False if PSU is faulty
"""
if index is None:
return False
status = 0
try:
p = os.popen("ipmitool raw 0x38 0x2 3 0x6a 0x3 1")
content = p.readline().rstrip()
reg_value = int(content, 16)
if index == 1:
mask = (1 << 6)
else:
mask = (1 << 2)
if reg_value & mask == 0:
return False
status = 1
p.close()
except IOError:
return False
return status == 1


def get_psu_presence(self, index):
"""
Retrieves the presence status of power supply unit (PSU) defined
by 1-based index <index>
:param index: An integer, 1-based index of the PSU of which to query status
:return: Boolean, True if PSU is plugged, False if not
"""
if index is None:
return False

status = 0
try:
p = os.popen("ipmitool raw 0x38 0x2 3 0x6a 0x3 1")
content = p.readline().rstrip()
reg_value = int(content, 16)
if index == 1:
mask = (1 << 7)
if reg_value & mask == 0x80:
return False
else:
mask = (1 << 3)
if reg_value & mask == 0x08:
return False
status = 1
p.close()
except IOError:
return False
return status == 1

183 changes: 183 additions & 0 deletions device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# sfputil.py
#
# Platform-specific SFP transceiver interface for SONiC
#

try:
import time
from sonic_sfp.sfputilbase import SfpUtilBase
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))


class SfpUtil(SfpUtilBase):
"""Platform-specific SfpUtil class"""

PORT_START = 0
PORT_END = 32
PORTS_IN_BLOCK = 33

EEPROM_OFFSET = 20

_port_to_eeprom_mapping = {}

@property
def port_start(self):
return self.PORT_START

@property
def port_end(self):
return self.PORT_END

@property
def qsfp_ports(self):
return range(0, self.PORT_END - self.PORT_START + 1)

@property
def port_to_eeprom_mapping(self):
return self._port_to_eeprom_mapping

def __init__(self):
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)

def get_presence(self, port_num):
# Check for invalid port_num
if port_num < self.port_start or port_num > self.port_end:
return False

try:
reg_file = open("/sys/devices/platform/delta-ag9032v2a-swpld1.0/sfp_is_present")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False

content = reg_file.readline().rstrip()

# content is a string containing the hex representation of the register
reg_value = int(content, 16)

# Mask off the bit corresponding to our port
mask = (1 << port_num)

# ModPrsL is active low
if reg_value & mask == 0:
return True

return False

def get_low_power_mode(self, port_num):
# Check for invalid port_num
if port_num < self.port_start or port_num > self.port_end - 1:
return False

try:
reg_file = open("/sys/devices/platform/delta-ag9032v2a-swpld1.0/qsfp_lpmode")
except IOError as e:
print "Error: unable to open file: %s" % str(e)

content = reg_file.readline().rstrip()

# content is a string containing the hex representation of the register
reg_value = int(content, 16)

# Mask off the bit corresponding to our port
mask = (1 << port_num)

# LPMode is active high
if reg_value & mask == 0:
return False

return True

def set_low_power_mode(self, port_num, lpmode):
# Check for invalid port_num
if port_num < self.port_start or port_num > self.port_end - 1:
return False

try:
reg_file = open("/sys/devices/platform/delta-ag9032v2a-swpld1.0/qsfp_lpmode", "r+")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False

content = reg_file.readline().rstrip()

# content is a string containing the hex representation of the register
reg_value = int(content, 16)

# Mask off the bit corresponding to our port
mask = (1 << port_num)

# LPMode is active high; set or clear the bit accordingly
if lpmode is True:
reg_value = reg_value | mask
else:
reg_value = reg_value & ~mask

# Convert our register value back to a hex string and write back
content = hex(reg_value)

reg_file.seek(0)
reg_file.write(content)
reg_file.close()

return True

def reset(self, port_num):
QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/delta-ag9032v2a-swpld1.0/qsfp_reset"

# Check for invalid port_num
if port_num < self.port_start or port_num > self.port_end - 1:
return False

try:
reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False

content = reg_file.readline().rstrip()

# File content is a string containing the hex representation of the register
reg_value = int(content, 16)

# Mask off the bit corresponding to our port
mask = (1 << port_num)

# ResetL is active low
reg_value = reg_value & ~mask

# Convert our register value back to a hex string and write back
reg_file.seek(0)
reg_file.write(hex(reg_value))
reg_file.close()

# Sleep 1 second to allow it to settle
time.sleep(1)

# Flip the bit back high and write back to the register to take port out of reset
try:
reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False

reg_value = reg_value | mask
reg_file.seek(0)
reg_file.write(hex(reg_value))
reg_file.close()

return True

def get_transceiver_change_event(self):
"""
TODO: This function need to be implemented
when decide to support monitoring SFP(Xcvrd)
on this platform.
"""
raise NotImplementedError
3 changes: 2 additions & 1 deletion platform/broadcom/one-image.mk
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
$(MITAC_LY1200_32X_PLATFORM_MODULE) \
$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \
$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \
$(BRCM_XLR_GTS_PLATFORM_MODULE)
$(BRCM_XLR_GTS_PLATFORM_MODULE) \
$(DELTA_AG9032V2A_PLATFORM_MODULE)
ifeq ($(INSTALL_DEBUG_TOOLS),y)
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
Expand Down
8 changes: 7 additions & 1 deletion platform/broadcom/platform-modules-delta.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ DELTA_AG9032V1_PLATFORM_MODULE_VERSION = 1.1
DELTA_AG9064_PLATFORM_MODULE_VERSION = 1.1
DELTA_AG5648_PLATFORM_MODULE_VERSION = 1.1
DELTA_ET6248BRB_PLATFORM_MODULE_VERSION = 1.1
DELTA_AG9032V2A_PLATFORM_MODULE_VERSION = 1.1

export DELTA_AG9032V1_PLATFORM_MODULE_VERSION
export DELTA_AG9064_PLATFORM_MODULE_VERSION
export DELTA_AG5648_PLATFORM_MODULE_VERSION
export DELTA_ET6248BRB_PLATFORM_MODULE_VERSION
export DELTA_AG9032V2A_PLATFORM_MODULE_VERSION

DELTA_AG9032V1_PLATFORM_MODULE = platform-modules-ag9032v1_$(DELTA_AG9032V1_PLATFORM_MODULE_VERSION)_amd64.deb
$(DELTA_AG9032V1_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-delta
Expand All @@ -28,4 +30,8 @@ DELTA_ET6248BRB_PLATFORM_MODULE = platform-modules-et-6248brb_$(DELTA_ET6248BRB_
$(DELTA_ET6248BRB_PLATFORM_MODULE)_PLATFORM = x86_64-delta_et-6248brb-r0
$(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_ET6248BRB_PLATFORM_MODULE)))

SONIC_STRETCH_DEBS += $(DELTA_AG9032V1_PLATFORM_MODULE)
DELTA_AG9032V2A_PLATFORM_MODULE = platform-modules-ag9032v2a_$(DELTA_AG9032V2A_PLATFORM_MODULE_VERSION)_amd64.deb
$(DELTA_AG9032V2A_PLATFORM_MODULE)_PLATFORM = x86_64-delta_ag9032v2a-r0
$(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_AG9032V2A_PLATFORM_MODULE)))

SONIC_STRETCH_DEBS += $(DELTA_AG9032V1_PLATFORM_MODULE)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

i2c-i801
i2c-isch
i2c-ismt
i2c-dev
i2c-mux
i2c-smbus
i2c-mux-gpio
i2c-mux-pca954x
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj-m += delta_ag9032v2a_platform.o
Loading

0 comments on commit ca1534a

Please # to comment.