diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/buffers.json.j2 b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/buffers.json.j2 new file mode 120000 index 0000000000..202fff9921 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/buffers.json.j2 @@ -0,0 +1 @@ +../Accton-AS9737-32DB/buffers.json.j2 \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/buffers_defaults_t0.j2 b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/buffers_defaults_t0.j2 new file mode 120000 index 0000000000..32e7e9fadd --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../Accton-AS9737-32DB/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/buffers_defaults_t1.j2 b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/buffers_defaults_t1.j2 new file mode 120000 index 0000000000..10359bcc6f --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../Accton-AS9737-32DB/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/hwsku.json b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/hwsku.json new file mode 100644 index 0000000000..7ba51bfedc --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/hwsku.json @@ -0,0 +1,169 @@ +{ + "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" + } + } +} + diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/port_config.ini b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/port_config.ini new file mode 100644 index 0000000000..ad5a9a5d61 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/port_config.ini @@ -0,0 +1,34 @@ +# name lanes alias index speed +Ethernet0 74,75,76,77 Eth1(Port1) 1 100000 +Ethernet8 66,67,68,69 Eth2(Port2) 2 100000 +Ethernet16 82,83,84,85 Eth3(Port3) 3 100000 +Ethernet24 90,91,92,93 Eth4(Port4) 4 100000 +Ethernet32 98,99,100,101 Eth5(Port5) 5 100000 +Ethernet40 106,107,108,109 Eth6(Port6) 6 100000 +Ethernet48 114,115,116,117 Eth7(Port7) 7 100000 +Ethernet56 122,123,124,125 Eth8(Port8) 8 100000 +Ethernet64 42,43,44,45 Eth9(Port9) 9 100000 +Ethernet72 34,35,36,37 Eth10(Port10) 10 100000 +Ethernet80 50,51,52,53 Eth11(Port11) 11 100000 +Ethernet88 58,59,60,61 Eth12(Port12) 12 100000 +Ethernet96 386,387,388,389 Eth13(Port13) 13 100000 +Ethernet104 394,395,396,397 Eth14(Port14) 14 100000 +Ethernet112 402,403,404,405 Eth15(Port15) 15 100000 +Ethernet120 410,411,412,413 Eth16(Port16) 16 100000 +Ethernet128 426,427,428,429 Eth17(Port17) 17 100000 +Ethernet136 418,419,420,421 Eth18(Port18) 18 100000 +Ethernet144 434,435,436,437 Eth19(Port19) 19 100000 +Ethernet152 442,443,444,445 Eth20(Port20) 20 100000 +Ethernet160 2,3,4,5 Eth21(Port21) 21 100000 +Ethernet168 10,11,12,13 Eth22(Port22) 22 100000 +Ethernet176 18,19,20,21 Eth23(Port23) 23 100000 +Ethernet184 26,27,28,29 Eth24(Port24) 24 100000 +Ethernet192 458,459,460,461 Eth25(Port25) 25 100000 +Ethernet200 450,451,452,453 Eth26(Port26) 26 100000 +Ethernet208 474,475,476,477 Eth27(Port27) 27 100000 +Ethernet216 466,467,468,469 Eth28(Port28) 28 100000 +Ethernet224 490,491,492,493 Eth29(Port29) 29 100000 +Ethernet232 482,483,484,485 Eth30(Port30) 30 100000 +Ethernet240 506,507,508,509 Eth31(Port31) 31 100000 +Ethernet248 498,499,500,501 Eth32(Port32) 32 100000 +Ethernet256 516 Eth33(Port33) 33 10000 diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/qos.json.j2 b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/qos.json.j2 new file mode 120000 index 0000000000..b67b43a7f3 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/qos.json.j2 @@ -0,0 +1 @@ +../Accton-AS9737-32DB/qos.json.j2 \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/sai.profile b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/sai.profile new file mode 100644 index 0000000000..8d1f9d0787 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th4-as9737-32x100G.config.yml diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/th4-as9737-32x100G.config.yml b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/th4-as9737-32x100G.config.yml new file mode 100644 index 0000000000..c5bd1283c1 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB-100G/th4-as9737-32x100G.config.yml @@ -0,0 +1,665 @@ +--- +bcm_device: + 0: + global: + pktio_mode: 1 + rx_cosq_mapping_management_mode: 1 + vlan_default_port: 3 + l3_alpm_template: 1 + port_allow_tpid_disable: 1 + riot_overlay_l3_intf_mem_size: 4096 + riot_overlay_l3_egress_mem_size: 8192 + l3_ecmp_member_first_lkup_mem_size: 8192 + l3_intf_vlan_split_egress: 1 +... +--- +bcm_device: + 0: + global: + dport_map_enable: 0 + port: + "35": + dport_map_port: 1 + "34": + dport_map_port: 2 + "36": + dport_map_port: 3 + "37": + dport_map_port: 4 + "51": + dport_map_port: 5 + "52": + dport_map_port: 6 + "53": + dport_map_port: 7 + "54": + dport_map_port: 8 + "18": + dport_map_port: 9 + "17": + dport_map_port: 10 + "19": + dport_map_port: 11 + "20": + dport_map_port: 12 + "204": + dport_map_port: 13 + "205": + dport_map_port: 14 + "206": + dport_map_port: 15 + "207": + dport_map_port: 16 + "222": + dport_map_port: 17 + "221": + dport_map_port: 18 + "223": + dport_map_port: 19 + "224": + dport_map_port: 20 + "1": + dport_map_port: 21 + "2": + dport_map_port: 22 + "3": + dport_map_port: 23 + "4": + dport_map_port: 24 + "239": + dport_map_port: 25 + "238": + dport_map_port: 26 + "241": + dport_map_port: 27 + "240": + dport_map_port: 28 + "256": + dport_map_port: 29 + "255": + dport_map_port: 30 + "258": + dport_map_port: 31 + "257": + dport_map_port: 32 + "50": + dport_map_port: 33 +# "152": +# dport_map_port: 34 +... +--- +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: 0x76301425 + TX_LANE_MAP: 0x02671435 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x22 + ? + 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: 0x21653074 + TX_LANE_MAP: 0x53146072 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x4f + ? + 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: 0x47325610 + TX_LANE_MAP: 0x03672415 + RX_POLARITY_FLIP: 0x00 + 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: 0x64123507 + TX_LANE_MAP: 0x17053246 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x49 + ? + 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: 0x42731506 + TX_LANE_MAP: 0x45016372 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x8e + ? + 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: 0x45102736 + TX_LANE_MAP: 0x23160574 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x23 + ? + 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: 0x20145763 + TX_LANE_MAP: 0x25764013 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x24 + ? + 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: 0x10765423 + TX_LANE_MAP: 0x06237415 + RX_POLARITY_FLIP: 0xfe + TX_POLARITY_FLIP: 0xe3 + ? + 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: 0x57024613 + TX_LANE_MAP: 0x13672405 + RX_POLARITY_FLIP: 0x3b + TX_POLARITY_FLIP: 0xe1 + ? + 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: 0x10765342 + TX_LANE_MAP: 0x50637412 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0xe2 + ? + 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: 0x21573046 + TX_LANE_MAP: 0x41326705 + RX_POLARITY_FLIP: 0x01 + TX_POLARITY_FLIP: 0x04 + ? + 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: 0x27051643 + TX_LANE_MAP: 0x01546273 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x1d + ? + 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: 0x50467132 + TX_LANE_MAP: 0x04567321 + RX_POLARITY_FLIP: 0x3a + TX_POLARITY_FLIP: 0x1a + ? + 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: 0x76305421 + TX_LANE_MAP: 0x20673415 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xff + ? + 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: 0x42361057 + TX_LANE_MAP: 0x54017362 + RX_POLARITY_FLIP: 0x01 + TX_POLARITY_FLIP: 0x24 + ? + 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: 0x30215476 + TX_LANE_MAP: 0x72351604 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xf4 + ? + PC_PM_ID: 49 + 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: 0x35140627 + TX_LANE_MAP: 0x25461370 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xff + ? + PC_PM_ID: 50 + 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: 0x41562073 + TX_LANE_MAP: 0x01764253 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x31 + ? + PC_PM_ID: 51 + 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: 0x74126305 + TX_LANE_MAP: 0x35762014 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xbc + ? + PC_PM_ID: 52 + 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: 0x21754063 + TX_LANE_MAP: 0x04237516 + RX_POLARITY_FLIP: 0xeb + TX_POLARITY_FLIP: 0x3d + ? + PC_PM_ID: 53 + 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: 0x40572316 + TX_LANE_MAP: 0x64537102 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x48 + ? + PC_PM_ID: 54 + 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: 0x57143620 + TX_LANE_MAP: 0x36472051 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x44 + ? + PC_PM_ID: 55 + 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: 0x01426357 + TX_LANE_MAP: 0x03741526 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x4f + ? + PC_PM_ID: 56 + 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: 0x05234617 + TX_LANE_MAP: 0x63254170 + RX_POLARITY_FLIP: 0x05 + TX_POLARITY_FLIP: 0xd8 + ? + PC_PM_ID: 57 + 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: 0x61573204 + TX_LANE_MAP: 0x27035164 + RX_POLARITY_FLIP: 0x19 + TX_POLARITY_FLIP: 0x08 + ? + PC_PM_ID: 58 + 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: 0x05132467 + TX_LANE_MAP: 0x63457102 + RX_POLARITY_FLIP: 0xfb + TX_POLARITY_FLIP: 0xdc + ? + PC_PM_ID: 59 + 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: 0x14530276 + TX_LANE_MAP: 0x05274361 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x80 + ? + PC_PM_ID: 60 + 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: 0x73146502 + TX_LANE_MAP: 0x41735062 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xba + ? + PC_PM_ID: 61 + 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: 0x05236417 + TX_LANE_MAP: 0x26417350 + RX_POLARITY_FLIP: 0xdd + TX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 62 + 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: 0x64153072 + TX_LANE_MAP: 0x74310625 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xff + ? + PC_PM_ID: 63 + 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: 0x65712430 + TX_LANE_MAP: 0x42615073 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x81 + ? + PC_PM_ID: 64 + 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: 0x35621470 + TX_LANE_MAP: 0x23456170 + RX_POLARITY_FLIP: 0xf7 + TX_POLARITY_FLIP: 0x7f +... +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 1 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 2 + : + PC_PHYS_PORT_ID: 5 + ? + PORT_ID: 3 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 4 + : + PC_PHYS_PORT_ID: 13 + ? + PORT_ID: 17 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 18 + : + PC_PHYS_PORT_ID: 21 + ? + PORT_ID: 19 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 20 + : + PC_PHYS_PORT_ID: 29 + ? + PORT_ID: 34 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 35 + : + PC_PHYS_PORT_ID: 37 + ? + PORT_ID: 36 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 37 + : + PC_PHYS_PORT_ID: 45 + ? + PORT_ID: 51 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 52 + : + PC_PHYS_PORT_ID: 53 + ? + PORT_ID: 53 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 54 + : + PC_PHYS_PORT_ID: 61 + ? + PORT_ID: 204 + : + PC_PHYS_PORT_ID: 193 + ? + PORT_ID: 205 + : + PC_PHYS_PORT_ID: 197 + ? + PORT_ID: 206 + : + PC_PHYS_PORT_ID: 201 + ? + PORT_ID: 207 + : + PC_PHYS_PORT_ID: 205 + ? + PORT_ID: 221 + : + PC_PHYS_PORT_ID: 209 + ? + PORT_ID: 222 + : + PC_PHYS_PORT_ID: 213 + ? + PORT_ID: 223 + : + PC_PHYS_PORT_ID: 217 + ? + PORT_ID: 224 + : + PC_PHYS_PORT_ID: 221 + ? + PORT_ID: 238 + : + PC_PHYS_PORT_ID: 225 + ? + PORT_ID: 239 + : + PC_PHYS_PORT_ID: 229 + ? + PORT_ID: 240 + : + PC_PHYS_PORT_ID: 233 + ? + PORT_ID: 241 + : + PC_PHYS_PORT_ID: 237 + ? + PORT_ID: 255 + : + PC_PHYS_PORT_ID: 241 + ? + PORT_ID: 256 + : + PC_PHYS_PORT_ID: 245 + ? + PORT_ID: 257 + : + PC_PHYS_PORT_ID: 249 + ? + PORT_ID: 258 + : + PC_PHYS_PORT_ID: 253 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 258 +# ? +# PORT_ID: 152 +# : +# PC_PHYS_PORT_ID: 257 +... +--- +device: + 0: + PC_PORT: + ? + PORT_ID: [[1, 4], [17, 20], [34, 37], [51, 54], [204, 207], [221, 224], [238, 241], [255, 258]] + : + ENABLE: 0 + SPEED: 100000 + NUM_LANES: 4 + FEC_MODE: PC_FEC_RS528 + MAX_FRAME_SIZE: 9416 + ? +# PORT_ID: [50, 152] + PORT_ID: [50] + : + ENABLE: 0 + SPEED: 10000 + NUM_LANES: 1 + FEC_MODE: PC_FEC_NONE + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + FEC_MODE: PC_FEC_NONE + + PC_PMD_FIRMWARE: + ? + PORT_ID: [[1, 4], [17, 20], [34, 37], [51, 54], [204, 207], [221, 224], [238, 241], [255, 258]] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_COPPER +... +--- +device: + 0: + TM_SCHEDULER_CONFIG: + DYNAMIC_VOQ: 0 +... diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/buffers.json.j2 b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/buffers.json.j2 new file mode 100644 index 0000000000..9354b7ec5b --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/buffers_defaults_t0.j2 b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/buffers_defaults_t0.j2 new file mode 100644 index 0000000000..bf2fd5174b --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/buffers_defaults_t0.j2 @@ -0,0 +1,126 @@ +{% set ingress_lossless_pool_size = '10171826' %} +{% set ingress_lossless_pool_xoff = '50859134' %} +{% set ingress_lossy_pool_size = '51989336' %} +{% set egress_lossless_pool_size = '10171826' %} +{% set egress_lossy_pool_size = '51989336' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 8)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"ingress_lossless_pool", + "size": "0", + "dynamic_th":"1", + "xoff":"25429567", + "xon":"0", + "xon_offset": "18432" + }, + "ingress_lossy_profile": { + "pool":"ingress_lossy_pool", + "size":"0", + "dynamic_th":"1" + }, + "egress_lossless_profile": { + "pool":"egress_lossless_pool", + "size":"0", + "dynamic_th":"1" + }, + "egress_lossy_profile": { + "pool":"egress_lossy_pool", + "size":"0", + "dynamic_th":"0" + } + }, + +{%- endmacro %} + +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { +{% for port in port_names.split(',') %} + "{{ port }}|0": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|1": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|2": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|3": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|4": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|5": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|6": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|7": { + "profile" : "ingress_lossy_profile" + }{% if not loop.last %},{% endif %} +{% endfor %} + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|0": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|1": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|2": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|3": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|4": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|5": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|6": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|7": { + "profile" : "egress_lossy_profile" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +{%- endmacro %} diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/buffers_defaults_t1.j2 b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/buffers_defaults_t1.j2 new file mode 100644 index 0000000000..bf2fd5174b --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/buffers_defaults_t1.j2 @@ -0,0 +1,126 @@ +{% set ingress_lossless_pool_size = '10171826' %} +{% set ingress_lossless_pool_xoff = '50859134' %} +{% set ingress_lossy_pool_size = '51989336' %} +{% set egress_lossless_pool_size = '10171826' %} +{% set egress_lossy_pool_size = '51989336' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 8)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"ingress_lossless_pool", + "size": "0", + "dynamic_th":"1", + "xoff":"25429567", + "xon":"0", + "xon_offset": "18432" + }, + "ingress_lossy_profile": { + "pool":"ingress_lossy_pool", + "size":"0", + "dynamic_th":"1" + }, + "egress_lossless_profile": { + "pool":"egress_lossless_pool", + "size":"0", + "dynamic_th":"1" + }, + "egress_lossy_profile": { + "pool":"egress_lossy_pool", + "size":"0", + "dynamic_th":"0" + } + }, + +{%- endmacro %} + +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { +{% for port in port_names.split(',') %} + "{{ port }}|0": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|1": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|2": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|3": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|4": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|5": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|6": { + "profile" : "ingress_lossy_profile" + }, + "{{ port }}|7": { + "profile" : "ingress_lossy_profile" + }{% if not loop.last %},{% endif %} +{% endfor %} + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|0": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|1": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|2": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|3": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|4": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|5": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|6": { + "profile" : "egress_lossy_profile" + }, + "{{ port }}|7": { + "profile" : "egress_lossy_profile" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +{%- endmacro %} diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/hwsku.json b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/hwsku.json new file mode 100644 index 0000000000..53620319cd --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/hwsku.json @@ -0,0 +1,169 @@ +{ + "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" + } + } +} + diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/port_config.ini b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/port_config.ini new file mode 100644 index 0000000000..da4f17c08b --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/port_config.ini @@ -0,0 +1,34 @@ +# name lanes alias index speed +Ethernet0 74,75,76,77,78,79,80,81 Eth1(Port1) 1 400000 +Ethernet8 66,67,68,69,70,71,72,73 Eth2(Port2) 2 400000 +Ethernet16 82,83,84,85,86,87,88,89 Eth3(Port3) 3 400000 +Ethernet24 90,91,92,93,94,95,96,97 Eth4(Port4) 4 400000 +Ethernet32 98,99,100,101,102,103,104,105 Eth5(Port5) 5 400000 +Ethernet40 106,107,108,109,110,111,112,113 Eth6(Port6) 6 400000 +Ethernet48 114,115,116,117,118,119,120,121 Eth7(Port7) 7 400000 +Ethernet56 122,123,124,125,126,127,128,129 Eth8(Port8) 8 400000 +Ethernet64 42,43,44,45,46,47,48,49 Eth9(Port9) 9 400000 +Ethernet72 34,35,36,37,38,39,40,41 Eth10(Port10) 10 400000 +Ethernet80 50,51,52,53,54,55,56,57 Eth11(Port11) 11 400000 +Ethernet88 58,59,60,61,62,63,64,65 Eth12(Port12) 12 400000 +Ethernet96 386,387,388,389,390,391,392,393 Eth13(Port13) 13 400000 +Ethernet104 394,395,396,397,398,399,400,401 Eth14(Port14) 14 400000 +Ethernet112 402,403,404,405,406,407,408,409 Eth15(Port15) 15 400000 +Ethernet120 410,411,412,413,414,415,416,417 Eth16(Port16) 16 400000 +Ethernet128 426,427,428,429,430,431,432,433 Eth17(Port17) 17 400000 +Ethernet136 418,419,420,421,422,423,424,425 Eth18(Port18) 18 400000 +Ethernet144 434,435,436,437,438,439,440,441 Eth19(Port19) 19 400000 +Ethernet152 442,443,444,445,446,447,448,449 Eth20(Port20) 20 400000 +Ethernet160 2,3,4,5,6,7,8,9 Eth21(Port21) 21 400000 +Ethernet168 10,11,12,13,14,15,16,17 Eth22(Port22) 22 400000 +Ethernet176 18,19,20,21,22,23,24,25 Eth23(Port23) 23 400000 +Ethernet184 26,27,28,29,30,31,32,33 Eth24(Port24) 24 400000 +Ethernet192 458,459,460,461,462,463,464,465 Eth25(Port25) 25 400000 +Ethernet200 450,451,452,453,454,455,456,457 Eth26(Port26) 26 400000 +Ethernet208 474,475,476,477,478,479,480,481 Eth27(Port27) 27 400000 +Ethernet216 466,467,468,469,470,471,472,473 Eth28(Port28) 28 400000 +Ethernet224 490,491,492,493,494,495,496,497 Eth29(Port29) 29 400000 +Ethernet232 482,483,484,485,486,487,488,489 Eth30(Port30) 30 400000 +Ethernet240 506,507,508,509,510,511,512,513 Eth31(Port31) 31 400000 +Ethernet248 498,499,500,501,502,503,504,505 Eth32(Port32) 32 400000 +Ethernet256 516 Eth33(Port33) 33 10000 diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/qos.json.j2 b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/qos.json.j2 new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/qos.json.j2 @@ -0,0 +1 @@ +{} diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/sai.profile b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/sai.profile new file mode 100644 index 0000000000..3ea81120fc --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th4-as9737-32x400G.config.yml diff --git a/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/th4-as9737-32x400G.config.yml b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/th4-as9737-32x400G.config.yml new file mode 100644 index 0000000000..4f0b447934 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/Accton-AS9737-32DB/th4-as9737-32x400G.config.yml @@ -0,0 +1,665 @@ +--- +bcm_device: + 0: + global: + pktio_mode: 1 + rx_cosq_mapping_management_mode: 1 + vlan_default_port: 3 + l3_alpm_template: 1 + port_allow_tpid_disable: 1 + riot_overlay_l3_intf_mem_size: 4096 + riot_overlay_l3_egress_mem_size: 8192 + l3_ecmp_member_first_lkup_mem_size: 8192 + l3_intf_vlan_split_egress: 1 +... +--- +bcm_device: + 0: + global: + dport_map_enable: 0 + port: + "35": + dport_map_port: 1 + "34": + dport_map_port: 2 + "36": + dport_map_port: 3 + "37": + dport_map_port: 4 + "51": + dport_map_port: 5 + "52": + dport_map_port: 6 + "53": + dport_map_port: 7 + "54": + dport_map_port: 8 + "18": + dport_map_port: 9 + "17": + dport_map_port: 10 + "19": + dport_map_port: 11 + "20": + dport_map_port: 12 + "204": + dport_map_port: 13 + "205": + dport_map_port: 14 + "206": + dport_map_port: 15 + "207": + dport_map_port: 16 + "222": + dport_map_port: 17 + "221": + dport_map_port: 18 + "223": + dport_map_port: 19 + "224": + dport_map_port: 20 + "1": + dport_map_port: 21 + "2": + dport_map_port: 22 + "3": + dport_map_port: 23 + "4": + dport_map_port: 24 + "239": + dport_map_port: 25 + "238": + dport_map_port: 26 + "241": + dport_map_port: 27 + "240": + dport_map_port: 28 + "256": + dport_map_port: 29 + "255": + dport_map_port: 30 + "258": + dport_map_port: 31 + "257": + dport_map_port: 32 + "50": + dport_map_port: 33 +# "152": +# dport_map_port: 34 +... +--- +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: 0x76301425 + TX_LANE_MAP: 0x02671435 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x22 + ? + 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: 0x21653074 + TX_LANE_MAP: 0x53146072 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x4f + ? + 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: 0x47325610 + TX_LANE_MAP: 0x03672415 + RX_POLARITY_FLIP: 0x00 + 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: 0x64123507 + TX_LANE_MAP: 0x17053246 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x49 + ? + 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: 0x42731506 + TX_LANE_MAP: 0x45016372 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x8e + ? + 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: 0x45102736 + TX_LANE_MAP: 0x23160574 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x23 + ? + 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: 0x20145763 + TX_LANE_MAP: 0x25764013 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x24 + ? + 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: 0x10765423 + TX_LANE_MAP: 0x06237415 + RX_POLARITY_FLIP: 0xfe + TX_POLARITY_FLIP: 0xe3 + ? + 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: 0x57024613 + TX_LANE_MAP: 0x13672405 + RX_POLARITY_FLIP: 0x3b + TX_POLARITY_FLIP: 0xe1 + ? + 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: 0x10765342 + TX_LANE_MAP: 0x50637412 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0xe2 + ? + 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: 0x21573046 + TX_LANE_MAP: 0x41326705 + RX_POLARITY_FLIP: 0x01 + TX_POLARITY_FLIP: 0x04 + ? + 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: 0x27051643 + TX_LANE_MAP: 0x01546273 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x1d + ? + 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: 0x50467132 + TX_LANE_MAP: 0x04567321 + RX_POLARITY_FLIP: 0x3a + TX_POLARITY_FLIP: 0x1a + ? + 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: 0x76305421 + TX_LANE_MAP: 0x20673415 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xff + ? + 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: 0x42361057 + TX_LANE_MAP: 0x54017362 + RX_POLARITY_FLIP: 0x01 + TX_POLARITY_FLIP: 0x24 + ? + 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: 0x30215476 + TX_LANE_MAP: 0x72351604 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xf4 + ? + PC_PM_ID: 49 + 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: 0x35140627 + TX_LANE_MAP: 0x25461370 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xff + ? + PC_PM_ID: 50 + 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: 0x41562073 + TX_LANE_MAP: 0x01764253 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x31 + ? + PC_PM_ID: 51 + 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: 0x74126305 + TX_LANE_MAP: 0x35762014 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xbc + ? + PC_PM_ID: 52 + 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: 0x21754063 + TX_LANE_MAP: 0x04237516 + RX_POLARITY_FLIP: 0xeb + TX_POLARITY_FLIP: 0x3d + ? + PC_PM_ID: 53 + 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: 0x40572316 + TX_LANE_MAP: 0x64537102 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x48 + ? + PC_PM_ID: 54 + 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: 0x57143620 + TX_LANE_MAP: 0x36472051 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x44 + ? + PC_PM_ID: 55 + 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: 0x01426357 + TX_LANE_MAP: 0x03741526 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0x4f + ? + PC_PM_ID: 56 + 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: 0x05234617 + TX_LANE_MAP: 0x63254170 + RX_POLARITY_FLIP: 0x05 + TX_POLARITY_FLIP: 0xd8 + ? + PC_PM_ID: 57 + 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: 0x61573204 + TX_LANE_MAP: 0x27035164 + RX_POLARITY_FLIP: 0x19 + TX_POLARITY_FLIP: 0x08 + ? + PC_PM_ID: 58 + 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: 0x05132467 + TX_LANE_MAP: 0x63457102 + RX_POLARITY_FLIP: 0xfb + TX_POLARITY_FLIP: 0xdc + ? + PC_PM_ID: 59 + 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: 0x14530276 + TX_LANE_MAP: 0x05274361 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x80 + ? + PC_PM_ID: 60 + 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: 0x73146502 + TX_LANE_MAP: 0x41735062 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xba + ? + PC_PM_ID: 61 + 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: 0x05236417 + TX_LANE_MAP: 0x26417350 + RX_POLARITY_FLIP: 0xdd + TX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 62 + 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: 0x64153072 + TX_LANE_MAP: 0x74310625 + RX_POLARITY_FLIP: 0xff + TX_POLARITY_FLIP: 0xff + ? + PC_PM_ID: 63 + 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: 0x65712430 + TX_LANE_MAP: 0x42615073 + RX_POLARITY_FLIP: 0x00 + TX_POLARITY_FLIP: 0x81 + ? + PC_PM_ID: 64 + 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: 0x35621470 + TX_LANE_MAP: 0x23456170 + RX_POLARITY_FLIP: 0xf7 + TX_POLARITY_FLIP: 0x7f +... +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 1 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 2 + : + PC_PHYS_PORT_ID: 5 + ? + PORT_ID: 3 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 4 + : + PC_PHYS_PORT_ID: 13 + ? + PORT_ID: 17 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 18 + : + PC_PHYS_PORT_ID: 21 + ? + PORT_ID: 19 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 20 + : + PC_PHYS_PORT_ID: 29 + ? + PORT_ID: 34 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 35 + : + PC_PHYS_PORT_ID: 37 + ? + PORT_ID: 36 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 37 + : + PC_PHYS_PORT_ID: 45 + ? + PORT_ID: 51 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 52 + : + PC_PHYS_PORT_ID: 53 + ? + PORT_ID: 53 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 54 + : + PC_PHYS_PORT_ID: 61 + ? + PORT_ID: 204 + : + PC_PHYS_PORT_ID: 193 + ? + PORT_ID: 205 + : + PC_PHYS_PORT_ID: 197 + ? + PORT_ID: 206 + : + PC_PHYS_PORT_ID: 201 + ? + PORT_ID: 207 + : + PC_PHYS_PORT_ID: 205 + ? + PORT_ID: 221 + : + PC_PHYS_PORT_ID: 209 + ? + PORT_ID: 222 + : + PC_PHYS_PORT_ID: 213 + ? + PORT_ID: 223 + : + PC_PHYS_PORT_ID: 217 + ? + PORT_ID: 224 + : + PC_PHYS_PORT_ID: 221 + ? + PORT_ID: 238 + : + PC_PHYS_PORT_ID: 225 + ? + PORT_ID: 239 + : + PC_PHYS_PORT_ID: 229 + ? + PORT_ID: 240 + : + PC_PHYS_PORT_ID: 233 + ? + PORT_ID: 241 + : + PC_PHYS_PORT_ID: 237 + ? + PORT_ID: 255 + : + PC_PHYS_PORT_ID: 241 + ? + PORT_ID: 256 + : + PC_PHYS_PORT_ID: 245 + ? + PORT_ID: 257 + : + PC_PHYS_PORT_ID: 249 + ? + PORT_ID: 258 + : + PC_PHYS_PORT_ID: 253 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 258 +# ? +# PORT_ID: 152 +# : +# PC_PHYS_PORT_ID: 257 +... +--- +device: + 0: + PC_PORT: + ? + PORT_ID: [[1, 4], [17, 20], [34, 37], [51, 54], [204, 207], [221, 224], [238, 241], [255, 258]] + : + ENABLE: 0 + SPEED: 400000 + NUM_LANES: 8 + FEC_MODE: PC_FEC_RS544_2XN + MAX_FRAME_SIZE: 9416 + ? +# PORT_ID: [50, 152] + PORT_ID: [50] + : + ENABLE: 0 + SPEED: 10000 + NUM_LANES: 1 + FEC_MODE: PC_FEC_NONE + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + FEC_MODE: PC_FEC_NONE + + PC_PMD_FIRMWARE: + ? + PORT_ID: [[1, 4], [17, 20], [34, 37], [51, 54], [204, 207], [221, 224], [238, 241], [255, 258]] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_COPPER +... +--- +device: + 0: + TM_SCHEDULER_CONFIG: + DYNAMIC_VOQ: 0 +... diff --git a/device/accton/x86_64-accton_as9737_32db-r0/an_support.json b/device/accton/x86_64-accton_as9737_32db-r0/an_support.json new file mode 100644 index 0000000000..0920fcd7e6 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/an_support.json @@ -0,0 +1,15 @@ +{ + "1x400G": { + "400000": ["CR8", "KR8", "LR8", "SR8"] + }, + "2x200G": { + "200000": ["CR4", "KR4", "LR4", "SR4"] + }, + "4x100G": { + "100000": ["CR2", "KR2", "SR2"] + }, + "1x100G[40G](4)": { + "100000": ["CR4", "KR4", "LR4", "SR4"], + "40000": ["CR4", "KR4", "LR4", "SR4"] + } +} diff --git a/device/accton/x86_64-accton_as9737_32db-r0/default_sku b/device/accton/x86_64-accton_as9737_32db-r0/default_sku new file mode 100644 index 0000000000..7c8eeacec1 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/default_sku @@ -0,0 +1 @@ +Accton-AS9737-32DB t1 diff --git a/device/accton/x86_64-accton_as9737_32db-r0/fast-reboot_plugin b/device/accton/x86_64-accton_as9737_32db-r0/fast-reboot_plugin new file mode 120000 index 0000000000..295bfa58fb --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/fast-reboot_plugin @@ -0,0 +1 @@ +warm-reboot_plugin \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9737_32db-r0/installer.conf b/device/accton/x86_64-accton_as9737_32db-r0/installer.conf new file mode 100644 index 0000000000..f16c4fd212 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_iommu=off pcie_aspm=off modprobe.blacklist=i2c-ismt,i2c_ismt,i2c-i801,i2c_i801,ast,ice" diff --git a/device/accton/x86_64-accton_as9737_32db-r0/media_settings.json b/device/accton/x86_64-accton_as9737_32db-r0/media_settings.json new file mode 100644 index 0000000000..2b6ffb5e24 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/media_settings.json @@ -0,0 +1,7152 @@ +{ + "PORT_MEDIA_SETTINGS": { + "1": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6904", + "lane1": "0x125f08", + "lane2": "0x106108", + "lane3": "0x106108" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c900c", + "lane1": "0x108c0c", + "lane2": "0x0c9408", + "lane3": "0x08940c", + "lane4": "0x0c900c", + "lane5": "0x108c0c", + "lane6": "0x109008", + "lane7": "0x0c900c" + } + } + }, + "2": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6904", + "lane1": "0x0c6904", + "lane2": "0x0c6904", + "lane3": "0x106504" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x108c0c", + "lane1": "0x0c900c", + "lane2": "0x049808", + "lane3": "0x0c900c", + "lane4": "0x0c900c", + "lane5": "0x0c900c", + "lane6": "0x0c900c", + "lane7": "0x0c900c" + } + } + }, + "3": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6508", + "lane1": "0x0c6508", + "lane2": "0x0c6508", + "lane3": "0x0c6508" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c9008", + "lane1": "0x109008", + "lane2": "0x0c9408", + "lane3": "0x0c900c", + "lane4": "0x0c900c", + "lane5": "0x108c0c", + "lane6": "0x108c0c", + "lane7": "0x0c8c08" + } + } + }, + "4": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6508", + "lane1": "0x106108", + "lane2": "0x0c6508", + "lane3": "0x0c6508" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8c0c", + "lane1": "0x0c8c08", + "lane2": "0x08940c", + "lane3": "0x089008", + "lane4": "0x08940c", + "lane5": "0x14880c", + "lane6": "0x0c900c", + "lane7": "0x0c900c" + } + } + }, + "5": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6508", + "lane1": "0x0c6508", + "lane2": "0x0c6508", + "lane3": "0x0c6508" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c900c", + "lane1": "0x0c900c", + "lane2": "0x08900c", + "lane3": "0x08940c", + "lane4": "0x0c8c0c", + "lane5": "0x0c9008", + "lane6": "0x108c0c", + "lane7": "0x0c9008" + } + } + }, + "6": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6508", + "lane1": "0x0c6508", + "lane2": "0x086908", + "lane3": "0x106504" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008c0c", + "lane1": "0x0c8c08", + "lane2": "0x008c0c", + "lane3": "0x0c8c0c", + "lane4": "0x08940c", + "lane5": "0x08900c", + "lane6": "0x0c8c0c", + "lane7": "0x08940c" + } + } + }, + "7": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c610c", + "lane1": "0x0c610c", + "lane2": "0x0c610c", + "lane3": "0x0c610c" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x048808", + "lane1": "0x048c08", + "lane2": "0x008c0c", + "lane3": "0x008c0c", + "lane4": "0x048c08", + "lane5": "0x0c9408", + "lane6": "0x048c08", + "lane7": "0x008c0c" + } + } + }, + "8": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c610c", + "lane1": "0x08650c", + "lane2": "0x0c610c", + "lane3": "0x0c6508" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x00840c", + "lane1": "0x008408", + "lane2": "0x00840c", + "lane3": "0x00840c", + "lane4": "0x00840c", + "lane5": "0x088c08", + "lane6": "0x048c0c", + "lane7": "0x008c0c" + } + } + }, + "9": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6508", + "lane1": "0x0c6508", + "lane2": "0x0c6508", + "lane3": "0x0c6508" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x088c0c", + "lane1": "0x08880c", + "lane2": "0x08940c", + "lane3": "0x08900c", + "lane4": "0x088c0c", + "lane5": "0x088c08", + "lane6": "0x088c0c", + "lane7": "0x088c08" + } + } + }, + "10": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6508", + "lane1": "0x126708", + "lane2": "0x106b08", + "lane3": "0x106f04" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x04900c", + "lane1": "0x089008", + "lane2": "0x088c0c", + "lane3": "0x089008", + "lane4": "0x0c900c", + "lane5": "0x0c9008", + "lane6": "0x0c9008", + "lane7": "0x0c9008" + } + } + }, + "11": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106308", + "lane1": "0x0c6508", + "lane2": "0x0c6508", + "lane3": "0x0c6108" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x04840c", + "lane1": "0x0c900c", + "lane2": "0x00840c", + "lane3": "0x048408", + "lane4": "0x08880c", + "lane5": "0x0c8c10", + "lane6": "0x049008", + "lane7": "0x048c0c" + } + } + }, + "12": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6108", + "lane1": "0x0c6508", + "lane2": "0x086508", + "lane3": "0x086508" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x08940c", + "lane1": "0x04980c", + "lane2": "0x049c08", + "lane3": "0x108c08", + "lane4": "0x108c0c", + "lane5": "0x0c9008", + "lane6": "0x089008", + "lane7": "0x0c8c10" + } + } + }, + "13": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x0c6000", + "lane2": "0x0c6000", + "lane3": "0x0c6000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x085908", + "lane1": "0x085d08", + "lane2": "0x085708", + "lane3": "0x085708" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008408", + "lane1": "0x00840c", + "lane2": "0x00840c", + "lane3": "0x008408", + "lane4": "0x048408", + "lane5": "0x008408", + "lane6": "0x008408", + "lane7": "0x008408" + } + } + }, + "14": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x0c6000", + "lane2": "0x0c6000", + "lane3": "0x0c6000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x045b04", + "lane1": "0x045b04", + "lane2": "0x045b04", + "lane3": "0x045b04" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008408", + "lane1": "0x008c08", + "lane2": "0x00840c", + "lane3": "0x00840c", + "lane4": "0x00840c", + "lane5": "0x00840c", + "lane6": "0x008408", + "lane7": "0x00840c" + } + } + }, + "15": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x0c6000", + "lane2": "0x0c6000", + "lane3": "0x0c6000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x045704", + "lane1": "0x045d04", + "lane2": "0x045104", + "lane3": "0x045104" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008408", + "lane1": "0x008408", + "lane2": "0x008008", + "lane3": "0x008408", + "lane4": "0x00840c", + "lane5": "0x008408", + "lane6": "0x008408", + "lane7": "0x008408" + } + } + }, + "16": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x0c6000", + "lane2": "0x0c6000", + "lane3": "0x0c6000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x045904", + "lane1": "0x045904", + "lane2": "0x045d04", + "lane3": "0x045d04" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x00880c", + "lane1": "0x00840c", + "lane2": "0x00840c", + "lane3": "0x00840c", + "lane4": "0x048408", + "lane5": "0x04840c", + "lane6": "0x048408", + "lane7": "0x00840c" + } + } + }, + "17": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x0c6000", + "lane2": "0x0c6000", + "lane3": "0x0c6000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x045504", + "lane1": "0x045904", + "lane2": "0x045504", + "lane3": "0x045504" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008008", + "lane1": "0x008408", + "lane2": "0x008408", + "lane3": "0x008008", + "lane4": "0x008408", + "lane5": "0x008408", + "lane6": "0x008408", + "lane7": "0x008408" + } + } + }, + "18": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x0c6000", + "lane2": "0x0c6000", + "lane3": "0x0c6000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x045904", + "lane1": "0x045b04", + "lane2": "0x045f04", + "lane3": "0x045d04" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008c0c", + "lane1": "0x00900c", + "lane2": "0x008c0c", + "lane3": "0x008c08", + "lane4": "0x049410", + "lane5": "0x04980c", + "lane6": "0x04980c", + "lane7": "0x009c0c" + } + } + }, + "19": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x0c6000", + "lane2": "0x0c6000", + "lane3": "0x0c6000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x045504", + "lane1": "0x045504", + "lane2": "0x045904", + "lane3": "0x045904" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007c08", + "lane1": "0x008408", + "lane2": "0x008408", + "lane3": "0x008408", + "lane4": "0x048408", + "lane5": "0x008408", + "lane6": "0x008408", + "lane7": "0x008408" + } + } + }, + "20": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x0c6000", + "lane2": "0x0c6000", + "lane3": "0x0c6000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x045104", + "lane1": "0x045904", + "lane2": "0x045904", + "lane3": "0x045904" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008408", + "lane1": "0x008008", + "lane2": "0x048808", + "lane3": "0x008008", + "lane4": "0x00840c", + "lane5": "0x048408", + "lane6": "0x048408", + "lane7": "0x048408" + } + } + }, + "21": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x0c6000", + "lane2": "0x0c6000", + "lane3": "0x0c6000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x045904", + "lane1": "0x045904", + "lane2": "0x045904", + "lane3": "0x045904" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008c08", + "lane1": "0x008c0c", + "lane2": "0x008c08", + "lane3": "0x008c08", + "lane4": "0x008c08", + "lane5": "0x008c08", + "lane6": "0x088c08", + "lane7": "0x08940c" + } + } + }, + "22": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6000", + "lane1": "0x106000", + "lane2": "0x106000", + "lane3": "0x106000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x086504", + "lane1": "0x086504", + "lane2": "0x086304", + "lane3": "0x086304" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x08900c", + "lane1": "0x088c0c", + "lane2": "0x048c0c", + "lane3": "0x089008", + "lane4": "0x08900c", + "lane5": "0x08900c", + "lane6": "0x0c8c10", + "lane7": "0x009008" + } + } + }, + "23": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106000", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x085f04", + "lane1": "0x106b04", + "lane2": "0x106b04", + "lane3": "0x106b04" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x08900c", + "lane1": "0x0c900c", + "lane2": "0x009008", + "lane3": "0x0c9008", + "lane4": "0x0c900c", + "lane5": "0x0c900c", + "lane6": "0x0c9008", + "lane7": "0x0c9008" + } + } + }, + "24": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x145c00", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106b04", + "lane1": "0x146308", + "lane2": "0x106b04", + "lane3": "0x106b04" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x04980c", + "lane1": "0x108c0c", + "lane2": "0x08900c", + "lane3": "0x049008", + "lane4": "0x0c900c", + "lane5": "0x14880c", + "lane6": "0x08940c", + "lane7": "0x0c900c" + } + } + }, + "25": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106000", + "lane1": "0x106000", + "lane2": "0x106000", + "lane3": "0x106000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x045b04", + "lane1": "0x045f04", + "lane2": "0x045b04", + "lane3": "0x045704" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x00880c", + "lane1": "0x048808", + "lane2": "0x048c08", + "lane3": "0x048808", + "lane4": "0x04880c", + "lane5": "0x088c0c", + "lane6": "0x00880c", + "lane7": "0x04880c" + } + } + }, + "26": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106000", + "lane1": "0x106000", + "lane2": "0x106000", + "lane3": "0x106000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x046304", + "lane1": "0x045f04", + "lane2": "0x045f04", + "lane3": "0x046704" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008c08", + "lane1": "0x008c08", + "lane2": "0x008c0c", + "lane3": "0x048c0c", + "lane4": "0x04900c", + "lane5": "0x049008", + "lane6": "0x049008", + "lane7": "0x048c08" + } + } + }, + "27": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106000", + "lane1": "0x106000", + "lane2": "0x106000", + "lane3": "0x106000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x085f04", + "lane1": "0x085f04", + "lane2": "0x045f04", + "lane3": "0x046704" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x008c0c", + "lane1": "0x008c08", + "lane2": "0x008c0c", + "lane3": "0x008c08", + "lane4": "0x0c900c", + "lane5": "0x008c08", + "lane6": "0x0c9408", + "lane7": "0x08900c" + } + } + }, + "28": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106000", + "lane1": "0x106000", + "lane2": "0x106000", + "lane3": "0x106000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x046704", + "lane1": "0x046704", + "lane2": "0x046704", + "lane3": "0x046f04" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x08940c", + "lane1": "0x04980c", + "lane2": "0x089808", + "lane3": "0x08940c", + "lane4": "0x0c9008", + "lane5": "0x08900c", + "lane6": "0x089008", + "lane7": "0x08940c" + } + } + }, + "29": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106000", + "lane1": "0x106000", + "lane2": "0x106000", + "lane3": "0x106000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x086b04", + "lane1": "0x086304", + "lane2": "0x086304", + "lane3": "0x086704" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8c0c", + "lane1": "0x08900c", + "lane2": "0x088c08", + "lane3": "0x0c8c08", + "lane4": "0x0c8c0c", + "lane5": "0x0c8c08", + "lane6": "0x0c8c08", + "lane7": "0x0c8c08" + } + } + }, + "30": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106000", + "lane1": "0x106000", + "lane2": "0x106000", + "lane3": "0x106000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x086704", + "lane1": "0x086b04", + "lane2": "0x086f04", + "lane3": "0x086b04" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x088c0c", + "lane1": "0x0c8c10", + "lane2": "0x088c08", + "lane3": "0x0c8c0c", + "lane4": "0x0c8c08", + "lane5": "0x0c8c0c", + "lane6": "0x0c8c0c", + "lane7": "0x0c8c08" + } + } + }, + "31": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x106000", + "lane1": "0x106000", + "lane2": "0x106000", + "lane3": "0x106000" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x086304", + "lane1": "0x086f04", + "lane2": "0x086f04", + "lane3": "0x0c6b04" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x089808", + "lane1": "0x0c900c", + "lane2": "0x089808", + "lane3": "0x088c0c", + "lane4": "0x0c900c", + "lane5": "0x0c8c10", + "lane6": "0x108c0c", + "lane7": "0x0c8c0c" + } + } + }, + "32": { + "COPPER-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x007F00", + "lane1": "0x007F00", + "lane2": "0x007F00", + "lane3": "0x007F00", + "lane4": "0x007F00", + "lane5": "0x007F00", + "lane6": "0x007F00", + "lane7": "0x007F00" + } + }, + "COPPER-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x145c00", + "lane1": "0x145c00", + "lane2": "0x106000", + "lane3": "0x145c00" + } + }, + "OPTICAL-25000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100" + }, + "preemphasis": { + "lane0": "0x0c6b04", + "lane1": "0x0c6f04", + "lane2": "0x106b04", + "lane3": "0x106708" + } + }, + "OPTICAL-50000": { + "post2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "post3": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "pre2": { + "lane0": "0x0100", + "lane1": "0x0100", + "lane2": "0x0100", + "lane3": "0x0100", + "lane4": "0x0100", + "lane5": "0x0100", + "lane6": "0x0100", + "lane7": "0x0100" + }, + "preemphasis": { + "lane0": "0x049808", + "lane1": "0x088c0c", + "lane2": "0x0c8c10", + "lane3": "0x108c08", + "lane4": "0x108c0c", + "lane5": "0x109008", + "lane6": "0x108c0c", + "lane7": "0x08900c" + } + } + }, + "33": { + "COPPER-1000": { + "post2": { + "lane0": "0x0100" + }, + "post3": { + "lane0": "0x01ff" + }, + "pre2": { + "lane0": "0x01ff" + }, + "preemphasis": { + "lane0": "0x0a3200" + } + }, + "COPPER-10000": { + "post2": { + "lane0": "0x0100" + }, + "post3": { + "lane0": "0x01ff" + }, + "pre2": { + "lane0": "0x01ff" + }, + "preemphasis": { + "lane0": "0x0a3200" + } + }, + "OPTICAL-10000": { + "post2": { + "lane0": "0x0000" + }, + "post3": { + "lane0": "0x0000" + }, + "pre2": { + "lane0": "0x0000" + }, + "preemphasis": { + "lane0": "0x042506" + } + } + } + } +} diff --git a/device/accton/x86_64-accton_as9737_32db-r0/pcie.yaml b/device/accton/x86_64-accton_as9737_32db-r0/pcie.yaml new file mode 100644 index 0000000000..32d8a8acd1 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/pcie.yaml @@ -0,0 +1,435 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 09a2 + name: 'System peripheral: Intel Corporation Device 09a2 (rev 04)' +- bus: '00' + dev: '00' + fn: '1' + id: 09a4 + name: 'System peripheral: Intel Corporation Device 09a4 (rev 04)' +- bus: '00' + dev: '00' + fn: '2' + id: 09a3 + name: 'System peripheral: Intel Corporation Device 09a3 (rev 04)' +- bus: '00' + dev: '00' + fn: '3' + id: 09a5 + name: 'System peripheral: Intel Corporation Device 09a5 (rev 04)' +- bus: '00' + dev: '00' + fn: '4' + id: 0998 + name: 'Host bridge: Intel Corporation Device 0998' +- bus: '00' + dev: '01' + fn: '0' + id: '0b00' + name: 'System peripheral: Intel Corporation Device 0b00' +- bus: '00' + dev: '01' + fn: '1' + id: '0b00' + name: 'System peripheral: Intel Corporation Device 0b00' +- bus: '00' + dev: '01' + fn: '2' + id: '0b00' + name: 'System peripheral: Intel Corporation Device 0b00' +- bus: '00' + dev: '01' + fn: '3' + id: '0b00' + name: 'System peripheral: Intel Corporation Device 0b00' +- bus: '00' + dev: '01' + fn: '4' + id: '0b00' + name: 'System peripheral: Intel Corporation Device 0b00' +- bus: '00' + dev: '01' + fn: '5' + id: '0b00' + name: 'System peripheral: Intel Corporation Device 0b00' +- bus: '00' + dev: '01' + fn: '6' + id: '0b00' + name: 'System peripheral: Intel Corporation Device 0b00' +- bus: '00' + dev: '01' + fn: '7' + id: '0b00' + name: 'System peripheral: Intel Corporation Device 0b00' +- bus: '00' + dev: '02' + fn: '0' + id: 09a6 + name: 'System peripheral: Intel Corporation Device 09a6' +- bus: '00' + dev: '02' + fn: '1' + id: 09a7 + name: 'System peripheral: Intel Corporation Device 09a7' +- bus: '00' + dev: '02' + fn: '4' + id: '3456' + name: 'Non-Essential Instrumentation [1300]: Intel Corporation Device 3456 (rev + 01)' +- bus: '00' + dev: '06' + fn: '0' + id: 18da + name: 'PCI bridge: Intel Corporation Device 18da (rev 11)' +- bus: '00' + dev: 09 + fn: '0' + id: 18a4 + name: 'PCI bridge: Intel Corporation Device 18a4 (rev 11)' +- bus: '00' + dev: 0b + fn: '0' + id: 18a6 + name: 'PCI bridge: Intel Corporation Device 18a6 (rev 11)' +- bus: '00' + dev: 0e + fn: '0' + id: 18f2 + name: 'SATA controller: Intel Corporation Device 18f2 (rev 11)' +- bus: '00' + dev: 0f + fn: '0' + id: 18ac + name: 'System peripheral: Intel Corporation Device 18ac (rev 11)' +- bus: '00' + dev: '14' + fn: '0' + id: 18ad + name: 'PCI bridge: Intel Corporation Device 18ad (rev 11)' +- bus: '00' + dev: '18' + fn: '0' + id: 18d3 + name: 'Communication controller: Intel Corporation Device 18d3 (rev 11)' +- bus: '00' + dev: '18' + fn: '1' + id: 18d4 + name: 'Communication controller: Intel Corporation Device 18d4 (rev 11)' +- bus: '00' + dev: '18' + fn: '4' + id: 18d6 + name: 'Communication controller: Intel Corporation Device 18d6 (rev 11)' +- bus: '00' + dev: 1a + fn: '0' + id: 18d8 + name: 'Serial controller: Intel Corporation Device 18d8 (rev 11)' +- bus: '00' + dev: 1a + fn: '1' + id: 18d8 + name: 'Serial controller: Intel Corporation Device 18d8 (rev 11)' +- bus: '00' + dev: 1a + fn: '2' + id: 18d8 + name: 'Serial controller: Intel Corporation Device 18d8 (rev 11)' +- bus: '00' + dev: 1a + fn: '3' + id: 18d9 + name: 'Unassigned class [ff00]: Intel Corporation Device 18d9 (rev 11)' +- bus: '00' + dev: 1d + fn: '0' + id: 0998 + name: 'Host bridge: Intel Corporation Device 0998' +- bus: '00' + dev: 1e + fn: '0' + id: 18d0 + name: 'USB controller: Intel Corporation Device 18d0 (rev 11)' +- bus: '00' + dev: 1f + fn: '0' + id: 18dc + name: 'ISA bridge: Intel Corporation Device 18dc (rev 11)' +- bus: '00' + dev: 1f + fn: '4' + id: 18df + name: 'SMBus: Intel Corporation Device 18df (rev 11)' +- bus: '00' + dev: 1f + fn: '5' + id: 18e0 + name: 'Serial bus controller [0c80]: Intel Corporation Device 18e0 (rev 11)' +- bus: '00' + dev: 1f + fn: '7' + id: 18e1 + name: 'Non-Essential Instrumentation [1300]: Intel Corporation Device 18e1 (rev + 11)' +- bus: '01' + dev: '00' + fn: '0' + id: 18ee + name: 'Co-processor: Intel Corporation Device 18ee (rev 11)' +- bus: '02' + dev: '00' + fn: '0' + id: '0004' + name: 'Non-VGA unclassified device: Altera Corporation Device 0004 (rev 01)' +- bus: '03' + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: '04' + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: '14' + dev: '00' + fn: '0' + id: 09a2 + name: 'System peripheral: Intel Corporation Device 09a2 (rev 04)' +- bus: '14' + dev: '00' + fn: '1' + id: 09a4 + name: 'System peripheral: Intel Corporation Device 09a4 (rev 04)' +- bus: '14' + dev: '00' + fn: '2' + id: 09a3 + name: 'System peripheral: Intel Corporation Device 09a3 (rev 04)' +- bus: '14' + dev: '00' + fn: '3' + id: 09a5 + name: 'System peripheral: Intel Corporation Device 09a5 (rev 04)' +- bus: '14' + dev: '00' + fn: '4' + id: 0998 + name: 'Host bridge: Intel Corporation Device 0998' +- bus: '14' + dev: '02' + fn: '0' + id: 347a + name: 'PCI bridge: Intel Corporation Device 347a (rev 06)' +- bus: '14' + dev: '04' + fn: '0' + id: 347c + name: 'PCI bridge: Intel Corporation Device 347c (rev 06)' +- bus: '15' + dev: '00' + fn: '0' + id: b993 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b993 (rev 11)' +- bus: '16' + dev: '00' + fn: '0' + id: '1537' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Backplane Connection + (rev 03)' +- bus: f3 + dev: '00' + fn: '0' + id: 09a2 + name: 'System peripheral: Intel Corporation Device 09a2 (rev 04)' +- bus: f3 + dev: '00' + fn: '1' + id: 09a4 + name: 'System peripheral: Intel Corporation Device 09a4 (rev 04)' +- bus: f3 + dev: '00' + fn: '2' + id: 09a3 + name: 'System peripheral: Intel Corporation Device 09a3 (rev 04)' +- bus: f3 + dev: '00' + fn: '3' + id: 09a5 + name: 'System peripheral: Intel Corporation Device 09a5 (rev 04)' +- bus: f3 + dev: '00' + fn: '4' + id: 0998 + name: 'Host bridge: Intel Corporation Device 0998' +- bus: f3 + dev: '04' + fn: '0' + id: 18d1 + name: 'PCI bridge: Intel Corporation Device 18d1' +- bus: f4 + dev: '00' + fn: '0' + id: 124c + name: 'Ethernet controller: Intel Corporation Ethernet Connection E823-L for backplane' +- bus: f4 + dev: '00' + fn: '1' + id: 124c + name: 'Ethernet controller: Intel Corporation Ethernet Connection E823-L for backplane' +- bus: f4 + dev: '00' + fn: '2' + id: 124c + name: 'Ethernet controller: Intel Corporation Ethernet Connection E823-L for backplane' +- bus: f4 + dev: '00' + fn: '3' + id: 124c + name: 'Ethernet controller: Intel Corporation Ethernet Connection E823-L for backplane' +- bus: fe + dev: '00' + fn: '0' + id: '3450' + name: 'System peripheral: Intel Corporation Device 3450' +- bus: fe + dev: '00' + fn: '1' + id: '3451' + name: 'System peripheral: Intel Corporation Device 3451' +- bus: fe + dev: '00' + fn: '2' + id: '3452' + name: 'System peripheral: Intel Corporation Device 3452' +- bus: fe + dev: '00' + fn: '3' + id: 0998 + name: 'Host bridge: Intel Corporation Device 0998' +- bus: fe + dev: '00' + fn: '5' + id: '3455' + name: 'System peripheral: Intel Corporation Device 3455' +- bus: fe + dev: 0b + fn: '0' + id: '3448' + name: 'System peripheral: Intel Corporation Device 3448' +- bus: fe + dev: 0b + fn: '1' + id: '3448' + name: 'System peripheral: Intel Corporation Device 3448' +- bus: fe + dev: 0b + fn: '2' + id: 344b + name: 'System peripheral: Intel Corporation Device 344b' +- bus: fe + dev: 0c + fn: '0' + id: 344a + name: 'Performance counters: Intel Corporation Device 344a' +- bus: fe + dev: 1a + fn: '0' + id: '2880' + name: 'Performance counters: Intel Corporation Device 2880' +- bus: ff + dev: '00' + fn: '0' + id: 344c + name: 'System peripheral: Intel Corporation Device 344c' +- bus: ff + dev: '00' + fn: '1' + id: 344c + name: 'System peripheral: Intel Corporation Device 344c' +- bus: ff + dev: '00' + fn: '2' + id: 344c + name: 'System peripheral: Intel Corporation Device 344c' +- bus: ff + dev: '00' + fn: '3' + id: 344c + name: 'System peripheral: Intel Corporation Device 344c' +- bus: ff + dev: 0a + fn: '0' + id: 344d + name: 'System peripheral: Intel Corporation Device 344d' +- bus: ff + dev: 0a + fn: '1' + id: 344d + name: 'System peripheral: Intel Corporation Device 344d' +- bus: ff + dev: 0a + fn: '2' + id: 344d + name: 'System peripheral: Intel Corporation Device 344d' +- bus: ff + dev: 0a + fn: '3' + id: 344d + name: 'System peripheral: Intel Corporation Device 344d' +- bus: ff + dev: 1d + fn: '0' + id: 344f + name: 'System peripheral: Intel Corporation Device 344f' +- bus: ff + dev: 1d + fn: '1' + id: '3457' + name: 'System peripheral: Intel Corporation Device 3457' +- bus: ff + dev: 1e + fn: '0' + id: '3458' + name: 'System peripheral: Intel Corporation Device 3458 (rev 01)' +- bus: ff + dev: 1e + fn: '1' + id: '3459' + name: 'System peripheral: Intel Corporation Device 3459 (rev 01)' +- bus: ff + dev: 1e + fn: '2' + id: 345a + name: 'System peripheral: Intel Corporation Device 345a (rev 01)' +- bus: ff + dev: 1e + fn: '3' + id: 345b + name: 'System peripheral: Intel Corporation Device 345b (rev 01)' +- bus: ff + dev: 1e + fn: '4' + id: 345c + name: 'System peripheral: Intel Corporation Device 345c (rev 01)' +- bus: ff + dev: 1e + fn: '5' + id: 345d + name: 'System peripheral: Intel Corporation Device 345d (rev 01)' +- bus: ff + dev: 1e + fn: '6' + id: 345e + name: 'System peripheral: Intel Corporation Device 345e (rev 01)' +- bus: ff + dev: 1e + fn: '7' + id: 345f + name: 'System peripheral: Intel Corporation Device 345f (rev 01)' diff --git a/device/accton/x86_64-accton_as9737_32db-r0/platform.json b/device/accton/x86_64-accton_as9737_32db-r0/platform.json new file mode 100644 index 0000000000..4308db97dc --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/platform.json @@ -0,0 +1,946 @@ +{ + "chassis": { + "name": "AS9737-32DB", + "thermal_manager":false, + "status_led": { + "controllable": true, + "colors": ["STATUS_LED_COLOR_RED", "STATUS_LED_COLOR_OFF"] + }, + "components": [ + { + "name": "CPLD1" + }, + { + "name": "CPLD2" + }, + { + "name": "CPLD3" + }, + { + "name": "FPGA" + }, + { + "name": "BIOS" + } + ], + "fans": [ + { + "name": "FAN-1F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-1R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-2F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-2R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-3F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-3R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-4F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-4R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-5F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-5R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-6F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-6R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + } + ], + "fan_drawers":[ + { + "name": "FanTray1", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-1F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-1R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray2", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-2F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-2R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray3", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-3F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-3R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray4", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-4F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-4R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray5", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-5F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-5R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + } + ] + }, + { + "name": "FanTray6", + "status_led": { + "controllable": false + }, + "num_fans" : 2, + "fans": [ + { + "name": "FAN-6F", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + }, + { + "name": "FAN-6R", + "speed": { + "controllable": true, + "minimum": 32 + }, + "status_led": { + "controllable": false + } + } + ] + } + ], + "psus": [ + { + "name": "PSU-1", + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU-1 FAN-1", + "speed": { + "controllable": false + }, + "status_led": { + "controllable": false + } + } + ], + "thermals": [ + { + "name": "PSU-1 temp sensor 1", + "controllable": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "PSU-1 temp sensor 2", + "controllable": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "PSU-1 temp sensor 3", + "controllable": false, + "low-crit-threshold": false, + "high-crit-threshold": false + } + ] + }, + { + "name": "PSU-2", + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU-2 FAN-1", + "speed": { + "controllable": false + }, + "status_led": { + "controllable": false + } + } + ], + "thermals": [ + { + "name": "PSU-2 temp sensor 1", + "controllable": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "PSU-2 temp sensor 2", + "controllable": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "PSU-2 temp sensor 3", + "controllable": false, + "low-crit-threshold": false, + "high-crit-threshold": false + } + ] + } + ], + "thermals": [ + { + "name": "MB_FrontCenter_temp(0x48)", + "controllable": false, + "low-threshold": false, + "high-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "MB_FrontRight_temp(0x49)", + "controllable": false, + "low-threshold": false, + "high-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "MB_RearCenter_temp(0x4A)", + "controllable": false, + "low-threshold": false, + "high-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "MB_RearLeft_temp(0x4C)", + "controllable": false, + "low-threshold": false, + "high-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "MB_RearCenter_temp(0x4F)", + "controllable": false, + "low-threshold": false, + "high-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "CPU_Package_temp", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": true + }, + { + "name": "CPU_Core_0_temp", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": true + }, + { + "name": "CPU_Core_1_temp", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": true + }, + { + "name": "CPU_Core_2_temp", + "controllable": true, + "low-threshold": false, + "high-threshold": true, + "low-crit-threshold": false, + "high-crit-threshold": true + }, + { + "name": "CPU_Core_3_temp", + "controllable": true, + "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" + } + ] + }, + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1,1,1,1,1", + "lanes": "74,75,76,77,78,79,80,81", + "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)"] + } + }, + + "Ethernet8": { + "index": "2,2,2,2,2,2,2,2", + "lanes": "66,67,68,69,70,71,72,73", + "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)"] + } + }, + + "Ethernet16": { + "index": "3,3,3,3,3,3,3,3", + "lanes": "82,83,84,85,86,87,88,89", + "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)"] + } + }, + + "Ethernet24": { + "index": "4,4,4,4,4,4,4,4", + "lanes": "90,91,92,93,94,95,96,97", + "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)"] + } + }, + + "Ethernet32": { + "index": "5,5,5,5,5,5,5,5", + "lanes": "98,99,100,101,102,103,104,105", + "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)"] + } + }, + + "Ethernet40": { + "index": "6,6,6,6,6,6,6,6", + "lanes": "106,107,108,109,110,111,112,113", + "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)"] + } + }, + + "Ethernet48": { + "index": "7,7,7,7,7,7,7,7", + "lanes": "114,115,116,117,118,119,120,121", + "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)"] + } + }, + + "Ethernet56": { + "index": "8,8,8,8,8,8,8,8", + "lanes": "122,123,124,125,126,127,128,129", + "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)"] + } + }, + + "Ethernet64": { + "index": "9,9,9,9,9,9,9,9", + "lanes": "42,43,44,45,46,47,48,49", + "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)"] + } + }, + + "Ethernet72": { + "index": "10,10,10,10,10,10,10,10", + "lanes": "34,35,36,37,38,39,40,41", + "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)"] + } + }, + + "Ethernet80": { + "index": "11,11,11,11,11,11,11,11", + "lanes": "50,51,52,53,54,55,56,57", + "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)"] + } + }, + + "Ethernet88": { + "index": "12,12,12,12,12,12,12,12", + "lanes": "58,59,60,61,62,63,64,65", + "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)"] + } + }, + + "Ethernet96": { + "index": "13,13,13,13,13,13,13,13", + "lanes": "386,387,388,389,390,391,392,393", + "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)"] + } + }, + + "Ethernet104": { + "index": "14,14,14,14,14,14,14,14", + "lanes": "394,395,396,397,398,399,400,401", + "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)"] + } + }, + + "Ethernet112": { + "index": "15,15,15,15,15,15,15,15", + "lanes": "402,403,404,405,406,407,408,409", + "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)"] + } + }, + + "Ethernet120": { + "index": "16,16,16,16,16,16,16,16", + "lanes": "410,411,412,413,414,415,416,417", + "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)"] + } + }, + + "Ethernet128": { + "index": "17,17,17,17,17,17,17,17", + "lanes": "426,427,428,429,430,431,432,433", + "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)"] + } + }, + + "Ethernet136": { + "index": "18,18,18,18,18,18,18,18", + "lanes": "418,419,420,421,422,423,424,425", + "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)"] + } + }, + + "Ethernet144": { + "index": "19,19,19,19,19,19,19,19", + "lanes": "434,435,436,437,438,439,440,441", + "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)"] + } + }, + + "Ethernet152": { + "index": "20,20,20,20,20,20,20,20", + "lanes": "442,443,444,445,446,447,448,449", + "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)"] + } + }, + + "Ethernet160": { + "index": "21,21,21,21,21,21,21,21", + "lanes": "2,3,4,5,6,7,8,9", + "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)"] + } + }, + + "Ethernet168": { + "index": "22,22,22,22,22,22,22,22", + "lanes": "10,11,12,13,14,15,16,17", + "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)"] + } + }, + + "Ethernet176": { + "index": "23,23,23,23,23,23,23,23", + "lanes": "18,19,20,21,22,23,24,25", + "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)"] + } + }, + + "Ethernet184": { + "index": "24,24,24,24,24,24,24,24", + "lanes": "26,27,28,29,30,31,32,33", + "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)"] + } + }, + + "Ethernet192": { + "index": "25,25,25,25,25,25,25,25", + "lanes": "458,459,460,461,462,463,464,465", + "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)"] + } + }, + + "Ethernet200": { + "index": "26,26,26,26,26,26,26,26", + "lanes": "450,451,452,453,454,455,456,457", + "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)"] + } + }, + + "Ethernet208": { + "index": "27,27,27,27,27,27,27,27", + "lanes": "474,475,476,477,478,479,480,481", + "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)"] + } + }, + + "Ethernet216": { + "index": "28,28,28,28,28,28,28,28", + "lanes": "466,467,468,469,470,471,472,473", + "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)"] + } + }, + + "Ethernet224": { + "index": "29,29,29,29,29,29,29,29", + "lanes": "490,491,492,493,494,495,496,497", + "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)"] + } + }, + + "Ethernet232": { + "index": "30,30,30,30,30,30,30,30", + "lanes": "482,483,484,485,486,487,488,489", + "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)"] + } + }, + + "Ethernet240": { + "index": "31,31,31,31,31,31,31,31", + "lanes": "506,507,508,509,510,511,512,513", + "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)"] + } + }, + + "Ethernet248": { + "index": "32,32,32,32,32,32,32,32", + "lanes": "498,499,500,501,502,503,504,505", + "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)"] + } + }, + + "Ethernet256": { + "index": "33", + "lanes": "516", + "breakout_modes": { + "1x10G[1G]": ["Eth33(Port33)"] + } + } + } +} + diff --git a/device/accton/x86_64-accton_as9737_32db-r0/platform_asic b/device/accton/x86_64-accton_as9737_32db-r0/platform_asic new file mode 100644 index 0000000000..9604676527 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/platform_asic @@ -0,0 +1 @@ +broadcom diff --git a/device/accton/x86_64-accton_as9737_32db-r0/platform_components.json b/device/accton/x86_64-accton_as9737_32db-r0/platform_components.json new file mode 100644 index 0000000000..44bccedba6 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/platform_components.json @@ -0,0 +1,13 @@ +{ + "chassis": { + "AS9737-32DB-O-AC-F": { + "component": { + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { }, + "FPGA": { }, + "BIOS": { } + } + } + } +} diff --git a/device/accton/x86_64-accton_as9737_32db-r0/platform_env.conf b/device/accton/x86_64-accton_as9737_32db-r0/platform_env.conf new file mode 100644 index 0000000000..aee1c756bf --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/platform_env.conf @@ -0,0 +1,2 @@ +SYNCD_SHM_SIZE=1G +is_ltsw_chip=1 diff --git a/device/accton/x86_64-accton_as9737_32db-r0/platform_reboot b/device/accton/x86_64-accton_as9737_32db-r0/platform_reboot new file mode 100755 index 0000000000..facc1c05f2 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/platform_reboot @@ -0,0 +1,10 @@ +#!/bin/bash + +echo "Do sync" +sync + +echo "Stop pmon.service" +systemctl stop pmon.service + +echo "Stop as9737_32db-platform-monitor.service" +systemctl stop as9737_32db-platform-monitor.service diff --git a/device/accton/x86_64-accton_as9737_32db-r0/plugins/ssd_util.py b/device/accton/x86_64-accton_as9737_32db-r0/plugins/ssd_util.py new file mode 100644 index 0000000000..1984747612 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/plugins/ssd_util.py @@ -0,0 +1,29 @@ +# ssd_util.py +# +# Platform-specific SSD interface for SONiC +## + +try: + from sonic_platform_base.sonic_ssd.ssd_generic import SsdUtil as MainSsdUtil + from sonic_platform_base.sonic_ssd.ssd_generic import NOT_AVAILABLE + from sonic_py_common import logger +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SYSLOG_IDENTIFIER = "ssd_util.py" + +# Global logger instance +log = logger.Logger(SYSLOG_IDENTIFIER) + +class SsdUtil(MainSsdUtil): + """Platform-specific SsdUtil class""" + + def __init__(self, diskdev): + super(SsdUtil, self).__init__(diskdev) + + # If it has no vendor tool to read SSD information, + # ssd_util.py will use generic SSD information + # for vendor SSD information. + if self.vendor_ssd_info == NOT_AVAILABLE or \ + len(self.vendor_ssd_info.strip()) == 0: + self.vendor_ssd_info = self.ssd_info diff --git a/device/accton/x86_64-accton_as9737_32db-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as9737_32db-r0/pmon_daemon_control.json new file mode 100644 index 0000000000..98506b4614 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sensors.conf b/device/accton/x86_64-accton_as9737_32db-r0/sensors.conf new file mode 100644 index 0000000000..52b590f8a5 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sensors.conf @@ -0,0 +1,40 @@ +chip "as9737_32db_fan-isa-0000" + 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 fan7 "Fan 1 Rear" + label fan8 "Fan 2 Rear" + label fan9 "Fan 3 Rear" + label fan10 "Fan 4 Rear" + label fan11 "Fan 5 Rear" + label fan12 "Fan 6 Rear" + +chip "as9737_32db_thermal-isa-0000" + label temp1 "MB_FrontCenter_temp(0x48)" + label temp2 "MB_FrontRight_temp(0x49)" + label temp3 "MB_RearCenter_temp(0x4A)" + label temp4 "MB_RearLeft_temp(0x4C)" + label temp5 "MB_RearCenter_temp(0x4F)" + +chip "as9737_32db_psu-isa-0000" + label in0 "PSU 1 Voltage" + label fan1 "PSU 1 Fan" + label temp1 "PSU 1 Temperature" + label power1 "PSU 1 Power" + label curr1 "PSU 1 Current" + +chip "as9737_32db_psu-isa-0001" + label in1 "PSU 2 Voltage" + label fan2 "PSU 2 Fan" + label temp2 "PSU 2 Temperature" + label power2 "PSU 2 Power" + label curr2 "PSU 2 Current" + +chip "nvme-pci-1600" + label temp1 "nvme0 Temperature" + +chip "nvme-pci-1700" + label temp1 "nvme1 Temperature" diff --git a/device/accton/x86_64-accton_as9737_32db-r0/soft-reboot_plugin b/device/accton/x86_64-accton_as9737_32db-r0/soft-reboot_plugin new file mode 120000 index 0000000000..295bfa58fb --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/soft-reboot_plugin @@ -0,0 +1 @@ +warm-reboot_plugin \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/__init__.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/__init__.py new file mode 100644 index 0000000000..706e231324 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp', 'thermal', 'fan', 'fan_drawer'] +from . import platform diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/chassis.py new file mode 100644 index 0000000000..c9deb5de32 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/chassis.py @@ -0,0 +1,308 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys + +try: + from sonic_platform_base.chassis_base import ChassisBase + from .helper import APIHelper + from .event import SfpEvent + from sonic_py_common import device_info + from sonic_py_common.general import getstatusoutput_noshell +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_TRAY = 6 +NUM_PSU = 2 +NUM_THERMAL = 10 +NUM_PORT = 33 +NUM_COMPONENT = 5 + +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" + +SYSLED_FNODE= "/sys/devices/platform/as9737_32db_led/led_alarm" +SYSLED_MODES = { + "0" : "STATUS_LED_COLOR_OFF", + "10" : "STATUS_LED_COLOR_RED", +} + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + ChassisBase.__init__(self) + self._api_helper = APIHelper() + self.is_host = self._api_helper.is_host() + + self.config_data = {} + + self.CPU_RESET_REASON = { + 0x80 : [self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC,"EC_DIMM CRITICAL RESET"] , + 0x40 : [self.REBOOT_CAUSE_WATCHDOG, "CPU WDT RESET" ], + 0x20 : [self.REBOOT_CAUSE_HARDWARE_OTHER, "CPU COLD RESET"], + 0x10 : [self.REBOOT_CAUSE_NON_HARDWARE, "CPU WARM RESET"], + 0x8 : [self.REBOOT_CAUSE_HARDWARE_OTHER, "RESET_BUTTON RESET"], + 0x4 : [self.REBOOT_CAUSE_HARDWARE_OTHER, "POWER_BUTTON RESET"], + 0x2 : [self.REBOOT_CAUSE_WATCHDOG, "EC WDT RESET"], + 0x1 : [self.REBOOT_CAUSE_HARDWARE_OTHER, "POWER_ON RESET"] + } + + self.__initialize_fan() + self.__initialize_psu() + self.__initialize_thermals() + self.__initialize_components() + self.__initialize_sfp() + self.__initialize_eeprom() + + def __initialize_sfp(self): + from sonic_platform.sfp import Sfp + intf_name = self._api_helper.get_intf_name() + for index in range(NUM_PORT): + sfp = Sfp(index, intf_name.get(index + 1, "Unknown")) + self._sfp_list.append(sfp) + self._sfpevent = SfpEvent(self._sfp_list) + self.sfp_module_initialized = True + + def __initialize_fan(self): + 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 + for index in range(NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + + def __initialize_thermals(self): + from sonic_platform.thermal import Thermal + for index in range(NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + def __initialize_eeprom(self): + from sonic_platform.eeprom import Tlv + self._eeprom = Tlv() + + def __initialize_components(self): + from sonic_platform.component import Component + for index in range(NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._eeprom.get_model() + + def get_presence(self): + """ + Retrieves the presence of the Chassis + Returns: + bool: True if Chassis is present, False if not + """ + return True + + 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_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.get_mac() + + 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: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_revision(self): + """ + Retrieves the hardware revision number for the chassis + Returns: + A string containing the hardware revision number for this chassis. + """ + return self._eeprom.get_revision() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + description = 'None' + + reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) \ + if self.is_host \ + else (PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) + prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) \ + if self.is_host \ + else (PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) + + sw_reboot_cause = self._api_helper.read_txt_file(reboot_cause_path) or "Unknown" + prev_sw_reboot_cause = self._api_helper.read_txt_file(prev_reboot_cause_path) or "Unknown" + + if sw_reboot_cause != "Unknown": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = sw_reboot_cause + elif prev_sw_reboot_cause != "Unknown": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = prev_sw_reboot_cause + else: # Try to get reboot cause from BMC + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'Unknown' + try: + err, res = getstatusoutput_noshell(['ipmitool', 'raw', '0x34', '0x22', '0x21', '0x30']) + if err != 0 or res is None: + return (reboot_cause, description) + + code = int(res.strip(), 16) + for (key, value) in self.CPU_RESET_REASON.items(): + if code & key: + reboot_cause = value[0] + description = value[1] + except Exception: + pass + + return (reboot_cause, description) + + def get_change_event(self, timeout=0): + # SFP event + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return self._sfpevent.get_sfp_event(timeout) + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 1 for Ethernet0, 2 for Ethernet4 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + if not self.sfp_module_initialized: + self.__initialize_sfp() + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp + + def get_port_or_cage_type(self, index): + """ + Retrieves sfp port or cage type corresponding to physical port + + Args: + index: An integer (>=0), the index of the sfp to retrieve. + The index should correspond to the physical port in a chassis. + For example:- + 1 for Ethernet0, 2 for Ethernet4 and so on for one platform. + 0 for Ethernet0, 1 for Ethernet4 and so on for another platform. + + Returns: + The masks of all types of port or cage that can be supported on the port + Types are defined in sfp_base.py + Eg. + Both SFP and SFP+ are supported on the port, the return value should be 0x0a + which is 0x02 | 0x08 + """ + from sonic_platform_base.sfp_base import SfpBase + + if index in range(1, 33): + return (SfpBase.SFP_PORT_TYPE_BIT_QSFP | SfpBase.SFP_PORT_TYPE_BIT_QSFP_PLUS | + SfpBase.SFP_PORT_TYPE_BIT_QSFP28 | SfpBase.SFP_PORT_TYPE_BIT_QSFPDD) + elif index == 33: + return SfpBase.SFP_PORT_TYPE_BIT_SFP | SfpBase.SFP_PORT_TYPE_BIT_SFP_PLUS + + 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): + val = self._api_helper.read_txt_file(SYSLED_FNODE) + return SYSLED_MODES[val] if val in SYSLED_MODES else "UNKNOWN" + + def set_status_led(self, color): + mode = None + for key, val in SYSLED_MODES.items(): + if val == color: + mode = key + break + if mode is None: + return False + else: + return self._api_helper.write_txt_file(SYSLED_FNODE, mode) + + diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/component.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/component.py new file mode 100644 index 0000000000..582d507644 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/component.py @@ -0,0 +1,159 @@ +############################################################################# +# Edgecore +# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +# +############################################################################# + +try: + import os + import json + from sonic_platform_base.component_base import ComponentBase + from .helper import APIHelper + from sonic_py_common.general import getstatusoutput_noshell +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CPLD_SYSFS_MAPPING = { + "CPLD1": "/sys/bus/i2c/devices/2-0061/version", + "CPLD2": "/sys/bus/i2c/devices/3-0062/version", + "CPLD3": "/sys/devices/platform/as9737_32db_fan/hwmon/hwmon*/version", + "FPGA": "/sys/devices/platform/as9737_32db_sys/fpga_version", +} +BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" + +COMPONENT_LIST= [ + ("CPLD1", "CPLD 2"), + ("CPLD2", "CPLD 3"), + ("CPLD3", "FAN CPLD"), + ("FPGA", "FPGA"), + ("BIOS", "Basic Input/Output System") +] + +class Component(ComponentBase): + """Platform-specific Component class""" + + DEVICE_TYPE = "component" + + def __init__(self, component_index=0): + ComponentBase.__init__(self) + self._api_helper = APIHelper() + self.index = component_index + self.name = self.get_name() + + def __get_bios_version(self): + # Retrieves the BIOS firmware version + try: + with open(BIOS_VERSION_PATH, 'r') as fd: + bios_version = fd.read() + return bios_version.strip() + except Exception as e: + return None + + def __get_cpld_version(self, cpld_name): + # Retrieves the CPLD firmware version + cpld_version = 'None' + try: + version_path = CPLD_SYSFS_MAPPING[cpld_name] + cpld_version_raw = self._api_helper.glob_read_txt_file(version_path) + if cpld_version_raw is not None: + cpld_version = "{}".format(float(cpld_version_raw)) + except Exception as e: + pass + + return cpld_version + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_LIST[self.index][0] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_LIST[self.index][1] + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + fw_version = None + + if self.name == "BIOS": + fw_version = self.__get_bios_version() + elif "CPLD" in self.name or "FPGA" in self.name: + cpld_version = self.__get_cpld_version(self.name) + fw_version = cpld_version + return fw_version + + def install_firmware(self, image_path): + """ + Install firmware to module + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install successfully, False if not + """ + return False + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return 'N/A' + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return 'N/A' + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + If the agent cannot determine the parent-relative position + for some reason, or if the associated value of + entPhysicalContainedIn is'0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device + or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/eeprom.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/eeprom.py new file mode 100644 index 0000000000..946fe37fe8 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/eeprom.py @@ -0,0 +1,139 @@ +try: + import os + import sys + import re + if sys.version_info[0] >= 3: + from io import StringIO + else: + from cStringIO import StringIO + + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' +NULL = 'N/A' + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + #self._eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + self._eeprom_path = "/sys/devices/platform/as9737_32db_sys/eeprom" + super(Tlv, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)(.+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except Exception: + pass + + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + try: + self.read_eeprom_db() + except Exception: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self.__parse_output(decode_output) + + status = self.check_status() + if 'ok' not in status: + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except Exception: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except Exception: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except Exception: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return False + + return self.__parse_output(decode_output) + + def _valid_tlv(self, eeprom_data): + tlvinfo_type_codes_list = [ + self._TLV_CODE_PRODUCT_NAME, + self._TLV_CODE_PART_NUMBER, + self._TLV_CODE_SERIAL_NUMBER, + self._TLV_CODE_MAC_BASE, + self._TLV_CODE_MANUF_DATE, + self._TLV_CODE_DEVICE_VERSION, + self._TLV_CODE_LABEL_REVISION, + self._TLV_CODE_PLATFORM_NAME, + self._TLV_CODE_ONIE_VERSION, + self._TLV_CODE_MAC_SIZE, + self._TLV_CODE_MANUF_NAME, + self._TLV_CODE_MANUF_COUNTRY, + self._TLV_CODE_VENDOR_NAME, + self._TLV_CODE_DIAG_VERSION, + self._TLV_CODE_SERVICE_TAG, + self._TLV_CODE_VENDOR_EXT, + self._TLV_CODE_CRC_32 + ] + + for code in tlvinfo_type_codes_list: + code_str = "0x{:X}".format(code) + eeprom_data[code_str] = eeprom_data.get(code_str, NULL) + return eeprom_data + + def get_eeprom(self): + return self._valid_tlv(self._eeprom) + + def get_pn(self): + return self._eeprom.get('0x22', NULL) + + def get_serial(self): + return self._eeprom.get('0x23', NULL) + + def get_mac(self): + return self._eeprom.get('0x24', NULL) + + def get_model(self): + return self._eeprom.get('0x21', NULL) + + def get_revision(self): + return self._eeprom.get('0x27', NULL) + diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/event.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/event.py new file mode 100644 index 0000000000..936758c3e4 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/event.py @@ -0,0 +1,113 @@ +try: + import time + 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._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.get_position_in_parent() - 1 + if (changed_ports & (1 << i)) == 0: + continue + + if (bitmap & (1 << i)) == 0: + port_dict[i+1] = '0' + else: + # sfp_state_bits = self.get_sfp_state_bits(sfp, True) + # sfp_state_bits = self.check_sfp_blocking_errors(sfp_state_bits) + # port_dict[i+1] = str(sfp_state_bits) + + # In xcvrd, its current implementation does not + # expect to identify the value when more than one bit is set + # in the return value, and will run into the problem + # + 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_as9737_32db-r0/sonic_platform/fan.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/fan.py new file mode 100644 index 0000000000..7012487cb5 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/fan.py @@ -0,0 +1,298 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_base import FanBase + import os.path + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +TARGET_SPEED_PATH = "/tmp/fan_target_speed" +PSU_FAN_MAX_RPM = 29952 # PMBus MFR_FAN_SPEED_MAX(0xC3) +FAN_HWMON_PATH = "/sys/devices/platform/as9737_32db_fan/hwmon/hwmon*/fan" +PSU_HWMON_PATH = { + 0: "/sys/devices/platform/as9737_32db_psu.0/hwmon/hwmon*/psu1", + 1: "/sys/devices/platform/as9737_32db_psu.1/hwmon/hwmon*/psu2", +} + +fan_list = { + 0: {"name":"FAN-1F", "ss_index":1}, + 1: {"name":"FAN-1R", "ss_index":7}, + 2: {"name":"FAN-2F", "ss_index":2}, + 3: {"name":"FAN-2R", "ss_index":8}, + 4: {"name":"FAN-3F", "ss_index":3}, + 5: {"name":"FAN-3R", "ss_index":9}, + 6: {"name":"FAN-4F", "ss_index":4}, + 7: {"name":"FAN-4R", "ss_index":10}, + 8: {"name":"FAN-5F", "ss_index":5}, + 9: {"name":"FAN-5R", "ss_index":11}, + 10: {"name":"FAN-6F", "ss_index":6}, + 11: {"name":"FAN-6R", "ss_index":12}, +} + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, + fan_tray_index, + fan_index=0, + is_psu_fan=False, + psu_index=0): + self._api_helper = APIHelper() + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.is_psu_fan = is_psu_fan + self.psu_index = psu_index + + if self.is_psu_fan: + self.psu_hwmon_path = PSU_HWMON_PATH[psu_index] + else: + self.hwmon_path = FAN_HWMON_PATH + str(fan_list[fan_tray_index * 2 + fan_index]["ss_index"]) + FanBase.__init__(self) + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = self.FAN_DIRECTION_NOT_APPLICABLE + if not self.is_psu_fan: + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_dir") + if val is not None: + direction = self.FAN_DIRECTION_EXHAUST \ + if val == "F2B" \ + else self.FAN_DIRECTION_INTAKE + else: + val = self._api_helper.glob_read_txt_file(self.psu_hwmon_path + '_power_good') + if val is None or int(val, 10)==0: + return self.FAN_DIRECTION_NOT_APPLICABLE + + val = self._api_helper.glob_read_txt_file(self.psu_hwmon_path + "_fan_dir") + if val is not None: + direction = self.FAN_DIRECTION_EXHAUST \ + if val == "F2B" \ + else self.FAN_DIRECTION_INTAKE + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + 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_speed_rpm = self._api_helper.glob_read_txt_file( + self.psu_hwmon_path + "_fan1_input") + if psu_fan_speed_rpm is not None: + speed = (int(psu_fan_speed_rpm, 10)) * 100 / PSU_FAN_MAX_RPM + else: + return 0 + elif self.get_presence(): + if os.path.isfile(TARGET_SPEED_PATH): + speed = self._api_helper.read_txt_file(TARGET_SPEED_PATH) + else: + fan_input = self._api_helper.glob_read_txt_file(self.hwmon_path + "_input") + + fan_target = self._api_helper.glob_read_txt_file(self.hwmon_path + "_target") + + if fan_input is None or fan_target is None: + return 0 + + speed = (int(fan_input) * self.get_target_speed()) / int(fan_target) + + speed = int(speed) + if speed > 100: + speed = 100 + return int(speed) + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + """ + speed = 0 + if self.is_psu_fan: + fan_speed_rpm = self._api_helper.glob_read_txt_file( + self.psu_hwmon_path + "_fan1_input") + if fan_speed_rpm is not None: + speed = (int(fan_speed_rpm, 10)) * 100 / PSU_FAN_MAX_RPM + speed = 100 if (speed > 100) else speed + else: + return 0 + elif self.get_presence(): + if os.path.isfile(TARGET_SPEED_PATH): + speed = self._api_helper.read_txt_file(TARGET_SPEED_PATH) + else: + speed = self._api_helper.glob_read_txt_file(self.hwmon_path + '_pwm') + if speed is None: + return 0 + + return int(speed) + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return 20 + + speed = 0 + if not self.is_psu_fan: + speed = self._api_helper.glob_read_txt_file(self.hwmon_path + '_tolerance') + if speed is None: + return 0 + + return int(speed) + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + + """ + + if not self.is_psu_fan and self.get_presence(): + ret = self._api_helper.glob_write_txt_file(self.hwmon_path + '_pwm', speed) + if ret == True: + self._api_helper.write_txt_file(TARGET_SPEED_PATH, int(speed)) + return ret + + return False + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + 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 + """ + return { + True: self.STATUS_LED_COLOR_GREEN, + False: self.STATUS_LED_COLOR_RED + }.get(self.get_status(), self.STATUS_LED_COLOR_OFF) + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + if self.is_psu_fan: + val = self._api_helper.glob_read_txt_file(self.psu_hwmon_path + "_present") + else: + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_present") + + 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: + val = self._api_helper.glob_read_txt_file(self.psu_hwmon_path + '_power_good') + if val is None or int(val, 10)==0: + return False + + val = self._api_helper.glob_read_txt_file(self.psu_hwmon_path + '_fan1_input') + if val is not None: + return int(val, 10)!=0 + else: + return False + else: + val = self._api_helper.glob_read_txt_file(self.hwmon_path + '_fault') + if val is not None: + return int(val, 10)==0 + else: + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + fan_name = fan_list[self.fan_tray_index * 2 + self.fan_index]["name"] \ + if not self.is_psu_fan \ + else "PSU-{} FAN-{}".format(self.psu_index+1, self.fan_index+1) + + return fan_name + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return "N/A" + + def get_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_as9737_32db-r0/sonic_platform/fan_drawer.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/fan_drawer.py new file mode 100644 index 0000000000..b560a42bf8 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/fan_drawer.py @@ -0,0 +1,109 @@ +######################################################################## +# +# 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 is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_presence(self): + """ + Retrieves the presence of the 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 + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return False #Not supported + diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/helper.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/helper.py new file mode 100644 index 0000000000..8e6e130d6e --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/helper.py @@ -0,0 +1,433 @@ +import os +import struct +import json +import fcntl +import glob +from mmap import * +from sonic_py_common import device_info +from sonic_py_common import logger +from threading import Lock +from typing import cast +from sonic_py_common.general import getstatusoutput_noshell_pipe +from sonic_py_common.general import getstatusoutput_noshell + +HOST_CHK_CMD = ["docker"] +EMPTY_STRING = "" +MACHINE_CONF_FILE = "/host/machine.conf" +HOST_PLATFORM_JSON_FILE = "/usr/share/sonic/device/{}/platform.json" +PMON_PLATFORM_JSON_FILE = "/usr/share/sonic/platform/platform.json" +INTF_KEY = "interfaces" + + +class APIHelper(): + + def __init__(self): + pass + + def is_host(self): + try: + status, output = getstatusoutput_noshell(HOST_CHK_CMD) + return status == 0 + except Exception: + return False + + def pci_get_value(self, resource, offset): + status = True + result = "" + try: + fd = os.open(resource, os.O_RDWR) + mm = mmap(fd, 0) + mm.seek(int(offset)) + read_data_stream = mm.read(4) + result = struct.unpack('I', read_data_stream) + except Exception: + status = False + return status, result + + def run_interactive_command(self, cmd): + try: + os.system(cmd) + except Exception: + return False + return True + + def read_txt_file(self, file_path): + try: + with open(file_path, encoding='unicode_escape', errors='replace') as fd: + data = fd.read() + ret = data.strip() + if len(ret) > 0: + return ret + except IOError: + pass + return None + + def glob_read_txt_file(self, file_path): + for filename in glob.glob(file_path): + try: + with open(filename, encoding='unicode_escape', errors='replace') as fd: + data = fd.read() + ret = data.strip() + if len(ret) > 0: + return ret + except IOError as e: + pass + + return None + + def write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + fd.flush() + except IOError: + return False + return True + + def glob_write_txt_file(self, file_path, value): + for filename in glob.glob(file_path): + try: + with open(filename, 'w') as fd: + fd.write(str(value)) + fd.flush() + return True + except IOError as e: + pass + + return False + + def ipmi_raw(self, netfn, cmd): + status = True + result = "" + try: + err, raw_data = getstatusoutput_noshell_pipe(['ipmitool', 'raw', str(netfn), str(cmd)]) + if err == [0]: + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def ipmi_fru_id(self, id, key=None): + status = True + result = "" + try: + if (key is None): + err, raw_data = getstatusoutput_noshell_pipe(['ipmitool', 'fru', 'print', str(id)]) + else: + err, raw_data = getstatusoutput_noshell_pipe(['ipmitool', 'fru', 'print', str(id)], ['grep', str(key)]) + if err == [0] or err == [0, 0]: + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def ipmi_set_ss_thres(self, id, threshold_key, value): + status = True + result = "" + try: + err, raw_data = getstatusoutput_noshell_pipe(['ipmitool', 'sensor', 'thresh', str(id), str(threshold_key), str(value)]) + if err == [0]: + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def get_intf_name(self): + """ + Fetches interface names indexed by port numbers from platform.json file. + + Returns: + - A dictionary with port indices as keys and interface names as values. + Example: {1: 'Ethernet0', ...}. + - Returns an empty dictionary on errors or if key not found. + """ + platform_json_file_path = PMON_PLATFORM_JSON_FILE + if self.is_host(): + platform = "None" + with open(MACHINE_CONF_FILE, 'r') as file: + for line in file: + if 'onie_platform=' in line: + platform = line.strip().split('=')[1] + break + platform_json_file_path = HOST_PLATFORM_JSON_FILE.format(platform) + + port_dict = {} + try: + with open(platform_json_file_path) as fp: + port_dict = json.load(fp) + except Exception as e: + pass + + intf_name_by_index = {} + if INTF_KEY in port_dict: + for intf_name, port_info in port_dict[INTF_KEY].items(): + if 'index' in port_info: + fp_port_index = int(port_info['index'].split(",")[0]) + intf_name_by_index[fp_port_index] = intf_name + + return intf_name_by_index + + +class FileLock: + """ + Due to pmon docker not installing the py-filelock, this class + implements a simple file lock feature. + Ref: https://github.com/tox-dev/py-filelock/blob/main/src/filelock/ + """ + + def __init__(self, lock_file): + self._lock_file = lock_file + self._thread_lock = Lock() + self.is_locked = False + + def acquire(self): + with self._thread_lock: + if self.is_locked: + return + + fd = os.open(self._lock_file, flags=(os.O_RDWR | os.O_CREAT | os.O_TRUNC)) + fcntl.flock(fd, fcntl.LOCK_EX) + self._lock_file_fd = fd + self.is_locked = True + + def release(self): + with self._thread_lock: + if self.is_locked: + fd = cast(int, self._lock_file_fd) + self._lock_file_fd = None + fcntl.flock(fd, fcntl.LOCK_UN) + os.close(fd) + self.is_locked = False + + def __enter__(self): + self.acquire() + return self + + def __exit__(self, exc_type, exc_val, traceback): + self.release() + + def __del__(self): + self.release() + + +DEVICE_THRESHOLD_JSON_PATH = "/tmp/device_threshold.json" + +class DeviceThreshold: + HIGH_THRESHOLD = 'high_threshold' + LOW_THRESHOLD = 'low_threshold' + HIGH_CRIT_THRESHOLD = 'high_critical_threshold' + LOW_CRIT_THRESHOLD = 'low_critical_threshold' + NOT_AVAILABLE = 'N/A' + + def __init__(self, th_name = NOT_AVAILABLE): + self.flock = FileLock("{}.lock".format(DEVICE_THRESHOLD_JSON_PATH)) + self.name = th_name + self.__log = logger.Logger(log_identifier="DeviceThreshold") + + self.__db_data = {} + self.__db_mtime = 0 + + def __reload_db(self): + try: + db_data = {} + with self.flock: + with open(DEVICE_THRESHOLD_JSON_PATH, "r") as db_file: + db_data = json.load(db_file) + except Exception as e: + return None + + return db_data + + def __get_data(self, field): + """ + Retrieves data frome JSON file by field + + Args : + field: String + + Returns: + A string if getting is successfully, 'N/A' if not + """ + if os.path.exists(DEVICE_THRESHOLD_JSON_PATH): + new_mtime = os.path.getmtime(DEVICE_THRESHOLD_JSON_PATH) + if new_mtime != self.__db_mtime: + new_data = self.__reload_db() + if new_data is not None: + self.__db_data = new_data + self.__db_mtime = new_mtime + + if self.name not in self.__db_data.keys(): + return self.NOT_AVAILABLE + + if field not in self.__db_data[self.name].keys(): + return self.NOT_AVAILABLE + + return self.__db_data[self.name][field] + + def __set_data(self, field, new_val): + """ + Set data to JSON file by field + + Args : + field: String + new_val: String + + Returns: + A boolean, True if setting is set successfully, False if not + """ + if self.name not in self.__db_data.keys(): + self.__db_data[self.name] = {} + + old_val = self.__db_data[self.name].get(field, None) + if old_val is not None and old_val == new_val: + return True + + self.__db_data[self.name][field] = new_val + + try: + with self.flock: + db_data = {} + mode = "r+" if os.path.exists(DEVICE_THRESHOLD_JSON_PATH) else "w+" + with open(DEVICE_THRESHOLD_JSON_PATH, mode) as db_file: + if mode == "r+": + db_data = json.load(db_file) + + if self.name not in db_data.keys(): + db_data[self.name] = {} + + db_data[self.name][field] = new_val + + if mode == "r+": + db_file.seek(0) + # erase old data + db_file.truncate(0) + # write all data + json.dump(db_data, db_file, indent=4) + self.__db_mtime = os.path.getmtime(DEVICE_THRESHOLD_JSON_PATH) + except Exception as e: + self.__log.log_error('{}'.format(str(e))) + return False + + return True + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature from JSON file. + + Returns: + string : the high threshold temperature of thermal, + e.g. "30.125" + """ + return self.__get_data(self.HIGH_THRESHOLD) + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + Args : + temperature: A string of temperature, e.g. "30.125" + Returns: + A boolean, True if threshold is set successfully, False if not + """ + if isinstance(temperature, str) is not True: + raise TypeError('The parameter requires string type.') + + try: + if temperature != self.NOT_AVAILABLE: + float(temperature) + except ValueError: + raise ValueError('The parameter requires a float string. ex:\"30.1\"') + + return self.__set_data(self.HIGH_THRESHOLD, temperature) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature from JSON file. + + Returns: + string : the low threshold temperature of thermal, + e.g. "30.125" + """ + return self.__get_data(self.LOW_THRESHOLD) + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + Args : + temperature: A string of temperature, e.g. "30.125" + Returns: + A boolean, True if threshold is set successfully, False if not + """ + if isinstance(temperature, str) is not True: + raise TypeError('The parameter requires string type.') + + try: + if temperature != self.NOT_AVAILABLE: + float(temperature) + except ValueError: + raise ValueError('The parameter requires a float string. ex:\"30.1\"') + + return self.__set_data(self.LOW_THRESHOLD, temperature) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature from JSON file. + + Returns: + string : the high critical threshold temperature of thermal, + e.g. "30.125" + """ + return self.__get_data(self.HIGH_CRIT_THRESHOLD) + + def set_high_critical_threshold(self, temperature): + """ + Sets the high critical threshold temperature of thermal + Args : + temperature: A string of temperature, e.g. "30.125" + Returns: + A boolean, True if threshold is set successfully, False if not + """ + if isinstance(temperature, str) is not True: + raise TypeError('The parameter requires string type.') + + try: + if temperature != self.NOT_AVAILABLE: + float(temperature) + except ValueError: + raise ValueError('The parameter requires a float string. ex:\"30.1\"') + + return self.__set_data(self.HIGH_CRIT_THRESHOLD, temperature) + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature from JSON file. + + Returns: + string : the low critical threshold temperature of thermal, + e.g. "30.125" + """ + return self.__get_data(self.LOW_CRIT_THRESHOLD) + + def set_low_critical_threshold(self, temperature): + """ + Sets the low critical threshold temperature of thermal + Args : + temperature: A string of temperature, e.g. "30.125" + Returns: + A boolean, True if threshold is set successfully, False if not + """ + if isinstance(temperature, str) is not True: + raise TypeError('The parameter requires string type.') + + try: + if temperature != self.NOT_AVAILABLE: + float(temperature) + except ValueError: + raise ValueError('The parameter requires a float string. ex:\"30.1\"') + + return self.__set_data(self.LOW_CRIT_THRESHOLD, temperature) diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/pcie.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/pcie.py new file mode 100644 index 0000000000..73d3627dbf --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/pcie.py @@ -0,0 +1,19 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# Base PCIe class +############################################################################# + +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Pcie(PcieUtil): + """Edgecore Platform-specific PCIe class""" + + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/platform.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/platform.py new file mode 100644 index 0000000000..2f2c2a447f --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/platform.py @@ -0,0 +1,21 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/psu.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/psu.py new file mode 100644 index 0000000000..a6da432e5d --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/psu.py @@ -0,0 +1,279 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.psu_base import PsuBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PSU_NAME_LIST = ["PSU-1", "PSU-2"] +PSU_NUM_FAN = [1, 1] +PSU_HWMON_PATH = { + 0: "/sys/devices/platform/as9737_32db_psu.0/hwmon/hwmon*/psu1", + 1: "/sys/devices/platform/as9737_32db_psu.1/hwmon/hwmon*/psu2", +} + +THERMAL_COUNT_PER_PSU = 3 + +SYSLED_FNODE= { + 0: "/sys/devices/platform/as9737_32db_led/led_psu1", + 1: "/sys/devices/platform/as9737_32db_led/led_psu2" +} + +SYSLED_MODES = { + "0" : PsuBase.STATUS_LED_COLOR_OFF, + "16" : PsuBase.STATUS_LED_COLOR_GREEN, + "10" : PsuBase.STATUS_LED_COLOR_RED +} + +class Psu(PsuBase): + """Platform-specific Psu class""" + + def __init__(self, psu_index=0): + PsuBase.__init__(self) + self.index = psu_index + self._api_helper = APIHelper() + + self.hwmon_path = PSU_HWMON_PATH[psu_index] + + self.__initialize_fan() + self.__initialize_thermal() + + def __initialize_fan(self): + from sonic_platform.fan import Fan + for fan_index in range(0, PSU_NUM_FAN[self.index]): + fan = Fan(fan_index, is_psu_fan=True, psu_index=self.index) + self._fan_list.append(fan) + + def __initialize_thermal(self): + from sonic_platform.thermal import Thermal + for thermal_id in range(0, THERMAL_COUNT_PER_PSU): + thermal = Thermal(thermal_index=thermal_id, is_psu=True, psu_index=self.index) + self._thermal_list.append(thermal) + + def get_voltage(self): + """ + Retrieves current PSU voltage output + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + if self.get_status() is not True: + return 0.0 + + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_vout") + if val is not None: + return float(val)/ 1000 + else: + return 0.0 + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + if self.get_status() is not True: + return 0.0 + + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_iout") + if val is not None: + return float(val)/1000 + else: + return 0.0 + + def get_power(self): + """ + Retrieves current energy supplied by PSU + Returns: + A float number, the power in watts, e.g. 302.6 + """ + if self.get_status() is not True: + return 0.0 + + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_pout") + if val is not None: + return float(val)/1000 + else: + return 0.0 + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the PSU status LED + Note: Only support green and off + Returns: + bool: True if status LED state is set successfully, False if not + """ + + return False # Controlled by BMC + + def get_status_led(self): + """ + Gets the state of the PSU status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + val = self._api_helper.read_txt_file(SYSLED_FNODE[self.index]) + return SYSLED_MODES[val] if val in SYSLED_MODES else "UNKNOWN" + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + return self._thermal_list[1].get_temperature() + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + Returns: + A float number, the high threshold temperature of PSU in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self._thermal_list[1].get_high_threshold() + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + Returns: + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + return 12.57 + + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_vout_max") + if val is not None: + return float(val)/ 1000 + else: + return 0.0 + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + Returns: + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + return 11.83 + + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_vout_min") + if val is not None: + return float(val)/ 1000 + else: + return 0.0 + + def get_maximum_supplied_power(self): + """ + Retrieves the maximum supplied power by PSU + Returns: + A float number, the maximum power output in Watts. + e.g. 1200.1 + """ + return 3000.0 + + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_pout_max") + if val is not None: + return float(val)/1000 + else: + return 0.0 + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return PSU_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_present") + 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 + """ + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_power_good") + if val is not None: + return int(val, 10) == 1 + else: + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model = self._api_helper.glob_read_txt_file(self.hwmon_path + "_model") + 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 = self._api_helper.glob_read_txt_file(self.hwmon_path + "_serial") + if serial is None: + return "N/A" + return serial + + def get_revision(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + revision = None + if revision is None: + return "N/A" + return revision + + 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 diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/sfp.py new file mode 100644 index 0000000000..69a0c5a9ae --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/sfp.py @@ -0,0 +1,512 @@ +############################################################################# +# Edgecore +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# + +try: + import time + import natsort + from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CPLD2_PATH = "/sys/bus/i2c/devices/2-0061/" +CPLD3_PATH = "/sys/bus/i2c/devices/3-0062/" +EEPROM_PATH = '/sys/bus/i2c/devices/{}-00{}/eeprom' + +class Sfp(SfpOptoeBase): + """Platform-specific Sfp class""" + + # Port number + PORT_START = 1 + PORT_END = 33 + + LAST_QSFP_PORT_NUM = 32 + CPLD3_FIRST_PORT_NUM = 17 + + 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" + + _port_to_i2c_mapping = { + 1:9, 2:10, 3:11, 4:12, + 5:13, 6:14, 7:15, 8:16, + 9:17, 10:18, 11:19, 12:20, + 13:21, 14:22, 15:23, 16:24, + 17:25, 18:26, 19:27, 20:28, + 21:29, 22:30, 23:31, 24:32, + 25:33, 26:34, 27:35, 28:36, + 29:37, 30:38, 31:39, 32:40, + 33:41 + } + + def __init__(self, sfp_index=0, sfp_name=None): + SfpOptoeBase.__init__(self) + self._api_helper=APIHelper() + + # Init index + self.port_num = sfp_index + 1 + self.index = self.port_num + self.name = sfp_name + + # Init eeprom path + self.port_to_eeprom_mapping = {} + 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], "50") + + # xvcrd will use 'sfp_type' for configuring the media type. + if self.port_num > self.LAST_QSFP_PORT_NUM: + self.sfp_type = self.SFP_TYPE + else: + self.sfp_type = self.QSFP_TYPE + + self.update_sfp_type() + + def get_eeprom_path(self): + # print(self.port_to_eeprom_mapping[self.port_num]) + return self.port_to_eeprom_mapping[self.port_num] + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + if self.port_num > self.LAST_QSFP_PORT_NUM: + # SFP doesn't support this feature + return False + + if self.port_num < self.CPLD3_FIRST_PORT_NUM: + reset_path = "{}{}{}".format(CPLD2_PATH, 'module_reset_', self.port_num) + else: + reset_path = "{}{}{}".format(CPLD3_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 + + return False + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + if self.port_num > self.LAST_QSFP_PORT_NUM: + # SFP doesn't support this feature + return False + + if self.sfp_type in [self.QSFP_DD_TYPE]: + api = self.get_xcvr_api() + return api.get_lpmode() + else: + if self.port_num < self.CPLD3_FIRST_PORT_NUM: + lpmode_path = "{}{}{}".format(CPLD2_PATH, 'module_lpmode_', self.port_num) + else: + lpmode_path = "{}{}{}".format(CPLD3_PATH, 'module_lpmode_', self.port_num) + + val=self._api_helper.read_txt_file(lpmode_path) + if val is not None: + return int(val, 10)==1 + + return False + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + if not self.get_presence(): + return False + + # Check for invalid port_num + if self.port_num > self.LAST_QSFP_PORT_NUM: + return False # SFP doesn't support this feature + + if self.port_num < self.CPLD3_FIRST_PORT_NUM: + reset_path = "{}{}{}".format(CPLD2_PATH, 'module_reset_', self.port_num) + else: + reset_path = "{}{}{}".format(CPLD3_PATH, 'module_reset_', self.port_num) + + ret = self._api_helper.write_txt_file(reset_path, 1) + if ret is not True: + return ret + + time.sleep(0.2) + ret = self._api_helper.write_txt_file(reset_path, 0) + time.sleep(0.2) + + return ret + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + if not self.get_presence(): + return False + + if self.port_num > self.LAST_QSFP_PORT_NUM: + return False # SFP doesn't support this feature + + if self.sfp_type in [self.QSFP_DD_TYPE]: + api = self.get_xcvr_api() + ret = api.set_lpmode(lpmode) + else: + if self.port_num < self.CPLD3_FIRST_PORT_NUM: + lpmode_path = "{}{}{}".format(CPLD2_PATH, 'module_lpmode_', self.port_num) + else: + lpmode_path = "{}{}{}".format(CPLD3_PATH, 'module_lpmode_', self.port_num) + + if lpmode is True: + ret = self._api_helper.write_txt_file(lpmode_path, 1) #enable lpmode + else: + ret = self._api_helper.write_txt_file(lpmode_path, 0) #disable lpmode + + return ret + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + if not self.get_presence(): + return False + + if self.port_num > self.LAST_QSFP_PORT_NUM: + txdisable_path = "{}{}{}".format(CPLD3_PATH, 'module_tx_disable_', self.port_num) + + if tx_disable is True: + ret = self._api_helper.write_txt_file(txdisable_path, 1) #enable tx_disable + else: + ret = self._api_helper.write_txt_file(txdisable_path, 0) #disable tx_disable + else: + api = self.get_xcvr_api() + if api is None: + return False + + ret = api.tx_disable(tx_disable) + + return ret + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + + return self.name + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + if self.port_num < self.CPLD3_FIRST_PORT_NUM: + present_path = "{}{}{}".format(CPLD2_PATH, 'module_present_', self.port_num) + else: + present_path = "{}{}{}".format(CPLD3_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 + + 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 + """ + return self.get_presence() + + 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.port_num + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def update_sfp_type(self): + """ + Updates the sfp type + + """ + if not self.get_presence(): + return self.EEPROM_DATA_NOT_READY + + 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 False + + 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 False + + 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 False + + 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() + elif id in self.OSFP_TYPE_CODE_LIST: + return self.validate_eeprom_cmis() + else: + return False + + def validate_temperature(self): + temperature = self.get_temperature() + if temperature is None: + return False + + threshold_dict = self.get_transceiver_threshold_info() + if threshold_dict is None: + return False + + if isinstance(temperature, float) is not True: + return True + + if isinstance(threshold_dict['temphighalarm'], float) is not True: + return True + + return threshold_dict['temphighalarm'] > temperature + + def __get_error_description(self): + if not self.get_presence(): + return self.SFP_STATUS_UNPLUGGED + + err_stat = self.SFP_STATUS_BIT_INSERTED + + status = self.validate_eeprom() + if status is not True: + err_stat = (err_stat | self.SFP_ERROR_BIT_BAD_EEPROM) + + status = self.validate_temperature() + if status is not True: + err_stat = (err_stat | self.SFP_ERROR_BIT_HIGH_TEMP) + + if err_stat is self.SFP_STATUS_BIT_INSERTED: + return self.SFP_STATUS_OK + else: + err_desc = '' + cnt = 0 + for key in self.SFP_ERROR_BIT_TO_DESCRIPTION_DICT: + if (err_stat & key) != 0: + if cnt > 0: + err_desc = err_desc + "|" + cnt = cnt + 1 + err_desc = err_desc + self.SFP_ERROR_BIT_TO_DESCRIPTION_DICT[key] + + return err_desc + + def get_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 + + try: + state = super().get_error_description() + if state is None: + return self.SFP_STATUS_OK + return state + except NotImplementedError: + return self.__get_error_description() diff --git a/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/thermal.py b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/thermal.py new file mode 100644 index 0000000000..877e097080 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/sonic_platform/thermal.py @@ -0,0 +1,463 @@ +############################################################################# +# Edgecore +# +# Thermal contains an implementation of SONiC Platform Base API and +# provides the thermal device status which are available in the platform +# +############################################################################# + +import os +import os.path + +try: + from sonic_platform_base.thermal_base import ThermalBase + from .helper import DeviceThreshold, APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +THERMAL_COUNT_PER_PSU = 3 + +NOT_AVAILABLE = DeviceThreshold.NOT_AVAILABLE +HIGH_THRESHOLD = DeviceThreshold.HIGH_THRESHOLD +LOW_THRESHOLD = DeviceThreshold.LOW_THRESHOLD +HIGH_CRIT_THRESHOLD = DeviceThreshold.HIGH_CRIT_THRESHOLD +LOW_CRIT_THRESHOLD = DeviceThreshold.LOW_CRIT_THRESHOLD + +# Default thresholds +DEFAULT_THRESHOLD = { + 'MB_FrontCenter_temp(0x48)' : { + HIGH_THRESHOLD : '70.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '85.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'MB_FrontRight_temp(0x49)' : { + HIGH_THRESHOLD : '70.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '85.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'MB_RearCenter_temp(0x4A)' : { + HIGH_THRESHOLD : '70.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '85.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'MB_RearLeft_temp(0x4C)' : { + HIGH_THRESHOLD : '70.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '85.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'MB_RearCenter_temp(0x4F)' : { + HIGH_THRESHOLD : '70.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '85.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'CPU_Package_temp' : { + HIGH_THRESHOLD : '90.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '100.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'CPU_Core_0_temp' : { + HIGH_THRESHOLD : '90.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '100.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'CPU_Core_1_temp' : { + HIGH_THRESHOLD : '90.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '100.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'CPU_Core_2_temp' : { + HIGH_THRESHOLD : '90.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '100.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'CPU_Core_3_temp' : { + HIGH_THRESHOLD : '90.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '100.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'PSU-1 temp sensor 1' : { + HIGH_THRESHOLD : '77.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '80.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'PSU-1 temp sensor 2' : { + HIGH_THRESHOLD : '110.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '113.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'PSU-1 temp sensor 3' : { + HIGH_THRESHOLD : '114.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '117.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'PSU-2 temp sensor 1' : { + HIGH_THRESHOLD : '77.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '80.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'PSU-2 temp sensor 2' : { + HIGH_THRESHOLD : '110.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '113.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + }, + 'PSU-2 temp sensor 3' : { + HIGH_THRESHOLD : '114.0', + LOW_THRESHOLD : NOT_AVAILABLE, + HIGH_CRIT_THRESHOLD : '117.0', + LOW_CRIT_THRESHOLD : NOT_AVAILABLE + } +} + +HWMON_PATH = { + True: { + 0: { + 0: {"hwmon_path":"as9737_32db_psu.0/hwmon/hwmon*/psu1", "ss_index":1}, + 1: {"hwmon_path":"as9737_32db_psu.0/hwmon/hwmon*/psu1", "ss_index":2}, + 2: {"hwmon_path":"as9737_32db_psu.0/hwmon/hwmon*/psu1", "ss_index":3}, + }, + 1: { + 0: {"hwmon_path":"as9737_32db_psu.1/hwmon/hwmon*/psu2", "ss_index":1}, + 1: {"hwmon_path":"as9737_32db_psu.1/hwmon/hwmon*/psu2", "ss_index":2}, + 2: {"hwmon_path":"as9737_32db_psu.1/hwmon/hwmon*/psu2", "ss_index":3}, + } + }, + False: { + 0: {"hwmon_path":"as9737_32db_thermal/hwmon/hwmon*/", "ss_index":1}, + 1: {"hwmon_path":"as9737_32db_thermal/hwmon/hwmon*/", "ss_index":2}, + 2: {"hwmon_path":"as9737_32db_thermal/hwmon/hwmon*/", "ss_index":3}, + 3: {"hwmon_path":"as9737_32db_thermal/hwmon/hwmon*/", "ss_index":4}, + 4: {"hwmon_path":"as9737_32db_thermal/hwmon/hwmon*/", "ss_index":5}, + 5: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":1}, + 6: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":2}, + 7: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":3}, + 8: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":4}, + 9: {"hwmon_path":"coretemp.0/hwmon/hwmon*/", "ss_index":5} + } +} + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + THERMAL_NAME_LIST = [] + PSU_THERMAL_NAME_LIST = [] + SYSFS_PATH_PREFIX = "/sys/devices/platform" + + def __init__(self, thermal_index=0, is_psu=False, psu_index=0): + self._api_helper = APIHelper() + self.index = thermal_index + self.is_psu = is_psu + self.is_cpu = False + self.psu_index = psu_index + self.hwmon_path = None + self.ss_index = 0 + self.min_temperature = None + self.max_temperature = None + + # Add thermal name + for thermal_name in DEFAULT_THRESHOLD.keys(): + if "PSU" in thermal_name: + self.PSU_THERMAL_NAME_LIST.append(thermal_name) + else: + self.THERMAL_NAME_LIST.append(thermal_name) + + # Threshold Configuration + self.__conf = DeviceThreshold(self.get_name()) + # Default threshold. + self.__default_threshold = DEFAULT_THRESHOLD[self.get_name()] + + sysfs_path = None + hwmon_path = HWMON_PATH.get(self.is_psu, None) + if self.is_psu: + # Set hwmon path + psu_hwmon_path = hwmon_path.get(self.psu_index, None) + if psu_hwmon_path is not None: + sysfs_path = psu_hwmon_path.get(self.index, None) + else : + # Set hwmon path + sysfs_path = hwmon_path.get(self.index, None) + if self.index in range(5,10): + self.is_cpu = True + + if sysfs_path is not None: + self.hwmon_path = "{}/{}".format(self.SYSFS_PATH_PREFIX, + sysfs_path["hwmon_path"]) + self.ss_index = sysfs_path["ss_index"] + + def __get_temp(self, 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._api_helper.glob_read_txt_file(temp_file_path) + if raw_temp is not None: + return float(raw_temp) / 1000 + else: + return 0.0 + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + if not self.is_psu: + temp_file = "temp{}_input".format(self.ss_index) + else: + val = self._api_helper.glob_read_txt_file(self.hwmon_path + '_power_good') + if val is None or int(val, 10)==0: + return 0.0 + + temp_file = self.hwmon_path + "_temp{}_input".format(self.ss_index) + + 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_threshold(self): + """ + Retrieves the high threshold temperature of thermal + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + value = self.__conf.get_high_threshold() + if value != NOT_AVAILABLE: + return float(value) + + default_value = self.__default_threshold[HIGH_THRESHOLD] + if default_value != NOT_AVAILABLE: + return float(default_value) + + raise NotImplementedError + + def set_high_threshold(self, temperature): + """ + Sets the 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 Exception: + return False + + # The new value can not be more than the default value. + default_value = self.__default_threshold[HIGH_THRESHOLD] + if default_value != NOT_AVAILABLE: + if value > float(default_value): + return False + + try: + self.__conf.set_high_threshold(str(value)) + except Exception: + return False + + return True + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal by 1-based index + Actions should be taken immediately if the temperature becomes higher than the high critical + threshold otherwise the device will be damaged. + + :param index: An integer, 1-based index of the thermal sensor of which to query status + :return: 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 != NOT_AVAILABLE: + return float(value) + + default_value = self.__default_threshold[HIGH_CRIT_THRESHOLD] + if default_value != NOT_AVAILABLE: + return float(default_value) + + raise NotImplementedError + + def set_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 Exception: + return False + + # The new value can not be more than the default value. + default_value = self.__default_threshold[HIGH_CRIT_THRESHOLD] + if default_value != NOT_AVAILABLE: + if value > float(default_value): + return False + + try: + self.__conf.set_high_critical_threshold(str(value)) + except Exception: + return False + + return True + + def get_name(self): + """ + Retrieves the name of the thermal device + Returns: + string: The name of the thermal device + """ + if self.is_psu: + return self.PSU_THERMAL_NAME_LIST[(self.psu_index * THERMAL_COUNT_PER_PSU) + self.index] + else: + return self.THERMAL_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + if self.is_cpu: + return True + + if self.is_psu: + val = self._api_helper.glob_read_txt_file(self.hwmon_path + "_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._api_helper.glob_read_txt_file(temp_file_path) + if raw_txt is not None: + return True + 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_cpu: + return True + + if self.is_psu: + val = self._api_helper.glob_read_txt_file(self.hwmon_path + '_power_good') + if val is None or int(val, 10)==0: + return False + + temp_file = self.hwmon_path + "_temp_fault" + psu_temp_fault = self._api_helper.glob_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) + + raw_txt = self._api_helper.glob_read_txt_file(file_path) + if raw_txt is None: + 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.is_psu: + val = self._api_helper.glob_read_txt_file(self.hwmon_path + '_power_good') + if val is None or int(val, 10)==0: + return None + + 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.is_psu: + val = self._api_helper.glob_read_txt_file(self.hwmon_path + '_power_good') + if val is None or int(val, 10)==0: + return None + + if self.max_temperature is None: + self.get_temperature() + + return self.max_temperature diff --git a/device/accton/x86_64-accton_as9737_32db-r0/system_health_monitoring_config.json b/device/accton/x86_64-accton_as9737_32db-r0/system_health_monitoring_config.json new file mode 100644 index 0000000000..5af0e4067a --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/system_health_monitoring_config.json @@ -0,0 +1,13 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [ + "asic" + ], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "STATUS_LED_COLOR_RED", + "normal": "STATUS_LED_COLOR_OFF", + "booting": "STATUS_LED_COLOR_OFF" + } +} diff --git a/device/accton/x86_64-accton_as9737_32db-r0/warm-reboot_plugin b/device/accton/x86_64-accton_as9737_32db-r0/warm-reboot_plugin new file mode 120000 index 0000000000..a94494bc56 --- /dev/null +++ b/device/accton/x86_64-accton_as9737_32db-r0/warm-reboot_plugin @@ -0,0 +1 @@ +platform_reboot \ No newline at end of file diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 272c29478f..bb77239392 100755 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -49,6 +49,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(ACCTON_AS7315_27XB_PLATFORM_MODULE) \ $(ACCTON_AS4625_54P_PLATFORM_MODULE) \ $(ACCTON_AS4625_54T_PLATFORM_MODULE) \ + $(ACCTON_AS9737_32DB_PLATFORM_MODULE) \ $(INVENTEC_D7032Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7054Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7264Q28B_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-accton.mk b/platform/broadcom/platform-modules-accton.mk index 04d7b1a5b0..70a4183d50 100644 --- a/platform/broadcom/platform-modules-accton.mk +++ b/platform/broadcom/platform-modules-accton.mk @@ -23,6 +23,7 @@ ACCTON_AS7312_54XS_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS7315_27XB_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS4625_54P_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS4625_54T_PLATFORM_MODULE_VERSION = 1.1 +ACCTON_AS9737_32DB_PLATFORM_MODULE_VERSION = 1.1 export ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION export ACCTON_AS5712_54X_PLATFORM_MODULE_VERSION @@ -47,6 +48,7 @@ export ACCTON_AS7312_54XS_PLATFORM_MODULE_VERSION export ACCTON_AS7315_27XB_PLATFORM_MODULE_VERSION export ACCTON_AS4625_54P_PLATFORM_MODULE_VERSION export ACCTON_AS4625_54T_PLATFORM_MODULE_VERSION +export ACCTON_AS9737_32DB_PLATFORM_MODULE_VERSION ACCTON_AS7712_32X_PLATFORM_MODULE = sonic-platform-accton-as7712-32x_$(ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION)_amd64.deb $(ACCTON_AS7712_32X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-accton @@ -141,3 +143,7 @@ $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS ACCTON_AS4625_54T_PLATFORM_MODULE = sonic-platform-accton-as4625-54t_$(ACCTON_AS4625_54T_PLATFORM_MODULE_VERSION)_amd64.deb $(ACCTON_AS4625_54T_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as4625_54t-r0 $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS4625_54T_PLATFORM_MODULE))) + +ACCTON_AS9737_32DB_PLATFORM_MODULE = sonic-platform-accton-as9737-32db_$(ACCTON_AS9737_32DB_PLATFORM_MODULE_VERSION)_amd64.deb +$(ACCTON_AS9737_32DB_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9737_32db-r0 +$(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS9737_32DB_PLATFORM_MODULE))) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/classes/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/Makefile new file mode 100644 index 0000000000..615479c90f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/Makefile @@ -0,0 +1,3 @@ +obj-m:=i2c-ocores.o accton_as9737_32db_fpga.o accton_as9737_32db_mux.o accton_as9737_32db_cpld.o \ + accton_as9737_32db_psu.o accton_as9737_32db_fan.o accton_as9737_32db_thermal.o \ + accton_as9737_32db_leds.o accton_as9737_32db_sys.o diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_cpld.c new file mode 100644 index 0000000000..387b17ce9c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_cpld.c @@ -0,0 +1,789 @@ +/* + * Copyright (C) Roger Ho + * + * This module provides support for accessing the Accton CPLD and + * retrieving the status of QSFP-DD/SFP port. + * This includes the: + * Accton as9737_32db FPGA/CPLD2/CPLD3 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define I2C_RW_RETRY_COUNT (10) +#define I2C_RW_RETRY_INTERVAL (60) /* ms */ + +#define PORT_NUM (32 + 2) /* 32 QSFPDDs + 2 SFPs */ + +/* FPGA */ +#define FPGA_BOARD_INFO_REG (0x00) +#define FPGA_VERSION_REG (0x01) + +/* CPLD 2 */ +#define CPLD2_VERSION_REG (0x01) +#define XCVR_P8_P1_PRESENT_REG (0x12) +#define XCVR_P16_P9_PRESENT_REG (0x13) +#define XCVR_P8_P1_RESET_REG (0x14) +#define XCVR_P16_P9_RESET_REG (0x15) +#define XCVR_P8_P1_LPMODE_REG (0x60) +#define XCVR_P16_P9_LPMODE_REG (0x61) +#define XCVR_P8_P1_PWR_EN_REG (0X81) +#define XCVR_P16_P9_PWR_EN_REG (0X82) +#define XCVR_P8_P1_PWR_GOOD_REG (0X83) +#define XCVR_P16_P9_PWR_GOOD_REG (0X84) + +/* CPLD 3 */ +#define CPLD3_VERSION_REG (0x01) +#define XCVR_P24_P17_PRESENT_REG (0x12) +#define XCVR_P32_P25_PRESENT_REG (0x13) +#define XCVR_P24_P17_RESET_REG (0x14) +#define XCVR_P32_P25_RESET_REG (0x15) +#define SFP_PRESENT_REG (0x20) +#define SFP_TXDIS_REG (0x21) +#define SFP_RATE_SEL (0x20) +#define SFP_RXLOSS_REG (0x26) +#define SFP_TXFAULT_REG (0x27) +#define XCVR_P24_P17_LPMODE_REG (0x60) +#define XCVR_P32_P25_LPMODE_REG (0x61) +#define XCVR_P24_P17_PWR_EN_REG (0X81) +#define XCVR_P32_P25_PWR_EN_REG (0X82) +#define XCVR_P24_P17_PWR_GOOD_REG (0X83) +#define XCVR_P32_P25_PWR_GOOD_REG (0X84) + + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +enum cpld_type { + as9737_32db_fpga, + as9737_32db_cpld2, + as9737_32db_cpld3 +}; + +struct as9737_32db_cpld_data { + enum cpld_type type; + u8 reg; + struct mutex update_lock; +}; + +static const struct i2c_device_id as9737_32db_cpld_id[] = { + { "as9737_32db_fpga", as9737_32db_fpga}, + { "as9737_32db_cpld2", as9737_32db_cpld2 }, + { "as9737_32db_cpld3", as9737_32db_cpld3 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, as9737_32db_cpld_id); + +#define QDD_TRANSCEIVER_ATTR_ID(index) \ + MODULE_PRESENT_##index = (index - 1), \ + MODULE_LPMODE_##index = (index - 1) + (PORT_NUM * 1), \ + MODULE_RESET_##index = (index - 1) + (PORT_NUM * 2), \ + MODULE_PWR_GOOD_##index = (index - 1) + (PORT_NUM * 3), \ + MODULE_PWR_ENABLE_##index = (index - 1) + (PORT_NUM * 4) + +#define SFP_TRANSCEIVER_ATTR_ID(index) \ + MODULE_PRESENT_##index = (index - 1), \ + MODULE_TX_DISABLE_##index = (index - 1) + (PORT_NUM * 5), \ + MODULE_RX_LOS_##index = (index - 1) + (PORT_NUM * 6), \ + MODULE_TX_FAULT_##index = (index - 1) + (PORT_NUM * 7) + +/* + * MODULE_PRESENT_1 ... MODULE_PRESENT_34 => 0 ... 33 + * MODULE_LPMODE_1 ... MODULE_LPMODE_32 => 34 ... 65 + * MODULE_RESET_1 ... MODULE_RESET_32 => 68 ... 99 + * MODULE_PWR_GOOD_1 ... MODULE_PWR_GOOD_32 => 102 ... 133 + * MODULE_PWR_ENABLE_1 ... MODULE_PWR_ENABLE_32 => 136 ... 167 + * MODULE_TX_DISABLE_33 ... MODULE_TX_DISABLE_34 => 202 ... 203 + * MODULE_RX_LOS_33 ... MODULE_RX_LOS_34 => 236 ... 237 + * MODULE_TX_FAULT_33 ... MODULE_TX_FAULT_34 => 270 ... 271 + */ + +enum as9737_32db_cpld_sysfs_attributes { + /* transceiver attributes */ + QDD_TRANSCEIVER_ATTR_ID(1), + QDD_TRANSCEIVER_ATTR_ID(2), + QDD_TRANSCEIVER_ATTR_ID(3), + QDD_TRANSCEIVER_ATTR_ID(4), + QDD_TRANSCEIVER_ATTR_ID(5), + QDD_TRANSCEIVER_ATTR_ID(6), + QDD_TRANSCEIVER_ATTR_ID(7), + QDD_TRANSCEIVER_ATTR_ID(8), + QDD_TRANSCEIVER_ATTR_ID(9), + QDD_TRANSCEIVER_ATTR_ID(10), + QDD_TRANSCEIVER_ATTR_ID(11), + QDD_TRANSCEIVER_ATTR_ID(12), + QDD_TRANSCEIVER_ATTR_ID(13), + QDD_TRANSCEIVER_ATTR_ID(14), + QDD_TRANSCEIVER_ATTR_ID(15), + QDD_TRANSCEIVER_ATTR_ID(16), + QDD_TRANSCEIVER_ATTR_ID(17), + QDD_TRANSCEIVER_ATTR_ID(18), + QDD_TRANSCEIVER_ATTR_ID(19), + QDD_TRANSCEIVER_ATTR_ID(20), + QDD_TRANSCEIVER_ATTR_ID(21), + QDD_TRANSCEIVER_ATTR_ID(22), + QDD_TRANSCEIVER_ATTR_ID(23), + QDD_TRANSCEIVER_ATTR_ID(24), + QDD_TRANSCEIVER_ATTR_ID(25), + QDD_TRANSCEIVER_ATTR_ID(26), + QDD_TRANSCEIVER_ATTR_ID(27), + QDD_TRANSCEIVER_ATTR_ID(28), + QDD_TRANSCEIVER_ATTR_ID(29), + QDD_TRANSCEIVER_ATTR_ID(30), + QDD_TRANSCEIVER_ATTR_ID(31), + QDD_TRANSCEIVER_ATTR_ID(32), + SFP_TRANSCEIVER_ATTR_ID(33), + SFP_TRANSCEIVER_ATTR_ID(34), + BOARD_INFO, + VERSION, + ACCESS, +}; + +/* sysfs attributes for hwmon */ +static ssize_t show(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_status(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t reg_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t reg_write(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static int as9737_32db_cpld_read_internal(struct i2c_client *client, u8 reg); +static int as9737_32db_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); + +/* transceiver attributes */ +#define DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index); \ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO|S_IWUSR, show_status, set_status, MODULE_RESET_##index); \ + static SENSOR_DEVICE_ATTR(module_lpmode_##index, S_IRUGO|S_IWUSR, show_status, set_status, MODULE_LPMODE_##index); \ + static SENSOR_DEVICE_ATTR(module_pwr_good_##index, S_IRUGO, show_status, NULL, MODULE_PWR_GOOD_##index); \ + static SENSOR_DEVICE_ATTR(module_pwr_enable_##index, S_IRUGO|S_IWUSR, show_status, set_status, MODULE_PWR_ENABLE_##index) + +#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index); \ + static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_status, MODULE_TX_DISABLE_##index); \ + static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RX_LOS_##index); \ + static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TX_FAULT_##index) + +/* declare transceiver attributes callback function */ +static SENSOR_DEVICE_ATTR(board_info, S_IRUGO, show, NULL, BOARD_INFO); +static SENSOR_DEVICE_ATTR(version, S_IRUGO, show, NULL, VERSION); +static SENSOR_DEVICE_ATTR(access, S_IRUGO|S_IWUSR, reg_read, reg_write, ACCESS); + +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(1); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(2); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(3); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(4); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(5); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(6); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(7); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(8); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(9); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(10); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(11); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(12); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(13); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(14); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(15); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(16); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(17); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(18); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(19); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(20); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(21); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(22); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(23); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(24); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(25); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(26); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(27); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(28); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(29); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(30); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(31); +DECLARE_QDD_TRANSCEIVER_SENSOR_DEVICE_ATTR(32); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(33); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34); + +#define DECLARE_QDD_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_present_##index.dev_attr.attr, \ + &sensor_dev_attr_module_reset_##index.dev_attr.attr, \ + &sensor_dev_attr_module_lpmode_##index.dev_attr.attr, \ + &sensor_dev_attr_module_pwr_good_##index.dev_attr.attr, \ + &sensor_dev_attr_module_pwr_enable_##index.dev_attr.attr + +#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_present_##index.dev_attr.attr, \ + &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ + &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ + &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr + +static struct attribute *as9737_32db_cpld2_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + DECLARE_QDD_TRANSCEIVER_ATTR(1), + DECLARE_QDD_TRANSCEIVER_ATTR(2), + DECLARE_QDD_TRANSCEIVER_ATTR(3), + DECLARE_QDD_TRANSCEIVER_ATTR(4), + DECLARE_QDD_TRANSCEIVER_ATTR(5), + DECLARE_QDD_TRANSCEIVER_ATTR(6), + DECLARE_QDD_TRANSCEIVER_ATTR(7), + DECLARE_QDD_TRANSCEIVER_ATTR(8), + DECLARE_QDD_TRANSCEIVER_ATTR(9), + DECLARE_QDD_TRANSCEIVER_ATTR(10), + DECLARE_QDD_TRANSCEIVER_ATTR(11), + DECLARE_QDD_TRANSCEIVER_ATTR(12), + DECLARE_QDD_TRANSCEIVER_ATTR(13), + DECLARE_QDD_TRANSCEIVER_ATTR(14), + DECLARE_QDD_TRANSCEIVER_ATTR(15), + DECLARE_QDD_TRANSCEIVER_ATTR(16), + NULL +}; + +static const struct attribute_group as9737_32db_cpld2_group = { + .attrs = as9737_32db_cpld2_attributes, +}; + +static struct attribute *as9737_32db_cpld3_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + DECLARE_QDD_TRANSCEIVER_ATTR(17), + DECLARE_QDD_TRANSCEIVER_ATTR(18), + DECLARE_QDD_TRANSCEIVER_ATTR(19), + DECLARE_QDD_TRANSCEIVER_ATTR(20), + DECLARE_QDD_TRANSCEIVER_ATTR(21), + DECLARE_QDD_TRANSCEIVER_ATTR(22), + DECLARE_QDD_TRANSCEIVER_ATTR(23), + DECLARE_QDD_TRANSCEIVER_ATTR(24), + DECLARE_QDD_TRANSCEIVER_ATTR(25), + DECLARE_QDD_TRANSCEIVER_ATTR(26), + DECLARE_QDD_TRANSCEIVER_ATTR(27), + DECLARE_QDD_TRANSCEIVER_ATTR(28), + DECLARE_QDD_TRANSCEIVER_ATTR(29), + DECLARE_QDD_TRANSCEIVER_ATTR(30), + DECLARE_QDD_TRANSCEIVER_ATTR(31), + DECLARE_QDD_TRANSCEIVER_ATTR(32), + DECLARE_SFP_TRANSCEIVER_ATTR(33), + DECLARE_SFP_TRANSCEIVER_ATTR(34), + NULL +}; + +static const struct attribute_group as9737_32db_cpld3_group = { + .attrs = as9737_32db_cpld3_attributes, +}; + +static struct attribute *as9737_32db_fpga_attributes[] = { + &sensor_dev_attr_board_info.dev_attr.attr, + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + NULL +}; + +static const struct attribute_group as9737_32db_fpga_group = { + .attrs = as9737_32db_fpga_attributes, +}; + +struct attribute_mapping { + u16 attr_base; + u8 reg; + u8 revert; +}; + +static const struct attribute_mapping attribute_mappings[] = { + [MODULE_PRESENT_1 ... MODULE_PRESENT_8] = {MODULE_PRESENT_1, XCVR_P8_P1_PRESENT_REG, 1}, + [MODULE_PRESENT_9 ... MODULE_PRESENT_16] = {MODULE_PRESENT_9, XCVR_P16_P9_PRESENT_REG, 1}, + [MODULE_PRESENT_17 ... MODULE_PRESENT_24] = {MODULE_PRESENT_17, XCVR_P24_P17_PRESENT_REG, 1}, + [MODULE_PRESENT_25 ... MODULE_PRESENT_32] = {MODULE_PRESENT_25, XCVR_P32_P25_PRESENT_REG, 1}, + /* Bit 1:SFP P2, Bit 0: SFP P1 */ + [MODULE_PRESENT_33 ... MODULE_PRESENT_34] = {MODULE_PRESENT_33, SFP_PRESENT_REG, 1}, + + [MODULE_LPMODE_1 ... MODULE_LPMODE_8] = {MODULE_LPMODE_1, XCVR_P8_P1_LPMODE_REG, 0}, + [MODULE_LPMODE_9 ... MODULE_LPMODE_16] = {MODULE_LPMODE_9, XCVR_P16_P9_LPMODE_REG, 0}, + [MODULE_LPMODE_17 ... MODULE_LPMODE_24] = {MODULE_LPMODE_17, XCVR_P24_P17_LPMODE_REG, 0}, + [MODULE_LPMODE_25 ... MODULE_LPMODE_32] = {MODULE_LPMODE_25, XCVR_P32_P25_LPMODE_REG, 0}, + + [MODULE_RESET_1 ... MODULE_RESET_8] = {MODULE_RESET_1, XCVR_P8_P1_RESET_REG, 1}, + [MODULE_RESET_9 ... MODULE_RESET_16] = {MODULE_RESET_9, XCVR_P16_P9_RESET_REG, 1}, + [MODULE_RESET_17 ... MODULE_RESET_24] = {MODULE_RESET_17, XCVR_P24_P17_RESET_REG, 1}, + [MODULE_RESET_25 ... MODULE_RESET_32] = {MODULE_RESET_25, XCVR_P32_P25_RESET_REG, 1}, + + [MODULE_PWR_GOOD_1 ... MODULE_PWR_GOOD_8] = {MODULE_PWR_GOOD_1, XCVR_P8_P1_PWR_GOOD_REG, 0}, + [MODULE_PWR_GOOD_9 ... MODULE_PWR_GOOD_16] = {MODULE_PWR_GOOD_1, XCVR_P16_P9_PWR_GOOD_REG, 0}, + [MODULE_PWR_GOOD_17 ... MODULE_PWR_GOOD_24] = {MODULE_PWR_GOOD_1, XCVR_P24_P17_PWR_GOOD_REG, 0}, + [MODULE_PWR_GOOD_25 ... MODULE_PWR_GOOD_32] = {MODULE_PWR_GOOD_1, XCVR_P32_P25_PWR_GOOD_REG, 0}, + + [MODULE_PWR_ENABLE_1 ... MODULE_PWR_ENABLE_8] = {MODULE_PWR_ENABLE_1, XCVR_P8_P1_PWR_EN_REG, 0}, + [MODULE_PWR_ENABLE_9 ... MODULE_PWR_ENABLE_16] = {MODULE_PWR_ENABLE_1, XCVR_P16_P9_PWR_EN_REG, 0}, + [MODULE_PWR_ENABLE_17 ... MODULE_PWR_ENABLE_24] = {MODULE_PWR_ENABLE_1, XCVR_P24_P17_PWR_EN_REG, 0}, + [MODULE_PWR_ENABLE_25 ... MODULE_PWR_ENABLE_32] = {MODULE_PWR_ENABLE_1, XCVR_P32_P25_PWR_EN_REG, 0}, + + /* Bit 1:SFP P2, Bit 0: SFP P1 */ + [MODULE_TX_DISABLE_33 ... MODULE_TX_DISABLE_34] ={MODULE_TX_DISABLE_33, SFP_TXDIS_REG, 0}, + [MODULE_RX_LOS_33 ... MODULE_RX_LOS_34] = {MODULE_RX_LOS_33, SFP_RXLOSS_REG, 0}, + [MODULE_TX_FAULT_33 ... MODULE_TX_FAULT_34] = {MODULE_TX_FAULT_33, SFP_TXFAULT_REG, 0}, +}; + +static ssize_t show(struct device *dev, struct device_attribute *da, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as9737_32db_cpld_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + u8 reg = 0; + int val = 0; + + switch(attr->index) + { + case VERSION: + switch (data->type) { + case as9737_32db_fpga: + reg = FPGA_VERSION_REG; + break; + case as9737_32db_cpld2: + reg = CPLD2_VERSION_REG; + break; + case as9737_32db_cpld3: + reg = CPLD3_VERSION_REG; + break; + default: + break; + } + break; + case BOARD_INFO: + reg = FPGA_BOARD_INFO_REG; + break; + default: + break; + } + + val = i2c_smbus_read_byte_data(client, reg); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%02x) reg(0x%02x) err %d\n", + client->addr, reg, val); + } + + return sprintf(buf, "%d\n", val); +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as9737_32db_cpld_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int status = 0; + u8 reg = 0, reg_val = 0, bits_shift = 0; + + switch(attr->index) + { + case MODULE_PRESENT_1 ... MODULE_TX_FAULT_34: + reg = attribute_mappings[attr->index].reg; + mutex_lock(&data->update_lock); + status = as9737_32db_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + reg_val = status; + + bits_shift = attr->index - attribute_mappings[attr->index].attr_base; + reg_val = (reg_val >> bits_shift) & 0x01; + if (attribute_mappings[attr->index].revert) { + reg_val = !reg_val; + } + + status = sprintf(buf, "%d\n", reg_val); + break; + default: + break; + } + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_status(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as9737_32db_cpld_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int status = 0; + u8 input; + u8 reg = 0, mask = 0, should_set_bit = 0; + + status = kstrtou8(buf, 10, &input); + if (status) { + return status; + } + + reg = attribute_mappings[attr->index].reg; + + mask = 0x01 << (attr->index - attribute_mappings[attr->index].attr_base); + should_set_bit = attribute_mappings[attr->index].revert ? !input : input; + + mutex_lock(&data->update_lock); + status = as9737_32db_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + if (should_set_bit) { + status |= mask; + } else { + status &= ~mask; + } + status = as9737_32db_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t reg_read(struct device *dev, struct device_attribute *da, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as9737_32db_cpld_data *data = i2c_get_clientdata(client); + int reg_val, status = 0; + + mutex_lock(&data->update_lock); + reg_val = as9737_32db_cpld_read_internal(client, data->reg); + if (unlikely(reg_val < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + status = sprintf(buf, "0x%02x\n", reg_val); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t reg_write(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as9737_32db_cpld_data *data = i2c_get_clientdata(client); + int args, status; + char *opt, tmp[32] = {0}; + char *tmp_p; + size_t copy_size; + u8 input[2] = {0}; + + copy_size = (count < sizeof(tmp)) ? count : sizeof(tmp) - 1; + #ifdef __STDC_LIB_EXT1__ + memcpy_s(tmp, copy_size, buf, copy_size); + #else + memcpy(tmp, buf, copy_size); + #endif + tmp[copy_size] = '\0'; + + args = 0; + tmp_p = tmp; + while (args < 2 && (opt = strsep(&tmp_p, " ")) != NULL) { + if (kstrtou8(opt, 16, &input[args]) == 0) { + args++; + } + } + + switch(args) + { + case 2: + /* Write value to register */ + mutex_lock(&data->update_lock); + status = as9737_32db_cpld_write_internal(client, input[0], input[1]); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + break; + case 1: + /* Read value from register */ + data->reg = input[0]; + break; + default: + return -EINVAL; + } + + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static void as9737_32db_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void as9737_32db_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +/* + * I2C init/probing/exit functions + */ +static int as9737_32db_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + struct as9737_32db_cpld_data *data; + int ret = -ENODEV; + const struct attribute_group *group = NULL; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + goto exit; + + data = kzalloc(sizeof(struct as9737_32db_cpld_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->type = id->driver_data; + + /* Register sysfs hooks */ + switch (data->type) { + case as9737_32db_fpga: + data->reg = FPGA_VERSION_REG; + group = &as9737_32db_fpga_group; + break; + case as9737_32db_cpld2: + data->reg = CPLD2_VERSION_REG; + group = &as9737_32db_cpld2_group; + break; + case as9737_32db_cpld3: + data->reg = CPLD3_VERSION_REG; + group = &as9737_32db_cpld3_group; + break; + default: + break; + } + + if (group) { + ret = sysfs_create_group(&client->dev.kobj, group); + if (ret) { + goto exit_free; + } + } + + as9737_32db_cpld_add_client(client); + return 0; + +exit_free: + kfree(data); +exit: + return ret; +} + +static int as9737_32db_cpld_remove(struct i2c_client *client) +{ + struct as9737_32db_cpld_data *data = i2c_get_clientdata(client); + const struct attribute_group *group = NULL; + + as9737_32db_cpld_remove_client(client); + + /* Remove sysfs hooks */ + switch (data->type) { + case as9737_32db_fpga: + group = &as9737_32db_fpga_group; + break; + case as9737_32db_cpld2: + group = &as9737_32db_cpld2_group; + break; + case as9737_32db_cpld3: + group = &as9737_32db_cpld3_group; + break; + default: + break; + } + + if (group) { + sysfs_remove_group(&client->dev.kobj, group); + } + + kfree(data); + + return 0; +} + +static int as9737_32db_cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int as9737_32db_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +int as9737_32db_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as9737_32db_cpld_read_internal(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as9737_32db_cpld_read); + +int as9737_32db_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as9737_32db_cpld_write_internal(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as9737_32db_cpld_write); + +static struct i2c_driver as9737_32db_cpld_driver = { + .driver = { + .name = "as9737_32db_cpld", + .owner = THIS_MODULE, + }, + .probe = as9737_32db_cpld_probe, + .remove = as9737_32db_cpld_remove, + .id_table = as9737_32db_cpld_id, +}; + +static int __init as9737_32db_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as9737_32db_cpld_driver); +} + +static void __exit as9737_32db_cpld_exit(void) +{ + i2c_del_driver(&as9737_32db_cpld_driver); +} + +MODULE_AUTHOR("Roger Ho "); +MODULE_DESCRIPTION("AS9373-32DB CPLD driver"); +MODULE_LICENSE("GPL"); + +module_init(as9737_32db_cpld_init); +module_exit(as9737_32db_cpld_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_fan.c b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_fan.c new file mode 100644 index 0000000000..4a4a4c73fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_fan.c @@ -0,0 +1,824 @@ +/* + * Copyright (C) Roger Ho + * + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as9737_32db_fan" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_FAN_READ_CMD 0x14 +#define IPMI_FAN_WRITE_CMD 0x15 +#define IPMI_FAN_READ_RPM_CMD 0x20 +#define IPMI_TIMEOUT (5 * HZ) +#define IPMI_ERR_RETRY_TIMES 1 +#define IPMI_FAN_REG_READ_CMD 0x20 +#define IPMI_FAN_REG_WRITE_CMD 0x21 +#define MAX_FAN_SPEED_RPM 33000 + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static ssize_t set_fan(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_fan(struct device *dev, struct device_attribute *attr, + char *buf); +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_dir(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_threshold(struct device *dev, struct device_attribute *da, + char *buf); +static int as9737_32db_fan_probe(struct platform_device *pdev); +static int as9737_32db_fan_remove(struct platform_device *pdev); + +enum fan_id { + FAN_1, + FAN_2, + FAN_3, + FAN_4, + FAN_5, + FAN_6, + FAN_7, + FAN_8, + FAN_9, + FAN_10, + FAN_11, + FAN_12, + NUM_OF_FAN, + NUM_OF_FAN_MODULE = NUM_OF_FAN +}; + +enum fan_data_index { + FAN_PRESENT, + FAN_PWM, + FAN_SPEED0, + FAN_SPEED1, + FAN_DATA_COUNT, + + FAN_TARGET_SPEED0 = 0, + FAN_TARGET_SPEED1, + FAN_SPEED_TOLERANCE, + FAN_SPEED_DATA_COUNT +}; + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + struct ipmi_user *user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct as9737_32db_fan_data { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + /* 4 bytes for each fan, the last 2 bytes is fan dir */ + unsigned char ipmi_resp[NUM_OF_FAN * FAN_DATA_COUNT + 2]; + unsigned char ipmi_resp_cpld[2]; + unsigned char ipmi_resp_speed[NUM_OF_FAN * FAN_SPEED_DATA_COUNT]; + struct ipmi_data ipmi; + unsigned char ipmi_tx_data[3]; /* 0: FAN id, 1: 0x02, 2: PWM */ +}; + +struct as9737_32db_fan_data *data = NULL; + +static struct platform_driver as9737_32db_fan_driver = { + .probe = as9737_32db_fan_probe, + .remove = as9737_32db_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +#define FAN_PRESENT_ATTR_ID(index) FAN##index##_PRESENT +#define FAN_PWM_ATTR_ID(index) FAN##index##_PWM +#define FAN_RPM_ATTR_ID(index) FAN##index##_INPUT +#define FAN_DIR_ATTR_ID(index) FAN##index##_DIR +#define FAN_FAULT_ATTR_ID(index) FAN##index##_FAULT +#define FAN_RPM_TARGET_ATTR_ID(index) FAN##index##_TARGET +#define FAN_RPM_TOLERANCE_ATTR_ID(index) FAN##index##_TOLERANCE + +#define FAN_ATTR(fan_id) \ + FAN_PRESENT_ATTR_ID(fan_id), \ + FAN_PWM_ATTR_ID(fan_id), \ + FAN_RPM_ATTR_ID(fan_id), \ + FAN_DIR_ATTR_ID(fan_id), \ + FAN_FAULT_ATTR_ID(fan_id) + +#define FAN_RPM_THRESHOLD_ATTR(fan_id) \ + FAN_RPM_TARGET_ATTR_ID(fan_id), \ + FAN_RPM_TOLERANCE_ATTR_ID(fan_id) + +enum as9737_32db_fan_sysfs_attrs { + FAN_ATTR(1), + FAN_ATTR(2), + FAN_ATTR(3), + FAN_ATTR(4), + FAN_ATTR(5), + FAN_ATTR(6), + FAN_ATTR(7), + FAN_ATTR(8), + FAN_ATTR(9), + FAN_ATTR(10), + FAN_ATTR(11), + FAN_ATTR(12), + NUM_OF_FAN_ATTR, + FAN_VERSION, + FAN_MAX_RPM, + NUM_OF_PER_FAN_ATTR = (NUM_OF_FAN_ATTR/NUM_OF_FAN), + FAN_RPM_THRESHOLD_ATTR(1), + FAN_RPM_THRESHOLD_ATTR(2), + FAN_RPM_THRESHOLD_ATTR(3), + FAN_RPM_THRESHOLD_ATTR(4), + FAN_RPM_THRESHOLD_ATTR(5), + FAN_RPM_THRESHOLD_ATTR(6), + FAN_RPM_THRESHOLD_ATTR(7), + FAN_RPM_THRESHOLD_ATTR(8), + FAN_RPM_THRESHOLD_ATTR(9), + FAN_RPM_THRESHOLD_ATTR(10), + FAN_RPM_THRESHOLD_ATTR(11), + FAN_RPM_THRESHOLD_ATTR(12), + NUM_OF_FAN_RPM_THRESHOLD_ATTR, + NUM_OF_PER_FAN_RPM_THRESHOLD_ATTR = ((NUM_OF_FAN_RPM_THRESHOLD_ATTR-NUM_OF_PER_FAN_ATTR)/NUM_OF_FAN), +}; + +/* fan attributes */ +#define DECLARE_FAN_VER_SENSOR_DEVICE_ATTR() \ + static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, FAN_VERSION) +#define DECLARE_FAN_VER_ATTR() \ + &sensor_dev_attr_version.dev_attr.attr + +#define DECLARE_FAN_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, show_fan, NULL, \ + FAN##index##_PRESENT); \ + static SENSOR_DEVICE_ATTR(fan##index##_pwm, S_IWUSR | S_IRUGO, show_fan, \ + set_fan, FAN##index##_PWM); \ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, show_fan, NULL, \ + FAN##index##_INPUT); \ + static SENSOR_DEVICE_ATTR(fan##index##_dir, S_IRUGO, show_dir, NULL, \ + FAN##index##_DIR); \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, show_fan, NULL, \ + FAN##index##_FAULT); \ + static SENSOR_DEVICE_ATTR(fan##index##_target, S_IRUGO, show_threshold, \ + NULL, FAN##index##_TARGET); \ + static SENSOR_DEVICE_ATTR(fan##index##_tolerance, S_IRUGO, show_threshold,\ + NULL, FAN##index##_TOLERANCE) + +static SENSOR_DEVICE_ATTR(fan_max_speed_rpm, S_IRUGO, show_fan, NULL, \ + FAN_MAX_RPM); +#define DECLARE_FAN_MAX_RPM_ATTR(index) \ + &sensor_dev_attr_fan_max_speed_rpm.dev_attr.attr + +#define DECLARE_FAN_ATTR(index) \ + &sensor_dev_attr_fan##index##_present.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_pwm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_dir.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_target.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_tolerance.dev_attr.attr + +DECLARE_FAN_SENSOR_DEVICE_ATTR(1); +DECLARE_FAN_SENSOR_DEVICE_ATTR(2); +DECLARE_FAN_SENSOR_DEVICE_ATTR(3); +DECLARE_FAN_SENSOR_DEVICE_ATTR(4); +DECLARE_FAN_SENSOR_DEVICE_ATTR(5); +DECLARE_FAN_SENSOR_DEVICE_ATTR(6); +DECLARE_FAN_SENSOR_DEVICE_ATTR(7); +DECLARE_FAN_SENSOR_DEVICE_ATTR(8); +DECLARE_FAN_SENSOR_DEVICE_ATTR(9); +DECLARE_FAN_SENSOR_DEVICE_ATTR(10); +DECLARE_FAN_SENSOR_DEVICE_ATTR(11); +DECLARE_FAN_SENSOR_DEVICE_ATTR(12); +DECLARE_FAN_VER_SENSOR_DEVICE_ATTR(); + +static struct attribute *as9737_32db_fan_attrs[] = { + /* fan attributes */ + DECLARE_FAN_ATTR(1), + DECLARE_FAN_ATTR(2), + DECLARE_FAN_ATTR(3), + DECLARE_FAN_ATTR(4), + DECLARE_FAN_ATTR(5), + DECLARE_FAN_ATTR(6), + DECLARE_FAN_ATTR(7), + DECLARE_FAN_ATTR(8), + DECLARE_FAN_ATTR(9), + DECLARE_FAN_ATTR(10), + DECLARE_FAN_ATTR(11), + DECLARE_FAN_ATTR(12), + DECLARE_FAN_VER_ATTR(), + DECLARE_FAN_MAX_RPM_ATTR(), + NULL +}; +ATTRIBUTE_GROUPS(as9737_32db_fan); + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Send an IPMI command with retry */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int status = 0, retry = 0; + + char *cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); + + int i = 0; + char raw_cmd[20] = ""; + sprintf(raw_cmd, "0x%02x", cmd); + if(tx_len) + { + for( i=0; i < tx_len; i++) { + sprintf(raw_cmd + strlen(raw_cmd), " 0x%02x", tx_data[i]); + } + } + + for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { + status = _ipmi_send_message(ipmi,cmd, tx_data, tx_len, rx_data, rx_len); + if (unlikely(status != 0)) { + dev_err(&data->pdev->dev, "ipmi_send_message_%d err status(%d)[%s] raw_cmd=[%s]\r\n", + retry, status, cmdline ? cmdline : "", raw_cmd); + continue; + } + + if (unlikely(ipmi->rx_result != 0)) { + dev_err(&data->pdev->dev, "ipmi_send_message_%d err result(%d)[%s] raw_cmd=[%s]\r\n", + retry, ipmi->rx_result, cmdline ? cmdline : "", raw_cmd); + continue; + } + + break; + } + + if (cmdline) kfree(cmdline); + return status; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static struct as9737_32db_fan_data *as9737_32db_fan_update_device(void) +{ + int status = 0; + + if (time_before(jiffies, data->last_updated + HZ * 5) && data->valid) + return data; + + data->valid = 0; + status = ipmi_send_message(&data->ipmi, IPMI_FAN_READ_CMD, NULL, 0, + data->ipmi_resp, sizeof(data->ipmi_resp)); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + + data->ipmi_tx_data[0] = IPMI_FAN_READ_RPM_CMD; + status = ipmi_send_message(&data->ipmi, IPMI_FAN_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp_speed, + sizeof(data->ipmi_resp_speed)); + data->last_updated = jiffies; + data->valid = 1; + +exit: + return data; +} + +static ssize_t show_fan(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char fid = attr->index / NUM_OF_PER_FAN_ATTR; + int value = 0; + int index = 0; + int present = 0; + int error = 0; + + if (attr->index == FAN_MAX_RPM) + return sprintf(buf, "%d\n", MAX_FAN_SPEED_RPM); + + mutex_lock(&data->update_lock); + + data = as9737_32db_fan_update_device(); + if (!data->valid) { + error = -EIO; + goto exit; + } + + index = fid * FAN_DATA_COUNT; /* base index */ + present = !!data->ipmi_resp[index + FAN_PRESENT]; + + switch (attr->index) { + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + case FAN7_PRESENT: + case FAN8_PRESENT: + case FAN9_PRESENT: + case FAN10_PRESENT: + case FAN11_PRESENT: + case FAN12_PRESENT: + value = present; + break; + case FAN1_PWM: + case FAN2_PWM: + case FAN3_PWM: + case FAN4_PWM: + case FAN5_PWM: + case FAN6_PWM: + case FAN7_PWM: + case FAN8_PWM: + case FAN9_PWM: + case FAN10_PWM: + case FAN11_PWM: + case FAN12_PWM: + index = (fid % NUM_OF_FAN_MODULE) * FAN_DATA_COUNT; + value = DIV_ROUND_CLOSEST(data->ipmi_resp[index + FAN_PWM] * 100, 255); + break; + case FAN1_INPUT: + case FAN2_INPUT: + case FAN3_INPUT: + case FAN4_INPUT: + case FAN5_INPUT: + case FAN6_INPUT: + case FAN7_INPUT: + case FAN8_INPUT: + case FAN9_INPUT: + case FAN10_INPUT: + case FAN11_INPUT: + case FAN12_INPUT: + value = (int)data->ipmi_resp[index + FAN_SPEED0] | + (int)data->ipmi_resp[index + FAN_SPEED1] << 8; + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + case FAN7_FAULT: + case FAN8_FAULT: + case FAN9_FAULT: + case FAN10_FAULT: + case FAN11_FAULT: + case FAN12_FAULT: + value = (int)data->ipmi_resp[index + FAN_SPEED0] | + (int)data->ipmi_resp[index + FAN_SPEED1] << 8; + value = !value; + break; + default: + error = -EINVAL; + goto exit; + } + + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", value); + +exit: + mutex_unlock(&data->update_lock); + return error; +} + +static ssize_t set_fan(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long pwm; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char fid = attr->index / NUM_OF_PER_FAN_ATTR; + + status = kstrtol(buf, 10, &pwm); + if (status) + return status; + + pwm = DIV_ROUND_CLOSEST(pwm * 255, 100); /* Convert pwm to register value */ + + mutex_lock(&data->update_lock); + + /* + * Send IPMI write command : + * BMC supports a design with four fan modules, each containing two fans. + * Since NUM_OF_FAN_MODULE is 12 in AS9737-32DB, it needs to be divided by 2. + * The result : + * fan1_pwm(Front) : ipmi_tx_data[0] = 1, fan2_pwm(Front) : ipmi_tx_data[0] = 2 + * fan3_pwm(Front) : ipmi_tx_data[0] = 3, fan4_pwm(Front) : ipmi_tx_data[0] = 4 + * fan5_pwm(Rear) : ipmi_tx_data[0] = 1, fan6_pwm(Rear) : ipmi_tx_data[0] = 2 + * fan7_pwm(Rear) : ipmi_tx_data[0] = 3, fan8_pwm(Rear) : ipmi_tx_data[0] = 4 + * fan9_pwm(Rear) : ipmi_tx_data[0] = 1, fan10_pwm(Rear) : ipmi_tx_data[0] = 2 + * fan11_pwm(Rear) : ipmi_tx_data[0] = 3, fan12_pwm(Rear) : ipmi_tx_data[0] = 4 + * + */ + data->ipmi_tx_data[0] = (fid % (NUM_OF_FAN_MODULE / 2)) + 1; + data->ipmi_tx_data[1] = 0x02; + data->ipmi_tx_data[2] = pwm; + status = ipmi_send_message(&data->ipmi, IPMI_FAN_WRITE_CMD, + data->ipmi_tx_data, sizeof(data->ipmi_tx_data), + NULL, 0); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + /* Update pwm to ipmi_resp buffer to prevent from the impact of lazy update */ + data->ipmi_resp[fid * FAN_DATA_COUNT + FAN_PWM] = pwm; + status = count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static struct as9737_32db_fan_data *as9737_32db_fan_update_cpld_ver(void) +{ + int status = 0; + + data->valid = 0; + data->ipmi_tx_data[0] = 0x66; + status = ipmi_send_message(&data->ipmi, IPMI_FAN_REG_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp_cpld, + sizeof(data->ipmi_resp_cpld)); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + +exit: + return data; +} + +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf) +{ + unsigned char major; + unsigned char minor; + int error = 0; + + mutex_lock(&data->update_lock); + + data = as9737_32db_fan_update_cpld_ver(); + if (!data->valid) { + error = -EIO; + goto exit; + } + + major = data->ipmi_resp_cpld[0]; + minor = data->ipmi_resp_cpld[1]; + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d.%d\n", major, minor); + +exit: + mutex_unlock(&data->update_lock); + return error; +} + +static ssize_t show_dir(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char fid = (attr->index / NUM_OF_PER_FAN_ATTR); + int value = 0; + int index = 0; + int present = 0; + int error = 0; + + mutex_lock(&data->update_lock); + + data = as9737_32db_fan_update_device(); + if (!data->valid) { + error = -EIO; + goto exit; + } + + index = fid * FAN_DATA_COUNT; /* base index */ + present = !!data->ipmi_resp[index + FAN_PRESENT]; + + value = data->ipmi_resp[NUM_OF_FAN * FAN_DATA_COUNT] | + (data->ipmi_resp[NUM_OF_FAN * FAN_DATA_COUNT + 1] << 8); + mutex_unlock(&data->update_lock); + + if (!present) + return sprintf(buf, "0\n"); + else + return sprintf(buf, "%s\n", + (value & BIT(fid % NUM_OF_FAN_MODULE)) ? "B2F" : "F2B"); + +exit: + mutex_unlock(&data->update_lock); + return error; +} + +static ssize_t show_threshold(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char fid; + int index = 0; + int value = 0; + int error = 0; + + mutex_lock(&data->update_lock); + + data = as9737_32db_fan_update_device(); + if (!data->valid) { + error = -EIO; + goto exit; + } + + switch (attr->index) { + case FAN1_TARGET: + case FAN2_TARGET: + case FAN3_TARGET: + case FAN4_TARGET: + case FAN5_TARGET: + case FAN6_TARGET: + case FAN7_TARGET: + case FAN8_TARGET: + case FAN9_TARGET: + case FAN10_TARGET: + case FAN11_TARGET: + case FAN12_TARGET: + fid = (attr->index - FAN1_TARGET) / NUM_OF_PER_FAN_RPM_THRESHOLD_ATTR; + index = fid * FAN_SPEED_DATA_COUNT; + value = (int)data->ipmi_resp_speed[index + FAN_TARGET_SPEED0] | + (int)data->ipmi_resp_speed[index + FAN_TARGET_SPEED1] << 8; + break; + case FAN1_TOLERANCE: + case FAN2_TOLERANCE: + case FAN3_TOLERANCE: + case FAN4_TOLERANCE: + case FAN5_TOLERANCE: + case FAN6_TOLERANCE: + case FAN7_TOLERANCE: + case FAN8_TOLERANCE: + case FAN9_TOLERANCE: + case FAN10_TOLERANCE: + case FAN11_TOLERANCE: + case FAN12_TOLERANCE: + fid = (attr->index - FAN1_TOLERANCE) / NUM_OF_PER_FAN_RPM_THRESHOLD_ATTR; + index = fid * FAN_SPEED_DATA_COUNT; + value = (int)data->ipmi_resp_speed[index + FAN_SPEED_TOLERANCE]; + break; + default: + error = -EINVAL; + goto exit; + } + + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", value); + +exit: + mutex_unlock(&data->update_lock); + return error; +} + +static int as9737_32db_fan_probe(struct platform_device *pdev) +{ + int status = 0; + struct device *hwmon_dev; + + hwmon_dev = hwmon_device_register_with_info(&pdev->dev, DRVNAME, + NULL, NULL, as9737_32db_fan_groups); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + return status; + } + + mutex_lock(&data->update_lock); + data->hwmon_dev = hwmon_dev; + mutex_unlock(&data->update_lock); + + dev_info(&pdev->dev, "Device Created\n"); + + return status; +} + +static int as9737_32db_fan_remove(struct platform_device *pdev) +{ + mutex_lock(&data->update_lock); + if (data->hwmon_dev) { + hwmon_device_unregister(data->hwmon_dev); + data->hwmon_dev = NULL; + } + mutex_unlock(&data->update_lock); + + return 0; +} + +static int __init as9737_32db_fan_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as9737_32db_fan_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + + ret = platform_driver_register(&as9737_32db_fan_driver); + if (ret < 0) + goto dri_reg_err; + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) { + goto ipmi_err; + } + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as9737_32db_fan_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as9737_32db_fan_exit(void) +{ + if (data) { + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + kfree(data); + } + platform_driver_unregister(&as9737_32db_fan_driver); +} + +MODULE_AUTHOR("Roger Ho "); +MODULE_DESCRIPTION("as9737_32db_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(as9737_32db_fan_init); +module_exit(as9737_32db_fan_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_fpga.c b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_fpga.c new file mode 100644 index 0000000000..b93c67b8f9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_fpga.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) Roger Ho + * + * This module provides support for accessing + * QSFP-DD/SFP eeprom by I2C. + * + * This includes the: + * Accton as9737_32db FPGA I2C + * + * Copyright (C) 2017 Finisar Corp. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include + +/*********************************************** + * variable define + * *********************************************/ +#define DRVNAME "as9737_32db_fpga_i2c" +#define OCORES_I2C_DRVNAME "ocores-i2c" + +#define PORT_NUM (32 + 2) /* 32 QSFPDDs + 1 SFP+ + 1 SFP */ + +/* + * PCIE BAR0 address + */ +#define BAR0_NUM 0 +#define FPGA_PCI_VENDOR_ID 0x1172 +#define FPGA_PCI_DEVICE_ID 0x0004 + +#define CPLD2 0x01 +#define CPLD3 0x02 + +/*********************************************** + * macro define + * *********************************************/ +#define pcie_err(fmt, args...) \ + printk(KERN_ERR "["DRVNAME"]: " fmt " ", ##args) + +#define pcie_info(fmt, args...) \ + printk(KERN_ERR "["DRVNAME"]: " fmt " ", ##args) + +#define DEFINE_RES_REG_NAMED(_start, _size, _name) \ + DEFINE_RES_NAMED((_start), (_size), (_name), IORESOURCE_REG) + +/*********************************************** + * structure & variable declare + * *********************************************/ +typedef struct pci_fpga_device_s { + struct pci_dev *pci_dev; + struct platform_device *fpga_i2c[PORT_NUM]; +} pci_fpga_device_t; + +static struct platform_device *pdev = NULL; + +/*********************************************** + * enum define + * *********************************************/ + + +/*********************************************** + * function declare + * *********************************************/ + +#if 0 +static inline unsigned int fpga_read(const void __iomem *addr) +{ + return ioread8(addr); +} + +static inline void fpga_write(void __iomem *addr, u8 val) +{ + iowrite8(val, addr); +} +#endif + +struct port_data { + u16 offset; + u16 channel; + u16 cpld; /* 0x01 --> CPLD2, 0x02 --> CPLD3 */ +}; + +/* ============PCIe Bar Offset to I2C Master Mapping============== */ +#ifdef HAS_CHANNEL_REG +static const struct port_data port[PORT_NUM]= { + {0x00, 0x00, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port1 */ + {0x00, 0x01, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port2 */ + {0x00, 0x02, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port3 */ + {0x00, 0x03, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port4 */ + {0x00, 0x04, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port5 */ + {0x00, 0x05, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port6 */ + {0x00, 0x06, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port7 */ + {0x00, 0x07, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port8 */ + {0x00, 0x08, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port9 */ + {0x00, 0x09, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port10 */ + {0x00, 0x0a, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port11 */ + {0x00, 0x0b, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port12 */ + {0x00, 0x0c, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port13 */ + {0x00, 0x0d, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port14 */ + {0x00, 0x0e, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port15 */ + {0x00, 0x0f, CPLD2},/* 0x00 - 0x05 CPLD2 I2C Master Port16 */ + {0x00, 0x10, CPLD3},/* 0x00 - 0x05 CPLD2 I2C Master Port17 */ + {0x00, 0x11, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port18 */ + {0x00, 0x12, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port19 */ + {0x00, 0x13, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port20 */ + {0x00, 0x14, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port21 */ + {0x00, 0x15, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port22 */ + {0x00, 0x16, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port23 */ + {0x00, 0x17, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port24 */ + {0x00, 0x18, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port25 */ + {0x00, 0x19, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port26 */ + {0x00, 0x1a, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port27 */ + {0x00, 0x1b, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port28 */ + {0x00, 0x1c, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port29 */ + {0x00, 0x1d, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port30 */ + {0x00, 0x1e, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port31 */ + {0x00, 0x1f, CPLD3},/* 0x00 - 0x05 CPLD3 I2C Master Port32 */ + {0x00, 0x20, CPLD2},/* 0x00 - 0x05 CPLD3 I2C Master Port33 */ + {0x00, 0x21, CPLD2},/* 0x00 - 0x05 CPLD3 I2C Master Port34 */ +}; +#else +static const struct port_data port[PORT_NUM]= { + {0x0000, 0x00, CPLD2},/* 0x0000 - 0x0010 CPLD2 I2C Master Port1 */ + {0x0014, 0x00, CPLD2},/* 0x0014 - 0x0024 CPLD2 I2C Master Port2 */ + {0x0028, 0x00, CPLD2},/* 0x0028 - 0x0038 CPLD2 I2C Master Port3 */ + {0x003C, 0x00, CPLD2},/* 0x003c - 0x004c CPLD2 I2C Master Port4 */ + {0x0050, 0x00, CPLD2},/* 0x0050 - 0x0060 CPLD2 I2C Master Port5 */ + {0x0064, 0x00, CPLD2},/* 0x0064 - 0x0074 CPLD2 I2C Master Port6 */ + {0x0078, 0x00, CPLD2},/* 0x0078 - 0x0088 CPLD2 I2C Master Port7 */ + {0x008C, 0x00, CPLD2},/* 0x008c - 0x009c CPLD2 I2C Master Port8 */ + {0x00A0, 0x00, CPLD2},/* 0x00a0 - 0x00b0 CPLD2 I2C Master Port9 */ + {0x00B4, 0x00, CPLD2},/* 0x00b4 - 0x00c4 CPLD2 I2C Master Port10*/ + {0x00C8, 0x00, CPLD2},/* 0x00c8 - 0x00d8 CPLD2 I2C Master Port11 */ + {0x00DC, 0x00, CPLD2},/* 0x00dc - 0x00ec CPLD2 I2C Master Port12 */ + {0x00F0, 0x00, CPLD2},/* 0x00f0 - 0x0100 CPLD2 I2C Master Port13 */ + {0x0104, 0x00, CPLD2},/* 0x0104 - 0x0114 CPLD2 I2C Master Port14 */ + {0x0118, 0x00, CPLD2},/* 0x0118 - 0x0128 CPLD2 I2C Master Port15 */ + {0x012C, 0x00, CPLD2},/* 0x012c - 0x013c CPLD2 I2C Master Port16 */ + {0x0140, 0x00, CPLD3},/* 0x0140 - 0x0150 CPLD2 I2C Master Port17 */ + {0x0154, 0x00, CPLD3},/* 0x0154 - 0x0164 CPLD3 I2C Master Port18 */ + {0x0168, 0x00, CPLD3},/* 0x0168 - 0x0178 CPLD3 I2C Master Port19 */ + {0x017C, 0x00, CPLD3},/* 0x017c - 0x018c CPLD3 I2C Master Port20 */ + {0x0190, 0x00, CPLD3},/* 0x0190 - 0x01a0 CPLD3 I2C Master Port21 */ + {0x01A4, 0x00, CPLD3},/* 0x01a4 - 0x01b4 CPLD3 I2C Master Port22 */ + {0x01B8, 0x00, CPLD3},/* 0x01b8 - 0x01c8 CPLD3 I2C Master Port23 */ + {0x01CC, 0x00, CPLD3},/* 0x01cc - 0x01dc CPLD3 I2C Master Port24 */ + {0x01E0, 0x00, CPLD3},/* 0x01e0 - 0x01f0 CPLD3 I2C Master Port25 */ + {0x01F4, 0x00, CPLD3},/* 0x01f4 - 0x0204 CPLD3 I2C Master Port26 */ + {0x0208, 0x00, CPLD3},/* 0x0208 - 0x0218 CPLD3 I2C Master Port27 */ + {0x021C, 0x00, CPLD3},/* 0x021c - 0x022c CPLD3 I2C Master Port28 */ + {0x0230, 0x00, CPLD3},/* 0x0230 - 0x0240 CPLD3 I2C Master Port29 */ + {0x0244, 0x00, CPLD3},/* 0x0244 - 0x0254 CPLD3 I2C Master Port30 */ + {0x0258, 0x00, CPLD3},/* 0x0258 - 0x0268 CPLD3 I2C Master Port31 */ + {0x026C, 0x00, CPLD3},/* 0x026c - 0x027c CPLD3 I2C Master Port32 */ + {0x0280, 0x00, CPLD2},/* 0x0280 - 0x0290 CPLD3 I2C Master Port33 */ + {0x0294, 0x00, CPLD2},/* 0x0294 - 0x02a4 CPLD3 I2C Master Port34 */ +}; +#endif + +static struct ocores_i2c_platform_data as9737_32db_platform_data = { + .reg_io_width = 1, + .reg_shift = 2, + /* + * PRER_L and PRER_H are calculated based on clock_khz and bus_khz + * in i2c-ocores.c:ocores_init. + */ +#if 1 + /* SCL 100KHZ in FPGA spec. => PRER_L = 0x6D, PRER_H = 0x00 */ + .clock_khz = 55000, + .bus_khz = 100, +#else + /* SCL 400KHZ in FPGA spec. => PRER_L = 0x6D, PRER_H = 0x00 */ + .clock_khz = 220000, + .bus_khz = 400, +#endif +}; + +struct platform_device *ocore_i2c_device_add(unsigned int id, unsigned long bar_base, + const struct port_data port) +{ + struct platform_device *pdev; + int err; + struct resource res[] = { + DEFINE_RES_MEM_NAMED(bar_base + port.offset, 0x14, "mem_map"), +#ifdef HAS_CHANNEL_REG + DEFINE_RES_REG_NAMED(port.channel, 0x01, "channel"), +#endif + }; + + pdev = platform_device_alloc(OCORES_I2C_DRVNAME, id); + if (!pdev) { + err = -ENOMEM; + pcie_err("Port%u device allocation failed (%d)\n", (id & 0xFF) + 1, err); + goto exit; + } + + err = platform_device_add_resources(pdev, res, ARRAY_SIZE(res)); + if (err) { + pcie_err("Port%u device resource addition failed (%d)\n", (id & 0xFF) + 1, err); + goto exit_device_put; + } + + err = platform_device_add_data(pdev, &as9737_32db_platform_data, + sizeof(struct ocores_i2c_platform_data)); + if (err) { + pcie_err("Port%u platform data allocation failed (%d)\n", (id & 0xFF) + 1, err); + goto exit_device_put; + } + + err = platform_device_add(pdev); + if (err) { + pcie_err("Port%u device addition failed (%d)\n", (id & 0xFF) + 1, err); + goto exit_device_put; + } + + return pdev; + +exit_device_put: + platform_device_put(pdev); +exit: + return NULL; +} + +static int as9737_32db_pcie_fpga_i2c_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + pci_fpga_device_t *fpga_dev; + struct pci_dev *pcidev; + int i; + int status = 0, err = 0; + unsigned long bar_base; + + fpga_dev = devm_kzalloc(dev, sizeof(pci_fpga_device_t), GFP_KERNEL); + if (!fpga_dev) { + return -ENOMEM; + } + platform_set_drvdata(pdev, fpga_dev); + + pcidev = pci_get_device(FPGA_PCI_VENDOR_ID, FPGA_PCI_DEVICE_ID, NULL); + if (!pcidev) { + dev_err(dev, "Cannot found PCI device(%x:%x)\n", + FPGA_PCI_VENDOR_ID, FPGA_PCI_DEVICE_ID); + return -ENODEV; + } + fpga_dev->pci_dev = pcidev; + + err = pci_enable_device(pcidev); + if (err != 0) { + dev_err(dev, "Cannot enable PCI device(%x:%x)\n", + FPGA_PCI_VENDOR_ID, FPGA_PCI_DEVICE_ID); + status = -ENODEV; + goto exit_pci_disable; + } + /* enable PCI bus-mastering */ + pci_set_master(pcidev); + + /* Create I2C ocore devices first, then create the FPGA sysfs. + * To prevent the application from accessing an ocore device + * that has not been fully created due to the port status + * being present. + */ + + /* + * Create ocore_i2c device for QSFP-DD EEPROM + */ + bar_base = pci_resource_start(pcidev, BAR0_NUM); + for (i = 0; i < PORT_NUM; i++) { + fpga_dev->fpga_i2c[i] = + ocore_i2c_device_add(i + 1, bar_base, port[i]); + if (IS_ERR(fpga_dev->fpga_i2c[i])) { + status = PTR_ERR(fpga_dev->fpga_i2c[i]); + dev_err(dev, "rc:%d, unload Port%u[0x%ux] device\n", + status, i + 1, port[i].offset); + goto exit_ocores_device; + } + } + + return 0; + +exit_ocores_device: + while (i > 0) { + i--; + platform_device_unregister(fpga_dev->fpga_i2c[i]); + } + +exit_pci_disable: + pci_disable_device(fpga_dev->pci_dev); + + return status; +} + +static int as9737_32db_pcie_fpga_i2c_remove(struct platform_device *pdev) +{ + pci_fpga_device_t *fpga_dev = platform_get_drvdata(pdev); + + if (pci_is_enabled(fpga_dev->pci_dev)) { + int i; + + /* Unregister ocore_i2c device */ + for (i = 0; i < PORT_NUM; i++) { + platform_device_unregister(fpga_dev->fpga_i2c[i]); + } + pci_disable_device(fpga_dev->pci_dev); + } + + return 0; +} + +static struct platform_driver pcie_fpga_i2c_driver = { + .probe = as9737_32db_pcie_fpga_i2c_probe, + .remove = as9737_32db_pcie_fpga_i2c_remove, + .driver = { + .owner = THIS_MODULE, + .name = DRVNAME, + }, +}; + +static int __init as9737_32db_pcie_fpga_i2c_init(void) +{ + int status = 0; + + /* + * Create FPGA I2C platform driver and device + */ + status = platform_driver_register(&pcie_fpga_i2c_driver); + if (status < 0) { + return status; + } + + pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(pdev)) { + status = PTR_ERR(pdev); + goto exit_pci; + } + + return status; + +exit_pci: + platform_driver_unregister(&pcie_fpga_i2c_driver); + + return status; +} + +static void __exit as9737_32db_pcie_fpga_i2c_exit(void) +{ + platform_device_unregister(pdev); + platform_driver_unregister(&pcie_fpga_i2c_driver); +} + + +module_init(as9737_32db_pcie_fpga_i2c_init); +module_exit(as9737_32db_pcie_fpga_i2c_exit); + +MODULE_AUTHOR("Roger Ho "); +MODULE_DESCRIPTION("AS9737-32DB FPGA I2C driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_leds.c b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_leds.c new file mode 100644 index 0000000000..3e7bb976c0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_leds.c @@ -0,0 +1,561 @@ +/* + * Copyright (C) Roger Ho + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as9737_32db_led" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_LED_READ_CMD 0x1A +#define IPMI_LED_WRITE_CMD 0x1B +#define IPMI_TIMEOUT (5 * HZ) +#define IPMI_ERR_RETRY_TIMES 1 + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static ssize_t set_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_led(struct device *dev, struct device_attribute *attr, + char *buf); +static int as9737_32db_led_probe(struct platform_device *pdev); +static int as9737_32db_led_remove(struct platform_device *pdev); + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + struct ipmi_user * user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct as9737_32db_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned char ipmi_resp[6]; /* 0:Loc 1:Diag 2:Gnss 3:Fan 4:Psu1 5:Psu2 */ + struct ipmi_data ipmi; +}; + +struct as9737_32db_led_data *data = NULL; + +static struct platform_driver as9737_32db_led_driver = { + .probe = as9737_32db_led_probe, + .remove = as9737_32db_led_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +enum ipmi_led_light_mode { + IPMI_LED_MODE_OFF, + IPMI_LED_MODE_RED = 2, + IPMI_LED_MODE_RED_BLINKING = 3, + IPMI_LED_MODE_GREEN = 4, + IPMI_LED_MODE_GREEN_BLINKING = 5, + IPMI_LED_MODE_YELLOW = 6, + IPMI_LED_MODE_YELLOW_BLINKING = 7, + IPMI_LED_MODE_BLUE = 8, + IPMI_LED_MODE_BLUE_BLINKING = 9, + IPMI_LED_MODE_CYAN = 0xC, + IPMI_LED_MODE_WHITE = 0xE, + IPMI_LED_MODE_AMBER = 0x10, + IPMI_LED_MODE_ORANGE = 0x20, +}; + +enum led_light_mode { + LED_MODE_OFF, + LED_MODE_RED = 10, + LED_MODE_RED_BLINKING = 11, + LED_MODE_ORANGE = 12, + LED_MODE_ORANGE_BLINKING = 13, + LED_MODE_YELLOW = 14, + LED_MODE_YELLOW_BLINKING = 15, + LED_MODE_GREEN = 16, + LED_MODE_GREEN_BLINKING = 17, + LED_MODE_BLUE = 18, + LED_MODE_BLUE_BLINKING = 19, + LED_MODE_PURPLE = 20, + LED_MODE_PURPLE_BLINKING = 21, + LED_MODE_AUTO = 22, + LED_MODE_AUTO_BLINKING = 23, + LED_MODE_WHITE = 24, + LED_MODE_WHITE_BLINKING = 25, + LED_MODE_CYAN = 26, + LED_MODE_CYAN_BLINKING = 27, + LED_MODE_UNKNOWN = 99 +}; + +enum as9737_32db_led_sysfs_attrs { + LED_LOC, + LED_DIAG, + LED_FAN, + LED_PSU1, + LED_PSU2 +}; + +static SENSOR_DEVICE_ATTR(led_loc, S_IWUSR | S_IRUGO, show_led, set_led, + LED_LOC); +static SENSOR_DEVICE_ATTR(led_diag, S_IWUSR | S_IRUGO, show_led, set_led, + LED_DIAG); +static SENSOR_DEVICE_ATTR(led_fan, S_IWUSR | S_IRUGO, show_led, set_led, + LED_FAN); +static SENSOR_DEVICE_ATTR(led_psu1, S_IWUSR | S_IRUGO, show_led, set_led, + LED_PSU1); +static SENSOR_DEVICE_ATTR(led_psu2, S_IWUSR | S_IRUGO, show_led, set_led, + LED_PSU2); + +static struct attribute *as9737_32db_led_attributes[] = { + &sensor_dev_attr_led_loc.dev_attr.attr, + &sensor_dev_attr_led_diag.dev_attr.attr, + &sensor_dev_attr_led_fan.dev_attr.attr, + &sensor_dev_attr_led_psu1.dev_attr.attr, + &sensor_dev_attr_led_psu2.dev_attr.attr, + NULL +}; + +static const struct attribute_group as9737_32db_led_group = { + .attrs = as9737_32db_led_attributes, +}; + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Send an IPMI command with retry */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int status = 0, retry = 0; + + char *cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); + + int i = 0; + char raw_cmd[20] = ""; + sprintf(raw_cmd, "0x%02x", cmd); + if(tx_len) + { + for( i=0; i < tx_len; i++) { + sprintf(raw_cmd + strlen(raw_cmd), " 0x%02x", tx_data[i]); + } + } + + for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { + status = _ipmi_send_message(ipmi, cmd, tx_data, tx_len, rx_data, rx_len); + if (unlikely(status != 0)) { + dev_err(&data->pdev->dev, "ipmi_send_message_%d err status(%d)[%s] raw_cmd=[%s]\r\n", + retry, status, cmdline ? cmdline : "", raw_cmd); + continue; + } + + if (unlikely(ipmi->rx_result != 0)) { + dev_err(&data->pdev->dev, "ipmi_send_message_%d err result(%d)[%s] raw_cmd=[%s]\r\n", + retry, ipmi->rx_result, cmdline ? cmdline : "", raw_cmd); + continue; + } + + break; + } + + if (cmdline) kfree(cmdline); + return status; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static struct as9737_32db_led_data *as9737_32db_led_update_device(void) +{ + int status = 0; + + if (time_before(jiffies, data->last_updated + HZ * 5) && data->valid) { + return data; + } + + data->valid = 0; + status = ipmi_send_message(&data->ipmi, IPMI_LED_READ_CMD, NULL, 0, + data->ipmi_resp, sizeof(data->ipmi_resp)); + if (unlikely(status != 0)) { + goto exit; + } + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + +exit: + return data; +} + +static ssize_t show_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int value = 0; + int error = 0; + + mutex_lock(&data->update_lock); + + data = as9737_32db_led_update_device(); + if (!data->valid) { + error = -EIO; + goto exit; + } + + switch (data->ipmi_resp[attr->index]) { + case IPMI_LED_MODE_OFF: + value = LED_MODE_OFF; + break; + case IPMI_LED_MODE_RED: + value = LED_MODE_RED; + break; + case IPMI_LED_MODE_RED_BLINKING: + value = LED_MODE_RED_BLINKING; + break; + case IPMI_LED_MODE_GREEN: + value = LED_MODE_GREEN; + break; + case IPMI_LED_MODE_GREEN_BLINKING: + value = LED_MODE_GREEN_BLINKING; + break; + case IPMI_LED_MODE_BLUE: + value = LED_MODE_BLUE; + break; + case IPMI_LED_MODE_BLUE_BLINKING: + value = LED_MODE_BLUE_BLINKING; + break; + case IPMI_LED_MODE_CYAN: + value = LED_MODE_CYAN; + break; + case IPMI_LED_MODE_WHITE: + value = LED_MODE_WHITE; + break; + case IPMI_LED_MODE_AMBER: + value = IPMI_LED_MODE_AMBER; + break; + case IPMI_LED_MODE_ORANGE: + value = LED_MODE_ORANGE; + break; + case IPMI_LED_MODE_YELLOW: + value = LED_MODE_YELLOW; + break; + case IPMI_LED_MODE_YELLOW_BLINKING: + value = LED_MODE_YELLOW_BLINKING; + break; + default: + error = -EINVAL; + goto exit; + } + + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", value); + +exit: + mutex_unlock(&data->update_lock); + return error; +} + +static ssize_t set_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long mode; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = kstrtol(buf, 10, &mode); + if (status) + return status; + + mutex_lock(&data->update_lock); + + data = as9737_32db_led_update_device(); + if (!data->valid) { + status = -EIO; + goto exit; + } + + data->ipmi_resp[0] = attr->index + 1; + + switch (mode) { + case LED_MODE_OFF: + data->ipmi_resp[1] = IPMI_LED_MODE_OFF; + break; + case LED_MODE_RED: + data->ipmi_resp[1] = IPMI_LED_MODE_RED; + break; + case LED_MODE_RED_BLINKING: + data->ipmi_resp[1] = IPMI_LED_MODE_RED_BLINKING; + break; + case LED_MODE_GREEN: + data->ipmi_resp[1] = IPMI_LED_MODE_GREEN; + break; + case LED_MODE_GREEN_BLINKING: + data->ipmi_resp[1] = IPMI_LED_MODE_GREEN_BLINKING; + break; + case LED_MODE_BLUE: + data->ipmi_resp[1] = IPMI_LED_MODE_BLUE; + break; + case LED_MODE_BLUE_BLINKING: + data->ipmi_resp[1] = IPMI_LED_MODE_BLUE_BLINKING; + break; + case LED_MODE_CYAN: + data->ipmi_resp[1] = IPMI_LED_MODE_CYAN; + break; + case LED_MODE_WHITE: + data->ipmi_resp[1] = IPMI_LED_MODE_WHITE; + break; + case LED_MODE_YELLOW: + data->ipmi_resp[1] = IPMI_LED_MODE_YELLOW; + break; + case LED_MODE_YELLOW_BLINKING: + data->ipmi_resp[1] = IPMI_LED_MODE_YELLOW_BLINKING; + break; + case LED_MODE_ORANGE: + data->ipmi_resp[1] = IPMI_LED_MODE_ORANGE; + break; + default: + status = -EINVAL; + goto exit; + } + + /* Send IPMI write command */ + status = ipmi_send_message(&data->ipmi, IPMI_LED_WRITE_CMD, + data->ipmi_resp, 2, NULL, 0); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + status = count; + data->valid = 0; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static int as9737_32db_led_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &as9737_32db_led_group); + if (status) + goto exit; + + dev_info(&pdev->dev, "device created\n"); + + return 0; + +exit: + return status; +} + +static int as9737_32db_led_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &as9737_32db_led_group); + + return 0; +} + +static int __init as9737_32db_led_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as9737_32db_led_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + data->valid = 0; + + ret = platform_driver_register(&as9737_32db_led_driver); + if (ret < 0) + goto dri_reg_err; + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) + goto ipmi_err; + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as9737_32db_led_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as9737_32db_led_exit(void) +{ + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + platform_driver_unregister(&as9737_32db_led_driver); + kfree(data); +} + +MODULE_AUTHOR("Roger Ho "); +MODULE_DESCRIPTION("as9737_32db_led driver"); +MODULE_LICENSE("GPL"); + +module_init(as9737_32db_led_init); +module_exit(as9737_32db_led_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_mux.c b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_mux.c new file mode 100644 index 0000000000..728001cb14 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_mux.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as456x CPLD1/CPLD2/CPLD3 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as9737_32db_mux" + +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +#define AS9737_MUX_NCHANS 7 +#define AS9737_MUX_SELECT_REG 0x0 +#define AS9737_MUX_DESELECT_VAL 0x3 + +enum mux_type { + as9737_32db_mux +}; + +struct chip_desc { + u8 nchans; + u8 select_reg; + u8 deselect_val; +}; + +struct as9737_32db_mux_data { + enum mux_type type; + struct mutex update_lock; + struct i2c_client *client; +}; + +/* Provide specs for the as456x CPLD types we know about */ +static const struct chip_desc chips[] = { + [as9737_32db_mux] = { + .nchans = AS9737_MUX_NCHANS, + .select_reg = AS9737_MUX_SELECT_REG, + .deselect_val = AS9737_MUX_DESELECT_VAL + } +}; + +static const struct i2c_device_id as9737_32db_mux_id[] = { + { "as9737_32db_mux", as9737_32db_mux }, + { } +}; +MODULE_DEVICE_TABLE(i2c, as9737_32db_mux_id); + +static const struct of_device_id as9737_32db_mux_of_match[] = { + { .compatible = "edgecore,as9737_32db_mux", .data = &chips[as9737_32db_mux] }, + {} +}; +MODULE_DEVICE_TABLE(of, as9737_32db_mux_of_match); + +/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() + for this as they will try to lock adapter a second time */ +static int as9737_32db_mux_write(struct i2c_adapter *adap, + struct i2c_client *client, u8 reg, u8 val) +{ + union i2c_smbus_data data; + + data.byte = val; + return __i2c_smbus_xfer(adap, client->addr, client->flags, + I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &data); +} + +static int as9737_32db_mux_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct as9737_32db_mux_data *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret = 0; + + mutex_lock(&data->update_lock); + switch (data->type) { + case as9737_32db_mux: + ret = as9737_32db_mux_write(muxc->parent, client, + chips[data->type].select_reg, chan & 0x7); + break; + default: + break; + } + + mutex_unlock(&data->update_lock); + return ret; +} + +static int as9737_32db_mux_deselect_mux(struct i2c_mux_core *muxc, u32 chan) +{ + struct as9737_32db_mux_data *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret = 0; + + mutex_lock(&data->update_lock); + ret = as9737_32db_mux_write(muxc->parent, client, + chips[data->type].select_reg, chips[data->type].deselect_val); + mutex_unlock(&data->update_lock); + return ret; +} + +static void as9737_32db_mux_cleanup(struct i2c_mux_core *muxc) +{ + i2c_mux_del_adapters(muxc); +} + +/* + * I2C init/probing/exit functions + */ +static int as9737_32db_mux_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + struct device *dev = &client->dev; + struct as9737_32db_mux_data *data; + struct i2c_mux_core *muxc; + int ret = -ENODEV; + int i = 0; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + + muxc = i2c_mux_alloc(adap, dev, AS9737_MUX_NCHANS, sizeof(*data), 0, + as9737_32db_mux_select_chan, as9737_32db_mux_deselect_mux); + if (!muxc) + return -ENOMEM; + + data = i2c_mux_priv(muxc); + mutex_init(&data->update_lock); + data->type = id->driver_data; + data->client = client; + i2c_set_clientdata(client, muxc); + + /* Now create an adapter for each channel */ + for (i = 0; i < chips[data->type].nchans; i++) { + ret = i2c_mux_add_adapter(muxc, 0, i, 0); + if (ret) + goto exit_mux; + } + + return 0; + +exit_mux: + as9737_32db_mux_cleanup(muxc); + return ret; +} + +static int as9737_32db_mux_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + as9737_32db_mux_cleanup(muxc); + return 0; +} + +static struct i2c_driver as9737_32db_mux_driver = { + .driver = { + .name = "as9737_32db_mux", + .owner = THIS_MODULE, + }, + .probe = as9737_32db_mux_probe, + .remove = as9737_32db_mux_remove, + .id_table = as9737_32db_mux_id, +}; + +module_i2c_driver(as9737_32db_mux_driver); + +MODULE_AUTHOR("Roger Ho "); +MODULE_DESCRIPTION("as9737_32db_mux driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_psu.c b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_psu.c new file mode 100644 index 0000000000..b5f8dd009c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_psu.c @@ -0,0 +1,1084 @@ +/* + * Copyright (C) Roger Ho + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as9737_32db_psu" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_PSU_READ_CMD 0x16 +#define IPMI_PSU_MODEL_NAME_CMD 0x10 +#define IPMI_PSU_SERIAL_NUM_CMD 0x11 +#define IPMI_PSU_FAN_DIR_CMD 0x13 +#define IPMI_PSU_INFO_CMD 0x20 +#define IPMI_TIMEOUT (5 * HZ) +#define IPMI_ERR_RETRY_TIMES 1 +#define IPMI_MODEL_SERIAL_LEN 32 +#define IPMI_FAN_DIR_LEN 3 + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static ssize_t show_psu(struct device *dev, struct device_attribute *attr, + char *buf); +static ssize_t show_psu_info(struct device *dev, struct device_attribute *attr, + char *buf); +static ssize_t show_string(struct device *dev, struct device_attribute *attr, + char *buf); +static int as9737_32db_psu_probe(struct platform_device *pdev); +static int as9737_32db_psu_remove(struct platform_device *pdev); + +enum psu_id { + PSU_1, + PSU_2, + NUM_OF_PSU +}; + +enum psu_data_index { + PSU_PRESENT = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD_CPLD, + PSU_POWER_GOOD_PMBUS, + PSU_OVER_VOLTAGE, + PSU_OVER_CURRENT, + PSU_POWER_ON, + PSU_VIN0, + PSU_VIN1, + PSU_VIN2, + PSU_VOUT0, + PSU_VOUT1, + PSU_VOUT2, + PSU_IIN0, + PSU_IIN1, + PSU_IIN2, + PSU_IOUT0, + PSU_IOUT1, + PSU_IOUT2, + PSU_PIN0, + PSU_PIN1, + PSU_PIN2, + PSU_PIN3, + PSU_POUT0, + PSU_POUT1, + PSU_POUT2, + PSU_POUT3, + PSU_TEMP1_0, + PSU_TEMP1_1, + PSU_TEMP2_0, + PSU_TEMP2_1, + PSU_TEMP3_0, + PSU_TEMP3_1, + PSU_FAN0, + PSU_FAN1, + PSU_VOUT_MODE, + PSU_STATUS_COUNT, + PSU_MODEL = 0, + PSU_SERIAL = 0, + PSU_TEMP1_MAX0 = 2, + PSU_TEMP1_MAX1, + PSU_TEMP1_MIN0, + PSU_TEMP1_MIN1, + PSU_TEMP2_MAX0, + PSU_TEMP2_MAX1, + PSU_TEMP2_MIN0, + PSU_TEMP2_MIN1, + PSU_TEMP3_MAX0, + PSU_TEMP3_MAX1, + PSU_TEMP3_MIN0, + PSU_TEMP3_MIN1, + PSU_VIN_UPPER_CRIT0, + PSU_VIN_UPPER_CRIT1, + PSU_VIN_UPPER_CRIT2, + PSU_VIN_MAX0, + PSU_VIN_MAX1, + PSU_VIN_MAX2, + PSU_VIN_MIN0, + PSU_VIN_MIN1, + PSU_VIN_MIN2, + PSU_VIN_LOWER_CRIT0, + PSU_VIN_LOWER_CRIT1, + PSU_VIN_LOWER_CRIT2, + PSU_VOUT_MAX0, + PSU_VOUT_MAX1, + PSU_VOUT_MAX2, + PSU_VOUT_MIN0, + PSU_VOUT_MIN1, + PSU_VOUT_MIN2, + PSU_IIN_MAX0, + PSU_IIN_MAX1, + PSU_IIN_MAX2, + PSU_IOUT_MAX0, + PSU_IOUT_MAX1, + PSU_IOUT_MAX2, + PSU_PIN_MAX0, + PSU_PIN_MAX1, + PSU_PIN_MAX2, + PSU_PIN_MAX3, + PSU_POUT_MAX0, + PSU_POUT_MAX1, + PSU_POUT_MAX2, + PSU_POUT_MAX3, + PSU_INFO_COUNT +}; + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + struct ipmi_user * user; + int interface; + int pid; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct ipmi_psu_resp_data { + unsigned char status[PSU_STATUS_COUNT]; + unsigned char info[PSU_INFO_COUNT]; + char serial[IPMI_MODEL_SERIAL_LEN+1]; + char model[IPMI_MODEL_SERIAL_LEN+1]; + char fandir[IPMI_FAN_DIR_LEN+1]; +}; + +struct as9737_32db_psu_data { + struct platform_device *pdev[2]; + struct device *hwmon_dev[2]; + struct mutex update_lock; + char valid[2]; /* != 0 if registers are valid, 0: PSU1, 1: PSU2 */ + unsigned long last_updated[2]; /* In jiffies, 0: PSU1, 1: PSU2 */ + struct ipmi_data ipmi; + struct ipmi_psu_resp_data ipmi_resp[2]; /* 0: PSU1, 1: PSU2 */ + unsigned char ipmi_tx_data[2]; +}; + +struct as9737_32db_psu_data *data = NULL; + +static struct platform_driver as9737_32db_psu_driver = { + .probe = as9737_32db_psu_probe, + .remove = as9737_32db_psu_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +#define PSU_PRESENT_ATTR_ID(index) PSU##index##_PRESENT +#define PSU_POWERGOOD_ATTR_ID(index) PSU##index##_POWER_GOOD +#define PSU_VIN_ATTR_ID(index) PSU##index##_VIN +#define PSU_VOUT_ATTR_ID(index) PSU##index##_VOUT +#define PSU_IIN_ATTR_ID(index) PSU##index##_IIN +#define PSU_IOUT_ATTR_ID(index) PSU##index##_IOUT +#define PSU_PIN_ATTR_ID(index) PSU##index##_PIN +#define PSU_POUT_ATTR_ID(index) PSU##index##_POUT +#define PSU_MODEL_ATTR_ID(index) PSU##index##_MODEL +#define PSU_SERIAL_ATTR_ID(index) PSU##index##_SERIAL +#define PSU_TEMP1_INPUT_ATTR_ID(index) PSU##index##_TEMP1_INPUT +#define PSU_TEMP2_INPUT_ATTR_ID(index) PSU##index##_TEMP2_INPUT +#define PSU_TEMP3_INPUT_ATTR_ID(index) PSU##index##_TEMP3_INPUT +#define PSU_FAN_INPUT_ATTR_ID(index) PSU##index##_FAN_INPUT +#define PSU_FAN_DIR_ATTR_ID(index) PSU##index##_FAN_DIR + +#define PSU_TEMP1_INPUT_MAX_ATTR_ID(index) PSU##index##_TEMP1_INPUT_MAX +#define PSU_TEMP1_INPUT_MIN_ATTR_ID(index) PSU##index##_TEMP1_INPUT_MIN +#define PSU_TEMP2_INPUT_MAX_ATTR_ID(index) PSU##index##_TEMP2_INPUT_MAX +#define PSU_TEMP2_INPUT_MIN_ATTR_ID(index) PSU##index##_TEMP2_INPUT_MIN +#define PSU_TEMP3_INPUT_MAX_ATTR_ID(index) PSU##index##_TEMP3_INPUT_MAX +#define PSU_TEMP3_INPUT_MIN_ATTR_ID(index) PSU##index##_TEMP3_INPUT_MIN +#define PSU_VIN_MAX_ATTR_ID(index) PSU##index##_VIN_MAX +#define PSU_VIN_MIN_ATTR_ID(index) PSU##index##_VIN_MIN +#define PSU_VIN_UPPER_CRIT_ATTR_ID(index) PSU##index##_VIN_UPPER_CRIT +#define PSU_VIN_LOWER_CRIT_ATTR_ID(index) PSU##index##_VIN_LOWER_CRIT +#define PSU_VOUT_MAX_ATTR_ID(index) PSU##index##_VOUT_MAX +#define PSU_VOUT_MIN_ATTR_ID(index) PSU##index##_VOUT_MIN +#define PSU_IIN_MAX_ATTR_ID(index) PSU##index##_IIN_MAX +#define PSU_IOUT_MAX_ATTR_ID(index) PSU##index##_IOUT_MAX +#define PSU_PIN_MAX_ATTR_ID(index) PSU##index##_PIN_MAX +#define PSU_POUT_MAX_ATTR_ID(index) PSU##index##_POUT_MAX + +#define PSU_ATTR(psu_id) \ + PSU_PRESENT_ATTR_ID(psu_id), \ + PSU_POWERGOOD_ATTR_ID(psu_id), \ + PSU_VIN_ATTR_ID(psu_id), \ + PSU_VOUT_ATTR_ID(psu_id), \ + PSU_IIN_ATTR_ID(psu_id), \ + PSU_IOUT_ATTR_ID(psu_id), \ + PSU_PIN_ATTR_ID(psu_id), \ + PSU_POUT_ATTR_ID(psu_id), \ + PSU_MODEL_ATTR_ID(psu_id), \ + PSU_SERIAL_ATTR_ID(psu_id), \ + PSU_TEMP1_INPUT_ATTR_ID(psu_id), \ + PSU_TEMP2_INPUT_ATTR_ID(psu_id), \ + PSU_TEMP3_INPUT_ATTR_ID(psu_id), \ + PSU_FAN_INPUT_ATTR_ID(psu_id), \ + PSU_FAN_DIR_ATTR_ID(psu_id), \ + PSU_TEMP1_INPUT_MAX_ATTR_ID(psu_id), \ + PSU_TEMP1_INPUT_MIN_ATTR_ID(psu_id), \ + PSU_TEMP2_INPUT_MAX_ATTR_ID(psu_id), \ + PSU_TEMP2_INPUT_MIN_ATTR_ID(psu_id), \ + PSU_TEMP3_INPUT_MAX_ATTR_ID(psu_id), \ + PSU_TEMP3_INPUT_MIN_ATTR_ID(psu_id), \ + PSU_VIN_MAX_ATTR_ID(psu_id), \ + PSU_VIN_MIN_ATTR_ID(psu_id), \ + PSU_VIN_UPPER_CRIT_ATTR_ID(psu_id), \ + PSU_VIN_LOWER_CRIT_ATTR_ID(psu_id), \ + PSU_VOUT_MAX_ATTR_ID(psu_id), \ + PSU_VOUT_MIN_ATTR_ID(psu_id), \ + PSU_IIN_MAX_ATTR_ID(psu_id), \ + PSU_IOUT_MAX_ATTR_ID(psu_id), \ + PSU_PIN_MAX_ATTR_ID(psu_id), \ + PSU_POUT_MAX_ATTR_ID(psu_id) + +enum as9737_32db_psu_sysfs_attrs { + /* psu attributes */ + PSU_ATTR(1), + PSU_ATTR(2), + NUM_OF_PSU_ATTR, + NUM_OF_PER_PSU_ATTR = (NUM_OF_PSU_ATTR/NUM_OF_PSU) +}; + +/* psu attributes */ +#define DECLARE_PSU_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(psu##index##_present, S_IRUGO, show_psu, NULL, \ + PSU##index##_PRESENT); \ + static SENSOR_DEVICE_ATTR(psu##index##_power_good, S_IRUGO, show_psu, NULL,\ + PSU##index##_POWER_GOOD); \ + static SENSOR_DEVICE_ATTR(psu##index##_vin, S_IRUGO, show_psu, NULL, \ + PSU##index##_VIN); \ + static SENSOR_DEVICE_ATTR(psu##index##_vout, S_IRUGO, show_psu, NULL, \ + PSU##index##_VOUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_iin, S_IRUGO, show_psu, NULL, \ + PSU##index##_IIN); \ + static SENSOR_DEVICE_ATTR(psu##index##_iout, S_IRUGO, show_psu, NULL, \ + PSU##index##_IOUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_pin, S_IRUGO, show_psu, NULL, \ + PSU##index##_PIN); \ + static SENSOR_DEVICE_ATTR(psu##index##_pout, S_IRUGO, show_psu, NULL, \ + PSU##index##_POUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_model, S_IRUGO, show_string, NULL, \ + PSU##index##_MODEL); \ + static SENSOR_DEVICE_ATTR(psu##index##_serial, S_IRUGO, show_string, NULL,\ + PSU##index##_SERIAL);\ + static SENSOR_DEVICE_ATTR(psu##index##_temp1_input, S_IRUGO, show_psu,NULL,\ + PSU##index##_TEMP1_INPUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_temp2_input, S_IRUGO, show_psu,NULL,\ + PSU##index##_TEMP2_INPUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_temp3_input, S_IRUGO, show_psu,NULL,\ + PSU##index##_TEMP3_INPUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_fan1_input, S_IRUGO, show_psu, NULL,\ + PSU##index##_FAN_INPUT); \ + static SENSOR_DEVICE_ATTR(psu##index##_fan_dir, S_IRUGO, show_string, NULL,\ + PSU##index##_FAN_DIR); \ + static SENSOR_DEVICE_ATTR(psu##index##_temp1_input_max, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_TEMP1_INPUT_MAX); \ + static SENSOR_DEVICE_ATTR(psu##index##_temp1_input_min, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_TEMP1_INPUT_MIN); \ + static SENSOR_DEVICE_ATTR(psu##index##_temp2_input_max, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_TEMP2_INPUT_MAX); \ + static SENSOR_DEVICE_ATTR(psu##index##_temp2_input_min, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_TEMP2_INPUT_MIN); \ + static SENSOR_DEVICE_ATTR(psu##index##_temp3_input_max, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_TEMP3_INPUT_MAX); \ + static SENSOR_DEVICE_ATTR(psu##index##_temp3_input_min, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_TEMP3_INPUT_MIN); \ + static SENSOR_DEVICE_ATTR(psu##index##_vin_max, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_VIN_MAX); \ + static SENSOR_DEVICE_ATTR(psu##index##_vin_min, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_VIN_MIN); \ + static SENSOR_DEVICE_ATTR(psu##index##_vin_upper_crit, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_VIN_UPPER_CRIT); \ + static SENSOR_DEVICE_ATTR(psu##index##_vin_lower_crit, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_VIN_LOWER_CRIT); \ + static SENSOR_DEVICE_ATTR(psu##index##_vout_max, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_VOUT_MAX); \ + static SENSOR_DEVICE_ATTR(psu##index##_vout_min, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_VOUT_MIN); \ + static SENSOR_DEVICE_ATTR(psu##index##_iin_max, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_IIN_MAX); \ + static SENSOR_DEVICE_ATTR(psu##index##_iout_max, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_IOUT_MAX); \ + static SENSOR_DEVICE_ATTR(psu##index##_pin_max, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_PIN_MAX); \ + static SENSOR_DEVICE_ATTR(psu##index##_pout_max, S_IRUGO, \ + show_psu_info, NULL, PSU##index##_POUT_MAX) + +#define DECLARE_PSU_ATTR(index) \ + &sensor_dev_attr_psu##index##_present.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_power_good.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_vin.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_vout.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_iin.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_iout.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_pin.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_pout.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_model.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_serial.dev_attr.attr,\ + &sensor_dev_attr_psu##index##_temp1_input.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_temp2_input.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_temp3_input.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_fan1_input.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_fan_dir.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_temp1_input_max.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_temp1_input_min.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_temp2_input_max.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_temp2_input_min.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_temp3_input_max.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_temp3_input_min.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_vin_max.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_vin_min.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_vin_upper_crit.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_vin_lower_crit.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_vout_max.dev_attr.attr,\ + &sensor_dev_attr_psu##index##_vout_min.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_iin_max.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_iout_max.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_pin_max.dev_attr.attr, \ + &sensor_dev_attr_psu##index##_pout_max.dev_attr.attr + +DECLARE_PSU_SENSOR_DEVICE_ATTR(1); +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_psu, NULL, PSU1_VOUT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, show_psu, NULL, PSU1_IOUT); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_psu, NULL, PSU1_POUT); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_psu, NULL, PSU1_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_psu, NULL, PSU1_FAN_INPUT); + +static struct attribute *as9737_32db_psu1_attrs[] = { + /* psu attributes */ + DECLARE_PSU_ATTR(1), + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + NULL +}; +static struct attribute_group as9737_32db_psu1_group = { + .attrs = as9737_32db_psu1_attrs, +}; +/* ATTRIBUTE_GROUPS(as9737_32db_psu1); */ + +DECLARE_PSU_SENSOR_DEVICE_ATTR(2); +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_psu, NULL, PSU2_VOUT); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_psu, NULL, PSU2_IOUT); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_psu, NULL, PSU2_POUT); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_psu, NULL, PSU2_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_psu, NULL, PSU2_FAN_INPUT); +static struct attribute *as9737_32db_psu2_attrs[] = { + /* psu attributes */ + DECLARE_PSU_ATTR(2), + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + NULL +}; +static struct attribute_group as9737_32db_psu2_group = { + .attrs = as9737_32db_psu2_attrs, +}; +/* ATTRIBUTE_GROUPS(as9737_32db_psu2); */ + +const struct attribute_group *as9737_32db_psu_groups[][2] = { + {&as9737_32db_psu1_group, NULL}, + {&as9737_32db_psu2_group, NULL} +}; + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev, int pid) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + ipmi->pid = dev->id; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len, unsigned char pid) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev[pid]->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev[pid]->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev[pid]->dev, "validate_addr=%x\n", err); + return err; +} + +/* Send an IPMI command with retry */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int status = 0, retry = 0; + int pid = 0; + struct device *dev; + char *cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); + + int i = 0; + char raw_cmd[20] = ""; + sprintf(raw_cmd, "0x%02x", cmd); + if(tx_len) + { + for( i=0; i < tx_len; i++) { + sprintf(raw_cmd + strlen(raw_cmd), " 0x%02x", tx_data[i]); + } + } + + /* Get PSU device index */ + pid = (tx_data != NULL) ? tx_data[0] - 1 : 0; + + dev = &data->pdev[pid]->dev; + + for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { + status = _ipmi_send_message(ipmi, cmd, tx_data, tx_len, rx_data, rx_len, pid); + if (unlikely(status != 0)) { + dev_err(dev, "ipmi_send_message_%d err status(%d)[%s] raw_cmd=[%s]\r\n", + retry, status, cmdline ? cmdline : "", raw_cmd); + continue; + } + + if (unlikely(ipmi->rx_result != 0)) { + dev_err(dev, "ipmi_send_message_%d err result(%d)[%s] raw_cmd=[%s]\r\n", + retry, ipmi->rx_result, cmdline ? cmdline : "", raw_cmd); + continue; + } + + break; + } + + if (cmdline) kfree(cmdline); + + return status; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev[ipmi->pid]->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static struct as9737_32db_psu_data *as9737_32db_psu_update_device(struct device_attribute *da) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR; + int status = 0; + + if (time_before(jiffies, data->last_updated[pid] + HZ * 5) && data->valid[pid]) + return data; + + data->valid[pid] = 0; + /* To be compatible for older BMC firmware */ + data->ipmi_resp[pid].status[PSU_VOUT_MODE] = 0xff; + + /* Get status from ipmi */ + data->ipmi_tx_data[0] = pid + 1; /* PSU ID base id for ipmi start from 1 */ + status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp[pid].status, + sizeof(data->ipmi_resp[pid].status)); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + /* Get model name from ipmi */ + data->ipmi_tx_data[1] = IPMI_PSU_MODEL_NAME_CMD; + status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, + data->ipmi_tx_data, 2, + data->ipmi_resp[pid].model, + sizeof(data->ipmi_resp[pid].model) - 1); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + /* Get serial number from ipmi */ + data->ipmi_tx_data[1] = IPMI_PSU_SERIAL_NUM_CMD; + status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, + data->ipmi_tx_data, 2, + data->ipmi_resp[pid].serial, + sizeof(data->ipmi_resp[pid].serial) - 1); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + /* Get fan direction from ipmi */ + data->ipmi_tx_data[1] = IPMI_PSU_FAN_DIR_CMD; + status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, + data->ipmi_tx_data, 2, + data->ipmi_resp[pid].fandir, + sizeof(data->ipmi_resp[pid].fandir) - 1); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + /* Get capability from ipmi */ + data->ipmi_tx_data[1] = IPMI_PSU_INFO_CMD; + status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, + data->ipmi_tx_data, 2, + data->ipmi_resp[pid].info, + sizeof(data->ipmi_resp[pid].info)); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->last_updated[pid] = jiffies; + data->valid[pid] = 1; + +exit: + return data; +} + +#define VALIDATE_PRESENT_RETURN(id) \ +do { \ + if (data->ipmi_resp[id].status[PSU_PRESENT] == 0) { \ + mutex_unlock(&data->update_lock); \ + return -ENXIO; \ + } \ +} while (0) + +static ssize_t show_psu(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR; + u32 value = 0; + int present = 0; + int error = 0; + int multiplier = 1000; + + mutex_lock(&data->update_lock); + + data = as9737_32db_psu_update_device(da); + if (!data->valid[pid]) { + error = -EIO; + goto exit; + } + + present = !!(data->ipmi_resp[pid].status[PSU_PRESENT]); + + switch (attr->index) { + case PSU1_PRESENT: + case PSU2_PRESENT: + value = present; + break; + case PSU1_POWER_GOOD: + case PSU2_POWER_GOOD: + VALIDATE_PRESENT_RETURN(pid); + value = data->ipmi_resp[pid].status[PSU_POWER_GOOD_PMBUS]; + break; + case PSU1_IIN: + case PSU2_IIN: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].status[PSU_IIN0] | + (u32)data->ipmi_resp[pid].status[PSU_IIN1] << 8 | + (u32)data->ipmi_resp[pid].status[PSU_IIN2] << 16); + break; + case PSU1_IOUT: + case PSU2_IOUT: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].status[PSU_IOUT0] | + (u32)data->ipmi_resp[pid].status[PSU_IOUT1] << 8 | + (u32)data->ipmi_resp[pid].status[PSU_IOUT2] << 16); + break; + case PSU1_VIN: + case PSU2_VIN: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].status[PSU_VIN0] | + (u32)data->ipmi_resp[pid].status[PSU_VIN1] << 8 | + (u32)data->ipmi_resp[pid].status[PSU_VIN2] << 16); + break; + case PSU1_VOUT: + case PSU2_VOUT: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].status[PSU_VOUT0] | + (u32)data->ipmi_resp[pid].status[PSU_VOUT1] << 8 | + (u32)data->ipmi_resp[pid].status[PSU_VOUT2] << 16); + break; + case PSU1_PIN: + case PSU2_PIN: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].status[PSU_PIN0] | + (u32)data->ipmi_resp[pid].status[PSU_PIN1] << 8 | + (u32)data->ipmi_resp[pid].status[PSU_PIN2] << 16 | + (u32)data->ipmi_resp[pid].status[PSU_PIN3] << 24); + value /= 1000; // Convert to milliwatt + break; + case PSU1_POUT: + case PSU2_POUT: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].status[PSU_POUT0] | + (u32)data->ipmi_resp[pid].status[PSU_POUT1] << 8 | + (u32)data->ipmi_resp[pid].status[PSU_POUT2] << 16 | + (u32)data->ipmi_resp[pid].status[PSU_POUT3] << 24); + value /= 1000; // Convert to milliwatt + break; + case PSU1_TEMP1_INPUT: + case PSU2_TEMP1_INPUT: + VALIDATE_PRESENT_RETURN(pid); + value = (s16)((u16)data->ipmi_resp[pid].status[PSU_TEMP1_0] | + (u16)data->ipmi_resp[pid].status[PSU_TEMP1_1] << 8); + value *= 1000; // Convert to millidegree Celsius + break; + case PSU1_TEMP2_INPUT: + case PSU2_TEMP2_INPUT: + VALIDATE_PRESENT_RETURN(pid); + value = (s16)((u16)data->ipmi_resp[pid].status[PSU_TEMP2_0] | + (u16)data->ipmi_resp[pid].status[PSU_TEMP2_1] << 8); + value *= 1000; // Convert to millidegree Celsius + break; + case PSU1_TEMP3_INPUT: + case PSU2_TEMP3_INPUT: + VALIDATE_PRESENT_RETURN(pid); + value = (s16)((u16)data->ipmi_resp[pid].status[PSU_TEMP3_0] | + (u16)data->ipmi_resp[pid].status[PSU_TEMP3_1] << 8); + value *= 1000; // Convert to millidegree Celsius + break; + case PSU1_FAN_INPUT: + case PSU2_FAN_INPUT: + VALIDATE_PRESENT_RETURN(pid); + multiplier = 1; + value = ((u32)data->ipmi_resp[pid].status[PSU_FAN0] | + (u32)data->ipmi_resp[pid].status[PSU_FAN1] << 8); + break; + default: + error = -EINVAL; + goto exit; + } + + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", present ? value : 0); + +exit: + mutex_unlock(&data->update_lock); + return error; +} + +static ssize_t show_psu_info(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR; + s32 value = 0; + int present = 0; + int error = 0; + + mutex_lock(&data->update_lock); + + data = as9737_32db_psu_update_device(da); + if (!data->valid[pid]) { + error = -EIO; + goto exit; + } + + present = !!(data->ipmi_resp[pid].status[PSU_PRESENT]); + + switch (attr->index) { + case PSU1_TEMP1_INPUT_MAX: + case PSU2_TEMP1_INPUT_MAX: + VALIDATE_PRESENT_RETURN(pid); + value = (s16)((u16)data->ipmi_resp[pid].info[PSU_TEMP1_MAX0] | + (u16)data->ipmi_resp[pid].info[PSU_TEMP1_MAX1] << 8); + value *= 1000; // Convert to millidegree Celsius + break; + case PSU1_TEMP1_INPUT_MIN: + case PSU2_TEMP1_INPUT_MIN: + VALIDATE_PRESENT_RETURN(pid); + value = (s16)((u16)data->ipmi_resp[pid].info[PSU_TEMP1_MIN0] | + (u16)data->ipmi_resp[pid].info[PSU_TEMP1_MIN1] << 8); + value *= 1000; // Convert to millidegree Celsius + break; + case PSU1_TEMP2_INPUT_MAX: + case PSU2_TEMP2_INPUT_MAX: + VALIDATE_PRESENT_RETURN(pid); + value = (s16)((u16)data->ipmi_resp[pid].info[PSU_TEMP2_MAX0] | + (u16)data->ipmi_resp[pid].info[PSU_TEMP2_MAX1] << 8); + value *= 1000; // Convert to millidegree Celsius + break; + case PSU1_TEMP2_INPUT_MIN: + case PSU2_TEMP2_INPUT_MIN: + VALIDATE_PRESENT_RETURN(pid); + value = (s16)((u16)data->ipmi_resp[pid].info[PSU_TEMP2_MIN0] | + (u16)data->ipmi_resp[pid].info[PSU_TEMP2_MIN1] << 8); + value *= 1000; // Convert to millidegree Celsius + break; + case PSU1_TEMP3_INPUT_MAX: + case PSU2_TEMP3_INPUT_MAX: + VALIDATE_PRESENT_RETURN(pid); + value = (s16)((u16)data->ipmi_resp[pid].info[PSU_TEMP3_MAX0] | + (u16)data->ipmi_resp[pid].info[PSU_TEMP3_MAX1] << 8); + value *= 1000; // Convert to millidegree Celsius + break; + case PSU1_TEMP3_INPUT_MIN: + case PSU2_TEMP3_INPUT_MIN: + VALIDATE_PRESENT_RETURN(pid); + value = (s16)((u16)data->ipmi_resp[pid].info[PSU_TEMP3_MIN0] | + (u16)data->ipmi_resp[pid].info[PSU_TEMP3_MIN1] << 8); + value *= 1000; // Convert to millidegree Celsius + break; + case PSU1_VIN_UPPER_CRIT: + case PSU2_VIN_UPPER_CRIT: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_VIN_UPPER_CRIT0] | + (u32)data->ipmi_resp[pid].info[PSU_VIN_UPPER_CRIT1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_VIN_UPPER_CRIT2] << 16); + break; + case PSU1_VIN_LOWER_CRIT: + case PSU2_VIN_LOWER_CRIT: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_VIN_LOWER_CRIT0] | + (u32)data->ipmi_resp[pid].info[PSU_VIN_LOWER_CRIT1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_VIN_LOWER_CRIT2] << 16); + break; + case PSU1_VIN_MAX: + case PSU2_VIN_MAX: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_VIN_MAX0] | + (u32)data->ipmi_resp[pid].info[PSU_VIN_MAX1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_VIN_MAX2] << 16); + break; + case PSU1_VIN_MIN: + case PSU2_VIN_MIN: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_VIN_MIN0] | + (u32)data->ipmi_resp[pid].info[PSU_VIN_MIN1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_VIN_MIN2] << 16); + break; + case PSU1_VOUT_MAX: + case PSU2_VOUT_MAX: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_VOUT_MAX0] | + (u32)data->ipmi_resp[pid].info[PSU_VOUT_MAX1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_VOUT_MAX2] << 16); + break; + case PSU1_VOUT_MIN: + case PSU2_VOUT_MIN: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_VOUT_MIN0] | + (u32)data->ipmi_resp[pid].info[PSU_VOUT_MIN1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_VOUT_MIN2] << 16); + break; + case PSU1_IIN_MAX: + case PSU2_IIN_MAX: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_IIN_MAX0] | + (u32)data->ipmi_resp[pid].info[PSU_IIN_MAX1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_IIN_MAX2] << 16); + break; + case PSU1_IOUT_MAX: + case PSU2_IOUT_MAX: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_IOUT_MAX0] | + (u32)data->ipmi_resp[pid].info[PSU_IOUT_MAX1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_IOUT_MAX2] << 16); + break; + case PSU1_PIN_MAX: + case PSU2_PIN_MAX: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_PIN_MAX0] | + (u32)data->ipmi_resp[pid].info[PSU_PIN_MAX1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_PIN_MAX2] << 16 | + (u32)data->ipmi_resp[pid].info[PSU_PIN_MAX3] << 24); + value /= 1000; // Convert to milliwatt + break; + case PSU1_POUT_MAX: + case PSU2_POUT_MAX: + VALIDATE_PRESENT_RETURN(pid); + value = ((u32)data->ipmi_resp[pid].info[PSU_POUT_MAX0] | + (u32)data->ipmi_resp[pid].info[PSU_POUT_MAX1] << 8 | + (u32)data->ipmi_resp[pid].info[PSU_POUT_MAX2] << 16 | + (u32)data->ipmi_resp[pid].info[PSU_POUT_MAX3] << 24); + value /= 1000; // Convert to milliwatt + break; + default: + error = -EINVAL; + goto exit; + } + + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", present ? value : 0); + +exit: + mutex_unlock(&data->update_lock); + return error; +} + +static ssize_t show_string(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR; + char *str = NULL; + int error = 0; + + mutex_lock(&data->update_lock); + + data = as9737_32db_psu_update_device(da); + if (!data->valid[pid]) { + error = -EIO; + goto exit; + } + + switch (attr->index) { + case PSU1_MODEL: + case PSU2_MODEL: + VALIDATE_PRESENT_RETURN(pid); + str = data->ipmi_resp[pid].model; + break; + case PSU1_SERIAL: + case PSU2_SERIAL: + VALIDATE_PRESENT_RETURN(pid); + str = data->ipmi_resp[pid].serial; + break; + case PSU1_FAN_DIR: + case PSU2_FAN_DIR: + VALIDATE_PRESENT_RETURN(pid); + str = data->ipmi_resp[pid].fandir; + break; + default: + error = -EINVAL; + goto exit; + } + + mutex_unlock(&data->update_lock); + return sprintf(buf, "%s\n", str); + +exit: + mutex_unlock(&data->update_lock); + return error; +} + +static int as9737_32db_psu_probe(struct platform_device *pdev) +{ + int status = 0; + struct device *hwmon_dev = NULL; + + hwmon_dev = hwmon_device_register_with_info(&pdev->dev, DRVNAME, + NULL, NULL, as9737_32db_psu_groups[pdev->id]); + if (IS_ERR(hwmon_dev)) { + status = PTR_ERR(hwmon_dev); + return status; + } + + mutex_lock(&data->update_lock); + data->hwmon_dev[pdev->id] = hwmon_dev; + mutex_unlock(&data->update_lock); + + dev_info(&pdev->dev, "PSU%d device created\n", pdev->id + 1); + + return 0; +} + +static int as9737_32db_psu_remove(struct platform_device *pdev) +{ + mutex_lock(&data->update_lock); + if (data->hwmon_dev[pdev->id]) { + hwmon_device_unregister(data->hwmon_dev[pdev->id]); + data->hwmon_dev[pdev->id] = NULL; + } + mutex_unlock(&data->update_lock); + + return 0; +} + +static int __init as9737_32db_psu_init(void) +{ + int ret; + int i; + + data = kzalloc(sizeof(struct as9737_32db_psu_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + + ret = platform_driver_register(&as9737_32db_psu_driver); + if (ret < 0) + goto dri_reg_err; + + for (i = 0; i < NUM_OF_PSU; i++) { + data->pdev[i] = platform_device_register_simple(DRVNAME, i, NULL, 0); + if (IS_ERR(data->pdev[i])) { + ret = PTR_ERR(data->pdev[i]); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev[i]->dev, i); + if (ret) { + goto ipmi_err; + } + } + + + return 0; + +ipmi_err: + while (i > 0) { + i--; + platform_device_unregister(data->pdev[i]); + } +dev_reg_err: + platform_driver_unregister(&as9737_32db_psu_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as9737_32db_psu_exit(void) +{ + int i; + + ipmi_destroy_user(data->ipmi.user); + for (i = 0; i < NUM_OF_PSU; i++) { + platform_device_unregister(data->pdev[i]); + } + platform_driver_unregister(&as9737_32db_psu_driver); + kfree(data); +} + +MODULE_AUTHOR("Roger Ho "); +MODULE_DESCRIPTION("as9737_32db_psu driver"); +MODULE_LICENSE("GPL"); + +module_init(as9737_32db_psu_init); +module_exit(as9737_32db_psu_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_sys.c b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_sys.c new file mode 100644 index 0000000000..fec19617de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_sys.c @@ -0,0 +1,479 @@ +/* + * Copyright (C) Roger Ho + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as9737_32db_sys" +#define ACCTON_IPMI_NETFN 0x34 + +#define IPMI_TIMEOUT (5 * HZ) +#define IPMI_ERR_RETRY_TIMES 1 +#define IPMI_READ_MAX_LEN 128 + +#define EEPROM_NAME "eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +#define IPMI_SYSEEPROM_READ_CMD 0x18 +#define IPMI_CPLD_READ_CMD 0x20 + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static int as9737_32db_sys_probe(struct platform_device *pdev); +static int as9737_32db_sys_remove(struct platform_device *pdev); +static ssize_t show_version(struct device *dev, + struct device_attribute *da, char *buf); + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + struct ipmi_user * user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct as9737_32db_sys_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct ipmi_data ipmi; + unsigned char ipmi_resp_eeprom[EEPROM_SIZE]; + unsigned char ipmi_resp_cpld[2]; + unsigned char ipmi_tx_data[2]; + struct bin_attribute eeprom; /* eeprom data */ +}; + +struct as9737_32db_sys_data *data = NULL; + +static struct platform_driver as9737_32db_sys_driver = { + .probe = as9737_32db_sys_probe, + .remove = as9737_32db_sys_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +enum as9737_32db_sys_sysfs_attrs { + FPGA_VER, /* FPGA version */ +}; + +static SENSOR_DEVICE_ATTR(fpga_version, S_IRUGO, show_version, NULL, FPGA_VER); + +static struct attribute *as9737_32db_sys_attributes[] = { + &sensor_dev_attr_fpga_version.dev_attr.attr, + NULL +}; + +static const struct attribute_group as9737_32db_sys_group = { + .attrs = as9737_32db_sys_attributes, +}; + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Send an IPMI command with retry */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int status = 0, retry = 0; + + char *cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); + + int i = 0; + char raw_cmd[20] = ""; + sprintf(raw_cmd, "0x%02x", cmd); + if(tx_len) + { + for( i=0; i < tx_len; i++) { + sprintf(raw_cmd + strlen(raw_cmd), " 0x%02x", tx_data[i]); + } + } + + for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { + status = _ipmi_send_message(ipmi,cmd, tx_data, tx_len, rx_data, rx_len); + if (unlikely(status != 0)) { + dev_err(&data->pdev->dev, + "ipmi_send_message_%d err status(%d)[%s] raw_cmd=[%s]\r\n", + retry, status, cmdline ? cmdline : "", raw_cmd); + continue; + } + + if (unlikely(ipmi->rx_result != 0)) { + dev_err(&data->pdev->dev, + "ipmi_send_message_%d err rx_result(%d)[%s] raw_cmd=[%s]\r\n", + retry, ipmi->rx_result, cmdline ? cmdline : "", raw_cmd); + continue; + } + + break; + } + + if (cmdline) kfree(cmdline); + + return status; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } + else { + ipmi->rx_msg_len = 0; + } + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +static ssize_t sys_eeprom_read(loff_t off, char *buf, size_t count) +{ + int status = 0; + unsigned char length = 0; + + if ((off + count) > EEPROM_SIZE) + return -EINVAL; + + length = (count >= IPMI_READ_MAX_LEN) ? IPMI_READ_MAX_LEN : count; + data->ipmi_tx_data[0] = (off & 0xff); + data->ipmi_tx_data[1] = length; + status = ipmi_send_message(&data->ipmi, IPMI_SYSEEPROM_READ_CMD, + data->ipmi_tx_data, sizeof(data->ipmi_tx_data), + data->ipmi_resp_eeprom + off, length); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + status = length; /* Read length */ + memcpy(buf, data->ipmi_resp_eeprom + off, length); + +exit: + return status; +} + +static ssize_t sysfs_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) + return count; + + /* + * Read data from chip, protecting against concurrent updates + * from this host + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sys_eeprom_read(off, buf, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + +static int sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IRUGO; + eeprom->read = sysfs_bin_read; + eeprom->size = EEPROM_SIZE; + eeprom->write = NULL; + + /* Create eeprom file */ + return sysfs_create_bin_file(kobj, eeprom); +} + +static int sysfs_eeprom_cleanup(struct kobject *kobj, + struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static struct as9737_32db_sys_data *as9737_32db_sys_update_fpga_ver(void) +{ + int status = 0; + + data->valid = 0; + data->ipmi_tx_data[0] = 0x60; + status = ipmi_send_message(&data->ipmi, IPMI_CPLD_READ_CMD, + data->ipmi_tx_data, 1, + data->ipmi_resp_cpld, + sizeof(data->ipmi_resp_cpld)); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + +exit: + return data; +} + +static ssize_t show_version(struct device *dev, + struct device_attribute *da, char *buf) +{ + unsigned char major; + unsigned char minor; + int error = 0; + + mutex_lock(&data->update_lock); + + data = as9737_32db_sys_update_fpga_ver(); + if (!data->valid) { + error = -EIO; + goto exit; + } + + major = data->ipmi_resp_cpld[0]; + minor = data->ipmi_resp_cpld[1]; + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d.%d\n", major, minor); + +exit: + mutex_unlock(&data->update_lock); + return error; +} + +static int as9737_32db_sys_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_eeprom_init(&pdev->dev.kobj, &data->eeprom); + if (status) + goto exit; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &as9737_32db_sys_group); + if (status) + goto exit; + + dev_info(&pdev->dev, "device created\n"); + + return 0; + +exit: + return status; +} + +static int as9737_32db_sys_remove(struct platform_device *pdev) +{ + sysfs_eeprom_cleanup(&pdev->dev.kobj, &data->eeprom); + sysfs_remove_group(&pdev->dev.kobj, &as9737_32db_sys_group); + + return 0; +} + +static int __init as9737_32db_sys_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as9737_32db_sys_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + + ret = platform_driver_register(&as9737_32db_sys_driver); + if (ret < 0) + goto dri_reg_err; + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) + goto ipmi_err; + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as9737_32db_sys_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as9737_32db_sys_exit(void) +{ + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + platform_driver_unregister(&as9737_32db_sys_driver); + kfree(data); +} + +MODULE_AUTHOR("Roger Ho "); +MODULE_DESCRIPTION("as9737_32db_sys driver"); +MODULE_LICENSE("GPL"); + +module_init(as9737_32db_sys_init); +module_exit(as9737_32db_sys_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_thermal.c b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_thermal.c new file mode 100644 index 0000000000..f72dc7bb59 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/accton_as9737_32db_thermal.c @@ -0,0 +1,501 @@ +/* + * Copyright (C) Roger Ho + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as9737_32db_thermal" +#define ACCTON_IPMI_NETFN 0x34 +#define IPMI_THERMAL_READ_CMD 0x12 +#define THERMAL_COUNT 5 +#define THERMAL_DATA_LEN 3 +#define THERMAL_DATA_COUNT (THERMAL_COUNT * THERMAL_DATA_LEN) + +#define IPMI_TIMEOUT (5 * HZ) +#define IPMI_ERR_RETRY_TIMES 1 + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, + char *buf); +#ifdef ENABLE_THRESHOLD +static ssize_t show_threshold(struct device *dev, struct device_attribute *da, + char *buf); +#endif +static int as9737_32db_thermal_probe(struct platform_device *pdev); +static int as9737_32db_thermal_remove(struct platform_device *pdev); + +enum temp_data_index { + TEMP_ADDR, + TEMP_FAULT, + TEMP_INPUT, + TEMP_DATA_COUNT +}; + +struct ipmi_data { + struct completion read_complete; + struct ipmi_addr address; + struct ipmi_user * user; + int interface; + + struct kernel_ipmi_msg tx_message; + long tx_msgid; + + void *rx_msg_data; + unsigned short rx_msg_len; + unsigned char rx_result; + int rx_recv_type; + + struct ipmi_user_hndl ipmi_hndlrs; +}; + +struct as9737_32db_thermal_data { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + char ipmi_resp[THERMAL_DATA_COUNT]; /* 3 bytes for each thermal */ + struct ipmi_data ipmi; + unsigned char ipmi_tx_data[2]; /* 0: thermal id, 1: temp */ +}; + +#ifdef ENABLE_THRESHOLD +static s8 temp_max_alarm[THERMAL_COUNT] = { 85, 85, 85, 79, 92}; +static s8 temp_max[THERMAL_COUNT] = { 80, 80, 80, 74, 87}; +static s8 temp_min[THERMAL_COUNT] = { -45, -45, -45, -45, -45}; +static s8 temp_min_alarm[THERMAL_COUNT] = { -50, -50, -50, -50, -50}; +#endif + +struct as9737_32db_thermal_data *data = NULL; + +static struct platform_driver as9737_32db_thermal_driver = { + .probe = as9737_32db_thermal_probe, + .remove = as9737_32db_thermal_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +enum as9737_32db_thermal_sysfs_attrs { + TEMP1_INPUT, // 0x48 + TEMP2_INPUT, // 0x49 + TEMP3_INPUT, // 0x4A + TEMP4_INPUT, // 0x4C + TEMP5_INPUT, // 0x4F + TEMP1_MAX_ALARM, + TEMP2_MAX_ALARM, + TEMP3_MAX_ALARM, + TEMP4_MAX_ALARM, + TEMP5_MAX_ALARM, + TEMP1_MAX, + TEMP2_MAX, + TEMP3_MAX, + TEMP4_MAX, + TEMP5_MAX, + TEMP1_MIN, + TEMP2_MIN, + TEMP3_MIN, + TEMP4_MIN, + TEMP5_MIN, + TEMP1_MIN_ALARM, + TEMP2_MIN_ALARM, + TEMP3_MIN_ALARM, + TEMP4_MIN_ALARM, + TEMP5_MIN_ALARM, +}; + +#ifdef ENABLE_THRESHOLD +// Read only temp_input +#define DECLARE_THERMAL_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(temp##index##_input, S_IRUGO, show_temp, \ + NULL, TEMP##index##_INPUT); \ + static SENSOR_DEVICE_ATTR(temp##index##_crit, S_IRUGO, show_threshold,\ + NULL, TEMP##index##_MAX_ALARM); \ + static SENSOR_DEVICE_ATTR(temp##index##_max, S_IRUGO, show_threshold,\ + NULL, TEMP##index##_MAX); \ + static SENSOR_DEVICE_ATTR(temp##index##_min, S_IRUGO, show_threshold,\ + NULL, TEMP##index##_MIN); \ + static SENSOR_DEVICE_ATTR(temp##index##_lcrit, S_IRUGO, show_threshold,\ + NULL, TEMP##index##_MIN_ALARM) + +#define DECLARE_THERMAL_ATTR(index) \ + &sensor_dev_attr_temp##index##_input.dev_attr.attr, \ + &sensor_dev_attr_temp##index##_crit.dev_attr.attr, \ + &sensor_dev_attr_temp##index##_max.dev_attr.attr, \ + &sensor_dev_attr_temp##index##_min.dev_attr.attr, \ + &sensor_dev_attr_temp##index##_lcrit.dev_attr.attr +#else +#define DECLARE_THERMAL_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(temp##index##_input, S_IRUGO, show_temp, \ + NULL, TEMP##index##_INPUT); + +#define DECLARE_THERMAL_ATTR(index) \ + &sensor_dev_attr_temp##index##_input.dev_attr.attr +#endif + +DECLARE_THERMAL_SENSOR_DEVICE_ATTR(1); +DECLARE_THERMAL_SENSOR_DEVICE_ATTR(2); +DECLARE_THERMAL_SENSOR_DEVICE_ATTR(3); +DECLARE_THERMAL_SENSOR_DEVICE_ATTR(4); +DECLARE_THERMAL_SENSOR_DEVICE_ATTR(5); + +static struct attribute *as9737_32db_thermal_attrs[] = { + DECLARE_THERMAL_ATTR(1), + DECLARE_THERMAL_ATTR(2), + DECLARE_THERMAL_ATTR(3), + DECLARE_THERMAL_ATTR(4), + DECLARE_THERMAL_ATTR(5), + NULL +}; +ATTRIBUTE_GROUPS(as9737_32db_thermal); + +/* Functions to talk to the IPMI layer */ + +/* Initialize IPMI address, message buffers and user data */ +static int init_ipmi_data(struct ipmi_data *ipmi, int iface, + struct device *dev) +{ + int err; + + init_completion(&ipmi->read_complete); + + /* Initialize IPMI address */ + ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + ipmi->address.channel = IPMI_BMC_CHANNEL; + ipmi->address.data[0] = 0; + ipmi->interface = iface; + + /* Initialize message buffers */ + ipmi->tx_msgid = 0; + ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; + + ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; + + /* Create IPMI messaging interface user */ + err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, + ipmi, &ipmi->user); + if (err < 0) { + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", ipmi->interface); + return -EACCES; + } + + return 0; +} + +/* Send an IPMI command */ +static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int err; + + ipmi->tx_message.cmd = cmd; + ipmi->tx_message.data = tx_data; + ipmi->tx_message.data_len = tx_len; + ipmi->rx_msg_data = rx_data; + ipmi->rx_msg_len = rx_len; + + err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); + if (err) + goto addr_err; + + ipmi->tx_msgid++; + err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, + &ipmi->tx_message, ipmi, 0, 0, 0); + if (err) + goto ipmi_req_err; + + err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); + if (!err) + goto ipmi_timeout_err; + + return 0; + +ipmi_timeout_err: + err = -ETIMEDOUT; + dev_err(&data->pdev->dev, "request_timeout=%x\n", err); + return err; +ipmi_req_err: + dev_err(&data->pdev->dev, "request_settime=%x\n", err); + return err; +addr_err: + dev_err(&data->pdev->dev, "validate_addr=%x\n", err); + return err; +} + +/* Send an IPMI command with retry */ +static int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, + unsigned char *tx_data, unsigned short tx_len, + unsigned char *rx_data, unsigned short rx_len) +{ + int status = 0, retry = 0; + + char *cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); + + int i = 0; + char raw_cmd[20] = ""; + sprintf(raw_cmd, "0x%02x", cmd); + if(tx_len) + { + for( i=0; i < tx_len; i++) { + sprintf(raw_cmd + strlen(raw_cmd), " 0x%02x", tx_data[i]); + } + } + + for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { + status = _ipmi_send_message(ipmi, cmd, tx_data, tx_len, rx_data, rx_len); + if (unlikely(status != 0)) { + dev_err(&data->pdev->dev, "ipmi cmd(%x) err status(%d)[%s] raw_cmd=[%s]\r\n", + cmd, status, cmdline ? cmdline : "", raw_cmd); + continue; + } + + if (unlikely(ipmi->rx_result != 0)) { + dev_err(&data->pdev->dev, "ipmi cmd(%x) err result(%d)[%s] raw_cmd=[%s]\r\n", + cmd, ipmi->rx_result, cmdline ? cmdline : "", raw_cmd); + continue; + } + + break; + } + + if (cmdline) kfree(cmdline); + + return status; +} + +/* Dispatch IPMI messages to callers */ +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + unsigned short rx_len; + struct ipmi_data *ipmi = user_msg_data; + + if (msg->msgid != ipmi->tx_msgid) { + dev_err(&data->pdev->dev, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", + (int)msg->msgid, + (int)ipmi->tx_msgid); + ipmi_free_recv_msg(msg); + return; + } + + ipmi->rx_recv_type = msg->recv_type; + if (msg->msg.data_len > 0) + ipmi->rx_result = msg->msg.data[0]; + else + ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; + + if (msg->msg.data_len > 1) { + rx_len = msg->msg.data_len - 1; + if (ipmi->rx_msg_len < rx_len) + rx_len = ipmi->rx_msg_len; + ipmi->rx_msg_len = rx_len; + memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); + } else + ipmi->rx_msg_len = 0; + + ipmi_free_recv_msg(msg); + complete(&ipmi->read_complete); +} + +#ifdef ENABLE_THRESHOLD +static ssize_t show_threshold(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + mutex_lock(&data->update_lock); + + switch (attr->index) { + case TEMP1_MAX_ALARM ... TEMP5_MAX_ALARM: + status = (int)temp_max_alarm[attr->index - TEMP1_MAX_ALARM]; + break; + case TEMP1_MAX ... TEMP5_MAX: + status = (int)temp_max[attr->index - TEMP1_MAX]; + break; + case TEMP1_MIN ... TEMP5_MIN: + status = (int)temp_min[attr->index - TEMP1_MIN]; + break; + case TEMP1_MIN_ALARM ... TEMP5_MIN_ALARM: + status = (int)temp_min_alarm[attr->index - TEMP1_MIN_ALARM]; + break; + default: + status = -EINVAL; + goto exit; + } + + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", status * 1000); + +exit: + mutex_unlock(&data->update_lock); + return status; +} +#endif + +static ssize_t show_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status = 0; + int index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ * 5) || !data->valid) { + data->valid = 0; + + status = ipmi_send_message(&data->ipmi, IPMI_THERMAL_READ_CMD, NULL, 0, + data->ipmi_resp, sizeof(data->ipmi_resp)); + if (unlikely(status != 0)) + goto exit; + + if (unlikely(data->ipmi.rx_result != 0)) { + status = -EIO; + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + } + + /* Get temp fault status */ + index = attr->index * TEMP_DATA_COUNT + TEMP_FAULT; + if (unlikely(data->ipmi_resp[index] == 0)) { + status = -EIO; + goto exit; + } + + /* Get temperature in degree celsius */ + index = attr->index * TEMP_DATA_COUNT + TEMP_INPUT; + status = ((s8)data->ipmi_resp[index]) * 1000; + + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", status); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static int as9737_32db_thermal_probe(struct platform_device *pdev) +{ + int status = 0; + struct device *hwmon_dev; + + hwmon_dev = hwmon_device_register_with_info(&pdev->dev, DRVNAME, + NULL, NULL, as9737_32db_thermal_groups); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + return status; + } + + mutex_lock(&data->update_lock); + data->hwmon_dev = hwmon_dev; + mutex_unlock(&data->update_lock); + + dev_info(&pdev->dev, "Device Created\n"); + + return status; +} + +static int as9737_32db_thermal_remove(struct platform_device *pdev) +{ + mutex_lock(&data->update_lock); + if (data->hwmon_dev) { + hwmon_device_unregister(data->hwmon_dev); + data->hwmon_dev = NULL; + } + mutex_unlock(&data->update_lock); + + return 0; +} + +static int __init as9737_32db_thermal_init(void) +{ + int ret; + + data = kzalloc(sizeof(struct as9737_32db_thermal_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto alloc_err; + } + + mutex_init(&data->update_lock); + + ret = platform_driver_register(&as9737_32db_thermal_driver); + if (ret < 0) + goto dri_reg_err; + + data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(data->pdev)) { + ret = PTR_ERR(data->pdev); + goto dev_reg_err; + } + + /* Set up IPMI interface */ + ret = init_ipmi_data(&data->ipmi, 0, &data->pdev->dev); + if (ret) { + goto ipmi_err; + } + + return 0; + +ipmi_err: + platform_device_unregister(data->pdev); +dev_reg_err: + platform_driver_unregister(&as9737_32db_thermal_driver); +dri_reg_err: + kfree(data); +alloc_err: + return ret; +} + +static void __exit as9737_32db_thermal_exit(void) +{ + if (data) { + ipmi_destroy_user(data->ipmi.user); + platform_device_unregister(data->pdev); + platform_driver_unregister(&as9737_32db_thermal_driver); + kfree(data); + } +} + +MODULE_AUTHOR("Roger Ho "); +MODULE_DESCRIPTION("as9737_32db_thermal driver"); +MODULE_LICENSE("GPL"); + +module_init(as9737_32db_thermal_init); +module_exit(as9737_32db_thermal_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/i2c-ocores.c b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/i2c-ocores.c new file mode 100644 index 0000000000..9471d9f3f1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/modules/i2c-ocores.c @@ -0,0 +1,975 @@ + +// SPDX-License-Identifier: GPL-2.0 +/* + * i2c-ocores.c: I2C bus driver for OpenCores I2C controller + * (https://opencores.org/project/i2c/overview) + * + * Peter Korsgaard + * + * Support for the GRLIB port of the controller by + * Andreas Larsson + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 'process_lock' exists because ocores_process() and ocores_process_timeout() + * can't run in parallel. + */ +struct ocores_i2c { + void __iomem *base; + int iobase; + u32 reg_shift; + u32 reg_io_width; + unsigned long flags; + wait_queue_head_t wait; + struct i2c_adapter adap; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + spinlock_t process_lock; + struct clk *clk; + int ip_clock_khz; + int bus_clock_khz; +#ifdef HAS_CHANNEL_REG + u8 channel; +#endif + void (*setreg)(struct ocores_i2c *i2c, int reg, u8 value); + u8 (*getreg)(struct ocores_i2c *i2c, int reg); +}; + +/* registers */ +#define OCI2C_PRELOW 0 +#define OCI2C_PREHIGH 1 +#define OCI2C_CONTROL 2 +#define OCI2C_DATA 3 +#define OCI2C_CMD 4 /* write only */ +#define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */ +#ifdef HAS_CHANNEL_REG +#define OCI2C_CHANNEL 5 /* Assign port num; Only for AS9737-32DB FPGA */ +#endif + +#define OCI2C_CTRL_IEN 0x40 +#define OCI2C_CTRL_EN 0x80 + +#define OCI2C_CMD_START 0x91 +#define OCI2C_CMD_STOP 0x41 +#define OCI2C_CMD_READ 0x21 +#define OCI2C_CMD_WRITE 0x11 +#define OCI2C_CMD_READ_ACK 0x21 +#define OCI2C_CMD_READ_NACK 0x29 +#define OCI2C_CMD_IACK 0x01 + +#define OCI2C_STAT_IF 0x01 +#define OCI2C_STAT_TIP 0x02 +#define OCI2C_STAT_ARBLOST 0x20 +#define OCI2C_STAT_BUSY 0x40 +#define OCI2C_STAT_NACK 0x80 + +#define STATE_DONE 0 +#define STATE_START 1 +#define STATE_WRITE 2 +#define STATE_READ 3 +#define STATE_ERROR 4 + +#define TYPE_OCORES 0 +#define TYPE_GRLIB 1 +#define TYPE_SIFIVE_REV0 2 + +#define OCORES_FLAG_BROKEN_IRQ BIT(1) /* Broken IRQ for FU540-C000 SoC */ + +static unsigned int timeout = 1; +module_param(timeout , uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(timeout, "Timeout for ocores_poll_wait, measured in milliseconds."); + +static unsigned int debug = 1; +module_param(debug , uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(debug, "Enable or disable debug message. 1 -> enable, 0 -> disable"); + +#ifdef HAS_CHANNEL_REG +spinlock_t cpld_access_lock; + +#define LOCK(lock) \ +do { \ + spin_lock(lock); \ +} while (0) + +#define UNLOCK(lock) \ +do { \ + spin_unlock(lock); \ +} while (0) +#endif + +static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_16(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite16(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_32(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite32(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_16be(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_32be(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_8(struct ocores_i2c *i2c, int reg) +{ + return ioread8(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_16(struct ocores_i2c *i2c, int reg) +{ + return ioread16(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_32(struct ocores_i2c *i2c, int reg) +{ + return ioread32(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_16be(struct ocores_i2c *i2c, int reg) +{ + return ioread16be(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_32be(struct ocores_i2c *i2c, int reg) +{ + return ioread32be(i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_io_8(struct ocores_i2c *i2c, int reg, u8 value) +{ + outb(value, i2c->iobase + reg); +} + +static inline u8 oc_getreg_io_8(struct ocores_i2c *i2c, int reg) +{ + return inb(i2c->iobase + reg); +} + +static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) +{ + i2c->setreg(i2c, reg, value); +} + +static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) +{ + return i2c->getreg(i2c, reg); +} + +static void ocores_process(struct ocores_i2c *i2c, u8 stat) +{ + struct i2c_msg *msg = i2c->msg; + unsigned long flags; + struct device *dev = i2c->adap.dev.parent; + char *cmdline = NULL; + + if (debug) { + cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); + } + /* + * If we spin here is because we are in timeout, so we are going + * to be in STATE_ERROR. See ocores_process_timeout() + */ + spin_lock_irqsave(&i2c->process_lock, flags); + if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + /* stop has been sent */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + wake_up(&i2c->wait); + goto out; + } + + /* error? */ + if (stat & OCI2C_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + if (debug) { + dev_warn(dev, "I2C %s arbitration lost", i2c->adap.name); + } + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + goto out; + } + + if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { + i2c->state = + (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & OCI2C_STAT_NACK) { + i2c->state = STATE_ERROR; + if (debug) { + dev_warn(dev, "I2C %s, no ACK from slave 0x%02x (%s)", i2c->adap.name, msg->addr, cmdline ? cmdline : ""); + } + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + goto out; + } + } else { + msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { /* end? */ + /* send start? */ + if (!(msg->flags & I2C_M_NOSTART)) { + u8 addr = i2c_8bit_addr_from_msg(msg); + + i2c->state = STATE_START; + + oc_setreg(i2c, OCI2C_DATA, addr); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + goto out; + } + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } else { + i2c->state = STATE_DONE; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + goto out; + } + } + + if (i2c->state == STATE_READ) { + oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? + OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); + } else { + oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); + } + +out: + spin_unlock_irqrestore(&i2c->process_lock, flags); + if (cmdline) kfree(cmdline); + +} + +static irqreturn_t ocores_isr(int irq, void *dev_id) +{ + struct ocores_i2c *i2c = dev_id; + u8 stat = oc_getreg(i2c, OCI2C_STATUS); + + if (i2c->flags & OCORES_FLAG_BROKEN_IRQ) { + if ((stat & OCI2C_STAT_IF) && !(stat & OCI2C_STAT_BUSY)) + return IRQ_NONE; + } else if (!(stat & OCI2C_STAT_IF)) { + return IRQ_NONE; + } + ocores_process(i2c, stat); + + return IRQ_HANDLED; +} + +/** + * Process timeout event + * @i2c: ocores I2C device instance + */ +static void ocores_process_timeout(struct ocores_i2c *i2c) +{ + unsigned long flags; + + spin_lock_irqsave(&i2c->process_lock, flags); + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + spin_unlock_irqrestore(&i2c->process_lock, flags); +} + +/** + * Wait until something change in a given register + * @i2c: ocores I2C device instance + * @reg: register to query + * @mask: bitmask to apply on register value + * @val: expected result + * @timeout: timeout in jiffies + * + * Timeout is necessary to avoid to stay here forever when the chip + * does not answer correctly. + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_wait(struct ocores_i2c *i2c, + int reg, u8 mask, u8 val, + const unsigned long timeout) +{ + unsigned long j; + + j = jiffies + timeout; + while (1) { + u8 status = oc_getreg(i2c, reg); + + if ((status & mask) == val) + break; + + if (time_after(jiffies, j)) + return -ETIMEDOUT; + } + return 0; +} + +/** + * Wait until is possible to process some data + * @i2c: ocores I2C device instance + * + * Used when the device is in polling mode (interrupts disabled). + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_poll_wait(struct ocores_i2c *i2c) +{ + u8 mask; + int err; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* transfer is over */ + mask = OCI2C_STAT_BUSY; + } else { + /* on going transfer */ + mask = OCI2C_STAT_TIP; + /* + * We wait for the data to be transferred (8bit), + * then we start polling on the ACK/NACK bit + */ + udelay((8 * 1000) / i2c->bus_clock_khz); + } + + /* + * once we are here we expect to get the expected result immediately + * so if after 1ms we timeout then something is broken. + */ + err = ocores_wait(i2c, OCI2C_STATUS, mask, 0, msecs_to_jiffies(timeout)); + if (err) { + if (debug) { + dev_warn(i2c->adap.dev.parent, + "%s: STATUS timeout, bit 0x%x did not clear in %ums(msecs_to_jiffies(%u)=%lu)\n", + __func__, mask, timeout, timeout, msecs_to_jiffies(timeout)); + } + } + return err; +} + +/** + * It handles an IRQ-less transfer + * @i2c: ocores I2C device instance + * + * Even if IRQ are disabled, the I2C OpenCore IP behavior is exactly the same + * (only that IRQ are not produced). This means that we can re-use entirely + * ocores_isr(), we just add our polling code around it. + * + * It can run in atomic context + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_process_polling(struct ocores_i2c *i2c) +{ + irqreturn_t ret; + int err; + + while (1) { + err = ocores_poll_wait(i2c); + if (err) { + break; /* timeout */ + } + + ret = ocores_isr(-1, i2c); + if (ret == IRQ_NONE) + break; /* all messages have been transferred */ + else { + if (i2c->flags & OCORES_FLAG_BROKEN_IRQ) + if (i2c->state == STATE_DONE) + break; + } + } + + return err; +} + +static int ocores_xfer_core(struct ocores_i2c *i2c, + struct i2c_msg *msgs, int num, + bool polling) +{ + int ret = 0; + u8 ctrl; + +#ifdef HAS_CHANNEL_REG + LOCK(&cpld_access_lock); + + /* Only for AS9737-32DB FPGA */ + oc_setreg(i2c, OCI2C_CHANNEL, i2c->channel); +#endif + + ctrl = oc_getreg(i2c, OCI2C_CONTROL); + if (polling) + oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~OCI2C_CTRL_IEN); + else + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN); + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = STATE_START; + + oc_setreg(i2c, OCI2C_DATA, i2c_8bit_addr_from_msg(i2c->msg)); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + + if (polling) { + ret = ocores_process_polling(i2c); + } else { + if (wait_event_timeout(i2c->wait, + (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ) == 0) + ret = -ETIMEDOUT; + } + if (ret) { + ocores_process_timeout(i2c); +#ifdef HAS_CHANNEL_REG + UNLOCK(&cpld_access_lock); +#endif + return ret; + } + +#ifdef HAS_CHANNEL_REG + UNLOCK(&cpld_access_lock); +#endif + return (i2c->state == STATE_DONE) ? num : -EIO; +} + +static int ocores_xfer_polling(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, true); +} + +static int ocores_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, false); +} + +static int ocores_init(struct device *dev, struct ocores_i2c *i2c) +{ + int prescale; + int diff; + u8 ctrl; + +#ifdef HAS_CHANNEL_REG + oc_setreg(i2c, OCI2C_CHANNEL, i2c->channel); +#endif + + ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* make sure the device is disabled */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); + + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + dev_err(dev, + "Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } + +#ifdef HAS_CHANNEL_REG + dev_info(dev, "OCI2C_CHANNEL=0x%02x OCI2C_PRELOW=0x%02x OCI2C_PREHIGH=0x%02x\n", + i2c->channel, prescale & 0xff, prescale >> 8); +#else + dev_info(dev, "OCI2C_PRELOW=0x%02x OCI2C_PREHIGH=0x%02x\n", + prescale & 0xff, prescale >> 8); +#endif + oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); + oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); + + /* Init the device */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); + + return 0; +} + + +static u32 ocores_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static struct i2c_algorithm ocores_algorithm = { + .master_xfer = ocores_xfer, + .master_xfer_atomic = ocores_xfer_polling, + .functionality = ocores_func, +}; + +static const struct i2c_adapter ocores_adapter = { + .owner = THIS_MODULE, + .name = "i2c-ocores", + .class = I2C_CLASS_DEPRECATED, + .algo = &ocores_algorithm, +}; + +static const struct of_device_id ocores_i2c_match[] = { + { + .compatible = "opencores,i2c-ocores", + .data = (void *)TYPE_OCORES, + }, + { + .compatible = "aeroflexgaisler,i2cmst", + .data = (void *)TYPE_GRLIB, + }, + { + .compatible = "sifive,fu540-c000-i2c", + .data = (void *)TYPE_SIFIVE_REV0, + }, + { + .compatible = "sifive,i2c0", + .data = (void *)TYPE_SIFIVE_REV0, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ocores_i2c_match); + +#ifdef CONFIG_OF +/* + * Read and write functions for the GRLIB port of the controller. Registers are + * 32-bit big endian and the PRELOW and PREHIGH registers are merged into one + * register. The subsequent registers have their offsets decreased accordingly. + */ +static u8 oc_getreg_grlib(struct ocores_i2c *i2c, int reg) +{ + u32 rd; + int rreg = reg; + + if (reg != OCI2C_PRELOW) + rreg--; + rd = ioread32be(i2c->base + (rreg << i2c->reg_shift)); + if (reg == OCI2C_PREHIGH) + return (u8)(rd >> 8); + else + return (u8)rd; +} + +static void oc_setreg_grlib(struct ocores_i2c *i2c, int reg, u8 value) +{ + u32 curr, wr; + int rreg = reg; + + if (reg != OCI2C_PRELOW) + rreg--; + if (reg == OCI2C_PRELOW || reg == OCI2C_PREHIGH) { + curr = ioread32be(i2c->base + (rreg << i2c->reg_shift)); + if (reg == OCI2C_PRELOW) + wr = (curr & 0xff00) | value; + else + wr = (((u32)value) << 8) | (curr & 0xff); + } else { + wr = value; + } + iowrite32be(wr, i2c->base + (rreg << i2c->reg_shift)); +} + +static int ocores_i2c_of_probe(struct platform_device *pdev, + struct ocores_i2c *i2c) +{ + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *match; + u32 val; + u32 clock_frequency; + bool clock_frequency_present; + + if (of_property_read_u32(np, "reg-shift", &i2c->reg_shift)) { + /* no 'reg-shift', check for deprecated 'regstep' */ + if (!of_property_read_u32(np, "regstep", &val)) { + if (!is_power_of_2(val)) { + dev_err(&pdev->dev, "invalid regstep %d\n", + val); + return -EINVAL; + } + i2c->reg_shift = ilog2(val); + dev_warn(&pdev->dev, + "regstep property deprecated, use reg-shift\n"); + } + } + + clock_frequency_present = !of_property_read_u32(np, "clock-frequency", + &clock_frequency); + i2c->bus_clock_khz = 100; + + i2c->clk = devm_clk_get(&pdev->dev, NULL); + + if (!IS_ERR(i2c->clk)) { + int ret = clk_prepare_enable(i2c->clk); + + if (ret) { + dev_err(&pdev->dev, + "clk_prepare_enable failed: %d\n", ret); + return ret; + } + i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000; + if (clock_frequency_present) + i2c->bus_clock_khz = clock_frequency / 1000; + } + + if (i2c->ip_clock_khz == 0) { + if (of_property_read_u32(np, "opencores,ip-clock-frequency", + &val)) { + if (!clock_frequency_present) { + dev_err(&pdev->dev, + "Missing required parameter 'opencores,ip-clock-frequency'\n"); + clk_disable_unprepare(i2c->clk); + return -ENODEV; + } + i2c->ip_clock_khz = clock_frequency / 1000; + dev_warn(&pdev->dev, + "Deprecated usage of the 'clock-frequency' property, please update to 'opencores,ip-clock-frequency'\n"); + } else { + i2c->ip_clock_khz = val / 1000; + if (clock_frequency_present) + i2c->bus_clock_khz = clock_frequency / 1000; + } + } + + of_property_read_u32(pdev->dev.of_node, "reg-io-width", + &i2c->reg_io_width); + + match = of_match_node(ocores_i2c_match, pdev->dev.of_node); + if (match && (long)match->data == TYPE_GRLIB) { + dev_dbg(&pdev->dev, "GRLIB variant of i2c-ocores\n"); + i2c->setreg = oc_setreg_grlib; + i2c->getreg = oc_getreg_grlib; + } + + return 0; +} +#else +#define ocores_i2c_of_probe(pdev, i2c) -ENODEV +#endif + +#ifdef HAS_CHANNEL_REG +static void __iomem *devm_ioremap_shared_resource(struct device *dev, + const struct resource *res) +{ + resource_size_t size; + void __iomem *dest_ptr; + char *pretty_name; + + BUG_ON(!dev); + + if (!res || resource_type(res) != IORESOURCE_MEM) { + dev_err(dev, "invalid resource\n"); + return IOMEM_ERR_PTR(-EINVAL); + } + + size = resource_size(res); + + if (res->name) + pretty_name = devm_kasprintf(dev, GFP_KERNEL, "%s %s", dev_name(dev), res->name); + else + pretty_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); + if (!pretty_name) + return IOMEM_ERR_PTR(-ENOMEM); + + /*********************************************** + * Cannot use devm_request_mem_region in here. * + ***********************************************/ + + dest_ptr = devm_ioremap(dev, res->start, size); + if (!dest_ptr) { + dev_err(dev, "ioremap failed for resource %pR\n", res); + dest_ptr = IOMEM_ERR_PTR(-ENOMEM); + } + + return dest_ptr; +} +#endif + +static int ocores_i2c_probe(struct platform_device *pdev) +{ + struct ocores_i2c *i2c; + struct ocores_i2c_platform_data *pdata; + const struct of_device_id *match; + struct resource *res; + int irq; + int ret; + int i; + + i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) + return -ENOMEM; + + spin_lock_init(&i2c->process_lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) { +#ifdef HAS_CHANNEL_REG + i2c->base = devm_ioremap_shared_resource(&pdev->dev, res); +#else + i2c->base = devm_ioremap_resource(&pdev->dev, res); +#endif + dev_info(&pdev->dev, "Resouce Memory: start:0x%llx, end:0x%llx", res->start, res->end); + if (IS_ERR(i2c->base)) + return PTR_ERR(i2c->base); + } else { + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!res) + return -EINVAL; + i2c->iobase = res->start; + if (!devm_request_region(&pdev->dev, res->start, + resource_size(res), + pdev->name)) { + dev_err(&pdev->dev, "Can't get I/O resource.\n"); + return -EBUSY; + } + i2c->setreg = oc_setreg_io_8; + i2c->getreg = oc_getreg_io_8; + } + +#ifdef HAS_CHANNEL_REG + res = platform_get_resource_byname(pdev, IORESOURCE_REG, "channel"); + if (res) { + i2c->channel = res->start; + dev_info(&pdev->dev, "Resouce Channel: 0x%llx", res->start); + } else { + dev_err(&pdev->dev, "No Channel resource for port number identification.\n"); + return -EINVAL; + } +#endif + + pdata = dev_get_platdata(&pdev->dev); + if (pdata) { + i2c->reg_shift = pdata->reg_shift; + i2c->reg_io_width = pdata->reg_io_width; + i2c->ip_clock_khz = pdata->clock_khz; + dev_info(&pdev->dev, "Write %d KHz, ioWidth:%d, shift:%d", i2c->ip_clock_khz, pdata->reg_io_width ,pdata->reg_shift); + if (pdata->bus_khz) + i2c->bus_clock_khz = pdata->bus_khz; + else + i2c->bus_clock_khz = 100; + } else { + ret = ocores_i2c_of_probe(pdev, i2c); + if (ret) + return ret; + } + + if (i2c->reg_io_width == 0) + i2c->reg_io_width = 1; /* Set to default value */ + + if (!i2c->setreg || !i2c->getreg) { + bool be = pdata ? pdata->big_endian : + of_device_is_big_endian(pdev->dev.of_node); + + switch (i2c->reg_io_width) { + case 1: + i2c->setreg = oc_setreg_8; + i2c->getreg = oc_getreg_8; + break; + + case 2: + i2c->setreg = be ? oc_setreg_16be : oc_setreg_16; + i2c->getreg = be ? oc_getreg_16be : oc_getreg_16; + break; + + case 4: + i2c->setreg = be ? oc_setreg_32be : oc_setreg_32; + i2c->getreg = be ? oc_getreg_32be : oc_getreg_32; + break; + + default: + dev_err(&pdev->dev, "Unsupported I/O width (%d)\n", + i2c->reg_io_width); + ret = -EINVAL; + goto err_clk; + } + } + + init_waitqueue_head(&i2c->wait); + + irq = platform_get_irq_optional(pdev, 0); + if (irq == -ENXIO) { + ocores_algorithm.master_xfer = ocores_xfer_polling; + + /* + * Set in OCORES_FLAG_BROKEN_IRQ to enable workaround for + * FU540-C000 SoC in polling mode. + */ + match = of_match_node(ocores_i2c_match, pdev->dev.of_node); + if (match && (long)match->data == TYPE_SIFIVE_REV0) + i2c->flags |= OCORES_FLAG_BROKEN_IRQ; + } else { + if (irq < 0) + return irq; + } + + if (ocores_algorithm.master_xfer != ocores_xfer_polling) { + ret = devm_request_any_context_irq(&pdev->dev, irq, + ocores_isr, 0, + pdev->name, i2c); + if (ret) { + dev_err(&pdev->dev, "Cannot claim IRQ\n"); + goto err_clk; + } + } + ret = ocores_init(&pdev->dev, i2c); + if (ret) { + goto err_clk; + } + /* hook up driver to tree */ + platform_set_drvdata(pdev, i2c); + i2c->adap = ocores_adapter; + i2c_set_adapdata(&i2c->adap, i2c); + i2c->adap.dev.parent = &pdev->dev; + i2c->adap.dev.of_node = pdev->dev.of_node; + + /* add i2c adapter to i2c tree */ + ret = i2c_add_adapter(&i2c->adap); + if (ret) { + goto err_clk; + } + /* add in known devices to the bus */ + if (pdata) { + for (i = 0; i < pdata->num_devices; i++){ + i2c_new_client_device(&i2c->adap, pdata->devices + i); + } + } + + return 0; + +err_clk: + clk_disable_unprepare(i2c->clk); + return ret; +} + +static int ocores_i2c_remove(struct platform_device *pdev) +{ + struct ocores_i2c *i2c = platform_get_drvdata(pdev); + u8 ctrl; + + ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* disable i2c logic */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + /* remove adapter & data */ + i2c_del_adapter(&i2c->adap); + + if (!IS_ERR(i2c->clk)) + clk_disable_unprepare(i2c->clk); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int ocores_i2c_suspend(struct device *dev) +{ + struct ocores_i2c *i2c = dev_get_drvdata(dev); + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* make sure the device is disabled */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + if (!IS_ERR(i2c->clk)) + clk_disable_unprepare(i2c->clk); + return 0; +} + +static int ocores_i2c_resume(struct device *dev) +{ + struct ocores_i2c *i2c = dev_get_drvdata(dev); + + if (!IS_ERR(i2c->clk)) { + unsigned long rate; + int ret = clk_prepare_enable(i2c->clk); + + if (ret) { + dev_err(dev, + "clk_prepare_enable failed: %d\n", ret); + return ret; + } + rate = clk_get_rate(i2c->clk) / 1000; + if (rate) + i2c->ip_clock_khz = rate; + } + return ocores_init(dev, i2c); +} + +static SIMPLE_DEV_PM_OPS(ocores_i2c_pm, ocores_i2c_suspend, ocores_i2c_resume); +#define OCORES_I2C_PM (&ocores_i2c_pm) +#else +#define OCORES_I2C_PM NULL +#endif + +static struct platform_driver ocores_i2c_driver = { + .probe = ocores_i2c_probe, + .remove = ocores_i2c_remove, + .driver = { + .name = "ocores-i2c", + .of_match_table = ocores_i2c_match, + .pm = OCORES_I2C_PM, + }, +}; + +#ifdef HAS_CHANNEL_REG +static int __init ocores_i2c_as9817_64_init(void) +{ + int err; + + err = platform_driver_register(&ocores_i2c_driver); + if (err < 0) { + pr_err("Failed to register ocores_i2c_driver"); + return err; + } + + spin_lock_init(&cpld_access_lock); + + return 0; +} +static void __exit ocores_i2c_as9817_64_exit(void) +{ + platform_driver_unregister(&ocores_i2c_driver); +} + +module_init(ocores_i2c_as9817_64_init); +module_exit(ocores_i2c_as9817_64_exit); +#else +module_platform_driver(ocores_i2c_driver); +#endif + +MODULE_AUTHOR("Peter Korsgaard "); +MODULE_DESCRIPTION("OpenCores I2C bus driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ocores-i2c"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/service/as9737_32db-platform-init.service b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/service/as9737_32db-platform-init.service new file mode 100644 index 0000000000..77079f45df --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/service/as9737_32db-platform-init.service @@ -0,0 +1,15 @@ +[Unit] +Description=Accton AS9737-32DB Platform Initialization Service +Before=pmon.service determine-reboot-cause.service system-health.service +DefaultDependencies=no + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/accton_as9737_32db_util.py install + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/service/as9737_32db-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/service/as9737_32db-platform-monitor.service new file mode 100644 index 0000000000..9bea2dd5b9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/service/as9737_32db-platform-monitor.service @@ -0,0 +1,17 @@ +[Unit] +Description=Accton AS9737-32DB Platform Monitoring service +Before=pmon.service +After=as9737_32db-platform-init.service +Requires=as9737_32db-platform-init.service + +[Service] +ExecStart=/usr/local/bin/accton_as9737_32db_monitor.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL +#StandardOutput=tty + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/setup.py b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/setup.py new file mode 100755 index 0000000000..8d0c392a65 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='as9737_32db', + version='1.0', + description='Module to initialize Accton AS9737-32DB platforms', + + packages=['as9737_32db'], + package_dir={'as9737_32db': 'as9737-32db/classes'}, +) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/sonic_platform_setup.py b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/sonic_platform_setup.py new file mode 100644 index 0000000000..cdd5b24d49 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/sonic_platform_setup.py @@ -0,0 +1,34 @@ +from setuptools import setup + +DEVICE_NAME = 'accton' +HW_SKU = 'x86_64-accton_as9737_32db-r0' + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Accton Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Roger Ho', + maintainer_email='roger530_ho@edge-core.com', + packages=[ + 'sonic_platform', + ], + package_dir={ + 'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 3.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/utils/accton_as9737_32db_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/utils/accton_as9737_32db_monitor.py new file mode 100755 index 0000000000..9603e98172 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/utils/accton_as9737_32db_monitor.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -* +# Copyright (c) 2024 Edgecore Networks Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# +# HISTORY: +# mm/dd/yyyy (A.D.)# +# 05/31/2024:Roger create for as9737_64 thermal monitor +# ------------------------------------------------------------------ + +try: + import os + import sys + import getopt + import logging + import logging.config + import logging.handlers + import signal + import time + import re + from sonic_platform import platform + from swsscommon import swsscommon + from sonic_py_common.general import getstatusoutput_noshell +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'accton_as9737_32db_monitor' + +STATE_DB = 'STATE_DB' +TRANSCEIVER_DOM_SENSOR_TABLE = 'TRANSCEIVER_DOM_SENSOR' +TEMPERATURE_FIELD_NAME = 'temperature' + +MONITOR_INTERVAL = 5 + +exit_by_sigterm = 0 + +DEBUG = False + +class device_monitor(object): + def __init__(self, log_file, log_level): + """ + Initializes the device monitor with logging and platform setup. + Parameters: + - log_file: The file path for logging output. + - log_level: The logging level to control output verbosity. + Sets up logging, initializes platform chassis and SFPs. + """ + self.platform_chassis = platform.Platform().get_chassis() + self.sfps = self.platform_chassis.get_all_sfps() + + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(asctime)s %(name)-12s: %(levelname)-8s %(message)s', datefmt='%H:%M:%S') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + sys_handler = logging.handlers.SysLogHandler(address = '/dev/log') + sys_handler.setLevel(logging.WARNING) + logging.getLogger('').addHandler(sys_handler) + + self.mac_thermal_val = 0.0 + self.sfps_thermal_val = [(i, 0.0, "", False) for i in range(self.platform_chassis.get_num_sfps())] + self.sfp_max_thermal_port = 0 + self.sfp_max_thermal_val = 0.0 + self.sfp_max_thermal_name = "" + self.transceiver_dom_sensor_tbl = None + self.transceiver_status_tbl = None + + #bcmcmd 'show temp'|grep 'Average current temperature is' + def get_mac_temperature(self): + """ + Retrieves the MAC temperature using the 'bcmcmd' system command. + + - Executes the command to show the MAC temperature. + - Parses the output to find the average current temperature. + - Returns the temperature in millidegrees Celsius. + - Logs a warning if the temperature retrieval fails. + + Returns: + - The MAC temperature in millidegrees Celsius (float), or 0.0 if retrieval fails. + """ + cmd = ['bcmcmd', 'show temp'] + status, output = getstatusoutput_noshell(cmd) + + if status == 0: + res_list = re.findall('Average current temperature is\s*(.+?)\n', output) + if res_list: + return (float(res_list[0])) + logging.warning("Warning: Failed to read the MAC temperature") + return (0.0) + + def get_transceiver_temperature(self, iface_name): + """ + Fetches the temperature of a specified transceiver using the STATE_DB. + Parameters: + - iface_name: The interface name of the transceiver. + Returns the temperature in degrees Celsius as a float. + """ + # NOTE: the main loop calls 'is_database_ready()' to ensure the redis server + # is ready. So the exception handler here takes effect only when the redis server is down + # suddenly after database.service is up. + if self.transceiver_dom_sensor_tbl is None: + try: + state_db = swsscommon.DBConnector(STATE_DB, 0, False) + self.transceiver_dom_sensor_tbl = swsscommon.Table(state_db, TRANSCEIVER_DOM_SENSOR_TABLE) + except Exception as e: + logging.debug("{}".format(e)) + return (0.0) + + try: + (status, ret) = self.transceiver_dom_sensor_tbl.hget(iface_name, TEMPERATURE_FIELD_NAME) + if status: + return (float(ret)) + except (TypeError, ValueError): + pass + + return (0.0) + + def collect_temperature(self): + """ + Collects temperature data from the MAC and all transceivers. + + - Retrieves MAC temperature. + - Initializes SFP presence count. + - Iterates over SFP modules to collect presence and temperature data. + - Updates `sfps_thermal_val` with collected data. + - Identifies and logs the SFP with the highest temperature. + """ + self.mac_thermal_val = self.get_mac_temperature() # MAC average temp + logging.debug("MAC Thermal: {}".format(self.mac_thermal_val)) + + for sfp in self.sfps: + if sfp.port_num > self.platform_chassis.get_num_sfps(): + continue + intf_name = sfp.get_name() + temperature = 0.0 + presence = sfp.get_presence() + if presence: + temperature = self.get_transceiver_temperature(intf_name) + self.sfps_thermal_val[sfp.port_num - 1] = (sfp.port_num, temperature, intf_name, presence) + logging.debug("Transceiver Thermal(Port Number, Temperature, Interface Name, Presence): {}".format(self.sfps_thermal_val)) + + if self.sfps_thermal_val: + max_thermal_tuple = max(self.sfps_thermal_val, key=lambda item: item[1]) + self.sfp_max_thermal_port = max_thermal_tuple[0] + self.sfp_max_thermal_val = max_thermal_tuple[1] + self.sfp_max_thermal_name = max_thermal_tuple[2] + logging.debug( + f"Max Transceiver Thermal: Port {self.sfp_max_thermal_port}, " + f"{self.sfp_max_thermal_name}, " + f"{self.sfp_max_thermal_val}" + ) + + def send_thermal_report(self): + """ + Sends the collected thermal data to the BMC using IPMI commands. + Constructs the command with MAC and transceiver temperature values. + """ + try: + # Construct the command with thermal data + cmd = [ + 'ipmitool', 'raw', '0x34', '0x13', + str(int(self.mac_thermal_val)), # MAC temperature + str(int(self.sfp_max_thermal_val)), # Transceiver temperature + str(self.sfp_max_thermal_port) # Transceiver port number + ] + logging.debug(f"IPMI Command: {cmd}") + + status, output = getstatusoutput_noshell(cmd) + if status != 0: + logging.warning("Warning: Failed to send thermal report. [{}]".format(output)) + return False + return True + except Exception as e: + logging.warning("Warning: Exception occurred while sending thermal report. [{}]".format(e)) + return False + + def manage_thermal(self): + """ + Manages the thermal monitoring process. + Collects current temperature data from all transceivers and MAC. + Sends temperature data to BMC. + """ + # Collect current temperature data from all transceivers and MAC. + self.collect_temperature() + # Send temperature data to BMC. + self.send_thermal_report() + + return True + +def signal_handler(sig, frame): + """ + Handles signal interrupts (e.g., SIGTERM) to gracefully exit the monitoring loop. + Parameters: + - sig: The signal number. + - frame: The current stack frame. + Sets a flag to indicate the monitoring loop should exit. + """ + global exit_by_sigterm + + if sig == signal.SIGTERM: + print("Caught SIGTERM - exiting...") + exit_by_sigterm = 1 + else: + pass + +def is_database_ready(): + """ + Checks if the database service is active. + Returns True if the database service is active, otherwise False. + """ + cmd_str = ["systemctl", "is-active", "database.service"] + (status, output) = getstatusoutput_noshell(cmd_str) + if output == "active": + return True + else: + return False + +def main(argv): + """ + The main entry point for the device monitor script. + Parses command-line arguments for logging level and test mode options. + Initializes and runs the device monitor in a loop until a SIGTERM signal is received. + Parameters: + - argv: Command-line arguments passed to the script. + """ + global exit_by_sigterm + + if os.geteuid() != 0: + print("Error: Root privileges are required") + sys.exit(1) + + signal.signal(signal.SIGTERM, signal_handler) + + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdlt:',['lfile=']) + except getopt.GetoptError: + print('Usage: %s [-d] [-l ]' % sys.argv[0]) + return 0 + for opt, arg in opts: + if opt == '-h': + print('Usage: %s [-d] [-l ]' % sys.argv[0]) + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + monitor = device_monitor(log_file, log_level) + while True: + monitor.manage_thermal() + time.sleep(MONITOR_INTERVAL) + if exit_by_sigterm == 1: + break + + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9737-32db/utils/accton_as9737_32db_util.py b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/utils/accton_as9737_32db_util.py new file mode 100755 index 0000000000..2bc2d0a8d2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9737-32db/utils/accton_as9737_32db_util.py @@ -0,0 +1,744 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2016 Accton Networks, Inc. +# +# 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 3 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, see . + +""" +usage: accton_as9737_32db_util.py [-h] [-d] [-f] {install,clean,threshold} ... + +AS9737-32DB Platform Utility + +optional arguments: + -h, --help show this help message and exit + -d, --debug run with debug mode + -f, --force ignore error during installation or clean + +Utility Command: + {install,clean,threshold} + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + threshold : modify thermal threshold + ten : enable 10G to CPU or front port +""" +import subprocess +import sys +import logging +import re +import time +import os +import glob +import argparse +from sonic_py_common.general import getstatusoutput_noshell + + +PROJECT_NAME = 'as9737_32db' +version = '0.1.0' +verbose = False +DEBUG = False +FAN_PWM = 50 +args = [] +FORCE = 0 +CPU = 0 +FRONT = 1 +#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +#logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print(sys.argv[0]) + print('ARGV :', sys.argv[1:]) + + +def main(): + global DEBUG + global args + global FORCE + global THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH + + util_parser = argparse.ArgumentParser(description="AS9737-32DB Platform Utility") + util_parser.add_argument("-d", "--debug", dest='debug', action='store_true', default=False, + help="run with debug mode") + util_parser.add_argument("-f", "--force", dest='force', action='store_true', default=False, + help="ignore error during installation or clean") + subcommand = util_parser.add_subparsers(dest='cmd', title='Utility Command', required=True) + subcommand.add_parser('install', help=': install drivers and generate related sysfs nodes') + subcommand.add_parser('clean', help=': uninstall drivers and remove related sysfs nodes') + ten = subcommand.add_parser('ten', help=': enable 10G to CPU or front port') + ten.add_argument("-c", dest='cpu', action='store_true', default=False, + help="enable 10G to CPU") + ten.add_argument("-f", dest='front', action='store_true', default=False, + help="enable 10G to front port") + threshold_parser = subcommand.add_parser('threshold', help=': modify thermal threshold') + threshold_parser.add_argument("-l", dest='list', action='store_true', default=False, + help="list avaliable thermal") + threshold_parser.add_argument("-t", dest='thermal', type=str, metavar='THERMAL_NAME', + help="thermal name, ex: -t 'Temp sensor 1'") + threshold_parser.add_argument("-ht", dest='high_threshold', type=restricted_float, + metavar='THRESHOLD_VALUE', + help="high threshold: %.1f ~ %.1f" % (THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH)) + threshold_parser.add_argument("-hct", dest='high_crit_threshold', type=restricted_float, + metavar='THRESHOLD_VALUE', + help="high critical threshold : %.1f ~ %.1f" % (THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH)) + args = util_parser.parse_args() + + if DEBUG == True: + print(args) + print(len(sys.argv)) + + DEBUG = args.debug + #FORCE = 1 if args.force else 0 + FORCE = 1 + + if args.cmd == 'install': + do_install() + elif args.cmd == 'clean': + do_uninstall() + elif args.cmd == 'threshold': + do_threshold() + elif args.cmd == 'ten': + do_10g() + + return 0 + +def show_help(): + print(__doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}) + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print("[DEBUG]"+txt) + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = subprocess.getstatusoutput(cmd) + #status, output = getstatusoutput_noshell(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) + logging.info('mods:'+lsmod) + if ret : + return False + else : + return True + +ipmi_ko = [ + 'modprobe ipmi_msghandler', + 'modprobe ipmi_ssif', + 'modprobe ipmi_si', + 'modprobe ipmi_devintf'] + +ATTEMPTS = 5 +INTERVAL = 3 + +def init_ipmi_dev_intf(): + attempts = ATTEMPTS + interval = INTERVAL + + while attempts: + for i in range(0, len(ipmi_ko)): + subprocess.getstatusoutput(ipmi_ko[i]) + + if os.path.exists('/dev/ipmi0') or os.path.exists('/dev/ipmidev/0'): + return (0, (ATTEMPTS - attempts) * interval) + + for i in reversed(range(0, len(ipmi_ko))): + rm = ipmi_ko[i].replace("modprobe", "modprobe -rq") + subprocess.getstatusoutput(rm) + + attempts -= 1 + time.sleep(interval) + + return (1, ATTEMPTS * interval) + +def init_ipmi_oem_cmd(): + attempts = ATTEMPTS + interval = INTERVAL + + while attempts: + status, output = subprocess.getstatusoutput('ipmitool raw 0x34 0x95') + if status: + attempts -= 1 + time.sleep(interval) + continue + + return (0, (ATTEMPTS - attempts) * interval) + + return (1, ATTEMPTS * interval) + +def init_ipmi(): + attempts = ATTEMPTS + interval = 60 + + while attempts: + attempts -= 1 + + (status, elapsed_dev) = init_ipmi_dev_intf() + if status: + time.sleep(max(0, interval - elapsed_dev)) + continue + + (status, elapsed_oem) = init_ipmi_oem_cmd() + if status: + time.sleep(max(0, interval - elapsed_dev - elapsed_oem)) + continue + + print('IPMI dev interface is ready.') + return 0 + + print('Failed to initialize IPMI dev interface') + return 1 + + +kos = [ + 'modprobe i2c_dev', + 'modprobe i2c_i801', + 'modprobe i2c_ismt', + 'modprobe optoe', + 'modprobe at24', + 'modprobe accton_as9737_32db_mux', + 'modprobe accton_as9737_32db_cpld', + 'modprobe accton_as9737_32db_fan', + 'modprobe accton_as9737_32db_psu', + 'modprobe accton_as9737_32db_thermal', + 'modprobe accton_as9737_32db_sys', + 'modprobe accton_as9737_32db_leds' +] + +kos2 = [ + 'modprobe i2c-ocores', + 'modprobe accton_as9737_32db_fpga', +] + +#EERPOM +eeprom_mknod =[ + 'echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', +] + +def eeprom_check(): + cmd = ["i2cget", "-f", "-y", "0", "0x56"] + status, output = getstatusoutput_noshell(cmd) + return status + +def set_i2c_register(bus, device, register, value): + cmd = ['i2cset', '-f', '-y', str(bus), str(device), str(register), str(value)] + status, output = log_os_system(' '.join(cmd), 1) + #status, output = getstatusoutput_noshell(cmd) + if status != 0: + print(f"Error setting register {register} to {value}: {output}") + return False + return True + +def enable_10G(dest): + bus = 6 + device = '0x58' + register_values = [ + ('0x06', '0x18'), # VOD DEM EQ Adjustment + ('0x0F', '0x00'), # CH0 NC - S_INA0 EQ + ('0x16', '0x00'), # CH1 D_OUT0 - S_INB0 EQ + ('0x17', '0xAA'), + ('0x18', '0x00'), + ('0x2C', '0x00'), # CH4 D_IN0 - S_OUTA0 EQ + ('0x2D', '0xAA'), + ('0x2E', '0x00'), + ('0x34', '0xAA'), # CH5 NC - S_OUTB0 VOD + ('0x35', '0x00'), + ('0x5E', '0x02'), # Override/Control SEL[1:0] and INPUT_EN + ('0x5F', '0x30'), # ('0x5F', '0x00') => CPU, ('0x5F', '0x30') => front port + ] + + if dest == CPU: + register_values[-1] = ('0x5F', '0x00') + + for register, value in register_values: + if not set_i2c_register(bus, device, register, value): + return False + time.sleep(0.5) + return True + +def driver_install(): + global FORCE + + # Load 10G ethernet driver + status, output = log_os_system("modprobe ice", 1) + if status: + if FORCE == 0: + return status + + status = init_ipmi() + if status: + if FORCE == 0: + return status + + status, output = log_os_system("depmod -ae", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + print("Done driver_install") + + return 0 + +def driver_uninstall(): + global FORCE + + for i in range(0,len(kos2)): + rm = kos2[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + lst = rm.split(" ") + if len(lst) > 3: + del(lst[3]) + rm = " ".join(lst) + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + lst = rm.split(" ") + if len(lst) > 3: + del(lst[3]) + rm = " ".join(lst) + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +i2c_prefix = '/sys/bus/i2c/devices/' + +sfp_map = [ + 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, + 25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, + 41,42 +] + +qsfp_dd_start = 0 +qsfp_dd_end = 31 + +mknod =[ +'echo as9737_32db_mux 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as9737_32db_cpld2 0x61 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo as9737_32db_cpld3 0x62 > /sys/bus/i2c/devices/i2c-3/new_device' +] + +mkfile = [ + '/tmp/device_threshold.json', + '/tmp/device_threshold.json.lock' +] + +def device_install(): + global FORCE + + for i in range(0,len(mknod)): + status, output = log_os_system(mknod[i], 1) + if status: + print(output) + if FORCE == 0: + return status + + #for as9737_32db_mux need times to built new i2c buses + if mknod[i].find('as9737_32db_mux') != -1: + time.sleep(1) + + + # Select I2C relay channel to MB_EEPROM + #log_os_system("i2cset -f -a -y 0 0x78 0x00 0x01", 1) + #time.sleep(0.2) + + #ret=eeprom_check() + #if ret==0: + # log_os_system(eeprom_mknod[0], 1) + # time.sleep(0.2) + # exists = os.path.isfile('/sys/bus/i2c/devices/0-0056/eeprom') + # if (exists is False): + # subprocess.call('echo 0x56 > /sys/bus/i2c/devices/i2c-1/delete_device', shell=True) + + status, output = log_os_system("depmod -ae", 1) + for i in range(0,len(kos2)): + status, output = log_os_system(kos2[i], 1) + if status: + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + if i > qsfp_dd_end: + status, output =log_os_system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + else: + status, output =log_os_system("echo optoe3 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print(output) + if FORCE == 0: + return status + + # Release RESET pin for all QSFP. + for i in range(0, (qsfp_dd_end + 1)): + if i < 17: + status, output = log_os_system("echo 0 > /sys/bus/i2c/devices/2-0061/module_reset_{}".format(i + 1), 1) + else: + status, output = log_os_system("echo 0 > /sys/bus/i2c/devices/3-0062/module_reset_{}".format(i + 1), 1) + if status: + print(output) + + # Enable 10G Front Ports + enable_10G(FRONT) + + # Prevent permission issues between root or admin users for sonic_platform/helper.py + for i in range(0,len(mkfile)): + try: + # Create empty file + open(mkfile[i], 'a').close() + os.chmod(mkfile[i], 0o666) + except OSError: + print('Failed : creating the file %s.' % (mkfile[i])) + os.chmod(mkfile[i], 0o666) + if FORCE == 0: + return -1 + + print("Done device_install") + return + +def device_uninstall(): + global FORCE + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + print("echo 0x50 > "+ target) + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print(output) + if FORCE == 0: + return status + + for i in range(len(mknod)): + target = mknod[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + print(" ".join(temp)) + status, output = log_os_system(" ".join(temp), 1) + if status: + print(output) + if FORCE == 0: + return status + + # Deal with for del 0x56 sysfs device + #exists = os.path.isfile('/sys/bus/i2c/devices/0-0056/eeprom') + #if (exists is True): + # target = eeprom_mknod[0] #0x56 + # + #temp = target.split() + #del temp[1] + #temp[-1] = temp[-1].replace('new_device', 'delete_device') + #status, output = log_os_system(" ".join(temp), 1) + #if status: + # print(output) + # if FORCE == 0: + # return status + + for i in range(0,len(mkfile)): + status, output = log_os_system('rm -f ' + mkfile[i], 1) + if status: + print(output) + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +PLATFORM_API2_WHL_FILE_PY3 ='sonic_platform-1.0-py3-none-any.whl' +def do_sonic_platform_install(): + device_path = "{}{}{}{}".format(PLATFORM_ROOT_PATH, '/x86_64-accton_', PROJECT_NAME, '-r0') + SONIC_PLATFORM_BSP_WHL_PKG_PY3 = "/".join([device_path, PLATFORM_API2_WHL_FILE_PY3]) + + #Check API2.0 on py whl file + status, output = log_os_system("pip3 show sonic-platform > /dev/null 2>&1", 0) + if status: + if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_PY3): + status, output = log_os_system("pip3 install "+ SONIC_PLATFORM_BSP_WHL_PKG_PY3, 1) + if status: + print("Error: Failed to install {}".format(PLATFORM_API2_WHL_FILE_PY3)) + return status + else: + print("Successfully installed {} package".format(PLATFORM_API2_WHL_FILE_PY3)) + else: + print('{} is not found'.format(PLATFORM_API2_WHL_FILE_PY3)) + else: + print('{} has installed'.format(PLATFORM_API2_WHL_FILE_PY3)) + + return + +def do_sonic_platform_clean(): + status, output = log_os_system("pip3 show sonic-platform > /dev/null 2>&1", 0) + if status: + print('{} does not install, not need to uninstall'.format(PLATFORM_API2_WHL_FILE_PY3)) + + else: + status, output = log_os_system("pip3 uninstall sonic-platform -y", 0) + if status: + print('Error: Failed to uninstall {}'.format(PLATFORM_API2_WHL_FILE_PY3)) + return status + else: + print('{} is uninstalled'.format(PLATFORM_API2_WHL_FILE_PY3)) + + return + +def do_install(): + print("Checking system....") + if driver_check() == False: + print("No driver, installing....") + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print(PROJECT_NAME.upper()+" drivers detected....") + + if not device_exist(): + print("No device, installing....") + status = device_install() + if status: + if FORCE == 0: + return status + else: + print(PROJECT_NAME.upper()+" devices detected....") + + # Turn off LOC LED if needed + log_os_system("echo 0 > /sys/devices/platform/as9737_32db_led/led_loc", 1) + + # Chnage all fan_pwm to 50% + for filename in glob.glob("/sys/devices/platform/as9737_32db_fan/hwmon/*/fan*_pwm"): + try: + with open(filename, 'w') as fd: + fd.write(str(FAN_PWM)) + except IOError as e: + pass + + do_sonic_platform_install() + + return + +def do_uninstall(): + print("Checking system....") + if not device_exist(): + print(PROJECT_NAME.upper() +" has no device installed....") + else: + print("Removing device....") + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print(PROJECT_NAME.upper() +" has no driver installed....") + else: + print("Removing installed driver....") + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + do_sonic_platform_clean() + + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0078", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +THRESHOLD_RANGE_LOW = 30.0 +THRESHOLD_RANGE_HIGH = 110.0 +# Code to initialize chassis object +init_chassis_code = \ + "import sonic_platform.platform\n"\ + "platform = sonic_platform.platform.Platform()\n"\ + "chassis = platform.get_chassis()\n\n" + +# Looking for thermal +looking_for_thermal_code = \ + "thermal = None\n"\ + "all_thermals = chassis.get_all_thermals()\n"\ + "for psu in chassis.get_all_psus():\n"\ + " all_thermals += psu.get_all_thermals()\n"\ + "for tmp in all_thermals:\n"\ + " if '{}' == tmp.get_name():\n"\ + " thermal = tmp\n"\ + " break\n"\ + "if thermal == None:\n"\ + " print('{} not found!')\n"\ + " exit(1)\n\n" + +def avaliable_thermals(): + global init_chassis_code + + get_all_thermal_name_code = \ + "thermal_list = []\n"\ + "all_thermals = chassis.get_all_thermals()\n"\ + "for psu in chassis.get_all_psus():\n"\ + " all_thermals += psu.get_all_thermals()\n"\ + "for tmp in all_thermals:\n"\ + " thermal_list.append(tmp.get_name())\n"\ + "print(str(thermal_list)[1:-1])\n" + + all_code = "{}{}".format(init_chassis_code, get_all_thermal_name_code) + + status, output = getstatusoutput_noshell(["docker", "exec", "pmon", "python3", "-c", all_code]) + if status != 0: + return "" + return output + +def restricted_float(x): + global THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH + + try: + x = float(x) + except ValueError: + raise argparse.ArgumentTypeError("%r not a floating-point literal" % (x,)) + + if x < THRESHOLD_RANGE_LOW or x > THRESHOLD_RANGE_HIGH: + raise argparse.ArgumentTypeError("%r not in range [%.1f ~ %.1f]" % + (x, THRESHOLD_RANGE_LOW, THRESHOLD_RANGE_HIGH)) + + return x + +def get_high_threshold(name): + global init_chassis_code, looking_for_thermal_code + + get_high_threshold_code = \ + "try:\n"\ + " print(thermal.get_high_threshold())\n"\ + " exit(0)\n"\ + "except NotImplementedError:\n"\ + " print('Not implement the get_high_threshold method!')\n"\ + " exit(1)" + + all_code = "{}{}{}".format(init_chassis_code, looking_for_thermal_code.format(name, name), + get_high_threshold_code) + + status, output = getstatusoutput_noshell(["docker", "exec", "pmon", "python3", "-c", all_code]) + if status == 1: + return None + + return float(output) + +def get_high_crit_threshold(name): + global init_chassis_code, looking_for_thermal_code + + get_high_crit_threshold_code = \ + "try:\n"\ + " print(thermal.get_high_critical_threshold())\n"\ + " exit(0)\n"\ + "except NotImplementedError:\n"\ + " print('Not implement the get_high_critical_threshold method!')\n"\ + " exit(1)" + + all_code = "{}{}{}".format(init_chassis_code, looking_for_thermal_code.format(name, name), + get_high_crit_threshold_code) + + status, output = getstatusoutput_noshell(["docker", "exec", "pmon", "python3", "-c", all_code]) + if status == 1: + return None + + return float(output) + +def do_10g(): + if args.cpu: + enable_10G(CPU) + + if args.front: + enable_10G(FRONT) + +def do_threshold(): + global args, init_chassis_code, looking_for_thermal_code + + if args.list: + print("Thermals: " + avaliable_thermals()) + return + + if args.thermal is None: + print("The following arguments are required: -t") + return + + set_threshold_code = "" + if args.high_threshold is not None: + if args.high_crit_threshold is not None and \ + args.high_threshold >= args.high_crit_threshold: + print("Invalid Threshold!(High threshold can not be more than " \ + "or equal to high critical threshold.)") + exit(1) + + high_crit = get_high_crit_threshold(args.thermal) + if high_crit is not None and \ + args.high_threshold >= high_crit: + print("Invalid Threshold!(High threshold can not be more than " \ + "or equal to high critical threshold.)") + exit(1) + + set_threshold_code += \ + "try:\n"\ + " if thermal.set_high_threshold({}) is False:\n"\ + " print('{}: set_high_threshold failure!')\n"\ + " exit(1)\n"\ + "except NotImplementedError:\n"\ + " print('Not implement the set_high_threshold method!')\n"\ + "print('Apply the new high threshold successfully.')\n"\ + "\n".format(args.high_threshold, args.thermal) + + if args.high_crit_threshold is not None: + high = get_high_threshold(args.thermal) + if high is not None and \ + args.high_crit_threshold <= high: + print("Invalid Threshold!(High critical threshold can not " \ + "be less than or equal to high threshold.)") + exit(1) + + set_threshold_code += \ + "try:\n"\ + " if thermal.set_high_critical_threshold({}) is False:\n"\ + " print('{}: set_high_critical_threshold failure!')\n"\ + " exit(1)\n"\ + "except NotImplementedError:\n"\ + " print('Not implement the set_high_critical_threshold method!')\n"\ + "print('Apply the new high critical threshold successfully.')\n"\ + "\n".format(args.high_crit_threshold, args.thermal) + + if set_threshold_code == "": + return + + all_code = "{}{}{}".format(init_chassis_code, looking_for_thermal_code.format(args.thermal, args.thermal), set_threshold_code) + + status, output = getstatusoutput_noshell(["docker", "exec", "pmon", "python3", "-c", all_code]) + print(output) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/control b/platform/broadcom/sonic-platform-modules-accton/debian/control index 5206571729..4dd8be9f82 100644 --- a/platform/broadcom/sonic-platform-modules-accton/debian/control +++ b/platform/broadcom/sonic-platform-modules-accton/debian/control @@ -96,3 +96,7 @@ Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as4625-54t Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-accton-as9737-32db +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/rules b/platform/broadcom/sonic-platform-modules-accton/debian/rules index 18fa0582ef..9c737a9e86 100644 --- a/platform/broadcom/sonic-platform-modules-accton/debian/rules +++ b/platform/broadcom/sonic-platform-modules-accton/debian/rules @@ -22,7 +22,7 @@ MOD_SRC_DIR:= $(shell pwd) MODULE_DIRS := as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x MODULE_DIRS += as7326-56x as6712-32x as7726-32x as4630-54pe as4630-54te minipack as5812-54x MODULE_DIRS += as5835-54x as9716-32d as9726-32d as9736-64d as5835-54t as7312-54xs as7315-27xb as5812-54t -MODULE_DIRS += as4625-54p as4625-54t +MODULE_DIRS += as4625-54p as4625-54t as9737-32db MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/sonic-platform-accton-as9737-32db.install b/platform/broadcom/sonic-platform-modules-accton/debian/sonic-platform-accton-as9737-32db.install new file mode 100644 index 0000000000..1885c68db8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/debian/sonic-platform-accton-as9737-32db.install @@ -0,0 +1,2 @@ +as9737-32db/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-accton_as9737_32db-r0 +