This commit is contained in:
Roger Ho 2024-03-25 08:54:22 +08:00 committed by GitHub
commit bf5991289e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 2468 additions and 138 deletions

View File

@ -0,0 +1,167 @@
- bus: '00'
dev: '00'
fn: '0'
id: '1980'
name: 'Host bridge: Intel Corporation Atom Processor C3000 Series System Agent (rev
11)'
- bus: '00'
dev: '04'
fn: '0'
id: 19a1
name: 'Host bridge: Intel Corporation Atom Processor C3000 Series Error Registers
(rev 11)'
- bus: '00'
dev: '05'
fn: '0'
id: 19a2
name: 'Generic system peripheral [0807]: Intel Corporation Atom Processor C3000
Series Root Complex Event Collector (rev 11)'
- bus: '00'
dev: '06'
fn: '0'
id: 19a3
name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated QAT
Root Port (rev 11)'
- bus: '00'
dev: 09
fn: '0'
id: 19a4
name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root
Port #0 (rev 11)'
- bus: '00'
dev: 0b
fn: '0'
id: 19a6
name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root
Port #2 (rev 11)'
- bus: '00'
dev: 0e
fn: '0'
id: 19a8
name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root
Port #4 (rev 11)'
- bus: '00'
dev: '10'
fn: '0'
id: 19aa
name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root
Port #6 (rev 11)'
- bus: '00'
dev: '12'
fn: '0'
id: 19ac
name: 'System peripheral: Intel Corporation Atom Processor C3000 Series SMBus Contoller
- Host (rev 11)'
- bus: '00'
dev: '13'
fn: '0'
id: 19b2
name: 'SATA controller: Intel Corporation Atom Processor C3000 Series SATA Controller
0 (rev 11)'
- bus: '00'
dev: '15'
fn: '0'
id: 19d0
name: 'USB controller: Intel Corporation Atom Processor C3000 Series USB 3.0 xHCI
Controller (rev 11)'
- bus: '00'
dev: '16'
fn: '0'
id: 19d1
name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated LAN
Root Port #0 (rev 11)'
- bus: '00'
dev: '17'
fn: '0'
id: 19d2
name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated LAN
Root Port #1 (rev 11)'
- bus: '00'
dev: '18'
fn: '0'
id: 19d3
name: 'Communication controller: Intel Corporation Atom Processor C3000 Series ME
HECI 1 (rev 11)'
- bus: '00'
dev: 1a
fn: '0'
id: 19d8
name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller
(rev 11)'
- bus: '00'
dev: 1a
fn: '1'
id: 19d8
name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller
(rev 11)'
- bus: '00'
dev: 1a
fn: '2'
id: 19d8
name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller
(rev 11)'
- bus: '00'
dev: 1c
fn: '0'
id: 19db
name: 'SD Host controller: Intel Corporation Device 19db (rev 11)'
- bus: '00'
dev: 1f
fn: '0'
id: 19dc
name: 'ISA bridge: Intel Corporation Atom Processor C3000 Series LPC or eSPI (rev
11)'
- bus: '00'
dev: 1f
fn: '1'
id: 19dd
name: 'Memory controller: Intel Corporation Atom Processor C3000 Series Primary
to Side Band (P2SB) Bridge (rev 11)'
- bus: '00'
dev: 1f
fn: '2'
id: 19de
name: 'Memory controller: Intel Corporation Atom Processor C3000 Series Power Management
Controller (rev 11)'
- bus: '00'
dev: 1f
fn: '4'
id: 19df
name: 'SMBus: Intel Corporation Atom Processor C3000 Series SMBus controller (rev
11)'
- bus: '00'
dev: 1f
fn: '5'
id: 19e0
name: 'Serial bus controller [0c80]: Intel Corporation Atom Processor C3000 Series
SPI Controller (rev 11)'
- bus: '01'
dev: '00'
fn: '0'
id: 19e2
name: 'Co-processor: Intel Corporation Atom Processor C3000 Series QuickAssist Technology
(rev 11)'
- bus: '05'
dev: '00'
fn: '0'
id: b371
name: 'Ethernet controller: Broadcom Inc. and subsidiaries BCM56371 Switch ASIC
(rev 03)'
- bus: '06'
dev: '00'
fn: '0'
id: 15c2
name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane
(rev 11)'
- bus: '06'
dev: '00'
fn: '1'
id: 15c2
name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane
(rev 11)'
- bus: 08
dev: '00'
fn: '0'
id: 15e5
name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 1GbE (rev
11)'

View File

@ -33,11 +33,11 @@
{ {
"i2c": "i2c":
{ {
"valmap": { "F2B":"EXHAUST", "B2F":"INTAKE" } "valmap": { "F2B":"exhaust", "B2F":"intake" }
} }
}, },
"PSU_FAN_MAX_SPEED":"18000" "PSU_FAN_MAX_SPEED":"26688"
}, },
"FAN": "FAN":
@ -46,7 +46,7 @@
{ {
"i2c": "i2c":
{ {
"valmap": {"1":"EXHAUST", "0":"INTAKE"} "valmap": {"1":"exhaust", "0":"intake"}
} }
}, },

View File

@ -5,7 +5,7 @@
"num_fantrays":3, "num_fantrays":3,
"num_fans_pertray":1, "num_fans_pertray":1,
"num_ports":54, "num_ports":54,
"num_temps": 3, "num_temps": 4,
"pddf_dev_types": "pddf_dev_types":
{ {
"description":"AS4630 - Below is the list of supported PDDF device types (chip names) for various components. If any component uses some other driver, we will create the client using 'echo <dev-address> <dev-type> > <path>/new_device' method", "description":"AS4630 - Below is the list of supported PDDF device types (chip names) for various components. If any component uses some other driver, we will create the client using 'echo <dev-address> <dev-type> > <path>/new_device' method",
@ -211,6 +211,21 @@
} }
}, },
"TEMP4" :
{
"dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP4"},
"dev_attr": { "display_name":"coretemp-isa-0000"},
"i2c":
{
"path_info": {"sysfs_base_path": "/sys/class/hwmon/hwmon1"},
"attr_list":
[
{ "attr_name": "temp1_high_crit_threshold", "drv_attr_name":"temp1_crit"},
{ "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"},
{ "attr_name": "temp1_input"}
]
}
},
"CPLD1": "CPLD1":
{ {
@ -251,15 +266,15 @@
"SYS_LED": "SYS_LED":
{ {
"dev_info": { "device_type":"LED", "device_name":"SYS_LED"}, "dev_info": { "device_type":"LED", "device_name":"SYS_LED"},
"dev_attr": { "index":"0"}, "dev_attr": { "index":"0", "flag": "rw"},
"i2c" : { "i2c" : {
"attr_list": "attr_list":
[ [
{"attr_name":"STATUS_LED_COLOR_GREEN", "bits" : "7:5", "descr" : "", "value" : "0x1", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"}, {"attr_name":"green", "bits" : "7:5", "descr" : "", "value" : "0x1", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"},
{"attr_name":"STATUS_LED_COLOR_GREEN_BLINK", "bits" : "7:5", "descr" : "", "value" : "0x3", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"}, {"attr_name":"green_blink", "bits" : "7:5", "descr" : "", "value" : "0x3", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"},
{"attr_name":"STATUS_LED_COLOR_AMBER", "bits" : "7:5", "descr" : "", "value" : "0x4", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"}, {"attr_name":"amber", "bits" : "7:5", "descr" : "", "value" : "0x4", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"},
{"attr_name":"STATUS_LED_COLOR_AMBER_BLINK", "bits" : "7:5", "descr" : "", "value" : "0x2", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"}, {"attr_name":"amber_blink", "bits" : "7:5", "descr" : "", "value" : "0x2", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"},
{"attr_name":"STATUS_LED_COLOR_OFF", "bits" : "7:5", "descr" : "", "value" : "0x7", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"} {"attr_name":"off", "bits" : "7:5", "descr" : "", "value" : "0x7", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"}
] ]
} }
}, },
@ -268,13 +283,13 @@
"PSU1_LED": "PSU1_LED":
{ {
"dev_info": { "device_type":"LED", "device_name":"PSU_LED"}, "dev_info": { "device_type":"LED", "device_name":"PSU_LED"},
"dev_attr": { "index":"0"}, "dev_attr": { "index":"0", "flag": "r"},
"i2c" : { "i2c" : {
"attr_list": "attr_list":
[ [
{"attr_name":"STATUS_LED_COLOR_GREEN", "bits" : "1:0", "descr" : "", "value" : "0x1", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"}, {"attr_name":"green", "bits" : "1:0", "descr" : "", "value" : "0x1", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"},
{"attr_name":"STATUS_LED_COLOR_AMBER", "bits" : "1:0", "descr" : "", "value" : "0x2", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"}, {"attr_name":"amber", "bits" : "1:0", "descr" : "", "value" : "0x2", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"},
{"attr_name":"STATUS_LED_COLOR_OFF", "bits" : "1:0", "descr" : "", "value" : "0x3", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"} {"attr_name":"off", "bits" : "1:0", "descr" : "", "value" : "0x3", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x30"}
] ]
} }
}, },
@ -282,13 +297,13 @@
"PSU2_LED": "PSU2_LED":
{ {
"dev_info": { "device_type":"LED", "device_name":"PSU_LED"}, "dev_info": { "device_type":"LED", "device_name":"PSU_LED"},
"dev_attr": { "index":"1"}, "dev_attr": { "index":"1", "flag": "r"},
"i2c" : { "i2c" : {
"attr_list": "attr_list":
[ [
{"attr_name":"STATUS_LED_COLOR_GREEN", "bits" : "7:6", "descr" : "", "value" : "0x1", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"}, {"attr_name":"green", "bits" : "7:6", "descr" : "", "value" : "0x1", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"},
{"attr_name":"STATUS_LED_COLOR_AMBER", "bits" : "7:6", "descr" : "", "value" : "0x2", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"}, {"attr_name":"amber", "bits" : "7:6", "descr" : "", "value" : "0x2", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"},
{"attr_name":"STATUS_LED_COLOR_OFF", "bits" : "7:6", "descr" : "", "value" : "0x3", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"} {"attr_name":"off", "bits" : "7:6", "descr" : "", "value" : "0x3", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"}
] ]
} }
}, },
@ -296,13 +311,13 @@
"FAN_LED": "FAN_LED":
{ {
"dev_info": { "device_type":"LED", "device_name":"FAN_LED"}, "dev_info": { "device_type":"LED", "device_name":"FAN_LED"},
"dev_attr": { "index":"0"}, "dev_attr": { "index":"0", "flag": "r"},
"i2c" : { "i2c" : {
"attr_list": "attr_list":
[ [
{"attr_name":"STATUS_LED_COLOR_GREEN", "bits" : "3:2", "descr" : "", "value" : "0x1", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"}, {"attr_name":"green", "bits" : "3:2", "descr" : "", "value" : "0x1", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"},
{"attr_name":"STATUS_LED_COLOR_AMBER", "bits" : "3:2", "descr" : "", "value" : "0x2", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"}, {"attr_name":"amber", "bits" : "3:2", "descr" : "", "value" : "0x2", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"},
{"attr_name":"STATUS_LED_COLOR_OFF", "bits" : "3:2", "descr" : "", "value" : "0x3", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"} {"attr_name":"off", "bits" : "3:2", "descr" : "", "value" : "0x3", "swpld_addr" : "0x60", "swpld_addr_offset" : "0x31"}
] ]
} }
}, },
@ -336,7 +351,11 @@
{ "attr_name":"psu_i_out", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x8c", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, { "attr_name":"psu_i_out", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x8c", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_p_out", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x96", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, { "attr_name":"psu_p_out", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x96", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_fan1_speed_rpm", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x90", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, { "attr_name":"psu_fan1_speed_rpm", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x90", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_temp1_input", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x8d", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"} { "attr_name":"psu_temp1_input", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x8d", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_v_out_max", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0xa5", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_v_out_min", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0xa4", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_p_out_max", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0xa7", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_temp1_high_threshold", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0xa8", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}
] ]
} }
}, },
@ -387,7 +406,11 @@
{ "attr_name":"psu_i_out", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x8c", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, { "attr_name":"psu_i_out", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x8c", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_p_out", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x96", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, { "attr_name":"psu_p_out", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x96", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_fan1_speed_rpm", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x90", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, { "attr_name":"psu_fan1_speed_rpm", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x90", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_temp1_input", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x8d", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"} { "attr_name":"psu_temp1_input", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x8d", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_v_out_max", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0xa5", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_v_out_min", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0xa4", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_p_out_max", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0xa7", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"},
{ "attr_name":"psu_temp1_high_threshold", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0xa8", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}
] ]
} }
}, },
@ -592,7 +615,9 @@
"topo_info": { "parent_bus":"0x16", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, "topo_info": { "parent_bus":"0x16", "dev_addr":"0x53", "dev_type":"pddf_xcvr"},
"attr_list": "attr_list":
[ [
{ "attr_name":"xcvr_present", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x21", "attr_mask":"0x0", "attr_cmpval":"0x0", "attr_len":"1"} { "attr_name":"xcvr_present", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x21", "attr_mask":"0x0", "attr_cmpval":"0x0", "attr_len":"1"},
{ "attr_name":"xcvr_reset", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x21", "attr_mask":"0x3", "attr_cmpval":"0x0", "attr_len":"1"},
{ "attr_name":"xcvr_intr_status", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x21", "attr_mask":"0x2", "attr_cmpval":"0x0", "attr_len":"1"}
] ]
} }
}, },
@ -630,7 +655,9 @@
"topo_info": { "parent_bus":"0x17", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, "topo_info": { "parent_bus":"0x17", "dev_addr":"0x53", "dev_type":"pddf_xcvr"},
"attr_list": "attr_list":
[ [
{ "attr_name":"xcvr_present", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x21", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"} { "attr_name":"xcvr_present", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x21", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"},
{ "attr_name":"xcvr_reset", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x21", "attr_mask":"0x7", "attr_cmpval":"0x0", "attr_len":"1"},
{ "attr_name":"xcvr_intr_status", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x21", "attr_mask":"0x5", "attr_cmpval":"0x0", "attr_len":"1"}
] ]
} }
} }

View File

@ -0,0 +1,785 @@
{
"chassis": {
"name": "4630-54PE",
"thermal_manager":false,
"status_led": {
"controllable": true,
"colors": ["STATUS_LED_COLOR_GREEN", "STATUS_LED_COLOR_GREEN_BLINK", "STATUS_LED_COLOR_AMBER", "STATUS_LED_COLOR_AMBER_BLINK", "STATUS_LED_COLOR_OFF"]
},
"components": [
{
"name": "CPLD1"
},
{
"name": "BIOS"
}
],
"fans": [
{
"name": "FAN-1",
"speed": {
"controllable": true,
"minimum": 7
},
"status_led": {
"controllable": false
}
},
{
"name": "FAN-2",
"speed": {
"controllable": true,
"minimum": 7
},
"status_led": {
"controllable": false
}
},
{
"name": "FAN-3",
"speed": {
"controllable": true,
"minimum": 7
},
"status_led": {
"controllable": false
}
}
],
"fan_drawers":[
{
"name": "FanTray1",
"status_led": {
"controllable": false
},
"num_fans" : 1,
"fans": [
{
"name": "FAN-1",
"speed": {
"controllable": true,
"minimum": 7
},
"status_led": {
"controllable": false
}
}
]
},
{
"name": "FanTray2",
"status_led": {
"controllable": false
},
"num_fans" : 1,
"fans": [
{
"name": "FAN-2",
"speed": {
"controllable": true,
"minimum": 7
},
"status_led": {
"controllable": false
}
}
]
},
{
"name": "FanTray3",
"status_led": {
"controllable": false
},
"num_fans" : 1,
"fans": [
{
"name": "FAN-3",
"speed": {
"controllable": true,
"minimum": 7
},
"status_led": {
"controllable": false
}
}
]
}
],
"psus": [
{
"name": "PSU-1",
"status_led": {
"controllable": true,
"colors": ["STATUS_LED_COLOR_GREEN", "STATUS_LED_COLOR_AMBER", "STATUS_LED_COLOR_OFF"]
},
"fans": [
{
"name": "PSU-1 FAN-1"
}
],
"thermals": [
{
"name": "PSU-1 temp sensor 1",
"controllable": false,
"low-crit-threshold": false,
"high-crit-threshold": false
}
]
},
{
"name": "PSU-2",
"status_led": {
"controllable": true,
"colors": ["STATUS_LED_COLOR_GREEN", "STATUS_LED_COLOR_AMBER", "STATUS_LED_COLOR_OFF"]
},
"fans": [
{
"name": "PSU-2 FAN-1"
}
],
"thermals": [
{
"name": "PSU-2 temp sensor 1",
"controllable": false,
"low-crit-threshold": false,
"high-crit-threshold": false
}
]
}
],
"thermals": [
{
"name": "Temp sensor 1",
"controllable": true,
"low-threshold": false,
"high-threshold": true,
"low-crit-threshold": false,
"high-crit-threshold": false
},
{
"name": "Temp sensor 2",
"controllable": true,
"low-threshold": false,
"high-threshold": true,
"low-crit-threshold": false,
"high-crit-threshold": false
},
{
"name": "Temp sensor 3",
"controllable": true,
"low-threshold": false,
"high-threshold": true,
"low-crit-threshold": false,
"high-crit-threshold": false
},
{
"name": "Temp sensor 4",
"controllable": false,
"low-threshold": false,
"high-threshold": true,
"low-crit-threshold": false,
"high-crit-threshold": true
}
],
"sfps": [
{
"name": "Ethernet0"
},
{
"name": "Ethernet1"
},
{
"name": "Ethernet2"
},
{
"name": "Ethernet3"
},
{
"name": "Ethernet4"
},
{
"name": "Ethernet5"
},
{
"name": "Ethernet6"
},
{
"name": "Ethernet7"
},
{
"name": "Ethernet8"
},
{
"name": "Ethernet9"
},
{
"name": "Ethernet10"
},
{
"name": "Ethernet11"
},
{
"name": "Ethernet12"
},
{
"name": "Ethernet13"
},
{
"name": "Ethernet14"
},
{
"name": "Ethernet15"
},
{
"name": "Ethernet16"
},
{
"name": "Ethernet17"
},
{
"name": "Ethernet18"
},
{
"name": "Ethernet19"
},
{
"name": "Ethernet20"
},
{
"name": "Ethernet21"
},
{
"name": "Ethernet22"
},
{
"name": "Ethernet23"
},
{
"name": "Ethernet24"
},
{
"name": "Ethernet25"
},
{
"name": "Ethernet26"
},
{
"name": "Ethernet27"
},
{
"name": "Ethernet28"
},
{
"name": "Ethernet29"
},
{
"name": "Ethernet30"
},
{
"name": "Ethernet31"
},
{
"name": "Ethernet32"
},
{
"name": "Ethernet33"
},
{
"name": "Ethernet34"
},
{
"name": "Ethernet35"
},
{
"name": "Ethernet36"
},
{
"name": "Ethernet37"
},
{
"name": "Ethernet38"
},
{
"name": "Ethernet39"
},
{
"name": "Ethernet40"
},
{
"name": "Ethernet41"
},
{
"name": "Ethernet42"
},
{
"name": "Ethernet43"
},
{
"name": "Ethernet44"
},
{
"name": "Ethernet45"
},
{
"name": "Ethernet46"
},
{
"name": "Ethernet47"
},
{
"name": "Ethernet48"
},
{
"name": "Ethernet49"
},
{
"name": "Ethernet50"
},
{
"name": "Ethernet51"
},
{
"name": "Ethernet52"
},
{
"name": "Ethernet56"
}
]
},
"interfaces": {
"Ethernet0": {
"index": "1",
"lanes": "26",
"breakout_modes": {
"1x1G": ["Eth1(Port1)"]
}
},
"Ethernet1": {
"index": "2",
"lanes": "25",
"breakout_modes": {
"1x1G": ["Eth2(Port2)"]
}
},
"Ethernet2": {
"index": "3",
"lanes": "28",
"breakout_modes": {
"1x1G": ["Eth3(Port3)"]
}
},
"Ethernet3": {
"index": "4",
"lanes": "27",
"breakout_modes": {
"1x1G": ["Eth4(Port4)"]
}
},
"Ethernet4": {
"index": "5",
"lanes": "30",
"breakout_modes": {
"1x1G": ["Eth5(Port5)"]
}
},
"Ethernet5": {
"index": "6",
"lanes": "29",
"breakout_modes": {
"1x1G": ["Eth6(Port6)"]
}
},
"Ethernet6": {
"index": "7",
"lanes": "32",
"breakout_modes": {
"1x1G": ["Eth7(Port7)"]
}
},
"Ethernet7": {
"index": "8",
"lanes": "31",
"breakout_modes": {
"1x1G": ["Eth8(Port8)"]
}
},
"Ethernet8": {
"index": "9",
"lanes": "38",
"breakout_modes": {
"1x1G": ["Eth9(Port9)"]
}
},
"Ethernet9": {
"index": "10",
"lanes": "37",
"breakout_modes": {
"1x1G": ["Eth10(Port10)"]
}
},
"Ethernet10": {
"index": "11",
"lanes": "40",
"breakout_modes": {
"1x1G": ["Eth11(Port11)"]
}
},
"Ethernet11": {
"index": "12",
"lanes": "39",
"breakout_modes": {
"1x1G": ["Eth12(Port12)"]
}
},
"Ethernet12": {
"index": "13",
"lanes": "34",
"breakout_modes": {
"1x1G": ["Eth13(Port13)"]
}
},
"Ethernet13": {
"index": "14",
"lanes": "33",
"breakout_modes": {
"1x1G": ["Eth14(Port14)"]
}
},
"Ethernet14": {
"index": "15",
"lanes": "36",
"breakout_modes": {
"1x1G": ["Eth15(Port15)"]
}
},
"Ethernet15": {
"index": "16",
"lanes": "35",
"breakout_modes": {
"1x1G": ["Eth16(Port16)"]
}
},
"Ethernet16": {
"index": "17",
"lanes": "46",
"breakout_modes": {
"1x1G": ["Eth17(Port17)"]
}
},
"Ethernet17": {
"index": "18",
"lanes": "45",
"breakout_modes": {
"1x1G": ["Eth18(Port18)"]
}
},
"Ethernet18": {
"index": "19",
"lanes": "48",
"breakout_modes": {
"1x1G": ["Eth19(Port19)"]
}
},
"Ethernet19": {
"index": "20",
"lanes": "47",
"breakout_modes": {
"1x1G": ["Eth20(Port20)"]
}
},
"Ethernet20": {
"index": "21",
"lanes": "42",
"breakout_modes": {
"1x1G": ["Eth21(Port21)"]
}
},
"Ethernet21": {
"index": "22",
"lanes": "41",
"breakout_modes": {
"1x1G": ["Eth22(Port22)"]
}
},
"Ethernet22": {
"index": "23",
"lanes": "44",
"breakout_modes": {
"1x1G": ["Eth23(Port23)"]
}
},
"Ethernet23": {
"index": "24",
"lanes": "43",
"breakout_modes": {
"1x1G": ["Eth24(Port24)"]
}
},
"Ethernet24": {
"index": "25",
"lanes": "2",
"breakout_modes": {
"1x1G": ["Eth25(Port25)"]
}
},
"Ethernet25": {
"index": "26",
"lanes": "1",
"breakout_modes": {
"1x1G": ["Eth26(Port26)"]
}
},
"Ethernet26": {
"index": "27",
"lanes": "4",
"breakout_modes": {
"1x1G": ["Eth27(Port27)"]
}
},
"Ethernet27": {
"index": "28",
"lanes": "3",
"breakout_modes": {
"1x1G": ["Eth28(Port28)"]
}
},
"Ethernet28": {
"index": "29",
"lanes": "6",
"breakout_modes": {
"1x1G": ["Eth29(Port29)"]
}
},
"Ethernet29": {
"index": "30",
"lanes": "5",
"breakout_modes": {
"1x1G": ["Eth30(Port30)"]
}
},
"Ethernet30": {
"index": "31",
"lanes": "8",
"breakout_modes": {
"1x1G": ["Eth31(Port31)"]
}
},
"Ethernet31": {
"index": "32",
"lanes": "7",
"breakout_modes": {
"1x1G": ["Eth32(Port32)"]
}
},
"Ethernet32": {
"index": "33",
"lanes": "10",
"breakout_modes": {
"1x1G": ["Eth33(Port33)"]
}
},
"Ethernet33": {
"index": "34",
"lanes": "9",
"breakout_modes": {
"1x1G": ["Eth34(Port34)"]
}
},
"Ethernet34": {
"index": "35",
"lanes": "12",
"breakout_modes": {
"1x1G": ["Eth35(Port35)"]
}
},
"Ethernet35": {
"index": "36",
"lanes": "11",
"breakout_modes": {
"1x1G": ["Eth36(Port36)"]
}
},
"Ethernet36": {
"index": "37",
"lanes": "14",
"breakout_modes": {
"1x1G": ["Eth37(Port37)"]
}
},
"Ethernet37": {
"index": "38",
"lanes": "13",
"breakout_modes": {
"1x1G": ["Eth38(Port38)"]
}
},
"Ethernet38": {
"index": "39",
"lanes": "16",
"breakout_modes": {
"1x1G": ["Eth39(Port39)"]
}
},
"Ethernet39": {
"index": "40",
"lanes": "15",
"breakout_modes": {
"1x1G": ["Eth40(Port40)"]
}
},
"Ethernet40": {
"index": "41",
"lanes": "18",
"breakout_modes": {
"1x1G": ["Eth41(Port41)"]
}
},
"Ethernet41": {
"index": "42",
"lanes": "17",
"breakout_modes": {
"1x1G": ["Eth42(Port42)"]
}
},
"Ethernet42": {
"index": "43",
"lanes": "20",
"breakout_modes": {
"1x1G": ["Eth43(Port43)"]
}
},
"Ethernet43": {
"index": "44",
"lanes": "19",
"breakout_modes": {
"1x1G": ["Eth44(Port44)"]
}
},
"Ethernet44": {
"index": "45",
"lanes": "22",
"breakout_modes": {
"1x1G": ["Eth45(Port45)"]
}
},
"Ethernet45": {
"index": "46",
"lanes": "21",
"breakout_modes": {
"1x1G": ["Eth46(Port46)"]
}
},
"Ethernet46": {
"index": "47",
"lanes": "24",
"breakout_modes": {
"1x1G": ["Eth47(Port47)"]
}
},
"Ethernet47": {
"index": "48",
"lanes": "23",
"breakout_modes": {
"1x1G": ["Eth48(Port48)"]
}
},
"Ethernet48": {
"index": "49",
"lanes": "67",
"breakout_modes": {
"1x25G[10G]": ["Eth49(Port49)"]
}
},
"Ethernet49": {
"index": "50",
"lanes": "66",
"breakout_modes": {
"1x25G[10G]": ["Eth50(Port50)"]
}
},
"Ethernet50": {
"index": "51",
"lanes": "65",
"breakout_modes": {
"1x25G[10G]": ["Eth51(Port51)"]
}
},
"Ethernet51": {
"index": "52",
"lanes": "68",
"breakout_modes": {
"1x25G[10G]": ["Eth52(Port52)"]
}
},
"Ethernet52": {
"index": "53,53,53,53",
"lanes": "73,74,75,76",
"breakout_modes": {
"1x100G[40G]": ["Eth53(Port53)"],
"2x50G": ["Eth53/1(Port53)", "Eth53/2(Port53)"],
"4x25G[10G]": ["Eth53/1(Port53)", "Eth53/2(Port53)", "Eth53/3(Port53)", "Eth53/4(Port53)"]
}
},
"Ethernet56": {
"index": "54,54,54,54",
"lanes": "69,70,71,72",
"breakout_modes": {
"1x100G[40G]": ["Eth54(Port54)"],
"2x50G": ["Eth54/1(Port54)", "Eth54/2(Port54)"],
"4x25G[10G]": ["Eth54/1(Port54)", "Eth54/2(Port54)", "Eth54/3(Port54)", "Eth54/4(Port54)"]
}
}
}
}

View File

@ -0,0 +1,10 @@
{
"chassis": {
"4630-54PE-O-AC-F": {
"component": {
"CPLD1": { },
"BIOS": { }
}
}
}
}

View File

@ -1,5 +1,4 @@
{ {
"skip_ledd": true, "skip_ledd": true
"skip_pcied": true
} }

View File

@ -1,17 +1,13 @@
{ {
"services_to_ignore": [], "services_to_ignore": [],
"devices_to_ignore": [ "devices_to_ignore": [
"asic", "asic"
"psu.voltage",
"psu.temperature",
"PSU1_FAN1.speed",
"PSU2_FAN1.speed"
], ],
"user_defined_checkers": [], "user_defined_checkers": [],
"polling_interval": 60, "polling_interval": 60,
"led_color": { "led_color": {
"fault": "STATUS_LED_COLOR_AMBER", "fault": "amber",
"normal": "STATUS_LED_COLOR_GREEN", "normal": "green",
"booting": "STATUS_LED_COLOR_GREEN_BLINK" "booting": "green_blink"
} }
} }

View File

@ -0,0 +1,16 @@
[Unit]
Description=Accton AS4630-54PE Platform Monitoring service
Before=pmon.service
After=pddf-platform-init.service
DefaultDependencies=no
[Service]
ExecStart=/usr/local/bin/accton_as4630_54pe_pddf_monitor.py
KillSignal=SIGKILL
SuccessExitStatus=SIGKILL
# Resource Limitations
LimitCORE=infinity
[Install]
WantedBy=multi-user.target

View File

@ -10,10 +10,14 @@ try:
import sys import sys
from sonic_platform_pddf_base.pddf_chassis import PddfChassis from sonic_platform_pddf_base.pddf_chassis import PddfChassis
from .event import SfpEvent from .event import SfpEvent
from .helper import APIHelper
except ImportError as e: except ImportError as e:
raise ImportError(str(e) + "- required module not found") raise ImportError(str(e) + "- required module not found")
NUM_COMPONENT = 2 NUM_COMPONENT = 2
HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/"
PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/"
REBOOT_CAUSE_FILE = "reboot-cause.txt"
class Chassis(PddfChassis): class Chassis(PddfChassis):
""" """
@ -26,6 +30,7 @@ class Chassis(PddfChassis):
PddfChassis.__init__(self, pddf_data, pddf_plugin_data) PddfChassis.__init__(self, pddf_data, pddf_plugin_data)
self.__initialize_components() self.__initialize_components()
self._sfpevent = SfpEvent(self.get_all_sfps()) self._sfpevent = SfpEvent(self.get_all_sfps())
self._api_helper = APIHelper()
def __initialize_components(self): def __initialize_components(self):
from sonic_platform.component import Component from sonic_platform.component import Component
@ -68,3 +73,57 @@ class Chassis(PddfChassis):
def set_status_led(self, color): def set_status_led(self, color):
return self.set_system_led(self.SYSLED_DEV_NAME, color) return self.set_system_led(self.SYSLED_DEV_NAME, color)
def get_port_or_cage_type(self, port):
from sonic_platform_base.sfp_base import SfpBase
if port in range(1, 49):
return SfpBase.SFP_PORT_TYPE_BIT_RJ45
elif port in range(49, 53):
return SfpBase.SFP_PORT_TYPE_BIT_SFP | SfpBase.SFP_PORT_TYPE_BIT_SFP_PLUS | SfpBase.SFP_PORT_TYPE_BIT_SFP28
else:
return SfpBase.SFP_PORT_TYPE_BIT_QSFP | SfpBase.SFP_PORT_TYPE_BIT_QSFP_PLUS | SfpBase.SFP_PORT_TYPE_BIT_QSFP28
def get_reboot_cause(self):
"""
Retrieves the cause of the previous reboot
Returns:
A tuple (string, string) where the first element is a string
containing the cause of the previous reboot. This string must be
one of the predefined strings in this class. If the first string
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
to pass a description of the reboot cause.
"""
reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE)
sw_reboot_cause = self._api_helper.read_txt_file(
reboot_cause_path) or "Unknown"
return ('REBOOT_CAUSE_NON_HARDWARE', sw_reboot_cause)
def get_position_in_parent(self):
"""
Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position
for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned
Returns:
integer: The 1-based relative physical position in parent device or -1 if cannot determine the position
"""
return -1
def is_replaceable(self):
"""
Indicate whether this device is replaceable.
Returns:
bool: True if it is replaceable.
"""
return False
def get_revision(self):
"""
Retrieves the hardware revision of the device
Returns:
string: Revision value of device
"""
return self._eeprom.revision_str()

View File

@ -8,6 +8,8 @@
############################################################################# #############################################################################
try: try:
import os
import json
from sonic_platform_base.component_base import ComponentBase from sonic_platform_base.component_base import ComponentBase
from sonic_py_common.general import getstatusoutput_noshell from sonic_py_common.general import getstatusoutput_noshell
except ImportError as e: except ImportError as e:
@ -82,4 +84,85 @@ class Component(ComponentBase):
Returns: Returns:
A boolean, True if install successfully, False if not A boolean, True if install successfully, False if not
""" """
raise NotImplementedError ret, output = getstatusoutput_noshell(["tar", "-C", "/tmp", "-xzf", image_path ] )
if ret != 0 :
print("Installation failed because of wrong image package")
return False
if os.path.exists("/tmp/install.json") is False:
print("Installation failed without jsonfile")
return False
input_file = open ('/tmp/install.json')
json_array = json.load(input_file)
ret = 1
for item in json_array:
if item.get('id')==None or item.get('path')==None:
continue
if self.name == item['id'] and item['path'] and item.get('cpu'):
print( "Find", item['id'], item['path'], item['cpu'] )
ret, output = getstatusoutput_noshell(["/tmp/run_install.sh", item['id'], item['path'], item['cpu'] ])
if ret==0:
break
elif self.name == item['id'] and item['path']:
print( "Find", item['id'], item['path'] )
ret, output = getstatusoutput_noshell(["/tmp/run_install.sh", item['id'], item['path'] ])
if ret==0:
break
if ret==0:
return True
else :
return False
def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
return True
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
return 'N/A'
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
return 'N/A'
def get_status(self):
"""
Retrieves the operational status of the device
Returns:
A boolean value, True if device is operating properly, False if not
"""
return True
def get_position_in_parent(self):
"""
Retrieves 1-based relative physical position in parent device.
If the agent cannot determine the parent-relative position
for some reason, or if the associated value of
entPhysicalContainedIn is'0', then the value '-1' is returned
Returns:
integer: The 1-based relative physical position in parent device
or -1 if cannot determine the position
"""
return -1
def is_replaceable(self):
"""
Indicate whether this device is replaceable.
Returns:
bool: True if it is replaceable.
"""
return False

View File

@ -1,11 +1,21 @@
try: try:
import time import time
from sonic_py_common.logger import Logger from sonic_py_common.logger import Logger
from .sfp import Sfp
except ImportError as e: except ImportError as e:
raise ImportError(repr(e) + " - required module not found") raise ImportError(repr(e) + " - required module not found")
POLL_INTERVAL_IN_SEC = 1 POLL_INTERVAL_IN_SEC = 1
# SFP errors that will block eeprom accessing
SFP_BLOCKING_ERRORS = [
Sfp.SFP_ERROR_BIT_I2C_STUCK,
Sfp.SFP_ERROR_BIT_BAD_EEPROM,
Sfp.SFP_ERROR_BIT_UNSUPPORTED_CABLE,
Sfp.SFP_ERROR_BIT_HIGH_TEMP,
Sfp.SFP_ERROR_BIT_BAD_CABLE
]
class SfpEvent: class SfpEvent:
''' Listen to insert/remove sfp events ''' ''' Listen to insert/remove sfp events '''
@ -46,15 +56,54 @@ class SfpEvent:
if changed_ports != 0: if changed_ports != 0:
for sfp in self._sfp_list: for sfp in self._sfp_list:
i=sfp.get_position_in_parent() - 1 i=sfp.get_position_in_parent() - 1
if (changed_ports & (1 << i)): if (changed_ports & (1 << i)) == 0:
continue
if (bitmap & (1 << i)) == 0: if (bitmap & (1 << i)) == 0:
port_dict[i+1] = '0' port_dict[i+1] = '0'
else: else:
port_dict[i+1] = '1' # sfp.refresh_optoe_dev_class()
sfp_state_bits = self.get_sfp_state_bits(sfp, True)
sfp_state_bits = self.check_sfp_blocking_errors(sfp_state_bits)
port_dict[i+1] = str(sfp_state_bits)
# Update the cache dict # Update the cache dict
self._sfp_change_event_data['present'] = bitmap self._sfp_change_event_data['present'] = bitmap
return True, change_dict return True, change_dict
else: else:
return True, change_dict return True, change_dict
def get_sfp_state_bits(self, sfp, present):
sfp_state_bits = 0
if present is True:
sfp_state_bits |= Sfp.SFP_STATUS_BIT_INSERTED
else:
return sfp_state_bits
status = sfp.validate_eeprom()
if status is None:
sfp_state_bits |= Sfp.SFP_ERROR_BIT_I2C_STUCK
return sfp_state_bits
elif status is not True:
sfp_state_bits |= Sfp.SFP_ERROR_BIT_BAD_EEPROM
return sfp_state_bits
status = sfp.validate_temperature()
if status is None:
sfp_state_bits |= Sfp.SFP_ERROR_BIT_I2C_STUCK
return sfp_state_bits
elif status is not True:
sfp_state_bits |= Sfp.SFP_ERROR_BIT_HIGH_TEMP
return sfp_state_bits
return sfp_state_bits
def check_sfp_blocking_errors(self, sfp_state_bits):
for i in SFP_BLOCKING_ERRORS:
if (i & sfp_state_bits) == 0:
continue
sfp_state_bits |= Sfp.SFP_ERROR_BIT_BLOCKING
return sfp_state_bits

View File

@ -6,6 +6,7 @@ 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")
FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3"]
class Fan(PddfFan): class Fan(PddfFan):
"""PDDF Platform-Specific Fan class""" """PDDF Platform-Specific Fan class"""
@ -24,25 +25,53 @@ class Fan(PddfFan):
A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST
depending on fan direction depending on fan direction
""" """
direction = 'N/A'
if self.is_psu_fan: if self.is_psu_fan:
direction = self.FAN_DIRECTION_EXHAUST direction = self.FAN_DIRECTION_EXHAUST
else: else:
idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index direction = super().get_direction()
attr = "fan" + str(idx) + "_direction" if direction is not None and len(direction) > 0:
output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) return direction
if not output:
return False
mode = output['mode']
val = output['status']
val = val.rstrip()
vmap = self.plugin_data['FAN']['direction'][mode]['valmap']
if val in vmap:
direction = vmap[val]
else:
direction = val
return direction return direction
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
fan_name = FAN_NAME_LIST[self.fantray_index - 1] \
if not self.is_psu_fan \
else "PSU-{} FAN-{}".format(self.fans_psu_index, self.fan_index)
return fan_name
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
return 'N/A'
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
return 'N/A'
def get_target_speed(self):
"""
Retrieves the target (expected) speed of the fan
Returns:
An integer, the percentage of full fan speed, in the range 0 (off)
to 100 (full speed)
"""
if self.is_psu_fan:
return super().get_speed()
else:
return super().get_target_speed()

View File

@ -15,3 +15,26 @@ class FanDrawer(PddfFanDrawer):
PddfFanDrawer.__init__(self, tray_idx, pddf_data, pddf_plugin_data) PddfFanDrawer.__init__(self, tray_idx, pddf_data, pddf_plugin_data)
# Provide the functions/variables below for which implementation is to be overwritten # Provide the functions/variables below for which implementation is to be overwritten
def get_name(self):
"""
Retrieves the fan drawer name
Returns:
string: The name of the device
"""
return "FanTray{}".format(self.fantray_index)
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
return 'N/A'
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
return 'N/A'

View File

@ -0,0 +1,368 @@
import os
import struct
import json
import fcntl
from mmap import *
from sonic_py_common import device_info
from sonic_py_common import logger
from threading import Lock
from typing import cast
from sonic_py_common.general import getstatusoutput_noshell_pipe
from sonic_py_common.general import getstatusoutput_noshell
HOST_CHK_CMD = ["docker"]
EMPTY_STRING = ""
class APIHelper():
def __init__(self):
(self.platform, self.hwsku) = device_info.get_platform_and_hwsku()
def is_host(self):
try:
status, output = getstatusoutput_noshell(HOST_CHK_CMD)
return status == 0
except Exception:
return False
def pci_get_value(self, resource, offset):
status = True
result = ""
try:
fd = os.open(resource, os.O_RDWR)
mm = mmap(fd, 0)
mm.seek(int(offset))
read_data_stream = mm.read(4)
result = struct.unpack('I', read_data_stream)
except Exception:
status = False
return status, result
def run_interactive_command(self, cmd):
try:
os.system(cmd)
except Exception:
return False
return True
def read_txt_file(self, file_path):
try:
with open(file_path, 'r', errors='replace') as fd:
data = fd.read()
ret = data.strip()
if len(ret) > 0:
return ret
except IOError:
pass
return None
def write_txt_file(self, file_path, value):
try:
with open(file_path, 'w') as fd:
fd.write(str(value))
except IOError:
return False
return True
def ipmi_raw(self, netfn, cmd):
status = True
result = ""
try:
err, raw_data = getstatusoutput_noshell_pipe(['ipmitool', 'raw', str(netfn), str(cmd)])
if err == [0]:
result = raw_data.strip()
else:
status = False
except Exception:
status = False
return status, result
def ipmi_fru_id(self, id, key=None):
status = True
result = ""
try:
if (key is None):
err, raw_data = getstatusoutput_noshell_pipe(['ipmitool', 'fru', 'print', str(id)])
else:
err, raw_data = getstatusoutput_noshell_pipe(['ipmitool', 'fru', 'print', str(id)], ['grep', str(key)])
if err == [0] or err == [0, 0]:
result = raw_data.strip()
else:
status = False
except Exception:
status = False
return status, result
def ipmi_set_ss_thres(self, id, threshold_key, value):
status = True
result = ""
try:
err, raw_data = getstatusoutput_noshell_pipe(['ipmitool', 'sensor', 'thresh', str(id), str(threshold_key), str(value)])
if err == [0]:
result = raw_data.strip()
else:
status = False
except Exception:
status = False
return status, result
class FileLock:
"""
Due to pmon docker not installing the py-filelock, this class
implements a simple file lock feature.
Ref: https://github.com/tox-dev/py-filelock/blob/main/src/filelock/
"""
def __init__(self, lock_file):
self._lock_file = lock_file
self._thread_lock = Lock()
self.is_locked = False
def acquire(self):
with self._thread_lock:
if self.is_locked:
return
fd = os.open(self._lock_file, flags=(os.O_RDWR | os.O_CREAT | os.O_TRUNC))
fcntl.flock(fd, fcntl.LOCK_EX)
self._lock_file_fd = fd
self.is_locked = True
def release(self):
with self._thread_lock:
if self.is_locked:
fd = cast(int, self._lock_file_fd)
self._lock_file_fd = None
fcntl.flock(fd, fcntl.LOCK_UN)
os.close(fd)
self.is_locked = False
def __enter__(self):
self.acquire()
return self
def __exit__(self, exc_type, exc_val, traceback):
self.release()
def __del__(self):
self.release()
DEVICE_THRESHOLD_JSON_PATH = "/tmp/device_threshold.json"
class DeviceThreshold:
HIGH_THRESHOLD = 'high_threshold'
LOW_THRESHOLD = 'low_threshold'
HIGH_CRIT_THRESHOLD = 'high_critical_threshold'
LOW_CRIT_THRESHOLD = 'low_critical_threshold'
NOT_AVAILABLE = 'N/A'
def __init__(self, th_name = NOT_AVAILABLE):
self.flock = FileLock("{}.lock".format(DEVICE_THRESHOLD_JSON_PATH))
self.name = th_name
self.__log = logger.Logger(log_identifier="DeviceThreshold")
self.__db_data = {}
self.__db_mtime = 0
def __reload_db(self):
try:
db_data = {}
with self.flock:
with open(DEVICE_THRESHOLD_JSON_PATH, "r") as db_file:
db_data = json.load(db_file)
except Exception as e:
self.__log.log_warning('{}'.format(str(e)))
return None
return db_data
def __get_data(self, field):
"""
Retrieves data frome JSON file by field
Args :
field: String
Returns:
A string if getting is successfully, 'N/A' if not
"""
if os.path.exists(DEVICE_THRESHOLD_JSON_PATH):
new_mtime = os.path.getmtime(DEVICE_THRESHOLD_JSON_PATH)
if new_mtime != self.__db_mtime:
new_data = self.__reload_db()
if new_data is not None:
self.__db_data = new_data
self.__db_mtime = new_mtime
if self.name not in self.__db_data.keys():
return self.NOT_AVAILABLE
if field not in self.__db_data[self.name].keys():
return self.NOT_AVAILABLE
return self.__db_data[self.name][field]
def __set_data(self, field, new_val):
"""
Set data to JSON file by field
Args :
field: String
new_val: String
Returns:
A boolean, True if setting is set successfully, False if not
"""
if self.name not in self.__db_data.keys():
self.__db_data[self.name] = {}
old_val = self.__db_data[self.name].get(field, None)
if old_val is not None and old_val == new_val:
return True
self.__db_data[self.name][field] = new_val
try:
with self.flock:
db_data = {}
mode = "r+" if os.path.exists(DEVICE_THRESHOLD_JSON_PATH) else "w+"
with open(DEVICE_THRESHOLD_JSON_PATH, mode) as db_file:
if mode == "r+":
db_data = json.load(db_file)
if self.name not in db_data.keys():
db_data[self.name] = {}
db_data[self.name][field] = new_val
if mode == "r+":
db_file.seek(0)
# erase old data
db_file.truncate(0)
# write all data
json.dump(db_data, db_file, indent=4)
self.__db_mtime = os.path.getmtime(DEVICE_THRESHOLD_JSON_PATH)
except Exception as e:
self.__log.log_error('{}'.format(str(e)))
return False
return True
def get_high_threshold(self):
"""
Retrieves the high threshold temperature from JSON file.
Returns:
string : the high threshold temperature of thermal,
e.g. "30.125"
"""
return self.__get_data(self.HIGH_THRESHOLD)
def set_high_threshold(self, temperature):
"""
Sets the high threshold temperature of thermal
Args :
temperature: A string of temperature, e.g. "30.125"
Returns:
A boolean, True if threshold is set successfully, False if not
"""
if isinstance(temperature, str) is not True:
raise TypeError('The parameter requires string type.')
try:
if temperature != self.NOT_AVAILABLE:
float(temperature)
except ValueError:
raise ValueError('The parameter requires a float string. ex:\"30.1\"')
return self.__set_data(self.HIGH_THRESHOLD, temperature)
def get_low_threshold(self):
"""
Retrieves the low threshold temperature from JSON file.
Returns:
string : the low threshold temperature of thermal,
e.g. "30.125"
"""
return self.__get_data(self.LOW_THRESHOLD)
def set_low_threshold(self, temperature):
"""
Sets the low threshold temperature of thermal
Args :
temperature: A string of temperature, e.g. "30.125"
Returns:
A boolean, True if threshold is set successfully, False if not
"""
if isinstance(temperature, str) is not True:
raise TypeError('The parameter requires string type.')
try:
if temperature != self.NOT_AVAILABLE:
float(temperature)
except ValueError:
raise ValueError('The parameter requires a float string. ex:\"30.1\"')
return self.__set_data(self.LOW_THRESHOLD, temperature)
def get_high_critical_threshold(self):
"""
Retrieves the high critical threshold temperature from JSON file.
Returns:
string : the high critical threshold temperature of thermal,
e.g. "30.125"
"""
return self.__get_data(self.HIGH_CRIT_THRESHOLD)
def set_high_critical_threshold(self, temperature):
"""
Sets the high critical threshold temperature of thermal
Args :
temperature: A string of temperature, e.g. "30.125"
Returns:
A boolean, True if threshold is set successfully, False if not
"""
if isinstance(temperature, str) is not True:
raise TypeError('The parameter requires string type.')
try:
if temperature != self.NOT_AVAILABLE:
float(temperature)
except ValueError:
raise ValueError('The parameter requires a float string. ex:\"30.1\"')
return self.__set_data(self.HIGH_CRIT_THRESHOLD, temperature)
def get_low_critical_threshold(self):
"""
Retrieves the low critical threshold temperature from JSON file.
Returns:
string : the low critical threshold temperature of thermal,
e.g. "30.125"
"""
return self.__get_data(self.LOW_CRIT_THRESHOLD)
def set_low_critical_threshold(self, temperature):
"""
Sets the low critical threshold temperature of thermal
Args :
temperature: A string of temperature, e.g. "30.125"
Returns:
A boolean, True if threshold is set successfully, False if not
"""
if isinstance(temperature, str) is not True:
raise TypeError('The parameter requires string type.')
try:
if temperature != self.NOT_AVAILABLE:
float(temperature)
except ValueError:
raise ValueError('The parameter requires a float string. ex:\"30.1\"')
return self.__set_data(self.LOW_CRIT_THRESHOLD, temperature)

View File

@ -0,0 +1,19 @@
#############################################################################
# Edgecore
#
# Module contains an implementation of SONiC Platform Base API and
# provides the fan status which are available in the platform
# Base PCIe class
#############################################################################
try:
from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Pcie(PcieUtil):
"""Edgecore Platform-specific PCIe class"""
def __init__(self, platform_path):
PcieUtil.__init__(self, platform_path)

View File

@ -11,41 +11,120 @@ except ImportError as e:
class Psu(PddfPsu): class Psu(PddfPsu):
"""PDDF Platform-Specific PSU class""" """PDDF Platform-Specific PSU class"""
PLATFORM_PSU_CAPACITY = 1200
def __init__(self, index, pddf_data=None, pddf_plugin_data=None): def __init__(self, index, pddf_data=None, pddf_plugin_data=None):
PddfPsu.__init__(self, index, pddf_data, pddf_plugin_data) PddfPsu.__init__(self, index, pddf_data, pddf_plugin_data)
# Provide the functions/variables below for which implementation is to be overwritten # Provide the functions/variables below for which implementation is to be overwritten
def get_capacity(self): def get_name(self):
return "PSU-{}".format(self.psu_index)
def get_revision(self):
""" """
Gets the capacity (maximum output power) of the PSU in watts Retrieves the hardware revision of the device
Returns: Returns:
An integer, the capacity of PSU string: Revision value of device
""" """
return (self.PLATFORM_PSU_CAPACITY) return 'N/A'
def get_type(self): def get_temperature_high_threshold(self):
""" """
Gets the type of the PSU Retrieves the high threshold temperature of PSU
Returns:
A float number, the high threshold temperature of PSU in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
threshold = super().get_temperature_high_threshold()
for psu_thermal_idx in range(self.num_psu_thermals):
try:
tmp = self._thermal_list[psu_thermal_idx].get_high_threshold()
if threshold > tmp or threshold == 0.0:
threshold = tmp
except Exception:
pass
return threshold
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns: Returns:
A string, the type of PSU (AC/DC) string: Model/part number of device
""" """
ptype = "AC" model = super().get_model()
# Currently the platform supports only AC type of PSUs if model and model.strip() == "":
#try: return None
#import sonic_platform.platform
#ch=sonic_platform.platform.Platform().get_chassis() return model
#e=ch.sys_eeprom.read_eeprom()
#ret, prod_name = ch.sys_eeprom.get_tlv_field(e,0x21) def get_serial(self):
#if ret: """
#prod_name = prod_name[2] Retrieves the serial number of the device
##print("Product name is {}".format(prod_name))
#if '48V' in prod_name: Returns:
#ptype = 'DC' string: Serial number of device
#except Exception as e: """
#print("Error while trying to read syseeprom to get PSU type") serial = super().get_serial()
if serial and serial.strip() == "":
return None
return serial
def get_voltage(self):
"""
Retrieves current PSU voltage output
Returns:
A float number, the output voltage in volts,
e.g. 12.1
"""
if self.get_status() is not True:
return 0.0
return super().get_voltage()
def get_current(self):
"""
Retrieves present electric current supplied by PSU
Returns:
A float number, electric current in amperes,
e.g. 15.4
"""
if self.get_status() is not True:
return 0.0
return super().get_current()
def get_power(self):
"""
Retrieves current energy supplied by PSU
Returns:
A float number, the power in watts,
e.g. 302.6
"""
if self.get_status() is not True:
return 0.0
return super().get_power()
def get_maximum_supplied_power(self):
"""
Retrieves current energy supplied by PSU
Returns:
A float number, the power in watts,
e.g. 302.6
"""
device = "PSU{}".format(self.psu_index)
output = self.pddf_obj.get_attr_name_output(device, "psu_p_out_max")
if not output:
return 0.0
p_out = output['status']
# power is returned in micro watts
return float(p_out)/1000
return ptype

View File

@ -1,7 +1,10 @@
#!/usr/bin/env python #!/usr/bin/env python
try: try:
import natsort
from sonic_platform_pddf_base.pddf_sfp import PddfSfp from sonic_platform_pddf_base.pddf_sfp import PddfSfp
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
from sonic_py_common import device_info
except ImportError as e: except ImportError as e:
raise ImportError (str(e) + "- required module not found") raise ImportError (str(e) + "- required module not found")
@ -11,10 +14,197 @@ class Sfp(PddfSfp):
PDDF Platform-Specific Sfp class PDDF Platform-Specific Sfp class
""" """
SFP_TYPE_CODE_LIST = [
0x03, # SFP/SFP+/SFP28
0x0b # DWDM-SFP/SFP+
]
QSFP_TYPE_CODE_LIST = [
0x0c, # QSFP
0x0d, # QSFP+ or later
0x11, # QSFP28 or later
0xe1 # QSFP28 EDFA
]
def __init__(self, index, pddf_data=None, pddf_plugin_data=None): def __init__(self, index, pddf_data=None, pddf_plugin_data=None):
PddfSfp.__init__(self, index, pddf_data, pddf_plugin_data) PddfSfp.__init__(self, index, pddf_data, pddf_plugin_data)
self.index = self.port_index
# Provide the functions/variables below for which implementation is to be overwritten # Provide the functions/variables below for which implementation is to be overwritten
def get_position_in_parent(self): def get_position_in_parent(self):
"""Retrieves 1-based relative physical position in parent device.""" """Retrieves 1-based relative physical position in parent device."""
return self.port_index return self.port_index
def __get_path_to_port_config_file(self):
platform, hwsku = device_info.get_platform_and_hwsku()
hwsku_path = "/".join(["/usr/share/sonic/platform",hwsku])
return "/".join([hwsku_path, "port_config.ini"])
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
sfputil_helper = SfpUtilHelper()
sfputil_helper.read_porttab_mappings(
self.__get_path_to_port_config_file())
logical_port_list = sfputil_helper.logical
logical_port_list = natsort.natsorted(logical_port_list)
name = logical_port_list[self.port_index-1] or "Unknown"
return name
def __validate_eeprom_sfp(self):
checksum_test = 0
eeprom_raw = self.read_eeprom(0, 96)
if eeprom_raw is None:
return None
for i in range(0, 63):
checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF
else:
if checksum_test != eeprom_raw[63]:
return False
checksum_test = 0
for i in range(64, 95):
checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF
else:
if checksum_test != eeprom_raw[95]:
return False
api = self.get_xcvr_api()
if api is None:
return False
if api.is_flat_memory():
return True
checksum_test = 0
eeprom_raw = self.read_eeprom(384, 96)
if eeprom_raw is None:
return None
for i in range(0, 95):
checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF
else:
if checksum_test != eeprom_raw[95]:
return False
return True
def __validate_eeprom_qsfp(self):
checksum_test = 0
eeprom_raw = self.read_eeprom(128, 96)
if eeprom_raw is None:
return None
for i in range(0, 63):
checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF
else:
if checksum_test != eeprom_raw[63]:
return False
checksum_test = 0
for i in range(64, 95):
checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF
else:
if checksum_test != eeprom_raw[95]:
return False
api = self.get_xcvr_api()
if api is None:
return False
if api.is_flat_memory():
return True
return True
def validate_eeprom(self):
id_byte_raw = self.read_eeprom(0, 1)
if id_byte_raw is None:
return None
id = id_byte_raw[0]
if id in self.QSFP_TYPE_CODE_LIST:
return self.__validate_eeprom_qsfp()
elif id in self.SFP_TYPE_CODE_LIST:
return self.__validate_eeprom_sfp()
else:
return False
def validate_temperature(self):
temperature = self.get_temperature()
if temperature is None:
return None
threshold_dict = self.get_transceiver_threshold_info()
if threshold_dict is None:
return None
if isinstance(temperature, float) is not True:
return True
if isinstance(threshold_dict['temphighalarm'], float) is not True:
return True
return threshold_dict['temphighalarm'] > temperature
def __get_error_description(self):
if not self.get_presence():
return self.SFP_STATUS_UNPLUGGED
err_stat = self.SFP_STATUS_BIT_INSERTED
status = self.validate_eeprom()
if status is not True:
err_stat = (err_stat | self.SFP_ERROR_BIT_BAD_EEPROM)
status = self.validate_temperature()
if status is not True:
err_stat = (err_stat | self.SFP_ERROR_BIT_HIGH_TEMP)
if err_stat is self.SFP_STATUS_BIT_INSERTED:
return self.SFP_STATUS_OK
else:
err_desc = ''
cnt = 0
for key in self.SFP_ERROR_BIT_TO_DESCRIPTION_DICT:
if (err_stat & key) != 0:
if cnt > 0:
err_desc = err_desc + "|"
cnt = cnt + 1
err_desc = err_desc + self.SFP_ERROR_BIT_TO_DESCRIPTION_DICT[key]
return err_desc
def get_reset_status(self):
if self.sfp_type == "QSFP28":
return super().get_reset_status()
return False
def reset(self):
if self.sfp_type == "QSFP28":
return super().reset()
return False
def get_error_description(self):
"""
Retrives the error descriptions of the SFP module
Returns:
String that represents the current error descriptions of vendor specific errors
In case there are multiple errors, they should be joined by '|',
like: "Bad EEPROM|Unsupported cable"
"""
if self.sfp_type != "SFP28" and self.sfp_type != "QSFP28":
return "Not implemented"
try:
ret = super().get_error_description()
if ret is not None:
return ret
except NotImplementedError:
pass
return self.__get_error_description()

View File

@ -3,10 +3,55 @@
try: try:
from sonic_platform_pddf_base.pddf_thermal import PddfThermal from sonic_platform_pddf_base.pddf_thermal import PddfThermal
from .helper import DeviceThreshold
except ImportError as e: except ImportError as e:
raise ImportError(str(e) + "- required module not found") raise ImportError(str(e) + "- required module not found")
NOT_AVAILABLE = DeviceThreshold.NOT_AVAILABLE
HIGH_THRESHOLD = DeviceThreshold.HIGH_THRESHOLD
LOW_THRESHOLD = DeviceThreshold.LOW_THRESHOLD
HIGH_CRIT_THRESHOLD = DeviceThreshold.HIGH_CRIT_THRESHOLD
LOW_CRIT_THRESHOLD = DeviceThreshold.LOW_CRIT_THRESHOLD
DEFAULT_THRESHOLD = {
'Temp sensor 1' : {
HIGH_THRESHOLD : '80.0',
LOW_THRESHOLD : NOT_AVAILABLE,
HIGH_CRIT_THRESHOLD : NOT_AVAILABLE,
LOW_CRIT_THRESHOLD : NOT_AVAILABLE
},
'Temp sensor 2' : {
HIGH_THRESHOLD : '80.0',
LOW_THRESHOLD : NOT_AVAILABLE,
HIGH_CRIT_THRESHOLD : NOT_AVAILABLE,
LOW_CRIT_THRESHOLD : NOT_AVAILABLE
},
'Temp sensor 3' : {
HIGH_THRESHOLD : '80.0',
LOW_THRESHOLD : NOT_AVAILABLE,
HIGH_CRIT_THRESHOLD : NOT_AVAILABLE,
LOW_CRIT_THRESHOLD : NOT_AVAILABLE
},
'Temp sensor 4' : {
HIGH_THRESHOLD : '71.0',
LOW_THRESHOLD : NOT_AVAILABLE,
HIGH_CRIT_THRESHOLD : '91.0',
LOW_CRIT_THRESHOLD : NOT_AVAILABLE
},
'PSU-1 temp sensor 1' : {
HIGH_THRESHOLD : '80.0',
LOW_THRESHOLD : NOT_AVAILABLE,
HIGH_CRIT_THRESHOLD : NOT_AVAILABLE,
LOW_CRIT_THRESHOLD : NOT_AVAILABLE
},
'PSU-2 temp sensor 1' : {
HIGH_THRESHOLD : '80.0',
LOW_THRESHOLD : NOT_AVAILABLE,
HIGH_CRIT_THRESHOLD : NOT_AVAILABLE,
LOW_CRIT_THRESHOLD : NOT_AVAILABLE
}
}
class Thermal(PddfThermal): class Thermal(PddfThermal):
"""PDDF Platform-Specific Thermal class""" """PDDF Platform-Specific Thermal class"""
@ -14,4 +59,196 @@ class Thermal(PddfThermal):
def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0):
PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index)
# Threshold Configuration
self.__conf = DeviceThreshold(self.get_name())
# Default threshold.
self.__default_threshold = DEFAULT_THRESHOLD[self.get_name()]
self.min_temperature = None
self.max_temperature = None
# Provide the functions/variables below for which implementation is to be overwritten # Provide the functions/variables below for which implementation is to be overwritten
def get_name(self):
if self.is_psu_thermal:
return "PSU-{0} temp sensor 1".format(self.thermals_psu_index)
else:
return "Temp sensor {0}".format(self.thermal_index)
def get_status(self):
get_temp=self.get_temperature()
if get_temp is not None:
return True if get_temp else False
def get_temperature(self):
current = super().get_temperature()
if self.min_temperature is None or \
current < self.min_temperature:
self.min_temperature = current
if self.max_temperature is None or \
current > self.max_temperature:
self.max_temperature = current
return current
def set_high_threshold(self, temperature):
try:
value = float(temperature)
except Exception:
return False
# The new value can not be more than the default value.
default_value = self.__default_threshold[HIGH_THRESHOLD]
if default_value != NOT_AVAILABLE:
if value > float(default_value):
return False
try:
self.__conf.set_high_threshold(str(value))
except Exception:
return False
return True
def get_high_threshold(self):
value = self.__conf.get_high_threshold()
if value != NOT_AVAILABLE:
return float(value)
default_value = self.__default_threshold[HIGH_THRESHOLD]
if default_value != NOT_AVAILABLE:
return float(default_value)
raise NotImplementedError
def set_low_threshold(self, temperature):
try:
value = float(temperature)
except Exception:
return False
# The new value can not be less than the default value.
default_value = self.__default_threshold[LOW_THRESHOLD]
if default_value != NOT_AVAILABLE:
if value < float(default_value):
return False
try:
self.__conf.set_low_threshold(str(value))
except Exception:
return False
return True
def get_low_threshold(self):
value = self.__conf.get_low_threshold()
if value != NOT_AVAILABLE:
return float(value)
default_value = self.__default_threshold[LOW_THRESHOLD]
if default_value != NOT_AVAILABLE:
return float(default_value)
raise NotImplementedError
def set_high_critical_threshold(self, temperature):
try:
value = float(temperature)
except Exception:
return False
# The new value can not be more than the default value.
default_value = self.__default_threshold[HIGH_CRIT_THRESHOLD]
if default_value != NOT_AVAILABLE:
if value > float(default_value):
return False
try:
self.__conf.set_high_critical_threshold(str(value))
except Exception:
return False
return True
def get_high_critical_threshold(self):
value = self.__conf.get_high_critical_threshold()
if value != NOT_AVAILABLE:
return float(value)
default_value = self.__default_threshold[HIGH_CRIT_THRESHOLD]
if default_value != NOT_AVAILABLE:
return float(default_value)
raise NotImplementedError
def set_low_critical_threshold(self, temperature):
try:
value = float(temperature)
except Exception:
return False
# The new value can not be less than the default value.
default_value = self.__default_threshold[LOW_CRIT_THRESHOLD]
if default_value != NOT_AVAILABLE:
if value < float(default_value):
return False
try:
self.__conf.set_low_critical_threshold(str(value))
except Exception:
return False
return True
def get_low_critical_threshold(self):
value = self.__conf.get_low_critical_threshold()
if value != NOT_AVAILABLE:
return float(value)
default_value = self.__default_threshold[LOW_CRIT_THRESHOLD]
if default_value != NOT_AVAILABLE:
return float(default_value)
raise NotImplementedError
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
return "N/A"
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
return "N/A"
def get_minimum_recorded(self):
"""
Retrieves the minimum recorded temperature of thermal
Returns:
A float number, the minimum recorded temperature of thermal in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
if self.min_temperature is None:
self.get_temperature()
return self.min_temperature
def get_maximum_recorded(self):
"""
Retrieves the maximum recorded temperature of thermal
Returns:
A float number, the maximum recorded temperature of thermal in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
if self.max_temperature is None:
self.get_temperature()
return self.max_temperature

View File

@ -207,14 +207,24 @@ class device_monitor(object):
fan_fail_list[i] = 0 fan_fail_list[i] = 0
if sum(fan_fail_list) == NUM_FANS: if sum(fan_fail_list) == NUM_FANS:
logging.critical(
'Alarm for all fan faulty/absent is detected, disable PoE')
cmd_str = ["i2cset", "-f", "-y", "16", "0x20", "0x06", "0x0", "0x0", "0xff", "0xff", "0xff", "0xff", "0xff", "0xff", "0xff", "0xff", "0xFE", "i"]
getstatusoutput_noshell(cmd_str) # Disable PoE
# Critical: Either all the fans are faulty or they are removed, shutdown the system # Critical: Either all the fans are faulty or they are removed, shutdown the system
logging.critical('Alarm for all fan faulty/absent is detected') logging.critical('Alarm for all fan faulty/absent is detected')
logging.critical("Alarm for all fan faulty/absent is detected, reset DUT") logging.critical("Alarm for all fan faulty/absent is detected, shutdown DUT")
cmd_str = ["i2cset", "-y", "-f", "3", "0x60", "0x4", "0xE4"]
# Sync log buffer to disk
cmd_str = ["sync"]
getstatusoutput_noshell(cmd_str)
cmd_str = ["/sbin/fstrim", "-av"]
getstatusoutput_noshell(cmd_str)
time.sleep(3)
cmd_str = ["i2cset", "-y", "-f", "3", "0x60", "0x4", "0x74"]
time.sleep(2) time.sleep(2)
getstatusoutput_noshell('sync')
getstatusoutput_noshell('sync')
getstatusoutput_noshell('sync')
getstatusoutput_noshell(cmd_str) getstatusoutput_noshell(cmd_str)
elif sum(fan_fail_list) != 0: elif sum(fan_fail_list) != 0:
# Set the 100% speed only for first fan failure detection # Set the 100% speed only for first fan failure detection
@ -243,8 +253,13 @@ class device_monitor(object):
if temp[0] >= 70000: # LM77-48 if temp[0] >= 70000: # LM77-48
# critical case*/ # critical case*/
logging.critical(
'Alarm-Critical for temperature critical is detected, disable PoE')
cmd_str = ["i2cset", "-f", "-y", "16", "0x20", "0x06", "0x0", "0x0", "0xff", "0xff", "0xff", "0xff", "0xff", "0xff", "0xff", "0xff", "0xFE", "i"]
getstatusoutput_noshell(cmd_str) # Disable PoE
logging.critical('Alarm for temperature critical is detected') logging.critical('Alarm for temperature critical is detected')
logging.critical("Alarm-Critical for temperature critical is detected, reset DUT") logging.critical("Alarm-Critical for temperature critical is detected, shutdown DUT")
# Update the reboot cause file to reflect that critical temperature # Update the reboot cause file to reflect that critical temperature
# has been crossed. Upon next boot, the contents of this file will # has been crossed. Upon next boot, the contents of this file will
# be used to determine the cause of the previous reboot # be used to determine the cause of the previous reboot
@ -255,10 +270,14 @@ class device_monitor(object):
if status: if status:
logging.warning('Reboot cause file not updated. {}'.format(output)) logging.warning('Reboot cause file not updated. {}'.format(output))
cmd_str = ["i2cset", "-y", "-f", "3", "0x60", "0x4", "0xE4"] # Sync log buffer to disk
getstatusoutput_noshell('sync') cmd_str = ["sync"]
getstatusoutput_noshell('sync') getstatusoutput_noshell(cmd_str)
getstatusoutput_noshell('sync') cmd_str = ["/sbin/fstrim", "-av"]
getstatusoutput_noshell(cmd_str)
time.sleep(3)
cmd_str = ["i2cset", "-y", "-f", "3", "0x60", "0x4", "0x74"]
time.sleep(3) time.sleep(3)
getstatusoutput_noshell(cmd_str) getstatusoutput_noshell(cmd_str)

View File

@ -16,21 +16,30 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
Usage: %(scriptName)s [options] command object usage: accton_as4630_54pe_util.py [-h] [-d] [-f] {install,clean,api,api_clean,threshold} ...
options:
-h | --help : this help message AS4630-54PE Platform Utility
-d | --debug : run with debug mode
-f | --force : ignore error during installation or clean optional arguments:
command: -h, --help show this help message and exit
-d, --debug run with debug mode
-f, --force ignore error during installation or clean
Utility Command:
{install,clean,api,api_clean,threshold}
install : install drivers and generate related sysfs nodes install : install drivers and generate related sysfs nodes
clean : uninstall drivers and remove related sysfs nodes clean : uninstall drivers and remove related sysfs nodes
api : install SONiC platform API
api_clean : uninstall SONiC platform API
threshold : modify thermal threshold
""" """
import subprocess import subprocess
import getopt
import sys import sys
import logging import logging
import time import time
import os import os
import argparse
from sonic_py_common.general import getstatusoutput_noshell
PROJECT_NAME = 'as4630_54pe' PROJECT_NAME = 'as4630_54pe'
version = '0.0.1' version = '0.0.1'
@ -97,40 +106,48 @@ def main():
global DEBUG global DEBUG
global args global args
global FORCE global FORCE
global THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH
if len(sys.argv)<2: util_parser = argparse.ArgumentParser(description="AS4630-54PE Platform Utility")
show_help() util_parser.add_argument("-d", "--debug", dest='debug', action='store_true', default=False,
help="run with debug mode")
util_parser.add_argument("-f", "--force", dest='force', action='store_true', default=False,
help="ignore error during installation or clean")
subcommand = util_parser.add_subparsers(dest='cmd', title='Utility Command', required=True)
subcommand.add_parser('install', help=': install drivers and generate related sysfs nodes')
subcommand.add_parser('clean', help=': uninstall drivers and remove related sysfs nodes')
subcommand.add_parser('api', help=': install SONiC platform API')
subcommand.add_parser('api_clean', help=': uninstall SONiC platform API')
threshold_parser = subcommand.add_parser('threshold', help=': modify thermal threshold')
threshold_parser.add_argument("-l", dest='list', action='store_true', default=False,
help="list avaliable thermal")
threshold_parser.add_argument("-t", dest='thermal', type=str, metavar='THERMAL_NAME',
help="thermal name, ex: -t 'Temp sensor 1'")
threshold_parser.add_argument("-ht", dest='high_threshold', type=restricted_float,
metavar='THRESHOLD_VALUE',
help="high threshold: %.1f ~ %.1f" % (THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH))
threshold_parser.add_argument("-hct", dest='high_crit_threshold', type=restricted_float,
metavar='THRESHOLD_VALUE',
help="high critical threshold : %.1f ~ %.1f" % (THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH))
args = util_parser.parse_args()
options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help',
'debug',
'force',
])
if DEBUG == True: if DEBUG == True:
print(options)
print(args) print(args)
print(len(sys.argv)) print(len(sys.argv))
for opt, arg in options: DEBUG = args.debug
if opt in ('-h', '--help'): FORCE = 1 if args.force else 0
show_help()
elif opt in ('-d', '--debug'): if args.cmd == 'install':
DEBUG = True
logging.basicConfig(level=logging.INFO)
elif opt in ('-f', '--force'):
FORCE = 1
else:
logging.info('no option')
for arg in args:
if arg == 'install':
do_install() do_install()
elif arg == 'clean': elif args.cmd == 'clean':
do_uninstall() do_uninstall()
elif arg == 'api': elif args.cmd == 'api':
do_sonic_platform_install() do_sonic_platform_install()
elif arg == 'api_clean': elif args.cmd == 'api_clean':
do_sonic_platform_clean() do_sonic_platform_clean()
else: elif args.cmd == 'threshold':
show_help() do_threshold()
return 0 return 0
@ -382,5 +399,162 @@ def device_exist():
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0)
return not(ret1 or ret2) return not(ret1 or ret2)
THRESHOLD_RANGE_LOW = 30.0
THRESHOLD_RANGE_HIGH = 110.0
# Code to initialize chassis object
init_chassis_code = \
"import sonic_platform.platform\n"\
"platform = sonic_platform.platform.Platform()\n"\
"chassis = platform.get_chassis()\n\n"
# Looking for thermal
looking_for_thermal_code = \
"thermal = None\n"\
"all_thermals = chassis.get_all_thermals()\n"\
"for psu in chassis.get_all_psus():\n"\
" all_thermals += psu.get_all_thermals()\n"\
"for tmp in all_thermals:\n"\
" if '{}' == tmp.get_name():\n"\
" thermal = tmp\n"\
" break\n"\
"if thermal == None:\n"\
" print('{} not found!')\n"\
" exit(1)\n\n"
def avaliable_thermals():
global init_chassis_code
get_all_thermal_name_code = \
"thermal_list = []\n"\
"all_thermals = chassis.get_all_thermals()\n"\
"for psu in chassis.get_all_psus():\n"\
" all_thermals += psu.get_all_thermals()\n"\
"for tmp in all_thermals:\n"\
" thermal_list.append(tmp.get_name())\n"\
"print(str(thermal_list)[1:-1])\n"
all_code = "{}{}".format(init_chassis_code, get_all_thermal_name_code)
status, output = getstatusoutput_noshell(["docker", "exec", "pmon", "python3", "-c", all_code])
if status != 0:
return ""
return output
def restricted_float(x):
global THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH
try:
x = float(x)
except ValueError:
raise argparse.ArgumentTypeError("%r not a floating-point literal" % (x,))
if x < THRESHOLD_RANGE_LOW or x > THRESHOLD_RANGE_HIGH:
raise argparse.ArgumentTypeError("%r not in range [%.1f ~ %.1f]" %
(x, THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH))
return x
def get_high_threshold(name):
global init_chassis_code, looking_for_thermal_code
get_high_threshold_code = \
"try:\n"\
" print(thermal.get_high_threshold())\n"\
" exit(0)\n"\
"except NotImplementedError:\n"\
" print('Not implement the get_high_threshold method!')\n"\
" exit(1)"
all_code = "{}{}{}".format(init_chassis_code, looking_for_thermal_code.format(name, name),
get_high_threshold_code)
status, output = getstatusoutput_noshell(["docker", "exec", "pmon", "python3", "-c", all_code])
if status == 1:
return None
return float(output)
def get_high_crit_threshold(name):
global init_chassis_code, looking_for_thermal_code
get_high_crit_threshold_code = \
"try:\n"\
" print(thermal.get_high_critical_threshold())\n"\
" exit(0)\n"\
"except NotImplementedError:\n"\
" print('Not implement the get_high_critical_threshold method!')\n"\
" exit(1)"
all_code = "{}{}{}".format(init_chassis_code, looking_for_thermal_code.format(name, name),
get_high_crit_threshold_code)
status, output = getstatusoutput_noshell(["docker", "exec", "pmon", "python3", "-c", all_code])
if status == 1:
return None
return float(output)
def do_threshold():
global args, init_chassis_code, looking_for_thermal_code
if args.list:
print("Thermals: " + avaliable_thermals())
return
if args.thermal is None:
print("The following arguments are required: -t")
return
set_threshold_code = ""
if args.high_threshold is not None:
if args.high_crit_threshold is not None and \
args.high_threshold >= args.high_crit_threshold:
print("Invalid Threshold!(High threshold can not be more than " \
"or equal to high critical threshold.)")
exit(1)
high_crit = get_high_crit_threshold(args.thermal)
if high_crit is not None and \
args.high_threshold >= high_crit:
print("Invalid Threshold!(High threshold can not be more than " \
"or equal to high critical threshold.)")
exit(1)
set_threshold_code += \
"try:\n"\
" if thermal.set_high_threshold({}) is False:\n"\
" print('{}: set_high_threshold failure!')\n"\
" exit(1)\n"\
"except NotImplementedError:\n"\
" print('Not implement the set_high_threshold method!')\n"\
"print('Apply the new high threshold successfully.')\n"\
"\n".format(args.high_threshold, args.thermal)
if args.high_crit_threshold is not None:
high = get_high_threshold(args.thermal)
if high is not None and \
args.high_crit_threshold <= high:
print("Invalid Threshold!(High critical threshold can not " \
"be less than or equal to high threshold.)")
exit(1)
set_threshold_code += \
"try:\n"\
" if thermal.set_high_critical_threshold({}) is False:\n"\
" print('{}: set_high_critical_threshold failure!')\n"\
" exit(1)\n"\
"except NotImplementedError:\n"\
" print('Not implement the set_high_critical_threshold method!')\n"\
"print('Apply the new high critical threshold successfully.')\n"\
"\n".format(args.high_crit_threshold, args.thermal)
if set_threshold_code == "":
return
all_code = "{}{}{}".format(init_chassis_code, looking_for_thermal_code.format(args.thermal, args.thermal), set_threshold_code)
status, output = getstatusoutput_noshell(["docker", "exec", "pmon", "python3", "-c", all_code])
print(output)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -1,9 +1,7 @@
#!/bin/bash #!/bin/bash
#Due to the hardware design, as4630-54pe use "eth2" instead of "eth0" as management interface. # Re-install the igb and ixgbe again to make the NIC sequence follow the udev rule
#Rename netdev "eth0" and "eth2" to swap original "eth2" to "eth0". modprobe -r igb
modprobe -r ixgbe
ifconfig eth0 down modprobe igb
ip link set eth0 name eth3 modprobe ixgbe
ip link set eth2 name eth0
ifconfig eth0 up

View File

@ -27,6 +27,7 @@ UTILS_DIR := utils
SERVICE_DIR := service SERVICE_DIR := service
UDEV_DIR := udev UDEV_DIR := udev
CONF_DIR := conf CONF_DIR := conf
UDEV_DIR := udev
%: %:
dh $@ --with systemd,python3 --buildsystem=pybuild dh $@ --with systemd,python3 --buildsystem=pybuild

View File

@ -8,3 +8,5 @@ systemctl start pddf-platform-init.service
systemctl enable as4630-54pe-pddf-platform-monitor.service systemctl enable as4630-54pe-pddf-platform-monitor.service
systemctl start as4630-54pe-pddf-platform-monitor.service systemctl start as4630-54pe-pddf-platform-monitor.service
/usr/local/bin/restart_ixgbe.sh /usr/local/bin/restart_ixgbe.sh
systemctl enable as4630-54pe-platform-handle-mgmt-interface.service
systemctl start as4630-54pe-platform-handle-mgmt-interface.service