[DellEMC] S5212F and S5224F 2.0 API changes (#10315)
Why I did it S5212F - Platform API 2.0 changes S5224F - Platform API 2.0 changes How I did it Implemented the functional API's needed for Platform API 2.0 Added media_settings.json, pcie.yaml, platform.json, system_health_monitoring_config.json files. How to verify it Used the API 2.0 test suite to validate the test cases.
This commit is contained in:
parent
1d68efe671
commit
faecf38417
313
device/dell/x86_64-dellemc_s5212f_c3538-r0/media_settings.json
Normal file
313
device/dell/x86_64-dellemc_s5212f_c3538-r0/media_settings.json
Normal file
@ -0,0 +1,313 @@
|
||||
{
|
||||
"GLOBAL_MEDIA_SETTINGS": {
|
||||
"1-12": {
|
||||
"(.*-C6Y7M)|(.*-V250M)|(.*-05CWK6)|(.*-53HVN)|(.*-358VV)|(.*-MV799)|(.*-59970000.)|(.*-P4YPY)|(.*-TCPM2)|(.*-JNPF8)|(.*-27GG5)|(.*-P8T4W)|(.*-JR54Y)|(.*-L56[SQ]F0..-SD-R)|(.*-61676000.)|(.*-74752.*)|(SFP\\+-CR-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x19410a"
|
||||
}
|
||||
},
|
||||
"(.*-58KM3)|(.*-2JVDD)|(.*-26FN3)|(SFP28-CR-((0\\.5)|(1\\.0)|(0\\.0)|(N/A)))": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x16440a"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-D0R73)|(.*-YFNDD)|(SFP28-CR-2\\.0)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15430c"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-VXFJY)|(.*-7R9N9)|(SFP28-CR-3\\.0)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x17400d"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-9X8JP)|(SFP28-CR-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x173f0e"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"13-15": {
|
||||
"(.*-035KG)|(.*-P7C7N)|(QSFP28-CR-((0\\.5)|(1\\.0)|(0\\.0)|(N/A)))": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x16440a",
|
||||
"lane1": "0x16440a",
|
||||
"lane2": "0x16440a",
|
||||
"lane3": "0x16440a"
|
||||
}
|
||||
},
|
||||
|
||||
".*-76V43|(QSFP28-CR-2\\.0)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15430c",
|
||||
"lane1": "0x15430c",
|
||||
"lane2": "0x15430c",
|
||||
"lane3": "0x15430c"
|
||||
}
|
||||
},
|
||||
|
||||
".*-3CC35|(QSFP28-CR-3\\.0)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15430c",
|
||||
"lane1": "0x15430c",
|
||||
"lane2": "0x15430c",
|
||||
"lane3": "0x15430c"
|
||||
}
|
||||
},
|
||||
|
||||
".*-FN4FC|(QSFP28-CR-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x10460e",
|
||||
"lane1": "0x10460e",
|
||||
"lane2": "0x10460e",
|
||||
"lane3": "0x10460e"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"PORT_MEDIA_SETTINGS": {
|
||||
"1": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x073702"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15450a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"2": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x073702"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x14460a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"3": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x063602"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15450a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"4": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x073702"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x16440a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"5": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x063602"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15450a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"6": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x073702"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15450a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"7": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x063602"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15450a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"8": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x073702"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x16440a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"9": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x063602"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15450a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"10": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x073702"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15450a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"11": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x063602"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x15450a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"12": {
|
||||
"(.*-WTRD1)|(.*-RN84N)|(.*-DT87G)|(.*-HMTNW)|(.*-1F80G)|(.*-6K3Y6)|(.*-YJF03)|(.*-P9GND)|(.*-T1KCN)|(.*-1DXKP)|(.*-MT7R2)|(.*-C4DD6)|(.*-8JHPY)|(.*-PGYJT)|(.*-FCBG110SD1C)|(.*-FCCG125SD1C)|(SFP\\+-.*)": {
|
||||
|
||||
"preemphasis": {
|
||||
"lane0": "0x073702"
|
||||
}
|
||||
},
|
||||
|
||||
"(.*-P7D7R)|(.*-W4GPP)|(.*-07RN7)|(.*-3YWG7)|(.*-5CMT2)|(.*-FTLF8540P4BCL)|(SFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x16440a"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"13": {
|
||||
"(.*-14NV5)|(.*-D7P80)|(.*-THPF3)|(.*-X7CCC)|(.*-YKMH7)|(.*-0X9CT)|(.*-05J8P)|(.*-5WGKD)|(.*-XFDRT)|(.*-1002971101)|(QSFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x134809",
|
||||
"lane1": "0x134809",
|
||||
"lane2": "0x134809",
|
||||
"lane3": "0x134809"
|
||||
}
|
||||
},
|
||||
|
||||
"QSFP\\+-.*": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x134809",
|
||||
"lane1": "0x134809",
|
||||
"lane2": "0x134809",
|
||||
"lane3": "0x134809"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"14": {
|
||||
"(.*-14NV5)|(.*-D7P80)|(.*-THPF3)|(.*-X7CCC)|(.*-YKMH7)|(.*-0X9CT)|(.*-05J8P)|(.*-5WGKD)|(.*-XFDRT)|(.*-1002971101)|(QSFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x134809",
|
||||
"lane1": "0x134809",
|
||||
"lane2": "0x134809",
|
||||
"lane3": "0x134809"
|
||||
}
|
||||
},
|
||||
|
||||
"QSFP\\+-.*": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x134809",
|
||||
"lane1": "0x134809",
|
||||
"lane2": "0x134809",
|
||||
"lane3": "0x134809"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"15": {
|
||||
"(.*-14NV5)|(.*-D7P80)|(.*-THPF3)|(.*-X7CCC)|(.*-YKMH7)|(.*-0X9CT)|(.*-05J8P)|(.*-5WGKD)|(.*-XFDRT)|(.*-1002971101)|(QSFP28-.*)": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x13470a",
|
||||
"lane1": "0x13470a",
|
||||
"lane2": "0x13470a",
|
||||
"lane3": "0x13470a"
|
||||
}
|
||||
},
|
||||
|
||||
"QSFP\\+-.*": {
|
||||
"preemphasis": {
|
||||
"lane0": "0x13470a",
|
||||
"lane1": "0x13470a",
|
||||
"lane2": "0x13470a",
|
||||
"lane3": "0x13470a"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
device/dell/x86_64-dellemc_s5212f_c3538-r0/pcie.yaml
Normal file
36
device/dell/x86_64-dellemc_s5212f_c3538-r0/pcie.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
- bus: '00'
|
||||
dev: '09'
|
||||
fn: '0'
|
||||
id: '19a4'
|
||||
name: 'Intel Corporation Atom Processor C3000 Series PCI Express Root Port #0 (rev 11)'
|
||||
- bus: '00'
|
||||
dev: '0b'
|
||||
fn: '0'
|
||||
id: '19a6'
|
||||
name: 'Intel Corporation Atom Processor C3000 Series PCI Express Root Port #2 (rev 11)'
|
||||
- bus: '00'
|
||||
dev: '0c'
|
||||
fn: '0'
|
||||
id: '19a7'
|
||||
name: 'Intel Corporation Atom Processor C3000 Series PCI Express Root Port #3 (rev 11)'
|
||||
- bus: '02'
|
||||
dev: '00'
|
||||
fn: '0'
|
||||
id: '1533'
|
||||
name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev
|
||||
03)'
|
||||
- bus: '01'
|
||||
dev: '00'
|
||||
fn: '0'
|
||||
id: 'b771'
|
||||
name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b771 (rev 01)'
|
||||
- bus: '03'
|
||||
dev: '00'
|
||||
fn: '0'
|
||||
id: '7021'
|
||||
name: 'Non-VGA unclassified device: Xilinx Corporation Device 7021'
|
||||
- bus: '00'
|
||||
dev: '14'
|
||||
fn: '0'
|
||||
id: '19c2'
|
||||
name: 'SATA controller: Intel Corporation DNV SATA Controller 1 (rev 11)'
|
342
device/dell/x86_64-dellemc_s5212f_c3538-r0/platform.json
Normal file
342
device/dell/x86_64-dellemc_s5212f_c3538-r0/platform.json
Normal file
@ -0,0 +1,342 @@
|
||||
{
|
||||
"chassis": {
|
||||
"name": "S5212F-ON",
|
||||
"status_led": {
|
||||
"controllable": true,
|
||||
"colors": ["blinking_green", "green", "amber", "blinking_amber"]
|
||||
},
|
||||
"thermal_manager": false,
|
||||
"components": [
|
||||
{
|
||||
"name": "BIOS"
|
||||
},
|
||||
{
|
||||
"name": "FPGA"
|
||||
},
|
||||
{
|
||||
"name": "BMC"
|
||||
},
|
||||
{
|
||||
"name": "System CPLD"
|
||||
},
|
||||
{
|
||||
"name": "Slave CPLD 1"
|
||||
}
|
||||
],
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray1-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray1-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray2-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray2-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray3-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray3-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray4-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray4-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"fan_drawers":[
|
||||
{
|
||||
"name": "FanTray1",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray1-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray1-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "FanTray2",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray2-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray2-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "FanTray3",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray3-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray3-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "FanTray4",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray4-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray4-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"psus": [
|
||||
{
|
||||
"name": "PSU1",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "PSU1 Fan",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PSU2",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "PSU2 Fan",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"thermals": [
|
||||
{
|
||||
"name": "CPU On-board",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "ASIC On-board",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "System Front Left",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "System Front Middle",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "System Front Right",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "Inlet Airflow Sensor",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
}
|
||||
],
|
||||
"modules": [],
|
||||
"sfps": [
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "QSFP28 or later"
|
||||
},
|
||||
{
|
||||
"name": "QSFP28 or later"
|
||||
},
|
||||
{
|
||||
"name": "QSFP28 or later"
|
||||
}
|
||||
]
|
||||
},
|
||||
"interfaces": {}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#############################################################################
|
||||
# DellEMC S5248f
|
||||
# DellEMC S5212f
|
||||
#
|
||||
# Platform and model specific eeprom subclass, inherits from the base class,
|
||||
# and provides the followings:
|
||||
@ -9,10 +9,11 @@
|
||||
# - specific encoder/decoder if there is special need
|
||||
#############################################################################
|
||||
|
||||
import os.path
|
||||
|
||||
try:
|
||||
import os.path
|
||||
from sonic_eeprom import eeprom_tlvinfo
|
||||
except ImportError, e:
|
||||
except ImportError as e:
|
||||
raise ImportError (str(e) + "- required module not found")
|
||||
|
||||
|
||||
|
@ -3,6 +3,19 @@
|
||||
# Platform-specific PSU status interface for SONiC
|
||||
#
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
S5212F_MAX_PSUS = 2
|
||||
IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list"
|
||||
IPMI_PSU_DATA_DOCKER = "ipmitool sdr list"
|
||||
PSU_PRESENCE = "PSU{0}_stat"
|
||||
# Use this for older firmware
|
||||
# PSU_PRESENCE="PSU{0}_prsnt"
|
||||
ipmi_sdr_list = ""
|
||||
|
||||
|
||||
try:
|
||||
from sonic_psu.psu_base import PsuBase
|
||||
except ImportError as e:
|
||||
@ -17,7 +30,38 @@ class PsuUtil(PsuBase):
|
||||
|
||||
def isDockerEnv(self):
|
||||
num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker")
|
||||
return (num_docker > 0)
|
||||
if num_docker > 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
# Fetch a BMC register
|
||||
def get_pmc_register(self, reg_name):
|
||||
|
||||
global ipmi_sdr_list
|
||||
ipmi_cmd = IPMI_PSU_DATA
|
||||
dockerenv = self.isDockerEnv()
|
||||
if dockerenv == True:
|
||||
ipmi_cmd = IPMI_PSU_DATA_DOCKER
|
||||
|
||||
status, ipmi_sdr_list = subprocess.getstatusoutput(ipmi_cmd)
|
||||
|
||||
if status:
|
||||
logging.error('Failed to execute:' + ipmi_sdr_list)
|
||||
sys.exit(0)
|
||||
|
||||
for item in ipmi_sdr_list.split("\n"):
|
||||
if reg_name in item:
|
||||
output = item.strip()
|
||||
|
||||
if not output:
|
||||
print('\nFailed to fetch: ' + reg_name + ' sensor ')
|
||||
sys.exit(0)
|
||||
|
||||
output = output.split('|')[1]
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
return output
|
||||
|
||||
def get_num_psus(self):
|
||||
"""
|
||||
@ -37,7 +81,8 @@ class PsuUtil(PsuBase):
|
||||
"""
|
||||
# Until psu_status is implemented this is hardcoded temporarily
|
||||
|
||||
return 1
|
||||
status = 1
|
||||
return status
|
||||
|
||||
def get_psu_presence(self, index):
|
||||
"""
|
||||
@ -46,5 +91,6 @@ class PsuUtil(PsuBase):
|
||||
:param index: An integer, index of the PSU of which to query status
|
||||
:return: Boolean, True if PSU is plugged, False if not
|
||||
"""
|
||||
return 1
|
||||
cmd_status, psu_status = subprocess.getstatusoutput('ipmitool raw 0x04 0x2d ' + hex(0x30 + index) + " | awk '{print substr($0,9,1)}'")
|
||||
return 1 if psu_status == '1' else 0
|
||||
|
||||
|
@ -45,7 +45,7 @@ SFP_MODULE_THRESHOLD_WIDTH = 56
|
||||
XCVR_DOM_CAPABILITY_OFFSET = 92
|
||||
XCVR_DOM_CAPABILITY_WIDTH = 1
|
||||
|
||||
XCVR_EEPROM_TYPE_SFP = 1
|
||||
|
||||
class SfpUtil(SfpUtilBase):
|
||||
"""Platform-specific SfpUtil class"""
|
||||
|
||||
@ -147,10 +147,10 @@ class SfpUtil(SfpUtilBase):
|
||||
return False
|
||||
|
||||
# Port offset starts with 0x4004
|
||||
port_offset = 16388 + ((port_num-1) * 16)
|
||||
port_offset = 16388 + ((port_num-1) * 16)
|
||||
|
||||
status = self.pci_get_value(self.BASE_RES_PATH, port_offset)
|
||||
reg_value = int(status)
|
||||
status = self.pci_get_value(self.BASE_RES_PATH, port_offset)
|
||||
reg_value = int(status)
|
||||
|
||||
# Absence of status throws error
|
||||
if (reg_value == "" ):
|
||||
@ -161,7 +161,6 @@ class SfpUtil(SfpUtilBase):
|
||||
if (port_num > 12):
|
||||
mask = (1 << 4)
|
||||
|
||||
|
||||
# ModPrsL is active low
|
||||
if reg_value & mask == 0:
|
||||
return True
|
||||
@ -174,17 +173,17 @@ class SfpUtil(SfpUtilBase):
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
|
||||
# Port offset starts with 0x4000
|
||||
port_offset = 16384 + ((port_num-1) * 16)
|
||||
# Port offset starts with 0x4000
|
||||
port_offset = 16384 + ((port_num-1) * 16)
|
||||
|
||||
status = self.pci_get_value(self.BASE_RES_PATH, port_offset)
|
||||
reg_value = int(status)
|
||||
status = self.pci_get_value(self.BASE_RES_PATH, port_offset)
|
||||
reg_value = int(status)
|
||||
|
||||
# Absence of status throws error
|
||||
if (reg_value == "" ):
|
||||
return False
|
||||
|
||||
# Mask off 4th bit for presence
|
||||
# Mask off 6th bit for lpmode status
|
||||
mask = (1 << 6)
|
||||
|
||||
# LPMode is active high
|
||||
@ -199,62 +198,68 @@ class SfpUtil(SfpUtilBase):
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
|
||||
# Port offset starts with 0x4000
|
||||
port_offset = 16384 + ((port_num-1) * 16)
|
||||
# Port offset starts with 0x4000
|
||||
port_offset = 16384 + ((port_num-1) * 16)
|
||||
|
||||
status = self.pci_get_value(self.BASE_RES_PATH, port_offset)
|
||||
reg_value = int(status)
|
||||
status = self.pci_get_value(self.BASE_RES_PATH, port_offset)
|
||||
reg_value = int(status)
|
||||
|
||||
# Absence of status throws error
|
||||
if (reg_value == "" ):
|
||||
return False
|
||||
|
||||
# Mask off 4th bit for presence
|
||||
# Mask off 6th bit for lpmode status
|
||||
mask = (1 << 6)
|
||||
|
||||
# LPMode is active high; set or clear the bit accordingly
|
||||
# LPMode is active high; set or clear the bit accordingly
|
||||
if lpmode is True:
|
||||
reg_value = reg_value | mask
|
||||
else:
|
||||
reg_value = reg_value & ~mask
|
||||
|
||||
# Convert our register value back to a hex string and write back
|
||||
self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset)
|
||||
status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset)
|
||||
if status != reg_value:
|
||||
print ("Error: Set LP mode status %d", status)
|
||||
|
||||
return True
|
||||
|
||||
def reset(self, port_num):
|
||||
|
||||
# Check for invalid port_num
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
|
||||
# Port offset starts with 0x4000
|
||||
port_offset = 16384 + ((port_num-1) * 16)
|
||||
# Port offset starts with 0x4000
|
||||
port_offset = 16384 + ((port_num-1) * 16)
|
||||
|
||||
status = self.pci_get_value(self.BASE_RES_PATH, port_offset)
|
||||
reg_value = int(status)
|
||||
status = self.pci_get_value(self.BASE_RES_PATH, port_offset)
|
||||
reg_value = int(status)
|
||||
|
||||
# Absence of status throws error
|
||||
if (reg_value == "" ):
|
||||
return False
|
||||
|
||||
# Mask off 4th bit for presence
|
||||
mask = (1 << 6)
|
||||
# Mask off 4th bit for reset status
|
||||
mask = (1 << 4)
|
||||
|
||||
# ResetL is active low
|
||||
reg_value = reg_value & ~mask
|
||||
|
||||
# Convert our register value back to a hex string and write back
|
||||
self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset)
|
||||
# Convert our register value back to a hex string and write back
|
||||
status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset)
|
||||
if status != reg_value:
|
||||
print ("Error: pci_set_value reset status %d", status)
|
||||
|
||||
# Sleep 1 second to allow it to settle
|
||||
time.sleep(1)
|
||||
|
||||
reg_value = reg_value | mask
|
||||
|
||||
# Convert our register value back to a hex string and write back
|
||||
self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset)
|
||||
# Convert our register value back to a hex string and write back
|
||||
status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset)
|
||||
if status != reg_value:
|
||||
print ("Error: pci_set_value reset status %d", status)
|
||||
|
||||
return True
|
||||
|
||||
@ -276,7 +281,6 @@ class SfpUtil(SfpUtilBase):
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
|
||||
def get_transceiver_dom_info_dict(self, port_num):
|
||||
transceiver_dom_info_dict = {}
|
||||
|
||||
@ -288,8 +292,8 @@ class SfpUtil(SfpUtilBase):
|
||||
]
|
||||
transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A')
|
||||
|
||||
if port_num in self.qsfp_ports:
|
||||
offset = 0
|
||||
if port_num in self.qsfp_ports:
|
||||
offset = 0
|
||||
offset_xcvr = 128
|
||||
file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR)
|
||||
if not self._sfp_eeprom_present(file_path, 0):
|
||||
@ -320,7 +324,7 @@ class SfpUtil(SfpUtilBase):
|
||||
return transceiver_dom_info_dict
|
||||
|
||||
dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH)
|
||||
if dom_temperature_raw is not None:
|
||||
if dom_temperature_raw is not None:
|
||||
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
|
||||
else:
|
||||
return transceiver_dom_info_dict
|
||||
@ -352,11 +356,11 @@ class SfpUtil(SfpUtilBase):
|
||||
else:
|
||||
return transceiver_dom_info_dict
|
||||
|
||||
transceiver_dom_info_dict['tx1power'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx1power'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx2power'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx3power'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx4power'] = 'N/A'
|
||||
try:
|
||||
try:
|
||||
sysfsfile_eeprom.close()
|
||||
except IOError:
|
||||
print("Error: closing sysfs file %s" % file_path)
|
||||
@ -374,7 +378,7 @@ class SfpUtil(SfpUtilBase):
|
||||
transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value']
|
||||
|
||||
else:
|
||||
offset = 256
|
||||
offset = 256
|
||||
file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR)
|
||||
if not self._sfp_eeprom_present(file_path, 0):
|
||||
return None
|
||||
@ -387,10 +391,10 @@ class SfpUtil(SfpUtilBase):
|
||||
|
||||
sfpd_obj = sff8472Dom(None,1)
|
||||
if sfpd_obj is None:
|
||||
return transceiver_dom_info_dict
|
||||
return None
|
||||
|
||||
dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET),
|
||||
SFP_TEMPE_WIDTH)
|
||||
SFP_TEMPE_WIDTH)
|
||||
|
||||
if dom_temperature_raw is not None:
|
||||
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
|
||||
@ -432,7 +436,7 @@ class SfpUtil(SfpUtilBase):
|
||||
transceiver_dom_info_dict['tx3power'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx4power'] = 'N/A'
|
||||
|
||||
return transceiver_dom_info_dict
|
||||
return transceiver_dom_info_dict
|
||||
|
||||
def get_transceiver_dom_threshold_info_dict(self, port_num):
|
||||
transceiver_dom_threshold_info_dict = {}
|
||||
@ -450,115 +454,116 @@ class SfpUtil(SfpUtilBase):
|
||||
transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A')
|
||||
|
||||
if port_num in self.qsfp_ports:
|
||||
file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR)
|
||||
if not self._sfp_eeprom_present(file_path, 0):
|
||||
file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR)
|
||||
if not self._sfp_eeprom_present(file_path, 0):
|
||||
return None
|
||||
|
||||
try:
|
||||
try:
|
||||
sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0)
|
||||
except IOError:
|
||||
except IOError:
|
||||
print("Error: reading sysfs file %s" % file_path)
|
||||
return None
|
||||
|
||||
sfpd_obj = sff8436Dom()
|
||||
if sfpd_obj is None:
|
||||
sfpd_obj = sff8436Dom()
|
||||
if sfpd_obj is None:
|
||||
return transceiver_dom_threshold_info_dict
|
||||
|
||||
# Dom Threshold data starts from offset 384
|
||||
# Revert offset back to 0 once data is retrieved
|
||||
offset = 384
|
||||
dom_module_threshold_raw = self._read_eeprom_specific_bytes(
|
||||
offset = 384
|
||||
dom_module_threshold_raw = self._read_eeprom_specific_bytes(
|
||||
sysfsfile_eeprom,
|
||||
(offset + QSFP_MODULE_THRESHOLD_OFFSET),
|
||||
QSFP_MODULE_THRESHOLD_WIDTH)
|
||||
if dom_module_threshold_raw is not None:
|
||||
if dom_module_threshold_raw is not None:
|
||||
dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0)
|
||||
else:
|
||||
else:
|
||||
return transceiver_dom_threshold_info_dict
|
||||
|
||||
dom_channel_threshold_raw = self._read_eeprom_specific_bytes(
|
||||
dom_channel_threshold_raw = self._read_eeprom_specific_bytes(
|
||||
sysfsfile_eeprom,
|
||||
(offset + QSFP_CHANNL_THRESHOLD_OFFSET),
|
||||
QSFP_CHANNL_THRESHOLD_WIDTH)
|
||||
if dom_channel_threshold_raw is not None:
|
||||
if dom_channel_threshold_raw is not None:
|
||||
dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0)
|
||||
else:
|
||||
else:
|
||||
return transceiver_dom_threshold_info_dict
|
||||
|
||||
try:
|
||||
try:
|
||||
sysfsfile_eeprom.close()
|
||||
except IOError:
|
||||
except IOError:
|
||||
print("Error: closing sysfs file %s" % file_path)
|
||||
return None
|
||||
|
||||
# Threshold Data
|
||||
transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value']
|
||||
|
||||
else:
|
||||
offset = 256
|
||||
file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR)
|
||||
if not self._sfp_eeprom_present(file_path, 0):
|
||||
offset = 256
|
||||
file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR)
|
||||
if not self._sfp_eeprom_present(file_path, 0):
|
||||
return None
|
||||
|
||||
try:
|
||||
try:
|
||||
sysfsfile_eeprom = io.open(file_path,"rb",0)
|
||||
except IOError:
|
||||
except IOError:
|
||||
print("Error: reading sysfs file %s" % file_path)
|
||||
return None
|
||||
|
||||
sfpd_obj = sff8472Dom(None,1)
|
||||
if sfpd_obj is None:
|
||||
sfpd_obj = sff8472Dom(None,1)
|
||||
if sfpd_obj is None:
|
||||
return transceiver_dom_threshold_info_dict
|
||||
|
||||
dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom,
|
||||
dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom,
|
||||
(offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH)
|
||||
|
||||
if dom_module_threshold_raw is not None:
|
||||
if dom_module_threshold_raw is not None:
|
||||
dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0)
|
||||
else:
|
||||
else:
|
||||
return transceiver_dom_threshold_info_dict
|
||||
|
||||
try:
|
||||
try:
|
||||
sysfsfile_eeprom.close()
|
||||
except IOError:
|
||||
except IOError:
|
||||
print("Error: closing sysfs file %s" % file_path)
|
||||
return None
|
||||
|
||||
#Threshold Data
|
||||
transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value']
|
||||
|
||||
return transceiver_dom_threshold_info_dict
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"services_to_ignore": [],
|
||||
"devices_to_ignore": ["fan.speed"],
|
||||
"user_defined_checkers": [],
|
||||
"polling_interval": 60,
|
||||
"led_color": {
|
||||
"fault": "amber",
|
||||
"normal": "green",
|
||||
"booting": "blinking_green"
|
||||
}
|
||||
}
|
41
device/dell/x86_64-dellemc_s5224f_c3538-r0/pcie.yaml
Normal file
41
device/dell/x86_64-dellemc_s5224f_c3538-r0/pcie.yaml
Normal file
@ -0,0 +1,41 @@
|
||||
- bus: '00'
|
||||
dev: '09'
|
||||
fn: '0'
|
||||
id: '19a4'
|
||||
name: 'Intel Corporation Atom Processor C3000 Series PCI Express Root Port #0 (rev 11)'
|
||||
- bus: '00'
|
||||
dev: '0b'
|
||||
fn: '0'
|
||||
id: '19a6'
|
||||
name: 'Intel Corporation Atom Processor C3000 Series PCI Express Root Port #2 (rev 11)'
|
||||
- bus: '00'
|
||||
dev: '0c'
|
||||
fn: '0'
|
||||
id: '19a7'
|
||||
name: 'Intel Corporation Atom Processor C3000 Series PCI Express Root Port #3 (rev 11)'
|
||||
- bus: '00'
|
||||
dev: '0e'
|
||||
fn: '0'
|
||||
id: '19a8'
|
||||
name: 'Intel Corporation Atom Processor C3000 Series PCI Express Root Port #4 (rev 11)'
|
||||
- bus: '03'
|
||||
dev: '00'
|
||||
fn: '0'
|
||||
id: '1533'
|
||||
name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev
|
||||
03)'
|
||||
- bus: '02'
|
||||
dev: '00'
|
||||
fn: '0'
|
||||
id: b771
|
||||
name: 'Ethernet controller: Broadcom Limited Device b771 (rev 01)'
|
||||
- bus: '04'
|
||||
dev: '00'
|
||||
fn: '0'
|
||||
id: '7021'
|
||||
name: 'Non-VGA unclassified device: Xilinx Corporation Device 7021'
|
||||
- bus: '00'
|
||||
dev: '14'
|
||||
fn: '0'
|
||||
id: 19c2
|
||||
name: 'SATA controller: Intel Corporation DNV SATA Controller 1 (rev 11)'
|
397
device/dell/x86_64-dellemc_s5224f_c3538-r0/platform.json
Normal file
397
device/dell/x86_64-dellemc_s5224f_c3538-r0/platform.json
Normal file
@ -0,0 +1,397 @@
|
||||
{
|
||||
"chassis": {
|
||||
"name": "S5224F-ON",
|
||||
"status_led": {
|
||||
"controllable": true,
|
||||
"colors": ["blinking_green", "green", "amber", "blinking_amber"]
|
||||
},
|
||||
"thermal_manager": false,
|
||||
"components": [
|
||||
{
|
||||
"name": "BIOS"
|
||||
},
|
||||
{
|
||||
"name": "FPGA"
|
||||
},
|
||||
{
|
||||
"name": "BMC"
|
||||
},
|
||||
{
|
||||
"name": "System CPLD"
|
||||
},
|
||||
{
|
||||
"name": "Slave CPLD 1"
|
||||
}
|
||||
],
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray1-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray1-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray2-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray2-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray3-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray3-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray4-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray4-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"fan_drawers":[
|
||||
{
|
||||
"name": "FanTray1",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray1-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray1-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "FanTray2",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray2-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray2-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "FanTray3",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray3-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray3-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "FanTray4",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "FanTray4-Fan1",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FanTray4-Fan2",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"psus": [
|
||||
{
|
||||
"name": "PSU1",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "PSU1 Fan",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PSU2",
|
||||
"status_led": {
|
||||
"controllable": false
|
||||
},
|
||||
"fans": [
|
||||
{
|
||||
"name": "PSU2 Fan",
|
||||
"speed": {
|
||||
"controllable": false
|
||||
},
|
||||
"status_led": {
|
||||
"available": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"thermals": [
|
||||
{
|
||||
"name": "CPU On-board",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "ASIC On-board",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "System Front Left",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "System Front Middle",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "System Front Right",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "Inlet Airflow Sensor",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "PSU1 Airflow Sensor",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
},
|
||||
{
|
||||
"name": "PSU2 Airflow Sensor",
|
||||
"controllable": false,
|
||||
"low-crit-threshold": false,
|
||||
"high-threshold": false,
|
||||
"minimum-recorded": false,
|
||||
"maximum-recorded": false
|
||||
}
|
||||
],
|
||||
"modules": [],
|
||||
"sfps": [
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "SFP/SFP+/SFP28"
|
||||
},
|
||||
{
|
||||
"name": "QSFP28 or later"
|
||||
},
|
||||
{
|
||||
"name": "QSFP28 or later"
|
||||
},
|
||||
{
|
||||
"name": "QSFP28 or later"
|
||||
},
|
||||
{
|
||||
"name": "QSFP28 or later"
|
||||
}
|
||||
]
|
||||
},
|
||||
"interfaces": {}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
- bus: '03'
|
||||
dev: '00'
|
||||
fn: '0'
|
||||
id: '1533'
|
||||
name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev
|
||||
03)'
|
||||
- bus: '02'
|
||||
dev: '00'
|
||||
fn: '0'
|
||||
id: b771
|
||||
name: 'Ethernet controller: Broadcom Limited Device b771 (rev 01)'
|
||||
- bus: '04'
|
||||
dev: '00'
|
||||
fn: '0'
|
||||
id: '7021'
|
||||
name: 'Non-VGA unclassified device: Xilinx Corporation Device 7021'
|
||||
- bus: '00'
|
||||
dev: '14'
|
||||
fn: '0'
|
||||
id: 19c2
|
||||
name: 'SATA controller: Intel Corporation DNV SATA Controller 1 (rev 11)'
|
@ -48,7 +48,6 @@ XCVR_DOM_CAPABILITY_OFFSET = 92
|
||||
XCVR_DOM_CAPABILITY_WIDTH = 1
|
||||
|
||||
|
||||
|
||||
class SfpUtil(SfpUtilBase):
|
||||
"""Platform-specific SfpUtil class"""
|
||||
|
||||
@ -166,7 +165,7 @@ class SfpUtil(SfpUtilBase):
|
||||
if (reg_value == "" ):
|
||||
return False
|
||||
|
||||
# Mask off 4th bit for presence
|
||||
# Mask off 6th bit for lpmode status
|
||||
mask = (1 << 6)
|
||||
|
||||
# LPMode is active high
|
||||
@ -191,7 +190,7 @@ class SfpUtil(SfpUtilBase):
|
||||
if (reg_value == "" ):
|
||||
return False
|
||||
|
||||
# Mask off 4th bit for presence
|
||||
# Mask off 6th bit for lpmode status
|
||||
mask = (1 << 6)
|
||||
|
||||
# LPMode is active high; set or clear the bit accordingly
|
||||
@ -223,8 +222,8 @@ class SfpUtil(SfpUtilBase):
|
||||
if (reg_value == "" ):
|
||||
return False
|
||||
|
||||
# Mask off 4th bit for presence
|
||||
mask = (1 << 6)
|
||||
# Mask off 4th bit for reset status
|
||||
mask = (1 << 4)
|
||||
|
||||
# ResetL is active low
|
||||
reg_value = reg_value & ~mask
|
||||
@ -375,8 +374,10 @@ class SfpUtil(SfpUtilBase):
|
||||
sfpd_obj = sff8472Dom(None,1)
|
||||
if sfpd_obj is None:
|
||||
return None
|
||||
|
||||
dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET),
|
||||
SFP_TEMPE_WIDTH)
|
||||
SFP_TEMPE_WIDTH)
|
||||
|
||||
if dom_temperature_raw is not None:
|
||||
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
|
||||
else:
|
||||
@ -417,7 +418,7 @@ class SfpUtil(SfpUtilBase):
|
||||
transceiver_dom_info_dict['tx3power'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx4power'] = 'N/A'
|
||||
|
||||
return transceiver_dom_info_dict
|
||||
return transceiver_dom_info_dict
|
||||
|
||||
def get_transceiver_dom_threshold_info_dict(self, port_num):
|
||||
transceiver_dom_threshold_info_dict = {}
|
||||
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"services_to_ignore": [],
|
||||
"devices_to_ignore": ["fan.speed"],
|
||||
"user_defined_checkers": [],
|
||||
"polling_interval": 60,
|
||||
"led_color": {
|
||||
"fault": "amber",
|
||||
"normal": "green",
|
||||
"booting": "blinking_green"
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ try:
|
||||
from sonic_platform.thermal import Thermal
|
||||
from sonic_platform.fan_drawer import FanDrawer
|
||||
from sonic_platform.watchdog import Watchdog
|
||||
from sonic_platform.fan import Fan
|
||||
from sonic_platform.hwaccess import pci_get_value, pci_set_value
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
@ -29,6 +29,9 @@ MAX_S5212F_FANTRAY =4
|
||||
MAX_S5212F_FAN = 2
|
||||
MAX_S5212F_PSU = 2
|
||||
MAX_S5212F_THERMAL = 6
|
||||
SYSTEM_LED_REG = 0x24
|
||||
SYSTEM_BEACON_LED_SET = 0x8
|
||||
SYSTEM_BEACON_LED_CLEAR = 0xFFFFFFF7
|
||||
|
||||
media_part_num_list = set([ \
|
||||
"8T47V","XTY28","MHVPK","GF76J","J6FGD","F1KMV","9DN5J","H4DHD","6MCNV","0WRX0","X7F70","5R2PT","WTRD1","WTRD1","WTRD1","WTRD1","5250G","WTRD1","C5RNH","C5RNH","FTLX8571D3BCL-FC",
|
||||
@ -53,14 +56,32 @@ class Chassis(ChassisBase):
|
||||
|
||||
REBOOT_CAUSE_PATH = "/host/reboot-cause/platform/reboot_reason"
|
||||
OIR_FD_PATH = "/sys/bus/pci/devices/0000:03:00.0/port_msi"
|
||||
pci_res = "/sys/bus/pci/devices/0000:03:00.0/resource0"
|
||||
|
||||
oir_fd = -1
|
||||
epoll = -1
|
||||
|
||||
sysled_offset = 0x0024
|
||||
SYSLED_COLOR_TO_REG = {
|
||||
"blinking_green": 0x0,
|
||||
"green" : 0x10,
|
||||
"amber" : 0x20,
|
||||
"blinking_amber": 0x30
|
||||
}
|
||||
|
||||
REG_TO_SYSLED_COLOR = {
|
||||
0x0 : "blinking_green",
|
||||
0x10 : "green",
|
||||
0x20 : "amber",
|
||||
0x30 : "blinking_amber"
|
||||
}
|
||||
|
||||
_global_port_pres_dict = {}
|
||||
|
||||
def __init__(self):
|
||||
ChassisBase.__init__(self)
|
||||
self.STATUS_LED_COLOR_BLUE_BLINK = "blinking blue"
|
||||
self.STATUS_LED_COLOR_OFF = "off"
|
||||
# sfp.py will read eeprom contents and retrive the eeprom data.
|
||||
# We pass the eeprom path from chassis.py
|
||||
self.PORT_START = 1
|
||||
@ -79,6 +100,9 @@ class Chassis(ChassisBase):
|
||||
self._sfp_list.append(sfp_node)
|
||||
|
||||
self._eeprom = Eeprom()
|
||||
self._watchdog = Watchdog()
|
||||
self._num_sfps = self.PORT_END
|
||||
self._num_fans = MAX_S5212F_FAN * MAX_S5212F_FANTRAY
|
||||
|
||||
for i in range(MAX_S5212F_THERMAL):
|
||||
thermal = Thermal(i)
|
||||
@ -92,12 +116,6 @@ class Chassis(ChassisBase):
|
||||
psu = Psu(i)
|
||||
self._psu_list.append(psu)
|
||||
|
||||
|
||||
for i in range(MAX_S5212F_FANTRAY):
|
||||
for j in range(MAX_S5212F_FAN):
|
||||
fan = Fan(i,j)
|
||||
self._fan_list.append(fan)
|
||||
|
||||
for i in range(MAX_S5212F_FANTRAY):
|
||||
fandrawer = FanDrawer(i)
|
||||
self._fan_drawer_list.append(fandrawer)
|
||||
@ -105,13 +123,15 @@ class Chassis(ChassisBase):
|
||||
|
||||
for port_num in range(self.PORT_START, (self.PORT_END + 1)):
|
||||
# sfp get uses zero-indexing, but port numbers start from 1
|
||||
presence = self.get_sfp(port_num).get_presence()
|
||||
presence = self.get_sfp(port_num-1).get_presence()
|
||||
if presence:
|
||||
self._global_port_pres_dict[port_num] = '1'
|
||||
else:
|
||||
self._global_port_pres_dict[port_num] = '0'
|
||||
|
||||
self._watchdog = Watchdog()
|
||||
self.LOCATOR_LED_ON = self.STATUS_LED_COLOR_BLUE_BLINK
|
||||
self.LOCATOR_LED_OFF = self.STATUS_LED_COLOR_OFF
|
||||
|
||||
|
||||
def __del__(self):
|
||||
if self.oir_fd != -1:
|
||||
@ -180,12 +200,12 @@ class Chassis(ChassisBase):
|
||||
port_dict[port_num] = '0'
|
||||
|
||||
if(len(port_dict) > 0):
|
||||
return True, change_dict
|
||||
return True, change_dict
|
||||
|
||||
if timeout:
|
||||
now_ms = time.time() * 1000
|
||||
if (now_ms - start_ms >= timeout):
|
||||
return True, change_dict
|
||||
return True, change_dict
|
||||
|
||||
|
||||
def get_sfp(self, index):
|
||||
@ -286,6 +306,34 @@ class Chassis(ChassisBase):
|
||||
values.
|
||||
"""
|
||||
return self._eeprom.system_eeprom_info()
|
||||
|
||||
def get_eeprom(self):
|
||||
"""
|
||||
Retrieves the Sys Eeprom instance for the chassis.
|
||||
Returns :
|
||||
The instance of the Sys Eeprom
|
||||
"""
|
||||
return self._eeprom
|
||||
|
||||
def get_num_fans(self):
|
||||
"""
|
||||
Retrives the number of Fans on the chassis.
|
||||
Returns :
|
||||
An integer represents the number of Fans on the chassis.
|
||||
"""
|
||||
return self._num_fans
|
||||
|
||||
def get_num_sfps(self):
|
||||
"""
|
||||
Retrives the numnber of Media on the chassis.
|
||||
Returns:
|
||||
An integer represences the number of SFPs on the chassis.
|
||||
"""
|
||||
return self._num_sfps
|
||||
|
||||
def initizalize_system_led(self):
|
||||
self.sys_ledcolor = "green"
|
||||
|
||||
def get_reboot_cause(self):
|
||||
"""
|
||||
Retrieves the cause of the previous reboot
|
||||
@ -325,3 +373,85 @@ class Chassis(ChassisBase):
|
||||
|
||||
def get_qualified_media_list(self):
|
||||
return media_part_num_list
|
||||
|
||||
def set_locator_led(self, color):
|
||||
"""
|
||||
Sets the state of the Chassis Locator LED
|
||||
Args:
|
||||
color: A string representing the color with which to set the Chassis Locator LED
|
||||
Returns:
|
||||
bool: True if the Chassis Locator LED state is set successfully, False if not
|
||||
"""
|
||||
resource = "/sys/bus/pci/devices/0000:04:00.0/resource0"
|
||||
val = pci_get_value(resource, SYSTEM_LED_REG)
|
||||
if self.LOCATOR_LED_ON == color:
|
||||
val = int(val) | SYSTEM_BEACON_LED_SET
|
||||
elif self.LOCATOR_LED_OFF == color:
|
||||
val = int(val) & SYSTEM_BEACON_LED_CLEAR
|
||||
else:
|
||||
return False
|
||||
pci_set_value(resource, val, SYSTEM_LED_REG)
|
||||
return True
|
||||
|
||||
def get_locator_led(self):
|
||||
"""
|
||||
Gets the state of the Chassis Locator LED
|
||||
Returns:
|
||||
LOCATOR_LED_ON or LOCATOR_LED_OFF
|
||||
"""
|
||||
resource = "/sys/bus/pci/devices/0000:04:00.0/resource0"
|
||||
val = pci_get_value(resource, SYSTEM_LED_REG)
|
||||
val = int(val) & SYSTEM_BEACON_LED_SET
|
||||
if not val:
|
||||
return self.LOCATOR_LED_OFF
|
||||
else:
|
||||
return self.LOCATOR_LED_ON
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
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 Chassis is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return False
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Sets the state of the system LED
|
||||
Args:
|
||||
color: A string representing the color with which to set the
|
||||
system LED
|
||||
Returns:
|
||||
bool: True if system LED state is set successfully, False if not
|
||||
"""
|
||||
if color not in list(self.SYSLED_COLOR_TO_REG.keys()):
|
||||
return False
|
||||
|
||||
val = pci_get_value(self.pci_res, self.sysled_offset)
|
||||
val = (val & 0xFFCF) | self.SYSLED_COLOR_TO_REG[color]
|
||||
|
||||
pci_set_value(self.pci_res, val, self.sysled_offset)
|
||||
self.sys_ledcolor = color
|
||||
return True
|
||||
|
||||
def get_status_led(self):
|
||||
"""
|
||||
Gets the state of the system LED
|
||||
Returns:
|
||||
A string, one of the valid LED color strings which could be
|
||||
vendor specified.
|
||||
"""
|
||||
val = pci_get_value(self.pci_res, self.sysled_offset)
|
||||
if val != -1:
|
||||
val = val & 0x30
|
||||
return self.REG_TO_SYSLED_COLOR.get(val)
|
||||
return self.sys_ledcolor
|
||||
|
@ -9,26 +9,28 @@
|
||||
#
|
||||
########################################################################
|
||||
|
||||
|
||||
try:
|
||||
import subprocess
|
||||
from sonic_platform_base.component_base import ComponentBase
|
||||
import sonic_platform.hwaccess as hwaccess
|
||||
|
||||
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
def get_bios_version():
|
||||
return subprocess.check_output(['dmidecode', '-s', 'system-version']).strip()
|
||||
return subprocess.check_output(['dmidecode', '-s',
|
||||
'system-version']).decode('utf-8').strip()
|
||||
|
||||
def get_fpga_version():
|
||||
val = hwaccess.pci_get_value('/sys/bus/pci/devices/0000:03:00.0/resource0', 0)
|
||||
return '{}.{}'.format((val >> 8) & 0xff, val & 0xff)
|
||||
|
||||
|
||||
def get_bmc_version():
|
||||
return subprocess.check_output(
|
||||
['cat', '/sys/class/ipmi/ipmi0/device/bmc/firmware_revision']
|
||||
).strip()
|
||||
).decode('utf-8').strip()
|
||||
|
||||
def get_cpld_version(bus, i2caddr):
|
||||
return '{}.{}'.format(hwaccess.i2c_get(bus, i2caddr, 1),
|
||||
@ -102,6 +104,55 @@ class Component(ComponentBase):
|
||||
"""
|
||||
return self.version
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the component
|
||||
Returns:
|
||||
bool: True if present, False if not
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the part number of the component
|
||||
Returns:
|
||||
string: Part number of component
|
||||
"""
|
||||
return 'NA'
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the component
|
||||
Returns:
|
||||
string: Serial number of component
|
||||
"""
|
||||
return 'NA'
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the component
|
||||
Returns:
|
||||
bool: True if component is operating properly, False if not
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
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 component is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return False
|
||||
|
||||
def install_firmware(self, image_path):
|
||||
"""
|
||||
Installs firmware to the component
|
||||
@ -111,3 +162,39 @@ class Component(ComponentBase):
|
||||
A boolean, True if install was successful, False if not
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_available_firmware_version(self, image_path):
|
||||
"""
|
||||
Retrieves the available firmware version of the component
|
||||
Note: the firmware version will be read from image
|
||||
Args:
|
||||
image_path: A string, path to firmware image
|
||||
Returns:
|
||||
A string containing the available firmware version of the component
|
||||
"""
|
||||
return "N/A"
|
||||
|
||||
def get_firmware_update_notification(self, image_path):
|
||||
"""
|
||||
Retrieves a notification on what should be done in order to complete
|
||||
the component firmware update
|
||||
Args:
|
||||
image_path: A string, path to firmware image
|
||||
Returns:
|
||||
A string containing the component firmware update notification if required.
|
||||
By default 'None' value will be used, which indicates that no actions are required
|
||||
"""
|
||||
return "None"
|
||||
|
||||
def update_firmware(self, image_path):
|
||||
"""
|
||||
Updates firmware of the component
|
||||
This API performs firmware update: it assumes firmware installation and loading in a single call.
|
||||
In case platform component requires some extra steps (apart from calling Low Level Utility)
|
||||
to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically by API
|
||||
Args:
|
||||
image_path: A string, path to firmware image
|
||||
Raises:
|
||||
RuntimeError: update failed
|
||||
"""
|
||||
return False
|
||||
|
@ -32,34 +32,34 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
self.eeprom_tlv_dict = dict()
|
||||
try:
|
||||
self.eeprom_data = self.read_eeprom()
|
||||
except:
|
||||
except Exception:
|
||||
self.eeprom_data = "N/A"
|
||||
raise RuntimeError("Eeprom is not Programmed")
|
||||
else:
|
||||
eeprom = self.eeprom_data
|
||||
|
||||
if not self.is_valid_tlvinfo_header(eeprom):
|
||||
return
|
||||
eeprom = self.eeprom_data
|
||||
|
||||
total_length = eeprom[9] << 8 | eeprom[10]
|
||||
tlv_index = self._TLV_INFO_HDR_LEN
|
||||
tlv_end = self._TLV_INFO_HDR_LEN + total_length
|
||||
if not self.is_valid_tlvinfo_header(eeprom):
|
||||
return
|
||||
|
||||
while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end:
|
||||
if not self.is_valid_tlv(eeprom[tlv_index:]):
|
||||
break
|
||||
total_length = (eeprom[9] << 8) | eeprom[10]
|
||||
tlv_index = self._TLV_INFO_HDR_LEN
|
||||
tlv_end = self._TLV_INFO_HDR_LEN + total_length
|
||||
|
||||
tlv = eeprom[tlv_index:tlv_index + 2
|
||||
+ eeprom[tlv_index + 1]]
|
||||
code = "0x%02X" % tlv[0]
|
||||
while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end:
|
||||
if not self.is_valid_tlv(eeprom[tlv_index:]):
|
||||
break
|
||||
|
||||
name, value = self.decoder(None, tlv)
|
||||
tlv = eeprom[tlv_index:tlv_index + 2
|
||||
+ eeprom[tlv_index + 1]]
|
||||
code = "0x%02X" % tlv[0]
|
||||
|
||||
self.eeprom_tlv_dict[code] = value
|
||||
if eeprom[tlv_index] == self._TLV_CODE_CRC_32:
|
||||
break
|
||||
name, value = self.decoder(None, tlv)
|
||||
|
||||
tlv_index += eeprom[tlv_index+1] + 2
|
||||
self.eeprom_tlv_dict[code] = value
|
||||
if eeprom[tlv_index] == self._TLV_CODE_CRC_32:
|
||||
break
|
||||
|
||||
tlv_index += eeprom[tlv_index+1] + 2
|
||||
|
||||
def serial_number_str(self):
|
||||
"""
|
||||
@ -80,7 +80,7 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
if not is_valid or t[1] != 6:
|
||||
return super(TlvInfoDecoder, self).switchaddrstr(e)
|
||||
|
||||
return ":".join([binascii.b2a_hex(T) for T in t[2]])
|
||||
return ":".join(["{:02x}".format(T) for T in t[2]]).upper()
|
||||
|
||||
def modelstr(self):
|
||||
"""
|
||||
@ -133,7 +133,3 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
found in the system EEPROM.
|
||||
"""
|
||||
return self.eeprom_tlv_dict
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
########################################################################
|
||||
# DellEMC SS5212F
|
||||
# DellEMC S5212F
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the Fans' information which are available in the platform.
|
||||
@ -46,8 +46,8 @@ class Fan(FanBase):
|
||||
2: {"Prsnt": 0x5b, "State": 0x5b, "Speed": 0x20},
|
||||
3: {"Prsnt": 0x58, "State": 0x58, "Speed": 0x25},
|
||||
4: {"Prsnt": 0x5c, "State": 0x5c, "Speed": 0x21},
|
||||
5: {"Prsnt": 0x59, "State": 0x59, "Speed": 0x26},
|
||||
6: {"Prsnt": 0x5d, "State": 0x5d, "Speed": 0x22},
|
||||
5: {"Prsnt": 0x57, "State": 0x59, "Speed": 0x26},
|
||||
6: {"Prsnt": 0x59, "State": 0x5d, "Speed": 0x22},
|
||||
7: {"Prsnt": 0x5a, "State": 0x5a, "Speed": 0x27},
|
||||
8: {"Prsnt": 0x5e, "State": 0x5e, "Speed": 0x23} }
|
||||
PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x31, "Speed": 0x2e},
|
||||
@ -119,7 +119,11 @@ class Fan(FanBase):
|
||||
Returns:
|
||||
bool: True if fan is present, False if not
|
||||
"""
|
||||
return True
|
||||
if self.is_psu_fan:
|
||||
return self.dependency.get_presence()
|
||||
else:
|
||||
# In S5212F, Fans are fixed
|
||||
return True
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
@ -130,8 +134,12 @@ class Fan(FanBase):
|
||||
status = False
|
||||
is_valid, state = self.state_sensor.get_reading()
|
||||
if is_valid:
|
||||
if (state == 0x00):
|
||||
status = True
|
||||
if self.is_psu_fan:
|
||||
if not state > 1:
|
||||
status = True
|
||||
else:
|
||||
if state == 0x00:
|
||||
status = True
|
||||
return status
|
||||
|
||||
def get_direction(self):
|
||||
@ -160,13 +168,13 @@ class Fan(FanBase):
|
||||
int: percentage of the max fan speed
|
||||
"""
|
||||
speed = None
|
||||
if not self.is_psu_fan :
|
||||
if not self.is_psu_fan:
|
||||
if self.max_speed == 0:
|
||||
self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1]
|
||||
self.max_speed = self.max_speed[1] << 8 | self.max_speed[0]
|
||||
is_valid, fan_speed = self.speed_sensor.get_reading()
|
||||
if is_valid and self.max_speed > 0:
|
||||
speed = (100 * fan_speed)/self.max_speed
|
||||
speed = (100 * fan_speed)//self.max_speed
|
||||
return speed
|
||||
|
||||
def get_speed_rpm(self):
|
||||
@ -178,4 +186,49 @@ class Fan(FanBase):
|
||||
fan_speed = None
|
||||
if not self.is_psu_fan :
|
||||
is_valid, fan_speed = self.speed_sensor.get_reading()
|
||||
return fan_speed
|
||||
return fan_speed if is_valid else None
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.fanindex
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether Fan is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_speed_tolerance(self):
|
||||
"""
|
||||
Retrieves the speed tolerance of the fan
|
||||
Returns:
|
||||
An integer, the percentage of variance from target speed which is
|
||||
considered tolerable
|
||||
"""
|
||||
if self.get_presence():
|
||||
# The tolerance value is fixed as 20% for all the DellEMC platforms
|
||||
tolerance = 20
|
||||
else:
|
||||
tolerance = 0
|
||||
|
||||
return tolerance
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Set led to expected color
|
||||
Args:
|
||||
color: A string representing the color with which to set the
|
||||
fan status LED
|
||||
Returns:
|
||||
bool: True if set success, False if fail.
|
||||
"""
|
||||
# Fan tray status LED controlled by HW
|
||||
# Return True to avoid thermalctld alarm
|
||||
return True
|
||||
|
@ -35,3 +35,78 @@ class FanDrawer(FanDrawerBase):
|
||||
string: The name of the device
|
||||
"""
|
||||
return "FanTray{}".format(self.fantrayindex)
|
||||
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrives the presence of the fan drawer
|
||||
Returns:
|
||||
bool: True if fan_tray is present, False if not
|
||||
"""
|
||||
return self.get_fan(0).get_presence()
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the part number of the fan drawer
|
||||
Returns:
|
||||
string: Part number of fan drawer
|
||||
"""
|
||||
return "NA"
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the fan drawer
|
||||
Returns:
|
||||
string: Serial number of the fan drawer
|
||||
"""
|
||||
return "NA"
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the fan drawer
|
||||
Returns:
|
||||
bool: True if fan drawer is operating properly, False if not
|
||||
"""
|
||||
status = True
|
||||
for fan in self.get_all_fans():
|
||||
status &= fan.get_status()
|
||||
return status
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.fantrayindex
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether this fan drawer is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable, False if not
|
||||
"""
|
||||
return False
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Set led to expected color
|
||||
Args:
|
||||
color: A string representing the color with which to set the
|
||||
fan module status LED
|
||||
Returns:
|
||||
bool: True if set success, False if fail.
|
||||
"""
|
||||
# Fan tray status LED controlled by BMC
|
||||
# Return True to avoid thermalctld alarm
|
||||
return True
|
||||
|
||||
def get_maximum_consumed_power(self):
|
||||
"""
|
||||
Retrives the maximum power drawn by Fan Drawer
|
||||
Returns:
|
||||
A float, with value of the maximum consumable power of the
|
||||
component.
|
||||
"""
|
||||
return 0.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
########################################################################
|
||||
# DellEMC S5212F
|
||||
# DellEMC S5212F
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the PSUs' information which are available in the platform
|
||||
@ -83,6 +83,15 @@ class Psu(PsuBase):
|
||||
|
||||
return presence
|
||||
|
||||
def get_temperature(self):
|
||||
"""
|
||||
Retrieves current temperature reading from thermal
|
||||
Returns:
|
||||
A float number of current temperature in Celcius up to
|
||||
nearest thousandth of one degree celcius, e.g. 30.125
|
||||
"""
|
||||
return 0.0
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the part number of the PSU
|
||||
@ -101,6 +110,26 @@ class Psu(PsuBase):
|
||||
"""
|
||||
return self.fru.get_board_serial()
|
||||
|
||||
def get_revision(self):
|
||||
"""
|
||||
Retrives thehardware revision of the device
|
||||
Returns:
|
||||
String: revision value of device
|
||||
"""
|
||||
serial = self.fru.get_board_serial()
|
||||
if serial != "NA" and len(serial) == 23:
|
||||
return serial[-3:]
|
||||
else:
|
||||
return "NA"
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether this PSU is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the PSU
|
||||
@ -124,7 +153,7 @@ class Psu(PsuBase):
|
||||
A float number, the output voltage in volts,
|
||||
e.g. 12.1
|
||||
"""
|
||||
return None
|
||||
return 0.0
|
||||
|
||||
def get_current(self):
|
||||
"""
|
||||
@ -134,7 +163,7 @@ class Psu(PsuBase):
|
||||
A float number, electric current in amperes,
|
||||
e.g. 15.4
|
||||
"""
|
||||
return None
|
||||
return 0.0
|
||||
|
||||
def get_power(self):
|
||||
"""
|
||||
@ -144,7 +173,37 @@ class Psu(PsuBase):
|
||||
A float number, the power in watts,
|
||||
e.g. 302.6
|
||||
"""
|
||||
return None
|
||||
return 0.0
|
||||
|
||||
def get_input_voltage(self):
|
||||
"""
|
||||
Retrieves current PSU voltage input
|
||||
|
||||
Returns:
|
||||
A float number, the input voltage in volts,
|
||||
e.g. 12.1
|
||||
"""
|
||||
return 0.0
|
||||
|
||||
def get_input_current(self):
|
||||
"""
|
||||
Retrieves present electric current supplied to PSU
|
||||
|
||||
Returns:
|
||||
A float number, electric current in amperes,
|
||||
e.g. 15.4
|
||||
"""
|
||||
return 0.0
|
||||
|
||||
def get_input_power(self):
|
||||
"""
|
||||
Retrieves current energy supplied to PSU
|
||||
|
||||
Returns:
|
||||
A float number, the power in watts,
|
||||
e.g. 302.6
|
||||
"""
|
||||
return 0.0
|
||||
|
||||
def get_powergood_status(self):
|
||||
"""
|
||||
@ -162,6 +221,15 @@ class Psu(PsuBase):
|
||||
|
||||
return status
|
||||
|
||||
def get_mfr_id(self):
|
||||
"""
|
||||
Retrives the Manufacturer Id of PSU
|
||||
|
||||
Returns:
|
||||
A string, the manunfacturer id.
|
||||
"""
|
||||
return self.fru.get_board_mfr_id()
|
||||
|
||||
def get_type(self):
|
||||
"""
|
||||
Retrives the Power Type of PSU
|
||||
@ -169,12 +237,54 @@ class Psu(PsuBase):
|
||||
Returns :
|
||||
A string, PSU power type
|
||||
"""
|
||||
board_info = self.fru.get_board_part_number()
|
||||
if board_info is not None :
|
||||
board_part_no = board_info[0:6]
|
||||
if board_part_no in switch_sku:
|
||||
return switch_sku[board_part_no][0]
|
||||
board_product = self.fru.get_board_product()
|
||||
if board_product is not None :
|
||||
info = board_product.split(',')
|
||||
if 'AC' in info : return 'AC'
|
||||
if 'DC' in info : return 'DC'
|
||||
return None
|
||||
|
||||
def get_mfr_id(self):
|
||||
return self.fru.get_board_mfr_id()
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.index
|
||||
|
||||
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 0.0
|
||||
|
||||
def get_voltage_high_threshold(self):
|
||||
"""
|
||||
Returns PSU high threshold in Volts
|
||||
"""
|
||||
return 0.0
|
||||
|
||||
def get_maximum_supplied_power(self):
|
||||
"""
|
||||
Retrieves the maximum supplied power by PSU
|
||||
Returns:
|
||||
A float number, the maximum power output in Watts.
|
||||
e.g. 1200.1
|
||||
"""
|
||||
return float(750)
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Sets the state of the PSU status LED
|
||||
Args:
|
||||
color: A string representing the color with which to set the PSU status LED
|
||||
Note: Only support green and off
|
||||
Returns:
|
||||
bool: True if status LED state is set successfully, False if not
|
||||
"""
|
||||
# Hardware not supported
|
||||
return False
|
||||
|
@ -19,6 +19,10 @@ try:
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
QSFP_INFO_OFFSET = 128
|
||||
SFP_INFO_OFFSET = 0
|
||||
QSFP_DD_PAGE0 = 0
|
||||
|
||||
SFP_TYPE_LIST = [
|
||||
'0x3' # SFP/SFP+/SFP28 and later
|
||||
]
|
||||
@ -39,6 +43,7 @@ class Sfp(SfpOptoeBase):
|
||||
|
||||
def __init__(self, index, sfp_type, eeprom_path):
|
||||
SfpOptoeBase.__init__(self)
|
||||
self.port_type = sfp_type
|
||||
self.sfp_type = sfp_type
|
||||
self.port_type = sfp_type
|
||||
self.index = index
|
||||
@ -92,6 +97,23 @@ class Sfp(SfpOptoeBase):
|
||||
self.set_media_type()
|
||||
self.reinit_sfp_driver()
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.index
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether this device is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the sfp
|
||||
@ -313,3 +335,33 @@ class Sfp(SfpOptoeBase):
|
||||
except IOError as e:
|
||||
print("Error: Unable to open file: %s" % str(e))
|
||||
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 not self.get_presence():
|
||||
return self.SFP_STATUS_UNPLUGGED
|
||||
else:
|
||||
if not os.path.isfile(self.eeprom_path):
|
||||
return "EEPROM driver is not attached"
|
||||
|
||||
if self.sfp_type == 'SFP':
|
||||
offset = SFP_INFO_OFFSET
|
||||
elif self.sfp_type == 'QSFP':
|
||||
offset = QSFP_INFO_OFFSET
|
||||
elif self.sfp_type == 'QSFP_DD':
|
||||
offset = QSFP_DD_PAGE0
|
||||
|
||||
try:
|
||||
with open(self.eeprom_path, mode="rb", buffering=0) as eeprom:
|
||||
eeprom.seek(offset)
|
||||
eeprom.read(1)
|
||||
except OSError as e:
|
||||
return "EEPROM read failed ({})".format(e.strerror)
|
||||
|
||||
return self.SFP_STATUS_OK
|
||||
|
@ -21,12 +21,12 @@ class Thermal(ThermalBase):
|
||||
|
||||
# [ Sensor-Name, Sensor-ID ]
|
||||
SENSOR_MAPPING = [
|
||||
['Port Mid', 0x1],
|
||||
['NPU Near', 0x2],
|
||||
['Port Left', 0x3],
|
||||
['Port Right', 0x4],
|
||||
['Inlet Airflow Sensor', 0x5],
|
||||
['CPU', 0xe],
|
||||
['CPU On-board', 0xe],
|
||||
['ASIC On-board', 0x2],
|
||||
['System Front Left', 0x3],
|
||||
['System Front Middle', 0x1],
|
||||
['System Front Right', 0x4],
|
||||
['Inlet Airflow Sensor', 0x5]
|
||||
]
|
||||
|
||||
def __init__(self, thermal_index):
|
||||
@ -92,7 +92,7 @@ class Thermal(ThermalBase):
|
||||
if not is_valid:
|
||||
temperature = 0
|
||||
|
||||
return "{:.3f}".format(temperature)
|
||||
return float(temperature)
|
||||
|
||||
def get_high_threshold(self):
|
||||
"""
|
||||
@ -105,9 +105,9 @@ class Thermal(ThermalBase):
|
||||
"""
|
||||
is_valid, high_threshold = self.sensor.get_threshold("UpperNonCritical")
|
||||
if not is_valid:
|
||||
high_threshold = 0
|
||||
return 0.0
|
||||
|
||||
return "{:.3f}".format(high_threshold)
|
||||
return float(high_threshold)
|
||||
|
||||
def get_high_critical_threshold(self):
|
||||
"""
|
||||
@ -120,9 +120,9 @@ class Thermal(ThermalBase):
|
||||
"""
|
||||
is_valid, high_crit_threshold = self.sensor.get_threshold("UpperCritical")
|
||||
if not is_valid:
|
||||
high_crit_threshold = 0
|
||||
return 0.0
|
||||
|
||||
return "{:.3f}".format(high_crit_threshold)
|
||||
return float(high_crit_threshold)
|
||||
|
||||
def get_low_threshold(self):
|
||||
"""
|
||||
@ -137,7 +137,7 @@ class Thermal(ThermalBase):
|
||||
if not is_valid:
|
||||
low_threshold = 0
|
||||
|
||||
return "{:.3f}".format(low_threshold)
|
||||
return float(low_threshold)
|
||||
|
||||
def set_high_threshold(self, temperature):
|
||||
"""
|
||||
@ -166,3 +166,20 @@ class Thermal(ThermalBase):
|
||||
"""
|
||||
# Thermal threshold values are pre-defined based on HW.
|
||||
return False
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.index
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether this Thermal is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return False
|
||||
|
@ -13,7 +13,7 @@ try:
|
||||
import ctypes
|
||||
import subprocess
|
||||
import syslog
|
||||
import sonic_platform.component as Component
|
||||
import sonic_platform.component as Component
|
||||
from sonic_platform_base.watchdog_base import WatchdogBase
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
@ -48,7 +48,7 @@ class Watchdog(WatchdogBase):
|
||||
stderr=subprocess.STDOUT)
|
||||
stdout = proc.communicate()[0]
|
||||
proc.wait()
|
||||
result = stdout.rstrip('\n')
|
||||
result = stdout.rstrip('\n'.encode())
|
||||
except OSError:
|
||||
result = None
|
||||
|
||||
@ -95,7 +95,7 @@ class Watchdog(WatchdogBase):
|
||||
"""
|
||||
timer_offset = -1
|
||||
for key,timer_seconds in enumerate(self.TIMERS):
|
||||
if seconds <= timer_seconds:
|
||||
if seconds > 0 and seconds <= timer_seconds:
|
||||
timer_offset = key
|
||||
seconds = timer_seconds
|
||||
break
|
||||
@ -126,18 +126,15 @@ class Watchdog(WatchdogBase):
|
||||
# Last bit = WD Timer punch
|
||||
self._set_reg_val(reg_val & 0xFE)
|
||||
|
||||
self.armed_time = self._get_time()
|
||||
self.timeout = seconds
|
||||
return seconds
|
||||
else:
|
||||
# Setting 4th bit to enable WD
|
||||
# 4th bit = Enable WD
|
||||
reg_val = self._get_reg_val()
|
||||
self._set_reg_val(reg_val | 0x8)
|
||||
|
||||
self.armed_time = self._get_time()
|
||||
self.timeout = seconds
|
||||
return seconds
|
||||
self.armed_time = self._get_time()
|
||||
self.timeout = seconds
|
||||
return seconds
|
||||
|
||||
def disarm(self):
|
||||
"""
|
||||
|
@ -9,6 +9,7 @@
|
||||
#############################################################################
|
||||
|
||||
try:
|
||||
import os
|
||||
import time
|
||||
import sys
|
||||
from sonic_platform_base.chassis_base import ChassisBase
|
||||
@ -17,9 +18,8 @@ try:
|
||||
from sonic_platform.component import Component
|
||||
from sonic_platform.psu import Psu
|
||||
from sonic_platform.thermal import Thermal
|
||||
from sonic_platform.watchdog import Watchdog
|
||||
from sonic_platform.fan import Fan
|
||||
from sonic_platform.fan_drawer import FanDrawer
|
||||
from sonic_platform.watchdog import Watchdog
|
||||
from sonic_platform.hwaccess import pci_get_value, pci_set_value
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
@ -56,11 +56,32 @@ class Chassis(ChassisBase):
|
||||
|
||||
REBOOT_CAUSE_PATH = "/host/reboot-cause/platform/reboot_reason"
|
||||
OIR_FD_PATH = "/sys/bus/pci/devices/0000:04:00.0/port_msi"
|
||||
pci_res = "/sys/bus/pci/devices/0000:04:00.0/resource0"
|
||||
|
||||
oir_fd = -1
|
||||
epoll = -1
|
||||
|
||||
sysled_offset = 0x0024
|
||||
SYSLED_COLOR_TO_REG = {
|
||||
"blinking_green": 0x0,
|
||||
"green" : 0x10,
|
||||
"amber" : 0x20,
|
||||
"blinking_amber": 0x30
|
||||
}
|
||||
|
||||
REG_TO_SYSLED_COLOR = {
|
||||
0x0 : "blinking_green",
|
||||
0x10 : "green",
|
||||
0x20 : "amber",
|
||||
0x30 : "blinking_amber"
|
||||
}
|
||||
|
||||
_global_port_pres_dict = {}
|
||||
|
||||
def __init__(self):
|
||||
ChassisBase.__init__(self)
|
||||
self.STATUS_LED_COLOR_BLUE_BLINK = "blinking blue"
|
||||
self.STATUS_LED_COLOR_OFF = "off"
|
||||
# sfp.py will read eeprom contents and retrive the eeprom data.
|
||||
# We pass the eeprom path from chassis.py
|
||||
self.PORT_START = 1
|
||||
@ -97,11 +118,6 @@ class Chassis(ChassisBase):
|
||||
psu = Psu(i)
|
||||
self._psu_list.append(psu)
|
||||
|
||||
for i in range(MAX_S5224F_FANTRAY):
|
||||
for j in range(MAX_S5224F_FAN):
|
||||
fan = Fan(i,j)
|
||||
self._fan_list.append(fan)
|
||||
|
||||
for i in range(MAX_S5224F_FANTRAY):
|
||||
fandrawer = FanDrawer(i)
|
||||
self._fan_drawer_list.append(fandrawer)
|
||||
@ -115,6 +131,52 @@ class Chassis(ChassisBase):
|
||||
else:
|
||||
self._global_port_pres_dict[port_num] = '0'
|
||||
|
||||
self.LOCATOR_LED_ON = self.STATUS_LED_COLOR_BLUE_BLINK
|
||||
self.LOCATOR_LED_OFF = self.STATUS_LED_COLOR_OFF
|
||||
|
||||
|
||||
def __del__(self):
|
||||
if self.oir_fd != -1:
|
||||
self.epoll.unregister(self.oir_fd.fileno())
|
||||
self.epoll.close()
|
||||
self.oir_fd.close()
|
||||
|
||||
# not needed /delete after validation
|
||||
|
||||
def _get_register(self, reg_file):
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(reg_file)):
|
||||
print(reg_file, 'not found !')
|
||||
return retval
|
||||
|
||||
try:
|
||||
with os.fdopen(os.open(reg_file, os.O_RDONLY)) as fd:
|
||||
retval = fd.read()
|
||||
except Exception:
|
||||
pass
|
||||
retval = retval.rstrip('\r\n')
|
||||
retval = retval.lstrip(" ")
|
||||
return retval
|
||||
|
||||
# not needed /delete after validation
|
||||
|
||||
def _check_interrupts(self, port_dict):
|
||||
retval = 0
|
||||
is_port_dict_updated = False
|
||||
for port_num in range(self.PORT_START, (self.PORT_END + 1)):
|
||||
# sfp get uses zero-indexing, but port numbers start from 1
|
||||
sfp = self.get_sfp(port_num-1)
|
||||
presence = sfp.get_presence()
|
||||
if(presence and (self._global_port_pres_dict[port_num] == '0')):
|
||||
is_port_dict_updated = True
|
||||
self._global_port_pres_dict[port_num] = '1'
|
||||
port_dict[port_num] = '1'
|
||||
elif(not presence and (self._global_port_pres_dict[port_num] == '1')):
|
||||
is_port_dict_updated = True
|
||||
self._global_port_pres_dict[port_num] = '0'
|
||||
port_dict[port_num] = '0'
|
||||
return retval, is_port_dict_updated
|
||||
|
||||
# check for this event change for sfp / do we need to handle timeout/sleep
|
||||
|
||||
def get_change_event(self, timeout=0):
|
||||
@ -167,8 +229,8 @@ class Chassis(ChassisBase):
|
||||
# The index will start from 0
|
||||
sfp = self._sfp_list[index-1]
|
||||
except IndexError:
|
||||
sys.stderr.write("SFP index {} out of range (1-{})\n".format(
|
||||
index, len(self._sfp_list)))
|
||||
sys.stderr.write("SFP index {} out of range (0-{})\n".format(
|
||||
index, len(self._sfp_list)-1))
|
||||
return sfp
|
||||
|
||||
def get_name(self):
|
||||
@ -203,6 +265,14 @@ class Chassis(ChassisBase):
|
||||
"""
|
||||
return self._eeprom.serial_str()
|
||||
|
||||
def get_revision(self):
|
||||
"""
|
||||
Retrieves the revision number of the chassis (Service tag)
|
||||
Returns:
|
||||
string: Revision number of chassis
|
||||
"""
|
||||
return self._eeprom.revision_str()
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the chassis
|
||||
@ -263,6 +333,9 @@ class Chassis(ChassisBase):
|
||||
"""
|
||||
return self._num_sfps
|
||||
|
||||
def initizalize_system_led(self):
|
||||
self.sys_ledcolor = "green"
|
||||
|
||||
def get_reboot_cause(self):
|
||||
"""
|
||||
Retrieves the cause of the previous reboot
|
||||
@ -276,7 +349,7 @@ class Chassis(ChassisBase):
|
||||
try:
|
||||
with open(self.REBOOT_CAUSE_PATH) as fd:
|
||||
reboot_cause = int(fd.read(), 16)
|
||||
except EnvironmentError:
|
||||
except Exception:
|
||||
return (self.REBOOT_CAUSE_NON_HARDWARE, None)
|
||||
|
||||
if reboot_cause & 0x1:
|
||||
@ -306,13 +379,10 @@ class Chassis(ChassisBase):
|
||||
def set_locator_led(self, color):
|
||||
"""
|
||||
Sets the state of the Chassis Locator LED
|
||||
|
||||
Args:
|
||||
color: A string representing the color with which to set the Chassis Locator LED
|
||||
|
||||
Returns:
|
||||
bool: True if the Chassis Locator LED state is set successfully, False if not
|
||||
|
||||
"""
|
||||
resource = "/sys/bus/pci/devices/0000:04:00.0/resource0"
|
||||
val = pci_get_value(resource, SYSTEM_LED_REG)
|
||||
@ -328,7 +398,6 @@ class Chassis(ChassisBase):
|
||||
def get_locator_led(self):
|
||||
"""
|
||||
Gets the state of the Chassis Locator LED
|
||||
|
||||
Returns:
|
||||
LOCATOR_LED_ON or LOCATOR_LED_OFF
|
||||
"""
|
||||
@ -340,3 +409,51 @@ class Chassis(ChassisBase):
|
||||
else:
|
||||
return self.LOCATOR_LED_ON
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
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 Chassis is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return False
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Sets the state of the system LED
|
||||
Args:
|
||||
color: A string representing the color with which to set the
|
||||
system LED
|
||||
Returns:
|
||||
bool: True if system LED state is set successfully, False if not
|
||||
"""
|
||||
if color not in list(self.SYSLED_COLOR_TO_REG.keys()):
|
||||
return False
|
||||
|
||||
val = pci_get_value(self.pci_res, self.sysled_offset)
|
||||
val = (val & 0xFFCF) | self.SYSLED_COLOR_TO_REG[color]
|
||||
|
||||
pci_set_value(self.pci_res, val, self.sysled_offset)
|
||||
self.sys_ledcolor = color
|
||||
return True
|
||||
|
||||
def get_status_led(self):
|
||||
"""
|
||||
Gets the state of the system LED
|
||||
Returns:
|
||||
A string, one of the valid LED color strings which could be
|
||||
vendor specified.
|
||||
"""
|
||||
val = pci_get_value(self.pci_res, self.sysled_offset)
|
||||
if val != -1:
|
||||
val = val & 0x30
|
||||
return self.REG_TO_SYSLED_COLOR.get(val)
|
||||
return self.sys_ledcolor
|
||||
|
@ -19,7 +19,8 @@ except ImportError as e:
|
||||
|
||||
|
||||
def get_bios_version():
|
||||
return subprocess.check_output(['dmidecode', '-s', 'system-version']).strip()
|
||||
return subprocess.check_output(['dmidecode', '-s',
|
||||
'system-version']).decode('utf-8').strip()
|
||||
|
||||
def get_fpga_version():
|
||||
val = hwaccess.pci_get_value('/sys/bus/pci/devices/0000:03:00.0/resource0', 0)
|
||||
@ -28,7 +29,7 @@ def get_fpga_version():
|
||||
def get_bmc_version():
|
||||
return subprocess.check_output(
|
||||
['cat', '/sys/class/ipmi/ipmi0/device/bmc/firmware_revision']
|
||||
).strip()
|
||||
).decode('utf-8').strip()
|
||||
|
||||
def get_cpld_version(bus, i2caddr):
|
||||
return '{}.{}'.format(hwaccess.i2c_get(bus, i2caddr, 1),
|
||||
@ -111,3 +112,88 @@ class Component(ComponentBase):
|
||||
A boolean, True if install was successful, False if not
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the component
|
||||
Returns:
|
||||
bool: True if present, False if not
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the part number of the component
|
||||
Returns:
|
||||
string: Part number of component
|
||||
"""
|
||||
return 'NA'
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the component
|
||||
Returns:
|
||||
string: Serial number of component
|
||||
"""
|
||||
return 'NA'
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the component
|
||||
Returns:
|
||||
bool: True if component is operating properly, False if not
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
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 component is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_available_firmware_version(self, image_path):
|
||||
"""
|
||||
Retrieves the available firmware version of the component
|
||||
Note: the firmware version will be read from image
|
||||
Args:
|
||||
image_path: A string, path to firmware image
|
||||
Returns:
|
||||
A string containing the available firmware version of the component
|
||||
"""
|
||||
return "N/A"
|
||||
|
||||
def get_firmware_update_notification(self, image_path):
|
||||
"""
|
||||
Retrieves a notification on what should be done in order to complete
|
||||
the component firmware update
|
||||
Args:
|
||||
image_path: A string, path to firmware image
|
||||
Returns:
|
||||
A string containing the component firmware update notification if required.
|
||||
By default 'None' value will be used, which indicates that no actions are required
|
||||
"""
|
||||
return "None"
|
||||
|
||||
def update_firmware(self, image_path):
|
||||
"""
|
||||
Updates firmware of the component
|
||||
This API performs firmware update: it assumes firmware installation and loading in a single call.
|
||||
In case platform component requires some extra steps (apart from calling Low Level Utility)
|
||||
to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically by API
|
||||
Args:
|
||||
image_path: A string, path to firmware image
|
||||
Raises:
|
||||
RuntimeError: update failed
|
||||
"""
|
||||
return False
|
||||
|
@ -11,6 +11,7 @@
|
||||
try:
|
||||
import os.path
|
||||
from sonic_eeprom import eeprom_tlvinfo
|
||||
import binascii
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
@ -48,7 +49,7 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
break
|
||||
|
||||
tlv = eeprom[tlv_index:tlv_index + 2
|
||||
+ eeprom[tlv_index + 1]]
|
||||
+ eeprom[tlv_index + 1]]
|
||||
code = "0x%02X" % tlv[0]
|
||||
|
||||
name, value = self.decoder(None, tlv)
|
||||
@ -69,14 +70,14 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
return "N/A"
|
||||
return results[2].decode('ascii')
|
||||
|
||||
def base_mac_addr(self, e):
|
||||
def base_mac_addr(self, e=None):
|
||||
"""
|
||||
Returns the base mac address found in the system EEPROM
|
||||
"""
|
||||
(is_valid, t) = self.get_tlv_field(
|
||||
self.eeprom_data, self._TLV_CODE_MAC_BASE)
|
||||
if not is_valid or t[1] != 6:
|
||||
return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(t)
|
||||
return super(TlvInfoDecoder, self).switchaddrstr(e)
|
||||
|
||||
return ":".join(["{:02x}".format(T) for T in t[2]]).upper()
|
||||
|
||||
@ -122,7 +123,7 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
if not is_valid:
|
||||
return "N/A"
|
||||
|
||||
return results[2].decode('ascii')
|
||||
return (binascii.b2a_hex(results[2])).decode('ascii')
|
||||
|
||||
def system_eeprom_info(self):
|
||||
"""
|
||||
|
@ -91,10 +91,7 @@ class Fan(FanBase):
|
||||
Returns:
|
||||
String: Part number of FAN
|
||||
"""
|
||||
if self.is_psu_fan:
|
||||
return None
|
||||
else:
|
||||
return self.fru.get_board_part_number()
|
||||
return self.fru.get_board_part_number()
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
@ -102,10 +99,7 @@ class Fan(FanBase):
|
||||
Returns:
|
||||
String: Serial number of FAN
|
||||
"""
|
||||
if self.is_psu_fan:
|
||||
return None
|
||||
else:
|
||||
return self.fru.get_board_serial()
|
||||
return self.fru.get_board_serial()
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
@ -132,8 +126,12 @@ class Fan(FanBase):
|
||||
status = False
|
||||
is_valid, state = self.state_sensor.get_reading()
|
||||
if is_valid:
|
||||
if not state > 1:
|
||||
status = True
|
||||
if self.is_psu_fan:
|
||||
if not state > 1:
|
||||
status = True
|
||||
else:
|
||||
if state == 0x00:
|
||||
status = True
|
||||
return status
|
||||
|
||||
def get_direction(self):
|
||||
@ -183,3 +181,48 @@ class Fan(FanBase):
|
||||
fan_speed = 0
|
||||
is_valid, fan_speed = self.speed_sensor.get_reading()
|
||||
return fan_speed if is_valid else None
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.fanindex
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether Fan is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_speed_tolerance(self):
|
||||
"""
|
||||
Retrieves the speed tolerance of the fan
|
||||
Returns:
|
||||
An integer, the percentage of variance from target speed which is
|
||||
considered tolerable
|
||||
"""
|
||||
if self.get_presence():
|
||||
# The tolerance value is fixed as 20% for all the DellEMC platforms
|
||||
tolerance = 20
|
||||
else:
|
||||
tolerance = 0
|
||||
|
||||
return tolerance
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Set led to expected color
|
||||
Args:
|
||||
color: A string representing the color with which to set the
|
||||
fan status LED
|
||||
Returns:
|
||||
bool: True if set success, False if fail.
|
||||
"""
|
||||
# Fan tray status LED controlled by HW
|
||||
# Return True to avoid thermalctld alarm
|
||||
return True
|
||||
|
@ -11,6 +11,7 @@
|
||||
try:
|
||||
from sonic_platform_base.fan_drawer_base import FanDrawerBase
|
||||
from sonic_platform.fan import Fan
|
||||
from sonic_platform.ipmihelper import IpmiFru
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
@ -20,6 +21,8 @@ S5224F_FANS_PER_FANTRAY = 2
|
||||
class FanDrawer(FanDrawerBase):
|
||||
"""DellEMC Platform-specific Fan class"""
|
||||
|
||||
FAN_FRU_MAPPING = { 1: 3, 2: 4, 3: 5, 4: 6 }
|
||||
|
||||
def __init__(self, fantray_index):
|
||||
|
||||
FanDrawerBase.__init__(self)
|
||||
@ -27,6 +30,7 @@ class FanDrawer(FanDrawerBase):
|
||||
self.fantrayindex = fantray_index + 1
|
||||
for i in range(S5224F_FANS_PER_FANTRAY):
|
||||
self._fan_list.append(Fan(fantray_index, i))
|
||||
self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex])
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
@ -35,3 +39,88 @@ class FanDrawer(FanDrawerBase):
|
||||
string: The name of the device
|
||||
"""
|
||||
return "FanTray{}".format(self.fantrayindex)
|
||||
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrives the presence of the fan drawer
|
||||
Returns:
|
||||
bool: True if fan_tray is present, False if not
|
||||
"""
|
||||
return self.get_fan(0).get_presence()
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the part number of the fan drawer
|
||||
Returns:
|
||||
string: Part number of fan drawer
|
||||
"""
|
||||
return self.fru.get_board_part_number()
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the fan drawer
|
||||
Returns:
|
||||
string: Serial number of the fan drawer
|
||||
"""
|
||||
return self.fru.get_board_serial()
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the fan drawer
|
||||
Returns:
|
||||
bool: True if fan drawer is operating properly, False if not
|
||||
"""
|
||||
status = True
|
||||
for fan in self.get_all_fans():
|
||||
status &= fan.get_status()
|
||||
return status
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.fantrayindex
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether this fan drawer is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable, False if not
|
||||
"""
|
||||
return True
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Set led to expected color
|
||||
Args:
|
||||
color: A string representing the color with which to set the
|
||||
fan module status LED
|
||||
Returns:
|
||||
bool: True if set success, False if fail.
|
||||
"""
|
||||
# Fan tray status LED controlled by BMC
|
||||
# Return True to avoid thermalctld alarm
|
||||
return True
|
||||
|
||||
def get_status_led(self, color):
|
||||
"""
|
||||
Gets the state of the fan drawer LED
|
||||
Returns:
|
||||
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||
"""
|
||||
# Fan tray status LED controlled by BMC
|
||||
# Return True to avoid thermalctld alarm
|
||||
return True
|
||||
|
||||
def get_maximum_consumed_power(self):
|
||||
"""
|
||||
Retrives the maximum power drawn by Fan Drawer
|
||||
Returns:
|
||||
A float, with value of the maximum consumable power of the
|
||||
component.
|
||||
"""
|
||||
return 0.0
|
||||
|
@ -24,11 +24,11 @@ class Psu(PsuBase):
|
||||
SENSOR_MAPPING = { 1: { "State": 0x31, "Current": 0x39,
|
||||
"Power": 0x37, "Voltage": 0x38,
|
||||
"InCurrent": 0x36, "InPower": 0x34,
|
||||
"InVoltage": 0x35 },
|
||||
"InVoltage": 0x35, "Temperature": 0xc },
|
||||
2: { "State": 0x32, "Current": 0x3F,
|
||||
"Power": 0x3D, "Voltage": 0x3E,
|
||||
"InCurrent": 0x3C, "InPower": 0x3A,
|
||||
"InVoltage": 0x3B } }
|
||||
"InVoltage": 0x3B, "Temperature": 0xd } }
|
||||
# ( PSU-ID: FRU-ID }
|
||||
FRU_MAPPING = { 1: 1, 2: 2 }
|
||||
|
||||
@ -44,6 +44,7 @@ class Psu(PsuBase):
|
||||
self.input_voltage_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["InVoltage"])
|
||||
self.input_current_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["InCurrent"])
|
||||
self.input_power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["InPower"])
|
||||
self.temp_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Temperature"])
|
||||
self.fru = IpmiFru(self.FRU_MAPPING[self.index])
|
||||
|
||||
self._fan_list.append(Fan(fan_index=self.index, psu_fan=True,
|
||||
@ -68,11 +69,36 @@ class Psu(PsuBase):
|
||||
presence = False
|
||||
is_valid, state = self.state_sensor.get_reading()
|
||||
if is_valid:
|
||||
if (state & 0b1):
|
||||
if (state == 0x01):
|
||||
presence = True
|
||||
|
||||
return presence
|
||||
|
||||
def get_temperature(self):
|
||||
"""
|
||||
Retrieves current temperature reading from thermal
|
||||
Returns:
|
||||
A float number of current temperature in Celcius up to
|
||||
nearest thousandth of one degree celcius, e.g. 30.125
|
||||
"""
|
||||
is_valid, temperature = self.temp_sensor.get_reading()
|
||||
if not is_valid:
|
||||
temperature = 0
|
||||
|
||||
return float(temperature)
|
||||
|
||||
def get_temperature_high_threshold(self):
|
||||
"""
|
||||
Returns the high temperature threshold for PSU in Celsius
|
||||
"""
|
||||
|
||||
is_valid, high_threshold = self.temp_sensor.get_threshold("UpperCritical")
|
||||
if not is_valid:
|
||||
high_threshold = 105
|
||||
high_threshold = "{:.2f}".format(high_threshold)
|
||||
|
||||
return float(high_threshold)
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the part number of the PSU
|
||||
@ -91,6 +117,26 @@ class Psu(PsuBase):
|
||||
"""
|
||||
return self.fru.get_board_serial()
|
||||
|
||||
def get_revision(self):
|
||||
"""
|
||||
Retrives thehardware revision of the device
|
||||
Returns:
|
||||
String: revision value of device
|
||||
"""
|
||||
serial = self.fru.get_board_serial()
|
||||
if serial != "NA" and len(serial) == 23:
|
||||
return serial[-3:]
|
||||
else:
|
||||
return "NA"
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether this PSU is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the PSU
|
||||
@ -116,9 +162,33 @@ class Psu(PsuBase):
|
||||
"""
|
||||
is_valid, voltage = self.voltage_sensor.get_reading()
|
||||
if not is_valid:
|
||||
return None
|
||||
return 0.0
|
||||
|
||||
return "{:.1f}".format(voltage)
|
||||
return float(voltage)
|
||||
|
||||
def get_voltage_low_threshold(self):
|
||||
"""
|
||||
Returns PSU low threshold in Volts
|
||||
"""
|
||||
|
||||
is_valid, low_threshold = self.voltage_sensor.get_threshold("LowerCritical")
|
||||
if not is_valid:
|
||||
low_threshold = 11.6
|
||||
low_threshold = "{:.2f}".format(low_threshold)
|
||||
|
||||
return float(low_threshold)
|
||||
|
||||
def get_voltage_high_threshold(self):
|
||||
"""
|
||||
Returns PSU high threshold in Volts
|
||||
"""
|
||||
|
||||
is_valid, high_threshold = self.voltage_sensor.get_threshold("UpperCritical")
|
||||
if not is_valid:
|
||||
high_threshold = 12.8
|
||||
high_threshold = "{:.2f}".format(high_threshold)
|
||||
|
||||
return float(high_threshold)
|
||||
|
||||
def get_current(self):
|
||||
"""
|
||||
@ -130,9 +200,9 @@ class Psu(PsuBase):
|
||||
"""
|
||||
is_valid, current = self.current_sensor.get_reading()
|
||||
if not is_valid:
|
||||
return None
|
||||
return 0.0
|
||||
|
||||
return "{:.1f}".format(current)
|
||||
return float(current)
|
||||
|
||||
def get_power(self):
|
||||
"""
|
||||
@ -144,9 +214,9 @@ class Psu(PsuBase):
|
||||
"""
|
||||
is_valid, power = self.power_sensor.get_reading()
|
||||
if not is_valid:
|
||||
return None
|
||||
return 0.0
|
||||
|
||||
return "{:.1f}".format(power)
|
||||
return float(power)
|
||||
|
||||
def get_input_voltage(self):
|
||||
"""
|
||||
@ -158,9 +228,9 @@ class Psu(PsuBase):
|
||||
"""
|
||||
is_valid, input_voltage = self.input_voltage_sensor.get_reading()
|
||||
if not is_valid:
|
||||
return None
|
||||
return 0.0
|
||||
|
||||
return "{:.1f}".format(input_voltage)
|
||||
return float(input_voltage)
|
||||
|
||||
def get_input_current(self):
|
||||
"""
|
||||
@ -172,9 +242,9 @@ class Psu(PsuBase):
|
||||
"""
|
||||
is_valid, input_current = self.input_current_sensor.get_reading()
|
||||
if not is_valid:
|
||||
return None
|
||||
return 0.0
|
||||
|
||||
return "{:.1f}".format(input_current)
|
||||
return float(input_current)
|
||||
|
||||
def get_input_power(self):
|
||||
"""
|
||||
@ -188,7 +258,7 @@ class Psu(PsuBase):
|
||||
if not is_valid:
|
||||
return None
|
||||
|
||||
return "{:.1f}".format(input_power)
|
||||
return float(input_power)
|
||||
|
||||
def get_powergood_status(self):
|
||||
"""
|
||||
@ -201,7 +271,7 @@ class Psu(PsuBase):
|
||||
status = False
|
||||
is_valid, state = self.state_sensor.get_reading()
|
||||
if is_valid:
|
||||
if (state == 0x01):
|
||||
if (state == 0x01):
|
||||
status = True
|
||||
|
||||
return status
|
||||
@ -228,3 +298,33 @@ class Psu(PsuBase):
|
||||
if 'AC' in info : return 'AC'
|
||||
if 'DC' in info : return 'DC'
|
||||
return None
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.index
|
||||
|
||||
def get_maximum_supplied_power(self):
|
||||
"""
|
||||
Retrieves the maximum supplied power by PSU
|
||||
Returns:
|
||||
A float number, the maximum power output in Watts.
|
||||
e.g. 1200.1
|
||||
"""
|
||||
return float(750)
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Sets the state of the PSU status LED
|
||||
Args:
|
||||
color: A string representing the color with which to set the PSU status LED
|
||||
Note: Only support green and off
|
||||
Returns:
|
||||
bool: True if status LED state is set successfully, False if not
|
||||
"""
|
||||
# Hardware not supported
|
||||
return False
|
||||
|
@ -19,6 +19,10 @@ try:
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
QSFP_INFO_OFFSET = 128
|
||||
SFP_INFO_OFFSET = 0
|
||||
QSFP_DD_PAGE0 = 0
|
||||
|
||||
SFP_TYPE_LIST = [
|
||||
'0x3' # SFP/SFP+/SFP28 and later
|
||||
]
|
||||
@ -39,6 +43,7 @@ class Sfp(SfpOptoeBase):
|
||||
|
||||
def __init__(self, index, sfp_type, eeprom_path):
|
||||
SfpOptoeBase.__init__(self)
|
||||
self.port_type = sfp_type
|
||||
self.sfp_type = sfp_type
|
||||
self.port_type = sfp_type
|
||||
self.index = index
|
||||
@ -92,6 +97,23 @@ class Sfp(SfpOptoeBase):
|
||||
self.set_media_type()
|
||||
self.reinit_sfp_driver()
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.index
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether this device is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the sfp
|
||||
@ -313,3 +335,33 @@ class Sfp(SfpOptoeBase):
|
||||
except IOError as e:
|
||||
print("Error: Unable to open file: %s" % str(e))
|
||||
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 not self.get_presence():
|
||||
return self.SFP_STATUS_UNPLUGGED
|
||||
else:
|
||||
if not os.path.isfile(self.eeprom_path):
|
||||
return "EEPROM driver is not attached"
|
||||
|
||||
if self.sfp_type == 'SFP':
|
||||
offset = SFP_INFO_OFFSET
|
||||
elif self.sfp_type == 'QSFP':
|
||||
offset = QSFP_INFO_OFFSET
|
||||
elif self.sfp_type == 'QSFP_DD':
|
||||
offset = QSFP_DD_PAGE0
|
||||
|
||||
try:
|
||||
with open(self.eeprom_path, mode="rb", buffering=0) as eeprom:
|
||||
eeprom.seek(offset)
|
||||
eeprom.read(1)
|
||||
except OSError as e:
|
||||
return "EEPROM read failed ({})".format(e.strerror)
|
||||
|
||||
return self.SFP_STATUS_OK
|
||||
|
@ -107,7 +107,7 @@ class Thermal(ThermalBase):
|
||||
"""
|
||||
is_valid, high_threshold = self.sensor.get_threshold("UpperNonCritical")
|
||||
if not is_valid:
|
||||
return super(Thermal, self).get_high_threshold()
|
||||
return 0.0
|
||||
|
||||
return float(high_threshold)
|
||||
|
||||
@ -122,7 +122,7 @@ class Thermal(ThermalBase):
|
||||
"""
|
||||
is_valid, high_crit_threshold = self.sensor.get_threshold("UpperCritical")
|
||||
if not is_valid:
|
||||
return super(Thermal, self).get_high_critical_threshold()
|
||||
return 0.0
|
||||
|
||||
return float(high_crit_threshold)
|
||||
|
||||
@ -168,3 +168,20 @@ class Thermal(ThermalBase):
|
||||
"""
|
||||
# Thermal threshold values are pre-defined based on HW.
|
||||
return False
|
||||
|
||||
def get_position_in_parent(self):
|
||||
"""
|
||||
Retrieves 1-based relative physical position in parent device.
|
||||
Returns:
|
||||
integer: The 1-based relative physical position in parent
|
||||
device or -1 if cannot determine the position
|
||||
"""
|
||||
return self.index
|
||||
|
||||
def is_replaceable(self):
|
||||
"""
|
||||
Indicate whether this Thermal is replaceable.
|
||||
Returns:
|
||||
bool: True if it is replaceable.
|
||||
"""
|
||||
return False
|
||||
|
@ -95,7 +95,7 @@ class Watchdog(WatchdogBase):
|
||||
"""
|
||||
timer_offset = -1
|
||||
for key,timer_seconds in enumerate(self.TIMERS):
|
||||
if seconds <= timer_seconds:
|
||||
if seconds > 0 and seconds <= timer_seconds:
|
||||
timer_offset = key
|
||||
seconds = timer_seconds
|
||||
break
|
||||
@ -126,18 +126,15 @@ class Watchdog(WatchdogBase):
|
||||
# Last bit = WD Timer punch
|
||||
self._set_reg_val(reg_val & 0xFE)
|
||||
|
||||
self.armed_time = self._get_time()
|
||||
self.timeout = seconds
|
||||
return seconds
|
||||
else:
|
||||
# Setting 4th bit to enable WD
|
||||
# 4th bit = Enable WD
|
||||
reg_val = self._get_reg_val()
|
||||
self._set_reg_val(reg_val | 0x8)
|
||||
|
||||
self.armed_time = self._get_time()
|
||||
self.timeout = seconds
|
||||
return seconds
|
||||
self.armed_time = self._get_time()
|
||||
self.timeout = seconds
|
||||
return seconds
|
||||
|
||||
def disarm(self):
|
||||
"""
|
||||
|
Reference in New Issue
Block a user