[Ingrasys] Add platform support for S9180-32X/S9280-64X with Barefoot ASIC on master branch (#1880)
* delete barefoot sonic-platform-modules-ingrasys * add submodule for barefoot sonic-platform-modules-ingrasys * add barefoot platform supports on master branch * change the default speed from 40G to 100G * remove barefoot sonic-platform-modules-ingrasys submodule * add ingrasys s9180-32x, s9280-64x barefoot platform drivers * update s9280-64x vdd core voltage * update ingrasys barefoot platform debian rules
This commit is contained in:
parent
a8c41d9a66
commit
8e74230e86
@ -93,7 +93,7 @@
|
||||
<PngDec>
|
||||
<DeviceInterfaceLinks>
|
||||
<DeviceLinkBase i:type="DeviceInterfaceLink">
|
||||
<Bandwidth>40000</Bandwidth>
|
||||
<Bandwidth>100000</Bandwidth>
|
||||
<ElementType>DeviceInterfaceLink</ElementType>
|
||||
<EndDevice>OCPSCH0104001MS</EndDevice>
|
||||
<EndPort>Ethernet24</EndPort>
|
||||
@ -101,7 +101,7 @@
|
||||
<StartPort>Ethernet0</StartPort>
|
||||
</DeviceLinkBase>
|
||||
<DeviceLinkBase i:type="DeviceInterfaceLink">
|
||||
<Bandwidth>40000</Bandwidth>
|
||||
<Bandwidth>100000</Bandwidth>
|
||||
<ElementType>DeviceInterfaceLink</ElementType>
|
||||
<EndDevice>OCPSCH0104002MS</EndDevice>
|
||||
<EndPort>Ethernet24</EndPort>
|
||||
|
@ -40,9 +40,9 @@ chip "w83795adg-*"
|
||||
label in0 "0.9V"
|
||||
set in0_max 0.927
|
||||
set in0_min 0.873
|
||||
label in1 "0.86V"
|
||||
set in1_max 0.877
|
||||
set in1_min 0.843
|
||||
label in1 "VDD"
|
||||
set in1_max 0.962
|
||||
set in1_min 0.717
|
||||
ignore in2
|
||||
ignore in3
|
||||
ignore in4
|
||||
|
@ -0,0 +1,65 @@
|
||||
# name lanes alias speed autoneg fec index
|
||||
Ethernet0 0,1,2,3 Ethernet0 100000 0 0 0
|
||||
Ethernet4 4,5,6,7 Ethernet4 100000 0 0 1
|
||||
Ethernet8 8,9,10,11 Ethernet8 100000 0 0 2
|
||||
Ethernet12 12,13,14,15 Ethernet12 100000 0 0 3
|
||||
Ethernet16 16,17,18,19 Ethernet16 100000 0 0 4
|
||||
Ethernet20 20,21,22,23 Ethernet20 100000 0 0 5
|
||||
Ethernet24 24,25,26,27 Ethernet24 100000 0 0 6
|
||||
Ethernet28 28,29,30,31 Ethernet28 100000 0 0 7
|
||||
Ethernet32 32,33,34,35 Ethernet32 100000 0 0 8
|
||||
Ethernet36 36,37,38,39 Ethernet36 100000 0 0 9
|
||||
Ethernet40 40,41,42,43 Ethernet40 100000 0 0 10
|
||||
Ethernet44 44,45,46,47 Ethernet44 100000 0 0 11
|
||||
Ethernet48 48,49,50,51 Ethernet48 100000 0 0 12
|
||||
Ethernet52 52,53,54,55 Ethernet52 100000 0 0 13
|
||||
Ethernet56 56,57,58,59 Ethernet56 100000 0 0 14
|
||||
Ethernet60 60,61,62,63 Ethernet60 100000 0 0 15
|
||||
Ethernet64 64,65,66,67 Ethernet64 100000 0 0 16
|
||||
Ethernet68 68,69,70,71 Ethernet68 100000 0 0 17
|
||||
Ethernet72 72,73,74,75 Ethernet72 100000 0 0 18
|
||||
Ethernet76 76,77,78,79 Ethernet76 100000 0 0 19
|
||||
Ethernet80 80,81,82,83 Ethernet80 100000 0 0 20
|
||||
Ethernet84 84,85,86,87 Ethernet84 100000 0 0 21
|
||||
Ethernet88 88,89,90,91 Ethernet88 100000 0 0 22
|
||||
Ethernet92 92,93,94,95 Ethernet92 100000 0 0 23
|
||||
Ethernet96 96,97,98,99 Ethernet96 100000 0 0 24
|
||||
Ethernet100 100,101,102,103 Ethernet100 100000 0 0 25
|
||||
Ethernet104 104,105,106,107 Ethernet104 100000 0 0 26
|
||||
Ethernet108 108,109,110,111 Ethernet108 100000 0 0 27
|
||||
Ethernet112 112,113,114,115 Ethernet112 100000 0 0 28
|
||||
Ethernet116 116,117,118,119 Ethernet116 100000 0 0 29
|
||||
Ethernet120 120,121,122,123 Ethernet120 100000 0 0 30
|
||||
Ethernet124 124,125,126,127 Ethernet124 100000 0 0 31
|
||||
Ethernet128 128,129,130,131 Ethernet128 100000 0 0 32
|
||||
Ethernet132 132,133,134,135 Ethernet132 100000 0 0 33
|
||||
Ethernet136 136,137,138,139 Ethernet136 100000 0 0 34
|
||||
Ethernet140 140,141,142,143 Ethernet140 100000 0 0 35
|
||||
Ethernet144 144,145,146,147 Ethernet144 100000 0 0 36
|
||||
Ethernet148 148,149,150,151 Ethernet148 100000 0 0 37
|
||||
Ethernet152 152,153,154,155 Ethernet152 100000 0 0 38
|
||||
Ethernet156 156,157,158,159 Ethernet156 100000 0 0 39
|
||||
Ethernet160 160,161,162,163 Ethernet160 100000 0 0 40
|
||||
Ethernet164 164,165,166,167 Ethernet164 100000 0 0 41
|
||||
Ethernet168 168,169,170,171 Ethernet168 100000 0 0 42
|
||||
Ethernet172 172,173,174,175 Ethernet172 100000 0 0 43
|
||||
Ethernet176 176,177,178,179 Ethernet176 100000 0 0 44
|
||||
Ethernet180 180,181,182,183 Ethernet180 100000 0 0 45
|
||||
Ethernet184 184,185,186,187 Ethernet184 100000 0 0 46
|
||||
Ethernet188 188,189,190,191 Ethernet188 100000 0 0 47
|
||||
Ethernet192 192,193,194,195 Ethernet192 100000 0 0 48
|
||||
Ethernet196 196,197,198,199 Ethernet196 100000 0 0 49
|
||||
Ethernet200 200,201,202,203 Ethernet200 100000 0 0 50
|
||||
Ethernet204 204,205,206,207 Ethernet204 100000 0 0 51
|
||||
Ethernet208 208,209,210,211 Ethernet208 100000 0 0 52
|
||||
Ethernet212 212,213,214,215 Ethernet212 100000 0 0 53
|
||||
Ethernet216 216,217,218,219 Ethernet216 100000 0 0 54
|
||||
Ethernet220 220,221,222,223 Ethernet220 100000 0 0 55
|
||||
Ethernet224 224,225,226,227 Ethernet224 100000 0 0 56
|
||||
Ethernet228 228,229,230,231 Ethernet228 100000 0 0 57
|
||||
Ethernet232 232,233,234,235 Ethernet232 100000 0 0 58
|
||||
Ethernet236 236,237,238,239 Ethernet236 100000 0 0 59
|
||||
Ethernet240 240,241,242,243 Ethernet240 100000 0 0 60
|
||||
Ethernet244 244,245,246,247 Ethernet244 100000 0 0 61
|
||||
Ethernet248 248,249,250,251 Ethernet248 100000 0 0 62
|
||||
Ethernet252 252,253,254,255 Ethernet252 100000 0 0 63
|
@ -0,0 +1,33 @@
|
||||
{
|
||||
"chip_list": [
|
||||
{
|
||||
"id": "asic-0",
|
||||
"chip_family": "Tofino",
|
||||
"instance": 0,
|
||||
"pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0",
|
||||
"pcie_domain": 0,
|
||||
"pcie_bus": 5,
|
||||
"pcie_fn": 0,
|
||||
"pcie_dev": 0,
|
||||
"pcie_int_mode": 1,
|
||||
"sds_fw_path": "share/tofino_sds_fw/avago/firmware"
|
||||
}
|
||||
],
|
||||
"instance": 0,
|
||||
"p4_program_list": [
|
||||
{
|
||||
"id": "pgm-0",
|
||||
"instance": 0,
|
||||
"path": "switch",
|
||||
"program-name": "switch",
|
||||
"pd": "lib/tofinopd/switch/libpd.so",
|
||||
"pd-thrift": "lib/tofinopd/switch/libpdthrift.so",
|
||||
"table-config": "share/tofinopd/switch/context.json",
|
||||
"tofino-bin": "share/tofinopd/switch/tofino.bin",
|
||||
"switchapi": "lib/libswitchapi.so",
|
||||
"switchsai": "lib/libswitchsai.so",
|
||||
"agent0": "lib/platform/x86_64-ingrasys_s9280_64x-r0/libpltfm_mgr.so",
|
||||
"switchapi_port_add": false
|
||||
}
|
||||
]
|
||||
}
|
9
device/ingrasys/x86_64-ingrasys_s9280_64x-r0/fancontrol
Normal file
9
device/ingrasys/x86_64-ingrasys_s9280_64x-r0/fancontrol
Normal file
@ -0,0 +1,9 @@
|
||||
INTERVAL=10
|
||||
DEVPATH=hwmon1=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-16/16-002f hwmon3=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-6/6-004e
|
||||
DEVNAME=hwmon1=w83795adg
|
||||
FCTEMPS=hwmon1/device/pwm2=hwmon3/temp1_input
|
||||
FCFANS=hwmon1/device/pwm2=hwmon1/device/fan7_input hwmon1/device/pwm2=hwmon1/device/fan5_input hwmon1/device/pwm2=hwmon1/device/fan3_input hwmon1/device/pwm2=hwmon1/device/fan1_input
|
||||
MINTEMP=hwmon1/device/pwm2=20
|
||||
MAXTEMP=hwmon1/device/pwm2=60
|
||||
MINSTART=hwmon1/device/pwm2=75
|
||||
MINSTOP=hwmon1/device/pwm2=22
|
@ -0,0 +1,3 @@
|
||||
CONSOLE_PORT=0x3f8
|
||||
CONSOLE_DEV=0
|
||||
CONSOLE_SPEED=115200
|
151
device/ingrasys/x86_64-ingrasys_s9280_64x-r0/minigraph.xml
Normal file
151
device/ingrasys/x86_64-ingrasys_s9280_64x-r0/minigraph.xml
Normal file
@ -0,0 +1,151 @@
|
||||
<DeviceMiniGraph xmlns="Microsoft.Search.Autopilot.Evolution" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<CpgDec>
|
||||
<IsisRouters xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
|
||||
<PeeringSessions>
|
||||
<BGPSession>
|
||||
<StartRouter>OCPSCH0104001MS</StartRouter>
|
||||
<StartPeer>10.10.1.26</StartPeer>
|
||||
<EndRouter>OCPSCH01040GGLF</EndRouter>
|
||||
<EndPeer>10.10.1.25</EndPeer>
|
||||
<Multihop>1</Multihop>
|
||||
<HoldTime>10</HoldTime>
|
||||
<KeepAliveTime>3</KeepAliveTime>
|
||||
</BGPSession>
|
||||
<BGPSession>
|
||||
<StartRouter>OCPSCH0104002MS</StartRouter>
|
||||
<StartPeer>10.10.2.26</StartPeer>
|
||||
<EndRouter>OCPSCH01040GGLF</EndRouter>
|
||||
<EndPeer>10.10.2.25</EndPeer>
|
||||
<Multihop>1</Multihop>
|
||||
<HoldTime>10</HoldTime>
|
||||
<KeepAliveTime>3</KeepAliveTime>
|
||||
</BGPSession>
|
||||
</PeeringSessions>
|
||||
<Routers xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
|
||||
<a:BGPRouterDeclaration>
|
||||
<a:ASN>64536</a:ASN>
|
||||
<a:Hostname>OCPSCH01040GGLF</a:Hostname>
|
||||
<a:Peers>
|
||||
<BGPPeer>
|
||||
<Address>10.10.1.26</Address>
|
||||
<RouteMapIn i:nil="true"/>
|
||||
<RouteMapOut i:nil="true"/>
|
||||
</BGPPeer>
|
||||
<BGPPeer>
|
||||
<Address>10.10.2.26</Address>
|
||||
<RouteMapIn i:nil="true"/>
|
||||
<RouteMapOut i:nil="true"/>
|
||||
</BGPPeer>
|
||||
</a:Peers>
|
||||
<a:RouteMaps/>
|
||||
</a:BGPRouterDeclaration>
|
||||
<a:BGPRouterDeclaration>
|
||||
<a:ASN>64542</a:ASN>
|
||||
<a:Hostname>OCPSCH0104001MS</a:Hostname>
|
||||
<a:RouteMaps/>
|
||||
</a:BGPRouterDeclaration>
|
||||
<a:BGPRouterDeclaration>
|
||||
<a:ASN>64543</a:ASN>
|
||||
<a:Hostname>OCPSCH0104002MS</a:Hostname>
|
||||
<a:RouteMaps/>
|
||||
</a:BGPRouterDeclaration>
|
||||
</Routers>
|
||||
</CpgDec>
|
||||
<DpgDec>
|
||||
<DeviceDataPlaneInfo>
|
||||
<IPSecTunnels/>
|
||||
<LoopbackIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
|
||||
<a:LoopbackIPInterface>
|
||||
<Name>HostIP</Name>
|
||||
<AttachTo>Loopback0</AttachTo>
|
||||
<a:Prefix xmlns:b="Microsoft.Search.Autopilot.NetMux">
|
||||
<b:IPPrefix>100.0.0.9/32</b:IPPrefix>
|
||||
</a:Prefix>
|
||||
<a:PrefixStr>100.0.0.9/32</a:PrefixStr>
|
||||
</a:LoopbackIPInterface>
|
||||
</LoopbackIPInterfaces>
|
||||
<ManagementIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
|
||||
</ManagementIPInterfaces>
|
||||
<MplsInterfaces/>
|
||||
<MplsTeInterfaces/>
|
||||
<RsvpInterfaces/>
|
||||
<Hostname>OCPSCH01040GGLF</Hostname>
|
||||
<PortChannelInterfaces/>
|
||||
<VlanInterfaces/>
|
||||
<IPInterfaces>
|
||||
<IPInterface>
|
||||
<Name i:nil="true"/>
|
||||
<AttachTo>Ethernet0</AttachTo>
|
||||
<Prefix>10.10.1.25/30</Prefix>
|
||||
</IPInterface>
|
||||
<IPInterface>
|
||||
<Name i:nil="true"/>
|
||||
<AttachTo>Ethernet4</AttachTo>
|
||||
<Prefix>10.10.2.25/30</Prefix>
|
||||
</IPInterface>
|
||||
</IPInterfaces>
|
||||
<DataAcls/>
|
||||
<AclInterfaces/>
|
||||
<DownstreamSummaries/>
|
||||
<DownstreamSummarySet xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
|
||||
</DeviceDataPlaneInfo>
|
||||
</DpgDec>
|
||||
<PngDec>
|
||||
<DeviceInterfaceLinks>
|
||||
<DeviceLinkBase i:type="DeviceInterfaceLink">
|
||||
<Bandwidth>100000</Bandwidth>
|
||||
<ElementType>DeviceInterfaceLink</ElementType>
|
||||
<EndDevice>OCPSCH0104001MS</EndDevice>
|
||||
<EndPort>Ethernet24</EndPort>
|
||||
<StartDevice>OCPSCH01040GGLF</StartDevice>
|
||||
<StartPort>Ethernet0</StartPort>
|
||||
</DeviceLinkBase>
|
||||
<DeviceLinkBase i:type="DeviceInterfaceLink">
|
||||
<Bandwidth>100000</Bandwidth>
|
||||
<ElementType>DeviceInterfaceLink</ElementType>
|
||||
<EndDevice>OCPSCH0104002MS</EndDevice>
|
||||
<EndPort>Ethernet24</EndPort>
|
||||
<StartDevice>OCPSCH01040GGLF</StartDevice>
|
||||
<StartPort>Ethernet4</StartPort>
|
||||
</DeviceLinkBase>
|
||||
</DeviceInterfaceLinks>
|
||||
<Devices>
|
||||
<Device i:type="LeafRouter">
|
||||
<Hostname>OCPSCH01040GGLF</Hostname>
|
||||
<HwSku>INGRASYS-S9280-64X</HwSku>
|
||||
</Device>
|
||||
</Devices>
|
||||
</PngDec>
|
||||
<MetadataDeclaration>
|
||||
<Devices xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
|
||||
<a:DeviceMetadata>
|
||||
<a:Name>OCPSCH01040GGLF</a:Name>
|
||||
<a:Properties>
|
||||
<a:DeviceProperty>
|
||||
<a:Name>DhcpResources</a:Name>
|
||||
<a:Reference i:nil="true"/>
|
||||
<a:Value></a:Value>
|
||||
</a:DeviceProperty>
|
||||
<a:DeviceProperty>
|
||||
<a:Name>NtpResources</a:Name>
|
||||
<a:Reference i:nil="true"/>
|
||||
<a:Value>0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org</a:Value>
|
||||
</a:DeviceProperty>
|
||||
<a:DeviceProperty>
|
||||
<a:Name>SyslogResources</a:Name>
|
||||
<a:Reference i:nil="true"/>
|
||||
<a:Value></a:Value>
|
||||
</a:DeviceProperty>
|
||||
<a:DeviceProperty>
|
||||
<a:Name>ErspanDestinationIpv4</a:Name>
|
||||
<a:Reference i:nil="true"/>
|
||||
<a:Value>2.2.2.2</a:Value>
|
||||
</a:DeviceProperty>
|
||||
</a:Properties>
|
||||
</a:DeviceMetadata>
|
||||
</Devices>
|
||||
<Properties xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
|
||||
</MetadataDeclaration>
|
||||
<Hostname>OCPSCH01040GGLF</Hostname>
|
||||
<HwSku>INGRASYS-S9280-64X</HwSku>
|
||||
</DeviceMiniGraph>
|
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#############################################################################
|
||||
# Ingrasys S9280-64X
|
||||
#
|
||||
# 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:
|
||||
from sonic_eeprom import eeprom_tlvinfo
|
||||
except ImportError, e:
|
||||
raise ImportError (str(e) + "- required module not found")
|
||||
|
||||
|
||||
class board(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
|
||||
def __init__(self, name, path, cpld_root, ro):
|
||||
self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0051/eeprom"
|
||||
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
@ -0,0 +1,93 @@
|
||||
#
|
||||
# psuutil.py
|
||||
# Platform-specific PSU status interface for SONiC
|
||||
#
|
||||
|
||||
|
||||
import os.path
|
||||
|
||||
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"""
|
||||
|
||||
# TODO: need to check if the patch mapping correct
|
||||
SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/i2c-18/18-0050",
|
||||
"/sys/bus/i2c/devices/i2c-17/17-0050"]
|
||||
|
||||
def __init__(self):
|
||||
PsuBase.__init__(self)
|
||||
|
||||
|
||||
# Get sysfs attribute
|
||||
def get_attr_value(self, attr_path):
|
||||
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(attr_path)):
|
||||
return retval
|
||||
|
||||
try:
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open ", attr_path, " file !")
|
||||
|
||||
retval = retval.rstrip('\r\n')
|
||||
return retval
|
||||
|
||||
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
|
||||
"""
|
||||
MAX_PSUS = 2
|
||||
return MAX_PSUS
|
||||
|
||||
def get_psu_status(self, index):
|
||||
"""
|
||||
Retrieves the oprational status of power supply unit (PSU) defined
|
||||
by index <index>
|
||||
:param index: An integer, index of the PSU of which to query status
|
||||
:return: Boolean, True if PSU is operating properly, False if PSU is\
|
||||
faulty
|
||||
"""
|
||||
status = 0
|
||||
attr_file = 'psu_pg'
|
||||
attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file
|
||||
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
|
||||
if (attr_value != 'ERR'):
|
||||
attr_value = int(attr_value, 16)
|
||||
# Check for PSU status
|
||||
if (attr_value == 1):
|
||||
status = 1
|
||||
|
||||
return status
|
||||
|
||||
def get_psu_presence(self, index):
|
||||
"""
|
||||
Retrieves the presence status of power supply unit (PSU) defined
|
||||
by index <index>
|
||||
:param index: An integer, index of the PSU of which to query status
|
||||
:return: Boolean, True if PSU is plugged, False if not
|
||||
"""
|
||||
status = 0
|
||||
psu_absent = 0
|
||||
attr_file ='psu_abs'
|
||||
attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file
|
||||
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
|
||||
if (attr_value != 'ERR'):
|
||||
attr_value = int(attr_value, 16)
|
||||
# Check for PSU presence
|
||||
if (attr_value == 0):
|
||||
status = 1
|
||||
|
||||
return status
|
||||
|
300
device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/sfputil.py
Normal file
300
device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/sfputil.py
Normal file
@ -0,0 +1,300 @@
|
||||
# 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 = 63
|
||||
PORTS_IN_BLOCK = 64
|
||||
EEPROM_OFFSET = 41
|
||||
CPLD1_PORTS = 12
|
||||
CPLDx_PORTS = 13
|
||||
#TODO: check init sequence for CPLD i2c bus
|
||||
CPLD_OFFSET = 1
|
||||
CPLD_PRES_BIT = 1
|
||||
CPLD_RESET_BIT = 0
|
||||
CPLD_LPMOD_BIT = 2
|
||||
CPLDx_I2C_ADDR = "33"
|
||||
EEPROM_I2C_ADDR = "50"
|
||||
CPLD_PORT_STATUS_KEY = "cpld_qsfp_port_status"
|
||||
CPLD_PORT_CONFIG_KEY = "cpld_qsfp_port_config"
|
||||
CPLD_REG_PATH = "/sys/bus/i2c/devices/{0}-00{1}/{2}_{3}"
|
||||
|
||||
_port_to_eeprom_mapping = {}
|
||||
|
||||
#TODO: check the fp port to phy port mapping
|
||||
_fp2phy_port_mapping = {
|
||||
0: 0,
|
||||
1: 1,
|
||||
2: 4,
|
||||
3: 5,
|
||||
4: 8,
|
||||
5: 9,
|
||||
6: 12,
|
||||
7: 13,
|
||||
8: 16,
|
||||
9: 17,
|
||||
10: 20,
|
||||
11: 21,
|
||||
12: 24,
|
||||
13: 25,
|
||||
14: 28,
|
||||
15: 29,
|
||||
16: 32,
|
||||
17: 33,
|
||||
18: 36,
|
||||
19: 37,
|
||||
20: 40,
|
||||
21: 41,
|
||||
22: 44,
|
||||
23: 45,
|
||||
24: 48,
|
||||
25: 49,
|
||||
26: 52,
|
||||
27: 53,
|
||||
28: 56,
|
||||
29: 57,
|
||||
30: 60,
|
||||
31: 61,
|
||||
32: 2,
|
||||
33: 3,
|
||||
34: 6,
|
||||
35: 7,
|
||||
36: 10,
|
||||
37: 11,
|
||||
38: 14,
|
||||
39: 15,
|
||||
40: 18,
|
||||
41: 19,
|
||||
42: 22,
|
||||
43: 23,
|
||||
44: 26,
|
||||
45: 27,
|
||||
46: 30,
|
||||
47: 31,
|
||||
48: 34,
|
||||
49: 35,
|
||||
50: 38,
|
||||
51: 39,
|
||||
52: 42,
|
||||
53: 43,
|
||||
54: 46,
|
||||
55: 47,
|
||||
56: 50,
|
||||
57: 51,
|
||||
58: 54,
|
||||
59: 55,
|
||||
60: 58,
|
||||
61: 59,
|
||||
62: 62,
|
||||
63: 63
|
||||
}
|
||||
|
||||
@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.PORTS_IN_BLOCK + 1)
|
||||
|
||||
@property
|
||||
def port_to_eeprom_mapping(self):
|
||||
return self._port_to_eeprom_mapping
|
||||
|
||||
|
||||
def __init__(self):
|
||||
# Override port_to_eeprom_mapping for class initialization
|
||||
eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-00{1}/eeprom"
|
||||
for x in range(self.port_start, self.port_end + 1):
|
||||
phy_port = self.fp2phy_port_num(x)
|
||||
port_eeprom_path = eeprom_path.format(phy_port + self.EEPROM_OFFSET, self.EEPROM_I2C_ADDR)
|
||||
self.port_to_eeprom_mapping[x] = port_eeprom_path
|
||||
|
||||
SfpUtilBase.__init__(self)
|
||||
|
||||
def qsfp_to_cpld_index(self, port_num):
|
||||
if port_num < self.CPLD1_PORTS:
|
||||
cpld_id = 0
|
||||
cpld_port_index = port_num + 1
|
||||
else:
|
||||
cpld_id = 1 + (port_num - self.CPLD1_PORTS) / self.CPLDx_PORTS
|
||||
cpld_port_index = ((port_num - self.CPLD1_PORTS) % self.CPLDx_PORTS) + 1
|
||||
return cpld_id, cpld_port_index
|
||||
|
||||
def fp2phy_port_num(self, fp_port_num):
|
||||
|
||||
phy_port_num = self._fp2phy_port_mapping[fp_port_num]
|
||||
return phy_port_num
|
||||
|
||||
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
|
||||
|
||||
# logic port to physical port mapping
|
||||
port_num = self.fp2phy_port_num(port_num)
|
||||
|
||||
cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num)
|
||||
i2c_id = self.CPLD_OFFSET + cpld_id
|
||||
reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \
|
||||
self.CPLD_PORT_STATUS_KEY, cpld_port_index)
|
||||
|
||||
try:
|
||||
reg_file = open(reg_path)
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
# content is a string containing the status register value
|
||||
content = reg_file.readline().rstrip()
|
||||
reg_file.close()
|
||||
|
||||
reg_value = int(content, 16)
|
||||
# mask for presence bit (bit 1)
|
||||
mask = (1 << self.CPLD_PRES_BIT)
|
||||
|
||||
# 0 - presence, 1 - absence
|
||||
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:
|
||||
return False
|
||||
|
||||
# logic port to physical port mapping
|
||||
port_num = self.fp2phy_port_num(port_num)
|
||||
|
||||
cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num)
|
||||
i2c_id = self.CPLD_OFFSET + cpld_id
|
||||
reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \
|
||||
self.CPLD_PORT_CONFIG_KEY, cpld_port_index)
|
||||
|
||||
try:
|
||||
reg_file = open(reg_path)
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
# content is a string containing the status register value
|
||||
content = reg_file.readline().rstrip()
|
||||
reg_file.close()
|
||||
|
||||
reg_value = int(content, 16)
|
||||
# mask for lp_mod bit (bit 2)
|
||||
mask = (1 << self.CPLD_LPMOD_BIT)
|
||||
|
||||
# 0 - disable, 1 - low power mode
|
||||
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:
|
||||
return False
|
||||
|
||||
# logic port to physical port mapping
|
||||
port_num = self.fp2phy_port_num(port_num)
|
||||
|
||||
cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num)
|
||||
i2c_id = self.CPLD_OFFSET + cpld_id
|
||||
reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \
|
||||
self.CPLD_PORT_CONFIG_KEY, cpld_port_index)
|
||||
|
||||
try:
|
||||
reg_file = open(reg_path, "r+")
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
# content is a string containing the status register value
|
||||
content = reg_file.readline().rstrip()
|
||||
reg_value = int(content, 16)
|
||||
# mask for lp_mod bit (bit 2)
|
||||
mask = (1 << self.CPLD_LPMOD_BIT)
|
||||
|
||||
# 1 - low power mode, 0 - high power mode
|
||||
if lpmode is True:
|
||||
reg_value = reg_value | mask
|
||||
else:
|
||||
reg_value = reg_value & ~mask
|
||||
|
||||
# convert value to hex string
|
||||
content = hex(reg_value)
|
||||
|
||||
reg_file.seek(0)
|
||||
reg_file.write(content)
|
||||
reg_file.close()
|
||||
|
||||
return True
|
||||
|
||||
def reset(self, port_num):
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
|
||||
# logic port to physical port mapping
|
||||
port_num = self.fp2phy_port_num(port_num)
|
||||
|
||||
cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num)
|
||||
i2c_id = self.CPLD_OFFSET + cpld_id
|
||||
reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \
|
||||
self.CPLD_PORT_CONFIG_KEY, cpld_port_index)
|
||||
|
||||
# reset the port
|
||||
try:
|
||||
reg_file = open(reg_path, "r+")
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
# content is a string containing the status register value
|
||||
content = reg_file.readline().rstrip()
|
||||
reg_value = int(content, 16)
|
||||
# mask for reset bit (bit 0)
|
||||
mask = (1 << self.CPLD_RESET_BIT)
|
||||
|
||||
# 1 - out of reset, 0 - reset
|
||||
reg_value = reg_value & ~mask
|
||||
|
||||
reg_file.seek(0)
|
||||
reg_file.write(hex(reg_value))
|
||||
reg_file.close()
|
||||
|
||||
# Sleep 1 second to reset done
|
||||
time.sleep(1)
|
||||
|
||||
# take the port out of reset
|
||||
try:
|
||||
reg_file = open(reg_path, "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
|
||||
|
85
device/ingrasys/x86_64-ingrasys_s9280_64x-r0/sensors.conf
Normal file
85
device/ingrasys/x86_64-ingrasys_s9280_64x-r0/sensors.conf
Normal file
@ -0,0 +1,85 @@
|
||||
# libsensors configuration file
|
||||
chip "i350bb-*"
|
||||
ignore loc1
|
||||
|
||||
chip "jc42-*"
|
||||
|
||||
bus "i2c-16" "i2c-mux-1 (chan_id 7)"
|
||||
chip "w83795adg-*"
|
||||
ignore in0
|
||||
label in1 "VDD_CORE"
|
||||
set in1_min 0.717
|
||||
set in1_max 0.962
|
||||
ignore in2
|
||||
ignore in3
|
||||
label in4 "3.3V"
|
||||
compute in4 @/(0.3052), (0.3052)*@
|
||||
set in4_min 3.3 * 0.95
|
||||
set in4_max 3.3 * 1.05
|
||||
label in5 "0.9V"
|
||||
set in5_min 0.90 * 0.98
|
||||
set in5_max 0.90 * 1.02
|
||||
ignore in6
|
||||
ignore in7
|
||||
ignore in8
|
||||
ignore in9
|
||||
ignore in10
|
||||
ignore in11
|
||||
ignore in12
|
||||
ignore in13
|
||||
ignore in14
|
||||
ignore in15
|
||||
ignore in16
|
||||
ignore in17
|
||||
ignore in18
|
||||
ignore in19
|
||||
label fan1 "FANTRAY 1"
|
||||
ignore fan2
|
||||
label fan3 "FANTRAY 2"
|
||||
ignore fan4
|
||||
label fan5 "FANTRAY 3"
|
||||
ignore fan6
|
||||
label fan7 "FANTRAY 4"
|
||||
ignore fan8
|
||||
ignore temp1
|
||||
ignore temp2
|
||||
ignore temp3
|
||||
ignore temp4
|
||||
ignore temp5
|
||||
ignore temp6
|
||||
ignore intrusion0
|
||||
|
||||
chip "tmp75-i2c-*-4A"
|
||||
label temp1 "BMC Board Temp"
|
||||
set temp1_max 50
|
||||
set temp1_max_hyst 45
|
||||
|
||||
bus "i2c-0" "SMBus I801 adapter at f000"
|
||||
chip "tmp75-i2c-*-4F"
|
||||
label temp1 "x86 CPU Board Temp"
|
||||
set temp1_max 50
|
||||
set temp1_max_hyst 45
|
||||
|
||||
bus "i2c-6" "i2c-0-mux (chan_id 5)"
|
||||
chip "lm75-i2c-6-4D"
|
||||
label temp1 "Rear Panel Temp"
|
||||
set temp1_max 50
|
||||
set temp1_max_hyst 45
|
||||
chip "lm75-i2c-6-4E"
|
||||
label temp1 "Rear MAC Temp"
|
||||
set temp1_max 50
|
||||
set temp1_max_hyst 45
|
||||
chip "lm86-i2c-6-4C"
|
||||
label temp1 "MB Temp"
|
||||
set temp1_max 50
|
||||
label temp2 "MAC Temp"
|
||||
set temp2_max 70
|
||||
bus "i2c-7" "i2c-0-mux (chan_id 6)"
|
||||
chip "lm75-i2c-7-4D"
|
||||
label temp1 "Front Panel Temp"
|
||||
set temp1_max 50
|
||||
set temp1_max_hyst 45
|
||||
chip "lm75-i2c-7-4E"
|
||||
label temp1 "Front MAC Temp"
|
||||
set temp1_max 50
|
||||
set temp1_max_hyst 45
|
@ -1,5 +1,5 @@
|
||||
BFN_INGRASYS_PLATFORM = bfnplatform-ingrasys_1.0.0_amd64.deb
|
||||
$(BFN_INGRASYS_PLATFORM)_URL = "https://github.com/Ingrasys-sonic/packages/raw/master/lib/bfnplatform-ingrasys_1.0.0_amd64.deb"
|
||||
BFN_INGRASYS_PLATFORM = bfnplatform-ingrasys_8.2.0_amd64.deb
|
||||
$(BFN_INGRASYS_PLATFORM)_URL = "https://github.com/Ingrasys-sonic/packages/raw/master/lib/bfnplatform-ingrasys_8.2.0_amd64.deb"
|
||||
|
||||
SONIC_ONLINE_DEBS += $(BFN_INGRASYS_PLATFORM) # $(BFN_SAI_DEV)
|
||||
$(BFN_SAI_DEV)_DEPENDS += $(BFN_INGRASYS_PLATFORM)
|
||||
|
@ -7,5 +7,6 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE)
|
||||
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE)
|
||||
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE)
|
||||
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE)
|
||||
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9280_64X_PLATFORM_MODULE)
|
||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES)
|
||||
SONIC_INSTALLERS += $(SONIC_ONE_IMAGE)
|
||||
|
@ -1,11 +1,18 @@
|
||||
# Ingrasys S9180-32X Platform modules
|
||||
|
||||
INGRASYS_S9180_32X_PLATFORM_MODULE_VERSION = 1.1.0
|
||||
INGRASYS_S9280_64X_PLATFORM_MODULE_VERSION = 1.1.0
|
||||
|
||||
export INGRASYS_S9180_32X_PLATFORM_MODULE_VERSION
|
||||
export INGRASYS_S9280_64X_PLATFORM_MODULE_VERSION
|
||||
|
||||
INGRASYS_S9180_32X_PLATFORM_MODULE = sonic-platform-ingrasys-s9180-32x_$(INGRASYS_S9180_32X_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
$(INGRASYS_S9180_32X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-ingrasys
|
||||
$(INGRASYS_S9180_32X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
|
||||
$(INGRASYS_S9180_32X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9180_32x-r0
|
||||
SONIC_DPKG_DEBS += $(INGRASYS_S9180_32X_PLATFORM_MODULE)
|
||||
|
||||
INGRASYS_S9280_64X_PLATFORM_MODULE = sonic-platform-ingrasys-s9280-64x_$(INGRASYS_S9280_64X_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
$(INGRASYS_S9280_64X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9280_64x-r0
|
||||
|
||||
$(eval $(call add_extra_package,$(INGRASYS_S9180_32X_PLATFORM_MODULE),$(INGRASYS_S9280_64X_PLATFORM_MODULE)))
|
||||
|
@ -1,15 +1,9 @@
|
||||
platform-driver (1.1.0) unstable; urgency=low
|
||||
|
||||
* Add support for s9180-32x
|
||||
* Add support for s9180-32x s9280-64x
|
||||
|
||||
-- developer <developer@ingrasys.com> Fri, 26 May 2017 11:00:00 +0800
|
||||
|
||||
platform-driver (1.1.0) unstable; urgency=low
|
||||
|
||||
* Add support for s8900 series
|
||||
|
||||
-- developer <developer@ingrasys.com> Wed, 29 Mar 2017 11:00:00 +0800
|
||||
|
||||
platform-driver (1.0.0) unstable; urgency=low
|
||||
|
||||
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
|
||||
|
@ -8,3 +8,7 @@ Standards-Version: 1.0.0
|
||||
Package: sonic-platform-ingrasys-s9180-32x
|
||||
Architecture: amd64
|
||||
Description: This package contains S9180-32X platform driver utility for SONiC project.
|
||||
|
||||
Package: sonic-platform-ingrasys-s9280-64x
|
||||
Architecture: amd64
|
||||
Description: This package contains S9280-64X platform driver utility for SONiC project.
|
||||
|
@ -1,13 +1,4 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
export INSTALL_MOD_DIR:=extra
|
||||
|
||||
@ -15,7 +6,7 @@ PACKAGE_PRE_NAME := sonic-platform-ingrasys
|
||||
KVERSION ?= $(shell uname -r)
|
||||
KERNEL_SRC := /lib/modules/$(KVERSION)
|
||||
MOD_SRC_DIR:= $(shell pwd)
|
||||
MODULE_DIRS:= s9180-32x
|
||||
MODULE_DIRS:= s9180-32x s9280-64x
|
||||
MODULE_DIR := modules
|
||||
UTILS_DIR := utils
|
||||
SERVICE_DIR := service
|
||||
@ -24,58 +15,28 @@ CONF_DIR := conf
|
||||
%:
|
||||
dh $@ --with systemd
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean
|
||||
|
||||
build:
|
||||
#make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC)
|
||||
override_dh_auto_build:
|
||||
(for mod in $(MODULE_DIRS); do \
|
||||
make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
|
||||
done)
|
||||
|
||||
binary: binary-arch binary-indep
|
||||
# Nothing to do
|
||||
|
||||
binary-arch:
|
||||
# Nothing to do
|
||||
|
||||
#install: build
|
||||
#dh_testdir
|
||||
#dh_testroot
|
||||
#dh_clean -k
|
||||
#dh_installdirs
|
||||
|
||||
binary-indep:
|
||||
dh_testdir
|
||||
dh_installdirs
|
||||
|
||||
# Custom package commands
|
||||
override_dh_auto_install:
|
||||
(for mod in $(MODULE_DIRS); do \
|
||||
mkdir debian/tmp/usr/sbin -p; \
|
||||
mkdir debian/tmp/lib/systemd/system -p; \
|
||||
mkdir debian/tmp/etc/init.d -p; \
|
||||
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.sh debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/sbin/; \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/bfn debian/$(PACKAGE_PRE_NAME)-$${mod}/etc/init\.d/; \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \
|
||||
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} \
|
||||
$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko \
|
||||
debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/sbin; \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.sh \
|
||||
debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/sbin; \
|
||||
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} lib/systemd/system; \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service \
|
||||
debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \
|
||||
done)
|
||||
# Resuming debhelper scripts
|
||||
dh_testroot
|
||||
dh_install
|
||||
dh_installchangelogs
|
||||
dh_installdocs
|
||||
dh_systemd_enable
|
||||
dh_installinit
|
||||
dh_systemd_start
|
||||
dh_link
|
||||
dh_fixperms
|
||||
dh_compress
|
||||
dh_strip
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
.PHONY: build binary binary-arch binary-indep clean
|
||||
|
||||
override_dh_clean:
|
||||
dh_clean
|
||||
(for mod in $(MODULE_DIRS); do \
|
||||
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \
|
||||
done)
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
usr/sbin
|
||||
lib/systemd/system
|
||||
etc/
|
||||
etc/init.d/
|
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: setup-board
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: S
|
||||
# Default-Stop: 0 6
|
||||
# Short-Description: Setup S9180-32X board.
|
||||
### END INIT INFO
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Setting up board... "
|
||||
|
||||
depmod -a
|
||||
|
||||
echo "done."
|
||||
;;
|
||||
|
||||
stop)
|
||||
|
||||
i2c_utils.sh i2c_deinit
|
||||
|
||||
echo "done."
|
||||
|
||||
;;
|
||||
|
||||
force-reload|restart)
|
||||
echo "Not supported"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: /etc/init.d/sonic-platform-ingrasys-s9180-32x.init {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
@ -1,4 +0,0 @@
|
||||
lib/systemd/
|
||||
usr/sbin/
|
||||
etc/
|
||||
etc/init.d/
|
@ -1,57 +0,0 @@
|
||||
# Automatically added by dh_systemd_enable
|
||||
# This will only remove masks created by d-s-h on package removal.
|
||||
deb-systemd-helper unmask s9180-32x-monitor.service >/dev/null || true
|
||||
deb-systemd-helper unmask bfn.service >/dev/null || true
|
||||
deb-systemd-helper unmask qsfp-monitor.service >/dev/null || true
|
||||
# Generate kernel modules.dep and map files for add eeprom_mb.
|
||||
depmod -a || true
|
||||
# was-enabled defaults to true, so new installations run enable.
|
||||
if deb-systemd-helper --quiet was-enabled s9180-32x-monitor.service; then
|
||||
# Enables the unit on first installation, creates new
|
||||
# symlinks on upgrades if the unit file has changed.
|
||||
deb-systemd-helper enable s9180-32x-monitor.service >/dev/null || true
|
||||
else
|
||||
# Update the statefile to add new symlinks (if any), which need to be
|
||||
# cleaned up on purge. Also remove old symlinks.
|
||||
deb-systemd-helper update-state s9180-32x-monitor.service >/dev/null || true
|
||||
fi
|
||||
if deb-systemd-helper --quiet was-enabled bfn.service; then
|
||||
# Enables the unit on first installation, creates new
|
||||
# symlinks on upgrades if the unit file has changed.
|
||||
deb-systemd-helper enable bfn.service >/dev/null || true
|
||||
else
|
||||
# Update the statefile to add new symlinks (if any), which need to be
|
||||
# cleaned up on purge. Also remove old symlinks.
|
||||
deb-systemd-helper update-state bfn.service >/dev/null || true
|
||||
fi
|
||||
if deb-systemd-helper --quiet was-enabled qsfp-monitor.service; then
|
||||
# Enables the unit on first installation, creates new
|
||||
# symlinks on upgrades if the unit file has changed.
|
||||
deb-systemd-helper enable qsfp-monitor.service >/dev/null || true
|
||||
else
|
||||
# Update the statefile to add new symlinks (if any), which need to be
|
||||
# cleaned up on purge. Also remove old symlinks.
|
||||
deb-systemd-helper update-state qsfp-monitor.service >/dev/null || true
|
||||
fi
|
||||
# End automatically added section
|
||||
# Automatically added by dh_installinit
|
||||
if [ -x "/etc/init.d/s9180-32x-monitor" ]; then
|
||||
update-rc.d s9180-32x-monitor defaults >/dev/null
|
||||
invoke-rc.d s9180-32x-monitor start || exit $?
|
||||
fi
|
||||
if [ -x "/etc/init.d/qsfp-monitor" ]; then
|
||||
update-rc.d qsfp-monitor defaults >/dev/null
|
||||
invoke-rc.d qsfp-monitor start || exit $?
|
||||
fi
|
||||
if [ -x "/etc/init.d/bfn" ]; then
|
||||
invoke-rc.d bfn start || exit $?
|
||||
fi
|
||||
# End automatically added section
|
||||
# Automatically added by dh_systemd_start
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
deb-systemd-invoke start s9180-32x-monitor.service >/dev/null || true
|
||||
deb-systemd-invoke start qsfp-monitor.service >/dev/null || true
|
||||
deb-systemd-invoke start bfn.service >/dev/null || true
|
||||
fi
|
||||
# End automatically added section
|
@ -1,42 +0,0 @@
|
||||
# Automatically added by dh_systemd_start
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
fi
|
||||
# End automatically added section
|
||||
# Automatically added by dh_installinit
|
||||
if [ "$1" = "purge" ] ; then
|
||||
update-rc.d s9180-32x-monitor remove >/dev/null
|
||||
update-rc.d bfn remove >/dev/null
|
||||
update-rc.d qsfp-monitor remove >/dev/null
|
||||
fi
|
||||
|
||||
|
||||
# In case this system is running systemd, we make systemd reload the unit files
|
||||
# to pick up changes.
|
||||
if [ -d /run/systemd/system ] ; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
fi
|
||||
# End automatically added section
|
||||
# Automatically added by dh_systemd_enable
|
||||
if [ "$1" = "remove" ]; then
|
||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
||||
deb-systemd-helper mask s9180-32x-monitor.service >/dev/null
|
||||
deb-systemd-helper mask bfn.service >/dev/null
|
||||
deb-systemd-helper mask qsfp-monitor.service >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "purge" ]; then
|
||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
||||
deb-systemd-helper purge s9180-32x-monitor.service >/dev/null
|
||||
deb-systemd-helper unmask s9180-32x-monitor.service >/dev/null
|
||||
deb-systemd-helper purge bfn.service >/dev/null
|
||||
deb-systemd-helper unmask bfn.service >/dev/null
|
||||
deb-systemd-helper purge qsfp-monitor.service >/dev/null
|
||||
deb-systemd-helper unmask qsfp-monitor.service >/dev/null
|
||||
fi
|
||||
fi
|
||||
# Generate kernel modules.dep and map files for remove eeprom_mb.
|
||||
depmod -a || true
|
||||
# End automatically added section
|
||||
|
@ -1,21 +0,0 @@
|
||||
# Automatically added by dh_systemd_start
|
||||
if [ -d /run/systemd/system ]; then
|
||||
deb-systemd-invoke stop s9180-32x-monitor.service >/dev/null
|
||||
deb-systemd-invoke stop bfn.service >/dev/null
|
||||
deb-systemd-invoke stop qsfp-monitor.service >/dev/null
|
||||
fi
|
||||
# End automatically added section
|
||||
# Automatically added by dh_installinit
|
||||
if [ -x "/etc/init.d/s9180-32x-monitor" ]; then
|
||||
invoke-rc.d s9180-32x-monitor stop || exit $?
|
||||
fi
|
||||
if [ -x "/etc/init.d/bfn" ]; then
|
||||
invoke-rc.d bfn stop || exit $?
|
||||
fi
|
||||
if [ -x "/etc/init.d/qsfp-monitor" ]; then
|
||||
invoke-rc.d qsfp-monitor stop || exit $?
|
||||
fi
|
||||
# Driver deinit
|
||||
/usr/sbin/i2c_utils.sh i2c_deinit
|
||||
# End automatically added section
|
||||
|
@ -1,7 +0,0 @@
|
||||
description "SONiC platform service"
|
||||
|
||||
respawn
|
||||
|
||||
exec /usr/sbin/s9180_32x_monitor.sh
|
||||
exec /usr/sbin/qsfp_monitor.sh
|
||||
exec /etc/init.d/bfn start
|
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: setup-board
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: S
|
||||
# Default-Stop: 0 6
|
||||
# Short-Description: Setup S9280-64X board.
|
||||
### END INIT INFO
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Setting up board... "
|
||||
|
||||
depmod -a
|
||||
|
||||
echo "done."
|
||||
;;
|
||||
|
||||
stop)
|
||||
|
||||
i2c_utils i2c_deinit
|
||||
|
||||
echo "done."
|
||||
|
||||
;;
|
||||
|
||||
force-reload|restart)
|
||||
echo "Not supported"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: /etc/init.d/sonic-platform-ingrasys-s9280-64x.init {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
@ -1 +1,3 @@
|
||||
obj-m := eeprom_mb.o
|
||||
obj-m+= cpld_wdt.o
|
||||
|
||||
|
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* CPLD Watchdog Driver
|
||||
*
|
||||
* Copyright (c) 2018 Ingrasys Corp.
|
||||
*
|
||||
* Author: Wade He <feng.cf.lee@ingrasys.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Includes, defines, variables, module parameters, ...
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
/* Module and version information */
|
||||
#define DRV_NAME "cpld_wdt"
|
||||
#define DRV_VERSION "1.0"
|
||||
|
||||
/* Includes */
|
||||
#include <linux/module.h> /* For module specific items */
|
||||
#include <linux/moduleparam.h> /* For new moduleparam's */
|
||||
#include <linux/types.h> /* For standard types (like size_t) */
|
||||
#include <linux/errno.h> /* For the -ENODEV/... values */
|
||||
#include <linux/kernel.h> /* For printk/panic/... */
|
||||
#include <linux/watchdog.h> /* For the watchdog specific items */
|
||||
#include <linux/init.h> /* For __init/__exit/... */
|
||||
#include <linux/fs.h> /* For file operations */
|
||||
#include <linux/platform_device.h> /* For platform_driver framework */
|
||||
#include <linux/pci.h> /* For pci functions */
|
||||
#include <linux/ioport.h> /* For io-port access */
|
||||
#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
|
||||
#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
|
||||
#include <linux/io.h> /* For inb/outb/... */
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/lpc_ich.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
/* Address definitions for the CPLD */
|
||||
/* CPLD base address */
|
||||
#define TCOBASE 0x600
|
||||
/* SMI Control and Enable Register */
|
||||
|
||||
#define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */
|
||||
#define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */
|
||||
#define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */
|
||||
#define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */
|
||||
#define TCO1_STS (TCOBASE + 0x04) /* Control Watchdog Register */
|
||||
#define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */
|
||||
#define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */
|
||||
#define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */
|
||||
#define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */
|
||||
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_PRINT(fmt, args...) \
|
||||
printk (KERN_INFO "%s[%d]: " fmt "\r\n", \
|
||||
__FUNCTION__, __LINE__, ##args)
|
||||
#else
|
||||
#define DEBUG_PRINT(fmt, args...)
|
||||
#endif
|
||||
|
||||
#define ERROR_MSG(fmt, args...) \
|
||||
printk(KERN_ERR "%s[%d]: " fmt "\r\n", \
|
||||
__FUNCTION__, __LINE__, ##args)
|
||||
|
||||
|
||||
|
||||
/* internal variables */
|
||||
static struct { /* this is private data for the cpld_wdt device */
|
||||
/* the lock for io operations */
|
||||
spinlock_t io_lock;
|
||||
struct platform_device *dev;
|
||||
} cpld_wdt_private;
|
||||
|
||||
static struct task_struct *cpld_wdt_tsk;
|
||||
static int data;
|
||||
|
||||
static void device_release(struct device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_device cpld_wdt = {
|
||||
.name = DRV_NAME,
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = NULL,
|
||||
.release = device_release
|
||||
},
|
||||
};
|
||||
|
||||
/* module parameters */
|
||||
#define WATCHDOG_TIMEOUT 15 /* 15 sec default heartbeat */
|
||||
static int heartbeat = WATCHDOG_TIMEOUT; /* in seconds */
|
||||
module_param(heartbeat, int, 0);
|
||||
MODULE_PARM_DESC(heartbeat, "Watchdog ping period in seconds. "
|
||||
"5..20, default="
|
||||
__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
|
||||
|
||||
static bool nowayout = WATCHDOG_NOWAYOUT;
|
||||
module_param(nowayout, bool, 0);
|
||||
MODULE_PARM_DESC(nowayout,
|
||||
"Watchdog cannot be stopped once started (default="
|
||||
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
||||
|
||||
|
||||
static int cpld_wdt_check_timeout_range(unsigned int tmrval)
|
||||
{
|
||||
if (tmrval < 5 || tmrval > 20) {
|
||||
DEBUG_PRINT("heartbeat out of range, using default=%d\n", WATCHDOG_TIMEOUT);
|
||||
heartbeat = WATCHDOG_TIMEOUT;
|
||||
} else {
|
||||
DEBUG_PRINT("heartbeat using %d seconds\n", heartbeat);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some TCO specific functions
|
||||
*/
|
||||
|
||||
static int cpld_wdt_stop(void *arg)
|
||||
{
|
||||
|
||||
spin_lock(&cpld_wdt_private.io_lock);
|
||||
|
||||
outb(0x1, TCO1_STS);
|
||||
|
||||
DEBUG_PRINT("cpld_wdt_stop done");
|
||||
|
||||
spin_unlock(&cpld_wdt_private.io_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpld_wdt_ping(void *arg)
|
||||
{
|
||||
spin_lock(&cpld_wdt_private.io_lock);
|
||||
|
||||
/* Reload the timer by writing to the TCO Timer Counter register */
|
||||
outb(0x1, TCO1_STS); /* write 1 to clear bit */
|
||||
udelay(100);
|
||||
outb(0x3, TCO1_STS);
|
||||
|
||||
DEBUG_PRINT("cpld_wdt_ping done");
|
||||
|
||||
spin_unlock(&cpld_wdt_private.io_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kthread_wdt_ping_loop(void *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
while(!kthread_should_stop()) {
|
||||
DEBUG_PRINT("ping start");
|
||||
cpld_wdt_ping(NULL);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
for (i=0;i<heartbeat;i++) {
|
||||
msleep_interruptible(1000);
|
||||
if(kthread_should_stop()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUG_PRINT("ping once.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Init & exit routines
|
||||
*/
|
||||
|
||||
static void cpld_wdt_cleanup(void)
|
||||
{
|
||||
/* Stop the timer before we leave */
|
||||
if (!nowayout) {
|
||||
cpld_wdt_stop(NULL);
|
||||
DEBUG_PRINT("nowayout disabled. stop CPLD WDT success.");
|
||||
}
|
||||
DEBUG_PRINT("cpld_wdt_cleanup done");
|
||||
|
||||
}
|
||||
|
||||
static int cpld_wdt_probe(struct platform_device *dev)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
|
||||
spin_lock_init(&cpld_wdt_private.io_lock);
|
||||
|
||||
/* Make sure the watchdog is not running */
|
||||
cpld_wdt_stop(NULL);
|
||||
|
||||
cpld_wdt_check_timeout_range(heartbeat);
|
||||
|
||||
cpld_wdt_tsk = kthread_create(kthread_wdt_ping_loop, &data, "cpld_wdt_tsk");
|
||||
if (IS_ERR(cpld_wdt_tsk)) {
|
||||
ret = PTR_ERR(cpld_wdt_tsk);
|
||||
cpld_wdt_tsk = NULL;
|
||||
ERROR_MSG("cpld_wdt_tsk create kthread failed.");
|
||||
goto out;
|
||||
}
|
||||
DEBUG_PRINT("wake_up_process cpld_wdt_tsk");
|
||||
wake_up_process(cpld_wdt_tsk);
|
||||
DEBUG_PRINT("wake_up_process done");
|
||||
|
||||
return 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cpld_wdt_remove(struct platform_device *dev)
|
||||
{
|
||||
cpld_wdt_cleanup();
|
||||
kthread_stop(cpld_wdt_tsk);
|
||||
DEBUG_PRINT("cpld_wdt_remove done");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpld_wdt_shutdown(struct platform_device *dev)
|
||||
{
|
||||
cpld_wdt_stop(NULL);
|
||||
DEBUG_PRINT("cpld_wdt_shutdown done");
|
||||
}
|
||||
|
||||
static struct platform_driver cpld_wdt_driver = {
|
||||
.probe = cpld_wdt_probe,
|
||||
.remove = cpld_wdt_remove,
|
||||
.shutdown = cpld_wdt_shutdown,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init cpld_wdt_init_module(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
DEBUG_PRINT("Intel TCO WatchDog Timer Driver v%s\n", DRV_VERSION);
|
||||
|
||||
err = platform_driver_register(&cpld_wdt_driver);
|
||||
if (err) {
|
||||
ERROR_MSG("platform_driver_register error, err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
DEBUG_PRINT("platform_driver_register done\n");
|
||||
err = platform_device_register(&cpld_wdt);
|
||||
if (err) {
|
||||
printk(KERN_WARNING "Fail to create cpld device\n");
|
||||
goto error_cpld;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
error_cpld:
|
||||
platform_driver_unregister(&cpld_wdt_driver);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit cpld_wdt_cleanup_module(void)
|
||||
{
|
||||
platform_device_unregister(&cpld_wdt);
|
||||
platform_driver_unregister(&cpld_wdt_driver);
|
||||
DEBUG_PRINT("Watchdog Module Unloaded\n");
|
||||
}
|
||||
|
||||
module_init(cpld_wdt_init_module);
|
||||
module_exit(cpld_wdt_cleanup_module);
|
||||
|
||||
MODULE_AUTHOR("Wade He<feng.cf.lee@ingrasys.com>");
|
||||
MODULE_DESCRIPTION("CPLD Watchdog Timer Kernel Driver");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
@ -1,13 +0,0 @@
|
||||
[Unit]
|
||||
Description=Barefoot Kernel Module
|
||||
After=local-fs.target
|
||||
Before=docker.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=-/etc/init.d/bfn start
|
||||
ExecStop=-/etc/init.d/bfn stop
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -1,44 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This script load/unload Barefoot kernel modules
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides:
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: S
|
||||
# Default-Stop: 0 6
|
||||
# Short-Description: Load Barefoot kernel modules
|
||||
### END INIT INFO
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Load Barefoot kernel modules... "
|
||||
|
||||
modprobe bf_kdrv
|
||||
modprobe bf_tun
|
||||
|
||||
echo "done."
|
||||
;;
|
||||
|
||||
stop)
|
||||
echo -n "Unload Barefoot kernel modules... "
|
||||
|
||||
rmmod bf_tun
|
||||
rmmod bf_kdrv
|
||||
|
||||
echo "done."
|
||||
;;
|
||||
|
||||
force-reload|restart)
|
||||
echo "Not supported"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: /etc/init.d/bfn {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
@ -72,6 +72,7 @@ NUM_FRU_MUX_CHAN2_DEVICE=$(( ${NUM_FRU_MUX_CHAN0_DEVICE} + 2 )) # FAN
|
||||
NUM_CPLD_DEVICE=$(( ${NUM_MUX7_CHAN0_DEVICE} + 3 )) # CPLD
|
||||
NUM_SFP1_DEVICE=$(( ${NUM_MUX7_CHAN0_DEVICE} + 4 )) # CPLD
|
||||
NUM_SFP2_DEVICE=$(( ${NUM_MUX7_CHAN0_DEVICE} + 5 )) # CPLD
|
||||
NUM_ROV_DEVICE=${NUM_MAIN_MUX_CHAN6_DEVICE}
|
||||
|
||||
PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices"
|
||||
PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon"
|
||||
@ -89,12 +90,20 @@ PATH_MUX_CHAN7_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN7_DEVICE}"
|
||||
PATH_MUX7_CHAN0_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX7_CHAN0_DEVICE}"
|
||||
PATH_MAIN_MUX_CHAN0_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MAIN_MUX_CHAN0_DEVICE}"
|
||||
|
||||
# i2c address for deviecs
|
||||
CPLD_I2C_ADDR=0x33
|
||||
ROV_I2C_ADDR=0x22
|
||||
|
||||
#Power Supply Status
|
||||
PSU_DC_ON=1
|
||||
PSU_DC_OFF=0
|
||||
PSU_EXIST=1
|
||||
PSU_NOT_EXIST=0
|
||||
|
||||
# vdd value for mac
|
||||
rov_val_array=( 0.85 0.82 0.77 0.87 0.74 0.84 0.79 0.89 )
|
||||
rov_reg_array=( 0x24 0x21 0x1c 0x26 0x19 0x23 0x1e 0x28 )
|
||||
|
||||
# Help usage function
|
||||
function _help {
|
||||
echo "========================================================="
|
||||
@ -159,6 +168,7 @@ function _i2c_init {
|
||||
modprobe i2c_i801
|
||||
modprobe i2c_dev
|
||||
modprobe i2c_mux_pca954x force_deselect_on_exit=1
|
||||
#modprobe cpld_wdt
|
||||
|
||||
if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN0_DEVICE}" ]; then
|
||||
_retry "echo 'pca9548 0x70' > ${PATH_I801_DEVICE}/new_device"
|
||||
@ -227,9 +237,35 @@ function _i2c_init {
|
||||
_i2c_led_fan_status_set
|
||||
_i2c_led_fan_tray_status_set
|
||||
|
||||
# rov for mac init
|
||||
_mac_vdd_init
|
||||
|
||||
#SYS LED set green
|
||||
COLOR_SYS_LED="green"
|
||||
_i2c_sys_led
|
||||
|
||||
}
|
||||
|
||||
function _mac_vdd_init {
|
||||
# read mac vid register value from CPLD
|
||||
val=`i2cget -y ${NUM_CPLD_DEVICE} ${CPLD_I2C_ADDR} 0x42 2>/dev/null`
|
||||
|
||||
# get vid form register value [0:2]
|
||||
vid=$(($val & 0x7))
|
||||
|
||||
# get rov val and reg according to vid
|
||||
rov_val=${rov_val_array[$vid]}
|
||||
rov_reg=${rov_reg_array[$vid]}
|
||||
echo "vid=${vid}, rov_val=${rov_val}, rov_reg=${rov_reg}"
|
||||
|
||||
# write the rov reg to rov
|
||||
i2cset -y -r ${NUM_ROV_DEVICE} ${ROV_I2C_ADDR} 0x21 ${rov_reg} w
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "set ROV for mac vdd done"
|
||||
else
|
||||
echo "set ROV for mac vdd fail"
|
||||
fi
|
||||
}
|
||||
|
||||
#I2C Deinit
|
||||
@ -290,7 +326,7 @@ function _i2c_io_exp_init {
|
||||
i2cset -y -r ${NUM_I801_DEVICE} 0x26 5 0x00
|
||||
i2cset -y -r ${NUM_I801_DEVICE} 0x26 2 0x3F
|
||||
i2cset -y -r ${NUM_I801_DEVICE} 0x26 3 0x1F
|
||||
i2cset -y -r ${NUM_I801_DEVICE} 0x26 6 0xC0
|
||||
i2cset -y -r ${NUM_I801_DEVICE} 0x26 6 0xD0
|
||||
i2cset -y -r ${NUM_I801_DEVICE} 0x26 7 0x00
|
||||
|
||||
#CPU Baord
|
||||
@ -914,7 +950,7 @@ function _i2c_qsfp_eeprom_init {
|
||||
|
||||
if [ "${action}" == "new" ] && \
|
||||
! [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then
|
||||
echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/new_device
|
||||
echo "optoe1 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/new_device
|
||||
elif [ "${action}" == "delete" ] && \
|
||||
[ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then
|
||||
echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/delete_device
|
||||
@ -1006,7 +1042,7 @@ function _i2c_sfp_eeprom_init {
|
||||
return
|
||||
fi
|
||||
|
||||
#Init 1-32 ports EEPROM
|
||||
#Init 33-34 ports EEPROM
|
||||
if [ "${action}" == "new" ] && \
|
||||
! [ -L ${PATH_SYS_I2C_DEVICES}/${NUM_SFP1_DEVICE}-0050 ] && \
|
||||
! [ -L ${PATH_SYS_I2C_DEVICES}/${NUM_SFP2_DEVICE}-0050 ]; then
|
||||
|
@ -21,6 +21,7 @@ I2C_UTILS="/usr/sbin/i2c_utils.sh"
|
||||
# TBD: LED status monitor
|
||||
function _led_monitor {
|
||||
${I2C_UTILS} i2c_led_fan_status_set >/dev/null
|
||||
${I2C_UTILS} i2c_led_psu_status_set >/dev/null
|
||||
${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null
|
||||
}
|
||||
|
||||
@ -38,4 +39,4 @@ function _main {
|
||||
done
|
||||
}
|
||||
|
||||
_main
|
||||
_main
|
||||
|
@ -0,0 +1,175 @@
|
||||
# Ingrasys S9280-64X Platform Driver for SONiC
|
||||
|
||||
Copyright (C) 2016 Ingrasys, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
## Licensing terms
|
||||
|
||||
The Licensing terms of the files within this project is split 2 parts.
|
||||
The Linux kernel is released under the GNU General Public License version 2.
|
||||
All other code is released under the GNU General Public License version 3.
|
||||
Please see the LICENSE file for copies of both licenses.
|
||||
|
||||
## Contents of this package
|
||||
|
||||
- service/
|
||||
> Service config files for platform initialization and monitoring
|
||||
- utils/
|
||||
> Scripts useful during platform bringup and sysfs function
|
||||
- conf/
|
||||
> Platform configure files.
|
||||
|
||||
## Kernel modules and drivers
|
||||
|
||||
The driver for interacting with Ingrasys S9280-64X is contained in the I2C
|
||||
kernel module and initialization script. The initialization script loads
|
||||
the modules in the correct order. It has been built and tested against
|
||||
the Linux 3.16 kernel.
|
||||
|
||||
The initialization script will modprobe the needed modules, navigate to the
|
||||
module's device directory in sysfs, and write configuration data to
|
||||
the kernel module.
|
||||
|
||||
### IGB
|
||||
|
||||
This is OOB Ports on front panel for management plane.
|
||||
|
||||
The IGB module must be loaded first on Ingrasys S9280-64X platform.
|
||||
|
||||
### I2C i801
|
||||
|
||||
The I2C i801 on Ingrasys S9280-64X can be found in
|
||||
`/sys/bus/i2c/devices/i2c-0/`
|
||||
|
||||
This is I2C bus for Clock Gen, DIMM channel and digital potentiometers.
|
||||
|
||||
The i801 module must be loaded second on Ingrasys S9280-64X.
|
||||
|
||||
### I2C PCA9548
|
||||
The PCA9548 module on S9280-64X can be found in
|
||||
`/sys/bus/i2c/devices/i2c-0/` , `/sys/bus/i2c/devices/i2c-17/`,
|
||||
`/sys/bus/i2c/devices/i2c-18/` , `/sys/bus/i2c/devices/i2c-19/`,
|
||||
`/sys/bus/i2c/devices/i2c-20/`, `/sys/bus/i2c/devices/i2c-21/`,
|
||||
`/sys/bus/i2c/devices/i2c-22/`, `/sys/bus/i2c/devices/i2c-23/`,
|
||||
`/sys/bus/i2c/devices/i2c-24/`.
|
||||
|
||||
The pca9548 module for zQSFP module get/set functions, PSU information,
|
||||
fan status and EEPROM.
|
||||
|
||||
## Hardware components
|
||||
|
||||
The hardware components are initialized in the init script on S9280-64X.
|
||||
The following describes manual initialization as well as interaction.
|
||||
The examples below are just for Ingrasys S9280-64X platform.
|
||||
|
||||
### Hardware initialization
|
||||
|
||||
When the sonic-platform-ingrasys-s9280 package is installed on the S9280-64X,
|
||||
it is automatically initialized. If you want to manual initialization, the
|
||||
utility command usage as follows:
|
||||
```
|
||||
i2c_utils.sh i2c_init
|
||||
```
|
||||
|
||||
### EEPROM
|
||||
|
||||
The EEPROM is including the board SKU, model name, vendor name, serial number,
|
||||
and other information can be accessed with the specific eeprom kernel module.
|
||||
After using `modprobe eeprom_mb` to detect the eeprom, it will show up in sysfs.
|
||||
|
||||
The hexdump utility can be used to decode the raw output of the EEPROM.
|
||||
For example,
|
||||
```
|
||||
bash# echo "mb_eeprom 0x55" > /sys/bus/i2c/devices/i2c-0/new_device
|
||||
bash# cat /sys/bus/i2c/drivers/mb_eeprom/0-0055/eeprom | hexdump -C
|
||||
```
|
||||
|
||||
### Front panel LEDs
|
||||
|
||||
LEDs can be setup on/off by using i2c utility `/usr/sbin/i2c_utils.sh`.
|
||||
Utility function command usage as follows:
|
||||
|
||||
```
|
||||
Status LED:
|
||||
i2c_utils.sh i2c_sys_led green|amber on|off
|
||||
|
||||
Fan status LED:
|
||||
i2c_utils.sh i2c_fan_led green|amber on|off
|
||||
|
||||
PSU1 status LED:
|
||||
i2c_utils.sh i2c_psu1_led green|amber on|off
|
||||
|
||||
PSU2 status LED:
|
||||
i2c_utils.sh i2c_psu2_led green|amber on|off
|
||||
|
||||
```
|
||||
QSFP Module Port LEDs control by ASIC library.
|
||||
|
||||
|
||||
### Fan speed
|
||||
|
||||
Fan speed are controlled by the w83795 kernel module.
|
||||
It can be found in `/sys/class/hwmon/hwmon2/device/`.
|
||||
If they were compiled as modules, you will need to modprobe w83795 for
|
||||
their sysfs entries to show up. Each fan has an `fan<N>_input` file
|
||||
for reading the fan speed. And `pwm1` setting fan1 to fan4,
|
||||
`pwm2` setting fan5 to fan8.
|
||||
|
||||
There is docker-platform-monitor container installed fancontrol package that can
|
||||
automatic control platform fan speed.
|
||||
|
||||
|
||||
### Temperature sensors
|
||||
|
||||
Temperature sensors are controlled by the w83795 kernel
|
||||
module. It can be found in `/sys/class/hwmon/hwmon3/device/`.
|
||||
If they were compiled as modules, then you will need to modprobe w83795 for
|
||||
their sysfs entries to show up.
|
||||
`temp1_input` is front MAC temperature sensor. `temp2_input` is rear MAC
|
||||
temperature sensor.
|
||||
|
||||
There is docker-platform-monitor container installed lm-sensors package that can
|
||||
monitor platform temperature. And `sensors` command can show each
|
||||
temperature sensors status.
|
||||
|
||||
### Power supplies
|
||||
|
||||
Power supplies status and its EEPROM info can be used i2c utility
|
||||
`/usr/sbin/i2c_utils.sh` to get.
|
||||
The usage as follows:
|
||||
```
|
||||
PSU EEPROM:
|
||||
i2c_utils.sh i2c_psu_eeprom_get
|
||||
|
||||
PSU Status:
|
||||
i2c_utils.sh i2c_psu_status
|
||||
```
|
||||
|
||||
### QSFPs
|
||||
QSFP modules are managed by the pca9548 kernel driver.
|
||||
The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and
|
||||
module EEPROM informations.
|
||||
The usage as follows:
|
||||
```
|
||||
QSFP EEPROM:
|
||||
i2c_utils.sh i2c_qsfp_eeprom_get [1-64]
|
||||
|
||||
QSFP Insert Event:
|
||||
i2c_utils.sh i2c_qsfp_status_get [1-64]
|
||||
0 => not insert
|
||||
1 => inserted
|
||||
```
|
||||
|
@ -0,0 +1,3 @@
|
||||
obj-m := eeprom_mb.o
|
||||
obj-m += ingrasys_s9280_64x_i2c_cpld.o
|
||||
obj-m += ingrasys_s9280_64x_psu.o
|
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
|
||||
* Philip Edelbrock <phil@netroedge.com>
|
||||
* Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
|
||||
* Copyright (C) 2003 IBM Corp.
|
||||
* Copyright (C) 2004 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/* enable dev_dbg print out */
|
||||
//#define DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
/* Addresses to scan */
|
||||
static const unsigned short normal_i2c[] = { /*0x50, 0x51, 0x52, 0x53, 0x54,
|
||||
0x55, 0x56, 0x57,*/ I2C_CLIENT_END };
|
||||
|
||||
/* Size of EEPROM in bytes */
|
||||
#define EEPROM_SIZE 512
|
||||
|
||||
#define SLICE_BITS (6)
|
||||
#define SLICE_SIZE (1 << SLICE_BITS)
|
||||
#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE)
|
||||
|
||||
/* Each client has this additional data */
|
||||
struct eeprom_data {
|
||||
struct mutex update_lock;
|
||||
u8 valid; /* bitfield, bit!=0 if slice is valid */
|
||||
unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */
|
||||
u8 data[EEPROM_SIZE]; /* Register values */
|
||||
};
|
||||
|
||||
|
||||
static void mb_eeprom_update_client(struct i2c_client *client, u8 slice)
|
||||
{
|
||||
struct eeprom_data *data = i2c_get_clientdata(client);
|
||||
int i, j;
|
||||
int ret;
|
||||
int addr;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
if (!(data->valid & (1 << slice)) ||
|
||||
time_after(jiffies, data->last_updated[slice] + 300 * HZ)) {
|
||||
dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice);
|
||||
|
||||
addr = slice << SLICE_BITS;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, (u8)((addr >> 8) & 0xFF), (u8)(addr & 0xFF));
|
||||
/* select the eeprom address */
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "address set failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) {
|
||||
for (j = i; j < (i+SLICE_SIZE); j++) {
|
||||
int res;
|
||||
|
||||
res = i2c_smbus_read_byte(client);
|
||||
if (res < 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data->data[j] = res & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
data->last_updated[slice] = jiffies;
|
||||
data->valid |= (1 << slice);
|
||||
}
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
}
|
||||
|
||||
static ssize_t mb_eeprom_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
|
||||
struct eeprom_data *data = i2c_get_clientdata(client);
|
||||
u8 slice;
|
||||
|
||||
if (off > EEPROM_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
if (off + count > EEPROM_SIZE) {
|
||||
count = EEPROM_SIZE - off;
|
||||
}
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only refresh slices which contain requested bytes */
|
||||
for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) {
|
||||
mb_eeprom_update_client(client, slice);
|
||||
}
|
||||
|
||||
memcpy(buf, &data->data[off], count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t mb_eeprom_write(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
|
||||
struct eeprom_data *data = i2c_get_clientdata(client);
|
||||
int ret;
|
||||
int i;
|
||||
u8 cmd;
|
||||
u16 value16;
|
||||
|
||||
dev_dbg(&client->dev, "mb_eeprom_write off=%d, count=%d\n", (int)off, (int)count);
|
||||
|
||||
if (off > EEPROM_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
if (off + count > EEPROM_SIZE) {
|
||||
count = EEPROM_SIZE - off;
|
||||
}
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
for(i=0; i < count; i++) {
|
||||
/* write command */
|
||||
cmd = (off >> 8) & 0xff;
|
||||
value16 = off & 0xff;
|
||||
value16 |= buf[i] << 8;
|
||||
ret = i2c_smbus_write_word_data(client, cmd, value16);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "write address failed at %d \n", (int)off);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
off++;
|
||||
|
||||
/* need to wait for write complete */
|
||||
udelay(10000);
|
||||
}
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
/* force to update client when reading */
|
||||
for(i=0; i < SLICE_NUM; i++) {
|
||||
data->last_updated[i] = 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct bin_attribute mb_eeprom_attr = {
|
||||
.attr = {
|
||||
.name = "eeprom",
|
||||
.mode = S_IRUGO | S_IWUSR,
|
||||
},
|
||||
.size = EEPROM_SIZE,
|
||||
.read = mb_eeprom_read,
|
||||
.write = mb_eeprom_write,
|
||||
};
|
||||
|
||||
/* Return 0 if detection is successful, -ENODEV otherwise */
|
||||
static int mb_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info)
|
||||
{
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
|
||||
/* EDID EEPROMs are often 24C00 EEPROMs, which answer to all
|
||||
addresses 0x50-0x57, but we only care about 0x51 and 0x55. So decline
|
||||
attaching to addresses >= 0x56 on DDC buses */
|
||||
if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x56) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE)
|
||||
&& !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
strlcpy(info->type, "eeprom", I2C_NAME_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mb_eeprom_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct eeprom_data *data;
|
||||
int err;
|
||||
|
||||
if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
|
||||
err = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(data->data, 0xff, EEPROM_SIZE);
|
||||
i2c_set_clientdata(client, data);
|
||||
mutex_init(&data->update_lock);
|
||||
|
||||
/* create the sysfs eeprom file */
|
||||
err = sysfs_create_bin_file(&client->dev.kobj, &mb_eeprom_attr);
|
||||
if (err) {
|
||||
goto exit_kfree;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
exit_kfree:
|
||||
kfree(data);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mb_eeprom_remove(struct i2c_client *client)
|
||||
{
|
||||
sysfs_remove_bin_file(&client->dev.kobj, &mb_eeprom_attr);
|
||||
kfree(i2c_get_clientdata(client));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id mb_eeprom_id[] = {
|
||||
{ "mb_eeprom", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver mb_eeprom_driver = {
|
||||
.driver = {
|
||||
.name = "mb_eeprom",
|
||||
},
|
||||
.probe = mb_eeprom_probe,
|
||||
.remove = mb_eeprom_remove,
|
||||
.id_table = mb_eeprom_id,
|
||||
|
||||
.class = I2C_CLASS_DDC | I2C_CLASS_SPD,
|
||||
.detect = mb_eeprom_detect,
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
module_i2c_driver(mb_eeprom_driver);
|
||||
|
||||
MODULE_AUTHOR("Wade <wade.ce.he@@ingrasys.com>");
|
||||
MODULE_DESCRIPTION("Ingrasys Mother Borad EEPROM driver");
|
||||
MODULE_LICENSE("GPL");
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,338 @@
|
||||
/* header file for i2c cpld driver of ingrasys_s9280_64x
|
||||
*
|
||||
* Copyright (C) 2017 Ingrasys Technology Corporation.
|
||||
* Leo Lin <feng.lee.usa@ingrasys.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef INGRASYS_S9280_64X_I2C_CPLD_H
|
||||
#define INGRASYS_S9280_64X_I2C_CPLD_H
|
||||
|
||||
/* CPLD device index value */
|
||||
enum cpld_id {
|
||||
cpld1,
|
||||
cpld2,
|
||||
cpld3,
|
||||
cpld4,
|
||||
cpld5
|
||||
};
|
||||
|
||||
enum LED_BLINK {
|
||||
BLINK,
|
||||
NOBLINK,
|
||||
};
|
||||
|
||||
enum LED_YELLOW {
|
||||
YELLOW_OFF,
|
||||
YELLOW_ON,
|
||||
};
|
||||
|
||||
enum LED_GREEN {
|
||||
GREEN_OFF,
|
||||
GREEN_ON,
|
||||
};
|
||||
|
||||
/* port number on CPLD */
|
||||
#define CPLD_1_PORT_NUM 12
|
||||
#define CPLD_2_PORT_NUM 13
|
||||
|
||||
/* QSFP port number */
|
||||
#define QSFP_MAX_PORT_NUM 64
|
||||
#define QSFP_MIN_PORT_NUM 1
|
||||
|
||||
/* SFP+ port number */
|
||||
#define SFP_MAX_PORT_NUM 2
|
||||
#define SFP_MIN_PORT_NUM 1
|
||||
|
||||
|
||||
/* CPLD registers */
|
||||
#define CPLD_BOARD_TYPE_REG 0x0
|
||||
#define CPLD_EXT_BOARD_TYPE_REG 0x7
|
||||
#define CPLD_VERSION_REG 0x1
|
||||
#define CPLD_ID_REG 0x2
|
||||
#define CPLD_QSFP_PORT_STATUS_BASE_REG 0x20
|
||||
#define CPLD_QSFP_PORT_CONFIG_BASE_REG 0x30
|
||||
#define CPLD_QSFP_PORT_INTERRUPT_REG 0x40
|
||||
#define CPLD_SFP_PORT_STATUS_REG 0x2F
|
||||
#define CPLD_SFP_PORT_CONFIG_REG 0x3F
|
||||
#define CPLD_QSFP_PORT_INTERRUPT_REG 0x40
|
||||
#define CPLD_10GMUX_CONFIG_REG 0x41
|
||||
#define CPLD_BMC_STATUS_REG 0x42
|
||||
#define CPLD_BMC_WATCHDOG_REG 0x43
|
||||
#define CPLD_USB_STATUS_REG 0x44
|
||||
#define CPLD_RESET_CONTROL_REG 0x4A
|
||||
#define CPLD_SFP_LED_REG 0x80
|
||||
#define CPLD_SFP_LED_BLINK_REG 0x90
|
||||
#define CPLD_QSFP_LED_BASE_REG 0x80
|
||||
#define CPLD_QSFP_LED_BLINK_BASE_REG 0x90
|
||||
#define CPLD_RTMR_RESET_REG 0x4B
|
||||
#define CPLD_ROV_STATUS_REG 0x4C
|
||||
|
||||
/* bit definition for register value */
|
||||
enum CPLD_QSFP_PORT_STATUS_BITS {
|
||||
CPLD_QSFP_PORT_STATUS_INT_BIT,
|
||||
CPLD_QSFP_PORT_STATUS_ABS_BIT,
|
||||
};
|
||||
enum CPLD_QSFP_PORT_CONFIG_BITS {
|
||||
CPLD_QSFP_PORT_CONFIG_RESET_BIT,
|
||||
CPLD_QSFP_PORT_CONFIG_RESERVE_BIT,
|
||||
CPLD_QSFP_PORT_CONFIG_LPMODE_BIT,
|
||||
};
|
||||
enum CPLD_SFP_PORT_STATUS_BITS {
|
||||
CPLD_SFP0_PORT_STATUS_PRESENT_BIT,
|
||||
CPLD_SFP0_PORT_STATUS_TXFAULT_BIT,
|
||||
CPLD_SFP0_PORT_STATUS_RXLOS_BIT,
|
||||
CPLD_SFP_PORT_STATUS_DUMMY,
|
||||
CPLD_SFP1_PORT_STATUS_PRESENT_BIT,
|
||||
CPLD_SFP1_PORT_STATUS_TXFAULT_BIT,
|
||||
CPLD_SFP1_PORT_STATUS_RXLOS_BIT,
|
||||
};
|
||||
enum CPLD_SFP_PORT_CONFIG_BITS {
|
||||
CPLD_SFP0_PORT_CONFIG_TXDIS_BIT,
|
||||
CPLD_SFP0_PORT_CONFIG_RS_BIT,
|
||||
CPLD_SFP0_PORT_CONFIG_TS_BIT,
|
||||
CPLD_SFP_PORT_CONFIG_DUMMY,
|
||||
CPLD_SFP1_PORT_CONFIG_TXDIS_BIT,
|
||||
CPLD_SFP1_PORT_CONFIG_RS_BIT,
|
||||
CPLD_SFP1_PORT_CONFIG_TS_BIT,
|
||||
|
||||
};
|
||||
enum CPLD_10GMUX_CONFIG_BITS {
|
||||
CPLD_10GMUX_CONFIG_ENSMB_BIT,
|
||||
CPLD_10GMUX_CONFIG_ENINPUT_BIT,
|
||||
CPLD_10GMUX_CONFIG_SEL1_BIT,
|
||||
CPLD_10GMUX_CONFIG_SEL0_BIT,
|
||||
};
|
||||
enum CPLD_BMC_WATCHDOG_BITS {
|
||||
CPLD_10GMUX_CONFIG_ENTIMER_BIT,
|
||||
CPLD_10GMUX_CONFIG_TIMEOUT_BIT,
|
||||
};
|
||||
enum CPLD_RESET_CONTROL_BITS {
|
||||
CPLD_RESET_CONTROL_SWRST_BIT,
|
||||
CPLD_RESET_CONTROL_CP2104RST_BIT,
|
||||
CPLD_RESET_CONTROL_82P33814RST_BIT,
|
||||
CPLD_RESET_CONTROL_BMCRST_BIT,
|
||||
};
|
||||
enum CPLD_SFP_LED_BITS {
|
||||
CPLD_SFP_LED_SFP0_GREEN_BIT,
|
||||
CPLD_SFP_LED_SFP0_YELLOW_BIT,
|
||||
CPLD_SFP_LED_SFP1_GREEN_BIT,
|
||||
CPLD_SFP_LED_SFP1_YELLOW_BIT,
|
||||
};
|
||||
enum CPLD_SFP_LED_BLINK_BITS {
|
||||
CPLD_SFP_LED_BLINK_SFP0_BIT,
|
||||
CPLD_SFP_LED_BLINK_SFP1_BIT,
|
||||
};
|
||||
enum CPLD_QSFP_LED_BITS {
|
||||
CPLD_QSFP_LED_CHAN_0_GREEN_BIT,
|
||||
CPLD_QSFP_LED_CHAN_0_YELLOW_BIT,
|
||||
CPLD_QSFP_LED_CHAN_1_GREEN_BIT,
|
||||
CPLD_QSFP_LED_CHAN_1_YELLOW_BIT,
|
||||
CPLD_QSFP_LED_CHAN_2_GREEN_BIT,
|
||||
CPLD_QSFP_LED_CHAN_2_YELLOW_BIT,
|
||||
CPLD_QSFP_LED_CHAN_3_GREEN_BIT,
|
||||
CPLD_QSFP_LED_CHAN_3_YELLOW_BIT,
|
||||
|
||||
};
|
||||
enum CPLD_QSFP_LED_BLINK_BITS {
|
||||
CPLD_QSFP_LED_BLINK_X_CHAN0_BIT,
|
||||
CPLD_QSFP_LED_BLINK_X_CHAN1_BIT,
|
||||
CPLD_QSFP_LED_BLINK_X_CHAN2_BIT,
|
||||
CPLD_QSFP_LED_BLINK_X_CHAN3_BIT,
|
||||
CPLD_QSFP_LED_BLINK_XPLUS_CHAN0_BIT,
|
||||
CPLD_QSFP_LED_BLINK_XPLUS_CHAN1_BIT,
|
||||
CPLD_QSFP_LED_BLINK_XPLUS_CHAN2_BIT,
|
||||
CPLD_QSFP_LED_BLINK_XPLUS_CHAN3_BIT,
|
||||
};
|
||||
|
||||
/* bit field structure for register value */
|
||||
struct cpld_reg_board_type_t {
|
||||
u8 build_rev:2;
|
||||
u8 hw_rev:2;
|
||||
u8 board_id:4;
|
||||
};
|
||||
|
||||
struct cpld_reg_version_t {
|
||||
u8 revision:6;
|
||||
u8 release:1;
|
||||
u8 reserve:1;
|
||||
};
|
||||
|
||||
struct cpld_reg_id_t {
|
||||
u8 id:3;
|
||||
u8 release:5;
|
||||
};
|
||||
|
||||
/* common manipulation */
|
||||
#define INVALID(i, min, max) ((i < min) || (i > max) ? 1u : 0u)
|
||||
#define READ_BIT(val, bit) ((0u == (val & (1<<bit))) ? 0u : 1u)
|
||||
#define SET_BIT(val, bit) (val |= (1 << bit))
|
||||
#define CLEAR_BIT(val, bit) (val &= ~(1 << bit))
|
||||
#define TOGGLE_BIT(val, bit) (val ^= (1 << bit))
|
||||
#define _BIT(n) (1<<(n))
|
||||
#define _BIT_MASK(len) (BIT(len)-1)
|
||||
|
||||
/* bitfield of register manipulation */
|
||||
#define READ_BF(bf_struct, val, bf_name, bf_value) \
|
||||
(bf_value = ((struct bf_struct *)&val)->bf_name)
|
||||
#define READ_BF_1(bf_struct, val, bf_name, bf_value) \
|
||||
bf_struct bf; \
|
||||
bf.data = val; \
|
||||
bf_value = bf.bf_name
|
||||
#define BOARD_TYPE_BUILD_REV_GET(val, res) \
|
||||
READ_BF(cpld_reg_board_type_t, val, build_rev, res)
|
||||
#define BOARD_TYPE_HW_REV_GET(val, res) \
|
||||
READ_BF(cpld_reg_board_type_t, val, hw_rev, res)
|
||||
#define BOARD_TYPE_BOARD_ID_GET(val, res) \
|
||||
READ_BF(cpld_reg_board_type_t, val, board_id, res)
|
||||
#define CPLD_VERSION_REV_GET(val, res) \
|
||||
READ_BF(cpld_reg_version_t, val, revision, res)
|
||||
#define CPLD_VERSION_REL_GET(val, res) \
|
||||
READ_BF(cpld_reg_version_t, val, release, res)
|
||||
#define CPLD_ID_ID_GET(val, res) \
|
||||
READ_BF(cpld_reg_id_t, val, id, res)
|
||||
#define CPLD_ID_REL_GET(val, res) \
|
||||
READ_BF(cpld_reg_id_t, val, release, res)
|
||||
/* SFP/QSFP port led registers manipulation */
|
||||
#define SFP_LED_TO_CPLD_IDX(sfp_port) cpld1
|
||||
#define SFP_LED_REG(sfp_port) CPLD_SFP_LED_REG
|
||||
#define SFP_LED_BLINK_REG(sfp_port) CPLD_SFP_LED_BLINK_REG
|
||||
#define QSFP_LED_TO_CPLD_IDX(qsfp_port) \
|
||||
((qsfp_port - 1) / 16 + 2)
|
||||
#define QSFP_LED_REG(qsfp_port) \
|
||||
((qsfp_port - 1) % 16 + CPLD_QSFP_LED_BASE_REG)
|
||||
#define QSFP_LED_BLINK_REG(qsfp_port) \
|
||||
(((qsfp_port - 1) % 16) / 2 + CPLD_QSFP_LED_BLINK_BASE_REG)
|
||||
/* QSFP/SFP port status registers manipulation */
|
||||
#define QSFP_TO_CPLD_IDX(qsfp_port, cpld_index, cpld_port) \
|
||||
{ \
|
||||
if (QSFP_MIN_PORT_NUM <= qsfp_port && qsfp_port <= CPLD_1_PORT_NUM) { \
|
||||
cpld_index = cpld1; \
|
||||
cpld_port = qsfp_port - 1; \
|
||||
} else if (CPLD_1_PORT_NUM < qsfp_port \
|
||||
&& qsfp_port <= QSFP_MAX_PORT_NUM) { \
|
||||
cpld_index = cpld2 + (qsfp_port - 1 - CPLD_1_PORT_NUM) \
|
||||
/ CPLD_2_PORT_NUM; \
|
||||
cpld_port = (qsfp_port - 1 - CPLD_1_PORT_NUM) % \
|
||||
CPLD_2_PORT_NUM; \
|
||||
} else { \
|
||||
cpld_index = 0; \
|
||||
cpld_port = 0; \
|
||||
} \
|
||||
}
|
||||
#define QSFP_PORT_STATUS_REG(cpld_port) \
|
||||
(CPLD_QSFP_PORT_STATUS_BASE_REG + cpld_port)
|
||||
#define QSFP_PORT_CONFIG_REG(cpld_port) \
|
||||
(CPLD_QSFP_PORT_CONFIG_BASE_REG + cpld_port)
|
||||
#define QSFP_PORT_INT_BIT_GET(port_status_value) \
|
||||
READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_INT_BIT)
|
||||
#define QSFP_PORT_ABS_BIT_GET(port_status_value) \
|
||||
READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_ABS_BIT)
|
||||
#define QSFP_PORT_RESET_BIT_GET(port_config_value) \
|
||||
READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT)
|
||||
#define QSFP_PORT_LPMODE_BIT_GET(port_config_value) \
|
||||
READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT)
|
||||
#define QSFP_PORT_RESET_BIT_SET(port_config_value) \
|
||||
SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT)
|
||||
#define QSFP_PORT_RESET_BIT_CLEAR(port_config_value) \
|
||||
CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT)
|
||||
#define QSFP_PORT_LPMODE_BIT_SET(port_config_value) \
|
||||
SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT)
|
||||
#define QSFP_PORT_LPMODE_BIT_CLEAR(port_config_value) \
|
||||
CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT)
|
||||
#define SFP_PORT_PRESENT_BIT_GET(sfp_port, port_status_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
READ_BIT(port_status_value, CPLD_SFP0_PORT_STATUS_PRESENT_BIT); \
|
||||
} else { \
|
||||
READ_BIT(port_status_value, CPLD_SFP1_PORT_STATUS_PRESENT_BIT); \
|
||||
}
|
||||
#define SFP_PORT_TXFAULT_BIT_GET(sfp_port, port_status_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
READ_BIT(port_status_value, CPLD_SFP0_PORT_STATUS_TXFAULT_BIT); \
|
||||
} else { \
|
||||
READ_BIT(port_status_value, CPLD_SFP1_PORT_STATUS_TXFAULT_BIT); \
|
||||
}
|
||||
#define SFP_PORT_RXLOS_BIT_GET(sfp_port, port_status_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
READ_BIT(port_status_value, CPLD_SFP0_PORT_STATUS_RXLOS_BIT); \
|
||||
} else { \
|
||||
READ_BIT(port_status_value, CPLD_SFP1_PORT_STATUS_RXLOS_BIT); \
|
||||
}
|
||||
#define SFP_PORT_TXDIS_BIT_GET(sfp_port, port_config_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
READ_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TXDIS_BIT); \
|
||||
} else { \
|
||||
READ_BIT(port_config_value, CPLD_SFP1_PORT_STATUS_RXLOS_BIT); \
|
||||
}
|
||||
#define SFP_PORT_RS_BIT_GET(sfp_port, port_config_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
READ_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_RS_BIT); \
|
||||
} else { \
|
||||
READ_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_RS_BIT); \
|
||||
}
|
||||
#define SFP_PORT_TS_BIT_GET(sfp_port, port_config_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
READ_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TS_BIT); \
|
||||
} else { \
|
||||
READ_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TS_BIT); \
|
||||
}
|
||||
#define SFP_PORT_TXDIS_BIT_SET(sfp_port, port_config_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
SET_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TXDIS_BIT); \
|
||||
} else { \
|
||||
SET_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_TXDIS_BIT); \
|
||||
}
|
||||
#define SFP_PORT_TXDIS_BIT_CLEAR(sfp_port, port_config_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
CLEAR_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TXDIS_BIT); \
|
||||
} else { \
|
||||
CLEAR_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_TXDIS_BIT); \
|
||||
}
|
||||
#define SFP_PORT_RS_BIT_SET(sfp_port, port_config_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
SET_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_RS_BIT); \
|
||||
} else { \
|
||||
SET_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_RS_BIT); \
|
||||
}
|
||||
#define SFP_PORT_RS_BIT_CLEAR(sfp_port, port_config_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
CLEAR_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_RS_BIT); \
|
||||
} else { \
|
||||
CLEAR_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_RS_BIT); \
|
||||
}
|
||||
#define SFP_PORT_TS_BIT_SET(sfp_port, port_config_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
SET_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TS_BIT); \
|
||||
} else { \
|
||||
SET_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_TS_BIT); \
|
||||
}
|
||||
#define SFP_PORT_TS_BIT_CLEAR(sfp_port, port_config_value) \
|
||||
if (sfp_port == SFP_MIN_PORT_NUM) { \
|
||||
CLEAR_BIT(port_config_value, CPLD_SFP0_PORT_CONFIG_TS_BIT); \
|
||||
} else { \
|
||||
CLEAR_BIT(port_config_value, CPLD_SFP1_PORT_CONFIG_TS_BIT); \
|
||||
}
|
||||
|
||||
/* CPLD access functions */
|
||||
extern int ingrasys_i2c_cpld_get_qsfp_port_status_val(u8 port_num);
|
||||
extern int ingrasys_i2c_cpld_get_qsfp_port_config_val(u8 port_num);
|
||||
extern int ingrasys_i2c_cpld_set_qsfp_port_config_val(u8 port_num, u8 reg_val);
|
||||
extern int ingrasys_i2c_cpld_get_sfp_port_status_val(void);
|
||||
extern int ingrasys_i2c_cpld_get_sfp_port_config_val(void);
|
||||
extern int ingrasys_i2c_cpld_set_sfp_port_config_val(u8 reg_val);
|
||||
extern u8 fp_port_to_phy_port(u8 fp_port);
|
||||
#endif
|
||||
|
@ -0,0 +1,158 @@
|
||||
#ifndef _S9230_64X_PLATFORM_H
|
||||
#define _S9230_64X_PLATFORM_H
|
||||
|
||||
#include <linux/i2c.h>
|
||||
|
||||
// remove debug before release
|
||||
#define DEBUG
|
||||
|
||||
enum bus_order {
|
||||
I2C_BUS_MAIN,
|
||||
MUX_9548_0_CH0,
|
||||
MUX_9548_0_CH1,
|
||||
MUX_9548_0_CH2,
|
||||
MUX_9548_0_CH3,
|
||||
MUX_9548_0_CH4,
|
||||
MUX_9548_0_CH5,
|
||||
MUX_9548_0_CH6,
|
||||
MUX_9548_0_CH7,
|
||||
MUX_9548_1_CH0,
|
||||
MUX_9548_1_CH1,
|
||||
MUX_9548_1_CH2,
|
||||
MUX_9548_1_CH3,
|
||||
MUX_9548_1_CH4,
|
||||
MUX_9548_1_CH5,
|
||||
MUX_9548_1_CH6,
|
||||
MUX_9548_1_CH7,
|
||||
MUX_9548_2_CH0,
|
||||
MUX_9548_2_CH1,
|
||||
MUX_9548_2_CH2,
|
||||
MUX_9548_2_CH3,
|
||||
MUX_9548_2_CH4,
|
||||
MUX_9548_2_CH5,
|
||||
MUX_9548_2_CH6,
|
||||
MUX_9548_2_CH7,
|
||||
MUX_9546_0_CH0,
|
||||
MUX_9546_0_CH1,
|
||||
MUX_9546_0_CH2,
|
||||
MUX_9546_0_CH3,
|
||||
MUX_9546_1_CH0,
|
||||
MUX_9546_1_CH1,
|
||||
MUX_9546_1_CH2,
|
||||
MUX_9546_1_CH3,
|
||||
MUX_9548_11_CH0,
|
||||
MUX_9548_11_CH1,
|
||||
MUX_9548_11_CH2,
|
||||
MUX_9548_11_CH3,
|
||||
MUX_9548_11_CH4,
|
||||
MUX_9548_11_CH5,
|
||||
MUX_9548_11_CH6,
|
||||
MUX_9548_11_CH7,
|
||||
MUX_9548_3_CH0,
|
||||
MUX_9548_3_CH1,
|
||||
MUX_9548_3_CH2,
|
||||
MUX_9548_3_CH3,
|
||||
MUX_9548_3_CH4,
|
||||
MUX_9548_3_CH5,
|
||||
MUX_9548_3_CH6,
|
||||
MUX_9548_3_CH7,
|
||||
MUX_9548_4_CH0,
|
||||
MUX_9548_4_CH1,
|
||||
MUX_9548_4_CH2,
|
||||
MUX_9548_4_CH3,
|
||||
MUX_9548_4_CH4,
|
||||
MUX_9548_4_CH5,
|
||||
MUX_9548_4_CH6,
|
||||
MUX_9548_4_CH7,
|
||||
MUX_9548_5_CH0,
|
||||
MUX_9548_5_CH1,
|
||||
MUX_9548_5_CH2,
|
||||
MUX_9548_5_CH3,
|
||||
MUX_9548_5_CH4,
|
||||
MUX_9548_5_CH5,
|
||||
MUX_9548_5_CH6,
|
||||
MUX_9548_5_CH7,
|
||||
MUX_9548_6_CH0,
|
||||
MUX_9548_6_CH1,
|
||||
MUX_9548_6_CH2,
|
||||
MUX_9548_6_CH3,
|
||||
MUX_9548_6_CH4,
|
||||
MUX_9548_6_CH5,
|
||||
MUX_9548_6_CH6,
|
||||
MUX_9548_6_CH7,
|
||||
MUX_9548_7_CH0,
|
||||
MUX_9548_7_CH1,
|
||||
MUX_9548_7_CH2,
|
||||
MUX_9548_7_CH3,
|
||||
MUX_9548_7_CH4,
|
||||
MUX_9548_7_CH5,
|
||||
MUX_9548_7_CH6,
|
||||
MUX_9548_7_CH7,
|
||||
MUX_9548_8_CH0,
|
||||
MUX_9548_8_CH1,
|
||||
MUX_9548_8_CH2,
|
||||
MUX_9548_8_CH3,
|
||||
MUX_9548_8_CH4,
|
||||
MUX_9548_8_CH5,
|
||||
MUX_9548_8_CH6,
|
||||
MUX_9548_8_CH7,
|
||||
MUX_9548_9_CH0,
|
||||
MUX_9548_9_CH1,
|
||||
MUX_9548_9_CH2,
|
||||
MUX_9548_9_CH3,
|
||||
MUX_9548_9_CH4,
|
||||
MUX_9548_9_CH5,
|
||||
MUX_9548_9_CH6,
|
||||
MUX_9548_9_CH7,
|
||||
MUX_9548_10_CH0,
|
||||
MUX_9548_10_CH1,
|
||||
MUX_9548_10_CH2,
|
||||
MUX_9548_10_CH3,
|
||||
MUX_9548_10_CH4,
|
||||
MUX_9548_10_CH5,
|
||||
MUX_9548_10_CH6,
|
||||
MUX_9548_10_CH7,
|
||||
};
|
||||
|
||||
#define I2C_ADDR_MUX_9555_0 (0x20)
|
||||
#define I2C_ADDR_MUX_9555_1 (0x24)
|
||||
#define I2C_ADDR_MUX_9555_2 (0x25)
|
||||
#define I2C_ADDR_MUX_9555_3 (0x26)
|
||||
#define I2C_ADDR_MUX_9539_0 (0x76)
|
||||
#define I2C_ADDR_MUX_9539_1 (0x76)
|
||||
#define I2C_BUS_FAN_STATUS (I2C_BUS_MAIN)
|
||||
#define I2C_BUS_SYS_LED (MUX_9548_1_CH1)
|
||||
#define I2C_BUS_PSU_STATUS (I2C_BUS_MAIN)
|
||||
#define I2C_ADDR_PSU_STATUS (I2C_ADDR_MUX_9555_2)
|
||||
|
||||
#define NUM_OF_I2C_MUX (11)
|
||||
#define NUM_OF_CPLD (5)
|
||||
#define NUM_OF_QSFP_PORT (64)
|
||||
#define NUM_OF_SFP_PORT (2)
|
||||
#define QSFP_EEPROM_I2C_ADDR (0x50)
|
||||
|
||||
enum gpio_reg {
|
||||
REG_PORT0_IN,
|
||||
REG_PORT1_IN,
|
||||
REG_PORT0_OUT,
|
||||
REG_PORT1_OUT,
|
||||
REG_PORT0_POL,
|
||||
REG_PORT1_POL,
|
||||
REG_PORT0_DIR,
|
||||
REG_PORT1_DIR,
|
||||
};
|
||||
|
||||
struct ing_i2c_board_info {
|
||||
int ch;
|
||||
int size;
|
||||
struct i2c_board_info *board_info;
|
||||
};
|
||||
|
||||
struct i2c_init_data {
|
||||
__u16 ch;
|
||||
__u16 addr;
|
||||
__u8 reg;
|
||||
__u8 value;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,394 @@
|
||||
/*
|
||||
* S9280-64x PSU driver
|
||||
*
|
||||
* Copyright (C) 2017 Ingrasys, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include "ingrasys_s9280_64x_platform.h"
|
||||
|
||||
static ssize_t show_psu_eeprom(struct device *dev,
|
||||
struct device_attribute *da,
|
||||
char *buf);
|
||||
static struct s9280_psu_data *s9280_psu_update_status(struct device *dev);
|
||||
static struct s9280_psu_data *s9280_psu_update_eeprom(struct device *dev);
|
||||
static int s9280_psu_read_block(struct i2c_client *client,
|
||||
u8 command,
|
||||
u8 *data,
|
||||
int data_len);
|
||||
|
||||
|
||||
#define DRIVER_NAME "psu"
|
||||
|
||||
// Addresses scanned
|
||||
static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
|
||||
|
||||
/* PSU EEPROM SIZE */
|
||||
#define EEPROM_SZ 256
|
||||
#define READ_EEPROM 1
|
||||
#define NREAD_EEPROM 0
|
||||
|
||||
static struct i2c_client pca9555_client;
|
||||
|
||||
/* pca9555 gpio pin mapping */
|
||||
#define PSU2_PWROK 0
|
||||
#define PSU2_PRSNT_L 1
|
||||
#define PSU2_PWRON_L 2
|
||||
#define PSU1_PWROK 3
|
||||
#define PSU1_PRSNT_L 4
|
||||
#define PSU1_PWRON_L 5
|
||||
#define TMP_75_INT_L 6
|
||||
|
||||
/* Driver Private Data */
|
||||
struct s9280_psu_data {
|
||||
struct mutex lock;
|
||||
char valid; /* !=0 if registers are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
u8 index; /* PSU index */
|
||||
s32 status; /* IO expander value */
|
||||
char eeprom[EEPROM_SZ]; /* psu eeprom data */
|
||||
char psuABS; /* PSU absent */
|
||||
char psuPG; /* PSU power good */
|
||||
};
|
||||
|
||||
enum psu_index
|
||||
{
|
||||
s9280_psu1,
|
||||
s9280_psu2
|
||||
};
|
||||
|
||||
/*
|
||||
* display power good attribute
|
||||
*/
|
||||
static ssize_t
|
||||
show_psu_pg(struct device *dev,
|
||||
struct device_attribute *devattr,
|
||||
char *buf)
|
||||
{
|
||||
struct s9280_psu_data *data = s9280_psu_update_status(dev);
|
||||
unsigned int value;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
value = data->psuPG;
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return sprintf(buf, "%d\n", value);
|
||||
}
|
||||
|
||||
/*
|
||||
* display power absent attribute
|
||||
*/
|
||||
static ssize_t
|
||||
show_psu_abs(struct device *dev,
|
||||
struct device_attribute *devattr,
|
||||
char *buf)
|
||||
{
|
||||
struct s9280_psu_data *data = s9280_psu_update_status(dev);
|
||||
unsigned int value;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
value = data->psuABS;
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return sprintf(buf, "%d\n", value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sysfs attributes for psu
|
||||
*/
|
||||
static DEVICE_ATTR(psu_pg, S_IRUGO, show_psu_pg, NULL);
|
||||
static DEVICE_ATTR(psu_abs, S_IRUGO, show_psu_abs, NULL);
|
||||
static DEVICE_ATTR(psu_eeprom, S_IRUGO, show_psu_eeprom, NULL);
|
||||
|
||||
static struct attribute *s9280_psu_attributes[] = {
|
||||
&dev_attr_psu_pg.attr,
|
||||
&dev_attr_psu_abs.attr,
|
||||
&dev_attr_psu_eeprom.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* display psu eeprom content
|
||||
*/
|
||||
static ssize_t
|
||||
show_psu_eeprom(struct device *dev,
|
||||
struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct s9280_psu_data *data = s9280_psu_update_eeprom(dev);
|
||||
|
||||
memcpy(buf, (char *)data->eeprom, EEPROM_SZ);
|
||||
return EEPROM_SZ;
|
||||
}
|
||||
|
||||
static const struct attribute_group s9280_psu_group = {
|
||||
.attrs = s9280_psu_attributes,
|
||||
};
|
||||
|
||||
/*
|
||||
* check gpio expander is accessible
|
||||
*/
|
||||
static int
|
||||
pca9555_detect(struct i2c_client *client)
|
||||
{
|
||||
if (i2c_smbus_read_byte_data(client, REG_PORT0_DIR) < 0) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* client init
|
||||
*/
|
||||
static void
|
||||
i2c_devices_client_address_init(struct i2c_client *client)
|
||||
{
|
||||
pca9555_client = *client;
|
||||
|
||||
/* get i2c adapter for the target */
|
||||
pca9555_client.adapter = i2c_get_adapter(I2C_BUS_PSU_STATUS);
|
||||
|
||||
/* get the i2c addr for the target */
|
||||
pca9555_client.addr = I2C_ADDR_PSU_STATUS;
|
||||
}
|
||||
|
||||
static int
|
||||
s9280_psu_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *dev_id)
|
||||
{
|
||||
struct s9280_psu_data *data;
|
||||
int status, err;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(struct s9280_psu_data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
status = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
memset(data, 0, sizeof(struct s9280_psu_data));
|
||||
i2c_set_clientdata(client, data);
|
||||
data->valid = 0;
|
||||
data->index = dev_id->driver_data;
|
||||
mutex_init(&data->lock);
|
||||
|
||||
i2c_devices_client_address_init(client);
|
||||
|
||||
err = pca9555_detect(&pca9555_client);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "chip found\n");
|
||||
|
||||
/* Register sysfs hooks */
|
||||
status = sysfs_create_group(&client->dev.kobj, &s9280_psu_group);
|
||||
if (status) {
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
exit_free:
|
||||
kfree(data);
|
||||
exit:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
s9280_psu_remove(struct i2c_client *client)
|
||||
{
|
||||
struct s9280_psu_data *data = i2c_get_clientdata(client);
|
||||
|
||||
sysfs_remove_group(&client->dev.kobj, &s9280_psu_group);
|
||||
kfree(data);
|
||||
|
||||
/* free i2c adapter */
|
||||
i2c_put_adapter(pca9555_client.adapter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* psu eeprom read utility
|
||||
*/
|
||||
static int
|
||||
s9280_psu_read_block(struct i2c_client *client,
|
||||
u8 command,
|
||||
u8 *data,
|
||||
int data_len)
|
||||
{
|
||||
int i=0, ret=0;
|
||||
int blk_max = 32; //max block read size
|
||||
|
||||
/* read eeprom, 32 * 8 = 256 bytes */
|
||||
for (i=0; i < EEPROM_SZ/blk_max; i++) {
|
||||
ret = i2c_smbus_read_i2c_block_data(client, (i*blk_max), blk_max,
|
||||
data + (i*blk_max));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* update eeprom content
|
||||
*/
|
||||
static struct s9280_psu_data
|
||||
*s9280_psu_update_eeprom(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct s9280_psu_data *data = i2c_get_clientdata(client);
|
||||
s32 status = 0;
|
||||
int psu_pwrok = 0;
|
||||
int psu_prsnt_l = 0;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
|
||||
if (time_after(jiffies, data->last_updated + 300 * HZ)
|
||||
|| !data->valid) {
|
||||
|
||||
/* Read psu status */
|
||||
|
||||
status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN);
|
||||
data->status = status;
|
||||
|
||||
/*read psu status from io expander*/
|
||||
|
||||
if (data->index == s9280_psu1) {
|
||||
psu_pwrok = PSU1_PWROK;
|
||||
psu_prsnt_l = PSU1_PRSNT_L;
|
||||
} else {
|
||||
psu_pwrok = PSU2_PWROK;
|
||||
psu_prsnt_l = PSU2_PRSNT_L;
|
||||
}
|
||||
data->psuPG = (status >> psu_pwrok) & 0x1;
|
||||
data->psuABS = (status >> psu_prsnt_l) & 0x1;
|
||||
|
||||
/* Read eeprom */
|
||||
if (!data->psuABS) {
|
||||
//clear local eeprom data
|
||||
memset(data->eeprom, 0, EEPROM_SZ);
|
||||
|
||||
//read eeprom
|
||||
status = s9280_psu_read_block(client, 0, data->eeprom,
|
||||
ARRAY_SIZE(data->eeprom));
|
||||
|
||||
if (status < 0) {
|
||||
memset(data->eeprom, 0, EEPROM_SZ);
|
||||
dev_err(&client->dev, "Read eeprom failed, status=(%d)\n", status);
|
||||
} else {
|
||||
data->valid = 1;
|
||||
}
|
||||
} else {
|
||||
memset(data->eeprom, 0, EEPROM_SZ);
|
||||
}
|
||||
data->last_updated = jiffies;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* update psu status
|
||||
*/
|
||||
static struct s9280_psu_data
|
||||
*s9280_psu_update_status(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct s9280_psu_data *data = i2c_get_clientdata(client);
|
||||
s32 status = 0;
|
||||
int psu_pwrok = 0;
|
||||
int psu_prsnt_l = 0;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
|
||||
/* Read psu status */
|
||||
|
||||
status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN);
|
||||
data->status = status;
|
||||
|
||||
/*read psu status from io expander*/
|
||||
|
||||
if (data->index == s9280_psu1) {
|
||||
psu_pwrok = PSU1_PWROK;
|
||||
psu_prsnt_l = PSU1_PRSNT_L;
|
||||
} else {
|
||||
psu_pwrok = PSU2_PWROK;
|
||||
psu_prsnt_l = PSU2_PRSNT_L;
|
||||
}
|
||||
data->psuPG = (status >> psu_pwrok) & 0x1;
|
||||
data->psuABS = (status >> psu_prsnt_l) & 0x1;
|
||||
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id s9280_psu_id[] = {
|
||||
{ "psu1", s9280_psu1 },
|
||||
{ "psu2", s9280_psu2 },
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, s9280_psu_id);
|
||||
|
||||
static struct i2c_driver s9280_psu_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
},
|
||||
.probe = s9280_psu_probe,
|
||||
.remove = s9280_psu_remove,
|
||||
.id_table = s9280_psu_id,
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
static int __init s9280_psu_init(void)
|
||||
{
|
||||
return i2c_add_driver(&s9280_psu_driver);
|
||||
}
|
||||
|
||||
static void __exit s9280_psu_exit(void)
|
||||
{
|
||||
i2c_del_driver(&s9280_psu_driver);
|
||||
}
|
||||
|
||||
module_init(s9280_psu_init);
|
||||
module_exit(s9280_psu_exit);
|
||||
|
||||
MODULE_AUTHOR("Leo Lin <feng.lee.usa@ingrasys.com>");
|
||||
MODULE_DESCRIPTION("S9280-64X psu driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description= This QSFP Monitor service is to setup QSFP SI.
|
||||
Requires=s9280-64x-monitor.service
|
||||
After=s9280-64x-monitor.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/sbin/qsfp_monitor.sh
|
||||
KillSignal=SIGKILL
|
||||
SuccessExitStatus=SIGKILL
|
||||
|
||||
# Resource Limitations
|
||||
LimitCORE=infinity
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description= This Platform Monitor service is to initialize platform and monitor platform.
|
||||
Before=platform-monitor.service
|
||||
After=sysinit.target
|
||||
Wants=fancontrol.service
|
||||
Wants=qsfp-monitor.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
ExecStartPre=/usr/sbin/i2c_utils.sh i2c_init
|
||||
ExecStart=/usr/sbin/s9280_64x_monitor.sh
|
||||
KillSignal=SIGKILL
|
||||
SuccessExitStatus=SIGKILL
|
||||
|
||||
# Resource Limitations
|
||||
LimitCORE=infinity
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
1844
platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/i2c_utils.sh
Executable file
1844
platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/i2c_utils.sh
Executable file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,105 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2017 Ingrasys, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
INTERVAL=3
|
||||
I2C_UTILS="/usr/sbin/i2c_utils.sh"
|
||||
QSFP_SI_SCRIPT="/usr/sbin/qsfp_si_cfg.sh"
|
||||
QSFP_ARRAY=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
|
||||
|
||||
#QSFP SI monitor
|
||||
function _qsfp_si_monitor {
|
||||
local i
|
||||
local status
|
||||
for i in {0..63};
|
||||
do
|
||||
status=`${I2C_UTILS} i2c_qsfp_status_get $(expr $i + 1) | egrep '^status=.*$' | sed -e 's/status=//g'`
|
||||
if [ "${status}" == "1" ]; then
|
||||
_qsfp_type_check $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#QSFP type
|
||||
function _qsfp_type_check {
|
||||
local port=$1
|
||||
local qsfp_type=`${I2C_UTILS} i2c_qsfp_type_get $(expr $port + 1)`
|
||||
local identifier=`echo "$qsfp_type" | grep '^identifier=.*$' | sed -e 's/identifier=//g'`
|
||||
if [ "${identifier}" == "11" ]; then
|
||||
connector=`echo "$qsfp_type" | grep '^connector=.*$' | sed -e 's/connector=//g'`
|
||||
case ${connector} in
|
||||
21|23)
|
||||
#DAC
|
||||
if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then
|
||||
echo "Change Port $(expr $port + 1) to DAC"
|
||||
QSFP_ARRAY[$port]=${connector}
|
||||
${QSFP_SI_SCRIPT} dac $port >/dev/null
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
#Optical
|
||||
if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then
|
||||
echo "Change Port $(expr $port + 1) to Optical"
|
||||
QSFP_ARRAY[$port]=${connector}
|
||||
${QSFP_SI_SCRIPT} optical $port >/dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
#Docker exist check
|
||||
function _docker_swss_check {
|
||||
while true
|
||||
do
|
||||
# Check if syncd starts
|
||||
result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME
|
||||
if [ "$result" == "3" ]; then
|
||||
return
|
||||
fi
|
||||
sleep $INTERVAL
|
||||
done
|
||||
}
|
||||
|
||||
#Docker exist check
|
||||
function _qsfp_si_cfg_script_check {
|
||||
|
||||
if [ -f ${QSFP_SI_SCRIPT} ] && [ -x ${QSFP_SI_SCRIPT} ]; then
|
||||
echo "SI Script exists. Start monitor."
|
||||
return
|
||||
else
|
||||
echo "SI Script not exist. Exit monitor."
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
# main function
|
||||
function _main {
|
||||
#Check SI Script
|
||||
_qsfp_si_cfg_script_check
|
||||
#Check docker swss is running
|
||||
_docker_swss_check
|
||||
while true
|
||||
do
|
||||
_qsfp_si_monitor
|
||||
# Sleep while still handling signals
|
||||
sleep $INTERVAL &
|
||||
wait $!
|
||||
done
|
||||
}
|
||||
|
||||
_main
|
||||
|
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2016 Ingrasys, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
INTERVAL=5
|
||||
I2C_UTILS="/usr/sbin/i2c_utils.sh"
|
||||
|
||||
|
||||
# TBD: LED status monitor
|
||||
function _led_monitor {
|
||||
${I2C_UTILS} i2c_led_fan_status_set >/dev/null
|
||||
${I2C_UTILS} i2c_led_psu_status_set >/dev/null
|
||||
${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null
|
||||
}
|
||||
|
||||
# main function
|
||||
function _main {
|
||||
while true
|
||||
do
|
||||
#PSU controlled by dummy board,
|
||||
#but fan LED and fan tray LED must controlled by this service
|
||||
_led_monitor
|
||||
|
||||
# Sleep while still handling signals
|
||||
sleep $INTERVAL &
|
||||
wait $!
|
||||
done
|
||||
}
|
||||
|
||||
_main
|
Loading…
Reference in New Issue
Block a user