[Nokia-7215-A1]Update Nokia-7215-A1 Platform (#18147)
1) Update Nokia-7215-A1 platform to address UT and OC test failures 2) Enable watchdog service 3) EZB files for SAI upgrade
This commit is contained in:
parent
0c6b143e00
commit
d4ca86bf9d
@ -1 +1 @@
|
|||||||
ee44e299ca857b9f0abf2e804ec4850f
|
4983b60d1d68623c202b91093f3730db
|
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
|||||||
8d006b7a29c75f81b641df68102a6aa3
|
48c76e16726ad2b1cb797c55c477fc30
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" version="2023-05-05-1.04" profile="Askl1" dsig="md5">
|
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" version="2023-11-20-1.05" profile="Askl1" sid="a9deb744-f6cb-4675-bab3-11132e7db1cd">
|
||||||
<ASKL1plt:ASK-L1 xmlns:ASKL1plt="urn:marvell:ASKL1:yang">
|
<ASKL1plt:ASK-L1 xmlns:ASKL1plt="urn:marvell:ASKL1:yang">
|
||||||
<ASKL1plt:typedefs>
|
<ASKL1plt:typedefs>
|
||||||
<ASKL1plt:typedef>
|
<ASKL1plt:typedef>
|
||||||
|
@ -1 +1 @@
|
|||||||
b42f2a2be9da6c7752c0807f9dee48bf
|
d36319f76733ae8593e31f3231599936
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" version="2023-05-05-1.04" profile="Askpp" dsig="md5">
|
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" version="2023-11-20-1.05" profile="Askpp" sid="fdf5b1c2-b80a-47a6-ac37-47e174286524">
|
||||||
<askppplt:ASK-PP xmlns:askppplt="urn:marvell:askpp:yang">
|
<askppplt:ASK-PP xmlns:askppplt="urn:marvell:askpp:yang">
|
||||||
<askppplt:typedefs>
|
<askppplt:typedefs>
|
||||||
<askppplt:typedef>
|
<askppplt:typedef>
|
||||||
@ -357,28 +357,28 @@
|
|||||||
<askppplt:enum>
|
<askppplt:enum>
|
||||||
<askppplt:name>NATIVE</askppplt:name>
|
<askppplt:name>NATIVE</askppplt:name>
|
||||||
<askppplt:description>NATIVE
|
<askppplt:description>NATIVE
|
||||||
* the trunk members are filled
|
* the trunk members are filled
|
||||||
* according to the order given by application.
|
* according to the order given by application.
|
||||||
* Regular trunk may hold max of 8 members.
|
* Regular trunk may hold max of 8 members.
|
||||||
* Cascade trunk may hold :
|
* Cascade trunk may hold :
|
||||||
* max of 64 members</askppplt:description>
|
* max of 64 members</askppplt:description>
|
||||||
<askppplt:value>0</askppplt:value>
|
<askppplt:value>0</askppplt:value>
|
||||||
</askppplt:enum>
|
</askppplt:enum>
|
||||||
<askppplt:enum>
|
<askppplt:enum>
|
||||||
<askppplt:name>FLEX</askppplt:name>
|
<askppplt:name>FLEX</askppplt:name>
|
||||||
<askppplt:description>FLEX
|
<askppplt:description>FLEX
|
||||||
* A mode to allows flexibility for
|
* A mode to allows flexibility for
|
||||||
* each Regular trunk to state it's max number of members (before starting to add members).
|
* each Regular trunk to state it's max number of members (before starting to add members).
|
||||||
* (this mode not effect 'cascade trunk' members)
|
* (this mode not effect 'cascade trunk' members)
|
||||||
* Regular trunk may hold : max of 4K members. (each trunk set it's own limit)
|
* Regular trunk may hold : max of 4K members. (each trunk set it's own limit)
|
||||||
* Cascade trunk may hold : max of 64 members.</askppplt:description>
|
* Cascade trunk may hold : max of 64 members.</askppplt:description>
|
||||||
<askppplt:value>2</askppplt:value>
|
<askppplt:value>2</askppplt:value>
|
||||||
</askppplt:enum>
|
</askppplt:enum>
|
||||||
</askppplt:typedef>
|
</askppplt:typedef>
|
||||||
<askppplt:typedef>
|
<askppplt:typedef>
|
||||||
<askppplt:name>number-physical-port-type</askppplt:name>
|
<askppplt:name>number-physical-port-type</askppplt:name>
|
||||||
<askppplt:type>enumeration</askppplt:type>
|
<askppplt:type>enumeration</askppplt:type>
|
||||||
<askppplt:description>ac5x 128, falcon 64,128,256, 512, 1024</askppplt:description>
|
<askppplt:description>AC3X/AC5X 128, falcon 64, 128, 256, 512, 1024</askppplt:description>
|
||||||
<askppplt:enum>
|
<askppplt:enum>
|
||||||
<askppplt:name>no-ports</askppplt:name>
|
<askppplt:name>no-ports</askppplt:name>
|
||||||
<askppplt:description>no-ports</askppplt:description>
|
<askppplt:description>no-ports</askppplt:description>
|
||||||
|
@ -1 +1 @@
|
|||||||
b43a871130f9e59ac21a74940574558f
|
1ff8c65eb4b5dfff5d2c9be67401c723
|
@ -1,13 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" version="2023-05-05-1.04" profile="SAI" dsig="md5">
|
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" version="2024-01-08-1.05" profile="SAI" sid="fd56a8b4-6b41-4ead-9a27-c491bc2f95b9">
|
||||||
<SAIplt:SAI xmlns:SAIplt="urn:marvell:SAI:yang">
|
<SAIplt:SAI xmlns:SAIplt="urn:marvell:SAI:yang">
|
||||||
<SAIplt:typedefs>
|
<SAIplt:typedefs>
|
||||||
<SAIplt:typedef>
|
<SAIplt:typedef>
|
||||||
<SAIplt:name>device-id-type</SAIplt:name>
|
<SAIplt:name>device-id-type</SAIplt:name>
|
||||||
<SAIplt:type>uint32</SAIplt:type>
|
<SAIplt:type>uint32</SAIplt:type>
|
||||||
<SAIplt:description>Device ID 0..1023</SAIplt:description>
|
<SAIplt:description>Device ID 0..1</SAIplt:description>
|
||||||
<SAIplt:min>0</SAIplt:min>
|
<SAIplt:min>0</SAIplt:min>
|
||||||
<SAIplt:max>1023</SAIplt:max>
|
<SAIplt:max>1</SAIplt:max>
|
||||||
</SAIplt:typedef>
|
</SAIplt:typedef>
|
||||||
<SAIplt:typedef>
|
<SAIplt:typedef>
|
||||||
<SAIplt:name>port-id-type</SAIplt:name>
|
<SAIplt:name>port-id-type</SAIplt:name>
|
||||||
@ -22,7 +22,7 @@
|
|||||||
<SAIplt:description>Logging Feature Options</SAIplt:description>
|
<SAIplt:description>Logging Feature Options</SAIplt:description>
|
||||||
<SAIplt:enum>
|
<SAIplt:enum>
|
||||||
<SAIplt:name>SAI_LOG_SYSLOG</SAIplt:name>
|
<SAIplt:name>SAI_LOG_SYSLOG</SAIplt:name>
|
||||||
<SAIplt:description>SYSLOG {Syslog service should be running to use this option}</SAIplt:description>
|
<SAIplt:description>SYSLOG {Syslog service should be running to use this option}</SAIplt:description>
|
||||||
<SAIplt:value>0</SAIplt:value>
|
<SAIplt:value>0</SAIplt:value>
|
||||||
</SAIplt:enum>
|
</SAIplt:enum>
|
||||||
<SAIplt:enum>
|
<SAIplt:enum>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
</SAIplt:enum>
|
</SAIplt:enum>
|
||||||
<SAIplt:enum>
|
<SAIplt:enum>
|
||||||
<SAIplt:name>SAI_LOG_FILE</SAIplt:name>
|
<SAIplt:name>SAI_LOG_FILE</SAIplt:name>
|
||||||
<SAIplt:description>FILE {Warning !!! Use with caution. Can cause disk full issues}</SAIplt:description>
|
<SAIplt:description>FILE {Warning !!! Use with caution. Can cause disk full issues}</SAIplt:description>
|
||||||
<SAIplt:value>2</SAIplt:value>
|
<SAIplt:value>2</SAIplt:value>
|
||||||
</SAIplt:enum>
|
</SAIplt:enum>
|
||||||
</SAIplt:typedef>
|
</SAIplt:typedef>
|
||||||
@ -43,11 +43,93 @@
|
|||||||
<SAIplt:min>2</SAIplt:min>
|
<SAIplt:min>2</SAIplt:min>
|
||||||
<SAIplt:max>30</SAIplt:max>
|
<SAIplt:max>30</SAIplt:max>
|
||||||
</SAIplt:typedef>
|
</SAIplt:typedef>
|
||||||
|
<SAIplt:typedef>
|
||||||
|
<SAIplt:name>acl-feature-name-type</SAIplt:name>
|
||||||
|
<SAIplt:type>enumeration</SAIplt:type>
|
||||||
|
<SAIplt:description/>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>port-sFlow</SAIplt:name>
|
||||||
|
<SAIplt:description>SFlow over Port</SAIplt:description>
|
||||||
|
<SAIplt:value>0</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>port-counters-ipv4-ipv6</SAIplt:name>
|
||||||
|
<SAIplt:description>Port ipv4/ipv6 counters</SAIplt:description>
|
||||||
|
<SAIplt:value>1</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>control-acl</SAIplt:name>
|
||||||
|
<SAIplt:description>ACLs for control packet handling</SAIplt:description>
|
||||||
|
<SAIplt:value>2</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
</SAIplt:typedef>
|
||||||
|
<SAIplt:typedef>
|
||||||
|
<SAIplt:name>ingress-acl-stage-type</SAIplt:name>
|
||||||
|
<SAIplt:type>enumeration</SAIplt:type>
|
||||||
|
<SAIplt:description/>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>disabled</SAIplt:name>
|
||||||
|
<SAIplt:description>Feature not enabled</SAIplt:description>
|
||||||
|
<SAIplt:value>0</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>IPCL0</SAIplt:name>
|
||||||
|
<SAIplt:description>Stage IPCL0</SAIplt:description>
|
||||||
|
<SAIplt:value>1</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>IPCL1</SAIplt:name>
|
||||||
|
<SAIplt:description>Stage IPCL1</SAIplt:description>
|
||||||
|
<SAIplt:value>2</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
</SAIplt:typedef>
|
||||||
|
<SAIplt:typedef>
|
||||||
|
<SAIplt:name>egress-acl-stage-type</SAIplt:name>
|
||||||
|
<SAIplt:type>enumeration</SAIplt:type>
|
||||||
|
<SAIplt:description/>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>disabled</SAIplt:name>
|
||||||
|
<SAIplt:description>Feature not enabled</SAIplt:description>
|
||||||
|
<SAIplt:value>0</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>EPCL0</SAIplt:name>
|
||||||
|
<SAIplt:description>Stage EPCL0</SAIplt:description>
|
||||||
|
<SAIplt:value>2</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
</SAIplt:typedef>
|
||||||
|
<SAIplt:typedef>
|
||||||
|
<SAIplt:name>feature-priority-type</SAIplt:name>
|
||||||
|
<SAIplt:type>uint32</SAIplt:type>
|
||||||
|
<SAIplt:description>Feature priority</SAIplt:description>
|
||||||
|
<SAIplt:min>2</SAIplt:min>
|
||||||
|
<SAIplt:max>15</SAIplt:max>
|
||||||
|
</SAIplt:typedef>
|
||||||
|
<SAIplt:typedef>
|
||||||
|
<SAIplt:name>hit-number-type</SAIplt:name>
|
||||||
|
<SAIplt:type>uint32</SAIplt:type>
|
||||||
|
<SAIplt:description>Hit/lookup number</SAIplt:description>
|
||||||
|
<SAIplt:min>0</SAIplt:min>
|
||||||
|
<SAIplt:max>3</SAIplt:max>
|
||||||
|
</SAIplt:typedef>
|
||||||
|
<SAIplt:typedef>
|
||||||
|
<SAIplt:name>asic-type</SAIplt:name>
|
||||||
|
<SAIplt:type>enumeration</SAIplt:type>
|
||||||
|
<SAIplt:description>ASIC Type</SAIplt:description>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>ASIC_AC3X</SAIplt:name>
|
||||||
|
<SAIplt:description>AC3X</SAIplt:description>
|
||||||
|
<SAIplt:value>0</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
<SAIplt:enum>
|
||||||
|
<SAIplt:name>ASIC_AC5X</SAIplt:name>
|
||||||
|
<SAIplt:description>AC5X</SAIplt:description>
|
||||||
|
<SAIplt:value>1</SAIplt:value>
|
||||||
|
</SAIplt:enum>
|
||||||
|
</SAIplt:typedef>
|
||||||
</SAIplt:typedefs>
|
</SAIplt:typedefs>
|
||||||
|
<SAIplt:ASIC_Type SAIplt:type="asic-type">ASIC_AC5X</SAIplt:ASIC_Type>
|
||||||
<SAIplt:ASK-BOARD-Profile-Name SAIplt:type="string">ASK-Board-AC5X-xb.xml</SAIplt:ASK-BOARD-Profile-Name>
|
<SAIplt:ASK-BOARD-Profile-Name SAIplt:type="string">ASK-Board-AC5X-xb.xml</SAIplt:ASK-BOARD-Profile-Name>
|
||||||
<SAIplt:Features>
|
|
||||||
<SAIplt:RoCE SAIplt:type="boolean">false</SAIplt:RoCE>
|
|
||||||
</SAIplt:Features>
|
|
||||||
<SAIplt:Ports>
|
<SAIplt:Ports>
|
||||||
<SAIplt:port-list>
|
<SAIplt:port-list>
|
||||||
<SAIplt:sai_port_id SAIplt:type="port-id-type">0</SAIplt:sai_port_id>
|
<SAIplt:sai_port_id SAIplt:type="port-id-type">0</SAIplt:sai_port_id>
|
||||||
@ -310,7 +392,7 @@
|
|||||||
<SAIplt:sdk_port_id SAIplt:type="port-id-type">51</SAIplt:sdk_port_id>
|
<SAIplt:sdk_port_id SAIplt:type="port-id-type">51</SAIplt:sdk_port_id>
|
||||||
</SAIplt:port-list>
|
</SAIplt:port-list>
|
||||||
</SAIplt:Ports>
|
</SAIplt:Ports>
|
||||||
<SAIplt:Scaling>
|
<SAIplt:scalingAC5>
|
||||||
<SAIplt:max_lag_members SAIplt:type="uint32">8</SAIplt:max_lag_members>
|
<SAIplt:max_lag_members SAIplt:type="uint32">8</SAIplt:max_lag_members>
|
||||||
<SAIplt:max_route_ipv4 SAIplt:type="uint32">0</SAIplt:max_route_ipv4>
|
<SAIplt:max_route_ipv4 SAIplt:type="uint32">0</SAIplt:max_route_ipv4>
|
||||||
<SAIplt:max_route_ipv6 SAIplt:type="uint32">0</SAIplt:max_route_ipv6>
|
<SAIplt:max_route_ipv6 SAIplt:type="uint32">0</SAIplt:max_route_ipv6>
|
||||||
@ -320,9 +402,45 @@
|
|||||||
<SAIplt:max_tti SAIplt:type="uint32">1024</SAIplt:max_tti>
|
<SAIplt:max_tti SAIplt:type="uint32">1024</SAIplt:max_tti>
|
||||||
<SAIplt:wred_size SAIplt:type="uint32">0</SAIplt:wred_size>
|
<SAIplt:wred_size SAIplt:type="uint32">0</SAIplt:wred_size>
|
||||||
<SAIplt:max_nat SAIplt:type="uint32">0</SAIplt:max_nat>
|
<SAIplt:max_nat SAIplt:type="uint32">0</SAIplt:max_nat>
|
||||||
</SAIplt:Scaling>
|
</SAIplt:scalingAC5>
|
||||||
<SAIplt:Logging>
|
<SAIplt:Logging>
|
||||||
<SAIplt:log_dest SAIplt:type="logDest-type">SAI_LOG_SYSLOG</SAIplt:log_dest>
|
<SAIplt:log_dest SAIplt:type="logDest-type">SAI_LOG_SYSLOG</SAIplt:log_dest>
|
||||||
</SAIplt:Logging>
|
</SAIplt:Logging>
|
||||||
|
<SAIplt:Features-using-acl>
|
||||||
|
<SAIplt:feature SAIplt:type="acl-feature-name-type">control-acl</SAIplt:feature>
|
||||||
|
<SAIplt:feature-priority SAIplt:type="feature-priority-type">2</SAIplt:feature-priority>
|
||||||
|
<SAIplt:Ingress>
|
||||||
|
<SAIplt:ingress-stage SAIplt:type="ingress-acl-stage-type">IPCL0</SAIplt:ingress-stage>
|
||||||
|
<SAIplt:hit-number SAIplt:type="hit-number-type">1</SAIplt:hit-number>
|
||||||
|
</SAIplt:Ingress>
|
||||||
|
<SAIplt:Egress>
|
||||||
|
<SAIplt:egress-stage SAIplt:type="egress-acl-stage-type">EPCL0</SAIplt:egress-stage>
|
||||||
|
<SAIplt:hit-number SAIplt:type="hit-number-type">0</SAIplt:hit-number>
|
||||||
|
</SAIplt:Egress>
|
||||||
|
</SAIplt:Features-using-acl>
|
||||||
|
<SAIplt:Features-using-acl>
|
||||||
|
<SAIplt:feature SAIplt:type="acl-feature-name-type">port-sFlow</SAIplt:feature>
|
||||||
|
<SAIplt:feature-priority SAIplt:type="feature-priority-type">3</SAIplt:feature-priority>
|
||||||
|
<SAIplt:Ingress>
|
||||||
|
<SAIplt:ingress-stage SAIplt:type="ingress-acl-stage-type">IPCL0</SAIplt:ingress-stage>
|
||||||
|
<SAIplt:hit-number SAIplt:type="hit-number-type">0</SAIplt:hit-number>
|
||||||
|
</SAIplt:Ingress>
|
||||||
|
<SAIplt:Egress>
|
||||||
|
<SAIplt:egress-stage SAIplt:type="egress-acl-stage-type">EPCL0</SAIplt:egress-stage>
|
||||||
|
<SAIplt:hit-number SAIplt:type="hit-number-type">0</SAIplt:hit-number>
|
||||||
|
</SAIplt:Egress>
|
||||||
|
</SAIplt:Features-using-acl>
|
||||||
|
<SAIplt:Features-using-acl>
|
||||||
|
<SAIplt:feature SAIplt:type="acl-feature-name-type">port-counters-ipv4-ipv6</SAIplt:feature>
|
||||||
|
<SAIplt:feature-priority SAIplt:type="feature-priority-type">4</SAIplt:feature-priority>
|
||||||
|
<SAIplt:Ingress>
|
||||||
|
<SAIplt:ingress-stage SAIplt:type="ingress-acl-stage-type">IPCL0</SAIplt:ingress-stage>
|
||||||
|
<SAIplt:hit-number SAIplt:type="hit-number-type">3</SAIplt:hit-number>
|
||||||
|
</SAIplt:Ingress>
|
||||||
|
<SAIplt:Egress>
|
||||||
|
<SAIplt:egress-stage SAIplt:type="egress-acl-stage-type">EPCL0</SAIplt:egress-stage>
|
||||||
|
<SAIplt:hit-number SAIplt:type="hit-number-type">0</SAIplt:hit-number>
|
||||||
|
</SAIplt:Egress>
|
||||||
|
</SAIplt:Features-using-acl>
|
||||||
</SAIplt:SAI>
|
</SAIplt:SAI>
|
||||||
</data>
|
</data>
|
@ -1,2 +1 @@
|
|||||||
VAR_LOG_SIZE=4096
|
|
||||||
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="default_hugepagesz=32M hugepages=4 loglevel=4"
|
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="default_hugepagesz=32M hugepages=4 loglevel=4"
|
||||||
|
10
device/nokia/arm64-nokia_ixs7215_52xb-r0/pcie.yaml
Normal file
10
device/nokia/arm64-nokia_ixs7215_52xb-r0/pcie.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
- bus: '00'
|
||||||
|
dev: '00'
|
||||||
|
fn: '0'
|
||||||
|
id: '0110'
|
||||||
|
name: 'PCI bridge: Marvell Technology Group Ltd. 88F60x0/88F70x0/88F80x0/CN913x ARM SoC'
|
||||||
|
- bus: '01'
|
||||||
|
dev: '00'
|
||||||
|
fn: '0'
|
||||||
|
id: '9821'
|
||||||
|
name: 'Ethernet controller: Marvell Technology Group Ltd. Device 9821'
|
@ -97,17 +97,22 @@
|
|||||||
"high-crit-threshold": false
|
"high-crit-threshold": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "AC5X CORE",
|
"name": "PCB MID",
|
||||||
"controllable": false,
|
"controllable": false,
|
||||||
"low-threshold": false,
|
"low-threshold": false,
|
||||||
"low-crit-threshold": false,
|
"low-crit-threshold": false,
|
||||||
"high-crit-threshold": false
|
"high-crit-threshold": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "OOB PHY",
|
"name": "ASIC",
|
||||||
|
"controllable": false,
|
||||||
|
"low-threshold": false,
|
||||||
|
"low-crit-threshold": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CPU CORE",
|
||||||
"controllable": false,
|
"controllable": false,
|
||||||
"low-threshold": false,
|
"low-threshold": false,
|
||||||
"high-threshold": false,
|
|
||||||
"low-crit-threshold": false
|
"low-crit-threshold": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
10
device/nokia/arm64-nokia_ixs7215_52xb-r0/platform_reboot
Normal file → Executable file
10
device/nokia/arm64-nokia_ixs7215_52xb-r0/platform_reboot
Normal file → Executable file
@ -1,11 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
function SafePwrCycle() {
|
function SafeReboot() {
|
||||||
sync ; sync
|
sync ; sync
|
||||||
sudo umount -fa > /dev/null 2&>1
|
sudo umount -fa > /dev/null 2&>1
|
||||||
|
|
||||||
# Write CPLD register to initiate cold reboot
|
# Turn off watchdog monitor gpio for correct reboot-cause
|
||||||
sudo echo 0 > /sys/bus/i2c/devices/i2c-0/0-0041/cold_reset
|
sudo echo 1 > /sys/class/gpio/gpio41/value
|
||||||
|
cat /sys/bus/i2c/devices/0-0041/last_reset_cause > /dev/null 2&>1
|
||||||
|
exec /sbin/reboot
|
||||||
}
|
}
|
||||||
|
|
||||||
SafePwrCycle
|
SafeReboot
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"skip_pcied": true
|
|
||||||
}
|
|
@ -2,9 +2,7 @@
|
|||||||
"services_to_ignore": [],
|
"services_to_ignore": [],
|
||||||
"devices_to_ignore": [
|
"devices_to_ignore": [
|
||||||
"asic",
|
"asic",
|
||||||
"psu.temperature",
|
"psu.temperature"
|
||||||
"fan",
|
|
||||||
"psu"
|
|
||||||
],
|
],
|
||||||
"user_defined_checkers": [],
|
"user_defined_checkers": [],
|
||||||
"polling_interval": 60,
|
"polling_interval": 60,
|
||||||
|
@ -1 +1 @@
|
|||||||
obj-m:= nokia_7215_ixs_a1_cpld.o ac5_thermal_sensor.o
|
obj-m:= nokia_7215_ixs_a1_cpld.o cn9130_cpu_thermal_sensor.o
|
||||||
|
@ -1,218 +0,0 @@
|
|||||||
/*
|
|
||||||
* HWMON Driver for AC5x thermal sensor
|
|
||||||
*
|
|
||||||
* Author: Natarajan Subbiramani <nataraja.subbiramani.ext@nokia.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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/miscdevice.h>
|
|
||||||
#include <linux/hwmon.h>
|
|
||||||
#include <linux/hwmon-sysfs.h>
|
|
||||||
#include <linux/err.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
|
|
||||||
#define AC5_DEFAULT_TEMP_CRIT 100000
|
|
||||||
#define AC5_DEFAULT_TEMP_MAX 110000
|
|
||||||
|
|
||||||
#define AC5_TEMP_BASE_ADDR 0x944F80D0
|
|
||||||
static unsigned long thermal_base_addr=AC5_TEMP_BASE_ADDR;
|
|
||||||
module_param(thermal_base_addr, ulong, 0444);
|
|
||||||
MODULE_PARM_DESC(thermal_base_addr,
|
|
||||||
"Initialize the base address of the thermal sensor");
|
|
||||||
|
|
||||||
struct ac5_thermal_data {
|
|
||||||
struct device *dev;
|
|
||||||
struct device *hwmon_dev;
|
|
||||||
uint8_t * __iomem temp_base;
|
|
||||||
int temp_input;
|
|
||||||
int temp_crit;
|
|
||||||
int temp_max;
|
|
||||||
};
|
|
||||||
|
|
||||||
static long ac5_thermal_read_reg_in_mcelcius(struct device *dev, struct ac5_thermal_data *data)
|
|
||||||
{
|
|
||||||
volatile uint8_t * __iomem temp_base = data->temp_base;
|
|
||||||
uint32_t regval;
|
|
||||||
long output=data->temp_max;
|
|
||||||
|
|
||||||
//STOP MEASUREMENT
|
|
||||||
writel(0xF0F01034, temp_base);
|
|
||||||
|
|
||||||
//delay for 1ms
|
|
||||||
mdelay(1);
|
|
||||||
|
|
||||||
//Read thermal value
|
|
||||||
regval = readl(temp_base+0xC);
|
|
||||||
|
|
||||||
//RE-START MEASUREMENT
|
|
||||||
writel(0xF0F01035, temp_base);
|
|
||||||
|
|
||||||
//Validate data
|
|
||||||
if(regval & 0x10000) {
|
|
||||||
//Calibrate it to milli-celcius
|
|
||||||
output = (regval>> 6) & 0x3FF;
|
|
||||||
output = ((output*42)-27250)*10;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
static int ac5_thermal_read(struct device *dev, enum hwmon_sensor_types type,
|
|
||||||
u32 attr, int channel, long *val)
|
|
||||||
{
|
|
||||||
struct ac5_thermal_data *data = dev_get_drvdata(dev);
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case hwmon_temp:
|
|
||||||
switch (attr) {
|
|
||||||
case hwmon_temp_input:
|
|
||||||
*val = ac5_thermal_read_reg_in_mcelcius(dev, data);
|
|
||||||
break;
|
|
||||||
case hwmon_temp_crit:
|
|
||||||
*val = data->temp_crit;
|
|
||||||
break;
|
|
||||||
case hwmon_temp_max:
|
|
||||||
*val = data->temp_max;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ac5_thermal_write(struct device *dev, enum hwmon_sensor_types type,
|
|
||||||
u32 attr, int channel, long val)
|
|
||||||
{
|
|
||||||
struct ac5_thermal_data *data = dev_get_drvdata(dev);
|
|
||||||
switch (type) {
|
|
||||||
case hwmon_temp:
|
|
||||||
switch (attr) {
|
|
||||||
case hwmon_temp_crit:
|
|
||||||
data->temp_crit = val;
|
|
||||||
break;
|
|
||||||
case hwmon_temp_max:
|
|
||||||
data->temp_max = val;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static umode_t ac5_thermal_is_visible(const void *data, enum hwmon_sensor_types type,
|
|
||||||
u32 attr, int channel)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case hwmon_temp:
|
|
||||||
switch (attr) {
|
|
||||||
case hwmon_temp_input:
|
|
||||||
return 0444;
|
|
||||||
case hwmon_temp_crit:
|
|
||||||
case hwmon_temp_max:
|
|
||||||
return 0644;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct hwmon_channel_info *ac5_thermal_info[] = {
|
|
||||||
HWMON_CHANNEL_INFO(temp,
|
|
||||||
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT),
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hwmon_ops ac5_thermal_hwmon_ops = {
|
|
||||||
.is_visible = ac5_thermal_is_visible,
|
|
||||||
.read = ac5_thermal_read,
|
|
||||||
.write = ac5_thermal_write,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hwmon_chip_info ac5_thermal_chip_info = {
|
|
||||||
.ops = &ac5_thermal_hwmon_ops,
|
|
||||||
.info = ac5_thermal_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct file_operations fops = {
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct miscdevice ac5_thermal_misc_device = {
|
|
||||||
.minor = TEMP_MINOR,
|
|
||||||
.name = "ac5_thermal",
|
|
||||||
.fops = &fops,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init ac5_thermal_init_misc_driver(void)
|
|
||||||
{
|
|
||||||
struct device *dev;
|
|
||||||
struct ac5_thermal_data *thermal_data;
|
|
||||||
int err;
|
|
||||||
void * __iomem reg;
|
|
||||||
|
|
||||||
err = misc_register(&ac5_thermal_misc_device);
|
|
||||||
if (err) {
|
|
||||||
pr_err("ac5_thermal misc_register failed!!!\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev = ac5_thermal_misc_device.this_device;
|
|
||||||
thermal_data = devm_kzalloc(dev, sizeof(struct ac5_thermal_data), GFP_KERNEL);
|
|
||||||
if (!thermal_data)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
thermal_data->dev = dev;
|
|
||||||
thermal_data->temp_crit = AC5_DEFAULT_TEMP_CRIT;
|
|
||||||
thermal_data->temp_max = AC5_DEFAULT_TEMP_MAX;
|
|
||||||
|
|
||||||
thermal_data->hwmon_dev = devm_hwmon_device_register_with_info(dev, ac5_thermal_misc_device.name,
|
|
||||||
thermal_data, &ac5_thermal_chip_info,
|
|
||||||
NULL);
|
|
||||||
if (IS_ERR(thermal_data->hwmon_dev)) {
|
|
||||||
dev_err(dev, "%s: hwmon registration failed.\n", ac5_thermal_misc_device.name);
|
|
||||||
return PTR_ERR(thermal_data->hwmon_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
reg = devm_ioremap(dev, thermal_base_addr, 16);
|
|
||||||
if (IS_ERR(reg)) {
|
|
||||||
dev_err(dev, "%s: base addr remap failed\n", ac5_thermal_misc_device.name);
|
|
||||||
return PTR_ERR(reg);
|
|
||||||
}
|
|
||||||
thermal_data->temp_base = reg;
|
|
||||||
/*Enable measurement*/
|
|
||||||
writel(0xF0F01035, thermal_data->temp_base);
|
|
||||||
writel(0x0584e680, thermal_data->temp_base+8);
|
|
||||||
|
|
||||||
dev_info(dev, "%s: initialized. base_addr: 0x%lx\n", dev_name(thermal_data->hwmon_dev), thermal_base_addr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit ac5_thermal_exit_misc_driver(void)
|
|
||||||
{
|
|
||||||
misc_deregister(&ac5_thermal_misc_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(ac5_thermal_init_misc_driver);
|
|
||||||
module_exit(ac5_thermal_exit_misc_driver);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Natarajan Subbiramani <natarajan.subbiramani.ext@nokia.com>");
|
|
||||||
MODULE_DESCRIPTION("AC5 Thermal sensor Driver");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
* HWMON Driver for CN9130 thermal sensor
|
||||||
|
*
|
||||||
|
* Author: Natarajan Subbiramani <nataraja.subbiramani.ext@nokia.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/miscdevice.h>
|
||||||
|
#include <linux/hwmon.h>
|
||||||
|
#include <linux/hwmon-sysfs.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
|
#define CN9130_DEFAULT_TEMP_CRIT 100000
|
||||||
|
#define CN9130_DEFAULT_TEMP_MAX 106000
|
||||||
|
|
||||||
|
#define CN9130_TEMP_BASE_ADDR 0xF06F8080
|
||||||
|
#define CN9130_TSEN_REG_CTRL_0_OFFSET 0x4
|
||||||
|
#define CN9130_TSEN_REG_CTRL_1_OFFSET 0x8
|
||||||
|
#define CN9130_TSEN_REG_STATUS_OFFSET 0xC
|
||||||
|
#define CN9130_TSEN_SENSOR_MAX_ID 6
|
||||||
|
static unsigned long thermal_base_addr=CN9130_TEMP_BASE_ADDR;
|
||||||
|
module_param(thermal_base_addr, ulong, 0444);
|
||||||
|
MODULE_PARM_DESC(thermal_base_addr,
|
||||||
|
"Initialize the base address of the thermal sensor");
|
||||||
|
|
||||||
|
struct cn9130_thermal_data {
|
||||||
|
struct device *dev;
|
||||||
|
struct device *hwmon_dev;
|
||||||
|
uint8_t * __iomem temp_base;
|
||||||
|
int temp_input;
|
||||||
|
int temp_crit;
|
||||||
|
int temp_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
static long cn9130_thermal_read_reg_in_mcelcius(struct device *dev, struct cn9130_thermal_data *data)
|
||||||
|
{
|
||||||
|
volatile uint8_t * __iomem temp_base = data->temp_base;
|
||||||
|
uint32_t regval;
|
||||||
|
uint32_t status_regval=0;
|
||||||
|
uint32_t output=data->temp_max;
|
||||||
|
|
||||||
|
//STOP MEASUREMENT
|
||||||
|
regval = readl(temp_base+CN9130_TSEN_REG_CTRL_0_OFFSET);
|
||||||
|
regval &= ~( 1 << 0); //TSEN_STOP
|
||||||
|
writel(regval, temp_base+CN9130_TSEN_REG_CTRL_0_OFFSET);
|
||||||
|
|
||||||
|
//delay for 1ms
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
//Read thermal value
|
||||||
|
status_regval = readl(temp_base+CN9130_TSEN_REG_STATUS_OFFSET);
|
||||||
|
dev_dbg(dev, "%s: cn9130_thermal_read_reg_in_mcelcius: addr: 0x%lx value:0x%x\n", dev_name(data->hwmon_dev), temp_base+CN9130_TSEN_REG_STATUS_OFFSET, status_regval);
|
||||||
|
|
||||||
|
//START MEASUREMENT
|
||||||
|
regval = readl(temp_base+CN9130_TSEN_REG_CTRL_0_OFFSET);
|
||||||
|
regval |= 1 << 0; //TSEN_START
|
||||||
|
writel(regval, temp_base+CN9130_TSEN_REG_CTRL_0_OFFSET);
|
||||||
|
|
||||||
|
//Validate data
|
||||||
|
if(status_regval &= 0x3ff) {
|
||||||
|
//Convert it to milli-celcius
|
||||||
|
output = 150000 - (~(status_regval-1) & 0x3ff) * 423;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
static int cn9130_thermal_read(struct device *dev, enum hwmon_sensor_types type,
|
||||||
|
u32 attr, int channel, long *val)
|
||||||
|
{
|
||||||
|
struct cn9130_thermal_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case hwmon_temp:
|
||||||
|
switch (attr) {
|
||||||
|
case hwmon_temp_input:
|
||||||
|
*val = cn9130_thermal_read_reg_in_mcelcius(dev, data);
|
||||||
|
break;
|
||||||
|
case hwmon_temp_crit:
|
||||||
|
*val = data->temp_crit;
|
||||||
|
break;
|
||||||
|
case hwmon_temp_max:
|
||||||
|
*val = data->temp_max;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cn9130_thermal_write(struct device *dev, enum hwmon_sensor_types type,
|
||||||
|
u32 attr, int channel, long val)
|
||||||
|
{
|
||||||
|
struct cn9130_thermal_data *data = dev_get_drvdata(dev);
|
||||||
|
switch (type) {
|
||||||
|
case hwmon_temp:
|
||||||
|
switch (attr) {
|
||||||
|
case hwmon_temp_crit:
|
||||||
|
data->temp_crit = val;
|
||||||
|
break;
|
||||||
|
case hwmon_temp_max:
|
||||||
|
data->temp_max = val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static umode_t cn9130_thermal_is_visible(const void *data, enum hwmon_sensor_types type,
|
||||||
|
u32 attr, int channel)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case hwmon_temp:
|
||||||
|
switch (attr) {
|
||||||
|
case hwmon_temp_input:
|
||||||
|
return 0444;
|
||||||
|
case hwmon_temp_crit:
|
||||||
|
case hwmon_temp_max:
|
||||||
|
return 0644;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct hwmon_channel_info *cn9130_thermal_info[] = {
|
||||||
|
HWMON_CHANNEL_INFO(temp,
|
||||||
|
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT),
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct hwmon_ops cn9130_thermal_hwmon_ops = {
|
||||||
|
.is_visible = cn9130_thermal_is_visible,
|
||||||
|
.read = cn9130_thermal_read,
|
||||||
|
.write = cn9130_thermal_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct hwmon_chip_info cn9130_thermal_chip_info = {
|
||||||
|
.ops = &cn9130_thermal_hwmon_ops,
|
||||||
|
.info = cn9130_thermal_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct file_operations fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct miscdevice cn9130_thermal_device = {
|
||||||
|
.minor = TEMP_MINOR,
|
||||||
|
.name = "cn9130_thermal",
|
||||||
|
.fops = &fops,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init cn9130_thermal_init_driver(void)
|
||||||
|
{
|
||||||
|
struct device *dev;
|
||||||
|
struct cn9130_thermal_data *thermal_data;
|
||||||
|
int err;
|
||||||
|
void * __iomem reg;
|
||||||
|
uint32_t regval=0;
|
||||||
|
|
||||||
|
err = misc_register(&cn9130_thermal_device);
|
||||||
|
if (err) {
|
||||||
|
pr_err("cn9130_thermal misc_register failed!!!\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = cn9130_thermal_device.this_device;
|
||||||
|
thermal_data = devm_kzalloc(dev, sizeof(struct cn9130_thermal_data), GFP_KERNEL);
|
||||||
|
if (!thermal_data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
thermal_data->dev = dev;
|
||||||
|
thermal_data->temp_crit = CN9130_DEFAULT_TEMP_CRIT;
|
||||||
|
thermal_data->temp_max = CN9130_DEFAULT_TEMP_MAX;
|
||||||
|
|
||||||
|
thermal_data->hwmon_dev = devm_hwmon_device_register_with_info(dev, cn9130_thermal_device.name,
|
||||||
|
thermal_data, &cn9130_thermal_chip_info,
|
||||||
|
NULL);
|
||||||
|
if (IS_ERR(thermal_data->hwmon_dev)) {
|
||||||
|
dev_err(dev, "%s: hwmon registration failed.\n", cn9130_thermal_device.name);
|
||||||
|
return PTR_ERR(thermal_data->hwmon_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
reg = devm_ioremap(dev, thermal_base_addr, 16);
|
||||||
|
if (IS_ERR(reg)) {
|
||||||
|
dev_err(dev, "%s: base addr remap failed\n", cn9130_thermal_device.name);
|
||||||
|
return PTR_ERR(reg);
|
||||||
|
}
|
||||||
|
thermal_data->temp_base = reg;
|
||||||
|
|
||||||
|
/*Enable measurement*/
|
||||||
|
regval = readl(thermal_data->temp_base+CN9130_TSEN_REG_CTRL_0_OFFSET);
|
||||||
|
regval |= 1 << 2; //TSEN_EN
|
||||||
|
writel(regval, thermal_data->temp_base+CN9130_TSEN_REG_CTRL_0_OFFSET);
|
||||||
|
mdelay(10);
|
||||||
|
|
||||||
|
// Set temperature reading zone as max reading
|
||||||
|
regval = readl(thermal_data->temp_base+CN9130_TSEN_REG_CTRL_1_OFFSET);
|
||||||
|
regval &= ~(0x7 << 21);
|
||||||
|
regval |= (CN9130_TSEN_SENSOR_MAX_ID & 0x7) << 21;
|
||||||
|
writel(regval, thermal_data->temp_base+CN9130_TSEN_REG_CTRL_1_OFFSET);
|
||||||
|
|
||||||
|
//START MEASUREMENT
|
||||||
|
regval = readl(thermal_data->temp_base+CN9130_TSEN_REG_CTRL_0_OFFSET);
|
||||||
|
regval |= 1 << 0; //TSEN_START
|
||||||
|
writel(regval, thermal_data->temp_base+CN9130_TSEN_REG_CTRL_0_OFFSET);
|
||||||
|
|
||||||
|
dev_info(dev, "%s: initialized. base_addr: 0x%lx virt_addr:0x%lx\n", dev_name(thermal_data->hwmon_dev), thermal_base_addr, thermal_data->temp_base);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit cn9101_thermal_exit_driver(void)
|
||||||
|
{
|
||||||
|
misc_deregister(&cn9130_thermal_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(cn9130_thermal_init_driver);
|
||||||
|
module_exit(cn9101_thermal_exit_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Natarajan Subbiramani <natarajan.subbiramani.ext@nokia.com>");
|
||||||
|
MODULE_DESCRIPTION("CN9130 CPU Thermal sensor Driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
46
platform/marvell-arm64/sonic-platform-nokia/7215/scripts/cpu_wdt.py
Executable file
46
platform/marvell-arm64/sonic-platform-nokia/7215/scripts/cpu_wdt.py
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from sonic_platform.chassis import Chassis
|
||||||
|
from sonic_py_common import logger
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
TIMEOUT=180
|
||||||
|
KEEPALIVE=60
|
||||||
|
sonic_logger = logger.Logger('Watchdog')
|
||||||
|
sonic_logger.set_min_log_priority_info()
|
||||||
|
time.sleep(60)
|
||||||
|
chassis = Chassis()
|
||||||
|
watchdog = chassis.get_watchdog()
|
||||||
|
|
||||||
|
def stopWdtService(signal, frame):
|
||||||
|
watchdog._disablewatchdog()
|
||||||
|
sonic_logger.log_notice("CPUWDT Disabled: watchdog armed=%s" % watchdog.is_armed() )
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
||||||
|
signal.signal(signal.SIGINT, stopWdtService)
|
||||||
|
signal.signal(signal.SIGTERM, stopWdtService)
|
||||||
|
|
||||||
|
watchdog.arm(TIMEOUT)
|
||||||
|
sonic_logger.log_notice("CPUWDT Enabled: watchdog armed=%s" % watchdog.is_armed() )
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
time.sleep(KEEPALIVE)
|
||||||
|
watchdog._keepalive()
|
||||||
|
sonic_logger.log_info("CPUWDT keepalive")
|
||||||
|
done
|
||||||
|
|
||||||
|
stopWdtService
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -0,0 +1,8 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=CPU WDT
|
||||||
|
After=nokia-7215init.service
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/local/bin/cpu_wdt.py
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -35,7 +35,7 @@ MAX_7215_COMPONENT=2
|
|||||||
MAX_7215_FAN_DRAWERS = 2
|
MAX_7215_FAN_DRAWERS = 2
|
||||||
MAX_7215_FANS_PER_DRAWER = 1
|
MAX_7215_FANS_PER_DRAWER = 1
|
||||||
MAX_7215_PSU = 2
|
MAX_7215_PSU = 2
|
||||||
MAX_7215_THERMAL = 4
|
MAX_7215_THERMAL = 5
|
||||||
CPLD_DIR = "/sys/bus/i2c/devices/0-0041/"
|
CPLD_DIR = "/sys/bus/i2c/devices/0-0041/"
|
||||||
|
|
||||||
SYSLOG_IDENTIFIER = "chassis"
|
SYSLOG_IDENTIFIER = "chassis"
|
||||||
@ -92,7 +92,7 @@ class Chassis(ChassisBase):
|
|||||||
drawer = drawer_ctor(drawer_index)
|
drawer = drawer_ctor(drawer_index)
|
||||||
self._fan_drawer_list.append(drawer)
|
self._fan_drawer_list.append(drawer)
|
||||||
for index in range(fan_num_per_drawer):
|
for index in range(fan_num_per_drawer):
|
||||||
fan = Fan(fan_index, drawer)
|
fan = Fan(fan_index, drawer, self.get_model())
|
||||||
fan_index += 1
|
fan_index += 1
|
||||||
drawer._fan_list.append(fan)
|
drawer._fan_list.append(fan)
|
||||||
self._fan_list.append(fan)
|
self._fan_list.append(fan)
|
||||||
@ -259,10 +259,21 @@ class Chassis(ChassisBase):
|
|||||||
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
|
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
|
||||||
to pass a description of the reboot cause.
|
to pass a description of the reboot cause.
|
||||||
"""
|
"""
|
||||||
# The ixs7215 CPLD does not have a hardware reboot cause register so
|
value = self._read_sysfs_file(CPLD_DIR+"last_reset_cause")
|
||||||
# the hardware portion of reboot cause can't be implemented
|
thermal = self._read_sysfs_file(CPLD_DIR+"temp_event_status")
|
||||||
|
if (value == 'cold_reset'):
|
||||||
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
|
reboot_cause=(ChassisBase.REBOOT_CAUSE_POWER_LOSS, "Cold Reset")
|
||||||
|
elif (value == 'warm_reset'):
|
||||||
|
reboot_cause=(ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Warm Reset")
|
||||||
|
elif (value == 'wdog_reset'):
|
||||||
|
reboot_cause=(ChassisBase.REBOOT_CAUSE_WATCHDOG, None)
|
||||||
|
elif (value == 'thermal_reset'):
|
||||||
|
reboot_cause=(ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER, thermal)
|
||||||
|
else:
|
||||||
|
reboot_cause=(ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
|
||||||
|
#unmask temperature event
|
||||||
|
self._write_sysfs_file(CPLD_DIR+"temp_event_mask", 0)
|
||||||
|
return reboot_cause
|
||||||
|
|
||||||
def get_watchdog(self):
|
def get_watchdog(self):
|
||||||
"""
|
"""
|
||||||
|
@ -175,7 +175,7 @@ class Component(ComponentBase):
|
|||||||
return self._get_cpld_version(self.index)
|
return self._get_cpld_version(self.index)
|
||||||
|
|
||||||
if self.index == 1:
|
if self.index == 1:
|
||||||
cmdstatus, uboot_version = cmd.getstatusoutput('grep --null-data ^U-Boot /dev/mtd0ro | cut -d" " -f2')
|
cmdstatus, uboot_version = cmd.getstatusoutput('grep --null-data ^U-Boot /dev/mtd0ro | cut -d" " -f4')
|
||||||
return uboot_version
|
return uboot_version
|
||||||
|
|
||||||
def install_firmware(self, image_path):
|
def install_firmware(self, image_path):
|
||||||
|
@ -41,8 +41,7 @@ class Eeprom(TlvInfoDecoder):
|
|||||||
self.index = psu_index
|
self.index = psu_index
|
||||||
self.part_number = '1'
|
self.part_number = '1'
|
||||||
self.model_str = 'PJT-12V100WBBA'
|
self.model_str = 'PJT-12V100WBBA'
|
||||||
self.serial_number = 'NA'
|
self.serial_number = 'NA'
|
||||||
self.serial_number = 'NA'
|
|
||||||
|
|
||||||
if self.is_fan_eeprom:
|
if self.is_fan_eeprom:
|
||||||
self.index = fan_index
|
self.index = fan_index
|
||||||
|
@ -16,8 +16,8 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
MAX_IXS7215_FAN_SPEED = 24000
|
MAX_IXS7215_FAN_SPEED = 23000
|
||||||
WORKING_IXS7215_FAN_SPEED = 2400
|
WORKING_IXS7215_FAN_SPEED = 2300
|
||||||
|
|
||||||
|
|
||||||
sonic_logger = logger.Logger('fan')
|
sonic_logger = logger.Logger('fan')
|
||||||
@ -26,10 +26,10 @@ sonic_logger = logger.Logger('fan')
|
|||||||
class Fan(FanBase):
|
class Fan(FanBase):
|
||||||
"""Nokia platform-specific Fan class"""
|
"""Nokia platform-specific Fan class"""
|
||||||
|
|
||||||
def __init__(self, fan_index, fan_drawer, psu_fan=False, dependency=None):
|
def __init__(self, fan_index, fan_drawer, chassis_model, psu_fan=False, dependency=None):
|
||||||
self.is_psu_fan = psu_fan
|
self.is_psu_fan = psu_fan
|
||||||
EMC2302_DIR = " "
|
EMC2302_DIR = " "
|
||||||
i2c_path = "/sys/bus/i2c/devices/0-002e/hwmon/"
|
i2c_path = "/sys/bus/i2c/devices/0-002f/hwmon/"
|
||||||
if(os.path.exists(i2c_path)):
|
if(os.path.exists(i2c_path)):
|
||||||
hwmon_node = os.listdir(i2c_path)[0]
|
hwmon_node = os.listdir(i2c_path)[0]
|
||||||
EMC2302_DIR = i2c_path + hwmon_node + '/'
|
EMC2302_DIR = i2c_path + hwmon_node + '/'
|
||||||
@ -38,6 +38,7 @@ class Fan(FanBase):
|
|||||||
# Fan is 1-based in Nokia platforms
|
# Fan is 1-based in Nokia platforms
|
||||||
self.index = fan_index + 1
|
self.index = fan_index + 1
|
||||||
self.fan_drawer = fan_drawer
|
self.fan_drawer = fan_drawer
|
||||||
|
self.chassis_model = chassis_model
|
||||||
self.set_fan_speed_reg = EMC2302_DIR+"pwm{}".format(self.index)
|
self.set_fan_speed_reg = EMC2302_DIR+"pwm{}".format(self.index)
|
||||||
self.get_fan_speed_reg = EMC2302_DIR+"fan{}_input".format(self.index)
|
self.get_fan_speed_reg = EMC2302_DIR+"fan{}_input".format(self.index)
|
||||||
self.max_fan_speed = MAX_IXS7215_FAN_SPEED
|
self.max_fan_speed = MAX_IXS7215_FAN_SPEED
|
||||||
@ -116,7 +117,16 @@ class Fan(FanBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: Model number of Fan. Use part number for this.
|
string: Model number of Fan. Use part number for this.
|
||||||
"""
|
"""
|
||||||
return self.eeprom.part_number_str()
|
return self.eeprom.modelstr()
|
||||||
|
|
||||||
|
def get_chassis_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number of the Fan
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
string: Model number of Fan. Use part number for this.
|
||||||
|
"""
|
||||||
|
return self.chassis_model
|
||||||
|
|
||||||
def get_serial(self):
|
def get_serial(self):
|
||||||
"""
|
"""
|
||||||
@ -169,8 +179,14 @@ class Fan(FanBase):
|
|||||||
A string, either FAN_DIRECTION_INTAKE or
|
A string, either FAN_DIRECTION_INTAKE or
|
||||||
FAN_DIRECTION_EXHAUST depending on fan direction
|
FAN_DIRECTION_EXHAUST depending on fan direction
|
||||||
"""
|
"""
|
||||||
|
ch_model=self.get_chassis_model()
|
||||||
|
#compare first 8 characters of chassis molel string
|
||||||
|
if(ch_model[:8]=='3HE18723'):
|
||||||
|
direction = 'intake'
|
||||||
|
else:
|
||||||
|
direction = 'exhaust'
|
||||||
|
|
||||||
return 'intake'
|
return direction
|
||||||
|
|
||||||
def get_position_in_parent(self):
|
def get_position_in_parent(self):
|
||||||
"""
|
"""
|
||||||
@ -219,8 +235,10 @@ class Fan(FanBase):
|
|||||||
which is considered tolerable
|
which is considered tolerable
|
||||||
"""
|
"""
|
||||||
if self.get_presence():
|
if self.get_presence():
|
||||||
# The tolerance value is fixed as 25% for this platform
|
if self.get_target_speed()<50:
|
||||||
tolerance = 50
|
tolerance=60
|
||||||
|
else:
|
||||||
|
tolerance = 25
|
||||||
else:
|
else:
|
||||||
tolerance = 0
|
tolerance = 0
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@ except ImportError as e:
|
|||||||
sonic_logger = logger.Logger('psu')
|
sonic_logger = logger.Logger('psu')
|
||||||
INA230_DIR = "/sys/bus/i2c/devices/0-0040/iio:device0/"
|
INA230_DIR = "/sys/bus/i2c/devices/0-0040/iio:device0/"
|
||||||
CPLD_DIR = "/sys/bus/i2c/devices/0-0041/"
|
CPLD_DIR = "/sys/bus/i2c/devices/0-0041/"
|
||||||
|
PSU_GPIO_DIR = ["/sys/class/gpio/gpio61/value", "/sys/class/gpio/gpio62/value"]
|
||||||
|
|
||||||
|
|
||||||
class Psu(PsuBase):
|
class Psu(PsuBase):
|
||||||
"""Nokia platform-specific PSU class for 7215 """
|
"""Nokia platform-specific PSU class for 7215 """
|
||||||
@ -32,6 +34,8 @@ class Psu(PsuBase):
|
|||||||
|
|
||||||
# PSU eeprom
|
# PSU eeprom
|
||||||
self.eeprom = Eeprom(is_psu=True, psu_index=self.index)
|
self.eeprom = Eeprom(is_psu=True, psu_index=self.index)
|
||||||
|
self.MAX_VOLTAGE = 14
|
||||||
|
self.MIN_VOLTAGE = 10
|
||||||
|
|
||||||
def _read_sysfs_file(self, sysfs_file):
|
def _read_sysfs_file(self, sysfs_file):
|
||||||
# On successful read, returns the value read from given
|
# On successful read, returns the value read from given
|
||||||
@ -80,8 +84,8 @@ class Psu(PsuBase):
|
|||||||
Integer: Number of active PSU's
|
Integer: Number of active PSU's
|
||||||
"""
|
"""
|
||||||
active_psus = 0
|
active_psus = 0
|
||||||
psu1_good = self._read_sysfs_file(CPLD_DIR+"psu1_power_good")
|
psu1_good = self._read_sysfs_file(PSU_GPIO_DIR[0])
|
||||||
psu2_good = self._read_sysfs_file(CPLD_DIR+"psu2_power_good")
|
psu2_good = self._read_sysfs_file(PSU_GPIO_DIR[1])
|
||||||
|
|
||||||
active_psus = int(psu1_good) + int(psu2_good)
|
active_psus = int(psu1_good) + int(psu2_good)
|
||||||
|
|
||||||
@ -150,7 +154,7 @@ class Psu(PsuBase):
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if PSU is operating properly, False if not
|
bool: True if PSU is operating properly, False if not
|
||||||
"""
|
"""
|
||||||
psu_sysfs_str=CPLD_DIR+"psu{}_power_good".format(self.index)
|
psu_sysfs_str=PSU_GPIO_DIR[self.index-1]
|
||||||
psu_status = self._read_sysfs_file(psu_sysfs_str)
|
psu_status = self._read_sysfs_file(psu_sysfs_str)
|
||||||
|
|
||||||
if psu_status == '1':
|
if psu_status == '1':
|
||||||
@ -212,6 +216,26 @@ class Psu(PsuBase):
|
|||||||
"""
|
"""
|
||||||
return self.index
|
return self.index
|
||||||
|
|
||||||
|
def get_voltage_high_threshold(self):
|
||||||
|
"""
|
||||||
|
Retrieves the high threshold PSU voltage output
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A float number, the high threshold output voltage in volts,
|
||||||
|
e.g. 12.1
|
||||||
|
"""
|
||||||
|
return self.MAX_VOLTAGE
|
||||||
|
|
||||||
|
def get_voltage_low_threshold(self):
|
||||||
|
"""
|
||||||
|
Retrieves the low threshold PSU voltage output
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A float number, the low threshold output voltage in volts,
|
||||||
|
e.g. 12.1
|
||||||
|
"""
|
||||||
|
return self.MIN_VOLTAGE
|
||||||
|
|
||||||
def is_replaceable(self):
|
def is_replaceable(self):
|
||||||
"""
|
"""
|
||||||
Indicate whether this device is replaceable.
|
Indicate whether this device is replaceable.
|
||||||
@ -227,7 +251,7 @@ class Psu(PsuBase):
|
|||||||
A boolean, True if PSU has stablized its output voltages and
|
A boolean, True if PSU has stablized its output voltages and
|
||||||
passed all its internal self-tests, False if not.
|
passed all its internal self-tests, False if not.
|
||||||
"""
|
"""
|
||||||
psu_sysfs_str=CPLD_DIR+"psu{}_power_good".format(self.index)
|
psu_sysfs_str=PSU_GPIO_DIR[self.index-1]
|
||||||
psu_pg_status = self._read_sysfs_file(psu_sysfs_str)
|
psu_pg_status = self._read_sysfs_file(psu_sysfs_str)
|
||||||
|
|
||||||
if psu_pg_status == '1':
|
if psu_pg_status == '1':
|
||||||
@ -294,4 +318,4 @@ class Psu(PsuBase):
|
|||||||
if status == "ERR":
|
if status == "ERR":
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -30,7 +30,7 @@ logger = Logger()
|
|||||||
|
|
||||||
class Sfp(SfpOptoeBase):
|
class Sfp(SfpOptoeBase):
|
||||||
"""
|
"""
|
||||||
Nokia IXR-7215 Platform-specific Sfp refactor class
|
Nokia IXS-7215 Platform-specific Sfp refactor class
|
||||||
"""
|
"""
|
||||||
instances = []
|
instances = []
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
try:
|
try:
|
||||||
import os
|
import os
|
||||||
from sonic_platform_base.thermal_base import ThermalBase
|
from sonic_platform_base.thermal_base import ThermalBase
|
||||||
|
from swsscommon.swsscommon import SonicV2Connector
|
||||||
from sonic_py_common import logger
|
from sonic_py_common import logger
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
@ -21,12 +22,13 @@ class Thermal(ThermalBase):
|
|||||||
|
|
||||||
I2C_CLASS_DIR = "/sys/class/i2c-adapter/"
|
I2C_CLASS_DIR = "/sys/class/i2c-adapter/"
|
||||||
I2C_DEV_MAPPING = (['i2c-0/0-0048/hwmon/', 1],
|
I2C_DEV_MAPPING = (['i2c-0/0-0048/hwmon/', 1],
|
||||||
['i2c-0/0-0049/hwmon/', 1])
|
['i2c-0/0-0049/hwmon/', 1],
|
||||||
|
['i2c-0/0-004a/hwmon/', 1])
|
||||||
|
|
||||||
HWMON_CLASS_DIR = "/sys/class/hwmon/hwmon0/"
|
CN9130_THERMAL_DIR = "/sys/class/hwmon/hwmon1/"
|
||||||
AC5X_THERMAL_DIR = "/sys/class/hwmon/hwmon1/"
|
ASIC_TEMP_INFO = "ASIC_TEMPERATURE_INFO"
|
||||||
|
|
||||||
THERMAL_NAME = ("PCB BACK", "PCB FRONT", "AC5X CORE", "OOB PHY")
|
THERMAL_NAME = ("PCB BACK", "PCB FRONT", "PCB MID", "ASIC", "CPU CORE")
|
||||||
|
|
||||||
def __init__(self, thermal_index):
|
def __init__(self, thermal_index):
|
||||||
ThermalBase.__init__(self)
|
ThermalBase.__init__(self)
|
||||||
@ -37,7 +39,7 @@ class Thermal(ThermalBase):
|
|||||||
self._maximum = None
|
self._maximum = None
|
||||||
self.thermal_high_threshold_file = None
|
self.thermal_high_threshold_file = None
|
||||||
# PCB temperature sensors
|
# PCB temperature sensors
|
||||||
if self.index < 3:
|
if self.index < 4:
|
||||||
i2c_path = self.I2C_CLASS_DIR + self.I2C_DEV_MAPPING[self.index - 1][0]
|
i2c_path = self.I2C_CLASS_DIR + self.I2C_DEV_MAPPING[self.index - 1][0]
|
||||||
sensor_index = self.I2C_DEV_MAPPING[self.index - 1][1]
|
sensor_index = self.I2C_DEV_MAPPING[self.index - 1][1]
|
||||||
sensor_high_suffix = "max"
|
sensor_high_suffix = "max"
|
||||||
@ -45,24 +47,26 @@ class Thermal(ThermalBase):
|
|||||||
hwmon_node = os.listdir(i2c_path)[0]
|
hwmon_node = os.listdir(i2c_path)[0]
|
||||||
self.SENSOR_DIR = i2c_path + hwmon_node + '/'
|
self.SENSOR_DIR = i2c_path + hwmon_node + '/'
|
||||||
|
|
||||||
# SOC temperature sensor
|
#ASIC temperature sensor
|
||||||
elif self.index == 3:
|
elif self.index == 4:
|
||||||
dev_path = self.AC5X_THERMAL_DIR
|
|
||||||
sensor_index = 1
|
|
||||||
sensor_high_suffix = "max"
|
|
||||||
sensor_high_crit_suffix = None
|
|
||||||
self.SENSOR_DIR = dev_path
|
|
||||||
#
|
|
||||||
else:
|
|
||||||
dev_path = self.HWMON_CLASS_DIR
|
|
||||||
sensor_index = 1
|
|
||||||
sensor_high_suffix = None
|
sensor_high_suffix = None
|
||||||
sensor_high_crit_suffix = "crit"
|
sensor_high_crit_suffix = None
|
||||||
|
self.sensor_high_threshold = 100.0
|
||||||
|
self.sensor_crit_threshold = 110.0
|
||||||
|
self.SENSOR_DIR = None
|
||||||
|
|
||||||
|
# CPU CN9130 temperature sensor
|
||||||
|
elif self.index == 5:
|
||||||
|
dev_path = self.CN9130_THERMAL_DIR
|
||||||
|
sensor_index = 1
|
||||||
|
sensor_high_suffix = "crit"
|
||||||
|
sensor_high_crit_suffix = "max"
|
||||||
self.SENSOR_DIR = dev_path
|
self.SENSOR_DIR = dev_path
|
||||||
|
|
||||||
# sysfs file for current temperature value
|
# sysfs file for current temperature value
|
||||||
self.thermal_temperature_file = self.SENSOR_DIR \
|
if self.SENSOR_DIR:
|
||||||
+ "temp{}_input".format(sensor_index)
|
self.thermal_temperature_file = self.SENSOR_DIR \
|
||||||
|
+ "temp{}_input".format(sensor_index)
|
||||||
|
|
||||||
# sysfs file for high threshold value if supported for this sensor
|
# sysfs file for high threshold value if supported for this sensor
|
||||||
if sensor_high_suffix:
|
if sensor_high_suffix:
|
||||||
@ -156,16 +160,23 @@ class Thermal(ThermalBase):
|
|||||||
A float number of current temperature in Celsius up to
|
A float number of current temperature in Celsius up to
|
||||||
nearest thousandth of one degree Celsius, e.g. 30.125
|
nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
"""
|
"""
|
||||||
thermal_temperature = self._read_sysfs_file(
|
#read from state_db for asic temperature
|
||||||
self.thermal_temperature_file)
|
if self.index == 4:
|
||||||
if (thermal_temperature != 'ERR'):
|
db = SonicV2Connector()
|
||||||
thermal_temperature = float(thermal_temperature) / 1000
|
db.connect(db.STATE_DB)
|
||||||
if self._minimum is None or self._minimum > thermal_temperature:
|
data_dict = db.get_all(db.STATE_DB, self.ASIC_TEMP_INFO)
|
||||||
self._minimum = thermal_temperature
|
thermal_temperature = float(data_dict['maximum_temperature'])
|
||||||
if self._maximum is None or self._maximum < thermal_temperature:
|
|
||||||
self._maximum = thermal_temperature
|
|
||||||
else:
|
else:
|
||||||
thermal_temperature = 0
|
thermal_temperature = self._read_sysfs_file(self.thermal_temperature_file)
|
||||||
|
if (thermal_temperature != 'ERR'):
|
||||||
|
thermal_temperature = float(thermal_temperature) / 1000
|
||||||
|
else:
|
||||||
|
thermal_temperature = 0
|
||||||
|
|
||||||
|
if self._minimum is None or self._minimum > thermal_temperature:
|
||||||
|
self._minimum = thermal_temperature
|
||||||
|
if self._maximum is None or self._maximum < thermal_temperature:
|
||||||
|
self._maximum = thermal_temperature
|
||||||
|
|
||||||
return float("{:.3f}".format(thermal_temperature))
|
return float("{:.3f}".format(thermal_temperature))
|
||||||
|
|
||||||
@ -178,12 +189,13 @@ class Thermal(ThermalBase):
|
|||||||
Celsius up to nearest thousandth of one degree Celsius,
|
Celsius up to nearest thousandth of one degree Celsius,
|
||||||
e.g. 30.125
|
e.g. 30.125
|
||||||
"""
|
"""
|
||||||
|
if self.index == 4:
|
||||||
|
return float("{:.3f}".format(self.sensor_high_threshold))
|
||||||
# Not implemented for this sensor
|
# Not implemented for this sensor
|
||||||
if not self.thermal_high_threshold_file:
|
if not self.thermal_high_threshold_file:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
thermal_high_threshold = self._read_sysfs_file(
|
thermal_high_threshold = self._read_sysfs_file(self.thermal_high_threshold_file)
|
||||||
self.thermal_high_threshold_file)
|
|
||||||
if (thermal_high_threshold != 'ERR'):
|
if (thermal_high_threshold != 'ERR'):
|
||||||
thermal_high_threshold = float(thermal_high_threshold) / 1000
|
thermal_high_threshold = float(thermal_high_threshold) / 1000
|
||||||
else:
|
else:
|
||||||
@ -213,7 +225,8 @@ class Thermal(ThermalBase):
|
|||||||
A float number, the high critical threshold temperature of thermal in Celsius
|
A float number, the high critical threshold temperature of thermal in Celsius
|
||||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
"""
|
"""
|
||||||
|
if self.index == 4:
|
||||||
|
return float("{:.3f}".format(self.sensor_crit_threshold))
|
||||||
# Not implemented for this sensor
|
# Not implemented for this sensor
|
||||||
if not self.thermal_high_crit_threshold_file:
|
if not self.thermal_high_crit_threshold_file:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -73,14 +73,22 @@ class ThermalInfo(ThermalPolicyInfoBase):
|
|||||||
self._current_threshold_level = 0
|
self._current_threshold_level = 0
|
||||||
self._num_fan_levels = 3
|
self._num_fan_levels = 3
|
||||||
self._high_crital_threshold = 75
|
self._high_crital_threshold = 75
|
||||||
self._level_up_threshold = [[31,39,58,46],
|
#THERMAL_NAME ("PCB BACK", "PCB FRONT", "PCB MID", "ASIC", "CPU CORE")
|
||||||
[39,46,65,54],
|
self._f2b_level_up_threshold = [[38,30,37,60,77],
|
||||||
[51,57,77,68]]
|
[51,44,50,72,90],
|
||||||
|
[61,57,61,77,94]]
|
||||||
|
|
||||||
self._level_down_threshold = [[24,31,47,40],
|
self._f2b_level_down_threshold = [[29,24,29,50,64],
|
||||||
[31,38,53,46],
|
[40,37,40,59,75],
|
||||||
[48,54,72,63]]
|
[58,54,58,72,90]]
|
||||||
|
|
||||||
|
self._b2f_level_up_threshold = [[30,38,41,65,71],
|
||||||
|
[43,50,54,76,86],
|
||||||
|
[53,59,61,79,92]]
|
||||||
|
|
||||||
|
self._b2f_level_down_threshold = [[22,30,33,54,60],
|
||||||
|
[37,44,46,62,73],
|
||||||
|
[51,57,58,75,90]]
|
||||||
def collect(self, chassis):
|
def collect(self, chassis):
|
||||||
"""
|
"""
|
||||||
Collect thermal sensor temperature change status
|
Collect thermal sensor temperature change status
|
||||||
@ -99,6 +107,13 @@ class ThermalInfo(ThermalPolicyInfoBase):
|
|||||||
for index in range(num_of_thermals):
|
for index in range(num_of_thermals):
|
||||||
self._temps.insert(index, chassis.get_thermal(index).get_temperature())
|
self._temps.insert(index, chassis.get_thermal(index).get_temperature())
|
||||||
|
|
||||||
|
fan_direction=chassis.get_fan(1).get_direction()
|
||||||
|
if(fan_direction == "intake"):
|
||||||
|
level_up_threshold=self._f2b_level_up_threshold
|
||||||
|
level_down_threshold=self._f2b_level_down_threshold
|
||||||
|
else:
|
||||||
|
level_up_threshold=self._b2f_level_up_threshold
|
||||||
|
level_down_threshold=self._b2f_level_down_threshold
|
||||||
|
|
||||||
# Find current required threshold level
|
# Find current required threshold level
|
||||||
max_level =0
|
max_level =0
|
||||||
@ -106,10 +121,10 @@ class ThermalInfo(ThermalPolicyInfoBase):
|
|||||||
for index in range(num_of_thermals):
|
for index in range(num_of_thermals):
|
||||||
for level in range(self._num_fan_levels):
|
for level in range(self._num_fan_levels):
|
||||||
|
|
||||||
if self._temps[index]>self._level_up_threshold[level][index]:
|
if self._temps[index]>level_up_threshold[level][index]:
|
||||||
if max_level<level+1:
|
if max_level<level+1:
|
||||||
max_level=level+1
|
max_level=level+1
|
||||||
if self._temps[index]<self._level_down_threshold[level][index]:
|
if self._temps[index]<level_down_threshold[level][index]:
|
||||||
if min_level[index]>level:
|
if min_level[index]>level:
|
||||||
min_level[index]=level
|
min_level[index]=level
|
||||||
|
|
||||||
|
@ -6,9 +6,8 @@ provides access to hardware watchdog
|
|||||||
import os
|
import os
|
||||||
import fcntl
|
import fcntl
|
||||||
import array
|
import array
|
||||||
|
import time
|
||||||
from sonic_platform_base.watchdog_base import WatchdogBase
|
from sonic_platform_base.watchdog_base import WatchdogBase
|
||||||
from sonic_py_common import logger
|
|
||||||
|
|
||||||
""" ioctl constants """
|
""" ioctl constants """
|
||||||
IO_WRITE = 0x40000000
|
IO_WRITE = 0x40000000
|
||||||
@ -34,13 +33,12 @@ WDIOS_DISABLECARD = 0x0001
|
|||||||
WDIOS_ENABLECARD = 0x0002
|
WDIOS_ENABLECARD = 0x0002
|
||||||
|
|
||||||
""" watchdog sysfs """
|
""" watchdog sysfs """
|
||||||
WD_SYSFS_PATH = "/sys/class/watchdog/"
|
WD_SYSFS_PATH = "/sys/class/watchdog/watchdog0/"
|
||||||
|
WD_GPIO_PATH = "/sys/class/gpio/gpio41/value"
|
||||||
|
CPLD_DIR = "/sys/bus/i2c/devices/0-0041/"
|
||||||
|
|
||||||
WD_COMMON_ERROR = -1
|
WD_COMMON_ERROR = -1
|
||||||
|
|
||||||
sonic_logger = logger.Logger()
|
|
||||||
|
|
||||||
|
|
||||||
class WatchdogImplBase(WatchdogBase):
|
class WatchdogImplBase(WatchdogBase):
|
||||||
"""
|
"""
|
||||||
Base class that implements common logic for interacting
|
Base class that implements common logic for interacting
|
||||||
@ -53,34 +51,53 @@ class WatchdogImplBase(WatchdogBase):
|
|||||||
@param wd_device_path Path to watchdog device
|
@param wd_device_path Path to watchdog device
|
||||||
"""
|
"""
|
||||||
super(WatchdogImplBase, self).__init__()
|
super(WatchdogImplBase, self).__init__()
|
||||||
|
|
||||||
|
self.watchdog=""
|
||||||
self.watchdog_path = wd_device_path
|
self.watchdog_path = wd_device_path
|
||||||
self.watchdog = os.open(self.watchdog_path, os.O_WRONLY)
|
self.watchdog_gpio_reg = WD_GPIO_PATH
|
||||||
|
self.wd_state_reg = WD_SYSFS_PATH+"state"
|
||||||
# Opening a watchdog descriptor starts
|
self.wd_timeout_reg = WD_SYSFS_PATH+"timeout"
|
||||||
# watchdog timer; by default it should be stopped
|
self.wd_timeleft_reg = WD_SYSFS_PATH+"timeleft"
|
||||||
self._disablewatchdog()
|
|
||||||
self.armed = False
|
|
||||||
self.timeout = self._gettimeout()
|
self.timeout = self._gettimeout()
|
||||||
|
|
||||||
def disarm(self):
|
def _read_sysfs_file(self, sysfs_file):
|
||||||
"""
|
# On successful read, returns the value read from given
|
||||||
Disarm the hardware watchdog
|
# reg_name and on failure returns 'ERR'
|
||||||
|
rv = 'ERR'
|
||||||
Returns:
|
|
||||||
A boolean, True if watchdog is disarmed successfully, False
|
|
||||||
if not
|
|
||||||
"""
|
|
||||||
sonic_logger.log_info(" Debug disarm watchdog ")
|
|
||||||
|
|
||||||
|
if (not os.path.isfile(sysfs_file)):
|
||||||
|
return rv
|
||||||
try:
|
try:
|
||||||
self._disablewatchdog()
|
with open(sysfs_file, 'r') as fd:
|
||||||
self.armed = False
|
rv = fd.read()
|
||||||
self.timeout = 0
|
except Exception as e:
|
||||||
except IOError:
|
rv = 'ERR'
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
rv = rv.rstrip('\r\n')
|
||||||
|
rv = rv.lstrip(" ")
|
||||||
|
return rv
|
||||||
|
|
||||||
|
def _write_sysfs_file(self, sysfs_file, value):
|
||||||
|
# On successful write, the value read will be written on
|
||||||
|
# reg_name and on failure returns 'ERR'
|
||||||
|
rv = 'ERR'
|
||||||
|
|
||||||
|
if (not os.path.isfile(sysfs_file)):
|
||||||
|
return rv
|
||||||
|
try:
|
||||||
|
with open(sysfs_file, 'w') as fd:
|
||||||
|
rv = fd.write(str(value))
|
||||||
|
except Exception as e:
|
||||||
|
rv = 'ERR'
|
||||||
|
|
||||||
|
# Ensure that the write operation has succeeded
|
||||||
|
if (int(self._read_sysfs_file(sysfs_file)) != value ):
|
||||||
|
time.sleep(3)
|
||||||
|
if (int(self._read_sysfs_file(sysfs_file)) != value ):
|
||||||
|
rv = 'ERR'
|
||||||
|
|
||||||
|
return rv
|
||||||
|
|
||||||
def _disablewatchdog(self):
|
def _disablewatchdog(self):
|
||||||
"""
|
"""
|
||||||
@ -89,6 +106,23 @@ class WatchdogImplBase(WatchdogBase):
|
|||||||
|
|
||||||
req = array.array('h', [WDIOS_DISABLECARD])
|
req = array.array('h', [WDIOS_DISABLECARD])
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
|
fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
|
||||||
|
self._write_sysfs_file(self.watchdog_gpio_reg, 1)
|
||||||
|
self._read_sysfs_file(CPLD_DIR+"last_reset_cause")
|
||||||
|
|
||||||
|
def _enablewatchdog(self):
|
||||||
|
"""
|
||||||
|
Turn on the watchdog timer
|
||||||
|
"""
|
||||||
|
|
||||||
|
req = array.array('h', [WDIOS_ENABLECARD])
|
||||||
|
fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
|
||||||
|
|
||||||
|
def _keepalive(self):
|
||||||
|
"""
|
||||||
|
Keep alive watchdog timer
|
||||||
|
"""
|
||||||
|
|
||||||
|
fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE)
|
||||||
|
|
||||||
def _settimeout(self, seconds):
|
def _settimeout(self, seconds):
|
||||||
"""
|
"""
|
||||||
@ -107,11 +141,10 @@ class WatchdogImplBase(WatchdogBase):
|
|||||||
Get watchdog timeout
|
Get watchdog timeout
|
||||||
@return watchdog timeout
|
@return watchdog timeout
|
||||||
"""
|
"""
|
||||||
|
timeout=0
|
||||||
|
timeout=self._read_sysfs_file(self.wd_timeout_reg)
|
||||||
|
|
||||||
req = array.array('I', [0])
|
return timeout
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True)
|
|
||||||
|
|
||||||
return int(req[0])
|
|
||||||
|
|
||||||
def _gettimeleft(self):
|
def _gettimeleft(self):
|
||||||
"""
|
"""
|
||||||
@ -128,47 +161,62 @@ class WatchdogImplBase(WatchdogBase):
|
|||||||
"""
|
"""
|
||||||
Implements arm WatchdogBase API
|
Implements arm WatchdogBase API
|
||||||
"""
|
"""
|
||||||
sonic_logger.log_info(" Debug arm watchdog4 ")
|
|
||||||
ret = WD_COMMON_ERROR
|
|
||||||
if seconds < 0:
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
ret = WD_COMMON_ERROR
|
||||||
|
if (seconds < 0 or seconds > 340 ):
|
||||||
|
return ret
|
||||||
|
# Stop the watchdog service to gain access of watchdog file pointer
|
||||||
|
if self.is_armed():
|
||||||
|
os.popen("systemctl stop cpu_wdt.service")
|
||||||
|
time.sleep(2)
|
||||||
|
if not self.watchdog:
|
||||||
|
self.watchdog = os.open(self.watchdog_path, os.O_WRONLY)
|
||||||
try:
|
try:
|
||||||
if self.timeout != seconds:
|
if self.timeout != seconds:
|
||||||
self.timeout = self._settimeout(seconds)
|
self.timeout = self._settimeout(seconds)
|
||||||
if self.armed:
|
if self.is_armed():
|
||||||
self._keepalive()
|
self._keepalive()
|
||||||
else:
|
else:
|
||||||
sonic_logger.log_info(" Debug arm watchdog5 ")
|
|
||||||
self._enablewatchdog()
|
self._enablewatchdog()
|
||||||
self.armed = True
|
|
||||||
ret = self.timeout
|
ret = self.timeout
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
if(ret == seconds):
|
||||||
|
self._write_sysfs_file(self.watchdog_gpio_reg, 0)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def _enablewatchdog(self):
|
def disarm(self):
|
||||||
"""
|
|
||||||
Turn on the watchdog timer
|
|
||||||
"""
|
"""
|
||||||
|
Implements disarm WatchdogBase API
|
||||||
|
|
||||||
req = array.array('h', [WDIOS_ENABLECARD])
|
Returns:
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
|
A boolean, True if watchdog is disarmed successfully, False
|
||||||
|
if not
|
||||||
def _keepalive(self):
|
|
||||||
"""
|
"""
|
||||||
Keep alive watchdog timer
|
|
||||||
"""
|
if self.is_armed():
|
||||||
|
os.popen("systemctl stop cpu_wdt.service")
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE)
|
time.sleep(2)
|
||||||
|
if not self.watchdog:
|
||||||
|
self.watchdog = os.open(self.watchdog_path, os.O_WRONLY)
|
||||||
|
try:
|
||||||
|
self._disablewatchdog()
|
||||||
|
self.timeout = 0
|
||||||
|
except IOError:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def is_armed(self):
|
def is_armed(self):
|
||||||
"""
|
"""
|
||||||
Implements is_armed WatchdogBase API
|
Implements is_armed WatchdogBase API
|
||||||
"""
|
"""
|
||||||
|
status = False
|
||||||
|
|
||||||
return self.armed
|
state = self._read_sysfs_file(self.wd_state_reg)
|
||||||
|
if (state != 'inactive'):
|
||||||
|
status = True
|
||||||
|
|
||||||
|
return status
|
||||||
|
|
||||||
def get_remaining_time(self):
|
def get_remaining_time(self):
|
||||||
"""
|
"""
|
||||||
@ -177,10 +225,7 @@ class WatchdogImplBase(WatchdogBase):
|
|||||||
|
|
||||||
timeleft = WD_COMMON_ERROR
|
timeleft = WD_COMMON_ERROR
|
||||||
|
|
||||||
if self.armed:
|
if self.is_armed():
|
||||||
try:
|
timeleft=self._read_sysfs_file(self.wd_timeleft_reg)
|
||||||
timeleft = self._gettimeleft()
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return timeleft
|
return int(timeleft)
|
||||||
|
@ -33,7 +33,7 @@ build:
|
|||||||
(for mod in $(MODULE_DIRS); do \
|
(for mod in $(MODULE_DIRS); do \
|
||||||
cd $(MOD_SRC_DIR)/../$(PRESTERA_MODULE_SRC)/; \
|
cd $(MOD_SRC_DIR)/../$(PRESTERA_MODULE_SRC)/; \
|
||||||
make clean; \
|
make clean; \
|
||||||
make modules -C $(KERNEL_SRC)/build M=`pwd` CONFIG_KM_MVMBUS=y CONFIG_KM_MVINT=y || exit 1; \
|
make modules -C $(KERNEL_SRC)/build M=`pwd` CONFIG_KM_MVPCI=y CONFIG_KM_MVINT=y || exit 1; \
|
||||||
mkdir $(MOD_SRC_DIR)/$${mod}/$(MRVL_MODULE_DIR); \
|
mkdir $(MOD_SRC_DIR)/$${mod}/$(MRVL_MODULE_DIR); \
|
||||||
cp *.ko $(MOD_SRC_DIR)/$${mod}/$(MRVL_MODULE_DIR)/; \
|
cp *.ko $(MOD_SRC_DIR)/$${mod}/$(MRVL_MODULE_DIR)/; \
|
||||||
cd $(MOD_SRC_DIR); \
|
cd $(MOD_SRC_DIR); \
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
7215/scripts/nokia-7215-init.sh usr/local/bin
|
7215/scripts/nokia-7215-init.sh usr/local/bin
|
||||||
|
7215/scripts/cpu_wdt.py usr/local/bin
|
||||||
7215/service/nokia-7215init.service etc/systemd/system
|
7215/service/nokia-7215init.service etc/systemd/system
|
||||||
|
7215/service/cpu_wdt.service etc/systemd/system
|
||||||
7215/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/arm64-nokia_ixs7215_52xb-r0
|
7215/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/arm64-nokia_ixs7215_52xb-r0
|
||||||
../mrvl-prestera/platform/arm64/ac5x/* /
|
../mrvl-prestera/platform/arm64/ac5x/* /
|
||||||
|
@ -26,6 +26,9 @@ case "$1" in
|
|||||||
systemctl enable nokia-7215init.service
|
systemctl enable nokia-7215init.service
|
||||||
systemctl start nokia-7215init.service
|
systemctl start nokia-7215init.service
|
||||||
|
|
||||||
|
systemctl enable cpu_wdt.service
|
||||||
|
systemctl start cpu_wdt.service
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
abort-upgrade|abort-remove|abort-deconfigure)
|
abort-upgrade|abort-remove|abort-deconfigure)
|
||||||
|
Loading…
Reference in New Issue
Block a user