diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-Board-ac5x-G3748.md5 b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-Board-ac5x-G3748.md5 new file mode 100755 index 0000000000..e6272e216b --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-Board-ac5x-G3748.md5 @@ -0,0 +1 @@ +1dd040e3e3ec7740ad5778e9da49a59d \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-Board-ac5x-G3748.xml b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-Board-ac5x-G3748.xml new file mode 100755 index 0000000000..d927a18f3e --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-Board-ac5x-G3748.xml @@ -0,0 +1,1607 @@ + + + + + + std-string + string + standard string. + 1 + 100 + + + board-callback-type + enumeration + Specifies os/ext drv callback types. + + linux-static + Linux Static + 0 + + + linux-shared + Linux Shared Lib mode + 1 + + + external + External Os + 3 + + + freeBsd + Free BSD + 4 + + + + board-pp-map-type + enumeration + Specifies pci info types. + + fixed + Fixed + 0 + + + autoscan + Auto scan + 1 + + + + board-pp-interface-channel-type + enumeration + Specifies interface tunnel. + + pci + PCI + 0 + + + smi + SMI + 1 + + + pex + PEX + 3 + + + pex_eagle + PEX EAGLE + 5 + + + pex_falcon_z + PEX FALCON Z + 6 + + + + device-id-type + uint32 + Device ID 0..1023 + 0 + 1023 + + + port-mapping-type + enumeration + Specifies port map type. + + ethernet_mac + ETHERNET_MAC + 0 + + + cpu_sdma + CPU_SDMA + 1 + + + + interface-num-type + uint32 + Interface number + 0 + 1023 + + + txq-port-number-type + uint32 + 0 - 8 queues are configured per port (legacy mode), +1...16 - the number of queues configured per port + SIP 5 : Bobcat2,BobK:0..71 ;Bobcat3: 0..576 ;Aldrin2:0..99 + 0 + 576 + + + phy-smi-interface-type + uint32 + Phy SMI interface type. + 0 + 3 + + + phy-xsmi-interface-type + uint32 + Phy XSMI interface type. + 0 + 15 + + + phy-type + enumeration + Specifies the PHY Part Identifier. + + NA + No Phy + 0 + + + alaska-88E1543 + Specifies PHY identifier 88E1543, used for Combo ports. + 1 + + + alaska-88E1545 + Specifies PHY identifier 88E1545, used for Copper GE with MAC on PHY support. + 2 + + + alaska-88E1680 + Specifies PHY identifier 88E1680, used for Copper with speeds of 10M/100M/1G. + 3 + + + alaska-88E151X + Specifies PHY identifier 88E151X, used for Copper (HW supports combo and fiber). + 4 + + + alaska-88E3140 + Specifies PHY identifier 88E3140, used for Copper with speeds of 100M/1G/10G. Uses with FW SolarFlare next generation. + 5 + + + alaska-88E3240 + Specifies PHY identifier 88E3240, used for Copper with speeds of 100M/1G/10G. Uses with FW, SolarFlare next generation. + 6 + + + alaska-88E3680 + Specifies PHY identifier 88E3680, used for Octal Copper 100M. + 7 + + + alaska-88E3220 + Specifies PHY identifier 88E3220, used for Combo port with speeds of 100M/1G/10G. Uses FW, SolarFlare next generation. + 8 + + + alaska-88E1680L + Specifies PHY identifier 88E1680L, used for Copper with speeds of 10M/100M/1G. + 9 + + + alaska-88E33X0 + Specifies PHY identifier 88E33X0, used for MGIG Combo. + 10 + + + alaska-88E1548 + Specifies PHY identifier 88E1548, used for Fiber GE. + 11 + + + alaska-88E20X0 + Specifies PHY identifier 88E20X0, used for Copper with speeds of 10M/100M/1G/2.5G/5G. + 12 + + + alaska-88E1512 + Specifies PHY identifier 88E1512, used for Copper with speeds of 10M/100M/1G. + 13 + + + alaska-88E2180 + Specifies PHY identifier 88E2180, used for Copper with speeds of 10M/100M/1G/2.5G/5G. + 14 + + + alaska-88E1780 + Specifies PHY identifier 88E1780, Integrated Octal 10/100/1000 Mbps Energy Efficient Ethernet Transceiver + 15 + + + alaska-88E2540 + Specifies PHY identifier 88E2540, 4 ports 10/100/1000/2.5G/5GBASE-T Ethernet Transceiver with IEEE 1588v2 PTP Support + 16 + + + alaska-88E2580 + Specifies PHY identifier 88E12580, Octal 10/100/1000/2.5G/5GBASE-T Ethernet Transceiver with IEEE 1588v2 PTP Support + 17 + + + + physical-port-num-type + uint32 + PHYSICAL PORT NUM + 0 + 1023 + + + led-stream-port-type + enumeration + Specifies the ledstream port type. + + PORT_TYPE_TRI_SPEED + tri-speed port. + 1 + + + PORT_TYPE_XG + XG port. + 2 + + + + led-stream-blink-select-type + enumeration + Specifies the LED stream blink select type. + + BLINK_SELECT_0 + Blink 0 signal. + 1 + + + BLINK_SELECT_1 + Blink 1 signal + 2 + + + + led-stream-order-mode-type + enumeration + Specifies the LED stream ordering mode. + + ORDER_MODE_BY_PORT + the indication order is arranged by port. + 1 + + + ORDER_MODE_BY_CLASS + the indication order is arranged by class. + 2 + + + + led-stream-blink-duty-cycle-type + enumeration + Specifies the LED stream blink cycle duty cycle type. + + BLINK_DUTY_CYCLE_0 + 25% on, 75% off. + 1 + + + BLINK_DUTY_CYCLE_1 + 50% on, 50% off. + 2 + + + BLINK_DUTY_CYCLE_2 + 50% on, 50% off. + 3 + + + BLINK_DUTY_CYCLE_3 + 75% on, 25% off. + 4 + + + + led-stream-blink-duration-type + enumeration + Specifies the LED stream blink period type. + + BLINK_DURATION_0 + BLINK_DURATION_0. + 1 + + + BLINK_DURATION_1 + BLINK_DURATION_1. + 2 + + + BLINK_DURATION_2 + BLINK_DURATION_2. + 3 + + + BLINK_DURATION_3 + BLINK_DURATION_3. + 4 + + + BLINK_DURATION_4 + BLINK_DURATION_4. + 5 + + + BLINK_DURATION_5 + BLINK_DURATION_5. + 6 + + + BLINK_DURATION_6 + (APPLICABLE DEVICES: xCat3; AC5; Lion2; Bobcat2; Caelum; Aldrin; AC3X; Bobcat3; Aldrin2; Pipe) . + 7 + + + BLINK_DURATION_7 + APPLICABLE DEVICES: Bobcat2; Caelum; Aldrin; AC3X; Bobcat3; Aldrin2; Pipe). + 8 + + + + led-stream-pulse-stretch-type + enumeration + Specifies the LED stream length of stretching for dynamic signals. + + PULSE_STRETCH_0_NO + PULSE_STRETCH_0_NO. + 1 + + + PULSE_STRETCH_1 + PULSE_STRETCH_1. + 2 + + + PULSE_STRETCH_2 + PULSE_STRETCH_2. + 3 + + + PULSE_STRETCH_3 + PULSE_STRETCH_3. + 4 + + + PULSE_STRETCH_4 + PULSE_STRETCH_4. + 5 + + + PULSE_STRETCH_5 + PULSE_STRETCH_5. + 6 + + + PULSE_STRETCH_6 + (APPLICABLE DEVICES: Bobcat2; Caelum; Aldrin; AC3X; Bobcat3; Aldrin2; Falcon; AC5P; Pipe). + 7 + + + PULSE_STRETCH_7 + (APPLICABLE DEVICES: Bobcat2; Caelum; Aldrin; AC3X; Bobcat3; Aldrin2; Falcon; AC5P; Pipe). + 8 + + + + led-stream-clock-out-frequency-type + enumeration + Specifies the LED stream blink cycle duty cycle type. + + _CLOCK_OUT_FREQUENCY_500 + 500 KHz LED clock frequency. + 1 + + + CLOCK_OUT_FREQUENCY_1000 + 1 MHz LED clock frequency. + 2 + + + CLOCK_OUT_FREQUENCY_2000 + 2 MHz LED clock frequency. + 3 + + + CLOCK_OUT_FREQUENCY_3000 + 3 MHz LED clock frequency. + 4 + + + + led-stream-class5-select-type + enumeration + Specifies the LED stream indication displayed on class5 (for dual-media port/phy). + + CLASS_5_SELECT_HALF_DUPLEX + Half Duplex is displayed on class5. + 1 + + + CLASS_5_SELECT_FIBER_LINK_UP + If port is a dual media port, Fiber Link Up is displayed on class5. + 2 + + + + led-stream-class13-select-type + enumeration + Specifies the LED stream indication displayed on class13 (for dual-media port/phy). + + CLASS_13_SELECT_LINK_DOWN + Link Down is displayed on class13. + 1 + + + CLASS_13_SELECT_COPPER_LINK_UP + If port is a dual media port, Copper Link Up is displayed on class13. + 2 + + + + led-class-num-type + uint32 + Led Class number + 0 + 11 + + + boolean-type + enumeration + Boolean 32 bits , due to bing endian + + false + False + 0 + + + true + True + 1 + + + + bus-id-type + uint32 + Bus Id Type, PCI/SMI + 0 + 255 + + + function-id-type + uint32 + Function Id Type, PCI/SMI + 0 + 255 + + + domain-type + uint32 + Domain, PCI/SMI + 0 + 255 + + + led-interface-type + uint32 + Led interface + 0 + 255 + + + led-position-type + uint32 + Led position + 0 + 63 + + + serdes-lane-type + uint32 + serdes lane + 0 + 255 + + + cpu-type + enumeration + The CPU Internal/External + + external + Extrenal connected CPU + 0 + + + internal + Internal CPU + 1 + + + + led-stream-clock-frequency-type + uint32 + Led Clock Frequency Sip6 + 500 + 80000 + + + led-unit-type + uint32 + Led units + 1 + 16 + + + led-unit-or-no-unit-type + uint32 + Led units, 0 for no Unit + 0 + 16 + + + led-group-type + uint32 + Led Group + 0 + 1 + + + led-stream-force-data-type + string + A hexadecimal string with octets represented as hex digits +separated by colons. The canonical representation uses +lowercase characters. + 3 + 11 + + + bit-type + uint32 + Bit range 0..31 + 0 + 31 + + + bit-size-type + uint32 + Bit leng 1..32 + 1 + 32 + + + led-sip-type + enumeration + The LED scehme + + na + NA + 0 + + + sip5 + SIP5: AC5, AC3x + 5 + + + sip6 + SIP6: Falcon, AC5x, AC5P + 6 + + + + port-cscd-type + enumeration + Specifies the cascade port type. + + DSA_1_WORD + DSA Regular + 0 + + + DSA_2_WORDS + DSA Extended + 1 + + + NETWORK + Network. + 2 + + + DSA_3_WORDS + DSA 3 Words + 3 + + + DSA_4_WORD + DSA 4 Words + 4 + + + + trunk-cscd-type + uint32 + Specifies the Cascade Trunk id. + 0 + 127 + + + port-trunk-cscd-type + enumeration + Specifies the cascade port type. + + cscdPort + Cascade port + 0 + + + cscdTrunk + Csacde trunk + 1 + + + + hash-cscd-type + enumeration + Specifies the hash used by cascade trunk. + + pkt + Hash based on packet + 0 + + + srcPort + Hash based on source port + 1 + + + + AC5X-RD-G3748 + linux-static + linux-static + autoscan + internal + pex_eagle + + 0 + 0 + ASK-PP-AC5X-G3748.xml + ASK-L1-AC5X-G3748.xml + na + + 0 + + ethernet_mac + 0 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 0 + 0 + + + + + 1 + + ethernet_mac + 1 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 1 + 0 + + + + + 2 + + ethernet_mac + 2 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 2 + 0 + + + + + 3 + + ethernet_mac + 3 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 3 + 0 + + + + + 4 + + ethernet_mac + 4 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 4 + 0 + + + + + 5 + + ethernet_mac + 5 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 5 + 0 + + + + + 6 + + ethernet_mac + 6 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 6 + 0 + + + + + 7 + + ethernet_mac + 7 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 7 + 0 + + + + + 8 + + ethernet_mac + 8 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 8 + 0 + + + + + 9 + + ethernet_mac + 9 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 9 + 0 + + + + + 10 + + ethernet_mac + 10 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 10 + 0 + + + + + 11 + + ethernet_mac + 11 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 11 + 0 + + + + + 12 + + ethernet_mac + 12 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 12 + 0 + + + + + 13 + + ethernet_mac + 13 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 13 + 0 + + + + + 14 + + ethernet_mac + 14 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 14 + 0 + + + + + 15 + + ethernet_mac + 15 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 15 + 0 + + + + + 16 + + ethernet_mac + 16 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 16 + 0 + + + + + 17 + + ethernet_mac + 17 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 17 + 0 + + + + + 18 + + ethernet_mac + 18 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 18 + 0 + + + + + 19 + + ethernet_mac + 19 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 19 + 0 + + + + + 20 + + ethernet_mac + 20 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 20 + 0 + + + + + 21 + + ethernet_mac + 21 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 21 + 0 + + + + + 22 + + ethernet_mac + 22 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 22 + 0 + + + + + 23 + + ethernet_mac + 23 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 23 + 0 + + + + + 24 + + ethernet_mac + 24 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 0 + 1 + + + + + 25 + + ethernet_mac + 25 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 1 + 1 + + + + + 26 + + ethernet_mac + 26 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 2 + 1 + + + + + 27 + + ethernet_mac + 27 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 3 + 1 + + + + + 28 + + ethernet_mac + 28 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 4 + 1 + + + + + 29 + + ethernet_mac + 29 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 5 + 1 + + + + + 30 + + ethernet_mac + 30 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 6 + 1 + + + + + 31 + + ethernet_mac + 31 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 7 + 1 + + + + + 32 + + ethernet_mac + 32 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 8 + 1 + + + + + 33 + + ethernet_mac + 33 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 9 + 1 + + + + + 34 + + ethernet_mac + 34 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 10 + 1 + + + + + 35 + + ethernet_mac + 35 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 11 + 1 + + + + + 36 + + ethernet_mac + 36 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 12 + 1 + + + + + 37 + + ethernet_mac + 37 + 0 + false + + NETWORK + + alaska-88E1780 + 5 + 13 + 1 + + + + + 38 + + ethernet_mac + 38 + 0 + false + + NETWORK + + alaska-88E1780 + 5 + 14 + 1 + + + + + 39 + + ethernet_mac + 39 + 0 + false + + NETWORK + + alaska-88E1780 + 5 + 15 + 1 + + + + + 40 + + ethernet_mac + 40 + 0 + false + + NETWORK + + alaska-88E1780 + 5 + 16 + 1 + + + + + 41 + + ethernet_mac + 41 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 17 + 1 + + + + + 42 + + ethernet_mac + 42 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 18 + 1 + + + + + 43 + + ethernet_mac + 43 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 19 + 1 + + + + + 44 + + ethernet_mac + 44 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 20 + 1 + + + + + 45 + + ethernet_mac + 45 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 21 + 1 + + + + + 46 + + ethernet_mac + 46 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 22 + 1 + + + + + 47 + + ethernet_mac + 47 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 23 + 1 + + + + + 48 + + ethernet_mac + 48 + 0 + false + + NETWORK + + NA + + + + + 53 + + ethernet_mac + 53 + 0 + false + + NETWORK + + NA + + + + + 52 + + ethernet_mac + 52 + 0 + false + + NETWORK + + NA + + + + + 51 + + ethernet_mac + 51 + 0 + false + + NETWORK + + NA + + + + + 50 + + ethernet_mac + 50 + 0 + false + + NETWORK + + NA + + + + + 49 + + ethernet_mac + 49 + 0 + false + + NETWORK + + NA + + + + + 63 + + cpu_sdma + 54 + 0 + false + + NETWORK + + + 60 + + cpu_sdma + 55 + 0 + false + + NETWORK + + + . + + 1 + + + \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-L1-AC5X-G3748.md5 b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-L1-AC5X-G3748.md5 new file mode 100755 index 0000000000..3f39c0bfe3 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-L1-AC5X-G3748.md5 @@ -0,0 +1 @@ +cccaf00bb8ea243d5c2884fb05bfd528 \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-L1-AC5X-G3748.xml b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-L1-AC5X-G3748.xml new file mode 100755 index 0000000000..dd78325643 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-L1-AC5X-G3748.xml @@ -0,0 +1,1219 @@ + + + + + + interface-mode-type + enumeration + Specifies supported Interface modes + + 1000BASE_X + 1G + 6 + + + SGMII + 1G , 2.5G + 3 + + + QSGMII + 1G + 13 + + + KR + 10G, 12G, 20G, 40G, 100G + 16 + + + SR_LR + 5G, 10G, 12G, 20G, 40G + 20 + + + KR2 + + 27 + + + KR4 + + 28 + + + SR_LR2 + + 29 + + + SR_LR4 + 100G + 30 + + + KR_C + CONSORTIUM - 25G + 32 + + + CR_C + CONSORTIUM - 25G + 33 + + + KR2_C + CONSORTIUM - 50G + 34 + + + CR2_C + CONSORTIUM - 50G + 35 + + + CR + + 36 + + + CR2 + + 37 + + + CR4 + + 38 + + + KR_S + + 39 + + + CR_S + + 40 + + + KR8 + + 41 + + + CR8 + + 42 + + + SR_LR8 + + 43 + + + USX_10G_QXGMII + + 51 + + + USX_20G_QXGMII + + 52 + + + USX_OUSGMII + + 53 + + + USX_20G_OXGMII + + 54 + + + NA + + 57 + + + + port-speed-type + enumeration + Specifies supported speeds + + 1G + 1G + 2 + + + 10G + 10G + 3 + + + 2500M + 2.5G + 5 + + + 5G + 5G + 6 + + + 25G + 25G, used in combination with CPSS_PORT_INTERFACE_MODE_KR_E, CPSS_PORT_INTERFACE_MODE_KR2_E + 21 + + + 40G + 40G + 9 + + + 50G + 50G + 14 + + + 100G + 100G + 13 + + + 200G + 200G + 24 + + + 400G + 400G + 25 + + + NA + NA + 35 + + + + fec-type + enumeration + Rx parameter type + + enabled + Enabled + 0 + + + disabled + Disabled + 1 + + + rs_enabled + RS FEC enabled + 2 + + + both_enabled + Both enabled + 3 + + + rs_544_514_enabled + RS FEC 544 and 514 + 4 + + + + physical-port-num-type + uint32 + PHYSICAL PORT NUM + 0 + 1023 + + + tx-param-type + enumeration + Tx parameter type + + atten + atten + 0 + + + post + post + 1 + + + pre + pre + 2 + + + pre2 + pre2 + 3 + + + pre3 + pre3 + 4 + + + peak + peak + 5 + + + main + main + 6 + + + txAmpAdjEn + txAmpAdjEn + 7 + + + emph0 + emph0 + 8 + + + emph1 + emph1 + 9 + + + txAmpShft + txAmpShft + 10 + + + txEmphEn + txEmphEn + 11 + + + txEmphEn1 + txEmphEn1 + 12 + + + txAmpAdj + txAmpAdj + 13 + + + slewCtrlEn + slewCtrlEn + 14 + + + slewRate + slewRate + 15 + + + + rx-param-type + enumeration + Rx parameter type + + sqlch + sqlch + 0 + + + DC + DC + 1 + + + LF + LF + 2 + + + HF + HF + 3 + + + gainShape1 + gainShape1 + 4 + + + gainShape2 + gainShape2 + 5 + + + shortChannelEn + shortChannelEn + 7 + + + bfLf + bfLf + 8 + + + bfHf + bfHf + 9 + + + minLf + minLf + 10 + + + maxLf + maxLf + 11 + + + minHf + minHf + 12 + + + maxHf + maxHf + 13 + + + minPre1 + minPre1 + 14 + + + maxPre1 + maxPre1 + 15 + + + minPre2 + minPre2 + 16 + + + maxPre2 + + 17 + + + minPost + minPost + 18 + + + maxPost + maxPost + 19 + + + squelch + squelch + 20 + + + termination + termination + 27 + + + coldEnvelope + coldEnvelope + 35 + + + hotEnvelope + hotEnvelope + 36 + + + dcGain + dcGain + 37 + + + bandWidth + bandWidth + 38 + + + dfe + dfe + 39 + + + ffeR + ffeR + 40 + + + ffeC + ffeC + 41 + + + sampler + sampler + 42 + + + align90 + align90 + 43 + + + ffeS + ffeS + 44 + + + resSel + resSel + 45 + + + resShift + resShift + 46 + + + capSel + capSel + 47 + + + ffeSettingForce + ffeSettingForce + 48 + + + adaptedResSel + adaptedResSel + 49 + + + adaptedCapSel + adaptedCapSel + 50 + + + selmufi + selmufi + 51 + + + selmuff + selmuff + 52 + + + selmupi + selmupi + 53 + + + selmupf + selmupf + 54 + + + slewRateCtrl0 + slewRateCtrl0 + 55 + + + slewRateCtrl1 + slewRateCtrl1 + 56 + + + EO + EO + 57 + + + dataRate + dataRate + 58 + + + res1Sel + res1Sel + 59 + + + res2Sel + res2Sel + 60 + + + cap1Sel + cap1Sel + 61 + + + cap2Sel + cap2Sel + 62 + + + midpointLargeThresKLane + midpointLargeThresKLane + 63 + + + midpointSmallThresKLane + midpointSmallThresKLane + 64 + + + midpointLargeThresCLane + midpointLargeThresCLane + 65 + + + midpointSmallThresCLane + midpointSmallThresCLane + 66 + + + dfeResF0aHighThresInitLane + dfeResF0aHighThresInitLane + 67 + + + dfeResF0aHighThresEndLane + dfeResF0aHighThresEndLane + 68 + + + current1Sel + current1Sel + 69 + + + rl1Sel + rl1Sel + 70 + + + rl1Extra + rl1Extra + 71 + + + cl1Ctrl + cl1Ctrl + 72 + + + enMidFreq + enMidFreq + 73 + + + cs1Mid + cs1Mid + 74 + + + rs1Mid + rs1Mid + 75 + + + rfCtrl + rfCtrl + 76 + + + rl1TiaSel + rl1TiaSel + 77 + + + rl1TiaExtra + rl1TiaExtra + 78 + + + hpfRSel1st + hpfRSel1st + 79 + + + current1TiaSel + current1TiaSel + 80 + + + rl2Tune + rl2Tune + 81 + + + rl2Sel + rl2Sel + 82 + + + rs2Sel + rs2Sel + 83 + + + current2Sel + current2Sel + 84 + + + hpfRsel2nd + hpfRsel2nd + 85 + + + BW + BW + 86 + + + dfeGAIN + dfeGAIN + 87 + + + dfeGAIN2 + dfeGAIN2 + 88 + + + pre1 + pre1 + 89 + + + pre2 + pre2 + 90 + + + post1 + post1 + 91 + + + + boolean-type + enumeration + Boolean 32 bits , due to bing endian + + false + False + 0 + + + true + True + 1 + + + + serdes-type + enumeration + Serdes Type + + NA + No serdes + 0 + + + AVAGO + AVAGO + 1 + + + COMPHY + COMPHY + 2 + + + COMPHY_C12G + COMPHY_C12G + 3 + + + COMPHY_C28G + COMPHY_C28G + 4 + + + COMPHY_C112G + COMPHY_C112G + 5 + + + + uint8-type + uint32 + Uint8 32 bits , due to bing endian + 0 + 255 + + + serdes-termination-type + enumeration + RX termination mode + + GND + Enabled + 0 + + + VDD + Disabled + 1 + + + FLOATING + RS FEC enabled + 2 + + + + port-interconnect-profile-type + enumeration + Enumerator of interconnect profile. + + profile_default + Profile Default + 0 + + + profile_1 + Profile 1 + 1 + + + profile_2 + Profile 2 + 2 + + + + + + 1000MR1 + + USX_OUSGMII + 1G + disabled + + + USX_OUSGMII + 1G + disabled + disabled + + + + 2500MR1 + + USX_20G_OXGMII + 2500M + rs_enabled + + + USX_20G_OXGMII + 1G + rs_enabled + + + USX_20G_OXGMII + 2500M + rs_enabled + rs_enabled + + + USX_20G_OXGMII + 1G + rs_enabled + rs_enabled + + + + 25GR1 + + CR + 25G + rs_enabled + + + KR + 25G + rs_enabled + + + KR + 10G + disabled + + + CR + 25G + rs_enabled + rs_enabled + + + KR + 25G + rs_enabled + rs_enabled + + + KR + 10G + disabled + disabled + + + + + + 0 + AVAGO + profile_default + 1000MR1 + + + 1 + AVAGO + profile_default + 1000MR1 + + + 2 + AVAGO + profile_default + 1000MR1 + + + 3 + AVAGO + profile_default + 1000MR1 + + + 4 + AVAGO + profile_default + 1000MR1 + + + 5 + AVAGO + profile_default + 1000MR1 + + + 6 + AVAGO + profile_default + 1000MR1 + + + 7 + AVAGO + profile_default + 1000MR1 + + + 8 + AVAGO + profile_default + 1000MR1 + + + 9 + AVAGO + profile_default + 1000MR1 + + + 10 + AVAGO + profile_default + 1000MR1 + + + 11 + AVAGO + profile_default + 1000MR1 + + + 12 + AVAGO + profile_default + 1000MR1 + + + 13 + AVAGO + profile_default + 1000MR1 + + + 14 + AVAGO + profile_default + 1000MR1 + + + 15 + AVAGO + profile_default + 1000MR1 + + + 16 + AVAGO + profile_default + 1000MR1 + + + 17 + AVAGO + profile_default + 1000MR1 + + + 18 + AVAGO + profile_default + 1000MR1 + + + 19 + AVAGO + profile_default + 1000MR1 + + + 20 + AVAGO + profile_default + 1000MR1 + + + 21 + AVAGO + profile_default + 1000MR1 + + + 22 + AVAGO + profile_default + 1000MR1 + + + 23 + AVAGO + profile_default + 1000MR1 + + + 24 + AVAGO + profile_default + 1000MR1 + + + 25 + AVAGO + profile_default + 1000MR1 + + + 26 + AVAGO + profile_default + 1000MR1 + + + 27 + AVAGO + profile_default + 1000MR1 + + + 28 + AVAGO + profile_default + 1000MR1 + + + 29 + AVAGO + profile_default + 1000MR1 + + + 30 + AVAGO + profile_default + 1000MR1 + + + 31 + AVAGO + profile_default + 1000MR1 + + + 32 + AVAGO + profile_default + 1000MR1 + + + 33 + AVAGO + profile_default + 1000MR1 + + + 34 + AVAGO + profile_default + 1000MR1 + + + 35 + AVAGO + profile_default + 1000MR1 + + + 36 + AVAGO + profile_default + 1000MR1 + + + 37 + AVAGO + profile_default + 1000MR1 + + + 38 + AVAGO + profile_default + 1000MR1 + + + 39 + AVAGO + profile_default + 1000MR1 + + + 40 + AVAGO + profile_default + 1000MR1 + + + 41 + AVAGO + profile_default + 1000MR1 + + + 42 + AVAGO + profile_default + 1000MR1 + + + 43 + AVAGO + profile_default + 1000MR1 + + + 44 + AVAGO + profile_default + 1000MR1 + + + 45 + AVAGO + profile_default + 1000MR1 + + + 46 + AVAGO + profile_default + 1000MR1 + + + 47 + AVAGO + profile_default + 1000MR1 + + + 48 + AVAGO + profile_default + 25GR1 + + + 49 + AVAGO + profile_default + 25GR1 + + + 50 + AVAGO + profile_default + 25GR1 + + + 51 + AVAGO + profile_default + 25GR1 + + + 52 + AVAGO + profile_default + 25GR1 + + + 53 + AVAGO + profile_default + 25GR1 + + + + \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-PP-AC5X-G3748.md5 b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-PP-AC5X-G3748.md5 new file mode 100755 index 0000000000..e0b9509d1d --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-PP-AC5X-G3748.md5 @@ -0,0 +1 @@ +75737f56687883d181ea3da8d1c24da6 \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-PP-AC5X-G3748.xml b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-PP-AC5X-G3748.xml new file mode 100755 index 0000000000..50daefc694 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/ASK-PP-AC5X-G3748.xml @@ -0,0 +1,871 @@ + + + + + + std-string + string + standard string. + 1 + 100 + + + queue-id-type + uint32 + Queue id + 0 + 7 + + + precent-type + uint32 + Precent + 0 + 100 + + + phaThreadId-type + uint32 + Thread id + 1 + 255 + + + routing-mode-type + enumeration + Specifies routing mode. + + POLICY_BASED_ROUTING_ONLY + PBR only + 0 + + + TCAM_ROUTER_BASED + Router engine or PBR + 1 + + + + shared-table-mode-type + enumeration + Specifies table sharing modes for L3 (LPM), L2 (FDB), EM (Exact Match) + + MID_L3_MID_L2_NO_EM + MID_L3_MID_L2_NO_EM + 0 + + + MID_L3_MID_L2_MIN_EM + MID_L3_MID_L2_MIN_EM + 1 + + + LOW_MAX_L3_MID_LOW_L2_NO_EM + LOW_MAX_L3_MID_LOW_L2_NO_EM + 2 + + + MAX_L3_MIN_L2_NO_EM + MAX_L3_MIN_L2_NO_EM + 3 + + + + pha-firmware-image-id-type + enumeration + Specifies supported Pha image id + + DEFAULT + Default PHA firmware image ID + 0 + + + 01 + 01 firmware image ID + 1 + + + 02 + 02 PHA firmware image ID + 2 + + + + pha-firmware-thread-type + enumeration + Specifies supported Pha thread type + + IOAM_INGRESS_SWITCH_IPV4 + IOAM_INGRESS_SWITCH_IPV4 + 1 + + + IOAM_INGRESS_SWITCH_IPV6 + IOAM_INGRESS_SWITCH_IPV6 + 2 + + + IOAM_TRANSIT_SWITCH_IPV4 + IOAM_TRANSIT_SWITCH_IPV4 + 3 + + + IOAM_TRANSIT_SWITCH_IPV6 + IOAM_TRANSIT_SWITCH_IPV6 + 4 + + + INT_IOAM_MIRRORING + INT_IOAM_MIRRORING + 5 + + + INT_IOAM_EGRESS_SWITCH + INT_IOAM_EGRESS_SWITCH + 6 + + + MPLS_SR_NO_EL + MPLS_SR_NO_EL + 7 + + + MPLS_SR_ONE_EL + MPLS_SR_ONE_EL + 8 + + + MPLS_SR_TWO_EL + MPLS_SR_TWO_EL + 9 + + + MPLS_SR_THREE_EL + MPLS_SR_THREE_EL + 10 + + + UNIFIED_SR + UNIFIED_SR + 11 + + + CLASSIFIER_NSH_OVER_ETHERNET + CLASSIFIER_NSH_OVER_ETHERNET + 12 + + + CLASSIFIER_NSH_OVER_VXLAN_GPE + CLASSIFIER_NSH_OVER_VXLAN_GPE + 13 + + + SFF_NSH_VXLAN_GPE_TO_ETHERNET + SFF_NSH_VXLAN_GPE_TO_ETHERNET + 14 + + + SFF_NSH_ETHERNET_TO_VXLAN_GPE + SFF_NSH_ETHERNET_TO_VXLAN_GPE + 15 + + + IOAM_EGRESS_SWITCH_IPV6 + IOAM_EGRESS_SWITCH_IPV6 + 16 + + + SRV6_END_NODE + SRV6_END_NODE + 17 + + + SRV6_PENULTIMATE_END_NODE + SRV6_PENULTIMATE_END_NODE + 18 + + + SRV6_SRC_NODE_1_SEGMENT + SRV6_SRC_NODE_1_SEGMENT + 19 + + + SRV6_SRC_NODE_FIRST_PASS_2_3_SEGMENTS + SRV6_SRC_NODE_FIRST_PASS_2_3_SEGMENTS + 20 + + + SRV6_SRC_NODE_SECOND_PASS_3_SEGMENTS + SRV6_SRC_NODE_SECOND_PASS_3_SEGMENTS + 21 + + + SRV6_SRC_NODE_SECOND_PASS_2_SEGMENTS + SRV6_SRC_NODE_SECOND_PASS_2_SEGMENTS + 22 + + + SGT_NETWORK_ADD_MSB + SGT_NETWORK_ADD_MSB + 23 + + + SGT_NETWORK_FIX + SGT_NETWORK_FIX + 24 + + + SGT_NETWORK_REMOVE + SGT_NETWORK_REMOVE + 25 + + + SGT_EDSA_FIX + SGT_EDSA_FIX + 26 + + + SGT_EDSA_REMOVE + SGT_EDSA_REMOVE + 27 + + + SGT_GBP_FIX_IPV4 + SGT_GBP_FIX_IPV4 + 28 + + + SGT_GBP_FIX_IPV6 + SGT_GBP_FIX_IPV6 + 29 + + + SGT_GBP_REMOVE_IPV4 + SGT_GBP_REMOVE_IPV4 + 30 + + + SGT_GBP_REMOVE_IPV6 + SGT_GBP_REMOVE_IPV6 + 31 + + + PTP_PHY_1_STEP + PTP_PHY_1_STEP + 32 + + + EGRESS_MIRRORING_METADATA + EGRESS_MIRRORING_METADATA + 33 + + + CC_ERSPAN_TYPE_II_TRG_DEV_LC_IPV4 + CC_ERSPAN_TYPE_II_TRG_DEV_LC_IPV4 + 34 + + + CC_ERSPAN_TYPE_II_TRG_DEV_LC_IPV6 + CC_ERSPAN_TYPE_II_TRG_DEV_LC_IPV6 + 35 + + + CC_ERSPAN_TYPE_II_TRG_DEV_DIRECT_IPV4 + CC_ERSPAN_TYPE_II_TRG_DEV_DIRECT_IPV4 + 36 + + + CC_ERSPAN_TYPE_II_TRG_DEV_DIRECT_IPV6 + CC_ERSPAN_TYPE_II_TRG_DEV_DIRECT_IPV6 + 37 + + + CC_ERSPAN_TYPE_II_SRC_DEV + CC_ERSPAN_TYPE_II_SRC_DEV + 38 + + + VXLAN_GBP_SOURCE_GROUP_POLICY_ID + VXLAN_GBP_SOURCE_GROUP_POLICY_ID + 39 + + + SRV6_BEST_EFFORT + SRV6_BEST_EFFORT + 40 + + + SRV6_SRC_NODE_1_CONTAINER + SRV6_SRC_NODE_1_CONTAINER + 41 + + + SRV6_SRC_NODE_FIRST_PASS_2_3_CONTAINERS + SRV6_SRC_NODE_FIRST_PASS_2_3_CONTAINERS + 42 + + + SRV6_SRC_NODE_SECOND_PASS_2_CONTAINERS + SRV6_SRC_NODE_SECOND_PASS_2_CONTAINERS + 43 + + + SRV6_SRC_NODE_SECOND_PASS_3_CONTAINERS + SRV6_SRC_NODE_SECOND_PASS_3_CONTAINERS + 44 + + + SRV6_END_NODE_COC32_GSID + SRV6_END_NODE_COC32_GSID + 45 + + + IPV4_TTL_INCREMENT + IPV4_TTL_INCREMENT + 46 + + + IPV6_HOP_LIMIT_INCREMENT + IPV6_HOP_LIMIT_INCREMENT + 47 + + + CLEAR_OUTGOING_MTAG_COMMAND + CLEAR_OUTGOING_MTAG_COMMAND + 48 + + + SFLOW_V5_IPV4 + SFLOW_V5_IPV4 + 49 + + + SFLOW_V5_IPV6 + SFLOW_V5_IPV6 + 50 + + + SLS + SLS + 51 + + + + trunk-member-mode-type + enumeration + Specifies supported Pha image id + + NATIVE + NATIVE + * the trunk members are filled + * according to the order given by application. + * Regular trunk may hold max of 8 members. + * Cascade trunk may hold : + * max of 64 members + 0 + + + FLEX + FLEX + * A mode to allows flexibility for + * each Regular trunk to state it's max number of members (before starting to add members). + * (this mode not effect 'cascade trunk' members) + * Regular trunk may hold : max of 4K members. (each trunk set it's own limit) + * Cascade trunk may hold : max of 64 members. + 2 + + + + number-physical-port-type + enumeration + ac5x 128, falcon 64,128,256, 512, 1024 + + no-ports + no-ports + 0 + + + 64-ports + 64-ports + 64 + + + 128-ports + 128-ports + 128 + + + 256-ports + 256-ports + 256 + + + 512-ports + 512-ports + 512 + + + 1024-ports + 1024-ports + 1024 + + + + serdes-ref-clock-type + enumeration + Specifies serdes refernce clock. + + external_25_single_ended + EXTERNAL_25_SINGLE_ENDED + 0 + + + external_125_single_ended + EXTERNAL_125_SINGLE_ENDED + 1 + + + external_125_diff + EXTERNAL_125_DIFF + 2 + + + external_156_25_single_ended + EXTERNAL_156_25_SINGLE_ENDED + 3 + + + external_156_25_diff + EXTERNAL_156_25_DIFF + 4 + + + internal_125 + INTERNAL_125 + 5 + + + + cpu-port-id-type + uint32 + CPU port id + 0 + 7 + + + rx-buffer-size-type + uint32 + Rx Buffer size + 64 + 10240 + + + tx-sdma-queue-mode-type + enumeration + Specifies TX queue mode. + + Normal + Application + 0 + + + Packet_Generator + Traffic generator + 1 + + + + alloc-method-type + enumeration + Specifies Buffers allocation method. + + Dynamic_Alloc + Dynamic + 0 + + + Static_Alloc + Static + 1 + + + + au_mesage_lenght-type + enumeration + Specifies Buffers allocation method. + + 4_words + 4 Words + 0 + + + 8_words + 8 Words + 1 + + + + boolean-type + enumeration + Boolean 32 bits , due to bing endian + + false + False + 0 + + + true + True + 1 + + + + + AC5X-RD + + 4294967295 + external_25_single_ended + 2 + 60 + 128-ports + false + false + 0 + + + true + + 4096 + + + 2048 + + + + 0 + 0 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 7 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 6 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 5 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 4 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 3 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 2 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 1 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 0 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 7 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 6 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 5 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 4 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 3 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 2 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 1 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 0 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 1 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 2 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 3 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 4 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 5 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 6 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 7 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 0 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 1 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 2 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 3 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 4 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 5 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 6 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 7 + Static_Alloc + Normal + 20 + 0 + 128 + + + + false + false + false + 0 + 8_words + false + + + + TCAM_ROUTER_BASED + 0 + MID_L3_MID_L2_NO_EM + true + + + true + true + true + true + true + true + + 511 + FLEX + + true + true + true + true + + false + 01 + 0 + + + + + \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/SAI-AC5X-G3748.md5 b/device/supermicro/arm64-supermicro_sse_g3748-r0/SAI-AC5X-G3748.md5 new file mode 100755 index 0000000000..e06cc46bf9 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/SAI-AC5X-G3748.md5 @@ -0,0 +1 @@ +32fa759aabe89e7d76a2b8f35a9babc0 \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/SAI-AC5X-G3748.xml b/device/supermicro/arm64-supermicro_sse_g3748-r0/SAI-AC5X-G3748.xml new file mode 100755 index 0000000000..03d240255b --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/SAI-AC5X-G3748.xml @@ -0,0 +1,346 @@ + + + + + + device-id-type + uint32 + Device ID 0..1023 + 0 + 1023 + + + port-id-type + uint32 + Interface number + 0 + 1023 + + + logDest-type + enumeration + Logging Feature Options + + SAI_LOG_SYSLOG + SYSLOG {Syslog service should be running to use this option} + 0 + + + SAI_LOG_CONSOLE + CONSOLE + 1 + + + SAI_LOG_FILE + FILE {Warning !!! Use with caution. Can cause disk full issues} + 2 + + + + log-dest-file-path-type + string + A string with path to file for logging feature + 2 + 30 + + + ASK-Board-ac5x-G3748.xml + + false + + + + 0 + 0 + 0 + + + 1 + 0 + 1 + + + 2 + 0 + 2 + + + 3 + 0 + 3 + + + 4 + 0 + 4 + + + 5 + 0 + 5 + + + 6 + 0 + 6 + + + 7 + 0 + 7 + + + 8 + 0 + 8 + + + 9 + 0 + 9 + + + 10 + 0 + 10 + + + 11 + 0 + 11 + + + 12 + 0 + 12 + + + 13 + 0 + 13 + + + 14 + 0 + 14 + + + 15 + 0 + 15 + + + 16 + 0 + 16 + + + 17 + 0 + 17 + + + 18 + 0 + 18 + + + 19 + 0 + 19 + + + 20 + 0 + 20 + + + 21 + 0 + 21 + + + 22 + 0 + 22 + + + 23 + 0 + 23 + + + 24 + 0 + 24 + + + 25 + 0 + 25 + + + 26 + 0 + 26 + + + 27 + 0 + 27 + + + 28 + 0 + 28 + + + 29 + 0 + 29 + + + 30 + 0 + 30 + + + 31 + 0 + 31 + + + 32 + 0 + 32 + + + 33 + 0 + 33 + + + 34 + 0 + 34 + + + 35 + 0 + 35 + + + 36 + 0 + 36 + + + 37 + 0 + 37 + + + 38 + 0 + 38 + + + 39 + 0 + 39 + + + 40 + 0 + 40 + + + 41 + 0 + 41 + + + 42 + 0 + 42 + + + 43 + 0 + 43 + + + 44 + 0 + 44 + + + 45 + 0 + 45 + + + 46 + 0 + 46 + + + 47 + 0 + 47 + + + 48 + 0 + 48 + + + 49 + 0 + 49 + + + 50 + 0 + 50 + + + 51 + 0 + 51 + + + 52 + 0 + 52 + + + 53 + 0 + 53 + + + + 8 + 0 + 0 + 64 + 8 + 8 + 1024 + 0 + 0 + + + + 0 + + + 2048 + + + + SAI_LOG_SYSLOG + + + \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/default_sku b/device/supermicro/arm64-supermicro_sse_g3748-r0/default_sku new file mode 100644 index 0000000000..9bde3d72ef --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/default_sku @@ -0,0 +1 @@ +supermicro_sse_g3748 t1 diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/pcie.yaml b/device/supermicro/arm64-supermicro_sse_g3748-r0/pcie.yaml new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/pcie.yaml @@ -0,0 +1 @@ +[] diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/platform.json b/device/supermicro/arm64-supermicro_sse_g3748-r0/platform.json new file mode 100644 index 0000000000..127ce8c955 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/platform.json @@ -0,0 +1,116 @@ +{ + "chassis": { + "name": "SSE-G3748", + "components": [ + { + "name": "U-Boot" + }, + { + "name": "ONIE-VERSION" + }, + { + "name": "System-CPLD" + } + ], + "fans": [ + { + "name": "Fan1", + "status_led": { + "controllable": true, + "colors": ["red", "green"] + } + }, + { + "name": "Fan2", + "status_led": { + "controllable": true, + "colors": ["red", "green"] + } + } + ], + "fan_drawers": [ + { + "name": "drawer1", + "status_led": { + "controllable": true, + "colors": ["red", "green"] + }, + "max_consumed_power": false, + "fans": [ + { + "name": "Fan1" + }, + { + "name": "Fan2" + } + ] + } + ], + "psus": [ + { + "name": "PSU1", + "status_led": { + "controllable": false + }, + "current": false, + "power": false, + "max_power": false, + "voltage_high_threshold": false, + "voltage_low_threshold": false, + "temperature": false + }, + { + "name": "PSU2", + "status_led": { + "controllable": false + }, + "current": false, + "power": false, + "max_power": false, + "voltage_high_threshold": false, + "voltage_low_threshold": false, + "temperature": false + } + ], + "thermals": [ + { + "name": "FRONT", + "controllable": false, + "low-threshold": false, + "high-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "REAR", + "controllable": false, + "low-threshold": false, + "high-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + } + ], + "sfps": [ + { + "name": "Ethernet48" + }, + { + "name": "Ethernet49" + }, + { + "name": "Ethernet50" + }, + { + "name": "Ethernet51" + }, + { + "name": "Ethernet52" + }, + { + "name": "Ethernet53" + } + ] + }, + "interfaces": {} +} + diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/platform_asic b/device/supermicro/arm64-supermicro_sse_g3748-r0/platform_asic new file mode 100644 index 0000000000..558e01e184 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/platform_asic @@ -0,0 +1 @@ +marvell-arm64 diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/platform_components.json b/device/supermicro/arm64-supermicro_sse_g3748-r0/platform_components.json new file mode 100644 index 0000000000..eeb9e6edfd --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/platform_components.json @@ -0,0 +1,21 @@ +{ + "chassis": { + "SSE-G3748": { + "component": { + "U-Boot": { }, + "ONIE-VERSION": { }, + "System-CPLD": { } + } + } + }, + "chassis": { + "SSE-G3748R": { + "component": { + "U-Boot": { }, + "ONIE-VERSION": { }, + "System-CPLD": { } + } + } + } + +} diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/platform_reboot b/device/supermicro/arm64-supermicro_sse_g3748-r0/platform_reboot new file mode 100755 index 0000000000..a95459054c --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/platform_reboot @@ -0,0 +1,11 @@ +#!/bin/bash + +function SafePwrCycle() { + sync ; sync + umount -fa > /dev/null 2&>1 + + # Write CPLD register to initiate cold reboot + sudo i2cset -f -y 0 0x66 0x02 0x80 +} + +SafePwrCycle diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/eeprom.py b/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/eeprom.py new file mode 100644 index 0000000000..b8d18f7ee9 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/eeprom.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + #self.eeprom_path = "/etc/sonic/eeprom" + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0054/eeprom" + if not os.path.exists(self.eeprom_path): + os.system("echo 24c02 0x54 > /sys/class/i2c-adapter/i2c-0/new_device") + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/led_control.py b/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/led_control.py new file mode 100644 index 0000000000..c710eb6257 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/led_control.py @@ -0,0 +1,225 @@ +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + from sonic_led.led_control_base import LedControlBase + import os + import time + import syslog + import sonic_platform.platform + import sonic_platform.chassis +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +def DBG_PRINT(str): + syslog.openlog("sse-g3748-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + SONIC_PORT_NAME_PREFIX = "Ethernet" + + # Constructor + def __init__(self): + self.chassis = sonic_platform.platform.Platform().get_chassis() + self._initDefaultConfig() + + def _initDefaultConfig(self): + # The fan tray leds and system led managed by new chassis class API + # leaving only a couple other front panel leds to be done old style + DBG_PRINT("starting system leds") + self._initSystemLed() + DBG_PRINT(" led done") + + def _get_i2c_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _set_i2c_register(self, reg_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + try: + with open(reg_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + + # Ensure that the write operation has succeeded + if (int(self._get_i2c_register(reg_file)) != value ): + time.sleep(3) + if (int(self._get_i2c_register(reg_file)) != value ): + rv = 'ERR' + + return rv + + def _initSystemLed(self): + # Front Panel System LEDs setting + oldfan = 0xf + oldpsu0 = 0xf + oldpsu1 = 0xf + G3748CPLD_I2C_DIR = "/sys/bus/i2c/devices/0-0066/" + self.fan_sys_frontled_reg = G3748CPLD_I2C_DIR+"fan_sys_frontled".format() + self.psu_frontled_reg = G3748CPLD_I2C_DIR+"psu_frontled".format() + + + # Write sys led + if smbus_present == 0: + DBG_PRINT(" PMON LED SET ERROR -> smbus present = 0 ") + else: + # System LED is controlled by CPLD (i2c 0x66) register 0x11 bits:3-0 + #bus = smbus.SMBus(0) + #DEVICE_ADDRESS = 0x66 + #DEVICEREG = 0x11 + #register = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + ## write System LED Green + #register = register & 0xFC | 0x01 + #bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, register) + #DBG_PRINT(" System LED set O.K. ") + + register = self._get_i2c_register(self.fan_sys_frontled_reg) + # write System LED solid green + register = int(register) & 0xFC | 0x01 + self._set_i2c_register(self.fan_sys_frontled_reg, register) + + while True: + # Front Panel FAN Panel LED setting in CPLD (i2c 0x66) register 0x11 bits:7-4 + if (self.chassis.get_fan(0).get_status() == self.chassis.get_fan(1).get_status() == True): + if oldfan != 0x1: + # Set Front Panel FAN LED to green + #bus = smbus.SMBus(0) + #DEVICE_ADDRESS = 0x66 + #DEVICEREG = 0x11 + #register = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + #register = register & 0xCF | 0x20 + #bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, register) + register = self._get_i2c_register(self.fan_sys_frontled_reg) + register = int(register) & 0xCF | 0x20 + self._set_i2c_register(self.fan_sys_frontled_reg, register) + oldfan = 0x1 + DBG_PRINT(" Front panel LED FAN set green") + else: + if oldfan != 0x0: + # Set Front Panel FAN LED to red + #bus = smbus.SMBus(0) + #DEVICE_ADDRESS = 0x66 + #DEVICEREG = 0x11 + #register = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + #register = register & 0xCF | 0x10 + #bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, register) + register = self._get_i2c_register(self.fan_sys_frontled_reg) + register = int(register) & 0xCF | 0x10 + self._set_i2c_register(self.fan_sys_frontled_reg, register) + oldfan = 0x0 + DBG_PRINT(" Front panel LED FAN set red") + + # Front Panel PSU Panel LED setting in CPLD (i2c 0x66) register 0x12 + # PSU0 -- bits: 1..0 PSU1 -- bits: 3..2 + if (self.chassis.get_psu(0).get_status() == True): + if oldpsu0 != 0x1: + # Set PSU0 LED to green + #bus = smbus.SMBus(0) + #DEVICE_ADDRESS = 0x66 + #DEVICEREG = 0x12 + #register = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + #register = register & 0xFC | 0x02 + #bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, register) + register = self._get_i2c_register(self.psu_frontled_reg) + register = int(register) & 0xFC | 0x02 + self._set_i2c_register(self.psu_frontled_reg, register) + oldpsu0 = 0x1 + DBG_PRINT(" Front panel LED PSU0 set green") + else: + if oldpsu0 != 0x0: + # Set PSU0 LED to red + #bus = smbus.SMBus(0) + #DEVICE_ADDRESS = 0x66 + #DEVICEREG = 0x12 + #register = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + #register = register & 0xFC | 0x01 + #bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, register) + register = self._get_i2c_register(self.psu_frontled_reg) + register = int(register) & 0xFC | 0x01 + self._set_i2c_register(self.psu_frontled_reg, register) + oldpsu0 = 0x0 + DBG_PRINT(" Front panel LED PSU0 set red") + + if (self.chassis.get_psu(1).get_status() == True): + if oldpsu1 != 0x1: + # Set PSU1 LED to green + #bus = smbus.SMBus(0) + #DEVICE_ADDRESS = 0x66 + #DEVICEREG = 0x12 + #register = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + #register = register & 0xF3 | 0x08 + #bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, register) + register = self._get_i2c_register(self.psu_frontled_reg) + register = int(register) & 0xF3 | 0x08 + self._set_i2c_register(self.psu_frontled_reg, register) + oldpsu1 = 0x1 + DBG_PRINT(" Front panel LED PSU1 set green") + else: + if oldpsu1 != 0x0: + # Set PSU1 LED to red + #bus = smbus.SMBus(0) + #DEVICE_ADDRESS = 0x66 + #DEVICEREG = 0x12 + #register = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + #register = register & 0xF3 | 0x04 + #bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, register) + register = self._get_i2c_register(self.psu_frontled_reg) + register = int(register) & 0xF3 | 0x04 + self._set_i2c_register(self.psu_frontled_reg, register) + oldpsu1 = 0x0 + DBG_PRINT(" Front panel LED PSU1 set red") + + time.sleep(6) + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + # Strip "Ethernet" off port name + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return -1 + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + return port_idx + + def _port_state_to_mode(self, port_idx, state): + DBG_PRINT("_port_state_to_mode") + + def _port_led_mode_update(self, port_idx, ledMode): + DBG_PRINT("_port_led_mode_update") + + # called when port states change- implementation of port_link_state_change() method if needed + def port_link_state_change(self, portname, state): + # DBG_PRINT("port_link_state_change ") + return diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/psuutil.py b/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/psuutil.py new file mode 100755 index 0000000000..513b3ae408 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/psuutil.py @@ -0,0 +1,32 @@ +try: + import sonic_platform.platform + import sonic_platform.chassis + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + self.chassis = sonic_platform.platform.Platform().get_chassis() + + def get_num_psus(self): + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + # print " psuUtil redirect to PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_psu(index-1).get_status() + else: + return False + + def get_psu_presence(self, index): + # print " psuUtil redirect to PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_psu(index-1).get_presence() + else: + return False diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/sfputil.py b/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/sfputil.py new file mode 100755 index 0000000000..5f2a061f94 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/plugins/sfputil.py @@ -0,0 +1,118 @@ +try: + import glob + import sonic_platform.platform + import sonic_platform.chassis + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + + _port_start = 49 + _port_end = 54 + ports_in_block = 4 + + _port_to_eeprom_mapping = {} + port_to_i2c_mapping = { + 49: 2, + 50: 3, + 51: 4, + 52: 5, + 53: 6, + 54: 7 + } + _changed_ports = [0, 0, 0, 0] + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return list(range(0, 0)) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + # Mux Ordering + mux_dev = sorted(glob.glob("/sys/class/i2c-adapter/i2c-1/i2c-[2-7]")) + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + y = 0 + self.presence = {} + for x in range(self.port_start, self.port_end + 1): + mux_dev_num = mux_dev[y] + self.port_to_i2c_mapping[x] = mux_dev_num[-1] + y = y + 1 + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + self._port_to_eeprom_mapping[x] = port_eeprom_path + self.presence[x] = False; + + SfpUtilBase.__init__(self) + + self.chassis = sonic_platform.platform.Platform().get_chassis() + + def reset(self, port_num): + # print " SfpUtil(SfpUtilBase) re-directed to chassis PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_sfp(port_num).reset() + else: + return False + + def set_low_power_mode(self, port_nuM, lpmode): + # print " SfpUtil(SfpUtilBase) targeted for deprecation " + return False + + def get_low_power_mode(self, port_num): + # print " SfpUtil(SfpUtilBase) targeted for deprecation " + return False + + def get_presence(self, port_num): + # print " SfpUtil(SfpUtilBase) re-directed to chassis PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_sfp(port_num).get_presence() + else: + return False + + def get_transceiver_change_event(self, timeout): + # print " SfpUtil(SfpUtilBase) targeted for deprecation " +# +# raise NotImplementedError +# eyen remove above line and add below. Refer to centec/arm64-centec_e530_48t4x_p-r0/plugins/sfputil.py + + 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 True, {} + + for x in range(self.port_start, self.port_end + 1): + presence = self.get_presence(x) + if presence != self.presence[x]: + self.presence[x] = presence + # index in port_config.ini + if presence: + port_dict[x] = SFP_STATUS_INSERTED + else: + port_dict[x] = SFP_STATUS_REMOVED + + if bool(port_dict): + self.data['last'] = now + self.data['valid'] = 1 + return True, port_dict + else: + time.sleep(0.5) + return True, {} + diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/pmon_daemon_control.json b/device/supermicro/arm64-supermicro_sse_g3748-r0/pmon_daemon_control.json new file mode 100644 index 0000000000..f2a407daaf --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": false +} + diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/sensors.conf b/device/supermicro/arm64-supermicro_sse_g3748-r0/sensors.conf new file mode 100644 index 0000000000..105d3dfff8 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/sensors.conf @@ -0,0 +1,20 @@ +chip "lm75-i2c-*-48" + label temp1 "Board temp sensor 1" + set temp1_max 65 + set temp1_max_hyst 50 + +chip "lm75-i2c-*-49" + label temp1 "Board temp sensor 2" + set temp1_max 65 + set temp1_max_hyst 50 + +chip "7f022004mdiomii00-mdio-*" + label temp1 "Management ethernet port PHY temp" + set temp1_crit 50 + +chip "g3748cpld-i2c-*-66" + label in1 "Power Supply Unit PSU1" + label in2 "Power Supply Unit PSU2" + label fan1 "Fan Module FAN1" + label fan2 "Fan Module FAN2" + diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/soft-reboot_plugin b/device/supermicro/arm64-supermicro_sse_g3748-r0/soft-reboot_plugin new file mode 100755 index 0000000000..1030cb07ba --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/soft-reboot_plugin @@ -0,0 +1,6 @@ +#!/bin/bash + +#echo "Issuing OS-level reboot .." +exec /sbin/reboot -f + + diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-Board-ac5x-G3748.md5 b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-Board-ac5x-G3748.md5 new file mode 100644 index 0000000000..ad85b28162 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-Board-ac5x-G3748.md5 @@ -0,0 +1 @@ +a9434f801bdf89ef55e49be4ae288046 \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-Board-ac5x-G3748.xml b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-Board-ac5x-G3748.xml new file mode 100644 index 0000000000..a7bf814dc9 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-Board-ac5x-G3748.xml @@ -0,0 +1,1607 @@ + + + + + + std-string + string + standard string. + 1 + 100 + + + board-callback-type + enumeration + Specifies os/ext drv callback types. + + linux-static + Linux Static + 0 + + + linux-shared + Linux Shared Lib mode + 1 + + + external + External Os + 3 + + + freeBsd + Free BSD + 4 + + + + board-pp-map-type + enumeration + Specifies pci info types. + + fixed + Fixed + 0 + + + autoscan + Auto scan + 1 + + + + board-pp-interface-channel-type + enumeration + Specifies interface tunnel. + + pci + PCI + 0 + + + smi + SMI + 1 + + + pex + PEX + 3 + + + pex_eagle + PEX EAGLE + 5 + + + pex_falcon_z + PEX FALCON Z + 6 + + + + device-id-type + uint32 + Device ID 0..1023 + 0 + 1023 + + + port-mapping-type + enumeration + Specifies port map type. + + ethernet_mac + ETHERNET_MAC + 0 + + + cpu_sdma + CPU_SDMA + 1 + + + + interface-num-type + uint32 + Interface number + 0 + 1023 + + + txq-port-number-type + uint32 + 0 - 8 queues are configured per port (legacy mode), +1...16 - the number of queues configured per port + SIP 5 : Bobcat2,BobK:0..71 ;Bobcat3: 0..576 ;Aldrin2:0..99 + 0 + 576 + + + phy-smi-interface-type + uint32 + Phy SMI interface type. + 0 + 3 + + + phy-xsmi-interface-type + uint32 + Phy XSMI interface type. + 0 + 15 + + + phy-type + enumeration + Specifies the PHY Part Identifier. + + NA + No Phy + 0 + + + alaska-88E1543 + Specifies PHY identifier 88E1543, used for Combo ports. + 1 + + + alaska-88E1545 + Specifies PHY identifier 88E1545, used for Copper GE with MAC on PHY support. + 2 + + + alaska-88E1680 + Specifies PHY identifier 88E1680, used for Copper with speeds of 10M/100M/1G. + 3 + + + alaska-88E151X + Specifies PHY identifier 88E151X, used for Copper (HW supports combo and fiber). + 4 + + + alaska-88E3140 + Specifies PHY identifier 88E3140, used for Copper with speeds of 100M/1G/10G. Uses with FW SolarFlare next generation. + 5 + + + alaska-88E3240 + Specifies PHY identifier 88E3240, used for Copper with speeds of 100M/1G/10G. Uses with FW, SolarFlare next generation. + 6 + + + alaska-88E3680 + Specifies PHY identifier 88E3680, used for Octal Copper 100M. + 7 + + + alaska-88E3220 + Specifies PHY identifier 88E3220, used for Combo port with speeds of 100M/1G/10G. Uses FW, SolarFlare next generation. + 8 + + + alaska-88E1680L + Specifies PHY identifier 88E1680L, used for Copper with speeds of 10M/100M/1G. + 9 + + + alaska-88E33X0 + Specifies PHY identifier 88E33X0, used for MGIG Combo. + 10 + + + alaska-88E1548 + Specifies PHY identifier 88E1548, used for Fiber GE. + 11 + + + alaska-88E20X0 + Specifies PHY identifier 88E20X0, used for Copper with speeds of 10M/100M/1G/2.5G/5G. + 12 + + + alaska-88E1512 + Specifies PHY identifier 88E1512, used for Copper with speeds of 10M/100M/1G. + 13 + + + alaska-88E2180 + Specifies PHY identifier 88E2180, used for Copper with speeds of 10M/100M/1G/2.5G/5G. + 14 + + + alaska-88E1780 + Specifies PHY identifier 88E1780, Integrated Octal 10/100/1000 Mbps Energy Efficient Ethernet Transceiver + 15 + + + alaska-88E2540 + Specifies PHY identifier 88E2540, 4 ports 10/100/1000/2.5G/5GBASE-T Ethernet Transceiver with IEEE 1588v2 PTP Support + 16 + + + alaska-88E2580 + Specifies PHY identifier 88E12580, Octal 10/100/1000/2.5G/5GBASE-T Ethernet Transceiver with IEEE 1588v2 PTP Support + 17 + + + + physical-port-num-type + uint32 + PHYSICAL PORT NUM + 0 + 1023 + + + led-stream-port-type + enumeration + Specifies the ledstream port type. + + PORT_TYPE_TRI_SPEED + tri-speed port. + 1 + + + PORT_TYPE_XG + XG port. + 2 + + + + led-stream-blink-select-type + enumeration + Specifies the LED stream blink select type. + + BLINK_SELECT_0 + Blink 0 signal. + 1 + + + BLINK_SELECT_1 + Blink 1 signal + 2 + + + + led-stream-order-mode-type + enumeration + Specifies the LED stream ordering mode. + + ORDER_MODE_BY_PORT + the indication order is arranged by port. + 1 + + + ORDER_MODE_BY_CLASS + the indication order is arranged by class. + 2 + + + + led-stream-blink-duty-cycle-type + enumeration + Specifies the LED stream blink cycle duty cycle type. + + BLINK_DUTY_CYCLE_0 + 25% on, 75% off. + 1 + + + BLINK_DUTY_CYCLE_1 + 50% on, 50% off. + 2 + + + BLINK_DUTY_CYCLE_2 + 50% on, 50% off. + 3 + + + BLINK_DUTY_CYCLE_3 + 75% on, 25% off. + 4 + + + + led-stream-blink-duration-type + enumeration + Specifies the LED stream blink period type. + + BLINK_DURATION_0 + BLINK_DURATION_0. + 1 + + + BLINK_DURATION_1 + BLINK_DURATION_1. + 2 + + + BLINK_DURATION_2 + BLINK_DURATION_2. + 3 + + + BLINK_DURATION_3 + BLINK_DURATION_3. + 4 + + + BLINK_DURATION_4 + BLINK_DURATION_4. + 5 + + + BLINK_DURATION_5 + BLINK_DURATION_5. + 6 + + + BLINK_DURATION_6 + (APPLICABLE DEVICES: xCat3; AC5; Lion2; Bobcat2; Caelum; Aldrin; AC3X; Bobcat3; Aldrin2; Pipe) . + 7 + + + BLINK_DURATION_7 + APPLICABLE DEVICES: Bobcat2; Caelum; Aldrin; AC3X; Bobcat3; Aldrin2; Pipe). + 8 + + + + led-stream-pulse-stretch-type + enumeration + Specifies the LED stream length of stretching for dynamic signals. + + PULSE_STRETCH_0_NO + PULSE_STRETCH_0_NO. + 1 + + + PULSE_STRETCH_1 + PULSE_STRETCH_1. + 2 + + + PULSE_STRETCH_2 + PULSE_STRETCH_2. + 3 + + + PULSE_STRETCH_3 + PULSE_STRETCH_3. + 4 + + + PULSE_STRETCH_4 + PULSE_STRETCH_4. + 5 + + + PULSE_STRETCH_5 + PULSE_STRETCH_5. + 6 + + + PULSE_STRETCH_6 + (APPLICABLE DEVICES: Bobcat2; Caelum; Aldrin; AC3X; Bobcat3; Aldrin2; Falcon; AC5P; Pipe). + 7 + + + PULSE_STRETCH_7 + (APPLICABLE DEVICES: Bobcat2; Caelum; Aldrin; AC3X; Bobcat3; Aldrin2; Falcon; AC5P; Pipe). + 8 + + + + led-stream-clock-out-frequency-type + enumeration + Specifies the LED stream blink cycle duty cycle type. + + _CLOCK_OUT_FREQUENCY_500 + 500 KHz LED clock frequency. + 1 + + + CLOCK_OUT_FREQUENCY_1000 + 1 MHz LED clock frequency. + 2 + + + CLOCK_OUT_FREQUENCY_2000 + 2 MHz LED clock frequency. + 3 + + + CLOCK_OUT_FREQUENCY_3000 + 3 MHz LED clock frequency. + 4 + + + + led-stream-class5-select-type + enumeration + Specifies the LED stream indication displayed on class5 (for dual-media port/phy). + + CLASS_5_SELECT_HALF_DUPLEX + Half Duplex is displayed on class5. + 1 + + + CLASS_5_SELECT_FIBER_LINK_UP + If port is a dual media port, Fiber Link Up is displayed on class5. + 2 + + + + led-stream-class13-select-type + enumeration + Specifies the LED stream indication displayed on class13 (for dual-media port/phy). + + CLASS_13_SELECT_LINK_DOWN + Link Down is displayed on class13. + 1 + + + CLASS_13_SELECT_COPPER_LINK_UP + If port is a dual media port, Copper Link Up is displayed on class13. + 2 + + + + led-class-num-type + uint32 + Led Class number + 0 + 11 + + + boolean-type + enumeration + Boolean 32 bits , due to bing endian + + false + False + 0 + + + true + True + 1 + + + + bus-id-type + uint32 + Bus Id Type, PCI/SMI + 0 + 255 + + + function-id-type + uint32 + Function Id Type, PCI/SMI + 0 + 255 + + + domain-type + uint32 + Domain, PCI/SMI + 0 + 255 + + + led-interface-type + uint32 + Led interface + 0 + 255 + + + led-position-type + uint32 + Led position + 0 + 63 + + + serdes-lane-type + uint32 + serdes lane + 0 + 255 + + + cpu-type + enumeration + The CPU Internal/External + + external + Extrenal connected CPU + 0 + + + internal + Internal CPU + 1 + + + + led-stream-clock-frequency-type + uint32 + Led Clock Frequency Sip6 + 500 + 80000 + + + led-unit-type + uint32 + Led units + 1 + 16 + + + led-unit-or-no-unit-type + uint32 + Led units, 0 for no Unit + 0 + 16 + + + led-group-type + uint32 + Led Group + 0 + 1 + + + led-stream-force-data-type + string + A hexadecimal string with octets represented as hex digits +separated by colons. The canonical representation uses +lowercase characters. + 3 + 11 + + + bit-type + uint32 + Bit range 0..31 + 0 + 31 + + + bit-size-type + uint32 + Bit leng 1..32 + 1 + 32 + + + led-sip-type + enumeration + The LED scehme + + na + NA + 0 + + + sip5 + SIP5: AC5, AC3x + 5 + + + sip6 + SIP6: Falcon, AC5x, AC5P + 6 + + + + port-cscd-type + enumeration + Specifies the cascade port type. + + DSA_1_WORD + DSA Regular + 0 + + + DSA_2_WORDS + DSA Extended + 1 + + + NETWORK + Network. + 2 + + + DSA_3_WORDS + DSA 3 Words + 3 + + + DSA_4_WORD + DSA 4 Words + 4 + + + + trunk-cscd-type + uint32 + Specifies the Cascade Trunk id. + 0 + 127 + + + port-trunk-cscd-type + enumeration + Specifies the cascade port type. + + cscdPort + Cascade port + 0 + + + cscdTrunk + Csacde trunk + 1 + + + + hash-cscd-type + enumeration + Specifies the hash used by cascade trunk. + + pkt + Hash based on packet + 0 + + + srcPort + Hash based on source port + 1 + + + + AC5X-RD-G3748 + linux-static + linux-static + autoscan + internal + pex_eagle + + 0 + 0 + ASK-PP-AC5X-G3748.xml + ASK-L1-AC5X-G3748.xml + na + + 0 + + ethernet_mac + 0 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 0 + 0 + + + + + 1 + + ethernet_mac + 1 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 1 + 0 + + + + + 2 + + ethernet_mac + 2 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 2 + 0 + + + + + 3 + + ethernet_mac + 3 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 3 + 0 + + + + + 4 + + ethernet_mac + 4 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 4 + 0 + + + + + 5 + + ethernet_mac + 5 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 5 + 0 + + + + + 6 + + ethernet_mac + 6 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 6 + 0 + + + + + 7 + + ethernet_mac + 7 + 0 + false + + NETWORK + + alaska-88E1780 + 0 + 7 + 0 + + + + + 8 + + ethernet_mac + 8 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 8 + 0 + + + + + 9 + + ethernet_mac + 9 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 9 + 0 + + + + + 10 + + ethernet_mac + 10 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 10 + 0 + + + + + 11 + + ethernet_mac + 11 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 11 + 0 + + + + + 12 + + ethernet_mac + 12 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 12 + 0 + + + + + 13 + + ethernet_mac + 13 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 13 + 0 + + + + + 14 + + ethernet_mac + 14 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 14 + 0 + + + + + 15 + + ethernet_mac + 15 + 0 + false + + NETWORK + + alaska-88E1780 + 1 + 15 + 0 + + + + + 16 + + ethernet_mac + 16 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 16 + 0 + + + + + 17 + + ethernet_mac + 17 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 17 + 0 + + + + + 18 + + ethernet_mac + 18 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 18 + 0 + + + + + 19 + + ethernet_mac + 19 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 19 + 0 + + + + + 20 + + ethernet_mac + 20 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 20 + 0 + + + + + 21 + + ethernet_mac + 21 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 21 + 0 + + + + + 22 + + ethernet_mac + 22 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 22 + 0 + + + + + 23 + + ethernet_mac + 23 + 0 + false + + NETWORK + + alaska-88E1780 + 2 + 23 + 0 + + + + + 24 + + ethernet_mac + 24 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 0 + 1 + + + + + 25 + + ethernet_mac + 25 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 1 + 1 + + + + + 26 + + ethernet_mac + 26 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 2 + 1 + + + + + 27 + + ethernet_mac + 27 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 3 + 1 + + + + + 28 + + ethernet_mac + 28 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 4 + 1 + + + + + 29 + + ethernet_mac + 29 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 5 + 1 + + + + + 30 + + ethernet_mac + 30 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 6 + 1 + + + + + 31 + + ethernet_mac + 31 + 0 + false + + NETWORK + + alaska-88E1780 + 3 + 7 + 1 + + + + + 32 + + ethernet_mac + 32 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 8 + 1 + + + + + 33 + + ethernet_mac + 33 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 9 + 1 + + + + + 34 + + ethernet_mac + 34 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 10 + 1 + + + + + 35 + + ethernet_mac + 35 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 11 + 1 + + + + + 36 + + ethernet_mac + 36 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 12 + 1 + + + + + 37 + + ethernet_mac + 37 + 0 + false + + NETWORK + + alaska-88E1780 + 5 + 13 + 1 + + + + + 38 + + ethernet_mac + 38 + 0 + false + + NETWORK + + alaska-88E1780 + 5 + 14 + 1 + + + + + 39 + + ethernet_mac + 39 + 0 + false + + NETWORK + + alaska-88E1780 + 5 + 15 + 1 + + + + + 40 + + ethernet_mac + 40 + 0 + false + + NETWORK + + alaska-88E1780 + 5 + 16 + 1 + + + + + 41 + + ethernet_mac + 41 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 17 + 1 + + + + + 42 + + ethernet_mac + 42 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 18 + 1 + + + + + 43 + + ethernet_mac + 43 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 19 + 1 + + + + + 44 + + ethernet_mac + 44 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 20 + 1 + + + + + 45 + + ethernet_mac + 45 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 21 + 1 + + + + + 46 + + ethernet_mac + 46 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 22 + 1 + + + + + 47 + + ethernet_mac + 47 + 0 + false + + NETWORK + + alaska-88E1780 + 4 + 23 + 1 + + + + + 48 + + ethernet_mac + 48 + 0 + false + + NETWORK + + NA + + + + + 53 + + ethernet_mac + 53 + 0 + false + + NETWORK + + NA + + + + + 52 + + ethernet_mac + 52 + 0 + false + + NETWORK + + NA + + + + + 51 + + ethernet_mac + 51 + 0 + false + + NETWORK + + NA + + + + + 50 + + ethernet_mac + 50 + 0 + false + + NETWORK + + NA + + + + + 49 + + ethernet_mac + 49 + 0 + false + + NETWORK + + NA + + + + + 63 + + cpu_sdma + 54 + 0 + false + + NETWORK + + + 60 + + cpu_sdma + 55 + 0 + false + + NETWORK + + + . + + 1 + + + \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-L1-AC5X-G3748.md5 b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-L1-AC5X-G3748.md5 new file mode 100644 index 0000000000..0a8f542ec0 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-L1-AC5X-G3748.md5 @@ -0,0 +1 @@ +8e51017346a381613f8660e192883697 \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-L1-AC5X-G3748.xml b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-L1-AC5X-G3748.xml new file mode 100644 index 0000000000..f4622aa75c --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-L1-AC5X-G3748.xml @@ -0,0 +1,1219 @@ + + + + + + interface-mode-type + enumeration + Specifies supported Interface modes + + 1000BASE_X + 1G + 6 + + + SGMII + 1G , 2.5G + 3 + + + QSGMII + 1G + 13 + + + KR + 10G, 12G, 20G, 40G, 100G + 16 + + + SR_LR + 5G, 10G, 12G, 20G, 40G + 20 + + + KR2 + + 27 + + + KR4 + + 28 + + + SR_LR2 + + 29 + + + SR_LR4 + 100G + 30 + + + KR_C + CONSORTIUM - 25G + 32 + + + CR_C + CONSORTIUM - 25G + 33 + + + KR2_C + CONSORTIUM - 50G + 34 + + + CR2_C + CONSORTIUM - 50G + 35 + + + CR + + 36 + + + CR2 + + 37 + + + CR4 + + 38 + + + KR_S + + 39 + + + CR_S + + 40 + + + KR8 + + 41 + + + CR8 + + 42 + + + SR_LR8 + + 43 + + + USX_10G_QXGMII + + 51 + + + USX_20G_QXGMII + + 52 + + + USX_OUSGMII + + 53 + + + USX_20G_OXGMII + + 54 + + + NA + + 57 + + + + port-speed-type + enumeration + Specifies supported speeds + + 1G + 1G + 2 + + + 10G + 10G + 3 + + + 2500M + 2.5G + 5 + + + 5G + 5G + 6 + + + 25G + 25G, used in combination with CPSS_PORT_INTERFACE_MODE_KR_E, CPSS_PORT_INTERFACE_MODE_KR2_E + 21 + + + 40G + 40G + 9 + + + 50G + 50G + 14 + + + 100G + 100G + 13 + + + 200G + 200G + 24 + + + 400G + 400G + 25 + + + NA + NA + 35 + + + + fec-type + enumeration + Rx parameter type + + enabled + Enabled + 0 + + + disabled + Disabled + 1 + + + rs_enabled + RS FEC enabled + 2 + + + both_enabled + Both enabled + 3 + + + rs_544_514_enabled + RS FEC 544 and 514 + 4 + + + + physical-port-num-type + uint32 + PHYSICAL PORT NUM + 0 + 1023 + + + tx-param-type + enumeration + Tx parameter type + + atten + atten + 0 + + + post + post + 1 + + + pre + pre + 2 + + + pre2 + pre2 + 3 + + + pre3 + pre3 + 4 + + + peak + peak + 5 + + + main + main + 6 + + + txAmpAdjEn + txAmpAdjEn + 7 + + + emph0 + emph0 + 8 + + + emph1 + emph1 + 9 + + + txAmpShft + txAmpShft + 10 + + + txEmphEn + txEmphEn + 11 + + + txEmphEn1 + txEmphEn1 + 12 + + + txAmpAdj + txAmpAdj + 13 + + + slewCtrlEn + slewCtrlEn + 14 + + + slewRate + slewRate + 15 + + + + rx-param-type + enumeration + Rx parameter type + + sqlch + sqlch + 0 + + + DC + DC + 1 + + + LF + LF + 2 + + + HF + HF + 3 + + + gainShape1 + gainShape1 + 4 + + + gainShape2 + gainShape2 + 5 + + + shortChannelEn + shortChannelEn + 7 + + + bfLf + bfLf + 8 + + + bfHf + bfHf + 9 + + + minLf + minLf + 10 + + + maxLf + maxLf + 11 + + + minHf + minHf + 12 + + + maxHf + maxHf + 13 + + + minPre1 + minPre1 + 14 + + + maxPre1 + maxPre1 + 15 + + + minPre2 + minPre2 + 16 + + + maxPre2 + + 17 + + + minPost + minPost + 18 + + + maxPost + maxPost + 19 + + + squelch + squelch + 20 + + + termination + termination + 27 + + + coldEnvelope + coldEnvelope + 35 + + + hotEnvelope + hotEnvelope + 36 + + + dcGain + dcGain + 37 + + + bandWidth + bandWidth + 38 + + + dfe + dfe + 39 + + + ffeR + ffeR + 40 + + + ffeC + ffeC + 41 + + + sampler + sampler + 42 + + + align90 + align90 + 43 + + + ffeS + ffeS + 44 + + + resSel + resSel + 45 + + + resShift + resShift + 46 + + + capSel + capSel + 47 + + + ffeSettingForce + ffeSettingForce + 48 + + + adaptedResSel + adaptedResSel + 49 + + + adaptedCapSel + adaptedCapSel + 50 + + + selmufi + selmufi + 51 + + + selmuff + selmuff + 52 + + + selmupi + selmupi + 53 + + + selmupf + selmupf + 54 + + + slewRateCtrl0 + slewRateCtrl0 + 55 + + + slewRateCtrl1 + slewRateCtrl1 + 56 + + + EO + EO + 57 + + + dataRate + dataRate + 58 + + + res1Sel + res1Sel + 59 + + + res2Sel + res2Sel + 60 + + + cap1Sel + cap1Sel + 61 + + + cap2Sel + cap2Sel + 62 + + + midpointLargeThresKLane + midpointLargeThresKLane + 63 + + + midpointSmallThresKLane + midpointSmallThresKLane + 64 + + + midpointLargeThresCLane + midpointLargeThresCLane + 65 + + + midpointSmallThresCLane + midpointSmallThresCLane + 66 + + + dfeResF0aHighThresInitLane + dfeResF0aHighThresInitLane + 67 + + + dfeResF0aHighThresEndLane + dfeResF0aHighThresEndLane + 68 + + + current1Sel + current1Sel + 69 + + + rl1Sel + rl1Sel + 70 + + + rl1Extra + rl1Extra + 71 + + + cl1Ctrl + cl1Ctrl + 72 + + + enMidFreq + enMidFreq + 73 + + + cs1Mid + cs1Mid + 74 + + + rs1Mid + rs1Mid + 75 + + + rfCtrl + rfCtrl + 76 + + + rl1TiaSel + rl1TiaSel + 77 + + + rl1TiaExtra + rl1TiaExtra + 78 + + + hpfRSel1st + hpfRSel1st + 79 + + + current1TiaSel + current1TiaSel + 80 + + + rl2Tune + rl2Tune + 81 + + + rl2Sel + rl2Sel + 82 + + + rs2Sel + rs2Sel + 83 + + + current2Sel + current2Sel + 84 + + + hpfRsel2nd + hpfRsel2nd + 85 + + + BW + BW + 86 + + + dfeGAIN + dfeGAIN + 87 + + + dfeGAIN2 + dfeGAIN2 + 88 + + + pre1 + pre1 + 89 + + + pre2 + pre2 + 90 + + + post1 + post1 + 91 + + + + boolean-type + enumeration + Boolean 32 bits , due to bing endian + + false + False + 0 + + + true + True + 1 + + + + serdes-type + enumeration + Serdes Type + + NA + No serdes + 0 + + + AVAGO + AVAGO + 1 + + + COMPHY + COMPHY + 2 + + + COMPHY_C12G + COMPHY_C12G + 3 + + + COMPHY_C28G + COMPHY_C28G + 4 + + + COMPHY_C112G + COMPHY_C112G + 5 + + + + uint8-type + uint32 + Uint8 32 bits , due to bing endian + 0 + 255 + + + serdes-termination-type + enumeration + RX termination mode + + GND + Enabled + 0 + + + VDD + Disabled + 1 + + + FLOATING + RS FEC enabled + 2 + + + + port-interconnect-profile-type + enumeration + Enumerator of interconnect profile. + + profile_default + Profile Default + 0 + + + profile_1 + Profile 1 + 1 + + + profile_2 + Profile 2 + 2 + + + + + + 1000MR1 + + USX_OUSGMII + 1G + disabled + + + USX_OUSGMII + 1G + disabled + disabled + + + + 2500MR1 + + USX_20G_OXGMII + 2500M + rs_enabled + + + USX_20G_OXGMII + 1G + rs_enabled + + + USX_20G_OXGMII + 2500M + rs_enabled + rs_enabled + + + USX_20G_OXGMII + 1G + rs_enabled + rs_enabled + + + + 25GR1 + + CR + 25G + rs_enabled + + + KR + 25G + rs_enabled + + + KR + 10G + disabled + + + CR + 25G + rs_enabled + rs_enabled + + + KR + 25G + rs_enabled + rs_enabled + + + KR + 10G + disabled + disabled + + + + + + 0 + AVAGO + profile_default + 1000MR1 + + + 1 + AVAGO + profile_default + 1000MR1 + + + 2 + AVAGO + profile_default + 1000MR1 + + + 3 + AVAGO + profile_default + 1000MR1 + + + 4 + AVAGO + profile_default + 1000MR1 + + + 5 + AVAGO + profile_default + 1000MR1 + + + 6 + AVAGO + profile_default + 1000MR1 + + + 7 + AVAGO + profile_default + 1000MR1 + + + 8 + AVAGO + profile_default + 1000MR1 + + + 9 + AVAGO + profile_default + 1000MR1 + + + 10 + AVAGO + profile_default + 1000MR1 + + + 11 + AVAGO + profile_default + 1000MR1 + + + 12 + AVAGO + profile_default + 1000MR1 + + + 13 + AVAGO + profile_default + 1000MR1 + + + 14 + AVAGO + profile_default + 1000MR1 + + + 15 + AVAGO + profile_default + 1000MR1 + + + 16 + AVAGO + profile_default + 1000MR1 + + + 17 + AVAGO + profile_default + 1000MR1 + + + 18 + AVAGO + profile_default + 1000MR1 + + + 19 + AVAGO + profile_default + 1000MR1 + + + 20 + AVAGO + profile_default + 1000MR1 + + + 21 + AVAGO + profile_default + 1000MR1 + + + 22 + AVAGO + profile_default + 1000MR1 + + + 23 + AVAGO + profile_default + 1000MR1 + + + 24 + AVAGO + profile_default + 1000MR1 + + + 25 + AVAGO + profile_default + 1000MR1 + + + 26 + AVAGO + profile_default + 1000MR1 + + + 27 + AVAGO + profile_default + 1000MR1 + + + 28 + AVAGO + profile_default + 1000MR1 + + + 29 + AVAGO + profile_default + 1000MR1 + + + 30 + AVAGO + profile_default + 1000MR1 + + + 31 + AVAGO + profile_default + 1000MR1 + + + 32 + AVAGO + profile_default + 1000MR1 + + + 33 + AVAGO + profile_default + 1000MR1 + + + 34 + AVAGO + profile_default + 1000MR1 + + + 35 + AVAGO + profile_default + 1000MR1 + + + 36 + AVAGO + profile_default + 1000MR1 + + + 37 + AVAGO + profile_default + 1000MR1 + + + 38 + AVAGO + profile_default + 1000MR1 + + + 39 + AVAGO + profile_default + 1000MR1 + + + 40 + AVAGO + profile_default + 1000MR1 + + + 41 + AVAGO + profile_default + 1000MR1 + + + 42 + AVAGO + profile_default + 1000MR1 + + + 43 + AVAGO + profile_default + 1000MR1 + + + 44 + AVAGO + profile_default + 1000MR1 + + + 45 + AVAGO + profile_default + 1000MR1 + + + 46 + AVAGO + profile_default + 1000MR1 + + + 47 + AVAGO + profile_default + 1000MR1 + + + 48 + AVAGO + profile_default + 25GR1 + + + 49 + AVAGO + profile_default + 25GR1 + + + 50 + AVAGO + profile_default + 25GR1 + + + 51 + AVAGO + profile_default + 25GR1 + + + 52 + AVAGO + profile_default + 25GR1 + + + 53 + AVAGO + profile_default + 25GR1 + + + + \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-PP-AC5X-G3748.md5 b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-PP-AC5X-G3748.md5 new file mode 100644 index 0000000000..18f55a9315 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-PP-AC5X-G3748.md5 @@ -0,0 +1 @@ +330bea15c5dc5dcc0bdabd95940b6bab \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-PP-AC5X-G3748.xml b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-PP-AC5X-G3748.xml new file mode 100644 index 0000000000..6944bbcb42 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ASK-PP-AC5X-G3748.xml @@ -0,0 +1,891 @@ + + + + + + std-string + string + standard string. + 1 + 100 + + + queue-id-type + uint32 + Queue id + 0 + 7 + + + precent-type + uint32 + Precent + 0 + 100 + + + phaThreadId-type + uint32 + Thread id + 1 + 255 + + + routing-mode-type + enumeration + Specifies routing mode. + + POLICY_BASED_ROUTING_ONLY + PBR only + 0 + + + TCAM_ROUTER_BASED + Router engine or PBR + 1 + + + + shared-table-mode-type + enumeration + Specifies table sharing modes. + + MAX_L3_MIN_L2_NO_EM + MAX_L3_MIN_L2_NO_EM + 0 + + + MIN_L3_MAX_L2_NO_EM + MIN_L3_MAX_L2_NO_EM + 1 + + + MID_L3_MID_L2_MIN_EM + MID_L3_MID_L2_MIN_EM + 2 + + + MID_L3_MIN_L2_MAX_EM + MID_L3_MIN_L2_MAX_EM + 3 + + + MID_LOW_L3_MID_LOW_L2_MAX_EM + MID_LOW_L3_MID_LOW_L2_MAX_EM + 4 + + + MID_L3_MID_L2_NO_EM + MID_L3_MID_L2_NO_EM + 5 + + + MID_LOW_L3_MID_L2_MID_EM + MID_LOW_L3_MID_L2_MID_EM + 6 + + + MID_L3_MID_LOW_L2_MID_EM_MAX_ARP + MID_L3_MID_LOW_L2_MID_EM_MAX_ARP + 7 + + + + pha-firmware-image-id-type + enumeration + Specifies supported Pha image id + + DEFAULT + Default PHA firmware image ID + 0 + + + 01 + 01 firmware image ID + 1 + + + 02 + 02 PHA firmware image ID + 2 + + + + pha-firmware-thread-type + enumeration + Specifies supported Pha thread type + + IOAM_INGRESS_SWITCH_IPV4 + IOAM_INGRESS_SWITCH_IPV4 + 1 + + + IOAM_INGRESS_SWITCH_IPV6 + IOAM_INGRESS_SWITCH_IPV6 + 2 + + + IOAM_TRANSIT_SWITCH_IPV4 + IOAM_TRANSIT_SWITCH_IPV4 + 3 + + + IOAM_TRANSIT_SWITCH_IPV6 + IOAM_TRANSIT_SWITCH_IPV6 + 4 + + + INT_IOAM_MIRRORING + INT_IOAM_MIRRORING + 5 + + + INT_IOAM_EGRESS_SWITCH + INT_IOAM_EGRESS_SWITCH + 6 + + + MPLS_SR_NO_EL + MPLS_SR_NO_EL + 7 + + + MPLS_SR_ONE_EL + MPLS_SR_ONE_EL + 8 + + + MPLS_SR_TWO_EL + MPLS_SR_TWO_EL + 9 + + + MPLS_SR_THREE_EL + MPLS_SR_THREE_EL + 10 + + + UNIFIED_SR + UNIFIED_SR + 11 + + + CLASSIFIER_NSH_OVER_ETHERNET + CLASSIFIER_NSH_OVER_ETHERNET + 12 + + + CLASSIFIER_NSH_OVER_VXLAN_GPE + CLASSIFIER_NSH_OVER_VXLAN_GPE + 13 + + + SFF_NSH_VXLAN_GPE_TO_ETHERNET + SFF_NSH_VXLAN_GPE_TO_ETHERNET + 14 + + + SFF_NSH_ETHERNET_TO_VXLAN_GPE + SFF_NSH_ETHERNET_TO_VXLAN_GPE + 15 + + + IOAM_EGRESS_SWITCH_IPV6 + IOAM_EGRESS_SWITCH_IPV6 + 16 + + + SRV6_END_NODE + SRV6_END_NODE + 17 + + + SRV6_PENULTIMATE_END_NODE + SRV6_PENULTIMATE_END_NODE + 18 + + + SRV6_SRC_NODE_1_SEGMENT + SRV6_SRC_NODE_1_SEGMENT + 19 + + + SRV6_SRC_NODE_FIRST_PASS_2_3_SEGMENTS + SRV6_SRC_NODE_FIRST_PASS_2_3_SEGMENTS + 20 + + + SRV6_SRC_NODE_SECOND_PASS_3_SEGMENTS + SRV6_SRC_NODE_SECOND_PASS_3_SEGMENTS + 21 + + + SRV6_SRC_NODE_SECOND_PASS_2_SEGMENTS + SRV6_SRC_NODE_SECOND_PASS_2_SEGMENTS + 22 + + + SGT_NETWORK_ADD_MSB + SGT_NETWORK_ADD_MSB + 23 + + + SGT_NETWORK_FIX + SGT_NETWORK_FIX + 24 + + + SGT_NETWORK_REMOVE + SGT_NETWORK_REMOVE + 25 + + + SGT_EDSA_FIX + SGT_EDSA_FIX + 26 + + + SGT_EDSA_REMOVE + SGT_EDSA_REMOVE + 27 + + + SGT_GBP_FIX_IPV4 + SGT_GBP_FIX_IPV4 + 28 + + + SGT_GBP_FIX_IPV6 + SGT_GBP_FIX_IPV6 + 29 + + + SGT_GBP_REMOVE_IPV4 + SGT_GBP_REMOVE_IPV4 + 30 + + + SGT_GBP_REMOVE_IPV6 + SGT_GBP_REMOVE_IPV6 + 31 + + + PTP_PHY_1_STEP + PTP_PHY_1_STEP + 32 + + + EGRESS_MIRRORING_METADATA + EGRESS_MIRRORING_METADATA + 33 + + + CC_ERSPAN_TYPE_II_TRG_DEV_LC_IPV4 + CC_ERSPAN_TYPE_II_TRG_DEV_LC_IPV4 + 34 + + + CC_ERSPAN_TYPE_II_TRG_DEV_LC_IPV6 + CC_ERSPAN_TYPE_II_TRG_DEV_LC_IPV6 + 35 + + + CC_ERSPAN_TYPE_II_TRG_DEV_DIRECT_IPV4 + CC_ERSPAN_TYPE_II_TRG_DEV_DIRECT_IPV4 + 36 + + + CC_ERSPAN_TYPE_II_TRG_DEV_DIRECT_IPV6 + CC_ERSPAN_TYPE_II_TRG_DEV_DIRECT_IPV6 + 37 + + + CC_ERSPAN_TYPE_II_SRC_DEV + CC_ERSPAN_TYPE_II_SRC_DEV + 38 + + + VXLAN_GBP_SOURCE_GROUP_POLICY_ID + VXLAN_GBP_SOURCE_GROUP_POLICY_ID + 39 + + + SRV6_BEST_EFFORT + SRV6_BEST_EFFORT + 40 + + + SRV6_SRC_NODE_1_CONTAINER + SRV6_SRC_NODE_1_CONTAINER + 41 + + + SRV6_SRC_NODE_FIRST_PASS_2_3_CONTAINERS + SRV6_SRC_NODE_FIRST_PASS_2_3_CONTAINERS + 42 + + + SRV6_SRC_NODE_SECOND_PASS_2_CONTAINERS + SRV6_SRC_NODE_SECOND_PASS_2_CONTAINERS + 43 + + + SRV6_SRC_NODE_SECOND_PASS_3_CONTAINERS + SRV6_SRC_NODE_SECOND_PASS_3_CONTAINERS + 44 + + + SRV6_END_NODE_COC32_GSID + SRV6_END_NODE_COC32_GSID + 45 + + + IPV4_TTL_INCREMENT + IPV4_TTL_INCREMENT + 46 + + + IPV6_HOP_LIMIT_INCREMENT + IPV6_HOP_LIMIT_INCREMENT + 47 + + + CLEAR_OUTGOING_MTAG_COMMAND + CLEAR_OUTGOING_MTAG_COMMAND + 48 + + + SFLOW_V5_IPV4 + SFLOW_V5_IPV4 + 49 + + + SFLOW_V5_IPV6 + SFLOW_V5_IPV6 + 50 + + + SLS + SLS + 51 + + + + trunk-member-mode-type + enumeration + Specifies supported Pha image id + + NATIVE + NATIVE + * the trunk members are filled + * according to the order given by application. + * Regular trunk may hold max of 8 members. + * Cascade trunk may hold : + * max of 64 members + 0 + + + FLEX + FLEX + * A mode to allows flexibility for + * each Regular trunk to state it's max number of members (before starting to add members). + * (this mode not effect 'cascade trunk' members) + * Regular trunk may hold : max of 4K members. (each trunk set it's own limit) + * Cascade trunk may hold : max of 64 members. + 2 + + + + number-physical-port-type + enumeration + ac5x 128, falcon 64,128,256, 512, 1024 + + no-ports + no-ports + 0 + + + 64-ports + 64-ports + 64 + + + 128-ports + 128-ports + 128 + + + 256-ports + 256-ports + 256 + + + 512-ports + 512-ports + 512 + + + 1024-ports + 1024-ports + 1024 + + + + serdes-ref-clock-type + enumeration + Specifies serdes refernce clock. + + external_25_single_ended + EXTERNAL_25_SINGLE_ENDED + 0 + + + external_125_single_ended + EXTERNAL_125_SINGLE_ENDED + 1 + + + external_125_diff + EXTERNAL_125_DIFF + 2 + + + external_156_25_single_ended + EXTERNAL_156_25_SINGLE_ENDED + 3 + + + external_156_25_diff + EXTERNAL_156_25_DIFF + 4 + + + internal_125 + INTERNAL_125 + 5 + + + + cpu-port-id-type + uint32 + CPU port id + 0 + 7 + + + rx-buffer-size-type + uint32 + Rx Buffer size + 64 + 10240 + + + tx-sdma-queue-mode-type + enumeration + Specifies TX queue mode. + + Normal + Application + 0 + + + Packet_Generator + Traffic generator + 1 + + + + alloc-method-type + enumeration + Specifies Buffers allocation method. + + Dynamic_Alloc + Dynamic + 0 + + + Static_Alloc + Static + 1 + + + + au_mesage_lenght-type + enumeration + Specifies Buffers allocation method. + + 4_words + 4 Words + 0 + + + 8_words + 8 Words + 1 + + + + boolean-type + enumeration + Boolean 32 bits , due to bing endian + + false + False + 0 + + + true + True + 1 + + + + + AC5X-RD + + 4294967295 + external_25_single_ended + 2 + 60 + 128-ports + false + false + 0 + + + true + + 4096 + + + 2048 + + + + 0 + 0 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 7 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 6 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 5 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 4 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 3 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 2 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 1 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 1 + 0 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 7 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 6 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 5 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 4 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 3 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 2 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 1 + Static_Alloc + 20 + 20 + 2048 + 0 + + + 0 + 0 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 1 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 2 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 3 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 4 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 5 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 6 + Static_Alloc + Normal + 20 + 0 + 128 + + + 0 + 7 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 0 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 1 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 2 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 3 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 4 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 5 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 6 + Static_Alloc + Normal + 20 + 0 + 128 + + + 1 + 7 + Static_Alloc + Normal + 20 + 0 + 128 + + + + false + false + false + 0 + 8_words + false + + + + TCAM_ROUTER_BASED + 0 + MID_L3_MID_L2_NO_EM + true + + + true + true + true + true + true + true + + 511 + FLEX + + true + true + true + true + + false + 01 + 0 + + + + + \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/SAI-AC5X-G3748.md5 b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/SAI-AC5X-G3748.md5 new file mode 100644 index 0000000000..6cdba7a1b7 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/SAI-AC5X-G3748.md5 @@ -0,0 +1 @@ +3ac4dbcd6e23c747318b7e7c27e08a02 \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/SAI-AC5X-G3748.xml b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/SAI-AC5X-G3748.xml new file mode 100644 index 0000000000..bb2f800047 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/SAI-AC5X-G3748.xml @@ -0,0 +1,315 @@ + + + + + + device-id-type + uint32 + Device ID 0..1023 + 0 + 1023 + + + port-id-type + uint32 + Interface number + 0 + 1023 + + + ASK-Board-ac5x-G3748.xml + + false + + + + 0 + 0 + 0 + + + 1 + 0 + 1 + + + 2 + 0 + 2 + + + 3 + 0 + 3 + + + 4 + 0 + 4 + + + 5 + 0 + 5 + + + 6 + 0 + 6 + + + 7 + 0 + 7 + + + 8 + 0 + 8 + + + 9 + 0 + 9 + + + 10 + 0 + 10 + + + 11 + 0 + 11 + + + 12 + 0 + 12 + + + 13 + 0 + 13 + + + 14 + 0 + 14 + + + 15 + 0 + 15 + + + 16 + 0 + 16 + + + 17 + 0 + 17 + + + 18 + 0 + 18 + + + 19 + 0 + 19 + + + 20 + 0 + 20 + + + 21 + 0 + 21 + + + 22 + 0 + 22 + + + 23 + 0 + 23 + + + 24 + 0 + 24 + + + 25 + 0 + 25 + + + 26 + 0 + 26 + + + 27 + 0 + 27 + + + 28 + 0 + 28 + + + 29 + 0 + 29 + + + 30 + 0 + 30 + + + 31 + 0 + 31 + + + 32 + 0 + 32 + + + 33 + 0 + 33 + + + 34 + 0 + 34 + + + 35 + 0 + 35 + + + 36 + 0 + 36 + + + 37 + 0 + 37 + + + 38 + 0 + 38 + + + 39 + 0 + 39 + + + 40 + 0 + 40 + + + 41 + 0 + 41 + + + 42 + 0 + 42 + + + 43 + 0 + 43 + + + 44 + 0 + 44 + + + 45 + 0 + 45 + + + 46 + 0 + 46 + + + 47 + 0 + 47 + + + 48 + 0 + 48 + + + 49 + 0 + 49 + + + 50 + 0 + 50 + + + 51 + 0 + 51 + + + 52 + 0 + 52 + + + 53 + 0 + 53 + + + + 8 + 0 + 0 + 64 + 8 + 8 + 1024 + 0 + + + + 0 + + + 2048 + + + + \ No newline at end of file diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/hwsku.json b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/hwsku.json new file mode 100644 index 0000000000..362f53a7c1 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/hwsku.json @@ -0,0 +1,214 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet1": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet2": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet3": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet4": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet5": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet6": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet7": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet8": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet9": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet10": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet11": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet12": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet13": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet14": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet15": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet16": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet17": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet18": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet19": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet20": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet21": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet22": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet23": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet24": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet25": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet26": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet27": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet28": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet29": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet30": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet31": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet32": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet33": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet34": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet35": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet36": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet37": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet38": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet39": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet40": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet41": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet42": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet43": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet44": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet45": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet46": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet47": { + "default_brkout_mode": "1x1000[100,10]", + "port_type": "RJ45" + }, + "Ethernet48": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet49": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet50": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet51": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet53": { + "default_brkout_mode": "1x25G[10G]" + } + } +} diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/platform.ini b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/platform.ini new file mode 100644 index 0000000000..782144317a --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/platform.ini @@ -0,0 +1 @@ +# Port lane speed DC BW HF LF sqlch minLf maxLf minHf maxHf diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/port_config.ini b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/port_config.ini new file mode 100644 index 0000000000..003307d32f --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias speed autoneg fec index +Ethernet0 0 Gi0/1 1000 on none 1 +Ethernet1 1 Gi0/2 1000 on none 2 +Ethernet2 2 Gi0/3 1000 on none 3 +Ethernet3 3 Gi0/4 1000 on none 4 +Ethernet4 4 Gi0/5 1000 on none 5 +Ethernet5 5 Gi0/6 1000 on none 6 +Ethernet6 6 Gi0/7 1000 on none 7 +Ethernet7 7 Gi0/8 1000 on none 8 +Ethernet8 8 Gi0/9 1000 on none 9 +Ethernet9 9 Gi0/10 1000 on none 10 +Ethernet10 10 Gi0/11 1000 on none 11 +Ethernet11 11 Gi0/12 1000 on none 12 +Ethernet12 12 Gi0/13 1000 on none 13 +Ethernet13 13 Gi0/14 1000 on none 14 +Ethernet14 14 Gi0/15 1000 on none 15 +Ethernet15 15 Gi0/16 1000 on none 16 +Ethernet16 16 Gi0/17 1000 on none 17 +Ethernet17 17 Gi0/18 1000 on none 18 +Ethernet18 18 Gi0/19 1000 on none 19 +Ethernet19 19 Gi0/20 1000 on none 20 +Ethernet20 20 Gi0/21 1000 on none 21 +Ethernet21 21 Gi0/22 1000 on none 22 +Ethernet22 22 Gi0/23 1000 on none 23 +Ethernet23 23 Gi0/24 1000 on none 24 +Ethernet24 24 Gi0/25 1000 on none 25 +Ethernet25 25 Gi0/26 1000 on none 26 +Ethernet26 26 Gi0/27 1000 on none 27 +Ethernet27 27 Gi0/28 1000 on none 28 +Ethernet28 28 Gi0/29 1000 on none 29 +Ethernet29 29 Gi0/30 1000 on none 30 +Ethernet30 30 Gi0/31 1000 on none 31 +Ethernet31 31 Gi0/32 1000 on none 32 +Ethernet32 32 Gi0/33 1000 on none 33 +Ethernet33 33 Gi0/34 1000 on none 34 +Ethernet34 34 Gi0/35 1000 on none 35 +Ethernet35 35 Gi0/36 1000 on none 36 +Ethernet36 36 Gi0/37 1000 on none 37 +Ethernet37 37 Gi0/38 1000 on none 38 +Ethernet38 38 Gi0/39 1000 on none 39 +Ethernet39 39 Gi0/40 1000 on none 40 +Ethernet40 40 Gi0/41 1000 on none 41 +Ethernet41 41 Gi0/42 1000 on none 42 +Ethernet42 42 Gi0/43 1000 on none 43 +Ethernet43 43 Gi0/44 1000 on none 44 +Ethernet44 44 Gi0/45 1000 on none 45 +Ethernet45 45 Gi0/46 1000 on none 46 +Ethernet46 46 Gi0/47 1000 on none 47 +Ethernet47 47 Gi0/48 1000 on none 48 +Ethernet48 48 Fx0/1 25000 on rs 49 +Ethernet49 49 Fx0/2 25000 on rs 50 +Ethernet50 50 Fx0/3 25000 on rs 51 +Ethernet51 51 Fx0/4 25000 on rs 52 +Ethernet52 52 Fx0/5 25000 on rs 53 +Ethernet53 53 Fx0/6 25000 on rs 54 diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/profile.ini b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/profile.ini new file mode 100644 index 0000000000..16600d34e6 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/profile.ini @@ -0,0 +1,7 @@ +switchMacAddress=00:01:02:03:04:05 +portListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 016:1 017:1 018:1 019:1 020:1 021:1 022:1 023:1 024:1 025:1 026:1 027:1 028:1 029:1 030:1 031:1 032:1 033:1 034:1 035:1 036:1 037:1 038:1 039:1 040:1 041:1 042:1 043:1 044:1 045:1 046:1 047:1 048:1 049:1 050:1 051:1 052:1 053:1 +platformConfigFile=/usr/share/sonic/hwsku/platform.ini +lpm_fdb_em_profile=MID_L3_MID_L2_NO_EM +l3_counter_index_base=0 2K +pbrMaxEntries=0 +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/sai.profile b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/sai.profile new file mode 100644 index 0000000000..2f3febd68e --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/sai.profile @@ -0,0 +1,4 @@ +mode=1 +hwId=AC5XG3748 +switchProfile=/usr/share/sonic/hwsku/SAI-AC5X-G3748.xml +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/system_health_monitoring_config.json b/device/supermicro/arm64-supermicro_sse_g3748-r0/system_health_monitoring_config.json new file mode 100644 index 0000000000..d5f3a7b983 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/system_health_monitoring_config.json @@ -0,0 +1,14 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [ + "asic", + "psu.temperature" + ], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "amber", + "normal": "green", + "booting": "blinking green" + } +} diff --git a/device/supermicro/arm64-supermicro_sse_g3748-r0/thermal_policy.json b/device/supermicro/arm64-supermicro_sse_g3748-r0/thermal_policy.json new file mode 100644 index 0000000000..7757303c54 --- /dev/null +++ b/device/supermicro/arm64-supermicro_sse_g3748-r0/thermal_policy.json @@ -0,0 +1,65 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "false", + "fan_speed_when_suspend": "50" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "thermal_info" + }, + { + "type": "chassis_info" + } + ], + "policies": [ + { + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "all fan presence", + "conditions": [ + { + "type": "fan.all.presence" + } + ], + "actions": [ + { + "type": "thermal.temp_check_and_set_all_fan_speed", + "default_speed": "25", + "hightemp_speed": "100" + } + ] + }, + { + "name": "temp over high critical threshold", + "conditions": [ + { + "type": "thermal.over.high_critical_threshold" + } + ], + "actions": [ + { + "type": "switch.shutdown" + } + ] + } + ] +} diff --git a/platform/marvell-arm64/one-image.mk b/platform/marvell-arm64/one-image.mk index 1aa36f2b1d..41aa274c86 100644 --- a/platform/marvell-arm64/one-image.mk +++ b/platform/marvell-arm64/one-image.mk @@ -7,7 +7,8 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_INSTALLS += $(MRVL_PRESTERA_DEB) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(NOKIA_7215_PLATFORM) \ $(AC5X_RD98DX35xx_PLATFORM) \ - $(AC5X_RD98DX35xxCN9131_PLATFORM) + $(AC5X_RD98DX35xxCN9131_PLATFORM) \ + $(SUPERMICRO_SSE_G3748_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/marvell-arm64/platform-modules-supermicro.mk b/platform/marvell-arm64/platform-modules-supermicro.mk new file mode 100644 index 0000000000..874a1129bc --- /dev/null +++ b/platform/marvell-arm64/platform-modules-supermicro.mk @@ -0,0 +1,12 @@ +# Supermicro SSE-G3748 (using AC5X) Platform modules + +SUPERMICRO_SSE_G3748_PLATFORM_MODULE_VERSION=1.0 + +export SUPERMICRO_SSE_G3748_PLATFORM_MODULE_VERSION + +SUPERMICRO_SSE_G3748_PLATFORM_MODULE = sonic-platform-supermicro-sse-g3748_$(SUPERMICRO_SSE_G3748_PLATFORM_MODULE_VERSION)_$(CONFIGURED_ARCH).deb +$(SUPERMICRO_SSE_G3748_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-supermicro +$(SUPERMICRO_SSE_G3748_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(SUPERMICRO_SSE_G3748_PLATFORM_MODULE)_PLATFORM = arm64-supermicro_sse_g3748-r0 +SONIC_DPKG_DEBS += $(SUPERMICRO_SSE_G3748_PLATFORM_MODULE) + diff --git a/platform/marvell-arm64/platform.conf b/platform/marvell-arm64/platform.conf index a11314acf8..96c85f94f6 100644 --- a/platform/marvell-arm64/platform.conf +++ b/platform/marvell-arm64/platform.conf @@ -40,6 +40,9 @@ case $PLATFORM in arm64-marvell_rd98DX35xx_cn9131-r0) PLATFORM_CN9131=1; fdt_fname="/boot/cn9131-db-comexpress.dtb"; fit_conf_name="#conf_cn9131";; + arm64-supermicro_sse_g3748-r0) PLATFORM_AC5X=2; + fdt_fname="/usr/lib/linux-image-${kernel_version}/marvell/smc_sse-g3748.dtb"; + fit_conf_name="#conf_smc_sse-g3748";; esac if [ $PLATFORM_AC5X -eq 1 ]; then @@ -57,6 +60,39 @@ elif [ $PLATFORM_CN9131 -eq 1 ]; then demo_part=2 FW_ENV_DEFAULT='/dev/mtd1 0x1F0000 0x10000 0x10000' mmc_bus="mmc0:0001" +lif [ $PLATFORM_AC5X -eq 2 ]; then + fdt_addr=0x201000000 + fit_addr=0x210000000 + initrd_addr=0x206000000 + + #--------------------------------------------------------------- + # device name offset Env size sector size + # ----------- ------- -------- ----------- + FW_ENV_DEFAULT='/dev/mtd1 0x000000 0x10000 0x10000' + demo_part=2 + mmc_bus="mmc0:0001" + + onie_part_size=168M + onie_part_num=1 + onie_part_label=ONIE + + sonic_part_num=2 + sonic_part_label=SONiC-OS + + swap_part_size=3G + swap_part_num=3 + swap_part_label=swap + + debug_part_size=2G + debug_swap_part_size=5G + debug_part_num=4 + debug_part_label=DEBUG + + current_image_dir="" + current_image_name="" + current_fdt_name="" + current_fit_name="" + current_sonic_version_1="" else fdt_addr=0x1000000 fit_addr=0x8000000 @@ -110,15 +146,86 @@ remove_dev_partitions() { } create_demo_partition() { - # SD CARD - remove_dev_partitions + if [ $PLATFORM_AC5X -eq 2 ]; then + onie_part=$(sgdisk -p "$blk_dev" | grep -e "$onie_part_label" | awk '{print $1}') + sonic_part=$(sgdisk -p "$blk_dev" | grep -e "$sonic_part_label" | awk '{print $1}') + swap_part=$(sgdisk -p "$blk_dev" | grep -e "$swap_part_label" | awk '{print $1}') + debug_part=$(sgdisk -p "$blk_dev" | grep -e "$debug_part_label" | awk '{print $1}') - # Create sonic partition - sgdisk --new ${demo_part}:: \ - --change-name=${demo_part}:${demo_volume_label} \ - --typecode=${demo_part}:8300 -p ${blk_dev} + if [ -z "$onie_part" ] + then + echo "Partitioning is Incorrect. Re-partitioning" + sgdisk -oZ ${blk_dev} - partprobe + sgdisk --new ${onie_part_num}:0:+${onie_part_size} \ + --change-name=${onie_part_num}:${onie_part_label} \ + --typecode=${onie_part_num}:8300 -p ${blk_dev} + + if [ $? -ne 0 ]; then + echo "Failed creating onie eMMC partition" + return 2 + fi + + mkfs.ext4 -F -L ${onie_part_label} ${blk_dev}p${onie_part_num} + else + fsck.ext4 -v -p ${blk_dev}p${onie_part_num} + fi + + if [ -z "$debug_part" ]; then + # Create debug partition + sgdisk --new ${debug_part_num}:-${debug_part_size}: \ + --change-name=${debug_part_num}:${debug_part_label} \ + --typecode=${debug_part_num}:8300 -p ${blk_dev} + + mkfs.ext4 -F -L ${debug_part_label} ${blk_dev}p${debug_part_num} + else + fsck.ext4 -v -p ${blk_dev}p${debug_part_num} + fi + + if [ -z "$swap_part" ]; then + # Create swap partition + swap_start_num=-${debug_swap_part_size} + swap_end_num=-${debug_part_size} + #sgdisk --new ${swap_part_num}:-${swap_part_size}: \ + sgdisk --new ${swap_part_num}:${swap_start_num}:${swap_end_num} \ + --change-name=${swap_part_num}:${swap_part_label} \ + --typecode=${swap_part_num}:8200 -p ${blk_dev} + fi + + if [ -z "$sonic_part" ]; then + # Create sonic partition + start_num=$(sgdisk -F $blk_dev) + end_num=$(sgdisk -E $blk_dev) + + sgdisk --new ${sonic_part_num}:${start_num}:${end_num} \ + --change-name=${sonic_part_num}:${sonic_part_label} \ + --typecode=${sonic_part_num}:8300 -p ${blk_dev} + + mkfs.ext4 -F -L ${sonic_part_label} ${blk_dev}p${sonic_part_num} + else + mkfs.ext4 -F -L ${sonic_part_label} ${blk_dev}p${sonic_part_num} + fi + + partprobe + sync + + mkswap ${blk_dev}p${swap_part_num} + echo "${blk_dev}p${swap_part_num} swap swap defaults 0 0" > /etc/fstab + swapon -a + + return 0 + + else + # SD CARD + remove_dev_partitions + + # Create sonic partition + sgdisk --new ${demo_part}:: \ + --change-name=${demo_part}:${demo_volume_label} \ + --typecode=${demo_part}:8300 -p ${blk_dev} + + partprobe + fi } create_partition() { @@ -171,6 +278,13 @@ prepare_boot_menu() { initrd_name=${image_dir}${initrd_fname} fdt_name=${image_dir}${fdt_fname} fit_name=${image_dir}${fit_fname} + if [ $PLATFORM_AC5X -eq 2 ]; then + current_image_dir="image-$running_sonic_revision" + current_image_name=${current_image_dir}${kernel_name} + current_fdt_name=${current_image_dir}${fdt_fname} + current_fit_name=${current_image_dir}${fit_fname} + current_sonic_version_1="${demo_volume_label}-${running_sonic_revision}" + fi if [ "$install_env" = "onie" ]; then FW_ARG="-f" @@ -181,12 +295,55 @@ prepare_boot_menu() { fit_name_old="" sonic_version_2="None" else - image_dir_old=$(fw_printenv -n image_dir || true) - image_name_old=$(fw_printenv -n image_name || true) - initrd_name_old=$(fw_printenv -n initrd_name || true) - fdt_name_old=$(fw_printenv -n fdt_name || true) - fit_name_old=$(fw_printenv -n fit_name || true) - sonic_version_2=$(fw_printenv -n sonic_version_1 || true) + if [ $PLATFORM_AC5X -eq 2 ]; then + sonic_version_1=$(fw_printenv -n sonic_version_1 || true) + sonic_version_2=$(fw_printenv -n sonic_version_2 || true) + if [ "$sonic_version_1" != "NONE" ] && [ "$sonic_version_1" != "None" ] + then + if [ "$running_sonic_revision" != "None" ] + then + image_dir_old=${current_image_dir} + image_name_old=${current_image_name} + initrd_name_old=${current_initrd_name} + fdt_name_old=${current_fdt_name} + fit_name_old=${current_fit_name} + sonic_version_2=${current_sonic_version_1} + else + image_dir_old=$(fw_printenv -n image_dir || true) + image_name_old=$(fw_printenv -n image_name || true) + initrd_name_old=$(fw_printenv -n initrd_name || true) + fdt_name_old=$(fw_printenv -n fdt_name || true) + fit_name_old=$(fw_printenv -n fit_name || true) + sonic_version_2=$(fw_printenv -n sonic_version_1 || true) + fi + else + if [ "$sonic_version_2" != "NONE" ] && [ "$sonic_version_2" != "None" ] + then + image_dir_old=$(fw_printenv -n image_dir_old || true) + image_name_old=$(fw_printenv -n image_name_old || true) + initrd_name_old=$(fw_printenv -n initrd_name_old || true) + fdt_name_old=$(fw_printenv -n fdt_name_old || true) + fit_name_old=$(fw_printenv -n fit_name_old || true) + fi + fi + + if [ -z "$demo_dev" ]; then + get_install_device + if [ $? -ne 0 ]; then + echo "Error: Unable to detect $blk_dev $demo_dev" + exit 1 + fi + demo_part=${sonic_part_num} + demo_dev=${blk_dev}p${sonic_part_num} + fi + else + image_dir_old=$(fw_printenv -n image_dir || true) + image_name_old=$(fw_printenv -n image_name || true) + initrd_name_old=$(fw_printenv -n initrd_name || true) + fdt_name_old=$(fw_printenv -n fdt_name || true) + fit_name_old=$(fw_printenv -n fit_name || true) + sonic_version_2=$(fw_printenv -n sonic_version_1 || true) + fi fi # Set boot variables @@ -204,14 +361,27 @@ prepare_boot_menu() { fw_setenv ${FW_ARG} sonic_version_2 $sonic_version_2 > /dev/null BOOT1='echo " > Boot1: $sonic_version_1 - run sonic_image_1";echo;' BOOT2='echo " > Boot2: $sonic_version_2 - run sonic_image_2";echo;' - BOOT3='echo " > Boot3: ONIE - run onie_boot";echo;' - BORDER='echo "---------------------------------------------------";echo;' - fw_setenv ${FW_ARG} print_menu $BORDER $BOOT1 $BOOT2 $BOOT3 $BORDER > /dev/null - fw_setenv ${FW_ARG} linuxargs "net.ifnames=0 loopfstype=squashfs loop=$image_dir/$FILESYSTEM_SQUASHFS systemd.unified_cgroup_hierarchy=0 varlog_size=$VAR_LOG ${ONIE_PLATFORM_EXTRA_CMDLINE_LINUX}" > /dev/null - fw_setenv ${FW_ARG} linuxargs_old "net.ifnames=0 loopfstype=squashfs loop=$image_dir_old/$FILESYSTEM_SQUASHFS systemd.unified_cgroup_hierarchy=0 varlog_size=$VAR_LOG ${ONIE_PLATFORM_EXTRA_CMDLINE_LINUX}" > /dev/null - sonic_bootargs_old='setenv bootargs root='$demo_dev' rw rootwait rootfstype=ext4 panic=1 console=ttyS0,${baudrate} ${othbootargs} ${mtdparts} ${linuxargs_old}' - fw_setenv ${FW_ARG} sonic_bootargs_old $sonic_bootargs_old > /dev/null || true + if [ $PLATFORM -eq 2 ]; then + BOOT3='echo " > Boot3: ONIE - run onie_emmc_boot";echo;' + BORDER='echo "---------------------------------------------------";echo;' + fw_setenv ${FW_ARG} print_menu "$BORDER $BOOT1 $BOOT2 $BOOT3 $BORDER" > /dev/null + + fw_setenv ${FW_ARG} linuxargs "net.ifnames=0 loopfstype=squashfs loop=$image_dir/$FILESYSTEM_SQUASHFS systemd.unified_cgroup_hierarchy=0 varlog_size=$VAR_LOG ${extra_cmdline_linux} loglevel=4" > /dev/null + fw_setenv ${FW_ARG} linuxargs_old "net.ifnames=0 loopfstype=squashfs loop=$image_dir_old/$FILESYSTEM_SQUASHFS systemd.unified_cgroup_hierarchy=0 varlog_size=$VAR_LOG loglevel=4" > /dev/null + sonic_bootargs_old='setenv bootargs root='$demo_dev' rw rootwait rootfstype=ext4 panic=1 console=ttyS0,${baudrate} ${othbootargs} ${mtdparts} ${linuxargs_old}' + fw_setenv ${FW_ARG} sonic_bootargs_old "$sonic_bootargs_old" > /dev/null || true + else + BOOT3='echo " > Boot3: ONIE - run onie_boot";echo;' + BORDER='echo "---------------------------------------------------";echo;' + fw_setenv ${FW_ARG} print_menu $BORDER $BOOT1 $BOOT2 $BOOT3 $BORDER > /dev/null + + fw_setenv ${FW_ARG} linuxargs "net.ifnames=0 loopfstype=squashfs loop=$image_dir/$FILESYSTEM_SQUASHFS systemd.unified_cgroup_hierarchy=0 varlog_size=$VAR_LOG ${ONIE_PLATFORM_EXTRA_CMDLINE_LINUX}" > /dev/null + fw_setenv ${FW_ARG} linuxargs_old "net.ifnames=0 loopfstype=squashfs loop=$image_dir_old/$FILESYSTEM_SQUASHFS systemd.unified_cgroup_hierarchy=0 varlog_size=$VAR_LOG ${ONIE_PLATFORM_EXTRA_CMDLINE_LINUX}" > /dev/null + sonic_bootargs_old='setenv bootargs root='$demo_dev' rw rootwait rootfstype=ext4 panic=1 console=ttyS0,${baudrate} ${othbootargs} ${mtdparts} ${linuxargs_old}' + fw_setenv ${FW_ARG} sonic_bootargs_old $sonic_bootargs_old > /dev/null || true + fi + sonic_boot_load_old=$(fw_printenv -n sonic_boot_load || true) old_str="_old" fw_setenv ${FW_ARG} sonic_boot_load_old "$sonic_boot_load_old$old_str" > /dev/null || true @@ -226,13 +396,24 @@ prepare_boot_menu() { SONIC_BOOT_CMD='run sonic_bootargs; run sonic_boot_load; bootm $fit_addr${fit_conf_name}' SONIC_BOOT_CMD_OLD='run sonic_bootargs_old; run sonic_boot_load_old; bootm $fit_addr${fit_conf_name}' BOOTARGS='setenv bootargs root='$demo_dev' rw rootwait rootfstype=ext4 panic=1 console=ttyS0,${baudrate} ${othbootargs} ${mtdparts} ${linuxargs}' - fw_setenv ${FW_ARG} sonic_bootargs $BOOTARGS > /dev/null - fw_setenv ${FW_ARG} sonic_bootcmd $SONIC_BOOT_CMD > /dev/null - fw_setenv ${FW_ARG} sonic_image_2 $SONIC_BOOT_CMD_OLD > /dev/null + if [ $PLATFORM -eq 2 ]; then + fw_setenv ${FW_ARG} sonic_bootargs "$BOOTARGS" > /dev/null + fw_setenv ${FW_ARG} sonic_bootcmd "$SONIC_BOOT_CMD" > /dev/null + fw_setenv ${FW_ARG} sonic_image_2 "$SONIC_BOOT_CMD_OLD" > /dev/null + else + fw_setenv ${FW_ARG} sonic_bootargs $BOOTARGS > /dev/null + fw_setenv ${FW_ARG} sonic_bootcmd $SONIC_BOOT_CMD > /dev/null + fw_setenv ${FW_ARG} sonic_image_2 $SONIC_BOOT_CMD_OLD > /dev/null + fi fw_setenv ${FW_ARG} sonic_image_1 "$SONIC_BOOT_CMD" > /dev/null fw_setenv ${FW_ARG} boot_next 'run sonic_image_1'> /dev/null - fw_setenv ${FW_ARG} bootcmd 'run print_menu; usb start; test -n "$boot_once" && run boot_once; run boot_next' > /dev/null - + if [ $PLATFORM -eq 2 ]; then + fw_setenv ${FW_ARG} boot_once > /dev/null + fw_setenv ${FW_ARG} nos_bootcmd 'run print_menu; usb start; test -n "$boot_once" && run boot_once; run boot_next' > /dev/null + fw_setenv ${FW_ARG} bootcmd 'run diag_bootcmd; run check_boot_reason; run nos_bootcmd; run onie_bootcmd' > /dev/null + else + fw_setenv ${FW_ARG} bootcmd 'run print_menu; usb start; test -n "$boot_once" && run boot_once; run boot_next' > /dev/null + fi } bootloader_menu_config() { diff --git a/platform/marvell-arm64/rules.mk b/platform/marvell-arm64/rules.mk index 882a9451e9..34fc7a0f1f 100644 --- a/platform/marvell-arm64/rules.mk +++ b/platform/marvell-arm64/rules.mk @@ -8,6 +8,7 @@ include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/mrvl-prestera.mk include $(PLATFORM_PATH)/platform-nokia.mk include $(PLATFORM_PATH)/platform-marvell.mk +include $(PLATFORM_PATH)/platform-modules-supermicro.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) \ diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/changelog b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/changelog new file mode 100644 index 0000000000..1914959d83 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/changelog @@ -0,0 +1,6 @@ +sonic-supermicro-platform-modules (1.0) unstable; urgency=low + + * Add support for Supermicro SSE-G3748 + * Initial release + + -- Supermicro Team Wed, 03 Jan 2024 09:00:00 +0800 diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/compat b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/compat new file mode 100644 index 0000000000..ec635144f6 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/control b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/control new file mode 100644 index 0000000000..c5aaa274cd --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/control @@ -0,0 +1,13 @@ +Source: sonic-supermicro-platform-modules +Section: main +Priority: extra +Maintainer: Supermicro Team +Build-Depends: debhelper (>=9) +Standards-Version: 3.9.6 +Homepage: + +Package: sonic-platform-supermicro-sse-g3748 +Architecture: arm64 +Depends: ${misc:Depends} +Description: Kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/rules b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/rules new file mode 100755 index 0000000000..42e43c1a30 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/rules @@ -0,0 +1,74 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + +include /usr/share/dpkg/pkg-info.mk +#-------------------------------------------------------- + +export INSTALL_MOD_DIR:=extra + +PACKAGE_PRE_NAME := sonic-platform-supermicro +KVERSION ?= $(shell uname -r) +KERNEL_SRC ?= /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= sse-g3748 +MODULE_DIR:= modules +UTILS_DIR := utils +SERVICE_DIR := service + +%: + dh $@ --with systemd,python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + (for mod in $(MODULE_DIRS); do \ + if [ $$mod = "sse-g3748" ]; then \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + python3 $${mod}/setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}; \ + echo "Finished making whl package for $$mod"; \ + fi; \ + done) + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +binary-indep: + dh_testdir + dh_installdirs + + # Custom package commands + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /usr/local/bin; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + python2 $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + python3 $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + done) + + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +.PHONY: build binary binary-arch binary-indep clean diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/sonic-platform-supermicro-sse-g3748.install b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/sonic-platform-supermicro-sse-g3748.install new file mode 100644 index 0000000000..f826c9dc69 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/sonic-platform-supermicro-sse-g3748.install @@ -0,0 +1,10 @@ +sse-g3748/scripts/setup_all_ports_l2.py usr/local/bin +sse-g3748/scripts/show-techsupport usr/local/bin +sse-g3748/scripts/techfile_v2.py usr/local/bin +sse-g3748/scripts/sse-g3748_plt_setup.sh usr/local/bin +sse-g3748/scripts/entropy.py etc/ +sse-g3748/scripts/sse-g3748-init.sh usr/local/bin +sse-g3748/scripts/reset-to-factory-default usr/local/bin +sse-g3748/service/sse-g3748-init.service etc/systemd/system +sse-g3748/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/arm64-supermicro_sse_g3748-r0 +sse-g3748/scripts/add_port_range usr/local/bin diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/sonic-platform-supermicro-sse-g3748.postinst b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/sonic-platform-supermicro-sse-g3748.postinst new file mode 100644 index 0000000000..ad6cfcc41e --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/debian/sonic-platform-supermicro-sse-g3748.postinst @@ -0,0 +1,47 @@ +#!/bin/sh +# postinst script for platform-modules-sse-g3748 +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see https://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + sh /usr/local/bin/sse-g3748_plt_setup.sh + chmod a+x /usr/local/bin/sse-g3748-init.sh + chmod a+x /usr/local/bin/setup_all_ports_l2.py + chmod a+x /usr/local/bin/add_port_range + chmod a+x /usr/local/bin/reset-to-factory-default + systemctl enable sse-g3748-init.service + systemctl start sse-g3748-init.service + + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/Makefile b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/Makefile new file mode 100644 index 0000000000..fea5efe53a --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := g3748cpld.o +obj-m += smc-i2c-mux-pca954x.o diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/g3748cpld.c b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/g3748cpld.c new file mode 100644 index 0000000000..db6a592721 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/g3748cpld.c @@ -0,0 +1,818 @@ +/* + * g3748cpld.c - A driver for control of SMC SSE-G3748 cpld based on lm75.c + * + * Copyright (c) 1998, 1999 Frodo Looijaard + * Copyright (c) 2023 Supermicro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x66, I2C_CLIENT_END }; + +/* CPLD WDT global timeout */ +static u32 gTimeout = 0; + +/* Size of EEPROM in bytes */ +#define CPLD_SIZE 12 + +#define FAN_NUM 2 +#define PSU_NUM 2 +#define DEFAULT_VOLTAGE_MIN 11000 +#define DEFAULT_VOLTAGE_MAX 13000 +#define DEFAULT_VOLTAGE_LCRIT 11500 +#define DEFAULT_VOLTAGE_CRIT 12500 + +#define G3748_CPLD_VER_REG 0x09 +//#define G3748_POWER_GOOD_REG 0x0A +//#define G3748_PSU_PRESENT_REG 0x0A +#define G3748_PSU_STATUS_REG 0x0A +#define G3748_FAN_STATUS_REG 0x3B +#define G3748_FAN_CONTROL_REG 0x3C +#define G3748_FAN_SPEED_REG 0x3E +#define G3748_PSU_FRONTLED_REG 0x12 +#define G3748_FAN_SYS_FRONTLED_REG 0x11 +#define G3748_WDT_TIMER_REG 0x1B +#define G3748_WDT_CTRL_REG 0x1C +#define G3748_WDT_INTR_CNT_MASK_REG 0x1D +#define G3748_WDT_INTR_FLAG_REG 0x1E + +/* Each client has this additional data */ +struct cpld_data { + struct device *hwmon_dev; + struct i2c_client *client; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 data[CPLD_SIZE]; /* Register value */ + + u32 in[PSU_NUM]; /* Register value for PSU Voltage input value */ + u32 in_min[PSU_NUM]; /* Register value for PSU Voltage min value */ + u32 in_max[PSU_NUM]; /* Register value for PSU Voltage max value */ + u32 in_crit[PSU_NUM]; /* Register value for PSU Voltage critical max value */ + u32 in_lcrit[PSU_NUM]; /* Register value for PSU Voltage critical min value */ + + u32 fan[FAN_NUM]; /* Register value for FAN speed(RPM) input value */ + u32 fan_min[FAN_NUM]; /* Register value for FAN speed(RPM) min value */ + u32 fan_max[FAN_NUM]; /* Register value for FAN speed(RPM) max value */ + u32 fan_target[FAN_NUM]; /* Register value for FAN desired speed(RPM) value */ + u8 pwm[FAN_NUM]; /* Register value for Pulse Width Modulation Ctrl 0-255 255:max(100%) */ +}; + +static int g3748cpld_read (struct cpld_data *data, u8 reg) +{ + int ret = -EPERM; + //u8 high_reg = 0x00; + + mutex_lock(&data->update_lock); + //ret = i2c_smbus_write_byte_data (data->client, high_reg, reg); + ret = i2c_smbus_read_byte_data (data->client, reg); + mutex_unlock(&data->update_lock); + + return ret; +} + +static int g3748cpld_write (struct cpld_data *data, u8 reg, u8 val) +{ + int ret = 0; + + mutex_lock(&data->update_lock); + ret = i2c_smbus_write_byte_data (data->client, reg, val); + mutex_unlock(&data->update_lock); + + return ret; +} + +#if 0 +static ssize_t show_hwmon_value(struct device *dev, struct device_attribute *da, char *buf) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int index = to_sensor_dev_attr_2(da)->index; + + mutex_lock(&data->update_lock); + data->data[0] = i2c_smbus_read_byte_data(client, index); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", data->data[0]); +} + +static ssize_t show_sysfs_value(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + data->data[0] = i2c_smbus_read_byte_data(client, attr->index); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%02x\n", data->data[0]); +} + +static ssize_t set_hwmon_value(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int index = to_sensor_dev_attr_2(da)->index; + u8 temp; + int error; + + error = kstrtou8(buf, 10, &temp); + if (error) + return error; + + mutex_lock(&data->update_lock); + i2c_smbus_write_byte_data(client, index, temp); + mutex_unlock(&data->update_lock); + + return count; +} +#endif + +static ssize_t get_cpld_ver(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + u8 devdata = 0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = g3748cpld_read (data, G3748_CPLD_VER_REG); + if (ret < 0) + return sprintf(buf, "cpld read error"); + + devdata = (u8)ret & 0xff; + return sprintf(buf, "0x%02X\n", devdata); +} + +static ssize_t get_power_good(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + u8 devdata = 0; + struct cpld_data *data = dev_get_drvdata(dev); + int index = to_sensor_dev_attr_2(da)->index; + + //ret = g3748cpld_read (data, G3748_POWER_GOOD_REG); + ret = g3748cpld_read (data, G3748_PSU_STATUS_REG); + if (ret < 0) + return sprintf(buf, "cpld read error"); + + if (index == 1) { + devdata = (u8)ret & 0x04; + } else if (index == 2) { + devdata = (u8)ret & 0x08; + } + + return sprintf(buf, "%s\n", (devdata == 0)? "12000":"0"); +} + +static ssize_t get_psu_status(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + //u8 devdata = 0; + struct cpld_data *data = dev_get_drvdata(dev); + //int index = to_sensor_dev_attr_2(da)->index; + + ret = g3748cpld_read (data, G3748_PSU_STATUS_REG); + if (ret < 0) + return sprintf(buf, "cpld psu status read error"); + + //if (index == 1) { + // devdata = (u8)ret & 0x01; + //} else if (index == 2) { + // devdata = (u8)ret & 0x02; + //} + + return sprintf(buf, "%d\n", (u8)ret); +} + +static void initCpldDataReg (struct cpld_data *data) +{ + if (data != NULL) { + data->in_min[0] = data->in_min[1] = DEFAULT_VOLTAGE_MIN; + data->in_max[0] = data->in_max[1] = DEFAULT_VOLTAGE_MAX; + data->in_lcrit[0] = data->in_lcrit[1] = DEFAULT_VOLTAGE_LCRIT; + data->in_crit[0] = data->in_crit[1] = DEFAULT_VOLTAGE_CRIT; + } +} + +static ssize_t get_voltage_limit(struct device *dev, struct device_attribute *da, char *buf) +{ + struct cpld_data *data = dev_get_drvdata(dev); + int index = to_sensor_dev_attr_2(da)->index; + u32 inData = 0; + //ret = g3748cpld_read (data, G3748_PSU_PRESENT_REG); + //if (ret < 0) + // return sprintf(buf, "cpld read error"); + + /* Register data read from our cpld_data structure storage area */ + if ((index == 11) || (index == 12)) { + /* Read for in1_min or in2_min */ + inData = data->in_min[index - 11]; + } else if ((index == 21) || (index == 22)) { + /* Read for in1_max or in2_max */ + inData = data->in_max[index - 21]; + } else if ((index == 31) || (index == 32)) { + /* Read for in1_lcrit or in2_lcrit */ + inData = data->in_lcrit[index - 31]; + } else if ((index == 41) || (index == 42)) { + /* Read for in1_crit or in2_crit */ + inData = data->in_crit[index - 41]; + } + + return sprintf(buf, "%d\n", (int)inData); +} + +static ssize_t set_voltage_limit(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + int index = to_sensor_dev_attr_2(da)->index; + u32 inData = 0; + int error; + + error = kstrtou32(buf, 10, &inData); + if (error) + return error; + + /* Register data read from our cpld_data structure storage area */ + if ((index == 11) || (index == 12)) { + /* write in1_min or in2_min */ + data->in_min[index - 11] = inData; + } else if ((index == 21) || (index == 22)) { + /* write in1_max or in2_max */ + data->in_max[index - 21] = inData; + } else if ((index == 31) || (index == 32)) { + /* write in1_lcrit or in2_lcrit */ + data->in_lcrit[index - 31] = inData; + } else if ((index == 41) || (index == 42)) { + /* Read for in1_crit or in2_crit */ + data->in_crit[index - 41] = inData; + } + + return count; +} + +static ssize_t get_fan_status(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + //u8 devdata = 0; + struct cpld_data *data = dev_get_drvdata(dev); + //int index = to_sensor_dev_attr_2(da)->index; + + ret = g3748cpld_read (data, G3748_FAN_STATUS_REG); + if (ret < 0) + return sprintf(buf, "cpld fan status read error"); + + //if (index == 1) { + // devdata = (u8)ret & 0x04; + //} else if (index == 2) { + // devdata = (u8)ret & 0x08; + //} + + return sprintf(buf, "%d\n", (u8)ret); +} + +static ssize_t get_fan_fault(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + u8 fault = 0; + struct cpld_data *data = dev_get_drvdata(dev); + int index = to_sensor_dev_attr_2(da)->index; + + ret = g3748cpld_read (data, G3748_FAN_STATUS_REG); + if (ret < 0) + return sprintf(buf, "ERR: fan status read"); + + if (index == 1) { + if (((u8)ret & 0x04) == 0) { + fault = 1; /* not present */ + } + } else if (index == 2) { + if (((u8)ret & 0x084) == 0) { + fault = 1; /* not present */ + } + } + + return sprintf(buf, "%d\n", fault); +} + +static ssize_t get_fan_speed(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret, rpm; + //u8 devdata = 0; + struct cpld_data *data = dev_get_drvdata(dev); + int index = to_sensor_dev_attr_2(da)->index; + + ret = g3748cpld_read (data, (G3748_FAN_SPEED_REG + index - 1)); + if (ret < 0) + return sprintf(buf, "ERR"); + + rpm = (5000 * 60) / ret; + + return sprintf(buf, "%d\n", rpm); +} + +/* G3748 FAN Control Register: + * Register value -- total 32 steps (0-31(0x1f)) to control system FAN PWM value (0% to 100%) + * RPM -- 0x00:0rpm, 0x0F:8800rpm, 0x1F:17600rpm. + * PWM -- 0x00:0%, 0x0F:50%, 0x1F:100% + */ +static ssize_t get_fan_pwm(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + //u8 devdata = 0; + struct cpld_data *data = dev_get_drvdata(dev); + int index = to_sensor_dev_attr_2(da)->index; + u8 pwm; + + ret = g3748cpld_read (data, (G3748_FAN_CONTROL_REG + index - 1)); + if (ret < 0) + return sprintf(buf, "cpld fan ctrl read error"); + + ret = ret & 0x1F; + if (ret == 0x1F) { + pwm = 100; + } else if (ret == 0) { + pwm = 0; + } else { + pwm = (u8)((ret * 100) / 31); + } + + return sprintf(buf, "%d\n", pwm); +} + +static ssize_t set_fan_pwm(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + //struct i2c_client *client = data->client; + int index = to_sensor_dev_attr_2(da)->index; + u8 temp; + int error; + u8 regVal = 0; + + error = kstrtou8(buf, 10, &temp); + if (error) + return error; + if (temp > 100) { + temp = 100; + } else if (temp < 0) { + temp = 0; + } + regVal = (u8)((int)temp * 31 / 100); + + g3748cpld_write (data, (G3748_FAN_CONTROL_REG + index - 1), regVal); + + return count; +} + +static ssize_t get_fan_target(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + //u8 devdata = 0; + struct cpld_data *data = dev_get_drvdata(dev); + int index = to_sensor_dev_attr_2(da)->index; + int rpm; + + ret = g3748cpld_read (data, (G3748_FAN_CONTROL_REG + index - 1)); + if (ret < 0) + return sprintf(buf, "cpld fan ctrl read error"); + + ret = ret & 0x1F; + if (ret == 0x1F) { + rpm = 17600; + } else if (ret == 0) { + rpm = 0; + } else { + rpm = (ret * 17600) / 31; + } + + return sprintf(buf, "%d\n", rpm); +} + +static ssize_t set_fan_target(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + //struct i2c_client *client = data->client; + int index = to_sensor_dev_attr_2(da)->index; + int temp; + int error; + u8 regVal = 0; + + error = kstrtou32(buf, 10, (u32 *)&temp); + if (error) + return error; + if (temp > 17600) { + temp = 17600; + } else if (temp < 0) { + temp = 0; + } + regVal = (u8)((temp * 31) / 17600); + + g3748cpld_write (data, (G3748_FAN_CONTROL_REG + index - 1), regVal); + + return count; +} + +static ssize_t get_psu_frontled_reg(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = g3748cpld_read (data, G3748_PSU_FRONTLED_REG); + if (ret < 0) { + return sprintf(buf, "ERR: psu reg read"); + } + + return sprintf(buf, "%d\n", ret); +} + +static ssize_t set_psu_frontled_reg(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + u8 temp; + int error; + + error = kstrtou8(buf, 10, &temp); + if (error) { + return error; + } + + g3748cpld_write (data, G3748_PSU_FRONTLED_REG, temp); + + return count; +} + +static ssize_t get_fan_sys_frontled_reg(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = g3748cpld_read (data, G3748_FAN_SYS_FRONTLED_REG); + if (ret < 0) { + return sprintf(buf, "ERR: fan_sys reg read"); + } + + return sprintf(buf, "%d\n", ret); +} + +static ssize_t set_fan_sys_frontled_reg(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + u8 temp; + int error; + + error = kstrtou8(buf, 10, &temp); + if (error) { + return error; + } + + g3748cpld_write (data, G3748_FAN_SYS_FRONTLED_REG, temp); + + return count; +} + +static ssize_t get_wdt_timer_reg(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = g3748cpld_read (data, G3748_WDT_TIMER_REG); + if (ret < 0) { + return sprintf(buf, "ERR: WDT Timer reg read"); + } + + return sprintf(buf, "%d\n", ret); +} + +static ssize_t set_wdt_timer_reg(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + u8 temp; + int error; + + error = kstrtou8(buf, 10, &temp); + if (error) { + return error; + } + + g3748cpld_write (data, G3748_WDT_TIMER_REG, temp); + + return count; +} + +static ssize_t get_wdt_ctrl_reg(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = g3748cpld_read (data, G3748_WDT_CTRL_REG); + if (ret < 0) { + return sprintf(buf, "ERR: WDT Ctrl reg read"); + } + + return sprintf(buf, "%d\n", ret); +} + +static ssize_t set_wdt_ctrl_reg(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + u8 temp; + int error; + + error = kstrtou8(buf, 10, &temp); + if (error) { + return error; + } + + g3748cpld_write (data, G3748_WDT_CTRL_REG, temp); + + return count; +} + +static ssize_t get_wdt_intr_cnt_mask_reg(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = g3748cpld_read (data, G3748_WDT_INTR_CNT_MASK_REG); + if (ret < 0) { + return sprintf(buf, "ERR: WDT Intr Count Mask reg read"); + } + + return sprintf(buf, "%d\n", ret); +} + +static ssize_t set_wdt_intr_cnt_mask_reg(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + u8 temp; + int error; + + error = kstrtou8(buf, 10, &temp); + if (error) { + return error; + } + + g3748cpld_write (data, G3748_WDT_INTR_CNT_MASK_REG, temp); + + return count; +} + +static ssize_t get_wdt_intr_flag_reg(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = g3748cpld_read (data, G3748_WDT_INTR_FLAG_REG); + if (ret < 0) { + return sprintf(buf, "ERR: WDT Intr Flag reg read"); + } + + return sprintf(buf, "%d\n", ret); +} + +static ssize_t set_wdt_intr_flag_reg(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + u8 temp; + int error; + + error = kstrtou8(buf, 10, &temp); + if (error) { + return error; + } + + g3748cpld_write (data, G3748_WDT_INTR_FLAG_REG, temp); + + return count; +} + +static ssize_t get_wdt_timeout(struct device *dev, struct device_attribute *da, char *buf) +{ + return sprintf(buf, "%u\n", gTimeout); +} + +static ssize_t set_wdt_timeout(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + u32 temp; + int error; + + error = kstrtou32(buf, 10, &temp); + if (error) { + return error; + } + + gTimeout = temp; + + return count; +} + +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, get_power_good, NULL, 1); /* PSU1 voltage (power good) */ +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, get_power_good, NULL, 2); /* PSU2 voltage (power good) */ +static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR, get_voltage_limit, set_voltage_limit, 11); /* PSU1 voltage min */ +static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO | S_IWUSR, get_voltage_limit, set_voltage_limit, 12); /* PSU2 voltage min */ +static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR, get_voltage_limit, set_voltage_limit, 21); /* PSU1 voltage max */ +static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO | S_IWUSR, get_voltage_limit, set_voltage_limit, 22); /* PSU2 voltage max */ +static SENSOR_DEVICE_ATTR(in1_lcrit, S_IRUGO | S_IWUSR, get_voltage_limit, set_voltage_limit, 31); /* PSU1 voltage lcrit */ +static SENSOR_DEVICE_ATTR(in2_lcrit, S_IRUGO | S_IWUSR, get_voltage_limit, set_voltage_limit, 32); /* PSU2 voltage lcrit */ +static SENSOR_DEVICE_ATTR(in1_crit, S_IRUGO | S_IWUSR, get_voltage_limit, set_voltage_limit, 41); /* PSU1 voltage crit */ +static SENSOR_DEVICE_ATTR(in2_crit, S_IRUGO | S_IWUSR, get_voltage_limit, set_voltage_limit, 42); /* PSU2 voltage crit */ + +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_fan_pwm, set_fan_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, get_fan_pwm, set_fan_pwm, 1); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan_speed, NULL, 1); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan_speed, NULL, 2); +static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, get_fan_target, set_fan_target, 1); +static SENSOR_DEVICE_ATTR(fan2_target, S_IRUGO | S_IWUSR, get_fan_target, set_fan_target, 1); +static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan_fault, NULL, 1); +static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, get_fan_fault, NULL, 2); + +static struct attribute *cpld_hwmon_attrs[] = { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in1_lcrit.dev_attr.attr, + &sensor_dev_attr_in2_lcrit.dev_attr.attr, + &sensor_dev_attr_in1_crit.dev_attr.attr, + &sensor_dev_attr_in2_crit.dev_attr.attr, + + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan1_target.dev_attr.attr, + &sensor_dev_attr_fan2_target.dev_attr.attr, + &sensor_dev_attr_fan1_fault.dev_attr.attr, + &sensor_dev_attr_fan2_fault.dev_attr.attr, + NULL +}; + +ATTRIBUTE_GROUPS(cpld_hwmon); +#if 0 +static const struct attribute_group cpld_hwmon_group = { + .attrs = cpld_hwmon_attrs, +}; +#endif + +static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, get_cpld_ver, NULL, 0x00); +static SENSOR_DEVICE_ATTR(psu_status, S_IRUGO, get_psu_status, NULL, 0); /* PSU Status Register */ +static SENSOR_DEVICE_ATTR(fan_status, S_IRUGO, get_fan_status, NULL, 0); /* FAN Status Register */ +static SENSOR_DEVICE_ATTR(fan_sys_frontled, S_IRUGO | S_IWUSR, get_fan_sys_frontled_reg, set_fan_sys_frontled_reg, 0); /* FAN front panel LED */ +static SENSOR_DEVICE_ATTR(psu_frontled, S_IRUGO | S_IWUSR, get_psu_frontled_reg, set_psu_frontled_reg, 0); /* PSU front panel LED */ + +static SENSOR_DEVICE_ATTR(wdt_timer, S_IRUGO | S_IWUSR, get_wdt_timer_reg, set_wdt_timer_reg, 0); +static SENSOR_DEVICE_ATTR(wdt_ctrl, S_IRUGO | S_IWUSR, get_wdt_ctrl_reg, set_wdt_ctrl_reg, 0); +static SENSOR_DEVICE_ATTR(wdt_intr_cnt_mask, S_IRUGO | S_IWUSR, get_wdt_intr_cnt_mask_reg, set_wdt_intr_cnt_mask_reg, 0); +static SENSOR_DEVICE_ATTR(wdt_intr_flag, S_IRUGO | S_IWUSR, get_wdt_intr_flag_reg, set_wdt_intr_flag_reg, 0); +static SENSOR_DEVICE_ATTR(wdt_timeout, S_IRUGO | S_IWUSR, get_wdt_timeout, set_wdt_timeout, 0); + +static struct attribute *cpld_sysfs_attrs[] = { + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_psu_status.dev_attr.attr, + &sensor_dev_attr_fan_status.dev_attr.attr, + &sensor_dev_attr_fan_sys_frontled.dev_attr.attr, + &sensor_dev_attr_psu_frontled.dev_attr.attr, + + &sensor_dev_attr_wdt_timer.dev_attr.attr, + &sensor_dev_attr_wdt_ctrl.dev_attr.attr, + &sensor_dev_attr_wdt_intr_cnt_mask.dev_attr.attr, + &sensor_dev_attr_wdt_intr_flag.dev_attr.attr, + &sensor_dev_attr_wdt_timeout.dev_attr.attr, + + NULL +}; + +static const struct attribute_group cpld_sysfs_group = { + .attrs = cpld_sysfs_attrs, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int g3748cpld_detect(struct i2c_client *new_client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int conf; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + /* Unused bits */ + conf = i2c_smbus_read_byte_data(new_client, 0); + if (!conf) + return -ENODEV; + + return 0; +} + +static void g3748cpld_add_client (struct i2c_client *client) +{ + struct cpld_data *data; + + data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), GFP_KERNEL); + if (!data) { + dev_info(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); +} + +static int g3748cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int status; + struct cpld_data *data; + int err; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_info(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + return status; + } + + dev_info(&client->dev, "chip found - CPLD\n"); + g3748cpld_add_client(client); + + /* Register sysfs hooks */ + //printk(KERN_INFO "g3748cpld_probe: Register sysfs hooks\n"); + status = sysfs_create_group(&client->dev.kobj, &cpld_sysfs_group); + if (status) { + printk(KERN_INFO "g3748cpld cannot create sysfs\n"); + } + + data = i2c_get_clientdata(client); + //data->hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, client->name, data, cpld_hwmon_groups); + data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, cpld_hwmon_groups); + + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove_files; + } + + initCpldDataReg(data); + dev_info(&client->dev, "%s: sensor '%s'\n", dev_name(data->hwmon_dev), client->name); + return 0; + +exit_remove_files: + sysfs_remove_group(&client->dev.kobj, &cpld_sysfs_group); + return err; +} + +static int g3748cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + //devm_hwmon_device_unregister(&client->dev); + sysfs_remove_group(&client->dev.kobj, &cpld_sysfs_group); + return 0; +} + +static const struct i2c_device_id g3748cpld_id[] = { + { "g3748cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, g3748cpld_id); + +static struct i2c_driver g3748cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "g3748cpld", + }, + .probe = g3748cpld_probe, + .remove = g3748cpld_remove, + .id_table = g3748cpld_id, + .detect = g3748cpld_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(g3748cpld_driver); + +MODULE_AUTHOR("SMC "); +MODULE_DESCRIPTION("SMC SSE-G3748 CPLD driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/smc-i2c-mux-pca954x.c b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/smc-i2c-mux-pca954x.c new file mode 100644 index 0000000000..80162bd9df --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/smc-i2c-mux-pca954x.c @@ -0,0 +1,591 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * I2C multiplexer + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This module supports the PCA954x and PCA984x series of I2C multiplexer/switch + * chips made by NXP Semiconductors. + * This includes the: + * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547, + * PCA9548, PCA9846, PCA9847, PCA9848 and PCA9849. + * + * These chips are all controlled via the I2C bus itself, and all have a + * single 8-bit register. The upstream "parent" bus fans out to two, + * four, or eight downstream busses or channels; which of these + * are selected is determined by the chip type and register contents. A + * mux can select only one sub-bus at a time; a switch can select any + * combination simultaneously. + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "smc-pca954x.h" + +#define PCA954X_MAX_NCHANS 8 + +#define PCA954X_IRQ_OFFSET 4 + +enum pca_type { + pca_9540, + pca_9542, + pca_9543, + pca_9544, + pca_9545, + pca_9546, + pca_9547, + pca_9548, + pca_9846, + pca_9847, + pca_9848, + pca_9849, +}; + +struct chip_desc { + u8 nchans; + u8 enable; /* used for muxes only */ + u8 has_irq; + enum muxtype { + pca954x_ismux = 0, + pca954x_isswi + } muxtype; + struct i2c_device_identity id; +}; + +struct pca954x { + const struct chip_desc *chip; + + u8 last_chan; /* last register value */ + /* MUX_IDLE_AS_IS, MUX_IDLE_DISCONNECT or >= 0 for channel */ + s32 idle_state; + + struct i2c_client *client; + + struct irq_domain *irq; + unsigned int irq_mask; + raw_spinlock_t lock; +}; + +/* Provide specs for the PCA954x types we know about */ +static const struct chip_desc chips[] = { + [pca_9540] = { + .nchans = 2, + .enable = 0x4, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9542] = { + .nchans = 2, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9543] = { + .nchans = 2, + .has_irq = 1, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9544] = { + .nchans = 4, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9545] = { + .nchans = 4, + .has_irq = 1, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9546] = { + .nchans = 4, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9547] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9548] = { + .nchans = 8, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9846] = { + .nchans = 4, + .muxtype = pca954x_isswi, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x10b, + }, + }, + [pca_9847] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x108, + }, + }, + [pca_9848] = { + .nchans = 8, + .muxtype = pca954x_isswi, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x10a, + }, + }, + [pca_9849] = { + .nchans = 4, + .enable = 0x4, + .muxtype = pca954x_ismux, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x109, + }, + }, +}; + +static const struct i2c_device_id pca954x_id[] = { + { "smc_pca9540", pca_9540 }, + { "smc_pca9542", pca_9542 }, + { "smc_pca9543", pca_9543 }, + { "smc_pca9544", pca_9544 }, + { "smc_pca9545", pca_9545 }, + { "smc_pca9546", pca_9546 }, + { "smc_pca9547", pca_9547 }, + { "smc_pca9548", pca_9548 }, + { "smc_pca9846", pca_9846 }, + { "smc_pca9847", pca_9847 }, + { "smc_pca9848", pca_9848 }, + { "smc_pca9849", pca_9849 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pca954x_id); + +/* Force deselect-on-exit feature for PCA954X devices. Default is disabled. */ +static unsigned int force_deselect_on_exit = 0; +module_param(force_deselect_on_exit, uint, S_IRUGO); +MODULE_PARM_DESC(force_deselect_on_exit, "Force deselect-on-exit feature for PCA954X devices. Default is disabled."); + +static const struct of_device_id pca954x_of_match[] = { + { .compatible = "nxp,smc_pca9540", .data = &chips[pca_9540] }, + { .compatible = "nxp,smc_pca9542", .data = &chips[pca_9542] }, + { .compatible = "nxp,smc_pca9543", .data = &chips[pca_9543] }, + { .compatible = "nxp,smc_pca9544", .data = &chips[pca_9544] }, + { .compatible = "nxp,smc_pca9545", .data = &chips[pca_9545] }, + { .compatible = "nxp,smc_pca9546", .data = &chips[pca_9546] }, + { .compatible = "nxp,smc_pca9547", .data = &chips[pca_9547] }, + { .compatible = "nxp,smc_pca9548", .data = &chips[pca_9548] }, + { .compatible = "nxp,smc_pca9846", .data = &chips[pca_9846] }, + { .compatible = "nxp,smc_pca9847", .data = &chips[pca_9847] }, + { .compatible = "nxp,smc_pca9848", .data = &chips[pca_9848] }, + { .compatible = "nxp,smc_pca9849", .data = &chips[pca_9849] }, + {} +}; +MODULE_DEVICE_TABLE(of, pca954x_of_match); + +/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() + for this as they will try to lock adapter a second time */ +static int pca954x_reg_write(struct i2c_adapter *adap, + struct i2c_client *client, u8 val) +{ + union i2c_smbus_data dummy; + + return __i2c_smbus_xfer(adap, client->addr, client->flags, + I2C_SMBUS_WRITE, val, + I2C_SMBUS_BYTE, &dummy); +} + +static u8 pca954x_regval(struct pca954x *data, u8 chan) +{ + /* We make switches look like muxes, not sure how to be smarter. */ + if (data->chip->muxtype == pca954x_ismux) + return chan | data->chip->enable; + else + return 1 << chan; +} + +static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + u8 regval; + int ret = 0; + + regval = pca954x_regval(data, chan); + /* Only select the channel if its different from the last channel */ + if (data->last_chan != regval) { + ret = pca954x_reg_write(muxc->parent, client, regval); + data->last_chan = ret < 0 ? 0 : regval; + } + + return ret; +} + +static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + s32 idle_state; + + idle_state = READ_ONCE(data->idle_state); + if (idle_state >= 0) + /* Set the mux back to a predetermined channel */ + return pca954x_select_chan(muxc, idle_state); + + if (idle_state == MUX_IDLE_DISCONNECT) { + /* Deselect active channel */ + data->last_chan = 0; + return pca954x_reg_write(muxc->parent, client, + data->last_chan); + } + + /* otherwise leave as-is */ + + return 0; +} + +static ssize_t idle_state_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + + return sprintf(buf, "%d\n", READ_ONCE(data->idle_state)); +} + +static ssize_t idle_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + int val; + int ret; + + ret = kstrtoint(buf, 0, &val); + if (ret < 0) + return ret; + + if (val != MUX_IDLE_AS_IS && val != MUX_IDLE_DISCONNECT && + (val < 0 || val >= data->chip->nchans)) + return -EINVAL; + + i2c_lock_bus(muxc->parent, I2C_LOCK_SEGMENT); + + WRITE_ONCE(data->idle_state, val); + /* + * Set the mux into a state consistent with the new + * idle_state. + */ + if (data->last_chan || val != MUX_IDLE_DISCONNECT) + ret = pca954x_deselect_mux(muxc, 0); + + i2c_unlock_bus(muxc->parent, I2C_LOCK_SEGMENT); + + return ret < 0 ? ret : count; +} + +static DEVICE_ATTR_RW(idle_state); + +static irqreturn_t pca954x_irq_handler(int irq, void *dev_id) +{ + struct pca954x *data = dev_id; + unsigned long pending; + int ret, i; + + ret = i2c_smbus_read_byte(data->client); + if (ret < 0) + return IRQ_NONE; + + pending = (ret >> PCA954X_IRQ_OFFSET) & (BIT(data->chip->nchans) - 1); + for_each_set_bit(i, &pending, data->chip->nchans) + handle_nested_irq(irq_linear_revmap(data->irq, i)); + + return IRQ_RETVAL(pending); +} + +static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type) +{ + if ((type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_LOW) + return -EINVAL; + return 0; +} + +static struct irq_chip pca954x_irq_chip = { + .name = "i2c-mux-pca954x", + .irq_set_type = pca954x_irq_set_type, +}; + +static int pca954x_irq_setup(struct i2c_mux_core *muxc) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int c, irq; + + if (!data->chip->has_irq || client->irq <= 0) + return 0; + + raw_spin_lock_init(&data->lock); + + data->irq = irq_domain_add_linear(client->dev.of_node, + data->chip->nchans, + &irq_domain_simple_ops, data); + if (!data->irq) + return -ENODEV; + + for (c = 0; c < data->chip->nchans; c++) { + irq = irq_create_mapping(data->irq, c); + if (!irq) { + dev_err(&client->dev, "failed irq create map\n"); + return -EINVAL; + } + irq_set_chip_data(irq, data); + irq_set_chip_and_handler(irq, &pca954x_irq_chip, + handle_simple_irq); + } + + return 0; +} + +static void pca954x_cleanup(struct i2c_mux_core *muxc) +{ + struct pca954x *data = i2c_mux_priv(muxc); + int c, irq; + + if (data->irq) { + for (c = 0; c < data->chip->nchans; c++) { + irq = irq_find_mapping(data->irq, c); + irq_dispose_mapping(irq); + } + irq_domain_remove(data->irq); + } + i2c_mux_del_adapters(muxc); +} + +static int pca954x_init(struct i2c_client *client, struct pca954x *data) +{ + int ret; + + printk("pca954x_init is called\n"); + if (data->idle_state >= 0) + data->last_chan = pca954x_regval(data, data->idle_state); + else + data->last_chan = 0; /* Disconnect multiplexer */ + + ret = i2c_smbus_write_byte(client, data->last_chan); + if (ret < 0) + data->last_chan = 0; + + return ret; +} + +/* + * I2C init/probing/exit functions + */ +static int pca954x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = client->adapter; + struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); + struct device *dev = &client->dev; + struct gpio_desc *gpio; + struct i2c_mux_core *muxc; + struct pca954x *data; + int num, force; + int ret; + + printk("pca954x_probe is called\n"); + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + + muxc = i2c_mux_alloc(adap, dev, PCA954X_MAX_NCHANS, sizeof(*data), 0, + pca954x_select_chan, pca954x_deselect_mux); + if (!muxc) + return -ENOMEM; + data = i2c_mux_priv(muxc); + + i2c_set_clientdata(client, muxc); + data->client = client; + + /* Reset the mux if a reset GPIO is specified. */ + gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + if (gpio) { + udelay(1); + gpiod_set_value_cansleep(gpio, 0); + /* Give the chip some time to recover. */ + udelay(1); + } + + data->chip = device_get_match_data(dev); + if (!data->chip) + data->chip = &chips[id->driver_data]; + + if (data->chip->id.manufacturer_id != I2C_DEVICE_ID_NONE) { + struct i2c_device_identity id; + + ret = i2c_get_device_id(client, &id); + if (ret && ret != -EOPNOTSUPP) + return ret; + + if (!ret && + (id.manufacturer_id != data->chip->id.manufacturer_id || + id.part_id != data->chip->id.part_id)) { + dev_warn(dev, "unexpected device id %03x-%03x-%x\n", + id.manufacturer_id, id.part_id, + id.die_revision); + return -ENODEV; + } + } + + data->idle_state = MUX_IDLE_AS_IS; + if (device_property_read_u32(dev, "idle-state", &data->idle_state)) { + if (device_property_read_bool(dev, "i2c-mux-idle-disconnect")) + data->idle_state = MUX_IDLE_DISCONNECT; + } + if (force_deselect_on_exit) + data->idle_state = MUX_IDLE_DISCONNECT; + printk("pca954x_probe: data->idle_state = %d\n", data->idle_state); + + /* + * Write the mux register at addr to verify + * that the mux is in fact present. This also + * initializes the mux to a channel + * or disconnected state. + */ + ret = pca954x_init(client, data); + if (ret < 0) { + dev_warn(dev, "probe failed\n"); + return -ENODEV; + } + + ret = pca954x_irq_setup(muxc); + if (ret) + goto fail_cleanup; + + /* Now create an adapter for each channel */ + for (num = 0; num < data->chip->nchans; num++) { + force = 0; /* dynamic adap number */ + if (pdata) { + if (num < pdata->num_modes) { + /* force static number */ + force = pdata->modes[num].adap_id; + } else + /* discard unconfigured channels */ + break; + } + + ret = i2c_mux_add_adapter(muxc, force, num, 0); + if (ret) + goto fail_cleanup; + } + + if (data->irq) { + ret = devm_request_threaded_irq(dev, data->client->irq, + NULL, pca954x_irq_handler, + IRQF_ONESHOT | IRQF_SHARED, + "pca954x", data); + if (ret) + goto fail_cleanup; + } + + /* + * The attr probably isn't going to be needed in most cases, + * so don't fail completely on error. + */ + device_create_file(dev, &dev_attr_idle_state); + + /* dev_info(dev, "registered %d multiplexed busses for I2C %s %s\n", + */ + printk("registered %d multiplexed busses for I2C %s %s\n", + num, data->chip->muxtype == pca954x_ismux + ? "mux" : "switch", client->name); + + return 0; + +fail_cleanup: + pca954x_cleanup(muxc); + return ret; +} + +static int pca954x_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + device_remove_file(&client->dev, &dev_attr_idle_state); + + pca954x_cleanup(muxc); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int pca954x_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + int ret; + + ret = pca954x_init(client, data); + if (ret < 0) + dev_err(&client->dev, "failed to verify mux presence\n"); + + return ret; +} +#endif + +static SIMPLE_DEV_PM_OPS(pca954x_pm, NULL, pca954x_resume); + +static struct i2c_driver pca954x_driver = { + .driver = { + .name = "smc_pca954x", + .pm = &pca954x_pm, + .of_match_table = pca954x_of_match, + }, + .probe = pca954x_probe, + .remove = pca954x_remove, + .id_table = pca954x_id, +}; + +module_i2c_driver(pca954x_driver); + +MODULE_AUTHOR("Rodolfo Giometti "); +MODULE_DESCRIPTION("PCA954x I2C mux/switch driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/smc-pca954x.h b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/smc-pca954x.h new file mode 100644 index 0000000000..15b9fe4146 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/modules/smc-pca954x.h @@ -0,0 +1,44 @@ +/* + * + * cls-pca954x.h - I2C multiplexer/switch support + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * Michael Lawnick + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef _LINUX_I2C_PCA954X_H +#define _LINUX_I2C_PCA954X_H + +/* Platform data for the PCA954x I2C multiplexers */ + +/* Per channel initialisation data: + * @adap_id: bus number for the adapter. 0 = don't care + * + */ +struct pca954x_platform_mode { + int adap_id; +}; + +/* Per mux/switch data, used with i2c_register_board_info */ +struct pca954x_platform_data { + struct pca954x_platform_mode *modes; + int num_modes; +}; + +#endif /* _LINUX_I2C_PCA954X_H */ \ No newline at end of file diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/add_port_range b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/add_port_range new file mode 100644 index 0000000000..9266e334b4 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/add_port_range @@ -0,0 +1,73 @@ +#!/usr/bin/python +import os +import sys +from sys import argv +import re + +# Quit if user doesn't input all the required variables + +if len(argv) < 3 or len(argv) > 5: + print('\n' + 'Usage: add_port_range EthernetX-X vlan [OPTIONS] ' + '\n' + '\n' + + 'Add ports as Tagged/Untagged and configure VLAN onto them' + '\n' + '\n' + + 'OPTIONS:' + '\n' + + '-u, --untagged' + '\n' + + '-h, ?, -?, --help Show this message and exit' + '\n') + quit() + + +# Quit if user inputs 'help' options + +if '?' in argv or '--help' in argv or '-help' in argv or 'help' in argv or '-?' in argv or '-h' in argv: + print('\n' + 'Usage: add_port_range EthernetX-X vlan [OPTIONS] ' + '\n' + '\n' + + 'Add ports as Tagged/Untagged and configure VLAN onto them' + '\n' + '\n' + + 'OPTIONS:' + '\n' + + '-u, --untagged' + '\n' + + '-h, ?, -?, --help Show this message and exit' + '\n') + quit() + +# User has to pass the VLAN argument using atleast the first two letters i.e. 'V/v' 'L/l' +pattern = '[Vv]+[Ll]' + +def match(text): + if re.match(pattern,text): + return ('Yes') + else: + return('No') + +if ((match(argv[2]) == 'Yes') and (int(argv[3]) < 4094)): + command2 = 'sudo config vlan add ' + str(argv[3]) + os.system(command2) +else: + print('\n' + 'Usage: add_port_range EthernetX-X vlan [OPTIONS] ' + '\n' + '\n' + + 'Add ports as Tagged/Untagged and configure VLAN onto them' + '\n' + '\n' + + 'OPTIONS:' + '\n' + + '-u, --untagged' + '\n' + + '-h, ?, -?, --help Show this message and exit' + '\n') + quit() + +#Find and create a list of all the interfaces +int_range1 = re.findall('[0-9]+-[0-9]+',argv[1]) +int_range = int_range1[0].split('-') + +#Add ports as untagged + +if ((match(argv[2]) == 'Yes') and ('-u' in argv)): + + for interface in range(int(int_range[0]),int(int_range[1])): + os.system('sudo config vlan member add -u ' + str(argv[3]) + ' Ethernet' + str(interface)) + +#Add ports as tagged + +elif ((match(argv[2]) == 'Yes') and len(argv)) == 4: + + for interface in range(int(int_range[0]),int(int_range[1])): + os.system('sudo config vlan member add ' + str(argv[3]) + ' Ethernet' + str(interface)) + +else: + print('\n' + 'Usage: add_port_range EthernetX-X vlan [OPTIONS] ' + '\n' + '\n' + + 'Add ports as Tagged/Untagged and configure VLAN onto them' + '\n' + '\n' + + 'OPTIONS:' + '\n' + + '-u, --untagged' + '\n' + + '-h, ?, -?, --help Show this message and exit' + '\n') + quit() + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/entropy.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/entropy.py new file mode 100644 index 0000000000..338e2ad9bc --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/entropy.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +import fcntl, struct +import time +from os import path + +RNDADDENTROPY=0x40085203 + +def avail(): + with open("/proc/sys/kernel/random/entropy_avail", mode='r') as avail: + return int(avail.read()) + +if path.exists("/proc/sys/kernel/random/entropy_avail"): + while 1: + while avail() < 2048: + with open('/dev/urandom', 'rb') as urnd, open("/dev/random", mode='wb') as rnd: + d = urnd.read(512) + t = struct.pack('ii', 4 * len(d), len(d)) + d + fcntl.ioctl(rnd, RNDADDENTROPY, t) + time.sleep(30) diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/reset-to-factory-default b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/reset-to-factory-default new file mode 100644 index 0000000000..dea0ad7fe3 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/reset-to-factory-default @@ -0,0 +1,84 @@ +#!/usr/bin/bash + +# This script is used to reset the current host file system and docker containers +# to the initial state of the firmware. + +# Because this is a factory reset hook, execute the script only if the hook script is +# either executed directorly or called as "config-setup factory" command +if [ -n $CMD ] && [ "$CMD" != "" ]; then + if [ "$CMD" != "factory" ]; then + exit 0 + fi +fi + +# if called from the sonic cli, then python click has already confirmed +# this, so just set var_yn to y here. + +if [ ! -r /tmp/sonic_cli_factory_reset ]; then +# if called by the monitor script then no ask confirm +PARENT_COMMAND=$(ps -o args= $PPID) +if [[ "$PARENT_COMMAND" != *"reset_button_monitor.py"* ]]; then + cat << EOF +This command will reset settings to factory defaults. +After resetting to factory defaults, switch will be reloaded immediately. +Do you really want to execute this command and reload the switch? [y/n] +EOF + + read var_yn + if [ "$var_yn" != "y" ]; then + exit 1 + fi +fi +else + var_yn="y" +fi + + +if [ "$EUID" -ne 0 ] + then echo "Root privileges are required for this operation" + exit 2 +fi + +# PB issue: 156474: Enable ZTP back.-start +ztp enable -y +ztp run -y +# PB issue: 156474: Enable ZTP back.-end + +# if there is any backup config saved via the command "config-setup backup" +# then remove it during factory reset, else these configs will get applied +# after factory reset. + +if [ -d /host/old_config ]; then + rm -rf /host/old_config +fi + +# stop SONiC services to prevent docker restart +# keep syslog for debugging +grep -v @ /etc/sonic/generated_services.conf | grep -v rsyslog-config.service | xargs systemctl disable +grep -v @ /etc/sonic/generated_services.conf | grep -v rsyslog-config.service | xargs systemctl stop + +# rm docker containers +docker ps -aq | xargs docker rm -f + +# rm overlay upper dir, ex: /host/image-3.0.0.5/rw +UPPER=`mount | grep "root-overlay on /" | sed 's/.*upperdir=\/root\([^,]*\),.*/\1/'` +rm -rf $UPPER +WORK=`mount | grep "root-overlay on /" | sed 's/.*workdir=\/root\([^)]*\)).*/\1/'` +rm -rf $WORK +sync;sync +echo 3 > /proc/sys/vm/drop_caches + +# rm other files in /host/ + +# create "image-xxx/platform/firsttime" +IMGPATH=`dirname $UPPER` +touch "$IMGPATH/platform/firsttime" +sync;sync + +rm -f /etc/sonic/config_db.json + +# force reboot if called by user +if [ "$var_yn" == "y" ]; then + shutdown -r now +fi + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/setup_all_ports_l2.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/setup_all_ports_l2.py new file mode 100644 index 0000000000..c1c9ba594e --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/setup_all_ports_l2.py @@ -0,0 +1,13 @@ +#!/usr/bin/python + +import os + +command1 = "" +command2 = "sudo config vlan add 10" +command3 = "" +os.system(command2) +for interface in range(0,54): + command1 = ('sudo config interface ip remove Ethernet' + str(interface) + " " + '10.0.0.' + str(interface*2) + '/31' + '\n') + os.system(command1) + command3 = "sudo config vlan member add -u 10 Ethernet" + str(interface) + '\n' + os.system(command3) diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/show-techsupport b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/show-techsupport new file mode 100644 index 0000000000..1b19b7a33d --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/show-techsupport @@ -0,0 +1,88 @@ +#!/usr/bin/python +import os +import sys +import re +import time +import sys + +interface_output = str(os.popen('show interface stat').read()) +pattern_int = re.findall('Ethernet[0-9]+',interface_output) + +os.system('sudo config feature state iccpd enabled') +mclag_output = str(os.popen('mclagdctl dump state').read()) + +commands = [] + +if not mclag_output: + + commands = commands + ['show platform syseeprom', 'show version', 'show boot', 'show tacacs', 'show radius', 'show aaa', + 'show platform psustatus', 'show platform pcieinfo', 'show platform temp', + 'show platform summary', 'show platform firmware status', + 'show platform fan', 'show interface status', 'sudo ifconfig -a', 'show ip interface', + 'show vlan brief', 'show lldp neighbors' , 'show lldp table', 'show ztp status', 'show ip bgp summary', 'show ip bgp neighbors', 'show route-map', + 'show interface portchannel', 'show ip route', 'sudo route -n', 'show arp', 'sudo arp -n', 'show mac', + 'show acl rule', 'sudo aclshow -a -vv', 'show acl table', 'show interface counters -a', 'show int autoneg status', + 'mclagdctl dump state','sudo show system-health detail', 'show system-mem', + 'docker ps', 'top -n 1', 'show uptime', 'show reboot-cause history', + 'sudo show system-health summary','show int transceiver presence', 'show int transceiver eeprom', 'show int transceiver error-status', + 'show int transceiver lpmode', 'show clock', 'show ntp', 'sudo timedatectl status', 'show runningconfiguration all'] + +else: + + mclag_domain = re.findall('Domain id: [0-9]+',mclag_output) + mclag_final = mclag_domain[0].split(':') + commands = commands + ['show platform syseeprom', 'show version', 'show boot', 'show tacacs', 'show radius', 'show aaa', + 'show platform psustatus', 'show platform pcieinfo', 'show platform temp', + 'show platform summary', 'show platform firmware status', + 'show platform fan', 'show interface status', 'sudo ifconfig -a', 'show ip interface', + 'show vlan brief', 'show lldp neighbors' , 'show lldp table', 'show ztp status', 'show ip bgp summary', 'show ip bgp neighbors', 'show route-map', + 'show interface portchannel', 'show ip route', 'sudo route -n', 'show arp', 'sudo arp -n', 'show mac', + 'show acl rule', 'sudo aclshow -a -vv', 'show acl table', 'show interface counters -a', 'show int autoneg status', + 'mclagdctl dump state', ('mclagdctl dump mac -i ' + str(mclag_final[1])), ('mclagdctl dump arp -i ' + str(mclag_final[1])), + 'sudo show system-health detail', 'show system-mem', + 'docker ps', 'top -n 1', 'show uptime', 'show reboot-cause history', + 'sudo show system-health summary','show int transceiver presence', 'show int transceiver eeprom', 'show int transceiver error-status', + 'show int transceiver lpmode', 'show clock', 'show ntp', 'sudo timedatectl status', 'show runningconfiguration all'] + +output = '' + +print('Fetching data....This might take a few minutes...') + +toolbar_width = 83 + +# setup toolbar +sys.stdout.write("[%s]" % (" " * toolbar_width)) +sys.stdout.flush() +sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '[' + +for command in commands: + time.sleep(0.1) + output = output + str(command) + '\n' + output = output + os.popen(str(command)).read() + '\n' + output = str(output) +# update the bar + sys.stdout.write("-") + sys.stdout.flush() + +for interface in pattern_int: + time.sleep(0.1) + int_command = '\n' + 'show interface counters detailed ' + str(interface) + '\n' + output = '\n' + output + int_command + '\n' + output = output + os.popen(str(int_command)).read() + output = str(output) +# update the bar + sys.stdout.write("-") + sys.stdout.flush() + +# end the progress bar +sys.stdout.write("\n") + +print('Generated a text file techsupport.txt in the tmp directory') +orig_stdout = sys.stdout +f = open('/tmp/techsupport.txt', 'w') +sys.stdout = f + +print(output) + +sys.stdout = orig_stdout +f.close() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/sse-g3748-init.sh b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/sse-g3748-init.sh new file mode 100644 index 0000000000..8b58a17efe --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/sse-g3748-init.sh @@ -0,0 +1,342 @@ +#!/bin/bash + +# Platform init script + +NUM_I2C_1_DEVICE=1 + +# MAIN MUX PCA9548 0x71 +NUM_MUX_9548_CH0=$(( ${NUM_I2C_DEVICE} + 1 )) # MUX #1 SFP28 Port1 EEPROM 0x50 +NUM_MUX_9548_CH1=$(( ${NUM_I2C_DEVICE} + 2 )) # MUX #2 SFP28 Port2 EEPROM 0x50 +NUM_MUX_9548_CH2=$(( ${NUM_I2C_DEVICE} + 3 )) # MUX #3 SFP28 Port3 EEPROM 0x50 +NUM_MUX_9548_CH3=$(( ${NUM_I2C_DEVICE} + 4 )) # MUX #4 SFP28 Port4 EEPROM 0x50 +NUM_MUX_9548_CH4=$(( ${NUM_I2C_DEVICE} + 5 )) # MUX #5 SFP28 Port5 EEPROM 0x50 +NUM_MUX_9548_CH5=$(( ${NUM_I2C_DEVICE} + 6 )) # MUX #6 SFP28 Port6 EEPROM 0x50 +NUM_MUX_9548_CH6=$(( ${NUM_I2C_DEVICE} + 7 )) # MUX #7 FAN EEPROM (0x56, 0x57) +NUM_MUX_9548_CH7=$(( ${NUM_I2C_DEVICE} + 8 )) # MUX #8 PSU EEPROM (0x56, 0x57) + +PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" +PATH_I2C_1_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I2C_1_DEVICE}" +PATH_MUX_9548_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_CH0}" +PATH_MUX_9548_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_CH1}" +PATH_MUX_9548_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_CH2}" +PATH_MUX_9548_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_CH3}" +PATH_MUX_9548_CH4="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_CH4}" +PATH_MUX_9548_CH5="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_CH5}" +PATH_MUX_9548_CH6="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_CH6}" +PATH_MUX_9548_CH7="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_CH7}" + +# I2C Address +### I2C MUX PCA9548 +I2C_ADDR_MUX_9548_CH0=0x71 # SFP28 MUX #1 EEPROM +I2C_ADDR_MUX_9548_CH1=0x71 # SFP28 MUX #2 EEPROM +I2C_ADDR_MUX_9548_CH2=0x71 # SFP28 MUX #3 EEPROM +I2C_ADDR_MUX_9548_CH3=0x71 # SFP28 MUX #4 EEPROM +I2C_ADDR_MUX_9548_CH4=0x71 # SFP28 MUX #5 EEPROM +I2C_ADDR_MUX_9548_CH5=0x71 # SFP28 MUX #6 EEPROM +I2C_ADDR_MUX_9548_CH6=0x71 # FAN MUX #7 EEPROM +I2C_ADDR_MUX_9548_CH7=0x71 # PSU MUX #8 EEPROM +### GPIO Expander +I2C_ADDR_IO_PCAL6416=0x20 # GPIO Expander PCAL6416A +I2C_ADDR_IO_PCAL6524=0x22 # GPIO Expander PCAL6524 +### peripheral +I2C_ADDR_FAN1_EEPROM=0x56 # FAN1 EEPROM +I2C_ADDR_FAN2_EEPROM=0x57 # FAN2 EEPROM +I2C_ADDR_PSU1_EEPROM=0x56 # PSU1 EEPROM +I2C_ADDR_PSU2_EEPROM=0x57 # PSU2 EEPROM +I2C_ADDR_TMP75_1=0x48 # LM75 temperature sensor 1 +I2C_ADDR_TMP75_2=0x49 # LM75 temperature sensor 2 +I2C_ADDR_QSFP_EEPROM=0x50 # SFP28 port EEPROM + +# IO Expander Register +# direction +PCAL6524_REG_PORT0_DIR=0x0C +PCAL6524_REG_PORT1_DIR=0x0D +PCAL6524_REG_PORT2_DIR=0x0E + +PCAL6416_REG_PORT0_DIR=6 +PCAL6416_REG_PORT1_DIR=7 + +# polarity +PCAL6524_REG_PORT0_POL=0x08 +PCAL6524_REG_PORT1_POL=0x09 +PCAL6524_REG_PORT2_POL=0x0A + +PCAL6416_REG_PORT0_POL=4 +PCAL6416_REG_PORT1_POL=5 + +# output +PCAL6524_REG_PORT0_OUT=0x04 +PCAL6524_REG_PORT1_OUT=0x05 +PCAL6524_REG_PORT2_OUT=0x06 + +PCAL6416_REG_PORT0_OUT=2 +PCAL6416_REG_PORT1_OUT=3 + +# input +PCAL6524_REG_PORT0_IN=0x00 +PCAL6524_REG_PORT1_IN=0x01 +PCAL6524_REG_PORT2_IN=0x02 + +PCAL6416_REG_PORT0_IN=0 +PCAL6416_REG_PORT1_IN=1 + +# Load required kernel-mode drivers +load_kernel_drivers() { + echo "Load SSE-G3748 Linux kernel drivers ...\n" + # Remove modules loaded during Linux init + # FIX-ME: This will be removed in the future when Linux init no longer loads these + rmmod i2c_dev + rmmod i2c_mv64xxx + rmmod smc_i2c_mux_pca954x + + # Carefully control the load order here to ensure consistent i2c bus numbering + depmod -a + modprobe g3748cpld + modprobe smc_i2c_mux_pca954x force_deselect_on_exit=1 + modprobe i2c_mv64xxx + modprobe i2c_dev + modprobe eeprom + modprobe mvMbusDrv +} + +# i2c MUX PCA9548 init +i2c_mux_init() { + # add MUX PCA9548 on I2C_1, assume to be i2c-2~9 + if [ ! -e ${PATH_MUX_9548_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_CH0}' > ${PATH_I2C_1_DEVICE}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_CH0} already init." + fi + +} + +# I/O Expander init +#---------------------------------------------------------------------------- +# PCAL6524 -- [I2C 0x22] 24 bits I/O for SFP status and TX_DIS +# Port 0 -- 7 6 5 4 3 2 1 0 +# TX_FAULT TX_DIS LOS PRESENT TX_FAULT TX_DIS LOS PRESENT +# SFP1 SFP1 SFP1 SFP1 SFP0 SFP0 SFP0 SFP0 +# +# Port 1 -- 7 6 5 4 3 2 1 0 +# TX_FAULT TX_DIS LOS PRESENT TX_FAULT TX_DIS LOS PRESENT +# SFP3 SFP3 SFP3 SFP3 SFP2 SFP2 SFP2 SFP2 +# +# Port 1 -- 7 6 5 4 3 2 1 0 +# TX_FAULT TX_DIS LOS PRESENT TX_FAULT TX_DIS LOS PRESENT +# SFP5 SFP5 SFP5 SFP5 SFP4 SFP4 SFP4 SFP4 +# [TX_DIS bit is output, all other bits are input] +#--------------------------------------------------------------------------- +# PCAL6416A -- [I2C 0x20] 16 bits I/) Expander SFP RS0 and RS1 +# Port 0 -- 7 6 5 4 3 2 1 0 +# RS0 RS1 RS0 RS1 RS0 RS1 RS0 RS1 +# SF2 SF3 SF0 SF1 +# +# Port 0 -- 7 6 5 4 3 2 1 0 +# N/A N/A N/A N/A RS0 RS1 RS0 RS1 +# SF4 SF5 +# [ All bits are output] +# According to SFF-8431 +# RS0 - low : RX signalling rate less than or equal to 4.25GBd +# high: RX signalling rate greater than 4.25GBd +# RS1 - low : TX signalling rate less than or equal to 4.25GBd +# high: TX signalling rate greater than 4.25GBd +#--------------------------------------------------------------------------- + +i2c_io_exp_init() { + echo "Init SFP status and ctrl IO Expander" + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6524} ${PCAL6524_REG_PORT0_DIR} 0xBB + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6524} ${PCAL6524_REG_PORT1_DIR} 0xBB + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6524} ${PCAL6524_REG_PORT2_DIR} 0xBB + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6524} ${PCAL6524_REG_PORT0_POL} 0x00 + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6524} ${PCAL6524_REG_PORT1_POL} 0x00 + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6524} ${PCAL6524_REG_PORT2_POL} 0x00 + + echo "Init SFP RS0 and RS1 IO Expander" + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6416} ${PCAL6416_REG_PORT0_DIR} 0x00 + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6416} ${PCAL6416_REG_PORT1_DIR} 0x00 + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6416} ${PCAL6416_REG_PORT0_POL} 0x00 + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6416} ${PCAL6416_REG_PORT1_POL} 0x00 + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6416} ${PCAL6416_REG_PORT0_OUT} 0xFF + sudo i2cset -y -r ${NUM_I2C_1_DEVICE} ${I2C_ADDR_IO_PCAL6416} ${PCAL6416_REG_PORT1_OUT} 0xFF +} + +update_share_password() +{ + echo "Update shared password !!!" + SONIC_VERSION=$(cat /etc/sonic/sonic_version.yml | grep "build_version" | sed -e "s/build_version: //g;s/'//g") + image_dir=$(cat /proc/cmdline | sed -e 's/.*loop=\(\S*\)\/.*/\1/') + if [ -f /host/reboot-cause/platform/last_boot_image ]; then + last_image_ver=$(cat /host/reboot-cause/platform/last_boot_image) + else + last_image_ver="" + fi + echo "last_image_ver=${last_image_ver}" + + find /host -name "*image-*" | sed -e 's/\/host\/image-//' | while read var ; do + #echo "var=${var} image_dir=${image_dir}" + if [ "image-${var}" != "$image_dir" ] && [ "$last_image_ver" != "${SONIC_VERSION}" ]; then + cp /host/image-${var}/rw/etc/shadow /host/${image_dir}/rw/etc/shadow + cp /host/image-${var}/rw/etc/passwd /host/${image_dir}/rw/etc/passwd + cp /host/image-${var}/rw/etc/gshadow /host/${image_dir}/rw/etc/gshadow + cp /host/image-${var}/rw/etc/group /host/${image_dir}/rw/etc/group + fi + done + + if [ -d /host/reboot-cause/platform ]; then + echo "${SONIC_VERSION}" | sudo tee /host/reboot-cause/platform/last_boot_image > /dev/null + fi +} + +check_and_install_certificate_key_for_telemetry() +{ + echo "Check and install certificate and key for telemetry." + if [ ! -d /etc/sonic/telemetry ]; then + sudo mkdir -p /etc/sonic/telemetry + fi + if [ -d /etc/sonic/telemetry ]; then + if [ ! -f /etc/sonic/telemetry/dsmsroot.key ] || [ ! -f /etc/sonic/telemetry/dsmsroot.cer ]; then + echo "Create dsmsroot.key and dsmsroot.cer in /etc/sonic/telemetry/" + sudo openssl req -x509 -newkey rsa:4096 -keyout /etc/sonic/telemetry/dsmsroot.key \ + -out /etc/sonic/telemetry/dsmsroot.cer -sha256 -days 365 -nodes -subj '/CN=lab-ca' + fi + + if [ ! -f /etc/sonic/telemetry/streamingtelemetryserver.csr ] || [ ! -f /etc/sonic/telemetry/streamingtelemetryserver.key ]; then + echo "Create streamingtelemetryserver.key, streamingtelemetryserver.csr in /etc/sonic/telemetry/" + sudo openssl req -new -newkey rsa:4096 -nodes \ + -keyout /etc/sonic/telemetry/streamingtelemetryserver.key -out /etc/sonic/telemetry/streamingtelemetryserver.csr \ + -subj "/CN=dev-pygnmi-sonic-003" + fi + + if [ ! -f /etc/sonic/telemetry/streamingtelemetryserver.cer ] || [ ! -f /etc/sonic/telemetry/dsmsroot.srl ]; then + echo "Create streamingtelemetryserver.cer, dsmsroot.srl in /etc/sonic/telemetry/" + sudo openssl x509 -req -in /etc/sonic/telemetry/streamingtelemetryserver.csr \ + -CA /etc/sonic/telemetry/dsmsroot.cer -CAkey /etc/sonic/telemetry/dsmsroot.key \ + -CAcreateserial -out /etc/sonic/telemetry/streamingtelemetryserver.cer \ + -days 365 -sha512 + fi + fi +} + +# - Main entry + +# Install kernel drivers required for i2c bus access +load_kernel_drivers +#entropy setting +#python /etc/entropy.py + +# LOGIC to enumerate SFP eeprom devices - send 0x50 to kernel i2c driver - initialize devices +# the mux may be enumerated at number 4 or 5 so we check for the mux and skip if needed +echo pca9548 ${I2C_ADDR_MUX_9548_CH0} > ${PATH_I2C_1_DEVICE}/new_device +sleep 2 + +# Get list of the mux channels +ismux_bus=$(i2cdetect -l|grep mux|cut -f1) + +# Enumerate the SFP eeprom device on each mux channel +#echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device +for mux in ${ismux_bus} +do + if [[ "${mux}" != "i2c-8" ]] && [[ "${mux}" != "i2c-9" ]]; then + echo optoe2 ${I2C_ADDR_QSFP_EEPROM} > /sys/class/i2c-adapter/${mux}/new_device + mux_num=$(echo ${mux} | cut -b5) + #sleep 1 + chmod 644 /sys/class/i2c-adapter/${mux}/${mux_num}-0050/eeprom + fi + + if [ "${mux}" == "i2c-8" ]; then + # Enumerate fan eeprom devices + echo eeprom 0x56 > /sys/class/i2c-adapter/i2c-8/new_device + #sleep 1 + chmod 644 /sys/class/i2c-adapter/i2c-8/8-0056/eeprom + + echo eeprom 0x57 > /sys/class/i2c-adapter/i2c-8/new_device + #sleep 1 + chmod 644 /sys/class/i2c-adapter/i2c-8/8-0057/eeprom + fi + + if [ "${mux}" == "i2c-9" ]; then + # Enumerate fan eeprom devices + echo eeprom 0x56 > /sys/class/i2c-adapter/i2c-9/new_device + #sleep 1 + chmod 644 /sys/class/i2c-adapter/i2c-9/9-0056/eeprom + + echo eeprom 0x57 > /sys/class/i2c-adapter/i2c-9/new_device + #sleep 1 + chmod 644 /sys/class/i2c-adapter/i2c-9/9-0057/eeprom + fi +done + +# Enumerate rtc +echo pcf8563 0x51 > /sys/bus/i2c/devices/i2c-0/new_device +# Enumerate system eeprom +echo 24c02 0x54 > /sys/class/i2c-adapter/i2c-0/new_device +#sleep 1 +#chmod 644 /sys/class/i2c-adapter/i2c-0/0-0054/eeprom + +# Enumerate PD eeprom +echo 24c02 0x52 > /sys/class/i2c-adapter/i2c-0/new_device +#sleep 1 +#chmod 644 /sys/class/i2c-adapter/i2c-0/0-0052/eeprom + +# Enumerate AC5X eeprom +echo 24c64 0x53 > /sys/class/i2c-adapter/i2c-0/new_device +#sleep 1 +#chmod 644 /sys/class/i2c-adapter/i2c-0/0-0053/eeprom + +# Enumerate temperature sensors +echo lm75 0x48 > /sys/class/i2c-adapter/i2c-0/new_device +sleep 1 +#chmod 644 /sys/class/i2c-adapter/i2c-0/0-0048/eeprom + +echo lm75 0x49 > /sys/class/i2c-adapter/i2c-0/new_device +sleep 1 +#chmod 644 /sys/class/i2c-adapter/i2c-0/0-0049/eeprom + +# Enumerate cpld +echo g3748cpld 0x66 > /sys/bus/i2c/devices/i2c-0/new_device +sleep 1 + +# Enumerate gpio +echo gpio 0x22 > /sys/class/i2c-adapter/i2c-1/new_device +#sleep 1 +#chmod 644 /sys/class/i2c-adapter/i2c-1/1-0022/ +echo gpio 0x20 > /sys/class/i2c-adapter/i2c-1/new_device +#sleep 1 +#chmod 644 /sys/class/i2c-adapter/i2c-1/1-0020/ + +sleep 1 +chmod 644 /sys/class/i2c-adapter/i2c-0/0-0054/eeprom +chmod 644 /sys/class/i2c-adapter/i2c-0/0-0052/eeprom +chmod 644 /sys/class/i2c-adapter/i2c-0/0-0053/eeprom + +i2c_io_exp_init + +# Updating password for each installed image +update_share_password + +# Check and setup certificate and key for telemetry +check_and_install_certificate_key_for_telemetry + +#setting boot_once to undefined everytime after reboot +/usr/bin/fw_setenv boot_once + + +#Handle 202211 image install from 202106 release image. ie. if platform +#directory sse_g3748 exists, this config is coming from 202106 code, +#the corresponding directory in 202211 is supermicro_sse_g3748. +# So we have to create a soft link from sse_g3748 to supermicro_sse_g3748. +# So let us delete the sse_g3748 directory first. + +sed "s/\/supermicro_sse_g3748/" /etc/sonic/sonic-enviornment -i + +tmp=$(mktemp) +jq '.DEVICE_METADATA.localhost.hwsku = "supermicro_sse_g3748"' /etc/sonic/config_db.json > "$tmp" && mv "$tmp" /etc/sonic/config_db.json + +if [ -d /usr/share/sonic/device/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748 ]; then + rm -rf /usr/share/sonic/device/arm64-supermicro_sse_g3748-r0/sse_g3748 + ln -s /usr/share/sonic/device/arm64-supermicro_sse_g3748-r0/supermicro_sse_g3748/ /usr/share/sonic/device/arm64-supermicro_sse_g3748-r0/sse_g3748 +fi + +hwclock -s + +exit 0 diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/sse-g3748_plt_setup.sh b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/sse-g3748_plt_setup.sh new file mode 100644 index 0000000000..dfbd649f30 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/sse-g3748_plt_setup.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +fw_uboot_env_cfg() +{ + echo "Setting up U-Boot environment..." + MACH_FILE="/host/machine.conf" + PLATFORM=`sed -n 's/onie_platform=\(.*\)/\1/p' $MACH_FILE` + + FW_ENV_DEFAULT='/dev/mtd1 0 0x10000 0x10000' + + echo $FW_ENV_DEFAULT + echo $FW_ENV_DEFAULT > /etc/fw_env.config +} + +sse_g3748_profile() +{ + MAC_ADDR=$(fw_printenv -n ethaddr) + find /usr/share/sonic/device/*sse_g3748* -name profile.ini | xargs sed -i "s/switchMacAddress=.*/switchMacAddress=$MAC_ADDR/g" + echo "SSE-G3748 Updating switch mac address ${MAC_ADDR}" +} + +update_modulelist() +{ + MODULE_FILE="/etc/modules-load.d/supermicro.conf" + + echo "# Module list to load during the boot" > $MODULE_FILE + echo "mvIntDrv" >> $MODULE_FILE + echo "psample" >> $MODULE_FILE +} + +haveged_service_cfg() +{ + # Workaround for failing haveged.service + sed -i 's/^DAEMON_ARGS=.*/DAEMON_ARGS="-w 1024 -d 16"/' /etc/default/haveged +} + +main() +{ + echo "Executing sse-g3748_plt_setup.sh ....." + fw_uboot_env_cfg + sse_g3748_profile + update_modulelist + haveged_service_cfg +} + +main $@ diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/techfile_v2.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/techfile_v2.py new file mode 100644 index 0000000000..1b19b7a33d --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/scripts/techfile_v2.py @@ -0,0 +1,88 @@ +#!/usr/bin/python +import os +import sys +import re +import time +import sys + +interface_output = str(os.popen('show interface stat').read()) +pattern_int = re.findall('Ethernet[0-9]+',interface_output) + +os.system('sudo config feature state iccpd enabled') +mclag_output = str(os.popen('mclagdctl dump state').read()) + +commands = [] + +if not mclag_output: + + commands = commands + ['show platform syseeprom', 'show version', 'show boot', 'show tacacs', 'show radius', 'show aaa', + 'show platform psustatus', 'show platform pcieinfo', 'show platform temp', + 'show platform summary', 'show platform firmware status', + 'show platform fan', 'show interface status', 'sudo ifconfig -a', 'show ip interface', + 'show vlan brief', 'show lldp neighbors' , 'show lldp table', 'show ztp status', 'show ip bgp summary', 'show ip bgp neighbors', 'show route-map', + 'show interface portchannel', 'show ip route', 'sudo route -n', 'show arp', 'sudo arp -n', 'show mac', + 'show acl rule', 'sudo aclshow -a -vv', 'show acl table', 'show interface counters -a', 'show int autoneg status', + 'mclagdctl dump state','sudo show system-health detail', 'show system-mem', + 'docker ps', 'top -n 1', 'show uptime', 'show reboot-cause history', + 'sudo show system-health summary','show int transceiver presence', 'show int transceiver eeprom', 'show int transceiver error-status', + 'show int transceiver lpmode', 'show clock', 'show ntp', 'sudo timedatectl status', 'show runningconfiguration all'] + +else: + + mclag_domain = re.findall('Domain id: [0-9]+',mclag_output) + mclag_final = mclag_domain[0].split(':') + commands = commands + ['show platform syseeprom', 'show version', 'show boot', 'show tacacs', 'show radius', 'show aaa', + 'show platform psustatus', 'show platform pcieinfo', 'show platform temp', + 'show platform summary', 'show platform firmware status', + 'show platform fan', 'show interface status', 'sudo ifconfig -a', 'show ip interface', + 'show vlan brief', 'show lldp neighbors' , 'show lldp table', 'show ztp status', 'show ip bgp summary', 'show ip bgp neighbors', 'show route-map', + 'show interface portchannel', 'show ip route', 'sudo route -n', 'show arp', 'sudo arp -n', 'show mac', + 'show acl rule', 'sudo aclshow -a -vv', 'show acl table', 'show interface counters -a', 'show int autoneg status', + 'mclagdctl dump state', ('mclagdctl dump mac -i ' + str(mclag_final[1])), ('mclagdctl dump arp -i ' + str(mclag_final[1])), + 'sudo show system-health detail', 'show system-mem', + 'docker ps', 'top -n 1', 'show uptime', 'show reboot-cause history', + 'sudo show system-health summary','show int transceiver presence', 'show int transceiver eeprom', 'show int transceiver error-status', + 'show int transceiver lpmode', 'show clock', 'show ntp', 'sudo timedatectl status', 'show runningconfiguration all'] + +output = '' + +print('Fetching data....This might take a few minutes...') + +toolbar_width = 83 + +# setup toolbar +sys.stdout.write("[%s]" % (" " * toolbar_width)) +sys.stdout.flush() +sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '[' + +for command in commands: + time.sleep(0.1) + output = output + str(command) + '\n' + output = output + os.popen(str(command)).read() + '\n' + output = str(output) +# update the bar + sys.stdout.write("-") + sys.stdout.flush() + +for interface in pattern_int: + time.sleep(0.1) + int_command = '\n' + 'show interface counters detailed ' + str(interface) + '\n' + output = '\n' + output + int_command + '\n' + output = output + os.popen(str(int_command)).read() + output = str(output) +# update the bar + sys.stdout.write("-") + sys.stdout.flush() + +# end the progress bar +sys.stdout.write("\n") + +print('Generated a text file techsupport.txt in the tmp directory') +orig_stdout = sys.stdout +f = open('/tmp/techsupport.txt', 'w') +sys.stdout = f + +print(output) + +sys.stdout = orig_stdout +f.close() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/service/sse-g3748-init.service b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/service/sse-g3748-init.service new file mode 100644 index 0000000000..201f60ada7 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/service/sse-g3748-init.service @@ -0,0 +1,14 @@ +[Unit] +Description=Platform SSE-G3748 Service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/sse-g3748-init.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL +#StandardOutput=tty + +[Install] +WantedBy=multi-user.target diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/setup.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/setup.py new file mode 100644 index 0000000000..bc44c7ddd7 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/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 Supermicro SSE-G3748 platforms', + + packages=['sonic_platform','sonic_platform.test'], + package_dir={'sonic_platform': 'sse-g3748/sonic_platform'}, +) + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/__init__.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/__init__.py new file mode 100644 index 0000000000..4bfefa0fb6 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/chassis.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/chassis.py new file mode 100644 index 0000000000..975e843216 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/chassis.py @@ -0,0 +1,548 @@ +#!/usr/bin/env python +################################################################## +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +################################################################## + +try: + import os + import sys + import glob + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan + from .fan_drawer import RealDrawer + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_py_common import logger + from sonic_platform.component import Component + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +smbus_present = 1 +try: + import smbus +except ImportError as e: + smbus_present = 0 + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + + +MAX_SELECT_DELAY = 3600 +COPPER_PORT_START = 1 +COPPER_PORT_END = 48 +SFP_PORT_START =49 +SFP_PORT_END = 54 +PORT_END = 54 +MAX_COMPONENT=3 + +# Device counts +MAX_G3748_FAN_DRAWERS = 1 +MAX_G3748_FANS_PER_DRAWER = 2 +MAX_G3748_PSU = 2 +MAX_G3748_THERMAL = 2 + +SYSLOG_IDENTIFIER = "chassis" +sonic_logger=logger.Logger(SYSLOG_IDENTIFIER) + +class Chassis(ChassisBase): + """ + Platform-specific Chassis class + derived from Dell S6000 platform. + customized for the platform. + """ + reset_reason_dict = {} + reset_reason_dict[0x02] = ChassisBase.REBOOT_CAUSE_POWER_LOSS + reset_reason_dict[0x20] = ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC + + reset_reason_dict[0x08] = ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU + reset_reason_dict[0x10] = ChassisBase.REBOOT_CAUSE_WATCHDOG + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + HOST_CHK_CMD = "docker > /dev/null 2>&1" + PLATFORM = "arm64-supermicro_sse_g3748-r0" + HWSKU = "supermicro_sse_g3748" + + I2C_CLASS_DIR = "/sys/class/i2c-adapter/" + I2C_DEV_MAPPING = (['i2c-0/0-0066/hwmon/', 1]) + + def __init__(self): + ChassisBase.__init__(self) + self.system_led_supported_color = ['off', 'green', 'amber', 'blue', 'blinking green', 'blinking amber', 'blinking blue'] + # Port numbers for Initialize SFP list + self.COPPER_PORT_START = COPPER_PORT_START + self.COPPER_PORT_END = COPPER_PORT_END + self.SFP_PORT_START = SFP_PORT_START + self.SFP_PORT_END = SFP_PORT_END + self.PORT_END = PORT_END + + G3748CPLD_I2C_DIR = "/sys/bus/i2c/devices/0-0066/" + + # for non-sfp ports create dummy objects for copper / non-sfp ports + for index in range(self.COPPER_PORT_START, self.COPPER_PORT_END+1): + sfp_node = Sfp(index, 'RJ45', 'N/A', 'N/A') + self._sfp_list.append(sfp_node) + + # Verify optoe2 driver SFP eeprom devices were enumerated and exist + # then create the sfp nodes + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + mux_dev = sorted(glob.glob("/sys/class/i2c-adapter/i2c-[2-7]")) + y = 0 + for index in range(self.SFP_PORT_START, self.SFP_PORT_END+1): + mux_dev_num = mux_dev[y] + port_i2c_map = mux_dev_num[-1] + y = y + 1 + port_eeprom_path = eeprom_path.format(port_i2c_map) + if not os.path.exists(port_eeprom_path): + sonic_logger.log_info("path %s didnt exist" % port_eeprom_path) + sfp_node = Sfp(index, 'SFP', port_eeprom_path, port_i2c_map) + self._sfp_list.append(sfp_node) + self.sfp_event_initialized = False + + # Instantiate ONIE system eeprom object + self._eeprom = Eeprom() + + # Construct lists fans, power supplies, thermals & components + drawer_num = MAX_G3748_FAN_DRAWERS + fan_num_per_drawer = MAX_G3748_FANS_PER_DRAWER + drawer_ctor = RealDrawer + fan_index = 0 + for drawer_index in range(drawer_num): + drawer = drawer_ctor(drawer_index) + self._fan_drawer_list.append(drawer) + for index in range(fan_num_per_drawer): + fan = Fan(fan_index, drawer) + fan_index += 1 + drawer._fan_list.append(fan) + self._fan_list.append(fan) + + for i in range(MAX_G3748_PSU): + psu = Psu(i) + self._psu_list.append(psu) + + for i in range(MAX_G3748_THERMAL): + thermal = Thermal(i) + self._thermal_list.append(thermal) + + for i in range(MAX_COMPONENT): + component = Component(i) + self._component_list.append(component) + + self.fan_sys_frontled_reg = G3748CPLD_I2C_DIR+"fan_sys_frontled".format() + + def _get_i2c_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _set_i2c_register(self, reg_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + + # Ensure that the write operation has succeeded + if (int(self._get_i2c_register(reg_file)) != value ): + time.sleep(3) + if (int(self._get_i2c_register(reg_file)) != value ): + rv = 'ERR' + + return rv + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + ############################################## + # EEPROM methods + ############################################## + + def get_eeprom(self): + """ + Retreives eeprom device on this chassis + Returns: + An object representing the hardware eeprom device + """ + return self._eeprom + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + 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 (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_str() + + def get_revision(self): + """ + Retrieves the device version of the chassis + Returns: + string: device version of chassis + """ + return self._eeprom.device_version() + + 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. + """ + return self._eeprom.system_eeprom_info() + + ############################################## + # SFP methods + ############################################## + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of physical SFP ports in a chassis, + starting from 1. + For example, 1 for first SFP port in the chassis and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp + + #index = index - 1 + #return super(Chassis, self).get_sfp(index) + + def get_port_or_cage_type(self, index): + """ + Retrieves sfp port or cage type corresponding to physical port + + Args: + index: An integer (>=0), the index of the sfp to retrieve. + The index should correspond to the physical port in a chassis. + For example:- + 1 for Ethernet0, 2 for Ethernet4 and so on for one platform. + 0 for Ethernet0, 1 for Ethernet4 and so on for another platform. + Returns: + The masks of all types of port or cage that can be supported on the port + Types are defined in sfp_base.py + Eg. + Both SFP and SFP+ are supported on the port, the return value should be 0x0a + which is 0x02 | 0x08 + """ + #if index in range(self.COPPER_PORT_START, self.COPPER_PORT_END): + if (index >= self.COPPER_PORT_START and index <= self.COPPER_PORT_END): + from sonic_platform_base.sfp_base import SfpBase + return SfpBase.SFP_PORT_TYPE_BIT_RJ45 + raise NotImplementedError + + def get_change_event(self, timeout=0): + """ + 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. + """ + # Initialize SFP event first + if not self.sfp_event_initialized: + from sonic_platform.sfp_event import sfp_event + self.sfp_event = sfp_event() + self.sfp_event.initialize() + self.MAX_SELECT_EVENT_RETURNED = self.PORT_END + self.sfp_event_initialized = True + + wait_for_ever = (timeout == 0) + port_dict = {} + if wait_for_ever: + # xrcvd will call this monitor loop in the "SYSTEM_READY" state + # logger.log_info(" wait_for_ever get_change_event %d" % timeout) + timeout = MAX_SELECT_DELAY + while True: + status = self.sfp_event.check_sfp_status( port_dict, timeout) + if not port_dict == {}: + break + else: + # At boot up and in "INIT" state call from xrcvd will have a timeout value + # return true without change after timeout and will transition to "SYSTEM_READY" + # logger.log_info(" initial get_change_event %d" % timeout ) + status = self.sfp_event.check_sfp_status( port_dict, timeout) + + if status: + return True, {'sfp':port_dict} + else: + return True, {'sfp':{}} + + ############################################## + # THERMAL methods + ############################################## + + def get_thermal_manager(self): + from .thermal_manager import ThermalManager + return ThermalManager + + ############################################## + # System LED methods + ############################################## + + def initizalize_system_led(self): + return True + + 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 + """ + #sonic_logger.log_warning(" System LED set_status_led color:{}".format(color)) + if color not in self.system_led_supported_color: + return False + + if (color == 'off'): + setbits = 0x00 + elif (color == 'blue'): + setbits = 0x03 + elif (color == 'amber'): + setbits = 0x02 + elif (color == 'green'): + setbits = 0x01 + elif (color == 'blinking blue'): + setbits = 0x07 + elif (color == 'blinking amber'): + setbits = 0x06 + elif (color == 'blinking green'): + setbits = 0x05 + else: + return False + + #sonic_logger.log_warning(" System LED set_status_led setbits:{}".format(setbits)) + # Write sys led + #if smbus_present == 0: # called from host (e.g. 'show system-health') + # cmdstatus, value = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0x11') + # value = int(value, 16) + # value = value & 0xF0 | setbits + # sonic_logger.log_warning(" System LED set color:{} value:{}".format(color, value)) + # cmdstatus, value = cmd.getstatusoutput('sudo i2cset -y 0 0x66 0x11 %d' % value) + # if cmdstatus: + # sonic_logger.log_warning(" System LED set %s failed" % value) + # return False + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICEREG = 0x11 + # value = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + # value = value & 0xF0 | setbits + # bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, value) + # sonic_logger.log_warning(" System LED set color:{} value:{}".format(color, value)) + + value = self._get_i2c_register(self.fan_sys_frontled_reg) + value = int(value) & 0xF0 | setbits + self._set_i2c_register(self.fan_sys_frontled_reg, value) + sonic_logger.log_warning(" System LED set color:{} value:{}".format(color, value)) + + return True + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + # Read sys led + #if smbus_present == 0: # called from host + # cmdstatus, value = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0x11') + # value = int(value, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0x11 + # value = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + #value = value & 0x07 + value = self._get_i2c_register(self.fan_sys_frontled_reg) + value = int(value) & 0x07 + + if value == 0x00: + color = 'off' + elif value == 0x01: + color = 'green' + elif value == 0x02: + color = 'amber' + elif value == 0x06: + color = 'amber_blink' + elif value == 0x05: + color = 'green_blink' + elif value == 0x04: + color = 'off' + else: + return None + + sonic_logger.log_warning(" System LED get color %s" % color) + return color + + def get_position_in_parent(self): + """ + Prasanna : This method is added, since M0 test named below fails without this method. + platform_tests/api/test_chassis.py::TestChassisApi::test_get_position_in_parent[lab-inno-01] + As done in other platforms such as nokia etc, return -1. + + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Prasanna : This method is added, since M0 test named below fails without this method. + platform_tests/api/test_chassis.py::TestChassisApi::test_is_replaceable[lab-inno-01] + As done in other platforms such as nokia etc, return False. + + Indicate whether Chassis is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + + 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. + """ + #lrr = self._get_cpld_register('mb_reboot_cause') + #if (lrr != 'ERR'): + # reset_reason = lrr + # if (reset_reason in self.reset_reason_dict): + # return (self.reset_reason_dict[reset_reason], None) + # + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + + def get_watchdog(self): + """ + Retrieves hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + try: + if self._watchdog is None: + from sonic_platform.watchdog import WatchdogImplBase + watchdog_device_path = "/dev/watchdog0" + self._watchdog = WatchdogImplBase(watchdog_device_path) + except Exception as e: + sonic_logger.log_warning(" Fail to load watchdog {}".format(repr(e))) + + return self._watchdog + + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/component.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/component.py new file mode 100644 index 0000000000..6cbaf70ace --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/component.py @@ -0,0 +1,166 @@ +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import sys + import subprocess + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + + +class Component(ComponentBase): + """platform-specific Component class""" + + CHASSIS_COMPONENTS = [ + ["U-Boot", "Performs initialization during booting"], + ["ONIE-VERSION", "ONIE - Open Network Install Environment"], + ["System-CPLD", "System - CPLD"], + ] + + def __init__(self, component_index): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + def get_model(self): + """ + Retrieves the part number of the component + + Returns: + string: Part number of component + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the component + + Returns: + string: Serial number of component + """ + return 'NA' + + def get_presence(self): + """ + Retrieves the presence of the component + + Returns: + bool: True if component is operating properly, False if not + """ + return True + + def get_status(self): + """ + Retrieves the presence of the component + + Returns: + bool: True if component is operating properly, False if not + """ + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether Chassis is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + + if self.index == 0: + cmdstatus, uboot_version = cmd.getstatusoutput('grep --null-data ^U-Boot /dev/mtd0ro | cut -d" " -f2') + return uboot_version + + if self.index == 1: + cmdstatus, onie_version = cmd.getstatusoutput('grep ^onie_version /host/machine.conf | cut -f2 -d"="') + return onie_version + + if self.index == 2: + cmdstatus, cpld_version = cmd.getstatusoutput('cat /sys/bus/i2c/devices/0-0066/cpld_version') + return cpld_version + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False + + + def get_available_firmware_version(self, image_path): + """ + Fix for issue: 160170:(SONIC-MGMT) platform_tests post /platform/chassis/component/ + returns empty reply. + + Retrieves the available firmware version of the component + Note: the firmware version will be read from image. + Args: + image_path: A string, path to firmware image + Returns: + A string containing the available firmware version of the component + """ + return "N/A" + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/eeprom.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/eeprom.py new file mode 100644 index 0000000000..1fb8adf599 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/eeprom.py @@ -0,0 +1,321 @@ +#!/usr/bin/env python + +######################################################################## +# Supermicro SSE-G3748 +# +# Module contains platform specific implementation of SONiC Platform +# Base API and provides the EEPROMs' information. +# +# The different EEPROMs available are as follows: +# - System EEPROM : Contains Serial number, Service tag, Base MA +# address, etc. in ONIE TlvInfo EEPROM format. +# - PSU EEPROM : Contains Serial number, Part number, Service Tag, +# PSU type, Revision. +# - Fan EEPROM : Contains Serial number, Part number, Service Tag, +# Fan type, Number of Fans in Fantray, Revision. +######################################################################## + + +try: + from sonic_platform_base.sonic_eeprom.eeprom_base import EepromDecoder + from sonic_platform_base.sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +# PSU eeprom fields in format required by EepromDecoder +psu_eeprom_format = [ + ('Frame Head', 's', 1), ('PSU Rev', 's', 3), ('Reserved_1', 's', 3), + ('Checksum', 's', 1), ('Reserved_2', 's', 2), + ('Part Number', 's', 17), ('Vendor', 's', 7), ('Serial Number', 's', 25), + ('Specification', 's', 141), ('Power', 's', 10), ('Mfg Date', 's', 3), + ('Reserved_3', 's', 43) + ] + +# Fan eeprom fields in format required by EepromDecoder +fan_eeprom_format = [ + ('Common Head', 's', 8), + ('Board Area Ver', 's', 1), ('Board Area Len', 's', 1), ('Language Code', 's', 1), + ('Mfg Date', 's', 3), ('Mfg TypeLen', 's', 1), ('Mfg Name', 's', 3), + ('Model TypeLen', 's', 1), ('Model', 's', 13), + ('Serial Number TypeLen', 's', 1), ('Serial Number', 's', 15), + ('Part Number TypeLen', 's',1), ('Part Number', 's', 12), + ('FRU TypeLen', 's', 1), ('FRU Id', 's', 1), + ('PCB Part Number TypeLen', 's', 1), ('PCB Part Number', 's', 12), + ('End Encoder', 's', 1), + ('Reserved', 's', 179) + ] + +sonic_logger = logger.Logger('eeprom') + +class Eeprom(TlvInfoDecoder): + """Supermicro SSE-G3748 platform-specific EEPROM class""" + + I2C_DIR = "/sys/class/i2c-adapter/" + + def __init__(self, is_psu=False, psu_index=0, is_fan=False, fan_index=0): + self.is_psu_eeprom = is_psu + self.is_fan_eeprom = is_fan + self.is_sys_eeprom = not (is_psu | is_fan) + + if self.is_sys_eeprom: + self.start_offset = 0 + #self.eeprom_path = "/etc/sonic/eeprom" + self.eeprom_path = self.I2C_DIR + "i2c-0/0-0054/eeprom" + # System EEPROM is in ONIE TlvInfo EEPROM format + super(Eeprom, self).__init__(self.eeprom_path, + self.start_offset, '', True) + self._load_system_eeprom() + else: + #print ("No other eeprom") + if self.is_psu_eeprom: + self.index = psu_index + self.start_offset = 0 + self.eeprom_path = self.I2C_DIR + "i2c-9/9-005{}/eeprom".format(self.index + 5) + self.format = psu_eeprom_format + + # Decode device eeprom as per specified format + EepromDecoder.__init__(self, self.eeprom_path, self.format, self.start_offset, '', True) + #sonic_logger.log_warning("_load_device_eeprom PSU##{}".format(self.index)) + #sonic_logger.log_warning("eeprom_path for PSU## is {}".format(self.eeprom_path)) + else: + self.index = fan_index + self.start_offset = 0 + self.eeprom_path = self.I2C_DIR + "i2c-8/8-005{}/eeprom".format(self.index + 5) + self.format = fan_eeprom_format + + # Fan EEPROM is in ONIE TlvInfo EEPROM format + EepromDecoder.__init__(self, self.eeprom_path, self.format, self.start_offset, '', True) + #sonic_logger.log_warning("_load_device_eeprom FAN##{}".format(self.index)) + #sonic_logger.log_warning("eeprom_path for FAN## is {}".format(self.eeprom_path)) + + self._load_device_eeprom() + + def _load_system_eeprom(self): + """ + Reads the system EEPROM and retrieves the values corresponding + to the codes defined as per ONIE TlvInfo EEPROM format and fills + them in a dictionary. + """ + try: + # Read System EEPROM as per ONIE TlvInfo EEPROM format. + self.eeprom_data = self.read_eeprom() + except Exception as e: + self.base_mac = 'NA' + self.serial_number = 'NA' + self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' + self.device_ver = 'NA' + self.eeprom_tlv_dict = dict() + else: + eeprom = self.eeprom_data + self.eeprom_tlv_dict = dict() + + if not self.is_valid_tlvinfo_header(eeprom): + self.base_mac = 'NA' + self.serial_number = 'NA' + self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' + self.device_ver = 'NA' + return + + total_length = (eeprom[9] << 8) | eeprom[10] + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + # Construct dictionary of eeprom TLV entries + 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 + + self.base_mac = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_MAC_BASE), 'NA') + self.serial_number = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_SERIAL_NUMBER), 'NA') + self.part_number = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_PART_NUMBER), 'NA') + self.model_str = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_PRODUCT_NAME), 'NA') + #self.serial = self.eeprom_tlv_dict.get( + # "0x%X" % (self._TLV_CODE_SERVICE_TAG), 'NA') + self.serial = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_SERIAL_NUMBER), 'NA') + self.device_ver = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_DEVICE_VERSION), 'NA') + + def _load_device_eeprom(self): + """ + Reads the Fan/PSU EEPROM and interprets as per the specified format + """ + self.serial_number = 'NA' + self.part_number = 'NA' + self.model_str = 'NA' + self.service_tag = 'NA' + self.mfg_date = 'NA' + self.hw_rev = 'NA' + + # PSU device eeproms use proprietary format + if self.is_psu_eeprom: + try: + # Read Fan/PSU EEPROM as per the specified format. + self.eeprom_data = EepromDecoder.read_eeprom(self) + except Exception as e: + sonic_logger.log_warning("Unable to read device eeprom for PSU#{}".format(self.index)) + return + + # Bail out if PSU eeprom unavailable + if self.eeprom_data[0] == 255: + sonic_logger.log_warning("Uninitialized device eeprom for PSU#{}".format(self.index)) + return + + (valid, data) = self._get_eeprom_field("Model") + if valid: + self.model_str = data.decode() + + (valid, data) = self._get_eeprom_field("Part Number") + if valid: + self.part_number = data.decode() + + (valid, data) = self._get_eeprom_field("PSU Rev") + if valid: + self.hw_rev = data.decode() + + # Early PSU device eeproms were not programmed with serial # + try: + (valid, data) = self._get_eeprom_field("Serial Number") + if valid: + self.serial_number = data.decode() + except Exception as e: + sonic_logger.log_warning("Unable to read serial# of PSU#{}".format(self.index)) + return + + # Fan device eeproms use proprietary proformat + else: + # Temporary hardcoded due to no eeprom data in FAN module + self.model_str = 'NA' + self.part_number = 'NA' + self.serial_number = 'NA' + + try: + # Read Fan EEPROM as per ONIE TlvInfo EEPROM format. + self.eeprom_data = EepromDecoder.read_eeprom(self) + except Exception as e: + sonic_logger.log_warning("Unable to read device eeprom for Fan#{}".format(self.index)) + return + + # Bail out if FAN eeprom unavailable + if self.eeprom_data[0] == 255 or self.eeprom_data[0] == 15: + sonic_logger.log_warning("Uninitialized device eeprom for Fan#{}".format(self.index)) + return + + (valid, data) = self._get_eeprom_field("Model") + if valid: + self.model_str = data.decode() + + (valid, data) = self._get_eeprom_field("Part Number") + if valid: + self.part_number = data.decode() + + # Early FAN device eeproms were not programmed with serial # + try: + (valid, data) = self._get_eeprom_field("Serial Number") + if valid: + self.serial_number = data.decode() + except Exception as e: + sonic_logger.log_warning("Unable to read serial# of FAN#{}".format(self.index)) + return + + def _get_eeprom_field(self, field_name): + """ + For a field name specified in the EEPROM format, returns the + presence of the field and the value for the same. + """ + field_start = 0 + for field in self.format: + field_end = field_start + field[2] + if field[0] == field_name: + return (True, self.eeprom_data[field_start:field_end]) + field_start = field_end + + return (False, None) + + def serial_number_str(self): + """ + Returns the serial number. + """ + return self.serial_number + + def part_number_str(self): + """ + Returns the part number. + """ + return self.part_number + + def revision_str(self): + """ + Return revision number + """ + return self.hw_rev + + def airflow_fan_type(self): + """ + Returns the airflow fan type. + """ + if self.is_psu_eeprom: + return int(self.psu_type.encode('hex'), 16) + if self.is_fan_eeprom: + return int(self.fan_type.encode('hex'), 16) + + # System EEPROM specific methods + def base_mac_addr(self): + """ + Returns the base MAC address found in the system EEPROM. + """ + return self.base_mac + + def modelstr(self): + """ + Returns the Model name. + """ + return self.model_str + + def serial_str(self): + """ + Returns the servicetag number. + Currently, we treat it as serial number from syseeprom + """ + return self.serial + + def device_version(self): + """ + Returns the device version. + """ + return self.device_ver + + 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/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/fan.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/fan.py new file mode 100644 index 0000000000..155e5f9439 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/fan.py @@ -0,0 +1,576 @@ +######################################################################## +# Supermicro SSE-G3748 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform +# +######################################################################## + + +try: + import math + import os + import sys + import time + from sonic_platform_base.fan_base import FanBase + from sonic_platform.eeprom import Eeprom + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 +try: + import smbus +except ImportError as e: + smbus_present = 0 + +sonic_logger = logger.Logger('fan') + + +MAX_G3748_FAN_SPEED = 17600 +WORKING_G3748_FAN_SPEED = 960 + +CPLD_I2C_ADDR = 0x66 +CPLD_FAN_STATUS_REG = 0x3B +CPLD_FAN_SPEED_PWM_REG = 0x3C +CPLD_FAN1_SPEED_CNT_REG = 0x3E +CPLD_FAN2_SPEED_CNT_REG = 0x3F + +#FAN_DIRECTION_EXHAUST = 'exhaust' +#FAN_DIRECTION_INTAKE = 'intake' + +class Fan(FanBase): + """Supermicro SSE-G3748 platform-specific Fan class""" + I2C_CLASS_DIR = "/sys/class/i2c-adapter/" + I2C_DEV_MAPPING = (['i2c-0/0-0066/hwmon/', 1]) + + def __init__(self, fan_index, fan_drawer, psu_fan=False, dependency=None): + self.is_psu_fan = psu_fan + G3748CPLD_I2C_DIR = "/sys/bus/i2c/devices/0-0066/" + + if not self.is_psu_fan: + # Fan is 1-based in Supermicro SSE-G3748 platforms + self.index = fan_index + 1 + self.fan_drawer = fan_drawer + + self.set_fan_pwm_reg = G3748CPLD_I2C_DIR+"hwmon/hwmon3/pwm{}".format(self.index) + self.get_fan_pwm_reg = G3748CPLD_I2C_DIR+"hwmon/hwmon3/pwm{}".format(self.index) + self.get_fan_speed_reg = G3748CPLD_I2C_DIR+"hwmon/hwmon3/fan{}_input".format(self.index) + self.get_fan_target_reg = G3748CPLD_I2C_DIR+"hwmon/hwmon3/fan{}_target".format(self.index) + self.set_fan_target_reg = G3748CPLD_I2C_DIR+"hwmon/hwmon3/fan{}_target".format(self.index) + self.get_fan_status_reg = G3748CPLD_I2C_DIR+"fan_status".format() + self.fan_sys_frontled_reg = G3748CPLD_I2C_DIR+"fan_sys_frontled".format() + + #self.fan_speed_cnt_reg = [ CPLD_FAN1_SPEED_CNT_REG, CPLD_FAN2_SPEED_CNT_REG] + self.max_fan_speed = MAX_G3748_FAN_SPEED + self.supported_led_color = ['off', 'green', 'red'] + + # Fan eeprom + self.eeprom = Eeprom(is_fan=True, fan_index=self.index) + else: + # this is a PSU Fan + self.index = fan_index + self.dependency = dependency + + def _get_i2c_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _set_i2c_register(self, reg_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + + # Ensure that the write operation has succeeded + if (int(self._get_i2c_register(reg_file)) != value ): + time.sleep(3) + if (int(self._get_i2c_register(reg_file)) != value ): + rv = 'ERR' + + return rv + + def get_name(self): + """ + Retrieves the name of the Fan + + Returns: + string: The name of the Fan + """ + if not self.is_psu_fan: + return "Fan{}".format(self.index) + else: + return "PSU{} Fan".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Fan Unit + + Returns: + bool: True if Fan is present, False if not + """ + #if smbus_present == 0: + # #sonic_logger.log_info("PMON fan-smbus ERROR - presence ") + # cmdstatus, fanstatus = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0x3B') + # fanstatus = int(fanstatus, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0x3B + # fanstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + # + #if self.index == 1: + # fanstatus = fanstatus & 4 + # if fanstatus == 4: + # return True + #if self.index == 2: + # fanstatus = fanstatus & 8 + # if fanstatus == 8: + # return True + #return False + fanstatus = self._get_i2c_register(self.get_fan_status_reg) + + if self.index == 1: + fanstatus = int(fanstatus) & 4 + if fanstatus == 4: + return True + if self.index == 2: + fanstatus = int(fanstatus) & 8 + if fanstatus == 8: + return True + return False + + def get_model(self): + """ + Retrieves the model number of the Fan + + Returns: + string: Model number of Fan. + """ + return self.eeprom.modelstr() + + def get_serial(self): + """ + Retrieves the serial number of the Fan + + Returns: + string: Serial number of Fan + """ + return self.eeprom.serial_number_str() + + def get_part_number(self): + """ + Retrieves the part number of the Fan + + Returns: + string: Part number of Fan + """ + return self.eeprom.part_number_str() + + def get_service_tag(self): + """ + Retrieves the service tag of the Fan + + Returns: + string: Service Tag of Fan + """ + #return self.eeprom.service_tag_str() + return 'N/A' + + def get_status(self): + """ + Retrieves the operational status of the Fan + + Returns: + bool: True if Fan is operating properly, False if not + """ + + #if smbus_present == 0: + # cmdstatus, fanstatus = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0x3B') + # fanstatus = int(fanstatus, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0x3B + # fanstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + #if self.index == 1: + # fanstatus = fanstatus & 0x10 + # if fanstatus == 0: + # return True + #if self.index == 2: + # fanstatus = fanstatus & 0x20 + # if fanstatus == 0: + # return True + #return False + fanstatus = self._get_i2c_register(self.get_fan_status_reg) + + if self.index == 1: + fanstatus = int(fanstatus) & 0x10 + if fanstatus == 0: + return True + if self.index == 2: + fanstatus = int(fanstatus) & 0x20 + if fanstatus == 0: + return True + return False + + def get_direction(self): + """ + Retrieves the fan airflow direction + Possible fan directions (relative to port-side of device) + Returns: + A string, either FAN_DIRECTION_INTAKE or + FAN_DIRECTION_EXHAUST depending on fan direction + """ + + #if smbus_present == 0: + # cmdstatus, fandir = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0x3B') + # fandir = int(fandir, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0x3B + # fandir = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + #if self.index == 1: + # fandir = fandir & 0x01 + # if fandir == 0: + # return self.FAN_DIRECTION_EXHAUST + #if self.index == 2: + # fandir = fandir & 0x02 + # if fandir == 0: + # return self.FAN_DIRECTION_EXHAUST + fandir = self._get_i2c_register(self.get_fan_status_reg) + + if self.index == 1: + fandir = int(fandir) & 0x01 + if fandir == 0: + return self.FAN_DIRECTION_EXHAUST + if self.index == 2: + fandir = int(fandir) & 0x02 + if fandir == 0: + return self.FAN_DIRECTION_EXHAUST + + #return 'intake' + return self.FAN_DIRECTION_INTAKE + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + + def get_speed(self): + """ + Retrieves the speed of a Front FAN in the tray in revolutions per + minute defined by 1-based index + :param index: An integer, 1-based index of the FAN to query speed + :return: integer, denoting front FAN speed + """ + speed = 0 + + #if smbus_present == 0: + # cmdstatus, speedcnt = cmd.getstatusoutput('sudo i2cget -y 0 0x66 %d' % self.fan_speed_cnt_reg[self.index - 1]) + # speedcnt = int(speedcnt, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = self.fan_speed_cnt_reg[self.index - 1] + # speedcnt = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + #speed_in_rpm = (5000 * 60) / speedcnt + #speed = 100*speed_in_rpm/MAX_G3748_FAN_SPEED + + speed_in_rpm = int(self._get_i2c_register(self.get_fan_speed_reg)) + + speed = 100*int(speed_in_rpm)/MAX_G3748_FAN_SPEED + if speed > 100: + speed = 100 + + #sonic_logger.log_warning("fan get_speed speed is %d" % speed ) + #sonic_logger.log_warning("get_speed FAN{} FAN_RPM={} FAN_PWM={}".format(self.index, speed_in_rpm, speed)) + return int(speed) + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed + which is considered tolerable + """ + if self.get_presence(): + # The tolerance value is fixed as 25% for this platform + tolerance = 25 + else: + tolerance = 0 + + return tolerance + + def set_speed(self, speed): + """ + Set fan speed to expected value + Args: + speed: An integer, the percentage of full fan speed to set + fan to, in the range 0 (off) to 100 (full speed) + Returns: + bool: True if set success, False if fail. + """ + if self.is_psu_fan: + return False + + # Set current fan duty cycle + # - 0x00 : fan off (0 rpm) + # - 0x0F : 50% duty cycle (8800 rpm) + # - 0x1F : 100% duty cycle (17600 rpm) + #fan_speed_pwm_reg_val = int((speed * 31) / 100) + + #if smbus_present == 0: + # cmdstatus, rv = cmd.getstatusoutput('sudo i2cset -y 0 0x66 0x3C %d' % fan_speed_pwm_reg_val) + # if cmdstatus: + # sonic_logger.log_warning("fan set_speed cmdstatus i2c write failed %s" % rv ) + # return False + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0x3C + # bus.write_byte_data(DEVICE_ADDRESS, DEVICE_REG, fan_speed_pwm_reg_val) + + rv = self._set_i2c_register(self.set_fan_pwm_reg, speed) + #sonic_logger.log_warning("fan set_speed PWM reg is %d" % speed ) + #sonic_logger.log_warning("set_speed FAN{} FAN_PWM_REG={}".format(self.index, speed)) + + return True + + ## - 0x00 : fan off + ## - 0x40 : 25% duty cycle + ## - 0x80 : 50% duty cycle (default) + ## - 0xff : 100% duty cycle (full speed) + #if speed in range(0, 6): + # fandutycycle = 0x00 + #elif speed in range(6, 41): + # fandutycycle = 64 + #elif speed in range(41, 76): + # fandutycycle = 128 + #elif speed in range(76, 101): + # fandutycycle = 255 + #else: + # return False + + #rv = self._set_i2c_register(self.set_fan_speed_reg, fandutycycle) + #sonic_logger.log_warning("fan set_speed PWM reg is %d" % speed ) + #if (rv != 'ERR'): + # return True + #else: + # return False + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if set success, False if fail. + + off , red and green are the only settings 7215 fans + """ + + if self.is_psu_fan or (color not in self.supported_led_color): + return False + if (color == self.STATUS_LED_COLOR_AMBER): + return False + if (color == self.STATUS_LED_COLOR_RED): + value = 0x10 + elif (color == self.STATUS_LED_COLOR_GREEN): + value = 0x20 + elif (color == self.STATUS_LED_COLOR_OFF): + value = 0x00 + else: + return False + + #if smbus_present == 0: + # return False + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICEREG = 0x11 + # original = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + # original = original & 0xCF + # ledstatus = original | value + # if (self.index == 1): + # if (color == self.STATUS_LED_COLOR_GREEN): + # ledstatus = ledstatus | 0x40 + # else: + # ledstatus = ledstatus & 0xBF + # elif self.index == 2: + # if (color == self.STATUS_LED_COLOR_GREEN): + # ledstatus = ledstatus | 0x80 + # else: + # ledstatus = ledstatus & 0x7F + # else: + # return False + + # bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, ledstatus) + # #sonic_logger.log_warning("fan set_status_led FAN{} FAN_LED_REG={}".format(self.index, ledstatus)) + + original = self._get_i2c_register(self.fan_sys_frontled_reg) + original = int(original) & 0xCF + ledstatus = original | value + if (self.index == 1): + if (color == self.STATUS_LED_COLOR_GREEN): + ledstatus = ledstatus | 0x40 + else: + ledstatus = ledstatus & 0xBF + elif self.index == 2: + if (color == self.STATUS_LED_COLOR_GREEN): + ledstatus = ledstatus | 0x80 + else: + ledstatus = ledstatus & 0x7F + else: + return False + + self._set_i2c_register(self.fan_sys_frontled_reg, ledstatus) + #sonic_logger.log_warning("set_status_led FAN{} FAN_SYS_LED_REG={} color={}".format(self.index, ledstatus, color)) + + return True + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + + if self.is_psu_fan: + return None + + #if smbus_present == 0: + # return None + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0x11 + # ledstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + ledstatus = int(self._get_i2c_register(self.fan_sys_frontled_reg)) + #sonic_logger.log_warning("get_status_led FAN{} FAN_SYS_LED_REG={}".format(self.index, ledstatus)) + + if ledstatus & 0x30 == 0x20: + if self.index == 1: + if ledstatus & 0x40 == 0x40: + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + elif self.index == 2: + if ledstatus & 0x80 == 0x80: + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + else: + return self.STATUS_LED_COLOR_OFF + elif ledstatus & 0x30 == 0x10: + return self.STATUS_LED_COLOR_RED + elif ledstatus & 0x30 == 0x00: + return self.STATUS_LED_COLOR_OFF + + #elif ledstatus & 0x30 == 0x20: + # return self.STATUS_LED_COLOR_RED + #elif ledstatus & 0x30 == 0x00: + # return self.STATUS_LED_COLOR_OFF + + #if self.index == 1: + # ledstatus = (ledstatus & 0x40) + # ledstatus = ledstatus >> 4 + #elif self.index == 2: + # ledstatus = (ledstatus & 0x80) + # ledstatus = ledstatus >> 6 + #if ledstatus == 0x02: + # return self.STATUS_LED_COLOR_RED + #elif ledstatus == 0x1: + # return self.STATUS_LED_COLOR_GREEN + #else: + # return self.STATUS_LED_COLOR_OFF + + 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) + """ + #speed = 0 + + #if smbus_present == 0: + # cmdstatus, rv = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0x3C') + # if cmdstatus: + # sonic_logger.log_warning("fan get_target_speed cmdstatus i2c get failed %s" % rv ) + # return speed + # rv = int(rv, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0x3C + # rv = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + #if rv > 0x1F: + # sonic_logger.log_warning("fan get_target_speed return value out of boundry") + # return speed + #speed = rv * 100 / 0x1F + speed = int(self._get_i2c_register(self.get_fan_pwm_reg)) + + #sonic_logger.log_warning("get_target_speed FAN{} FAN_PWM_REG={}".format(self.index, speed)) + #sonic_logger.log_warning("fan get_target_speed speed is %d" % int(speed) ) + return int(speed) + + #fan_duty = self._get_i2c_register(self.set_fan_speed_reg) + #if (fan_duty != 'ERR'): + # dutyspeed = int(fan_duty) + # if dutyspeed == 0: + # speed = 0 + # elif dutyspeed == 64: + # speed = 25 + # elif dutyspeed == 128: + # speed = 50 + # elif dutyspeed == 255: + # speed = 100 + # + #return speed diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/fan_drawer.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/fan_drawer.py new file mode 100644 index 0000000000..e19c6ee385 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/fan_drawer.py @@ -0,0 +1,102 @@ +############################################################################# +# Supermicro SSE-G3748 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan Drawer status which is available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +sonic_logger = logger.Logger('fan_drawer') + +class G3748FanDrawer(FanDrawerBase): + def __init__(self, index): + super(G3748FanDrawer, self).__init__() + self._index = index + 1 + self._led = None + + def get_index(self): + return self._index + + def get_presence(self): + return self._fan_list[0].get_presence() + + def get_model(self): + """ + Retrieves the model number of the Fan Drawer + Returns: + string: Part number of Fan Drawer + """ + return self._fan_list[0].get_model() + + def get_serial(self): + """ + Retrieves the serial number of the Fan Drawer + Returns: + string: Serial number of Fan + """ + return self._fan_list[0].get_serial() + + def get_status(self): + """ + Retrieves the operational status of the Fan Drawer + Returns: + bool: True if Fan is operating properly, False if not + """ + return self._fan_list[0].get_status() + + def get_direction(self): + return 'intake' + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + + Args: + color: A string representing the color with which to set the + fan drawer status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + return self._fan_list[0].set_status_led(color) + + def get_status_led(self): + """ + Gets the state of the fan drawer LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings + """ + return self._fan_list[0].get_status_led() + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self._index + + +# For Supermicro SSE-G3748 platforms with fan drawer(s) +class RealDrawer(G3748FanDrawer): + def __init__(self, index): + super(RealDrawer, self).__init__(index) + self._name = 'drawer{}'.format(self._index) + + def get_name(self): + return self._name diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/pcie.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/pcie.py new file mode 100644 index 0000000000..195a6098fd --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/pcie.py @@ -0,0 +1,57 @@ +####################################################################### +# Module contains a platform specific implementation of SONiC Platform +# Base PCIe class +####################################################################### +import os +import re + +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +SYSFS_PCI_DEVICE_PATH = '/sys/bus/pci/devices/' + +class Pcie(PcieUtil): + # Check the current PCIe device with config file and return the result. + # It uses bus from _device_id_to_bus_map instead of from default in yaml file. + def get_pcie_check(self): + self.load_config_file() + for item_conf in self.confInfo: + id_conf = item_conf["id"] + dev_conf = item_conf["dev"] + fn_conf = item_conf["fn"] + bus_conf = self._device_id_to_bus_map.get(str(id_conf)) + if bus_conf and self.check_pcie_sysfs(bus=int(bus_conf, base=16), device=int(dev_conf, base=16), + func=int(fn_conf, base=16)): + item_conf["result"] = "Passed" + else: + item_conf["result"] = "Failed" + return self.confInfo + + # Create bus from device id and store in self._device_id_to_bus_map + def _create_device_id_to_bus_map(self): + self._device_id_to_bus_map = {} + self.load_config_file() + device_folders = os.listdir(SYSFS_PCI_DEVICE_PATH) + # Search for device folder name pattern in sysfs tree. + # If there is a matching pattern found, create an id to bus mapping. + # Save the mapping in self._device_id_to_bus_map[ ]. + # Device folder name pattern: dddd:bb:ii:f + # where dddd - 4 hex digit of domain + # bb - 2 hex digit of bus + # ii - 2 hex digit of id + # f - 1 digit of fn + for folder in device_folders: + pattern_for_device_folder = re.search('....:(..):..\..', folder) + if pattern_for_device_folder: + bus = pattern_for_device_folder.group(1) + with open(os.path.join('/sys/bus/pci/devices', folder, 'device'), 'r') as device_file: + # The 'device' file contain an hex repesantaion of the id key in the yaml file. + # We will strip the new line character, and remove the 0x prefix that is not needed. + device_id = device_file.read().strip().replace('0x', '') + self._device_id_to_bus_map[device_id] = bus + + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) + self._create_device_id_to_bus_map() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/platform.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/platform.py new file mode 100644 index 0000000000..0b67a68b86 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/platform.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/psu.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/psu.py new file mode 100644 index 0000000000..dc7443afff --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/psu.py @@ -0,0 +1,527 @@ +####################################################################### +# Supermicro SSE-G3748 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + +try: + import os + import sys + from sonic_platform_base.psu_base import PsuBase + from sonic_py_common import logger + from sonic_platform.eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 +try: + import smbus +except ImportError as e: + smbus_present = 0 + +sonic_logger = logger.Logger('psu') + +class Psu(PsuBase): + """Supermicro platform-specific PSU class for SSE-G3748 """ + def __init__(self, psu_index): + PsuBase.__init__(self) + self.PSU_OUTPUT_VOLTAGE_MIN = 11 + self.PSU_OUTPUT_VOLTAGE_MAX = 13 + G3748CPLD_I2C_DIR = "/sys/bus/i2c/devices/0-0066/" + # PSU is 1-based in SMC G3748 platforms + self.index = psu_index + 1 + self._fan_list = [] + + self.get_psu_voltage_reg = G3748CPLD_I2C_DIR+"hwmon/hwmon3/in{}_input".format(self.index) + self.get_psu_status_reg = G3748CPLD_I2C_DIR+"psu_status".format() + self.psu_frontled_reg = G3748CPLD_I2C_DIR+"psu_frontled".format() + + # PSU eeprom + self.eeprom = Eeprom(is_psu=True, psu_index=self.index) + + def _read_sysfs_file(self, sysfs_file): + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _write_sysfs_file(self, sysfs_file, value): + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + + # Ensure that the write operation has succeeded + if (int(self._read_sysfs_file(sysfs_file)) != value ): + time.sleep(3) + if (int(self._read_sysfs_file(sysfs_file)) != value ): + rv = 'ERR' + + return rv + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + + #if smbus_present == 0: # if called from psuutil outside of pmon + # cmdstatus, psustatus = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0xa') + # psustatus = int(psustatus, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0xa + # psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + # + #if self.index == 1: + # psustatus = psustatus & 1 + # if psustatus == 1: + # return True + #if self.index == 2: + # psustatus = psustatus & 2 + # if psustatus == 2: + # return True + psustatus = self._read_sysfs_file(self.get_psu_status_reg) + + if self.index == 1: + psustatus = int(psustatus) & 1 + if psustatus == 1: + return True + if self.index == 2: + psustatus = int(psustatus) & 2 + if psustatus == 2: + return True + + return False + + def get_model(self): + """ + Retrieves the model of the PSU + + Returns: + string: Model name of PSU. + Part number of PSU if model name is not available. + """ + if self.eeprom.modelstr() == "NA": + return self.eeprom.part_number_str() + else: + return self.eeprom.modelstr() + + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + return self.eeprom.serial_number_str() + + + def get_part_number(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + return self.eeprom.part_number_str() + + def get_revision(self): + """ + Retrieves the hardware revision number of the PSU + + Returns: + string: Revision number of PSU + """ + return self.eeprom.revision_str() + + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + + #if smbus_present == 0: + # cmdstatus, psustatus = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0xa') + # psustatus = int(psustatus, 16) + # sonic_logger.log_warning("PMON psu-smbus - presence = 0 ") + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0xa + # psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + # + #if self.index == 1: + # psustatus = psustatus & 4 + # if psustatus == 4: + # return False + #if self.index == 2: + # psustatus = psustatus & 8 + # if psustatus == 8: + # return False + psustatus = self._read_sysfs_file(self.get_psu_status_reg) + + if self.index == 1: + psustatus = int(psustatus) & 4 + if psustatus == 4: + return False + if self.index == 2: + psustatus = int(psustatus) & 8 + if psustatus == 8: + return False + + return True + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + #if smbus_present == 0: + # cmdstatus, psustatus = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0xa') + # psustatus = int(psustatus, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0xa + # psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + #if self.index == 1: + # psustatus = psustatus & 4 + # if psustatus == 0: + # psu_voltage = 12.0 + # return psu_voltage + #if self.index == 2: + # psustatus = psustatus & 8 + # if psustatus == 0: + # psu_voltage = 12.0 + # return psu_voltage + psustatus = self._read_sysfs_file(self.get_psu_status_reg) + + if self.index == 1: + psustatus = int(psustatus) & 4 + if psustatus == 0: + psu_voltage = 12.0 + return psu_voltage + if self.index == 2: + psustatus = int(psustatus) & 8 + if psustatus == 0: + psu_voltage = 12.0 + return psu_voltage + + psu_voltage = 0.0 + return psu_voltage + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + + #if smbus_present == 0: + # cmdstatus, psustatus = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0xa') + # psustatus = int(psustatus, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0xa + # psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + #if self.index == 1: + # psustatus = psustatus & 4 + # if psustatus == 0: + # return True + #if self.index == 2: + # psustatus = psustatus & 8 + # if psustatus == 0: + # return True + psustatus = self._read_sysfs_file(self.get_psu_status_reg) + + if self.index == 1: + psustatus = int(psustatus) & 4 + if psustatus == 0: + return True + if self.index == 2: + psustatus = int(psustatus) & 8 + if psustatus == 0: + return True + + return False + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the + PSU status LED + Returns: + bool: True if status LED state is set successfully, False if + not + """ + # The firmware running in the PSU controls the LED + # and the PSU LED state cannot be changed from CPU. + + # Read current psu led register + #if smbus_present == 0: + # cmdstatus, psuled = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0x12') + # psuled = int(psuled, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0x12 + # psuled = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + psuled = self._read_sysfs_file(self.psu_frontled_reg) + + if color == self.STATUS_LED_COLOR_GREEN: + if self.index == 1: + psuled = int(psuled) & 0x0C | 0x02 + if self.index == 2: + psuled = int(psuled) & 0x03 | 0x08 + if color == self.STATUS_LED_COLOR_RED: + if self.index == 1: + psuled = int(psuled) & 0x0C | 0x01 + if self.index == 2: + psuled = int(psuled) & 0x03 | 0x04 + if color == self.STATUS_LED_COLOR_OFF: + if self.index == 1: + psuled = int(psuled) & 0x0C + if self.index == 2: + psuled = int(psuled) & 0x03 + + #if smbus_present == 0: + # cmdstatus, psustatus = cmd.getstatusoutput('sudo i2cset -y 0 0x66 0x12 %d' % psuled) + # psustatus = int(psustatus, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0x12 + # psustatus = bus.write_byte_data(DEVICE_ADDRESS, DEVICE_REG, psuled) + + self._write_sysfs_file(self.psu_frontled_reg, psuled) + #sonic_logger.log_warning("set_status_led PSU{} color={} PSU_LED_REG={}".format(self.index, color, psuled)) + + return True + + def get_status_master_led(self): + """ + Gets the state of the front panel PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if (not os.path.isfile("/sys/class/gpio/psuLedGreen/value") or + not os.path.isfile("/sys/class/gpio/psuLedAmber/value")): + return None + + green = self._read_sysfs_file("/sys/class/gpio/psuLedGreen/value") + amber = self._read_sysfs_file("/sys/class/gpio/psuLedAmber/value") + if green == "ERR" or amber == "ERR": + return None + if green == "1": + return self.STATUS_LED_COLOR_GREEN + elif amber == "1": + return self.STATUS_LED_COLOR_AMBER + else: + return None + + def set_status_master_led(self, color): + """ + Sets the state of the front panel PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if + not + """ + if (not os.path.isfile("/sys/class/gpio/psuLedGreen/value") or + not os.path.isfile("/sys/class/gpio/psuLedAmber/value")): + return False + + if color == self.STATUS_LED_COLOR_GREEN: + rvg = self._write_sysfs_file("/sys/class/gpio/psuLedGreen/value", 1) + if rvg != "ERR": + rva = self._write_sysfs_file("/sys/class/gpio/psuLedAmber/value", 0) + elif color == self.STATUS_LED_COLOR_AMBER: + rvg = self._write_sysfs_file("/sys/class/gpio/psuLedGreen/value", 0) + if rvg != "ERR": + rva = self._write_sysfs_file("/sys/class/gpio/psuLedAmber/value", 1) + else: + return False + + if rvg == "ERR" or rva == "ERR": + return False + + return True + + def get_power(self): + """ + Retrieves the output power of the PSU + + Returns: + string: output power of PSU + """ + #return self.eeprom.power_str() + #if smbus_present == 0: + # cmdstatus, psustatus = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0xa') + # psustatus = int(psustatus, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0xa + # psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + # + #if self.index == 1: + # psustatus = psustatus & 4 + # if psustatus == 0: + # psu_power = 150 + # return psu_power + #if self.index == 2: + # psustatus = psustatus & 8 + # if psustatus == 0: + # psu_power = 150 + # return psu_power + psustatus = self._read_sysfs_file(self.get_psu_status_reg) + + if self.index == 1: + psustatus = int(psustatus) & 4 + if psustatus == 0: + psu_power = 150 + return psu_power + if self.index == 2: + psustatus = int(psustatus) & 8 + if psustatus == 0: + psu_power = 150 + return psu_power + + psu_power = 0 + return psu_power + + def get_current(self): + """ + Retrieves the output current of the PSU + + Returns: + string: output current of PSU + """ + #return self.eeprom.current_str() + #if smbus_present == 0: + # cmdstatus, psustatus = cmd.getstatusoutput('sudo i2cget -y 0 0x66 0xa') + # psustatus = int(psustatus, 16) + #else: + # bus = smbus.SMBus(0) + # DEVICE_ADDRESS = 0x66 + # DEVICE_REG = 0xa + # psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + # + #if self.index == 1: + # psustatus = psustatus & 4 + # if psustatus == 0: + # psu_current = 12.5 + # return psu_current + #if self.index == 2: + # psustatus = psustatus & 8 + # if psustatus == 0: + # psu_current = 12.5 + # return psu_current + psustatus = self._read_sysfs_file(self.get_psu_status_reg) + + if self.index == 1: + psustatus = int(psustatus) & 4 + if psustatus == 0: + psu_current = 12.5 + return psu_current + if self.index == 2: + psustatus = int(psustatus) & 8 + if psustatus == 0: + psu_current = 12.5 + return psu_current + + psu_current = 0.0 + return psu_current + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + Returns: + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + return float(self.PSU_OUTPUT_VOLTAGE_MAX) + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + Returns: + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + return float(self.PSU_OUTPUT_VOLTAGE_MIN) + + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/sfp.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/sfp.py new file mode 100644 index 0000000000..cccffc4cef --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/sfp.py @@ -0,0 +1,573 @@ +############################################################################# +# Supermicro SSE-G3748 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information by using sfp refactor spec +# +############################################################################# +# +# There are 2 IO Expander connect to SFP transceiver status/control +#--------------------------------------------------------------------------- +# +# SFP transceiver status: +# +# PCAL6524 -- [I2C 0x22] 24 bits I/O for SFP status and TX_DIS +# Port 0 -- 7 6 5 4 3 2 1 0 +# TX_FAULT TX_DIS LOS PRESENT TX_FAULT TX_DIS LOS PRESENT +# SFP1 SFP1 SFP1 SFP1 SFP0 SFP0 SFP0 SFP0 +# +# Port 1 -- 7 6 5 4 3 2 1 0 +# TX_FAULT TX_DIS LOS PRESENT TX_FAULT TX_DIS LOS PRESENT +# SFP3 SFP3 SFP3 SFP3 SFP2 SFP2 SFP2 SFP2 +# +# Port 2 -- 7 6 5 4 3 2 1 0 +# TX_FAULT TX_DIS LOS PRESENT TX_FAULT TX_DIS LOS PRESENT +# SFP5 SFP5 SFP5 SFP5 SFP4 SFP4 SFP4 SFP4 +# [TX_DIS bit is output, all other bits are input] +#--------------------------------------------------------------------------- +# +# SFP transceiver control: +# +# PCAL6416A -- [I2C 0x20] 16 bits I/) Expander SFP RS0 and RS1 +# Port 0 -- 7 6 5 4 3 2 1 0 +# RS0 RS1 RS0 RS1 RS0 RS1 RS0 RS1 +# SF2 SF3 SF0 SF1 +# +# Port 0 -- 7 6 5 4 3 2 1 0 +# N/A N/A N/A N/A RS0 RS1 RS0 RS1 +# SF4 SF5 +# [ All bits are output] +# +############################################################################# + +try: + import os + import sys + import time + import subprocess + from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase + from sonic_platform_base.sfp_base import SfpBase + + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + +QSFP_INFO_OFFSET = 128 +SFP_INFO_OFFSET = 0 +QSFP_DD_PAGE0 = 0 + +SFP_TYPE_LIST = [ + '0x3' # SFP/SFP+/SFP28 and later +] +QSFP_TYPE_LIST = [ + '0x0c', # QSFP + '0x0d', # QSFP+ or later + '0x11' # QSFP28 or later +] +QSFP_DD_TYPE_LIST = [ + '0x18' #QSFP_DD Type +] + +OSFP_TYPE_LIST = [ + '0x19' # OSFP 8X Type +] + +COPPER_TYPE = "COPPER" +SFP_TYPE = "SFP" +RJ45_TYPE = "RJ45" + +# SFP PORT numbers +SFP_PORT_START = 49 +SFP_PORT_END = 54 + +SYSLOG_IDENTIFIER = "xcvrd" +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) + +class Sfp(SfpOptoeBase): + """ + Supermicro SSE-G3748 refactor Platform-specific Sfp class + """ + + def __init__(self, index, sfp_type, eeprom_path, port_i2c_map): + SfpOptoeBase.__init__(self) + self.index = index + self.port_num = index + self.eeprom_path = eeprom_path + self.sfp_eeprom_path = eeprom_path + #port_type is the native port type and sfp_type is the transceiver type + #sfp_type will be detected in get_transceiver_info + self.port_type = sfp_type + if (self.index < SFP_PORT_START): + self.port_type = RJ45_TYPE + self.sfp_type = self.port_type + + self._port_to_i2c_mapping = port_i2c_map + self.port_name = sfp_type + str(index) + + self._initialize_media(delay=False) + +# 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 +# sonic_logger.log_warning("sfp __get_path_to_port_config_file hwsku_path = %s" % hwsku_path) + + def sfp_status_get_value(self, port_off): + reg_in = [0x00, 0x00, 0x01, 0x01, 0x02, 0x02] + + if smbus_present == 0: # if called from sfputil outside of pmon + regin = reg_in[port_off] + cmdstatus, sfpstatus = cmd.getstatusoutput('sudo i2cget -y 1 0x22 %d' % regin) + if cmdstatus: + sonic_logger.log_warning("sfp cmdstatus i2c get failed %s" % status) + return False + sfpStatus = int(sfpstatus, 16) + else: + bus = smbus.SMBus(1) + DEVICE_ADDRESS = 0x22 + DEVICE_REG = reg_in[port_off] + sfpStatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + return sfpStatus + + def sfp_status_set_value(self, port_off, val): + reg_out = [0x04, 0x04, 0x05, 0x05, 0x06, 0x06] + + if smbus_present == 0: # if called from sfputil outside of pmon + regout = reg_out[port_off] + i2csetcmd = "i2cset -y 1 0x22 " + hex(regout) + hex(val) + cmdstatus, output = cmd.getstatusoutput(i2csetcmd) + if cmdstatus: + sonic_logger.log_warning("sfp cmdstatus i2c write failed %s" % output ) + return False + else: + bus = smbus.SMBus(1) + DEVICE_ADDRESS = 0x22 + DEVICE_REG = reg_out[port_off] + bus.write_byte_data(DEVICE_ADDRESS, DEVICE_REG, val) + + return True + + def _initialize_media(self, delay=False): + """ + Initialize the media type and eeprom driver for SFP + """ + if delay: + time.sleep(1) + self._xcvr_api = None + self.get_xcvr_api() + + self.set_media_type() + self.reinit_sfp_driver() + + def set_media_type(self): + """ + Reads optic eeprom byte to determine media type inserted + """ + eeprom_raw = [] + eeprom_raw = self._xcvr_api_factory._get_id() + if eeprom_raw is not None: + eeprom_raw = hex(eeprom_raw) + if eeprom_raw in SFP_TYPE_LIST: + self.sfp_type = 'SFP' + elif eeprom_raw in QSFP_TYPE_LIST: + self.sfp_type = 'QSFP' + elif eeprom_raw in QSFP_DD_TYPE_LIST: + self.sfp_type = 'QSFP_DD' + else: + #Set native port type if EEPROM type is not recognized/readable + self.sfp_type = self.port_type + else: + self.sfp_type = self.port_type + + return self.sfp_type + + def reinit_sfp_driver(self): + """ + Changes the driver based on media type detected + """ + """ + del_sfp_path = "/sys/class/i2c-adapter/i2c-{0}/delete_device".format( + self._port_to_i2c_mapping[self.index]) + new_sfp_path = "/sys/class/i2c-adapter/i2c-{0}/new_device".format( + self._port_to_i2c_mapping[self.index]) + driver_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/name".format( + self._port_to_i2c_mapping[self.index]) + """ + i2c_bus = self.sfp_eeprom_path[27:].split('/')[0] + del_sfp_path = "/sys/class/i2c-adapter/i2c-{0}/delete_device".format(i2c_bus) + new_sfp_path = "/sys/class/i2c-adapter/i2c-{0}/new_device".format(i2c_bus) + driver_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/name".format(i2c_bus) + delete_device = "echo 0x50 >" + del_sfp_path + + if not os.path.isfile(driver_path): + #print(driver_path, "does not exist") + return False + + try: + with os.fdopen(os.open(driver_path, os.O_RDONLY)) as filed: + driver_name = filed.read() + driver_name = driver_name.rstrip('\r\n') + driver_name = driver_name.lstrip(" ") + + #Avoid re-initialization of the QSFP/SFP optic on QSFP/SFP port. + if self.sfp_type == 'SFP' and driver_name in ['optoe1', 'optoe3']: + subprocess.Popen(delete_device, shell=True, stdout=subprocess.PIPE) + time.sleep(0.2) + new_device = "echo optoe2 0x50 >" + new_sfp_path + subprocess.Popen(new_device, shell=True, stdout=subprocess.PIPE) + time.sleep(2) + elif self.sfp_type == 'QSFP' and driver_name in ['optoe2', 'optoe3']: + subprocess.Popen(delete_device, shell=True, stdout=subprocess.PIPE) + time.sleep(0.2) + new_device = "echo optoe1 0x50 >" + new_sfp_path + subprocess.Popen(new_device, shell=True, stdout=subprocess.PIPE) + time.sleep(2) + elif self.sfp_type == 'QSFP_DD' and driver_name in ['optoe1', 'optoe2']: + subprocess.Popen(delete_device, shell=True, stdout=subprocess.PIPE) + time.sleep(0.2) + new_device = "echo optoe3 0x50 >" + new_sfp_path + subprocess.Popen(new_device, shell=True, stdout=subprocess.PIPE) + time.sleep(2) + + except IOError as err: + print("Error: Unable to open file: %s" %str(err)) + return False + + return True + +# Implemented in sfp_optoe_base +# def get_model(self): +# def get_serial(self): +# def get_transceiver_info(self): +# def get_transceiver_bulk_status(self): +# def get_transceiver_threshold_info(self): + + def get_transceiver_status(self): + return {} + + def get_transceiver_info(self): + if self.sfp_type == COPPER_TYPE or self.sfp_type == RJ45_TYPE: + transceiver_info_keys = ['manufacturer', + 'model', + 'vendor_rev', + 'serial', + 'vendor_oui', + 'vendor_date', + 'connector', + 'encoding', + 'ext_identifier', + 'ext_rateselect_compliance', + 'cable_type', + 'cable_length', + 'specification_compliance', + 'nominal_bit_rate', + 'application_advertisement'] + transceiver_info_dict = dict.fromkeys(transceiver_info_keys, 'N/A') + transceiver_info_dict['type'] = self.sfp_type + return transceiver_info_dict + else: + return super(Sfp, self).get_transceiver_info() + + def get_transceiver_bulk_status(self): + if self.sfp_type == COPPER_TYPE or self.sfp_type == RJ45_TYPE: + transceiver_dom_info_dict = {} + dom_info_dict_keys = ['temperature', 'voltage', + 'rx1power', 'rx2power', + 'rx3power', 'rx4power', + 'rx5power', 'rx6power', + 'rx7power', 'rx8power', + 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', + 'tx5bias', 'tx6bias', + 'tx7bias', 'tx8bias', + 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + 'tx5power', 'tx6power', + 'tx7power', 'tx8power' + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + return transceiver_dom_info_dict + else: + return super(Sfp, self).get_transceiver_bulk_status() + + def get_transceiver_threshold_info(self): + if self.sfp_type == COPPER_TYPE or self.sfp_type == RJ45_TYPE: + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + return transceiver_dom_threshold_info_dict + else: + return super(Sfp, self).get_transceiver_threshold_info() + +# def get_transceiver_loopback(self): +# def is_coherent_module(self): +# def get_transceiver_pm(self): +# def get_rx_los(self): +# def get_tx_fault(self): +# def get_tx_disable(self): +# def get_tx_disable_channel(self): +# def get_temperature(self): +# def get_voltage(self): +# def get_tx_bias(self): +# def get_rx_power(self): +# def get_tx_power(self): + + def tx_disable(self, tx_disable): + """ + Disable SFP TX + 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 self.sfp_type == COPPER_TYPE or self.sfp_type == RJ45_TYPE: + return False + + port_offset = self.index-SFP_PORT_START + sfpstatus=self.sfp_status_get_value(port_offset) + + tx_dis_bit = [0x04, 0x40, 0x04, 0x40, 0x04, 0x40] + tx_en_bit = [0xFB, 0xBF, 0xFB, 0xBF, 0xFB, 0xBF] + + if tx_disable == True: + setbits = sfpstatus | tx_dis_bit[port_offset] + else: + setbits = sfpstatus & tx_en_bit[port_offset] + + self.sfp_status_set_value(port_offset, setbits) + + return True + +# Implemented in sfp_optoe_base +# 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 +# """ +# +# return NotImplementedError + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + if self.sfp_type == COPPER_TYPE or self.sfp_type == RJ45_TYPE: + return False + if self.sfp_type == SFP_TYPE: + return False + +# Implemented in sfp_optoe_base +# 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 +# """ +# +# return NotImplementedError + + def get_eeprom_path(self): + """ + Returns SFP eeprom path + """ + return self.eeprom_path + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + if self.sfp_type == COPPER_TYPE or self.sfp_type == RJ45_TYPE: + return False + if self.sfp_type == SFP_TYPE: + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + if self.sfp_type == COPPER_TYPE or self.sfp_type == RJ45_TYPE: + return False + if self.sfp_type == SFP_TYPE: + return False + +# def read_eeprom(self, offset, num_bytes): +# def write_eeprom(self, offset, num_bytes, write_buffer): + + def reset(self): + """ + Reset SFP. + Returns: + A boolean, True if successful, False if not + """ + # RJ45 and SFP ports not resettable + return False + + def get_error_description(self): + """ + Retrives the error descriptions of the SFP module + + Returns: + String that represents the current error descriptions of vendor specific errors + In case there are multiple errors, they should be joined by '|', + like: "Bad EEPROM|Unsupported cable" + """ + if self.sfp_type == COPPER_TYPE or self.sfp_type == RJ45_TYPE: + return super(Sfp, self).get_error_description() + + if not self.get_presence(): + return self.SFP_STATUS_UNPLUGGED + else: + if not os.path.isfile(self.eeprom_path): + return "EEPROM driver is not attached" + + if self.sfp_type == 'SFP': + offset = SFP_INFO_OFFSET + elif self.sfp_type == 'QSFP': + offset = QSFP_INFO_OFFSET + elif self.sfp_type == 'QSFP_DD': + offset = QSFP_DD_PAGE0 + + try: + with open(self.eeprom_path, mode="rb", buffering=0) as eeprom: + eeprom.seek(offset) + eeprom.read(1) + except OSError as e: + return "EEPROM read failed ({})".format(e.strerror) + + return self.SFP_STATUS_OK + + def get_name(self): + """ + Returns native transceiver type + Returns: string - The name of the device + """ + return RJ45_TYPE if self.index < SFP_PORT_START else "SFP/SFP+/SFP28" + +# def get_name(self): +# """ +# Retrieves the name of the device +# Returns: +# string: The name of the device +# """ +# sfputil_helper = SfpUtilHelper() +# sfputil_helper.read_porttab_mappings( +# self.__get_path_to_port_config_file()) +# name = sfputil_helper.logical[self.index-1] or "Unknown" +# return name + + def get_presence(self): + """ + Retrieves the presence + Returns: + bool: True if is present, False if not + """ + if self.sfp_type == COPPER_TYPE or self.sfp_type == RJ45_TYPE: + return False + + port_offset = self.index-SFP_PORT_START + sfpstatus = self.sfp_status_get_value(port_offset) + + if ((port_offset%2) == 1): + sfpstatus = (sfpstatus >> 4) & 0X01 + else: + sfpstatus = sfpstatus & 0x01 + + if sfpstatus == 0: + # Present. Turn off tx_disable + self.tx_disable(False) + return True + + # Not present. Turn on tx_disable + self.tx_disable(True) + return False + + def get_reset_status(self): + """ + Retrives the reset status of SFP + """ + reset_status = False + return reset_status + + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + + if self.sfp_type == "SFP": + return True + else: + return False + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/sfp_event.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/sfp_event.py new file mode 100644 index 0000000000..53e0099c62 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/sfp_event.py @@ -0,0 +1,141 @@ +############################################################ +# listen for the SFP change event and return to chassis. +############################################################ + +import math +import os +import sys +import time +from sonic_py_common import logger + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +# system level event/error +EVENT_ON_ALL_SFP = '-1' +SYSTEM_NOT_READY = 'system_not_ready' +SYSTEM_READY = 'system_become_ready' +SYSTEM_FAIL = 'system_fail' + +# SFP PORT numbers +SFP_PORT_START = 49 +SFP_PORT_END = 54 +RJ45_PORT_START = 1 +RJ45_PORT_END = 48 + +SYSLOG_IDENTIFIER = "sfp_event" +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) + + +class sfp_event: + ''' Listen to plugin/plugout cable events ''' + + def __init__(self): + self.handle = None + + def initialize(self): + self.modprs_register = 0 + # Get Transceiver status + time.sleep(5) + self.modprs_register = self._get_transceiver_status() + sonic_logger.log_info("Initial SFP presence=%d" % self.modprs_register) + + def deinitialize(self): + if self.handle is None: + return + + def _get_transceiver_status(self): + + reg_in = [0x00, 0x00, 0x01, 0x01, 0x02, 0x02] + port = SFP_PORT_START + + sfpstatus = 0 + while (port >= SFP_PORT_START and port <= SFP_PORT_END): + if smbus_present == 0: + sonic_logger.log_info(" PMON - smbus ERROR - DEBUG sfp_event ") + regin = reg_in[port-SFP_PORT_START] + cmdstatus, sfpreg = cmd.getstatusoutput('sudo i2cget -y 0 0x22 %d' % regin) + sfpreg = int(sfpreg, 16) + else: + bus = smbus.SMBus(1) + DEVICE_ADDRESS = 0x22 + DEVICE_REG = reg_in[port-SFP_PORT_START] + sfpreg = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if ((port-SFP_PORT_START)%2) == 1: + sfpreg = (sfpreg >> 4) & 0x01 + else: + sfpreg = sfpreg & 0x01 + sfpstatus = sfpstatus | (sfpreg << (port-SFP_PORT_START)) + port += 1 + + return sfpstatus + + def check_sfp_status(self, port_change, timeout): + """ + check_sfp_status called from get_change_event, this will return correct + status of all 6 SFP ports if there is a change in any of them + """ + start_time = time.time() + #port = SFP_PORT_START + port = RJ45_PORT_START + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + return False, {} + end_time = start_time + timeout + + if (start_time > end_time): + return False, {} # Time wrap or possibly incorrect timeout + + while (timeout >= 0): + while (port >= RJ45_PORT_START and port <= RJ45_PORT_END): + port_change[port] = '1' + port += 1 + + # Check for OIR events and return updated port_change + reg_value = self._get_transceiver_status() + if (reg_value != self.modprs_register): + changed_ports = (self.modprs_register ^ reg_value) + while (port >= SFP_PORT_START and port <= SFP_PORT_END): + # Mask off the bit corresponding to our port + mask = (1 << port-SFP_PORT_START) + if (changed_ports & mask): + # ModPrsL is active high + if reg_value & mask == 0: + #G3748 reg_value==0 is inserted. In port_change 1 is inserted + port_change[port] = '1' + else: + #G3748 reg_value==1 is removed. In port_change 0 is removed + port_change[port] = '0' + port += 1 + + # Update reg value + self.modprs_register = reg_value + #return True, port_change + return True, port_change + + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + return False, {} diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/README b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/README new file mode 100644 index 0000000000..3efc8fabce --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/README @@ -0,0 +1 @@ +This directory contains unit tests of the Platform API 2.0 diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-chassis.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-chassis.py new file mode 100644 index 0000000000..772cf6d88d --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-chassis.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +#import sonic_platform +#from sonic_platform.chassis import Chassis + + +try: + import sonic_platform.platform + import sonic_platform.chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def main(): + print("-----------------") + print("Chassis Unit Test") + print("-----------------") + + chassis = sonic_platform.platform.Platform().get_chassis() + print(" Chassis name: {}".format(chassis.get_name())) + + print(" Chassis presence: {}".format(chassis.get_presence())) + + print(" Chassis model: {}".format(chassis.get_model())) + + print(" Chassis serial: {}".format(chassis.get_serial())) + + print(" Chassis status: {}".format(chassis.get_status())) + + print(" Chassis base_mac: {}".format(chassis.get_base_mac())) + + print(" Chassis reboot cause: {}\n".format(chassis.get_reboot_cause())) + + print(" Chassis watchdog: {}".format(chassis.get_watchdog())) + + print(" Chassis num_components: {}".format(chassis.get_num_components())) + + print(" Chassis all_components: {}\n".format(chassis.get_all_components())) + + print(" Chassis num_modules: {}".format(chassis.get_num_modules())) + + print(" Chassis all_modules: {}\n".format(chassis.get_all_modules())) + + print(" Chassis num_fans: {}".format(chassis.get_num_fans())) + + print(" Chassis all_fans: {}\n".format(chassis.get_all_fans())) + + print(" Chassis num_psus: {}".format(chassis.get_num_psus())) + + print(" Chassis all_psus: {}\n".format(chassis.get_all_psus())) + + print(" Chassis num_thermals: {}".format(chassis.get_num_thermals())) + + print(" Chassis all_thermals: {}\n".format(chassis.get_all_thermals())) + + print(" Chassis num_sfps: {}".format(chassis.get_num_sfps())) + + print(" Chassis all_sfps: {}\n".format(chassis.get_all_sfps())) + + print(" Chassis eeprom: {}".format(chassis.get_eeprom())) + + print(" Chassis system_eeprom_info: {}\n".format(chassis.get_system_eeprom_info())) + + print(" Chassis get_status_led start : {}\n".format(chassis.get_status_led())) + chassis.set_status_led('amber') + print(" Chassis get_status_led amber: {}\n".format(chassis.get_status_led())) + chassis.set_status_led('green') + print(" Chassis get_status_led green: {}\n".format(chassis.get_status_led())) + + print(" Chassis thermal_manager: {}\n".format(chassis.get_thermal_manager())) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-component.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-component.py new file mode 100644 index 0000000000..1116cc7b58 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-component.py @@ -0,0 +1,22 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------------") + print("Chassis Component Unit Test") + print("---------------------------") + + chassis = Chassis() + + for component in chassis.get_all_components(): + print(" Name: {}".format(component.get_name())) + print(" Description: {}".format(component.get_description())) + print(" FW version: {}\n".format(component.get_firmware_version())) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-eeprom.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-eeprom.py new file mode 100644 index 0000000000..4083661169 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-eeprom.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("------------------------") + print("Chassis eeprom Unit Test") + print("------------------------") + + chassis = Chassis() + + eeprom = chassis.get_eeprom() + + print(" Model: {}, Service Tag: {}".format(eeprom.modelstr(), + eeprom.service_tag_str())) + print(" Part#: {}, Serial#: {}".format(eeprom.part_number_str(), + eeprom.serial_number_str())) + print(" Base MAC: {}".format(eeprom.base_mac_addr())) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-fan.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-fan.py new file mode 100644 index 0000000000..5844e25b55 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-fan.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import sonic_platform +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------") + print("Chassis Fan Unit Test") + print("---------------------") + + chassis = Chassis() + + for fan in chassis.get_all_fans(): + if not fan.get_presence(): + print(" Name: {} not present".format(fan.get_name())) + else: + print(" Name:", fan.get_name()) + print(" Presence: {}, Status: {}, LED: {}".format(fan.get_presence(), + fan.get_status(), + fan.get_status_led())) + print(" Model: {}, Serial#: {}".format(fan.get_model(), + fan.get_serial())) + print(" Part#: {}, Service Tag: {}".format(fan.get_part_number(), + fan.get_service_tag())) + print(" Direction: {}, Speed: {}RPM, Target Speed: {}, Speed Tolerance: {}%\n".format(fan.get_direction(), + str(fan.get_speed()), + str(fan.get_target_speed()), + str(fan.get_speed_tolerance())) + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-psu.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-psu.py new file mode 100644 index 0000000000..ac04f06f93 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-psu.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +import sonic_platform +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------") + print("Chassis PSU Unit Test") + print("---------------------") + + chassis = Chassis() + + for psu in chassis.get_all_psus(): + if not psu.get_presence(): + print(" Name: {} not present".format(psu.get_name())) + else: + print(" Name:", psu.get_name()) + print(" Presence: {}, Status: {}, LED: {}".format(psu.get_presence(), + psu.get_status(), + psu.get_status_led())) + print(" Model: {}, Serial#: {}, Part#: {}".format(psu.get_model(), + psu.get_serial(), + psu.get_part_number())) + try: + current = psu.get_current() + except NotImplementedError: + current = "NA" + try: + power = psu.get_power() + except NotImplementedError: + power = "NA" + + print(" Voltage: {}, Current: {}, Power: {}\n".format(psu.get_voltage(), + current, + power)) + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-sfp.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-sfp.py new file mode 100644 index 0000000000..f5f2283f17 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-sfp.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import sonic_platform + +try: + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def main(): + print("---------------------") + print("Chassis SFP Unit Test") + print("---------------------") + + chassis = Chassis() + + PORT_START = 1 + PORT_END = 52 + + for physical_port in range(PORT_START, PORT_END+1): + print(" ") + print(" SFP transceiver tests PORT = ", physical_port) + name = chassis.get_sfp(physical_port).get_name() + print(" SFP transceiver tests NAME = ", name) + + presence = chassis.get_sfp(physical_port).get_presence() + print("TEST 1 - sfp presence [ True ] ", physical_port, presence) + + status = chassis.get_sfp(physical_port).get_reset_status() + print("TEST 2 - sfp reset status [ False ] ", physical_port, status) + + txdisable = chassis.get_sfp(physical_port).get_tx_disable() + print("TEST 3 - sfp tx_disable [ False ] ", physical_port, txdisable) + + rxlos = chassis.get_sfp(physical_port).get_rx_los() + print("TEST 4 - sfp status rxlos [ False ] ", physical_port, rxlos) + + txfault = chassis.get_sfp(physical_port).get_tx_fault() + print("TEST 5 - sfp status txfault [ False ] ", physical_port, txfault) + + lpmode = chassis.get_sfp(physical_port).get_lpmode() + print("TEST 6 - sfp enable lpmode [ False ] ", physical_port, lpmode) + + trans_info = chassis.get_sfp(physical_port).get_transceiver_info() + print("TEST 7 - sfp transceiver info for port:", physical_port, trans_info) + + trans_status = chassis.get_sfp(physical_port).get_transceiver_bulk_status() + print("TEST 8 - sfp bulk status for port:", physical_port, trans_status) + + threshold = chassis.get_sfp(physical_port).get_transceiver_threshold_info() + print("TEST 9 - sfp bulk status for port:", physical_port, threshold) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-thermal.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-thermal.py new file mode 100644 index 0000000000..91ef75d8f9 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-thermal.py @@ -0,0 +1,50 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + +def main(): + print("-------------------------") + print("Chassis Thermal Unit Test") + print("-------------------------") + + chassis = Chassis() + + for thermal in chassis.get_all_thermals(): + if not thermal.get_presence(): + print(" Name: {} not present".format(thermal.get_name())) + else: + print(" Name:", thermal.get_name()) + print(" Presence: {}, Status: {}".format(thermal.get_presence(), + thermal.get_status())) + print(" Model: {}, Serial#: {}".format(thermal.get_model(), + thermal.get_serial())) + print(" Temperature(C): {}".format(thermal.get_temperature())) + + try: + low_thresh = thermal.get_low_threshold() + except NotImplementedError: + low_thresh = "NA" + try: + high_thresh = thermal.get_high_threshold() + except NotImplementedError: + high_thresh = "NA" + + print(" Low Threshold(C): {}, High Threshold(C): {}".format(low_thresh, + high_thresh)) + + try: + crit_low_thresh = thermal.get_low_critical_threshold() + except NotImplementedError: + crit_low_thresh = "NA" + try: + crit_high_thresh = thermal.get_high_critical_threshold() + except NotImplementedError: + crit_high_thresh = "NA" + + print(" Crit Low Threshold(C): {}, Crit High Threshold(C): {}\n".format(crit_low_thresh, + crit_high_thresh)) + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-watchdog.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-watchdog.py new file mode 100644 index 0000000000..20805e04ed --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/test/test-watchdog.py @@ -0,0 +1,22 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------") + print("Chassis Watchdog Test") + print("---------------------") + + chassis = Chassis() + + watchdog = chassis.get_watchdog() + + print(" Armed: {}".format(watchdog.is_armed())) + print(" Time Left: {}".format(watchdog.get_remaining_time())) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal.py new file mode 100644 index 0000000000..76410f7c44 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal.py @@ -0,0 +1,245 @@ +######################################################################## +# Supermicro SSE-G3748 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.thermal_base import ThermalBase + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +sonic_logger = logger.Logger('thermal') + +class Thermal(ThermalBase): + """sse-g3748 platform-specific Thermal class""" + + I2C_CLASS_DIR = "/sys/class/i2c-adapter/" + I2C_DEV_MAPPING = (['i2c-0/0-0048/hwmon/', 1], + ['i2c-0/0-0049/hwmon/', 1]) + + HWMON_CLASS_DIR = "/sys/class/hwmon/" + + THERMAL_NAME = ("FRONT", "REAR") + + def __init__(self, thermal_index): + ThermalBase.__init__(self) + self.index = thermal_index + 1 + self.is_psu_thermal = False + self.dependency = None + self._minimum = None + self._maximum = None + self.thermal_high_threshold_file = None + # PCB temperature sensors + if self.index < 3: + i2c_path = self.I2C_CLASS_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] + sensor_index = self.I2C_DEV_MAPPING[self.index - 1][1] + sensor_max_suffix = "max" + sensor_crit_suffix = "max_hyst" + hwmon_node = os.listdir(i2c_path)[0] + self.SENSOR_DIR = i2c_path + hwmon_node + '/' + + # Armada 38x SOC temperature sensor + else: + dev_path = self.HWMON_CLASS_DIR + sensor_index = 1 + sensor_max_suffix = None + sensor_crit_suffix = None + hwmon_node = os.listdir(dev_path)[0] + self.SENSOR_DIR = dev_path + hwmon_node + '/' + + # sysfs file for current temperature value + self.thermal_temperature_file = self.SENSOR_DIR \ + + "temp{}_input".format(sensor_index) + + # sysfs file for high threshold value if supported for this sensor + if sensor_max_suffix: + self.thermal_high_threshold_file = self.SENSOR_DIR \ + + "temp{}_{}".format(sensor_index, sensor_max_suffix) + else: + self.thermal_high_threshold_file = None + + # sysfs file for crit high threshold value if supported for this sensor + if sensor_crit_suffix: + self.thermal_high_crit_threshold_file = self.SENSOR_DIR \ + + "temp{}_{}".format(sensor_index, sensor_crit_suffix) + else: + self.thermal_high_crit_threshold_file = None + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.THERMAL_NAME[self.index - 1] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + if self.dependency: + return self.dependency.get_presence() + else: + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the Thermal + + Returns: + string: Model/part number of Thermal + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + if self.dependency: + return self.dependency.get_status() + else: + return True + + 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 + """ + thermal_temperature = self._read_sysfs_file( + self.thermal_temperature_file) + if (thermal_temperature != 'ERR'): + thermal_temperature = float(thermal_temperature) / 1000 + if self._minimum is None or self._minimum > thermal_temperature: + self._minimum = thermal_temperature + if self._maximum is None or self._maximum < thermal_temperature: + self._maximum = thermal_temperature + else: + thermal_temperature = 0 + + return float("{:.3f}".format(thermal_temperature)) + + 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 + """ + # Not implemented for this sensor + if not self.thermal_high_threshold_file: + raise NotImplementedError + + thermal_high_threshold = self._read_sysfs_file( + self.thermal_high_threshold_file) + if (thermal_high_threshold != 'ERR'): + thermal_high_threshold = float(thermal_high_threshold) / 1000 + else: + thermal_high_threshold = 0.0 + + return float("{:.3f}".format(thermal_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 + """ + # Thermal threshold values are pre-defined based on HW. + return False + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + + # Not implemented for this sensor + if not self.thermal_high_crit_threshold_file: + raise NotImplementedError + + thermal_high_crit_threshold = self._read_sysfs_file( + self.thermal_high_crit_threshold_file) + if (thermal_high_crit_threshold != 'ERR'): + thermal_high_crit_threshold = float(thermal_high_crit_threshold) / 1000 + else: + thermal_high_crit_threshold = 0.0 + + return float("{:.3f}".format(thermal_high_crit_threshold)) + + def get_minimum_recorded(self): + self.get_temperature() + return self._minimum + + def get_maximum_recorded(self): + self.get_temperature() + return self._maximum + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_actions.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_actions.py new file mode 100644 index 0000000000..4bf1502ae3 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_actions.py @@ -0,0 +1,200 @@ +#try: +# import os +# from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase +# from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object +#except ImportError as e: +# raise ImportError(str(e) + "- required module not found") + +import os +from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + +from sonic_py_common import logger + +sonic_logger = logger.Logger('thermal_actions') + + +class SetFanSpeedAction(ThermalPolicyActionBase): + """ + Base thermal action class to set speed for fans + """ + # JSON field definition + JSON_FIELD_SPEED = 'speed' + JSON_FIELD_DEFAULT_SPEED = 'default_speed' + JSON_FIELD_HIGHTEMP_SPEED = 'hightemp_speed' + + def __init__(self): + """ + Constructor of SetFanSpeedAction + """ + self.default_speed = 50 + self.hightemp_speed = 100 + self.speed = self.default_speed + + def load_from_json(self, json_obj): + """ + Construct SetFanSpeedAction via JSON. JSON example: + { + "type": "fan.all.set_speed" + "speed": "100" + } + :param json_obj: A JSON object representing a SetFanSpeedAction action. + :return: + """ + if SetFanSpeedAction.JSON_FIELD_SPEED in json_obj: + speed = int(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + if speed < 0 or speed > 100: + raise ValueError('SetFanSpeedAction invalid speed value {} in JSON policy file, valid value should be [0, 100]'. + format(speed)) + self.speed = int(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_SPEED)) + + @classmethod + def set_all_fan_speed(cls, thermal_info_dict, speed): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] + for fan in fan_info_obj.get_presence_fans(): + fan.set_speed(int(speed)) + + +@thermal_json_object('fan.all.set_speed') +class SetAllFanSpeedAction(SetFanSpeedAction): + """ + Action to set speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + SetAllFanSpeedAction.set_all_fan_speed(thermal_info_dict, self.speed) + + +@thermal_json_object('thermal.temp_check_and_set_all_fan_speed') +class ThermalRecoverAction(SetFanSpeedAction): + """ + Action to check thermal sensor temperature change status and set speed for all fans + """ + + def load_from_json(self, json_obj): + """ + Construct ThermalRecoverAction via JSON. JSON example: + { + "type": "thermal.temp_check_and_set_all_fan_speed" + "default_speed": "50" + "hightemp_speed": "100" + } + :param json_obj: A JSON object representing a ThermalRecoverAction action. + :return: + """ + if SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED in json_obj: + default_speed = int(json_obj[SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED]) + if default_speed < 0 or default_speed > 100: + raise ValueError('SetFanSpeedAction invalid default speed value {} in JSON policy file, valid value should be [0, 100]'. + format(default_speed)) + self.default_speed = int(json_obj[SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED)) + + if SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED in json_obj: + hightemp_speed = int(json_obj[SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED]) + if hightemp_speed < 0 or hightemp_speed > 100: + raise ValueError('SetFanSpeedAction invalid hightemp speed value {} in JSON policy file, valid value should be [0, 100]'. + format(hightemp_speed)) + self.hightemp_speed = int(json_obj[SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED)) + + sonic_logger.log_warning("ThermalRecoverAction: default: {}, hightemp: {}".format(self.default_speed, self.hightemp_speed)) + + def execute(self, thermal_info_dict): + """ + Check check thermal sensor temperature change status and set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and \ + isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + + thermal_info_obj = thermal_info_dict[ThermalInfo.INFO_NAME] + if thermal_info_obj.is_warm_up_and_over_high_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.hightemp_speed) + elif thermal_info_obj.is_cool_down_and_below_low_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.default_speed) + + +@thermal_json_object('switch.shutdown') +class SwitchPolicyAction(ThermalPolicyActionBase): + """ + Base class for thermal action. Once all thermal conditions in a thermal policy are matched, + all predefined thermal action will be executed. + """ + def execute(self, thermal_info_dict): + """ + Take action when thermal condition matches. For example, adjust speed of fan or shut + down the switch. + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + sonic_logger.log_warning("Alarm for temperature critical is detected, reboot Device") + # import os + # os.system('reboot') + + +@thermal_json_object('thermal_control.control') +class ControlThermalAlgoAction(ThermalPolicyActionBase): + """ + Action to control the thermal control algorithm + """ + # JSON field definition + JSON_FIELD_STATUS = 'status' + + def __init__(self): + self.status = True + + def load_from_json(self, json_obj): + """ + Construct ControlThermalAlgoAction via JSON. JSON example: + { + "type": "thermal_control.control" + "status": "true" + } + :param json_obj: A JSON object representing a ControlThermalAlgoAction action. + :return: + """ + if ControlThermalAlgoAction.JSON_FIELD_STATUS in json_obj: + status_str = json_obj[ControlThermalAlgoAction.JSON_FIELD_STATUS].lower() + if status_str == 'true': + self.status = True + elif status_str == 'false': + self.status = False + else: + raise ValueError('Invalid {} field value, please specify true of false'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + else: + raise ValueError('ControlThermalAlgoAction ' + 'missing mandatory field {} in JSON policy file'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + + def execute(self, thermal_info_dict): + """ + Disable thermal control algorithm + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal_infos import ChassisInfo + if ChassisInfo.INFO_NAME in thermal_info_dict: + chassis_info_obj = thermal_info_dict[ChassisInfo.INFO_NAME] + chassis = chassis_info_obj.get_chassis() + thermal_manager = chassis.get_thermal_manager() + if self.status: + thermal_manager.start_thermal_control_algorithm() + else: + thermal_manager.stop_thermal_control_algorithm() diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_conditions.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_conditions.py new file mode 100644 index 0000000000..4923d63d74 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_conditions.py @@ -0,0 +1,81 @@ +from sonic_platform_base.sonic_thermal_control.thermal_condition_base import ThermalPolicyConditionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +class FanCondition(ThermalPolicyConditionBase): + def get_fan_info(self, thermal_info_dict): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + return thermal_info_dict[FanInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('fan.any.absence') +class AnyFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.absence') +class AllFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_presence_fans()) == 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.presence') +class AllFanPresenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) == 0 if fan_info_obj else False + + +class ThermalCondition(ThermalPolicyConditionBase): + def get_thermal_info(self, thermal_info_dict): + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + return thermal_info_dict[ThermalInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('thermal.over.high_critical_threshold') +class ThermalOverHighCriticalCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return thermal_info_obj.is_over_high_critical_threshold() + else: + return False + + +class PsuCondition(ThermalPolicyConditionBase): + def get_psu_info(self, thermal_info_dict): + from .thermal_infos import PsuInfo + if PsuInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[PsuInfo.INFO_NAME], PsuInfo): + return thermal_info_dict[PsuInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('psu.any.absence') +class AnyPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) > 0 if psu_info_obj else False + + +@thermal_json_object('psu.all.absence') +class AllPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_presence_psus()) == 0 if psu_info_obj else False + + +@thermal_json_object('psu.all.presence') +class AllPsuPresenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) == 0 if psu_info_obj else False diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_infos.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_infos.py new file mode 100644 index 0000000000..cd0a0591cd --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_infos.py @@ -0,0 +1,210 @@ +from sonic_platform_base.sonic_thermal_control.thermal_info_base import ThermalPolicyInfoBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +@thermal_json_object('fan_info') +class FanInfo(ThermalPolicyInfoBase): + """ + Fan information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'fan_info' + + def __init__(self): + self._absence_fans = set() + self._presence_fans = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence fans. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + for fan in chassis.get_all_fans(): + if fan.get_presence() and fan not in self._presence_fans: + self._presence_fans.add(fan) + self._status_changed = True + if fan in self._absence_fans: + self._absence_fans.remove(fan) + elif not fan.get_presence() and fan not in self._absence_fans: + self._absence_fans.add(fan) + self._status_changed = True + if fan in self._presence_fans: + self._presence_fans.remove(fan) + + def get_absence_fans(self): + """ + Retrieves absence fans + :return: A set of absence fans + """ + return self._absence_fans + + def get_presence_fans(self): + """ + Retrieves presence fans + :return: A set of presence fans + """ + return self._presence_fans + + def is_status_changed(self): + """ + Retrieves if the status of fan information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('thermal_info') +class ThermalInfo(ThermalPolicyInfoBase): + """ + Thermal information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'thermal_info' + + def __init__(self): + self.init = False + self._old_avg_temp = 0 + self._current_avg_temp = 0 + self._high_crital_threshold = 75 + self._high_threshold = 45 + self._low_threshold = 40 + + def collect(self, chassis): + """ + Collect thermal sensor temperature change status + :param chassis: The chassis object + :return: + """ + self._temps = [] + self._over_high_critical_threshold = False + self._warm_up_and_over_high_threshold = False + self._cool_down_and_below_low_threshold = False + + # Calculate average temp within the device + temp = 0 + num_of_thermals = chassis.get_num_thermals() + for index in range(num_of_thermals): + self._temps.insert(index, chassis.get_thermal(index).get_temperature()) + temp += self._temps[index] + + self._current_avg_temp = temp / num_of_thermals + + # Special case if first time + if self.init is False: + self._old_avg_temp = self._current_avg_temp + self.init = True + + # Check if new average temp exceeds high threshold value + if self._current_avg_temp >= self._old_avg_temp and self._current_avg_temp >= self._high_threshold: + self._warm_up_and_over_high_threshold = True + + # Check if new average temp exceeds low threshold value + if self._current_avg_temp <= self._old_avg_temp and self._current_avg_temp <= self._low_threshold: + self._cool_down_and_below_low_threshold = True + + self._old_avg_temp = self._current_avg_temp + + def is_warm_up_and_over_high_threshold(self): + """ + Retrieves if the temperature is warm up and over high threshold + :return: True if the temperature is warm up and over high threshold else False + """ + return self._warm_up_and_over_high_threshold + + def is_cool_down_and_below_low_threshold(self): + """ + Retrieves if the temperature is cold down and below low threshold + :return: True if the temperature is cold down and below low threshold else False + """ + return self._cool_down_and_below_low_threshold + + def is_over_high_critical_threshold(self): + """ + Retrieves if the temperature is over high critical threshold + :return: True if the temperature is over high critical threshold else False + """ + return self._over_high_critical_threshold + + +@thermal_json_object('psu_info') +class PsuInfo(ThermalPolicyInfoBase): + """ + PSU information needed by thermal policy + """ + INFO_NAME = 'psu_info' + + def __init__(self): + self._absence_psus = set() + self._presence_psus = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence PSUs. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + for psu in chassis.get_all_psus(): + if psu.get_presence() and psu.get_powergood_status() and psu not in self._presence_psus: + self._presence_psus.add(psu) + self._status_changed = True + if psu in self._absence_psus: + self._absence_psus.remove(psu) + elif (not psu.get_presence() or not psu.get_powergood_status()) and psu not in self._absence_psus: + self._absence_psus.add(psu) + self._status_changed = True + if psu in self._presence_psus: + self._presence_psus.remove(psu) + + def get_absence_psus(self): + """ + Retrieves presence PSUs + :return: A set of absence PSUs + """ + return self._absence_psus + + def get_presence_psus(self): + """ + Retrieves presence PSUs + :return: A set of presence fans + """ + return self._presence_psus + + def is_status_changed(self): + """ + Retrieves if the status of PSU information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('chassis_info') +class ChassisInfo(ThermalPolicyInfoBase): + """ + Chassis information needed by thermal policy + """ + INFO_NAME = 'chassis_info' + + def __init__(self): + self._chassis = None + + def collect(self, chassis): + """ + Collect platform chassis. + :param chassis: The chassis object + :return: + """ + self._chassis = chassis + + def get_chassis(self): + """ + Retrieves platform chassis object + :return: A platform chassis object. + """ + return self._chassis diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_manager.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_manager.py new file mode 100644 index 0000000000..10c3b67433 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/thermal_manager.py @@ -0,0 +1,68 @@ + +#try: +# import os +# from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +# from .thermal_actions import * +# from .thermal_conditions import * +# from .thermal_infos import * +#except ImportError as e: +# raise ImportError(str(e) + "- required module not found") + +import os +from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from sonic_py_common import logger +from .thermal_actions import * +from .thermal_conditions import * +from .thermal_infos import * + +sonic_logger = logger.Logger('thermal_manager') + +class ThermalManager(ThermalManagerBase): + THERMAL_ALGORITHM_CONTROL_PATH = '/var/run/hw-management/config/suspend' + + @classmethod + def initialize(cls): + cls.logger=sonic_logger + cls.logger.set_min_log_priority_info() + cls.logger.log_warning('ThermalManager initialize') + + @classmethod + def start_thermal_control_algorithm(cls): + """ + Start thermal control algorithm + + Returns: + bool: True if set success, False if fail. + """ + cls._control_thermal_control_algorithm(False) + + @classmethod + def stop_thermal_control_algorithm(cls): + """ + Stop thermal control algorithm + + Returns: + bool: True if set success, False if fail. + """ + cls._control_thermal_control_algorithm(True) + + @classmethod + def _control_thermal_control_algorithm(cls, suspend): + """ + Control thermal control algorithm + + Args: + suspend: Bool, indicate suspend the algorithm or not + + Returns: + bool: True if set success, False if fail. + """ + status = True + write_value = 1 if suspend else 0 + try: + with open(cls.THERMAL_ALGORITHM_CONTROL_PATH, 'w') as control_file: + control_file.write(str(write_value)) + except (ValueError, IOError): + status = False + + return status diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/watchdog.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/watchdog.py new file mode 100644 index 0000000000..53edc60fa9 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/sonic_platform/watchdog.py @@ -0,0 +1,289 @@ +""" +Module contains an implementation of SONiC Platform Base API and +provides access to hardware watchdog +""" + +import os +import fcntl +import array +import time + +from sonic_platform_base.watchdog_base import WatchdogBase +from sonic_py_common import logger + +WD_COMMON_ERROR = -1 + +sonic_logger = logger.Logger() + +# CPLD Watchdog Timer CTRL register bits +WDT_CTRL_INTR_EN_BIT = 0x80 +WDT_CTRL_RSET_EN_BIT = 0x40 +WDT_CTRL_CNTR_EN_BIT = 0x20 + +WDT_CTRL_FREQ_SEL_16HZ = 0x00 +WDT_CTRL_FREQ_SEL_4HZ = 0x01 +WDT_CTRL_FREQ_SEL_1HZ = 0x02 +WDT_CTRL_FREQ_SEL_0_25HZ = 0x03 + +WDT_MAX_TIMEOUT = 867 + +class WatchdogImplBase(WatchdogBase): + """ + Base class that implements common logic for interacting + with watchdog using ioctl commands + """ + + def __init__(self, wd_device_path): + """ + Open a watchdog handle + @param wd_device_path Path to watchdog device + """ + + G3748CPLD_I2C_DIR = "/sys/bus/i2c/devices/0-0066/" + #sonic_logger.log_info(" WatchdogImplBase: __init__") + + self.watchdog_path = wd_device_path + #self.watchdog = os.open(self.watchdog_path, os.O_WRONLY) + self.wdt_timer_reg = G3748CPLD_I2C_DIR+"wdt_timer".format() + self.wdt_ctrl_reg = G3748CPLD_I2C_DIR+"wdt_ctrl".format() + self.wdt_intr_cnt_mask_reg = G3748CPLD_I2C_DIR+"wdt_intr_cnt_mask".format() + self.wdt_intr_flag_reg = G3748CPLD_I2C_DIR+"wdt_intr_flag".format() + self.wdt_timeout = G3748CPLD_I2C_DIR+"wdt_timeout".format() + + self.armed = self._is_cpld_wd_armed() + self.timeout = self._gettimeout() + self.max_timeout = WDT_MAX_TIMEOUT + + def _read_cpld_reg(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + if (not os.path.isfile(reg_file)): + return rv + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _write_cpld_reg(self, reg_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + if (not os.path.isfile(reg_file)): + return rv + try: + with open(reg_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + # Ensure that the write operation has succeeded + if (int(self._read_cpld_reg(reg_file)) != value ): + time.sleep(3) + if (int(self._read_cpld_reg(reg_file)) != value ): + rv = 'ERR' + return rv + + def _is_cpld_wd_armed(self): + reg = self._read_cpld_reg(self.wdt_ctrl_reg) + state = (int(reg) & 0x20) >> 5 + #sonic_logger.log_warning(" state = {}".format(state)) + if (state == 0): + return False # Disabled + return True # Enabled + + def _disablewatchdog(self): + """ + Turn off the watchdog timer + """ + #sonic_logger.log_info(" _disablewatchdog") + reg = self._read_cpld_reg(self.wdt_ctrl_reg) + # Set reg bit(7-5) to 0 to disable timer + reg_val = int(reg) + reg_val = reg_val & ~(WDT_CTRL_INTR_EN_BIT | WDT_CTRL_RSET_EN_BIT | WDT_CTRL_CNTR_EN_BIT) + self._write_cpld_reg(self.wdt_ctrl_reg, reg_val) + # Reset timer counter to 0 + self._write_cpld_reg(self.wdt_timer_reg, 0) + + def _enablewatchdog(self): + """ + Turn on the watchdog timer + """ + #sonic_logger.log_info(" _enablewatchdog") + reg = self._read_cpld_reg(self.wdt_ctrl_reg) + # Set reg bit(5) to 1 to enable timer + reg_val = int(reg) | (WDT_CTRL_INTR_EN_BIT | WDT_CTRL_RSET_EN_BIT | WDT_CTRL_CNTR_EN_BIT) + self._write_cpld_reg(self.wdt_ctrl_reg, reg_val) + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + 1. The watchdog timer can be set to an initial value from 0 through 0xff. + Writing 0xff would generate an immediate watchdog reset. + 2. The watchdog timer will increment from the initial value after enabling + the watchdog timer reset function or the watchdog interrupt function. + 3. Writing a value to the watchdog timer register will restart the timer count. + 4. The watchdog timer will generate an interrupt when the watchdog timer + interrupt function is enabled by software and the current timer value + reaches watchdog interrupt count mask register value (power on default = 0X7f). + 5. The PLD will reset the whole system when watchdog timer reset function is enabled + by software and the current timer value is 0XFF. + + @param seconds - timeout in seconds + @return is the actual set timeout + """ + #sonic_logger.log_info(" _settimeout") + if (seconds > self.max_timeout or seconds < 0): + sonic_logger.log_warning("Error: WDT timeout value is out of range.") + return WD_COMMON_ERROR + # Save the timeout (seconds) value + self._write_cpld_reg(self.wdt_timeout, seconds) + # Configure the initial timer value to CPLD registor + if (seconds >= 0 and seconds <= self.max_timeout): + # Use 3.4 sec instead of 4 sec, to be more closer to real time + count = (seconds / 3.4) + clkval = WDT_CTRL_FREQ_SEL_0_25HZ # frequency 0.25 Hz + #elif (seconds >= 0 and seconds < 256): + # count = (seconds / 1) + # clkval = WDT_CTRL_FREQ_SEL_1HZ # frequency 1 Hz + + init_timer = int(255 - count) + if (init_timer > 1): + init_timer = init_timer - 1 + #sonic_logger.log_warning("_settimeout: init_timer = {}".format(init_timer)) + # Set initial timer count + self._write_cpld_reg(self.wdt_timer_reg, init_timer) + # Set clock frequency selector + # If Bit7 - Bit5 of fval has one bit '1', the timer will be restarted + reg = self._read_cpld_reg(self.wdt_ctrl_reg) + fval = (int(reg) & 0xF0) | clkval + self._write_cpld_reg(self.wdt_ctrl_reg, fval) + + return seconds + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + #sonic_logger.log_info(" _gettimeout") + timeout = self._read_cpld_reg(self.wdt_timeout) + return int(timeout) + + def _gettimeleft(self): + """ + Get time left before watchdog timer expires + @return time left in seconds + """ + #sonic_logger.log_info(" _gettimeleft") + timer_cnt = int(self._read_cpld_reg(self.wdt_timer_reg)) + if (timer_cnt < 254): + timer_cnt = timer_cnt + 1 + freq_sel = int(self._read_cpld_reg(self.wdt_ctrl_reg)) & 0x03 + timer_cnt_left = 0xFF - int(timer_cnt) + if (freq_sel == WDT_CTRL_FREQ_SEL_16HZ): + timeleft = timer_cnt_left / 16 + elif (freq_sel == WDT_CTRL_FREQ_SEL_4HZ): + timeleft = timer_cnt_left / 4 + elif (freq_sel == WDT_CTRL_FREQ_SEL_1HZ): + timeleft = timer_cnt_left / 1 + elif (freq_sel == WDT_CTRL_FREQ_SEL_0_25HZ): + #timeleft = timer_cnt_left * 4 + # Change from 4 sec to 3.4 sec to be more closer to real time. + timeleft = timer_cnt_left * 3.4 + + return int(timeleft) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + #sonic_logger.log_warning(" _keepalive") + self._disablewatchdog() + timeout = self._gettimeout() + self._settimeout(timeout) + self._enablewatchdog() + + def is_armed(self): + """ + Implements is_armed WatchdogBase API + """ + return self.armed + + def get_remaining_time(self): + """ + Implements get_remaining_time WatchdogBase API + """ + #sonic_logger.log_warning("get_remaining_time") + timeleft = WD_COMMON_ERROR + + if self.armed: + try: + timeleft = self._gettimeleft() + except IOError: + pass + + return timeleft + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + #sonic_logger.log_info(" Debug disarm watchdog ") + + disarmed = False + + if self.is_armed(): + try: + self._disablewatchdog() + self.armed = False + disarmed = True + self.timeout = 0 + self._write_cpld_reg(self.wdt_timeout, self.timeout) + except IOError: + pass + + return disarmed + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + #sonic_logger.log_info(" Debug arm ") + + ret = WD_COMMON_ERROR + if seconds < 0: + return ret + if seconds > self.max_timeout: + return ret + + try: + self._disablewatchdog() + #if self._gettimeout() != seconds: + #sonic_logger.log_info(" Debug arm-settimeout") + self.timeout = self._settimeout(seconds) + #sonic_logger.log_info(" Debug arm-enable ") + self._enablewatchdog() + self.armed = True + ret = self.timeout + except IOError as e: + pass + + return ret + + + diff --git a/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/utils/get-base-mac.py b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/utils/get-base-mac.py new file mode 100644 index 0000000000..fe271d04a9 --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-modules-supermicro/sse-g3748/utils/get-base-mac.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python + +def main(): + try: + import sonic_platform.platform + import sonic_platform.chassis + except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + chassis = sonic_platform.platform.Platform().get_chassis() + if chassis is None: + print "DEBUG chassis was None " + + base_mac = chassis.get_base_mac() + print base_mac + + return + +if __name__ == '__main__': + main() diff --git a/platform/marvell-arm64/sonic_fit.its b/platform/marvell-arm64/sonic_fit.its index e0d1e7b5d3..2879ff4f43 100644 --- a/platform/marvell-arm64/sonic_fit.its +++ b/platform/marvell-arm64/sonic_fit.its @@ -91,6 +91,17 @@ algo = "sha1"; }; }; + fdt_smc_sse-g3748 { + description = "Flattened Device Tree blob for Supermicro SSE-G3748"; + data = /incbin/("/usr/lib/linux-image-5.10.0-23-2-arm64/marvell/smc_sse-g3748.dtb"); + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + load = <0x2 0x1000000>; + hash@1 { + algo = "sha1"; + }; + }; }; configurations { default = "conf_ac5x"; @@ -121,5 +132,14 @@ algo = "sha1"; }; }; + conf_smc_sse-g3748 { + description = "Boot Linux kernel with FDT blob + ramdisk for Supermicro SSE-G3748"; + kernel = "kernel_ac5x"; + fdt = "fdt_smc_sse-g3748"; + ramdisk = "ramdisk_ac5x"; + hash@1 { + algo = "sha1"; + }; + }; }; };