[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"?>
|
||||
<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:typedefs>
|
||||
<ASKL1plt:typedef>
|
||||
|
@ -1 +1 @@
|
||||
b42f2a2be9da6c7752c0807f9dee48bf
|
||||
d36319f76733ae8593e31f3231599936
|
@ -1,5 +1,5 @@
|
||||
<?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:typedefs>
|
||||
<askppplt:typedef>
|
||||
@ -357,28 +357,28 @@
|
||||
<askppplt:enum>
|
||||
<askppplt:name>NATIVE</askppplt:name>
|
||||
<askppplt:description>NATIVE
|
||||
* the trunk members are filled
|
||||
* according to the order given by application.
|
||||
* Regular trunk may hold max of 8 members.
|
||||
* Cascade trunk may hold :
|
||||
* max of 64 members</askppplt:description>
|
||||
* the trunk members are filled
|
||||
* according to the order given by application.
|
||||
* Regular trunk may hold max of 8 members.
|
||||
* Cascade trunk may hold :
|
||||
* max of 64 members</askppplt:description>
|
||||
<askppplt:value>0</askppplt:value>
|
||||
</askppplt:enum>
|
||||
<askppplt:enum>
|
||||
<askppplt:name>FLEX</askppplt:name>
|
||||
<askppplt:description>FLEX
|
||||
* A mode to allows flexibility for
|
||||
* each Regular trunk to state it's max number of members (before starting to add members).
|
||||
* (this mode not effect 'cascade trunk' members)
|
||||
* 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>
|
||||
* A mode to allows flexibility for
|
||||
* each Regular trunk to state it's max number of members (before starting to add members).
|
||||
* (this mode not effect 'cascade trunk' members)
|
||||
* 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>
|
||||
<askppplt:value>2</askppplt:value>
|
||||
</askppplt:enum>
|
||||
</askppplt:typedef>
|
||||
<askppplt:typedef>
|
||||
<askppplt:name>number-physical-port-type</askppplt:name>
|
||||
<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:name>no-ports</askppplt:name>
|
||||
<askppplt:description>no-ports</askppplt:description>
|
||||
|
@ -1 +1 @@
|
||||
b43a871130f9e59ac21a74940574558f
|
||||
1ff8c65eb4b5dfff5d2c9be67401c723
|
@ -1,13 +1,13 @@
|
||||
<?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:typedefs>
|
||||
<SAIplt:typedef>
|
||||
<SAIplt:name>device-id-type</SAIplt:name>
|
||||
<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:max>1023</SAIplt:max>
|
||||
<SAIplt:max>1</SAIplt:max>
|
||||
</SAIplt:typedef>
|
||||
<SAIplt:typedef>
|
||||
<SAIplt:name>port-id-type</SAIplt:name>
|
||||
@ -22,7 +22,7 @@
|
||||
<SAIplt:description>Logging Feature Options</SAIplt:description>
|
||||
<SAIplt:enum>
|
||||
<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:enum>
|
||||
<SAIplt:enum>
|
||||
@ -32,7 +32,7 @@
|
||||
</SAIplt:enum>
|
||||
<SAIplt:enum>
|
||||
<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:enum>
|
||||
</SAIplt:typedef>
|
||||
@ -43,11 +43,93 @@
|
||||
<SAIplt:min>2</SAIplt:min>
|
||||
<SAIplt:max>30</SAIplt:max>
|
||||
</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: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:Features>
|
||||
<SAIplt:RoCE SAIplt:type="boolean">false</SAIplt:RoCE>
|
||||
</SAIplt:Features>
|
||||
<SAIplt:Ports>
|
||||
<SAIplt:port-list>
|
||||
<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:port-list>
|
||||
</SAIplt:Ports>
|
||||
<SAIplt:Scaling>
|
||||
<SAIplt:scalingAC5>
|
||||
<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_ipv6 SAIplt:type="uint32">0</SAIplt:max_route_ipv6>
|
||||
@ -320,9 +402,45 @@
|
||||
<SAIplt:max_tti SAIplt:type="uint32">1024</SAIplt:max_tti>
|
||||
<SAIplt:wred_size SAIplt:type="uint32">0</SAIplt:wred_size>
|
||||
<SAIplt:max_nat SAIplt:type="uint32">0</SAIplt:max_nat>
|
||||
</SAIplt:Scaling>
|
||||
</SAIplt:scalingAC5>
|
||||
<SAIplt:Logging>
|
||||
<SAIplt:log_dest SAIplt:type="logDest-type">SAI_LOG_SYSLOG</SAIplt:log_dest>
|
||||
</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>
|
||||
</data>
|
@ -1,2 +1 @@
|
||||
VAR_LOG_SIZE=4096
|
||||
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
|
||||
},
|
||||
{
|
||||
"name": "AC5X CORE",
|
||||
"name": "PCB MID",
|
||||
"controllable": false,
|
||||
"low-threshold": false,
|
||||
"low-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,
|
||||
"low-threshold": false,
|
||||
"high-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
|
||||
|
||||
function SafePwrCycle() {
|
||||
function SafeReboot() {
|
||||
sync ; sync
|
||||
sudo umount -fa > /dev/null 2&>1
|
||||
|
||||
# Write CPLD register to initiate cold reboot
|
||||
sudo echo 0 > /sys/bus/i2c/devices/i2c-0/0-0041/cold_reset
|
||||
# Turn off watchdog monitor gpio for correct reboot-cause
|
||||
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": [],
|
||||
"devices_to_ignore": [
|
||||
"asic",
|
||||
"psu.temperature",
|
||||
"fan",
|
||||
"psu"
|
||||
"psu.temperature"
|
||||
],
|
||||
"user_defined_checkers": [],
|
||||
"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_FANS_PER_DRAWER = 1
|
||||
MAX_7215_PSU = 2
|
||||
MAX_7215_THERMAL = 4
|
||||
MAX_7215_THERMAL = 5
|
||||
CPLD_DIR = "/sys/bus/i2c/devices/0-0041/"
|
||||
|
||||
SYSLOG_IDENTIFIER = "chassis"
|
||||
@ -92,7 +92,7 @@ class Chassis(ChassisBase):
|
||||
drawer = drawer_ctor(drawer_index)
|
||||
self._fan_drawer_list.append(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
|
||||
drawer._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
|
||||
to pass a description of the reboot cause.
|
||||
"""
|
||||
# The ixs7215 CPLD does not have a hardware reboot cause register so
|
||||
# the hardware portion of reboot cause can't be implemented
|
||||
|
||||
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
|
||||
value = self._read_sysfs_file(CPLD_DIR+"last_reset_cause")
|
||||
thermal = self._read_sysfs_file(CPLD_DIR+"temp_event_status")
|
||||
if (value == 'cold_reset'):
|
||||
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):
|
||||
"""
|
||||
|
@ -175,7 +175,7 @@ class Component(ComponentBase):
|
||||
return self._get_cpld_version(self.index)
|
||||
|
||||
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
|
||||
|
||||
def install_firmware(self, image_path):
|
||||
|
@ -42,7 +42,6 @@ class Eeprom(TlvInfoDecoder):
|
||||
self.part_number = '1'
|
||||
self.model_str = 'PJT-12V100WBBA'
|
||||
self.serial_number = 'NA'
|
||||
self.serial_number = 'NA'
|
||||
|
||||
if self.is_fan_eeprom:
|
||||
self.index = fan_index
|
||||
|
@ -16,8 +16,8 @@ try:
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
MAX_IXS7215_FAN_SPEED = 24000
|
||||
WORKING_IXS7215_FAN_SPEED = 2400
|
||||
MAX_IXS7215_FAN_SPEED = 23000
|
||||
WORKING_IXS7215_FAN_SPEED = 2300
|
||||
|
||||
|
||||
sonic_logger = logger.Logger('fan')
|
||||
@ -26,10 +26,10 @@ sonic_logger = logger.Logger('fan')
|
||||
class Fan(FanBase):
|
||||
"""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
|
||||
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)):
|
||||
hwmon_node = os.listdir(i2c_path)[0]
|
||||
EMC2302_DIR = i2c_path + hwmon_node + '/'
|
||||
@ -38,6 +38,7 @@ class Fan(FanBase):
|
||||
# Fan is 1-based in Nokia platforms
|
||||
self.index = fan_index + 1
|
||||
self.fan_drawer = fan_drawer
|
||||
self.chassis_model = chassis_model
|
||||
self.set_fan_speed_reg = EMC2302_DIR+"pwm{}".format(self.index)
|
||||
self.get_fan_speed_reg = EMC2302_DIR+"fan{}_input".format(self.index)
|
||||
self.max_fan_speed = MAX_IXS7215_FAN_SPEED
|
||||
@ -116,7 +117,16 @@ class Fan(FanBase):
|
||||
Returns:
|
||||
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):
|
||||
"""
|
||||
@ -169,8 +179,14 @@ class Fan(FanBase):
|
||||
A string, either FAN_DIRECTION_INTAKE or
|
||||
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):
|
||||
"""
|
||||
@ -219,8 +235,10 @@ class Fan(FanBase):
|
||||
which is considered tolerable
|
||||
"""
|
||||
if self.get_presence():
|
||||
# The tolerance value is fixed as 25% for this platform
|
||||
tolerance = 50
|
||||
if self.get_target_speed()<50:
|
||||
tolerance=60
|
||||
else:
|
||||
tolerance = 25
|
||||
else:
|
||||
tolerance = 0
|
||||
|
||||
|
@ -19,6 +19,8 @@ except ImportError as e:
|
||||
sonic_logger = logger.Logger('psu')
|
||||
INA230_DIR = "/sys/bus/i2c/devices/0-0040/iio:device0/"
|
||||
CPLD_DIR = "/sys/bus/i2c/devices/0-0041/"
|
||||
PSU_GPIO_DIR = ["/sys/class/gpio/gpio61/value", "/sys/class/gpio/gpio62/value"]
|
||||
|
||||
|
||||
class Psu(PsuBase):
|
||||
"""Nokia platform-specific PSU class for 7215 """
|
||||
@ -32,6 +34,8 @@ class Psu(PsuBase):
|
||||
|
||||
# PSU eeprom
|
||||
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):
|
||||
# On successful read, returns the value read from given
|
||||
@ -80,8 +84,8 @@ class Psu(PsuBase):
|
||||
Integer: Number of active PSU's
|
||||
"""
|
||||
active_psus = 0
|
||||
psu1_good = self._read_sysfs_file(CPLD_DIR+"psu1_power_good")
|
||||
psu2_good = self._read_sysfs_file(CPLD_DIR+"psu2_power_good")
|
||||
psu1_good = self._read_sysfs_file(PSU_GPIO_DIR[0])
|
||||
psu2_good = self._read_sysfs_file(PSU_GPIO_DIR[1])
|
||||
|
||||
active_psus = int(psu1_good) + int(psu2_good)
|
||||
|
||||
@ -150,7 +154,7 @@ class Psu(PsuBase):
|
||||
Returns:
|
||||
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)
|
||||
|
||||
if psu_status == '1':
|
||||
@ -212,6 +216,26 @@ class Psu(PsuBase):
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
Indicate whether this device is replaceable.
|
||||
@ -227,7 +251,7 @@ class Psu(PsuBase):
|
||||
A boolean, True if PSU has stablized its output voltages and
|
||||
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)
|
||||
|
||||
if psu_pg_status == '1':
|
||||
|
@ -30,7 +30,7 @@ logger = Logger()
|
||||
|
||||
class Sfp(SfpOptoeBase):
|
||||
"""
|
||||
Nokia IXR-7215 Platform-specific Sfp refactor class
|
||||
Nokia IXS-7215 Platform-specific Sfp refactor class
|
||||
"""
|
||||
instances = []
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
try:
|
||||
import os
|
||||
from sonic_platform_base.thermal_base import ThermalBase
|
||||
from swsscommon.swsscommon import SonicV2Connector
|
||||
from sonic_py_common import logger
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
@ -21,12 +22,13 @@ class Thermal(ThermalBase):
|
||||
|
||||
I2C_CLASS_DIR = "/sys/class/i2c-adapter/"
|
||||
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/"
|
||||
AC5X_THERMAL_DIR = "/sys/class/hwmon/hwmon1/"
|
||||
CN9130_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):
|
||||
ThermalBase.__init__(self)
|
||||
@ -37,7 +39,7 @@ class Thermal(ThermalBase):
|
||||
self._maximum = None
|
||||
self.thermal_high_threshold_file = None
|
||||
# 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]
|
||||
sensor_index = self.I2C_DEV_MAPPING[self.index - 1][1]
|
||||
sensor_high_suffix = "max"
|
||||
@ -45,24 +47,26 @@ class Thermal(ThermalBase):
|
||||
hwmon_node = os.listdir(i2c_path)[0]
|
||||
self.SENSOR_DIR = i2c_path + hwmon_node + '/'
|
||||
|
||||
# SOC temperature sensor
|
||||
elif self.index == 3:
|
||||
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
|
||||
#ASIC temperature sensor
|
||||
elif self.index == 4:
|
||||
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
|
||||
|
||||
# sysfs file for current temperature value
|
||||
self.thermal_temperature_file = self.SENSOR_DIR \
|
||||
+ "temp{}_input".format(sensor_index)
|
||||
if self.SENSOR_DIR:
|
||||
self.thermal_temperature_file = self.SENSOR_DIR \
|
||||
+ "temp{}_input".format(sensor_index)
|
||||
|
||||
# sysfs file for high threshold value if supported for this sensor
|
||||
if sensor_high_suffix:
|
||||
@ -156,16 +160,23 @@ class Thermal(ThermalBase):
|
||||
A float number of current temperature in Celsius up to
|
||||
nearest thousandth of one degree Celsius, e.g. 30.125
|
||||
"""
|
||||
thermal_temperature = self._read_sysfs_file(
|
||||
self.thermal_temperature_file)
|
||||
if (thermal_temperature != 'ERR'):
|
||||
thermal_temperature = float(thermal_temperature) / 1000
|
||||
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
|
||||
#read from state_db for asic temperature
|
||||
if self.index == 4:
|
||||
db = SonicV2Connector()
|
||||
db.connect(db.STATE_DB)
|
||||
data_dict = db.get_all(db.STATE_DB, self.ASIC_TEMP_INFO)
|
||||
thermal_temperature = float(data_dict['maximum_temperature'])
|
||||
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))
|
||||
|
||||
@ -178,12 +189,13 @@ class Thermal(ThermalBase):
|
||||
Celsius up to nearest thousandth of one degree Celsius,
|
||||
e.g. 30.125
|
||||
"""
|
||||
if self.index == 4:
|
||||
return float("{:.3f}".format(self.sensor_high_threshold))
|
||||
# Not implemented for this sensor
|
||||
if not self.thermal_high_threshold_file:
|
||||
raise NotImplementedError
|
||||
|
||||
thermal_high_threshold = self._read_sysfs_file(
|
||||
self.thermal_high_threshold_file)
|
||||
thermal_high_threshold = self._read_sysfs_file(self.thermal_high_threshold_file)
|
||||
if (thermal_high_threshold != 'ERR'):
|
||||
thermal_high_threshold = float(thermal_high_threshold) / 1000
|
||||
else:
|
||||
@ -213,7 +225,8 @@ class Thermal(ThermalBase):
|
||||
A float number, the high critical threshold temperature of thermal in Celsius
|
||||
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
|
||||
if not self.thermal_high_crit_threshold_file:
|
||||
raise NotImplementedError
|
||||
|
@ -73,14 +73,22 @@ class ThermalInfo(ThermalPolicyInfoBase):
|
||||
self._current_threshold_level = 0
|
||||
self._num_fan_levels = 3
|
||||
self._high_crital_threshold = 75
|
||||
self._level_up_threshold = [[31,39,58,46],
|
||||
[39,46,65,54],
|
||||
[51,57,77,68]]
|
||||
#THERMAL_NAME ("PCB BACK", "PCB FRONT", "PCB MID", "ASIC", "CPU CORE")
|
||||
self._f2b_level_up_threshold = [[38,30,37,60,77],
|
||||
[51,44,50,72,90],
|
||||
[61,57,61,77,94]]
|
||||
|
||||
self._level_down_threshold = [[24,31,47,40],
|
||||
[31,38,53,46],
|
||||
[48,54,72,63]]
|
||||
self._f2b_level_down_threshold = [[29,24,29,50,64],
|
||||
[40,37,40,59,75],
|
||||
[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):
|
||||
"""
|
||||
Collect thermal sensor temperature change status
|
||||
@ -99,6 +107,13 @@ class ThermalInfo(ThermalPolicyInfoBase):
|
||||
for index in range(num_of_thermals):
|
||||
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
|
||||
max_level =0
|
||||
@ -106,10 +121,10 @@ class ThermalInfo(ThermalPolicyInfoBase):
|
||||
for index in range(num_of_thermals):
|
||||
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:
|
||||
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:
|
||||
min_level[index]=level
|
||||
|
||||
|
@ -6,9 +6,8 @@ provides access to hardware watchdog
|
||||
import os
|
||||
import fcntl
|
||||
import array
|
||||
|
||||
import time
|
||||
from sonic_platform_base.watchdog_base import WatchdogBase
|
||||
from sonic_py_common import logger
|
||||
|
||||
""" ioctl constants """
|
||||
IO_WRITE = 0x40000000
|
||||
@ -34,13 +33,12 @@ WDIOS_DISABLECARD = 0x0001
|
||||
WDIOS_ENABLECARD = 0x0002
|
||||
|
||||
""" 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
|
||||
|
||||
sonic_logger = logger.Logger()
|
||||
|
||||
|
||||
class WatchdogImplBase(WatchdogBase):
|
||||
"""
|
||||
Base class that implements common logic for interacting
|
||||
@ -54,33 +52,52 @@ class WatchdogImplBase(WatchdogBase):
|
||||
"""
|
||||
super(WatchdogImplBase, self).__init__()
|
||||
|
||||
self.watchdog=""
|
||||
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"
|
||||
self.wd_timeout_reg = WD_SYSFS_PATH+"timeout"
|
||||
self.wd_timeleft_reg = WD_SYSFS_PATH+"timeleft"
|
||||
|
||||
# Opening a watchdog descriptor starts
|
||||
# watchdog timer; by default it should be stopped
|
||||
self._disablewatchdog()
|
||||
self.armed = False
|
||||
self.timeout = self._gettimeout()
|
||||
|
||||
def disarm(self):
|
||||
"""
|
||||
Disarm the hardware watchdog
|
||||
|
||||
Returns:
|
||||
A boolean, True if watchdog is disarmed successfully, False
|
||||
if not
|
||||
"""
|
||||
sonic_logger.log_info(" Debug disarm watchdog ")
|
||||
def _read_sysfs_file(self, sysfs_file):
|
||||
# On successful read, returns the value read from given
|
||||
# reg_name and on failure returns 'ERR'
|
||||
rv = 'ERR'
|
||||
|
||||
if (not os.path.isfile(sysfs_file)):
|
||||
return rv
|
||||
try:
|
||||
self._disablewatchdog()
|
||||
self.armed = False
|
||||
self.timeout = 0
|
||||
except IOError:
|
||||
return False
|
||||
with open(sysfs_file, 'r') as fd:
|
||||
rv = fd.read()
|
||||
except Exception as e:
|
||||
rv = 'ERR'
|
||||
|
||||
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):
|
||||
"""
|
||||
@ -89,6 +106,23 @@ class WatchdogImplBase(WatchdogBase):
|
||||
|
||||
req = array.array('h', [WDIOS_DISABLECARD])
|
||||
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):
|
||||
"""
|
||||
@ -107,11 +141,10 @@ class WatchdogImplBase(WatchdogBase):
|
||||
Get watchdog timeout
|
||||
@return watchdog timeout
|
||||
"""
|
||||
timeout=0
|
||||
timeout=self._read_sysfs_file(self.wd_timeout_reg)
|
||||
|
||||
req = array.array('I', [0])
|
||||
fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True)
|
||||
|
||||
return int(req[0])
|
||||
return timeout
|
||||
|
||||
def _gettimeleft(self):
|
||||
"""
|
||||
@ -128,47 +161,62 @@ class WatchdogImplBase(WatchdogBase):
|
||||
"""
|
||||
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:
|
||||
if self.timeout != seconds:
|
||||
self.timeout = self._settimeout(seconds)
|
||||
if self.armed:
|
||||
if self.is_armed():
|
||||
self._keepalive()
|
||||
else:
|
||||
sonic_logger.log_info(" Debug arm watchdog5 ")
|
||||
self._enablewatchdog()
|
||||
self.armed = True
|
||||
ret = self.timeout
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
if(ret == seconds):
|
||||
self._write_sysfs_file(self.watchdog_gpio_reg, 0)
|
||||
return ret
|
||||
|
||||
def _enablewatchdog(self):
|
||||
def disarm(self):
|
||||
"""
|
||||
Turn on the watchdog timer
|
||||
Implements disarm WatchdogBase API
|
||||
|
||||
Returns:
|
||||
A boolean, True if watchdog is disarmed successfully, False
|
||||
if not
|
||||
"""
|
||||
|
||||
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)
|
||||
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:
|
||||
self._disablewatchdog()
|
||||
self.timeout = 0
|
||||
except IOError:
|
||||
return False
|
||||
return True
|
||||
|
||||
def is_armed(self):
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
@ -177,10 +225,7 @@ class WatchdogImplBase(WatchdogBase):
|
||||
|
||||
timeleft = WD_COMMON_ERROR
|
||||
|
||||
if self.armed:
|
||||
try:
|
||||
timeleft = self._gettimeleft()
|
||||
except IOError:
|
||||
pass
|
||||
if self.is_armed():
|
||||
timeleft=self._read_sysfs_file(self.wd_timeleft_reg)
|
||||
|
||||
return timeleft
|
||||
return int(timeleft)
|
||||
|
@ -33,7 +33,7 @@ build:
|
||||
(for mod in $(MODULE_DIRS); do \
|
||||
cd $(MOD_SRC_DIR)/../$(PRESTERA_MODULE_SRC)/; \
|
||||
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); \
|
||||
cp *.ko $(MOD_SRC_DIR)/$${mod}/$(MRVL_MODULE_DIR)/; \
|
||||
cd $(MOD_SRC_DIR); \
|
||||
|
@ -1,4 +1,6 @@
|
||||
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/cpu_wdt.service etc/systemd/system
|
||||
7215/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/arm64-nokia_ixs7215_52xb-r0
|
||||
../mrvl-prestera/platform/arm64/ac5x/* /
|
||||
|
@ -26,6 +26,9 @@ case "$1" in
|
||||
systemctl enable nokia-7215init.service
|
||||
systemctl start nokia-7215init.service
|
||||
|
||||
systemctl enable cpu_wdt.service
|
||||
systemctl start cpu_wdt.service
|
||||
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
|
Loading…
Reference in New Issue
Block a user