diff --git a/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/hwsku.json b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/hwsku.json new file mode 100644 index 0000000000..db6e2c67e4 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/hwsku.json @@ -0,0 +1,175 @@ +{ + + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet8": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet16": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet24": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet32": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet40": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet48": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet56": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet64": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet72": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet80": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet88": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet96": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet104": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet112": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet120": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet128": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet136": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet144": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet152": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet160": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet168": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet176": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet184": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet192": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet200": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet208": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet216": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet224": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet232": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet240": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet248": { + "default_brkout_mode": "1x100G[40G](4)", + "autoneg": "off" + }, + + "Ethernet256": { + "default_brkout_mode": "1x10G[1G]", + "autoneg": "off" + }, + + "Ethernet257": { + "default_brkout_mode": "1x10G[1G]", + "autoneg": "off" + } + } +} + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/port_config.ini b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/port_config.ini new file mode 100644 index 0000000000..d32f4f7b3b --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index speed +Ethernet0 73,74,75,76 Eth1(Port1) 1 100000 +Ethernet8 65,66,67,68 Eth2(Port2) 2 100000 +Ethernet16 81,82,83,84 Eth3(Port3) 3 100000 +Ethernet24 89,90,91,92 Eth4(Port4) 4 100000 +Ethernet32 97,98,99,100 Eth5(Port5) 5 100000 +Ethernet40 105,106,107,108 Eth6(Port6) 6 100000 +Ethernet48 113,114,115,116 Eth7(Port7) 7 100000 +Ethernet56 121,122,123,124 Eth8(Port8) 8 100000 +Ethernet64 41,42,43,44 Eth9(Port9) 9 100000 +Ethernet72 33,34,35,36 Eth10(Port10) 10 100000 +Ethernet80 49,50,51,52 Eth11(Port11) 11 100000 +Ethernet88 57,58,59,60 Eth12(Port12) 12 100000 +Ethernet96 129,130,131,132 Eth13(Port13) 13 100000 +Ethernet104 137,138,139,140 Eth14(Port14) 14 100000 +Ethernet112 145,146,147,148 Eth15(Port15) 15 100000 +Ethernet120 153,154,155,156 Eth16(Port16) 16 100000 +Ethernet128 169,170,171,172 Eth17(Port17) 17 100000 +Ethernet136 161,162,163,164 Eth18(Port18) 18 100000 +Ethernet144 177,178,179,180 Eth19(Port19) 19 100000 +Ethernet152 185,186,187,188 Eth20(Port20) 20 100000 +Ethernet160 1,2,3,4 Eth21(Port21) 21 100000 +Ethernet168 9,10,11,12 Eth22(Port22) 22 100000 +Ethernet176 17,18,19,20 Eth23(Port23) 23 100000 +Ethernet184 25,26,27,28 Eth24(Port24) 24 100000 +Ethernet192 201,202,203,204 Eth25(Port25) 25 100000 +Ethernet200 193,194,195,196 Eth26(Port26) 26 100000 +Ethernet208 217,218,219,220 Eth27(Port27) 27 100000 +Ethernet216 209,210,211,212 Eth28(Port28) 28 100000 +Ethernet224 233,234,235,236 Eth29(Port29) 29 100000 +Ethernet232 225,226,227,228 Eth30(Port30) 30 100000 +Ethernet240 249,250,251,252 Eth31(Port31) 31 100000 +Ethernet248 241,242,243,244 Eth32(Port32) 32 100000 +Ethernet256 259 Eth33(Port33) 33 10000 +Ethernet257 260 Eth34(Port34) 34 10000 diff --git a/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/sai.profile b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/sai.profile new file mode 100644 index 0000000000..dffd07bce0 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td4-as9726-32x100G.config.yml diff --git a/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/td4-as9726-32x100G.config.yml b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/td4-as9726-32x100G.config.yml new file mode 100644 index 0000000000..f74d9f4345 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D-100G/td4-as9726-32x100G.config.yml @@ -0,0 +1,796 @@ +# +# BCM56880 32x400g port configuration. +# +# configuration yaml file +# device: +# : +# : +# ? +# : +# : +# ... +# : +# : +# : +# : +# ... +# : +# +# $Copyright: (c) 2019 Broadcom. +# Broadcom Proprietary and Confidential. All rights reserved.$ +# + +--- +bcm_device: + 0: + global: + pktio_mode: 1 + skip_protocol_default_entries: 1 + uft_mode: 3 + l3_alpm_template: 1 + vlan_default_port: 3 + max_vp_lags: 894 +... +--- +bcm_device: + 0: + port: + "*": + port_allow_tpid_disable: 1 +... +--- +device: + 0: + DEVICE_CONFIG: + # CORE CLOCK FREQUENCY + CORE_CLK_FREQ: CLK_1350MHZ + # PP CLOCK FREQUENCY + PP_CLK_FREQ: CLK_1350MHZ +... +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01476352 + TX_LANE_MAP: 0x67015324 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xDD + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x21563047 + TX_LANE_MAP: 0x70146253 + RX_POLARITY_FLIP: 0xEF + TX_POLARITY_FLIP: 0x6 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x34216570 + TX_LANE_MAP: 0x02453617 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xEE + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x26531470 + TX_LANE_MAP: 0x40726513 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xBE + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x23641705 + TX_LANE_MAP: 0x45326071 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xB3 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x45013726 + TX_LANE_MAP: 0x23170564 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x21 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x41025763 + TX_LANE_MAP: 0x25674013 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x4 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01675243 + TX_LANE_MAP: 0x07236415 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xEB + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x56024713 + TX_LANE_MAP: 0x21670534 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x3E + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01675342 + TX_LANE_MAP: 0x43607512 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x3D + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x20563147 + TX_LANE_MAP: 0x50126734 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xF3 + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x46150723 + TX_LANE_MAP: 0x13456072 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xEA + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x51276034 + TX_LANE_MAP: 0x35476012 + RX_POLARITY_FLIP: 0xC5 + TX_POLARITY_FLIP: 0xED + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x65217430 + TX_LANE_MAP: 0x02541637 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x4 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x32461057 + TX_LANE_MAP: 0x54107362 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xCD + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x31405267 + TX_LANE_MAP: 0x63150724 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xF4 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01475263 + TX_LANE_MAP: 0x63017524 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xFF + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x21463057 + TX_LANE_MAP: 0x70135462 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x9C + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x64217530 + TX_LANE_MAP: 0x23561407 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x53 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x10652473 + TX_LANE_MAP: 0x25306417 + RX_POLARITY_FLIP: 0x14 + TX_POLARITY_FLIP: 0xCA + ? + PC_PM_ID: 21 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x24561307 + TX_LANE_MAP: 0x65407321 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x37 + ? + PC_PM_ID: 22 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x27416350 + TX_LANE_MAP: 0x06573421 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xFB + ? + PC_PM_ID: 23 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x40517263 + TX_LANE_MAP: 0x30742516 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xB1 + ? + PC_PM_ID: 24 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x02561347 + TX_LANE_MAP: 0x53017624 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x23 + ? + PC_PM_ID: 25 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x64127503 + TX_LANE_MAP: 0x40572613 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xC + ? + PC_PM_ID: 26 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01475362 + TX_LANE_MAP: 0x67015324 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x5C + ? + PC_PM_ID: 27 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x46150723 + TX_LANE_MAP: 0x21630754 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xA0 + ? + PC_PM_ID: 28 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x20563147 + TX_LANE_MAP: 0x23607451 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xCF + ? + PC_PM_ID: 29 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x72541360 + TX_LANE_MAP: 0x50461237 + RX_POLARITY_FLIP: 0x22 + TX_POLARITY_FLIP: 0x15 + ? + PC_PM_ID: 30 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x32465071 + TX_LANE_MAP: 0x64312705 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x7F + ? + PC_PM_ID: 31 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x56412730 + TX_LANE_MAP: 0x31647250 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x20 + ? + PC_PM_ID: 32 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x64127503 + TX_LANE_MAP: 0x54321607 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x80 +... +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 1 + : + PC_PHYS_PORT_ID: 1 #TSC-BH7 0 in Pipe 0 + #? + # PORT_ID: 2 + #: + # PC_PHYS_PORT_ID: 5 #TSC-BH7 0 in Pipe 0 + ? + PORT_ID: 3 + : + PC_PHYS_PORT_ID: 9 #TSC-BH7 1 in Pipe 0 + #? + # PORT_ID: 4 + #: + # PC_PHYS_PORT_ID: 13 #TSC-BH7 1 in Pipe 0 + ? + PORT_ID: 5 + : + PC_PHYS_PORT_ID: 17 #TSC-BH7 2 in Pipe 0 + #? + # PORT_ID: 6 + #: + # PC_PHYS_PORT_ID: 21 #TSC-BH7 2 in Pipe 0 + ? + PORT_ID: 7 + : + PC_PHYS_PORT_ID: 25 #TSC-BH7 3 in Pipe 0 + #? + # PORT_ID: 8 + #: + # PC_PHYS_PORT_ID: 29 #TSC-BH7 3 in Pipe 0 + ? + PORT_ID: 20 + : + PC_PHYS_PORT_ID: 33 #TSC-BH7 4 in Pipe 1 + #? + # PORT_ID: 21 + #: + # PC_PHYS_PORT_ID: 37 #TSC-BH7 4 in Pipe 1 + ? + PORT_ID: 22 + : + PC_PHYS_PORT_ID: 41 #TSC-BH7 5 in Pipe 1 + #? + # PORT_ID: 23 + #: + # PC_PHYS_PORT_ID: 45 #TSC-BH7 5 in Pipe 1 + ? + PORT_ID: 24 + : + PC_PHYS_PORT_ID: 49 #TSC-BH7 6 in Pipe 1 + #? + # PORT_ID: 25 + #: + # PC_PHYS_PORT_ID: 53 #TSC-BH7 6 in Pipe 1 + ? + PORT_ID: 26 + : + PC_PHYS_PORT_ID: 57 #TSC-BH7 7 in Pipe 1 + #? + # PORT_ID: 27 + #: + # PC_PHYS_PORT_ID: 61 #TSC-BH7 7 in Pipe 1 + ? + PORT_ID: 40 + : + PC_PHYS_PORT_ID: 65 #TSC-BH7 8 in Pipe 2 + #? + # PORT_ID: 41 + #: + # PC_PHYS_PORT_ID: 69 #TSC-BH7 8 in Pipe 2 + ? + PORT_ID: 42 + : + PC_PHYS_PORT_ID: 73 #TSC-BH7 9 in Pipe 2 + #? + # PORT_ID: 43 + #: + # PC_PHYS_PORT_ID: 77 #TSC-BH7 9 in Pipe 2 + ? + PORT_ID: 44 + : + PC_PHYS_PORT_ID: 81 #TSC-BH7 10 in Pipe 2 + #? + # PORT_ID: 45 + #: + # PC_PHYS_PORT_ID: 85 #TSC-BH7 10 in Pipe 2 + ? + PORT_ID: 46 + : + PC_PHYS_PORT_ID: 89 #TSC-BH7 11 in Pipe 2 + #? + # PORT_ID: 47 + #: + # PC_PHYS_PORT_ID: 93 #TSC-BH7 11 in Pipe 2 + ? + PORT_ID: 60 + : + PC_PHYS_PORT_ID: 97 #TSC-BH7 12 in Pipe 3 + #? + # PORT_ID: 61 + #: + # PC_PHYS_PORT_ID: 101 #TSC-BH7 12 in Pipe 3 + ? + PORT_ID: 62 + : + PC_PHYS_PORT_ID: 105 #TSC-BH7 13 in Pipe 3 + #? + # PORT_ID: 63 + #: + # PC_PHYS_PORT_ID: 109 #TSC-BH7 13 in Pipe 3 + ? + PORT_ID: 64 + : + PC_PHYS_PORT_ID: 113 #TSC-BH7 14 in Pipe 3 + #? + # PORT_ID: 65 + #: + # PC_PHYS_PORT_ID: 117 #TSC-BH7 14 in Pipe 3 + ? + PORT_ID: 66 + : + PC_PHYS_PORT_ID: 121 #TSC-BH7 15 in Pipe 3 + #? + # PORT_ID: 67 + #: + # PC_PHYS_PORT_ID: 125 #TSC-BH7 15 in Pipe 3 + ? + PORT_ID: 80 + : + PC_PHYS_PORT_ID: 129 #TSC-BH7 16 in Pipe 4 + #? + # PORT_ID: 81 + #: + # PC_PHYS_PORT_ID: 133 #TSC-BH7 16 in Pipe 4 + ? + PORT_ID: 82 + : + PC_PHYS_PORT_ID: 137 #TSC-BH7 17 in Pipe 4 + #? + # PORT_ID: 83 + #: + # PC_PHYS_PORT_ID: 141 #TSC-BH7 17 in Pipe 4 + ? + PORT_ID: 84 + : + PC_PHYS_PORT_ID: 145 #TSC-BH7 18 in Pipe 4 + #? + # PORT_ID: 85 + #: + # PC_PHYS_PORT_ID: 149 #TSC-BH7 18 in Pipe 4 + ? + PORT_ID: 86 + : + PC_PHYS_PORT_ID: 153 #TSC-BH7 19 in Pipe 4 + #? + # PORT_ID: 87 + #: + # PC_PHYS_PORT_ID: 157 #TSC-BH7 19 in Pipe 4 + ? + PORT_ID: 100 + : + PC_PHYS_PORT_ID: 161 #TSC-BH7 20 in Pipe 5 + #? + # PORT_ID: 101 + #: + # PC_PHYS_PORT_ID: 165 #TSC-BH7 20 in Pipe 5 + ? + PORT_ID: 102 + : + PC_PHYS_PORT_ID: 169 #TSC-BH7 21 in Pipe 5 + #? + # PORT_ID: 103 + #: + # PC_PHYS_PORT_ID: 173 #TSC-BH7 21 in Pipe 5 + ? + PORT_ID: 104 + : + PC_PHYS_PORT_ID: 177 #TSC-BH7 22 in Pipe 5 + #? + # PORT_ID: 105 + #: + # PC_PHYS_PORT_ID: 181 #TSC-BH7 22 in Pipe 5 + ? + PORT_ID: 106 + : + PC_PHYS_PORT_ID: 185 #TSC-BH7 23 in Pipe 5 + #? + # PORT_ID: 107 + #: + # PC_PHYS_PORT_ID: 189 #TSC-BH7 23 in Pipe 5 + ? + PORT_ID: 120 + : + PC_PHYS_PORT_ID: 193 #TSC-BH7 24 in Pipe 6 + #? + # PORT_ID: 121 + #: + # PC_PHYS_PORT_ID: 197 #TSC-BH7 24 in Pipe 6 + ? + PORT_ID: 122 + : + PC_PHYS_PORT_ID: 201 #TSC-BH7 25 in Pipe 6 + #? + # PORT_ID: 123 + #: + # PC_PHYS_PORT_ID: 205 #TSC-BH7 25 in Pipe 6 + ? + PORT_ID: 124 + : + PC_PHYS_PORT_ID: 209 #TSC-BH7 26 in Pipe 6 + #? + # PORT_ID: 125 + #: + # PC_PHYS_PORT_ID: 213 #TSC-BH7 26 in Pipe 6 + ? + PORT_ID: 126 + : + PC_PHYS_PORT_ID: 217 #TSC-BH7 27 in Pipe 6 + #? + # PORT_ID: 127 + #: + # PC_PHYS_PORT_ID: 221 #TSC-BH7 27 in Pipe 6 + ? + PORT_ID: 140 + : + PC_PHYS_PORT_ID: 225 #TSC-BH7 28 in Pipe 7 + #? + # PORT_ID: 141 + #: + # PC_PHYS_PORT_ID: 229 #TSC-BH7 28 in Pipe 7 + ? + PORT_ID: 142 + : + PC_PHYS_PORT_ID: 233 #TSC-BH7 29 in Pipe 7 + #? + # PORT_ID: 143 + #: + # PC_PHYS_PORT_ID: 237 #TSC-BH7 29 in Pipe 7 + ? + PORT_ID: 144 + : + PC_PHYS_PORT_ID: 241 #TSC-BH7 30 in Pipe 7 + #? + # PORT_ID: 145 + #: + # PC_PHYS_PORT_ID: 245 #TSC-BH7 30 in Pipe 7 + ? + PORT_ID: 146 + : + PC_PHYS_PORT_ID: 249 #TSC-BH7 31 in Pipe 7 + #? + # PORT_ID: 147 + #: + # PC_PHYS_PORT_ID: 253 #TSC-BH7 31 in Pipe 7 + #? + # Management port 0 (Pipe 1) - CPU + # PORT_ID: 38 + #: + # PC_PHYS_PORT_ID: 257 + #? + # Management port 1 (Pipe 3) - CPU + # PORT_ID: 78 + #: + # PC_PHYS_PORT_ID: 258 + ? + # Management port 2 (Pipe 5) - Front Panel Port + PORT_ID: 118 + : + PC_PHYS_PORT_ID: 259 + ? + # Management port 3 (Pipe 7) - Front Panel Port + PORT_ID: 158 + : + PC_PHYS_PORT_ID: 260 +... +--- +device: + 0: + PC_PORT: + ? + PORT_ID: 0 + : + &port_mode_10g + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [[1],[3],[5],[7], + [20],[22],[24],[26], + [40],[42],[44],[46], + [60],[62],[64],[66], + [80],[82],[84],[86], + [100],[102],[104],[106], + [120],[122],[124],[126], + [140],[142],[144],[146]] + : + &port_mode_100g + ENABLE: 0 + SPEED: 100000 + NUM_LANES: 4 + FEC_MODE: PC_FEC_RS528 + MAX_FRAME_SIZE: 9416 + #? + # PORT_ID: [38, # Management port 0 (Pipe 1) - CPU + # 78] # Management port 1 (Pipe 3) - CPU + #: + # &port_mode_10g_xfi + # ENABLE: 0 + # SPEED: 10000 + # NUM_LANES: 1 + # MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [118, # Management port 2 (Pipe 5) - Front Panel Port + 158] # Management port 3 (Pipe 7) - Front Panel Port + : + &port_mode_10g_xfi + ENABLE: 0 + SPEED: 10000 + NUM_LANES: 1 + MAX_FRAME_SIZE: 9416 + + PC_PMD_FIRMWARE: + ? + PORT_ID: [[1],[3],[5],[7], + [20],[22],[24],[26], + [40],[42],[44],[46], + [60],[62],[64],[66], + [80],[82],[84],[86], + [100],[102],[104],[106], + [120],[122],[124],[126], + [140],[142],[144],[146]] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_COPPER +... +--- +device: + 0: + TM_THD_CONFIG: + THRESHOLD_MODE: LOSSLESS +... +--- +device: + 0: + FP_CONFIG: + FP_ING_OPERMODE: GLOBAL_PIPE_AWARE +... diff --git a/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/hwsku.json b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/hwsku.json new file mode 100644 index 0000000000..dc68e55859 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/hwsku.json @@ -0,0 +1,174 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet8": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet16": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet24": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet32": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet40": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet48": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet56": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet64": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet72": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet80": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet88": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet96": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet104": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet112": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet120": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet128": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet136": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet144": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet152": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet160": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet168": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet176": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet184": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet192": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet200": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet208": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet216": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet224": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet232": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet240": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet248": { + "default_brkout_mode": "1x400G", + "autoneg": "off" + }, + + "Ethernet256": { + "default_brkout_mode": "1x10G[1G]", + "autoneg": "off" + }, + + "Ethernet257": { + "default_brkout_mode": "1x10G[1G]", + "autoneg": "off" + } + } +} + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/port_config.ini b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/port_config.ini index f7fcf8517d..da6800cda1 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/port_config.ini +++ b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/port_config.ini @@ -1,35 +1,35 @@ -# name lanes alias index speed -Ethernet1 73,74,75,76,77,78,79,80 fourHundredGigE1 1 400000 -Ethernet2 65,66,67,68,69,70,71,72 fourHundredGigE2 2 400000 -Ethernet3 81,82,83,84,85,86,87,88 fourHundredGigE3 3 400000 -Ethernet4 89,90,91,92,93,94,95,96 fourHundredGigE4 4 400000 -Ethernet5 97,98,99,100,101,102,103,104 fourHundredGigE5 5 400000 -Ethernet6 105,106,107,108,109,110,111,112 fourHundredGigE6 6 400000 -Ethernet7 113,114,115,116,117,118,119,120 fourHundredGigE7 7 400000 -Ethernet8 121,122,123,124,125,126,127,128 fourHundredGigE8 8 400000 -Ethernet9 41,42,43,44,45,46,47,48 fourHundredGigE9 9 400000 -Ethernet10 33,34,35,36,37,38,39,40 fourHundredGigE10 10 400000 -Ethernet11 49,50,51,52,53,54,55,56 fourHundredGigE11 11 400000 -Ethernet12 57,58,59,60,61,62,63,64 fourHundredGigE12 12 400000 -Ethernet13 129,130,131,132,133,134,135,136 fourHundredGigE13 13 400000 -Ethernet14 137,138,139,140,141,142,143,144 fourHundredGigE14 14 400000 -Ethernet15 145,146,147,148,149,150,151,152 fourHundredGigE15 15 400000 -Ethernet16 153,154,155,156,157,158,159,160 fourHundredGigE16 16 400000 -Ethernet17 169,170,171,172,173,174,175,176 fourHundredGigE17 17 400000 -Ethernet18 161,162,163,164,165,166,167,168 fourHundredGigE18 18 400000 -Ethernet19 177,178,179,180,181,182,183,184 fourHundredGigE19 19 400000 -Ethernet20 185,186,187,188,189,190,191,192 fourHundredGigE20 20 400000 -Ethernet21 1,2,3,4,5,6,7,8 fourHundredGigE21 21 400000 -Ethernet22 9,10,11,12,13,14,15,16 fourHundredGigE22 22 400000 -Ethernet23 17,18,19,20,21,22,23,24 fourHundredGigE23 23 400000 -Ethernet24 25,26,27,28,29,30,31,32 fourHundredGigE24 24 400000 -Ethernet25 201,202,203,204,205,206,207,208 fourHundredGigE25 25 400000 -Ethernet26 193,194,195,196,197,198,199,200 fourHundredGigE26 26 400000 -Ethernet27 217,218,219,220,221,222,223,224 fourHundredGigE27 27 400000 -Ethernet28 209,210,211,212,213,214,215,216 fourHundredGigE28 28 400000 -Ethernet29 233,234,235,236,237,238,239,240 fourHundredGigE29 29 400000 -Ethernet30 225,226,227,228,229,230,231,232 fourHundredGigE30 30 400000 -Ethernet31 249,250,251,252,253,254,255,256 fourHundredGigE31 31 400000 -Ethernet32 241,242,243,244,245,246,247,248 fourHundredGigE32 32 400000 -Ethernet33 249 tenGigE33 33 10000 -Ethernet34 250 tenGigE34 34 10000 +# name lanes alias index speed +Ethernet0 73,74,75,76,77,78,79,80 Eth1(Port1) 1 400000 +Ethernet8 65,66,67,68,69,70,71,72 Eth2(Port2) 2 400000 +Ethernet16 81,82,83,84,85,86,87,88 Eth3(Port3) 3 400000 +Ethernet24 89,90,91,92,93,94,95,96 Eth4(Port4) 4 400000 +Ethernet32 97,98,99,100,101,102,103,104 Eth5(Port5) 5 400000 +Ethernet40 105,106,107,108,109,110,111,112 Eth6(Port6) 6 400000 +Ethernet48 113,114,115,116,117,118,119,120 Eth7(Port7) 7 400000 +Ethernet56 121,122,123,124,125,126,127,128 Eth8(Port8) 8 400000 +Ethernet64 41,42,43,44,45,46,47,48 Eth9(Port9) 9 400000 +Ethernet72 33,34,35,36,37,38,39,40 Eth10(Port10) 10 400000 +Ethernet80 49,50,51,52,53,54,55,56 Eth11(Port11) 11 400000 +Ethernet88 57,58,59,60,61,62,63,64 Eth12(Port12) 12 400000 +Ethernet96 129,130,131,132,133,134,135,136 Eth13(Port13) 13 400000 +Ethernet104 137,138,139,140,141,142,143,144 Eth14(Port14) 14 400000 +Ethernet112 145,146,147,148,149,150,151,152 Eth15(Port15) 15 400000 +Ethernet120 153,154,155,156,157,158,159,160 Eth16(Port16) 16 400000 +Ethernet128 169,170,171,172,173,174,175,176 Eth17(Port17) 17 400000 +Ethernet136 161,162,163,164,165,166,167,168 Eth18(Port18) 18 400000 +Ethernet144 177,178,179,180,181,182,183,184 Eth19(Port19) 19 400000 +Ethernet152 185,186,187,188,189,190,191,192 Eth20(Port20) 20 400000 +Ethernet160 1,2,3,4,5,6,7,8 Eth21(Port21) 21 400000 +Ethernet168 9,10,11,12,13,14,15,16 Eth22(Port22) 22 400000 +Ethernet176 17,18,19,20,21,22,23,24 Eth23(Port23) 23 400000 +Ethernet184 25,26,27,28,29,30,31,32 Eth24(Port24) 24 400000 +Ethernet192 201,202,203,204,205,206,207,208 Eth25(Port25) 25 400000 +Ethernet200 193,194,195,196,197,198,199,200 Eth26(Port26) 26 400000 +Ethernet208 217,218,219,220,221,222,223,224 Eth27(Port27) 27 400000 +Ethernet216 209,210,211,212,213,214,215,216 Eth28(Port28) 28 400000 +Ethernet224 233,234,235,236,237,238,239,240 Eth29(Port29) 29 400000 +Ethernet232 225,226,227,228,229,230,231,232 Eth30(Port30) 30 400000 +Ethernet240 249,250,251,252,253,254,255,256 Eth31(Port31) 31 400000 +Ethernet248 241,242,243,244,245,246,247,248 Eth32(Port32) 32 400000 +Ethernet256 259 Eth33(Port33) 33 10000 +Ethernet257 260 Eth34(Port34) 34 10000 diff --git a/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/sai.profile b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/sai.profile new file mode 100644 index 0000000000..40702dd484 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td4-as9726-32x400G.config.yml diff --git a/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/td4-as9726-32x400G.config.yml b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/td4-as9726-32x400G.config.yml new file mode 100644 index 0000000000..ebb3907766 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/Accton-AS9726-32D/td4-as9726-32x400G.config.yml @@ -0,0 +1,669 @@ +# +# BCM56880 32x400g port configuration. +# +# configuration yaml file +# device: +# : +#
: +# ? +# : +# : +# ... +# : +# : +# : +# : +# ... +# : +# +# $Copyright: (c) 2019 Broadcom. +# Broadcom Proprietary and Confidential. All rights reserved.$ +# + +--- +bcm_device: + 0: + global: + pktio_mode: 1 + skip_protocol_default_entries: 1 + uft_mode: 3 + l3_alpm_template: 1 + vlan_default_port: 3 + max_vp_lags: 894 +... +--- +bcm_device: + 0: + port: + "*": + port_allow_tpid_disable: 1 +... +--- +device: + 0: + DEVICE_CONFIG: + # CORE CLOCK FREQUENCY + CORE_CLK_FREQ: CLK_1350MHZ + # PP CLOCK FREQUENCY + PP_CLK_FREQ: CLK_1350MHZ +... +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01476352 + TX_LANE_MAP: 0x67015324 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xDD + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x21563047 + TX_LANE_MAP: 0x70146253 + RX_POLARITY_FLIP: 0xEF + TX_POLARITY_FLIP: 0x6 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x34216570 + TX_LANE_MAP: 0x02453617 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xEE + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x26531470 + TX_LANE_MAP: 0x40726513 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xBE + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x23641705 + TX_LANE_MAP: 0x45326071 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xB3 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x45013726 + TX_LANE_MAP: 0x23170564 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x21 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x41025763 + TX_LANE_MAP: 0x25674013 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x4 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01675243 + TX_LANE_MAP: 0x07236415 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xEB + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x56024713 + TX_LANE_MAP: 0x21670534 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x3E + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01675342 + TX_LANE_MAP: 0x43607512 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x3D + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x20563147 + TX_LANE_MAP: 0x50126734 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xF3 + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x46150723 + TX_LANE_MAP: 0x13456072 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xEA + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x51276034 + TX_LANE_MAP: 0x35476012 + RX_POLARITY_FLIP: 0xC5 + TX_POLARITY_FLIP: 0xED + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x65217430 + TX_LANE_MAP: 0x02541637 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x4 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x32461057 + TX_LANE_MAP: 0x54107362 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xCD + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x31405267 + TX_LANE_MAP: 0x63150724 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xF4 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01475263 + TX_LANE_MAP: 0x63017524 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xFF + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x21463057 + TX_LANE_MAP: 0x70135462 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x9C + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x64217530 + TX_LANE_MAP: 0x23561407 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x53 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x10652473 + TX_LANE_MAP: 0x25306417 + RX_POLARITY_FLIP: 0x14 + TX_POLARITY_FLIP: 0xCA + ? + PC_PM_ID: 21 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x24561307 + TX_LANE_MAP: 0x65407321 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x37 + ? + PC_PM_ID: 22 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x27416350 + TX_LANE_MAP: 0x06573421 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xFB + ? + PC_PM_ID: 23 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x40517263 + TX_LANE_MAP: 0x30742516 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xB1 + ? + PC_PM_ID: 24 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x02561347 + TX_LANE_MAP: 0x53017624 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x23 + ? + PC_PM_ID: 25 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x64127503 + TX_LANE_MAP: 0x40572613 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xC + ? + PC_PM_ID: 26 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x01475362 + TX_LANE_MAP: 0x67015324 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x5C + ? + PC_PM_ID: 27 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x46150723 + TX_LANE_MAP: 0x21630754 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0xA0 + ? + PC_PM_ID: 28 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x20563147 + TX_LANE_MAP: 0x23607451 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0xCF + ? + PC_PM_ID: 29 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x72541360 + TX_LANE_MAP: 0x50461237 + RX_POLARITY_FLIP: 0x22 + TX_POLARITY_FLIP: 0x15 + ? + PC_PM_ID: 30 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x32465071 + TX_LANE_MAP: 0x64312705 + RX_POLARITY_FLIP: 0xFF + TX_POLARITY_FLIP: 0x7F + ? + PC_PM_ID: 31 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x56412730 + TX_LANE_MAP: 0x31647250 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x20 + ? + PC_PM_ID: 32 + CORE_INDEX: 0 + : + RX_LANE_MAP_AUTO: 0 + TX_LANE_MAP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_LANE_MAP: 0x64127503 + TX_LANE_MAP: 0x54321607 + RX_POLARITY_FLIP: 0x0 + TX_POLARITY_FLIP: 0x80 +... +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 1 + : + PC_PHYS_PORT_ID: 1 #TSC-BH7 0 in Pipe 0 + ? + PORT_ID: 2 + : + PC_PHYS_PORT_ID: 9 #TSC-BH7 1 in Pipe 0 + ? + PORT_ID: 3 + : + PC_PHYS_PORT_ID: 17 #TSC-BH7 2 in Pipe 0 + ? + PORT_ID: 4 + : + PC_PHYS_PORT_ID: 25 #TSC-BH7 3 in Pipe 0 + ? + PORT_ID: 20 + : + PC_PHYS_PORT_ID: 33 #TSC-BH7 4 in Pipe 1 + ? + PORT_ID: 21 + : + PC_PHYS_PORT_ID: 41 #TSC-BH7 5 in Pipe 1 + ? + PORT_ID: 22 + : + PC_PHYS_PORT_ID: 49 #TSC-BH7 6 in Pipe 1 + ? + PORT_ID: 23 + : + PC_PHYS_PORT_ID: 57 #TSC-BH7 7 in Pipe 1 + ? + PORT_ID: 40 + : + PC_PHYS_PORT_ID: 65 #TSC-BH7 8 in Pipe 2 + ? + PORT_ID: 41 + : + PC_PHYS_PORT_ID: 73 #TSC-BH7 9 in Pipe 2 + ? + PORT_ID: 42 + : + PC_PHYS_PORT_ID: 81 #TSC-BH7 10 in Pipe 2 + ? + PORT_ID: 43 + : + PC_PHYS_PORT_ID: 89 #TSC-BH7 11 in Pipe 2 + ? + PORT_ID: 60 + : + PC_PHYS_PORT_ID: 97 #TSC-BH7 12 in Pipe 3 + ? + PORT_ID: 61 + : + PC_PHYS_PORT_ID: 105 #TSC-BH7 13 in Pipe 3 + ? + PORT_ID: 62 + : + PC_PHYS_PORT_ID: 113 #TSC-BH7 14 in Pipe 3 + ? + PORT_ID: 63 + : + PC_PHYS_PORT_ID: 121 #TSC-BH7 15 in Pipe 3 + ? + PORT_ID: 80 + : + PC_PHYS_PORT_ID: 129 #TSC-BH7 16 in Pipe 4 + ? + PORT_ID: 81 + : + PC_PHYS_PORT_ID: 137 #TSC-BH7 17 in Pipe 4 + ? + PORT_ID: 82 + : + PC_PHYS_PORT_ID: 145 #TSC-BH7 18 in Pipe 4 + ? + PORT_ID: 83 + : + PC_PHYS_PORT_ID: 153 #TSC-BH7 19 in Pipe 4 + ? + PORT_ID: 100 + : + PC_PHYS_PORT_ID: 161 #TSC-BH7 20 in Pipe 5 + ? + PORT_ID: 101 + : + PC_PHYS_PORT_ID: 169 #TSC-BH7 21 in Pipe 5 + ? + PORT_ID: 102 + : + PC_PHYS_PORT_ID: 177 #TSC-BH7 22 in Pipe 5 + ? + PORT_ID: 103 + : + PC_PHYS_PORT_ID: 185 #TSC-BH7 23 in Pipe 5 + ? + PORT_ID: 120 + : + PC_PHYS_PORT_ID: 193 #TSC-BH7 24 in Pipe 6 + ? + PORT_ID: 121 + : + PC_PHYS_PORT_ID: 201 #TSC-BH7 25 in Pipe 6 + ? + PORT_ID: 122 + : + PC_PHYS_PORT_ID: 209 #TSC-BH7 26 in Pipe 6 + ? + PORT_ID: 123 + : + PC_PHYS_PORT_ID: 217 #TSC-BH7 27 in Pipe 6 + ? + PORT_ID: 140 + : + PC_PHYS_PORT_ID: 225 #TSC-BH7 28 in Pipe 7 + ? + PORT_ID: 141 + : + PC_PHYS_PORT_ID: 233 #TSC-BH7 29 in Pipe 7 + ? + PORT_ID: 142 + : + PC_PHYS_PORT_ID: 241 #TSC-BH7 30 in Pipe 7 + ? + PORT_ID: 143 + : + PC_PHYS_PORT_ID: 249 #TSC-BH7 31 in Pipe 7 + #? + # Management port 0 (Pipe 1) - CPU + # PORT_ID: 38 + #: + # PC_PHYS_PORT_ID: 257 + #? + # Management port 1 (Pipe 3) - CPU + # PORT_ID: 78 + #: + # PC_PHYS_PORT_ID: 258 + ? + # Management port 2 (Pipe 5) - Front Panel Port + PORT_ID: 118 + : + PC_PHYS_PORT_ID: 259 + ? + # Management port 3 (Pipe 7) - Front Panel Port + PORT_ID: 158 + : + PC_PHYS_PORT_ID: 260 +... +--- +device: + 0: + PC_PORT: + ? + PORT_ID: 0 + : + &port_mode_10g + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [[1, 4], + [20, 23], + [40, 43], + [60, 63], + [80, 83], + [100, 103], + [120, 123], + [140, 143]] + : + &port_mode_400g + ENABLE: 0 + SPEED: 400000 + NUM_LANES: 8 + FEC_MODE: PC_FEC_RS544_2XN + MAX_FRAME_SIZE: 9416 + #LINK_TRAINING: 1 + #? + # PORT_ID: [38, # Management port 0 (Pipe 1) - CPU + # 78] # Management port 1 (Pipe 3) - CPU + #: + # &port_mode_10g_xfi + # ENABLE: 0 + # SPEED: 10000 + # NUM_LANES: 1 + # MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [118, # Management port 2 (Pipe 5) - Front Panel Port + 158] # Management port 3 (Pipe 7) - Front Panel Port + : + &port_mode_10g_xfi + ENABLE: 0 + SPEED: 10000 + NUM_LANES: 1 + MAX_FRAME_SIZE: 9416 + + PC_PMD_FIRMWARE: + ? + PORT_ID: [[1, 4], + [20, 23], + [40, 43], + [60, 63], + [80, 83], + [100, 103], + [120, 123], + [140, 143]] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_COPPER +... +--- +device: + 0: + TM_THD_CONFIG: + THRESHOLD_MODE: LOSSLESS +... +--- +device: + 0: + FP_CONFIG: + FP_ING_OPERMODE: GLOBAL_PIPE_AWARE +... diff --git a/device/accton/x86_64-accton_as9726_32d-r0/fast-reboot_plugin b/device/accton/x86_64-accton_as9726_32d-r0/fast-reboot_plugin new file mode 120000 index 0000000000..295bfa58fb --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/fast-reboot_plugin @@ -0,0 +1 @@ +warm-reboot_plugin \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9726_32d-r0/installer.conf b/device/accton/x86_64-accton_as9726_32d-r0/installer.conf index 925a32fc0c..d5f9419d77 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/installer.conf +++ b/device/accton/x86_64-accton_as9726_32d-r0/installer.conf @@ -1,3 +1,4 @@ CONSOLE_PORT=0x3f8 CONSOLE_DEV=0 CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pcie_aspm=off" diff --git a/device/accton/x86_64-accton_as9726_32d-r0/pcie.yaml b/device/accton/x86_64-accton_as9726_32d-r0/pcie.yaml new file mode 100644 index 0000000000..734feab956 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/pcie.yaml @@ -0,0 +1,424 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: '16' + fn: '0' + id: 8c3a + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #1 (rev 04)' +- bus: '00' + dev: '16' + fn: '1' + id: 8c3b + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #2 (rev 04)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '02' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '02' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '02' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '02' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '03' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '03' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '05' + dev: '00' + fn: '0' + id: b880 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries BCM56880 Switch ASIC + (rev 11)' +- bus: '06' + dev: '00' + fn: '0' + id: '1538' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '2' + id: 6fe2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '3' + id: 6fe3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/accton/x86_64-accton_as9726_32d-r0/platform.json b/device/accton/x86_64-accton_as9726_32d-r0/platform.json new file mode 100644 index 0000000000..6e92fbe39a --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/platform.json @@ -0,0 +1,901 @@ +{ + "chassis": { + "name": "9726-32D", + "status_led": { + "controllable": false + }, + "thermal_manager":false, + "components": [ + { + "name": "CPLD1" + }, + { + "name": "CPLD2" + }, + { + "name": "CPLD3" + }, + { + "name": "CPLD4" + }, + { + "name": "CPLD5" + }, + { + "name": "BIOS" + } + ], + "fans": [ + { + "name": "FAN-1F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-1R", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-2F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-2R", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-3F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-3R", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-4F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-4R", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-5F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-5R", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-6F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-6R", + "status_led": { + "controllable": false + } + } + ], + "fan_drawers":[ + { + "name": "FanTray1", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-1F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-1R", + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray2", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-2F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-2R", + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray3", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-3F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-3R", + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray4", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-4F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-4R", + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray5", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-5F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-5R", + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray6", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-6F", + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-6R", + "status_led": { + "controllable": false + } + } + ] + } + ], + "psus": [ + { + "name": "PSU-1", + "fans": [ + { + "name": "PSU-1 FAN-1" + } + ], + "thermals": [ + { + "name": "PSU-1 temp sensor 1", + "controllable": false, + "low-threshold": false, + "high-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + } + ], + "temperature": true, + "temperature_high_threshold": true + }, + { + "name": "PSU-2", + "fans": [ + { + "name": "PSU-2 FAN-1" + } + ], + "thermals": [ + { + "name": "PSU-2 temp sensor 1", + "controllable": false, + "low-threshold": false, + "high-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + } + ], + "temperature": true, + "temperature_high_threshold": true + } + ], + "thermals": [ + { + "name": "MB_FrontMiddle_temp(0x48)", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "MB_RightCenter_temp(0x49)", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "MB_LeftCenter_temp(0x4A)", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "CB_temp(0x4B)", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "OCXO_temp(0x4C)", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "MB_RearRight_temp(0x4F)", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "CPU_Package_temp", + "controllable": false, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": true + }, + { + "name": "CPU_Core_0_temp", + "controllable": false, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": true + }, + { + "name": "CPU_Core_1_temp", + "controllable": false, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": true + }, + { + "name": "CPU_Core_2_temp", + "controllable": false, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": true + }, + { + "name": "CPU_Core_3_temp", + "controllable": false, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": true + } + ], + "sfps": [ + { + "name": "Ethernet0" + }, + { + "name": "Ethernet8" + }, + { + "name": "Ethernet16" + }, + { + "name": "Ethernet24" + }, + { + "name": "Ethernet32" + }, + { + "name": "Ethernet40" + }, + { + "name": "Ethernet48" + }, + { + "name": "Ethernet56" + }, + { + "name": "Ethernet64" + }, + { + "name": "Ethernet72" + }, + { + "name": "Ethernet80" + }, + { + "name": "Ethernet88" + }, + { + "name": "Ethernet96" + }, + { + "name": "Ethernet104" + }, + { + "name": "Ethernet112" + }, + { + "name": "Ethernet120" + }, + { + "name": "Ethernet128" + }, + { + "name": "Ethernet136" + }, + { + "name": "Ethernet144" + }, + { + "name": "Ethernet152" + }, + { + "name": "Ethernet160" + }, + { + "name": "Ethernet168" + }, + { + "name": "Ethernet176" + }, + { + "name": "Ethernet184" + }, + { + "name": "Ethernet192" + }, + { + "name": "Ethernet200" + }, + { + "name": "Ethernet208" + }, + { + "name": "Ethernet216" + }, + { + "name": "Ethernet224" + }, + { + "name": "Ethernet232" + }, + { + "name": "Ethernet240" + }, + { + "name": "Ethernet248" + }, + { + "name": "Ethernet256" + }, + { + "name": "Ethernet257" + } + ] + }, + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1,1,1,1,1", + "lanes": "73,74,75,76,77,78,79,80", + "breakout_modes": { + "1x400G": ["Eth1(Port1)"], + "2x200G": ["Eth1/1(Port1)", "Eth1/2(Port1)"], + "4x100G": ["Eth1/1(Port1)", "Eth1/2(Port1)", "Eth1/3(Port1)", "Eth1/4(Port1)"], + "1x100G[40G](4)": ["Eth1(Port1)"], + "2x50G(4)": ["Eth1/1(Port1)", "Eth1/2(Port1)"], + "4x25G[10G](4)": ["Eth1/1(Port1)", "Eth1/2(Port1)", "Eth1/3(Port1)", "Eth1/4(Port1)"] + } + }, + + "Ethernet8": { + "index": "2,2,2,2,2,2,2,2", + "lanes": "65,66,67,68,69,70,71,72", + "breakout_modes": { + "1x400G": ["Eth2(Port2)"], + "2x200G": ["Eth2/1(Port2)", "Eth2/2(Port2)"], + "4x100G": ["Eth2/1(Port2)", "Eth2/2(Port2)", "Eth2/3(Port2)", "Eth2/4(Port2)"], + "1x100G[40G](4)": ["Eth2(Port2)"], + "2x50G(4)": ["Eth2/1(Port2)", "Eth2/2(Port2)"], + "4x25G[10G](4)": ["Eth2/1(Port2)", "Eth2/2(Port2)", "Eth2/3(Port2)", "Eth2/4(Port2)"] + } + }, + + "Ethernet16": { + "index": "3,3,3,3,3,3,3,3", + "lanes": "81,82,83,84,85,86,87,88", + "breakout_modes": { + "1x400G": ["Eth3(Port3)"], + "2x200G": ["Eth3/1(Port3)", "Eth3/2(Port3)"], + "4x100G": ["Eth3/1(Port3)", "Eth3/2(Port3)", "Eth3/3(Port3)", "Eth3/4(Port3)"], + "1x100G[40G](4)": ["Eth3(Port3)"], + "2x50G(4)": ["Eth3/1(Port3)", "Eth3/2(Port3)"], + "4x25G[10G](4)": ["Eth3/1(Port3)", "Eth3/2(Port3)", "Eth3/3(Port3)", "Eth3/4(Port3)"] + } + }, + + "Ethernet24": { + "index": "4,4,4,4,4,4,4,4", + "lanes": "89,90,91,92,93,94,95,96", + "breakout_modes": { + "1x400G": ["Eth4(Port4)"], + "2x200G": ["Eth4/1(Port4)", "Eth4/2(Port4)"], + "4x100G": ["Eth4/1(Port4)", "Eth4/2(Port4)", "Eth4/3(Port4)", "Eth4/4(Port4)"], + "1x100G[40G](4)": ["Eth4(Port4)"], + "2x50G(4)": ["Eth4/1(Port4)", "Eth4/2(Port4)"], + "4x25G[10G](4)": ["Eth4/1(Port4)", "Eth4/2(Port4)", "Eth4/3(Port4)", "Eth4/4(Port4)"] + } + }, + + "Ethernet32": { + "index": "5,5,5,5,5,5,5,5", + "lanes": "97,98,99,100,101,102,103,104", + "breakout_modes": { + "1x400G": ["Eth5(Port5)"], + "2x200G": ["Eth5/1(Port5)", "Eth5/2(Port5)"], + "4x100G": ["Eth5/1(Port5)", "Eth5/2(Port5)", "Eth5/3(Port5)", "Eth5/4(Port5)"], + "1x100G[40G](4)": ["Eth5(Port5)"], + "2x50G(4)": ["Eth5/1(Port5)", "Eth5/2(Port5)"], + "4x25G[10G](4)": ["Eth5/1(Port5)", "Eth5/2(Port5)", "Eth5/3(Port5)", "Eth5/4(Port5)"] + } + }, + + "Ethernet40": { + "index": "6,6,6,6,6,6,6,6", + "lanes": "105,106,107,108,109,110,111,112", + "breakout_modes": { + "1x400G": ["Eth6(Port6)"], + "2x200G": ["Eth6/1(Port6)", "Eth6/2(Port6)"], + "4x100G": ["Eth6/1(Port6)", "Eth6/2(Port6)", "Eth6/3(Port6)", "Eth6/4(Port6)"], + "1x100G[40G](4)": ["Eth6(Port6)"], + "2x50G(4)": ["Eth6/1(Port6)", "Eth6/2(Port6)"], + "4x25G[10G](4)": ["Eth6/1(Port6)", "Eth6/2(Port6)", "Eth6/3(Port6)", "Eth6/4(Port6)"] + } + }, + + "Ethernet48": { + "index": "7,7,7,7,7,7,7,7", + "lanes": "113,114,115,116,117,118,119,120", + "breakout_modes": { + "1x400G": ["Eth7(Port7)"], + "2x200G": ["Eth7/1(Port7)", "Eth7/2(Port7)"], + "4x100G": ["Eth7/1(Port7)", "Eth7/2(Port7)", "Eth7/3(Port7)", "Eth7/4(Port7)"], + "1x100G[40G](4)": ["Eth7(Port7)"], + "2x50G(4)": ["Eth7/1(Port7)", "Eth7/2(Port7)"], + "4x25G[10G](4)": ["Eth7/1(Port7)", "Eth7/2(Port7)", "Eth7/3(Port7)", "Eth7/4(Port7)"] + } + }, + + "Ethernet56": { + "index": "8,8,8,8,8,8,8,8", + "lanes": "121,122,123,124,125,126,127,128", + "breakout_modes": { + "1x400G": ["Eth8(Port8)"], + "2x200G": ["Eth8/1(Port8)", "Eth8/2(Port8)"], + "4x100G": ["Eth8/1(Port8)", "Eth8/2(Port8)", "Eth8/3(Port8)", "Eth8/4(Port8)"], + "1x100G[40G](4)": ["Eth8(Port8)"], + "2x50G(4)": ["Eth8/1(Port8)", "Eth8/2(Port8)"], + "4x25G[10G](4)": ["Eth8/1(Port8)", "Eth8/2(Port8)", "Eth8/3(Port8)", "Eth8/4(Port8)"] + } + }, + + "Ethernet64": { + "index": "9,9,9,9,9,9,9,9", + "lanes": "41,42,43,44,45,46,47,48", + "breakout_modes": { + "1x400G": ["Eth9(Port9)"], + "2x200G": ["Eth9/1(Port9)", "Eth9/2(Port9)"], + "4x100G": ["Eth9/1(Port9)", "Eth9/2(Port9)", "Eth9/3(Port9)", "Eth9/4(Port9)"], + "1x100G[40G](4)": ["Eth9(Port9)"], + "2x50G(4)": ["Eth9/1(Port9)", "Eth9/2(Port9)"], + "4x25G[10G](4)": ["Eth9/1(Port9)", "Eth9/2(Port9)", "Eth9/3(Port9)", "Eth9/4(Port9)"] + } + }, + + "Ethernet72": { + "index": "10,10,10,10,10,10,10,10", + "lanes": "33,34,35,36,37,38,39,40", + "breakout_modes": { + "1x400G": ["Eth10(Port10)"], + "2x200G": ["Eth10/1(Port10)", "Eth10/2(Port10)"], + "4x100G": ["Eth10/1(Port10)", "Eth10/2(Port10)", "Eth10/3(Port10)", "Eth10/4(Port10)"], + "1x100G[40G](4)": ["Eth10(Port10)"], + "2x50G(4)": ["Eth10/1(Port10)", "Eth10/2(Port10)"], + "4x25G[10G](4)": ["Eth10/1(Port10)", "Eth10/2(Port10)", "Eth10/3(Port10)", "Eth10/4(Port10)"] + } + }, + + "Ethernet80": { + "index": "11,11,11,11,11,11,11,11", + "lanes": "49,50,51,52,53,54,55,56", + "breakout_modes": { + "1x400G": ["Eth11(Port11)"], + "2x200G": ["Eth11/1(Port11)", "Eth11/2(Port11)"], + "4x100G": ["Eth11/1(Port11)", "Eth11/2(Port11)", "Eth11/3(Port11)", "Eth11/4(Port11)"], + "1x100G[40G](4)": ["Eth11(Port11)"], + "2x50G(4)": ["Eth11/1(Port11)", "Eth11/2(Port11)"], + "4x25G[10G](4)": ["Eth11/1(Port11)", "Eth11/2(Port11)", "Eth11/3(Port11)", "Eth11/4(Port11)"] + } + }, + + "Ethernet88": { + "index": "12,12,12,12,12,12,12,12", + "lanes": "57,58,59,60,61,62,63,64", + "breakout_modes": { + "1x400G": ["Eth12(Port12)"], + "2x200G": ["Eth12/1(Port12)", "Eth12/2(Port12)"], + "4x100G": ["Eth12/1(Port12)", "Eth12/2(Port12)", "Eth12/3(Port12)", "Eth12/4(Port12)"], + "1x100G[40G](4)": ["Eth12(Port12)"], + "2x50G(4)": ["Eth12/1(Port12)", "Eth12/2(Port12)"], + "4x25G[10G](4)": ["Eth12/1(Port12)", "Eth12/2(Port12)", "Eth12/3(Port12)", "Eth12/4(Port12)"] + } + }, + + "Ethernet96": { + "index": "13,13,13,13,13,13,13,13", + "lanes": "129,130,131,132,133,134,135,136", + "breakout_modes": { + "1x400G": ["Eth13(Port13)"], + "2x200G": ["Eth13/1(Port13)", "Eth13/2(Port13)"], + "4x100G": ["Eth13/1(Port13)", "Eth13/2(Port13)", "Eth13/3(Port13)", "Eth13/4(Port13)"], + "1x100G[40G](4)": ["Eth13(Port13)"], + "2x50G(4)": ["Eth13/1(Port13)", "Eth13/2(Port13)"], + "4x25G[10G](4)": ["Eth13/1(Port13)", "Eth13/2(Port13)", "Eth13/3(Port13)", "Eth13/4(Port13)"] + } + }, + + "Ethernet104": { + "index": "14,14,14,14,14,14,14,14", + "lanes": "137,138,139,140,141,142,143,144", + "breakout_modes": { + "1x400G": ["Eth14(Port14)"], + "2x200G": ["Eth14/1(Port14)", "Eth14/2(Port14)"], + "4x100G": ["Eth14/1(Port14)", "Eth14/2(Port14)", "Eth14/3(Port14)", "Eth14/4(Port14)"], + "1x100G[40G](4)": ["Eth14(Port14)"], + "2x50G(4)": ["Eth14/1(Port14)", "Eth14/2(Port14)"], + "4x25G[10G](4)": ["Eth14/1(Port14)", "Eth14/2(Port14)", "Eth14/3(Port14)", "Eth14/4(Port14)"] + } + }, + + "Ethernet112": { + "index": "15,15,15,15,15,15,15,15", + "lanes": "145,146,147,148,149,150,151,152", + "breakout_modes": { + "1x400G": ["Eth15(Port15)"], + "2x200G": ["Eth15/1(Port15)", "Eth15/2(Port15)"], + "4x100G": ["Eth15/1(Port15)", "Eth15/2(Port15)", "Eth15/3(Port15)", "Eth15/4(Port15)"], + "1x100G[40G](4)": ["Eth15(Port15)"], + "2x50G(4)": ["Eth15/1(Port15)", "Eth15/2(Port15)"], + "4x25G[10G](4)": ["Eth15/1(Port15)", "Eth15/2(Port15)", "Eth15/3(Port15)", "Eth15/4(Port15)"] + } + }, + + "Ethernet120": { + "index": "16,16,16,16,16,16,16,16", + "lanes": "153,154,155,156,157,158,159,160", + "breakout_modes": { + "1x400G": ["Eth16(Port16)"], + "2x200G": ["Eth16/1(Port16)", "Eth16/2(Port16)"], + "4x100G": ["Eth16/1(Port16)", "Eth16/2(Port16)", "Eth16/3(Port16)", "Eth16/4(Port16)"], + "1x100G[40G](4)": ["Eth16(Port16)"], + "2x50G(4)": ["Eth16/1(Port16)", "Eth16/2(Port16)"], + "4x25G[10G](4)": ["Eth16/1(Port16)", "Eth16/2(Port16)", "Eth16/3(Port16)", "Eth16/4(Port16)"] + } + }, + + "Ethernet128": { + "index": "17,17,17,17,17,17,17,17", + "lanes": "169,170,171,172,173,174,175,176", + "breakout_modes": { + "1x400G": ["Eth17(Port17)"], + "2x200G": ["Eth17/1(Port17)", "Eth17/2(Port17)"], + "4x100G": ["Eth17/1(Port17)", "Eth17/2(Port17)", "Eth17/3(Port17)", "Eth17/4(Port17)"], + "1x100G[40G](4)": ["Eth17(Port17)"], + "2x50G(4)": ["Eth17/1(Port17)", "Eth17/2(Port17)"], + "4x25G[10G](4)": ["Eth17/1(Port17)", "Eth17/2(Port17)", "Eth17/3(Port17)", "Eth17/4(Port17)"] + } + }, + + "Ethernet136": { + "index": "18,18,18,18,18,18,18,18", + "lanes": "161,162,163,164,165,166,167,168", + "breakout_modes": { + "1x400G": ["Eth18(Port18)"], + "2x200G": ["Eth18/1(Port18)", "Eth18/2(Port18)"], + "4x100G": ["Eth18/1(Port18)", "Eth18/2(Port18)", "Eth18/3(Port18)", "Eth18/4(Port18)"], + "1x100G[40G](4)": ["Eth18(Port18)"], + "2x50G(4)": ["Eth18/1(Port18)", "Eth18/2(Port18)"], + "4x25G[10G](4)": ["Eth18/1(Port18)", "Eth18/2(Port18)", "Eth18/3(Port18)", "Eth18/4(Port18)"] + } + }, + + "Ethernet144": { + "index": "19,19,19,19,19,19,19,19", + "lanes": "177,178,179,180,181,182,183,184", + "breakout_modes": { + "1x400G": ["Eth19(Port19)"], + "2x200G": ["Eth19/1(Port19)", "Eth19/2(Port19)"], + "4x100G": ["Eth19/1(Port19)", "Eth19/2(Port19)", "Eth19/3(Port19)", "Eth19/4(Port19)"], + "1x100G[40G](4)": ["Eth19(Port19)"], + "2x50G(4)": ["Eth19/1(Port19)", "Eth19/2(Port19)"], + "4x25G[10G](4)": ["Eth19/1(Port19)", "Eth19/2(Port19)", "Eth19/3(Port19)", "Eth19/4(Port19)"] + } + }, + + "Ethernet152": { + "index": "20,20,20,20,20,20,20,20", + "lanes": "185,186,187,188,189,190,191,192", + "breakout_modes": { + "1x400G": ["Eth20(Port20)"], + "2x200G": ["Eth20/1(Port20)", "Eth20/2(Port20)"], + "4x100G": ["Eth20/1(Port20)", "Eth20/2(Port20)", "Eth20/3(Port20)", "Eth20/4(Port20)"], + "1x100G[40G](4)": ["Eth20(Port20)"], + "2x50G(4)": ["Eth20/1(Port20)", "Eth20/2(Port20)"], + "4x25G[10G](4)": ["Eth20/1(Port20)", "Eth20/2(Port20)", "Eth20/3(Port20)", "Eth20/4(Port20)"] + } + }, + + "Ethernet160": { + "index": "21,21,21,21,21,21,21,21", + "lanes": "1,2,3,4,5,6,7,8", + "breakout_modes": { + "1x400G": ["Eth21(Port21)"], + "2x200G": ["Eth21/1(Port21)", "Eth21/2(Port21)"], + "4x100G": ["Eth21/1(Port21)", "Eth21/2(Port21)", "Eth21/3(Port21)", "Eth21/4(Port21)"], + "1x100G[40G](4)": ["Eth21(Port21)"], + "2x50G(4)": ["Eth21/1(Port21)", "Eth21/2(Port21)"], + "4x25G[10G](4)": ["Eth21/1(Port21)", "Eth21/2(Port21)", "Eth21/3(Port21)", "Eth21/4(Port21)"] + } + }, + + "Ethernet168": { + "index": "22,22,22,22,22,22,22,22", + "lanes": "9,10,11,12,13,14,15,16", + "breakout_modes": { + "1x400G": ["Eth22(Port22)"], + "2x200G": ["Eth22/1(Port22)", "Eth22/2(Port22)"], + "4x100G": ["Eth22/1(Port22)", "Eth22/2(Port22)", "Eth22/3(Port22)", "Eth22/4(Port22)"], + "1x100G[40G](4)": ["Eth22(Port22)"], + "2x50G(4)": ["Eth22/1(Port22)", "Eth22/2(Port22)"], + "4x25G[10G](4)": ["Eth22/1(Port22)", "Eth22/2(Port22)", "Eth22/3(Port22)", "Eth22/4(Port22)"] + } + }, + + "Ethernet176": { + "index": "23,23,23,23,23,23,23,23", + "lanes": "17,18,19,20,21,22,23,24", + "breakout_modes": { + "1x400G": ["Eth23(Port23)"], + "2x200G": ["Eth23/1(Port23)", "Eth23/2(Port23)"], + "4x100G": ["Eth23/1(Port23)", "Eth23/2(Port23)", "Eth23/3(Port23)", "Eth23/4(Port23)"], + "1x100G[40G](4)": ["Eth23(Port23)"], + "2x50G(4)": ["Eth23/1(Port23)", "Eth23/2(Port23)"], + "4x25G[10G](4)": ["Eth23/1(Port23)", "Eth23/2(Port23)", "Eth23/3(Port23)", "Eth23/4(Port23)"] + } + }, + + "Ethernet184": { + "index": "24,24,24,24,24,24,24,24", + "lanes": "25,26,27,28,29,30,31,32", + "breakout_modes": { + "1x400G": ["Eth24(Port24)"], + "2x200G": ["Eth24/1(Port24)", "Eth24/2(Port24)"], + "4x100G": ["Eth24/1(Port24)", "Eth24/2(Port24)", "Eth24/3(Port24)", "Eth24/4(Port24)"], + "1x100G[40G](4)": ["Eth24(Port24)"], + "2x50G(4)": ["Eth24/1(Port24)", "Eth24/2(Port24)"], + "4x25G[10G](4)": ["Eth24/1(Port24)", "Eth24/2(Port24)", "Eth24/3(Port24)", "Eth24/4(Port24)"] + } + }, + + "Ethernet192": { + "index": "25,25,25,25,25,25,25,25", + "lanes": "201,202,203,204,205,206,207,208", + "breakout_modes": { + "1x400G": ["Eth25(Port25)"], + "2x200G": ["Eth25/1(Port25)", "Eth25/2(Port25)"], + "4x100G": ["Eth25/1(Port25)", "Eth25/2(Port25)", "Eth25/3(Port25)", "Eth25/4(Port25)"], + "1x100G[40G](4)": ["Eth25(Port25)"], + "2x50G(4)": ["Eth25/1(Port25)", "Eth25/2(Port25)"], + "4x25G[10G](4)": ["Eth25/1(Port25)", "Eth25/2(Port25)", "Eth25/3(Port25)", "Eth25/4(Port25)"] + } + }, + + "Ethernet200": { + "index": "26,26,26,26,26,26,26,26", + "lanes": "193,194,195,196,197,198,199,200", + "breakout_modes": { + "1x400G": ["Eth26(Port26)"], + "2x200G": ["Eth26/1(Port26)", "Eth26/2(Port26)"], + "4x100G": ["Eth26/1(Port26)", "Eth26/2(Port26)", "Eth26/3(Port26)", "Eth26/4(Port26)"], + "1x100G[40G](4)": ["Eth26(Port26)"], + "2x50G(4)": ["Eth26/1(Port26)", "Eth26/2(Port26)"], + "4x25G[10G](4)": ["Eth26/1(Port26)", "Eth26/2(Port26)", "Eth26/3(Port26)", "Eth26/4(Port26)"] + } + }, + + "Ethernet208": { + "index": "27,27,27,27,27,27,27,27", + "lanes": "217,218,219,220,221,222,223,224", + "breakout_modes": { + "1x400G": ["Eth27(Port27)"], + "2x200G": ["Eth27/1(Port27)", "Eth27/2(Port27)"], + "4x100G": ["Eth27/1(Port27)", "Eth27/2(Port27)", "Eth27/3(Port27)", "Eth27/4(Port27)"], + "1x100G[40G](4)": ["Eth27(Port27)"], + "2x50G(4)": ["Eth27/1(Port27)", "Eth27/2(Port27)"], + "4x25G[10G](4)": ["Eth27/1(Port27)", "Eth27/2(Port27)", "Eth27/3(Port27)", "Eth27/4(Port27)"] + } + }, + + "Ethernet216": { + "index": "28,28,28,28,28,28,28,28", + "lanes": "209,210,211,212,213,214,215,216", + "breakout_modes": { + "1x400G": ["Eth28(Port28)"], + "2x200G": ["Eth28/1(Port28)", "Eth28/2(Port28)"], + "4x100G": ["Eth28/1(Port28)", "Eth28/2(Port28)", "Eth28/3(Port28)", "Eth28/4(Port28)"], + "1x100G[40G](4)": ["Eth28(Port28)"], + "2x50G(4)": ["Eth28/1(Port28)", "Eth28/2(Port28)"], + "4x25G[10G](4)": ["Eth28/1(Port28)", "Eth28/2(Port28)", "Eth28/3(Port28)", "Eth28/4(Port28)"] + } + }, + + "Ethernet224": { + "index": "29,29,29,29,29,29,29,29", + "lanes": "233,234,235,236,237,238,239,240", + "breakout_modes": { + "1x400G": ["Eth29(Port29)"], + "2x200G": ["Eth29/1(Port29)", "Eth29/2(Port29)"], + "4x100G": ["Eth29/1(Port29)", "Eth29/2(Port29)", "Eth29/3(Port29)", "Eth29/4(Port29)"], + "1x100G[40G](4)": ["Eth29(Port29)"], + "2x50G(4)": ["Eth29/1(Port29)", "Eth29/2(Port29)"], + "4x25G[10G](4)": ["Eth29/1(Port29)", "Eth29/2(Port29)", "Eth29/3(Port29)", "Eth29/4(Port29)"] + } + }, + + "Ethernet232": { + "index": "30,30,30,30,30,30,30,30", + "lanes": "225,226,227,228,229,230,231,232", + "breakout_modes": { + "1x400G": ["Eth30(Port30)"], + "2x200G": ["Eth30/1(Port30)", "Eth30/2(Port30)"], + "4x100G": ["Eth30/1(Port30)", "Eth30/2(Port30)", "Eth30/3(Port30)", "Eth30/4(Port30)"], + "1x100G[40G](4)": ["Eth30(Port30)"], + "2x50G(4)": ["Eth30/1(Port30)", "Eth30/2(Port30)"], + "4x25G[10G](4)": ["Eth30/1(Port30)", "Eth30/2(Port30)", "Eth30/3(Port30)", "Eth30/4(Port30)"] + } + }, + + "Ethernet240": { + "index": "31,31,31,31,31,31,31,31", + "lanes": "249,250,251,252,253,254,255,256", + "breakout_modes": { + "1x400G": ["Eth31(Port31)"], + "2x200G": ["Eth31/1(Port31)", "Eth31/2(Port31)"], + "4x100G": ["Eth31/1(Port31)", "Eth31/2(Port31)", "Eth31/3(Port31)", "Eth31/4(Port31)"], + "1x100G[40G](4)": ["Eth31(Port31)"], + "2x50G(4)": ["Eth31/1(Port31)", "Eth31/2(Port31)"], + "4x25G[10G](4)": ["Eth31/1(Port31)", "Eth31/2(Port31)", "Eth31/3(Port31)", "Eth31/4(Port31)"] + } + }, + + "Ethernet248": { + "index": "32,32,32,32,32,32,32,32", + "lanes": "241,242,243,244,245,246,247,248", + "breakout_modes": { + "1x400G": ["Eth32(Port32)"], + "2x200G": ["Eth32/1(Port32)", "Eth32/2(Port32)"], + "4x100G": ["Eth32/1(Port32)", "Eth32/2(Port32)", "Eth32/3(Port32)", "Eth32/4(Port32)"], + "1x100G[40G](4)": ["Eth32(Port32)"], + "2x50G(4)": ["Eth32/1(Port32)", "Eth32/2(Port32)"], + "4x25G[10G](4)": ["Eth32/1(Port32)", "Eth32/2(Port32)", "Eth32/3(Port32)", "Eth32/4(Port32)"] + } + }, + + "Ethernet256": { + "index": "33", + "lanes": "259", + "breakout_modes": { + "1x10G[1G]": ["Eth33(Port33)"] + } + }, + + "Ethernet257": { + "index": "34", + "lanes": "260", + "breakout_modes": { + "1x10G[1G]": ["Eth34(Port34)"] + } + } + } +} + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/platform_components.json b/device/accton/x86_64-accton_as9726_32d-r0/platform_components.json new file mode 100644 index 0000000000..bca01c849a --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/platform_components.json @@ -0,0 +1,14 @@ +{ + "chassis": { + "AS9726-32DB-O-AC-F": { + "component": { + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { }, + "CPLD4": { }, + "CPLD5": { }, + "BIOS": { } + } + } + } +} diff --git a/device/accton/x86_64-accton_as9726_32d-r0/platform_env.conf b/device/accton/x86_64-accton_as9726_32d-r0/platform_env.conf new file mode 100644 index 0000000000..51be884d84 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/platform_env.conf @@ -0,0 +1,2 @@ +SYNCD_SHM_SIZE=1g +is_ltsw_chip=1 diff --git a/device/accton/x86_64-accton_as9726_32d-r0/platform_reboot b/device/accton/x86_64-accton_as9726_32d-r0/platform_reboot new file mode 100755 index 0000000000..494eae1143 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/platform_reboot @@ -0,0 +1,20 @@ +#!/bin/bash + +echo "Do sync" +sync + +echo "Stop pmon.service" +systemctl stop pmon.service + +echo "Stop as9726-32d-platform-monitor-fan.service" +systemctl stop as9726-32d-platform-monitor-fan.service + +echo "Stop as9726-32d-platform-monitor-psu.service" +systemctl stop as9726-32d-platform-monitor-psu.service + +echo "Stop as9726-32d-platform-monitor.service" +systemctl stop as9726-32d-platform-monitor.service + +echo "Cold Reset via CPLD Offset 0x4 Bit 3" +i2cset -y -f 1 0x65 0x4 0x15 + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as9726_32d-r0/plugins/eeprom.py deleted file mode 100755 index 7409239d01..0000000000 --- a/device/accton/x86_64-accton_as9726_32d-r0/plugins/eeprom.py +++ /dev/null @@ -1,13 +0,0 @@ -try: - from sonic_eeprom import eeprom_tlvinfo - -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class board(eeprom_tlvinfo.TlvInfoDecoder): - _TLV_INFO_MAX_LEN = 256 - - def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as9726_32d-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as9726_32d-r0/plugins/psuutil.py deleted file mode 100755 index 104fee28c8..0000000000 --- a/device/accton/x86_64-accton_as9726_32d-r0/plugins/psuutil.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# Accton -# -# Module contains an implementation of SONiC PSU Base API and -# provides the PSUs status which are available in the platform -# -############################################################################# - - -try: - from sonic_psu.psu_base import PsuBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class PsuUtil(PsuBase): - """Platform-specific PSUutil class""" - - def __init__(self): - PsuBase.__init__(self) - - self.psu_path = "/sys/bus/i2c/devices/" - self.psu_presence = "/psu_present" - self.psu_oper_status = "/psu_power_good" - self.psu_mapping = { - 1: "9-0050", - 2: "9-0051", - } - - def get_num_psus(self): - return len(self.psu_mapping) - - def get_psu_status(self, index): - if index is None: - return False - - status = 0 - node = self.psu_path + self.psu_mapping[index] + self.psu_oper_status - try: - with open(node, 'r') as power_status: - status = int(power_status.read()) - except IOError: - return False - - return status == 1 - - def get_psu_presence(self, index): - if index is None: - return False - - status = 0 - node = self.psu_path + self.psu_mapping[index] + self.psu_presence - try: - with open(node, 'r') as presence_status: - status = int(presence_status.read()) - except IOError: - return False - - return status == 1 diff --git a/device/accton/x86_64-accton_as9726_32d-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as9726_32d-r0/plugins/sfputil.py deleted file mode 100755 index 2a365815ca..0000000000 --- a/device/accton/x86_64-accton_as9726_32d-r0/plugins/sfputil.py +++ /dev/null @@ -1,293 +0,0 @@ -# sfputil.py -# -# Platform-specific SFP transceiver interface for SONiC -# - -try: - import time - from ctypes import create_string_buffer - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError as e: - raise ImportError("%s - required module not found" % str(e)) - - -class SfpUtil(SfpUtilBase): - """Platform-specific SfpUtil class""" - - PORT_START = 1 - QSFP_PORT_END = 32 - PORT_END = 34 - PORTS_IN_BLOCK = 34 - - BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" - BASE_CPLD2_PATH = "/sys/bus/i2c/devices/10-0061/" - BASE_CPLD3_PATH = "/sys/bus/i2c/devices/10-0062/" - - _port_to_is_present = {} - _port_to_lp_mode = {} - - _port_to_eeprom_mapping = {} - _port_to_i2c_mapping = { - 1: 17, - 2: 18, - 3: 19, - 4: 20, - 5: 21, - 6: 22, - 7: 23, - 8: 24, - 9: 25, - 10: 26, - 11: 27, - 12: 28, - 13: 29, - 14: 30, - 15: 31, - 16: 32, - 17: 33, - 18: 34, - 19: 35, - 20: 36, - 21: 37, - 22: 38, - 23: 39, - 24: 40, - 25: 41, - 26: 42, - 27: 43, - 28: 44, - 29: 45, - 30: 46, - 31: 47, - 32: 48, - 33: 49, - 34: 50, - } - - @property - def port_start(self): - return self.PORT_START - - @property - def port_end(self): - return self.PORT_END - - @property - def qsfp_ports(self): - return list(range(self.PORT_START, self.PORTS_IN_BLOCK - 1)) - - @property - def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping - - def __init__(self): - eeprom_path = self.BASE_OOM_PATH + "eeprom" - - for x in range(self.port_start, self.port_end+1): - self.port_to_eeprom_mapping[x] = eeprom_path.format( - self._port_to_i2c_mapping[x] - ) - - SfpUtilBase.__init__(self) - - def __write_txt_file(self, file_path, value): - try: - reg_file = open(file_path, "w") - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - - reg_file.write(str(value)) - reg_file.close() - - return True - - def get_presence(self, port_num): - if port_num <= 16: - present_path = self.BASE_CPLD2_PATH + "module_present_" + str(port_num) - else: - present_path = self.BASE_CPLD3_PATH + "module_present_" + str(port_num) - self.__port_to_is_present = present_path - - try: - val_file = open(present_path) - content = val_file.readline().rstrip() - val_file.close() - except IOError as e: - print("Error: unable to access file: %s" % str(e)) - return False - - if content == "1": - return True - - return False - - def get_low_power_mode(self, port_num): - if port_num > self.QSFP_PORT_END: #sfp not support lpmode - return False - try: - eeprom = None - - if not self.get_presence(port_num): - return False - - eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") - eeprom.seek(93) - lpmode = ord(eeprom.read(1)) - - if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 - else: - # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 - return False - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - finally: - if eeprom is not None: - eeprom.close() - time.sleep(0.01) - - def set_low_power_mode(self, port_num, lpmode): - # Check for invalid port_num - if port_num > self.QSFP_PORT_END: #sfp not support lpmode: - return False - - try: - eeprom = None - if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom - - # Fill in write buffer - # 0x3:Low Power Mode. "Power override" bit is 1 and "Power set" bit is 1 - # 0x9:High Power Mode. "Power override" bit is 1 ,"Power set" bit is 0 and "High Power Class Enable" bit is 1 - regval = 0x3 if lpmode else 0x9 - - buffer = create_string_buffer(1) - buffer[0] = regval - - # Write to eeprom - eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") - eeprom.seek(93) - eeprom.write(buffer[0]) - return True - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - finally: - if eeprom is not None: - eeprom.close() - time.sleep(0.01) - - def reset(self, port_num): - if port_num > self.QSFP_PORT_END: #sfp not support lpmode: - return False - if not self.get_presence(port_num): - return False # Port is not present, unable to set reset - - if port_num < 16: - mod_rst_path = self.BASE_CPLD2_PATH + "module_reset_" + str(port_num) - else: - mod_rst_path = self.BASE_CPLD3_PATH + "module_reset_" + str(port_num) - - self.__port_to_mod_rst = mod_rst_path - - ret = self.__write_txt_file(self.__port_to_mod_rst, 1) - if ret is not True: - return ret - - time.sleep(0.2) - ret = self.__write_txt_file(self.__port_to_mod_rst, 0) - time.sleep(0.2) - - return ret - - def get_cpld_interrupt(self): - port_dict = {} - for i in range(0, 4): - if i == 0 or i == 1: - cpld_i2c_path = self.BASE_CPLD2_PATH + "cpld_intr_" + str(i+1) - else: - cpld_i2c_path = self.BASE_CPLD3_PATH + "cpld_intr_" + str(i+1) - - start_i = (i*8) - end_i = (i*8+8) - try: - val_file = open(cpld_i2c_path) - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - - for k in range(start_i, end_i): - port_dict[k] = 0 - return port_dict - - status = val_file.readline().rstrip() - val_file.close() - status = status.strip() - status = int(status, 16) - - interrupt_status = ~(status & 0xff) - if interrupt_status: - port_shift = 0 - for k in range(start_i, end_i): - if interrupt_status & (0x1 << port_shift): - port_dict[k] = 1 - else: - port_dict[k] = 0 - port_shift = port_shift+1 - - return port_dict - - def get_transceiver_change_event(self, timeout=0): - start_time = time.time() - port_dict = {} - forever = False - - if timeout == 0: - forever = True - elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs - else: - print("get_transceiver_change_event:Invalid timeout value", timeout) - return False, {} - - end_time = start_time + timeout - if start_time > end_time: - print('get_transceiver_change_event:' - 'time wrap / invalid timeout value', timeout) - - return False, {} # Time wrap or possibly incorrect timeout - - # for i in range(self.port_start, self.port_end+1): - # ori_present[i]=self.get_presence(i) - - while timeout >= 0: - change_status = 0 - - port_dict = self.get_cpld_interrupt() - present = 0 - for key, value in port_dict.items(): - if value == 1: - present = self.get_presence(key) - change_status = 1 - if present: - port_dict[key] = '1' - else: - port_dict[key] = '0' - - if change_status: - return True, port_dict - if forever: - time.sleep(1) - else: - timeout = end_time - time.time() - if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity - else: - if timeout > 0: - time.sleep(timeout) - return True, {} - print("get_evt_change_event: Should not reach here.") - return False, {} diff --git a/device/accton/x86_64-accton_as9726_32d-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as9726_32d-r0/pmon_daemon_control.json index 584a14b9d9..44bad64942 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as9726_32d-r0/pmon_daemon_control.json @@ -1,5 +1,4 @@ { - "skip_ledd": true, - "skip_thermalctld": true + "skip_ledd": true } diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sensors.conf b/device/accton/x86_64-accton_as9726_32d-r0/sensors.conf new file mode 100644 index 0000000000..3537211dcd --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/sensors.conf @@ -0,0 +1,56 @@ +# libsensors configuration file for as9726-32d +# ------------------------------------------------ +# + +bus "i2c-14" "i2c-1-mux (chan_id 5)" +bus "i2c-9" "i2c-1-mux (chan_id 0)" +bus "i2c-15" "i2c-1-mux (chan_id 6)" + + +chip "ym2401-i2c-*-58" + label in3 "PSU 1 Voltage" + label fan1 "PSU 1 Fan" + label temp1 "PSU 1 Temperature" + label power2 "PSU 1 Power" + label curr2 "PSU 1 Current" + +chip "ym2401-i2c-*-59" + label in3 "PSU 2 Voltage" + label fan1 "PSU 2 Fan" + label temp1 "PSU 2 Temperature" + label power2 "PSU 2 Power" + label curr2 "PSU 2 Current" + + +chip "as9726_32d_fan-*" + label fan1 "Fan 1 Front" + label fan2 "Fan 2 Front" + label fan3 "Fan 3 Front" + label fan4 "Fan 4 Front" + label fan5 "Fan 5 Front" + label fan6 "Fan 6 Front" + label fan11 "Fan 1 Rear" + label fan12 "Fan 2 Rear" + label fan13 "Fan 3 Rear" + label fan14 "Fan 4 Rear" + label fan15 "Fan 5 Rear" + label fan16 "Fan 6 Rear" + + +chip "lm75-i2c-*-48" + label temp1 "MB_FrontMiddle_temp" + +chip "lm75-i2c-*-49" + label temp1 "MB_RightCenter_temp" + +chip "lm75-i2c-*-4a" + label temp1 "MB_LeftCenter_temp" + +chip "lm75-i2c-*-4b" + label temp1 "CB_temp" + +chip "lm75-i2c-*-4c" + label temp1 "OCXO_temp" + +chip "lm75-i2c-*-4f" + label temp1 "MB_RearRight_temp" diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/__init__.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/__init__.py index a18a2a2d2a..cbd0cd4831 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/__init__.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/__init__.py @@ -1,2 +1,2 @@ -__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp', 'thermal', 'fan'] +__all__ = [ "platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan", "fan_drawer" ] from . import platform diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py index b0a573432b..f4c34f9180 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py @@ -6,29 +6,28 @@ # ############################################################################# -import subprocess try: from sonic_platform_base.chassis_base import ChassisBase from .helper import APIHelper + from .event import SfpEvent except ImportError as e: raise ImportError(str(e) + "- required module not found") NUM_FAN_TRAY = 6 NUM_FAN = 2 NUM_PSU = 2 -NUM_THERMAL = 3 +NUM_THERMAL = 11 NUM_QSFP = 32 PORT_START = 1 PORT_END = 34 QSFP_PORT_START = 0 QSFP_PORT_END = 31 -NUM_COMPONENT = 2 +NUM_COMPONENT = 6 HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" -HOST_CHK_CMD = ["docker"] class Chassis(ChassisBase): @@ -62,11 +61,11 @@ def __initialize_sfp(self): self.sfp_module_initialized = True def __initialize_fan(self): - from sonic_platform.fan import Fan - for fant_index in range(0, NUM_FAN_TRAY): - for fan_index in range(0, NUM_FAN): - fan = Fan(fant_index, fan_index) - self._fan_list.append(fan) + from sonic_platform.fan_drawer import FanDrawer + for fant_index in range(NUM_FAN_TRAY): + fandrawer = FanDrawer(fant_index) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) def __initialize_psu(self): from sonic_platform.psu import Psu @@ -95,18 +94,6 @@ def __initialize_watchdog(self): self._watchdog = Watchdog() - def __is_host(self): - return subprocess.call(HOST_CHK_CMD) == 0 - - 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 get_name(self): """ Retrieves the name of the device @@ -114,7 +101,7 @@ def get_name(self): string: The name of the device """ - return self._api_helper.hwsku + return self._eeprom.get_modelstr() def get_presence(self): """ @@ -141,7 +128,15 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._eeprom.get_pn() + + def get_serial(self): """ Retrieves the hardware serial number for the chassis Returns: @@ -159,6 +154,9 @@ def get_system_eeprom_info(self): """ return self._eeprom.get_eeprom() + def get_revision(self): + return self._eeprom.get_revision() + def get_reboot_cause(self): """ Retrieves the cause of the previous reboot @@ -177,6 +175,15 @@ def get_reboot_cause(self): return ('REBOOT_CAUSE_NON_HARDWARE', sw_reboot_cause) + def get_change_event(self, timeout=0): + # SFP event + if not self.sfp_module_initialized: + self.__initialize_sfp() + + status, sfp_event = SfpEvent(self._sfp_list).get_sfp_event(timeout) + + return status, sfp_event + def get_sfp(self, index): """ Retrieves sfp represented by (1-based) index @@ -199,3 +206,29 @@ def get_sfp(self, index): sys.stderr.write("SFP index {} out of range (1-{})\n".format( index, len(self._sfp_list))) return sfp + + 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 initizalize_system_led(self): + return True + + def get_status_led(self): + return "ControlledByFPGA" + + def set_status_led(self, color): + return True diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/component.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/component.py index 8137d0f3a7..e89c09d210 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/component.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/component.py @@ -14,12 +14,20 @@ raise ImportError(str(e) + "- required module not found") CPLD_ADDR_MAPPING = { - "CPLD1": "3-0060" + "CPLD1": "1-0060", + "CPLD2": "10-0061", + "CPLD3": "10-0062", + "CPLD4": "14-0066", + "CPLD5": "1-0065" } SYSFS_PATH = "/sys/bus/i2c/devices/" BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" COMPONENT_LIST= [ ("CPLD1", "CPLD 1"), + ("CPLD2", "CPLD 2"), + ("CPLD3", "CPLD 3"), + ("CPLD4", "CPLD FAN"), + ("CPLD5", "CPLD CPU"), ("BIOS", "Basic Input/Output System") ] @@ -100,3 +108,55 @@ def install_firmware(self, image_path): A boolean, True if install successfully, False if not """ raise NotImplementedError + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return 'N/A' + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return 'N/A' + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + If the agent cannot determine the parent-relative position + for some reason, or if the associated value of + entPhysicalContainedIn is'0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device + or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/eeprom.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/eeprom.py index 7bf2bb58d1..ba3cb8ab61 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/eeprom.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/eeprom.py @@ -95,8 +95,17 @@ def _load_eeprom(self): def get_eeprom(self): return self._eeprom + def get_pn(self): + return self._eeprom.get('0x22', "Undefined.") + def get_serial(self): return self._eeprom.get('0x23', "Undefined.") def get_mac(self): return self._eeprom.get('0x24', "Undefined.") + + def get_revision(self): + return self._eeprom.get('0x27', "Undefined.") + + def get_modelstr(self): + return self._eeprom.get('0x21', "Undefined.") diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/event.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/event.py new file mode 100644 index 0000000000..a9ed318a51 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/event.py @@ -0,0 +1,108 @@ +try: + import time + from .helper import APIHelper + from sonic_py_common.logger import Logger + from .sfp import Sfp +except ImportError as e: + raise ImportError(repr(e) + " - required module not found") + +POLL_INTERVAL_IN_SEC = 1 + +# SFP errors that will block eeprom accessing +SFP_BLOCKING_ERRORS = [ + Sfp.SFP_ERROR_BIT_I2C_STUCK, + Sfp.SFP_ERROR_BIT_BAD_EEPROM, + Sfp.SFP_ERROR_BIT_UNSUPPORTED_CABLE, + Sfp.SFP_ERROR_BIT_HIGH_TEMP, + Sfp.SFP_ERROR_BIT_BAD_CABLE + ] + + +class SfpEvent: + ''' Listen to insert/remove sfp events ''' + + def __init__(self, sfp_list): + self._api_helper = APIHelper() + self._sfp_list = sfp_list + self._logger = Logger() + self._sfp_change_event_data = {'present': 0} + + def get_presence_bitmap(self): + bitmap = 0 + for sfp in self._sfp_list: + modpres = sfp.get_presence() + i=sfp.get_position_in_parent() - 1 + if modpres: + bitmap = bitmap | (1 << i) + return bitmap + + def get_sfp_event(self, timeout=2000): + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + + if timeout < 1000: + cd_ms = 1000 + else: + cd_ms = timeout + + while cd_ms > 0: + bitmap = self.get_presence_bitmap() + changed_ports = self._sfp_change_event_data['present'] ^ bitmap + if changed_ports != 0: + break + time.sleep(POLL_INTERVAL_IN_SEC) + # timeout=0 means wait for event forever + if timeout != 0: + cd_ms = cd_ms - POLL_INTERVAL_IN_SEC * 1000 + + if changed_ports != 0: + for sfp in self._sfp_list: + i=sfp.port_num-1 + if (changed_ports & (1 << i)): + if (bitmap & (1 << i)) == 0: + port_dict[i+1] = '0' + else: + port_dict[i+1] = '1' + + + # Update the cache dict + self._sfp_change_event_data['present'] = bitmap + return True, change_dict + else: + return True, change_dict + + def get_sfp_state_bits(self, sfp, present): + sfp_state_bits = 0 + + if present is True: + sfp_state_bits |= Sfp.SFP_STATUS_BIT_INSERTED + else: + return sfp_state_bits + + status = sfp.validate_eeprom() + if status is None: + sfp_state_bits |= Sfp.SFP_ERROR_BIT_I2C_STUCK + return sfp_state_bits + elif status is not True: + sfp_state_bits |= Sfp.SFP_ERROR_BIT_BAD_EEPROM + return sfp_state_bits + + status = sfp.validate_temperature() + if status is None: + sfp_state_bits |= Sfp.SFP_ERROR_BIT_I2C_STUCK + return sfp_state_bits + elif status is not True: + sfp_state_bits |= Sfp.SFP_ERROR_BIT_HIGH_TEMP + return sfp_state_bits + + return sfp_state_bits + + def check_sfp_blocking_errors(self, sfp_state_bits): + for i in SFP_BLOCKING_ERRORS: + if (i & sfp_state_bits) == 0: + continue + sfp_state_bits |= Sfp.SFP_ERROR_BIT_BLOCKING + + return sfp_state_bits + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/fan.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/fan.py index a42bdba3bd..e881a7489c 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/fan.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/fan.py @@ -13,10 +13,10 @@ raise ImportError(str(e) + "- required module not found") PSU_FAN_MAX_RPM = 26688 - -CPLD_I2C_PATH = "/sys/bus/i2c/devices/14-0066/fan_" -PSU_HWMON_I2C_PATH ="/sys/bus/i2c/devices/{}-00{}/" -PSU_I2C_MAPPING = { +SPEED_TOLERANCE = 15 +CPLD_FAN_I2C_PATH = "/sys/bus/i2c/devices/14-0066/fan" +I2C_PATH ="/sys/bus/i2c/devices/{}-00{}/" +PSU_HWMON_I2C_MAPPING = { 0: { "num": 9, "addr": "58" @@ -27,6 +27,20 @@ }, } +PSU_CPLD_I2C_MAPPING = { + 0: { + "num": 9, + "addr": "50" + }, + 1: { + "num": 9, + "addr": "51" + }, +} + +FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R", + "FAN-3F", "FAN-3R", "FAN-4F", "FAN-4R", + "FAN-5F", "FAN-5R", "FAN-6F", "FAN-6R"] class Fan(FanBase): """Platform-specific Fan class""" @@ -39,12 +53,17 @@ def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): if self.is_psu_fan: self.psu_index = psu_index - self.psu_i2c_num = PSU_I2C_MAPPING[self.psu_index]['num'] - self.psu_i2c_addr = PSU_I2C_MAPPING[self.psu_index]['addr'] - self.psu_hwmon_path = PSU_HWMON_I2C_PATH.format( + self.psu_i2c_num = PSU_HWMON_I2C_MAPPING[self.psu_index]['num'] + self.psu_i2c_addr = PSU_HWMON_I2C_MAPPING[self.psu_index]['addr'] + self.psu_hwmon_path = I2C_PATH.format( + self.psu_i2c_num, self.psu_i2c_addr) + + self.psu_i2c_num = PSU_CPLD_I2C_MAPPING[self.psu_index]['num'] + self.psu_i2c_addr = PSU_CPLD_I2C_MAPPING[self.psu_index]['addr'] + self.psu_cpld_path = I2C_PATH.format( self.psu_i2c_num, self.psu_i2c_addr) - FanBase.__init__(self) + FanBase.__init__(self) def get_direction(self): @@ -57,10 +76,10 @@ def get_direction(self): if not self.is_psu_fan: - dir_str = "{}{}{}".format(CPLD_I2C_PATH, 'direction_', self.fan_tray_index) + dir_str = "{}{}{}".format(CPLD_FAN_I2C_PATH, self.fan_tray_index+1, '_direction') val=self._api_helper.read_txt_file(dir_str) if val is not None: - if val==0:#F2B + if int(val, 10)==0:#F2B direction=self.FAN_DIRECTION_EXHAUST else: direction=self.FAN_DIRECTION_INTAKE @@ -86,20 +105,20 @@ def get_speed(self): Returns: An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) - + """ speed = 0 if self.is_psu_fan: psu_fan_path= "{}{}".format(self.psu_hwmon_path, 'psu_fan1_speed_rpm') fan_speed_rpm = self._api_helper.read_txt_file(psu_fan_path) if fan_speed_rpm is not None: - speed = (int(fan_speed_rpm,10))*100/26688 + speed = (int(fan_speed_rpm,10))*100/PSU_FAN_MAX_RPM if speed > 100: speed=100 else: return 0 - elif self.get_presence(): - speed_path = "{}{}".format(CPLD_I2C_PATH, 'duty_cycle_percentage') + elif self.get_presence(): + speed_path = "{}{}".format(CPLD_FAN_I2C_PATH, '_duty_cycle_percentage') speed=self._api_helper.read_txt_file(speed_path) if speed is None: return 0 @@ -116,7 +135,7 @@ def get_target_speed(self): 0 : when PWM mode is use pwm : when pwm mode is not use """ - return False #Not supported + return self.get_speed() def get_speed_tolerance(self): """ @@ -125,7 +144,7 @@ def get_speed_tolerance(self): An integer, the percentage of variance from target speed which is considered tolerable """ - return False #Not supported + return SPEED_TOLERANCE def set_speed(self, speed): """ @@ -137,8 +156,8 @@ def set_speed(self, speed): A boolean, True if speed is set successfully, False if not """ - if not self.is_psu_fan and self.get_presence(): - speed_path = "{}{}".format(CPLD_I2C_PATH, 'duty_cycle_percentage') + if not self.is_psu_fan and self.get_presence(): + speed_path = "{}{}".format(CPLD_FAN_I2C_PATH, '_duty_cycle_percentage') return self._api_helper.write_txt_file(speed_path, int(speed)) return False @@ -154,18 +173,116 @@ def set_status_led(self, color): """ return False #Not supported + 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 + """ + status=self.get_status() + if status is None: + return self.STATUS_LED_COLOR_OFF + + return { + True: self.STATUS_LED_COLOR_GREEN, + False: self.STATUS_LED_COLOR_RED + }.get(status, self.STATUS_LED_COLOR_OFF) + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] \ + if not self.is_psu_fan \ + else "PSU-{} FAN-{}".format(self.psu_index+1, self.fan_index+1) + + return fan_name + def get_presence(self): """ Retrieves the presence of the FAN Returns: bool: True if FAN is present, False if not """ - present_path = "{}{}{}".format(CPLD_I2C_PATH, 'present_', self.fan_index+1) - val=self._api_helper.read_txt_file(present_path) if not self.is_psu_fan: + present_path = "{}{}{}".format(CPLD_FAN_I2C_PATH, self.fan_tray_index+1, '_present') + val=self._api_helper.read_txt_file(present_path) if val is not None: return int(val, 10)==1 else: return False else: - return True + present_path= "{}{}".format(self.psu_cpld_path, 'psu_present') + val=self._api_helper.read_txt_file(present_path) + if val is not None: + return int(val, 10)==1 + else: + return False + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + if self.is_psu_fan: + psu_path = "{}{}".format(self.psu_cpld_path, 'psu_power_good') + val = self._api_helper.read_txt_file(psu_path) + if val is None or int(val, 10)==0: + return False + + psu_path = "{}{}".format(self.psu_hwmon_path, 'psu_fan1_fault') + val = self._api_helper.read_txt_file(psu_path) + if val is not None: + return int(val, 10)==0 + else: + return False + else: + path = "{}{}{}".format(CPLD_FAN_I2C_PATH, self.fan_tray_index+1, '_fault') + val=self._api_helper.read_txt_file(path) + if val is not None: + return int(val, 10)==0 + else: + return False + + + 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_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_index+1) \ + if not self.is_psu_fan else (self.psu_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 + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/fan_drawer.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/fan_drawer.py new file mode 100644 index 0000000000..e21163c106 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/fan_drawer.py @@ -0,0 +1,90 @@ +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides 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") + +FANS_PER_FANTRAY = 2 + + +class FanDrawer(FanDrawerBase): + """Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 0-based in platforms + self.fantrayindex = fantray_index + self.__initialize_fan_drawer() + + + def __initialize_fan_drawer(self): + from sonic_platform.fan import Fan + for i in range(FANS_PER_FANTRAY): + self._fan_list.append(Fan(self.fantrayindex, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex+1) + + 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. + 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.fantrayindex+1) + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/helper.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/helper.py index 2c644ecbfb..b7debbe8cd 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/helper.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/helper.py @@ -1,8 +1,14 @@ import os import struct -import subprocess +import json +import fcntl from mmap import * from sonic_py_common import device_info +from sonic_py_common import logger +from threading import Lock +from typing import cast +from sonic_py_common.general import getstatusoutput_noshell +from sonic_py_common.general import getstatusoutput_noshell_pipe HOST_CHK_CMD = ["docker"] EMPTY_STRING = "" @@ -14,7 +20,11 @@ def __init__(self): (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() def is_host(self): - return subprocess.call(HOST_CHK_CMD) == 0 + try: + status, output = getstatusoutput_noshell(HOST_CHK_CMD) + return status == 0 + except Exception: + return False def pci_get_value(self, resource, offset): status = True @@ -31,9 +41,11 @@ def pci_get_value(self, resource, offset): def read_txt_file(self, file_path): try: - with open(file_path, 'r') as fd: + with open(file_path, 'r', errors='replace') as fd: data = fd.read() - return data.strip() + ret = data.strip() + if len(ret) > 0: + return ret except IOError: pass return None @@ -45,4 +57,264 @@ def write_txt_file(self, file_path, value): except IOError: return False return True +class FileLock: + + def __init__(self, lock_file): + self._lock_file = lock_file + self._thread_lock = Lock() + self.is_locked = False + + def acquire(self): + with self._thread_lock: + if self.is_locked: + return + + fd = os.open(self._lock_file, flags=(os.O_RDWR | os.O_CREAT | os.O_TRUNC)) + fcntl.flock(fd, fcntl.LOCK_EX) + self._lock_file_fd = fd + self.is_locked = True + + def release(self): + with self._thread_lock: + if self.is_locked: + fd = cast(int, self._lock_file_fd) + self._lock_file_fd = None + fcntl.flock(fd, fcntl.LOCK_UN) + os.close(fd) + self.is_locked = False + + def __enter__(self): + self.acquire() + return self + + def __exit__(self, exc_type, exc_val, traceback): + self.release() + + def __del__(self): + self.release() + + + +DEVICE_THRESHOLD_JSON_PATH = "/tmp/device_threshold.json" +HIGH_THRESHOLD_FIELD = 'high_threshold' +LOW_THRESHOLD_FIELD = 'low_threshold' +HIGH_CRIT_THRESHOLD_FIELD = 'high_critical_threshold' +LOW_CRIT_THRESHOLD_FIELD = 'low_critical_threshold' +NOT_AVAILABLE = 'N/A' + +class DeviceThreshold: + + def __init__(self, th_name = NOT_AVAILABLE): + self.flock = FileLock("{}.lock".format(DEVICE_THRESHOLD_JSON_PATH)) + self.name = th_name + self.__log = logger.Logger(log_identifier="DeviceThreshold") + + self.__db_data = {} + try: + with self.flock: + with open(DEVICE_THRESHOLD_JSON_PATH, "r") as db_file: + self.__db_data = json.load(db_file) + except Exception as e: + self.__log.log_warning('{}'.format(str(e))) + + @property + def HIGH_THRESHOLD_FIELD(self): + return HIGH_THRESHOLD_FIELD + + @property + def LOW_THRESHOLD_FIELD(self): + return LOW_THRESHOLD_FIELD + + @property + def HIGH_CRIT_THRESHOLD_FIELD(self): + return HIGH_CRIT_THRESHOLD_FIELD + + @property + def LOW_CRIT_THRESHOLD_FIELD(self): + return LOW_CRIT_THRESHOLD_FIELD + + @property + def NOT_AVAILABLE(self): + return NOT_AVAILABLE + + def __get_data(self, field): + """ + Retrieves data frome JSON file by field + + Args : + field: String + + Returns: + A string if getting is successfully, 'N/A' if not + """ + if self.name not in self.__db_data.keys(): + return NOT_AVAILABLE + + if field not in self.__db_data[self.name].keys(): + return NOT_AVAILABLE + + return self.__db_data[self.name][field] + + def __set_data(self, field, new_val): + """ + Set data to JSON file by field + + Args : + field: String + new_val: String + + Returns: + A boolean, True if setting is set successfully, False if not + """ + if self.name not in self.__db_data.keys(): + self.__db_data[self.name] = {} + + old_val = self.__db_data[self.name].get(field, None) + if old_val is not None and old_val == new_val: + return True + + self.__db_data[self.name][field] = new_val + + try: + with self.flock: + db_data = {} + mode = "w+" + if os.path.exists(DEVICE_THRESHOLD_JSON_PATH): + mode = "r+" + with open(DEVICE_THRESHOLD_JSON_PATH, mode) as db_file: + if mode == "r+": + db_data = json.load(db_file) + + if self.name not in db_data.keys(): + db_data[self.name] = {} + + db_data[self.name][field] = new_val + + if mode == "r+": + db_file.seek(0) + # erase old data + db_file.truncate(0) + # write all data + json.dump(db_data, db_file, indent=4) + except Exception as e: + self.__log.log_error('{}'.format(str(e))) + return False + + return True + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature from JSON file. + + Returns: + string : the high threshold temperature of thermal, + e.g. "30.125" + """ + return self.__get_data(HIGH_THRESHOLD_FIELD) + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + Args : + temperature: A string of temperature, e.g. "30.125" + Returns: + A boolean, True if threshold is set successfully, False if not + """ + if isinstance(temperature, str) is not True: + raise TypeError('The parameter requires string type.') + + try: + if temperature != NOT_AVAILABLE: + float(temperature) + except ValueError: + raise ValueError('The parameter requires a float string. ex:\"30.1\"') + + return self.__set_data(HIGH_THRESHOLD_FIELD, temperature) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature from JSON file. + + Returns: + string : the low threshold temperature of thermal, + e.g. "30.125" + """ + return self.__get_data(LOW_THRESHOLD_FIELD) + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + Args : + temperature: A string of temperature, e.g. "30.125" + Returns: + A boolean, True if threshold is set successfully, False if not + """ + if isinstance(temperature, str) is not True: + raise TypeError('The parameter requires string type.') + + try: + if temperature != NOT_AVAILABLE: + float(temperature) + except ValueError: + raise ValueError('The parameter requires a float string. ex:\"30.1\"') + + return self.__set_data(LOW_THRESHOLD_FIELD, temperature) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature from JSON file. + + Returns: + string : the high critical threshold temperature of thermal, + e.g. "30.125" + """ + return self.__get_data(HIGH_CRIT_THRESHOLD_FIELD) + + def set_high_critical_threshold(self, temperature): + """ + Sets the high critical threshold temperature of thermal + Args : + temperature: A string of temperature, e.g. "30.125" + Returns: + A boolean, True if threshold is set successfully, False if not + """ + if isinstance(temperature, str) is not True: + raise TypeError('The parameter requires string type.') + + try: + if temperature != NOT_AVAILABLE: + float(temperature) + except ValueError: + raise ValueError('The parameter requires a float string. ex:\"30.1\"') + + return self.__set_data(HIGH_CRIT_THRESHOLD_FIELD, temperature) + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature from JSON file. + + Returns: + string : the low critical threshold temperature of thermal, + e.g. "30.125" + """ + return self.__get_data(LOW_CRIT_THRESHOLD_FIELD) + + def set_low_critical_threshold(self, temperature): + """ + Sets the low critical threshold temperature of thermal + Args : + temperature: A string of temperature, e.g. "30.125" + Returns: + A boolean, True if threshold is set successfully, False if not + """ + if isinstance(temperature, str) is not True: + raise TypeError('The parameter requires string type.') + + try: + if temperature != NOT_AVAILABLE: + float(temperature) + except ValueError: + raise ValueError('The parameter requires a float string. ex:\"30.1\"') + + return self.__set_data(LOW_CRIT_THRESHOLD_FIELD, temperature) diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/pcie.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/pcie.py new file mode 100644 index 0000000000..2de810998f --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/pcie.py @@ -0,0 +1,20 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# Base PCIe class +############################################################################# + +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Pcie(PcieUtil): + """Edgecore Platform-specific PCIe class""" + + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/psu.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/psu.py index 0ccd83faf5..448d8c363c 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/psu.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/psu.py @@ -8,7 +8,7 @@ try: from sonic_platform_base.psu_base import PsuBase - #from sonic_platform.fan import Fan + from sonic_platform.thermal import Thermal from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -56,13 +56,6 @@ def __init__(self, psu_index=0): self.i2c_addr = PSU_CPLD_I2C_MAPPING[self.index]["addr"] self.cpld_path = I2C_PATH.format(self.i2c_num, self.i2c_addr) self.__initialize_fan() - ''' - for fan_index in range(0, PSU_NUM_FAN[self.index]): - #def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): - #fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) - fan = Fan(fan_index, 0, True, self.index) - self._fan_list.append(fan) - ''' def __initialize_fan(self): from sonic_platform.fan import Fan @@ -70,6 +63,8 @@ def __initialize_fan(self): fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) self._fan_list.append(fan) + self._thermal_list.append(Thermal(is_psu=True, psu_index=self.index)) + def get_voltage(self): """ Retrieves current PSU voltage output @@ -77,12 +72,15 @@ def get_voltage(self): A float number, the output voltage in volts, e.g. 12.1 """ + if self.get_status() is not True: + return 0.0 + vout_path = "{}{}".format(self.hwmon_path, 'psu_v_out') vout_val=self._api_helper.read_txt_file(vout_path) if vout_val is not None: return float(vout_val)/ 1000 else: - return 0 + return 0.0 def get_current(self): """ @@ -90,12 +88,15 @@ def get_current(self): Returns: A float number, the electric current in amperes, e.g 15.4 """ + if self.get_status() is not True: + return 0.0 + iout_path = "{}{}".format(self.hwmon_path, 'psu_i_out') val=self._api_helper.read_txt_file(iout_path) if val is not None: return float(val)/1000 else: - return 0 + return 0.0 def get_power(self): """ @@ -103,12 +104,15 @@ def get_power(self): Returns: A float number, the power in watts, e.g. 302.6 """ + if self.get_status() is not True: + return 0.0 + pout_path = "{}{}".format(self.hwmon_path, 'psu_p_out') val=self._api_helper.read_txt_file(pout_path) if val is not None: return float(val)/1000 else: - return 0 + return 0.0 def get_powergood_status(self): """ @@ -137,8 +141,16 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings above """ + status_ps=self.get_presence() #present + status=self.get_status() #power good - return False #Controlled by HW + if status is None or status_ps is False: + return self.STATUS_LED_COLOR_OFF + + return { + 1: self.STATUS_LED_COLOR_GREEN, + 0: self.STATUS_LED_COLOR_AMBER + }.get(status, self.STATUS_LED_COLOR_OFF) def get_temperature(self): """ @@ -147,12 +159,15 @@ def get_temperature(self): A float number of current temperature in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ + if self.get_status() is not True: + return 0.0 + temp_path = "{}{}".format(self.hwmon_path, 'psu_temp1_input') val=self._api_helper.read_txt_file(temp_path) if val is not None: return float(val)/1000 else: - return 0 + return 0.0 def get_temperature_high_threshold(self): """ @@ -161,7 +176,7 @@ def get_temperature_high_threshold(self): A float number, the high threshold temperature of PSU in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - return False #Not supported + return self._thermal_list[0].get_high_threshold() #Not supported def get_voltage_high_threshold(self): """ @@ -170,12 +185,15 @@ def get_voltage_high_threshold(self): A float number, the high threshold output voltage in volts, e.g. 12.1 """ + if self.get_status() is not True: + return 0.0 + vout_path = "{}{}".format(self.hwmon_path, 'psu_mfr_vout_max') vout_val=self._api_helper.read_txt_file(vout_path) if vout_val is not None: return float(vout_val)/ 1000 else: - return 0 + return 0.0 def get_voltage_low_threshold(self): """ @@ -184,12 +202,15 @@ def get_voltage_low_threshold(self): A float number, the low threshold output voltage in volts, e.g. 12.1 """ + if self.get_status() is not True: + return 0.0 + vout_path = "{}{}".format(self.hwmon_path, 'psu_mfr_vout_min') vout_val=self._api_helper.read_txt_file(vout_path) if vout_val is not None: return float(vout_val)/ 1000 else: - return 0 + return 0.0 def get_name(self): """ @@ -210,7 +231,7 @@ def get_presence(self): if val is not None: return int(val, 10) == 1 else: - return 0 + return False def get_status(self): """ @@ -223,4 +244,68 @@ def get_status(self): if val is not None: return int(val, 10) == 1 else: - return 0 + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model_path="{}{}".format(self.cpld_path, 'psu_model_name') + model=self._api_helper.read_txt_file(model_path) + + if model is None: + return "N/A" + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + serial_path="{}{}".format(self.cpld_path, 'psu_serial_number') + serial=self._api_helper.read_txt_file(serial_path) + + if serial is None: + return "N/A" + return serial + + def get_revision(self): + rev_path="{}{}".format(self.hwmon_path, 'psu_mfr_revision') + rev=self._api_helper.read_txt_file(rev_path) + if rev is None: + return "N/A" + return rev + + + 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.index+1 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_maximum_supplied_power(self): + if self.get_status() is not True: + return 0.0 + + pout_path = "{}{}".format(self.hwmon_path, 'psu_mfr_pout_max') + pout_val=self._api_helper.read_txt_file(pout_path) + if pout_val is not None: + return float(pout_val)/ 1000 + else: + return 0.0 + + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/sfp.py index 5d7c03d005..c6f60be996 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/sfp.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/sfp.py @@ -9,18 +9,13 @@ import sys import time import struct -import subprocess +import natsort + from ctypes import create_string_buffer try: - from sonic_platform_base.sfp_base import SfpBase - from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId - from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom - 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 sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_InterfaceId - from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_Dom + from sonic_py_common.logger import Logger + from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper from .helper import APIHelper except ImportError as e: @@ -30,250 +25,31 @@ CPLD2_I2C_PATH = "/sys/bus/i2c/devices/10-0061/" CPLD3_I2C_PATH = "/sys/bus/i2c/devices/10-0062/" -# definitions of the offset and width for values in XCVR info eeprom -XCVR_INTFACE_BULK_OFFSET = 0 -XCVR_INTFACE_BULK_WIDTH_QSFP = 20 -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_WIDTH = 16 -XCVR_VENDOR_OUI_OFFSET = 37 -XCVR_VENDOR_OUI_WIDTH = 3 -XCVR_VENDOR_PN_OFFSET = 40 -XCVR_VENDOR_PN_WIDTH = 16 -XCVR_HW_REV_OFFSET = 56 -XCVR_HW_REV_WIDTH_OSFP = 2 -XCVR_HW_REV_WIDTH_QSFP = 2 -XCVR_HW_REV_WIDTH_SFP = 4 -XCVR_EXT_SPECIFICATION_COMPLIANCE_OFFSET = 64 -XCVR_EXT_SPECIFICATION_COMPLIANCE_WIDTH = 1 -XCVR_VENDOR_SN_OFFSET = 68 -XCVR_VENDOR_SN_WIDTH = 16 -XCVR_VENDOR_DATE_OFFSET = 84 -XCVR_VENDOR_DATE_WIDTH = 8 -XCVR_DOM_CAPABILITY_OFFSET = 92 -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 -QSFP_DD_DOM_BULK_DATA_START = 14 -QSFP_DD_DOM_BULK_DATA_SIZE = 4 - -# 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 - -# definitions of the offset for values in QSFP_DD info eeprom -QSFP_DD_TYPE_OFFSET = 0 -QSFP_DD_VENDOR_NAME_OFFSET = 1 -QSFP_DD_VENDOR_PN_OFFSET = 20 -QSFP_DD_VENDOR_SN_OFFSET = 38 -QSFP_DD_VENDOR_OUI_OFFSET = 17 - -# definitions of the offset and width for values in XCVR_QSFP_DD info eeprom -XCVR_EXT_TYPE_OFFSET_QSFP_DD = 72 -XCVR_EXT_TYPE_WIDTH_QSFP_DD = 2 -XCVR_CONNECTOR_OFFSET_QSFP_DD = 75 -XCVR_CONNECTOR_WIDTH_QSFP_DD = 1 -XCVR_CABLE_LENGTH_OFFSET_QSFP_DD = 74 -XCVR_CABLE_LENGTH_WIDTH_QSFP_DD = 1 -XCVR_HW_REV_OFFSET_QSFP_DD = 36 -XCVR_HW_REV_WIDTH_QSFP_DD = 2 -XCVR_VENDOR_DATE_OFFSET_QSFP_DD = 54 -XCVR_VENDOR_DATE_WIDTH_QSFP_DD = 8 -XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD = 2 -XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD = 1 -XCVR_MEDIA_TYPE_OFFSET_QSFP_DD = 85 -XCVR_MEDIA_TYPE_WIDTH_QSFP_DD = 1 -XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD = 86 -XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD = 32 -XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD = 351 -XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD = 28 - -# 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_CONTROL_OFFSET = 86 + 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 - -SFP_TEMPE_OFFSET = 96 -SFP_TEMPE_WIDTH = 2 -SFP_VOLT_OFFSET = 98 -SFP_VOLT_WIDTH = 2 -SFP_CHANNL_MON_OFFSET = 100 -SFP_CHANNL_MON_WIDTH = 6 -SFP_CHANNL_STATUS_OFFSET = 110 -SFP_CHANNL_STATUS_WIDTH = 1 - -QSFP_DD_TEMPE_OFFSET = 14 -QSFP_DD_TEMPE_WIDTH = 2 -QSFP_DD_VOLT_OFFSET = 16 -QSFP_DD_VOLT_WIDTH = 2 -QSFP_DD_TX_BIAS_OFFSET = 42 -QSFP_DD_TX_BIAS_WIDTH = 16 -QSFP_DD_RX_POWER_OFFSET = 58 -QSFP_DD_RX_POWER_WIDTH = 16 -QSFP_DD_TX_POWER_OFFSET = 26 -QSFP_DD_TX_POWER_WIDTH = 16 -QSFP_DD_CHANNL_MON_OFFSET = 154 -QSFP_DD_CHANNL_MON_WIDTH = 48 -QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET = 86 -QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH = 1 -QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET = 19 -QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH = 1 -QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET = 7 -QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH = 1 -QSFP_DD_MODULE_THRESHOLD_OFFSET = 0 -QSFP_DD_MODULE_THRESHOLD_WIDTH = 72 -QSFP_DD_CHANNL_STATUS_OFFSET = 26 -QSFP_DD_CHANNL_STATUS_WIDTH = 1 - - -sfp_cable_length_tup = ( - 'LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', - 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', - 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)' -) - -sfp_compliance_code_tup = ( - '10GEthernetComplianceCode', 'InfinibandComplianceCode', - 'ESCONComplianceCodes', 'SONETComplianceCodes', - 'EthernetComplianceCodes', 'FibreChannelLinkLength', - 'FibreChannelTechnology', 'SFP+CableTechnology', - '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' -) - -info_dict_keys = [ - 'type', 'vendor_rev', 'serial', 'manufacturer', - 'model', 'connector', 'encoding', 'ext_identifier', - 'ext_rateselect_compliance', 'cable_type', 'cable_length', - 'nominal_bit_rate', 'specification_compliance', 'vendor_date', - 'vendor_oui', 'application_advertisement', 'type_abbrv_name' -] - -qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', - 'Length OM2(m)', 'Length OM1(m)', - 'Length Cable Assembly(m)') - -dom_info_dict_keys = [ - 'rx_los', 'tx_fault', 'reset_status', 'lp_mode', - 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', - 'rx1power', 'rx2power', 'rx3power', 'rx4power', - 'rx5power', 'rx6power', 'rx7power', 'rx8power', - 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', - 'tx5bias', 'tx6bias', 'tx7bias', 'tx8bias', - 'tx1power', 'tx2power', 'tx3power', 'tx4power', - 'tx5power', 'tx6power', 'tx7power', 'tx8power'] - -threshold_dict_keys = [ - 'temphighalarm', 'temphighwarning', - 'templowalarm', 'templowwarning', - 'vcchighalarm', 'vcchighwarning', - 'vcclowalarm', 'vcclowwarning', - 'rxpowerhighalarm', 'rxpowerhighwarning', - 'rxpowerlowalarm', 'rxpowerlowwarning', - 'txpowerhighalarm', 'txpowerhighwarning', - 'txpowerlowalarm', 'txpowerlowwarning', - 'txbiashighalarm', 'txbiashighwarning', - 'txbiaslowalarm', 'txbiaslowwarning'] - -SFP_TYPE_CODE_LIST = [ - '03' # SFP/SFP+/SFP28 -] -QSFP_TYPE_CODE_LIST = [ - '0d', # QSFP+ or later - '11' # QSFP28 or later -] -QSFP_DD_TYPE_CODE_LIST = [ - '18' # QSFP-DD Double Density 8X Pluggable Transceiver -] - -SFP_TYPE = "SFP" -QSFP_TYPE = "QSFP" -OSFP_TYPE = "OSFP" -QSFP_DD_TYPE = "QSFP_DD" NULL_VAL = 'N/A' -PORT_START = 1 -PORT_END = 34 -QSFP_PORT_START = 1 -QSFP_PORT_END = 32 SFP_I2C_START = 17 I2C_EEPROM_PATH = '/sys/bus/i2c/devices/{0}-0050/eeprom' +OPTOE_DEV_CLASS_PATH = '/sys/bus/i2c/devices/{0}-0050/dev_class' - -class Sfp(SfpBase): +logger = Logger() +class Sfp(SfpOptoeBase): """Platform-specific Sfp class""" - HOST_CHK_CMD = ["docker"] + HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" PLATFORM = "x86_64-accton_as9726_32d-r0" HWSKU = "Accton-AS9726-32D" + PORT_START = 1 + PORT_END = 34 + QSFP_PORT_START = 1 + QSFP_PORT_END = 32 # Path to sysfs PLATFORM_ROOT_PATH = "/usr/share/sonic/device" @@ -285,22 +61,54 @@ class Sfp(SfpBase): CPLD3_PORT_END = 32 PRS_PATH = "/sys/devices/platform/dx010_cpld/qsfp_modprs" + SFP_TYPE_CODE_LIST = [ + 0x03, # SFP/SFP+/SFP28 + 0x0b # DWDM-SFP/SFP+ + ] + QSFP_TYPE_CODE_LIST = [ + 0x0c, # QSFP + 0x0d, # QSFP+ or later + 0x11, # QSFP28 or later + 0xe1 # QSFP28 EDFA + ] + QSFP_DD_TYPE_CODE_LIST = [ + 0x18, # QSFP-DD Double Density 8X Pluggable Transceiver + 0x1E # QSFP+ or later with CMIS + ] + OSFP_TYPE_CODE_LIST = [ + 0x19 # OSFP + ] + + SFP_TYPE = "SFP" + QSFP_TYPE = "QSFP" + OSFP_TYPE = "OSFP" + QSFP_DD_TYPE = "QSFP_DD" + + UPDATE_DONE = "Done" + EEPROM_DATA_NOT_READY = "eeprom not ready" + UNKNOWN_SFP_TYPE_ID = "unknow sfp ID" + + # Path to sysfs + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + def __init__(self, sfp_index=0, sfp_name=None): + SfpOptoeBase.__init__(self) - self._index = sfp_index - self._port_num = self._index + 1 + self.port_num = sfp_index + 1 + self.index = self.port_num self._api_helper = APIHelper() self._name = sfp_name - self._dom_capability_detect() - self._eeprom_path = self._get_eeprom_path() - SfpBase.__init__(self) + self.sfp_type = self.QSFP_TYPE + self.update_sfp_type() + self.refresh_optoe_dev_class() def __write_txt_file(self, file_path, value): try: reg_file = open(file_path, "w") except IOError as e: - print("Error: unable to open file: %s" % str(e)) + logger.log_error("Error: unable to open file: %s" % str(e)) return False reg_file.write(str(value)) @@ -308,13 +116,11 @@ def __write_txt_file(self, file_path, value): return True - def __is_host(self): - return subprocess.call(self.HOST_CHK_CMD) == 0 def __get_path_to_port_config_file(self): platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) hwsku_path = "/".join([platform_path, self.HWSKU] - ) if self.__is_host() else self.PMON_HWSKU_PATH + ) if self._api_helper.is_host() else self.PMON_HWSKU_PATH return "/".join([hwsku_path, "port_config.ini"]) def _convert_string_to_num(self, value_str): @@ -337,964 +143,42 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' - def _read_eeprom_specific_bytes(self, offset, num_bytes): - sysfs_sfp_i2c_client_eeprom_path = self._get_eeprom_path() - eeprom_raw = [] - try: - eeprom = open( - sysfs_sfp_i2c_client_eeprom_path, - mode="rb", buffering=0) - except IOError: - return None - - for i in range(0, num_bytes): - eeprom_raw.append("0x00") - - try: - eeprom.seek(offset) - raw = eeprom.read(num_bytes) - except IOError: - eeprom.close() - return None - - try: - if isinstance(raw, str): - for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) - else: - for n in range(0, num_bytes): - eeprom_raw[n] = hex(raw[n])[2:].zfill(2) - - except BaseException: - eeprom.close() - return None - - eeprom.close() - return eeprom_raw - - def _detect_sfp_type(self): - sfp_type = QSFP_TYPE - eeprom_raw = [] - eeprom_raw = self._read_eeprom_specific_bytes( - XCVR_TYPE_OFFSET, XCVR_TYPE_WIDTH) - if eeprom_raw: - if eeprom_raw[0] in SFP_TYPE_CODE_LIST: - self.sfp_type = SFP_TYPE - elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST: - self.sfp_type = QSFP_TYPE - elif eeprom_raw[0] in QSFP_DD_TYPE_CODE_LIST: - self.sfp_type = QSFP_DD_TYPE - else: - self.sfp_type = sfp_type - else: - self.sfp_type = sfp_type - - def _get_eeprom_path(self): - port_to_i2c_mapping = SFP_I2C_START + self._index + def get_eeprom_path(self): + port_to_i2c_mapping = SFP_I2C_START + (self.index - 1) port_eeprom_path = I2C_EEPROM_PATH.format(port_to_i2c_mapping) return port_eeprom_path - def _dom_capability_detect(self): - self._detect_sfp_type() - - 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_TYPE: - 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 == QSFP_DD_TYPE: - sfpi_obj = qsfp_dd_InterfaceId() - if sfpi_obj is None: - self.dom_supported = False - - offset = 0 - # two types of QSFP-DD cable types supported: Copper and Optical. - qsfp_dom_capability_raw = self._read_eeprom_specific_bytes( - (offset + XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD), XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD) - if qsfp_dom_capability_raw is not None: - self.dom_temp_supported = True - self.dom_volt_supported = True - dom_capability = sfpi_obj.parse_dom_capability( - qsfp_dom_capability_raw, 0) - if dom_capability['data']['Flat_MEM']['value'] == 'Off': - self.dom_supported = True - self.second_application_list = True - self.dom_rx_power_supported = True - self.dom_tx_power_supported = True - self.dom_tx_bias_power_supported = True - self.dom_thresholds_supported = True - # currently set to False becasue Page 11h is not supported by FW - self.dom_rx_tx_power_bias_supported = False + def refresh_optoe_dev_class(self): + if self.get_presence(): + for retry in range(5): + ret = self.update_sfp_type() + if ret == self.EEPROM_DATA_NOT_READY: + time.sleep(1) else: - self.dom_supported = False - self.second_application_list = False - self.dom_rx_power_supported = False - self.dom_tx_power_supported = False - self.dom_tx_bias_power_supported = False - self.dom_thresholds_supported = False - self.dom_rx_tx_power_bias_supported = False - 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.dom_tx_bias_power_supported = False - self.dom_thresholds_supported = False - self.dom_rx_tx_power_bias_supported = False - - elif self.sfp_type == SFP_TYPE: - 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): - """ - Retrieves transceiver info of this SFP - Returns: - A dict which contains following keys/values : - ================================================================================ - keys |Value Format |Information - ---------------------------|---------------|---------------------------- - type |1*255VCHAR |type of SFP - vendor_rev |1*255VCHAR |vendor revision of SFP - serial |1*255VCHAR |serial number of the SFP - manufacturer |1*255VCHAR |SFP vendor name - model |1*255VCHAR |SFP model name - connector |1*255VCHAR |connector information - encoding |1*255VCHAR |encoding information - ext_identifier |1*255VCHAR |extend identifier - ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance - cable_length |INT |cable length in m - nominal_bit_rate |INT |nominal bit rate by 100Mbs - specification_compliance |1*255VCHAR |specification compliance - vendor_date |1*255VCHAR |vendor date - vendor_oui |1*255VCHAR |vendor OUI - application_advertisement |1*255VCHAR |supported applications advertisement - ================================================================================ - """ - - transceiver_info_dict = {} - compliance_code_dict = {} - transceiver_info_dict = dict.fromkeys( - info_dict_keys, NULL_VAL) - transceiver_info_dict["specification_compliance"] = '{}' - - # 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 - - sfpi_obj = inf8628InterfaceId() - if sfpi_obj is None: - return transceiver_info_dict - - 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 transceiver_info_dict - - sfp_vendor_name_raw = self._read_eeprom_specific_bytes( - (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_raw, 0) - else: - return transceiver_info_dict - - sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( - (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_raw, 0) - else: - return transceiver_info_dict - - sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( - (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_raw, 0) - else: - return transceiver_info_dict - - sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( - (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_raw, 0) - else: - return transceiver_info_dict - - transceiver_info_dict['type'] = sfp_type_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['vendor_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] - - elif self.sfp_type == QSFP_TYPE: - offset = 128 - vendor_rev_width = XCVR_HW_REV_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 transceiver_info_dict - - elif self.sfp_type == QSFP_DD_TYPE: - offset = 128 - - sfpi_obj = qsfp_dd_InterfaceId() - if sfpi_obj is None: - print("Error: sfp_object open failed") - return transceiver_info_dict - - sfp_type_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_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 transceiver_info_dict - - sfp_vendor_name_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_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_raw, 0) - else: - return transceiver_info_dict - - sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_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_raw, 0) - else: - return transceiver_info_dict - - sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( - (offset + XCVR_HW_REV_OFFSET_QSFP_DD), XCVR_HW_REV_WIDTH_QSFP_DD) - if sfp_vendor_rev_raw is not None: - sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( - sfp_vendor_rev_raw, 0) - else: - return transceiver_info_dict - - sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_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_raw, 0) - else: - return transceiver_info_dict - - sfp_vendor_oui_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) - if sfp_vendor_oui_raw is not None: - sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( - sfp_vendor_oui_raw, 0) - else: - return transceiver_info_dict - - sfp_vendor_date_raw = self._read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_DATE_OFFSET_QSFP_DD), XCVR_VENDOR_DATE_WIDTH_QSFP_DD) - if sfp_vendor_date_raw is not None: - sfp_vendor_date_data = sfpi_obj.parse_vendor_date( - sfp_vendor_date_raw, 0) - else: - return transceiver_info_dict - - sfp_connector_raw = self._read_eeprom_specific_bytes( - (offset + XCVR_CONNECTOR_OFFSET_QSFP_DD), XCVR_CONNECTOR_WIDTH_QSFP_DD) - if sfp_connector_raw is not None: - sfp_connector_data = sfpi_obj.parse_connector( - sfp_connector_raw, 0) - else: - return transceiver_info_dict - - sfp_ext_identifier_raw = self._read_eeprom_specific_bytes( - (offset + XCVR_EXT_TYPE_OFFSET_QSFP_DD), XCVR_EXT_TYPE_WIDTH_QSFP_DD) - if sfp_ext_identifier_raw is not None: - sfp_ext_identifier_data = sfpi_obj.parse_ext_iden( - sfp_ext_identifier_raw, 0) - else: - return transceiver_info_dict - - sfp_cable_len_raw = self._read_eeprom_specific_bytes( - (offset + XCVR_CABLE_LENGTH_OFFSET_QSFP_DD), XCVR_CABLE_LENGTH_WIDTH_QSFP_DD) - if sfp_cable_len_raw is not None: - sfp_cable_len_data = sfpi_obj.parse_cable_len( - sfp_cable_len_raw, 0) - else: - return transceiver_info_dict - - sfp_media_type_raw = self._read_eeprom_specific_bytes( - XCVR_MEDIA_TYPE_OFFSET_QSFP_DD, XCVR_MEDIA_TYPE_WIDTH_QSFP_DD) - if sfp_media_type_raw is not None: - sfp_media_type_dict = sfpi_obj.parse_media_type( - sfp_media_type_raw, 0) - if sfp_media_type_dict is None: - return transceiver_info_dict - - host_media_list = "" - sfp_application_type_first_list = self._read_eeprom_specific_bytes( - (XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD) - if self.second_application_list: - possible_application_count = 15 - sfp_application_type_second_list = self._read_eeprom_specific_bytes( - (XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD) - if sfp_application_type_first_list is not None and sfp_application_type_second_list is not None: - sfp_application_type_list = sfp_application_type_first_list + \ - sfp_application_type_second_list - else: - return transceiver_info_dict - else: - possible_application_count = 8 - if sfp_application_type_first_list is not None: - sfp_application_type_list = sfp_application_type_first_list - else: - return transceiver_info_dict - - for i in range(0, possible_application_count): - if sfp_application_type_list[i * 4] == 'ff': - break - host_electrical, media_interface = sfpi_obj.parse_application( - sfp_media_type_dict, sfp_application_type_list[i * 4], sfp_application_type_list[i * 4 + 1]) - host_media_list = host_media_list + host_electrical + \ - ' - ' + media_interface + '\n\t\t\t\t ' - else: - return transceiver_info_dict - - transceiver_info_dict['type'] = str( - sfp_type_data['data']['type']['value']) - transceiver_info_dict['manufacturer'] = str( - sfp_vendor_name_data['data']['Vendor Name']['value']) - transceiver_info_dict['model'] = str( - sfp_vendor_pn_data['data']['Vendor PN']['value']) - transceiver_info_dict['vendor_rev'] = str( - sfp_vendor_rev_data['data']['Vendor Rev']['value']) - transceiver_info_dict['serial'] = str( - sfp_vendor_sn_data['data']['Vendor SN']['value']) - transceiver_info_dict['vendor_oui'] = str( - sfp_vendor_oui_data['data']['Vendor OUI']['value']) - transceiver_info_dict['vendor_date'] = str( - sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']) - transceiver_info_dict['connector'] = str( - sfp_connector_data['data']['Connector']['value']) - transceiver_info_dict['encoding'] = "Not supported for CMIS cables" - transceiver_info_dict['ext_identifier'] = str( - sfp_ext_identifier_data['data']['Extended Identifier']['value']) - transceiver_info_dict['ext_rateselect_compliance'] = "Not supported for CMIS cables" - transceiver_info_dict['specification_compliance'] = "Not supported for CMIS cables" - transceiver_info_dict['cable_type'] = "Length Cable Assembly(m)" - transceiver_info_dict['cable_length'] = str( - sfp_cable_len_data['data']['Length Cable Assembly(m)']['value']) - transceiver_info_dict['nominal_bit_rate'] = "Not supported for CMIS cables" - transceiver_info_dict['application_advertisement'] = host_media_list - - else: - offset = 0 - vendor_rev_width = XCVR_HW_REV_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 transceiver_info_dict - - if self.sfp_type != QSFP_DD_TYPE: - 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 transceiver_info_dict - - 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_interface_bulk_raw[start: end], 0) - - start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START - end = start + XCVR_VENDOR_DATE_WIDTH - sfp_vendor_date_data = sfpi_obj.parse_vendor_date( - sfp_interface_bulk_raw[start: end], 0) - - 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['vendor_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['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_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] - - if self.sfp_type == QSFP_TYPE: - for key in qsfp_cable_length_tup: - if key in sfp_interface_bulk_data['data']: - transceiver_info_dict['cable_type'] = key - transceiver_info_dict['cable_length'] = str( - sfp_interface_bulk_data['data'][key]['value']) - - 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'] - sfp_ext_specification_compliance_raw = self._read_eeprom_specific_bytes( - offset + XCVR_EXT_SPECIFICATION_COMPLIANCE_OFFSET, XCVR_EXT_SPECIFICATION_COMPLIANCE_WIDTH) - if sfp_ext_specification_compliance_raw is not None: - sfp_ext_specification_compliance_data = sfpi_obj.parse_ext_specification_compliance( - sfp_ext_specification_compliance_raw[0: 1], 0) - if sfp_ext_specification_compliance_data['data']['Extended Specification compliance']['value'] != "Unspecified": - compliance_code_dict['Extended Specification compliance'] = sfp_ext_specification_compliance_data[ - 'data']['Extended Specification compliance']['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: - if key in sfp_interface_bulk_data['data']: - transceiver_info_dict['cable_type'] = key - transceiver_info_dict['cable_length'] = str( - sfp_interface_bulk_data['data'][key]['value']) - - for key in sfp_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']['NominalSignallingRate(UnitsOf100Mbd)']['value']) - - return transceiver_info_dict - - def get_transceiver_bulk_status(self): - """ - Retrieves transceiver bulk status of this SFP - Returns: - A dict which contains following keys/values : - ======================================================================== - keys |Value Format |Information - ---------------------------|---------------|---------------------------- - rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. - tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. - reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. - lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. - tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. - tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 - | |to channel 3. - temperature |INT |module temperature in Celsius - voltage |INT |supply voltage in mV - txbias |INT |TX Bias Current in mA, n is the channel number, - | |for example, tx2bias stands for tx bias of channel 2. - rxpower |INT |received optical power in mW, n is the channel number, - | |for example, rx2power stands for rx power of channel 2. - txpower |INT |TX output power in mW, n is the channel number, - | |for example, tx2power stands for tx power of channel 2. - ======================================================================== - """ - transceiver_dom_info_dict = dict.fromkeys( - dom_info_dict_keys, NULL_VAL) - - 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_data_raw[start: end], 0) - temp = dom_temperature_data['data']['Temperature']['value'] - if temp is not None: - transceiver_dom_info_dict['temperature'] = temp - - if self.dom_volt_supported: - start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START - end = start + QSFP_VOLT_WIDTH - dom_voltage_data = sfpd_obj.parse_voltage( - dom_data_raw[start: end], 0) - volt = dom_voltage_data['data']['Vcc']['value'] - if volt is not None: - transceiver_dom_info_dict['voltage'] = volt - - start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START - end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( - dom_data_raw[start: end], 0) - - if self.dom_tx_power_supported: - transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] - transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] - transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] - transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] - - if self.dom_rx_power_supported: - transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] - transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] - transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] - transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] - - transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] - transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] - transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] - transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] - - elif self.sfp_type == QSFP_DD_TYPE: - - offset = 0 - sfpd_obj = qsfp_dd_Dom() - if sfpd_obj is None: - return transceiver_dom_info_dict - - dom_data_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_DOM_BULK_DATA_START), QSFP_DD_DOM_BULK_DATA_SIZE) - if dom_data_raw is None: - return transceiver_dom_info_dict - - if self.dom_temp_supported: - start = QSFP_DD_TEMPE_OFFSET - QSFP_DD_DOM_BULK_DATA_START - end = start + QSFP_DD_TEMPE_WIDTH - dom_temperature_data = sfpd_obj.parse_temperature( - dom_data_raw[start: end], 0) - temp = dom_temperature_data['data']['Temperature']['value'] - if temp is not None: - transceiver_dom_info_dict['temperature'] = temp - - if self.dom_volt_supported: - start = QSFP_DD_VOLT_OFFSET - QSFP_DD_DOM_BULK_DATA_START - end = start + QSFP_DD_VOLT_WIDTH - dom_voltage_data = sfpd_obj.parse_voltage( - dom_data_raw[start: end], 0) - volt = dom_voltage_data['data']['Vcc']['value'] - if volt is not None: - transceiver_dom_info_dict['voltage'] = volt - - if self.dom_rx_tx_power_bias_supported: - # page 11h - dom_data_raw = self._read_eeprom_specific_bytes( - (QSFP_DD_CHANNL_MON_OFFSET), QSFP_DD_CHANNL_MON_WIDTH) - if dom_data_raw is None: - return transceiver_dom_info_dict - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( - dom_data_raw, 0) - - if self.dom_tx_power_supported: - transceiver_dom_info_dict['tx1power'] = str( - dom_channel_monitor_data['data']['TX1Power']['value']) - transceiver_dom_info_dict['tx2power'] = str( - dom_channel_monitor_data['data']['TX2Power']['value']) - transceiver_dom_info_dict['tx3power'] = str( - dom_channel_monitor_data['data']['TX3Power']['value']) - transceiver_dom_info_dict['tx4power'] = str( - dom_channel_monitor_data['data']['TX4Power']['value']) - transceiver_dom_info_dict['tx5power'] = str( - dom_channel_monitor_data['data']['TX5Power']['value']) - transceiver_dom_info_dict['tx6power'] = str( - dom_channel_monitor_data['data']['TX6Power']['value']) - transceiver_dom_info_dict['tx7power'] = str( - dom_channel_monitor_data['data']['TX7Power']['value']) - transceiver_dom_info_dict['tx8power'] = str( - dom_channel_monitor_data['data']['TX8Power']['value']) - - if self.dom_rx_power_supported: - transceiver_dom_info_dict['rx1power'] = str( - dom_channel_monitor_data['data']['RX1Power']['value']) - transceiver_dom_info_dict['rx2power'] = str( - dom_channel_monitor_data['data']['RX2Power']['value']) - transceiver_dom_info_dict['rx3power'] = str( - dom_channel_monitor_data['data']['RX3Power']['value']) - transceiver_dom_info_dict['rx4power'] = str( - dom_channel_monitor_data['data']['RX4Power']['value']) - transceiver_dom_info_dict['rx5power'] = str( - dom_channel_monitor_data['data']['RX5Power']['value']) - transceiver_dom_info_dict['rx6power'] = str( - dom_channel_monitor_data['data']['RX6Power']['value']) - transceiver_dom_info_dict['rx7power'] = str( - dom_channel_monitor_data['data']['RX7Power']['value']) - transceiver_dom_info_dict['rx8power'] = str( - dom_channel_monitor_data['data']['RX8Power']['value']) - - if self.dom_tx_bias_power_supported: - transceiver_dom_info_dict['tx1bias'] = str( - dom_channel_monitor_data['data']['TX1Bias']['value']) - transceiver_dom_info_dict['tx2bias'] = str( - dom_channel_monitor_data['data']['TX2Bias']['value']) - transceiver_dom_info_dict['tx3bias'] = str( - dom_channel_monitor_data['data']['TX3Bias']['value']) - transceiver_dom_info_dict['tx4bias'] = str( - dom_channel_monitor_data['data']['TX4Bias']['value']) - transceiver_dom_info_dict['tx5bias'] = str( - dom_channel_monitor_data['data']['TX5Bias']['value']) - transceiver_dom_info_dict['tx6bias'] = str( - dom_channel_monitor_data['data']['TX6Bias']['value']) - transceiver_dom_info_dict['tx7bias'] = str( - dom_channel_monitor_data['data']['TX7Bias']['value']) - transceiver_dom_info_dict['tx8bias'] = str( - dom_channel_monitor_data['data']['TX8Bias']['value']) - - return transceiver_dom_info_dict - - 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'] = dom_temperature_data['data']['Temperature']['value'] - transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] - transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] - transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] - transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] - - transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() - transceiver_dom_info_dict['reset_status'] = self.get_reset_status() - transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() - transceiver_dom_info_dict['tx_disabled_channel'] = self.get_tx_disable_channel( - ) - - for key in transceiver_dom_info_dict: - val = transceiver_dom_info_dict[key] - transceiver_dom_info_dict[key] = self._convert_string_to_num( - val) if type(val) is str else val - - return transceiver_dom_info_dict - - def get_transceiver_threshold_info(self): - """ - Retrieves transceiver threshold info of this SFP + break + if ret != self.UPDATE_DONE: + logger.log_error("Error: port {}: update sfp type fail due to {}".format(self.port_num, ret)) + return False - Returns: - A dict which contains following keys/values : - ======================================================================== - keys |Value Format |Information - ---------------------------|---------------|---------------------------- - temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. - templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. - temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. - templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. - vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. - vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. - vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. - vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. - rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. - rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. - rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. - rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. - txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. - txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. - txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. - txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. - txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. - txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. - txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. - txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. - ======================================================================== - """ - transceiver_dom_threshold_info_dict = dict.fromkeys( - threshold_dict_keys, NULL_VAL) - - 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( - (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'] - - elif self.sfp_type == QSFP_DD_TYPE: - if not self.dom_supported: - return transceiver_dom_threshold_info_dict - - if not self.dom_thresholds_supported: - return transceiver_dom_threshold_info_dict - - sfpd_obj = qsfp_dd_Dom() - if sfpd_obj is None: - return transceiver_dom_threshold_info_dict - - # page 02 - offset = 384 - dom_module_threshold_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_MODULE_THRESHOLD_OFFSET), QSFP_DD_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) - - # 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_module_threshold_data['data']['RxPowerHighAlarm']['value'] - transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RxPowerHighWarning']['value'] - transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RxPowerLowAlarm']['value'] - transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RxPowerLowWarning']['value'] - transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['TxBiasHighAlarm']['value'] - transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['TxBiasHighWarning']['value'] - transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['TxBiasLowAlarm']['value'] - transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['TxBiasLowWarning']['value'] - transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TxPowerHighAlarm']['value'] - transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TxPowerHighWarning']['value'] - transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TxPowerLowAlarm']['value'] - transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TxPowerLowWarning']['value'] + devclass_path = OPTOE_DEV_CLASS_PATH.format(SFP_I2C_START + (self.index - 1)) + devclass = self._api_helper.read_txt_file(devclass_path) + if devclass is None: + return False + if self.sfp_type == self.QSFP_TYPE: + if devclass == '1': + return True + return self._api_helper.write_txt_file(devclass_path, 1) + elif self.sfp_type == self.SFP_TYPE: + if devclass == '2': + return True + return self._api_helper.write_txt_file(devclass_path, 2) + elif self.sfp_type == self.QSFP_DD_TYPE: + if devclass == '3': + return True + return self._api_helper.write_txt_file(devclass_path, 3) 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: - dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( - 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['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] - transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] - transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] - transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] - transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] - transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ - 'data']['VoltageHighWarning']['value'] - transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] - transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] - transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] - transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] - transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] - transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] - transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] - transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] - transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] - transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] - transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] - transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] - transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] - - 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]) - - return transceiver_dom_threshold_info_dict + return False def get_reset_status(self): """ @@ -1302,180 +186,16 @@ def get_reset_status(self): Returns: A Boolean, True if reset enabled, False if disabled """ - if self._port_num <= 16: - reset_path = "{}{}{}".format(CPLD2_I2C_PATH, '/module_reset_', self._port_num) + if self.port_num <= 16: + reset_path = "{}{}{}".format(CPLD2_I2C_PATH, '/module_reset_', self.port_num) else: - reset_path = "{}{}{}".format(CPLD3_I2C_PATH, '/module_reset_', self._port_num) + reset_path = "{}{}{}".format(CPLD3_I2C_PATH, '/module_reset_', self.port_num) val=self._api_helper.read_txt_file(reset_path) if val is not None: return int(val, 10)==1 - else: - return False - - def get_rx_los(self): - """ - Retrieves the RX LOS (lost-of-signal) status of SFP - Returns: - A Boolean, True if SFP has RX LOS, False if not. - Note : RX LOS status is latched until a call to get_rx_los or a reset. - """ - rx_los_list = [] - - if self.sfp_type == OSFP_TYPE: - return None - elif self.sfp_type == QSFP_TYPE: - 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) - rx_los_list.append(rx_los_data & 0x01 != 0) - rx_los_list.append(rx_los_data & 0x02 != 0) - rx_los_list.append(rx_los_data & 0x04 != 0) - rx_los_list.append(rx_los_data & 0x08 != 0) - else: - return [False] * 4 - - elif self.sfp_type == QSFP_DD_TYPE: - # page 11h - if self.dom_rx_tx_power_bias_supported: - offset = 128 - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET), - QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - rx_los_data = int(dom_channel_monitor_raw[0], 8) - rx_los_list.append(rx_los_data & 0x01 != 0) - rx_los_list.append(rx_los_data & 0x02 != 0) - rx_los_list.append(rx_los_data & 0x04 != 0) - rx_los_list.append(rx_los_data & 0x08 != 0) - rx_los_list.append(rx_los_data & 0x10 != 0) - rx_los_list.append(rx_los_data & 0x20 != 0) - rx_los_list.append(rx_los_data & 0x40 != 0) - rx_los_list.append(rx_los_data & 0x80 != 0) - else: - return [False] * 8 - 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_list.append(rx_los_data & 0x02 != 0) - else: - return [False] - return rx_los_list - - def get_tx_fault(self): - """ - Retrieves the TX fault status of SFP - Returns: - 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. - """ - tx_fault_list = [] - - if self.sfp_type == OSFP_TYPE: - return None - 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) - tx_fault_list.append(tx_fault_data & 0x01 != 0) - tx_fault_list.append(tx_fault_data & 0x02 != 0) - tx_fault_list.append(tx_fault_data & 0x04 != 0) - tx_fault_list.append(tx_fault_data & 0x08 != 0) - else: - return [False] * 4 - elif self.sfp_type == QSFP_DD_TYPE: - # page 11h - if self.dom_rx_tx_power_bias_supported: - offset = 128 - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET), - QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - tx_fault_data = int(dom_channel_monitor_raw[0], 8) - tx_fault_list.append(tx_fault_data & 0x01 != 0) - tx_fault_list.append(tx_fault_data & 0x02 != 0) - tx_fault_list.append(tx_fault_data & 0x04 != 0) - tx_fault_list.append(tx_fault_data & 0x08 != 0) - tx_fault_list.append(tx_fault_data & 0x10 != 0) - tx_fault_list.append(tx_fault_data & 0x20 != 0) - tx_fault_list.append(tx_fault_data & 0x40 != 0) - tx_fault_list.append(tx_fault_data & 0x80 != 0) - else: - return [False] * 8 - 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) - tx_fault_list.append(tx_fault_data & 0x04 != 0) - else: - return None - return tx_fault_list - - def get_tx_disable(self): - """ - Retrieves the tx_disable status of this SFP - Returns: - A list of boolean values, representing the TX disable status - of each available channel, value is True if SFP channel - is TX disabled, False if not. - E.g., for a tranceiver with four channels: [False, False, True, False] - """ - tx_disable_list = [] - if self.sfp_type == OSFP_TYPE: - return None - elif self.sfp_type == QSFP_TYPE: - offset = 0 - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), - QSFP_CHANNL_DISABLE_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - tx_disable_data = int(dom_channel_monitor_raw[0], 16) - tx_disable_list.append(tx_disable_data & 0x01 != 0) - tx_disable_list.append(tx_disable_data & 0x02 != 0) - tx_disable_list.append(tx_disable_data & 0x04 != 0) - tx_disable_list.append(tx_disable_data & 0x08 != 0) - else: - return [False] * 4 - - elif self.sfp_type == QSFP_DD_TYPE: - if self.dom_rx_tx_power_bias_supported: - offset = 128 - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET), - QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - tx_disable_data = int(dom_channel_monitor_raw[0], 16) - tx_disable_list.append(tx_disable_data & 0x01 != 0) - tx_disable_list.append(tx_disable_data & 0x02 != 0) - tx_disable_list.append(tx_disable_data & 0x04 != 0) - tx_disable_list.append(tx_disable_data & 0x08 != 0) - tx_disable_list.append(tx_disable_data & 0x10 != 0) - tx_disable_list.append(tx_disable_data & 0x20 != 0) - tx_disable_list.append(tx_disable_data & 0x40 != 0) - tx_disable_list.append(tx_disable_data & 0x80 != 0) - else: - return [False] * 8 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_disable_data = int(dom_channel_monitor_raw[0], 16) - tx_disable_list.append(tx_disable_data & 0xC0 != 0) - else: - return [False] - return tx_disable_list + return False def get_tx_disable_channel(self): """ @@ -1483,7 +203,7 @@ def get_tx_disable_channel(self): Returns: A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent TX channels which have been disabled in this SFP. - As an example, a returned value of 0x5 indicates that channel 0 + As an example, a returned value of 0x5 indicates that channel 0 and channel 2 have been disabled. """ tx_disable_list = self.get_tx_disable() @@ -1501,497 +221,27 @@ def get_lpmode(self): Returns: A Boolean, True if lpmode is enabled, False if disabled """ - if self._port_num > 32: + if self.port_num > 32: # SFP doesn't support this feature return False - else: - try: - eeprom = None - - if not self.get_presence(): - return False - # Write to eeprom - port_to_i2c_mapping = SFP_I2C_START + self._index - port_eeprom_path = I2C_EEPROM_PATH.format(port_to_i2c_mapping) - - eeprom = open(port_eeprom_path, "rb") - eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) - lpmode = ord(eeprom.read(1)) - - if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 - else: - # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 - return False - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - finally: - if eeprom is not None: - eeprom.close() - time.sleep(0.01) - - def get_power_set(self): - if self._port_num > 32: - # SFP doesn't support this feature + if not self.get_presence(): return False - else: - power_set = False - - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return False - - dom_control_raw = self._read_eeprom_specific_bytes( - QSFP_POWEROVERRIDE_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None - if dom_control_raw is not None: - dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) - power_set = ( - 'On' == dom_control_data['data']['PowerSet']['value']) - - return power_set - - def get_power_override(self): - """ - Retrieves the power-override status of this SFP - Returns: - A Boolean, True if power-override is enabled, False if disabled - """ - if self.sfp_type == QSFP_TYPE: - offset = 0 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return False - - dom_control_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_CONTROL_OFFSET), QSFP_CONTROL_WIDTH) - if dom_control_raw is not None: - dom_control_data = sfpd_obj.parse_control_bytes( - dom_control_raw, 0) - return ('On' == dom_control_data['data']['PowerOverride']) - else: - return False - else: - return NotImplementedError - - def get_temperature(self): - """ - Retrieves the temperature of this SFP - Returns: - An integer number of current temperature in Celsius - """ - default = 0.0 - if not self.dom_supported: - return default - - if self.sfp_type == QSFP_TYPE: - offset = 0 - - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return default - - if self.dom_temp_supported: - dom_temperature_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) - if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature( - dom_temperature_raw, 0) - temp = self._convert_string_to_num( - dom_temperature_data['data']['Temperature']['value']) - return temp - - elif self.sfp_type == QSFP_DD_TYPE: - offset = 0 - - sfpd_obj = qsfp_dd_Dom() - if sfpd_obj is None: - return default - - if self.dom_temp_supported: - dom_temperature_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_TEMPE_OFFSET), QSFP_DD_TEMPE_WIDTH) - if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature( - dom_temperature_raw, 0) - temp = self._convert_string_to_num( - dom_temperature_data['data']['Temperature']['value']) - return temp - - else: - offset = 256 - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return default - sfpd_obj._calibration_type = 1 - - dom_temperature_raw = self._read_eeprom_specific_bytes( - (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) - if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature( - dom_temperature_raw, 0) - temp = self._convert_string_to_num( - dom_temperature_data['data']['Temperature']['value']) - return temp - - return default - - def get_voltage(self): - """ - Retrieves the supply voltage of this SFP - Returns: - An integer number of supply voltage in mV - """ - default = 0.0 - - if not self.dom_supported: - return default - - if self.sfp_type == QSFP_TYPE: - offset = 0 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return default - - if self.dom_volt_supported: - dom_voltage_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) - if dom_voltage_raw is not None: - dom_voltage_data = sfpd_obj.parse_voltage( - dom_voltage_raw, 0) - voltage = self._convert_string_to_num( - dom_voltage_data['data']['Vcc']['value']) - return voltage - - if self.sfp_type == QSFP_DD_TYPE: - offset = 128 - - sfpd_obj = qsfp_dd_Dom() - if sfpd_obj is None: - return default - - if self.dom_volt_supported: - dom_voltage_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_VOLT_OFFSET), QSFP_DD_VOLT_WIDTH) - if dom_voltage_raw is not None: - dom_voltage_data = sfpd_obj.parse_voltage( - dom_voltage_raw, 0) - voltage = self._convert_string_to_num( - dom_voltage_data['data']['Vcc']['value']) - return voltage - - else: - offset = 256 - - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return default - - sfpd_obj._calibration_type = self.calibration - - dom_voltage_raw = self._read_eeprom_specific_bytes( - (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) - if dom_voltage_raw is not None: - dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) - voltage = self._convert_string_to_num( - dom_voltage_data['data']['Vcc']['value']) - return voltage - - return default - - def get_tx_bias(self): - """ - Retrieves the TX bias current of this SFP - Returns: - A list of four integer numbers, representing TX bias in mA - for channel 0 to channel 4. - Ex. ['110.09', '111.12', '108.21', '112.09'] - """ - tx_bias_list = [] - if self.sfp_type == QSFP_TYPE: - offset = 0 - default = [0.0] * 4 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return default - - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_MON_OFFSET), 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_channel_monitor_raw, 0) - tx_bias_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TX1Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TX2Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TX3Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TX4Bias']['value'])) - else: - return default - - elif self.sfp_type == QSFP_DD_TYPE: - default = [0.0] * 8 - # page 11h - if self.dom_rx_tx_power_bias_supported: - offset = 128 - sfpd_obj = qsfp_dd_Dom() - if sfpd_obj is None: - return default - - if dom_tx_bias_power_supported: - dom_tx_bias_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_TX_BIAS_OFFSET), QSFP_DD_TX_BIAS_WIDTH) - if dom_tx_bias_raw is not None: - dom_tx_bias_data = sfpd_obj.parse_dom_tx_bias( - dom_tx_bias_raw, 0) - tx_bias_list.append(self._convert_string_to_num( - dom_tx_bias_data['data']['TX1Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_tx_bias_data['data']['TX2Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_tx_bias_data['data']['TX3Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_tx_bias_data['data']['TX4Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_tx_bias_data['data']['TX5Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_tx_bias_data['data']['TX6Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_tx_bias_data['data']['TX7Bias']['value'])) - tx_bias_list.append(self._convert_string_to_num( - dom_tx_bias_data['data']['TX8Bias']['value'])) - else: - return default - else: - return default + if self.sfp_type == self.QSFP_DD_TYPE: + api = self.get_xcvr_api() + return api.get_lpmode() else: - offset = 256 - default = [0.0] - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return default - sfpd_obj._calibration_type = self.calibration - - if self.dom_supported: - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( - dom_channel_monitor_raw, 0) - tx_bias_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TXBias']['value'])) - else: - return default + if self.port_num <= 16: + lpmode_path = "{}{}{}".format(CPLD2_I2C_PATH, '/module_lpmode_', self.port_num) else: - return default - - return tx_bias_list + lpmode_path = "{}{}{}".format(CPLD3_I2C_PATH, '/module_lpmode_', self.port_num) - def get_rx_power(self): - """ - Retrieves the received optical power for this SFP - Returns: - A list of four integer numbers, representing received optical - power in mW for channel 0 to channel 4. - Ex. ['1.77', '1.71', '1.68', '1.70'] - """ - rx_power_list = [] - if self.sfp_type == OSFP_TYPE: - # OSFP not supported on our platform yet. - return None - - elif self.sfp_type == QSFP_TYPE: - offset = 0 - default = [0.0] * 4 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return default - - if self.dom_rx_power_supported: - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_MON_OFFSET), 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_channel_monitor_raw, 0) - rx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['RX1Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['RX2Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['RX3Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['RX4Power']['value'])) - else: - return default + val=self._api_helper.read_txt_file(lpmode_path) + if val is not None: + return int(val, 10)==0 else: - return default - - elif self.sfp_type == QSFP_DD_TYPE: - default = [0.0] * 8 - # page 11 - if self.dom_rx_tx_power_bias_supported: - offset = 128 - sfpd_obj = qsfp_dd_Dom() - if sfpd_obj is None: - return default - - if self.dom_rx_power_supported: - dom_rx_power_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_RX_POWER_OFFSET), QSFP_DD_RX_POWER_WIDTH) - if dom_rx_power_raw is not None: - dom_rx_power_data = sfpd_obj.parse_dom_rx_power( - dom_rx_power_raw, 0) - rx_power_list.append(self._convert_string_to_num( - dom_rx_power_data['data']['RX1Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_rx_power_data['data']['RX2Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_rx_power_data['data']['RX3Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_rx_power_data['data']['RX4Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_rx_power_data['data']['RX5Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_rx_power_data['data']['RX6Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_rx_power_data['data']['RX7Power']['value'])) - rx_power_list.append(self._convert_string_to_num( - dom_rx_power_data['data']['RX8Power']['value'])) - else: - return default - else: - return default - - else: - offset = 256 - default = [0.0] - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return default - - if self.dom_supported: - sfpd_obj._calibration_type = self.calibration - - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( - dom_channel_monitor_raw, 0) - rx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['RXPower']['value'])) - else: - return default - else: - return default - return rx_power_list - - def get_tx_power(self): - """ - Retrieves the TX power of this SFP - Returns: - A list of four integer numbers, representing TX power in mW - for channel 0 to channel 4. - Ex. ['1.86', '1.86', '1.86', '1.86'] - """ - tx_power_list = [] - if self.sfp_type == OSFP_TYPE: - # OSFP not supported on our platform yet. - return tx_power_list - - elif self.sfp_type == QSFP_TYPE: - offset = 0 - default = [0.0] * 4 - - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return tx_power_list - - if self.dom_tx_power_supported: - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_MON_OFFSET), - 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_channel_monitor_raw, 0) - tx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TX1Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TX2Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TX3Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TX4Power']['value'])) - else: - return default - else: - return default - - elif self.sfp_type == QSFP_DD_TYPE: - default = [0.0] * 8 - - # page 11 - if self.dom_rx_tx_power_bias_supported: - offset = 128 - sfpd_obj = qsfp_dd_Dom() - if sfpd_obj is None: - return default - - if self.dom_tx_power_supported: - dom_tx_power_raw = self._read_eeprom_specific_bytes( - (offset + QSFP_DD_TX_POWER_OFFSET), - QSFP_DD_TX_POWER_WIDTH) - if dom_tx_power_raw is not None: - dom_tx_power_data = sfpd_obj.parse_dom_tx_power( - dom_tx_power_raw, 0) - tx_power_list.append(self._convert_string_to_num( - dom_tx_power_data['data']['TX1Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_tx_power_data['data']['TX2Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_tx_power_data['data']['TX3Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_tx_power_data['data']['TX4Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_tx_power_data['data']['TX5Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_tx_power_data['data']['TX6Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_tx_power_data['data']['TX7Power']['value'])) - tx_power_list.append(self._convert_string_to_num( - dom_tx_power_data['data']['TX8Power']['value'])) - else: - return default - else: - return default - - else: - offset = 256 - default = [0.0] - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return default - - if self.dom_supported: - sfpd_obj._calibration_type = self.calibration - - dom_channel_monitor_raw = self._read_eeprom_specific_bytes( - (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( - dom_channel_monitor_raw, 0) - tx_power_list.append(self._convert_string_to_num( - dom_channel_monitor_data['data']['TXPower']['value'])) - else: - return default - else: - return default - return tx_power_list + return False def reset(self): """ @@ -2001,25 +251,25 @@ def reset(self): """ # Check for invalid port_num - if self._port_num > 32: + if self.port_num > 32: return False # SFP doesn't support this feature else: if not self.get_presence(): return False - if self._port_num <= self.CPLD2_PORT_END: - reset_path = "{}{}{}".format(CPLD2_I2C_PATH, 'module_reset_', self._port_num) + if self.port_num <= self.CPLD2_PORT_END: + reset_path = "{}{}{}".format(CPLD2_I2C_PATH, 'module_reset_', self.port_num) else: - reset_path = "{}{}{}".format(CPLD3_I2C_PATH, 'module_reset_', self._port_num) + reset_path = "{}{}{}".format(CPLD3_I2C_PATH, 'module_reset_', self.port_num) ret = self.__write_txt_file(reset_path, 1) #sysfs 1: enable reset if ret is not True: return ret - + time.sleep(0.2) ret = self.__write_txt_file(reset_path, 0) #sysfs 0: disable reset time.sleep(0.2) - + return ret def tx_disable(self, tx_disable): @@ -2031,43 +281,12 @@ def tx_disable(self, tx_disable): Returns: A boolean, True if tx_disable is set successfully, False if not """ - if self.sfp_type == QSFP_TYPE: + if self.sfp_type == self.QSFP_TYPE: sysfsfile_eeprom = None try: tx_disable_value = 0xf if tx_disable else 0x0 # Write to eeprom - sysfsfile_eeprom = open(self._eeprom_path, "r+b") - sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) - sysfsfile_eeprom.write(struct.pack('B', tx_disable_value)) - except IOError: - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True - return False - - def tx_disable_channel(self, channel, disable): - """ - Sets the tx_disable for specified SFP channels - Args: - channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, - e.g. 0x5 for channel 0 and channel 2. - disable : A boolean, True to disable TX channels specified in channel, - False to enable - Returns: - A boolean, True if successful, False if not - """ - if self.sfp_type == QSFP_TYPE: - sysfsfile_eeprom = None - try: - current_state = self.get_tx_disable_channel() - tx_disable_value = (current_state | channel) if \ - disable else (current_state & (~channel)) - - # Write to eeprom - sysfsfile_eeprom = open(self._eeprom_path, "r+b") + sysfsfile_eeprom = open(self.get_eeprom_path(), "r+b") sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) sysfsfile_eeprom.write(struct.pack('B', tx_disable_value)) except IOError: @@ -2088,18 +307,30 @@ def set_lpmode(self, lpmode): Returns: A boolean, True if lpmode is set successfully, False if not """ - if self._port_num > 32: + if self.port_num > 32: return False # SFP doesn't support this feature else: if not self.get_presence(): return False - if lpmode is True: - self.set_power_override(True, True) + if self.sfp_type == self.QSFP_DD_TYPE: + api = self.get_xcvr_api() + # ToDO: The return code for CMIS set_lpmode have some issue + # workaround: always return True + api.set_lpmode(lpmode) + return True else: - self.set_power_override(True, False) + if self.port_num <= self.CPLD2_PORT_END: + lpmode_path = "{}{}{}".format(CPLD2_I2C_PATH, 'module_lpmode_', self.port_num) + else: + lpmode_path = "{}{}{}".format(CPLD3_I2C_PATH, 'module_lpmode_', self.port_num) - return True + if lpmode is True: + ret = self.__write_txt_file(lpmode_path, 0) #enable lpmode + else: + ret = self.__write_txt_file(lpmode_path, 1) #disable lpmode + + return ret def set_power_override(self, power_override, power_set): """ @@ -2118,7 +349,7 @@ def set_power_override(self, power_override, power_set): A boolean, True if power-override and power_set are set successfully, False if not """ - if self._port_num > 32: + if self.port_num > 32: return False # SFP doesn't support this feature else: if not self.get_presence(): @@ -2133,14 +364,12 @@ def set_power_override(self, power_override, power_set): else: buffer[0] = chr(power_override_bit | power_set_bit) # Write to eeprom - port_to_i2c_mapping = SFP_I2C_START + self._index - port_eeprom_path = I2C_EEPROM_PATH.format(port_to_i2c_mapping) - with open(port_eeprom_path, "r+b") as fd: + with open(self.get_eeprom_path(), "r+b") as fd: fd.seek(QSFP_POWEROVERRIDE_OFFSET) fd.write(buffer[0]) time.sleep(0.01) except Exception as e: - print ('Error: unable to open file: ', str(e)) + logger.log_error("Error: unable to open file: %s" % str(e)) return False return True @@ -2157,7 +386,8 @@ def get_name(self): sfputil_helper = SfpUtilHelper() sfputil_helper.read_porttab_mappings( self.__get_path_to_port_config_file()) - name = sfputil_helper.logical[self.index] or "Unknown" + logical_port_list = natsort.natsorted(sfputil_helper.logical) + name = logical_port_list[self.index - 1] or "Unknown" return name def get_presence(self): @@ -2166,36 +396,18 @@ def get_presence(self): Returns: bool: True if device is present, False if not """ - if self._port_num <= 16: - present_path = "{}{}{}".format(CPLD2_I2C_PATH, '/module_present_', self._port_num) + if self.port_num <= 16: + present_path = "{}{}{}".format(CPLD2_I2C_PATH, '/module_present_', self.port_num) else: - present_path = "{}{}{}".format(CPLD3_I2C_PATH, '/module_present_', self._port_num) + present_path = "{}{}{}".format(CPLD3_I2C_PATH, '/module_present_', self.port_num) val=self._api_helper.read_txt_file(present_path) if val is not None: return int(val, 10)==1 - else: + else: return False - def get_model(self): - """ - Retrieves the model number (or part number) of the device - Returns: - string: Model/part number of device - """ - transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("model", "N/A") - - def get_serial(self): - """ - Retrieves the serial number of the device - Returns: - string: Serial number of device - """ - transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serial", "N/A") - def get_status(self): """ Retrieves the operational status of the device @@ -2209,7 +421,7 @@ def get_position_in_parent(self): Returns: Temp return 0 """ - return 0 + return self.port_num def is_replaceable(self): """ @@ -2218,3 +430,219 @@ def is_replaceable(self): A boolean value, True if replaceable """ return True + + def update_sfp_type(self): + """ + Updates the sfp type + + """ + ret = self.UPDATE_DONE + eeprom_raw = [] + eeprom_raw = self.read_eeprom(0, 1) + if eeprom_raw and hasattr(self,'sfp_type'): + if eeprom_raw[0] in self.SFP_TYPE_CODE_LIST: + self.sfp_type = self.SFP_TYPE + elif eeprom_raw[0] in self.QSFP_TYPE_CODE_LIST: + self.sfp_type = self.QSFP_TYPE + elif eeprom_raw[0] in self.QSFP_DD_TYPE_CODE_LIST: + self.sfp_type = self.QSFP_DD_TYPE + elif eeprom_raw[0] in self.OSFP_TYPE_CODE_LIST: + self.sfp_type = self.OSFP_TYPE + else: + ret = self.UNKNOWN_SFP_TYPE_ID + else: + ret = self.EEPROM_DATA_NOT_READY + + return ret + + def validate_eeprom_sfp(self): + checksum_test = 0 + eeprom_raw = self.read_eeprom(0, 96) + if eeprom_raw is None: + return None + + for i in range(0, 63): + checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF + else: + if checksum_test != eeprom_raw[63]: + return False + + checksum_test = 0 + for i in range(64, 95): + checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF + else: + if checksum_test != eeprom_raw[95]: + return False + + api = self.get_xcvr_api() + if api is None: + return False + + if api.is_flat_memory(): + return True + + checksum_test = 0 + eeprom_raw = self.read_eeprom(384, 96) + if eeprom_raw is None: + return None + + for i in range(0, 95): + checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF + else: + if checksum_test != eeprom_raw[95]: + return False + + return True + + def validate_eeprom_qsfp(self): + checksum_test = 0 + eeprom_raw = self.read_eeprom(128, 96) + if eeprom_raw is None: + return None + + for i in range(0, 63): + checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF + else: + if checksum_test != eeprom_raw[63]: + return False + + checksum_test = 0 + for i in range(64, 95): + checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF + else: + if checksum_test != eeprom_raw[95]: + return False + + api = self.get_xcvr_api() + if api is None: + return False + + if api.is_flat_memory(): + return True + + return True + + def validate_eeprom_cmis(self): + checksum_test = 0 + eeprom_raw = self.read_eeprom(128, 95) + if eeprom_raw is None: + return None + + for i in range(0, 94): + checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF + else: + if checksum_test != eeprom_raw[94]: + return False + + api = self.get_xcvr_api() + if api is None: + return False + + if api.is_flat_memory(): + return True + + checksum_test = 0 + eeprom_raw = self.read_eeprom(258, 126) + if eeprom_raw is None: + return None + + for i in range(0, 125): + checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF + else: + if checksum_test != eeprom_raw[125]: + return False + + checksum_test = 0 + eeprom_raw = self.read_eeprom(384, 128) + if eeprom_raw is None: + return None + + for i in range(0, 127): + checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF + else: + if checksum_test != eeprom_raw[127]: + return False + + # CMIS_5.0 starts to support the checksum of page 04h + cmis_rev = float(api.get_cmis_rev()) + if cmis_rev >= 5.0: + checksum_test = 0 + eeprom_raw = self.read_eeprom(640, 128) + if eeprom_raw is None: + return None + + for i in range(0, 127): + checksum_test = (checksum_test + eeprom_raw[i]) & 0xFF + else: + if checksum_test != eeprom_raw[127]: + return False + + return True + + def validate_eeprom(self): + id_byte_raw = self.read_eeprom(0, 1) + if id_byte_raw is None: + return None + + id = id_byte_raw[0] + if id in self.QSFP_TYPE_CODE_LIST: + return self.validate_eeprom_qsfp() + elif id in self.SFP_TYPE_CODE_LIST: + return self.validate_eeprom_sfp() + elif id in self.QSFP_DD_TYPE_CODE_LIST: + return self.validate_eeprom_cmis() + else: + return False + + def validate_temperature(self): + temperature = self.get_temperature() + if temperature is None: + return None + + threshold_dict = self.get_transceiver_threshold_info() + if threshold_dict is None: + return None + + if isinstance(temperature, float) is not True: + return True + + if isinstance(threshold_dict['temphighalarm'], float) is not True: + return True + + return threshold_dict['temphighalarm'] > temperature + + def get_error_description(self): + """ + Retrives the error descriptions of the SFP module + Returns: + String that represents the current error descriptions of vendor specific errors + In case there are multiple errors, they should be joined by '|', + like: "Bad EEPROM|Unsupported cable" + """ + if not self.get_presence(): + return self.SFP_STATUS_UNPLUGGED + + err_stat = self.SFP_STATUS_BIT_INSERTED + + status = self.validate_eeprom() + if status is not True: + err_stat = (err_stat | self.SFP_ERROR_BIT_BAD_EEPROM) + + status = self.validate_temperature() + if status is False: + err_stat = (err_stat | self.SFP_ERROR_BIT_HIGH_TEMP) + + if err_stat is self.SFP_STATUS_BIT_INSERTED: + return self.SFP_STATUS_OK + else: + err_desc = '' + cnt = 0 + for key in self.SFP_ERROR_BIT_TO_DESCRIPTION_DICT: + if (err_stat & key) != 0: + if cnt > 0: + err_desc = err_desc + "|" + cnt = cnt + 1 + err_desc = err_desc + self.SFP_ERROR_BIT_TO_DESCRIPTION_DICT[key] + + return err_desc + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/thermal.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/thermal.py index 1a811719de..bae1fa1c7b 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/thermal.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/thermal.py @@ -1,5 +1,5 @@ ############################################################################# -# Accton +# Edgecore # # Thermal contains an implementation of SONiC Platform Base API and # provides the thermal device status which are available in the platform @@ -12,55 +12,187 @@ try: from sonic_platform_base.thermal_base import ThermalBase + from .helper import DeviceThreshold except ImportError as e: raise ImportError(str(e) + "- required module not found") +PSU_I2C_PATH = "/sys/bus/i2c/devices/{}-00{}/" + +PSU_HWMON_I2C_MAPPING = { + 0: { + "num": 9, + "addr": "58" + }, + 1: { + "num": 9, + "addr": "59" + }, +} + +PSU_CPLD_I2C_MAPPING = { + 0: { + "num": 9, + "addr": "50" + }, + 1: { + "num": 9, + "addr": "51" + }, +} + +THERMAL_NAME_LIST = ["MB_FrontMiddle_temp(0x48)", "MB_RightCenter_temp(0x49)", "MB_LeftCenter_temp(0x4A)", + "CB_temp(0x4B)", "OCXO_temp(0x4C)", "MB_RearRight_temp(0x4F)", + "CPU_Package_temp", "CPU_Core_0_temp", "CPU_Core_1_temp", + "CPU_Core_2_temp", "CPU_Core_3_temp"] + +PSU_THERMAL_NAME_LIST = ["PSU-1 temp sensor 1", "PSU-2 temp sensor 1"] + +SYSFS_PATH = "/sys/bus/i2c/devices" +CPU_SYSFS_PATH = "/sys/devices/platform" class Thermal(ThermalBase): """Platform-specific Thermal class""" - THERMAL_NAME_LIST = [] - SYSFS_PATH = "/sys/bus/i2c/devices" - - def __init__(self, thermal_index=0): - self.THERMAL_NAME_LIST = [] - self.SYSFS_PATH = "/sys/bus/i2c/devices" + def __init__(self, thermal_index=0, is_psu=False, psu_index=0): self.index = thermal_index - # Add thermal name - self.THERMAL_NAME_LIST.append("Temp sensor 1") - self.THERMAL_NAME_LIST.append("Temp sensor 2") - self.THERMAL_NAME_LIST.append("Temp sensor 3") - self.THERMAL_NAME_LIST.append("Temp sensor 4") - self.THERMAL_NAME_LIST.append("Temp sensor 5") - self.THERMAL_NAME_LIST.append("Temp sensor 6") + self.is_psu = is_psu + self.psu_index = psu_index + self.min_temperature = None + self.max_temperature = None + + if self.is_psu: + psu_i2c_bus = PSU_HWMON_I2C_MAPPING[psu_index]["num"] + psu_i2c_addr = PSU_HWMON_I2C_MAPPING[psu_index]["addr"] + self.psu_hwmon_path = PSU_I2C_PATH.format(psu_i2c_bus, + psu_i2c_addr) + psu_i2c_bus = PSU_CPLD_I2C_MAPPING[psu_index]["num"] + psu_i2c_addr = PSU_CPLD_I2C_MAPPING[psu_index]["addr"] + self.cpld_path = PSU_I2C_PATH.format(psu_i2c_bus, psu_i2c_addr) + + self.conf = DeviceThreshold(self.get_name()) + # Default thresholds + self.default_threshold = { + THERMAL_NAME_LIST[0] : { + self.conf.HIGH_THRESHOLD_FIELD : '80.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[1] : { + self.conf.HIGH_THRESHOLD_FIELD : '80.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[2] : { + self.conf.HIGH_THRESHOLD_FIELD : '80.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[3] : { + self.conf.HIGH_THRESHOLD_FIELD : '80.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[4] : { + self.conf.HIGH_THRESHOLD_FIELD : '80.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[5] : { + self.conf.HIGH_THRESHOLD_FIELD : '80.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[6] : { + self.conf.HIGH_THRESHOLD_FIELD : '82.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : '104.0', + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[7] : { + self.conf.HIGH_THRESHOLD_FIELD : '82.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : '104.0', + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[8] : { + self.conf.HIGH_THRESHOLD_FIELD : '82.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : '104.0', + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[9] : { + self.conf.HIGH_THRESHOLD_FIELD : '82.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : '104.0', + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + THERMAL_NAME_LIST[10] : { + self.conf.HIGH_THRESHOLD_FIELD : '82.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : '104.0', + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + PSU_THERMAL_NAME_LIST[0] : { + self.conf.HIGH_THRESHOLD_FIELD : '80.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + }, + PSU_THERMAL_NAME_LIST[1] : { + self.conf.HIGH_THRESHOLD_FIELD : '80.0', + self.conf.LOW_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.HIGH_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE, + self.conf.LOW_CRIT_THRESHOLD_FIELD : self.conf.NOT_AVAILABLE + } + } # Set hwmon path i2c_path = { - 0: "15-0048/hwmon/hwmon*/", - 1: "15-0049/hwmon/hwmon*/", - 2: "15-004a/hwmon/hwmon*/", - 3: "15-004b/hwmon/hwmon*/", - 4: "15-004c/hwmon/hwmon*/", - 5: "15-004f/hwmon/hwmon*/" + 0: {"hwmon_path":"15-0048/hwmon/hwmon*/", "ss_index":1}, + 1: {"hwmon_path":"15-0049/hwmon/hwmon*/", "ss_index":1}, + 2: {"hwmon_path":"15-004a/hwmon/hwmon*/", "ss_index":1}, + 3: {"hwmon_path":"15-004b/hwmon/hwmon*/", "ss_index":1}, + 4: {"hwmon_path":"15-004c/hwmon/hwmon*/", "ss_index":1}, + 5: {"hwmon_path":"15-004f/hwmon/hwmon*/", "ss_index":1}, + 6: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":1}, + 7: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":2}, + 8: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":3}, + 9: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":4}, + 10: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":5} }.get(self.index, None) - self.hwmon_path = "{}/{}".format(self.SYSFS_PATH, i2c_path) - self.ss_key = self.THERMAL_NAME_LIST[self.index] - self.ss_index = 1 + self.is_cpu = False + if self.index in range(6,11): + self.is_cpu = True + self.hwmon_path = "{}/{}".format(CPU_SYSFS_PATH, i2c_path["hwmon_path"]) + else: + self.hwmon_path = "{}/{}".format(SYSFS_PATH, i2c_path["hwmon_path"]) + self.ss_key = THERMAL_NAME_LIST[self.index] + self.ss_index = i2c_path["ss_index"] def __read_txt_file(self, file_path): for filename in glob.glob(file_path): try: with open(filename, 'r') as fd: - data =fd.readline().rstrip() - return data + data =fd.readline().strip() + if len(data) > 0: + return data except IOError as e: pass return None def __get_temp(self, temp_file): - temp_file_path = os.path.join(self.hwmon_path, temp_file) + if not self.is_psu: + temp_file_path = os.path.join(self.hwmon_path, temp_file) + else: + temp_file_path = temp_file raw_temp = self.__read_txt_file(temp_file_path) if raw_temp is not None: return float(raw_temp)/1000 @@ -68,6 +200,8 @@ def __get_temp(self, temp_file): return 0 def __set_threshold(self, file_name, temperature): + if self.is_psu: + return True temp_file_path = os.path.join(self.hwmon_path, file_name) for filename in glob.glob(temp_file_path): try: @@ -76,6 +210,7 @@ def __set_threshold(self, file_name, temperature): return True except IOError as e: print("IOError") + return False def get_temperature(self): @@ -85,8 +220,60 @@ def get_temperature(self): A float number of current temperature in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - temp_file = "temp{}_input".format(self.ss_index) - return self.__get_temp(temp_file) + if not self.is_psu: + temp_file = "temp{}_input".format(self.ss_index) + else: + temp_file = self.psu_hwmon_path + "psu_temp1_input" + + current = self.__get_temp(temp_file) + if self.min_temperature is None or current < self.min_temperature: + self.min_temperature = current + + if self.max_temperature is None or current > self.max_temperature: + self.max_temperature = current + + return current + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + value = self.conf.get_high_critical_threshold() + if value != self.conf.NOT_AVAILABLE: + return float(value) + + default_value = self.default_threshold[self.get_name()][self.conf.HIGH_CRIT_THRESHOLD_FIELD] + if default_value != self.conf.NOT_AVAILABLE: + return float(default_value) + + raise NotImplementedError + + def set_high_critical_threshold(self, temperature): + """ + Sets the critical high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + try: + value = float(temperature) + except: + return False + + try: + self.conf.set_high_critical_threshold(str(value)) + except: + return False + + return True def get_high_threshold(self): """ @@ -95,6 +282,9 @@ def get_high_threshold(self): A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ + if self.is_psu: + return 80 + temp_file = "temp{}_max".format(self.ss_index) return self.__get_temp(temp_file) @@ -119,7 +309,10 @@ def get_name(self): Returns: string: The name of the thermal device """ - return self.THERMAL_NAME_LIST[self.index] + if self.is_psu: + return PSU_THERMAL_NAME_LIST[self.psu_index] + else: + return THERMAL_NAME_LIST[self.index] def get_presence(self): """ @@ -127,6 +320,15 @@ def get_presence(self): Returns: bool: True if Thermal is present, False if not """ + if self.is_cpu: + return True + + if self.is_psu: + val = self.__read_txt_file(self.cpld_path + "psu_present") + if val is not None: + return int(val, 10) == 1 + else: + return False temp_file = "temp{}_input".format(self.ss_index) temp_file_path = os.path.join(self.hwmon_path, temp_file) raw_txt = self.__read_txt_file(temp_file_path) @@ -141,6 +343,15 @@ def get_status(self): Returns: A boolean value, True if device is operating properly, False if not """ + if self.is_cpu: + return True + + if self.is_psu: + temp_file = self.psu_hwmon_path + "psu_temp_fault" + psu_temp_fault = self.__read_txt_file(temp_file) + if psu_temp_fault is None: + psu_temp_fault = '1' + return self.get_presence() and (not int(psu_temp_fault)) file_str = "temp{}_input".format(self.ss_index) file_path = os.path.join(self.hwmon_path, file_str) @@ -149,3 +360,58 @@ def get_status(self): return False else: return int(raw_txt) != 0 + + 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_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.index+1 + + def is_replaceable(self): + """ + Retrieves whether thermal module is replaceable + Returns: + A boolean value, True if replaceable, False if not + """ + return False + + def get_minimum_recorded(self): + """ Retrieves the minimum recorded temperature of thermal + Returns: A float number, the minimum recorded temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if self.min_temperature is None: + self.get_temperature() + + return self.min_temperature + + def get_maximum_recorded(self): + """ Retrieves the maximum recorded temperature of thermal + Returns: A float number, the maximum recorded temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if self.max_temperature is None: + self.get_temperature() + + return self.max_temperature + diff --git a/device/accton/x86_64-accton_as9726_32d-r0/system_health_monitoring_config.json b/device/accton/x86_64-accton_as9726_32d-r0/system_health_monitoring_config.json new file mode 100644 index 0000000000..ee6fe350a4 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/system_health_monitoring_config.json @@ -0,0 +1,14 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [ + "asic", + "psu.temperature" + ], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "ControlledByFPGA", + "normal": "ControlledByFPGA", + "booting": "ControlledByFPGA" + } +} diff --git a/device/accton/x86_64-accton_as9726_32d-r0/warm-reboot_plugin b/device/accton/x86_64-accton_as9726_32d-r0/warm-reboot_plugin new file mode 100755 index 0000000000..8e564c07d6 --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/warm-reboot_plugin @@ -0,0 +1,11 @@ +#!/bin/bash + +echo "Stop as9726-32d-platform-monitor-fan.service" +systemctl stop as9726-32d-platform-monitor-fan.service + +echo "Stop as9726-32d-platform-monitor-psu.service" +systemctl stop as9726-32d-platform-monitor-psu.service + +echo "Stop as9726-32d-platform-monitor.service" +systemctl stop as9726-32d-platform-monitor.service + diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/classes/fanutil.py index 4d6e177edc..2384245fed 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/classes/fanutil.py @@ -104,7 +104,7 @@ def _get_fan_node_val(self, fan_num, node_num): return None try: - val_file.close() + val_file.close() except IOError: logging.debug('GET. unable to close file. device_path:%s', device_path) return None @@ -135,7 +135,7 @@ def _set_fan_node_val(self, fan_num, node_num, val): val_file.write(content) try: - val_file.close() + val_file.close() except BaseException: logging.debug('GET. unable to close file. device_path:%s', device_path) return None diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/classes/thermalutil.py index 1f00d72b84..8674ffc097 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/classes/thermalutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/classes/thermalutil.py @@ -70,7 +70,7 @@ def _get_thermal_val(self, thermal_num): logging.debug('GET. content is NULL. device_path:%s', device_path) return None try: - val_file.close() + val_file.close() except BaseException: logging.debug('GET. unable to close file. device_path:%s', device_path) return None diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/accton_psu_api.h b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/accton_psu_api.h new file mode 120000 index 0000000000..a6b156930a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/accton_psu_api.h @@ -0,0 +1 @@ +../../common/modules/accton_psu_api.h \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/accton_psu_defs.h b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/accton_psu_defs.h new file mode 120000 index 0000000000..96202b3ead --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/accton_psu_defs.h @@ -0,0 +1 @@ +../../common/modules/accton_psu_defs.h \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-cpld.c b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-cpld.c index 096d1384b6..b1a2d03158 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-cpld.c @@ -72,6 +72,7 @@ MODULE_DEVICE_TABLE(i2c, as9726_32d_cpld_id); #define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index #define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index #define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index +#define TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index #define CPLD_INTR_ATTR_ID(index) CPLD_INTR_##index enum as9726_32d_cpld_sysfs_attributes { @@ -150,6 +151,38 @@ enum as9726_32d_cpld_sysfs_attributes { TRANSCEIVER_RESET_ATTR_ID(30), TRANSCEIVER_RESET_ATTR_ID(31), TRANSCEIVER_RESET_ATTR_ID(32), + TRANSCEIVER_LPMODE_ATTR_ID(1), + TRANSCEIVER_LPMODE_ATTR_ID(2), + TRANSCEIVER_LPMODE_ATTR_ID(3), + TRANSCEIVER_LPMODE_ATTR_ID(4), + TRANSCEIVER_LPMODE_ATTR_ID(5), + TRANSCEIVER_LPMODE_ATTR_ID(6), + TRANSCEIVER_LPMODE_ATTR_ID(7), + TRANSCEIVER_LPMODE_ATTR_ID(8), + TRANSCEIVER_LPMODE_ATTR_ID(9), + TRANSCEIVER_LPMODE_ATTR_ID(10), + TRANSCEIVER_LPMODE_ATTR_ID(11), + TRANSCEIVER_LPMODE_ATTR_ID(12), + TRANSCEIVER_LPMODE_ATTR_ID(13), + TRANSCEIVER_LPMODE_ATTR_ID(14), + TRANSCEIVER_LPMODE_ATTR_ID(15), + TRANSCEIVER_LPMODE_ATTR_ID(16), + TRANSCEIVER_LPMODE_ATTR_ID(17), + TRANSCEIVER_LPMODE_ATTR_ID(18), + TRANSCEIVER_LPMODE_ATTR_ID(19), + TRANSCEIVER_LPMODE_ATTR_ID(20), + TRANSCEIVER_LPMODE_ATTR_ID(21), + TRANSCEIVER_LPMODE_ATTR_ID(22), + TRANSCEIVER_LPMODE_ATTR_ID(23), + TRANSCEIVER_LPMODE_ATTR_ID(24), + TRANSCEIVER_LPMODE_ATTR_ID(25), + TRANSCEIVER_LPMODE_ATTR_ID(26), + TRANSCEIVER_LPMODE_ATTR_ID(27), + TRANSCEIVER_LPMODE_ATTR_ID(28), + TRANSCEIVER_LPMODE_ATTR_ID(29), + TRANSCEIVER_LPMODE_ATTR_ID(30), + TRANSCEIVER_LPMODE_ATTR_ID(31), + TRANSCEIVER_LPMODE_ATTR_ID(32), CPLD_INTR_ATTR_ID(1), CPLD_INTR_ATTR_ID(2), CPLD_INTR_ATTR_ID(3), @@ -173,6 +206,10 @@ static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t get_mode_lpmode(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_mode_lpmode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); static int as9726_32d_cpld_read_internal(struct i2c_client *client, u8 reg); static int as9726_32d_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); @@ -201,6 +238,10 @@ static int as9726_32d_cpld_write_internal(struct i2c_client *client, u8 reg, u8 static SENSOR_DEVICE_ATTR(cpld_intr_##index, S_IRUGO, show_interrupt, NULL, CPLD_INTR_##index) #define DECLARE_CPLD_INTR_ATTR(index) &sensor_dev_attr_cpld_intr_##index.dev_attr.attr +/*lpmode*/ +#define DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_lpmode_##index, S_IWUSR | S_IRUGO, get_mode_lpmode, set_mode_lpmode, MODULE_LPMODE_##index) +#define DECLARE_TRANSCEIVER_LPMODE_ATTR(index) &sensor_dev_attr_module_lpmode_##index.dev_attr.attr static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); @@ -278,6 +319,38 @@ DECLARE_CPLD_DEVICE_INTR_ATTR(1); DECLARE_CPLD_DEVICE_INTR_ATTR(2); DECLARE_CPLD_DEVICE_INTR_ATTR(3); DECLARE_CPLD_DEVICE_INTR_ATTR(4); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(1); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(2); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(3); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(4); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(5); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(6); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(7); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(8); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(9); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(10); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(11); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(12); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(13); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(14); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(15); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(16); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(17); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(18); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(19); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(20); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(21); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(22); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(23); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(24); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(25); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(26); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(27); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(28); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(29); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(30); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(31); +DECLARE_TRANSCEIVER_LPMODE_SENSOR_DEVICE_ATTR(32); @@ -326,6 +399,22 @@ static struct attribute *as9726_32d_cpld2_attributes[] = { DECLARE_TRANSCEIVER_RESET_ATTR(14), DECLARE_TRANSCEIVER_RESET_ATTR(15), DECLARE_TRANSCEIVER_RESET_ATTR(16), + DECLARE_TRANSCEIVER_LPMODE_ATTR(1), + DECLARE_TRANSCEIVER_LPMODE_ATTR(2), + DECLARE_TRANSCEIVER_LPMODE_ATTR(3), + DECLARE_TRANSCEIVER_LPMODE_ATTR(4), + DECLARE_TRANSCEIVER_LPMODE_ATTR(5), + DECLARE_TRANSCEIVER_LPMODE_ATTR(6), + DECLARE_TRANSCEIVER_LPMODE_ATTR(7), + DECLARE_TRANSCEIVER_LPMODE_ATTR(8), + DECLARE_TRANSCEIVER_LPMODE_ATTR(9), + DECLARE_TRANSCEIVER_LPMODE_ATTR(10), + DECLARE_TRANSCEIVER_LPMODE_ATTR(11), + DECLARE_TRANSCEIVER_LPMODE_ATTR(12), + DECLARE_TRANSCEIVER_LPMODE_ATTR(13), + DECLARE_TRANSCEIVER_LPMODE_ATTR(14), + DECLARE_TRANSCEIVER_LPMODE_ATTR(15), + DECLARE_TRANSCEIVER_LPMODE_ATTR(16), DECLARE_CPLD_INTR_ATTR(1), DECLARE_CPLD_INTR_ATTR(2), NULL @@ -374,6 +463,22 @@ static struct attribute *as9726_32d_cpld3_attributes[] = { DECLARE_TRANSCEIVER_RESET_ATTR(30), DECLARE_TRANSCEIVER_RESET_ATTR(31), DECLARE_TRANSCEIVER_RESET_ATTR(32), + DECLARE_TRANSCEIVER_LPMODE_ATTR(17), + DECLARE_TRANSCEIVER_LPMODE_ATTR(18), + DECLARE_TRANSCEIVER_LPMODE_ATTR(19), + DECLARE_TRANSCEIVER_LPMODE_ATTR(20), + DECLARE_TRANSCEIVER_LPMODE_ATTR(21), + DECLARE_TRANSCEIVER_LPMODE_ATTR(22), + DECLARE_TRANSCEIVER_LPMODE_ATTR(23), + DECLARE_TRANSCEIVER_LPMODE_ATTR(24), + DECLARE_TRANSCEIVER_LPMODE_ATTR(25), + DECLARE_TRANSCEIVER_LPMODE_ATTR(26), + DECLARE_TRANSCEIVER_LPMODE_ATTR(27), + DECLARE_TRANSCEIVER_LPMODE_ATTR(28), + DECLARE_TRANSCEIVER_LPMODE_ATTR(29), + DECLARE_TRANSCEIVER_LPMODE_ATTR(30), + DECLARE_TRANSCEIVER_LPMODE_ATTR(31), + DECLARE_TRANSCEIVER_LPMODE_ATTR(32), DECLARE_CPLD_INTR_ATTR(3), DECLARE_CPLD_INTR_ATTR(4), NULL @@ -647,6 +752,116 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c return sprintf(buf, "0x%x\n", val); } +static ssize_t get_mode_lpmode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as9726_32d_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0; + + switch (attr->index) { + case MODULE_LPMODE_1 ... MODULE_LPMODE_8: + reg = 0x60; + mask = 0x1 << (attr->index - MODULE_LPMODE_1); + break; + case MODULE_LPMODE_9 ... MODULE_LPMODE_16: + reg = 0x61; + mask = 0x1 << (attr->index - MODULE_LPMODE_9); + break; + case MODULE_LPMODE_17 ... MODULE_LPMODE_24: + reg = 0x60; + mask = 0x1 << (attr->index - MODULE_LPMODE_17); + break; + case MODULE_LPMODE_25 ... MODULE_LPMODE_32: + reg = 0x61; + mask = 0x1 << (attr->index - MODULE_LPMODE_25); + break; + default: + return 0; + } + + mutex_lock(&data->update_lock); + status = as9726_32d_cpld_read_internal(client, reg); + + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\r\n", !(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; + +} + +static ssize_t set_mode_lpmode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as9726_32d_cpld_data *data = i2c_get_clientdata(client); + long lpmode; + int status=0, val, error; + u8 reg = 0, mask = 0; + + error = kstrtol(buf, 10, &lpmode); + if (error) { + return error; + } + + switch (attr->index) { + case MODULE_LPMODE_1 ... MODULE_LPMODE_8: + reg = 0x60; + mask = 0x1 << (attr->index - MODULE_LPMODE_1); + break; + case MODULE_LPMODE_9 ... MODULE_LPMODE_16: + reg = 0x61; + mask = 0x1 << (attr->index - MODULE_LPMODE_9); + break; + case MODULE_LPMODE_17 ... MODULE_LPMODE_24: + reg = 0x60; + mask = 0x1 << (attr->index - MODULE_LPMODE_17); + break; + case MODULE_LPMODE_25 ... MODULE_LPMODE_32: + reg = 0x61; + mask = 0x1 << (attr->index - MODULE_LPMODE_25); + break; + default: + return 0; + } + mutex_lock(&data->update_lock); + + status = as9726_32d_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update lp_mode status */ + if (lpmode) + { + val = status&(~mask); + } + else + { + val =status | (mask); + } + + status = as9726_32d_cpld_write_internal(client, reg, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, char *buf) { @@ -769,7 +984,7 @@ static int as9726_32d_cpld_probe(struct i2c_client *client, struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); struct as9726_32d_cpld_data *data; int ret = -ENODEV; - int status; + int status; const struct attribute_group *group = NULL; if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-fan.c b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-fan.c index 67a015f01c..88d2ddf516 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-fan.c +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-fan.c @@ -42,6 +42,7 @@ static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, /* fan related data, the index should match sysfs_fan_attributes */ static const u8 fan_reg[] = { + 0x01, /* fan cpld version */ 0x0F, /* fan 1-6 present status */ 0x10, /* fan 1-6 direction(0:F2B 1:B2F) */ 0x11, /* fan PWM(for all fan) */ @@ -80,6 +81,7 @@ enum fan_id { }; enum sysfs_fan_attributes { + FAN_VERSION, FAN_PRESENT_REG, FAN_DIRECTION_REG, FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ @@ -148,6 +150,12 @@ enum sysfs_fan_attributes { &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ &sensor_dev_attr_fan##index2##_input.dev_attr.attr +#define DECLARE_FAN_VERSION_SENSOR_DEV_ATTR() \ + static SENSOR_DEVICE_ATTR(version, S_IRUGO, fan_show_value, NULL, FAN_VERSION) + +#define DECLARE_FAN_VERSION_ATTR() &sensor_dev_attr_version.dev_attr.attr + + /* 6 fan fault attributes in this platform */ DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1); DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2); @@ -178,6 +186,7 @@ DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(6); /* 1 fan duty cycle attribute in this platform */ DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); +DECLARE_FAN_VERSION_SENSOR_DEV_ATTR(); static struct attribute *as9726_32d_fan_attributes[] = { /* fan related attributes */ @@ -206,6 +215,7 @@ static struct attribute *as9726_32d_fan_attributes[] = { DECLARE_FAN_DIRECTION_ATTR(5), DECLARE_FAN_DIRECTION_ATTR(6), DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_VERSION_ATTR(), NULL }; @@ -367,6 +377,11 @@ static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, if (data->valid) { switch (attr->index) { + case FAN_VERSION: + { + ret = sprintf(buf, "%x\n", data->reg_val[FAN_VERSION]); + break; + } case FAN_DUTY_CYCLE_PERCENTAGE: { u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-psu.c b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-psu.c index cdf11f503d..9ab685c842 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/x86-64-accton-as9726-32d-psu.c @@ -33,8 +33,9 @@ #include #include #include +#include "accton_psu_api.h" -#define MAX_MODEL_NAME 20 +#define MAX_MODEL_NAME 12 #define MAX_SERIAL_NUMBER 19 static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); @@ -94,15 +95,15 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, //printk("data->status=0x%x, attr->index=%d,data->index=%d \n", data->status, attr->index, data->index); if (attr->index == PSU_PRESENT) { if(data->index==0) - status = !( (data->status) & 0x1); - else status = !( (data->status >> 1) & 0x1); + else + status = !( (data->status) & 0x1); } else { /* PSU_POWER_GOOD */ if(data->index==0) - status = ( (data->status >> 2) & 0x1); + status = ( (data->status >> 3) & 0x1); else - status = ( (data->status >> 3) & 0x1); + status = ( (data->status >> 2) & 0x1); } return sprintf(buf, "%d\n", status); @@ -279,11 +280,11 @@ static struct as9726_32d_psu_data *as9726_32d_psu_update_device(struct device *d /* Read model name */ memset(data->model_name, 0, sizeof(data->model_name)); memset(data->serial_number, 0, sizeof(data->serial_number)); - psu_present = (data->status >> (data->index) & 0x1); //0:present, 1:not present + psu_present = (data->status >> (1 - data->index) & 0x1); //0:present, 1:not present if (!psu_present) { - status = as9726_32d_psu_read_block(client, 0x20, data->model_name, - ARRAY_SIZE(data->model_name)-1); + status = as9726_32d_psu_read_block(client, 0x21, data->model_name, + ARRAY_SIZE(data->model_name)-1); if (status < 0) { data->model_name[0] = '\0'; dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); @@ -294,14 +295,15 @@ static struct as9726_32d_psu_data *as9726_32d_psu_update_device(struct device *d } /* Read from offset 0x35 ~ 0x46 (18 bytes) */ - status = as9726_32d_psu_read_block(client, 0x35,data->serial_number, MAX_SERIAL_NUMBER); + status = as9726_32d_psu_read_block(client, 0x3A,data->serial_number, + ARRAY_SIZE(data->serial_number)-1); if (status < 0) { data->serial_number[0] = '\0'; dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x2e)\n", client->addr); printk("unable to read model name from (0x%x) offset(0x2e)\n", client->addr); } - data->serial_number[MAX_SERIAL_NUMBER-1]='\0'; + data->serial_number[ARRAY_SIZE(data->serial_number)-1]='\0'; } data->last_updated = jiffies; @@ -313,9 +315,81 @@ static struct as9726_32d_psu_data *as9726_32d_psu_update_device(struct device *d return data; } -module_i2c_driver(as9726_32d_psu_driver); +int as9726_32d_psu_get_presence(void *client_ptr) +{ + int status = 0; + int psu_index = 0; + int psu_present = 0; + struct i2c_client *client = NULL; + + if (!client_ptr) + return -EINVAL; + + client = client_ptr; + status = as9726_32d_cpld_read(0x60, 0x03); + if (status < 0) { + dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + return 0; + } + + psu_index = (client->addr == 0x58) ? as9726_32d_psu1 : as9726_32d_psu2; + if (psu_index == as9726_32d_psu1) { + psu_present = !((status >> 1) & 0x1); + } else { + psu_present = !((status) & 0x1); + } + + return psu_present; +} + +int as9726_32d_psu_get_powergood(void *client_ptr) +{ + int status = 0; + int psu_index = 0; + int psu_powergood = 0; + struct i2c_client *client = NULL; + + if (!client_ptr) + return -EINVAL; + + client = client_ptr; + status = as9726_32d_cpld_read(0x60, 0x03); + if (status < 0) { + dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + return 0; + } + + psu_index = (client->addr == 0x58) ? as9726_32d_psu1 : as9726_32d_psu2; + if (psu_index == as9726_32d_psu1) { + psu_powergood = ((status >> 3) & 0x1); + } else { + psu_powergood = ((status >> 2) & 0x1); + } + + return psu_powergood; +} + +static int __init as9726_32d_psu_init(void) +{ + PSU_STATUS_ENTRY access_psu_status = { + as9726_32d_psu_get_presence, + as9726_32d_psu_get_powergood + }; + register_psu_status_entry(&access_psu_status); + + return i2c_add_driver(&as9726_32d_psu_driver); +} + +static void __exit as9726_32d_psu_exit(void) +{ + register_psu_status_entry(NULL); + i2c_del_driver(&as9726_32d_psu_driver); +} + MODULE_AUTHOR("Michael Shih "); MODULE_DESCRIPTION("as9726_32d_psu driver"); MODULE_LICENSE("GPL"); +module_init(as9726_32d_psu_init); +module_exit(as9726_32d_psu_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/ym2651y.c deleted file mode 100755 index 63488d2c6c..0000000000 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/ym2651y.c +++ /dev/null @@ -1,678 +0,0 @@ -/* - * An hwmon driver for the 3Y Power YM-2651Y Power Module - * - * Copyright (C) 2014 Accton Technology Corporation. - * Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_FAN_DUTY_CYCLE 100 - -/* Addresses scanned - */ -static const unsigned short normal_i2c[] = { 0x58, 0x59, I2C_CLIENT_END }; - -enum chips { - YM2651, - YM2401, - YM2851, - YPEB1200AM, -}; - -/* Each client has this additional data - */ -struct ym2651y_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 chip; /* chip id */ - u8 capability; /* Register value */ - u16 status_word; /* Register value */ - u8 fan_fault; /* Register value */ - u8 over_temp; /* Register value */ - u16 v_out; /* Register value */ - u16 i_out; /* Register value */ - u16 p_out; /* Register value */ - u8 vout_mode; /* Register value */ - u16 temp; /* Register value */ - u16 fan_speed; /* Register value */ - u16 fan_duty_cycle[2]; /* Register value */ - u8 fan_dir[4]; /* Register value */ - u8 pmbus_revision; /* Register value */ - u8 mfr_id[10]; /* Register value */ - u8 mfr_model[10]; /* Register value */ - u8 mfr_revsion[3]; /* Register value */ - u16 mfr_vin_min; /* Register value */ - u16 mfr_vin_max; /* Register value */ - u16 mfr_iin_max; /* Register value */ - u16 mfr_iout_max; /* Register value */ - u16 mfr_pin_max; /* Register value */ - u16 mfr_pout_max; /* Register value */ - u16 mfr_vout_min; /* Register value */ - u16 mfr_vout_max; /* Register value */ -}; - -static ssize_t show_vout(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf); -static struct ym2651y_data *ym2651y_update_device(struct device *dev); -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); - -enum ym2651y_sysfs_attributes { - PSU_POWER_ON = 0, - PSU_TEMP_FAULT, - PSU_POWER_GOOD, - PSU_FAN1_FAULT, - PSU_FAN_DIRECTION, - PSU_OVER_TEMP, - PSU_V_OUT, - PSU_I_OUT, - PSU_P_OUT, - PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/ - PSU_TEMP1_INPUT, - PSU_FAN1_SPEED, - PSU_FAN1_DUTY_CYCLE, - PSU_PMBUS_REVISION, - PSU_MFR_ID, - PSU_MFR_MODEL, - PSU_MFR_REVISION, - PSU_MFR_VIN_MIN, - PSU_MFR_VIN_MAX, - PSU_MFR_VOUT_MIN, - PSU_MFR_VOUT_MAX, - PSU_MFR_IIN_MAX, - PSU_MFR_IOUT_MAX, - PSU_MFR_PIN_MAX, - PSU_MFR_POUT_MAX -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); -static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); -static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); -static SENSOR_DEVICE_ATTR(psu_pmbus_revision, S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); -static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); -static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); - -/*Duplicate nodes for lm-sensors.*/ -static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_vout, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_linear, NULL, PSU_P_OUT_UV); -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); - -static struct attribute *ym2651y_attributes[] = { - &sensor_dev_attr_psu_power_on.dev_attr.attr, - &sensor_dev_attr_psu_temp_fault.dev_attr.attr, - &sensor_dev_attr_psu_power_good.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_over_temp.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan_dir.dev_attr.attr, - &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_id.dev_attr.attr, - &sensor_dev_attr_psu_mfr_model.dev_attr.attr, - &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, - /*Duplicate nodes for lm-sensors.*/ - &sensor_dev_attr_curr2_input.dev_attr.attr, - &sensor_dev_attr_in3_input.dev_attr.attr, - &sensor_dev_attr_power2_input.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_temp1_fault.dev_attr.attr, - NULL -}; - -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : - sprintf(buf, "0\n"); -} - -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u16 status = 0; - - switch (attr->index) { - case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ - status = (data->status_word & 0x40) ? 0 : 1; - break; - case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ - status = (data->status_word & 0x4) >> 2; - break; - case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ - status = (data->status_word & 0x800) ? 0 : 1; - break; - } - - return sprintf(buf, "%d\n", status); -} - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask) -{ - u16 valid_data = data & mask; - bool is_negative = valid_data >> (valid_bit - 1); - - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; -} - -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; - - error = kstrtol(buf, 10, &speed); - if (error) - return error; - - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; - - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; - ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; - - switch (attr->index) { - case PSU_V_OUT: - value = data->v_out; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_OUT_UV: - multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ - /*Passing through*/ - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp; - break; - case PSU_FAN1_SPEED: - value = data->fan_speed; - multiplier = 1; - break; - case PSU_FAN1_DUTY_CYCLE: - value = data->fan_duty_cycle[0]; - multiplier = 1; - break; - case PSU_MFR_VIN_MIN: - value = data->mfr_vin_min; - break; - case PSU_MFR_VIN_MAX: - value = data->mfr_vin_max; - break; - case PSU_MFR_VOUT_MIN: - value = data->mfr_vout_min; - break; - case PSU_MFR_VOUT_MAX: - value = data->mfr_vout_max; - break; - case PSU_MFR_PIN_MAX: - value = data->mfr_pin_max; - break; - case PSU_MFR_POUT_MAX: - value = data->mfr_pout_max; - break; - case PSU_MFR_IOUT_MAX: - value = data->mfr_iout_max; - break; - case PSU_MFR_IIN_MAX: - value = data->mfr_iin_max; - break; - } - - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct ym2651y_data *data = ym2651y_update_device(dev); - - return sprintf(buf, "%d\n", data->over_temp >> 7); -} - -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u8 *ptr = NULL; - - switch (attr->index) { - case PSU_FAN_DIRECTION: /* psu_fan_dir */ - if (data->chip==YPEB1200AM) - { - memcpy(data->fan_dir, "F2B", 3); - data->fan_dir[3]='\0'; - } - ptr = data->fan_dir; - break; - case PSU_MFR_ID: /* psu_mfr_id */ - ptr = data->mfr_id; - break; - case PSU_MFR_MODEL: /* psu_mfr_model */ - ptr = data->mfr_model; - break; - case PSU_MFR_REVISION: /* psu_mfr_revision */ - ptr = data->mfr_revsion; - break; - default: - return 0; - } - - return sprintf(buf, "%s\n", ptr); -} - -static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - int exponent, mantissa; - int multiplier = 1000; - - if (!data->valid) { - return 0; - } - - exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); - switch (attr->index) { - case PSU_MFR_VOUT_MIN: - mantissa = data->mfr_vout_min; - break; - case PSU_MFR_VOUT_MAX: - mantissa = data->mfr_vout_max; - break; - case PSU_V_OUT: - mantissa = data->v_out; - break; - default: - return 0; - } - - return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t show_vout(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - u8 *ptr = NULL; - - ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */ - if (data->chip == YM2401) { - return show_vout_by_mode(dev, da, buf); - } - else { - return show_linear(dev, da, buf); - } -} - -static const struct attribute_group ym2651y_group = { - .attrs = ym2651y_attributes, -}; - -static int ym2651y_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - struct ym2651y_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_I2C_BLOCK)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - data->chip = dev_id->driver_data; - dev_info(&client->dev, "chip found\n"); - - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); - if (status) { - goto exit_free; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - dev_info(&client->dev, "%s: psu '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); -exit_free: - kfree(data); -exit: - - return status; -} - -static int ym2651y_remove(struct i2c_client *client) -{ - struct ym2651y_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); - kfree(data); - - return 0; -} - -static const struct i2c_device_id ym2651y_id[] = { - { "ym2651", YM2651 }, - { "ym2401", YM2401 }, - { "ym2851", YM2851 }, - { "ype1200am", YPEB1200AM }, - {} -}; -MODULE_DEVICE_TABLE(i2c, ym2651y_id); - -static struct i2c_driver ym2651y_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ym2651", - }, - .probe = ym2651y_probe, - .remove = ym2651y_remove, - .id_table = ym2651y_id, - .address_list = normal_i2c, -}; - -static int ym2651y_read_byte(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -static int ym2651y_read_word(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_word_data(client, reg); -} - -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) -{ - return i2c_smbus_write_word_data(client, reg, value); -} - -static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, - int data_len) -{ - int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); - - if (unlikely(result < 0)) - goto abort; - if (unlikely(result != data_len)) { - result = -EIO; - goto abort; - } - - result = 0; - -abort: - return result; -} - -struct reg_data_byte { - u8 reg; - u8 *value; -}; - -struct reg_data_word { - u8 reg; - u16 *value; -}; - -static struct ym2651y_data *ym2651y_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i, status; - u8 command; - u8 fan_dir[5] = {0}; - struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, - {0x20, &data->vout_mode}, - {0x7d, &data->over_temp}, - {0x81, &data->fan_fault}, - {0x98, &data->pmbus_revision} - }; - struct reg_data_word regs_word[] = { {0x79, &data->status_word}, - {0x8b, &data->v_out}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x8d, &data->temp}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x3c, &(data->fan_duty_cycle[1])}, - {0x90, &data->fan_speed}, - {0xa0, &data->mfr_vin_min}, - {0xa1, &data->mfr_vin_max}, - {0xa2, &data->mfr_iin_max}, - {0xa3, &data->mfr_pin_max}, - {0xa4, &data->mfr_vout_min}, - {0xa5, &data->mfr_vout_max}, - {0xa6, &data->mfr_iout_max}, - {0xa7, &data->mfr_pout_max} - }; - - dev_dbg(&client->dev, "Starting ym2651 update\n"); - - /* Read byte data */ - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = ym2651y_read_byte(client, regs_byte[i].reg); - - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - *(regs_byte[i].value) = 0; - } - else { - *(regs_byte[i].value) = status; - } - } - - /* Read word data */ - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { - status = ym2651y_read_word(client, regs_word[i].reg); - - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - *(regs_word[i].value) = 0; - } - else { - *(regs_word[i].value) = status; - } - } - - /* Read fan_direction */ - command = 0xC3; - status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - - strncpy(data->fan_dir, fan_dir+1, ARRAY_SIZE(data->fan_dir)-1); - data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; - - /* Read mfr_id */ - command = 0x99; - status = ym2651y_read_block(client, command, data->mfr_id, - ARRAY_SIZE(data->mfr_id)-1); - data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; - - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - - /* Read mfr_model */ - command = 0x9a; - status = ym2651y_read_block(client, command, data->mfr_model, - ARRAY_SIZE(data->mfr_model)-1); - data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0'; - - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - - /* Read mfr_revsion */ - command = 0x9b; - status = ym2651y_read_block(client, command, data->mfr_revsion, - ARRAY_SIZE(data->mfr_revsion)-1); - data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; - - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -module_i2c_driver(ym2651y_driver); - -MODULE_AUTHOR("Michael Shih "); -MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); -MODULE_LICENSE("GPL"); - - diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/ym2651y.c new file mode 120000 index 0000000000..f4d67640cc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/modules/ym2651y.c @@ -0,0 +1 @@ +../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor-fan.service b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor-fan.service index ac0114c8f5..8b4b18bee3 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor-fan.service +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor-fan.service @@ -6,8 +6,6 @@ DefaultDependencies=no [Service] ExecStart=/usr/local/bin/accton_as9726_32d_monitor_fan.py -KillSignal=SIGKILL -SuccessExitStatus=SIGKILL # Resource Limitations LimitCORE=infinity diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor-psu.service b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor-psu.service index 916219c9f7..93bba25cb5 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor-psu.service +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor-psu.service @@ -6,8 +6,6 @@ DefaultDependencies=no [Service] ExecStart=/usr/local/bin/accton_as9726_32d_monitor_psu.py -KillSignal=SIGKILL -SuccessExitStatus=SIGKILL # Resource Limitations LimitCORE=infinity diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor.service index 072a8227e7..e3328ddb8c 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor.service +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/service/as9726-32d-platform-monitor.service @@ -7,8 +7,6 @@ DefaultDependencies=no [Service] ExecStartPre=/usr/local/bin/accton_as9726_32d_util.py install ExecStart=/usr/local/bin/accton_as9726_32d_monitor.py -KillSignal=SIGKILL -SuccessExitStatus=SIGKILL # Resource Limitations LimitCORE=infinity diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor.py index da399becba..64becc6fee 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor.py @@ -13,9 +13,9 @@ # # See the Apache Version 2.0 License for specific language governing # permissions and limitations under the License. -# +# # HISTORY: -# mm/dd/yyyy (A.D.)# +# mm/dd/yyyy (A.D.)# # 04/23/2021: Michael_Shih create for as9726_32d thermal plan # ------------------------------------------------------------------ @@ -26,9 +26,13 @@ import logging import logging.config import logging.handlers + import signal import time # this is only being used as part of the example from as9726_32d.fanutil import FanUtil from as9726_32d.thermalutil import ThermalUtil + from swsscommon import swsscommon + from sonic_py_common.general import getstatusoutput_noshell + from sonic_platform import platform except ImportError as e: raise ImportError('%s - required module not found' % str(e)) @@ -36,16 +40,20 @@ VERSION = '1.0' FUNCTION_NAME = '/usr/local/bin/accton_as9726_32d_monitor' +STATE_DB = 'STATE_DB' +TRANSCEIVER_DOM_SENSOR_TABLE = 'TRANSCEIVER_DOM_SENSOR' +TEMPERATURE_FIELD_NAME = 'temperature' + class switch(object): def __init__(self, value): self.value = value self.fall = False - + def __iter__(self): """Return the match method once, then stop""" yield self.match raise StopIteration - + def match(self, *args): """Indicate whether or not to enter a case suite""" if self.fall or not args: @@ -88,6 +96,7 @@ def match(self, *args): # (CPU board) # Core>=50 # LM75-1(0X4B)>=43.4 +# Transceiver >=65 #Yellow Alarm #MB board @@ -99,6 +108,7 @@ def match(self, *args): #CPU Board #Core>=52 #LM75-1(0X4B)>=41.8 +#Transceiver >=73 #Red Alarm #MB board @@ -110,6 +120,7 @@ def match(self, *args): #CPU Board #Core>=57 #LM75-1(0X4B)>=46.8 +#Transceiver >=75 #Shut down #MB board @@ -121,7 +132,8 @@ def match(self, *args): #CPU Board #Core>=62 #LM75-1(0X4B)>=51.8 - +#Transceiver >=77 + # 2. For AFO: # At default, FAN duty_cycle was 100%(LEVEL_FAN_MAX). If all below case meet with, set to 75%(LEVEL_FAN_MID). # (MB board) @@ -144,7 +156,7 @@ def match(self, *args): # (CPU board) # Core<=56 # LM75-1(0X4B)<=38.8 - + # When fan_speed 50%(LEVEL_FAN_DEF). # Meet with below case, Fan duty_cycle will be 75%(LEVEL_FAN_MID) # (MB board) @@ -156,6 +168,7 @@ def match(self, *args): # (CPU board) # Core>=72 # LM75-1(0X4B)>=50 +# Transceiver >=55 # When FAN duty_cycle was 75%(LEVEL_FAN_MID). If all below case meet with, set to 100%(LEVEL_FAN_MAX). # (MB board) @@ -168,6 +181,7 @@ def match(self, *args): # (CPU board) # Core >=69 # LM75-1(0X4B)>=51.5 +# Transceiver >=65 #Yellow Alarm @@ -180,6 +194,7 @@ def match(self, *args): #CPU Board #Core>=73 #LM75-1(0X4B)>=67 +#Transceiver >=73 #Red Alarm #MB board @@ -191,6 +206,7 @@ def match(self, *args): #CPU Board #Core>=78 #LM75-1(0X4B)>=72 +#Transceiver >=75 #Shut down #MB board @@ -202,11 +218,17 @@ def match(self, *args): #CPU Board #Core>=83 #LM75-1(0X4B)>=77 +#Transceiver >=77 def power_off_dut(): - cmd_str="i2cset -y -f 1 0x60 0x60 0x10" - status, output = subprocess.getstatusoutput(cmd_str) - return status + cmd_str = ["i2cset", "-y", "-f", "19", "0x60", "0x60", "0x10"] + (status, output) = getstatusoutput_noshell(cmd_str) + return (status == 0) + +def shutdown_transceiver(iface_name): + cmd_str = ["config", "interface", "shutdown", str(iface_name)] + (status, output) = getstatusoutput_noshell(cmd_str) + return (status == 0) #If only one PSU insert(or one of PSU pwoer fail), and watt >800w. Must let DUT fan pwm >= 75% in AFO. # Because the psu temp is high. @@ -214,7 +236,7 @@ def power_off_dut(): # Return 0: Not full load def check_psu_loading(): psu_power_status=[1, 1] - + psu_power_good = { 2: "/sys/bus/i2c/devices/9-0051/psu_power_good", 1: "/sys/bus/i2c/devices/9-0050/psu_power_good", @@ -223,7 +245,7 @@ def check_psu_loading(): 2: "/sys/bus/i2c/devices/9-0059/psu_p_out", 1: "/sys/bus/i2c/devices/9-0058/psu_p_out", } - + check_psu_watt=0 for i in range(1,3): node = psu_power_good[i] @@ -232,11 +254,11 @@ def check_psu_loading(): status = int(power_status.read()) except IOError: return None - + psu_power_status[i-1]=int(status) if status==0: - check_psu_watt=1 - + check_psu_watt=1 + if check_psu_watt: for i in range(1,3): if psu_power_status[i-1]==1: @@ -252,8 +274,7 @@ def check_psu_loading(): return True else: return False - - + return False fan_policy_state=0 @@ -268,6 +289,10 @@ def check_psu_loading(): temp_test_data=0 test_temp_revert=0 +exit_by_sigterm=0 + +platform_chassis= None + # Make a class we can use to capture stdout and sterr in the log class device_monitor(object): # static temp var @@ -275,7 +300,7 @@ class device_monitor(object): new_duty_cycle = 0 duty_cycle=0 ori_duty_cycle = 0 - + def __init__(self, log_file, log_level): """Needs a logger and a logger level.""" @@ -299,13 +324,28 @@ def __init__(self, log_file, log_level): logging.getLogger('').addHandler(console) sys_handler = logging.handlers.SysLogHandler(address = '/dev/log') - sys_handler.setLevel(logging.WARNING) + sys_handler.setLevel(logging.WARNING) logging.getLogger('').addHandler(sys_handler) #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) - - + + self.transceiver_dom_sensor_table = None + + def get_transceiver_temperature(self, iface_name): + if self.transceiver_dom_sensor_table is None: + return 0.0 + + (status, ret) = self.transceiver_dom_sensor_table.hget(iface_name, TEMPERATURE_FIELD_NAME) + if status: + try: + return float(ret) + except (TypeError, ValueError): + pass + + return 0.0 + def manage_fans(self): - + + global platform_chassis global fan_policy_state global fan_policy_alarm global send_yellow_alarm @@ -316,17 +356,17 @@ def manage_fans(self): global test_temp_list global temp_test_data global test_temp_revert - + CHECK_TIMES=3 - + LEVEL_FAN_INIT=0 LEVEL_FAN_MIN=1 - LEVEL_FAN_MID=2 + LEVEL_FAN_MID=2 LEVEL_FAN_MAX=3 LEVEL_FAN_YELLOW_ALARM=4 LEVEL_FAN_RED_ALARM=5 LEVEL_FAN_SHUTDOWN=6 - + fan_policy_f2b = { #AFO LEVEL_FAN_MIN: [50, 0x7], LEVEL_FAN_MID: [75, 0xb], @@ -336,103 +376,166 @@ def manage_fans(self): LEVEL_FAN_MID: [75, 0xb], LEVEL_FAN_MAX: [100, 0xf] } - - afi_thermal_spec={ - "mid_to_max_temp":[61500, 51500, 49400, 49400, 45100, 46750, 48000, 38500], - "max_to_mid_temp":[57000, 47300, 45000, 45100, 40750, 42100, 44000, 35000], - "max_to_yellow_alarm": [57900, 51900, 48900, 55900, 48500, 52000, 41800], - "yellow_to_red_alarm": [62900, 56900, 53900, 58900, 53500, 57000, 46800], - "red_alarm_to_shutdown": [67900, 61900, 58900, 63900, 58500, 62000, 51800] + + TYPE_SENSOR = 1 + TYPE_TRANSCEIVER = 2 + # Support ZR/ZR+ Allocation Port + monitor_port = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31] + TRANSCEIVER_NUM_MAX = len(monitor_port) + + afi_thermal_spec = { + "mid_to_max_temp" : [(TYPE_SENSOR, 55900), (TYPE_SENSOR, 48800), (TYPE_SENSOR, 51500), (TYPE_SENSOR, 45300), + (TYPE_SENSOR, 43400), (TYPE_SENSOR, 50000), (TYPE_SENSOR, 43400)], + "max_to_mid_temp" : [(TYPE_SENSOR, 49500), (TYPE_SENSOR, 42900), (TYPE_SENSOR, 46300), (TYPE_SENSOR, 40100), + (TYPE_SENSOR, 39400), (TYPE_SENSOR, 46000), (TYPE_SENSOR, 34800)], + "max_to_yellow_alarm" : [(TYPE_SENSOR, 57900), (TYPE_SENSOR, 51900), (TYPE_SENSOR, 48900), (TYPE_SENSOR, 55900), + (TYPE_SENSOR, 48500), (TYPE_SENSOR, 52000), (TYPE_SENSOR, 41800)], + "yellow_to_red_alarm" : [(TYPE_SENSOR, 62900), (TYPE_SENSOR, 56900), (TYPE_SENSOR, 53900), (TYPE_SENSOR, 58900), + (TYPE_SENSOR, 53500), (TYPE_SENSOR, 57000), (TYPE_SENSOR, 46800)], + "red_alarm_to_shutdown": [(TYPE_SENSOR, 67900), (TYPE_SENSOR, 61900), (TYPE_SENSOR, 58900), (TYPE_SENSOR, 63900), + (TYPE_SENSOR, 58500), (TYPE_SENSOR, 62000), (TYPE_SENSOR, 51800)] } - afo_thermal_spec={ - "min_to_mid_temp": [63000, 60500, 60000, 60000, 61000, 72000, 50000], - "mid_to_max_temp": [63000, 60000, 60000, 59000, 60000, 69000, 51500], - "max_to_mid_temp": [56000, 53500, 52500, 52000, 52800, 62000, 45800], - "mid_to_min_temp": [50000, 47300, 46400, 44600, 47000, 56000, 38800], - "max_to_yellow_alarm": [67000, 65000, 64000, 62000, 64000, 73000, 67000], - "yellow_to_red_alarm": [72000, 70000, 69000, 67000, 69000, 78000, 72000], - "red_alarm_to_shutdown": [77000, 75000, 74000, 72000, 74000, 83000, 77000] + afi_thermal_spec["mid_to_max_temp"] += [(TYPE_TRANSCEIVER, 65000)]*TRANSCEIVER_NUM_MAX + afi_thermal_spec["max_to_mid_temp"] += [(TYPE_TRANSCEIVER, 64000)]*TRANSCEIVER_NUM_MAX + afi_thermal_spec["max_to_yellow_alarm"] += [(TYPE_TRANSCEIVER, 73000)]*TRANSCEIVER_NUM_MAX + afi_thermal_spec["yellow_to_red_alarm"] += [(TYPE_TRANSCEIVER, 75000)]*TRANSCEIVER_NUM_MAX + afi_thermal_spec["red_alarm_to_shutdown"] += [(TYPE_TRANSCEIVER, 77000)]*TRANSCEIVER_NUM_MAX + + afo_thermal_spec = { + "min_to_mid_temp" : [(TYPE_SENSOR, 63000), (TYPE_SENSOR, 60500), (TYPE_SENSOR, 60000), (TYPE_SENSOR, 60000), + (TYPE_SENSOR, 61000), (TYPE_SENSOR, 72000), (TYPE_SENSOR, 50000)], + "mid_to_max_temp" : [(TYPE_SENSOR, 63000), (TYPE_SENSOR, 60000), (TYPE_SENSOR, 60000), (TYPE_SENSOR, 59000), + (TYPE_SENSOR, 60000), (TYPE_SENSOR, 69000), (TYPE_SENSOR, 51500)], + "max_to_mid_temp" : [(TYPE_SENSOR, 56000), (TYPE_SENSOR, 53500), (TYPE_SENSOR, 52500), (TYPE_SENSOR, 52000), + (TYPE_SENSOR, 52800), (TYPE_SENSOR, 62000), (TYPE_SENSOR, 45800)], + "mid_to_min_temp" : [(TYPE_SENSOR, 50000), (TYPE_SENSOR, 47300), (TYPE_SENSOR, 46400), (TYPE_SENSOR, 44600), + (TYPE_SENSOR, 47000), (TYPE_SENSOR, 56000), (TYPE_SENSOR, 38800)], + "max_to_yellow_alarm" : [(TYPE_SENSOR, 67000), (TYPE_SENSOR, 65000), (TYPE_SENSOR, 64000), (TYPE_SENSOR, 62000), + (TYPE_SENSOR, 64000), (TYPE_SENSOR, 73000), (TYPE_SENSOR, 67000)], + "yellow_to_red_alarm" : [(TYPE_SENSOR, 72000), (TYPE_SENSOR, 70000), (TYPE_SENSOR, 69000), (TYPE_SENSOR, 67000), + (TYPE_SENSOR, 69000), (TYPE_SENSOR, 78000), (TYPE_SENSOR, 72000)], + "red_alarm_to_shutdown": [(TYPE_SENSOR, 77000), (TYPE_SENSOR, 75000), (TYPE_SENSOR, 74000), (TYPE_SENSOR, 72000), + (TYPE_SENSOR, 74000), (TYPE_SENSOR, 83000), (TYPE_SENSOR, 77000)] } - - thermal_val=[0,0,0,0,0,0,0] + afo_thermal_spec["min_to_mid_temp"] += [(TYPE_TRANSCEIVER, 55000)]*TRANSCEIVER_NUM_MAX + afo_thermal_spec["mid_to_max_temp"] += [(TYPE_TRANSCEIVER, 65000)]*TRANSCEIVER_NUM_MAX + afo_thermal_spec["max_to_mid_temp"] += [(TYPE_TRANSCEIVER, 64000)]*TRANSCEIVER_NUM_MAX + afo_thermal_spec["mid_to_min_temp"] += [(TYPE_TRANSCEIVER, 54000)]*TRANSCEIVER_NUM_MAX + afo_thermal_spec["max_to_yellow_alarm"] += [(TYPE_TRANSCEIVER, 73000)]*TRANSCEIVER_NUM_MAX + afo_thermal_spec["yellow_to_red_alarm"] += [(TYPE_TRANSCEIVER, 75000)]*TRANSCEIVER_NUM_MAX + afo_thermal_spec["red_alarm_to_shutdown"] += [(TYPE_TRANSCEIVER, 77000)]*TRANSCEIVER_NUM_MAX + + thermal_val = [] max_to_mid=0 mid_to_min=0 - + + # After booting, the database might not be ready for + # connection. So, it should try to connect to the database + # if self.transceiver_dom_sensor_table is None. + if self.transceiver_dom_sensor_table is None: + try: + state_db = swsscommon.DBConnector(STATE_DB, 0, False) + self.transceiver_dom_sensor_table = swsscommon.Table(state_db, TRANSCEIVER_DOM_SENSOR_TABLE) + except Exception as e: + logging.debug("{}".format(e)) + fan = self.fan if fan_policy_state==LEVEL_FAN_INIT: fan_policy_state=LEVEL_FAN_MAX #This is default state logging.debug("fan_policy_state=LEVEL_FAN_MAX") return - + count_check=count_check+1 if count_check < CHECK_TIMES: return else: count_check=0 - + thermal = self.thermal fan_dir=fan.get_fan_dir(1) - + if fan_dir==1: # AFI fan_thermal_spec = afi_thermal_spec fan_policy=fan_policy_b2f elif fan_dir==0: # AFO fan_thermal_spec = afo_thermal_spec - fan_policy=fan_policy_f2b + fan_policy=fan_policy_f2b else: logging.debug( "NULL case") - + ori_duty_cycle=fan.get_fan_duty_cycle() new_duty_cycle=0 if test_temp_revert==0: temp_test_data=temp_test_data+2000 - else: + else: temp_test_data=temp_test_data-2000 - + if test_temp==0: - for i in range (thermal.THERMAL_NUM_1_IDX, thermal.THERMAL_NUM_MAX+1): - thermal_val[i-1]=thermal._get_thermal_val(i) + for i in range(thermal.THERMAL_NUM_MAX): + thermal_val.append((TYPE_SENSOR, None, thermal._get_thermal_val(i+1))) + + for port_num in monitor_port: + sfp = platform_chassis.get_sfp(port_num) + thermal_val.append((TYPE_TRANSCEIVER, sfp, + self.get_transceiver_temperature(sfp.get_name()) * 1000)) + + logging.debug("Maximum avaliable port : %d", TRANSCEIVER_NUM_MAX) + logging.debug(thermal_val) else: - for i in range (thermal.THERMAL_NUM_1_IDX, thermal.THERMAL_NUM_MAX+1): - thermal_val[i-1]=test_temp_list[i-1] - thermal_val[i-1]= thermal_val[i-1] + temp_test_data + for i in range(THERMAL_NUM_MAX): + thermal_val.append((TYPE_SENSOR, None, test_temp_list[i] + temp_test_data)) logging.debug(thermal_val) fan_fail=0 - + ori_state=fan_policy_state; current_state=fan_policy_state; - + sfp_presence_num = 0 + if fan_dir==1: #AFI - for i in range (0, thermal.THERMAL_NUM_MAX): + for i in range (0, thermal.THERMAL_NUM_MAX + TRANSCEIVER_NUM_MAX): + (temp_type, obj, current_temp) = thermal_val[i] + + sfp = None + if temp_type == TYPE_TRANSCEIVER: + sfp = obj + if sfp.get_presence(): + sfp_presence_num += 1 + else: + continue + if ori_state==LEVEL_FAN_MID: - if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]: + if current_temp >= fan_thermal_spec["mid_to_max_temp"][i][1]: current_state=LEVEL_FAN_MAX logging.debug("current_state=LEVEL_FAN_MAX") break else: - if (thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i]): + if current_temp <= fan_thermal_spec["max_to_mid_temp"][i][1]: max_to_mid=max_to_mid+1 - if fan_policy_alarm==0: - if thermal_val[i] >= fan_thermal_spec["max_to_yellow_alarm"][i]: + if fan_policy_alarm==0: + if current_temp >= fan_thermal_spec["max_to_yellow_alarm"][i][1]: if send_yellow_alarm==0: logging.warning('Alarm-Yellow for temperature high is detected') fan_policy_alarm=LEVEL_FAN_YELLOW_ALARM send_yellow_alarm=1 elif fan_policy_alarm==LEVEL_FAN_YELLOW_ALARM: - if thermal_val[i] >= fan_thermal_spec["yellow_to_red_alarm"][i]: + if current_temp >= fan_thermal_spec["yellow_to_red_alarm"][i][1]: if send_red_alarm==0: logging.warning('Alarm-Red for temperature high is detected') fan_policy_alarm=LEVEL_FAN_RED_ALARM send_red_alarm=1 elif fan_policy_alarm==LEVEL_FAN_RED_ALARM: - if thermal_val[i] >= fan_thermal_spec["red_alarm_to_shutdown"][i]: - logging.critical('Alarm-Critical for temperature high is detected, shutdown DUT') - fan_policy_alarm=LEVEL_FAN_SHUTDOWN - time.sleep(2) - power_off_dut() - - if max_to_mid==thermal.THERMAL_NUM_MAX and fan_policy_state==LEVEL_FAN_MAX: + if current_temp >= fan_thermal_spec["red_alarm_to_shutdown"][i][1]: + if fan_thermal_spec["yellow_to_red_alarm"][i][0] == TYPE_SENSOR: + logging.critical('Alarm-Critical for temperature high is detected, shutdown DUT') + fan_policy_alarm=LEVEL_FAN_SHUTDOWN + time.sleep(2) + power_off_dut() + elif fan_thermal_spec["yellow_to_red_alarm"][i][0] == TYPE_TRANSCEIVER: + if shutdown_transceiver(sfp.get_name()): + logging.critical('Alarm-Critical for temperature high is detected, shutdown %s', sfp.get_name()) + + if max_to_mid==(thermal.THERMAL_NUM_MAX + sfp_presence_num) and fan_policy_state==LEVEL_FAN_MAX: current_state=LEVEL_FAN_MID if fan_policy_alarm!=0: logging.warning('Alarm for temperature high is cleared') @@ -441,48 +544,61 @@ def manage_fans(self): send_red_alarm=0 test_temp_revert=0 logging.debug("current_state=LEVEL_FAN_MID") - + else: #AFO psu_full_load=check_psu_loading() - for i in range (0, thermal.THERMAL_NUM_MAX): + for i in range (0, thermal.THERMAL_NUM_MAX + TRANSCEIVER_NUM_MAX): + (temp_type, obj, current_temp) = thermal_val[i] + + sfp = None + if temp_type == TYPE_TRANSCEIVER: + sfp = obj + if sfp.get_presence(): + sfp_presence_num += 1 + else: + continue if ori_state==LEVEL_FAN_MID: - if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]: + if current_temp >= fan_thermal_spec["mid_to_max_temp"][i][1]: current_state=LEVEL_FAN_MAX break else: - if psu_full_load!=True and thermal_val[i] <= fan_thermal_spec["mid_to_min_temp"][i]: + if psu_full_load!=True and current_temp <= fan_thermal_spec["mid_to_min_temp"][i][1]: mid_to_min=mid_to_min+1 elif ori_state==LEVEL_FAN_MIN: if psu_full_load==True: current_state=LEVEL_FAN_MID logging.debug("psu_full_load, set current_state=LEVEL_FAN_MID") - if thermal_val[i] >= fan_thermal_spec["min_to_mid_temp"][i]: + if current_temp >= fan_thermal_spec["min_to_mid_temp"][i][1]: current_state=LEVEL_FAN_MID else: - if thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i] : + if current_temp <= fan_thermal_spec["max_to_mid_temp"][i][1]: max_to_mid=max_to_mid+1 - if fan_policy_alarm==0: - if thermal_val[i] >= fan_thermal_spec["max_to_yellow_alarm"][i]: + if fan_policy_alarm==0: + if current_temp >= fan_thermal_spec["max_to_yellow_alarm"][i][1]: if send_yellow_alarm==0: logging.warning('Alarm-Yellow for temperature high is detected') fan_policy_alarm=LEVEL_FAN_YELLOW_ALARM send_yellow_alarm=1 elif fan_policy_alarm==LEVEL_FAN_YELLOW_ALARM: - if thermal_val[i] >= fan_thermal_spec["yellow_to_red_alarm"][i]: + if current_temp >= fan_thermal_spec["yellow_to_red_alarm"][i][1]: if send_red_alarm==0: logging.warning('Alarm-Red for temperature high is detected') fan_policy_alarm=LEVEL_FAN_RED_ALARM send_red_alarm=1 elif fan_policy_alarm==LEVEL_FAN_RED_ALARM: - if thermal_val[i] >= fan_thermal_spec["red_alarm_to_shutdown"][i]: - logging.critical('Alarm-Critical for temperature high is detected, shutdown DUT') - fan_policy_alarm=LEVEL_FAN_SHUTDOWN - time.sleep(2) - power_off_dut() - - if max_to_mid==thermal.THERMAL_NUM_MAX and ori_state==LEVEL_FAN_MAX: + if current_temp >= fan_thermal_spec["red_alarm_to_shutdown"][i][1]: + if fan_thermal_spec["red_alarm_to_shutdown"][i][0] == TYPE_SENSOR: + logging.critical('Alarm-Critical for temperature high is detected, shutdown DUT') + fan_policy_alarm=LEVEL_FAN_SHUTDOWN + time.sleep(2) + power_off_dut() + elif fan_thermal_spec["red_alarm_to_shutdown"][i][0] == TYPE_TRANSCEIVER: + if shutdown_transceiver(sfp.get_name()): + logging.critical('Alarm-Critical for temperature high is detected, shutdown %s', sfp.get_name()) + + if max_to_mid==(thermal.THERMAL_NUM_MAX + sfp_presence_num) and ori_state==LEVEL_FAN_MAX: current_state=LEVEL_FAN_MID if fan_policy_alarm!=0: logging.warning('Alarm for temperature high is cleared') @@ -491,18 +607,18 @@ def manage_fans(self): send_red_alarm=0 test_temp_revert=0 logging.debug("current_state=LEVEL_FAN_MID") - - if mid_to_min==thermal.THERMAL_NUM_MAX and ori_state==LEVEL_FAN_MID: + + if mid_to_min==(thermal.THERMAL_NUM_MAX + sfp_presence_num) and ori_state==LEVEL_FAN_MID: if psu_full_load==0: current_state=LEVEL_FAN_MIN logging.debug("current_state=LEVEL_FAN_MIN") - + #Check Fan fault status. True: fan not fault/present, 1: fan fault/un-present for i in range (fan.FAN_NUM_1_IDX, fan.FAN_NUM_ON_MAIN_BROAD+1): if fan.get_fan_status(i)==False: new_duty_cycle=100 current_state=LEVEL_FAN_MAX - logging.debug('fan_%d fail, set duty_cycle to 100',i) + logging.debug('fan_%d fail, set duty_cycle to 100',i) if test_temp==0: fan_fail=1 fan.set_fan_duty_cycle(new_duty_cycle) @@ -522,10 +638,20 @@ def manage_fans(self): return True +def signal_handler(sig, frame): + global exit_by_sigterm + if sig == signal.SIGTERM: + print("Caught SIGTERM - exiting...") + exit_by_sigterm = 1 + else: + pass + def main(argv): log_file = '%s.log' % FUNCTION_NAME log_level = logging.INFO global test_temp + global exit_by_sigterm + signal.signal(signal.SIGTERM, signal_handler) if len(sys.argv) != 1: try: opts, args = getopt.getopt(argv,'hdlt:',['lfile=']) @@ -539,8 +665,8 @@ def main(argv): elif opt in ('-d', '--debug'): log_level = logging.DEBUG elif opt in ('-l', '--lfile'): - log_file = arg - + log_file = arg + if sys.argv[1]== '-t': if len(sys.argv)!=9: print("temp test, need input 7 temp") @@ -552,14 +678,19 @@ def main(argv): test_temp = 1 log_level = logging.DEBUG print(test_temp_list) - + + global platform_chassis + platform_chassis = platform.Platform().get_chassis() + fan = FanUtil() fan.set_fan_duty_cycle(100) monitor = device_monitor(log_file, log_level) # Loop forever, doing something useful hopefully: while True: monitor.manage_fans() - time.sleep(3) + time.sleep(10) + if exit_by_sigterm == 1: + break if __name__ == '__main__': main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor_fan.py index 7f49be002f..7030629313 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor_fan.py @@ -27,6 +27,7 @@ import logging import logging.config import logging.handlers + import signal import time # this is only being used as part of the example except ImportError as e: raise ImportError('%s - required module not found' % str(e)) @@ -59,6 +60,9 @@ def match(self, *args): fan_state=[2, 2, 2, 2, 2, 2] #init state=2, insert=1, remove=0 fan_status_state=[2, 2, 2, 2, 2, 2] #init state=2, fault=1, normal=0 # Make a class we can use to capture stdout and sterr in the log + +exit_by_sigterm=0 + class device_monitor(object): def __init__(self, log_file, log_level): @@ -160,9 +164,20 @@ def manage_fan(self): return True +def signal_handler(sig, frame): + global exit_by_sigterm + if sig == signal.SIGTERM: + print("Caught SIGTERM - exiting...") + exit_by_sigterm = 1 + else: + pass + def main(argv): log_file = '%s.log' % FUNCTION_NAME log_level = logging.INFO + global exit_by_sigterm + signal.signal(signal.SIGTERM, signal_handler) + if len(sys.argv) != 1: try: opts, args = getopt.getopt(argv,'hdl:',['lfile=']) @@ -181,6 +196,8 @@ def main(argv): while True: monitor.manage_fan() time.sleep(3) + if exit_by_sigterm == 1: + break if __name__ == '__main__': main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor_psu.py index aa32d64bcb..104e11bf28 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9726-32d/utils/accton_as9726_32d_monitor_psu.py @@ -27,6 +27,7 @@ import logging import logging.config import logging.handlers + import signal import time # this is only being used as part of the example except ImportError as e: raise ImportError('%s - required module not found' % str(e)) @@ -37,6 +38,9 @@ psu_state=[2, 2] psu_status_state=[2, 2] + +exit_by_sigterm=0 + # Make a class we can use to capture stdout and sterr in the log class device_monitor(object): @@ -132,9 +136,19 @@ def manage_psu(self): return True +def signal_handler(sig, frame): + global exit_by_sigterm + if sig == signal.SIGTERM: + print("Caught SIGTERM - exiting...") + exit_by_sigterm = 1 + else: + pass + def main(argv): log_file = '%s.log' % FUNCTION_NAME log_level = logging.INFO + global exit_by_sigterm + signal.signal(signal.SIGTERM, signal_handler) if len(sys.argv) != 1: try: opts, args = getopt.getopt(argv,'hdl:',['lfile=']) @@ -154,6 +168,8 @@ def main(argv): while True: monitor.manage_psu() time.sleep(3) + if exit_by_sigterm == 1: + break if __name__ == '__main__': main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_psu_api.h b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_psu_api.h new file mode 100644 index 0000000000..d522979f1e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_psu_api.h @@ -0,0 +1,29 @@ +/* + * Copyright 2022 Accton Technology Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * PSU driver related api declarations + */ + +#ifndef ACCTON_PSU_API_H +#define ACCTON_PSU_API_H + +#include "accton_psu_defs.h" + +/** Description: + * Register psu status entry, set entry as NULL to unregister + */ +extern int register_psu_status_entry(PSU_STATUS_ENTRY *entry); + +#endif /* ACCTON_PSU_API_H */ diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_psu_defs.h b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_psu_defs.h new file mode 100644 index 0000000000..11bb253a57 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_psu_defs.h @@ -0,0 +1,28 @@ +/* + * Copyright 2022 Accton Technology Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform PSU defines/structures header file + */ + +#ifndef ACCTON_PSU_DEFS_H +#define ACCTON_PSU_DEFS_H + +typedef struct PSU_STATUS_ENTRY +{ + int (*get_presence)(void *client); + int (*get_powergood)(void *client); +} PSU_STATUS_ENTRY; + +#endif /* ACCTON_PSU_DEFS_H */ diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c index 66e7ad1186..82e5ba082d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c @@ -31,12 +31,49 @@ #include #include #include +#include +#include +#include "accton_psu_defs.h" +#define __STDC_WANT_LIB_EXT1__ 1 +#include #define MAX_FAN_DUTY_CYCLE 100 +#define ACCESS_INTERVAL_MAX 120 +#define ACCESS_INTERVAL_YM1151D_DEFAULT 60 +#define REFRESH_INTERVAL_SECOND 3 +#define REFRESH_INTERVAL_MSEC (REFRESH_INTERVAL_SECOND * 1000) +#define REFRESH_INTERVAL_HZ (REFRESH_INTERVAL_SECOND * HZ) + +#define EXIT_IF_POWER_FAILED(c) \ + do { \ + if (ym2651y_is_powergood(c) != 1) \ + goto exit; \ + } while (0) + +#define SLEEP_IF_INTERVAL(pInterval) \ + do { \ + int interval = atomic_read(pInterval); \ + if (interval > 0) \ + msleep(interval); \ + } while (0) + +/* SLEEP_IF_INTERVAL should be called before EXIT_IF_POWER_FAILED. + * It is known that accessing PSU when power failed might cause problems. + * So it is better to do sleep before checking power status because it avoids + * the risk that power status changes to failed during the sleep period. + */ +#define VALIDATE_POWERGOOD_AND_INTERVAL(client, pInterval) \ + do { \ + SLEEP_IF_INTERVAL(pInterval); \ + EXIT_IF_POWER_FAILED(client); \ + } while (0) + +struct mutex entry_lock; +PSU_STATUS_ENTRY access_psu_status = { NULL, NULL }; /* Addresses scanned */ -static const unsigned short normal_i2c[] = { 0x58, 0x5b, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x58, 0x59, 0x5b, I2C_CLIENT_END }; enum chips { YM2651, @@ -44,18 +81,12 @@ enum chips { YM2851, YM1401A, YPEB1200AM, + YM1151D, UMEC_UPD150SA, UMEC_UP1K21R }; -/* Each client has this additional data - */ -struct ym2651y_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 chip; /* chip id */ +struct pmbus_register_value { u8 capability; /* Register value */ u16 status_word; /* Register value */ u8 fan_fault; /* Register value */ @@ -83,6 +114,21 @@ struct ym2651y_data { u16 mfr_vout_max; /* Register value */ }; +/* Each client has this additional data + */ +struct ym2651y_data { + struct device *hwmon_dev; + struct mutex update_lock; + struct task_struct *update_task; + struct completion update_stop; + atomic_t access_interval; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 chip; /* chip id */ + u8 mfr_serial_supported; + struct pmbus_register_value reg_val; +}; + static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_byte(struct device *dev, struct device_attribute *da, @@ -97,7 +143,14 @@ static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_ascii(struct device *dev, struct device_attribute *da, char *buf); -static struct ym2651y_data *ym2651y_update_device(struct device *dev); +static ssize_t show_interval(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_interval(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static int mfr_serial_supported(u8 chip); +static int ym2651y_update_device(struct i2c_client *client, + struct pmbus_register_value *data); +static int ym2651y_update_thread(void *arg); static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); @@ -131,7 +184,8 @@ enum ym2651y_sysfs_attributes { PSU_MFR_IIN_MAX, PSU_MFR_IOUT_MAX, PSU_MFR_PIN_MAX, - PSU_MFR_POUT_MAX + PSU_MFR_POUT_MAX, + PSU_ACCESS_INTERVAL }; /* sysfs attributes for hwmon @@ -164,6 +218,7 @@ static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); +static SENSOR_DEVICE_ATTR(psu_access_interval, S_IWUSR | S_IRUGO, show_interval, set_interval, PSU_ACCESS_INTERVAL); /*Duplicate nodes for lm-sensors.*/ static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_vout, NULL, PSU_V_OUT); @@ -206,6 +261,7 @@ static struct attribute *ym2651y_attributes[] = { &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + &sensor_dev_attr_psu_access_interval.dev_attr.attr, /*Duplicate nodes for lm-sensors.*/ &sensor_dev_attr_curr2_input.dev_attr.attr, &sensor_dev_attr_in3_input.dev_attr.attr, @@ -224,32 +280,59 @@ static ssize_t show_byte(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + u8 status = 0; + + mutex_lock(&data->update_lock); + if (!data->valid) { + goto exit; + } - return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : - sprintf(buf, "0\n"); + if (attr->index == PSU_PMBUS_REVISION) + status = data->reg_val.pmbus_revision; + + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", status); + +exit: + mutex_unlock(&data->update_lock); + return 0; } static ssize_t show_word(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); u16 status = 0; + mutex_lock(&data->update_lock); + if (!data->valid) { + goto exit; + } + switch (attr->index) { case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ - status = (data->status_word & 0x40) ? 0 : 1; + status = (data->reg_val.status_word & 0x40) ? 0 : 1; break; case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ - status = (data->status_word & 0x4) >> 2; + status = (data->reg_val.status_word & 0x4) >> 2; break; case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ - status = (data->status_word & 0x800) ? 0 : 1; + status = (data->reg_val.status_word & 0x800) ? 0 : 1; break; + default: + goto exit; } + mutex_unlock(&data->update_lock); return sprintf(buf, "%d\n", status); + +exit: + mutex_unlock(&data->update_lock); + return 0; } static int two_complement_to_int(u16 data, u8 valid_bit, int mask) @@ -278,8 +361,8 @@ static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *d return -EINVAL; mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; - ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + data->reg_val.fan_duty_cycle[nr] = speed; + ym2651y_write_word(client, 0x3B + nr, data->reg_val.fan_duty_cycle[nr]); mutex_unlock(&data->update_lock); return count; @@ -289,153 +372,214 @@ static ssize_t show_linear(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); u16 value = 0; int exponent, mantissa; int multiplier = 1000; + mutex_lock(&data->update_lock); + if (!data->valid) { + goto exit; + } + switch (attr->index) { case PSU_V_OUT: - value = data->v_out; + value = data->reg_val.v_out; break; case PSU_I_OUT: - value = data->i_out; + value = data->reg_val.i_out; break; case PSU_P_OUT_UV: multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ /*Passing through*/ case PSU_P_OUT: - value = data->p_out; + value = data->reg_val.p_out; break; case PSU_TEMP1_INPUT: case PSU_TEMP2_INPUT: case PSU_TEMP3_INPUT: - value = data->temp_input[attr->index - PSU_TEMP1_INPUT]; + value = data->reg_val.temp_input[attr->index - PSU_TEMP1_INPUT]; break; case PSU_FAN1_SPEED: - value = data->fan_speed; + value = data->reg_val.fan_speed; multiplier = 1; break; case PSU_FAN1_DUTY_CYCLE: - value = data->fan_duty_cycle[0]; + value = data->reg_val.fan_duty_cycle[0]; multiplier = 1; break; case PSU_MFR_VIN_MIN: - value = data->mfr_vin_min; + value = data->reg_val.mfr_vin_min; break; case PSU_MFR_VIN_MAX: - value = data->mfr_vin_max; + value = data->reg_val.mfr_vin_max; break; case PSU_MFR_VOUT_MIN: - value = data->mfr_vout_min; + value = data->reg_val.mfr_vout_min; break; case PSU_MFR_VOUT_MAX: - value = data->mfr_vout_max; + value = data->reg_val.mfr_vout_max; break; case PSU_MFR_PIN_MAX: - value = data->mfr_pin_max; + value = data->reg_val.mfr_pin_max; break; case PSU_MFR_POUT_MAX: - value = data->mfr_pout_max; + value = data->reg_val.mfr_pout_max; break; case PSU_MFR_IOUT_MAX: - value = data->mfr_iout_max; + value = data->reg_val.mfr_iout_max; break; case PSU_MFR_IIN_MAX: - value = data->mfr_iin_max; + value = data->reg_val.mfr_iin_max; break; + default: + goto exit; } + mutex_unlock(&data->update_lock); exponent = two_complement_to_int(value >> 11, 5, 0x1f); mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + +exit: + mutex_unlock(&data->update_lock); + return 0; } static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + u8 shift = 0; + u8 fan_fault = 0; + + mutex_lock(&data->update_lock); + if (!data->valid) { + goto exit; + } + + fan_fault = data->reg_val.fan_fault; + mutex_unlock(&data->update_lock); - u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + return sprintf(buf, "%d\n", fan_fault >> shift); - return sprintf(buf, "%d\n", data->fan_fault >> shift); +exit: + mutex_unlock(&data->update_lock); + return 0; } static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, char *buf) { - struct ym2651y_data *data = ym2651y_update_device(dev); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + u8 over_temp = 0; + + mutex_lock(&data->update_lock); + if (!data->valid) { + goto exit; + } + + over_temp = data->reg_val.over_temp; + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", over_temp >> 7); - return sprintf(buf, "%d\n", data->over_temp >> 7); +exit: + mutex_unlock(&data->update_lock); + return 0; } static ssize_t show_ascii(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + ssize_t ret = 0; u8 *ptr = NULL; + mutex_lock(&data->update_lock); + if (!data->valid) { + goto exit; + } + switch (attr->index) { case PSU_FAN_DIRECTION: /* psu_fan_dir */ if (data->chip==YPEB1200AM) { - memcpy(data->fan_dir, "F2B", 3); - data->fan_dir[3]='\0'; + #ifdef __STDC_LIB_EXT1__ + memcpy_s(data->reg_val.fan_dir, 3, "F2B", 3); + #else + memcpy(data->reg_val.fan_dir, "F2B", 3); + #endif + data->reg_val.fan_dir[3]='\0'; } - ptr = data->fan_dir; + ptr = data->reg_val.fan_dir; break; case PSU_MFR_SERIAL: /* psu_mfr_serial */ - ptr = data->mfr_serial+1; /* The first byte is the count byte of string. */ + ptr = data->reg_val.mfr_serial+1; /* The first byte is the count byte of string. */ break; case PSU_MFR_ID: /* psu_mfr_id */ - ptr = data->mfr_id+1; /* The first byte is the count byte of string. */ + ptr = data->reg_val.mfr_id+1; /* The first byte is the count byte of string. */ break; case PSU_MFR_MODEL: /* psu_mfr_model */ - ptr = data->mfr_model+1; /* The first byte is the count byte of string. */ + ptr = data->reg_val.mfr_model+1; /* The first byte is the count byte of string. */ break; case PSU_MFR_REVISION: /* psu_mfr_revision */ - ptr = data->mfr_revsion+1; + ptr = data->reg_val.mfr_revsion+1; break; default: - return 0; + goto exit; } - return sprintf(buf, "%s\n", ptr); + ret = sprintf(buf, "%s\n", ptr); + +exit: + mutex_unlock(&data->update_lock); + return ret; } static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); int exponent, mantissa; int multiplier = 1000; + mutex_lock(&data->update_lock); if (!data->valid) { - return 0; + goto exit; } - exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + exponent = two_complement_to_int(data->reg_val.vout_mode, 5, 0x1f); switch (attr->index) { case PSU_MFR_VOUT_MIN: - mantissa = data->mfr_vout_min; + mantissa = data->reg_val.mfr_vout_min; break; case PSU_MFR_VOUT_MAX: - mantissa = data->mfr_vout_max; + mantissa = data->reg_val.mfr_vout_max; break; case PSU_V_OUT: - mantissa = data->v_out; + mantissa = data->reg_val.v_out; break; default: - return 0; + goto exit; } + mutex_unlock(&data->update_lock); return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + +exit: + mutex_unlock(&data->update_lock); + return 0; } static ssize_t show_vout(struct device *dev, struct device_attribute *da, @@ -452,6 +596,34 @@ static ssize_t show_vout(struct device *dev, struct device_attribute *da, } } +static ssize_t show_interval(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", atomic_read(&data->access_interval)); +} + +static ssize_t set_interval(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + long interval; + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + status = kstrtol(buf, 10, &interval); + if (status) + return status; + + if (interval < 0 || interval > ACCESS_INTERVAL_MAX) + return -EINVAL; + + atomic_set(&data->access_interval, (int)interval); + return count; +} + static const struct attribute_group ym2651y_group = { .attrs = ym2651y_attributes, }; @@ -479,6 +651,7 @@ static int ym2651y_probe(struct i2c_client *client, i2c_set_clientdata(client, data); mutex_init(&data->update_lock); data->chip = dev_id->driver_data; + data->mfr_serial_supported = mfr_serial_supported(data->chip); dev_info(&client->dev, "chip found\n"); /* Register sysfs hooks */ @@ -493,11 +666,26 @@ static int ym2651y_probe(struct i2c_client *client, goto exit_remove; } + /* create update thread */ + if (data->chip == YM1151D) + atomic_set(&data->access_interval, ACCESS_INTERVAL_YM1151D_DEFAULT); + else + atomic_set(&data->access_interval, 0); + + init_completion(&data->update_stop); + data->update_task = kthread_run(ym2651y_update_thread, client, "ym2651y_update_task"); + if (IS_ERR(data->update_task)) { + dev_dbg(&client->dev, "Failed to create ym2651y update task!\n"); + goto exit_hwmon; + } + dev_info(&client->dev, "%s: psu '%s'\n", dev_name(data->hwmon_dev), client->name); return 0; +exit_hwmon: + hwmon_device_unregister(data->hwmon_dev); exit_remove: sysfs_remove_group(&client->dev.kobj, &ym2651y_group); exit_free: @@ -511,6 +699,10 @@ static int ym2651y_remove(struct i2c_client *client) { struct ym2651y_data *data = i2c_get_clientdata(client); + /* Stop update task */ + kthread_stop(data->update_task); + wait_for_completion(&data->update_stop); + hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &ym2651y_group); kfree(data); @@ -524,6 +716,7 @@ static const struct i2c_device_id ym2651y_id[] = { { "ym2851", YM2851 }, { "ym1401a",YM1401A}, { "ype1200am", YPEB1200AM }, + { "ym1151d", YM1151D }, { "umec_upd150sa", UMEC_UPD150SA }, { "umec_up1k21r", UMEC_UP1K21R }, {} @@ -541,6 +734,23 @@ static struct i2c_driver ym2651y_driver = { .address_list = normal_i2c, }; +static int ym2651y_is_powergood(struct i2c_client *client) +{ + int powergood = 0; + + mutex_lock(&entry_lock); + if (access_psu_status.get_powergood == NULL) { + powergood = 1; /* skip powergood validation if API is not registered */ + goto exit; + } + + powergood = access_psu_status.get_powergood(client); + +exit: + mutex_unlock(&entry_lock); + return powergood; +} + static int ym2651y_read_byte(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); @@ -559,8 +769,9 @@ static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len) { - int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + int result; + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); if (unlikely(result < 0)) goto abort; if (unlikely(result != data_len)) { @@ -584,191 +795,253 @@ struct reg_data_word { u16 *value; }; -static struct ym2651y_data *ym2651y_update_device(struct device *dev) +static int ym2651y_update_device(struct i2c_client *client, + struct pmbus_register_value *data) { - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i, status, length; - u8 command, buf; - u8 fan_dir[5] = {0}; - struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, - {0x20, &data->vout_mode}, - {0x7d, &data->over_temp}, - {0x81, &data->fan_fault}, - {0x98, &data->pmbus_revision} - }; - struct reg_data_word regs_word[] = { {0x79, &data->status_word}, - {0x8b, &data->v_out}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x8d, &(data->temp_input[0])}, - {0x8e, &(data->temp_input[1])}, - {0x8f, &(data->temp_input[2])}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x3c, &(data->fan_duty_cycle[1])}, - {0x90, &data->fan_speed}, - {0xa0, &data->mfr_vin_min}, - {0xa1, &data->mfr_vin_max}, - {0xa2, &data->mfr_iin_max}, - {0xa3, &data->mfr_pin_max}, - {0xa4, &data->mfr_vout_min}, - {0xa5, &data->mfr_vout_max}, - {0xa6, &data->mfr_iout_max}, - {0xa7, &data->mfr_pout_max} - }; - - dev_dbg(&client->dev, "Starting ym2651 update\n"); - - /* Read byte data */ - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = ym2651y_read_byte(client, regs_byte[i].reg); - - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - *(regs_byte[i].value) = 0; - goto exit; - } - else { - *(regs_byte[i].value) = status; - } + struct ym2651y_data *driver_data = i2c_get_clientdata(client); + int i, status, length; + u8 command, buf; + u8 fan_dir[5] = {0}; + struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, + {0x20, &data->vout_mode}, + {0x7d, &data->over_temp}, + {0x81, &data->fan_fault}, + {0x98, &data->pmbus_revision} + }; + struct reg_data_word regs_word[] = { {0x79, &data->status_word}, + {0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x8f, &(data->temp_input[2])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &data->fan_speed}, + {0xa0, &data->mfr_vin_min}, + {0xa1, &data->mfr_vin_max}, + {0xa2, &data->mfr_iin_max}, + {0xa3, &data->mfr_pin_max}, + {0xa4, &data->mfr_vout_min}, + {0xa5, &data->mfr_vout_max}, + {0xa6, &data->mfr_iout_max}, + {0xa7, &data->mfr_pout_max} + }; + + dev_dbg(&client->dev, "Starting ym2651 update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + VALIDATE_POWERGOOD_AND_INTERVAL(client, &driver_data->access_interval); + + status = ym2651y_read_byte(client, regs_byte[i].reg); + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + goto exit; } + else { + *(regs_byte[i].value) = status; + } + } - /* Read word data */ - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { - /* To prevent hardware errors, - access to temp2_input and temp3_input should be skipped - if the chip ID is not in the following list. */ - if (regs_word[i].reg == 0x8e || regs_word[i].reg == 0x8f) { - if (data->chip != UMEC_UPD150SA && - data->chip != UMEC_UP1K21R) { - continue; - } - } - status = ym2651y_read_word(client, regs_word[i].reg); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - *(regs_word[i].value) = 0; - goto exit; - } - else { - *(regs_word[i].value) = status; + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + VALIDATE_POWERGOOD_AND_INTERVAL(client, &driver_data->access_interval); + + /* To prevent hardware errors, + access to temp2_input and temp3_input should be skipped + if the chip ID is not in the following list. */ + if (regs_word[i].reg == 0x8e || regs_word[i].reg == 0x8f) { + if (driver_data->chip != UMEC_UPD150SA && + driver_data->chip != UMEC_UP1K21R) { + continue; } } - /* Read fan_direction */ - command = 0xC3; - status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1); - + status = ym2651y_read_word(client, regs_word[i].reg); if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; goto exit; } + else { + *(regs_word[i].value) = status; + } + } + /* Read fan_direction */ + command = 0xC3; + VALIDATE_POWERGOOD_AND_INTERVAL(client, &driver_data->access_interval); + status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1); + if (status == 0) { strncpy(data->fan_dir, fan_dir+1, ARRAY_SIZE(data->fan_dir)-1); data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; + } - /* Read mfr_id */ - command = 0x99; - status = ym2651y_read_block(client, command, data->mfr_id, - ARRAY_SIZE(data->mfr_id)-1); + /* Read mfr_id */ + command = 0x99; + VALIDATE_POWERGOOD_AND_INTERVAL(client, &driver_data->access_interval); + status = ym2651y_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id)-1); + if (status == 0) data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + /* Read mfr_model */ + command = 0x9a; + length = 1; + /* Read first byte to determine the length of data */ + VALIDATE_POWERGOOD_AND_INTERVAL(client, &driver_data->access_interval); + status = ym2651y_read_block(client, command, &buf, length); + if (status == 0 && buf != 0xFF) { + VALIDATE_POWERGOOD_AND_INTERVAL(client, &driver_data->access_interval); + status = ym2651y_read_block(client, command, data->mfr_model, buf+1); + if (status == 0) { + if ((buf+1) >= (ARRAY_SIZE(data->mfr_model)-1)) + data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0'; + else + data->mfr_model[buf+1] = '\0'; + } + } - /* Read mfr_model */ - command = 0x9a; + /*YM-1401A PSU doens't support to get serial_num, so ignore it. + *It's vout doesn't support linear, so let it use show_vout_by_mode(). + */ + if (!strncmp("YM-1401A", data->mfr_model+1, strlen("YM-1401A"))) { + driver_data->chip=YM1401A; + } + else if (driver_data->mfr_serial_supported) { + /* Read mfr_serial */ + command = 0x9e; length = 1; /* Read first byte to determine the length of data */ + VALIDATE_POWERGOOD_AND_INTERVAL(client, &driver_data->access_interval); status = ym2651y_read_block(client, command, &buf, length); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; + if (status == 0 && buf != 0xFF) { + VALIDATE_POWERGOOD_AND_INTERVAL(client, &driver_data->access_interval); + status = ym2651y_read_block(client, command, data->mfr_serial, buf+1); + if (status == 0) { + if ((buf+1) >= (ARRAY_SIZE(data->mfr_serial)-1)) + data->mfr_serial[ARRAY_SIZE(data->mfr_serial)-1] = '\0'; + else + data->mfr_serial[buf+1] = '\0'; + } } - status = ym2651y_read_block(client, command, data->mfr_model, buf+1); + } - if ((buf+1) >= (ARRAY_SIZE(data->mfr_model)-1)) - { - data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0'; - } - else - data->mfr_model[buf+1] = '\0'; + /* Read mfr_revsion */ + command = 0x9b; + VALIDATE_POWERGOOD_AND_INTERVAL(client, &driver_data->access_interval); + status = ym2651y_read_block(client, command, data->mfr_revsion, + ARRAY_SIZE(data->mfr_revsion)-1); + if (status == 0) + data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } + return 1; /* Return 1 for valid data, 0 for invalid */ - /*YM-1401A PSU doens't support to get serial_num, so ignore it. - *It's vout doesn't support linear, so let it use show_vout_by_mode(). - */ - if(!strncmp("YM-1401A", data->mfr_model+1, strlen("YM-1401A"))) - { - data->chip=YM1401A; - } - else - { - /* Read mfr_serial */ - command = 0x9e; - length = 1; - /* Read first byte to determine the length of data */ - status = ym2651y_read_block(client, command, &buf, length); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - status = ym2651y_read_block(client, command, data->mfr_serial, buf+1); +exit: + return 0; +} - if ((buf+1) >= (ARRAY_SIZE(data->mfr_serial)-1)) - { - data->mfr_serial[ARRAY_SIZE(data->mfr_serial)-1] = '\0'; - } - else - data->mfr_serial[buf+1] = '\0'; +static int ym2651y_update_thread(void *arg) +{ + int valid = 0; + unsigned long start_time = 0; + unsigned long next_start_time = 0; /* expected next start time */ + struct i2c_client *client = arg; + struct ym2651y_data *data = i2c_get_clientdata(client); - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - } + if (data == NULL) + return -EINVAL; - /* Read mfr_revsion */ - command = 0x9b; - status = ym2651y_read_block(client, command, data->mfr_revsion, - ARRAY_SIZE(data->mfr_revsion)-1); - data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; + while (!kthread_should_stop()) { + struct pmbus_register_value reg_val = { 0 }; - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } + start_time = jiffies; + valid = ym2651y_update_device(client, ®_val); - data->last_updated = jiffies; + mutex_lock(&data->update_lock); data->valid = 1; + if (valid) { + #ifdef __STDC_LIB_EXT1__ + memcpy_s(&data->reg_val, sizeof(reg_val), ®_val, sizeof(reg_val)); + #else + memcpy(&data->reg_val, ®_val, sizeof(reg_val)); + #endif + } else { + #ifdef __STDC_LIB_EXT1__ + memset_s(&data->reg_val, sizeof(reg_val), 0, sizeof(reg_val)); + #else + memset(&data->reg_val, 0, sizeof(reg_val)); + #endif + + /* PMBus STATUS_WORD(0x79): psu_power_on, low byte bit 6, 0=>ON, 1=>OFF */ + data->reg_val.status_word |= 0x40; + + /* PMBus STATUS_WORD(0x79): psu_power_good, high byte bit 3, 0=>OK, 1=>FAIL */ + data->reg_val.status_word |= 0x800; + } + mutex_unlock(&data->update_lock); + + next_start_time = start_time + REFRESH_INTERVAL_HZ; + if (time_before(jiffies, next_start_time)) { + /* Sleep if time consumed is less than REFRESH_INTERVAL_SECOND */ + msleep(min(jiffies_to_msecs(next_start_time - jiffies), REFRESH_INTERVAL_MSEC)); + } } - exit: - mutex_unlock(&data->update_lock); + complete_all(&data->update_stop); + return 0; +} + +int register_psu_status_entry(PSU_STATUS_ENTRY *entry) +{ + mutex_lock(&entry_lock); + + if (entry) { + access_psu_status.get_presence = entry->get_presence; + access_psu_status.get_powergood = entry->get_powergood; + } + else { + access_psu_status.get_presence = NULL; + access_psu_status.get_powergood = NULL; + } - return data; + mutex_unlock(&entry_lock); + return 0; +} +EXPORT_SYMBOL(register_psu_status_entry); + +static int __init ym2651y_init(void) +{ + mutex_init(&entry_lock); + return i2c_add_driver(&ym2651y_driver); +} + +static void __exit ym2651y_exit(void) +{ + i2c_del_driver(&ym2651y_driver); } -module_i2c_driver(ym2651y_driver); +static int mfr_serial_supported(u8 chip) +{ + int i = 0; + u8 supported_chips[] = {}; + + for (i = 0; i < ARRAY_SIZE(supported_chips); i++) { + if (chip == supported_chips[i]) + return 1; + } + + return 0; +} MODULE_AUTHOR("Brandon Chuang "); MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); MODULE_LICENSE("GPL"); - +module_init(ym2651y_init); +module_exit(ym2651y_exit);