[device/celestica]: Fix failed test cases of Haliburton platform API (#7579)
- Why I did it To fix failed test cases of Haliburton platform APIs that found on platform_tests script - How I did it Add device/celestica/x86_64-cel_e1031-r0/platform.json Update functions to support python3.7 Add more functions follow latest sonic_platform_base Fix the bug - How to verify it Run platform_tests script Signed-off-by: Wirut Getbamrung [wgetbumr@celestica.com]
This commit is contained in:
parent
7698747028
commit
4bf873bf42
758
device/celestica/x86_64-cel_e1031-r0/platform.json
Normal file
758
device/celestica/x86_64-cel_e1031-r0/platform.json
Normal file
@ -0,0 +1,758 @@
|
|||||||
|
{
|
||||||
|
"chassis": {
|
||||||
|
"name": "Celestica-E1031-T48S4",
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"name": "SMC_CPLD"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "MMC_CPLD"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BIOS"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fan_drawers": [
|
||||||
|
{
|
||||||
|
"name": "Drawer1",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Drawer2",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Drawer3",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"psus": [
|
||||||
|
{
|
||||||
|
"name": "PSU-R",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "PSU-1 FAN-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "PSU-L",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "PSU-2 FAN-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thermals": [
|
||||||
|
{
|
||||||
|
"name": "Inlet ambient sensor (Rear to Front)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Helix shutdown sensor (Rear to Front)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Inlet ambient sensor (Front to Rear, right)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Helix shutdown sensor (Front to Rear)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Inlet ambient sensor (Front to Rear, left)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CPU errata sensor (Front to Rear)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CPU errata sensor (Rear to Front)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sfps": [
|
||||||
|
{
|
||||||
|
"name": "Ethernet54"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet12"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet13"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet14"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet15"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet17"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet18"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet19"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet21"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet22"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet23"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet25"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet26"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet27"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet28"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet30"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet31"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet33"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet34"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet35"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet36"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet37"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet38"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet39"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet40"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet41"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet42"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet43"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet44"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet45"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet46"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet47"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet48"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet49"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet51"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet52"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet53"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"interfaces": {
|
||||||
|
"Ethernet0": {
|
||||||
|
"index": "1",
|
||||||
|
"lanes": "2",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet1": {
|
||||||
|
"index": "2",
|
||||||
|
"lanes": "1",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet2": {
|
||||||
|
"index": "3",
|
||||||
|
"lanes": "4",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp3"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet3": {
|
||||||
|
"index": "4",
|
||||||
|
"lanes": "3",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp4"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet4": {
|
||||||
|
"index": "5",
|
||||||
|
"lanes": "6",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp5"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet5": {
|
||||||
|
"index": "6",
|
||||||
|
"lanes": "5",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp6"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet6": {
|
||||||
|
"index": "7",
|
||||||
|
"lanes": "8",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp7"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet7": {
|
||||||
|
"index": "8",
|
||||||
|
"lanes": "7",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet8": {
|
||||||
|
"index": "9",
|
||||||
|
"lanes": "10",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp9"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet9": {
|
||||||
|
"index": "10",
|
||||||
|
"lanes": "9",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp10"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet10": {
|
||||||
|
"index": "11",
|
||||||
|
"lanes": "12",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp11"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet11": {
|
||||||
|
"index": "12",
|
||||||
|
"lanes": "11",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp12"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet12": {
|
||||||
|
"index": "13",
|
||||||
|
"lanes": "14",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp13"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet13": {
|
||||||
|
"index": "14",
|
||||||
|
"lanes": "13",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp14"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet14": {
|
||||||
|
"index": "15",
|
||||||
|
"lanes": "16",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp15"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet15": {
|
||||||
|
"index": "16",
|
||||||
|
"lanes": "15",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp16"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet16": {
|
||||||
|
"index": "17",
|
||||||
|
"lanes": "18",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp17"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet17": {
|
||||||
|
"index": "18",
|
||||||
|
"lanes": "17",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp18"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet18": {
|
||||||
|
"index": "19",
|
||||||
|
"lanes": "20",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp19"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet19": {
|
||||||
|
"index": "20",
|
||||||
|
"lanes": "19",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp20"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet20": {
|
||||||
|
"index": "21",
|
||||||
|
"lanes": "22",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp21"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet21": {
|
||||||
|
"index": "22",
|
||||||
|
"lanes": "21",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp22"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet22": {
|
||||||
|
"index": "23",
|
||||||
|
"lanes": "24",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp23"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet23": {
|
||||||
|
"index": "24",
|
||||||
|
"lanes": "23",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp24"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet24": {
|
||||||
|
"index": "25",
|
||||||
|
"lanes": "26",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp25"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet25": {
|
||||||
|
"index": "26",
|
||||||
|
"lanes": "25",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp26"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet26": {
|
||||||
|
"index": "27",
|
||||||
|
"lanes": "28",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp27"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet27": {
|
||||||
|
"index": "28",
|
||||||
|
"lanes": "27",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp28"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet28": {
|
||||||
|
"index": "29",
|
||||||
|
"lanes": "30",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp29"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet29": {
|
||||||
|
"index": "30",
|
||||||
|
"lanes": "29",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp30"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet30": {
|
||||||
|
"index": "31",
|
||||||
|
"lanes": "32",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp31"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet31": {
|
||||||
|
"index": "32",
|
||||||
|
"lanes": "31",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp32"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet32": {
|
||||||
|
"index": "33",
|
||||||
|
"lanes": "34",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp33"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet33": {
|
||||||
|
"index": "34",
|
||||||
|
"lanes": "33",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp34"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet34": {
|
||||||
|
"index": "35",
|
||||||
|
"lanes": "36",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp35"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet35": {
|
||||||
|
"index": "36",
|
||||||
|
"lanes": "35",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp36"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet36": {
|
||||||
|
"index": "37",
|
||||||
|
"lanes": "38",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp37"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet37": {
|
||||||
|
"index": "38",
|
||||||
|
"lanes": "37",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp38"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet38": {
|
||||||
|
"index": "39",
|
||||||
|
"lanes": "40",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp39"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet39": {
|
||||||
|
"index": "40",
|
||||||
|
"lanes": "39",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp40"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet40": {
|
||||||
|
"index": "41",
|
||||||
|
"lanes": "42",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp41"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet41": {
|
||||||
|
"index": "42",
|
||||||
|
"lanes": "41",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp42"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet42": {
|
||||||
|
"index": "43",
|
||||||
|
"lanes": "44",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp43"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet43": {
|
||||||
|
"index": "44",
|
||||||
|
"lanes": "43",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp44"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet44": {
|
||||||
|
"index": "45",
|
||||||
|
"lanes": "46",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp45"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet45": {
|
||||||
|
"index": "46",
|
||||||
|
"lanes": "45",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp46"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet46": {
|
||||||
|
"index": "47",
|
||||||
|
"lanes": "48",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp47"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet47": {
|
||||||
|
"index": "48",
|
||||||
|
"lanes": "47",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x1G": [
|
||||||
|
"etp48"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet48": {
|
||||||
|
"index": "49",
|
||||||
|
"lanes": "48",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x10G": [
|
||||||
|
"etp49"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet49": {
|
||||||
|
"index": "50",
|
||||||
|
"lanes": "53",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x10G": [
|
||||||
|
"etp50"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet50": {
|
||||||
|
"index": "51",
|
||||||
|
"lanes": "56",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x10G": [
|
||||||
|
"etp51"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet51": {
|
||||||
|
"index": "52",
|
||||||
|
"lanes": "55",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x10G": [
|
||||||
|
"etp52"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet52": {
|
||||||
|
"index": "53",
|
||||||
|
"lanes": "49",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x10G": [
|
||||||
|
"etp53"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet53": {
|
||||||
|
"index": "54,54,54,54",
|
||||||
|
"lanes": "57,58,59,60 ",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x10G": [
|
||||||
|
"etp54"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Ethernet54": {
|
||||||
|
"index": "55,55,55,55",
|
||||||
|
"lanes": "61,62,63,64",
|
||||||
|
"breakout_modes": {
|
||||||
|
"1x10G": [
|
||||||
|
"etp55"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"chassis": {
|
||||||
|
"Celestica-E1031-T48S4": {
|
||||||
|
"component": {
|
||||||
|
"BIOS": {},
|
||||||
|
"SMC_CPLD": {},
|
||||||
|
"MMC_CPLD": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,63 +11,17 @@ class SfpUtil(SfpUtilBase):
|
|||||||
"""Platform-specific SfpUtil class"""
|
"""Platform-specific SfpUtil class"""
|
||||||
|
|
||||||
PORT_START = 1
|
PORT_START = 1
|
||||||
PORT_END = 52
|
PORT_END = 55
|
||||||
|
SFP_PORT_START = 49
|
||||||
|
SFP_PORT_END = 52
|
||||||
port_to_i2c_mapping = {
|
port_to_i2c_mapping = {
|
||||||
1: None,
|
|
||||||
2: None,
|
|
||||||
3: None,
|
|
||||||
4: None,
|
|
||||||
5: None,
|
|
||||||
6: None,
|
|
||||||
7: None,
|
|
||||||
8: None,
|
|
||||||
9: None,
|
|
||||||
10: None,
|
|
||||||
11: None,
|
|
||||||
12: None,
|
|
||||||
13: None,
|
|
||||||
14: None,
|
|
||||||
15: None,
|
|
||||||
16: None,
|
|
||||||
17: None,
|
|
||||||
18: None,
|
|
||||||
19: None,
|
|
||||||
20: None,
|
|
||||||
21: None,
|
|
||||||
22: None,
|
|
||||||
23: None,
|
|
||||||
24: None,
|
|
||||||
25: None,
|
|
||||||
26: None,
|
|
||||||
27: None,
|
|
||||||
28: None,
|
|
||||||
29: None,
|
|
||||||
30: None,
|
|
||||||
31: None,
|
|
||||||
32: None,
|
|
||||||
33: None,
|
|
||||||
34: None,
|
|
||||||
35: None,
|
|
||||||
36: None,
|
|
||||||
37: None,
|
|
||||||
38: None,
|
|
||||||
39: None,
|
|
||||||
40: None,
|
|
||||||
41: None,
|
|
||||||
42: None,
|
|
||||||
43: None,
|
|
||||||
44: None,
|
|
||||||
45: None,
|
|
||||||
46: None,
|
|
||||||
47: None,
|
|
||||||
48: None,
|
|
||||||
49: 15,
|
49: 15,
|
||||||
50: 14,
|
50: 14,
|
||||||
51: 17,
|
51: 17,
|
||||||
52: 16
|
52: 16
|
||||||
}
|
}
|
||||||
_port_to_eeprom_mapping = {}
|
_port_to_eeprom_mapping = {}
|
||||||
_sfp_port = list(range(49, PORT_END + 1))
|
_sfp_port = list(range(SFP_PORT_START, SFP_PORT_END + 1))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port_start(self):
|
def port_start(self):
|
||||||
@ -89,7 +43,7 @@ class SfpUtil(SfpUtilBase):
|
|||||||
# Override port_to_eeprom_mapping for class initialization
|
# Override port_to_eeprom_mapping for class initialization
|
||||||
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
|
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
|
||||||
for x in range(self.PORT_START, self.PORT_END + 1):
|
for x in range(self.PORT_START, self.PORT_END + 1):
|
||||||
port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x])
|
port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) if x in self._sfp_port else None
|
||||||
self.port_to_eeprom_mapping[x] = port_eeprom_path
|
self.port_to_eeprom_mapping[x] = port_eeprom_path
|
||||||
SfpUtilBase.__init__(self)
|
SfpUtilBase.__init__(self)
|
||||||
|
|
||||||
@ -103,7 +57,7 @@ class SfpUtil(SfpUtilBase):
|
|||||||
try:
|
try:
|
||||||
with open(sfp_modabs_path, 'r') as port_status:
|
with open(sfp_modabs_path, 'r') as port_status:
|
||||||
status = int(port_status.read(), 16)
|
status = int(port_status.read(), 16)
|
||||||
status = (status >> (port_num - 49)) & 1
|
status = (status >> (port_num - self.SFP_PORT_START)) & 1
|
||||||
except IOError:
|
except IOError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -138,7 +92,8 @@ class SfpUtil(SfpUtilBase):
|
|||||||
for port_num in self._sfp_port:
|
for port_num in self._sfp_port:
|
||||||
change = (changes >> (port_num - 49)) & 1
|
change = (changes >> (port_num - 49)) & 1
|
||||||
if change == 1:
|
if change == 1:
|
||||||
port_dict[str(port_num)] = str(int(self.get_presence(port_num)))
|
port_dict[str(port_num)] = str(
|
||||||
|
int(self.get_presence(port_num)))
|
||||||
found_flag = 1
|
found_flag = 1
|
||||||
|
|
||||||
if not found_flag:
|
if not found_flag:
|
||||||
|
@ -6,25 +6,26 @@
|
|||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import sys
|
|
||||||
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
|
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
|
||||||
from sonic_platform_base.chassis_base import ChassisBase
|
from sonic_platform_base.chassis_base import ChassisBase
|
||||||
|
from sonic_py_common import device_info
|
||||||
from .common import Common
|
from .common import Common
|
||||||
from .event import SfpEvent
|
from .event import SfpEvent
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
NUM_FAN_TRAY = 3
|
NUM_FAN_TRAY = 3
|
||||||
NUM_FAN = 1
|
|
||||||
NUM_PSU = 2
|
NUM_PSU = 2
|
||||||
NUM_THERMAL = 7
|
NUM_THERMAL = 7
|
||||||
NUM_SFP = 52
|
NUM_SFP = 55
|
||||||
NUM_COMPONENT = 3
|
NUM_COMPONENT = 3
|
||||||
RESET_REGISTER = "0x112"
|
RESET_REGISTER = "0x112"
|
||||||
HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt"
|
HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt"
|
||||||
PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/previous-reboot-cause.txt"
|
PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/previous-reboot-cause.txt"
|
||||||
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
||||||
|
STATUS_LED_PATH = "/sys/devices/platform/e1031.smc/master_led"
|
||||||
|
|
||||||
|
|
||||||
class Chassis(ChassisBase):
|
class Chassis(ChassisBase):
|
||||||
@ -32,66 +33,63 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
ChassisBase.__init__(self)
|
ChassisBase.__init__(self)
|
||||||
self._api_common = Common()
|
|
||||||
self.sfp_module_initialized = False
|
|
||||||
self.__initialize_eeprom()
|
|
||||||
self.is_host = self._api_common.is_host()
|
|
||||||
|
|
||||||
if not self.is_host:
|
self._api_common = Common()
|
||||||
|
self._is_host = self._api_common.is_host()
|
||||||
|
|
||||||
|
self.__initialize_eeprom()
|
||||||
self.__initialize_fan()
|
self.__initialize_fan()
|
||||||
self.__initialize_psu()
|
self.__initialize_psu()
|
||||||
self.__initialize_thermals()
|
self.__initialize_thermals()
|
||||||
else:
|
|
||||||
self.__initialize_components()
|
self.__initialize_components()
|
||||||
|
|
||||||
self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host(
|
self.sfp_module_initialized = False
|
||||||
) else PMON_REBOOT_CAUSE_PATH
|
self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self._is_host else PMON_REBOOT_CAUSE_PATH
|
||||||
|
|
||||||
def __initialize_sfp(self):
|
def __initialize_sfp(self):
|
||||||
sfputil_helper = SfpUtilHelper()
|
sfputil_helper = SfpUtilHelper()
|
||||||
port_config_file_path = device_info.get_path_to_port_config_file()
|
port_config_file_path = device_info.get_path_to_port_config_file()
|
||||||
sfputil_helper.read_porttab_mappings(port_config_file_path, 0)
|
sfputil_helper.read_porttab_mappings(port_config_file_path, 0)
|
||||||
|
|
||||||
from sonic_platform.sfp import Sfp
|
from .sfp import Sfp
|
||||||
for index in range(0, NUM_SFP):
|
for index in range(0, NUM_SFP):
|
||||||
name_idx = 0 if index+1 == NUM_SFP else index+1
|
sfp = Sfp(index, sfputil_helper.logical[index])
|
||||||
sfp = Sfp(index, sfputil_helper.logical[name_idx])
|
|
||||||
self._sfp_list.append(sfp)
|
self._sfp_list.append(sfp)
|
||||||
self.sfp_module_initialized = True
|
self.sfp_module_initialized = True
|
||||||
|
|
||||||
def __initialize_psu(self):
|
def __initialize_psu(self):
|
||||||
from sonic_platform.psu import Psu
|
from .psu import Psu
|
||||||
for index in range(0, NUM_PSU):
|
for index in range(0, NUM_PSU):
|
||||||
psu = Psu(index)
|
psu = Psu(index)
|
||||||
self._psu_list.append(psu)
|
self._psu_list.append(psu)
|
||||||
|
|
||||||
def __initialize_fan(self):
|
def __initialize_fan(self):
|
||||||
from sonic_platform.fan import Fan
|
from .fan_drawer import FanDrawer
|
||||||
for fant_index in range(0, NUM_FAN_TRAY):
|
for i in range(NUM_FAN_TRAY):
|
||||||
for fan_index in range(0, NUM_FAN):
|
fandrawer = FanDrawer(i)
|
||||||
fan = Fan(fant_index, fan_index)
|
self._fan_drawer_list.append(fandrawer)
|
||||||
self._fan_list.append(fan)
|
self._fan_list += fandrawer.get_all_fans()
|
||||||
|
|
||||||
def __initialize_thermals(self):
|
def __initialize_thermals(self):
|
||||||
from sonic_platform.thermal import Thermal
|
from .thermal import Thermal
|
||||||
airflow = self.__get_air_flow()
|
airflow = self.__get_air_flow()
|
||||||
for index in range(0, NUM_THERMAL):
|
for index in range(0, NUM_THERMAL):
|
||||||
thermal = Thermal(index, airflow)
|
thermal = Thermal(index, airflow)
|
||||||
self._thermal_list.append(thermal)
|
self._thermal_list.append(thermal)
|
||||||
|
|
||||||
def __initialize_eeprom(self):
|
def __initialize_eeprom(self):
|
||||||
from sonic_platform.eeprom import Tlv
|
from .eeprom import Tlv
|
||||||
self._eeprom = Tlv()
|
self._eeprom = Tlv()
|
||||||
|
|
||||||
def __initialize_components(self):
|
def __initialize_components(self):
|
||||||
from sonic_platform.component import Component
|
from .component import Component
|
||||||
for index in range(0, NUM_COMPONENT):
|
for index in range(0, NUM_COMPONENT):
|
||||||
component = Component(index)
|
component = Component(index)
|
||||||
self._component_list.append(component)
|
self._component_list.append(component)
|
||||||
|
|
||||||
def __get_air_flow(self):
|
def __get_air_flow(self):
|
||||||
air_flow_path = '/usr/share/sonic/device/{}/fan_airflow'.format(
|
air_flow_path = '/usr/share/sonic/device/{}/fan_airflow'.format(
|
||||||
self._api_common.platform) if self.is_host else '/usr/share/sonic/platform/fan_airflow'
|
self._api_common.get_platform()) if self._is_host else '/usr/share/sonic/platform/fan_airflow'
|
||||||
air_flow = self._api_common.read_txt_file(air_flow_path)
|
air_flow = self._api_common.read_txt_file(air_flow_path)
|
||||||
return air_flow or 'B2F'
|
return air_flow or 'B2F'
|
||||||
|
|
||||||
@ -154,7 +152,6 @@ class Chassis(ChassisBase):
|
|||||||
else:
|
else:
|
||||||
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
|
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
|
||||||
description = 'Unknown reason'
|
description = 'Unknown reason'
|
||||||
|
|
||||||
return (reboot_cause, description)
|
return (reboot_cause, description)
|
||||||
|
|
||||||
def get_watchdog(self):
|
def get_watchdog(self):
|
||||||
@ -247,7 +244,7 @@ class Chassis(ChassisBase):
|
|||||||
# The index will start from 1
|
# The index will start from 1
|
||||||
sfp = self._sfp_list[index-1]
|
sfp = self._sfp_list[index-1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
sys.stderr.write("SFP index {} out of range (1-{})\n".format(
|
print("SFP index {} out of range (1-{})\n".format(
|
||||||
index, len(self._sfp_list)))
|
index, len(self._sfp_list)))
|
||||||
return sfp
|
return sfp
|
||||||
|
|
||||||
@ -269,13 +266,13 @@ class Chassis(ChassisBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: The name of the device
|
string: The name of the device
|
||||||
"""
|
"""
|
||||||
return self._api_common.hwsku
|
return self._api_common.get_hwsku()
|
||||||
|
|
||||||
def get_presence(self):
|
def get_presence(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the presence of the PSU
|
Retrieves the presence of the Chassis
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if PSU is present, False if not
|
bool: True if Chassis is present, False if not
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -303,3 +300,52 @@ class Chassis(ChassisBase):
|
|||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_position_in_parent(self):
|
||||||
|
"""
|
||||||
|
Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position
|
||||||
|
for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned
|
||||||
|
Returns:
|
||||||
|
integer: The 1-based relative physical position in parent device or -1 if cannot determine the position
|
||||||
|
"""
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
|
||||||
|
status_str = {
|
||||||
|
self.STATUS_LED_COLOR_GREEN: 'green',
|
||||||
|
self.STATUS_LED_COLOR_AMBER: 'amber',
|
||||||
|
self.STATUS_LED_COLOR_OFF: 'off'
|
||||||
|
}.get(color, 'off')
|
||||||
|
|
||||||
|
return self._api_common.write_txt_file(STATUS_LED_PATH, status_str)
|
||||||
|
|
||||||
|
def get_status_led(self):
|
||||||
|
"""
|
||||||
|
Gets the state of the PSU status LED
|
||||||
|
Returns:
|
||||||
|
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||||
|
"""
|
||||||
|
status = self._api_common.read_txt_file(STATUS_LED_PATH)
|
||||||
|
status_str = {
|
||||||
|
'on': self.STATUS_LED_COLOR_GREEN,
|
||||||
|
'amber': self.STATUS_LED_COLOR_AMBER,
|
||||||
|
'off': self.STATUS_LED_COLOR_OFF
|
||||||
|
}.get(status, None)
|
||||||
|
|
||||||
|
return status_str
|
||||||
|
@ -29,7 +29,18 @@ class Common:
|
|||||||
|
|
||||||
def __init__(self, conf=None):
|
def __init__(self, conf=None):
|
||||||
self._main_conf = conf
|
self._main_conf = conf
|
||||||
(self.platform, self.hwsku) = device_info.get_platform_and_hwsku()
|
self.platform = None
|
||||||
|
self.hwsku = None
|
||||||
|
|
||||||
|
def get_platform(self):
|
||||||
|
(self.platform, self.hwsku) = device_info.get_platform_and_hwsku(
|
||||||
|
) if not self.platform else (self.platform, self.hwsku)
|
||||||
|
return self.platform
|
||||||
|
|
||||||
|
def get_hwsku(self):
|
||||||
|
(self.platform, self.hwsku) = device_info.get_platform_and_hwsku(
|
||||||
|
) if not self.hwsku else (self.platform, self.hwsku)
|
||||||
|
return self.hwsku
|
||||||
|
|
||||||
def run_command(self, command):
|
def run_command(self, command):
|
||||||
status = False
|
status = False
|
||||||
@ -38,7 +49,7 @@ class Common:
|
|||||||
p = subprocess.Popen(
|
p = subprocess.Popen(
|
||||||
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
raw_data, err = p.communicate()
|
raw_data, err = p.communicate()
|
||||||
if err == '':
|
if p.returncode == 0:
|
||||||
status, output = True, raw_data.strip()
|
status, output = True, raw_data.strip()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
@ -152,10 +163,28 @@ class Common:
|
|||||||
status, output = self.run_command(cmd)
|
status, output = self.run_command(cmd)
|
||||||
return output if status else None
|
return output if status else None
|
||||||
|
|
||||||
|
def set_reg(self, path, reg_addr, value):
|
||||||
|
cmd = "echo {0} {1} > {2}".format(reg_addr, value, path)
|
||||||
|
status, output = self.run_command(cmd)
|
||||||
|
return output if status else None
|
||||||
|
|
||||||
def read_txt_file(self, path):
|
def read_txt_file(self, path):
|
||||||
|
try:
|
||||||
with open(path, 'r') as f:
|
with open(path, 'r') as f:
|
||||||
output = f.readline()
|
output = f.readline()
|
||||||
return output.strip('\n')
|
return output.strip('\n')
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def read_one_line_file(self, file_path):
|
||||||
|
try:
|
||||||
|
with open(file_path, 'r') as fd:
|
||||||
|
data = fd.readline()
|
||||||
|
return data.strip()
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
return ''
|
||||||
|
|
||||||
def write_txt_file(self, file_path, value):
|
def write_txt_file(self, file_path, value):
|
||||||
try:
|
try:
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
import os.path
|
|
||||||
import shutil
|
|
||||||
import shlex
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
import os.path
|
||||||
|
import shutil
|
||||||
|
import shlex
|
||||||
|
import subprocess
|
||||||
from sonic_platform_base.component_base import ComponentBase
|
from sonic_platform_base.component_base import ComponentBase
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
@ -119,6 +119,29 @@ class Component(ComponentBase):
|
|||||||
|
|
||||||
return fw_version
|
return fw_version
|
||||||
|
|
||||||
|
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 install_firmware(self, image_path):
|
def install_firmware(self, image_path):
|
||||||
"""
|
"""
|
||||||
Install firmware to module
|
Install firmware to module
|
||||||
@ -139,5 +162,73 @@ class Component(ComponentBase):
|
|||||||
install_command = "ispvm %s" % new_image_path
|
install_command = "ispvm %s" % new_image_path
|
||||||
# elif self.name == "BIOS":
|
# elif self.name == "BIOS":
|
||||||
# install_command = "afulnx_64 %s /p /b /n /x /r" % image_path
|
# install_command = "afulnx_64 %s /p /b /n /x /r" % image_path
|
||||||
|
|
||||||
return self.__run_command(install_command)
|
return self.__run_command(install_command)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
###################### Device methods ########################
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
def get_presence(self):
|
||||||
|
"""
|
||||||
|
Retrieves the presence of the FAN
|
||||||
|
Returns:
|
||||||
|
bool: True if FAN is present, False if not
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the device
|
||||||
|
Returns:
|
||||||
|
string: Model/part number of device
|
||||||
|
"""
|
||||||
|
return 'N/A'
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the device
|
||||||
|
Returns:
|
||||||
|
string: Serial number of device
|
||||||
|
"""
|
||||||
|
return 'N/A'
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the device
|
||||||
|
Returns:
|
||||||
|
A boolean value, True if device is operating properly, False if not
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_position_in_parent(self):
|
||||||
|
"""
|
||||||
|
Retrieves 1-based relative physical position in parent device.
|
||||||
|
If the agent cannot determine the parent-relative position
|
||||||
|
for some reason, or if the associated value of
|
||||||
|
entPhysicalContainedIn is'0', then the value '-1' is returned
|
||||||
|
Returns:
|
||||||
|
integer: The 1-based relative physical position in parent device
|
||||||
|
or -1 if cannot determine the position
|
||||||
|
"""
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
@ -17,13 +17,14 @@ try:
|
|||||||
else:
|
else:
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
from sonic_platform_base.sonic_eeprom import eeprom_dts
|
|
||||||
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
|
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
|
||||||
|
from sonic_platform_base.sonic_eeprom.eeprom_base import EepromDecoder
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
CACHE_ROOT = '/var/cache/sonic/decode-syseeprom'
|
CACHE_ROOT = '/var/cache/sonic/decode-syseeprom'
|
||||||
CACHE_FILE = 'syseeprom_cache'
|
CACHE_FILE = 'syseeprom_cache'
|
||||||
|
NULL = 'N/A'
|
||||||
|
|
||||||
|
|
||||||
class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
||||||
@ -32,8 +33,8 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom"
|
self._eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom"
|
||||||
|
self._eeprom = None
|
||||||
super(Tlv, self).__init__(self._eeprom_path, 0, '', True)
|
super(Tlv, self).__init__(self._eeprom_path, 0, '', True)
|
||||||
self._eeprom = self._load_eeprom()
|
|
||||||
|
|
||||||
def __parse_output(self, decode_output):
|
def __parse_output(self, decode_output):
|
||||||
decode_output.replace('\0', '')
|
decode_output.replace('\0', '')
|
||||||
@ -50,7 +51,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
value = match.group(3).rstrip('\0')
|
value = match.group(3).rstrip('\0')
|
||||||
|
|
||||||
_eeprom_info_dict[idx] = value
|
_eeprom_info_dict[idx] = value
|
||||||
except Exception:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
return _eeprom_info_dict
|
return _eeprom_info_dict
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
sys.stdout = StringIO()
|
sys.stdout = StringIO()
|
||||||
try:
|
try:
|
||||||
self.read_eeprom_db()
|
self.read_eeprom_db()
|
||||||
except Exception:
|
except BaseException:
|
||||||
decode_output = sys.stdout.getvalue()
|
decode_output = sys.stdout.getvalue()
|
||||||
sys.stdout = original_stdout
|
sys.stdout = original_stdout
|
||||||
return self.__parse_output(decode_output)
|
return self.__parse_output(decode_output)
|
||||||
@ -71,7 +72,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
if not os.path.exists(CACHE_ROOT):
|
if not os.path.exists(CACHE_ROOT):
|
||||||
try:
|
try:
|
||||||
os.makedirs(CACHE_ROOT)
|
os.makedirs(CACHE_ROOT)
|
||||||
except Exception:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -80,7 +81,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
#
|
#
|
||||||
try:
|
try:
|
||||||
self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE))
|
self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE))
|
||||||
except Exception:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
e = self.read_eeprom()
|
e = self.read_eeprom()
|
||||||
@ -89,7 +90,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self.update_cache(e)
|
self.update_cache(e)
|
||||||
except Exception:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.decode_eeprom(e)
|
self.decode_eeprom(e)
|
||||||
@ -102,14 +103,98 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
|
|
||||||
return self.__parse_output(decode_output)
|
return self.__parse_output(decode_output)
|
||||||
|
|
||||||
|
def _valid_tlv(self, eeprom_data):
|
||||||
|
tlvinfo_type_codes_list = [
|
||||||
|
self._TLV_CODE_PRODUCT_NAME,
|
||||||
|
self._TLV_CODE_PART_NUMBER,
|
||||||
|
self._TLV_CODE_SERIAL_NUMBER,
|
||||||
|
self._TLV_CODE_MAC_BASE,
|
||||||
|
self._TLV_CODE_MANUF_DATE,
|
||||||
|
self._TLV_CODE_DEVICE_VERSION,
|
||||||
|
self._TLV_CODE_LABEL_REVISION,
|
||||||
|
self._TLV_CODE_PLATFORM_NAME,
|
||||||
|
self._TLV_CODE_ONIE_VERSION,
|
||||||
|
self._TLV_CODE_MAC_SIZE,
|
||||||
|
self._TLV_CODE_MANUF_NAME,
|
||||||
|
self._TLV_CODE_MANUF_COUNTRY,
|
||||||
|
self._TLV_CODE_VENDOR_NAME,
|
||||||
|
self._TLV_CODE_DIAG_VERSION,
|
||||||
|
self._TLV_CODE_SERVICE_TAG,
|
||||||
|
self._TLV_CODE_VENDOR_EXT,
|
||||||
|
self._TLV_CODE_CRC_32
|
||||||
|
]
|
||||||
|
|
||||||
|
for code in tlvinfo_type_codes_list:
|
||||||
|
code_str = "0x{:X}".format(code)
|
||||||
|
eeprom_data[code_str] = eeprom_data.get(code_str, NULL)
|
||||||
|
return eeprom_data
|
||||||
|
|
||||||
def get_eeprom(self):
|
def get_eeprom(self):
|
||||||
return self._eeprom
|
self._eeprom = self._load_eeprom() if not self._eeprom else self._eeprom
|
||||||
|
return self._valid_tlv(self._eeprom)
|
||||||
def get_serial(self):
|
|
||||||
return self._eeprom.get('0x23', "Undefined.")
|
|
||||||
|
|
||||||
def get_mac(self):
|
|
||||||
return self._eeprom.get('0x24', "Undefined.")
|
|
||||||
|
|
||||||
def get_pn(self):
|
def get_pn(self):
|
||||||
return self._eeprom.get('0x21', "Undefined.")
|
return self.get_eeprom()['0x22']
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
return self.get_eeprom()['0x23']
|
||||||
|
|
||||||
|
def get_mac(self):
|
||||||
|
return self.get_eeprom()['0x24']
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceEEPROM(eeprom_tlvinfo.TlvInfoDecoder):
|
||||||
|
|
||||||
|
def __init__(self, eeprom_path, device_format, start_offset):
|
||||||
|
# Decode device eeprom as per specified format
|
||||||
|
self.format = device_format
|
||||||
|
self.start_offset = start_offset
|
||||||
|
|
||||||
|
EepromDecoder.__init__(self, eeprom_path, self.format,
|
||||||
|
self.start_offset, '', True)
|
||||||
|
self._load_device_eeprom()
|
||||||
|
|
||||||
|
def _load_device_eeprom(self):
|
||||||
|
"""
|
||||||
|
Reads the Fan/PSU EEPROM and interprets as per the specified format
|
||||||
|
"""
|
||||||
|
self.serial_number = 'NA'
|
||||||
|
self.model_str = 'NA'
|
||||||
|
|
||||||
|
# device eeproms use proprietary format
|
||||||
|
try:
|
||||||
|
# Read Fan/PSU EEPROM as per the specified format.
|
||||||
|
self.eeprom_data = EepromDecoder.read_eeprom(self)
|
||||||
|
except Exception as e:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.eeprom_data[0] == 255:
|
||||||
|
return
|
||||||
|
|
||||||
|
(valid, data) = self._get_eeprom_field("Model")
|
||||||
|
if valid:
|
||||||
|
self.model_str = data.decode()
|
||||||
|
|
||||||
|
try:
|
||||||
|
(valid, data) = self._get_eeprom_field("Serial Number")
|
||||||
|
if valid:
|
||||||
|
self.serial_number = data.decode()
|
||||||
|
except Exception as e:
|
||||||
|
return
|
||||||
|
|
||||||
|
def _get_eeprom_field(self, field_name, decode=False):
|
||||||
|
"""
|
||||||
|
For a field name specified in the EEPROM format, returns the
|
||||||
|
presence of the field and the value for the same.
|
||||||
|
"""
|
||||||
|
field_start = 0
|
||||||
|
for field in self.format:
|
||||||
|
field_end = field_start + field[2]
|
||||||
|
if field[0] == field_name:
|
||||||
|
if decode:
|
||||||
|
return (True, self.eeprom_data[field_start:field_end].decode('ascii'))
|
||||||
|
else:
|
||||||
|
return (True, self.eeprom_data[field_start:field_end])
|
||||||
|
field_start = field_end
|
||||||
|
|
||||||
|
return (False, None)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
try:
|
try:
|
||||||
import time
|
import time
|
||||||
import select
|
import select
|
||||||
from .helper import APIHelper
|
from .common import Common
|
||||||
from sonic_py_common.logger import Logger
|
from sonic_py_common.logger import Logger
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(repr(e) + " - required module not found")
|
raise ImportError(repr(e) + " - required module not found")
|
||||||
@ -16,12 +16,12 @@ class SfpEvent:
|
|||||||
GPIO_SUS7 = '/sys/devices/platform/hlx-ich.0/sci_int_gpio_sus7'
|
GPIO_SUS7 = '/sys/devices/platform/hlx-ich.0/sci_int_gpio_sus7'
|
||||||
|
|
||||||
def __init__(self, sfp_list):
|
def __init__(self, sfp_list):
|
||||||
self._api_helper = APIHelper()
|
self._api_common = Common()
|
||||||
self._sfp_list = sfp_list
|
self._sfp_list = sfp_list
|
||||||
self._logger = Logger()
|
self._logger = Logger()
|
||||||
|
|
||||||
# clear interrupt
|
# clear interrupt
|
||||||
self._api_helper.read_one_line_file(self.INT_PATH)
|
self._api_common.read_one_line_file(self.INT_PATH)
|
||||||
|
|
||||||
def get_sfp_event(self, timeout):
|
def get_sfp_event(self, timeout):
|
||||||
epoll = select.epoll()
|
epoll = select.epoll()
|
||||||
@ -37,7 +37,7 @@ class SfpEvent:
|
|||||||
events = epoll.poll(timeout=timeout_sec if timeout != 0 else -1)
|
events = epoll.poll(timeout=timeout_sec if timeout != 0 else -1)
|
||||||
if events:
|
if events:
|
||||||
# Read the QSFP ABS interrupt & status registers
|
# Read the QSFP ABS interrupt & status registers
|
||||||
port_changes = self._api_helper.read_one_line_file(
|
port_changes = self._api_common.read_one_line_file(
|
||||||
self.INT_PATH)
|
self.INT_PATH)
|
||||||
changes = int(port_changes, 16)
|
changes = int(port_changes, 16)
|
||||||
for sfp in self._sfp_list:
|
for sfp in self._sfp_list:
|
||||||
@ -48,7 +48,8 @@ class SfpEvent:
|
|||||||
if change == 1:
|
if change == 1:
|
||||||
time.sleep(self.DELAY)
|
time.sleep(self.DELAY)
|
||||||
port_status = sfp.get_presence()
|
port_status = sfp.get_presence()
|
||||||
port_dict[str(sfp.port_num)] = '1' if port_status else '0'
|
port_dict[str(sfp.port_num)
|
||||||
|
] = '1' if port_status else '0'
|
||||||
|
|
||||||
return port_dict
|
return port_dict
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
|
from __future__ import division
|
||||||
import math
|
import math
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
@ -20,8 +21,10 @@ FAN_PATH = "/sys/devices/platform/e1031.smc/"
|
|||||||
EMC2305_MAX_PWM = 255
|
EMC2305_MAX_PWM = 255
|
||||||
EMC2305_FAN_PWM = "pwm{}"
|
EMC2305_FAN_PWM = "pwm{}"
|
||||||
EMC2305_FAN_TARGET = "fan{}_target"
|
EMC2305_FAN_TARGET = "fan{}_target"
|
||||||
|
EMC2305_FAN_PWM_MODE = "pwm{}_enable"
|
||||||
EMC2305_FAN_INPUT = "pwm{}"
|
EMC2305_FAN_INPUT = "pwm{}"
|
||||||
FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3"]
|
FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3"]
|
||||||
|
FAN_SPEED_TOLERANCE = 10
|
||||||
PSU_FAN_MAX_RPM = 11000
|
PSU_FAN_MAX_RPM = 11000
|
||||||
PSU_HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
PSU_HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
||||||
PSU_I2C_MAPPING = {
|
PSU_I2C_MAPPING = {
|
||||||
@ -34,12 +37,16 @@ PSU_I2C_MAPPING = {
|
|||||||
"addr": "5a"
|
"addr": "5a"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
NULL_VAL = 'N/A'
|
||||||
|
|
||||||
|
|
||||||
class Fan(FanBase):
|
class Fan(FanBase):
|
||||||
"""Platform-specific Fan class"""
|
"""Platform-specific Fan class"""
|
||||||
|
|
||||||
def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
|
def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
|
||||||
|
FanBase.__init__(self)
|
||||||
|
|
||||||
|
self._api_common = Common()
|
||||||
self.fan_index = fan_index
|
self.fan_index = fan_index
|
||||||
self.fan_tray_index = fan_tray_index
|
self.fan_tray_index = fan_tray_index
|
||||||
self.is_psu_fan = is_psu_fan
|
self.is_psu_fan = is_psu_fan
|
||||||
@ -64,13 +71,10 @@ class Fan(FanBase):
|
|||||||
self.fan_e1031_led = "fan{}_led"
|
self.fan_e1031_led = "fan{}_led"
|
||||||
self.fan_e1031_led_col_map = {
|
self.fan_e1031_led_col_map = {
|
||||||
self.STATUS_LED_COLOR_GREEN: "green",
|
self.STATUS_LED_COLOR_GREEN: "green",
|
||||||
self.STATUS_LED_COLOR_RED: "amber",
|
self.STATUS_LED_COLOR_AMBER: "amber",
|
||||||
self.STATUS_LED_COLOR_OFF: "off"
|
self.STATUS_LED_COLOR_OFF: "off"
|
||||||
}
|
}
|
||||||
|
|
||||||
self._api_common = Common()
|
|
||||||
FanBase.__init__(self)
|
|
||||||
|
|
||||||
def __search_file_by_name(self, directory, file_name):
|
def __search_file_by_name(self, directory, file_name):
|
||||||
for dirpath, dirnames, files in os.walk(directory):
|
for dirpath, dirnames, files in os.walk(directory):
|
||||||
for name in files:
|
for name in files:
|
||||||
@ -141,19 +145,26 @@ class Fan(FanBase):
|
|||||||
0 : when PWM mode is use
|
0 : when PWM mode is use
|
||||||
pwm : when pwm mode is not use
|
pwm : when pwm mode is not use
|
||||||
"""
|
"""
|
||||||
target = 0
|
target = NULL_VAL
|
||||||
if not self.is_psu_fan:
|
if not self.is_psu_fan:
|
||||||
chip = self.emc2305_chip_mapping[self.fan_index]
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
device = chip['device']
|
device = chip['device']
|
||||||
fan_index = chip['index_map']
|
fan_index = chip['index_map']
|
||||||
sysfs_path = "%s%s/%s" % (
|
|
||||||
EMC2305_PATH, device, EMC2305_FAN_TARGET)
|
enable_path = "%s%s/%s" % (
|
||||||
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
EMC2305_PATH, device, EMC2305_FAN_PWM_MODE)
|
||||||
raw = self._api_common.read_txt_file(sysfs_path).strip('\r\n')
|
enable = self._api_common.read_txt_file(
|
||||||
|
enable_path.format(fan_index[self.fan_tray_index]))
|
||||||
|
|
||||||
|
target_mode = EMC2305_FAN_TARGET if enable != "0" else EMC2305_FAN_PWM
|
||||||
|
target_path = "%s%s/%s" % (EMC2305_PATH, device,
|
||||||
|
target_mode.format(fan_index[self.fan_tray_index]))
|
||||||
|
|
||||||
|
raw = self._api_common.read_txt_file(target_path)
|
||||||
pwm = int(raw, 10) if raw else 0
|
pwm = int(raw, 10) if raw else 0
|
||||||
target = math.ceil(float(pwm) * 100 / EMC2305_MAX_PWM)
|
target = math.ceil(float(pwm) * 100 / EMC2305_MAX_PWM)
|
||||||
|
|
||||||
return target
|
return int(target)
|
||||||
|
|
||||||
def get_speed_tolerance(self):
|
def get_speed_tolerance(self):
|
||||||
"""
|
"""
|
||||||
@ -162,7 +173,7 @@ class Fan(FanBase):
|
|||||||
An integer, the percentage of variance from target speed which is
|
An integer, the percentage of variance from target speed which is
|
||||||
considered tolerable
|
considered tolerable
|
||||||
"""
|
"""
|
||||||
return 10
|
return FAN_SPEED_TOLERANCE
|
||||||
|
|
||||||
def set_speed(self, speed):
|
def set_speed(self, speed):
|
||||||
"""
|
"""
|
||||||
@ -211,6 +222,28 @@ class Fan(FanBase):
|
|||||||
|
|
||||||
return set_status_led
|
return set_status_led
|
||||||
|
|
||||||
|
def get_status_led(self):
|
||||||
|
"""
|
||||||
|
Gets the state of the fan status LED
|
||||||
|
Returns:
|
||||||
|
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||||
|
"""
|
||||||
|
led = self.STATUS_LED_COLOR_GREEN
|
||||||
|
if not self.is_psu_fan:
|
||||||
|
fan_led_file = (FAN_PATH +
|
||||||
|
self.fan_e1031_led.format(self.fan_tray_index+1))
|
||||||
|
|
||||||
|
led = self._api_common.read_txt_file(fan_led_file)
|
||||||
|
return {
|
||||||
|
'green': self.STATUS_LED_COLOR_GREEN,
|
||||||
|
'off': self.STATUS_LED_COLOR_OFF,
|
||||||
|
'amber': self.STATUS_LED_COLOR_AMBER
|
||||||
|
}.get(led, self.STATUS_LED_COLOR_OFF)
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
###################### Device methods ########################
|
||||||
|
##############################################################
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the device
|
Retrieves the name of the device
|
||||||
@ -240,24 +273,16 @@ class Fan(FanBase):
|
|||||||
Returns:
|
Returns:
|
||||||
string: Model/part number of device
|
string: Model/part number of device
|
||||||
"""
|
"""
|
||||||
if self.is_psu_fan:
|
|
||||||
return NULL_VAL
|
return NULL_VAL
|
||||||
|
|
||||||
model = NULL_VAL
|
|
||||||
return model
|
|
||||||
|
|
||||||
def get_serial(self):
|
def get_serial(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the serial number of the device
|
Retrieves the serial number of the device
|
||||||
Returns:
|
Returns:
|
||||||
string: Serial number of device
|
string: Serial number of device
|
||||||
"""
|
"""
|
||||||
if self.is_psu_fan:
|
|
||||||
return NULL_VAL
|
return NULL_VAL
|
||||||
|
|
||||||
serial = NULL_VAL
|
|
||||||
return serial
|
|
||||||
|
|
||||||
def get_status(self):
|
def get_status(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the operational status of the device
|
Retrieves the operational status of the device
|
||||||
@ -269,7 +294,7 @@ class Fan(FanBase):
|
|||||||
fan_fault_sysfs_name = "fan1_fault"
|
fan_fault_sysfs_name = "fan1_fault"
|
||||||
fan_fault_sysfs_path = self.__search_file_by_name(
|
fan_fault_sysfs_path = self.__search_file_by_name(
|
||||||
self.psu_hwmon_path, fan_fault_sysfs_name)
|
self.psu_hwmon_path, fan_fault_sysfs_name)
|
||||||
status = self._api_common.read_txt_file(fan_fault_sysfs_path)
|
status = self._api_common.read_one_line_file(fan_fault_sysfs_path)
|
||||||
|
|
||||||
elif self.get_presence():
|
elif self.get_presence():
|
||||||
chip = self.emc2305_chip_mapping[self.fan_index]
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
@ -278,7 +303,27 @@ class Fan(FanBase):
|
|||||||
sysfs_path = "%s%s/%s" % (
|
sysfs_path = "%s%s/%s" % (
|
||||||
EMC2305_PATH, device, 'fan{}_fault')
|
EMC2305_PATH, device, 'fan{}_fault')
|
||||||
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
||||||
status = self._api_common.read_txt_file(sysfs_path)
|
status = self._api_common.read_one_line_file(sysfs_path)
|
||||||
|
|
||||||
return False if int(status) != 0 else True
|
return False if int(status) != 0 else True
|
||||||
|
|
||||||
|
def get_position_in_parent(self):
|
||||||
|
"""
|
||||||
|
Retrieves 1-based relative physical position in parent device.
|
||||||
|
If the agent cannot determine the parent-relative position
|
||||||
|
for some reason, or if the associated value of
|
||||||
|
entPhysicalContainedIn is'0', then the value '-1' is returned
|
||||||
|
Returns:
|
||||||
|
integer: The 1-based relative physical position in parent device
|
||||||
|
or -1 if cannot determine the position
|
||||||
|
"""
|
||||||
|
return (self.fan_tray_index*2 + self.fan_index + 1) \
|
||||||
|
if not self.is_psu_fan else (self.fan_index+1)
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return True if not self.is_psu_fan else False
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Celestica
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC Platform Base API and
|
||||||
|
# provides the the Fan-Drawers' information available in the platform
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_platform_base.fan_drawer_base import FanDrawerBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
NUM_FAN = 1
|
||||||
|
|
||||||
|
|
||||||
|
class FanDrawer(FanDrawerBase):
|
||||||
|
def __init__(self, fantray_index):
|
||||||
|
FanDrawerBase.__init__(self)
|
||||||
|
self._index = fantray_index + 1
|
||||||
|
self._init_fan(fantray_index)
|
||||||
|
|
||||||
|
def _init_fan(self, fantray_index):
|
||||||
|
from sonic_platform.fan import Fan
|
||||||
|
for index in range(NUM_FAN):
|
||||||
|
fan = Fan(fantray_index, index)
|
||||||
|
self._fan_list.append(fan)
|
||||||
|
|
||||||
|
def set_status_led(self, color):
|
||||||
|
"""
|
||||||
|
Sets the state of the fan drawer status LED
|
||||||
|
Args:
|
||||||
|
color: A string representing the color with which to set the
|
||||||
|
fan drawer status LED
|
||||||
|
Returns:
|
||||||
|
bool: True if status LED state is set successfully, False if not
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].set_status_led(color)
|
||||||
|
|
||||||
|
def get_status_led(self, color=None):
|
||||||
|
"""
|
||||||
|
Gets the state of the fan drawer LED
|
||||||
|
Returns:
|
||||||
|
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_status_led()
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
###################### Device methods ########################
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the name of the device
|
||||||
|
Returns:
|
||||||
|
string: The name of the device
|
||||||
|
"""
|
||||||
|
return "Drawer{}".format(self._index)
|
||||||
|
|
||||||
|
def get_presence(self):
|
||||||
|
"""
|
||||||
|
Retrieves the presence of the device
|
||||||
|
Returns:
|
||||||
|
bool: True if device is present, False if not
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_presence()
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the device
|
||||||
|
Returns:
|
||||||
|
string: Model/part number of device
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_model()
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the device
|
||||||
|
Returns:
|
||||||
|
string: Serial number of device
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_serial()
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the device
|
||||||
|
Returns:
|
||||||
|
A boolean value, True if device is operating properly, False if not
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_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
|
||||||
|
"""
|
||||||
|
return self._index
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return True
|
@ -1,133 +0,0 @@
|
|||||||
import os
|
|
||||||
import struct
|
|
||||||
import subprocess
|
|
||||||
from mmap import *
|
|
||||||
|
|
||||||
from sonic_py_common import device_info
|
|
||||||
|
|
||||||
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
|
||||||
EMPTY_STRING = ""
|
|
||||||
|
|
||||||
|
|
||||||
class APIHelper():
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
(self.platform, self.hwsku) = device_info.get_platform_and_hwsku()
|
|
||||||
|
|
||||||
def is_host(self):
|
|
||||||
return os.system(HOST_CHK_CMD) == 0
|
|
||||||
|
|
||||||
def pci_get_value(self, resource, offset):
|
|
||||||
status = True
|
|
||||||
result = ""
|
|
||||||
try:
|
|
||||||
fd = os.open(resource, os.O_RDWR)
|
|
||||||
mm = mmap(fd, 0)
|
|
||||||
mm.seek(int(offset))
|
|
||||||
read_data_stream = mm.read(4)
|
|
||||||
result = struct.unpack('I', read_data_stream)
|
|
||||||
except Exception:
|
|
||||||
status = False
|
|
||||||
return status, result
|
|
||||||
|
|
||||||
def run_command(self, cmd):
|
|
||||||
status = True
|
|
||||||
result = ""
|
|
||||||
try:
|
|
||||||
p = subprocess.Popen(
|
|
||||||
cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
raw_data, err = p.communicate()
|
|
||||||
if err == '':
|
|
||||||
result = raw_data.strip()
|
|
||||||
except Exception:
|
|
||||||
status = False
|
|
||||||
return status, result
|
|
||||||
|
|
||||||
def run_interactive_command(self, cmd):
|
|
||||||
try:
|
|
||||||
os.system(cmd)
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def read_txt_file(self, file_path):
|
|
||||||
try:
|
|
||||||
with open(file_path, 'r') as fd:
|
|
||||||
data = fd.read()
|
|
||||||
return data.strip()
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
def read_one_line_file(self, file_path):
|
|
||||||
try:
|
|
||||||
with open(file_path, 'r') as fd:
|
|
||||||
data = fd.readline()
|
|
||||||
return data.strip()
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
def write_txt_file(self, file_path, value):
|
|
||||||
try:
|
|
||||||
with open(file_path, 'w') as fd:
|
|
||||||
fd.write(str(value))
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_cpld_reg_value(self, getreg_path, register):
|
|
||||||
cmd = "echo {1} > {0}; cat {0}".format(getreg_path, register)
|
|
||||||
status, result = self.run_command(cmd)
|
|
||||||
return result if status else None
|
|
||||||
|
|
||||||
def ipmi_raw(self, netfn, cmd):
|
|
||||||
status = True
|
|
||||||
result = ""
|
|
||||||
try:
|
|
||||||
cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd))
|
|
||||||
p = subprocess.Popen(
|
|
||||||
cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
raw_data, err = p.communicate()
|
|
||||||
if err == '':
|
|
||||||
result = raw_data.strip()
|
|
||||||
else:
|
|
||||||
status = False
|
|
||||||
except Exception:
|
|
||||||
status = False
|
|
||||||
return status, result
|
|
||||||
|
|
||||||
def ipmi_fru_id(self, id, key=None):
|
|
||||||
status = True
|
|
||||||
result = ""
|
|
||||||
try:
|
|
||||||
cmd = "ipmitool fru print {}".format(str(
|
|
||||||
id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key))
|
|
||||||
|
|
||||||
p = subprocess.Popen(
|
|
||||||
cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
raw_data, err = p.communicate()
|
|
||||||
if err == '':
|
|
||||||
result = raw_data.strip()
|
|
||||||
else:
|
|
||||||
status = False
|
|
||||||
except Exception:
|
|
||||||
status = False
|
|
||||||
return status, result
|
|
||||||
|
|
||||||
def ipmi_set_ss_thres(self, id, threshold_key, value):
|
|
||||||
status = True
|
|
||||||
result = ""
|
|
||||||
try:
|
|
||||||
cmd = "ipmitool sensor thresh '{}' {} {}".format(
|
|
||||||
str(id), str(threshold_key), str(value))
|
|
||||||
p = subprocess.Popen(
|
|
||||||
cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
raw_data, err = p.communicate()
|
|
||||||
if err == '':
|
|
||||||
result = raw_data.strip()
|
|
||||||
else:
|
|
||||||
status = False
|
|
||||||
except Exception:
|
|
||||||
status = False
|
|
||||||
return status, result
|
|
@ -11,10 +11,13 @@ import os.path
|
|||||||
try:
|
try:
|
||||||
from sonic_platform_base.psu_base import PsuBase
|
from sonic_platform_base.psu_base import PsuBase
|
||||||
from sonic_platform.fan import Fan
|
from sonic_platform.fan import Fan
|
||||||
|
from .common import Common
|
||||||
|
from .eeprom import DeviceEEPROM
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
FAN_E1031_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input"
|
FAN_E1031_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input"
|
||||||
|
PSU_E1031_STAT_PATH = "/sys/devices/platform/e1031.smc/"
|
||||||
HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
||||||
FAN_MAX_RPM = 11000
|
FAN_MAX_RPM = 11000
|
||||||
PSU_NAME_LIST = ["PSU-R", "PSU-L"]
|
PSU_NAME_LIST = ["PSU-R", "PSU-L"]
|
||||||
@ -22,13 +25,22 @@ PSU_NUM_FAN = [1, 1]
|
|||||||
PSU_I2C_MAPPING = {
|
PSU_I2C_MAPPING = {
|
||||||
0: {
|
0: {
|
||||||
"num": 13,
|
"num": 13,
|
||||||
"addr": "5b"
|
"addr": "5b",
|
||||||
|
"eeprom_addr": "53"
|
||||||
},
|
},
|
||||||
1: {
|
1: {
|
||||||
"num": 12,
|
"num": 12,
|
||||||
"addr": "5a"
|
"addr": "5a",
|
||||||
|
"eeprom_addr": "52"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
PSU_EEPROM_PATH = "/sys/bus/i2c/devices/{}-00{}/eeprom"
|
||||||
|
PSU_EEPROM_FORMAT = [
|
||||||
|
('Serial Number', 's', 16), ('burn', 'x', 16),
|
||||||
|
('Model', 's', 16),
|
||||||
|
('Part Number', 's', 16),
|
||||||
|
]
|
||||||
|
PSU_EEPROM_START_OFFSET = 48
|
||||||
|
|
||||||
|
|
||||||
class Psu(PsuBase):
|
class Psu(PsuBase):
|
||||||
@ -36,32 +48,26 @@ class Psu(PsuBase):
|
|||||||
|
|
||||||
def __init__(self, psu_index):
|
def __init__(self, psu_index):
|
||||||
PsuBase.__init__(self)
|
PsuBase.__init__(self)
|
||||||
|
|
||||||
|
self._api_common = Common()
|
||||||
self.index = psu_index
|
self.index = psu_index
|
||||||
self.psu_path = "/sys/devices/platform/e1031.smc/"
|
|
||||||
self.psu_presence = "psu{}_prs"
|
self.psu_presence = "psu{}_prs"
|
||||||
self.psu_oper_status = "psu{}_status"
|
self.psu_oper_status = "psu{}_status"
|
||||||
self.i2c_num = PSU_I2C_MAPPING[self.index]["num"]
|
self.i2c_num = PSU_I2C_MAPPING[self.index]["num"]
|
||||||
self.i2c_addr = PSU_I2C_MAPPING[self.index]["addr"]
|
self.i2c_addr = PSU_I2C_MAPPING[self.index]["addr"]
|
||||||
self.hwmon_path = HWMON_PATH.format(self.i2c_num, self.i2c_addr)
|
self.hwmon_path = HWMON_PATH.format(self.i2c_num, self.i2c_addr)
|
||||||
|
self.eeprom_addr = PSU_EEPROM_PATH.format(
|
||||||
|
self.i2c_num, PSU_I2C_MAPPING[self.index]["eeprom_addr"])
|
||||||
|
|
||||||
for fan_index in range(0, PSU_NUM_FAN[self.index]):
|
for fan_index in range(0, PSU_NUM_FAN[self.index]):
|
||||||
fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index)
|
fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index)
|
||||||
self._fan_list.append(fan)
|
self._fan_list.append(fan)
|
||||||
PsuBase.__init__(self)
|
|
||||||
|
|
||||||
def __read_txt_file(self, file_path):
|
def _search_file_by_contain(self, directory, search_str, file_start):
|
||||||
try:
|
|
||||||
with open(file_path, 'r') as fd:
|
|
||||||
data = fd.read()
|
|
||||||
return data.strip()
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def __search_file_by_contain(self, directory, search_str, file_start):
|
|
||||||
for dirpath, dirnames, files in os.walk(directory):
|
for dirpath, dirnames, files in os.walk(directory):
|
||||||
for name in files:
|
for name in files:
|
||||||
file_path = os.path.join(dirpath, name)
|
file_path = os.path.join(dirpath, name)
|
||||||
if name.startswith(file_start) and search_str in self.__read_txt_file(file_path):
|
if name.startswith(file_start) and search_str in self._api_common.read_txt_file(file_path):
|
||||||
return file_path
|
return file_path
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -76,7 +82,7 @@ class Psu(PsuBase):
|
|||||||
voltage_name = "in{}_input"
|
voltage_name = "in{}_input"
|
||||||
voltage_label = "vout1"
|
voltage_label = "vout1"
|
||||||
|
|
||||||
vout_label_path = self.__search_file_by_contain(
|
vout_label_path = self._search_file_by_contain(
|
||||||
self.hwmon_path, voltage_label, "in")
|
self.hwmon_path, voltage_label, "in")
|
||||||
if vout_label_path:
|
if vout_label_path:
|
||||||
dir_name = os.path.dirname(vout_label_path)
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
@ -84,7 +90,7 @@ class Psu(PsuBase):
|
|||||||
in_num = ''.join(list(filter(str.isdigit, basename)))
|
in_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
vout_path = os.path.join(
|
vout_path = os.path.join(
|
||||||
dir_name, voltage_name.format(in_num))
|
dir_name, voltage_name.format(in_num))
|
||||||
vout_val = self.__read_txt_file(vout_path)
|
vout_val = self._api_common.read_txt_file(vout_path)
|
||||||
psu_voltage = float(vout_val) / 1000
|
psu_voltage = float(vout_val) / 1000
|
||||||
|
|
||||||
return psu_voltage
|
return psu_voltage
|
||||||
@ -99,7 +105,7 @@ class Psu(PsuBase):
|
|||||||
current_name = "curr{}_input"
|
current_name = "curr{}_input"
|
||||||
current_label = "iout1"
|
current_label = "iout1"
|
||||||
|
|
||||||
curr_label_path = self.__search_file_by_contain(
|
curr_label_path = self._search_file_by_contain(
|
||||||
self.hwmon_path, current_label, "cur")
|
self.hwmon_path, current_label, "cur")
|
||||||
if curr_label_path:
|
if curr_label_path:
|
||||||
dir_name = os.path.dirname(curr_label_path)
|
dir_name = os.path.dirname(curr_label_path)
|
||||||
@ -107,7 +113,7 @@ class Psu(PsuBase):
|
|||||||
cur_num = ''.join(list(filter(str.isdigit, basename)))
|
cur_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
cur_path = os.path.join(
|
cur_path = os.path.join(
|
||||||
dir_name, current_name.format(cur_num))
|
dir_name, current_name.format(cur_num))
|
||||||
cur_val = self.__read_txt_file(cur_path)
|
cur_val = self._api_common.read_txt_file(cur_path)
|
||||||
psu_current = float(cur_val) / 1000
|
psu_current = float(cur_val) / 1000
|
||||||
|
|
||||||
return psu_current
|
return psu_current
|
||||||
@ -122,7 +128,7 @@ class Psu(PsuBase):
|
|||||||
current_name = "power{}_input"
|
current_name = "power{}_input"
|
||||||
current_label = "pout1"
|
current_label = "pout1"
|
||||||
|
|
||||||
pw_label_path = self.__search_file_by_contain(
|
pw_label_path = self._search_file_by_contain(
|
||||||
self.hwmon_path, current_label, "power")
|
self.hwmon_path, current_label, "power")
|
||||||
if pw_label_path:
|
if pw_label_path:
|
||||||
dir_name = os.path.dirname(pw_label_path)
|
dir_name = os.path.dirname(pw_label_path)
|
||||||
@ -130,7 +136,7 @@ class Psu(PsuBase):
|
|||||||
pw_num = ''.join(list(filter(str.isdigit, basename)))
|
pw_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
pw_path = os.path.join(
|
pw_path = os.path.join(
|
||||||
dir_name, current_name.format(pw_num))
|
dir_name, current_name.format(pw_num))
|
||||||
pw_val = self.__read_txt_file(pw_path)
|
pw_val = self._api_common.read_txt_file(pw_path)
|
||||||
psu_power = float(pw_val) / 1000000
|
psu_power = float(pw_val) / 1000000
|
||||||
|
|
||||||
return psu_power
|
return psu_power
|
||||||
@ -165,6 +171,10 @@ class Psu(PsuBase):
|
|||||||
# Hardware not supported
|
# Hardware not supported
|
||||||
return self.STATUS_LED_COLOR_OFF
|
return self.STATUS_LED_COLOR_OFF
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
###################### Device methods ########################
|
||||||
|
##############################################################
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the device
|
Retrieves the name of the device
|
||||||
@ -180,8 +190,8 @@ class Psu(PsuBase):
|
|||||||
bool: True if PSU is present, False if not
|
bool: True if PSU is present, False if not
|
||||||
"""
|
"""
|
||||||
psu_location = ["R", "L"]
|
psu_location = ["R", "L"]
|
||||||
presences_status = self.__read_txt_file(
|
presences_status = self._api_common.read_txt_file(
|
||||||
self.psu_path + self.psu_presence.format(psu_location[self.index])) or 0
|
PSU_E1031_STAT_PATH + self.psu_presence.format(psu_location[self.index])) or 0
|
||||||
|
|
||||||
return int(presences_status) == 1
|
return int(presences_status) == 1
|
||||||
|
|
||||||
@ -192,7 +202,153 @@ class Psu(PsuBase):
|
|||||||
A boolean value, True if device is operating properly, False if not
|
A boolean value, True if device is operating properly, False if not
|
||||||
"""
|
"""
|
||||||
psu_location = ["R", "L"]
|
psu_location = ["R", "L"]
|
||||||
power_status = self.__read_txt_file(
|
power_status = self._api_common.read_txt_file(
|
||||||
self.psu_path + self.psu_oper_status.format(psu_location[self.index])) or 0
|
PSU_E1031_STAT_PATH + self.psu_oper_status.format(psu_location[self.index])) or 0
|
||||||
|
|
||||||
return int(power_status) == 1
|
return int(power_status) == 1
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the device
|
||||||
|
Returns:
|
||||||
|
string: Model/part number of device
|
||||||
|
"""
|
||||||
|
self._eeprom = DeviceEEPROM(
|
||||||
|
self.eeprom_addr, PSU_EEPROM_FORMAT, PSU_EEPROM_START_OFFSET)
|
||||||
|
return self._eeprom.model_str
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the device
|
||||||
|
Returns:
|
||||||
|
string: Serial number of device
|
||||||
|
"""
|
||||||
|
self._eeprom = DeviceEEPROM(
|
||||||
|
self.eeprom_addr, PSU_EEPROM_FORMAT, PSU_EEPROM_START_OFFSET)
|
||||||
|
return self._eeprom.serial_number
|
||||||
|
|
||||||
|
def get_position_in_parent(self):
|
||||||
|
"""
|
||||||
|
Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position
|
||||||
|
for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned
|
||||||
|
Returns:
|
||||||
|
integer: The 1-based relative physical position in parent device or -1 if cannot determine the position
|
||||||
|
"""
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_temperature(self):
|
||||||
|
"""
|
||||||
|
Retrieves current temperature reading from PSU
|
||||||
|
Returns:
|
||||||
|
A float number of current temperature in Celsius up to nearest thousandth
|
||||||
|
of one degree Celsius, e.g. 30.125
|
||||||
|
there are three temp sensors , we choose one of them
|
||||||
|
"""
|
||||||
|
psu_temperature = None
|
||||||
|
temperature_name = "temp{}_input"
|
||||||
|
temperature_label = "vout1"
|
||||||
|
|
||||||
|
vout_label_path = self._search_file_by_contain(
|
||||||
|
self.hwmon_path, temperature_label, "in")
|
||||||
|
if vout_label_path:
|
||||||
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
|
basename = os.path.basename(vout_label_path)
|
||||||
|
in_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
|
temp_path = os.path.join(
|
||||||
|
dir_name, temperature_name.format(in_num))
|
||||||
|
vout_val = self._api_common.read_txt_file(temp_path)
|
||||||
|
psu_temperature = float(vout_val) / 1000
|
||||||
|
|
||||||
|
return psu_temperature
|
||||||
|
|
||||||
|
def get_temperature_high_threshold(self):
|
||||||
|
"""
|
||||||
|
Retrieves the high threshold temperature of PSU
|
||||||
|
Returns:
|
||||||
|
A float number, the high threshold temperature of PSU in Celsius
|
||||||
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
|
there are three temp sensors , we choose one of them
|
||||||
|
"""
|
||||||
|
psu_temperature = None
|
||||||
|
temperature_name = "temp{}_max"
|
||||||
|
temperature_label = "vout1"
|
||||||
|
|
||||||
|
vout_label_path = self._search_file_by_contain(
|
||||||
|
self.hwmon_path, temperature_label, "in")
|
||||||
|
if vout_label_path:
|
||||||
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
|
basename = os.path.basename(vout_label_path)
|
||||||
|
in_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
|
temp_path = os.path.join(
|
||||||
|
dir_name, temperature_name.format(in_num))
|
||||||
|
vout_val = self._api_common.read_txt_file(temp_path)
|
||||||
|
psu_temperature = float(vout_val) / 1000
|
||||||
|
|
||||||
|
return psu_temperature
|
||||||
|
|
||||||
|
def get_voltage_high_threshold(self):
|
||||||
|
"""
|
||||||
|
Retrieves the high threshold PSU voltage output
|
||||||
|
Returns:
|
||||||
|
A float number, the high threshold output voltage in volts,
|
||||||
|
e.g. 12.1
|
||||||
|
"""
|
||||||
|
psu_voltage = 12.6
|
||||||
|
voltage_name = "in{}_crit"
|
||||||
|
voltage_label = "vout1"
|
||||||
|
|
||||||
|
vout_label_path = self._search_file_by_contain(
|
||||||
|
self.hwmon_path, voltage_label, "in")
|
||||||
|
if vout_label_path:
|
||||||
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
|
basename = os.path.basename(vout_label_path)
|
||||||
|
in_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
|
vout_path = os.path.join(
|
||||||
|
dir_name, voltage_name.format(in_num))
|
||||||
|
if os.path.exists(vout_path):
|
||||||
|
vout_val = self._api_common.read_txt_file(vout_path)
|
||||||
|
psu_voltage = float(vout_val) / 1000
|
||||||
|
|
||||||
|
return psu_voltage
|
||||||
|
|
||||||
|
def get_voltage_low_threshold(self):
|
||||||
|
"""
|
||||||
|
Retrieves the low threshold PSU voltage output
|
||||||
|
Returns:
|
||||||
|
A float number, the low threshold output voltage in volts,
|
||||||
|
e.g. 12.1
|
||||||
|
"""
|
||||||
|
psu_voltage = 11.4
|
||||||
|
voltage_name = "in{}_lcrit"
|
||||||
|
voltage_label = "vout1"
|
||||||
|
|
||||||
|
vout_label_path = self._search_file_by_contain(
|
||||||
|
self.hwmon_path, voltage_label, "in")
|
||||||
|
if vout_label_path:
|
||||||
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
|
basename = os.path.basename(vout_label_path)
|
||||||
|
in_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
|
vout_path = os.path.join(
|
||||||
|
dir_name, voltage_name.format(in_num))
|
||||||
|
if os.path.exists(vout_path):
|
||||||
|
vout_val = self._api_common.read_txt_file(vout_path)
|
||||||
|
psu_voltage = float(vout_val) / 1000
|
||||||
|
|
||||||
|
return psu_voltage
|
||||||
|
|
||||||
|
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 200.0
|
||||||
|
@ -6,23 +6,44 @@
|
|||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
from ctypes import create_string_buffer
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
import time
|
||||||
|
from ctypes import create_string_buffer
|
||||||
from sonic_platform_base.sfp_base import SfpBase
|
from sonic_platform_base.sfp_base import SfpBase
|
||||||
from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
|
|
||||||
from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
|
from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
|
||||||
|
from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
|
||||||
from sonic_platform_base.sonic_sfp.sff8472 import sffbase
|
from sonic_platform_base.sonic_sfp.sff8472 import sffbase
|
||||||
|
from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
|
||||||
|
from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
|
||||||
|
from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId
|
||||||
|
from .common import Common
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
INFO_OFFSET = 0
|
INFO_OFFSET = 128
|
||||||
DOM_OFFSET = 256
|
DOM_OFFSET = 0
|
||||||
|
|
||||||
|
# definitions of the offset and width for values in XCVR info eeprom
|
||||||
XCVR_INTFACE_BULK_OFFSET = 0
|
XCVR_INTFACE_BULK_OFFSET = 0
|
||||||
|
XCVR_INTFACE_BULK_WIDTH_QSFP = 20
|
||||||
XCVR_INTFACE_BULK_WIDTH_SFP = 21
|
XCVR_INTFACE_BULK_WIDTH_SFP = 21
|
||||||
|
XCVR_TYPE_OFFSET = 0
|
||||||
|
XCVR_TYPE_WIDTH = 1
|
||||||
|
XCVR_EXT_TYPE_OFFSET = 1
|
||||||
|
XCVR_EXT_TYPE_WIDTH = 1
|
||||||
|
XCVR_CONNECTOR_OFFSET = 2
|
||||||
|
XCVR_CONNECTOR_WIDTH = 1
|
||||||
|
XCVR_COMPLIANCE_CODE_OFFSET = 3
|
||||||
|
XCVR_COMPLIANCE_CODE_WIDTH = 8
|
||||||
|
XCVR_ENCODING_OFFSET = 11
|
||||||
|
XCVR_ENCODING_WIDTH = 1
|
||||||
|
XCVR_NBR_OFFSET = 12
|
||||||
|
XCVR_NBR_WIDTH = 1
|
||||||
|
XCVR_EXT_RATE_SEL_OFFSET = 13
|
||||||
|
XCVR_EXT_RATE_SEL_WIDTH = 1
|
||||||
|
XCVR_CABLE_LENGTH_OFFSET = 14
|
||||||
|
XCVR_CABLE_LENGTH_WIDTH_QSFP = 5
|
||||||
|
XCVR_CABLE_LENGTH_WIDTH_SFP = 6
|
||||||
XCVR_VENDOR_NAME_OFFSET = 20
|
XCVR_VENDOR_NAME_OFFSET = 20
|
||||||
XCVR_VENDOR_NAME_WIDTH = 16
|
XCVR_VENDOR_NAME_WIDTH = 16
|
||||||
XCVR_VENDOR_OUI_OFFSET = 37
|
XCVR_VENDOR_OUI_OFFSET = 37
|
||||||
@ -30,30 +51,86 @@ XCVR_VENDOR_OUI_WIDTH = 3
|
|||||||
XCVR_VENDOR_PN_OFFSET = 40
|
XCVR_VENDOR_PN_OFFSET = 40
|
||||||
XCVR_VENDOR_PN_WIDTH = 16
|
XCVR_VENDOR_PN_WIDTH = 16
|
||||||
XCVR_HW_REV_OFFSET = 56
|
XCVR_HW_REV_OFFSET = 56
|
||||||
|
XCVR_HW_REV_WIDTH_OSFP = 2
|
||||||
|
XCVR_HW_REV_WIDTH_QSFP = 2
|
||||||
XCVR_HW_REV_WIDTH_SFP = 4
|
XCVR_HW_REV_WIDTH_SFP = 4
|
||||||
XCVR_VENDOR_SN_OFFSET = 68
|
XCVR_VENDOR_SN_OFFSET = 68
|
||||||
XCVR_VENDOR_SN_WIDTH = 16
|
XCVR_VENDOR_SN_WIDTH = 16
|
||||||
XCVR_VENDOR_DATE_OFFSET = 84
|
XCVR_VENDOR_DATE_OFFSET = 84
|
||||||
XCVR_VENDOR_DATE_WIDTH = 8
|
XCVR_VENDOR_DATE_WIDTH = 8
|
||||||
XCVR_DOM_CAPABILITY_OFFSET = 92
|
XCVR_DOM_CAPABILITY_OFFSET = 92
|
||||||
XCVR_DOM_CAPABILITY_WIDTH = 1
|
XCVR_DOM_CAPABILITY_WIDTH = 2
|
||||||
|
|
||||||
|
XCVR_INTERFACE_DATA_START = 0
|
||||||
|
XCVR_INTERFACE_DATA_SIZE = 92
|
||||||
|
|
||||||
|
QSFP_DOM_BULK_DATA_START = 22
|
||||||
|
QSFP_DOM_BULK_DATA_SIZE = 36
|
||||||
|
SFP_DOM_BULK_DATA_START = 96
|
||||||
|
SFP_DOM_BULK_DATA_SIZE = 10
|
||||||
|
|
||||||
|
# definitions of the offset for values in OSFP info eeprom
|
||||||
|
OSFP_TYPE_OFFSET = 0
|
||||||
|
OSFP_VENDOR_NAME_OFFSET = 129
|
||||||
|
OSFP_VENDOR_PN_OFFSET = 148
|
||||||
|
OSFP_HW_REV_OFFSET = 164
|
||||||
|
OSFP_VENDOR_SN_OFFSET = 166
|
||||||
|
|
||||||
|
# Offset for values in QSFP eeprom
|
||||||
|
QSFP_DOM_REV_OFFSET = 1
|
||||||
|
QSFP_DOM_REV_WIDTH = 1
|
||||||
|
QSFP_TEMPE_OFFSET = 22
|
||||||
|
QSFP_TEMPE_WIDTH = 2
|
||||||
|
QSFP_VOLT_OFFSET = 26
|
||||||
|
QSFP_VOLT_WIDTH = 2
|
||||||
|
QSFP_VERSION_COMPLIANCE_OFFSET = 1
|
||||||
|
QSFP_VERSION_COMPLIANCE_WIDTH = 2
|
||||||
|
QSFP_CHANNL_MON_OFFSET = 34
|
||||||
|
QSFP_CHANNL_MON_WIDTH = 16
|
||||||
|
QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24
|
||||||
|
QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86
|
||||||
|
QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1
|
||||||
|
QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3
|
||||||
|
QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1
|
||||||
|
QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4
|
||||||
|
QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1
|
||||||
|
QSFP_CONTROL_OFFSET = 86
|
||||||
|
QSFP_CONTROL_WIDTH = 8
|
||||||
|
QSFP_MODULE_MONITOR_OFFSET = 0
|
||||||
|
QSFP_MODULE_MONITOR_WIDTH = 9
|
||||||
|
QSFP_POWEROVERRIDE_OFFSET = 93
|
||||||
|
QSFP_POWEROVERRIDE_WIDTH = 1
|
||||||
|
QSFP_POWEROVERRIDE_BIT = 0
|
||||||
|
QSFP_POWERSET_BIT = 1
|
||||||
|
QSFP_OPTION_VALUE_OFFSET = 192
|
||||||
|
QSFP_OPTION_VALUE_WIDTH = 4
|
||||||
|
QSFP_MODULE_UPPER_PAGE3_START = 384
|
||||||
|
QSFP_MODULE_THRESHOLD_OFFSET = 128
|
||||||
|
QSFP_MODULE_THRESHOLD_WIDTH = 24
|
||||||
|
QSFP_CHANNL_THRESHOLD_OFFSET = 176
|
||||||
|
QSFP_CHANNL_THRESHOLD_WIDTH = 24
|
||||||
|
|
||||||
|
SFP_MODULE_ADDRA2_OFFSET = 256
|
||||||
|
SFP_MODULE_THRESHOLD_OFFSET = 0
|
||||||
|
SFP_MODULE_THRESHOLD_WIDTH = 56
|
||||||
|
SFP_CHANNL_THRESHOLD_OFFSET = 112
|
||||||
|
SFP_CHANNL_THRESHOLD_WIDTH = 2
|
||||||
|
|
||||||
# Offset for values in SFP eeprom
|
|
||||||
SFP_TEMPE_OFFSET = 96
|
SFP_TEMPE_OFFSET = 96
|
||||||
SFP_TEMPE_WIDTH = 2
|
SFP_TEMPE_WIDTH = 2
|
||||||
SFP_VOLT_OFFSET = 98
|
SFP_VOLT_OFFSET = 98
|
||||||
SFP_VOLT_WIDTH = 2
|
SFP_VOLT_WIDTH = 2
|
||||||
SFP_CHANNL_MON_OFFSET = 100
|
SFP_CHANNL_MON_OFFSET = 100
|
||||||
SFP_CHANNL_MON_WIDTH = 6
|
SFP_CHANNL_MON_WIDTH = 6
|
||||||
SFP_MODULE_THRESHOLD_OFFSET = 0
|
SFP_CHANNL_STATUS_OFFSET = 110
|
||||||
SFP_MODULE_THRESHOLD_WIDTH = 40
|
SFP_CHANNL_STATUS_WIDTH = 1
|
||||||
SFP_CHANNL_THRESHOLD_OFFSET = 112
|
|
||||||
SFP_CHANNL_THRESHOLD_WIDTH = 2
|
|
||||||
SFP_STATUS_CONTROL_OFFSET = 110
|
|
||||||
SFP_STATUS_CONTROL_WIDTH = 1
|
|
||||||
SFP_TX_DISABLE_HARD_BIT = 7
|
SFP_TX_DISABLE_HARD_BIT = 7
|
||||||
SFP_TX_DISABLE_SOFT_BIT = 6
|
SFP_TX_DISABLE_SOFT_BIT = 6
|
||||||
|
|
||||||
|
qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)',
|
||||||
|
'Length OM2(m)', 'Length OM1(m)',
|
||||||
|
'Length Cable Assembly(m)')
|
||||||
|
|
||||||
sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
|
sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
|
||||||
'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
|
'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
|
||||||
'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)')
|
'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)')
|
||||||
@ -64,44 +141,63 @@ sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCod
|
|||||||
'FibreChannelTechnology', 'SFP+CableTechnology',
|
'FibreChannelTechnology', 'SFP+CableTechnology',
|
||||||
'FibreChannelTransmissionMedia', 'FibreChannelSpeed')
|
'FibreChannelTransmissionMedia', 'FibreChannelSpeed')
|
||||||
|
|
||||||
|
qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes',
|
||||||
|
'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes',
|
||||||
|
'Fibre Channel link length/Transmitter Technology',
|
||||||
|
'Fibre Channel transmission media', 'Fibre Channel Speed')
|
||||||
|
|
||||||
|
SFP_TYPE = "SFP"
|
||||||
|
QSFP_TYPE = "QSFP"
|
||||||
|
OSFP_TYPE = "OSFP"
|
||||||
|
ETP_TYPE = "ETP"
|
||||||
|
|
||||||
|
SFP_PORT_START = 49
|
||||||
|
SFP_PORT_END = 52
|
||||||
|
|
||||||
|
PORT_START = 1
|
||||||
|
PORT_END = 55
|
||||||
|
|
||||||
|
|
||||||
class Sfp(SfpBase):
|
class Sfp(SfpBase):
|
||||||
"""Platform-specific Sfp class"""
|
"""Platform-specific Sfp class"""
|
||||||
|
|
||||||
# Port number
|
# Port I2C number
|
||||||
PORT_START = 1
|
|
||||||
PORT_END = 52
|
|
||||||
port_to_i2c_mapping = {
|
port_to_i2c_mapping = {
|
||||||
49: 15,
|
49: 15,
|
||||||
50: 14,
|
50: 14,
|
||||||
51: 17,
|
51: 17,
|
||||||
52: 16
|
52: 16
|
||||||
}
|
}
|
||||||
_sfp_port = list(range(49, PORT_END + 1))
|
_sfp_port = list(range(SFP_PORT_START, SFP_PORT_END + 1))
|
||||||
PRS_PATH = "/sys/devices/platform/e1031.smc/SFP/sfp_modabs"
|
|
||||||
PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
|
|
||||||
PMON_HWSKU_PATH = '/usr/share/sonic/hwsku'
|
|
||||||
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
|
||||||
|
|
||||||
PLATFORM = "x86_64-cel_e1031-r0"
|
PRS_PATH = "/sys/devices/platform/e1031.smc/SFP/sfp_modabs"
|
||||||
HWSKU = "Celestica-E1031-T48S4"
|
|
||||||
|
|
||||||
def __init__(self, sfp_index, sfp_name):
|
def __init__(self, sfp_index, sfp_name):
|
||||||
|
SfpBase.__init__(self)
|
||||||
|
|
||||||
|
# Init common function
|
||||||
|
self._api_common = Common()
|
||||||
|
|
||||||
# Init index
|
# Init index
|
||||||
self.index = sfp_index
|
self.index = sfp_index
|
||||||
self.port_num = self.index + 1
|
self.port_num = self.index + 1
|
||||||
|
|
||||||
|
# Init sfp data
|
||||||
|
self.sfp_type = self.__get_sfp_type()
|
||||||
|
self.name = sfp_name
|
||||||
|
|
||||||
# Init eeprom path
|
# Init eeprom path
|
||||||
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
|
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
|
||||||
self.port_to_eeprom_mapping = {}
|
self.port_to_eeprom_mapping = {}
|
||||||
for x in range(self.PORT_START, self.PORT_END + 1):
|
for x in range(PORT_START, PORT_END + 1):
|
||||||
if x not in self._sfp_port:
|
if x not in self._sfp_port:
|
||||||
self.port_to_i2c_mapping[x] = None
|
self.port_to_i2c_mapping[x] = None
|
||||||
self.port_to_eeprom_mapping[x] = eeprom_path.format(
|
self.port_to_eeprom_mapping[x] = eeprom_path.format(
|
||||||
self.port_to_i2c_mapping[x])
|
self.port_to_i2c_mapping[x])
|
||||||
|
|
||||||
self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier',
|
self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier',
|
||||||
'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui']
|
'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance',
|
||||||
|
'vendor_date', 'vendor_oui', "application_advertisement", "type_abbrv_name"]
|
||||||
|
|
||||||
self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage',
|
self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage',
|
||||||
'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power']
|
'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power']
|
||||||
@ -109,10 +205,12 @@ class Sfp(SfpBase):
|
|||||||
self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning',
|
self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning',
|
||||||
'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
|
'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
|
||||||
|
|
||||||
self.name = sfp_name
|
self._dom_capability_detect()
|
||||||
SfpBase.__init__(self)
|
|
||||||
|
|
||||||
def _convert_string_to_num(self, value_str):
|
def __get_sfp_type(self):
|
||||||
|
return SFP_TYPE if self.port_num in self._sfp_port else ETP_TYPE
|
||||||
|
|
||||||
|
def __convert_string_to_num(self, value_str):
|
||||||
if "-inf" in value_str:
|
if "-inf" in value_str:
|
||||||
return 'N/A'
|
return 'N/A'
|
||||||
elif "Unknown" in value_str:
|
elif "Unknown" in value_str:
|
||||||
@ -132,18 +230,6 @@ class Sfp(SfpBase):
|
|||||||
else:
|
else:
|
||||||
return 'N/A'
|
return 'N/A'
|
||||||
|
|
||||||
def __read_txt_file(self, file_path):
|
|
||||||
try:
|
|
||||||
with open(file_path, 'r') as fd:
|
|
||||||
data = fd.read()
|
|
||||||
return data.strip()
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def __is_host(self):
|
|
||||||
return os.system(self.HOST_CHK_CMD) == 0
|
|
||||||
|
|
||||||
def __read_eeprom_specific_bytes(self, offset, num_bytes):
|
def __read_eeprom_specific_bytes(self, offset, num_bytes):
|
||||||
sysfsfile_eeprom = None
|
sysfsfile_eeprom = None
|
||||||
eeprom_raw = []
|
eeprom_raw = []
|
||||||
@ -156,9 +242,13 @@ class Sfp(SfpBase):
|
|||||||
sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0)
|
sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0)
|
||||||
sysfsfile_eeprom.seek(offset)
|
sysfsfile_eeprom.seek(offset)
|
||||||
raw = sysfsfile_eeprom.read(num_bytes)
|
raw = sysfsfile_eeprom.read(num_bytes)
|
||||||
|
if isinstance(raw, str):
|
||||||
for n in range(0, num_bytes):
|
for n in range(0, num_bytes):
|
||||||
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
|
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
|
||||||
except Exception:
|
else:
|
||||||
|
for n in range(0, num_bytes):
|
||||||
|
eeprom_raw[n] = hex(raw[n])[2:].zfill(2)
|
||||||
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
if sysfsfile_eeprom:
|
if sysfsfile_eeprom:
|
||||||
@ -166,6 +256,106 @@ class Sfp(SfpBase):
|
|||||||
|
|
||||||
return eeprom_raw
|
return eeprom_raw
|
||||||
|
|
||||||
|
def _dom_capability_detect(self):
|
||||||
|
if not self.get_presence():
|
||||||
|
self.dom_supported = False
|
||||||
|
self.dom_temp_supported = False
|
||||||
|
self.dom_volt_supported = False
|
||||||
|
self.dom_rx_power_supported = False
|
||||||
|
self.dom_tx_power_supported = False
|
||||||
|
self.calibration = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.sfp_type == "QSFP":
|
||||||
|
self.calibration = 1
|
||||||
|
sfpi_obj = sff8436InterfaceId()
|
||||||
|
if sfpi_obj is None:
|
||||||
|
self.dom_supported = False
|
||||||
|
offset = 128
|
||||||
|
|
||||||
|
# QSFP capability byte parse, through this byte can know whether it support tx_power or not.
|
||||||
|
# TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
|
||||||
|
# need to add more code for determining the capability and version compliance
|
||||||
|
# in SFF-8636 dom capability definitions evolving with the versions.
|
||||||
|
qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH)
|
||||||
|
if qsfp_dom_capability_raw is not None:
|
||||||
|
qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH)
|
||||||
|
qsfp_version_compliance = int(
|
||||||
|
qsfp_version_compliance_raw[0], 16)
|
||||||
|
dom_capability = sfpi_obj.parse_dom_capability(
|
||||||
|
qsfp_dom_capability_raw, 0)
|
||||||
|
if qsfp_version_compliance >= 0x08:
|
||||||
|
self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On'
|
||||||
|
self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On'
|
||||||
|
self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On'
|
||||||
|
self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On'
|
||||||
|
else:
|
||||||
|
self.dom_temp_supported = True
|
||||||
|
self.dom_volt_supported = True
|
||||||
|
self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On'
|
||||||
|
self.dom_tx_power_supported = True
|
||||||
|
|
||||||
|
self.dom_supported = True
|
||||||
|
self.calibration = 1
|
||||||
|
sfpd_obj = sff8436Dom()
|
||||||
|
if sfpd_obj is None:
|
||||||
|
return None
|
||||||
|
qsfp_option_value_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH)
|
||||||
|
if qsfp_option_value_raw is not None:
|
||||||
|
optional_capability = sfpd_obj.parse_option_params(
|
||||||
|
qsfp_option_value_raw, 0)
|
||||||
|
self.dom_tx_disable_supported = optional_capability[
|
||||||
|
'data']['TxDisable']['value'] == 'On'
|
||||||
|
dom_status_indicator = sfpd_obj.parse_dom_status_indicator(
|
||||||
|
qsfp_version_compliance_raw, 1)
|
||||||
|
self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off'
|
||||||
|
else:
|
||||||
|
self.dom_supported = False
|
||||||
|
self.dom_temp_supported = False
|
||||||
|
self.dom_volt_supported = False
|
||||||
|
self.dom_rx_power_supported = False
|
||||||
|
self.dom_tx_power_supported = False
|
||||||
|
self.calibration = 0
|
||||||
|
self.qsfp_page3_available = False
|
||||||
|
|
||||||
|
elif self.sfp_type == "SFP":
|
||||||
|
sfpi_obj = sff8472InterfaceId()
|
||||||
|
if sfpi_obj is None:
|
||||||
|
return None
|
||||||
|
sfp_dom_capability_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH)
|
||||||
|
if sfp_dom_capability_raw is not None:
|
||||||
|
sfp_dom_capability = int(sfp_dom_capability_raw[0], 16)
|
||||||
|
self.dom_supported = (sfp_dom_capability & 0x40 != 0)
|
||||||
|
if self.dom_supported:
|
||||||
|
self.dom_temp_supported = True
|
||||||
|
self.dom_volt_supported = True
|
||||||
|
self.dom_rx_power_supported = True
|
||||||
|
self.dom_tx_power_supported = True
|
||||||
|
if sfp_dom_capability & 0x20 != 0:
|
||||||
|
self.calibration = 1
|
||||||
|
elif sfp_dom_capability & 0x10 != 0:
|
||||||
|
self.calibration = 2
|
||||||
|
else:
|
||||||
|
self.calibration = 0
|
||||||
|
else:
|
||||||
|
self.dom_temp_supported = False
|
||||||
|
self.dom_volt_supported = False
|
||||||
|
self.dom_rx_power_supported = False
|
||||||
|
self.dom_tx_power_supported = False
|
||||||
|
self.calibration = 0
|
||||||
|
self.dom_tx_disable_supported = (
|
||||||
|
int(sfp_dom_capability_raw[1], 16) & 0x40 != 0)
|
||||||
|
else:
|
||||||
|
self.dom_supported = False
|
||||||
|
self.dom_temp_supported = False
|
||||||
|
self.dom_volt_supported = False
|
||||||
|
self.dom_rx_power_supported = False
|
||||||
|
self.dom_tx_power_supported = False
|
||||||
|
|
||||||
def get_transceiver_info(self):
|
def get_transceiver_info(self):
|
||||||
"""
|
"""
|
||||||
Retrieves transceiver info of this SFP
|
Retrieves transceiver info of this SFP
|
||||||
@ -190,71 +380,168 @@ class Sfp(SfpBase):
|
|||||||
vendor_oui |1*255VCHAR |vendor OUI
|
vendor_oui |1*255VCHAR |vendor OUI
|
||||||
========================================================================
|
========================================================================
|
||||||
"""
|
"""
|
||||||
# check present status
|
compliance_code_dict = {}
|
||||||
sfpi_obj = sff8472InterfaceId()
|
transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A')
|
||||||
if not self.get_presence() or not sfpi_obj:
|
if not self.get_presence():
|
||||||
return {}
|
return transceiver_info_dict
|
||||||
|
|
||||||
offset = INFO_OFFSET
|
# ToDo: OSFP tranceiver info parsing not fully supported.
|
||||||
|
# in inf8628.py lack of some memory map definition
|
||||||
|
# will be implemented when the inf8628 memory map ready
|
||||||
|
if self.sfp_type == OSFP_TYPE:
|
||||||
|
offset = 0
|
||||||
|
vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP
|
||||||
|
|
||||||
sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(
|
sfpi_obj = inf8628InterfaceId()
|
||||||
(offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_SFP)
|
if sfpi_obj is None:
|
||||||
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(
|
return None
|
||||||
sfp_interface_bulk_raw, 0)
|
|
||||||
|
sfp_type_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH)
|
||||||
|
if sfp_type_raw is not None:
|
||||||
|
sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
sfp_vendor_name_raw = self.__read_eeprom_specific_bytes(
|
sfp_vendor_name_raw = self.__read_eeprom_specific_bytes(
|
||||||
(offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
|
(offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
|
||||||
|
if sfp_vendor_name_raw is not None:
|
||||||
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
|
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
|
||||||
sfp_vendor_name_raw, 0)
|
sfp_vendor_name_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
|
sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
|
||||||
(offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
|
(offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
|
||||||
|
if sfp_vendor_pn_raw is not None:
|
||||||
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
|
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
|
||||||
sfp_vendor_pn_raw, 0)
|
sfp_vendor_pn_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes(
|
sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes(
|
||||||
(offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_SFP)
|
(offset + OSFP_HW_REV_OFFSET), vendor_rev_width)
|
||||||
|
if sfp_vendor_rev_raw is not None:
|
||||||
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
|
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
|
||||||
sfp_vendor_rev_raw, 0)
|
sfp_vendor_rev_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
|
sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
|
||||||
(offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
|
(offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
|
||||||
|
if sfp_vendor_sn_raw is not None:
|
||||||
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
|
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
|
||||||
sfp_vendor_sn_raw, 0)
|
sfp_vendor_sn_raw, 0)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes(
|
transceiver_info_dict['type'] = sfp_type_data['data']['type']['value']
|
||||||
(offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
|
transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value']
|
||||||
if sfp_vendor_oui_raw is not None:
|
transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
|
||||||
|
transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
|
||||||
|
transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
|
||||||
|
transceiver_info_dict['vendor_oui'] = 'N/A'
|
||||||
|
transceiver_info_dict['vendor_date'] = 'N/A'
|
||||||
|
transceiver_info_dict['connector'] = 'N/A'
|
||||||
|
transceiver_info_dict['encoding'] = 'N/A'
|
||||||
|
transceiver_info_dict['ext_identifier'] = 'N/A'
|
||||||
|
transceiver_info_dict['ext_rateselect_compliance'] = 'N/A'
|
||||||
|
transceiver_info_dict['cable_type'] = 'N/A'
|
||||||
|
transceiver_info_dict['cable_length'] = 'N/A'
|
||||||
|
transceiver_info_dict['specification_compliance'] = '{}'
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = 'N/A'
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.sfp_type == QSFP_TYPE:
|
||||||
|
offset = 128
|
||||||
|
vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP
|
||||||
|
# cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP
|
||||||
|
interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP
|
||||||
|
|
||||||
|
sfpi_obj = sff8436InterfaceId()
|
||||||
|
if sfpi_obj is None:
|
||||||
|
print("Error: sfp_object open failed")
|
||||||
|
return None
|
||||||
|
|
||||||
|
else:
|
||||||
|
offset = 0
|
||||||
|
vendor_rev_width = XCVR_HW_REV_WIDTH_SFP
|
||||||
|
# cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP
|
||||||
|
interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP
|
||||||
|
|
||||||
|
sfpi_obj = sff8472InterfaceId()
|
||||||
|
if sfpi_obj is None:
|
||||||
|
print("Error: sfp_object open failed")
|
||||||
|
return None
|
||||||
|
sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE)
|
||||||
|
if sfp_interface_bulk_raw is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START
|
||||||
|
end = start + interface_info_bulk_width
|
||||||
|
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(
|
||||||
|
sfp_interface_bulk_raw[start: end], 0)
|
||||||
|
|
||||||
|
start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START
|
||||||
|
end = start + XCVR_VENDOR_NAME_WIDTH
|
||||||
|
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
|
||||||
|
sfp_interface_bulk_raw[start: end], 0)
|
||||||
|
|
||||||
|
start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START
|
||||||
|
end = start + XCVR_VENDOR_PN_WIDTH
|
||||||
|
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
|
||||||
|
sfp_interface_bulk_raw[start: end], 0)
|
||||||
|
|
||||||
|
start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START
|
||||||
|
end = start + vendor_rev_width
|
||||||
|
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
|
||||||
|
sfp_interface_bulk_raw[start: end], 0)
|
||||||
|
|
||||||
|
start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START
|
||||||
|
end = start + XCVR_VENDOR_SN_WIDTH
|
||||||
|
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
|
||||||
|
sfp_interface_bulk_raw[start: end], 0)
|
||||||
|
|
||||||
|
start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START
|
||||||
|
end = start + XCVR_VENDOR_OUI_WIDTH
|
||||||
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(
|
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(
|
||||||
sfp_vendor_oui_raw, 0)
|
sfp_interface_bulk_raw[start: end], 0)
|
||||||
|
|
||||||
sfp_vendor_date_raw = self.__read_eeprom_specific_bytes(
|
start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START
|
||||||
(offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
|
end = start + XCVR_VENDOR_DATE_WIDTH
|
||||||
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(
|
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(
|
||||||
sfp_vendor_date_raw, 0)
|
sfp_interface_bulk_raw[start: end], 0)
|
||||||
|
|
||||||
transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A')
|
|
||||||
compliance_code_dict = dict()
|
|
||||||
|
|
||||||
if sfp_interface_bulk_data:
|
|
||||||
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
|
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
|
||||||
|
transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value']
|
||||||
|
transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
|
||||||
|
transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
|
||||||
|
transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
|
||||||
|
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value']
|
||||||
|
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[
|
||||||
|
'data']['VendorDataCode(YYYY-MM-DD Lot)']['value']
|
||||||
transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value']
|
transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value']
|
||||||
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
|
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
|
||||||
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
|
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
|
||||||
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
|
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
|
||||||
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
|
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
|
||||||
|
|
||||||
transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[
|
if self.sfp_type == QSFP_TYPE:
|
||||||
'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A'
|
for key in qsfp_cable_length_tup:
|
||||||
transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
|
if key in sfp_interface_bulk_data['data']:
|
||||||
transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A'
|
transceiver_info_dict['cable_type'] = key
|
||||||
transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
|
transceiver_info_dict['cable_length'] = str(
|
||||||
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A'
|
sfp_interface_bulk_data['data'][key]['value'])
|
||||||
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[
|
|
||||||
'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A'
|
|
||||||
transceiver_info_dict['cable_type'] = "Unknown"
|
|
||||||
transceiver_info_dict['cable_length'] = "Unknown"
|
|
||||||
|
|
||||||
|
for key in qsfp_compliance_code_tup:
|
||||||
|
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
|
||||||
|
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
|
||||||
|
transceiver_info_dict['specification_compliance'] = str(
|
||||||
|
compliance_code_dict)
|
||||||
|
|
||||||
|
transceiver_info_dict['nominal_bit_rate'] = str(
|
||||||
|
sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value'])
|
||||||
|
else:
|
||||||
for key in sfp_cable_length_tup:
|
for key in sfp_cable_length_tup:
|
||||||
if key in sfp_interface_bulk_data['data']:
|
if key in sfp_interface_bulk_data['data']:
|
||||||
transceiver_info_dict['cable_type'] = key
|
transceiver_info_dict['cable_type'] = key
|
||||||
@ -266,6 +553,7 @@ class Sfp(SfpBase):
|
|||||||
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
|
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
|
||||||
transceiver_info_dict['specification_compliance'] = str(
|
transceiver_info_dict['specification_compliance'] = str(
|
||||||
compliance_code_dict)
|
compliance_code_dict)
|
||||||
|
|
||||||
transceiver_info_dict['nominal_bit_rate'] = str(
|
transceiver_info_dict['nominal_bit_rate'] = str(
|
||||||
sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
|
sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
|
||||||
|
|
||||||
@ -296,44 +584,117 @@ class Sfp(SfpBase):
|
|||||||
| |for example, tx2power stands for tx power of channel 2.
|
| |for example, tx2power stands for tx power of channel 2.
|
||||||
========================================================================
|
========================================================================
|
||||||
"""
|
"""
|
||||||
# check present status
|
|
||||||
sfpd_obj = sff8472Dom()
|
|
||||||
if not self.get_presence() or not sfpd_obj:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
|
|
||||||
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
|
|
||||||
cal_type = sfpi_obj.get_calibration_type()
|
|
||||||
sfpd_obj._calibration_type = cal_type
|
|
||||||
|
|
||||||
offset = DOM_OFFSET
|
|
||||||
transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A')
|
transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A')
|
||||||
dom_temperature_raw = self.__read_eeprom_specific_bytes(
|
|
||||||
(offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
|
|
||||||
|
|
||||||
if dom_temperature_raw is not None:
|
if self.sfp_type == OSFP_TYPE:
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif self.sfp_type == QSFP_TYPE:
|
||||||
|
if not self.dom_supported:
|
||||||
|
return transceiver_dom_info_dict
|
||||||
|
|
||||||
|
offset = 0
|
||||||
|
sfpd_obj = sff8436Dom()
|
||||||
|
if sfpd_obj is None:
|
||||||
|
return transceiver_dom_info_dict
|
||||||
|
|
||||||
|
dom_data_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE)
|
||||||
|
if dom_data_raw is None:
|
||||||
|
return transceiver_dom_info_dict
|
||||||
|
|
||||||
|
if self.dom_temp_supported:
|
||||||
|
start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START
|
||||||
|
end = start + QSFP_TEMPE_WIDTH
|
||||||
dom_temperature_data = sfpd_obj.parse_temperature(
|
dom_temperature_data = sfpd_obj.parse_temperature(
|
||||||
dom_temperature_raw, 0)
|
dom_data_raw[start: end], 0)
|
||||||
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
|
temp = self.__convert_string_to_num(
|
||||||
|
dom_temperature_data['data']['Temperature']['value'])
|
||||||
|
if temp is not None:
|
||||||
|
transceiver_dom_info_dict['temperature'] = temp
|
||||||
|
|
||||||
dom_voltage_raw = self.__read_eeprom_specific_bytes(
|
if self.dom_volt_supported:
|
||||||
(offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH)
|
start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START
|
||||||
if dom_voltage_raw is not None:
|
end = start + QSFP_VOLT_WIDTH
|
||||||
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
|
dom_voltage_data = sfpd_obj.parse_voltage(
|
||||||
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
|
dom_data_raw[start: end], 0)
|
||||||
|
volt = self.__convert_string_to_num(
|
||||||
|
dom_voltage_data['data']['Vcc']['value'])
|
||||||
|
if volt is not None:
|
||||||
|
transceiver_dom_info_dict['voltage'] = volt
|
||||||
|
|
||||||
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START
|
||||||
(offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
|
end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH
|
||||||
if dom_channel_monitor_raw is not None:
|
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(
|
||||||
dom_voltage_data = sfpd_obj.parse_channel_monitor_params(
|
dom_data_raw[start: end], 0)
|
||||||
dom_channel_monitor_raw, 0)
|
|
||||||
transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value']
|
|
||||||
transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value']
|
|
||||||
transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value']
|
|
||||||
|
|
||||||
for key in transceiver_dom_info_dict:
|
if self.dom_tx_power_supported:
|
||||||
transceiver_dom_info_dict[key] = self._convert_string_to_num(
|
transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num(
|
||||||
transceiver_dom_info_dict[key])
|
dom_channel_monitor_data['data']['TX1Power']['value'])
|
||||||
|
transceiver_dom_info_dict['tx2power'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['TX2Power']['value'])
|
||||||
|
transceiver_dom_info_dict['tx3power'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['TX3Power']['value'])
|
||||||
|
transceiver_dom_info_dict['tx4power'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['TX4Power']['value'])
|
||||||
|
|
||||||
|
if self.dom_rx_power_supported:
|
||||||
|
transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['RX1Power']['value'])
|
||||||
|
transceiver_dom_info_dict['rx2power'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['RX2Power']['value'])
|
||||||
|
transceiver_dom_info_dict['rx3power'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['RX3Power']['value'])
|
||||||
|
transceiver_dom_info_dict['rx4power'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['RX4Power']['value'])
|
||||||
|
|
||||||
|
transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['TX1Bias']['value'])
|
||||||
|
transceiver_dom_info_dict['tx2bias'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['TX2Bias']['value'])
|
||||||
|
transceiver_dom_info_dict['tx3bias'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['TX3Bias']['value'])
|
||||||
|
transceiver_dom_info_dict['tx4bias'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['TX4Bias']['value'])
|
||||||
|
|
||||||
|
else:
|
||||||
|
if not self.dom_supported:
|
||||||
|
return transceiver_dom_info_dict
|
||||||
|
|
||||||
|
offset = 256
|
||||||
|
sfpd_obj = sff8472Dom()
|
||||||
|
if sfpd_obj is None:
|
||||||
|
return transceiver_dom_info_dict
|
||||||
|
sfpd_obj._calibration_type = self.calibration
|
||||||
|
|
||||||
|
dom_data_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE)
|
||||||
|
|
||||||
|
start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START
|
||||||
|
end = start + SFP_TEMPE_WIDTH
|
||||||
|
dom_temperature_data = sfpd_obj.parse_temperature(
|
||||||
|
dom_data_raw[start: end], 0)
|
||||||
|
|
||||||
|
start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START
|
||||||
|
end = start + SFP_VOLT_WIDTH
|
||||||
|
dom_voltage_data = sfpd_obj.parse_voltage(
|
||||||
|
dom_data_raw[start: end], 0)
|
||||||
|
|
||||||
|
start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START
|
||||||
|
end = start + SFP_CHANNL_MON_WIDTH
|
||||||
|
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(
|
||||||
|
dom_data_raw[start: end], 0)
|
||||||
|
|
||||||
|
transceiver_dom_info_dict['temperature'] = self.__convert_string_to_num(
|
||||||
|
dom_temperature_data['data']['Temperature']['value'])
|
||||||
|
transceiver_dom_info_dict['voltage'] = self.__convert_string_to_num(
|
||||||
|
dom_voltage_data['data']['Vcc']['value'])
|
||||||
|
transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['RXPower']['value'])
|
||||||
|
transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['TXBias']['value'])
|
||||||
|
transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num(
|
||||||
|
dom_channel_monitor_data['data']['TXPower']['value'])
|
||||||
|
|
||||||
transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
|
transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
|
||||||
transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
|
transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
|
||||||
@ -372,26 +733,79 @@ class Sfp(SfpBase):
|
|||||||
txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA.
|
txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA.
|
||||||
========================================================================
|
========================================================================
|
||||||
"""
|
"""
|
||||||
# check present status
|
|
||||||
sfpd_obj = sff8472Dom()
|
|
||||||
|
|
||||||
if not self.get_presence() and not sfpd_obj:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
|
|
||||||
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
|
|
||||||
cal_type = sfpi_obj.get_calibration_type()
|
|
||||||
sfpd_obj._calibration_type = cal_type
|
|
||||||
|
|
||||||
offset = DOM_OFFSET
|
|
||||||
transceiver_dom_threshold_info_dict = dict.fromkeys(
|
transceiver_dom_threshold_info_dict = dict.fromkeys(
|
||||||
self.threshold_dict_keys, 'N/A')
|
self.threshold_dict_keys, 'N/A')
|
||||||
|
|
||||||
|
if self.sfp_type == OSFP_TYPE:
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif self.sfp_type == QSFP_TYPE:
|
||||||
|
if not self.dom_supported or not self.qsfp_page3_available:
|
||||||
|
return transceiver_dom_threshold_info_dict
|
||||||
|
|
||||||
|
# Dom Threshold data starts from offset 384
|
||||||
|
# Revert offset back to 0 once data is retrieved
|
||||||
|
offset = QSFP_MODULE_UPPER_PAGE3_START
|
||||||
|
sfpd_obj = sff8436Dom()
|
||||||
|
if sfpd_obj is None:
|
||||||
|
return transceiver_dom_threshold_info_dict
|
||||||
|
|
||||||
dom_module_threshold_raw = self.__read_eeprom_specific_bytes(
|
dom_module_threshold_raw = self.__read_eeprom_specific_bytes(
|
||||||
(offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH)
|
(offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH)
|
||||||
|
if dom_module_threshold_raw is None:
|
||||||
|
return transceiver_dom_threshold_info_dict
|
||||||
|
|
||||||
|
dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(
|
||||||
|
dom_module_threshold_raw, 0)
|
||||||
|
|
||||||
|
dom_channel_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET),
|
||||||
|
QSFP_CHANNL_THRESHOLD_WIDTH)
|
||||||
|
if dom_channel_threshold_raw is None:
|
||||||
|
return transceiver_dom_threshold_info_dict
|
||||||
|
dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(
|
||||||
|
dom_channel_threshold_raw, 0)
|
||||||
|
|
||||||
|
# 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['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value']
|
||||||
|
transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value']
|
||||||
|
|
||||||
|
else:
|
||||||
|
offset = SFP_MODULE_ADDRA2_OFFSET
|
||||||
|
|
||||||
|
if not self.dom_supported:
|
||||||
|
return transceiver_dom_threshold_info_dict
|
||||||
|
|
||||||
|
sfpd_obj = sff8472Dom(None, self.calibration)
|
||||||
|
if sfpd_obj is None:
|
||||||
|
return transceiver_dom_threshold_info_dict
|
||||||
|
|
||||||
|
dom_module_threshold_raw = self.__read_eeprom_specific_bytes((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_data = sfpd_obj.parse_alarm_warning_threshold(
|
||||||
dom_module_threshold_raw, 0)
|
dom_module_threshold_raw, 0)
|
||||||
|
else:
|
||||||
|
return transceiver_dom_threshold_info_dict
|
||||||
|
|
||||||
|
# Threshold Data
|
||||||
transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['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['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['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
|
||||||
@ -415,7 +829,7 @@ class Sfp(SfpBase):
|
|||||||
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value']
|
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value']
|
||||||
|
|
||||||
for key in transceiver_dom_threshold_info_dict:
|
for key in transceiver_dom_threshold_info_dict:
|
||||||
transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num(
|
transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(
|
||||||
transceiver_dom_threshold_info_dict[key])
|
transceiver_dom_threshold_info_dict[key])
|
||||||
|
|
||||||
return transceiver_dom_threshold_info_dict
|
return transceiver_dom_threshold_info_dict
|
||||||
@ -437,11 +851,27 @@ class Sfp(SfpBase):
|
|||||||
Note : RX LOS status is latched until a call to get_rx_los or a reset.
|
Note : RX LOS status is latched until a call to get_rx_los or a reset.
|
||||||
"""
|
"""
|
||||||
rx_los = False
|
rx_los = False
|
||||||
status_control_raw = self.__read_eeprom_specific_bytes(
|
if self.sfp_type == OSFP_TYPE:
|
||||||
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
return False
|
||||||
if status_control_raw:
|
|
||||||
data = int(status_control_raw[0], 16)
|
elif self.sfp_type == QSFP_TYPE:
|
||||||
rx_los = (sffbase().test_bit(data, 1) != 0)
|
offset = 0
|
||||||
|
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
rx_los_data = int(dom_channel_monitor_raw[0], 16)
|
||||||
|
rx1_los = (rx_los_data & 0x01 != 0)
|
||||||
|
rx2_los = (rx_los_data & 0x02 != 0)
|
||||||
|
rx3_los = (rx_los_data & 0x04 != 0)
|
||||||
|
rx4_los = (rx_los_data & 0x08 != 0)
|
||||||
|
rx_los = (rx1_los and rx2_los and rx3_los and rx4_los)
|
||||||
|
else:
|
||||||
|
offset = 256
|
||||||
|
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
rx_los_data = int(dom_channel_monitor_raw[0], 16)
|
||||||
|
rx_los = (rx_los_data & 0x02 != 0)
|
||||||
|
|
||||||
return rx_los
|
return rx_los
|
||||||
|
|
||||||
@ -452,14 +882,32 @@ class Sfp(SfpBase):
|
|||||||
A Boolean, True if SFP has TX fault, False if not
|
A Boolean, True if SFP has TX fault, False if not
|
||||||
Note : TX fault status is lached until a call to get_tx_fault or a reset.
|
Note : TX fault status is lached until a call to get_tx_fault or a reset.
|
||||||
"""
|
"""
|
||||||
tx_fault = False
|
tx4_fault = False
|
||||||
status_control_raw = self.__read_eeprom_specific_bytes(
|
|
||||||
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
|
||||||
if status_control_raw:
|
|
||||||
data = int(status_control_raw[0], 16)
|
|
||||||
tx_fault = (sffbase().test_bit(data, 2) != 0)
|
|
||||||
|
|
||||||
return tx_fault
|
if self.sfp_type == OSFP_TYPE or not self.dom_supported:
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif self.sfp_type == QSFP_TYPE:
|
||||||
|
offset = 0
|
||||||
|
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
tx_fault_data = int(dom_channel_monitor_raw[0], 16)
|
||||||
|
tx1_fault = (tx_fault_data & 0x01 != 0)
|
||||||
|
tx2_fault = (tx_fault_data & 0x02 != 0)
|
||||||
|
tx3_fault = (tx_fault_data & 0x04 != 0)
|
||||||
|
tx4_fault = (tx_fault_data & 0x08 != 0)
|
||||||
|
tx4_fault = (
|
||||||
|
tx1_fault and tx2_fault and tx3_fault and tx4_fault)
|
||||||
|
else:
|
||||||
|
offset = 256
|
||||||
|
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
|
||||||
|
(offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH)
|
||||||
|
if dom_channel_monitor_raw is not None:
|
||||||
|
tx_fault_data = int(dom_channel_monitor_raw[0], 16)
|
||||||
|
tx4_fault = (tx_fault_data & 0x04 != 0)
|
||||||
|
|
||||||
|
return tx4_fault
|
||||||
|
|
||||||
def get_tx_disable(self):
|
def get_tx_disable(self):
|
||||||
"""
|
"""
|
||||||
@ -469,7 +917,7 @@ class Sfp(SfpBase):
|
|||||||
"""
|
"""
|
||||||
tx_disable = False
|
tx_disable = False
|
||||||
status_control_raw = self.__read_eeprom_specific_bytes(
|
status_control_raw = self.__read_eeprom_specific_bytes(
|
||||||
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
SFP_CHANNL_STATUS_OFFSET, SFP_CHANNL_STATUS_WIDTH)
|
||||||
if status_control_raw:
|
if status_control_raw:
|
||||||
data = int(status_control_raw[0], 16)
|
data = int(status_control_raw[0], 16)
|
||||||
tx_disable_hard = (sffbase().test_bit(
|
tx_disable_hard = (sffbase().test_bit(
|
||||||
@ -516,8 +964,8 @@ class Sfp(SfpBase):
|
|||||||
Returns:
|
Returns:
|
||||||
An integer number of current temperature in Celsius
|
An integer number of current temperature in Celsius
|
||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
transceiver_bulk_status = self.get_transceiver_bulk_status()
|
||||||
return transceiver_dom_info_dict.get("temperature", "N/A")
|
return transceiver_bulk_status.get("temperature", "N/A")
|
||||||
|
|
||||||
def get_voltage(self):
|
def get_voltage(self):
|
||||||
"""
|
"""
|
||||||
@ -525,8 +973,8 @@ class Sfp(SfpBase):
|
|||||||
Returns:
|
Returns:
|
||||||
An integer number of supply voltage in mV
|
An integer number of supply voltage in mV
|
||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
transceiver_bulk_status = self.get_transceiver_bulk_status()
|
||||||
return transceiver_dom_info_dict.get("voltage", "N/A")
|
return transceiver_bulk_status.get("voltage", "N/A")
|
||||||
|
|
||||||
def get_tx_bias(self):
|
def get_tx_bias(self):
|
||||||
"""
|
"""
|
||||||
@ -584,7 +1032,7 @@ class Sfp(SfpBase):
|
|||||||
"""
|
"""
|
||||||
sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num]
|
sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num]
|
||||||
status_control_raw = self.__read_eeprom_specific_bytes(
|
status_control_raw = self.__read_eeprom_specific_bytes(
|
||||||
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
SFP_CHANNL_STATUS_OFFSET, SFP_CHANNL_STATUS_WIDTH)
|
||||||
if status_control_raw is not None:
|
if status_control_raw is not None:
|
||||||
# Set bit 6 for Soft TX Disable Select
|
# Set bit 6 for Soft TX Disable Select
|
||||||
# 01000000 = 64 and 10111111 = 191
|
# 01000000 = 64 and 10111111 = 191
|
||||||
@ -598,10 +1046,9 @@ class Sfp(SfpBase):
|
|||||||
buffer = create_string_buffer(1)
|
buffer = create_string_buffer(1)
|
||||||
buffer[0] = chr(tx_disable_ctl)
|
buffer[0] = chr(tx_disable_ctl)
|
||||||
# Write to eeprom
|
# Write to eeprom
|
||||||
sysfsfile_eeprom.seek(SFP_STATUS_CONTROL_OFFSET)
|
sysfsfile_eeprom.seek(SFP_CHANNL_STATUS_OFFSET)
|
||||||
sysfsfile_eeprom.write(buffer[0])
|
sysfsfile_eeprom.write(buffer[0])
|
||||||
except Exception:
|
except Exception:
|
||||||
#print("Error: unable to open file: %s" % str(e))
|
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
if sysfsfile_eeprom:
|
if sysfsfile_eeprom:
|
||||||
@ -656,6 +1103,10 @@ class Sfp(SfpBase):
|
|||||||
# SFP doesn't support this feature
|
# SFP doesn't support this feature
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
###################### Device methods ########################
|
||||||
|
##############################################################
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the device
|
Retrieves the name of the device
|
||||||
@ -700,3 +1151,26 @@ class Sfp(SfpBase):
|
|||||||
"""
|
"""
|
||||||
transceiver_dom_info_dict = self.get_transceiver_info()
|
transceiver_dom_info_dict = self.get_transceiver_info()
|
||||||
return transceiver_dom_info_dict.get("serial", "N/A")
|
return transceiver_dom_info_dict.get("serial", "N/A")
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the device
|
||||||
|
Returns:
|
||||||
|
A boolean value, True if device is operating properly, False if not
|
||||||
|
"""
|
||||||
|
return self.get_presence() and not self.get_reset_status()
|
||||||
|
|
||||||
|
def get_position_in_parent(self):
|
||||||
|
"""
|
||||||
|
Returns:
|
||||||
|
Temp return 0
|
||||||
|
"""
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Retrieves if replaceable
|
||||||
|
Returns:
|
||||||
|
A boolean value, True if replaceable
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
@ -93,7 +93,6 @@ I2C_ADAPTER_PATH = "/sys/class/i2c-adapter"
|
|||||||
class Thermal(ThermalBase):
|
class Thermal(ThermalBase):
|
||||||
"""Platform-specific Thermal class"""
|
"""Platform-specific Thermal class"""
|
||||||
|
|
||||||
THERMAL_NAME_LIST = []
|
|
||||||
MAINBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-11/11-001a/hwmon/hwmon2"
|
MAINBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-11/11-001a/hwmon/hwmon2"
|
||||||
CPUBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-3/3-001a/hwmon/hwmon1"
|
CPUBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-3/3-001a/hwmon/hwmon1"
|
||||||
SS_CONFIG_PATH = "/usr/share/sonic/device/x86_64-cel_e1031-r0/sensors.conf"
|
SS_CONFIG_PATH = "/usr/share/sonic/device/x86_64-cel_e1031-r0/sensors.conf"
|
||||||
@ -110,9 +109,12 @@ class Thermal(ThermalBase):
|
|||||||
|
|
||||||
self.name = self.get_name()
|
self.name = self.get_name()
|
||||||
self.postion = self._thermal_info["postion"]
|
self.postion = self._thermal_info["postion"]
|
||||||
|
self.minimum_thermal = self.get_temperature()
|
||||||
|
self.maximum_thermal = self.get_temperature()
|
||||||
|
|
||||||
def _get_hwmon_path(self):
|
def _get_hwmon_path(self):
|
||||||
hwmon_path = os.path.join(I2C_ADAPTER_PATH, self._thermal_info["i2c_path"])
|
hwmon_path = os.path.join(
|
||||||
|
I2C_ADAPTER_PATH, self._thermal_info["i2c_path"])
|
||||||
hwmon_dir = os.listdir(hwmon_path)[0]
|
hwmon_dir = os.listdir(hwmon_path)[0]
|
||||||
return os.path.join(hwmon_path, hwmon_dir)
|
return os.path.join(hwmon_path, hwmon_dir)
|
||||||
|
|
||||||
@ -126,6 +128,17 @@ class Thermal(ThermalBase):
|
|||||||
temp_file_path = os.path.join(self._hwmon_path, file_name)
|
temp_file_path = os.path.join(self._hwmon_path, file_name)
|
||||||
return self._api_common.write_txt_file(temp_file_path, str(temperature))
|
return self._api_common.write_txt_file(temp_file_path, str(temperature))
|
||||||
|
|
||||||
|
def _get_threshold(self, file_name):
|
||||||
|
temp_file_path = os.path.join(self._hwmon_path, file_name)
|
||||||
|
data = self._api_common.read_txt_file(temp_file_path)
|
||||||
|
if data:
|
||||||
|
try:
|
||||||
|
threshold = float(data)
|
||||||
|
return round(threshold/1000, 3)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
def get_temperature(self):
|
def get_temperature(self):
|
||||||
"""
|
"""
|
||||||
Retrieves current temperature reading from thermal
|
Retrieves current temperature reading from thermal
|
||||||
@ -144,7 +157,8 @@ class Thermal(ThermalBase):
|
|||||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
"""
|
"""
|
||||||
max_crit_key = '{}_max'.format(self._airflow)
|
max_crit_key = '{}_max'.format(self._airflow)
|
||||||
return self._thermal_info.get(max_crit_key, None)
|
high_threshold_file = "temp{}_max".format(self._ss_index)
|
||||||
|
return self._get_threshold(high_threshold_file) or self._thermal_info.get(max_crit_key, None)
|
||||||
|
|
||||||
def get_low_threshold(self):
|
def get_low_threshold(self):
|
||||||
"""
|
"""
|
||||||
@ -153,7 +167,7 @@ class Thermal(ThermalBase):
|
|||||||
A float number, the low threshold temperature of thermal in Celsius
|
A float number, the low threshold temperature of thermal in Celsius
|
||||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
"""
|
"""
|
||||||
return 0.0
|
return 0.001
|
||||||
|
|
||||||
def set_high_threshold(self, temperature):
|
def set_high_threshold(self, temperature):
|
||||||
"""
|
"""
|
||||||
@ -166,8 +180,8 @@ class Thermal(ThermalBase):
|
|||||||
"""
|
"""
|
||||||
temp_file = "temp{}_max".format(self._ss_index)
|
temp_file = "temp{}_max".format(self._ss_index)
|
||||||
is_set = self._set_threshold(temp_file, int(temperature*1000))
|
is_set = self._set_threshold(temp_file, int(temperature*1000))
|
||||||
file_set = False
|
file_set = True
|
||||||
if is_set:
|
if is_set and self._api_common.is_host():
|
||||||
try:
|
try:
|
||||||
with open(self.SS_CONFIG_PATH, 'r+') as f:
|
with open(self.SS_CONFIG_PATH, 'r+') as f:
|
||||||
content = f.readlines()
|
content = f.readlines()
|
||||||
@ -215,7 +229,35 @@ class Thermal(ThermalBase):
|
|||||||
A float number, the low critical threshold temperature of thermal in Celsius
|
A float number, the low critical threshold temperature of thermal in Celsius
|
||||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
"""
|
"""
|
||||||
return 0.0
|
return 0.001
|
||||||
|
|
||||||
|
def get_minimum_recorded(self):
|
||||||
|
"""
|
||||||
|
Retrieves the minimum recorded temperature of thermal
|
||||||
|
Returns:
|
||||||
|
A float number, the minimum recorded temperature of thermal in Celsius
|
||||||
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
|
"""
|
||||||
|
tmp = self.get_temperature()
|
||||||
|
if tmp < self.minimum_thermal:
|
||||||
|
self.minimum_thermal = tmp
|
||||||
|
return self.minimum_thermal
|
||||||
|
|
||||||
|
def get_maximum_recorded(self):
|
||||||
|
"""
|
||||||
|
Retrieves the maximum recorded temperature of thermal
|
||||||
|
Returns:
|
||||||
|
A float number, the maximum recorded temperature of thermal in Celsius
|
||||||
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
|
"""
|
||||||
|
tmp = self.get_temperature()
|
||||||
|
if tmp > self.maximum_thermal:
|
||||||
|
self.maximum_thermal = tmp
|
||||||
|
return self.maximum_thermal
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
###################### Device methods ########################
|
||||||
|
##############################################################
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
@ -267,3 +309,21 @@ class Thermal(ThermalBase):
|
|||||||
|
|
||||||
raw_txt = self._api_common.read_txt_file(fault_file_path)
|
raw_txt = self._api_common.read_txt_file(fault_file_path)
|
||||||
return int(raw_txt) == 0
|
return int(raw_txt) == 0
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Retrieves whether thermal module is replaceable
|
||||||
|
Returns:
|
||||||
|
A boolean value, True if replaceable, False if not
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_position_in_parent(self):
|
||||||
|
"""
|
||||||
|
Retrieves the thermal position information
|
||||||
|
Returns:
|
||||||
|
A int value, 0 represent ASIC thermal, 1 represent CPU thermal info
|
||||||
|
"""
|
||||||
|
if self.postion == "cpu":
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
@ -4,114 +4,107 @@
|
|||||||
# Watchdog contains an implementation of SONiC Platform Base API
|
# Watchdog contains an implementation of SONiC Platform Base API
|
||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
import fcntl
|
|
||||||
import os
|
|
||||||
import array
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
import os
|
||||||
|
import time
|
||||||
from sonic_platform_base.watchdog_base import WatchdogBase
|
from sonic_platform_base.watchdog_base import WatchdogBase
|
||||||
|
from .common import Common
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
""" ioctl constants """
|
|
||||||
IO_WRITE = 0x40000000
|
|
||||||
IO_READ = 0x80000000
|
|
||||||
IO_READ_WRITE = 0xC0000000
|
|
||||||
IO_SIZE_INT = 0x00040000
|
|
||||||
IO_SIZE_40 = 0x00280000
|
|
||||||
IO_TYPE_WATCHDOG = ord('W') << 8
|
|
||||||
|
|
||||||
WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG
|
|
||||||
WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG
|
|
||||||
WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG
|
|
||||||
|
|
||||||
""" Watchdog ioctl commands """
|
|
||||||
WDIOC_GETSUPPORT = 0 | WDR_40
|
|
||||||
WDIOC_GETSTATUS = 1 | WDR_INT
|
|
||||||
WDIOC_GETBOOTSTATUS = 2 | WDR_INT
|
|
||||||
WDIOC_GETTEMP = 3 | WDR_INT
|
|
||||||
WDIOC_SETOPTIONS = 4 | WDR_INT
|
|
||||||
WDIOC_KEEPALIVE = 5 | WDR_INT
|
|
||||||
WDIOC_SETTIMEOUT = 6 | WDWR_INT
|
|
||||||
WDIOC_GETTIMEOUT = 7 | WDR_INT
|
|
||||||
WDIOC_SETPRETIMEOUT = 8 | WDWR_INT
|
|
||||||
WDIOC_GETPRETIMEOUT = 9 | WDR_INT
|
|
||||||
WDIOC_GETTIMELEFT = 10 | WDR_INT
|
|
||||||
|
|
||||||
""" Watchdog status constants """
|
|
||||||
WDIOS_DISABLECARD = 0x0001
|
|
||||||
WDIOS_ENABLECARD = 0x0002
|
|
||||||
|
|
||||||
|
PLATFORM_CPLD_PATH = '/sys/devices/platform/e1031.smc/'
|
||||||
|
SETREG_FILE = 'setreg'
|
||||||
|
GETREG_FILE = 'getreg'
|
||||||
WDT_COMMON_ERROR = -1
|
WDT_COMMON_ERROR = -1
|
||||||
WD_MAIN_IDENTITY = "iTCO_wdt"
|
MMC_VERSION_REG = "0x100"
|
||||||
WDT_SYSFS_PATH = "/sys/class/watchdog/"
|
|
||||||
|
# watchdog infomation for cpld v06
|
||||||
|
V06_MMC_VERSION = 0x05
|
||||||
|
V06_WDT_WIDTH = '0x110'
|
||||||
|
V06_WDT_WIDTH_SELECTOR = {
|
||||||
|
30: '0x1',
|
||||||
|
60: '0x2',
|
||||||
|
180: '0x3'
|
||||||
|
}
|
||||||
|
|
||||||
|
V06_CPLD_WDT_INFO = {
|
||||||
|
'wdt_en_reg': '0x111',
|
||||||
|
'wdt_en_cmd': '0x0',
|
||||||
|
'wdt_dis_cmd': '0x1'
|
||||||
|
}
|
||||||
|
|
||||||
|
# watchdog infomation
|
||||||
|
WDT_TIMER_L_BIT_REG = '0x117'
|
||||||
|
WDT_TIMER_M_BIT_REG = '0x118'
|
||||||
|
WDT_TIMER_H_BIT_REG = '0x119'
|
||||||
|
WDT_KEEP_ALVIVE_REG = '0x11a'
|
||||||
|
|
||||||
|
CPLD_WDT_INFO = {
|
||||||
|
'wdt_en_reg': '0x116',
|
||||||
|
'wdt_en_cmd': '0x1',
|
||||||
|
'wdt_dis_cmd': '0x0'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Watchdog(WatchdogBase):
|
class Watchdog(WatchdogBase):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
WatchdogBase.__init__(self)
|
# Init api_common
|
||||||
|
self._api_common = Common()
|
||||||
|
|
||||||
|
# Init cpld reg path
|
||||||
|
self.setreg_path = os.path.join(PLATFORM_CPLD_PATH, SETREG_FILE)
|
||||||
|
self.getreg_path = os.path.join(PLATFORM_CPLD_PATH, GETREG_FILE)
|
||||||
|
|
||||||
|
self.mmc_v = self._get_mmc_version()
|
||||||
|
self.cpld_info = V06_CPLD_WDT_INFO if self.mmc_v <= V06_MMC_VERSION else CPLD_WDT_INFO
|
||||||
|
|
||||||
self.watchdog, self.wdt_main_dev_name = self._get_wdt()
|
|
||||||
self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name
|
|
||||||
self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name
|
|
||||||
self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name
|
|
||||||
# Set default value
|
# Set default value
|
||||||
self._disable()
|
self._disable()
|
||||||
self.armed = False
|
self.armed = False
|
||||||
self.timeout = self._gettimeout(self.timeout_path)
|
self.timeout = 0
|
||||||
|
|
||||||
def _is_wd_main(self, dev):
|
def _get_mmc_version(self):
|
||||||
"""
|
hex_str_v = self._api_common.get_reg(self.getreg_path, MMC_VERSION_REG)
|
||||||
Checks watchdog identity
|
return int(hex_str_v, 16)
|
||||||
"""
|
|
||||||
identity = self._read_file(
|
|
||||||
"{}/{}/identity".format(WDT_SYSFS_PATH, dev))
|
|
||||||
return identity == WD_MAIN_IDENTITY
|
|
||||||
|
|
||||||
def _get_wdt(self):
|
def _get_level_hex(self, sub_hex):
|
||||||
"""
|
sub_hex_str = sub_hex.replace("x", "0")
|
||||||
Retrieves watchdog device
|
return hex(int(sub_hex_str, 16))
|
||||||
"""
|
|
||||||
wdt_main_dev_list = [dev for dev in os.listdir(
|
|
||||||
"/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)]
|
|
||||||
if not wdt_main_dev_list:
|
|
||||||
return None
|
|
||||||
wdt_main_dev_name = wdt_main_dev_list[0]
|
|
||||||
watchdog_device_path = "/dev/{}".format(wdt_main_dev_name)
|
|
||||||
watchdog = os.open(watchdog_device_path, os.O_RDWR)
|
|
||||||
return watchdog, wdt_main_dev_name
|
|
||||||
|
|
||||||
def _read_file(self, file_path):
|
def _seconds_to_lmh_hex(self, seconds):
|
||||||
"""
|
ms = seconds*1000 # calculate timeout in ms format
|
||||||
Read text file
|
hex_str = hex(ms)
|
||||||
"""
|
l = self._get_level_hex(hex_str[-2:])
|
||||||
try:
|
m = self._get_level_hex(hex_str[-4:-2])
|
||||||
with open(file_path, "r") as fd:
|
h = self._get_level_hex(hex_str[-6:-4])
|
||||||
txt = fd.read()
|
return (l, m, h)
|
||||||
except IOError:
|
|
||||||
return WDT_COMMON_ERROR
|
|
||||||
return txt.strip()
|
|
||||||
|
|
||||||
def _enable(self):
|
def _enable(self):
|
||||||
"""
|
"""
|
||||||
Turn on the watchdog timer
|
Turn on the watchdog timer
|
||||||
"""
|
"""
|
||||||
req = array.array('h', [WDIOS_ENABLECARD])
|
return self._api_common.set_reg(self.setreg_path, self.cpld_info['wdt_en_reg'], self.cpld_info['wdt_en_cmd'])
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
|
|
||||||
|
|
||||||
def _disable(self):
|
def _disable(self):
|
||||||
"""
|
"""
|
||||||
Turn off the watchdog timer
|
Turn off the watchdog timer
|
||||||
"""
|
"""
|
||||||
req = array.array('h', [WDIOS_DISABLECARD])
|
return self._api_common.set_reg(self.setreg_path, self.cpld_info['wdt_en_reg'], self.cpld_info['wdt_dis_cmd'])
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
|
|
||||||
|
|
||||||
def _keepalive(self):
|
def _keepalive(self):
|
||||||
"""
|
"""
|
||||||
Keep alive watchdog timer
|
Keep alive watchdog timer
|
||||||
"""
|
"""
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE)
|
if self.mmc_v <= V06_MMC_VERSION:
|
||||||
|
self._disable()
|
||||||
|
self._enable()
|
||||||
|
|
||||||
|
else:
|
||||||
|
self._api_common.set_reg(
|
||||||
|
self.setreg_path, WDT_KEEP_ALVIVE_REG, self.cpld_info['wdt_en_cmd'])
|
||||||
|
|
||||||
def _settimeout(self, seconds):
|
def _settimeout(self, seconds):
|
||||||
"""
|
"""
|
||||||
@ -119,29 +112,23 @@ class Watchdog(WatchdogBase):
|
|||||||
@param seconds - timeout in seconds
|
@param seconds - timeout in seconds
|
||||||
@return is the actual set timeout
|
@return is the actual set timeout
|
||||||
"""
|
"""
|
||||||
req = array.array('I', [seconds])
|
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True)
|
|
||||||
return int(req[0])
|
|
||||||
|
|
||||||
def _gettimeout(self, timeout_path):
|
if self.mmc_v <= V06_MMC_VERSION:
|
||||||
"""
|
timeout_hex = V06_WDT_WIDTH_SELECTOR.get(seconds, '0x2')
|
||||||
Get watchdog timeout
|
seconds = 60 if timeout_hex == '0x2' else seconds
|
||||||
@return watchdog timeout
|
self._api_common.set_reg(
|
||||||
"""
|
self.setreg_path, V06_WDT_WIDTH, timeout_hex)
|
||||||
req = array.array('I', [0])
|
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True)
|
|
||||||
|
|
||||||
return int(req[0])
|
else:
|
||||||
|
(l, m, h) = self._seconds_to_lmh_hex(seconds)
|
||||||
|
self._api_common.set_reg(
|
||||||
|
self.setreg_path, WDT_TIMER_H_BIT_REG, h) # set high bit
|
||||||
|
self._api_common.set_reg(
|
||||||
|
self.setreg_path, WDT_TIMER_M_BIT_REG, m) # set med bit
|
||||||
|
self._api_common.set_reg(
|
||||||
|
self.setreg_path, WDT_TIMER_L_BIT_REG, l) # set low bit
|
||||||
|
|
||||||
def _gettimeleft(self):
|
return seconds
|
||||||
"""
|
|
||||||
Get time left before watchdog timer expires
|
|
||||||
@return time left in seconds
|
|
||||||
"""
|
|
||||||
req = array.array('I', [0])
|
|
||||||
fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True)
|
|
||||||
|
|
||||||
return int(req[0])
|
|
||||||
|
|
||||||
#################################################################
|
#################################################################
|
||||||
|
|
||||||
@ -157,22 +144,25 @@ class Watchdog(WatchdogBase):
|
|||||||
An integer specifying the *actual* number of seconds the watchdog
|
An integer specifying the *actual* number of seconds the watchdog
|
||||||
was armed with. On failure returns -1.
|
was armed with. On failure returns -1.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ret = WDT_COMMON_ERROR
|
ret = WDT_COMMON_ERROR
|
||||||
if seconds < 0:
|
|
||||||
|
if seconds < 0 or seconds > 180:
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.timeout != seconds:
|
if self.timeout != seconds:
|
||||||
self.timeout = self._settimeout(seconds)
|
self.timeout = self._settimeout(seconds)
|
||||||
|
|
||||||
if self.armed:
|
if self.armed:
|
||||||
self._keepalive()
|
self._keepalive()
|
||||||
else:
|
else:
|
||||||
self._enable()
|
self._enable()
|
||||||
self.armed = True
|
self.armed = True
|
||||||
|
|
||||||
ret = self.timeout
|
ret = self.timeout
|
||||||
|
self.arm_timestamp = time.time()
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
pass
|
print("Error: unable to enable wdt due to : {}".format(e))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -183,14 +173,12 @@ class Watchdog(WatchdogBase):
|
|||||||
A boolean, True if watchdog is disarmed successfully, False if not
|
A boolean, True if watchdog is disarmed successfully, False if not
|
||||||
"""
|
"""
|
||||||
disarmed = False
|
disarmed = False
|
||||||
if self.is_armed():
|
|
||||||
try:
|
try:
|
||||||
self._disable()
|
self._disable()
|
||||||
self.armed = False
|
self.armed = False
|
||||||
disarmed = True
|
disarmed = True
|
||||||
except IOError:
|
except IOError as e:
|
||||||
pass
|
print("Error: unable to disable wdt due to : {}".format(e))
|
||||||
|
|
||||||
return disarmed
|
return disarmed
|
||||||
|
|
||||||
def is_armed(self):
|
def is_armed(self):
|
||||||
@ -199,7 +187,6 @@ class Watchdog(WatchdogBase):
|
|||||||
Returns:
|
Returns:
|
||||||
A boolean, True if watchdog is armed, False if not
|
A boolean, True if watchdog is armed, False if not
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return self.armed
|
return self.armed
|
||||||
|
|
||||||
def get_remaining_time(self):
|
def get_remaining_time(self):
|
||||||
@ -214,16 +201,6 @@ class Watchdog(WatchdogBase):
|
|||||||
timeleft = WDT_COMMON_ERROR
|
timeleft = WDT_COMMON_ERROR
|
||||||
|
|
||||||
if self.armed:
|
if self.armed:
|
||||||
try:
|
timeleft = int(self.timeout - (time.time() - self.arm_timestamp))
|
||||||
timeleft = self._gettimeleft()
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return timeleft
|
return timeleft
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
"""
|
|
||||||
Close watchdog
|
|
||||||
"""
|
|
||||||
|
|
||||||
os.close(self.watchdog)
|
|
||||||
|
@ -53,12 +53,11 @@ start)
|
|||||||
echo max6699 0x1a > /sys/bus/i2c/devices/i2c-3/new_device
|
echo max6699 0x1a > /sys/bus/i2c/devices/i2c-3/new_device
|
||||||
echo max6699 0x1a > /sys/bus/i2c/devices/i2c-11/new_device
|
echo max6699 0x1a > /sys/bus/i2c/devices/i2c-11/new_device
|
||||||
|
|
||||||
## TODO: fix dps200 driver cause kernel panic issue
|
|
||||||
# https://github.com/Azure/sonic-buildimage/issues/6602
|
|
||||||
|
|
||||||
# Attach PSUs
|
# Attach PSUs
|
||||||
# echo dps200 0x5a > /sys/bus/i2c/devices/i2c-12/new_device
|
echo dps200 0x5a > /sys/bus/i2c/devices/i2c-12/new_device
|
||||||
# echo dps200 0x5b > /sys/bus/i2c/devices/i2c-13/new_device
|
echo 24c02 0x52 > /sys/bus/i2c/devices/i2c-12/new_device
|
||||||
|
echo dps200 0x5b > /sys/bus/i2c/devices/i2c-13/new_device
|
||||||
|
echo 24c02 0x53 > /sys/bus/i2c/devices/i2c-13/new_device
|
||||||
|
|
||||||
# Attach fans
|
# Attach fans
|
||||||
echo emc2305 0x4d > /sys/bus/i2c/devices/i2c-23/new_device
|
echo emc2305 0x4d > /sys/bus/i2c/devices/i2c-23/new_device
|
||||||
|
Loading…
Reference in New Issue
Block a user