diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/V682-48x8c-board.json b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/V682-48x8c-board.json new file mode 100644 index 00000000000..435ab418aab --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/V682-48x8c-board.json @@ -0,0 +1,597 @@ +{ + "macleds" : { + "polarity" : 1, + "cpumode" : 1, + "maps" : [ + { + "port_id" : 32, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port0/brightness" + }, + { + "port_id" : 33, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port1/brightness" + }, + { + "port_id" : 34, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port2/brightness" + }, + { + "port_id" : 35, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port3/brightness" + }, + { + "port_id" : 0, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port4/brightness" + }, + { + "port_id" : 4, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port5/brightness" + }, + { + "port_id" : 8, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port6/brightness" + }, + { + "port_id" : 12, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port7/brightness" + }, + { + "port_id" : 16, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port8/brightness" + }, + { + "port_id" : 20, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port9/brightness" + }, + { + "port_id" : 24, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port10/brightness" + }, + { + "port_id" : 28, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port11/brightness" + }, + { + "port_id" : 40, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port12/brightness" + }, + { + "port_id" : 44, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port13/brightness" + }, + { + "port_id" : 48, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port14/brightness" + }, + { + "port_id" : 52, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port15/brightness" + }, + { + "port_id" : 56, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port16/brightness" + }, + { + "port_id" : 60, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port17/brightness" + }, + { + "port_id" : 64, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port18/brightness" + }, + { + "port_id" : 68, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port19/brightness" + }, + { + "port_id" : 72, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port20/brightness" + }, + { + "port_id" : 73, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port21/brightness" + }, + { + "port_id" : 74, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port22/brightness" + }, + { + "port_id" : 75, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port23/brightness" + }, + + { + "port_id" : 120, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port48/brightness" + }, + { + "port_id" : 124, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port49/brightness" + }, + { + "port_id" : 80, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port50/brightness" + }, + { + "port_id" : 84, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port51/brightness" + }, + + { + "port_id" : 232, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port24/brightness" + }, + { + "port_id" : 233, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port25/brightness" + }, + { + "port_id" : 234, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port26/brightness" + }, + { + "port_id" : 235, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port27/brightness" + }, + { + "port_id" : 200, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port28/brightness" + }, + { + "port_id" : 204, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port29/brightness" + }, + { + "port_id" : 208, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port30/brightness" + }, + { + "port_id" : 212, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port31/brightness" + }, + { + "port_id" : 216, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port32/brightness" + }, + { + "port_id" : 220, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port33/brightness" + }, + { + "port_id" : 224, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port34/brightness" + }, + { + "port_id" : 228, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port35/brightness" + }, + { + "port_id" : 160, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port36/brightness" + }, + { + "port_id" : 164, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port37/brightness" + }, + { + "port_id" : 168, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port38/brightness" + }, + { + "port_id" : 172, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port39/brightness" + }, + { + "port_id" : 176, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port40/brightness" + }, + { + "port_id" : 180, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port41/brightness" + }, + { + "port_id" : 184, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port42/brightness" + }, + { + "port_id" : 188, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port43/brightness" + }, + { + "port_id" : 192, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port44/brightness" + }, + { + "port_id" : 193, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port45/brightness" + }, + { + "port_id" : 194, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port46/brightness" + }, + { + "port_id" : 195, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port47/brightness" + }, + + { + "port_id" : 240, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port52/brightness" + }, + { + "port_id" : 244, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 1, + "sysfs_path" : "/sys/class/leds/port53/brightness" + }, + { + "port_id" : 280, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 1, + "sysfs_path" : "/sys/class/leds/port54/brightness" + }, + { + "port_id" : 284, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 1, + "sysfs_path" : "/sys/class/leds/port55/brightness" + }, + + { + "port_id" : 161, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_1_FORCE_OFF", + "fixed" : 0 + }, + { + "port_id" : 162, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_1_FORCE_OFF", + "fixed" : 0 + }, + { + "port_id" : 165, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_1_FORCE_OFF", + "fixed" : 0 + }, + { + "port_id" : 166, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_1_FORCE_OFF", + "fixed" : 0 + } + ] + }, + "ffe" : { + "board_material" : "BOARD_MATERIAL_M4", + "config" : [ + { + "serdes_id" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75], + "is_dac" : 1, + "speed" : [10000, 25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [2, -13, 46, 0, 0] + }, + { + "serdes_id" : [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 50, 52, 53, 54, 55, 56, 57, 58, 59], + "is_dac" : 0, + "speed" : [10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 46, -8, 0] + }, + { + "serdes_id" : [0, 1, 16, 17, 18, 19, 20, 21, 22, 23], + "is_dac" : 0, + "speed" : [10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -6, 0] + }, + { + "serdes_id" : [24, 25, 26, 27, 72, 74, 75], + "is_dac" : 0, + "speed" : [10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -4, 0] + }, + { + "serdes_id" : [48, 49, 51, 64, 65, 66, 67, 68, 69, 70, 71, 73], + "is_dac" : 0, + "speed" : [10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -6, 0] + }, + { + "serdes_id" : [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 50, 52, 53, 54, 55, 56, 57, 58, 59], + "is_dac" : 0, + "speed" : [25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 44, -14, -1] + }, + { + "serdes_id" : [0, 1, 16, 17, 18, 19, 20, 21, 22, 23], + "is_dac" : 0, + "speed" : [25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 38, -10, -2] + }, + { + "serdes_id" : [24, 25, 26, 27, 72, 74, 75], + "is_dac" : 0, + "speed" : [25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 36, -6, -2] + }, + { + "serdes_id" : [48, 49, 51, 64, 65, 66, 67, 68, 69, 70, 71, 73], + "is_dac" : 0, + "speed" : [25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 38, -10, -2] + }, + { + "serdes_id" : [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95], + "is_dac" : 1, + "speed" : [100000, 25000, 40000, 10000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [2, -13, 46, 0, 0] + }, + { + "serdes_id" : [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95], + "is_dac" : 1, + "speed" : [1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -4, 0] + }, + { + "serdes_id" : [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95], + "is_dac" : 0, + "speed" : [100000, 25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 36, -6, -2] + }, + { + "serdes_id" : [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95], + "is_dac" : 0, + "speed" : [40000, 10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -4, 0] + } + ] + } +} diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/V682-48x8c-chip-profile.txt b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/V682-48x8c-chip-profile.txt new file mode 100644 index 00000000000..9fadec5d5f6 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/V682-48x8c-chip-profile.txt @@ -0,0 +1,116 @@ +#----------------- SDK Feature Support -------------- +[MPLS_SUPPORT] = 1; +[APS_SUPPORT] = 1; +[OAM_SUPPORT] = 1; +[PTP_SUPPORT] = 0; +[SYNCE_SUPPORT] = 0; +[STACKING_SUPPORT] = 1; +[BPE_SUPPORT] = 0; +[IPFIX_SUPPORT] = 1; +[MONITOR_SUPPORT] = 1; +[OVERLAY_SUPPORT] = 1; +[EFD_SUPPORT] = 1; +[FCOE_SUPPORT] = 0; +[TRILL_SUPPORT] = 0; +[WLAN_SUPPORT] = 0; +[NPM_SUPPORT] = 1; +[DOT1AE_SUPPORT] = 1; +[SRV6_SUPPORT] = 0; +[DTEL_SUPPORT] = 1; +[FLEXE_SUPPORT] = 0; +[FDBTOKEN_SUPPORT] = 1; + +#----------------- Chip Init Parameter -------------- +#Local chip number and global chip id +[Local chip_num] = 1 +[Local chip0] = 0 +[Local chip1] = 1 +[Port_phy_mapping] = 1 + +#Cut through mode 0: Disable; 1:10/40/100G; 2:1/10/100G; 3:1/10/40G; other:Flex, refer to CUT_THROUGH_BITMAP +[CUT_THROUGH_SPEED] = 0 +#Flex cut through mode, speed enable by bitmap, refer to ctc_port_speed_t, Notice: 10M/100M/1G treat as the same speed +[CUT_THROUGH_BITMAP] = 0 + +#Network cpu port +[CPU_NETWORK_PORT_EN] = 0 +[CPU_NETWORK_PORT_ID] = 47 + +#Enable parity error and multi-bit ecc recover +[ECC_RECOVER_EN] = 0 +[TCAM_SCAN_EN] = 0 +[SDB_EN] = 0 + +#----------------- KNET Init Parameter -------------- +[KNET_EN] = 0 + +#----------------- FTM Init Parameter -------------- +#0: not use; 1: default; 2: layer3; 3: ipv6 +[FTM Profile] = 0 + +#----------------- Interrupt Init Parameter -------------- +#0: pin, 1: msi +[Interrupt_mode] = 1 + +#----------------- NextHop Init Parameter -------------- +#0: SDK work in pizzbox (single chip system), 1: SDK work in multi-chip system +[Nexthop Edit Mode] = 0 +[External Nexthop Number] = 16384 +[MPLS Tunnel Number] = 1024 +[H_ECMP_EN] = 0 + +#----------------- L2 Init Parameter -------------- +[FDB Hw Learning] = 0 +[Logic Port Num] = 1024 +#0: 128 instance per port, 1: 64 instance per port, 2: 32 instance per port +[STP MODE] = 0 +[MAX_FID_NUM] = 5120 + +#----------------- Stats Init Parameter -------------- +[STATS_QUEUE_DEQ_EN] = 1 +[STATS_QUEUE_DROP_EN] = 1 +[STATS_FLOW_POLICER_EN] = 1 +[STATS_VLAN_EN] = 0 +[STATS_VRF_EN] = 0 +[STATS_POLICER_NUM] = 1024 +[STATS_PORT_EN] = 0 +[STATS_ECMP_EN] = 0 + +#----------------- BPE Init Parameter -------------- +[BPE_BR_PORT_EXTENDER_EN] = 0 +[BPE_BR_UC_MAX_ECID] = 1024 +[BPE_BR_MC_MAX_ECID] = 4096 +[BPE_BR_PORT_BASE] = 0 + +#----------------- Ipuc Init Parameter -------------- +#0: tcam use prefix 16; 1: tcam use prefix 8 +[IPUC_TCAM_PREFIX_8] = 1 + +#----------------- QoS Init Parameter -------------- +#QoS policer number support 1K/2K/4K/8K, default 4K +[QOS_POLICER_NUM] = 4096 +#qos queue mode 0: 8(basic)+1(cpu) +#qos queue mode 1: 8(basic)+1(span)+1(mcast) +[QOS_QUEUE_MODE] = 0 +#QoS port extend queue number support 0/4, default 0 +[QOS_PORT_EXT_QUEUE_NUM] = 0 +#QoS CPU reason queue number support 128/64/32, default 128 +[QOS_CPU_QUEUE_NUM] = 128 +[QOS_INGRESS_VLAN_POLICER_NUM] = 0 +[QOS_EGRESS_VLAN_POLICER_NUM] = 0 +#QoS the max number of igs/egs reserve macro policer,which ACL entry support micro and macro at the same time +[QOS_INGRESS_MACRO_POLICER_NUM] = 0 +[QOS_EGRESS_MACRO_POLICER_NUM] = 0 +#QOS service queue mode, default 0,0:logic scr port + dstport enq 1:service id + dstport enq +[QOS_SERVICE_QUEUE_MODE] = 0 +#mode 0:svc policer used for service policer +#mode 1:svc policer used for stormctl +[QOS_POLICER_SVC_MODE] = 0 + +#----------------- Stacking Init Parameter -------------- +#0: normal mode; 1: spine-leaf mode +[FABRIC MODE] = 0 +[STACKING VERSION] = 1 +#----------------- LB hash Init Parameter -------------- +#0: support 4 select num; 1: support 8 select num; only TM2 support mode 1 +[LB_HASH_MODE] = 0 diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/V682-48x8c-datapath.txt b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/V682-48x8c-datapath.txt new file mode 100644 index 00000000000..c77ae26c389 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/V682-48x8c-datapath.txt @@ -0,0 +1,1022 @@ +#SERDES_MODE: 0-NONE, 1-XFI, 2-SGMII, 3-Not Support, 4-QSGMII, 7-XLG, 8-100GR4, 9-SGMII2G5 +# 13-XXVG, 14-50GR2, 16-50GR1, 17-100GR2, 18-200G, 19-400G +#SERDES_POLY: 0-No Inverse, 1-Inverse +#SERDES_SWITCH: 0-Not Support Dynamic Switch, 1-Support Dynamic Switch exclude QSGMII, 2-Support Dynamic Switch include QSGMII + +[CORE_PLL] = 1050 +[DP0_FLEXE_CLIENT_NUM] = 0 +[DP1_FLEXE_CLIENT_NUM] = 0 +[DP0_XPIPE_PORT_NUM] = 0 +[DP1_XPIPE_PORT_NUM] = 0 +[DOT1AE_ENABLE] = 1 + +#{ +[SERDES_ITEM] + +[SERDES_ID] = 7 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 0 + +[SERDES_ID] = 6 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 1 + +[SERDES_ID] = 5 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 2 + +[SERDES_ID] = 4 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 3 + +[SERDES_ID] = 3 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 4 + +[SERDES_ID] = 2 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 5 + +[SERDES_ID] = 1 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 6 + +[SERDES_ID] = 0 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 7 + +[SERDES_ID] = 11 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 8 + +[SERDES_ID] = 10 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 9 + +[SERDES_ID] = 9 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 10 + +[SERDES_ID] = 8 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 11 + +[SERDES_ID] = 12 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 12 + +[SERDES_ID] = 13 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 13 + +[SERDES_ID] = 14 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 14 + +[SERDES_ID] = 15 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 15 + +[SERDES_ID] = 16 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 16 + +[SERDES_ID] = 17 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 17 + +[SERDES_ID] = 18 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 18 + +[SERDES_ID] = 19 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 19 + +[SERDES_ID] = 20 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 20 + +[SERDES_ID] = 21 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 21 + +[SERDES_ID] = 22 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 22 + +[SERDES_ID] = 23 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 23 + +[SERDES_ID] = 24 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 24 + +[SERDES_ID] = 25 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 25 + +[SERDES_ID] = 26 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 26 + +[SERDES_ID] = 27 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 27 + +[SERDES_ID] = 28 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 28 + +[SERDES_ID] = 29 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 29 + +[SERDES_ID] = 30 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 30 + +[SERDES_ID] = 31 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 31 + +[SERDES_ID] = 36 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 32 + +[SERDES_ID] = 37 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 33 + +[SERDES_ID] = 38 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 34 + +[SERDES_ID] = 32 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 35 + +[SERDES_ID] = 39 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 36 + +[SERDES_ID] = 34 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 37 + +[SERDES_ID] = 35 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 38 + +[SERDES_ID] = 33 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 39 + +[SERDES_ID] = 40 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 40 + +[SERDES_ID] = 44 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 41 + +[SERDES_ID] = 42 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 42 + +[SERDES_ID] = 41 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 43 + +[SERDES_ID] = 43 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 44 + +[SERDES_ID] = 46 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 45 + +[SERDES_ID] = 47 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 46 + +[SERDES_ID] = 45 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 47 + +[SERDES_ID] = 49 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 48 + +[SERDES_ID] = 48 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 49 + +[SERDES_ID] = 51 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 50 + +[SERDES_ID] = 50 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 51 + +[SERDES_ID] = 53 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 52 + +[SERDES_ID] = 52 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 53 + +[SERDES_ID] = 55 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 54 + +[SERDES_ID] = 54 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 55 + +[SERDES_ID] = 57 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 56 + +[SERDES_ID] = 56 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 57 + +[SERDES_ID] = 59 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 58 + +[SERDES_ID] = 58 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 59 + +[SERDES_ID] = 60 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 60 + +[SERDES_ID] = 61 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 61 + +[SERDES_ID] = 62 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 62 + +[SERDES_ID] = 63 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 63 + +[SERDES_ID] = 70 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 64 + +[SERDES_ID] = 71 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 65 + +[SERDES_ID] = 68 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 66 + +[SERDES_ID] = 69 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 67 + +[SERDES_ID] = 66 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 68 + +[SERDES_ID] = 67 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 69 + +[SERDES_ID] = 64 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 70 + +[SERDES_ID] = 65 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 71 + +[SERDES_ID] = 74 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 72 + +[SERDES_ID] = 75 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 73 + +[SERDES_ID] = 72 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 74 + +[SERDES_ID] = 73 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 75 + +[SERDES_ID] = 76 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 76 + +[SERDES_ID] = 77 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 77 + +[SERDES_ID] = 78 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 78 + +[SERDES_ID] = 79 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 79 + +[SERDES_ID] = 83 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 80 + +[SERDES_ID] = 81 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 81 + +[SERDES_ID] = 87 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 82 + +[SERDES_ID] = 82 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 83 + +[SERDES_ID] = 86 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 84 + +[SERDES_ID] = 80 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 85 + +[SERDES_ID] = 84 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 86 + +[SERDES_ID] = 85 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 87 + +[SERDES_ID] = 95 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 88 + +[SERDES_ID] = 93 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 89 + +[SERDES_ID] = 91 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 90 + +[SERDES_ID] = 94 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 91 + +[SERDES_ID] = 90 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 92 + +[SERDES_ID] = 89 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 93 + +[SERDES_ID] = 88 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 94 + +[SERDES_ID] = 92 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 95 + +[SERDES_ID] = 96 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 96 + +[SERDES_ID] = 97 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 97 + +[SERDES_ID] = 98 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 98 + +[SERDES_ID] = 99 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 99 + +#} +[SERDES_TO_LPORT] +#{ +#index |serdes |QSGMII |SGMII/SGMII2G5/XFI/XXVG |XLG |50GR1 |50GR2 |100GR4 |100GR2 |200G |400G +#----------|----------|------------|------------------------|--------|--------|--------|--------|--------|--------|-------- +#0 |7 |NA |0 |0 |0 |0 |0 |0 |NA |NA +#1 |6 |NA |1 |0 |NA |0 |0 |NA |NA |NA +#2 |5 |NA |2 |0 |2 |2 |0 |0 |NA |NA +#3 |4 |NA |3 |0 |NA |2 |0 |NA |NA |NA +#4 |3 |NA |4 |4 |4 |4 |4 |4 |NA |NA +#5 |2 |NA |5 |4 |NA |4 |4 |NA |NA |NA +#6 |1 |NA |6 |4 |6 |6 |4 |4 |NA |NA +#7 |0 |NA |7 |4 |NA |6 |4 |NA |NA |NA +#8 |11 |NA |8 |8 |8 |8 |8 |8 |NA |NA +#9 |10 |NA |9 |8 |NA |8 |8 |NA |NA |NA +#10 |9 |NA |10 |8 |10 |10 |8 |8 |NA |NA +#11 |8 |NA |11 |8 |NA |10 |8 |NA |NA |NA +#12 |12 |NA |12 |12 |12 |12 |12 |12 |NA |NA +#13 |13 |NA |13 |12 |NA |12 |12 |NA |NA |NA +#14 |14 |NA |14 |12 |14 |14 |12 |12 |NA |NA +#15 |15 |NA |15 |12 |NA |14 |12 |NA |NA |NA +#16 |16 |NA |16 |16 |16 |16 |16 |16 |NA |NA +#17 |17 |NA |17 |16 |NA |16 |16 |NA |NA |NA +#18 |18 |NA |18 |16 |18 |18 |16 |16 |NA |NA +#19 |19 |NA |19 |16 |NA |18 |16 |NA |NA |NA +#20 |20 |NA |20 |20 |20 |20 |20 |20 |NA |NA +#21 |21 |NA |21 |20 |NA |20 |20 |NA |NA |NA +#22 |22 |NA |22 |20 |22 |22 |20 |20 |NA |NA +#23 |23 |NA |23 |20 |NA |22 |20 |NA |NA |NA +#24 |24 |NA |24 |24 |24 |24 |24 |24 |NA |NA +#25 |25 |NA |25 |24 |NA |24 |24 |NA |NA |NA +#26 |26 |NA |26 |24 |26 |26 |24 |24 |NA |NA +#27 |27 |NA |27 |24 |NA |26 |24 |NA |NA |NA +#28 |28 |NA |28 |28 |28 |28 |28 |28 |NA |NA +#29 |29 |NA |29 |28 |NA |28 |28 |NA |NA |NA +#30 |30 |NA |30 |28 |30 |30 |28 |28 |NA |NA +#31 |31 |NA |31 |28 |NA |30 |28 |NA |NA |NA +#32 |36 |NA |32 |32 |32 |32 |32 |32 |32 |32 +#33 |37 |NA |33 |32 |33 |32 |32 |32 |32 |32 +#34 |38 |NA |34 |32 |34 |34 |32 |34 |32 |32 +#35 |32 |NA |35 |32 |35 |34 |32 |34 |32 |32 +#36 |39 |NA |36 |36 |36 |36 |36 |36 |36 |32 +#37 |34 |NA |37 |36 |37 |36 |36 |36 |36 |32 +#38 |35 |NA |38 |36 |38 |38 |36 |38 |36 |32 +#39 |33 |NA |39 |36 |39 |38 |36 |38 |36 |32 +#40 |40 |NA |40 |40 |40 |40 |40 |40 |40 |40 +#41 |44 |NA |41 |40 |41 |40 |40 |40 |40 |40 +#42 |42 |NA |42 |40 |42 |42 |40 |42 |40 |40 +#43 |41 |NA |43 |40 |43 |42 |40 |42 |40 |40 +#44 |43 |NA |44 |44 |44 |44 |44 |44 |44 |40 +#45 |46 |NA |45 |44 |45 |44 |44 |44 |44 |40 +#46 |47 |NA |46 |44 |46 |46 |44 |46 |44 |40 +#47 |45 |NA |47 |44 |47 |46 |44 |46 |44 |40 +#48 |49 |NA |48 |48 |48 |48 |48 |48 |NA |NA +#49 |48 |NA |49 |48 |NA |48 |48 |NA |NA |NA +#50 |51 |NA |50 |48 |50 |50 |48 |48 |NA |NA +#51 |50 |NA |51 |48 |NA |50 |48 |NA |NA |NA +#52 |53 |NA |52 |52 |52 |52 |52 |52 |NA |NA +#53 |52 |NA |53 |52 |NA |52 |52 |NA |NA |NA +#54 |55 |NA |54 |52 |54 |54 |52 |52 |NA |NA +#55 |54 |NA |55 |52 |NA |54 |52 |NA |NA |NA +#56 |57 |NA |56 |56 |56 |56 |56 |56 |NA |NA +#57 |56 |NA |57 |56 |NA |56 |56 |NA |NA |NA +#58 |59 |NA |58 |56 |58 |58 |56 |56 |NA |NA +#59 |58 |NA |59 |56 |NA |58 |56 |NA |NA |NA +#60 |60 |NA |60 |60 |60 |60 |60 |60 |NA |NA +#61 |61 |NA |61 |60 |NA |60 |60 |NA |NA |NA +#62 |62 |NA |62 |60 |62 |62 |60 |60 |NA |NA +#63 |63 |NA |63 |60 |NA |62 |60 |NA |NA |NA +#64 |70 |NA |64 |64 |64 |64 |64 |64 |NA |NA +#65 |71 |NA |65 |64 |NA |64 |64 |NA |NA |NA +#66 |68 |NA |66 |64 |66 |66 |64 |64 |NA |NA +#67 |69 |NA |67 |64 |NA |66 |64 |NA |NA |NA +#68 |66 |NA |68 |68 |68 |68 |68 |68 |NA |NA +#69 |67 |NA |69 |68 |NA |68 |68 |NA |NA |NA +#70 |64 |NA |70 |68 |70 |70 |68 |68 |NA |NA +#71 |65 |NA |71 |68 |NA |70 |68 |NA |NA |NA +#72 |74 |NA |72 |72 |72 |72 |72 |72 |NA |NA +#73 |75 |NA |73 |72 |NA |72 |72 |NA |NA |NA +#74 |72 |NA |74 |72 |74 |74 |72 |72 |NA |NA +#75 |73 |NA |75 |72 |NA |74 |72 |NA |NA |NA +#76 |76 |NA |76 |76 |76 |76 |76 |76 |NA |NA +#77 |77 |NA |77 |76 |NA |76 |76 |NA |NA |NA +#78 |78 |NA |78 |76 |78 |78 |76 |76 |NA |NA +#79 |79 |NA |79 |76 |NA |78 |76 |NA |NA |NA +#80 |83 |NA |80 |80 |80 |80 |80 |80 |80 |80 +#81 |81 |NA |81 |80 |81 |80 |80 |80 |80 |80 +#82 |87 |NA |82 |80 |82 |82 |80 |82 |80 |80 +#83 |82 |NA |83 |80 |83 |82 |80 |82 |80 |80 +#84 |86 |NA |84 |84 |84 |84 |84 |84 |84 |80 +#85 |80 |NA |85 |84 |85 |84 |84 |84 |84 |80 +#86 |84 |NA |86 |84 |86 |86 |84 |86 |84 |80 +#87 |85 |NA |87 |84 |87 |86 |84 |86 |84 |80 +#88 |95 |NA |88 |88 |88 |88 |88 |88 |88 |88 +#89 |93 |NA |89 |88 |89 |88 |88 |88 |88 |88 +#90 |91 |NA |90 |88 |90 |90 |88 |90 |88 |88 +#91 |94 |NA |91 |88 |91 |90 |88 |90 |88 |88 +#92 |90 |NA |92 |92 |92 |92 |92 |92 |92 |88 +#93 |89 |NA |93 |92 |93 |92 |92 |92 |92 |88 +#94 |88 |NA |94 |92 |94 |94 |92 |94 |92 |88 +#95 |92 |NA |95 |92 |95 |94 |92 |94 |92 |88 +#96 |96 |NA |232 |232 |232 |232 |232 |232 |NA |NA +#97 |97 |NA |233 |232 |NA |232 |232 |NA |NA |NA +#98 |98 |NA |243 |232 |243 |243 |232 |232 |NA |NA +#99 |99 |NA |244 |232 |NA |243 |232 |NA |NA |NA +#} + diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/buffers.json.j2 b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/buffers.json.j2 new file mode 100644 index 00000000000..08e21e428b6 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/buffers.json.j2 @@ -0,0 +1,70 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(1,default_ports_num+1) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + } +} + diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/pg_profile_lookup.ini b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/pg_profile_lookup.ini new file mode 100644 index 00000000000..a65244e69b5 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/pg_profile_lookup.ini @@ -0,0 +1,21 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 34816 18432 16384 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 34816 18432 16384 0 + 40000 5m 34816 18432 16384 0 + 50000 5m 34816 18432 16384 0 + 100000 5m 36864 18432 18432 0 + 1000 40m 36864 18432 18432 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 39936 18432 21504 0 + 40000 40m 41984 18432 23552 0 + 50000 40m 41984 18432 23552 0 + 100000 40m 54272 18432 35840 0 + 1000 300m 49152 18432 30720 0 + 10000 300m 49152 18432 30720 0 + 25000 300m 71680 18432 53248 0 + 40000 300m 94208 18432 75776 0 + 50000 300m 94208 18432 75776 0 + 100000 300m 184320 18432 165888 0 + diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/port_config.ini b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/port_config.ini new file mode 100644 index 00000000000..1dca36d97f6 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed fec +Ethernet0 32 eth-0-1 0 10000 none +Ethernet1 33 eth-0-2 1 10000 none +Ethernet2 34 eth-0-3 2 10000 none +Ethernet3 35 eth-0-4 3 10000 none +Ethernet4 0 eth-0-5 4 10000 none +Ethernet5 4 eth-0-6 5 10000 none +Ethernet6 8 eth-0-7 6 10000 none +Ethernet7 12 eth-0-8 7 10000 none +Ethernet8 16 eth-0-9 8 10000 none +Ethernet9 20 eth-0-10 9 10000 none +Ethernet10 24 eth-0-11 10 10000 none +Ethernet11 28 eth-0-12 11 10000 none +Ethernet12 40 eth-0-13 12 10000 none +Ethernet13 44 eth-0-14 13 10000 none +Ethernet14 48 eth-0-15 14 10000 none +Ethernet15 52 eth-0-16 15 10000 none +Ethernet16 56 eth-0-17 16 10000 none +Ethernet17 60 eth-0-18 17 10000 none +Ethernet18 64 eth-0-19 18 10000 none +Ethernet19 68 eth-0-20 19 10000 none +Ethernet20 72 eth-0-21 20 10000 none +Ethernet21 73 eth-0-22 21 10000 none +Ethernet22 74 eth-0-23 22 10000 none +Ethernet23 75 eth-0-24 23 10000 none +Ethernet24 232 eth-0-25 24 10000 none +Ethernet25 233 eth-0-26 25 10000 none +Ethernet26 234 eth-0-27 26 10000 none +Ethernet27 235 eth-0-28 27 10000 none +Ethernet28 200 eth-0-29 28 10000 none +Ethernet29 204 eth-0-30 29 10000 none +Ethernet30 208 eth-0-31 30 10000 none +Ethernet31 212 eth-0-32 31 10000 none +Ethernet32 216 eth-0-33 32 10000 none +Ethernet33 220 eth-0-34 33 10000 none +Ethernet34 224 eth-0-35 34 10000 none +Ethernet35 228 eth-0-36 35 10000 none +Ethernet36 160 eth-0-37 36 10000 none +Ethernet37 164 eth-0-38 37 10000 none +Ethernet38 168 eth-0-39 38 10000 none +Ethernet39 172 eth-0-40 39 10000 none +Ethernet40 176 eth-0-41 40 10000 none +Ethernet41 180 eth-0-42 41 10000 none +Ethernet42 184 eth-0-43 42 10000 none +Ethernet43 188 eth-0-44 43 10000 none +Ethernet44 192 eth-0-45 44 10000 none +Ethernet45 193 eth-0-46 45 10000 none +Ethernet46 194 eth-0-47 46 10000 none +Ethernet47 195 eth-0-48 47 10000 none +Ethernet48 120,121,122,123 eth-0-49 48 100000 none +Ethernet49 124,125,126,127 eth-0-50 49 100000 none +Ethernet50 80,81,82,83 eth-0-51 50 100000 none +Ethernet51 84,85,86,87 eth-0-52 51 100000 none +Ethernet52 240,241,242,243 eth-0-53 52 100000 none +Ethernet53 244,245,246,247 eth-0-54 53 100000 none +Ethernet54 280,281,282,283 eth-0-55 54 100000 none +Ethernet55 284,285,286,287 eth-0-56 55 100000 none diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/qos.json.j2 b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/qos.json.j2 new file mode 100644 index 00000000000..3e548325ea3 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/sai.profile b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/sai.profile new file mode 100644 index 00000000000..314a045bffc --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/V682-48x8c/sai.profile @@ -0,0 +1,3 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/V682-48x8c-chip-profile.txt +SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/usr/share/sonic/hwsku/V682-48x8c-datapath.txt +SAI_PLATFORM_CFG_FILE=/usr/share/sonic/hwsku/V682-48x8c-board.json diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/default_sku b/device/centec/x86_64-centec_v682_48x8c-r0/default_sku new file mode 100644 index 00000000000..a3168b7a0c3 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/default_sku @@ -0,0 +1 @@ +V682-48x8c l2 diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/fancontrol b/device/centec/x86_64-centec_v682_48x8c-r0/fancontrol new file mode 100644 index 00000000000..07420a6dba0 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/fancontrol @@ -0,0 +1,10 @@ +# Configuration file generated by pwmconfig, changes will be lost +INTERVAL=10 +DEVPATH=hwmon1=devices/pci0000:00/0000:00:1f.3/i2c-0/0-0049 hwmon2=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-9/9-002c hwmon3=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-9/9-002e +DEVNAME=hwmon1=lm77 hwmon2=adt7470 hwmon3=adt7470 +FCTEMPS=hwmon2/pwm1=hwmon1/temp1_input hwmon2/pwm2=hwmon1/temp1_input hwmon2/pwm3=hwmon1/temp1_input hwmon2/pwm4=hwmon1/temp1_input hwmon3/pwm1=hwmon1/temp1_input hwmon3/pwm2=hwmon1/temp1_input hwmon3/pwm3=hwmon1/temp1_input hwmon3/pwm4=hwmon1/temp1_input +FCFANS=hwmon2/pwm1=hwmon2/fan1_input hwmon2/pwm2=hwmon2/fan2_input hwmon2/pwm3=hwmon2/fan3_input hwmon2/pwm4=hwmon2/fan4_input hwmon3/pwm1=hwmon3/fan1_input hwmon3/pwm2=hwmon3/fan2_input hwmon3/pwm3=hwmon3/fan3_input hwmon3/pwm4=hwmon3/fan4_input +MINTEMP=hwmon2/pwm1=20 hwmon2/pwm2=20 hwmon2/pwm3=20 hwmon2/pwm4=20 hwmon3/pwm1=20 hwmon3/pwm2=20 hwmon3/pwm3=20 hwmon3/pwm4=20 +MAXTEMP=hwmon2/pwm1=60 hwmon2/pwm2=60 hwmon2/pwm3=60 hwmon2/pwm4=60 hwmon3/pwm1=60 hwmon3/pwm2=60 hwmon3/pwm3=60 hwmon3/pwm4=60 +MINSTART=hwmon2/pwm1=150 hwmon2/pwm2=150 hwmon2/pwm3=150 hwmon2/pwm4=150 hwmon3/pwm1=150 hwmon3/pwm2=150 hwmon3/pwm3=150 hwmon3/pwm4=150 +MINSTOP=hwmon2/pwm1=0 hwmon2/pwm2=0 hwmon2/pwm3=0 hwmon2/pwm4=0 hwmon3/pwm1=0 hwmon3/pwm2=0 hwmon3/pwm3=0 hwmon3/pwm4=0 diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/installer.conf b/device/centec/x86_64-centec_v682_48x8c-r0/installer.conf new file mode 100644 index 00000000000..3b97b7f99da --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/installer.conf @@ -0,0 +1 @@ +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="iommu=pt" diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/pcie.yaml b/device/centec/x86_64-centec_v682_48x8c-r0/pcie.yaml new file mode 100644 index 00000000000..5e00e24bc07 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/pcie.yaml @@ -0,0 +1,5 @@ +- bus: '05' + dev: '00' + fn: '0' + id: 8180 + name: 'Communication controller: Device cb10:8180' diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/platform_asic b/device/centec/x86_64-centec_v682_48x8c-r0/platform_asic new file mode 100644 index 00000000000..74dac3505ea --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/platform_asic @@ -0,0 +1 @@ +centec diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/platform_components.json b/device/centec/x86_64-centec_v682_48x8c-r0/platform_components.json new file mode 100644 index 00000000000..4eb9f0277b9 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/platform_components.json @@ -0,0 +1,8 @@ +{ + "chassis": { + "V682-48X8C": { + "component": { + } + } + } +} diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/platform_reboot b/device/centec/x86_64-centec_v682_48x8c-r0/platform_reboot new file mode 100755 index 00000000000..5e49eecb61c --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/platform_reboot @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import time + +def main(): + os.system('hwclock -w -f /dev/rtc1') + time.sleep(1) + + os.system('i2cset -y 0 0x36 0x23 0') + time.sleep(1) + os.system('i2cset -y 0 0x36 0x23 1') + +if __name__ == '__main__': + main() diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/plugins/eeprom.py b/device/centec/x86_64-centec_v682_48x8c-r0/plugins/eeprom.py new file mode 100644 index 00000000000..7093e4b0f82 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/plugins/eeprom.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +############################################################################# +# Centec V682-48X8C +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os + from sonic_eeprom import eeprom_tlvinfo + from sonic_py_common import device_info +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + self.eeprom_path = platform_path + '/eeprom_file' + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/plugins/led_control.py b/device/centec/x86_64-centec_v682_48x8c-r0/plugins/led_control.py new file mode 100644 index 00000000000..b787320d784 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/plugins/led_control.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + import os + import re + import syslog + import collections + from sonic_led.led_control_base import LedControlBase + from sonic_py_common import device_info + from subprocess import Popen +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +def DBG_PRINT(str): + syslog.openlog("centec-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Constructor + def __init__(self): + + self.mac_to_led = { + 32 : 0, + 33 : 1, + 34 : 2, + 35 : 3, + 0 : 4, + 4 : 5, + 8 : 6, + 12 : 7, + 16 : 8, + 20 : 9, + 24 : 10, + 28 : 11, + 40 : 12, + 44 : 13, + 48 : 14, + 52 : 15, + 56 : 16, + 60 : 17, + 64 : 18, + 68 : 19, + 72 : 20, + 73 : 21, + 74 : 22, + 75 : 23, + 232: 24, + 233: 25, + 234: 26, + 235: 27, + 200: 28, + 204: 29, + 208: 30, + 212: 31, + 216: 32, + 220: 33, + 224: 34, + 228: 35, + 160: 36, + 164: 37, + 168: 38, + 172: 39, + 176: 40, + 180: 41, + 184: 42, + 188: 43, + 192: 44, + 193: 45, + 194: 46, + 195: 47, + 120: 48, + 121: -1, + 122: -1, + 123: -1, + 124: 49, + 125: -1, + 126: -1, + 127: -1, + 80 : 50, + 81 : -1, + 82 : -1, + 83 : -1, + 84 : 51, + 85 : -1, + 86 : -1, + 87 : -1, + 240: 52, + 241: -1, + 242: -1, + 243: -1, + 244: 53, + 245: -1, + 246: -1, + 247: -1, + 280: 54, + 281: -1, + 282: -1, + 283: -1, + 284: 55, + 285: -1, + 286: -1, + 287: -1, + } + + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + port_config_file = "/".join([platform_path, "V682-48x8c", "port_config.ini"]) + try: + f = open(port_config_file) + except: + raise + for line in f: + line.strip() + if re.search('^#', line) is not None: + Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:]) + break + f.close() + f = open(port_config_file) + self._port_cfgs = [Port_cfg(*tuple((line.strip().split()))) + for line in f if re.search('^#', line) is None] + f.close() + + self.LED_MODE_UP = [5, 5] + self.LED_MODE_DOWN = [7, 7] + self.f_led = "/sys/class/leds/{}/brightness" + self._initDefaultConfig() + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + for port_cfg in self._port_cfgs: + if port_name == port_cfg.name: + macs = [int(x) for x in (port_cfg.lanes.split(','))] + led = self.mac_to_led[min(macs)] + if led < 0: + return None + return led + return None + + def _port_state_to_mode(self, port_idx, state): + if state == "up": + return self.LED_MODE_UP[1] if port_idx >= 48 else self.LED_MODE_UP[0] + else: + return self.LED_MODE_DOWN[1] if port_idx >= 48 else self.LED_MODE_DOWN[0] + + def _port_led_mode_update(self, port_idx, ledMode): + with open(self.f_led.format("port{}".format(port_idx)), 'w') as led_file: + led_file.write(str(ledMode)) + + def _initSystemLed(self): + try: + cmd = 'i2cset -y 0 0x36 0x2 0x5' + Popen(cmd, shell=True) + DBG_PRINT("init system led to normal") + cmd = 'i2cset -y 0 0x36 0x3 0x1' + Popen(cmd, shell=True) + DBG_PRINT("init idn led to off") + except IOError as e: + DBG_PRINT(str(e)) + + def _initPanelLed(self): + with open(self.f_led.format("port1"), 'r') as led_file: + shouldInit = (int(led_file.read()) == 0) + + if shouldInit == True: + for port_cfg in self._port_cfgs: + macs = [int(x) for x in (port_cfg.lanes.split(','))] + led = self.mac_to_led[min(macs)] + if led < 0: + continue + defmode = self._port_state_to_mode(led, "down") + with open(self.f_led.format("port{}".format(led)), 'w') as led_file: + led_file.write(str(defmode)) + DBG_PRINT("init port{} led to mode={}".format(led, defmode)) + + def _initDefaultConfig(self): + DBG_PRINT("start init led") + + self._initSystemLed() + self._initPanelLed() + + DBG_PRINT("init led done") + + # Concrete implementation of port_link_state_change() method + def port_link_state_change(self, portname, state): + port_idx = self._port_name_to_index(portname) + if port_idx is None: + return + ledMode = self._port_state_to_mode(port_idx, state) + with open(self.f_led.format("port{}".format(port_idx)), 'r') as led_file: + saveMode = int(led_file.read()) + + if ledMode == saveMode: + return + + self._port_led_mode_update(port_idx, ledMode) + DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode)) diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/plugins/psuutil.py b/device/centec/x86_64-centec_v682_48x8c-r0/plugins/psuutil.py new file mode 100644 index 00000000000..9e311d9b4f5 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/plugins/psuutil.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +############################################################################# +# Centec +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +from subprocess import Popen, PIPE, STDOUT + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + cmd = 'i2cget -y 0 0x36 0x1e' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + powergood = ((status & (1 << (3 * (index - 1) + 2))) != 0) + return powergood + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + cmd = 'i2cget -y 0 0x36 0x1e' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + presence = ((status & (1 << (3 * (index - 1) + 1))) == 0) + return presence diff --git a/device/centec/x86_64-centec_v682_48x8c-r0/pmon_daemon_control.json b/device/centec/x86_64-centec_v682_48x8c-r0/pmon_daemon_control.json new file mode 100644 index 00000000000..0db3279e44b --- /dev/null +++ b/device/centec/x86_64-centec_v682_48x8c-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/V682-48y8c-board.json b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/V682-48y8c-board.json new file mode 100644 index 00000000000..435ab418aab --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/V682-48y8c-board.json @@ -0,0 +1,597 @@ +{ + "macleds" : { + "polarity" : 1, + "cpumode" : 1, + "maps" : [ + { + "port_id" : 32, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port0/brightness" + }, + { + "port_id" : 33, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port1/brightness" + }, + { + "port_id" : 34, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port2/brightness" + }, + { + "port_id" : 35, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port3/brightness" + }, + { + "port_id" : 0, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port4/brightness" + }, + { + "port_id" : 4, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port5/brightness" + }, + { + "port_id" : 8, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port6/brightness" + }, + { + "port_id" : 12, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port7/brightness" + }, + { + "port_id" : 16, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port8/brightness" + }, + { + "port_id" : 20, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port9/brightness" + }, + { + "port_id" : 24, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port10/brightness" + }, + { + "port_id" : 28, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port11/brightness" + }, + { + "port_id" : 40, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port12/brightness" + }, + { + "port_id" : 44, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port13/brightness" + }, + { + "port_id" : 48, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port14/brightness" + }, + { + "port_id" : 52, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port15/brightness" + }, + { + "port_id" : 56, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port16/brightness" + }, + { + "port_id" : 60, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port17/brightness" + }, + { + "port_id" : 64, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port18/brightness" + }, + { + "port_id" : 68, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port19/brightness" + }, + { + "port_id" : 72, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port20/brightness" + }, + { + "port_id" : 73, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port21/brightness" + }, + { + "port_id" : 74, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port22/brightness" + }, + { + "port_id" : 75, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port23/brightness" + }, + + { + "port_id" : 120, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port48/brightness" + }, + { + "port_id" : 124, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port49/brightness" + }, + { + "port_id" : 80, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port50/brightness" + }, + { + "port_id" : 84, + "lchip" : 0, + "ctl_id" : 0, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port51/brightness" + }, + + { + "port_id" : 232, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port24/brightness" + }, + { + "port_id" : 233, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port25/brightness" + }, + { + "port_id" : 234, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port26/brightness" + }, + { + "port_id" : 235, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port27/brightness" + }, + { + "port_id" : 200, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port28/brightness" + }, + { + "port_id" : 204, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port29/brightness" + }, + { + "port_id" : 208, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port30/brightness" + }, + { + "port_id" : 212, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port31/brightness" + }, + { + "port_id" : 216, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port32/brightness" + }, + { + "port_id" : 220, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port33/brightness" + }, + { + "port_id" : 224, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port34/brightness" + }, + { + "port_id" : 228, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port35/brightness" + }, + { + "port_id" : 160, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port36/brightness" + }, + { + "port_id" : 164, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port37/brightness" + }, + { + "port_id" : 168, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port38/brightness" + }, + { + "port_id" : 172, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port39/brightness" + }, + { + "port_id" : 176, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port40/brightness" + }, + { + "port_id" : 180, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port41/brightness" + }, + { + "port_id" : 184, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port42/brightness" + }, + { + "port_id" : 188, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port43/brightness" + }, + { + "port_id" : 192, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port44/brightness" + }, + { + "port_id" : 193, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port45/brightness" + }, + { + "port_id" : 194, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port46/brightness" + }, + { + "port_id" : 195, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port47/brightness" + }, + + { + "port_id" : 240, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 0, + "sysfs_path" : "/sys/class/leds/port52/brightness" + }, + { + "port_id" : 244, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 1, + "sysfs_path" : "/sys/class/leds/port53/brightness" + }, + { + "port_id" : 280, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 1, + "sysfs_path" : "/sys/class/leds/port54/brightness" + }, + { + "port_id" : 284, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_2_FORCE_OFF", + "fixed" : 1, + "sysfs_path" : "/sys/class/leds/port55/brightness" + }, + + { + "port_id" : 161, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_1_FORCE_OFF", + "fixed" : 0 + }, + { + "port_id" : 162, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_1_FORCE_OFF", + "fixed" : 0 + }, + { + "port_id" : 165, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_1_FORCE_OFF", + "fixed" : 0 + }, + { + "port_id" : 166, + "lchip" : 0, + "ctl_id" : 1, + "mode" : "LED_MODE_1_FORCE_OFF", + "fixed" : 0 + } + ] + }, + "ffe" : { + "board_material" : "BOARD_MATERIAL_M4", + "config" : [ + { + "serdes_id" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75], + "is_dac" : 1, + "speed" : [10000, 25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [2, -13, 46, 0, 0] + }, + { + "serdes_id" : [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 50, 52, 53, 54, 55, 56, 57, 58, 59], + "is_dac" : 0, + "speed" : [10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 46, -8, 0] + }, + { + "serdes_id" : [0, 1, 16, 17, 18, 19, 20, 21, 22, 23], + "is_dac" : 0, + "speed" : [10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -6, 0] + }, + { + "serdes_id" : [24, 25, 26, 27, 72, 74, 75], + "is_dac" : 0, + "speed" : [10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -4, 0] + }, + { + "serdes_id" : [48, 49, 51, 64, 65, 66, 67, 68, 69, 70, 71, 73], + "is_dac" : 0, + "speed" : [10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -6, 0] + }, + { + "serdes_id" : [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 50, 52, 53, 54, 55, 56, 57, 58, 59], + "is_dac" : 0, + "speed" : [25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 44, -14, -1] + }, + { + "serdes_id" : [0, 1, 16, 17, 18, 19, 20, 21, 22, 23], + "is_dac" : 0, + "speed" : [25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 38, -10, -2] + }, + { + "serdes_id" : [24, 25, 26, 27, 72, 74, 75], + "is_dac" : 0, + "speed" : [25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 36, -6, -2] + }, + { + "serdes_id" : [48, 49, 51, 64, 65, 66, 67, 68, 69, 70, 71, 73], + "is_dac" : 0, + "speed" : [25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 38, -10, -2] + }, + { + "serdes_id" : [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95], + "is_dac" : 1, + "speed" : [100000, 25000, 40000, 10000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [2, -13, 46, 0, 0] + }, + { + "serdes_id" : [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95], + "is_dac" : 1, + "speed" : [1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -4, 0] + }, + { + "serdes_id" : [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95], + "is_dac" : 0, + "speed" : [100000, 25000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 36, -6, -2] + }, + { + "serdes_id" : [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95], + "is_dac" : 0, + "speed" : [40000, 10000, 1000], + + "mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE", + "cfg" : [0, 0, 42, -4, 0] + } + ] + } +} diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/V682-48y8c-chip-profile.txt b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/V682-48y8c-chip-profile.txt new file mode 100644 index 00000000000..9fadec5d5f6 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/V682-48y8c-chip-profile.txt @@ -0,0 +1,116 @@ +#----------------- SDK Feature Support -------------- +[MPLS_SUPPORT] = 1; +[APS_SUPPORT] = 1; +[OAM_SUPPORT] = 1; +[PTP_SUPPORT] = 0; +[SYNCE_SUPPORT] = 0; +[STACKING_SUPPORT] = 1; +[BPE_SUPPORT] = 0; +[IPFIX_SUPPORT] = 1; +[MONITOR_SUPPORT] = 1; +[OVERLAY_SUPPORT] = 1; +[EFD_SUPPORT] = 1; +[FCOE_SUPPORT] = 0; +[TRILL_SUPPORT] = 0; +[WLAN_SUPPORT] = 0; +[NPM_SUPPORT] = 1; +[DOT1AE_SUPPORT] = 1; +[SRV6_SUPPORT] = 0; +[DTEL_SUPPORT] = 1; +[FLEXE_SUPPORT] = 0; +[FDBTOKEN_SUPPORT] = 1; + +#----------------- Chip Init Parameter -------------- +#Local chip number and global chip id +[Local chip_num] = 1 +[Local chip0] = 0 +[Local chip1] = 1 +[Port_phy_mapping] = 1 + +#Cut through mode 0: Disable; 1:10/40/100G; 2:1/10/100G; 3:1/10/40G; other:Flex, refer to CUT_THROUGH_BITMAP +[CUT_THROUGH_SPEED] = 0 +#Flex cut through mode, speed enable by bitmap, refer to ctc_port_speed_t, Notice: 10M/100M/1G treat as the same speed +[CUT_THROUGH_BITMAP] = 0 + +#Network cpu port +[CPU_NETWORK_PORT_EN] = 0 +[CPU_NETWORK_PORT_ID] = 47 + +#Enable parity error and multi-bit ecc recover +[ECC_RECOVER_EN] = 0 +[TCAM_SCAN_EN] = 0 +[SDB_EN] = 0 + +#----------------- KNET Init Parameter -------------- +[KNET_EN] = 0 + +#----------------- FTM Init Parameter -------------- +#0: not use; 1: default; 2: layer3; 3: ipv6 +[FTM Profile] = 0 + +#----------------- Interrupt Init Parameter -------------- +#0: pin, 1: msi +[Interrupt_mode] = 1 + +#----------------- NextHop Init Parameter -------------- +#0: SDK work in pizzbox (single chip system), 1: SDK work in multi-chip system +[Nexthop Edit Mode] = 0 +[External Nexthop Number] = 16384 +[MPLS Tunnel Number] = 1024 +[H_ECMP_EN] = 0 + +#----------------- L2 Init Parameter -------------- +[FDB Hw Learning] = 0 +[Logic Port Num] = 1024 +#0: 128 instance per port, 1: 64 instance per port, 2: 32 instance per port +[STP MODE] = 0 +[MAX_FID_NUM] = 5120 + +#----------------- Stats Init Parameter -------------- +[STATS_QUEUE_DEQ_EN] = 1 +[STATS_QUEUE_DROP_EN] = 1 +[STATS_FLOW_POLICER_EN] = 1 +[STATS_VLAN_EN] = 0 +[STATS_VRF_EN] = 0 +[STATS_POLICER_NUM] = 1024 +[STATS_PORT_EN] = 0 +[STATS_ECMP_EN] = 0 + +#----------------- BPE Init Parameter -------------- +[BPE_BR_PORT_EXTENDER_EN] = 0 +[BPE_BR_UC_MAX_ECID] = 1024 +[BPE_BR_MC_MAX_ECID] = 4096 +[BPE_BR_PORT_BASE] = 0 + +#----------------- Ipuc Init Parameter -------------- +#0: tcam use prefix 16; 1: tcam use prefix 8 +[IPUC_TCAM_PREFIX_8] = 1 + +#----------------- QoS Init Parameter -------------- +#QoS policer number support 1K/2K/4K/8K, default 4K +[QOS_POLICER_NUM] = 4096 +#qos queue mode 0: 8(basic)+1(cpu) +#qos queue mode 1: 8(basic)+1(span)+1(mcast) +[QOS_QUEUE_MODE] = 0 +#QoS port extend queue number support 0/4, default 0 +[QOS_PORT_EXT_QUEUE_NUM] = 0 +#QoS CPU reason queue number support 128/64/32, default 128 +[QOS_CPU_QUEUE_NUM] = 128 +[QOS_INGRESS_VLAN_POLICER_NUM] = 0 +[QOS_EGRESS_VLAN_POLICER_NUM] = 0 +#QoS the max number of igs/egs reserve macro policer,which ACL entry support micro and macro at the same time +[QOS_INGRESS_MACRO_POLICER_NUM] = 0 +[QOS_EGRESS_MACRO_POLICER_NUM] = 0 +#QOS service queue mode, default 0,0:logic scr port + dstport enq 1:service id + dstport enq +[QOS_SERVICE_QUEUE_MODE] = 0 +#mode 0:svc policer used for service policer +#mode 1:svc policer used for stormctl +[QOS_POLICER_SVC_MODE] = 0 + +#----------------- Stacking Init Parameter -------------- +#0: normal mode; 1: spine-leaf mode +[FABRIC MODE] = 0 +[STACKING VERSION] = 1 +#----------------- LB hash Init Parameter -------------- +#0: support 4 select num; 1: support 8 select num; only TM2 support mode 1 +[LB_HASH_MODE] = 0 diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/V682-48y8c-datapath.txt b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/V682-48y8c-datapath.txt new file mode 100644 index 00000000000..c3bf7e2d4ab --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/V682-48y8c-datapath.txt @@ -0,0 +1,1022 @@ +#SERDES_MODE: 0-NONE, 1-XFI, 2-SGMII, 3-Not Support, 4-QSGMII, 7-XLG, 8-100GR4, 9-SGMII2G5 +# 13-XXVG, 14-50GR2, 16-50GR1, 17-100GR2, 18-200G, 19-400G +#SERDES_POLY: 0-No Inverse, 1-Inverse +#SERDES_SWITCH: 0-Not Support Dynamic Switch, 1-Support Dynamic Switch exclude QSGMII, 2-Support Dynamic Switch include QSGMII + +[CORE_PLL] = 1050 +[DP0_FLEXE_CLIENT_NUM] = 0 +[DP1_FLEXE_CLIENT_NUM] = 0 +[DP0_XPIPE_PORT_NUM] = 0 +[DP1_XPIPE_PORT_NUM] = 0 +[DOT1AE_ENABLE] = 1 + +#{ +[SERDES_ITEM] + +[SERDES_ID] = 7 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 0 + +[SERDES_ID] = 6 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 1 + +[SERDES_ID] = 5 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 2 + +[SERDES_ID] = 4 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 3 + +[SERDES_ID] = 3 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 4 + +[SERDES_ID] = 2 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 5 + +[SERDES_ID] = 1 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 6 + +[SERDES_ID] = 0 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 7 + +[SERDES_ID] = 11 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 8 + +[SERDES_ID] = 10 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 9 + +[SERDES_ID] = 9 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 10 + +[SERDES_ID] = 8 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 11 + +[SERDES_ID] = 12 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 12 + +[SERDES_ID] = 13 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 13 + +[SERDES_ID] = 14 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 14 + +[SERDES_ID] = 15 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 15 + +[SERDES_ID] = 16 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 16 + +[SERDES_ID] = 17 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 17 + +[SERDES_ID] = 18 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 18 + +[SERDES_ID] = 19 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 19 + +[SERDES_ID] = 20 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 20 + +[SERDES_ID] = 21 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 21 + +[SERDES_ID] = 22 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 22 + +[SERDES_ID] = 23 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 23 + +[SERDES_ID] = 24 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 24 + +[SERDES_ID] = 25 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 25 + +[SERDES_ID] = 26 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 26 + +[SERDES_ID] = 27 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 27 + +[SERDES_ID] = 28 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 28 + +[SERDES_ID] = 29 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 29 + +[SERDES_ID] = 30 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 30 + +[SERDES_ID] = 31 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 31 + +[SERDES_ID] = 36 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 32 + +[SERDES_ID] = 37 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 33 + +[SERDES_ID] = 38 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 34 + +[SERDES_ID] = 32 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 35 + +[SERDES_ID] = 39 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 36 + +[SERDES_ID] = 34 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 37 + +[SERDES_ID] = 35 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 38 + +[SERDES_ID] = 33 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 39 + +[SERDES_ID] = 40 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 40 + +[SERDES_ID] = 44 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 41 + +[SERDES_ID] = 42 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 42 + +[SERDES_ID] = 41 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 43 + +[SERDES_ID] = 43 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 44 + +[SERDES_ID] = 46 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 45 + +[SERDES_ID] = 47 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 46 + +[SERDES_ID] = 45 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 47 + +[SERDES_ID] = 49 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 48 + +[SERDES_ID] = 48 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 49 + +[SERDES_ID] = 51 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 50 + +[SERDES_ID] = 50 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 51 + +[SERDES_ID] = 53 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 52 + +[SERDES_ID] = 52 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 53 + +[SERDES_ID] = 55 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 54 + +[SERDES_ID] = 54 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 55 + +[SERDES_ID] = 57 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 56 + +[SERDES_ID] = 56 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 57 + +[SERDES_ID] = 59 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 58 + +[SERDES_ID] = 58 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 59 + +[SERDES_ID] = 60 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 60 + +[SERDES_ID] = 61 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 61 + +[SERDES_ID] = 62 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 62 + +[SERDES_ID] = 63 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 63 + +[SERDES_ID] = 70 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 64 + +[SERDES_ID] = 71 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 65 + +[SERDES_ID] = 68 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 66 + +[SERDES_ID] = 69 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 67 + +[SERDES_ID] = 66 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 68 + +[SERDES_ID] = 67 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 69 + +[SERDES_ID] = 64 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 70 + +[SERDES_ID] = 65 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 1 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 71 + +[SERDES_ID] = 74 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 72 + +[SERDES_ID] = 75 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 73 + +[SERDES_ID] = 72 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 74 + +[SERDES_ID] = 73 +[SERDES_MODE] = 13 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 75 + +[SERDES_ID] = 76 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 76 + +[SERDES_ID] = 77 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 77 + +[SERDES_ID] = 78 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 78 + +[SERDES_ID] = 79 +[SERDES_MODE] = 0 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 79 + +[SERDES_ID] = 83 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 80 + +[SERDES_ID] = 81 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 81 + +[SERDES_ID] = 87 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 82 + +[SERDES_ID] = 82 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 83 + +[SERDES_ID] = 86 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 84 + +[SERDES_ID] = 80 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 85 + +[SERDES_ID] = 84 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 86 + +[SERDES_ID] = 85 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 87 + +[SERDES_ID] = 95 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 88 + +[SERDES_ID] = 93 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 89 + +[SERDES_ID] = 91 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 90 + +[SERDES_ID] = 94 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 91 + +[SERDES_ID] = 90 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 92 + +[SERDES_ID] = 89 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 93 + +[SERDES_ID] = 88 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 94 + +[SERDES_ID] = 92 +[SERDES_MODE] = 8 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 95 + +[SERDES_ID] = 96 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 96 + +[SERDES_ID] = 97 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 97 + +[SERDES_ID] = 98 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 98 + +[SERDES_ID] = 99 +[SERDES_MODE] = 1 +[SERDES_RX_POLY] = 0 +[SERDES_TX_POLY] = 0 +[SERDES_SWITCH] = 1 +[SERDES_GROUP] = 0 +[SERDES_XPIPE] = 0 +[INDEX] = 99 + +#} +[SERDES_TO_LPORT] +#{ +#index |serdes |QSGMII |SGMII/SGMII2G5/XFI/XXVG |XLG |50GR1 |50GR2 |100GR4 |100GR2 |200G |400G +#----------|----------|------------|------------------------|--------|--------|--------|--------|--------|--------|-------- +#0 |7 |NA |0 |0 |0 |0 |0 |0 |NA |NA +#1 |6 |NA |1 |0 |NA |0 |0 |NA |NA |NA +#2 |5 |NA |2 |0 |2 |2 |0 |0 |NA |NA +#3 |4 |NA |3 |0 |NA |2 |0 |NA |NA |NA +#4 |3 |NA |4 |4 |4 |4 |4 |4 |NA |NA +#5 |2 |NA |5 |4 |NA |4 |4 |NA |NA |NA +#6 |1 |NA |6 |4 |6 |6 |4 |4 |NA |NA +#7 |0 |NA |7 |4 |NA |6 |4 |NA |NA |NA +#8 |11 |NA |8 |8 |8 |8 |8 |8 |NA |NA +#9 |10 |NA |9 |8 |NA |8 |8 |NA |NA |NA +#10 |9 |NA |10 |8 |10 |10 |8 |8 |NA |NA +#11 |8 |NA |11 |8 |NA |10 |8 |NA |NA |NA +#12 |12 |NA |12 |12 |12 |12 |12 |12 |NA |NA +#13 |13 |NA |13 |12 |NA |12 |12 |NA |NA |NA +#14 |14 |NA |14 |12 |14 |14 |12 |12 |NA |NA +#15 |15 |NA |15 |12 |NA |14 |12 |NA |NA |NA +#16 |16 |NA |16 |16 |16 |16 |16 |16 |NA |NA +#17 |17 |NA |17 |16 |NA |16 |16 |NA |NA |NA +#18 |18 |NA |18 |16 |18 |18 |16 |16 |NA |NA +#19 |19 |NA |19 |16 |NA |18 |16 |NA |NA |NA +#20 |20 |NA |20 |20 |20 |20 |20 |20 |NA |NA +#21 |21 |NA |21 |20 |NA |20 |20 |NA |NA |NA +#22 |22 |NA |22 |20 |22 |22 |20 |20 |NA |NA +#23 |23 |NA |23 |20 |NA |22 |20 |NA |NA |NA +#24 |24 |NA |24 |24 |24 |24 |24 |24 |NA |NA +#25 |25 |NA |25 |24 |NA |24 |24 |NA |NA |NA +#26 |26 |NA |26 |24 |26 |26 |24 |24 |NA |NA +#27 |27 |NA |27 |24 |NA |26 |24 |NA |NA |NA +#28 |28 |NA |28 |28 |28 |28 |28 |28 |NA |NA +#29 |29 |NA |29 |28 |NA |28 |28 |NA |NA |NA +#30 |30 |NA |30 |28 |30 |30 |28 |28 |NA |NA +#31 |31 |NA |31 |28 |NA |30 |28 |NA |NA |NA +#32 |36 |NA |32 |32 |32 |32 |32 |32 |32 |32 +#33 |37 |NA |33 |32 |33 |32 |32 |32 |32 |32 +#34 |38 |NA |34 |32 |34 |34 |32 |34 |32 |32 +#35 |32 |NA |35 |32 |35 |34 |32 |34 |32 |32 +#36 |39 |NA |36 |36 |36 |36 |36 |36 |36 |32 +#37 |34 |NA |37 |36 |37 |36 |36 |36 |36 |32 +#38 |35 |NA |38 |36 |38 |38 |36 |38 |36 |32 +#39 |33 |NA |39 |36 |39 |38 |36 |38 |36 |32 +#40 |40 |NA |40 |40 |40 |40 |40 |40 |40 |40 +#41 |44 |NA |41 |40 |41 |40 |40 |40 |40 |40 +#42 |42 |NA |42 |40 |42 |42 |40 |42 |40 |40 +#43 |41 |NA |43 |40 |43 |42 |40 |42 |40 |40 +#44 |43 |NA |44 |44 |44 |44 |44 |44 |44 |40 +#45 |46 |NA |45 |44 |45 |44 |44 |44 |44 |40 +#46 |47 |NA |46 |44 |46 |46 |44 |46 |44 |40 +#47 |45 |NA |47 |44 |47 |46 |44 |46 |44 |40 +#48 |49 |NA |48 |48 |48 |48 |48 |48 |NA |NA +#49 |48 |NA |49 |48 |NA |48 |48 |NA |NA |NA +#50 |51 |NA |50 |48 |50 |50 |48 |48 |NA |NA +#51 |50 |NA |51 |48 |NA |50 |48 |NA |NA |NA +#52 |53 |NA |52 |52 |52 |52 |52 |52 |NA |NA +#53 |52 |NA |53 |52 |NA |52 |52 |NA |NA |NA +#54 |55 |NA |54 |52 |54 |54 |52 |52 |NA |NA +#55 |54 |NA |55 |52 |NA |54 |52 |NA |NA |NA +#56 |57 |NA |56 |56 |56 |56 |56 |56 |NA |NA +#57 |56 |NA |57 |56 |NA |56 |56 |NA |NA |NA +#58 |59 |NA |58 |56 |58 |58 |56 |56 |NA |NA +#59 |58 |NA |59 |56 |NA |58 |56 |NA |NA |NA +#60 |60 |NA |60 |60 |60 |60 |60 |60 |NA |NA +#61 |61 |NA |61 |60 |NA |60 |60 |NA |NA |NA +#62 |62 |NA |62 |60 |62 |62 |60 |60 |NA |NA +#63 |63 |NA |63 |60 |NA |62 |60 |NA |NA |NA +#64 |70 |NA |64 |64 |64 |64 |64 |64 |NA |NA +#65 |71 |NA |65 |64 |NA |64 |64 |NA |NA |NA +#66 |68 |NA |66 |64 |66 |66 |64 |64 |NA |NA +#67 |69 |NA |67 |64 |NA |66 |64 |NA |NA |NA +#68 |66 |NA |68 |68 |68 |68 |68 |68 |NA |NA +#69 |67 |NA |69 |68 |NA |68 |68 |NA |NA |NA +#70 |64 |NA |70 |68 |70 |70 |68 |68 |NA |NA +#71 |65 |NA |71 |68 |NA |70 |68 |NA |NA |NA +#72 |74 |NA |72 |72 |72 |72 |72 |72 |NA |NA +#73 |75 |NA |73 |72 |NA |72 |72 |NA |NA |NA +#74 |72 |NA |74 |72 |74 |74 |72 |72 |NA |NA +#75 |73 |NA |75 |72 |NA |74 |72 |NA |NA |NA +#76 |76 |NA |76 |76 |76 |76 |76 |76 |NA |NA +#77 |77 |NA |77 |76 |NA |76 |76 |NA |NA |NA +#78 |78 |NA |78 |76 |78 |78 |76 |76 |NA |NA +#79 |79 |NA |79 |76 |NA |78 |76 |NA |NA |NA +#80 |83 |NA |80 |80 |80 |80 |80 |80 |80 |80 +#81 |81 |NA |81 |80 |81 |80 |80 |80 |80 |80 +#82 |87 |NA |82 |80 |82 |82 |80 |82 |80 |80 +#83 |82 |NA |83 |80 |83 |82 |80 |82 |80 |80 +#84 |86 |NA |84 |84 |84 |84 |84 |84 |84 |80 +#85 |80 |NA |85 |84 |85 |84 |84 |84 |84 |80 +#86 |84 |NA |86 |84 |86 |86 |84 |86 |84 |80 +#87 |85 |NA |87 |84 |87 |86 |84 |86 |84 |80 +#88 |95 |NA |88 |88 |88 |88 |88 |88 |88 |88 +#89 |93 |NA |89 |88 |89 |88 |88 |88 |88 |88 +#90 |91 |NA |90 |88 |90 |90 |88 |90 |88 |88 +#91 |94 |NA |91 |88 |91 |90 |88 |90 |88 |88 +#92 |90 |NA |92 |92 |92 |92 |92 |92 |92 |88 +#93 |89 |NA |93 |92 |93 |92 |92 |92 |92 |88 +#94 |88 |NA |94 |92 |94 |94 |92 |94 |92 |88 +#95 |92 |NA |95 |92 |95 |94 |92 |94 |92 |88 +#96 |96 |NA |232 |232 |232 |232 |232 |232 |NA |NA +#97 |97 |NA |233 |232 |NA |232 |232 |NA |NA |NA +#98 |98 |NA |243 |232 |243 |243 |232 |232 |NA |NA +#99 |99 |NA |244 |232 |NA |243 |232 |NA |NA |NA +#} + diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/buffers.json.j2 b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/buffers.json.j2 new file mode 100644 index 00000000000..08e21e428b6 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/buffers.json.j2 @@ -0,0 +1,70 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(1,default_ports_num+1) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + } +} + diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/pg_profile_lookup.ini b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/pg_profile_lookup.ini new file mode 100644 index 00000000000..a65244e69b5 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/pg_profile_lookup.ini @@ -0,0 +1,21 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 34816 18432 16384 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 34816 18432 16384 0 + 40000 5m 34816 18432 16384 0 + 50000 5m 34816 18432 16384 0 + 100000 5m 36864 18432 18432 0 + 1000 40m 36864 18432 18432 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 39936 18432 21504 0 + 40000 40m 41984 18432 23552 0 + 50000 40m 41984 18432 23552 0 + 100000 40m 54272 18432 35840 0 + 1000 300m 49152 18432 30720 0 + 10000 300m 49152 18432 30720 0 + 25000 300m 71680 18432 53248 0 + 40000 300m 94208 18432 75776 0 + 50000 300m 94208 18432 75776 0 + 100000 300m 184320 18432 165888 0 + diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/port_config.ini b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/port_config.ini new file mode 100644 index 00000000000..45206015c94 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed fec +Ethernet0 32 eth-0-1 0 25000 none +Ethernet1 33 eth-0-2 1 25000 none +Ethernet2 34 eth-0-3 2 25000 none +Ethernet3 35 eth-0-4 3 25000 none +Ethernet4 0 eth-0-5 4 25000 none +Ethernet5 4 eth-0-6 5 25000 none +Ethernet6 8 eth-0-7 6 25000 none +Ethernet7 12 eth-0-8 7 25000 none +Ethernet8 16 eth-0-9 8 25000 none +Ethernet9 20 eth-0-10 9 25000 none +Ethernet10 24 eth-0-11 10 25000 none +Ethernet11 28 eth-0-12 11 25000 none +Ethernet12 40 eth-0-13 12 25000 none +Ethernet13 44 eth-0-14 13 25000 none +Ethernet14 48 eth-0-15 14 25000 none +Ethernet15 52 eth-0-16 15 25000 none +Ethernet16 56 eth-0-17 16 25000 none +Ethernet17 60 eth-0-18 17 25000 none +Ethernet18 64 eth-0-19 18 25000 none +Ethernet19 68 eth-0-20 19 25000 none +Ethernet20 72 eth-0-21 20 25000 none +Ethernet21 73 eth-0-22 21 25000 none +Ethernet22 74 eth-0-23 22 25000 none +Ethernet23 75 eth-0-24 23 25000 none +Ethernet24 232 eth-0-25 24 25000 none +Ethernet25 233 eth-0-26 25 25000 none +Ethernet26 234 eth-0-27 26 25000 none +Ethernet27 235 eth-0-28 27 25000 none +Ethernet28 200 eth-0-29 28 25000 none +Ethernet29 204 eth-0-30 29 25000 none +Ethernet30 208 eth-0-31 30 25000 none +Ethernet31 212 eth-0-32 31 25000 none +Ethernet32 216 eth-0-33 32 25000 none +Ethernet33 220 eth-0-34 33 25000 none +Ethernet34 224 eth-0-35 34 25000 none +Ethernet35 228 eth-0-36 35 25000 none +Ethernet36 160 eth-0-37 36 25000 none +Ethernet37 164 eth-0-38 37 25000 none +Ethernet38 168 eth-0-39 38 25000 none +Ethernet39 172 eth-0-40 39 25000 none +Ethernet40 176 eth-0-41 40 25000 none +Ethernet41 180 eth-0-42 41 25000 none +Ethernet42 184 eth-0-43 42 25000 none +Ethernet43 188 eth-0-44 43 25000 none +Ethernet44 192 eth-0-45 44 25000 none +Ethernet45 193 eth-0-46 45 25000 none +Ethernet46 194 eth-0-47 46 25000 none +Ethernet47 195 eth-0-48 47 25000 none +Ethernet48 120,121,122,123 eth-0-49 48 100000 none +Ethernet49 124,125,126,127 eth-0-50 49 100000 none +Ethernet50 80,81,82,83 eth-0-51 50 100000 none +Ethernet51 84,85,86,87 eth-0-52 51 100000 none +Ethernet52 240,241,242,243 eth-0-53 52 100000 none +Ethernet53 244,245,246,247 eth-0-54 53 100000 none +Ethernet54 280,281,282,283 eth-0-55 54 100000 none +Ethernet55 284,285,286,287 eth-0-56 55 100000 none diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/qos.json.j2 b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/qos.json.j2 new file mode 100644 index 00000000000..3e548325ea3 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/sai.profile b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/sai.profile new file mode 100644 index 00000000000..9a3643c35b2 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/V682-48y8c/sai.profile @@ -0,0 +1,3 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/V682-48y8c-chip-profile.txt +SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/usr/share/sonic/hwsku/V682-48y8c-datapath.txt +SAI_PLATFORM_CFG_FILE=/usr/share/sonic/hwsku/V682-48y8c-board.json diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/default_sku b/device/centec/x86_64-centec_v682_48y8c-r0/default_sku new file mode 100644 index 00000000000..d169d963600 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/default_sku @@ -0,0 +1 @@ +V682-48y8c l2 diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/fancontrol b/device/centec/x86_64-centec_v682_48y8c-r0/fancontrol new file mode 100644 index 00000000000..07420a6dba0 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/fancontrol @@ -0,0 +1,10 @@ +# Configuration file generated by pwmconfig, changes will be lost +INTERVAL=10 +DEVPATH=hwmon1=devices/pci0000:00/0000:00:1f.3/i2c-0/0-0049 hwmon2=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-9/9-002c hwmon3=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-9/9-002e +DEVNAME=hwmon1=lm77 hwmon2=adt7470 hwmon3=adt7470 +FCTEMPS=hwmon2/pwm1=hwmon1/temp1_input hwmon2/pwm2=hwmon1/temp1_input hwmon2/pwm3=hwmon1/temp1_input hwmon2/pwm4=hwmon1/temp1_input hwmon3/pwm1=hwmon1/temp1_input hwmon3/pwm2=hwmon1/temp1_input hwmon3/pwm3=hwmon1/temp1_input hwmon3/pwm4=hwmon1/temp1_input +FCFANS=hwmon2/pwm1=hwmon2/fan1_input hwmon2/pwm2=hwmon2/fan2_input hwmon2/pwm3=hwmon2/fan3_input hwmon2/pwm4=hwmon2/fan4_input hwmon3/pwm1=hwmon3/fan1_input hwmon3/pwm2=hwmon3/fan2_input hwmon3/pwm3=hwmon3/fan3_input hwmon3/pwm4=hwmon3/fan4_input +MINTEMP=hwmon2/pwm1=20 hwmon2/pwm2=20 hwmon2/pwm3=20 hwmon2/pwm4=20 hwmon3/pwm1=20 hwmon3/pwm2=20 hwmon3/pwm3=20 hwmon3/pwm4=20 +MAXTEMP=hwmon2/pwm1=60 hwmon2/pwm2=60 hwmon2/pwm3=60 hwmon2/pwm4=60 hwmon3/pwm1=60 hwmon3/pwm2=60 hwmon3/pwm3=60 hwmon3/pwm4=60 +MINSTART=hwmon2/pwm1=150 hwmon2/pwm2=150 hwmon2/pwm3=150 hwmon2/pwm4=150 hwmon3/pwm1=150 hwmon3/pwm2=150 hwmon3/pwm3=150 hwmon3/pwm4=150 +MINSTOP=hwmon2/pwm1=0 hwmon2/pwm2=0 hwmon2/pwm3=0 hwmon2/pwm4=0 hwmon3/pwm1=0 hwmon3/pwm2=0 hwmon3/pwm3=0 hwmon3/pwm4=0 diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/installer.conf b/device/centec/x86_64-centec_v682_48y8c-r0/installer.conf new file mode 100644 index 00000000000..3b97b7f99da --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/installer.conf @@ -0,0 +1 @@ +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="iommu=pt" diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/pcie.yaml b/device/centec/x86_64-centec_v682_48y8c-r0/pcie.yaml new file mode 100644 index 00000000000..5e00e24bc07 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/pcie.yaml @@ -0,0 +1,5 @@ +- bus: '05' + dev: '00' + fn: '0' + id: 8180 + name: 'Communication controller: Device cb10:8180' diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/platform_asic b/device/centec/x86_64-centec_v682_48y8c-r0/platform_asic new file mode 100644 index 00000000000..74dac3505ea --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/platform_asic @@ -0,0 +1 @@ +centec diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/platform_components.json b/device/centec/x86_64-centec_v682_48y8c-r0/platform_components.json new file mode 100644 index 00000000000..15c644f6b46 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/platform_components.json @@ -0,0 +1,8 @@ +{ + "chassis": { + "V682-48Y8C": { + "component": { + } + } + } +} diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/platform_reboot b/device/centec/x86_64-centec_v682_48y8c-r0/platform_reboot new file mode 100755 index 00000000000..5e49eecb61c --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/platform_reboot @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import time + +def main(): + os.system('hwclock -w -f /dev/rtc1') + time.sleep(1) + + os.system('i2cset -y 0 0x36 0x23 0') + time.sleep(1) + os.system('i2cset -y 0 0x36 0x23 1') + +if __name__ == '__main__': + main() diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/plugins/eeprom.py b/device/centec/x86_64-centec_v682_48y8c-r0/plugins/eeprom.py new file mode 100644 index 00000000000..1651279722e --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/plugins/eeprom.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +############################################################################# +# Centec V682-48Y8C +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os + from sonic_eeprom import eeprom_tlvinfo + from sonic_py_common import device_info +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + self.eeprom_path = platform_path + '/eeprom_file' + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/plugins/led_control.py b/device/centec/x86_64-centec_v682_48y8c-r0/plugins/led_control.py new file mode 100644 index 00000000000..973a9354fbc --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/plugins/led_control.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + import os + import re + import syslog + import collections + from sonic_led.led_control_base import LedControlBase + from sonic_py_common import device_info + from subprocess import Popen +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +def DBG_PRINT(str): + syslog.openlog("centec-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Constructor + def __init__(self): + + self.mac_to_led = { + 32 : 0, + 33 : 1, + 34 : 2, + 35 : 3, + 0 : 4, + 4 : 5, + 8 : 6, + 12 : 7, + 16 : 8, + 20 : 9, + 24 : 10, + 28 : 11, + 40 : 12, + 44 : 13, + 48 : 14, + 52 : 15, + 56 : 16, + 60 : 17, + 64 : 18, + 68 : 19, + 72 : 20, + 73 : 21, + 74 : 22, + 75 : 23, + 232: 24, + 233: 25, + 234: 26, + 235: 27, + 200: 28, + 204: 29, + 208: 30, + 212: 31, + 216: 32, + 220: 33, + 224: 34, + 228: 35, + 160: 36, + 164: 37, + 168: 38, + 172: 39, + 176: 40, + 180: 41, + 184: 42, + 188: 43, + 192: 44, + 193: 45, + 194: 46, + 195: 47, + 120: 48, + 121: -1, + 122: -1, + 123: -1, + 124: 49, + 125: -1, + 126: -1, + 127: -1, + 80 : 50, + 81 : -1, + 82 : -1, + 83 : -1, + 84 : 51, + 85 : -1, + 86 : -1, + 87 : -1, + 240: 52, + 241: -1, + 242: -1, + 243: -1, + 244: 53, + 245: -1, + 246: -1, + 247: -1, + 280: 54, + 281: -1, + 282: -1, + 283: -1, + 284: 55, + 285: -1, + 286: -1, + 287: -1, + } + + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + port_config_file = "/".join([platform_path, "V682-48y8c", "port_config.ini"]) + try: + f = open(port_config_file) + except: + raise + for line in f: + line.strip() + if re.search('^#', line) is not None: + Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:]) + break + f.close() + f = open(port_config_file) + self._port_cfgs = [Port_cfg(*tuple((line.strip().split()))) + for line in f if re.search('^#', line) is None] + f.close() + + self.LED_MODE_UP = [5, 5] + self.LED_MODE_DOWN = [7, 7] + self.f_led = "/sys/class/leds/{}/brightness" + self._initDefaultConfig() + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + for port_cfg in self._port_cfgs: + if port_name == port_cfg.name: + macs = [int(x) for x in (port_cfg.lanes.split(','))] + led = self.mac_to_led[min(macs)] + if led < 0: + return None + return led + return None + + def _port_state_to_mode(self, port_idx, state): + if state == "up": + return self.LED_MODE_UP[1] if port_idx >= 48 else self.LED_MODE_UP[0] + else: + return self.LED_MODE_DOWN[1] if port_idx >= 48 else self.LED_MODE_DOWN[0] + + def _port_led_mode_update(self, port_idx, ledMode): + with open(self.f_led.format("port{}".format(port_idx)), 'w') as led_file: + led_file.write(str(ledMode)) + + def _initSystemLed(self): + try: + cmd = 'i2cset -y 0 0x36 0x2 0x5' + Popen(cmd, shell=True) + DBG_PRINT("init system led to normal") + cmd = 'i2cset -y 0 0x36 0x3 0x1' + Popen(cmd, shell=True) + DBG_PRINT("init idn led to off") + except IOError as e: + DBG_PRINT(str(e)) + + def _initPanelLed(self): + with open(self.f_led.format("port1"), 'r') as led_file: + shouldInit = (int(led_file.read()) == 0) + + if shouldInit == True: + for port_cfg in self._port_cfgs: + macs = [int(x) for x in (port_cfg.lanes.split(','))] + led = self.mac_to_led[min(macs)] + if led < 0: + continue + defmode = self._port_state_to_mode(led, "down") + with open(self.f_led.format("port{}".format(led)), 'w') as led_file: + led_file.write(str(defmode)) + DBG_PRINT("init port{} led to mode={}".format(led, defmode)) + + def _initDefaultConfig(self): + DBG_PRINT("start init led") + + self._initSystemLed() + self._initPanelLed() + + DBG_PRINT("init led done") + + # Concrete implementation of port_link_state_change() method + def port_link_state_change(self, portname, state): + port_idx = self._port_name_to_index(portname) + if port_idx is None: + return + ledMode = self._port_state_to_mode(port_idx, state) + with open(self.f_led.format("port{}".format(port_idx)), 'r') as led_file: + saveMode = int(led_file.read()) + + if ledMode == saveMode: + return + + self._port_led_mode_update(port_idx, ledMode) + DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode)) diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/plugins/psuutil.py b/device/centec/x86_64-centec_v682_48y8c-r0/plugins/psuutil.py new file mode 100644 index 00000000000..9e311d9b4f5 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/plugins/psuutil.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +############################################################################# +# Centec +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +from subprocess import Popen, PIPE, STDOUT + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + cmd = 'i2cget -y 0 0x36 0x1e' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + powergood = ((status & (1 << (3 * (index - 1) + 2))) != 0) + return powergood + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + cmd = 'i2cget -y 0 0x36 0x1e' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + presence = ((status & (1 << (3 * (index - 1) + 1))) == 0) + return presence diff --git a/device/centec/x86_64-centec_v682_48y8c-r0/pmon_daemon_control.json b/device/centec/x86_64-centec_v682_48y8c-r0/pmon_daemon_control.json new file mode 100644 index 00000000000..0db3279e44b --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/installer.conf b/device/centec/x86_64-centec_v682_48y8c_d-r0/installer.conf index e69de29bb2d..3b97b7f99da 100644 --- a/device/centec/x86_64-centec_v682_48y8c_d-r0/installer.conf +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/installer.conf @@ -0,0 +1 @@ +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="iommu=pt" diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_reboot b/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_reboot index 89e521978cb..a1dff65154b 100755 --- a/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_reboot +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_reboot @@ -1,9 +1,9 @@ -#!/usr/bin/python2 +#!/usr/bin/env python import os import sys -susi4_lib = '/usr/local/lib/python2.7/dist-packages' +susi4_lib = '/usr/local/lib/python3.9/dist-packages' if not susi4_lib in os.environ.setdefault('LD_LIBRARY_PATH', ''): os.environ['LD_LIBRARY_PATH'] += (':' + susi4_lib) try: diff --git a/platform/centec/one-image.mk b/platform/centec/one-image.mk index da129addb24..84b993bb598 100644 --- a/platform/centec/one-image.mk +++ b/platform/centec/one-image.mk @@ -9,6 +9,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) \ $(EMBEDWAY_ES6220_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_V682_48Y8C_D_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_V682_48Y8C_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_V682_48X8C_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) diff --git a/platform/centec/platform-modules-centec-v682.mk b/platform/centec/platform-modules-centec-v682.mk index 1736279fdce..46b64c3e6d7 100644 --- a/platform/centec/platform-modules-centec-v682.mk +++ b/platform/centec/platform-modules-centec-v682.mk @@ -2,8 +2,12 @@ CENTEC_V682_48Y8C_D_PLATFORM_MODULE_VERSION =1.0 +CENTEC_V682_48Y8C_PLATFORM_MODULE_VERSION =1.0 +CENTEC_V682_48X8C_PLATFORM_MODULE_VERSION =1.0 export CENTEC_V682_48Y8C_D_PLATFORM_MODULE_VERSION +export CENTEC_V682_48Y8C_PLATFORM_MODULE_VERSION +export CENTEC_V682_48X8C_PLATFORM_MODULE_VERSION CENTEC_V682_48Y8C_D_PLATFORM_MODULE = platform-modules-v682-48y8c-d_$(CENTEC_V682_48Y8C_D_PLATFORM_MODULE_VERSION)_amd64.deb @@ -12,3 +16,11 @@ $(CENTEC_V682_48Y8C_D_PLATFORM_MODULE)_PLATFORM = x86_64-centec_v682_48y8c_d-r0 $(CENTEC_V682_48Y8C_D_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_STRETCH_DEBS += $(CENTEC_V682_48Y8C_D_PLATFORM_MODULE) SONIC_DPKG_DEBS += $(CENTEC_V682_48Y8C_D_PLATFORM_MODULE) + +CENTEC_V682_48Y8C_PLATFORM_MODULE = platform-modules-v682-48y8c_$(CENTEC_V682_48Y8C_PLATFORM_MODULE_VERSION)_amd64.deb +$(CENTEC_V682_48Y8C_PLATFORM_MODULE)_PLATFORM = x86_64-centec_v682_48y8c-r0 +$(eval $(call add_extra_package,$(CENTEC_V682_48Y8C_D_PLATFORM_MODULE),$(CENTEC_V682_48Y8C_PLATFORM_MODULE))) + +CENTEC_V682_48X8C_PLATFORM_MODULE = platform-modules-v682-48x8c_$(CENTEC_V682_48X8C_PLATFORM_MODULE_VERSION)_amd64.deb +$(CENTEC_V682_48X8C_PLATFORM_MODULE)_PLATFORM = x86_64-centec_v682_48x8c-r0 +$(eval $(call add_extra_package,$(CENTEC_V682_48Y8C_D_PLATFORM_MODULE),$(CENTEC_V682_48X8C_PLATFORM_MODULE))) diff --git a/platform/centec/sdk.mk b/platform/centec/sdk.mk index ead6de87dd6..2f56265b489 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,5 +1,5 @@ # Centec SAI -CENTEC_SAI = libsai_1.8.1-0_amd64.deb +CENTEC_SAI = libsai_1.9.1-0_amd64.deb $(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/sai/$(CENTEC_SAI) $(eval $(call add_conflict_package,$(CENTEC_SAI),$(LIBSAIVS_DEV))) diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/modules/Makefile b/platform/centec/sonic-platform-modules-v682/48x8c/modules/Makefile new file mode 100644 index 00000000000..eabfe2733c4 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/modules/Makefile @@ -0,0 +1 @@ +obj-m := centec_v682_48x8c_platform.o rtc-sd2405.o diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/modules/centec_v682_48x8c_platform.c b/platform/centec/sonic-platform-modules-v682/48x8c/modules/centec_v682_48x8c_platform.c new file mode 100644 index 00000000000..049ca4a710c --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/modules/centec_v682_48x8c_platform.c @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include +#include + +#define SEP(XXX) 1 +#define IS_INVALID_PTR(_PTR_) ((_PTR_ == NULL) || IS_ERR(_PTR_)) +#define IS_VALID_PTR(_PTR_) (!IS_INVALID_PTR(_PTR_)) + +#if SEP("defines") +#define SFP_NUM 48 +#define QSFP_NUM 8 +#define PORT_NUM (SFP_NUM + QSFP_NUM) +#endif + +#if SEP("drivers:leds") +extern void v682_48x8c_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value); +extern enum led_brightness v682_48x8c_led_port_get(struct led_classdev *led_cdev); + +static struct led_classdev led_dev_port[PORT_NUM] = { +{ .name = "port0", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port1", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port2", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port3", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port4", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port5", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port6", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port7", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port8", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port9", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port10", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port11", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port12", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port13", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port14", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port15", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port16", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port17", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port18", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port19", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port20", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port21", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port22", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port23", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port24", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port25", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port26", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port27", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port28", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port29", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port30", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port31", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port32", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port33", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port34", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port35", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port36", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port37", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port38", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port39", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port40", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port41", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port42", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port43", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port44", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port45", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port46", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port47", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port48", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port49", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port50", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port51", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port52", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port53", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port54", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +{ .name = "port55", .brightness_set = v682_48x8c_led_port_set, .brightness_get = v682_48x8c_led_port_get,}, +}; +static unsigned char port_led_mode[PORT_NUM] = {0}; + +void v682_48x8c_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + port_led_mode[portNum] = set_value; + + return; +} + +enum led_brightness v682_48x8c_led_port_get(struct led_classdev *led_cdev) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + return port_led_mode[portNum]; +} + +static int v682_48x8c_init_led(void) +{ + int ret = 0; + int i = 0; + + for (i = 0; i < PORT_NUM; i++) + { + ret = led_classdev_register(NULL, &(led_dev_port[i])); + if (ret != 0) + { + printk(KERN_CRIT "create v682_48x8c led_dev_port%d device failed\n", i); + continue; + } + } + + return ret; +} + +static int v682_48x8c_exit_led(void) +{ + int i = 0; + + for (i = 0; i < PORT_NUM; i++) + { + led_classdev_unregister(&(led_dev_port[i])); + } + + return 0; +} +#endif + +static int v682_48x8c_init(void) +{ + int ret = 0; + int failed = 0; + + printk(KERN_ALERT "init v682_48x8c board dirver...\n"); + + ret = v682_48x8c_init_led(); + if (ret != 0) + { + failed = 1; + } + + if (failed) + printk(KERN_INFO "init v682_48x8c board driver failed\n"); + else + printk(KERN_ALERT "init v682_48x8c board dirver...ok\n"); + + return 0; +} + +static void v682_48x8c_exit(void) +{ + printk(KERN_INFO "deinit v682_48x8c board dirver...\n"); + + v682_48x8c_exit_led(); + + printk(KERN_INFO "deinit v682_48x8c board dirver...ok\n"); +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("shil centecNetworks, Inc"); +MODULE_DESCRIPTION("v682-48x8c board driver"); +module_init(v682_48x8c_init); +module_exit(v682_48x8c_exit); diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/modules/rtc-sd2405.c b/platform/centec/sonic-platform-modules-v682/48x8c/modules/rtc-sd2405.c new file mode 100644 index 00000000000..c22ab334914 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/modules/rtc-sd2405.c @@ -0,0 +1,264 @@ +/* + * rtc class driver for the SD2405 chip + * + * Author: Dale Farnsworth + * + * based on previously existing rtc class drivers + * + * 2007 (c) MontaVista, Software, Inc. 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 + +#define DRV_VERSION "0.1" + +/* + * register indices + */ +#define SD2405_REG_SC 0x0 /* seconds 00-59 */ +#define SD2405_REG_MN 0x1 /* minutes 00-59 */ +#define SD2405_REG_HR 0x2 /* hours 00-23 */ +#define SD2405_REG_DW 0x3 /* day of week 1-7 */ +#define SD2405_REG_DT 0x4 /* day of month 00-31 */ +#define SD2405_REG_MO 0x5 /* month 01-12 */ +#define SD2405_REG_YR 0x6 /* year 00-99 */ + +#define SD2405_REG_CTRL1 0xf /* control 1 */ +#define SD2405_REG_CTRL2 0x10 /* control 2 */ +#define SD2405_REG_CTRL3 0x11 /* control 3 ARST*/ + +#define SD2405_REG_LEN 7 + +/* + * register write protect + */ +#define SD2405_REG_CONTROL1_WRITE 0x80 +#define SD2405_REG_CONTROL2_WRITE 0x84 + + +#define SD2405_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */ + +static struct i2c_driver sd2405_driver; + +#if 1 +/* modified by shil, for bug 46153 */ +static int sd2405_i2c_read_regs(struct i2c_client *client, u8 *buf) +{ + int i; + + for (i = 0; i < SD2405_REG_LEN; i++) { + buf[i] = i2c_smbus_read_byte_data(client, SD2405_REG_SC+i); + } + return 0; +} + +/* modified by shil, for bug 46153 */ +static int sd2405_i2c_write_regs(struct i2c_client *client, u8 const *buf) +{ + int i; + + for (i = 0; i < SD2405_REG_LEN; i++) { + i2c_smbus_write_byte_data(client, SD2405_REG_SC+i, buf[i]); + msleep(SD2405_IDLE_TIME_AFTER_WRITE); + } + return 0; +} + +#else +static int sd2405_i2c_read_regs(struct i2c_client *client, u8 *buf) +{ + struct i2c_msg msgs[1] = { + { + .addr = client->addr, + .flags = I2C_M_RD, /* read */ + .len = SD2405_REG_LEN, + .buf = buf} + }; + int rc; + + rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (rc != ARRAY_SIZE(msgs)) { + dev_err(&client->dev, "%s: register read failed\n", __func__); + return -EIO; + } + return 0; +} + +static int sd2405_i2c_write_regs(struct i2c_client *client, u8 const *buf) +{ + int rc; + + u8 temp_reg[SD2405_REG_LEN+1] = {0}; + memcpy(&temp_reg[1], buf, SD2405_REG_LEN); + + struct i2c_msg msgs[1] = { + { + .addr = client->addr, + .flags = 0, /* write */ + .len = SD2405_REG_LEN+1, + .buf = temp_reg} + }; + + rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (rc != ARRAY_SIZE(msgs)) + goto write_failed; + msleep(SD2405_IDLE_TIME_AFTER_WRITE); + + return 0; + + write_failed: + dev_err(&client->dev, "%s: register write failed\n", __func__); + return -EIO; +} +#endif + +static int sd2405_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) +{ + int rc; + u8 regs[SD2405_REG_LEN]; + + rc = sd2405_i2c_read_regs(client, regs); + if (rc < 0) + return rc; + + tm->tm_sec = bcd2bin(regs[SD2405_REG_SC]); + tm->tm_min = bcd2bin(regs[SD2405_REG_MN]); + tm->tm_hour = bcd2bin(regs[SD2405_REG_HR] & 0x3f); + tm->tm_wday = bcd2bin(regs[SD2405_REG_DW]); + tm->tm_mday = bcd2bin(regs[SD2405_REG_DT]); + tm->tm_mon = bcd2bin(regs[SD2405_REG_MO]) - 1; + tm->tm_year = bcd2bin(regs[SD2405_REG_YR]) + 100; + + return 0; +} + +static int sd2405_i2c_set_write_protect(struct i2c_client *client) +{ + int rc; + rc = i2c_smbus_write_byte_data(client, SD2405_REG_CTRL1, 0); + rc += i2c_smbus_write_byte_data(client, SD2405_REG_CTRL2, 0); + if (rc < 0) { + dev_err(&client->dev, "%s: control register write failed\n", + __func__); + return -EIO; + } + return 0; +} + +static int sd2405_i2c_clear_write_protect(struct i2c_client *client) +{ + int rc; + rc = i2c_smbus_write_byte_data(client, SD2405_REG_CTRL2, SD2405_REG_CONTROL1_WRITE); + rc += i2c_smbus_write_byte_data(client, SD2405_REG_CTRL1, SD2405_REG_CONTROL2_WRITE); + if (rc < 0) { + dev_err(&client->dev, "%s: control register write failed\n", + __func__); + return -EIO; + } + return 0; +} + +static int +sd2405_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) +{ + u8 regs[SD2405_REG_LEN]; + int rc; + + rc = sd2405_i2c_clear_write_protect(client); + if (rc < 0) + return rc; + + regs[SD2405_REG_SC] = bin2bcd(tm->tm_sec); + regs[SD2405_REG_MN] = bin2bcd(tm->tm_min); + regs[SD2405_REG_HR] = bin2bcd(tm->tm_hour)|0x80; + regs[SD2405_REG_DW] = bin2bcd(tm->tm_wday); + regs[SD2405_REG_DT] = bin2bcd(tm->tm_mday); + regs[SD2405_REG_MO] = bin2bcd(tm->tm_mon + 1); + regs[SD2405_REG_YR] = bin2bcd(tm->tm_year - 100); + + rc = sd2405_i2c_write_regs(client, regs); + if (rc < 0) + return rc; + + rc = sd2405_i2c_set_write_protect(client); + if (rc < 0) + return rc; + + return 0; +} + +static int sd2405_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + return sd2405_i2c_read_time(to_i2c_client(dev), tm); +} + +static int sd2405_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + return sd2405_i2c_set_time(to_i2c_client(dev), tm); +} + +static const struct rtc_class_ops sd2405_rtc_ops = { + .read_time = sd2405_rtc_read_time, + .set_time = sd2405_rtc_set_time, +}; + +static int +sd2405_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct rtc_device *rtc; + +/* modified by shil, for bug 46153 */ +#if 0 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; +#endif + + dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); + + rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + i2c_set_clientdata(client, rtc); + rtc->ops = &sd2405_rtc_ops; + + return rtc_register_device(rtc); +} + +static struct i2c_device_id sd2405_id[] = { + { "sd2405", 0 }, + { } +}; + +static struct i2c_driver sd2405_driver = { + .driver = { + .name = "rtc-sd2405", + }, + .probe = sd2405_probe, + .id_table = sd2405_id, +}; + +static int __init sd2405_init(void) +{ + return i2c_add_driver(&sd2405_driver); +} + +static void __exit sd2405_exit(void) +{ + i2c_del_driver(&sd2405_driver); +} + +MODULE_DESCRIPTION("Maxim SD2405 RTC driver"); +MODULE_AUTHOR("Dale Farnsworth "); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +module_init(sd2405_init); +module_exit(sd2405_exit); diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/service/48x8c_platform.service b/platform/centec/sonic-platform-modules-v682/48x8c/service/48x8c_platform.service new file mode 100644 index 00000000000..af5f5b779e6 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/service/48x8c_platform.service @@ -0,0 +1,13 @@ +[Unit] +Description=Centec modules init +After=local-fs.target +Before=syncd.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-v682-48x8c start +ExecStop=-/etc/init.d/platform-modules-v682-48x8c stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/service/release.py b/platform/centec/sonic-platform-modules-v682/48x8c/service/release.py new file mode 100644 index 00000000000..8ae790a24fd --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/service/release.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +import os +import time + +def release_board(): + if open('/proc/cmdline', 'r').readlines()[0].find('SONIC_BOOT_TYPE=warm') != -1: + return + + os.system('i2cset -y 0 0x37 0x4 0x0') + time.sleep(1) + os.system('i2cset -y 0 0x37 0x4 0x1') + time.sleep(1) + os.system('echo 1 > /sys/bus/pci/devices/0000\:00\:1c.0/remove') + time.sleep(1) + os.system('echo 1 > /sys/bus/pci/rescan') + time.sleep(1) + # EPLD_QSFP_RST + os.system('i2cset -y 0 0x36 0x5 0xff') + os.system('i2cset -y 0 0x37 0x5 0xff') + # EPLD_QSFP_INT_MASK + os.system('i2cset -y 0 0x36 0xd 0xff') + os.system('i2cset -y 0 0x37 0xd 0xff') + # EPLD_PPU_INT_MASK + os.system('i2cset -y 0 0x36 0xb 0x00') + # EPLD_SFP_DISABLE1 + os.system('i2cset -y 0 0x36 0xe 0x00') + os.system('i2cset -y 0 0x37 0xe 0x00') + # EPLD_SFP_DISABLE2 + os.system('i2cset -y 0 0x36 0xf 0x00') + os.system('i2cset -y 0 0x37 0xf 0x00') + # EPLD_SFP_DISABLE3 + os.system('i2cset -y 0 0x36 0x10 0x00') + os.system('i2cset -y 0 0x37 0x10 0x00') + +if __name__ == '__main__': + release_board() diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/setup.py b/platform/centec/sonic-platform-modules-v682/48x8c/setup.py new file mode 100644 index 00000000000..57724ad4b4f --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize centec v682-48x8c platforms', + + packages=['sonic_platform'], + package_dir={'sonic_platform': 'sonic_platform'}, +) + diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/__init__.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/__init__.py new file mode 100644 index 00000000000..6e50c02e9d1 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis", "sfp", "eeprom", "psu", "thermal", "fan", "fan_drawer", "led"] +from . import platform diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/chassis.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/chassis.py new file mode 100644 index 00000000000..7a137fc534f --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/chassis.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import re + import time + import collections + from sonic_py_common import device_info + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.fan_drawer import FanDrawer + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_TRAY = 2 +NUM_THERMAL = 1 +NUM_PSU = 2 + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +REBOOT_CAUSE_DIR = "/host/reboot-cause/" +REBOOT_CAUSE_FILE = os.path.join(REBOOT_CAUSE_DIR, "reboot-cause.txt") + +class Chassis(ChassisBase): + # System status LED + _led = None + + def __init__(self): + ChassisBase.__init__(self) + + self.data = {'valid':0, 'last':0} + self.sfp_presence = {} + + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + port_config_file = "/".join([platform_path, "V682-48x8c", "port_config.ini"]) + try: + f = open(port_config_file) + except: + raise + for line in f: + line.strip() + if re.search('^#', line) is not None: + Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:]) + break + f.close() + f = open(port_config_file) + _port_cfgs = [Port_cfg(*tuple((line.strip().split()))) + for line in f if re.search('^#', line) is None] + f.close() + + # Initialize EEPROM + self._eeprom = Eeprom() + + # Initialize FAN + for i in range(NUM_FAN_TRAY): + fandrawer = FanDrawer(i + 1) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + + # Initialize PSU + for index in range(0, NUM_PSU): + psu = Psu(index + 1) + self._psu_list.append(psu) + + # Initialize THERMAL + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + # Initialize SFP + for port_cfg in _port_cfgs: + sfp = Sfp(int(port_cfg.index), 'SFP' if int(port_cfg.index) < 48 else 'QSFP') + self._sfp_list.append(sfp) + self.sfp_presence[int(port_cfg.index)] = False + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + +############################################## +# Chassis methods +############################################## + + 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.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + 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. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + return self._eeprom.system_eeprom_info() + + 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. + """ + if os.path.exists(REBOOT_CAUSE_FILE): + with open(REBOOT_CAUSE_FILE) as reboot_cause_file: + reboot_cause = reboot_cause_file.readline() + if re.search(r'User issued', reboot_cause) is None: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + else: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + else: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + + def get_change_event(self, timeout=2000): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the + format of {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + SFP_STATUS_INSERTED = '1' + SFP_STATUS_REMOVED = '0' + + now = time.time() + port_dict = {} + + if timeout < 1000: + timeout = 1000 + timeout = (timeout) / float(1000) # Convert to secs + + if now < (self.data['last'] + timeout) and self.data['valid']: + return False, {'sfp': {}} + + for sfp in self._sfp_list: + sfp_presence = sfp.get_presence() + if sfp_presence != self.sfp_presence[sfp.index]: + self.sfp_presence[sfp.index] = sfp_presence + if sfp_presence: + port_dict[sfp.index] = SFP_STATUS_INSERTED + else: + port_dict[sfp.index] = SFP_STATUS_REMOVED + + if bool(port_dict): + self.data['last'] = now + self.data['valid'] = 1 + ret = True + else: + time.sleep(0.5) + ret = False + + ret_dict = {'sfp': port_dict} + return ret, ret_dict + + def get_num_psus(self): + return len(self._psu_list) + + def get_psu(self, psu_index): + return self._psu_list[psu_index] + + def initizalize_system_led(self): + from .led import SystemLed + Chassis._led = SystemLed() + + def set_status_led(self, color): + """ + Sets the state of the system LED + + Args: + color: A string representing the color with which to set the + system LED + + Returns: + bool: True if system LED state is set successfully, False if not + """ + return False if not Chassis._led else Chassis._led.set_status(color) + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + return None if not Chassis._led else Chassis._led.get_status() diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/eeprom.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/eeprom.py new file mode 100644 index 00000000000..7d275047571 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/eeprom.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python +# +# Name: eeprom.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_eeprom import eeprom_tlvinfo + from sonic_py_common import device_info + import binascii +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + self.__eeprom_path = platform_path + '/eeprom_file' + + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + + self.__eeprom_tlv_dict = dict() + try: + self.open_eeprom() + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (eeprom[9] << 8) | eeprom[10] + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + eeprom[tlv_index + 1]] + code = "0x%02X" % (tlv[0]) + + if tlv[0] == self._TLV_CODE_VENDOR_EXT: + value = str((tlv[2] << 24) | (tlv[3] << 16) | + (tlv[4] << 8) | tlv[5]) + value += str(tlv[6:6 + tlv[1]]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: + break + + tlv_index += eeprom[tlv_index+1] + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2].decode('ascii') + + def base_mac_addr(self): + (is_valid, t) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(TlvInfoDecoder, self).switchaddrstr(e) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def serial_tag_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def revision_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/fan.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/fan.py new file mode 100644 index 00000000000..5f7b256eafb --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/fan.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import math +import os.path + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FAN_PATH = "/sys/class/hwmon/hwmon{}/" +FAN_MAX_PWM = 255 +FAN_FAN_PWM = "pwm{}" +FAN_FAN_INPUT = "fan{}_input" +FAN_MAX_RPM = 15000 +FAN_NAME_LIST = ["FAN-{}-1", "FAN-{}-2", "FAN-{}-3", "FAN-{}-4"] + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_tray_index, fan_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + + FanBase.__init__(self) + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except IOError: + return False + return True + + def __search_file_by_name(self, directory, file_name): + for dirpath, dirnames, files in os.walk(directory): + for name in files: + file_path = os.path.join(dirpath, name) + if name in file_name: + return file_path + return None + + 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_EXHAUST + 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) + + Note: + speed = pwm_in/255*100 + """ + speed = 0 + fan_speed_sysfs_name = "fan{}_input".format(self.fan_index+1) + fan_speed_sysfs_path = self.__search_file_by_name( + FAN_PATH.format(self.fan_tray_index + 1), fan_speed_sysfs_name) + fan_speed_rpm = self.__read_txt_file(fan_speed_sysfs_path) or 0 + speed = math.ceil(float(fan_speed_rpm) * 100 / FAN_MAX_RPM) + + 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 + """ + # target = 0 + # fan_target_sysfs_name = "pwm{}".format(self.fan_index+1) + # fan_target_sysfs_path = self.__search_file_by_name( + # FAN_PATH.format(self.fan_tray_index + 1), fan_target_sysfs_name) + # fan_target_pwm = self.__read_txt_file(fan_target_sysfs_path) or 0 + # target = math.ceil(float(fan_target_pwm) * 100 / FAN_MAX_PWM) + + # return target + speed = 0 + fan_speed_sysfs_name = "fan{}_input".format(self.fan_index+1) + fan_speed_sysfs_path = self.__search_file_by_name( + FAN_PATH.format(self.fan_tray_index + 1), fan_speed_sysfs_name) + fan_speed_rpm = self.__read_txt_file(fan_speed_sysfs_path) or 0 + speed = math.ceil(float(fan_speed_rpm) * 100 / FAN_MAX_RPM) + + return 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 10 + + 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 + + Note: + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + """ + pwm = speed * 255 / 100 + fan_target_sysfs_name = "pwm{}".format(self.fan_index+1) + fan_target_sysfs_path = self.__search_file_by_name( + FAN_PATH.format(self.fan_tray_index + 1), fan_target_sysfs_name) + return self.__write_txt_file(fan_target_sysfs_path, int(pwm)) + + 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: always True + """ + return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + fan_name = FAN_NAME_LIST[self.fan_index].format(self.fan_tray_index) + + return fan_name + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: always True + """ + + return True + + def get_status(self): + """ + Retrieves the status of the FAN + Returns: + bool: always True + """ + return True diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/fan_drawer.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/fan_drawer.py new file mode 100644 index 00000000000..9940645ff92 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/fan_drawer.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +######################################################################## +# Centec V682 48X8C +# +# 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 + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CENTEC_FANS_PER_FANTRAY = 4 + + +class FanDrawer(FanDrawerBase): + """Centec V682 48X8C Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + self.fantrayindex = fantray_index + for i in range(CENTEC_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + + Args: + color: A string representing the color with which to set the + fan drawer status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + return True diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/led.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/led.py new file mode 100644 index 00000000000..492d6983ea7 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/led.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the led status which are available in the platform +# +############################################################################# + +from subprocess import Popen, PIPE, STDOUT + +class SystemLed(object): + STATUS_LED_COLOR_GREEN = 'green' + STATUS_LED_COLOR_ORANGE = 'orange' + STATUS_LED_COLOR_OFF = 'off' + + SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' + + def set_status(self, color): + status = False + + if color == SystemLed.STATUS_LED_COLOR_ORANGE: + cmd = 'i2cset -y 0 0x36 0x2 0xb' + Popen(cmd, shell=True) + status = True + elif color == SystemLed.STATUS_LED_COLOR_OFF: + cmd = 'i2cset -y 0 0x36 0x2 0x0' + Popen(cmd, shell=True) + status = True + elif color == SystemLed.STATUS_LED_COLOR_GREEN: + cmd = 'i2cset -y 0 0x36 0x2 0x5' + Popen(cmd, shell=True) + status = True + + return status + + def get_status(self): + cmd = 'i2cget -y 0 0x36 0x2' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + if status == 11: + return SystemLed.STATUS_LED_COLOR_ORANGE + elif status == 0: + return SystemLed.STATUS_LED_COLOR_OFF + else: + return SystemLed.STATUS_LED_COLOR_GREEN diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/platform.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/platform.py new file mode 100644 index 00000000000..59d37da538a --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/platform.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs for Centec V682-48X8C +# + + +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): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() + diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/psu.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/psu.py new file mode 100644 index 00000000000..779209c71c2 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/psu.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +from __future__ import print_function + +from subprocess import Popen, PIPE, STDOUT + +try: + from sonic_platform_base.psu_base import PsuBase +except ImportError as e: + raise ImportError("%s - required module not found" % e) + +class Psu(PsuBase): + """Centec Platform-specific PSU class""" + + def __init__(self, index): + self._index = index + self._fan_list = [] + + def get_presence(self): + cmd = 'i2cget -y 0 0x36 0x1e' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + presence = ((status & (1 << (3 * (self._index - 1) + 1))) == 0) + return presence + + def get_powergood_status(self): + cmd = 'i2cget -y 0 0x36 0x1e' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + powergood = ((status & (1 << (3 * (self._index - 1) + 2))) != 0) + return powergood diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/sfp.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/sfp.py new file mode 100644 index 00000000000..1d4154ff838 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/sfp.py @@ -0,0 +1,1618 @@ +#!/usr/bin/env python + +############################################################################# +# Centec +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# + +import os +import time +import re +import collections +#import subprocess +#import sonic_device_util +from ctypes import create_string_buffer +from subprocess import Popen, PIPE, STDOUT +from sonic_py_common import device_info + +try: + from sonic_platform_base.sfp_base import SfpBase +# from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +QSFP_INFO_OFFSET = 128 +QSFP_DOM_OFFSET = 0 +SFP_INFO_OFFSET = 0 +SFP_DOM_OFFSET = 256 + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 2 + +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +QSFP_DOM_BULK_DATA_START = 22 +QSFP_DOM_BULK_DATA_SIZE = 36 +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 1 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_MODULE_MONITOR_OFFSET = 0 +QSFP_MODULE_MONITOR_WIDTH = 9 +QSFP_MODULE_THRESHOLD_OFFSET = 512 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 560 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_POWEROVERRIDE_BIT = 0 +QSFP_POWERSET_BIT = 1 +QSFP_OPTION_VALUE_OFFSET = 192 +QSFP_OPTION_VALUE_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes','FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia','FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + dom_supported = True + dom_temp_supported = True + dom_volt_supported = True + dom_rx_power_supported = True + dom_tx_power_supported = True + dom_tx_disable_supported = True + calibration = 1 + + # Path to QSFP sysfs + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "x86_64-centec_v682_48x8c-r0" + HWSKU = "V682-48x8c" + + def __init__(self, sfp_index, sfp_type): + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + port_config_file = "/".join([platform_path, self.HWSKU, "port_config.ini"]) + try: + f = open(port_config_file) + except: + raise + for line in f: + line.strip() + if re.search('^#', line) is not None: + Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:]) + break + f.close() + f = open(port_config_file) + self._port_cfgs = [Port_cfg(*tuple((line.strip().split()))) + for line in f if re.search('^#', line) is None] + f.close() + + # Port number + self.PORT_START = 256 + self.PORT_END = 0 + self.QSFP_START = 48 + self.QSFP_END = 0 + + for port_cfg in self._port_cfgs: + if int(port_cfg.index) <= self.PORT_START: + self.PORT_START = int(port_cfg.index) + elif int(port_cfg.index) >= self.PORT_END: + self.PORT_END = int(port_cfg.index) + self.QSFP_END = self.PORT_END + + # Init index + self.index = sfp_index + self.port_num = self.index + #self.dom_supported = False + self.sfp_type = sfp_type + # Init eeprom path + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + self.port_to_eeprom_mapping = {} + self.port_to_i2c_mapping = { + # mac i2c presence enable(or reset for qsfp) + 32 : (13, 0x36, 0x11, 0, 0x36, 0x0e, 0), + 33 : (12, 0x36, 0x11, 1, 0x36, 0x0e, 1), + 34 : (11, 0x36, 0x11, 2, 0x36, 0x0e, 2), + 35 : (10, 0x36, 0x11, 3, 0x36, 0x0e, 3), + 0 : (17, 0x36, 0x11, 4, 0x36, 0x0e, 4), + 4 : (16, 0x36, 0x11, 5, 0x36, 0x0e, 5), + 8 : (15, 0x36, 0x11, 6, 0x36, 0x0e, 6), + 12 : (14, 0x36, 0x11, 7, 0x36, 0x0e, 7), + 16 : (21, 0x36, 0x12, 0, 0x36, 0x0f, 0), + 20 : (20, 0x36, 0x12, 1, 0x36, 0x0f, 1), + 24 : (19, 0x36, 0x12, 2, 0x36, 0x0f, 2), + 28 : (18, 0x36, 0x12, 3, 0x36, 0x0f, 3), + 40 : (25, 0x36, 0x12, 4, 0x36, 0x0f, 4), + 44 : (24, 0x36, 0x12, 5, 0x36, 0x0f, 5), + 48 : (23, 0x36, 0x12, 6, 0x36, 0x0f, 6), + 52 : (22, 0x36, 0x12, 7, 0x36, 0x0f, 7), + 56 : (29, 0x36, 0x13, 0, 0x36, 0x10, 0), + 60 : (28, 0x36, 0x13, 1, 0x36, 0x10, 1), + 64 : (27, 0x36, 0x13, 2, 0x36, 0x10, 2), + 68 : (26, 0x36, 0x13, 3, 0x36, 0x10, 3), + 72 : (33, 0x36, 0x13, 4, 0x36, 0x10, 4), + 73 : (32, 0x36, 0x13, 5, 0x36, 0x10, 5), + 74 : (31, 0x36, 0x13, 6, 0x36, 0x10, 6), + 75 : (30, 0x36, 0x13, 7, 0x36, 0x10, 7), + 232 : (37, 0x37, 0x11, 0, 0x37, 0x0e, 0), + 233 : (36, 0x37, 0x11, 1, 0x37, 0x0e, 1), + 234 : (35, 0x37, 0x11, 2, 0x37, 0x0e, 2), + 235 : (34, 0x37, 0x11, 3, 0x37, 0x0e, 3), + 200 : (41, 0x37, 0x11, 4, 0x37, 0x0e, 4), + 204 : (40, 0x37, 0x11, 5, 0x37, 0x0e, 5), + 208 : (39, 0x37, 0x11, 6, 0x37, 0x0e, 6), + 212 : (38, 0x37, 0x11, 7, 0x37, 0x0e, 7), + 216 : (45, 0x37, 0x12, 0, 0x37, 0x0f, 0), + 220 : (44, 0x37, 0x12, 1, 0x37, 0x0f, 1), + 224 : (43, 0x37, 0x12, 2, 0x37, 0x0f, 2), + 228 : (42, 0x37, 0x12, 3, 0x37, 0x0f, 3), + 160 : (49, 0x37, 0x12, 4, 0x37, 0x0f, 4), + 164 : (48, 0x37, 0x12, 5, 0x37, 0x0f, 5), + 168 : (47, 0x37, 0x12, 6, 0x37, 0x0f, 6), + 172 : (46, 0x37, 0x12, 7, 0x37, 0x0f, 7), + 176 : (53, 0x37, 0x13, 0, 0x37, 0x10, 0), + 180 : (52, 0x37, 0x13, 1, 0x37, 0x10, 1), + 184 : (51, 0x37, 0x13, 2, 0x37, 0x10, 2), + 188 : (50, 0x37, 0x13, 3, 0x37, 0x10, 3), + 192 : (57, 0x37, 0x13, 4, 0x37, 0x10, 4), + 193 : (56, 0x37, 0x13, 5, 0x37, 0x10, 5), + 194 : (55, 0x37, 0x13, 6, 0x37, 0x10, 6), + 195 : (54, 0x37, 0x13, 7, 0x37, 0x10, 7), + 120 : (61, 0x36, 0x14, 0, 0x36, 0x05, 0), + 121 : (61, 0x36, 0x14, 0, 0x36, 0x05, 0), + 122 : (61, 0x36, 0x14, 0, 0x36, 0x05, 0), + 123 : (61, 0x36, 0x14, 0, 0x36, 0x05, 0), + 124 : (60, 0x36, 0x14, 1, 0x36, 0x05, 1), + 125 : (60, 0x36, 0x14, 1, 0x36, 0x05, 1), + 126 : (60, 0x36, 0x14, 1, 0x36, 0x05, 1), + 127 : (60, 0x36, 0x14, 1, 0x36, 0x05, 1), + 80 : (59, 0x36, 0x14, 2, 0x36, 0x05, 2), + 81 : (59, 0x36, 0x14, 2, 0x36, 0x05, 2), + 82 : (59, 0x36, 0x14, 2, 0x36, 0x05, 2), + 83 : (59, 0x36, 0x14, 2, 0x36, 0x05, 2), + 84 : (58, 0x36, 0x14, 3, 0x36, 0x05, 3), + 85 : (58, 0x36, 0x14, 3, 0x36, 0x05, 3), + 86 : (58, 0x36, 0x14, 3, 0x36, 0x05, 3), + 87 : (58, 0x36, 0x14, 3, 0x36, 0x05, 3), + 240 : (65, 0x37, 0x14, 0, 0x37, 0x05, 0), + 241 : (65, 0x37, 0x14, 0, 0x37, 0x05, 0), + 242 : (65, 0x37, 0x14, 0, 0x37, 0x05, 0), + 243 : (65, 0x37, 0x14, 0, 0x37, 0x05, 0), + 244 : (64, 0x37, 0x14, 1, 0x37, 0x05, 1), + 245 : (64, 0x37, 0x14, 1, 0x37, 0x05, 1), + 246 : (64, 0x37, 0x14, 1, 0x37, 0x05, 1), + 247 : (64, 0x37, 0x14, 1, 0x37, 0x05, 1), + 280 : (63, 0x37, 0x14, 2, 0x37, 0x05, 2), + 281 : (63, 0x37, 0x14, 2, 0x37, 0x05, 2), + 282 : (63, 0x37, 0x14, 2, 0x37, 0x05, 2), + 283 : (63, 0x37, 0x14, 2, 0x37, 0x05, 2), + 284 : (62, 0x37, 0x14, 3, 0x37, 0x05, 3), + 285 : (62, 0x37, 0x14, 3, 0x37, 0x05, 3), + 286 : (62, 0x37, 0x14, 3, 0x37, 0x05, 3), + 287 : (62, 0x37, 0x14, 3, 0x37, 0x05, 3) + } + + for port_cfg in self._port_cfgs: + i2c_idx = self.port_to_i2c_mapping[int(port_cfg.lanes.split(',')[0])][0] + port_eeprom_path = eeprom_path.format(i2c_idx) + self.port_to_eeprom_mapping[int(port_cfg.index)] = port_eeprom_path + + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', + 'model', 'connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', + 'nominal_bit_rate', 'specification_compliance', 'vendor_date', + 'vendor_oui', 'application_advertisement'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', + 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def get_presence(self): + """ + Retrieves the presence of the SFP module + Returns: + bool: True if SFP module is present, False if not + """ + # Check for invalid port_num + if self.port_num < self.PORT_START or self.port_num > self.PORT_END: + return False + + sfp_info = self.port_to_i2c_mapping[int(self._port_cfgs[self.port_num].lanes.split(',')[0])] + cmd = 'i2cget -y 0 {0} {1}'.format(sfp_info[1], sfp_info[2]) + presence = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + presence &= (1 << sfp_info[3]) + + try: + with open(self.port_to_eeprom_mapping[self.port_num], mode='rb', buffering=0) as fd: + fd.read() + except IOError: + return False + + return (presence == 0) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + except Exception: + eeprom_raw = None + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def _dom_capability_detect(self): + if not self.get_presence(): + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + if self.sfp_type == "QSFP": + self.calibration = 1 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + offset = 128 + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_dom_capability = int(qsfp_dom_capability_raw[0], 16) + + qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes( + QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_OFFSET) + if qsfp_version_compliance_raw is not None: + qsfp_version_compliance = int(qsfp_version_compliance_raw[0], 16) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = (qsfp_dom_capability & 0x20 != 0) + self.dom_volt_supported = (qsfp_dom_capability & 0x10 != 0) + self.dom_rx_power_supported = (qsfp_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = (qsfp_dom_capability & 0x04 != 0) + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = (qsfp_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = True + self.dom_supported = True + self.calibration = 1 + self.dom_tx_disable_supported = True + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + elif self.sfp_type == "SFP": + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = (int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + application_advertisement |1*255VCHAR |supported applications advertisement + ======================================================================== + """ + + transceiver_info_dict = {} + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + transceiver_info_dict['specification_compliance'] = '{}' + if not self.get_presence(): + return transceiver_info_dict + + if self.sfp_type == QSFP_TYPE: + offset = QSFP_INFO_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return transceiver_info_dict + + elif self.sfp_type == SFP_TYPE: + offset = SFP_INFO_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return transceiver_info_dict + else: + return transceiver_info_dict + + # Add retry for xcvr eeprom to get ready + max_retry = 10 + for i in range(0,max_retry): + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is not None: + break + else: + if not self.get_presence(): + return transceiver_info_dict + elif i == max_retry-1: + pass + else: + time.sleep(0.5) + + if sfp_interface_bulk_raw is None: + return transceiver_info_dict + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_interface_bulk_raw[start : end], 0) + transceiver_info_dict['type'] = sfp_interface_bulk_data \ + ['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data \ + ['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data \ + ['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data \ + ['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data \ + ['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data \ + ['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data \ + ['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data \ + ['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data \ + ['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data \ + ['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data \ + ['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = 'N/A' + if self.sfp_type == QSFP_TYPE: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data \ + ['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data \ + ['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data \ + ['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data \ + ['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + + if not self.get_presence(): + return None + + self._dom_capability_detect() + + if self.sfp_type == QSFP_TYPE: + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not sfpi_obj or not sfpd_obj: + return None + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + offset = QSFP_DOM_OFFSET + offset_xcvr = QSFP_INFO_OFFSET + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_dom_capability_data = sfpi_obj.parse_dom_capability( + qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qsfp_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + elif self.sfp_type == SFP_TYPE: + sfpd_obj = sff8472Dom() + if not sfpd_obj: + return None + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, SFP_DOM_OFFSET) + if eeprom_ifraw is not None: + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = SFP_DOM_OFFSET + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_voltage_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value'] + transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value'] + else: + return None + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + if self.sfp_type == QSFP_TYPE: + sfpd_obj = sff8436Dom() + if not self.get_presence() or not sfpd_obj: + return None + DOM_OFFSET = 0 + transceiver_dom_threshold_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + offset = DOM_OFFSET + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + module_threshold_values = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_channel_thres_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNEL_THRESHOLD_OFFSET), QSFP_CHANNEL_THRESHOLD_WIDTH) + if dom_channel_thres_raw is not None: + channel_threshold_values = sfpd_obj.parse_channel_threshold_values(dom_channel_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + else: + channel_threshold_data = None + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + elif self.sfp_type == SFP_TYPE: + sfpd_obj = sff8472Dom() + + if not self.get_presence() and not sfpd_obj: + return None + DOM_OFFSET = 256 + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + if eeprom_ifraw is not None: + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_threshold_info_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + else: + return None + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + # Check for invalid port_num + if self.port_num < self.PORT_START or self.port_num > self.PORT_END or self.sfp_type == SFP_TYPE: + return False + + sfp_info = self.port_to_i2c_mapping[int(self._port_cfgs[self.port_num].lanes.split(',')[0])] + cmd = 'i2cget -y 0 {0} {1}'.format(sfp_info[4], sfp_info[5]) + reset_status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + reset_status &= (1 << sfp_info[6]) + + return (reset_status == 1) + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + if not self.dom_supported: + return None + + rx_los_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + elif self.sfp_type == SFP_TYPE: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_STATUS_CONTROL_OFFSET), SFP_STATUS_CONTROL_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x02 != 0) + else: + return None + else: + return None + + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + if not self.dom_supported: + return None + + tx_fault_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + elif self.sfp_type == SFP_TYPE: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_STATUS_CONTROL_OFFSET), SFP_STATUS_CONTROL_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + else: + return None + else: + return None + + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + if not self.dom_supported: + return None + + tx_disable_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + elif self.sfp_type == SFP_TYPE: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_STATUS_CONTROL_OFFSET), SFP_STATUS_CONTROL_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0xC0 != 0) + else: + return None + else: + return None + + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + # SFP doesn't support this feature + if self.sfp_type == SFP_TYPE: + return 0 + elif self.sfp_type == QSFP_TYPE: + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + else: + return None + + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this QSFP module + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + return False + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + # SFP doesn't support this feature + if self.sfp_type == SFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_POWEROVERRIDE_OFFSET), QSFP_POWEROVERRIDE_WIDTH) + if dom_control_raw is not None: + if int(dom_control_raw[0],16) & (0x01 << QSFP_POWEROVERRIDE_BIT): + return True + else: + return False + else: + return None + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + elif self.sfp_type == SFP_TYPE: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = 1 + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + else: + return None + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + elif self.sfp_type == SFP_TYPE: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + sfpd_obj._calibration_type = self.calibration + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + else: + return None + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + tx_bias_list = [] + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX4Bias']['value'])) + elif self.sfp_type == SFP_TYPE: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = self.calibration + + if self.dom_supported: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( \ + dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TXBias']['value'])) + else: + return None + else: + return None + else: + return None + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX4Power']['value'])) + else: + return None + else: + return None + elif self.sfp_type == SFP_TYPE: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + else: + return None + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX4Power']['value'])) + else: + return None + else: + return None + elif self.sfp_type == SFP_TYPE: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + else: + return None + + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default state. + Returns: + A boolean, True if successful, False if not + """ + if not self.get_presence(): + return False + + # SFP doesn't support this feature + if self.sfp_type == SFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + sfp_info = self.port_to_i2c_mapping[int(self._port_cfgs[self.port_num].lanes.split(',')[0])] + cmd = 'i2cget -y 0 {0} {1}'.format(sfp_info[4], sfp_info[5]) + reset = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + + reset &= ~(1 << sfp_info[6]) + cmd = 'i2cset -y 0 {0} {1} {2}'.format(sfp_info[4], sfp_info[5], reset) + Popen(cmd, shell=True) + + reset |= (1 << sfp_info[6]) + cmd = 'i2cset -y 0 {0} {1} {2}'.format(sfp_info[4], sfp_info[5], reset) + Popen(cmd, shell=True) + + return True + + 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.sfp_type == SFP_TYPE: + if self.dom_tx_disable_supported: + offset = 256 + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + status_control_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_STATUS_CONTROL_OFFSET), SFP_STATUS_CONTROL_WIDTH) + if status_control_raw is not None: + # Set bit 6 for Soft TX Disable Select + # 01000000 = 64 and 10111111 = 191 + tx_disable_bit = 64 if tx_disable else 191 + status_control = int(status_control_raw[0], 16) + tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else ( + status_control & tx_disable_bit) + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom.seek(offset + SFP_STATUS_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + else: + return False + elif self.sfp_type == QSFP_TYPE: + if self.dom_tx_disable_supported: + channel_mask = 0x0f + if tx_disable: + return self.tx_disable_channel(channel_mask, True) + else: + return self.tx_disable_channel(channel_mask, False) + else: + return False + else: + return None + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + if not self.get_presence(): + return False + # SFP doesn't support this feature + if self.sfp_type == SFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + if self.dom_tx_disable_supported: + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + if disable: + tx_disable_ctl = channel_state | channel + else: + tx_disable_ctl = channel_state & (~channel) + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + else: + return False + else: + return None + + 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 + """ + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + # SFP doesn't support this feature + if not self.get_presence(): + return False + + if self.sfp_type == SFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfsfile_eeprom = open(self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + else: + return None + + return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return "Ethernet{}".format(self.port_num) + diff --git a/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/thermal.py b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/thermal.py new file mode 100644 index 00000000000..ca4e3596926 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48x8c/sonic_platform/thermal.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# 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 +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + THERMAL_NAME_LIST = [] + CPUBOARD_SS_PATH = "/sys/class/hwmon/hwmon1" + + def __init__(self, thermal_index): + self.index = thermal_index + self.high_threshold = float(112) + + # Add thermal name + self.THERMAL_NAME_LIST.append("ASIC") + + # Set hwmon path + self.ss_index, self.hwmon_path = 1, self.CPUBOARD_SS_PATH + self.ss_key = self.THERMAL_NAME_LIST[self.index - 1] + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + raise IOError("Unable to open %s file !" % file_path) + + def __get_temp(self, temp_file): + temp_file_path = os.path.join(self.hwmon_path, temp_file) + raw_temp = self.__read_txt_file(temp_file_path) + temp = float(raw_temp)/1000 + return float("{:.3f}".format(temp)) + + def __set_threshold(self, file_name, temperature): + temp_file_path = os.path.join(self.hwmon_path, file_name) + try: + with open(temp_file_path, 'w') as fd: + fd.write(str(temperature)) + return True + except IOError: + return False + + 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 + """ + temp_file = "temp{}_input".format(self.ss_index) + return self.__get_temp(temp_file) + + 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 + """ + return self.high_threshold + + 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 + """ + self.high_threshold = float(temperature) + return True + + def get_name(self): + """ + Retrieves the name of the thermal device + Returns: + string: The name of the thermal device + """ + 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 + """ + temp_file = "temp{}_input".format(self.ss_index) + temp_file_path = os.path.join(self.hwmon_path, temp_file) + return os.path.isfile(temp_file_path) + + 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 not self.get_presence(): + return False + + return True diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/service/release.py b/platform/centec/sonic-platform-modules-v682/48y8c-d/service/release.py index 2c799e6ef3d..a5174b02daa 100644 --- a/platform/centec/sonic-platform-modules-v682/48y8c-d/service/release.py +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/service/release.py @@ -1,10 +1,10 @@ -#!/usr/bin/python2 +#!/usr/bin/env python import os import sys import time -susi4_lib = '/usr/local/lib/python2.7/dist-packages/' +susi4_lib = '/usr/local/lib/python3.9/dist-packages/' if not susi4_lib in os.environ.setdefault('LD_LIBRARY_PATH', ''): os.environ['LD_LIBRARY_PATH'] += (':' + susi4_lib) try: diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/modules/Makefile b/platform/centec/sonic-platform-modules-v682/48y8c/modules/Makefile new file mode 100644 index 00000000000..53c96acb0cb --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/modules/Makefile @@ -0,0 +1 @@ +obj-m := centec_v682_48y8c_platform.o rtc-sd2405.o diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/modules/centec_v682_48y8c_platform.c b/platform/centec/sonic-platform-modules-v682/48y8c/modules/centec_v682_48y8c_platform.c new file mode 100644 index 00000000000..28e0e9f2610 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/modules/centec_v682_48y8c_platform.c @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include +#include + +#define SEP(XXX) 1 +#define IS_INVALID_PTR(_PTR_) ((_PTR_ == NULL) || IS_ERR(_PTR_)) +#define IS_VALID_PTR(_PTR_) (!IS_INVALID_PTR(_PTR_)) + +#if SEP("defines") +#define SFP_NUM 48 +#define QSFP_NUM 8 +#define PORT_NUM (SFP_NUM + QSFP_NUM) +#endif + +#if SEP("drivers:leds") +extern void v682_48y8c_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value); +extern enum led_brightness v682_48y8c_led_port_get(struct led_classdev *led_cdev); + +static struct led_classdev led_dev_port[PORT_NUM] = { +{ .name = "port0", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port1", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port2", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port3", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port4", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port5", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port6", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port7", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port8", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port9", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port10", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port11", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port12", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port13", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port14", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port15", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port16", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port17", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port18", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port19", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port20", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port21", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port22", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port23", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port24", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port25", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port26", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port27", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port28", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port29", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port30", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port31", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port32", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port33", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port34", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port35", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port36", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port37", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port38", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port39", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port40", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port41", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port42", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port43", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port44", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port45", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port46", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port47", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port48", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port49", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port50", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port51", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port52", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port53", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port54", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +{ .name = "port55", .brightness_set = v682_48y8c_led_port_set, .brightness_get = v682_48y8c_led_port_get,}, +}; +static unsigned char port_led_mode[PORT_NUM] = {0}; + +void v682_48y8c_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + port_led_mode[portNum] = set_value; + + return; +} + +enum led_brightness v682_48y8c_led_port_get(struct led_classdev *led_cdev) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + return port_led_mode[portNum]; +} + +static int v682_48y8c_init_led(void) +{ + int ret = 0; + int i = 0; + + for (i = 0; i < PORT_NUM; i++) + { + ret = led_classdev_register(NULL, &(led_dev_port[i])); + if (ret != 0) + { + printk(KERN_CRIT "create v682_48y8c led_dev_port%d device failed\n", i); + continue; + } + } + + return ret; +} + +static int v682_48y8c_exit_led(void) +{ + int i = 0; + + for (i = 0; i < PORT_NUM; i++) + { + led_classdev_unregister(&(led_dev_port[i])); + } + + return 0; +} +#endif + +static int v682_48y8c_init(void) +{ + int ret = 0; + int failed = 0; + + printk(KERN_ALERT "init v682_48y8c board dirver...\n"); + + ret = v682_48y8c_init_led(); + if (ret != 0) + { + failed = 1; + } + + if (failed) + printk(KERN_INFO "init v682_48y8c board driver failed\n"); + else + printk(KERN_ALERT "init v682_48y8c board dirver...ok\n"); + + return 0; +} + +static void v682_48y8c_exit(void) +{ + printk(KERN_INFO "deinit v682_48y8c board dirver...\n"); + + v682_48y8c_exit_led(); + + printk(KERN_INFO "deinit v682_48y8c board dirver...ok\n"); +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("shil centecNetworks, Inc"); +MODULE_DESCRIPTION("v682-48y8c board driver"); +module_init(v682_48y8c_init); +module_exit(v682_48y8c_exit); diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/modules/rtc-sd2405.c b/platform/centec/sonic-platform-modules-v682/48y8c/modules/rtc-sd2405.c new file mode 100644 index 00000000000..c22ab334914 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/modules/rtc-sd2405.c @@ -0,0 +1,264 @@ +/* + * rtc class driver for the SD2405 chip + * + * Author: Dale Farnsworth + * + * based on previously existing rtc class drivers + * + * 2007 (c) MontaVista, Software, Inc. 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 + +#define DRV_VERSION "0.1" + +/* + * register indices + */ +#define SD2405_REG_SC 0x0 /* seconds 00-59 */ +#define SD2405_REG_MN 0x1 /* minutes 00-59 */ +#define SD2405_REG_HR 0x2 /* hours 00-23 */ +#define SD2405_REG_DW 0x3 /* day of week 1-7 */ +#define SD2405_REG_DT 0x4 /* day of month 00-31 */ +#define SD2405_REG_MO 0x5 /* month 01-12 */ +#define SD2405_REG_YR 0x6 /* year 00-99 */ + +#define SD2405_REG_CTRL1 0xf /* control 1 */ +#define SD2405_REG_CTRL2 0x10 /* control 2 */ +#define SD2405_REG_CTRL3 0x11 /* control 3 ARST*/ + +#define SD2405_REG_LEN 7 + +/* + * register write protect + */ +#define SD2405_REG_CONTROL1_WRITE 0x80 +#define SD2405_REG_CONTROL2_WRITE 0x84 + + +#define SD2405_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */ + +static struct i2c_driver sd2405_driver; + +#if 1 +/* modified by shil, for bug 46153 */ +static int sd2405_i2c_read_regs(struct i2c_client *client, u8 *buf) +{ + int i; + + for (i = 0; i < SD2405_REG_LEN; i++) { + buf[i] = i2c_smbus_read_byte_data(client, SD2405_REG_SC+i); + } + return 0; +} + +/* modified by shil, for bug 46153 */ +static int sd2405_i2c_write_regs(struct i2c_client *client, u8 const *buf) +{ + int i; + + for (i = 0; i < SD2405_REG_LEN; i++) { + i2c_smbus_write_byte_data(client, SD2405_REG_SC+i, buf[i]); + msleep(SD2405_IDLE_TIME_AFTER_WRITE); + } + return 0; +} + +#else +static int sd2405_i2c_read_regs(struct i2c_client *client, u8 *buf) +{ + struct i2c_msg msgs[1] = { + { + .addr = client->addr, + .flags = I2C_M_RD, /* read */ + .len = SD2405_REG_LEN, + .buf = buf} + }; + int rc; + + rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (rc != ARRAY_SIZE(msgs)) { + dev_err(&client->dev, "%s: register read failed\n", __func__); + return -EIO; + } + return 0; +} + +static int sd2405_i2c_write_regs(struct i2c_client *client, u8 const *buf) +{ + int rc; + + u8 temp_reg[SD2405_REG_LEN+1] = {0}; + memcpy(&temp_reg[1], buf, SD2405_REG_LEN); + + struct i2c_msg msgs[1] = { + { + .addr = client->addr, + .flags = 0, /* write */ + .len = SD2405_REG_LEN+1, + .buf = temp_reg} + }; + + rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (rc != ARRAY_SIZE(msgs)) + goto write_failed; + msleep(SD2405_IDLE_TIME_AFTER_WRITE); + + return 0; + + write_failed: + dev_err(&client->dev, "%s: register write failed\n", __func__); + return -EIO; +} +#endif + +static int sd2405_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) +{ + int rc; + u8 regs[SD2405_REG_LEN]; + + rc = sd2405_i2c_read_regs(client, regs); + if (rc < 0) + return rc; + + tm->tm_sec = bcd2bin(regs[SD2405_REG_SC]); + tm->tm_min = bcd2bin(regs[SD2405_REG_MN]); + tm->tm_hour = bcd2bin(regs[SD2405_REG_HR] & 0x3f); + tm->tm_wday = bcd2bin(regs[SD2405_REG_DW]); + tm->tm_mday = bcd2bin(regs[SD2405_REG_DT]); + tm->tm_mon = bcd2bin(regs[SD2405_REG_MO]) - 1; + tm->tm_year = bcd2bin(regs[SD2405_REG_YR]) + 100; + + return 0; +} + +static int sd2405_i2c_set_write_protect(struct i2c_client *client) +{ + int rc; + rc = i2c_smbus_write_byte_data(client, SD2405_REG_CTRL1, 0); + rc += i2c_smbus_write_byte_data(client, SD2405_REG_CTRL2, 0); + if (rc < 0) { + dev_err(&client->dev, "%s: control register write failed\n", + __func__); + return -EIO; + } + return 0; +} + +static int sd2405_i2c_clear_write_protect(struct i2c_client *client) +{ + int rc; + rc = i2c_smbus_write_byte_data(client, SD2405_REG_CTRL2, SD2405_REG_CONTROL1_WRITE); + rc += i2c_smbus_write_byte_data(client, SD2405_REG_CTRL1, SD2405_REG_CONTROL2_WRITE); + if (rc < 0) { + dev_err(&client->dev, "%s: control register write failed\n", + __func__); + return -EIO; + } + return 0; +} + +static int +sd2405_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) +{ + u8 regs[SD2405_REG_LEN]; + int rc; + + rc = sd2405_i2c_clear_write_protect(client); + if (rc < 0) + return rc; + + regs[SD2405_REG_SC] = bin2bcd(tm->tm_sec); + regs[SD2405_REG_MN] = bin2bcd(tm->tm_min); + regs[SD2405_REG_HR] = bin2bcd(tm->tm_hour)|0x80; + regs[SD2405_REG_DW] = bin2bcd(tm->tm_wday); + regs[SD2405_REG_DT] = bin2bcd(tm->tm_mday); + regs[SD2405_REG_MO] = bin2bcd(tm->tm_mon + 1); + regs[SD2405_REG_YR] = bin2bcd(tm->tm_year - 100); + + rc = sd2405_i2c_write_regs(client, regs); + if (rc < 0) + return rc; + + rc = sd2405_i2c_set_write_protect(client); + if (rc < 0) + return rc; + + return 0; +} + +static int sd2405_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + return sd2405_i2c_read_time(to_i2c_client(dev), tm); +} + +static int sd2405_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + return sd2405_i2c_set_time(to_i2c_client(dev), tm); +} + +static const struct rtc_class_ops sd2405_rtc_ops = { + .read_time = sd2405_rtc_read_time, + .set_time = sd2405_rtc_set_time, +}; + +static int +sd2405_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct rtc_device *rtc; + +/* modified by shil, for bug 46153 */ +#if 0 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; +#endif + + dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); + + rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + i2c_set_clientdata(client, rtc); + rtc->ops = &sd2405_rtc_ops; + + return rtc_register_device(rtc); +} + +static struct i2c_device_id sd2405_id[] = { + { "sd2405", 0 }, + { } +}; + +static struct i2c_driver sd2405_driver = { + .driver = { + .name = "rtc-sd2405", + }, + .probe = sd2405_probe, + .id_table = sd2405_id, +}; + +static int __init sd2405_init(void) +{ + return i2c_add_driver(&sd2405_driver); +} + +static void __exit sd2405_exit(void) +{ + i2c_del_driver(&sd2405_driver); +} + +MODULE_DESCRIPTION("Maxim SD2405 RTC driver"); +MODULE_AUTHOR("Dale Farnsworth "); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +module_init(sd2405_init); +module_exit(sd2405_exit); diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/service/48y8c_platform.service b/platform/centec/sonic-platform-modules-v682/48y8c/service/48y8c_platform.service new file mode 100644 index 00000000000..48327ec456b --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/service/48y8c_platform.service @@ -0,0 +1,13 @@ +[Unit] +Description=Centec modules init +After=local-fs.target +Before=syncd.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-v682-48y8c start +ExecStop=-/etc/init.d/platform-modules-v682-48y8c stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/service/release.py b/platform/centec/sonic-platform-modules-v682/48y8c/service/release.py new file mode 100644 index 00000000000..8ae790a24fd --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/service/release.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +import os +import time + +def release_board(): + if open('/proc/cmdline', 'r').readlines()[0].find('SONIC_BOOT_TYPE=warm') != -1: + return + + os.system('i2cset -y 0 0x37 0x4 0x0') + time.sleep(1) + os.system('i2cset -y 0 0x37 0x4 0x1') + time.sleep(1) + os.system('echo 1 > /sys/bus/pci/devices/0000\:00\:1c.0/remove') + time.sleep(1) + os.system('echo 1 > /sys/bus/pci/rescan') + time.sleep(1) + # EPLD_QSFP_RST + os.system('i2cset -y 0 0x36 0x5 0xff') + os.system('i2cset -y 0 0x37 0x5 0xff') + # EPLD_QSFP_INT_MASK + os.system('i2cset -y 0 0x36 0xd 0xff') + os.system('i2cset -y 0 0x37 0xd 0xff') + # EPLD_PPU_INT_MASK + os.system('i2cset -y 0 0x36 0xb 0x00') + # EPLD_SFP_DISABLE1 + os.system('i2cset -y 0 0x36 0xe 0x00') + os.system('i2cset -y 0 0x37 0xe 0x00') + # EPLD_SFP_DISABLE2 + os.system('i2cset -y 0 0x36 0xf 0x00') + os.system('i2cset -y 0 0x37 0xf 0x00') + # EPLD_SFP_DISABLE3 + os.system('i2cset -y 0 0x36 0x10 0x00') + os.system('i2cset -y 0 0x37 0x10 0x00') + +if __name__ == '__main__': + release_board() diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/setup.py b/platform/centec/sonic-platform-modules-v682/48y8c/setup.py new file mode 100644 index 00000000000..e0713e550f1 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize centec v682-48y8c platforms', + + packages=['sonic_platform'], + package_dir={'sonic_platform': 'sonic_platform'}, +) + diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/__init__.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/__init__.py new file mode 100644 index 00000000000..6e50c02e9d1 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis", "sfp", "eeprom", "psu", "thermal", "fan", "fan_drawer", "led"] +from . import platform diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/chassis.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/chassis.py new file mode 100644 index 00000000000..566612e4065 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/chassis.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import re + import time + import collections + from sonic_py_common import device_info + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.fan_drawer import FanDrawer + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_TRAY = 2 +NUM_THERMAL = 1 +NUM_PSU = 2 + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +REBOOT_CAUSE_DIR = "/host/reboot-cause/" +REBOOT_CAUSE_FILE = os.path.join(REBOOT_CAUSE_DIR, "reboot-cause.txt") + +class Chassis(ChassisBase): + # System status LED + _led = None + + def __init__(self): + ChassisBase.__init__(self) + + self.data = {'valid':0, 'last':0} + self.sfp_presence = {} + + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + port_config_file = "/".join([platform_path, "V682-48y8c", "port_config.ini"]) + try: + f = open(port_config_file) + except: + raise + for line in f: + line.strip() + if re.search('^#', line) is not None: + Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:]) + break + f.close() + f = open(port_config_file) + _port_cfgs = [Port_cfg(*tuple((line.strip().split()))) + for line in f if re.search('^#', line) is None] + f.close() + + # Initialize EEPROM + self._eeprom = Eeprom() + + # Initialize FAN + for i in range(NUM_FAN_TRAY): + fandrawer = FanDrawer(i + 1) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + + # Initialize PSU + for index in range(0, NUM_PSU): + psu = Psu(index + 1) + self._psu_list.append(psu) + + # Initialize THERMAL + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + # Initialize SFP + for port_cfg in _port_cfgs: + sfp = Sfp(int(port_cfg.index), 'SFP' if int(port_cfg.index) < 48 else 'QSFP') + self._sfp_list.append(sfp) + self.sfp_presence[int(port_cfg.index)] = False + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + +############################################## +# Chassis methods +############################################## + + 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.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + 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. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + return self._eeprom.system_eeprom_info() + + 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. + """ + if os.path.exists(REBOOT_CAUSE_FILE): + with open(REBOOT_CAUSE_FILE) as reboot_cause_file: + reboot_cause = reboot_cause_file.readline() + if re.search(r'User issued', reboot_cause) is None: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + else: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + else: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + + def get_change_event(self, timeout=2000): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the + format of {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + SFP_STATUS_INSERTED = '1' + SFP_STATUS_REMOVED = '0' + + now = time.time() + port_dict = {} + + if timeout < 1000: + timeout = 1000 + timeout = (timeout) / float(1000) # Convert to secs + + if now < (self.data['last'] + timeout) and self.data['valid']: + return False, {'sfp': {}} + + for sfp in self._sfp_list: + sfp_presence = sfp.get_presence() + if sfp_presence != self.sfp_presence[sfp.index]: + self.sfp_presence[sfp.index] = sfp_presence + if sfp_presence: + port_dict[sfp.index] = SFP_STATUS_INSERTED + else: + port_dict[sfp.index] = SFP_STATUS_REMOVED + + if bool(port_dict): + self.data['last'] = now + self.data['valid'] = 1 + ret = True + else: + time.sleep(0.5) + ret = False + + ret_dict = {'sfp': port_dict} + return ret, ret_dict + + def get_num_psus(self): + return len(self._psu_list) + + def get_psu(self, psu_index): + return self._psu_list[psu_index] + + def initizalize_system_led(self): + from .led import SystemLed + Chassis._led = SystemLed() + + def set_status_led(self, color): + """ + Sets the state of the system LED + + Args: + color: A string representing the color with which to set the + system LED + + Returns: + bool: True if system LED state is set successfully, False if not + """ + return False if not Chassis._led else Chassis._led.set_status(color) + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + return None if not Chassis._led else Chassis._led.get_status() diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/eeprom.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/eeprom.py new file mode 100644 index 00000000000..7d275047571 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/eeprom.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python +# +# Name: eeprom.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_eeprom import eeprom_tlvinfo + from sonic_py_common import device_info + import binascii +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + self.__eeprom_path = platform_path + '/eeprom_file' + + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + + self.__eeprom_tlv_dict = dict() + try: + self.open_eeprom() + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (eeprom[9] << 8) | eeprom[10] + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + eeprom[tlv_index + 1]] + code = "0x%02X" % (tlv[0]) + + if tlv[0] == self._TLV_CODE_VENDOR_EXT: + value = str((tlv[2] << 24) | (tlv[3] << 16) | + (tlv[4] << 8) | tlv[5]) + value += str(tlv[6:6 + tlv[1]]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: + break + + tlv_index += eeprom[tlv_index+1] + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2].decode('ascii') + + def base_mac_addr(self): + (is_valid, t) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(TlvInfoDecoder, self).switchaddrstr(e) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def serial_tag_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def revision_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/fan.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/fan.py new file mode 100644 index 00000000000..5f7b256eafb --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/fan.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import math +import os.path + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FAN_PATH = "/sys/class/hwmon/hwmon{}/" +FAN_MAX_PWM = 255 +FAN_FAN_PWM = "pwm{}" +FAN_FAN_INPUT = "fan{}_input" +FAN_MAX_RPM = 15000 +FAN_NAME_LIST = ["FAN-{}-1", "FAN-{}-2", "FAN-{}-3", "FAN-{}-4"] + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_tray_index, fan_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + + FanBase.__init__(self) + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except IOError: + return False + return True + + def __search_file_by_name(self, directory, file_name): + for dirpath, dirnames, files in os.walk(directory): + for name in files: + file_path = os.path.join(dirpath, name) + if name in file_name: + return file_path + return None + + 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_EXHAUST + 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) + + Note: + speed = pwm_in/255*100 + """ + speed = 0 + fan_speed_sysfs_name = "fan{}_input".format(self.fan_index+1) + fan_speed_sysfs_path = self.__search_file_by_name( + FAN_PATH.format(self.fan_tray_index + 1), fan_speed_sysfs_name) + fan_speed_rpm = self.__read_txt_file(fan_speed_sysfs_path) or 0 + speed = math.ceil(float(fan_speed_rpm) * 100 / FAN_MAX_RPM) + + 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 + """ + # target = 0 + # fan_target_sysfs_name = "pwm{}".format(self.fan_index+1) + # fan_target_sysfs_path = self.__search_file_by_name( + # FAN_PATH.format(self.fan_tray_index + 1), fan_target_sysfs_name) + # fan_target_pwm = self.__read_txt_file(fan_target_sysfs_path) or 0 + # target = math.ceil(float(fan_target_pwm) * 100 / FAN_MAX_PWM) + + # return target + speed = 0 + fan_speed_sysfs_name = "fan{}_input".format(self.fan_index+1) + fan_speed_sysfs_path = self.__search_file_by_name( + FAN_PATH.format(self.fan_tray_index + 1), fan_speed_sysfs_name) + fan_speed_rpm = self.__read_txt_file(fan_speed_sysfs_path) or 0 + speed = math.ceil(float(fan_speed_rpm) * 100 / FAN_MAX_RPM) + + return 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 10 + + 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 + + Note: + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + """ + pwm = speed * 255 / 100 + fan_target_sysfs_name = "pwm{}".format(self.fan_index+1) + fan_target_sysfs_path = self.__search_file_by_name( + FAN_PATH.format(self.fan_tray_index + 1), fan_target_sysfs_name) + return self.__write_txt_file(fan_target_sysfs_path, int(pwm)) + + 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: always True + """ + return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + fan_name = FAN_NAME_LIST[self.fan_index].format(self.fan_tray_index) + + return fan_name + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: always True + """ + + return True + + def get_status(self): + """ + Retrieves the status of the FAN + Returns: + bool: always True + """ + return True diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/fan_drawer.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/fan_drawer.py new file mode 100644 index 00000000000..781ba7957a4 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/fan_drawer.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +######################################################################## +# Centec V682 48Y8C +# +# 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 + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CENTEC_FANS_PER_FANTRAY = 4 + + +class FanDrawer(FanDrawerBase): + """Centec V682 48Y8C Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + self.fantrayindex = fantray_index + for i in range(CENTEC_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + + Args: + color: A string representing the color with which to set the + fan drawer status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + return True diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/led.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/led.py new file mode 100644 index 00000000000..492d6983ea7 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/led.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the led status which are available in the platform +# +############################################################################# + +from subprocess import Popen, PIPE, STDOUT + +class SystemLed(object): + STATUS_LED_COLOR_GREEN = 'green' + STATUS_LED_COLOR_ORANGE = 'orange' + STATUS_LED_COLOR_OFF = 'off' + + SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' + + def set_status(self, color): + status = False + + if color == SystemLed.STATUS_LED_COLOR_ORANGE: + cmd = 'i2cset -y 0 0x36 0x2 0xb' + Popen(cmd, shell=True) + status = True + elif color == SystemLed.STATUS_LED_COLOR_OFF: + cmd = 'i2cset -y 0 0x36 0x2 0x0' + Popen(cmd, shell=True) + status = True + elif color == SystemLed.STATUS_LED_COLOR_GREEN: + cmd = 'i2cset -y 0 0x36 0x2 0x5' + Popen(cmd, shell=True) + status = True + + return status + + def get_status(self): + cmd = 'i2cget -y 0 0x36 0x2' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + if status == 11: + return SystemLed.STATUS_LED_COLOR_ORANGE + elif status == 0: + return SystemLed.STATUS_LED_COLOR_OFF + else: + return SystemLed.STATUS_LED_COLOR_GREEN diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/platform.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/platform.py new file mode 100644 index 00000000000..358edc6f19f --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/platform.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs for Centec V682-48Y8C-D +# + + +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): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() + diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/psu.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/psu.py new file mode 100644 index 00000000000..779209c71c2 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/psu.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +from __future__ import print_function + +from subprocess import Popen, PIPE, STDOUT + +try: + from sonic_platform_base.psu_base import PsuBase +except ImportError as e: + raise ImportError("%s - required module not found" % e) + +class Psu(PsuBase): + """Centec Platform-specific PSU class""" + + def __init__(self, index): + self._index = index + self._fan_list = [] + + def get_presence(self): + cmd = 'i2cget -y 0 0x36 0x1e' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + presence = ((status & (1 << (3 * (self._index - 1) + 1))) == 0) + return presence + + def get_powergood_status(self): + cmd = 'i2cget -y 0 0x36 0x1e' + status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + powergood = ((status & (1 << (3 * (self._index - 1) + 2))) != 0) + return powergood diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/sfp.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/sfp.py new file mode 100644 index 00000000000..3475753cd49 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/sfp.py @@ -0,0 +1,1618 @@ +#!/usr/bin/env python + +############################################################################# +# Centec +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# + +import os +import time +import re +import collections +#import subprocess +#import sonic_device_util +from ctypes import create_string_buffer +from subprocess import Popen, PIPE, STDOUT +from sonic_py_common import device_info + +try: + from sonic_platform_base.sfp_base import SfpBase +# from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +QSFP_INFO_OFFSET = 128 +QSFP_DOM_OFFSET = 0 +SFP_INFO_OFFSET = 0 +SFP_DOM_OFFSET = 256 + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 2 + +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +QSFP_DOM_BULK_DATA_START = 22 +QSFP_DOM_BULK_DATA_SIZE = 36 +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 1 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_MODULE_MONITOR_OFFSET = 0 +QSFP_MODULE_MONITOR_WIDTH = 9 +QSFP_MODULE_THRESHOLD_OFFSET = 512 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 560 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_POWEROVERRIDE_BIT = 0 +QSFP_POWERSET_BIT = 1 +QSFP_OPTION_VALUE_OFFSET = 192 +QSFP_OPTION_VALUE_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes','FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia','FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + dom_supported = True + dom_temp_supported = True + dom_volt_supported = True + dom_rx_power_supported = True + dom_tx_power_supported = True + dom_tx_disable_supported = True + calibration = 1 + + # Path to QSFP sysfs + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "x86_64-centec_v682_48y8c-r0" + HWSKU = "V682-48y8c" + + def __init__(self, sfp_index, sfp_type): + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + port_config_file = "/".join([platform_path, self.HWSKU, "port_config.ini"]) + try: + f = open(port_config_file) + except: + raise + for line in f: + line.strip() + if re.search('^#', line) is not None: + Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:]) + break + f.close() + f = open(port_config_file) + self._port_cfgs = [Port_cfg(*tuple((line.strip().split()))) + for line in f if re.search('^#', line) is None] + f.close() + + # Port number + self.PORT_START = 256 + self.PORT_END = 0 + self.QSFP_START = 48 + self.QSFP_END = 0 + + for port_cfg in self._port_cfgs: + if int(port_cfg.index) <= self.PORT_START: + self.PORT_START = int(port_cfg.index) + elif int(port_cfg.index) >= self.PORT_END: + self.PORT_END = int(port_cfg.index) + self.QSFP_END = self.PORT_END + + # Init index + self.index = sfp_index + self.port_num = self.index + #self.dom_supported = False + self.sfp_type = sfp_type + # Init eeprom path + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + self.port_to_eeprom_mapping = {} + self.port_to_i2c_mapping = { + # mac i2c presence enable(or reset for qsfp) + 32 : (13, 0x36, 0x11, 0, 0x36, 0x0e, 0), + 33 : (12, 0x36, 0x11, 1, 0x36, 0x0e, 1), + 34 : (11, 0x36, 0x11, 2, 0x36, 0x0e, 2), + 35 : (10, 0x36, 0x11, 3, 0x36, 0x0e, 3), + 0 : (17, 0x36, 0x11, 4, 0x36, 0x0e, 4), + 4 : (16, 0x36, 0x11, 5, 0x36, 0x0e, 5), + 8 : (15, 0x36, 0x11, 6, 0x36, 0x0e, 6), + 12 : (14, 0x36, 0x11, 7, 0x36, 0x0e, 7), + 16 : (21, 0x36, 0x12, 0, 0x36, 0x0f, 0), + 20 : (20, 0x36, 0x12, 1, 0x36, 0x0f, 1), + 24 : (19, 0x36, 0x12, 2, 0x36, 0x0f, 2), + 28 : (18, 0x36, 0x12, 3, 0x36, 0x0f, 3), + 40 : (25, 0x36, 0x12, 4, 0x36, 0x0f, 4), + 44 : (24, 0x36, 0x12, 5, 0x36, 0x0f, 5), + 48 : (23, 0x36, 0x12, 6, 0x36, 0x0f, 6), + 52 : (22, 0x36, 0x12, 7, 0x36, 0x0f, 7), + 56 : (29, 0x36, 0x13, 0, 0x36, 0x10, 0), + 60 : (28, 0x36, 0x13, 1, 0x36, 0x10, 1), + 64 : (27, 0x36, 0x13, 2, 0x36, 0x10, 2), + 68 : (26, 0x36, 0x13, 3, 0x36, 0x10, 3), + 72 : (33, 0x36, 0x13, 4, 0x36, 0x10, 4), + 73 : (32, 0x36, 0x13, 5, 0x36, 0x10, 5), + 74 : (31, 0x36, 0x13, 6, 0x36, 0x10, 6), + 75 : (30, 0x36, 0x13, 7, 0x36, 0x10, 7), + 232 : (37, 0x37, 0x11, 0, 0x37, 0x0e, 0), + 233 : (36, 0x37, 0x11, 1, 0x37, 0x0e, 1), + 234 : (35, 0x37, 0x11, 2, 0x37, 0x0e, 2), + 235 : (34, 0x37, 0x11, 3, 0x37, 0x0e, 3), + 200 : (41, 0x37, 0x11, 4, 0x37, 0x0e, 4), + 204 : (40, 0x37, 0x11, 5, 0x37, 0x0e, 5), + 208 : (39, 0x37, 0x11, 6, 0x37, 0x0e, 6), + 212 : (38, 0x37, 0x11, 7, 0x37, 0x0e, 7), + 216 : (45, 0x37, 0x12, 0, 0x37, 0x0f, 0), + 220 : (44, 0x37, 0x12, 1, 0x37, 0x0f, 1), + 224 : (43, 0x37, 0x12, 2, 0x37, 0x0f, 2), + 228 : (42, 0x37, 0x12, 3, 0x37, 0x0f, 3), + 160 : (49, 0x37, 0x12, 4, 0x37, 0x0f, 4), + 164 : (48, 0x37, 0x12, 5, 0x37, 0x0f, 5), + 168 : (47, 0x37, 0x12, 6, 0x37, 0x0f, 6), + 172 : (46, 0x37, 0x12, 7, 0x37, 0x0f, 7), + 176 : (53, 0x37, 0x13, 0, 0x37, 0x10, 0), + 180 : (52, 0x37, 0x13, 1, 0x37, 0x10, 1), + 184 : (51, 0x37, 0x13, 2, 0x37, 0x10, 2), + 188 : (50, 0x37, 0x13, 3, 0x37, 0x10, 3), + 192 : (57, 0x37, 0x13, 4, 0x37, 0x10, 4), + 193 : (56, 0x37, 0x13, 5, 0x37, 0x10, 5), + 194 : (55, 0x37, 0x13, 6, 0x37, 0x10, 6), + 195 : (54, 0x37, 0x13, 7, 0x37, 0x10, 7), + 120 : (61, 0x36, 0x14, 0, 0x36, 0x05, 0), + 121 : (61, 0x36, 0x14, 0, 0x36, 0x05, 0), + 122 : (61, 0x36, 0x14, 0, 0x36, 0x05, 0), + 123 : (61, 0x36, 0x14, 0, 0x36, 0x05, 0), + 124 : (60, 0x36, 0x14, 1, 0x36, 0x05, 1), + 125 : (60, 0x36, 0x14, 1, 0x36, 0x05, 1), + 126 : (60, 0x36, 0x14, 1, 0x36, 0x05, 1), + 127 : (60, 0x36, 0x14, 1, 0x36, 0x05, 1), + 80 : (59, 0x36, 0x14, 2, 0x36, 0x05, 2), + 81 : (59, 0x36, 0x14, 2, 0x36, 0x05, 2), + 82 : (59, 0x36, 0x14, 2, 0x36, 0x05, 2), + 83 : (59, 0x36, 0x14, 2, 0x36, 0x05, 2), + 84 : (58, 0x36, 0x14, 3, 0x36, 0x05, 3), + 85 : (58, 0x36, 0x14, 3, 0x36, 0x05, 3), + 86 : (58, 0x36, 0x14, 3, 0x36, 0x05, 3), + 87 : (58, 0x36, 0x14, 3, 0x36, 0x05, 3), + 240 : (65, 0x37, 0x14, 0, 0x37, 0x05, 0), + 241 : (65, 0x37, 0x14, 0, 0x37, 0x05, 0), + 242 : (65, 0x37, 0x14, 0, 0x37, 0x05, 0), + 243 : (65, 0x37, 0x14, 0, 0x37, 0x05, 0), + 244 : (64, 0x37, 0x14, 1, 0x37, 0x05, 1), + 245 : (64, 0x37, 0x14, 1, 0x37, 0x05, 1), + 246 : (64, 0x37, 0x14, 1, 0x37, 0x05, 1), + 247 : (64, 0x37, 0x14, 1, 0x37, 0x05, 1), + 280 : (63, 0x37, 0x14, 2, 0x37, 0x05, 2), + 281 : (63, 0x37, 0x14, 2, 0x37, 0x05, 2), + 282 : (63, 0x37, 0x14, 2, 0x37, 0x05, 2), + 283 : (63, 0x37, 0x14, 2, 0x37, 0x05, 2), + 284 : (62, 0x37, 0x14, 3, 0x37, 0x05, 3), + 285 : (62, 0x37, 0x14, 3, 0x37, 0x05, 3), + 286 : (62, 0x37, 0x14, 3, 0x37, 0x05, 3), + 287 : (62, 0x37, 0x14, 3, 0x37, 0x05, 3) + } + + for port_cfg in self._port_cfgs: + i2c_idx = self.port_to_i2c_mapping[int(port_cfg.lanes.split(',')[0])][0] + port_eeprom_path = eeprom_path.format(i2c_idx) + self.port_to_eeprom_mapping[int(port_cfg.index)] = port_eeprom_path + + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', + 'model', 'connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', + 'nominal_bit_rate', 'specification_compliance', 'vendor_date', + 'vendor_oui', 'application_advertisement'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', + 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def get_presence(self): + """ + Retrieves the presence of the SFP module + Returns: + bool: True if SFP module is present, False if not + """ + # Check for invalid port_num + if self.port_num < self.PORT_START or self.port_num > self.PORT_END: + return False + + sfp_info = self.port_to_i2c_mapping[int(self._port_cfgs[self.port_num].lanes.split(',')[0])] + cmd = 'i2cget -y 0 {0} {1}'.format(sfp_info[1], sfp_info[2]) + presence = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + presence &= (1 << sfp_info[3]) + + try: + with open(self.port_to_eeprom_mapping[self.port_num], mode='rb', buffering=0) as fd: + fd.read() + except IOError: + return False + + return (presence == 0) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + except Exception: + eeprom_raw = None + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def _dom_capability_detect(self): + if not self.get_presence(): + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + if self.sfp_type == "QSFP": + self.calibration = 1 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + offset = 128 + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_dom_capability = int(qsfp_dom_capability_raw[0], 16) + + qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes( + QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_OFFSET) + if qsfp_version_compliance_raw is not None: + qsfp_version_compliance = int(qsfp_version_compliance_raw[0], 16) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = (qsfp_dom_capability & 0x20 != 0) + self.dom_volt_supported = (qsfp_dom_capability & 0x10 != 0) + self.dom_rx_power_supported = (qsfp_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = (qsfp_dom_capability & 0x04 != 0) + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = (qsfp_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = True + self.dom_supported = True + self.calibration = 1 + self.dom_tx_disable_supported = True + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + elif self.sfp_type == "SFP": + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = (int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + application_advertisement |1*255VCHAR |supported applications advertisement + ======================================================================== + """ + + transceiver_info_dict = {} + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + transceiver_info_dict['specification_compliance'] = '{}' + if not self.get_presence(): + return transceiver_info_dict + + if self.sfp_type == QSFP_TYPE: + offset = QSFP_INFO_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return transceiver_info_dict + + elif self.sfp_type == SFP_TYPE: + offset = SFP_INFO_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return transceiver_info_dict + else: + return transceiver_info_dict + + # Add retry for xcvr eeprom to get ready + max_retry = 10 + for i in range(0,max_retry): + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is not None: + break + else: + if not self.get_presence(): + return transceiver_info_dict + elif i == max_retry-1: + pass + else: + time.sleep(0.5) + + if sfp_interface_bulk_raw is None: + return transceiver_info_dict + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_interface_bulk_raw[start : end], 0) + transceiver_info_dict['type'] = sfp_interface_bulk_data \ + ['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data \ + ['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data \ + ['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data \ + ['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data \ + ['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data \ + ['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data \ + ['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data \ + ['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data \ + ['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data \ + ['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data \ + ['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = 'N/A' + if self.sfp_type == QSFP_TYPE: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data \ + ['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data \ + ['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data \ + ['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data \ + ['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + + if not self.get_presence(): + return None + + self._dom_capability_detect() + + if self.sfp_type == QSFP_TYPE: + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not sfpi_obj or not sfpd_obj: + return None + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + offset = QSFP_DOM_OFFSET + offset_xcvr = QSFP_INFO_OFFSET + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_dom_capability_data = sfpi_obj.parse_dom_capability( + qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qsfp_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + elif self.sfp_type == SFP_TYPE: + sfpd_obj = sff8472Dom() + if not sfpd_obj: + return None + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, SFP_DOM_OFFSET) + if eeprom_ifraw is not None: + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = SFP_DOM_OFFSET + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_voltage_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value'] + transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value'] + else: + return None + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + if self.sfp_type == QSFP_TYPE: + sfpd_obj = sff8436Dom() + if not self.get_presence() or not sfpd_obj: + return None + DOM_OFFSET = 0 + transceiver_dom_threshold_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + offset = DOM_OFFSET + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + module_threshold_values = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_channel_thres_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNEL_THRESHOLD_OFFSET), QSFP_CHANNEL_THRESHOLD_WIDTH) + if dom_channel_thres_raw is not None: + channel_threshold_values = sfpd_obj.parse_channel_threshold_values(dom_channel_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + else: + channel_threshold_data = None + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + elif self.sfp_type == SFP_TYPE: + sfpd_obj = sff8472Dom() + + if not self.get_presence() and not sfpd_obj: + return None + DOM_OFFSET = 256 + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + if eeprom_ifraw is not None: + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_threshold_info_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + else: + return None + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + # Check for invalid port_num + if self.port_num < self.PORT_START or self.port_num > self.PORT_END or self.sfp_type == SFP_TYPE: + return False + + sfp_info = self.port_to_i2c_mapping[int(self._port_cfgs[self.port_num].lanes.split(',')[0])] + cmd = 'i2cget -y 0 {0} {1}'.format(sfp_info[4], sfp_info[5]) + reset_status = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + reset_status &= (1 << sfp_info[6]) + + return (reset_status == 1) + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + if not self.dom_supported: + return None + + rx_los_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + elif self.sfp_type == SFP_TYPE: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_STATUS_CONTROL_OFFSET), SFP_STATUS_CONTROL_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x02 != 0) + else: + return None + else: + return None + + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + if not self.dom_supported: + return None + + tx_fault_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + elif self.sfp_type == SFP_TYPE: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_STATUS_CONTROL_OFFSET), SFP_STATUS_CONTROL_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + else: + return None + else: + return None + + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + if not self.dom_supported: + return None + + tx_disable_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + elif self.sfp_type == SFP_TYPE: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_STATUS_CONTROL_OFFSET), SFP_STATUS_CONTROL_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0xC0 != 0) + else: + return None + else: + return None + + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + # SFP doesn't support this feature + if self.sfp_type == SFP_TYPE: + return 0 + elif self.sfp_type == QSFP_TYPE: + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + else: + return None + + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this QSFP module + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + return False + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + # SFP doesn't support this feature + if self.sfp_type == SFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_POWEROVERRIDE_OFFSET), QSFP_POWEROVERRIDE_WIDTH) + if dom_control_raw is not None: + if int(dom_control_raw[0],16) & (0x01 << QSFP_POWEROVERRIDE_BIT): + return True + else: + return False + else: + return None + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + elif self.sfp_type == SFP_TYPE: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = 1 + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + else: + return None + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + elif self.sfp_type == SFP_TYPE: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + sfpd_obj._calibration_type = self.calibration + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + else: + return None + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + tx_bias_list = [] + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX4Bias']['value'])) + elif self.sfp_type == SFP_TYPE: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = self.calibration + + if self.dom_supported: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( \ + dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TXBias']['value'])) + else: + return None + else: + return None + else: + return None + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX4Power']['value'])) + else: + return None + else: + return None + elif self.sfp_type == SFP_TYPE: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + else: + return None + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX4Power']['value'])) + else: + return None + else: + return None + elif self.sfp_type == SFP_TYPE: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = \ + sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + else: + return None + + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default state. + Returns: + A boolean, True if successful, False if not + """ + if not self.get_presence(): + return False + + # SFP doesn't support this feature + if self.sfp_type == SFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + sfp_info = self.port_to_i2c_mapping[int(self._port_cfgs[self.port_num].lanes.split(',')[0])] + cmd = 'i2cget -y 0 {0} {1}'.format(sfp_info[4], sfp_info[5]) + reset = int(Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True).stdout.readline(), 16) + + reset &= ~(1 << sfp_info[6]) + cmd = 'i2cset -y 0 {0} {1} {2}'.format(sfp_info[4], sfp_info[5], reset) + Popen(cmd, shell=True) + + reset |= (1 << sfp_info[6]) + cmd = 'i2cset -y 0 {0} {1} {2}'.format(sfp_info[4], sfp_info[5], reset) + Popen(cmd, shell=True) + + return True + + 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.sfp_type == SFP_TYPE: + if self.dom_tx_disable_supported: + offset = 256 + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + status_control_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_STATUS_CONTROL_OFFSET), SFP_STATUS_CONTROL_WIDTH) + if status_control_raw is not None: + # Set bit 6 for Soft TX Disable Select + # 01000000 = 64 and 10111111 = 191 + tx_disable_bit = 64 if tx_disable else 191 + status_control = int(status_control_raw[0], 16) + tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else ( + status_control & tx_disable_bit) + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom.seek(offset + SFP_STATUS_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + else: + return False + elif self.sfp_type == QSFP_TYPE: + if self.dom_tx_disable_supported: + channel_mask = 0x0f + if tx_disable: + return self.tx_disable_channel(channel_mask, True) + else: + return self.tx_disable_channel(channel_mask, False) + else: + return False + else: + return None + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + if not self.get_presence(): + return False + # SFP doesn't support this feature + if self.sfp_type == SFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + if self.dom_tx_disable_supported: + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + if disable: + tx_disable_ctl = channel_state | channel + else: + tx_disable_ctl = channel_state & (~channel) + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + else: + return False + else: + return None + + 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 + """ + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + # SFP doesn't support this feature + if not self.get_presence(): + return False + + if self.sfp_type == SFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfsfile_eeprom = open(self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + else: + return None + + return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return "Ethernet{}".format(self.port_num) + diff --git a/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/thermal.py b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/thermal.py new file mode 100644 index 00000000000..ca4e3596926 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c/sonic_platform/thermal.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# 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 +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + THERMAL_NAME_LIST = [] + CPUBOARD_SS_PATH = "/sys/class/hwmon/hwmon1" + + def __init__(self, thermal_index): + self.index = thermal_index + self.high_threshold = float(112) + + # Add thermal name + self.THERMAL_NAME_LIST.append("ASIC") + + # Set hwmon path + self.ss_index, self.hwmon_path = 1, self.CPUBOARD_SS_PATH + self.ss_key = self.THERMAL_NAME_LIST[self.index - 1] + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + raise IOError("Unable to open %s file !" % file_path) + + def __get_temp(self, temp_file): + temp_file_path = os.path.join(self.hwmon_path, temp_file) + raw_temp = self.__read_txt_file(temp_file_path) + temp = float(raw_temp)/1000 + return float("{:.3f}".format(temp)) + + def __set_threshold(self, file_name, temperature): + temp_file_path = os.path.join(self.hwmon_path, file_name) + try: + with open(temp_file_path, 'w') as fd: + fd.write(str(temperature)) + return True + except IOError: + return False + + 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 + """ + temp_file = "temp{}_input".format(self.ss_index) + return self.__get_temp(temp_file) + + 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 + """ + return self.high_threshold + + 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 + """ + self.high_threshold = float(temperature) + return True + + def get_name(self): + """ + Retrieves the name of the thermal device + Returns: + string: The name of the thermal device + """ + 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 + """ + temp_file = "temp{}_input".format(self.ss_index) + temp_file_path = os.path.join(self.hwmon_path, temp_file) + return os.path.isfile(temp_file_path) + + 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 not self.get_presence(): + return False + + return True diff --git a/platform/centec/sonic-platform-modules-v682/debian/control b/platform/centec/sonic-platform-modules-v682/debian/control index 2c79ea7193e..3460d4b00ba 100644 --- a/platform/centec/sonic-platform-modules-v682/debian/control +++ b/platform/centec/sonic-platform-modules-v682/debian/control @@ -7,5 +7,15 @@ Standards-Version: 3.9.3 Package: platform-modules-v682-48y8c-d Architecture: amd64 -Depends: linux-image-4.19.0-12-2-amd64-unsigned +Depends: linux-image-5.10.0-8-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-v682-48y8c +Architecture: amd64 +Depends: linux-image-5.10.0-8-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-v682-48x8c +Architecture: amd64 +Depends: linux-image-5.10.0-8-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48x8c.init b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48x8c.init new file mode 100644 index 00000000000..16b23082d6f --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48x8c.init @@ -0,0 +1,200 @@ +#!/bin/bash +# This script load/unload centec kernel modules + +### BEGIN INIT INFO +# Provides: platform-modules-v682-48x8c +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Load Centec kernel modules +### END INIT INFO + +function install_python_api_package() +{ + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -ne 0 ]; then + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) + fi +} + +function load_system_eeprom_file() +{ + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + mkdir -p /mnt/onie-boot + mount -t ext4 -L ONIE-BOOT /mnt/onie-boot + dd if=/mnt/onie-boot/eeprom_file of=$device/$platform/eeprom_file bs=1 skip=1046528 + dd if=/mnt/onie-boot/eeprom_file of=$device/$platform/eeprom_cipher bs=1 count=32 + MACADDR=`decode-syseeprom | grep "Base MAC Address" | awk '{print $6}'` + ifconfig eth0 hw ether $MACADDR + umount /mnt/onie-boot + rmdir /mnt/onie-boot +} + +function load_kernel_modules() +{ + modprobe centec_v682_48x8c_platform + modprobe dal + modprobe knet + modprobe tun + modprobe tap +} + +function remove_kernel_modules() +{ + modprobe -r tap + modprobe -r tun + modprobe -r knet + modprobe -r dal + modprobe -r centec_v682_48x8c_platform +} + +function release_board() +{ + systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target + chmod a+x /usr/local/lib/python3.9/dist-packages/release.py + /usr/local/lib/python3.9/dist-packages/release.py +} + +function create_i2c_device_nodes() +{ + # load pca954x driver for pca9548 + modprobe i2c-mux-pca954x + modprobe optoe + + # i2c-0 for SMBus + # i2c-1 for CP2112 + # create i2c 2,3,4,5,6,7,8,9 for pca9548 0x70 channel 0,1,2,3,4,5,6,7 + echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device + # create i2c 13,12,11,10,17,16,15,14 for fiber 0,1,2,3,4,5,6,7 + echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-13/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-17/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-16/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-15/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-14/new_device + # create i2c 21,20,19,18,25,24,23,22 for fiber 8,9,10,11,12,13,14,15 + echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-3/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-21/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-20/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-19/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-18/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-25/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-24/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-23/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-22/new_device + # create i2c 29,28,27,26,33,32,31,30 for fiber 16,17,18,19,20,21,22,23 + echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-4/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-29/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-28/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-27/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-26/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-33/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-32/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-31/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-30/new_device + # create i2c 37,36,35,34,41,40,39,38 for fiber 24,25,26,27,28,29,30,31 + echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-6/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-37/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-36/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-35/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-34/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-41/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-40/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-39/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-38/new_device + # create i2c 45,44,43,42,49,48,47,46 for fiber 32,33,34,35,36,37,38,39 + echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-7/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-45/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-44/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-43/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-42/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-49/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-48/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-47/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-46/new_device + # create i2c 53,52,51,50,57,56,55,54 for fiber 40,41,42,43,44,45,46,47 + echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-8/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-53/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-52/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-51/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-50/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-57/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-56/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-55/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-54/new_device + # create i2c 61,60,59,58,65,64,63,62 for fiber 48,49,50,51,52,53,54,55 + echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-5/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-61/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-60/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-59/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-58/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-65/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-64/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-63/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-62/new_device + + # for rtc sd2405 + echo sd2405 0x32 > /sys/bus/i2c/devices/i2c-0/new_device + # load rtc-sd2405 driver for rtc sd2405 + modprobe rtc-sd2405 + sleep 1 + hwclock -s -f /dev/rtc1 > /dev/null 2>&1 + + # for sensor lm77 + echo lm77 0x49 > /sys/bus/i2c/devices/i2c-0/new_device + # load lm77 driver for sensor lm77 + modprobe lm77 + + # for fan adt7470 + echo adt7470 0x2c > /sys/bus/i2c/devices/i2c-9/new_device + echo adt7470 0x2e > /sys/bus/i2c/devices/i2c-9/new_device + # load adt7470 driver for fan adt7470 + modprobe adt7470 +} + +case "$1" in +start) + echo -n "Init Centec V682-48X8C ... " + + depmod -a + modprobe i2c-dev + + release_board + load_kernel_modules + create_i2c_device_nodes + install_python_api_package + load_system_eeprom_file + + echo "done." + ;; + +stop) + echo -n "Deinit Centec V682-48X8C ... " + + remove_kernel_modules + + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-v682-48x8c {start|stop}" + exit 1 + ;; +esac + +exit 0 + diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48x8c.install b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48x8c.install new file mode 100644 index 00000000000..c798deffaed --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48x8c.install @@ -0,0 +1,2 @@ +48x8c/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-centec_v682_48x8c-r0 +48x8c/service/release.py usr/local/lib/python3.9/dist-packages diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48x8c.postinst b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48x8c.postinst new file mode 100644 index 00000000000..a4f0261a1d3 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48x8c.postinst @@ -0,0 +1,2 @@ +systemctl enable 48x8c_platform.service +systemctl start 48x8c_platform.service diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.init b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.init index 92ce88465d1..b74489e9a30 100644 --- a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.init +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.init @@ -17,16 +17,26 @@ function install_python_api_package() device="/usr/share/sonic/device" platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) - rv=$(pip2 show sonic-platform > /dev/null 2>/dev/null) - if [ $? -ne 0 ]; then - rv=$(pip2 install $device/$platform/sonic_platform-1.0-py2-none-any.whl) - fi rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) if [ $? -ne 0 ]; then rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) fi } +function load_system_eeprom_file() +{ + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + mkdir -p /mnt/onie-boot + mount -t ext4 -L ONIE-BOOT /mnt/onie-boot + dd if=/mnt/onie-boot/eeprom_file of=$device/$platform/eeprom_file bs=1 skip=1046528 + dd if=/mnt/onie-boot/eeprom_file of=$device/$platform/eeprom_cipher bs=1 count=32 + MACADDR=`decode-syseeprom | grep "Base MAC Address" | awk '{print $6}'` + ifconfig eth0 hw ether $MACADDR + umount /mnt/onie-boot + rmdir /mnt/onie-boot +} + function load_kernel_modules() { depmod -a @@ -50,10 +60,10 @@ function release_board() { systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target - chmod a+x /usr/local/lib/python2.7/dist-packages/libSUSI-4.00.so.1 - chmod a+x /usr/local/lib/python2.7/dist-packages/_Susi4.so - chmod a+x /usr/local/lib/python2.7/dist-packages/release.py - /usr/local/lib/python2.7/dist-packages/release.py + chmod a+x /usr/local/lib/python3.9/dist-packages/libSUSI-4.00.so.1 + chmod a+x /usr/local/lib/python3.9/dist-packages/_Susi4.so + chmod a+x /usr/local/lib/python3.9/dist-packages/release.py + /usr/local/lib/python3.9/dist-packages/release.py } @@ -64,6 +74,7 @@ start) release_board load_kernel_modules install_python_api_package + load_system_eeprom_file echo "done." ;; diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.install b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.install index e3f3758b333..8a5a1440cfe 100644 --- a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.install +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.install @@ -1,5 +1,4 @@ -48y8c-d/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-centec_v682_48y8c_d-r0 48y8c-d/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-centec_v682_48y8c_d-r0 -48y8c-d/service/release.py usr/local/lib/python2.7/dist-packages -48y8c-d/service/_Susi4.so usr/local/lib/python2.7/dist-packages -48y8c-d/service/libSUSI-4.00.so.1 usr/local/lib/python2.7/dist-packages +48y8c-d/service/release.py usr/local/lib/python3.9/dist-packages +48y8c-d/service/_Susi4.so usr/local/lib/python3.9/dist-packages +48y8c-d/service/libSUSI-4.00.so.1 usr/local/lib/python3.9/dist-packages diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c.init b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c.init new file mode 100644 index 00000000000..16a85d40e72 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c.init @@ -0,0 +1,200 @@ +#!/bin/bash +# This script load/unload centec kernel modules + +### BEGIN INIT INFO +# Provides: platform-modules-v682-48y8c +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Load Centec kernel modules +### END INIT INFO + +function install_python_api_package() +{ + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -ne 0 ]; then + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) + fi +} + +function load_system_eeprom_file() +{ + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + mkdir -p /mnt/onie-boot + mount -t ext4 -L ONIE-BOOT /mnt/onie-boot + dd if=/mnt/onie-boot/eeprom_file of=$device/$platform/eeprom_file bs=1 skip=1046528 + dd if=/mnt/onie-boot/eeprom_file of=$device/$platform/eeprom_cipher bs=1 count=32 + MACADDR=`decode-syseeprom | grep "Base MAC Address" | awk '{print $6}'` + ifconfig eth0 hw ether $MACADDR + umount /mnt/onie-boot + rmdir /mnt/onie-boot +} + +function load_kernel_modules() +{ + modprobe centec_v682_48y8c_platform + modprobe dal + modprobe knet + modprobe tun + modprobe tap +} + +function remove_kernel_modules() +{ + modprobe -r tap + modprobe -r tun + modprobe -r knet + modprobe -r dal + modprobe -r centec_v682_48y8c_platform +} + +function release_board() +{ + systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target + chmod a+x /usr/local/lib/python3.9/dist-packages/release.py + /usr/local/lib/python3.9/dist-packages/release.py +} + +function create_i2c_device_nodes() +{ + # load pca954x driver for pca9548 + modprobe i2c-mux-pca954x + modprobe optoe + + # i2c-0 for SMBus + # i2c-1 for CP2112 + # create i2c 2,3,4,5,6,7,8,9 for pca9548 0x70 channel 0,1,2,3,4,5,6,7 + echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device + # create i2c 13,12,11,10,17,16,15,14 for fiber 0,1,2,3,4,5,6,7 + echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-13/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-17/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-16/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-15/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-14/new_device + # create i2c 21,20,19,18,25,24,23,22 for fiber 8,9,10,11,12,13,14,15 + echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-3/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-21/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-20/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-19/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-18/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-25/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-24/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-23/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-22/new_device + # create i2c 29,28,27,26,33,32,31,30 for fiber 16,17,18,19,20,21,22,23 + echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-4/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-29/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-28/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-27/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-26/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-33/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-32/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-31/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-30/new_device + # create i2c 37,36,35,34,41,40,39,38 for fiber 24,25,26,27,28,29,30,31 + echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-6/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-37/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-36/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-35/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-34/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-41/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-40/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-39/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-38/new_device + # create i2c 45,44,43,42,49,48,47,46 for fiber 32,33,34,35,36,37,38,39 + echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-7/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-45/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-44/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-43/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-42/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-49/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-48/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-47/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-46/new_device + # create i2c 53,52,51,50,57,56,55,54 for fiber 40,41,42,43,44,45,46,47 + echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-8/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-53/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-52/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-51/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-50/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-57/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-56/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-55/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-54/new_device + # create i2c 61,60,59,58,65,64,63,62 for fiber 48,49,50,51,52,53,54,55 + echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-5/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-61/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-60/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-59/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-58/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-65/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-64/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-63/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-62/new_device + + # for rtc sd2405 + echo sd2405 0x32 > /sys/bus/i2c/devices/i2c-0/new_device + # load rtc-sd2405 driver for rtc sd2405 + modprobe rtc-sd2405 + sleep 1 + hwclock -s -f /dev/rtc1 > /dev/null 2>&1 + + # for sensor lm77 + echo lm77 0x49 > /sys/bus/i2c/devices/i2c-0/new_device + # load lm77 driver for sensor lm77 + modprobe lm77 + + # for fan adt7470 + echo adt7470 0x2c > /sys/bus/i2c/devices/i2c-9/new_device + echo adt7470 0x2e > /sys/bus/i2c/devices/i2c-9/new_device + # load adt7470 driver for fan adt7470 + modprobe adt7470 +} + +case "$1" in +start) + echo -n "Init Centec V682-48Y8C ... " + + depmod -a + modprobe i2c-dev + + release_board + load_kernel_modules + create_i2c_device_nodes + install_python_api_package + load_system_eeprom_file + + echo "done." + ;; + +stop) + echo -n "Deinit Centec V682-48Y8C ... " + + remove_kernel_modules + + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-v682-48y8c {start|stop}" + exit 1 + ;; +esac + +exit 0 + diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c.install b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c.install new file mode 100644 index 00000000000..999baedb4b2 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c.install @@ -0,0 +1,2 @@ +48y8c/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-centec_v682_48y8c-r0 +48y8c/service/release.py usr/local/lib/python3.9/dist-packages diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c.postinst b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c.postinst new file mode 100644 index 00000000000..30915b9e6fe --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c.postinst @@ -0,0 +1,2 @@ +systemctl enable 48y8c_platform.service +systemctl start 48y8c_platform.service diff --git a/platform/centec/sonic-platform-modules-v682/debian/rules b/platform/centec/sonic-platform-modules-v682/debian/rules index c50356d4517..2e0e0dc0ffe 100755 --- a/platform/centec/sonic-platform-modules-v682/debian/rules +++ b/platform/centec/sonic-platform-modules-v682/debian/rules @@ -17,7 +17,7 @@ PACKAGE_PRE_NAME := platform-modules-v682 KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= 48y8c-d +MODULE_DIRS:= 48y8c-d 48y8c 48x8c MODULE_DIR := modules SERVICE_DIR := service CLASSES_DIR := classes @@ -41,7 +41,6 @@ build: (for mod in $(MODULE_DIRS); do \ make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ cd $${mod}; \ - python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd -; \ done)