diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/B6510-48VS8CQ/port_config.ini b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/B6510-48VS8CQ/port_config.ini
new file mode 100755
index 000000000000..b39279e79862
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/B6510-48VS8CQ/port_config.ini
@@ -0,0 +1,57 @@
+#name lanes alias index speed
+Ethernet0 1 twentyfiveGigE0/1 0 25000
+Ethernet1 2 twentyfiveGigE0/2 1 25000
+Ethernet2 3 twentyfiveGigE0/3 2 25000
+Ethernet3 4 twentyfiveGigE0/4 3 25000
+Ethernet4 5 twentyfiveGigE0/5 4 25000
+Ethernet5 6 twentyfiveGigE0/6 5 25000
+Ethernet6 7 twentyfiveGigE0/7 6 25000
+Ethernet7 8 twentyfiveGigE0/8 7 25000
+Ethernet8 13 twentyfiveGigE0/9 8 25000
+Ethernet9 14 twentyfiveGigE0/10 9 25000
+Ethernet10 15 twentyfiveGigE0/11 10 25000
+Ethernet11 16 twentyfiveGigE0/12 11 25000
+Ethernet12 21 twentyfiveGigE0/13 12 25000
+Ethernet13 22 twentyfiveGigE0/14 13 25000
+Ethernet14 23 twentyfiveGigE0/15 14 25000
+Ethernet15 24 twentyfiveGigE0/16 15 25000
+Ethernet16 29 twentyfiveGigE0/17 16 25000
+Ethernet17 30 twentyfiveGigE0/18 17 25000
+Ethernet18 31 twentyfiveGigE0/19 18 25000
+Ethernet19 32 twentyfiveGigE0/20 19 25000
+Ethernet20 33 twentyfiveGigE0/21 20 25000
+Ethernet21 34 twentyfiveGigE0/22 21 25000
+Ethernet22 35 twentyfiveGigE0/23 22 25000
+Ethernet23 36 twentyfiveGigE0/24 23 25000
+Ethernet24 41 twentyfiveGigE0/25 24 25000
+Ethernet25 42 twentyfiveGigE0/26 25 25000
+Ethernet26 43 twentyfiveGigE0/27 26 25000
+Ethernet27 44 twentyfiveGigE0/28 27 25000
+Ethernet28 49 twentyfiveGigE0/29 28 25000
+Ethernet29 50 twentyfiveGigE0/30 29 25000
+Ethernet30 51 twentyfiveGigE0/31 30 25000
+Ethernet31 52 twentyfiveGigE0/32 31 25000
+Ethernet32 57 twentyfiveGigE0/33 32 25000
+Ethernet33 58 twentyfiveGigE0/34 33 25000
+Ethernet34 59 twentyfiveGigE0/35 34 25000
+Ethernet35 60 twentyfiveGigE0/36 35 25000
+Ethernet36 61 twentyfiveGigE0/37 36 25000
+Ethernet37 62 twentyfiveGigE0/38 37 25000
+Ethernet38 63 twentyfiveGigE0/39 38 25000
+Ethernet39 64 twentyfiveGigE0/40 39 25000
+Ethernet40 65 twentyfiveGigE0/41 40 25000
+Ethernet41 66 twentyfiveGigE0/42 41 25000
+Ethernet42 67 twentyfiveGigE0/43 42 25000
+Ethernet43 68 twentyfiveGigE0/44 43 25000
+Ethernet44 69 twentyfiveGigE0/45 44 25000
+Ethernet45 70 twentyfiveGigE0/46 45 25000
+Ethernet46 71 twentyfiveGigE0/47 46 25000
+Ethernet47 72 twentyfiveGigE0/48 47 25000
+Ethernet48 85,86,87,88 hundredGigE0/1 48 100000
+Ethernet52 77,78,79,80 hundredGigE0/2 49 100000
+Ethernet56 97,98,99,100 hundredGigE0/3 50 100000
+Ethernet60 93,94,95,96 hundredGigE0/4 51 100000
+Ethernet64 113,114,115,116 hundredGigE0/5 52 100000
+Ethernet68 105,106,107,108 hundredGigE0/6 53 100000
+Ethernet72 121,122,123,124 hundredGigE0/7 54 100000
+Ethernet76 125,126,127,128 hundredGigE0/8 55 100000
\ No newline at end of file
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/B6510-48VS8CQ/sai.profile b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/B6510-48VS8CQ/sai.profile
new file mode 100755
index 000000000000..042c8060d587
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/B6510-48VS8CQ/sai.profile
@@ -0,0 +1 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-b6510-48vs8cq-48x25G+8x100G.config.bcm
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/B6510-48VS8CQ/td3-b6510-48vs8cq-48x25G+8x100G.config.bcm b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/B6510-48VS8CQ/td3-b6510-48vs8cq-48x25G+8x100G.config.bcm
new file mode 100644
index 000000000000..4bd52d4f79f4
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/B6510-48VS8CQ/td3-b6510-48vs8cq-48x25G+8x100G.config.bcm
@@ -0,0 +1,579 @@
+cancun_dir=/usr/share/sonic/platform/cancun/sdk_6.5.14/
+l2_mem_entries=32768
+l2xmsg_mode=0
+l3_max_ecmp_mode=1
+l3_mem_entries=49152
+l3_alpm_enable=0
+bcm_num_cos=8
+bcm_stat_interval=2000000
+cdma_timeout_usec=3000000
+core_clock_frequency=1525
+dpp_clock_ratio=2:3
+help_cli_enable=1
+ifp_inports_support_enable=1
+ipv6_lpm_128b_enable=0x1
+#lpm_scaling_enable=1
+max_vp_lags=0
+mem_cache_enable=0
+memlist_enable=1
+miim_intr_enable=0
+module_64ports=1
+oversubscribe_mode=1
+parity_enable=0
+pbmp_gport_stack.0=0x0000000000000000000000000000000000000000000000000000000000000000
+#pbmp_xport_xe.0=0x00000000000000000000000000000000888ffffffffffff9fffffffffffffffe
+pbmp_xport_xe=0xffffffffffffffffffffffffffffffffffffffffe
+phy_chain_rx_lane_map_physical{1.0}=0x1032
+phy_chain_tx_lane_map_physical{1.0}=0x0123
+phy_chain_rx_lane_map_physical{5.0}=0x1032
+phy_chain_tx_lane_map_physical{5.0}=0x0123
+phy_chain_rx_lane_map_physical{13.0}=0x1032
+phy_chain_tx_lane_map_physical{13.0}=0x0123
+phy_chain_rx_lane_map_physical{21.0}=0x1032
+phy_chain_tx_lane_map_physical{21.0}=0x0123
+phy_chain_rx_lane_map_physical{29.0}=0x1032
+phy_chain_tx_lane_map_physical{29.0}=0x0123
+phy_chain_rx_lane_map_physical{33.0}=0x1032
+phy_chain_tx_lane_map_physical{33.0}=0x0123
+phy_chain_rx_lane_map_physical{41.0}=0x1032
+phy_chain_tx_lane_map_physical{41.0}=0x0123
+phy_chain_rx_lane_map_physical{49.0}=0x1032
+phy_chain_tx_lane_map_physical{49.0}=0x0123
+phy_chain_rx_lane_map_physical{57.0}=0x1032
+phy_chain_tx_lane_map_physical{57.0}=0x0123
+phy_chain_rx_lane_map_physical{61.0}=0x1032
+phy_chain_tx_lane_map_physical{61.0}=0x0123
+phy_chain_rx_lane_map_physical{65.0}=0x2301
+phy_chain_tx_lane_map_physical{65.0}=0x3210
+phy_chain_rx_lane_map_physical{69.0}=0x2301
+phy_chain_tx_lane_map_physical{69.0}=0x3210
+phy_chain_rx_lane_map_physical{77.0}=0x1032
+phy_chain_tx_lane_map_physical{77.0}=0x3210
+phy_chain_rx_lane_map_physical{85.0}=0x1032
+phy_chain_tx_lane_map_physical{85.0}=0x3210
+phy_chain_rx_lane_map_physical{93.0}=0x1032
+phy_chain_tx_lane_map_physical{93.0}=0x3210
+phy_chain_rx_lane_map_physical{97.0}=0x1032
+phy_chain_tx_lane_map_physical{97.0}=0x3210
+phy_chain_rx_lane_map_physical{105.0}=0x1032
+phy_chain_tx_lane_map_physical{105.0}=0x3210
+phy_chain_rx_lane_map_physical{113.0}=0x1032
+phy_chain_tx_lane_map_physical{113.0}=0x3210
+phy_chain_rx_lane_map_physical{121.0}=0x2031
+phy_chain_tx_lane_map_physical{121.0}=0x3210
+phy_chain_rx_lane_map_physical{125.0}=0x1032
+phy_chain_tx_lane_map_physical{125.0}=0x1203
+phy_chain_tx_polarity_flip_physical{1.0}=0x1
+phy_chain_rx_polarity_flip_physical{1.0}=0x0
+phy_chain_tx_polarity_flip_physical{2.0}=0x0
+phy_chain_rx_polarity_flip_physical{2.0}=0x0
+phy_chain_tx_polarity_flip_physical{3.0}=0x1
+phy_chain_rx_polarity_flip_physical{3.0}=0x0
+phy_chain_tx_polarity_flip_physical{4.0}=0x0
+phy_chain_rx_polarity_flip_physical{4.0}=0x0
+phy_chain_tx_polarity_flip_physical{5.0}=0x1
+phy_chain_rx_polarity_flip_physical{5.0}=0x0
+phy_chain_tx_polarity_flip_physical{6.0}=0x0
+phy_chain_rx_polarity_flip_physical{6.0}=0x0
+phy_chain_tx_polarity_flip_physical{7.0}=0x1
+phy_chain_rx_polarity_flip_physical{7.0}=0x0
+phy_chain_tx_polarity_flip_physical{8.0}=0x0
+phy_chain_rx_polarity_flip_physical{8.0}=0x0
+phy_chain_tx_polarity_flip_physical{13.0}=0x0
+phy_chain_rx_polarity_flip_physical{13.0}=0x0
+phy_chain_tx_polarity_flip_physical{14.0}=0x0
+phy_chain_rx_polarity_flip_physical{14.0}=0x0
+phy_chain_tx_polarity_flip_physical{15.0}=0x0
+phy_chain_rx_polarity_flip_physical{15.0}=0x0
+phy_chain_tx_polarity_flip_physical{16.0}=0x0
+phy_chain_rx_polarity_flip_physical{16.0}=0x0
+phy_chain_tx_polarity_flip_physical{21.0}=0x1
+phy_chain_rx_polarity_flip_physical{21.0}=0x0
+phy_chain_tx_polarity_flip_physical{22.0}=0x0
+phy_chain_rx_polarity_flip_physical{22.0}=0x0
+phy_chain_tx_polarity_flip_physical{23.0}=0x1
+phy_chain_rx_polarity_flip_physical{23.0}=0x0
+phy_chain_tx_polarity_flip_physical{24.0}=0x0
+phy_chain_rx_polarity_flip_physical{24.0}=0x0
+phy_chain_tx_polarity_flip_physical{29.0}=0x0
+phy_chain_rx_polarity_flip_physical{29.0}=0x1
+phy_chain_tx_polarity_flip_physical{30.0}=0x0
+phy_chain_rx_polarity_flip_physical{30.0}=0x1
+phy_chain_tx_polarity_flip_physical{31.0}=0x0
+phy_chain_rx_polarity_flip_physical{31.0}=0x1
+phy_chain_tx_polarity_flip_physical{32.0}=0x0
+phy_chain_rx_polarity_flip_physical{32.0}=0x1
+phy_chain_tx_polarity_flip_physical{33.0}=0x0
+phy_chain_rx_polarity_flip_physical{33.0}=0x0
+phy_chain_tx_polarity_flip_physical{34.0}=0x0
+phy_chain_rx_polarity_flip_physical{34.0}=0x0
+phy_chain_tx_polarity_flip_physical{35.0}=0x0
+phy_chain_rx_polarity_flip_physical{35.0}=0x0
+phy_chain_tx_polarity_flip_physical{36.0}=0x0
+phy_chain_rx_polarity_flip_physical{36.0}=0x0
+phy_chain_tx_polarity_flip_physical{41.0}=0x0
+phy_chain_rx_polarity_flip_physical{41.0}=0x0
+phy_chain_tx_polarity_flip_physical{42.0}=0x0
+phy_chain_rx_polarity_flip_physical{42.0}=0x0
+phy_chain_tx_polarity_flip_physical{43.0}=0x0
+phy_chain_rx_polarity_flip_physical{43.0}=0x0
+phy_chain_tx_polarity_flip_physical{44.0}=0x0
+phy_chain_rx_polarity_flip_physical{44.0}=0x0
+phy_chain_tx_polarity_flip_physical{49.0}=0x0
+phy_chain_rx_polarity_flip_physical{49.0}=0x0
+phy_chain_tx_polarity_flip_physical{50.0}=0x0
+phy_chain_rx_polarity_flip_physical{50.0}=0x0
+phy_chain_tx_polarity_flip_physical{51.0}=0x0
+phy_chain_rx_polarity_flip_physical{51.0}=0x0
+phy_chain_tx_polarity_flip_physical{52.0}=0x0
+phy_chain_rx_polarity_flip_physical{52.0}=0x0
+phy_chain_tx_polarity_flip_physical{57.0}=0x0
+phy_chain_rx_polarity_flip_physical{57.0}=0x0
+phy_chain_tx_polarity_flip_physical{58.0}=0x0
+phy_chain_rx_polarity_flip_physical{58.0}=0x0
+phy_chain_tx_polarity_flip_physical{59.0}=0x0
+phy_chain_rx_polarity_flip_physical{59.0}=0x0
+phy_chain_tx_polarity_flip_physical{60.0}=0x0
+phy_chain_rx_polarity_flip_physical{60.0}=0x0
+phy_chain_tx_polarity_flip_physical{61.0}=0x0
+phy_chain_rx_polarity_flip_physical{61.0}=0x1
+phy_chain_tx_polarity_flip_physical{62.0}=0x0
+phy_chain_rx_polarity_flip_physical{62.0}=0x1
+phy_chain_tx_polarity_flip_physical{63.0}=0x0
+phy_chain_rx_polarity_flip_physical{63.0}=0x1
+phy_chain_tx_polarity_flip_physical{64.0}=0x0
+phy_chain_rx_polarity_flip_physical{64.0}=0x1
+phy_chain_tx_polarity_flip_physical{65.0}=0x0
+phy_chain_rx_polarity_flip_physical{65.0}=0x1
+phy_chain_tx_polarity_flip_physical{66.0}=0x0
+phy_chain_rx_polarity_flip_physical{66.0}=0x1
+phy_chain_tx_polarity_flip_physical{67.0}=0x0
+phy_chain_rx_polarity_flip_physical{67.0}=0x1
+phy_chain_tx_polarity_flip_physical{68.0}=0x0
+phy_chain_rx_polarity_flip_physical{68.0}=0x1
+phy_chain_tx_polarity_flip_physical{69.0}=0x0
+phy_chain_rx_polarity_flip_physical{69.0}=0x0
+phy_chain_tx_polarity_flip_physical{70.0}=0x0
+phy_chain_rx_polarity_flip_physical{70.0}=0x0
+phy_chain_tx_polarity_flip_physical{71.0}=0x0
+phy_chain_rx_polarity_flip_physical{71.0}=0x0
+phy_chain_tx_polarity_flip_physical{72.0}=0x0
+phy_chain_rx_polarity_flip_physical{72.0}=0x0
+phy_chain_tx_polarity_flip_physical{85.0}=0x1
+phy_chain_rx_polarity_flip_physical{85.0}=0x1
+phy_chain_tx_polarity_flip_physical{86.0}=0x0
+phy_chain_rx_polarity_flip_physical{86.0}=0x1
+phy_chain_tx_polarity_flip_physical{87.0}=0x1
+phy_chain_rx_polarity_flip_physical{87.0}=0x1
+phy_chain_tx_polarity_flip_physical{88.0}=0x0
+phy_chain_rx_polarity_flip_physical{88.0}=0x1
+phy_chain_tx_polarity_flip_physical{77.0}=0x1
+phy_chain_rx_polarity_flip_physical{77.0}=0x1
+phy_chain_tx_polarity_flip_physical{78.0}=0x1
+phy_chain_rx_polarity_flip_physical{78.0}=0x0
+phy_chain_tx_polarity_flip_physical{79.0}=0x1
+phy_chain_rx_polarity_flip_physical{79.0}=0x1
+phy_chain_tx_polarity_flip_physical{80.0}=0x1
+phy_chain_rx_polarity_flip_physical{80.0}=0x1
+phy_chain_tx_polarity_flip_physical{97.0}=0x1
+phy_chain_rx_polarity_flip_physical{97.0}=0x0
+phy_chain_tx_polarity_flip_physical{98.0}=0x0
+phy_chain_rx_polarity_flip_physical{98.0}=0x0
+phy_chain_tx_polarity_flip_physical{99.0}=0x1
+phy_chain_rx_polarity_flip_physical{99.0}=0x0
+phy_chain_tx_polarity_flip_physical{100.0}=0x0
+phy_chain_rx_polarity_flip_physical{100.0}=0x0
+phy_chain_tx_polarity_flip_physical{93.0}=0x1
+phy_chain_rx_polarity_flip_physical{93.0}=0x1
+phy_chain_tx_polarity_flip_physical{94.0}=0x1
+phy_chain_rx_polarity_flip_physical{94.0}=0x0
+phy_chain_tx_polarity_flip_physical{95.0}=0x1
+phy_chain_rx_polarity_flip_physical{95.0}=0x1
+phy_chain_tx_polarity_flip_physical{96.0}=0x1
+phy_chain_rx_polarity_flip_physical{96.0}=0x1
+phy_chain_tx_polarity_flip_physical{113.0}=0x1
+phy_chain_rx_polarity_flip_physical{113.0}=0x1
+phy_chain_tx_polarity_flip_physical{114.0}=0x0
+phy_chain_rx_polarity_flip_physical{114.0}=0x1
+phy_chain_tx_polarity_flip_physical{115.0}=0x1
+phy_chain_rx_polarity_flip_physical{115.0}=0x1
+phy_chain_tx_polarity_flip_physical{116.0}=0x0
+phy_chain_rx_polarity_flip_physical{116.0}=0x1
+phy_chain_tx_polarity_flip_physical{105.0}=0x1
+phy_chain_rx_polarity_flip_physical{105.0}=0x1
+phy_chain_tx_polarity_flip_physical{106.0}=0x1
+phy_chain_rx_polarity_flip_physical{106.0}=0x0
+phy_chain_tx_polarity_flip_physical{107.0}=0x1
+phy_chain_rx_polarity_flip_physical{107.0}=0x1
+phy_chain_tx_polarity_flip_physical{108.0}=0x1
+phy_chain_rx_polarity_flip_physical{108.0}=0x1
+phy_chain_tx_polarity_flip_physical{121.0}=0x1
+phy_chain_rx_polarity_flip_physical{121.0}=0x1
+phy_chain_tx_polarity_flip_physical{122.0}=0x0
+phy_chain_rx_polarity_flip_physical{122.0}=0x0
+phy_chain_tx_polarity_flip_physical{123.0}=0x1
+phy_chain_rx_polarity_flip_physical{123.0}=0x0
+phy_chain_tx_polarity_flip_physical{124.0}=0x0
+phy_chain_rx_polarity_flip_physical{124.0}=0x1
+phy_chain_tx_polarity_flip_physical{125.0}=0x0
+phy_chain_rx_polarity_flip_physical{125.0}=0x0
+phy_chain_tx_polarity_flip_physical{126.0}=0x1
+phy_chain_rx_polarity_flip_physical{126.0}=0x1
+phy_chain_tx_polarity_flip_physical{127.0}=0x0
+phy_chain_rx_polarity_flip_physical{127.0}=0x0
+phy_chain_tx_polarity_flip_physical{128.0}=0x0
+phy_chain_rx_polarity_flip_physical{128.0}=0x0
+port_flex_enable=1
+portmap_1=1:25
+portmap_2=2:25
+portmap_3=3:25
+portmap_4=4:25
+portmap_5=5:25
+portmap_6=6:25
+portmap_7=7:25
+portmap_8=8:25
+portmap_13=13:25
+portmap_14=14:25
+portmap_15=15:25
+portmap_16=16:25
+portmap_21=21:25
+portmap_22=22:25
+portmap_23=23:25
+portmap_24=24:25
+portmap_29=29:25
+portmap_30=30:25
+portmap_31=31:25
+portmap_32=32:25
+portmap_33=33:25
+portmap_34=34:25
+portmap_35=35:25
+portmap_36=36:25
+portmap_41=41:25
+portmap_42=42:25
+portmap_43=43:25
+portmap_44=44:25
+portmap_49=49:25
+portmap_50=50:25
+portmap_51=51:25
+portmap_52=52:25
+portmap_57=57:25
+portmap_58=58:25
+portmap_59=59:25
+portmap_60=60:25
+portmap_61=61:25
+portmap_62=62:25
+portmap_63=63:25
+portmap_64=64:25
+portmap_67=65:25
+portmap_68=66:25
+portmap_69=67:25
+portmap_70=68:25
+portmap_71=69:25
+portmap_72=70:25
+portmap_73=71:25
+portmap_74=72:25
+portmap_79=77:100
+portmap_87=85:100
+portmap_95=93:100
+portmap_99=97:100
+portmap_107=105:100
+portmap_115=113:100
+portmap_123=121:100
+portmap_127=125:100
+
+dport_map_port_1=1
+dport_map_port_2=2
+dport_map_port_3=3
+dport_map_port_4=4
+dport_map_port_5=5
+dport_map_port_6=6
+dport_map_port_7=7
+dport_map_port_8=8
+dport_map_port_13=9
+dport_map_port_14=10
+dport_map_port_15=11
+dport_map_port_16=12
+dport_map_port_21=13
+dport_map_port_22=14
+dport_map_port_23=15
+dport_map_port_24=16
+dport_map_port_29=17
+dport_map_port_30=18
+dport_map_port_31=19
+dport_map_port_32=20
+dport_map_port_33=21
+dport_map_port_34=22
+dport_map_port_35=23
+dport_map_port_36=24
+dport_map_port_41=25
+dport_map_port_42=26
+dport_map_port_43=27
+dport_map_port_44=28
+dport_map_port_49=29
+dport_map_port_50=30
+dport_map_port_51=31
+dport_map_port_52=32
+dport_map_port_57=33
+dport_map_port_58=34
+dport_map_port_59=35
+dport_map_port_60=36
+dport_map_port_61=37
+dport_map_port_62=38
+dport_map_port_63=39
+dport_map_port_64=40
+dport_map_port_67=41
+dport_map_port_68=42
+dport_map_port_69=43
+dport_map_port_70=44
+dport_map_port_71=45
+dport_map_port_72=46
+dport_map_port_73=47
+dport_map_port_74=48
+dport_map_port_87=49
+dport_map_port_79=50
+dport_map_port_99=51
+dport_map_port_95=52
+dport_map_port_115=53
+dport_map_port_107=54
+dport_map_port_123=55
+dport_map_port_127=56
+dport_map_port_66=57
+dport_map_port_130=58
+
+portmap_66=129:10:m
+portmap_130=128:10:m
+port_init_autoneg_66=1
+port_init_autoneg_130=1
+serdes_if_type_66=11
+serdes_if_type_130=11
+
+serdes_preemphasis_lane0_1=0x0f480d
+serdes_preemphasis_lane1_1=0x0f480d
+serdes_preemphasis_lane2_1=0x0f480d
+serdes_preemphasis_lane3_1=0x0f480d
+serdes_preemphasis_lane0_2=0x0f480d
+serdes_preemphasis_lane1_2=0x0f480d
+serdes_preemphasis_lane2_2=0x0f480d
+serdes_preemphasis_lane3_2=0x0f480d
+serdes_preemphasis_lane0_3=0x0f480d
+serdes_preemphasis_lane1_3=0x0f480d
+serdes_preemphasis_lane2_3=0x0f480d
+serdes_preemphasis_lane3_3=0x0f480d
+serdes_preemphasis_lane0_4=0x0f480d
+serdes_preemphasis_lane1_4=0x0f480d
+serdes_preemphasis_lane2_4=0x0f480d
+serdes_preemphasis_lane3_4=0x0f480d
+serdes_preemphasis_lane0_5=0x0f480d
+serdes_preemphasis_lane1_5=0x0f480d
+serdes_preemphasis_lane2_5=0x0f480d
+serdes_preemphasis_lane3_5=0x0f480d
+serdes_preemphasis_lane0_6=0x0f480d
+serdes_preemphasis_lane1_6=0x0f480d
+serdes_preemphasis_lane2_6=0x0f480d
+serdes_preemphasis_lane3_6=0x0f480d
+serdes_preemphasis_lane0_7=0x0d4b0c
+serdes_preemphasis_lane1_7=0x0d4b0c
+serdes_preemphasis_lane2_7=0x0d4b0c
+serdes_preemphasis_lane3_7=0x0d4b0c
+serdes_preemphasis_lane0_8=0x0d4b0c
+serdes_preemphasis_lane1_8=0x0d4b0c
+serdes_preemphasis_lane2_8=0x0d4b0c
+serdes_preemphasis_lane3_8=0x0d4b0c
+serdes_preemphasis_lane0_13=0x0d4b0c
+serdes_preemphasis_lane1_13=0x0d4b0c
+serdes_preemphasis_lane2_13=0x0d4b0c
+serdes_preemphasis_lane3_13=0x0d4b0c
+serdes_preemphasis_lane0_14=0x0d4b0c
+serdes_preemphasis_lane1_14=0x0d4b0c
+serdes_preemphasis_lane2_14=0x0d4b0c
+serdes_preemphasis_lane3_14=0x0d4b0c
+serdes_preemphasis_lane0_15=0x0d4b0c
+serdes_preemphasis_lane1_15=0x0d4b0c
+serdes_preemphasis_lane2_15=0x0d4b0c
+serdes_preemphasis_lane3_15=0x0d4b0c
+serdes_preemphasis_lane0_16=0x0d4b0c
+serdes_preemphasis_lane1_16=0x0d4b0c
+serdes_preemphasis_lane2_16=0x0d4b0c
+serdes_preemphasis_lane3_16=0x0d4b0c
+serdes_preemphasis_lane0_21=0x0d4b0c
+serdes_preemphasis_lane1_21=0x0d4b0c
+serdes_preemphasis_lane2_21=0x0d4b0c
+serdes_preemphasis_lane3_21=0x0d4b0c
+serdes_preemphasis_lane0_22=0x0d4b0c
+serdes_preemphasis_lane1_22=0x0d4b0c
+serdes_preemphasis_lane2_22=0x0d4b0c
+serdes_preemphasis_lane3_22=0x0d4b0c
+serdes_preemphasis_lane0_23=0x0d4b0c
+serdes_preemphasis_lane1_23=0x0d4b0c
+serdes_preemphasis_lane2_23=0x0d4b0c
+serdes_preemphasis_lane3_23=0x0d4b0c
+serdes_preemphasis_lane0_24=0x0d4b0c
+serdes_preemphasis_lane1_24=0x0d4b0c
+serdes_preemphasis_lane2_24=0x0d4b0c
+serdes_preemphasis_lane3_24=0x0d4b0c
+serdes_preemphasis_lane0_29=0x0d4b0c
+serdes_preemphasis_lane1_29=0x0d4b0c
+serdes_preemphasis_lane2_29=0x0d4b0c
+serdes_preemphasis_lane3_29=0x0d4b0c
+serdes_preemphasis_lane0_30=0x0d4b0c
+serdes_preemphasis_lane1_30=0x0d4b0c
+serdes_preemphasis_lane2_30=0x0d4b0c
+serdes_preemphasis_lane3_30=0x0d4b0c
+serdes_preemphasis_lane0_31=0x0d4b0c
+serdes_preemphasis_lane1_31=0x0d4b0c
+serdes_preemphasis_lane2_31=0x0d4b0c
+serdes_preemphasis_lane3_31=0x0d4b0c
+serdes_preemphasis_lane0_32=0x0d4b0c
+serdes_preemphasis_lane1_32=0x0d4b0c
+serdes_preemphasis_lane2_32=0x0d4b0c
+serdes_preemphasis_lane3_32=0x0d4b0c
+serdes_preemphasis_lane0_33=0x0d4b0c
+serdes_preemphasis_lane1_33=0x0d4b0c
+serdes_preemphasis_lane2_33=0x0d4b0c
+serdes_preemphasis_lane3_33=0x0d4b0c
+serdes_preemphasis_lane0_34=0x0d4b0c
+serdes_preemphasis_lane1_34=0x0d4b0c
+serdes_preemphasis_lane2_34=0x0d4b0c
+serdes_preemphasis_lane3_34=0x0d4b0c
+serdes_preemphasis_lane0_35=0x0d4b0c
+serdes_preemphasis_lane1_35=0x0d4b0c
+serdes_preemphasis_lane2_35=0x0d4b0c
+serdes_preemphasis_lane3_35=0x0d4b0c
+serdes_preemphasis_lane0_36=0x0d4b0c
+serdes_preemphasis_lane1_36=0x0d4b0c
+serdes_preemphasis_lane2_36=0x0d4b0c
+serdes_preemphasis_lane3_36=0x0d4b0c
+serdes_preemphasis_lane0_41=0x0d4b0c
+serdes_preemphasis_lane1_41=0x0d4b0c
+serdes_preemphasis_lane2_41=0x0d4b0c
+serdes_preemphasis_lane3_41=0x0d4b0c
+serdes_preemphasis_lane0_42=0x0d4b0c
+serdes_preemphasis_lane1_42=0x0d4b0c
+serdes_preemphasis_lane2_42=0x0d4b0c
+serdes_preemphasis_lane3_42=0x0d4b0c
+serdes_preemphasis_lane0_43=0x0d4b0c
+serdes_preemphasis_lane1_43=0x0d4b0c
+serdes_preemphasis_lane2_43=0x0d4b0c
+serdes_preemphasis_lane3_43=0x0d4b0c
+serdes_preemphasis_lane0_44=0x0d4b0c
+serdes_preemphasis_lane1_44=0x0d4b0c
+serdes_preemphasis_lane2_44=0x0d4b0c
+serdes_preemphasis_lane3_44=0x0d4b0c
+serdes_preemphasis_lane0_49=0x0d4b0c
+serdes_preemphasis_lane1_49=0x0d4b0c
+serdes_preemphasis_lane2_49=0x0d4b0c
+serdes_preemphasis_lane3_49=0x0d4b0c
+serdes_preemphasis_lane0_50=0x0d4b0c
+serdes_preemphasis_lane1_50=0x0d4b0c
+serdes_preemphasis_lane2_50=0x0d4b0c
+serdes_preemphasis_lane3_50=0x0d4b0c
+serdes_preemphasis_lane0_51=0x0d4b0c
+serdes_preemphasis_lane1_51=0x0d4b0c
+serdes_preemphasis_lane2_51=0x0d4b0c
+serdes_preemphasis_lane3_51=0x0d4b0c
+serdes_preemphasis_lane0_52=0x0d4b0c
+serdes_preemphasis_lane1_52=0x0d4b0c
+serdes_preemphasis_lane2_52=0x0d4b0c
+serdes_preemphasis_lane3_52=0x0d4b0c
+serdes_preemphasis_lane0_57=0x0d4b0c
+serdes_preemphasis_lane1_57=0x0d4b0c
+serdes_preemphasis_lane2_57=0x0d4b0c
+serdes_preemphasis_lane3_57=0x0d4b0c
+serdes_preemphasis_lane0_58=0x0d4b0c
+serdes_preemphasis_lane1_58=0x0d4b0c
+serdes_preemphasis_lane2_58=0x0d4b0c
+serdes_preemphasis_lane3_58=0x0d4b0c
+serdes_preemphasis_lane0_59=0x0d4b0c
+serdes_preemphasis_lane1_59=0x0d4b0c
+serdes_preemphasis_lane2_59=0x0d4b0c
+serdes_preemphasis_lane3_59=0x0d4b0c
+serdes_preemphasis_lane0_60=0x0d4b0c
+serdes_preemphasis_lane1_60=0x0d4b0c
+serdes_preemphasis_lane2_60=0x0d4b0c
+serdes_preemphasis_lane3_60=0x0d4b0c
+serdes_preemphasis_lane0_61=0x0d4b0c
+serdes_preemphasis_lane1_61=0x0d4b0c
+serdes_preemphasis_lane2_61=0x0d4b0c
+serdes_preemphasis_lane3_61=0x0d4b0c
+serdes_preemphasis_lane0_62=0x0d4b0c
+serdes_preemphasis_lane1_62=0x0d4b0c
+serdes_preemphasis_lane2_62=0x0d4b0c
+serdes_preemphasis_lane3_62=0x0d4b0c
+serdes_preemphasis_lane0_63=0x0d4b0c
+serdes_preemphasis_lane1_63=0x0d4b0c
+serdes_preemphasis_lane2_63=0x0d4b0c
+serdes_preemphasis_lane3_63=0x0d4b0c
+serdes_preemphasis_lane0_64=0x0d4b0c
+serdes_preemphasis_lane1_64=0x0d4b0c
+serdes_preemphasis_lane2_64=0x0d4b0c
+serdes_preemphasis_lane3_64=0x0d4b0c
+serdes_preemphasis_lane0_67=0x0d4b0c
+serdes_preemphasis_lane1_67=0x0d4b0c
+serdes_preemphasis_lane2_67=0x0d4b0c
+serdes_preemphasis_lane3_67=0x0d4b0c
+serdes_preemphasis_lane0_68=0x0d4b0c
+serdes_preemphasis_lane1_68=0x0d4b0c
+serdes_preemphasis_lane2_68=0x0d4b0c
+serdes_preemphasis_lane3_68=0x0d4b0c
+serdes_preemphasis_lane0_69=0x0d4b0c
+serdes_preemphasis_lane1_69=0x0d4b0c
+serdes_preemphasis_lane2_69=0x0d4b0c
+serdes_preemphasis_lane3_69=0x0d4b0c
+serdes_preemphasis_lane0_70=0x0d4b0c
+serdes_preemphasis_lane1_70=0x0d4b0c
+serdes_preemphasis_lane2_70=0x0d4b0c
+serdes_preemphasis_lane3_70=0x0d4b0c
+serdes_preemphasis_lane0_71=0x0d4b0c
+serdes_preemphasis_lane1_71=0x0d4b0c
+serdes_preemphasis_lane2_71=0x0d4b0c
+serdes_preemphasis_lane3_71=0x0d4b0c
+serdes_preemphasis_lane0_72=0x0d4b0c
+serdes_preemphasis_lane1_72=0x0d4b0c
+serdes_preemphasis_lane2_72=0x0d4b0c
+serdes_preemphasis_lane3_72=0x0d4b0c
+serdes_preemphasis_lane0_73=0x0d4b0c
+serdes_preemphasis_lane1_73=0x0d4b0c
+serdes_preemphasis_lane2_73=0x0d4b0c
+serdes_preemphasis_lane3_73=0x0d4b0c
+serdes_preemphasis_lane0_74=0x0d4b0c
+serdes_preemphasis_lane1_74=0x0d4b0c
+serdes_preemphasis_lane2_74=0x0d4b0c
+serdes_preemphasis_lane3_74=0x0d4b0c
+serdes_preemphasis_lane0_87=0x0d4b0c
+serdes_preemphasis_lane1_87=0x0d4b0c
+serdes_preemphasis_lane2_87=0x0d4b0c
+serdes_preemphasis_lane3_87=0x0d4b0c
+serdes_preemphasis_lane0_79=0x0d4b0c
+serdes_preemphasis_lane1_79=0x0d4b0c
+serdes_preemphasis_lane2_79=0x0d4b0c
+serdes_preemphasis_lane3_79=0x0d4b0c
+serdes_preemphasis_lane0_99=0x0d4b0c
+serdes_preemphasis_lane1_99=0x0d4b0c
+serdes_preemphasis_lane2_99=0x0d4b0c
+serdes_preemphasis_lane3_99=0x0d4b0c
+serdes_preemphasis_lane0_95=0x0d4b0c
+serdes_preemphasis_lane1_95=0x0d4b0c
+serdes_preemphasis_lane2_95=0x0d4b0c
+serdes_preemphasis_lane3_95=0x0d4b0c
+serdes_preemphasis_lane0_115=0x0f480d
+serdes_preemphasis_lane1_115=0x0f480d
+serdes_preemphasis_lane2_115=0x0f480d
+serdes_preemphasis_lane3_115=0x0f480d
+serdes_preemphasis_lane0_107=0x0f480d
+serdes_preemphasis_lane1_107=0x0f480d
+serdes_preemphasis_lane2_107=0x0f480d
+serdes_preemphasis_lane3_107=0x0f480d
+serdes_preemphasis_lane0_123=0x0f480d
+serdes_preemphasis_lane1_123=0x0f480d
+serdes_preemphasis_lane2_123=0x0f480d
+serdes_preemphasis_lane3_123=0x0f480d
+serdes_preemphasis_lane0_127=0x0f480d
+serdes_preemphasis_lane1_127=0x0f480d
+serdes_preemphasis_lane2_127=0x0f480d
+serdes_preemphasis_lane3_127=0x0f480d
+
+reglist_enable=1
+scache_filename=/tmp/scache
+schan_intr_enable=0
+stable_size=0x5500000
+tdma_timeout_usec=3000000
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/b6510_48vs8cq_linkscan_led_fw.bin b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/b6510_48vs8cq_linkscan_led_fw.bin
new file mode 100644
index 000000000000..a6a4794ecc2b
Binary files /dev/null and b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/b6510_48vs8cq_linkscan_led_fw.bin differ
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/custom_led_b6510_48vs8cq.bin b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/custom_led_b6510_48vs8cq.bin
new file mode 100644
index 000000000000..1fe5585e0779
Binary files /dev/null and b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/custom_led_b6510_48vs8cq.bin differ
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/default_sku b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/default_sku
new file mode 100644
index 000000000000..3f0585c6e5b5
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/default_sku
@@ -0,0 +1 @@
+B6510-48VS8CQ t1
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/installer.conf b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/installer.conf
new file mode 100755
index 000000000000..5e62742c11bf
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/installer.conf
@@ -0,0 +1 @@
+CONSOLE_SPEED=115200
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/led_proc_init.soc b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/led_proc_init.soc
new file mode 100755
index 000000000000..8ffe4fde0c3c
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/led_proc_init.soc
@@ -0,0 +1,6 @@
+
+led auto on
+
+led start
+
+linkscan SwPortBitMap=xe,ce
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/minigraph.xml b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/minigraph.xml
new file mode 100755
index 000000000000..152060166911
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/minigraph.xml
@@ -0,0 +1,1199 @@
+
+
+
+
+
+ ARISTA01T0
+ 10.0.0.33
+ switch2
+ 10.0.0.32
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.0
+ ARISTA01T2
+ 10.0.0.1
+ 1
+ 180
+ 60
+
+
+ ARISTA02T0
+ 10.0.0.35
+ switch2
+ 10.0.0.34
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.2
+ ARISTA02T2
+ 10.0.0.3
+ 1
+ 180
+ 60
+
+
+ ARISTA03T0
+ 10.0.0.37
+ switch2
+ 10.0.0.36
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.4
+ ARISTA03T2
+ 10.0.0.5
+ 1
+ 180
+ 60
+
+
+ ARISTA04T0
+ 10.0.0.39
+ switch2
+ 10.0.0.38
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.6
+ ARISTA04T2
+ 10.0.0.7
+ 1
+ 180
+ 60
+
+
+ ARISTA05T0
+ 10.0.0.41
+ switch2
+ 10.0.0.40
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.8
+ ARISTA05T2
+ 10.0.0.9
+ 1
+ 180
+ 60
+
+
+ ARISTA06T0
+ 10.0.0.43
+ switch2
+ 10.0.0.42
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.10
+ ARISTA06T2
+ 10.0.0.11
+ 1
+ 180
+ 60
+
+
+ ARISTA07T0
+ 10.0.0.45
+ switch2
+ 10.0.0.44
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.12
+ ARISTA07T2
+ 10.0.0.13
+ 1
+ 180
+ 60
+
+
+ ARISTA08T0
+ 10.0.0.47
+ switch2
+ 10.0.0.46
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.14
+ ARISTA08T2
+ 10.0.0.15
+ 1
+ 180
+ 60
+
+
+ ARISTA09T0
+ 10.0.0.49
+ switch2
+ 10.0.0.48
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.16
+ ARISTA09T2
+ 10.0.0.17
+ 1
+ 180
+ 60
+
+
+ ARISTA10T0
+ 10.0.0.51
+ switch2
+ 10.0.0.50
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.18
+ ARISTA10T2
+ 10.0.0.19
+ 1
+ 180
+ 60
+
+
+ ARISTA11T0
+ 10.0.0.53
+ switch2
+ 10.0.0.52
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.20
+ ARISTA11T2
+ 10.0.0.21
+ 1
+ 180
+ 60
+
+
+ ARISTA12T0
+ 10.0.0.55
+ switch2
+ 10.0.0.54
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.22
+ ARISTA12T2
+ 10.0.0.23
+ 1
+ 180
+ 60
+
+
+ ARISTA13T0
+ 10.0.0.57
+ switch2
+ 10.0.0.56
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.24
+ ARISTA13T2
+ 10.0.0.25
+ 1
+ 180
+ 60
+
+
+ ARISTA14T0
+ 10.0.0.59
+ switch2
+ 10.0.0.58
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.26
+ ARISTA14T2
+ 10.0.0.27
+ 1
+ 180
+ 60
+
+
+ ARISTA15T0
+ 10.0.0.61
+ switch2
+ 10.0.0.60
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.28
+ ARISTA15T2
+ 10.0.0.29
+ 1
+ 180
+ 60
+
+
+ ARISTA16T0
+ 10.0.0.63
+ switch2
+ 10.0.0.62
+ 1
+ 180
+ 60
+
+
+ switch2
+ 10.0.0.30
+ ARISTA16T2
+ 10.0.0.31
+ 1
+ 180
+ 60
+
+
+
+
+ 65100
+ switch2
+
+
+ 10.0.0.33
+
+
+
+
+ 10.0.0.1
+
+
+
+
+ 10.0.0.35
+
+
+
+
+ 10.0.0.3
+
+
+
+
+ 10.0.0.37
+
+
+
+
+ 10.0.0.5
+
+
+
+
+ 10.0.0.39
+
+
+
+
+ 10.0.0.7
+
+
+
+
+ 10.0.0.41
+
+
+
+
+ 10.0.0.9
+
+
+
+
+ 10.0.0.43
+
+
+
+
+ 10.0.0.11
+
+
+
+
+ 10.0.0.45
+
+
+
+
+ 10.0.0.13
+
+
+
+
+ 10.0.0.47
+
+
+
+
+ 10.0.0.15
+
+
+
+
+ 10.0.0.49
+
+
+
+
+ 10.0.0.17
+
+
+
+
+ 10.0.0.51
+
+
+
+
+ 10.0.0.19
+
+
+
+
+ 10.0.0.53
+
+
+
+
+ 10.0.0.21
+
+
+
+
+ 10.0.0.55
+
+
+
+
+ 10.0.0.23
+
+
+
+
+ 10.0.0.57
+
+
+
+
+ 10.0.0.25
+
+
+
+
+ 10.0.0.59
+
+
+
+
+ 10.0.0.27
+
+
+
+
+ 10.0.0.61
+
+
+
+
+ 10.0.0.29
+
+
+
+
+ 10.0.0.63
+
+
+
+
+ 10.0.0.31
+
+
+
+
+
+
+
+ 64001
+ ARISTA01T0
+
+
+
+ 65200
+ ARISTA01T2
+
+
+
+ 64002
+ ARISTA02T0
+
+
+
+ 65200
+ ARISTA02T2
+
+
+
+ 64003
+ ARISTA03T0
+
+
+
+ 65200
+ ARISTA03T2
+
+
+
+ 64004
+ ARISTA04T0
+
+
+
+ 65200
+ ARISTA04T2
+
+
+
+ 64005
+ ARISTA05T0
+
+
+
+ 65200
+ ARISTA05T2
+
+
+
+ 64006
+ ARISTA06T0
+
+
+
+ 65200
+ ARISTA06T2
+
+
+
+ 64007
+ ARISTA07T0
+
+
+
+ 65200
+ ARISTA07T2
+
+
+
+ 64008
+ ARISTA08T0
+
+
+
+ 65200
+ ARISTA08T2
+
+
+
+ 64009
+ ARISTA09T0
+
+
+
+ 65200
+ ARISTA09T2
+
+
+
+ 64010
+ ARISTA10T0
+
+
+
+ 65200
+ ARISTA10T2
+
+
+
+ 64011
+ ARISTA11T0
+
+
+
+ 65200
+ ARISTA11T2
+
+
+
+ 64012
+ ARISTA12T0
+
+
+
+ 65200
+ ARISTA12T2
+
+
+
+ 64013
+ ARISTA13T0
+
+
+
+ 65200
+ ARISTA13T2
+
+
+
+ 64014
+ ARISTA14T0
+
+
+
+ 65200
+ ARISTA14T2
+
+
+
+ 64015
+ ARISTA15T0
+
+
+
+ 65200
+ ARISTA15T2
+
+
+
+ 64016
+ ARISTA16T0
+
+
+
+ 65200
+ ARISTA16T2
+
+
+
+
+
+
+
+
+
+ HostIP
+ Loopback0
+
+ 10.1.0.32/32
+
+ 10.1.0.32/32
+
+
+
+
+
+
+
+ switch2
+
+
+
+
+
+ Ethernet0
+ 10.0.0.0/31
+
+
+
+ Ethernet1
+ 10.0.0.2/31
+
+
+
+ Ethernet2
+ 10.0.0.4/31
+
+
+
+ Ethernet3
+ 10.0.0.6/31
+
+
+
+ Ethernet4
+ 10.0.0.8/31
+
+
+
+ Ethernet5
+ 10.0.0.10/31
+
+
+
+ Ethernet6
+ 10.0.0.12/31
+
+
+
+ Ethernet7
+ 10.0.0.14/31
+
+
+
+ Ethernet8
+ 10.0.0.16/31
+
+
+
+ Ethernet9
+ 10.0.0.18/31
+
+
+
+ Ethernet10
+ 10.0.0.20/31
+
+
+
+ Ethernet11
+ 10.0.0.22/31
+
+
+
+ Ethernet12
+ 10.0.0.24/31
+
+
+
+ Ethernet13
+ 10.0.0.26/31
+
+
+
+ Ethernet14
+ 10.0.0.28/31
+
+
+
+ Ethernet15
+ 10.0.0.30/31
+
+
+
+ Ethernet16
+ 10.0.0.32/31
+
+
+
+ Ethernet17
+ 10.0.0.34/31
+
+
+
+ Ethernet18
+ 10.0.0.36/31
+
+
+
+ Ethernet19
+ 10.0.0.38/31
+
+
+
+ Ethernet20
+ 10.0.0.40/31
+
+
+
+ Ethernet21
+ 10.0.0.42/31
+
+
+
+ Ethernet22
+ 10.0.0.44/31
+
+
+
+ Ethernet23
+ 10.0.0.46/31
+
+
+
+ Ethernet24
+ 10.0.0.48/31
+
+
+
+ Ethernet25
+ 10.0.0.50/31
+
+
+
+ Ethernet26
+ 10.0.0.52/31
+
+
+
+ Ethernet27
+ 10.0.0.54/31
+
+
+
+ Ethernet28
+ 10.0.0.56/31
+
+
+
+ Ethernet29
+ 10.0.0.58/31
+
+
+
+ Ethernet30
+ 10.0.0.60/31
+
+
+
+ Ethernet31
+ 10.0.0.62/31
+
+
+
+ Ethernet32
+ 10.0.0.64/31
+
+
+
+ Ethernet33
+ 10.0.0.66/31
+
+
+
+ Ethernet34
+ 10.0.0.68/31
+
+
+
+ Ethernet35
+ 10.0.0.70/31
+
+
+
+ Ethernet36
+ 10.0.0.72/31
+
+
+
+ Ethernet37
+ 10.0.0.74/31
+
+
+
+ Ethernet38
+ 10.0.0.76/31
+
+
+
+ Ethernet39
+ 10.0.0.78/31
+
+
+
+ Ethernet40
+ 10.0.0.80/31
+
+
+
+ Ethernet41
+ 10.0.0.82/31
+
+
+
+ Ethernet42
+ 10.0.0.84/31
+
+
+
+ Ethernet43
+ 10.0.0.86/31
+
+
+
+ Ethernet44
+ 10.0.0.88/31
+
+
+
+ Ethernet45
+ 10.0.0.90/31
+
+
+
+ Ethernet46
+ 10.0.0.92/31
+
+
+
+ Ethernet47
+ 10.0.0.94/31
+
+
+
+ Ethernet48
+ 10.0.0.96/31
+
+
+
+ Ethernet52
+ 10.0.0.98/31
+
+
+
+ Ethernet56
+ 10.0.0.100/31
+
+
+
+ Ethernet60
+ 10.0.0.102/31
+
+
+
+ Ethernet64
+ 10.0.0.104/31
+
+
+
+ Ethernet68
+ 10.0.0.106/31
+
+
+
+ Ethernet72
+ 10.0.0.108/31
+
+
+
+ Ethernet76
+ 10.0.0.110/31
+
+
+
+
+
+
+
+
+
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet0
+ ARISTA01T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet1
+ ARISTA02T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet2
+ ARISTA03T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet3
+ ARISTA04T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet4
+ ARISTA05T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet5
+ ARISTA06T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet6
+ ARISTA07T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet7
+ ARISTA08T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet8
+ ARISTA09T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet9
+ ARISTA10T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet10
+ ARISTA11T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet11
+ ARISTA12T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet12
+ ARISTA13T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet13
+ ARISTA14T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet14
+ ARISTA15T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet15
+ ARISTA16T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet16
+ ARISTA01T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet17
+ ARISTA02T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet18
+ ARISTA03T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet19
+ ARISTA04T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet20
+ ARISTA05T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet21
+ ARISTA06T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet22
+ ARISTA07T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet23
+ ARISTA08T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet24
+ ARISTA09T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet25
+ ARISTA10T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet26
+ ARISTA11T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet27
+ ARISTA12T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet28
+ ARISTA13T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet29
+ ARISTA14T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet30
+ ARISTA15T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch2
+ Ethernet31
+ ARISTA16T0
+ Ethernet1
+
+
+
+
+ switch2
+ B6510-48VS8CQ
+
+
+
+
+
+
+ switch2
+
+
+ DhcpResources
+
+
+
+
+ NtpResources
+
+ 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org
+
+
+ SyslogResources
+
+
+
+
+ ErspanDestinationIpv4
+
+ 2.2.2.2
+
+
+
+
+
+
+ switch2
+ B6510-48VS8CQ
+
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/plugins/eeprom.py b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/plugins/eeprom.py
new file mode 100755
index 000000000000..5744ad90dd18
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/plugins/eeprom.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+try:
+ import exceptions
+ import binascii
+ import time
+ import optparse
+ import warnings
+ import os
+ import sys
+ from sonic_eeprom import eeprom_base
+ from sonic_eeprom import eeprom_tlvinfo
+except ImportError, 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 = "/sys/bus/i2c/devices/2-0057/eeprom"
+ super(board, self).__init__(self.eeprom_path, 0, '', True)
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/plugins/psuutil.py b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/plugins/psuutil.py
new file mode 100755
index 000000000000..ca20dde21f3e
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/plugins/psuutil.py
@@ -0,0 +1,65 @@
+#
+# psuutil.py
+# Platform-specific PSU status interface for SONiC
+#
+
+import os.path
+
+try:
+ from sonic_psu.psu_base import PsuBase
+except ImportError as e:
+ raise ImportError(str(e) + "- required module not found")
+
+
+class PsuUtil(PsuBase):
+ """Platform-specific PSUutil class"""
+
+ def __init__(self):
+ PsuBase.__init__(self)
+
+ def get_num_psus(self):
+ return 2
+
+ def get_psu_status(self, index):
+ if index != 1 and index != 2:
+ return False
+
+ psu_path = "/sys/bus/i2c/devices/2-0037/psu_status"
+
+ try:
+ data = open(psu_path, "rb")
+ except IOError:
+ return False
+
+ result = int(data.read(2), 16)
+ data.close()
+
+ if index == 1 and (result & 0x2):
+ return True
+
+ if index == 2 and (result & 0x20):
+ return True
+
+ return False
+
+ def get_psu_presence(self, index):
+ if index != 1 and index != 2:
+ return False
+
+ psu_path = "/sys/bus/i2c/devices/2-0037/psu_status"
+
+ try:
+ data = open(psu_path, "rb")
+ except IOError:
+ return False
+
+ result = int(data.read(2), 16)
+ data.close()
+
+ if index == 1 and (result & 0x1) == 0:
+ return True
+
+ if index == 2 and (result & 0x10) == 0:
+ return True
+
+ return False
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/plugins/sfputil.py b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/plugins/sfputil.py
new file mode 100755
index 000000000000..119e21783705
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/plugins/sfputil.py
@@ -0,0 +1,310 @@
+# sfputil.py
+#
+# Platform-specific SFP transceiver interface for SONiC
+#
+
+try:
+ import time
+ import commands
+ import re
+ import os
+ import threading
+ from sonic_sfp.sfputilbase import SfpUtilBase
+except ImportError as e:
+ raise ImportError("%s - required module not found" % str(e))
+
+
+class SfpUtil(SfpUtilBase):
+ """Platform-specific SfpUtil class"""
+
+ PORT_START = 0
+ PORT_END = 55
+ PORTS_IN_BLOCK = 56
+
+ EEPROM_OFFSET = 11
+ SFP_DEVICE_TYPE = "optoe2"
+ QSFP_DEVICE_TYPE = "optoe1"
+ I2C_MAX_ATTEMPT = 3
+
+ _port_to_eeprom_mapping = {}
+ port_to_i2cbus_mapping ={}
+
+ @property
+ def port_start(self):
+ return self.PORT_START
+
+ @property
+ def port_end(self):
+ return self.PORT_END
+
+ @property
+ def qsfp_ports(self):
+ return range(48, self.PORTS_IN_BLOCK)
+
+ @property
+ def port_to_eeprom_mapping(self):
+ return self._port_to_eeprom_mapping
+
+ def __init__(self):
+ for x in range(self.PORT_START, self.PORTS_IN_BLOCK):
+ self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET)
+ SfpUtilBase.__init__(self)
+
+ def _sfp_read_file_path(self, file_path, offset, num_bytes):
+ attempts = 0
+ while attempts < self.I2C_MAX_ATTEMPT:
+ try:
+ sysfsfile = open(file_path, "rb", buffering=0)
+ sysfsfile.seek(offset)
+ read_buf = sysfsfile.read(num_bytes)
+ except:
+ attempts += 1
+ sysfsfile.close()
+ time.sleep(0.05)
+ else:
+ sysfsfile.close()
+ return True, read_buf
+ return False, None
+
+ def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset):
+ if not os.path.exists(sysfs_sfp_i2c_client_eeprompath):
+ return False
+ else:
+ rv, buf = self._sfp_read_file_path(sysfs_sfp_i2c_client_eeprompath, offset, 1)
+ return rv
+
+ def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype):
+ try:
+ sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path
+
+ # Write device address to new_device file
+ nd_file = open(sysfs_nd_path, "w")
+ nd_str = "%s %s" % (devtype, hex(devaddr))
+ nd_file.write(nd_str)
+ nd_file.close()
+
+ except Exception, err:
+ print "Error writing to new device file: %s" % str(err)
+ return 1
+ else:
+ return 0
+
+ def _read_eeprom_devid(self, port_num, devid, offset):
+ sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter"
+ eeprom_raw = []
+ num_bytes = 256
+
+ for i in range(0, num_bytes):
+ eeprom_raw.append("0x00")
+
+ if port_num in self.port_to_eeprom_mapping.keys():
+ sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num]
+ else:
+ sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter"
+
+ i2c_adapter_id = self._get_port_i2c_adapter_id(port_num)
+ if i2c_adapter_id is None:
+ print "Error getting i2c bus num"
+ return None
+
+ # Get i2c virtual bus path for the sfp
+ sysfs_sfp_i2c_adapter_path = "%s/i2c-%s" % (sysfs_i2c_adapter_base_path,
+ str(i2c_adapter_id))
+
+ # If i2c bus for port does not exist
+ if not os.path.exists(sysfs_sfp_i2c_adapter_path):
+ print "Could not find i2c bus %s. Driver not loaded?" % sysfs_sfp_i2c_adapter_path
+ return None
+
+ sysfs_sfp_i2c_client_path = "%s/%s-00%s" % (sysfs_sfp_i2c_adapter_path,
+ str(i2c_adapter_id),
+ hex(devid)[-2:])
+
+ # If sfp device is not present on bus, Add it
+ if not os.path.exists(sysfs_sfp_i2c_client_path):
+ if port_num in self.qsfp_ports:
+ ret = self._add_new_sfp_device(
+ sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DEVICE_TYPE)
+ else:
+ ret = self._add_new_sfp_device(
+ sysfs_sfp_i2c_adapter_path, devid, self.SFP_DEVICE_TYPE)
+ if ret != 0:
+ print "Error adding sfp device"
+ return None
+
+ sysfs_sfp_i2c_client_eeprom_path = "%s/eeprom" % sysfs_sfp_i2c_client_path
+
+ if not self._sfp_eeprom_present(sysfs_sfp_i2c_client_eeprom_path, offset):
+ return None
+
+ rv, raw = self._sfp_read_file_path(sysfs_sfp_i2c_client_eeprom_path, offset, num_bytes)
+ if rv == False:
+ return None
+
+ try:
+ for n in range(0, num_bytes):
+ eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
+ except:
+ return None
+
+ return eeprom_raw
+
+ def get_eeprom_dom_raw(self, port_num):
+ if port_num in self.qsfp_ports:
+ # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw
+ return None
+ else:
+ # Read dom eeprom at addr 0x51
+ return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256)
+
+ def get_presence(self, port_num):
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ if port_num <= 7:
+ presence_path = "/sys/bus/i2c/devices/1-0034/sfp_presence1"
+ elif port_num >= 8 and port_num <= 15:
+ presence_path = "/sys/bus/i2c/devices/1-0034/sfp_presence2"
+ elif port_num >= 16 and port_num <= 23:
+ presence_path = "/sys/bus/i2c/devices/1-0034/sfp_presence3"
+ elif port_num >= 24 and port_num <= 31:
+ presence_path = "/sys/bus/i2c/devices/1-0036/sfp_presence4"
+ elif port_num >= 32 and port_num <= 39:
+ presence_path = "/sys/bus/i2c/devices/1-0036/sfp_presence5"
+ elif port_num >= 40 and port_num <= 47:
+ presence_path = "/sys/bus/i2c/devices/1-0036/sfp_presence6"
+ elif port_num >= 48 and port_num <= 55:
+ presence_path = "/sys/bus/i2c/devices/1-0036/sfp_presence7"
+ else:
+ return False
+
+ try:
+ data = open(presence_path, "rb")
+ except IOError:
+ return False
+
+ presence_data = data.read(2)
+ if presence_data == "":
+ return False
+ result = int(presence_data, 16)
+ data.close()
+
+ # ModPrsL is active low
+ if result & (1 << (port_num % 8)) == 0:
+ return True
+
+ return False
+
+ def get_low_power_mode(self, port_num):
+ # Check for invalid port_num
+
+ return True
+
+ def set_low_power_mode(self, port_num, lpmode):
+ # Check for invalid port_num
+
+ return True
+
+ def reset(self, port_num):
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ return True
+
+ def read_porttab_mappings(self, porttabfile):
+ logical = []
+ logical_to_bcm = {}
+ logical_to_physical = {}
+ physical_to_logical = {}
+ last_fp_port_index = 0
+ last_portname = ""
+ first = 1
+ port_pos_in_file = 0
+ parse_fmt_port_config_ini = False
+ port_index = "index"
+
+ try:
+ f = open(porttabfile)
+ except:
+ raise
+
+ parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini")
+
+ # Read the porttab file and generate dicts
+ # with mapping for future reference.
+ # XXX: move the porttab
+ # parsing stuff to a separate module, or reuse
+ # if something already exists
+ first_line = f.readline().lstrip("#").split()
+ for line in f:
+ line.strip()
+ if re.search("^#", line) is not None:
+ continue
+
+ # Parsing logic for 'port_config.ini' file
+ if (parse_fmt_port_config_ini):
+ # bcm_port is not explicitly listed in port_config.ini format
+ # Currently we assume ports are listed in numerical order according to bcm_port
+ # so we use the port's position in the file (zero-based) as bcm_port
+ portname = line.split()[0]
+
+ bcm_port = str(port_pos_in_file)
+
+ if port_index in first_line:
+ fp_port_index = int(line.split()[first_line.index(port_index)])
+ else:
+ fp_port_index = portname.split("Ethernet").pop()
+ fp_port_index = int(fp_port_index.split("s").pop(0))/4
+ else: # Parsing logic for older 'portmap.ini' file
+ (portname, bcm_port) = line.split("=")[1].split(",")[:2]
+
+ fp_port_index = portname.split("Ethernet").pop()
+ fp_port_index = int(fp_port_index.split("s").pop(0))/4
+
+ if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)):
+ continue
+
+ if first == 1:
+ # Initialize last_[physical|logical]_port
+ # to the first valid port
+ last_fp_port_index = fp_port_index
+ last_portname = portname
+ first = 0
+
+ logical.append(portname)
+
+ logical_to_bcm[portname] = "xe" + bcm_port
+ logical_to_physical[portname] = [fp_port_index]
+ if physical_to_logical.get(fp_port_index) is None:
+ physical_to_logical[fp_port_index] = [portname]
+ else:
+ physical_to_logical[fp_port_index].append(
+ portname)
+
+ if (fp_port_index - last_fp_port_index) > 1:
+ # last port was a gang port
+ for p in range(last_fp_port_index+1, fp_port_index):
+ logical_to_physical[last_portname].append(p)
+ if physical_to_logical.get(p) is None:
+ physical_to_logical[p] = [last_portname]
+ else:
+ physical_to_logical[p].append(last_portname)
+
+ last_fp_port_index = fp_port_index
+ last_portname = portname
+
+ port_pos_in_file += 1
+
+ self.logical = logical
+ self.logical_to_bcm = logical_to_bcm
+ self.logical_to_physical = logical_to_physical
+ self.physical_to_logical = physical_to_logical
+
+ """
+ print "logical: " + self.logical
+ print "logical to bcm: " + self.logical_to_bcm
+ print "logical to physical: " + self.logical_to_physical
+ print "physical to logical: " + self.physical_to_logical
+ """
diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/sensors.conf b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/sensors.conf
new file mode 100755
index 000000000000..4fba4a3c9a0d
--- /dev/null
+++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/sensors.conf
@@ -0,0 +1,21 @@
+# libsensors configuration file
+# ----------------------------------------------
+#
+
+bus "i2c-2" "i2c-0-mux (chan_id 0)"
+
+chip "lm75-i2c-2-48"
+ label temp1 "LM75_0 air_inlet"
+ set temp1_max 75
+ set temp1_crit 65
+
+chip "lm75-i2c-2-49"
+ label temp1 "LM75_1 hottest"
+ set temp1_max 75
+ set temp1_crit 65
+
+chip "lm75-i2c-2-4a"
+ label temp1 "LM75_2 air_outlet"
+ set temp1_max 75
+ set temp1_crit 65
+
diff --git a/platform/broadcom/platform-modules-ruijie.mk b/platform/broadcom/platform-modules-ruijie.mk
new file mode 100644
index 000000000000..6fc2d8e1289a
--- /dev/null
+++ b/platform/broadcom/platform-modules-ruijie.mk
@@ -0,0 +1,10 @@
+## B6510-48VS8CQ
+RUIJIE_B6510_48VS8CQ_PLATFORM_MODULE_VERSION = 1.0
+export RUIJIE_B6510_48VS8CQ_PLATFORM_MODULE_VERSION
+
+RUIJIE_B6510_48VS8CQ_PLATFORM_MODULE = platform-modules-ruijie-b6510-48vs8cq_$(RUIJIE_B6510_48VS8CQ_PLATFORM_MODULE_VERSION)_amd64.deb
+$(RUIJIE_B6510_48VS8CQ_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-ruijie
+$(RUIJIE_B6510_48VS8CQ_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
+$(RUIJIE_B6510_48VS8CQ_PLATFORM_MODULE)_PLATFORM = x86_64-ruijie_b6510-48vs8cq-r0
+SONIC_DPKG_DEBS += $(RUIJIE_B6510_48VS8CQ_PLATFORM_MODULE)
+
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/LICENSE b/platform/broadcom/sonic-platform-modules-ruijie/LICENSE
new file mode 100755
index 000000000000..68463127d0bf
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/LICENSE
@@ -0,0 +1,15 @@
+Copyright (C) 2016 Microsoft, Inc
+Copyright (C) 2018 Ruijie Network Corporation
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/LICENSE b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/LICENSE
new file mode 100755
index 000000000000..68463127d0bf
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/LICENSE
@@ -0,0 +1,15 @@
+Copyright (C) 2016 Microsoft, Inc
+Copyright (C) 2018 Ruijie Network Corporation
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/MAINTAINERS b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/MAINTAINERS
new file mode 100755
index 000000000000..7b2f22c0328a
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/MAINTAINERS
@@ -0,0 +1,6 @@
+# This file describes the maintainers for sonic-platform-modules-ruijie
+# See the SONiC project governance document for more information
+
+Name = "sonic_rd"
+Email = "sonic_rd@ruijie.com.cn"
+Mailinglist = sonicproject@googlegroups.com
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/Makefile b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/Makefile
new file mode 100755
index 000000000000..1b09fe02bf6e
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/Makefile
@@ -0,0 +1,22 @@
+PWD = $(shell pwd)
+DIR_KERNEL_SRC = $(PWD)/modules/driver
+EXTRA_CFLAGS:= -I$(M)/include
+EXTRA_CFLAGS+= -Wall
+SUB_BUILD_DIR = $(PWD)/build
+INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)
+INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin
+
+KBUILD_EXTRA_SYMBOLS += $(DIR_KERNEL_SRC)/Module.symvers
+export KBUILD_EXTRA_SYMBOLS
+
+all:
+ $(MAKE) -C $(KBUILD_OUTPUT) M=$(DIR_KERNEL_SRC) modules
+ @if [ ! -d ${INSTALL_DIR} ]; then mkdir -p ${INSTALL_DIR} ;fi
+ cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_DIR)
+ @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi
+ cp -r $(PWD)/config/* $(INSTALL_SCRIPT_DIR)
+clean:
+ rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd
+ rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order
+ rm -rf ${DIR_KERNEL_SRC}/.tmp_versions
+ rm -rf $(SUB_BUILD_DIR)
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/README.md b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/README.md
new file mode 100755
index 000000000000..b4dbacd5e466
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/README.md
@@ -0,0 +1,2 @@
+# sonic-platform-modules-ruijie
+Device drivers for support of ruijie platform for the SONiC project
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/config/x86_64_ruijie_b6510_48vs8cq_r0_config.py b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/config/x86_64_ruijie_b6510_48vs8cq_r0_config.py
new file mode 100755
index 000000000000..2de2b48a0681
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/config/x86_64_ruijie_b6510_48vs8cq_r0_config.py
@@ -0,0 +1,499 @@
+#!/usr/bin/python
+# -*- coding: UTF-8 -*-
+
+from ruijiecommon import *
+
+RUIJIE_CARDID = 0x00004040
+RUIJIE_PRODUCTNAME = "B6510-48VS8CQ"
+
+fanlevel = {
+ "tips" : ["low", "mid", "high"],
+ "level" : [51, 150, 255],
+ "low_speed" : [500, 7500, 17000],
+ "high_speed" : [11000, 22500, 28500]
+}
+
+fanloc = [
+ {
+ "name":
+ "Fan1/Fna2/Fan3/Fan4",
+ "location":
+ "0-0032/fan_speed_set",
+ "childfans": [{
+ "name": "Fan1",
+ "location": "2-0037/hwmon/hwmon4/fan1_input"
+ }, {
+ "name": "Fan2",
+ "location": "2-0037/hwmon/hwmon4/fan2_input"
+ }, {
+ "name": "Fan3",
+ "location": "2-0037/hwmon/hwmon4/fan3_input"
+ }, {
+ "name": "Fan4",
+ "location": "2-0037/hwmon/hwmon4/fan4_input"
+ }]
+ },
+]
+
+# Fan control parameters
+MONITOR_TEMP_MIN = 38 # default temperature
+MONITOR_K = 11 # fan regulation coefficient
+MONITOR_MAC_IN = 35 # temperature difference between inlet value and critical value on MAC
+MONITOR_DEFAULT_SPEED = 0x60
+MONITOR_MAX_SPEED = 0xFF
+MONITOR_MIN_SPEED = 0x33
+MONITOR_MAC_ERROR_SPEED = 0XBB # speed when error occurs
+MONITOR_FAN_TOTAL_NUM = 4 # there are 4 fans in total, 3 main and 1 redundancy
+MONITOR_MAC_UP_TEMP = 50 # upper limit of temperature difference between mac and inlet
+MONITOR_MAC_LOWER_TEMP = -50 # lower limit of temperature difference between mac and inlet
+MONITOR_MAC_MAX_TEMP = 100
+
+"""
+critical value of temperature difference between previous and current moments,
+if the difference is bigger than this value the speed regulation would be started
+"""
+MONITOR_FALL_TEMP = 4
+MONITOR_MAC_WARNING_THRESHOLD = 100
+MONITOR_OUTTEMP_WARNING_THRESHOLD = 85
+MONITOR_BOARDTEMP_WARNING_THRESHOLD = 85
+MONITOR_CPUTEMP_WARNING_THRESHOLD = 85
+MONITOR_INTEMP_WARNING_THRESHOLD = 70
+
+MONITOR_MAC_CRITICAL_THRESHOLD = 105
+MONITOR_OUTTEMP_CRITICAL_THRESHOLD = 90
+MONITOR_BOARDTEMP_CRITICAL_THRESHOLD = 90
+MONITOR_CPUTEMP_CRITICAL_THRESHOLD = 100
+MONITOR_INTEMP_CRITICAL_THRESHOLD = 80
+MONITOR_CRITICAL_NUM = 3 # number of consecutive failures
+MONITOR_SHAKE_TIME = 20 # interval of anti-jitter
+MONITOR_INTERVAL = 60
+
+MONITOR_SYS_LED = [{
+ "bus": 2,
+ "devno": 0x33,
+ "addr": 0xb2,
+ "yellow": 0x03,
+ "red": 0x02,
+ "green": 0x01
+}, {
+ "bus": 2,
+ "devno": 0x37,
+ "addr": 0xb2,
+ "yellow": 0x03,
+ "red": 0x02,
+ "green": 0x01
+}]
+
+MONITOR_SYS_FAN_LED = [
+ {
+ "bus": 2,
+ "devno": 0x33,
+ "addr": 0xb4,
+ "yellow": 0x06,
+ "red": 0x02,
+ "green": 0x04
+ },
+]
+MONITOR_FANS_LED = [{
+ "bus": 2,
+ "devno": 0x32,
+ "addr": 0x23,
+ "green": 0x09,
+ "red": 0x0a
+}, {
+ "bus": 2,
+ "devno": 0x32,
+ "addr": 0x24,
+ "green": 0x09,
+ "red": 0x0a
+}, {
+ "bus": 2,
+ "devno": 0x32,
+ "addr": 0x25,
+ "green": 0x09,
+ "red": 0x0a
+}, {
+ "bus": 2,
+ "devno": 0x32,
+ "addr": 0x26,
+ "green": 0x09,
+ "red": 0x0a
+}]
+
+CPLDVERSIONS = [
+ {
+ "bus": 2,
+ "devno": 0x33,
+ "name": "MAC CPLD-A"
+ },
+ {
+ "bus": 2,
+ "devno": 0x35,
+ "name": "MAC CPLD-B"
+ },
+ {
+ "bus": 2,
+ "devno": 0x37,
+ "name": "CONNECT CPLD-A"
+ },
+ {
+ "bus": 0,
+ "devno": 0x0d,
+ "name": "CPU CPLD"
+ },
+]
+
+MONITOR_SYS_PSU_LED = [
+ {
+ "bus": 2,
+ "devno": 0x33,
+ "addr": 0xb3,
+ "yellow": 0x06,
+ "red": 0x02,
+ "green": 0x04
+ },
+]
+
+MONITOR_FAN_STATUS = [
+ {
+ 'status': 'green',
+ 'minOkNum': 4,
+ 'maxOkNum': 4
+ },
+ {
+ 'status': 'yellow',
+ 'minOkNum': 3,
+ 'maxOkNum': 3
+ },
+ {
+ 'status': 'red',
+ 'minOkNum': 0,
+ 'maxOkNum': 2
+ },
+]
+
+MONITOR_PSU_STATUS = [
+ {
+ 'status': 'green',
+ 'minOkNum': 2,
+ 'maxOkNum': 2
+ },
+ {
+ 'status': 'yellow',
+ 'minOkNum': 1,
+ 'maxOkNum': 1
+ },
+ {
+ 'status': 'red',
+ 'minOkNum': 0,
+ 'maxOkNum': 0
+ },
+]
+
+# B6510 AVS parameters
+MAC_AVS_PARAM = {
+ 0x72: 0x0384,
+ 0x73: 0x037e,
+ 0x74: 0x0378,
+ 0x75: 0x0372,
+ 0x76: 0x036b,
+ 0x77: 0x0365,
+ 0x78: 0x035f,
+ 0x79: 0x0359,
+ 0x7a: 0x0352,
+ 0x7b: 0x034c,
+ 0x7c: 0x0346,
+ 0x7d: 0x0340,
+ 0x7e: 0x0339,
+ 0x7f: 0x0333,
+ 0x80: 0x032d,
+ 0x81: 0x0327,
+ 0x82: 0x0320,
+ 0x83: 0x031a,
+ 0x84: 0x0314,
+ 0x85: 0x030e,
+ 0x86: 0x0307,
+ 0x87: 0x0301,
+ 0x88: 0x02fb,
+ 0x89: 0x02f5,
+ 0x8A: 0x02ee
+}
+
+# B6510 default configurations
+MAC_DEFAULT_PARAM = {
+ "type" : 1, # type of fan speed regulation
+ "default" : 0x74,
+ "loopaddr" : 0x00, # AVS loop address
+ "loop" : 0x00, # AVS loop value
+ "open" : 0x00, # disable write protection
+ "close" : 0x40, # enable write protection
+ "bus" : 2, # AVS I2C bus address
+ "devno" : 0x60,
+ "addr" : 0x21, # AVS address
+ "protectaddr" : 0x10, # AVS write protection address
+ "sdkreg" : "TOP_AVS_SEL_REG", # SDK register name
+ "sdktype" : 0, # type 0: disable shifting / 1: enable shifting
+ "macregloc" : 24, # shifting option
+ "mask" : 0xff # mask for shifting
+}
+
+DRIVERLISTS = [
+ {
+ "name": "i2c_dev",
+ "delay": 0
+ },
+ {
+ "name": "i2c_algo_bit",
+ "delay": 0
+ },
+ {
+ "name": "i2c_gpio",
+ "delay": 0
+ },
+ {
+ "name": "i2c_mux",
+ "delay": 0
+ },
+ {
+ "name": "i2c_mux_pca9641",
+ "delay": 0
+ },
+ {
+ "name": "i2c_mux_pca954x",
+ "delay": 0
+ },
+ {
+ "name": "lm75",
+ "delay": 0
+ },
+ {
+ "name": "optoe",
+ "delay": 0
+ },
+ {
+ "name": "at24",
+ "delay": 0
+ },
+ {
+ "name": "rg_sff",
+ "delay": 0
+ },
+ {
+ "name": "ruijie_platform",
+ "delay": 0
+ },
+ {
+ "name": "rg_cpld",
+ "delay": 0
+ },
+ {
+ "name": "rg_fan",
+ "delay": 0
+ },
+ {
+ "name": "rg_psu",
+ "delay": 0
+ },
+ {
+ "name": "csu550",
+ "delay": 0
+ },
+ {
+ "name": "rg_gpio_xeon",
+ "delay": 0
+ },
+]
+
+DEVICE = [
+ {
+ "name": "pca9641",
+ "bus": 0,
+ "loc": 0x10
+ },
+ {
+ "name": "pca9548",
+ "bus": 2,
+ "loc": 0x70
+ },
+ {
+ "name": "lm75",
+ "bus": 2,
+ "loc": 0x48
+ },
+ {
+ "name": "lm75",
+ "bus": 2,
+ "loc": 0x49
+ },
+ {
+ "name": "lm75",
+ "bus": 2,
+ "loc": 0x4a
+ },
+ {
+ "name": "24c02",
+ "bus": 2,
+ "loc": 0x57
+ },
+ {
+ "name": "rg_cpld",
+ "bus": 0,
+ "loc": 0x32
+ },
+ {
+ "name": "rg_cpld",
+ "bus": 1,
+ "loc": 0x34
+ },
+ {
+ "name": "rg_cpld",
+ "bus": 1,
+ "loc": 0x36
+ },
+ {
+ "name": "rg_cpld",
+ "bus": 2,
+ "loc": 0x33
+ },
+ {
+ "name": "rg_cpld",
+ "bus": 2,
+ "loc": 0x35
+ },
+ {
+ "name": "rg_cpld",
+ "bus": 2,
+ "loc": 0x37
+ },
+ {
+ "name": "rg_avs",
+ "bus": 2,
+ "loc": 0x60
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x70
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x71
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x72
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x73
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x74
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x75
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x76
+ },
+ {
+ "name": "rg_fan",
+ "bus": 3,
+ "loc": 0x53
+ },
+ {
+ "name": "rg_fan",
+ "bus": 4,
+ "loc": 0x53
+ },
+ {
+ "name": "rg_fan",
+ "bus": 5,
+ "loc": 0x53
+ },
+ {
+ "name": "rg_fan",
+ "bus": 6,
+ "loc": 0x53
+ },
+ {
+ "name": "rg_psu",
+ "bus": 7,
+ "loc": 0x50
+ },
+ {
+ "name": "dps550",
+ "bus": 7,
+ "loc": 0x58
+ },
+ {
+ "name": "rg_psu",
+ "bus": 8,
+ "loc": 0x53
+ },
+ {
+ "name": "dps550",
+ "bus": 8,
+ "loc": 0x5b
+ },
+]
+
+INIT_PARAM = [
+ {
+ "loc": "1-0034/sfp_enable",
+ "value": "01"
+ },
+ {
+ "loc": "2-0035/sfp_enable2",
+ "value": "ff"
+ },
+ {
+ "loc": "2-0033/mac_led",
+ "value": "ff"
+ },
+ {
+ "loc": "1-0034/sfp_txdis1",
+ "value": "00"
+ },
+ {
+ "loc": "1-0034/sfp_txdis2",
+ "value": "00"
+ },
+ {
+ "loc": "1-0034/sfp_txdis3",
+ "value": "00"
+ },
+ {
+ "loc": "1-0036/sfp_txdis4",
+ "value": "00"
+ },
+ {
+ "loc": "1-0036/sfp_txdis5",
+ "value": "00"
+ },
+ {
+ "loc": "1-0036/sfp_txdis6",
+ "value": "00"
+ },
+ {
+ "loc": fanloc[0]["location"],
+ "value": "80"
+ },
+ {
+ "loc": "2-0033/sfp_led1_yellow",
+ "value": "ad"
+ },
+ {
+ "loc": "2-0035/sfp_led2_yellow",
+ "value": "ad"
+ },
+]
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/modules/driver/Makefile
new file mode 100755
index 000000000000..f10216ec4d5a
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/modules/driver/Makefile
@@ -0,0 +1 @@
+obj-m := rg_cpld.o
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/modules/driver/rg_cpld.c b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/modules/driver/rg_cpld.c
new file mode 100755
index 000000000000..dc577eece5d5
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/b6510-48vs8cq/modules/driver/rg_cpld.c
@@ -0,0 +1,551 @@
+/*
+ * rg_cpld.c - A driver for cpld
+ *
+ * Copyright (c) 2019
+ *
+ * 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
+#include
+#include
+
+
+/* debug level */
+typedef enum {
+ DBG_START,
+ DBG_VERBOSE,
+ DBG_KEY,
+ DBG_WARN,
+ DBG_ERROR,
+ DBG_END,
+} dbg_level_t;
+
+static int debuglevel = 0;
+module_param(debuglevel, int, S_IRUGO);
+
+#define DBG_DEBUG(fmt, arg...) do { \
+ if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \
+ printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
+ } else if ( debuglevel >= DBG_ERROR ) { \
+ printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
+ } else { } \
+} while (0)
+
+#define DBG_ERROR(fmt, arg...) do { \
+ if ( debuglevel > DBG_START) { \
+ printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
+ } \
+} while (0)
+
+#define CPLD_SIZE (256)
+#define CPLD_I2C_RETRY_TIMES (3)
+
+struct cpld_data {
+ struct i2c_client *client;
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 data[CPLD_SIZE]; /* Register value */
+};
+
+static s32 cpld_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)
+{
+ int try;
+ s32 ret;
+
+ ret = -1;
+ for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) {
+ if ((ret = i2c_smbus_read_byte_data(client, command) ) >= 0 )
+ break;
+ }
+ return ret;
+}
+
+static s32 cpld_i2c_smbus_read_i2c_block_data(const struct i2c_client *client,
+ u8 command, u8 length, u8 *values)
+{
+ int try;
+ s32 ret;
+
+ ret = -1;
+ for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) {
+ if ((ret = i2c_smbus_read_i2c_block_data(client, command, length, values) ) >= 0 )
+ break;
+ }
+ return ret;
+}
+
+static ssize_t show_fan_rpm_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;
+ uint8_t size;
+ s32 status;
+ s32 ret_t;
+
+ ret_t = 0;
+ status = -1;
+ size = 0;
+ mutex_lock(&data->update_lock);
+ status = cpld_i2c_smbus_read_byte_data(client, index);
+ if (status < 0) {
+ mutex_unlock(&data->update_lock);
+ return 0;
+ }
+ data->data[0] = status;
+ status = cpld_i2c_smbus_read_byte_data(client, index + 1);
+ if (status < 0) {
+ mutex_unlock(&data->update_lock);
+ return 0;
+ }
+ data->data[1] = status;
+ DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index, data->data[0]);
+ DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index + 1, data->data[1]);
+ ret_t = (data->data[1] << 8) + data->data[0] ;
+ if (ret_t == 0 ) {
+ size = snprintf(buf, CPLD_SIZE, "%d\n", ret_t);
+ } else if (ret_t == 0xffff) {
+ size = snprintf(buf, CPLD_SIZE, "%d\n", 0);
+ } else {
+ size = snprintf(buf, CPLD_SIZE, "%d\n", 15000000 / ret_t);
+ }
+ mutex_unlock(&data->update_lock);
+ return size;
+}
+
+static ssize_t set_cpld_sysfs_value(struct device *dev,
+ struct device_attribute *da, const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cpld_data *data = i2c_get_clientdata(client);
+ unsigned long val;
+ int err;
+
+ err = kstrtoul(buf, 16, &val);
+ if (err)
+ return err;
+ if ((val < 0) || (val > 0xff)) {
+ DBG_ERROR("please enter 0x00 ~ 0xff\n");
+ return -1;
+ }
+ mutex_lock(&data->update_lock);
+ data->data[0] = (u8)val;
+ DBG_DEBUG("pos: 0x%02x count = %ld, data = 0x%02x\n", attr->index, count, data->data[0]);
+ i2c_smbus_write_byte_data(client, attr->index, data->data[0]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cpld_data *data = i2c_get_clientdata(client);
+ s32 status;
+
+ status = -1;
+ mutex_lock(&data->update_lock);
+ status = cpld_i2c_smbus_read_i2c_block_data(client, 0, 4, data->data);
+ if (status < 0) {
+ mutex_unlock(&data->update_lock);
+ return 0;
+ }
+ mutex_unlock(&data->update_lock);
+ return sprintf(buf, "%02x %02x %02x %02x \n", data->data[0], data->data[1], data->data[2], data->data[3]);
+}
+
+static ssize_t show_cpld_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);
+ s32 status;
+
+ status = -1;
+ mutex_lock(&data->update_lock);
+ status = cpld_i2c_smbus_read_byte_data(client, attr->index);
+ if (status < 0) {
+ mutex_unlock(&data->update_lock);
+ return 0;
+ }
+ data->data[0] = status;
+ DBG_DEBUG("cpld reg pos:0x%x value:0x%02x\n", attr->index, data->data[0]);
+ mutex_unlock(&data->update_lock);
+ return sprintf(buf, "%02x\n", data->data[0]);
+}
+
+/* common */
+static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO | S_IWUSR, show_cpld_version, NULL, 0);
+
+/*0x37 hwmon*/
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1B);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1D);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1F);
+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x21);
+
+/* 0x32 */
+static SENSOR_DEVICE_ATTR(fan_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15);
+static SENSOR_DEVICE_ATTR(fan0_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x23);
+static SENSOR_DEVICE_ATTR(fan1_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x24);
+static SENSOR_DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x25);
+static SENSOR_DEVICE_ATTR(fan3_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x26);
+
+/* 0x37 */
+static SENSOR_DEVICE_ATTR(fan_present, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, NULL, 0x30);
+static SENSOR_DEVICE_ATTR(fan_status, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, NULL, 0x31);
+static SENSOR_DEVICE_ATTR(psu_status, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, NULL, 0x51);
+static SENSOR_DEVICE_ATTR(broad_back_lct, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x2a);
+static SENSOR_DEVICE_ATTR(broad_back_sys, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb2);
+
+/* 0x33 */
+static SENSOR_DEVICE_ATTR(mac_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa0);
+static SENSOR_DEVICE_ATTR(broad_front_lct, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x2a);
+static SENSOR_DEVICE_ATTR(broad_front_bmc, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb1);
+static SENSOR_DEVICE_ATTR(broad_front_cpu, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb2);
+static SENSOR_DEVICE_ATTR(broad_front_pwr, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb3);
+static SENSOR_DEVICE_ATTR(broad_front_fan, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb4);
+static SENSOR_DEVICE_ATTR(sfp_led1_yellow, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xad);
+
+/* 0x34 */
+static SENSOR_DEVICE_ATTR(sfp_presence1, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x30);
+static SENSOR_DEVICE_ATTR(sfp_presence2, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x31);
+static SENSOR_DEVICE_ATTR(sfp_presence3, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x32);
+
+static SENSOR_DEVICE_ATTR(sfp_enable, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa1);
+static SENSOR_DEVICE_ATTR(sfp_led1, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa2);
+static SENSOR_DEVICE_ATTR(sfp_led2, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa3);
+static SENSOR_DEVICE_ATTR(sfp_led3, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa4);
+static SENSOR_DEVICE_ATTR(sfp_led_flash1, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa5);
+static SENSOR_DEVICE_ATTR(sfp_led_flash2, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa6);
+static SENSOR_DEVICE_ATTR(sfp_led_flash3, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa7);
+static SENSOR_DEVICE_ATTR(sfp_txdis1, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x60);
+static SENSOR_DEVICE_ATTR(sfp_txdis2, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x61);
+static SENSOR_DEVICE_ATTR(sfp_txdis3, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x62);
+
+static SENSOR_DEVICE_ATTR(port_speed1, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc0);
+static SENSOR_DEVICE_ATTR(port_speed2, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc1);
+static SENSOR_DEVICE_ATTR(port_speed3, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc2);
+static SENSOR_DEVICE_ATTR(port_speed4, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc3);
+static SENSOR_DEVICE_ATTR(port_speed5, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc4);
+static SENSOR_DEVICE_ATTR(port_speed6, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc5);
+
+/* 0x35 */
+static SENSOR_DEVICE_ATTR(sfp_enable2, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa0);
+static SENSOR_DEVICE_ATTR(sfp_led2_yellow, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xad);
+
+/* 0x36 */
+static SENSOR_DEVICE_ATTR(sfp_presence4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x30);
+static SENSOR_DEVICE_ATTR(sfp_presence5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x31);
+static SENSOR_DEVICE_ATTR(sfp_presence6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x32);
+static SENSOR_DEVICE_ATTR(sfp_presence7, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x33);
+static SENSOR_DEVICE_ATTR(sfp_led4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa2);
+static SENSOR_DEVICE_ATTR(sfp_led5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa3);
+static SENSOR_DEVICE_ATTR(sfp_led6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa4);
+static SENSOR_DEVICE_ATTR(sfp_led7, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa5);
+static SENSOR_DEVICE_ATTR(sfp_led_flash4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa6);
+static SENSOR_DEVICE_ATTR(sfp_led_flash5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa7);
+static SENSOR_DEVICE_ATTR(sfp_led_flash6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa8);
+static SENSOR_DEVICE_ATTR(sfp_led_flash7, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa9);
+
+static SENSOR_DEVICE_ATTR(sfp_txdis4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x60);
+static SENSOR_DEVICE_ATTR(sfp_txdis5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x61);
+static SENSOR_DEVICE_ATTR(sfp_txdis6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x62);
+
+static SENSOR_DEVICE_ATTR(port_speed7, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc0);
+static SENSOR_DEVICE_ATTR(port_speed8, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc1);
+static SENSOR_DEVICE_ATTR(port_speed9, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc2);
+static SENSOR_DEVICE_ATTR(port_speed10, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc3);
+static SENSOR_DEVICE_ATTR(port_speed11, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc4);
+static SENSOR_DEVICE_ATTR(port_speed12, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc5);
+static SENSOR_DEVICE_ATTR(port_speed13, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc6);
+static SENSOR_DEVICE_ATTR(port_speed14, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc7);
+
+static struct attribute *cpld32_sysfs_attrs[] = {
+ &sensor_dev_attr_fan_speed_set.dev_attr.attr,
+ &sensor_dev_attr_fan0_led.dev_attr.attr,
+ &sensor_dev_attr_fan1_led.dev_attr.attr,
+ &sensor_dev_attr_fan2_led.dev_attr.attr,
+ &sensor_dev_attr_fan3_led.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *cpld37_sysfs_attrs[] = {
+ &sensor_dev_attr_fan_present.dev_attr.attr,
+ &sensor_dev_attr_fan_status.dev_attr.attr,
+ &sensor_dev_attr_psu_status.dev_attr.attr,
+ &sensor_dev_attr_broad_back_lct.dev_attr.attr,
+ &sensor_dev_attr_broad_back_sys.dev_attr.attr,
+ &sensor_dev_attr_cpld_version.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *cpld33_sysfs_attrs[] = {
+ &sensor_dev_attr_mac_led.dev_attr.attr,
+ &sensor_dev_attr_broad_front_lct.dev_attr.attr,
+ &sensor_dev_attr_broad_front_bmc.dev_attr.attr,
+ &sensor_dev_attr_broad_front_cpu.dev_attr.attr,
+ &sensor_dev_attr_broad_front_pwr.dev_attr.attr,
+ &sensor_dev_attr_broad_front_fan.dev_attr.attr,
+ &sensor_dev_attr_sfp_led1_yellow.dev_attr.attr,
+ &sensor_dev_attr_cpld_version.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *cpld34_sysfs_attrs[] = {
+ &sensor_dev_attr_sfp_presence1.dev_attr.attr,
+ &sensor_dev_attr_sfp_presence2.dev_attr.attr,
+ &sensor_dev_attr_sfp_presence3.dev_attr.attr,
+ &sensor_dev_attr_sfp_enable.dev_attr.attr,
+ &sensor_dev_attr_sfp_led1.dev_attr.attr,
+ &sensor_dev_attr_sfp_led2.dev_attr.attr,
+ &sensor_dev_attr_sfp_led3.dev_attr.attr,
+ &sensor_dev_attr_sfp_led_flash1.dev_attr.attr,
+ &sensor_dev_attr_sfp_led_flash2.dev_attr.attr,
+ &sensor_dev_attr_sfp_led_flash3.dev_attr.attr,
+ &sensor_dev_attr_sfp_txdis1.dev_attr.attr,
+ &sensor_dev_attr_sfp_txdis2.dev_attr.attr,
+ &sensor_dev_attr_sfp_txdis3.dev_attr.attr,
+ &sensor_dev_attr_port_speed1.dev_attr.attr,
+ &sensor_dev_attr_port_speed2.dev_attr.attr,
+ &sensor_dev_attr_port_speed3.dev_attr.attr,
+ &sensor_dev_attr_port_speed4.dev_attr.attr,
+ &sensor_dev_attr_port_speed5.dev_attr.attr,
+ &sensor_dev_attr_port_speed6.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *cpld36_sysfs_attrs[] = {
+ &sensor_dev_attr_sfp_presence4.dev_attr.attr,
+ &sensor_dev_attr_sfp_presence5.dev_attr.attr,
+ &sensor_dev_attr_sfp_presence6.dev_attr.attr,
+ &sensor_dev_attr_sfp_presence7.dev_attr.attr,
+ &sensor_dev_attr_sfp_led4.dev_attr.attr,
+ &sensor_dev_attr_sfp_led5.dev_attr.attr,
+ &sensor_dev_attr_sfp_led6.dev_attr.attr,
+ &sensor_dev_attr_sfp_led7.dev_attr.attr,
+ &sensor_dev_attr_sfp_led_flash4.dev_attr.attr,
+ &sensor_dev_attr_sfp_led_flash5.dev_attr.attr,
+ &sensor_dev_attr_sfp_led_flash6.dev_attr.attr,
+ &sensor_dev_attr_sfp_led_flash7.dev_attr.attr,
+ &sensor_dev_attr_sfp_txdis4.dev_attr.attr,
+ &sensor_dev_attr_sfp_txdis5.dev_attr.attr,
+ &sensor_dev_attr_sfp_txdis6.dev_attr.attr,
+ &sensor_dev_attr_port_speed7.dev_attr.attr,
+ &sensor_dev_attr_port_speed8.dev_attr.attr,
+ &sensor_dev_attr_port_speed9.dev_attr.attr,
+ &sensor_dev_attr_port_speed10.dev_attr.attr,
+ &sensor_dev_attr_port_speed11.dev_attr.attr,
+ &sensor_dev_attr_port_speed12.dev_attr.attr,
+ &sensor_dev_attr_port_speed13.dev_attr.attr,
+ &sensor_dev_attr_port_speed14.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *cpld35_sysfs_attrs[] = {
+ &sensor_dev_attr_sfp_enable2.dev_attr.attr,
+ &sensor_dev_attr_broad_front_lct.dev_attr.attr,
+ &sensor_dev_attr_broad_front_bmc.dev_attr.attr,
+ &sensor_dev_attr_broad_front_cpu.dev_attr.attr,
+ &sensor_dev_attr_broad_front_pwr.dev_attr.attr,
+ &sensor_dev_attr_broad_front_fan.dev_attr.attr,
+ &sensor_dev_attr_sfp_led2_yellow.dev_attr.attr,
+ &sensor_dev_attr_cpld_version.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group cpld32_sysfs_group = {
+ .attrs = cpld32_sysfs_attrs,
+};
+
+static const struct attribute_group cpld37_sysfs_group = {
+ .attrs = cpld37_sysfs_attrs,
+};
+
+static const struct attribute_group cpld33_sysfs_group = {
+ .attrs = cpld33_sysfs_attrs,
+};
+
+static const struct attribute_group cpld34_sysfs_group = {
+ .attrs = cpld34_sysfs_attrs,
+};
+
+static const struct attribute_group cpld36_sysfs_group = {
+ .attrs = cpld36_sysfs_attrs,
+};
+
+static const struct attribute_group cpld35_sysfs_group = {
+ .attrs = cpld35_sysfs_attrs,
+};
+
+static struct attribute *cpld_hwmon_attrs[] = {
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_fan2_input.dev_attr.attr,
+ &sensor_dev_attr_fan3_input.dev_attr.attr,
+ &sensor_dev_attr_fan4_input.dev_attr.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(cpld_hwmon);
+
+struct cpld_attr_match_group {
+ int bus_nr; /* I2C BUS */
+ unsigned short addr; /* slave addr*/
+ const struct attribute_group *attr_group_ptr;
+ const struct attribute_group *attr_hwmon_ptr;
+};
+
+static struct cpld_attr_match_group g_cpld_attr_match[] = {
+ {0, 0x32, &cpld32_sysfs_group, NULL},
+ {2, 0x37, &cpld37_sysfs_group, (struct attribute_group *)cpld_hwmon_groups},
+ {2, 0x33, &cpld33_sysfs_group, NULL},
+ {1, 0x34, &cpld34_sysfs_group, NULL},
+ {1, 0x36, &cpld36_sysfs_group, NULL},
+ {2, 0x35, &cpld35_sysfs_group, NULL},
+};
+
+static const struct attribute_group *cpld_get_attr_group(struct i2c_client *client, int is_hwmon)
+{
+ int i;
+ struct cpld_attr_match_group *group;
+
+ for (i = 0; i < ARRAY_SIZE(g_cpld_attr_match); i++) {
+ group = &g_cpld_attr_match[i];
+ DBG_DEBUG("is_hwmon %d i %d client(nr:%d,addr:0x%x), group(nr:%d,addr:0x0%x).\n",
+ is_hwmon, i, client->adapter->nr, client->addr, group->bus_nr, group->addr);
+ if ((client->addr == group->addr) && (client->adapter->nr == group->bus_nr)) {
+ DBG_DEBUG("is_hwmon %d i %d nr %d addr %d .\n", is_hwmon, i, client->adapter->nr, client->addr);
+ return (is_hwmon) ? (group->attr_hwmon_ptr) : (group->attr_group_ptr);
+ }
+ }
+
+ DBG_DEBUG("is_hwmon %d nr %d addr %d dismatch, return NULL.\n", is_hwmon, client->adapter->nr, client->addr);
+ return NULL;
+}
+
+static int cpld_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct cpld_data *data;
+ int status;
+ const struct attribute_group *sysfs_group, *hwmon_group;
+
+ status = -1;
+ DBG_DEBUG("cpld_probe(addr:0x%x, nr:%d)\n", client->addr, client->adapter->nr);
+ data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), GFP_KERNEL);
+ if (!data) {
+ return -ENOMEM;
+ }
+
+ data->client = client;
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+ sysfs_group = NULL;
+ sysfs_group = cpld_get_attr_group(client, 0);
+ if (sysfs_group) {
+ status = sysfs_create_group(&client->dev.kobj, sysfs_group);
+ DBG_DEBUG("(addr:0x%x, nr:%d) sysfs_create_group status %d\n", client->addr, client->adapter->nr, status);
+ if (status != 0) {
+ DBG_ERROR("sysfs_create_group status %d.\n", status);
+ goto error;
+ }
+ } else {
+ DBG_DEBUG("(addr:0x%x, nr:%d) no sysfs_create_group\n", client->addr, client->adapter->nr);
+ }
+
+ hwmon_group = NULL;
+ hwmon_group = cpld_get_attr_group(client, 1);
+ if (hwmon_group) {
+ data->hwmon_dev = hwmon_device_register_with_groups(
+ &client->dev, client->name, data, (const struct attribute_group **)hwmon_group);
+ if (IS_ERR(data->hwmon_dev)) {
+ sysfs_remove_group(&client->dev.kobj, (const struct attribute_group *)sysfs_group);
+ DBG_ERROR("hwmon_device_register_with_groups failed ret %ld.\n", PTR_ERR(data->hwmon_dev));
+ return PTR_ERR(data->hwmon_dev);
+ }
+ DBG_DEBUG("(addr:0x%x, nr:%d) hwmon_device_register_with_groups success\n", client->addr, client->adapter->nr);
+ if (status != 0) {
+ DBG_ERROR("sysfs_create_group status %d.\n", status);
+ goto error;
+ }
+ } else {
+ DBG_DEBUG("(addr:0x%x, nr:%d) no hwmon_device_register_with_groups\n", client->addr, client->adapter->nr);
+ }
+
+error:
+ return status;
+
+}
+
+static int cpld_remove(struct i2c_client *client)
+{
+ struct cpld_data *data = i2c_get_clientdata(client);
+ const struct attribute_group *sysfs_group, *hwmon_group;
+
+ DBG_DEBUG("cpld_remove(addr:0x%x, nr:%d)\n", client->addr, client->adapter->nr);
+
+ sysfs_group = NULL;
+ sysfs_group = cpld_get_attr_group(client, 0);
+ if (sysfs_group) {
+ DBG_DEBUG("(addr:0x%x, nr:%d) do sysfs_remove_group\n", client->addr, client->adapter->nr);
+ sysfs_remove_group(&client->dev.kobj, (const struct attribute_group *)sysfs_group);
+ } else {
+ DBG_DEBUG("(addr:0x%x, nr:%d) no sysfs_remove_group\n", client->addr, client->adapter->nr);
+ }
+
+ hwmon_group = NULL;
+ hwmon_group = cpld_get_attr_group(client, 1);
+ if (hwmon_group) {
+ DBG_DEBUG("(addr:0x%x, nr:%d) do hwmon_device_unregister\n", client->addr, client->adapter->nr);
+ hwmon_device_unregister(data->hwmon_dev);
+ } else {
+ DBG_DEBUG("(addr:0x%x, nr:%d) no hwmon_device_unregister\n", client->addr, client->adapter->nr);
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id cpld_id[] = {
+ { "rg_cpld", 0 },
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, cpld_id);
+
+static struct i2c_driver rg_cpld_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "rg_cpld",
+ },
+ .probe = cpld_probe,
+ .remove = cpld_remove,
+ .id_table = cpld_id,
+};
+
+module_i2c_driver(rg_cpld_driver);
+
+MODULE_AUTHOR("sonic_rd ");
+MODULE_DESCRIPTION("ruijie CPLD driver");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/Makefile b/platform/broadcom/sonic-platform-modules-ruijie/common/Makefile
new file mode 100755
index 000000000000..a637dd7cd736
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/Makefile
@@ -0,0 +1,36 @@
+PWD = $(shell pwd)
+CC ?=gcc
+INSTALL_MOD_DIR ?=extra
+KVERSION ?= $(shell uname -r)
+KERNEL_SRC ?= /lib/modules/$(KVERSION)
+EXTRA_CFLAGS:= -I$(M)/include
+EXTRA_CFLAGS+= -Wall
+SUB_BUILD_DIR = $(PWD)/build
+DIR_KERNEL_SRC = $(PWD)/modules
+SCRIPT_DIR = $(PWD)/script
+SERVICE_DIR = $(PWD)/service
+
+KBUILD_EXTRA_SYMBOLS += $(DIR_KERNEL_SRC)/Module.symvers
+export KBUILD_EXTRA_SYMBOLS
+
+INSTALL_MODULE_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)
+INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin
+INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system
+INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python2.7/dist-packages
+
+all:
+ $(MAKE) -C $(KERNEL_SRC)/build M=$(DIR_KERNEL_SRC) modules
+ @if [ ! -d ${INSTALL_MODULE_DIR} ]; then mkdir -p ${INSTALL_MODULE_DIR} ;fi
+ @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi
+ @if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi
+ @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi
+ @if [ -d $(PWD)/lib/ ]; then cp -r $(PWD)/lib/* ${INSTALL_LIB_DIR} ;fi
+ cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_MODULE_DIR)
+ cp -r $(SCRIPT_DIR)/* $(INSTALL_SCRIPT_DIR)
+ cp -r $(SERVICE_DIR)/* $(INSTALL_SERVICE_DIR)
+ @if [ -d $(INSTALL_SCRIPT_DIR) ]; then chmod +x $(INSTALL_SCRIPT_DIR)/* ;fi
+clean:
+ rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd
+ rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order
+ rm -rf ${DIR_KERNEL_SRC}/.tmp_versions
+ rm -rf $(SUB_BUILD_DIR)
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/modules/Makefile b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/Makefile
new file mode 100755
index 000000000000..373027a26e00
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/Makefile
@@ -0,0 +1,7 @@
+obj-m := rg-gpio-xeon.o
+obj-m += rg_fan.o
+obj-m += rg_psu.o
+obj-m += ruijie_platform.o
+obj-m += i2c-mux-pca9641.o
+obj-m += i2c-mux-pca954x.o
+obj-m += csu550.o
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/modules/csu550.c b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/csu550.c
new file mode 100755
index 000000000000..d572fb44e2fe
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/csu550.c
@@ -0,0 +1,209 @@
+/*
+ * csu550.c - A driver for pmbus
+ *
+ * Copyright (c) 2010, 2011 Ericsson AB.
+ * Copyright (c) 2019
+ *
+ * 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
+#include
+#include "pmbus.h"
+
+
+/*
+ * Find sensor groups and status registers on each page.
+ */
+static void pmbus_find_sensor_groups(struct i2c_client *client,
+ struct pmbus_driver_info *info)
+{
+ int page;
+
+ /* Sensors detected on page 0 only */
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_VIN))
+ info->func[0] |= PMBUS_HAVE_VIN;
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_IIN))
+ info->func[0] |= PMBUS_HAVE_IIN;
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_PIN))
+ info->func[0] |= PMBUS_HAVE_PIN;
+ if (info->func[0] && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
+ info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
+ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
+ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
+ info->func[0] |= PMBUS_HAVE_FAN12;
+ if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
+ info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
+ }
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1))
+ info->func[0] |= PMBUS_HAVE_TEMP;
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
+ info->func[0] |= PMBUS_HAVE_TEMP2;
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
+ info->func[0] |= PMBUS_HAVE_TEMP3;
+ if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3)
+ && pmbus_check_byte_register(client, 0, PMBUS_STATUS_TEMPERATURE))
+ info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
+
+ /* Sensors detected on all pages */
+ for (page = 0; page < info->pages; page++) {
+ if (pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) {
+ info->func[page] |= PMBUS_HAVE_VOUT;
+ if (pmbus_check_byte_register(client, page,
+ PMBUS_STATUS_VOUT))
+ info->func[page] |= PMBUS_HAVE_STATUS_VOUT;
+ }
+ if (pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) {
+ info->func[page] |= PMBUS_HAVE_IOUT;
+ if (pmbus_check_byte_register(client, 0,
+ PMBUS_STATUS_IOUT))
+ info->func[page] |= PMBUS_HAVE_STATUS_IOUT;
+ }
+ if (pmbus_check_word_register(client, page, PMBUS_READ_POUT))
+ info->func[page] |= PMBUS_HAVE_POUT;
+ }
+}
+
+/*
+ * Identify chip parameters.
+ */
+static int pmbus_identify(struct i2c_client *client,
+ struct pmbus_driver_info *info)
+{
+ int ret = 0;
+
+ if (!info->pages) {
+ /*
+ * Check if the PAGE command is supported. If it is,
+ * keep setting the page number until it fails or until the
+ * maximum number of pages has been reached. Assume that
+ * this is the number of pages supported by the chip.
+ */
+ if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) {
+ int page;
+
+ for (page = 1; page < PMBUS_PAGES; page++) {
+ if (pmbus_set_page(client, page) < 0)
+ break;
+ }
+ pmbus_set_page(client, 0);
+ info->pages = page;
+ } else {
+ info->pages = 1;
+ }
+ }
+
+ if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) {
+ int vout_mode;
+
+ vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
+ if (vout_mode >= 0 && vout_mode != 0xff) {
+ switch (vout_mode >> 5) {
+ case 0:
+ break;
+ case 1:
+ info->format[PSC_VOLTAGE_OUT] = vid;
+ break;
+ case 2:
+ info->format[PSC_VOLTAGE_OUT] = direct;
+ break;
+ default:
+ ret = -ENODEV;
+ goto abort;
+ }
+ }
+ }
+
+ /*
+ * We should check if the COEFFICIENTS register is supported.
+ * If it is, and the chip is configured for direct mode, we can read
+ * the coefficients from the chip, one set per group of sensor
+ * registers.
+ *
+ * To do this, we will need access to a chip which actually supports the
+ * COEFFICIENTS command, since the command is too complex to implement
+ * without testing it. Until then, abort if a chip configured for direct
+ * mode was detected.
+ */
+ if (info->format[PSC_VOLTAGE_OUT] == direct) {
+ ret = -ENODEV;
+ goto abort;
+ }
+
+ /* Try to find sensor groups */
+ pmbus_find_sensor_groups(client, info);
+abort:
+ return ret;
+}
+
+static int pmbus_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct pmbus_driver_info *info;
+ struct pmbus_platform_data *pdata = NULL;
+ struct device *dev = &client->dev;
+
+ info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ if (!strncmp(id->name, "dps460", sizeof("dps460")) ||
+ !strncmp(id->name, "fsp1200", sizeof("fsp1200")) || !strncmp(id->name, "dps550", sizeof("dps550"))) {
+ pdata = kzalloc(sizeof(struct pmbus_platform_data), GFP_KERNEL);
+ if (!pdata) {
+ kfree(info);
+ return -ENOMEM;
+ }
+ pdata->flags = PMBUS_SKIP_STATUS_CHECK;
+ }
+
+ info->pages = id->driver_data;
+ info->identify = pmbus_identify;
+ dev->platform_data = pdata;
+
+ return pmbus_do_probe(client, id, info);
+}
+
+static const struct i2c_device_id pmbus_id[] = {
+ {"csu550", 0},
+ {"csu800", 1},
+ {"fsp1200", 1},
+ {"dps550", 1},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, pmbus_id);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver pmbus_driver = {
+ .probe = pmbus_probe,
+ .remove = pmbus_do_remove,
+ .id_table = pmbus_id,
+ .driver = {
+ .name = "pmbus",
+ },
+};
+
+module_i2c_driver(pmbus_driver);
+
+MODULE_AUTHOR("sonic_rd ");
+MODULE_DESCRIPTION("ruijie psupmbus driver");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/modules/i2c-mux-pca954x.c b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/i2c-mux-pca954x.c
new file mode 100755
index 000000000000..2b6632e62b58
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/i2c-mux-pca954x.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2008-2009 Rodolfo Giometti
+ * Copyright (c) 2008-2009 Eurotech S.p.A.
+ * Copyright (c) 2019
+ *
+ * I2C multiplexer
+ *
+ * This module supports the PCA954x series of I2C multiplexer/switch chips
+ * made by Philips Semiconductors.
+ * This includes the:
+ * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547
+ * and PCA9548.
+ *
+ * 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 .
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+extern int pca9641_setmuxflag(int nr, int flag);
+
+int force_create_bus = 0;
+module_param(force_create_bus, int, S_IRUGO | S_IWUSR);
+
+#define PCA954X_MAX_NCHANS (8)
+
+enum pca_type {
+ pca_9540,
+ pca_9542,
+ pca_9543,
+ pca_9544,
+ pca_9545,
+ pca_9546,
+ pca_9547,
+ pca_9548,
+};
+
+struct pca954x {
+ enum pca_type type;
+ struct i2c_adapter *virt_adaps[PCA954X_MAX_NCHANS];
+
+ u8 last_chan; /* last register value */
+};
+
+struct chip_desc {
+ u8 nchans;
+ u8 enable; /* used for muxes only */
+ enum muxtype {
+ pca954x_ismux = 0,
+ pca954x_isswi
+ } muxtype;
+};
+
+/* Provide specs for the PCA954x types we know about */
+static const struct chip_desc chips[] = {
+ [pca_9540] = {
+ .nchans = 2,
+ .enable = 0x4,
+ .muxtype = pca954x_ismux,
+ },
+ [pca_9543] = {
+ .nchans = 2,
+ .muxtype = pca954x_isswi,
+ },
+ [pca_9544] = {
+ .nchans = 4,
+ .enable = 0x4,
+ .muxtype = pca954x_ismux,
+ },
+ [pca_9545] = {
+ .nchans = 4,
+ .muxtype = pca954x_isswi,
+ },
+ [pca_9547] = {
+ .nchans = 8,
+ .enable = 0x8,
+ .muxtype = pca954x_ismux,
+ },
+ [pca_9548] = {
+ .nchans = 8,
+ .muxtype = pca954x_isswi,
+ },
+};
+
+static const struct i2c_device_id pca954x_id[] = {
+ { "pca9540", pca_9540 },
+ { "pca9542", pca_9540 },
+ { "pca9543", pca_9543 },
+ { "pca9544", pca_9544 },
+ { "pca9545", pca_9545 },
+ { "pca9546", pca_9545 },
+ { "pca9547", pca_9547 },
+ { "pca9548", pca_9548 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, pca954x_id);
+
+/* 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)
+{
+ int ret = -ENODEV;
+
+ if (adap->algo->master_xfer) {
+ struct i2c_msg msg;
+ char buf[1];
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = 1;
+ buf[0] = val;
+ msg.buf = buf;
+ ret = adap->algo->master_xfer(adap, &msg, 1);
+
+ if (ret >= 0 && ret != 1)
+ ret = -EREMOTEIO;
+ } else {
+ union i2c_smbus_data data;
+ ret = adap->algo->smbus_xfer(adap, client->addr,
+ client->flags,
+ I2C_SMBUS_WRITE,
+ val, I2C_SMBUS_BYTE, &data);
+ }
+
+ return ret;
+}
+
+static int pca954x_setmuxflag(struct i2c_adapter *adap, int flag)
+{
+ pca9641_setmuxflag(adap->nr, flag);
+ return 0;
+}
+
+static int pca954x_select_chan(struct i2c_adapter *adap,
+ void *client, u32 chan)
+{
+ struct pca954x *data = i2c_get_clientdata(client);
+ const struct chip_desc *chip = &chips[data->type];
+ u8 regval;
+ int ret = 0;
+
+ /* we make switches look like muxes, not sure how to be smarter */
+ if (chip->muxtype == pca954x_ismux)
+ regval = chan | chip->enable;
+ else
+ regval = 1 << chan;
+
+ /* Only select the channel if its different from the last channel */
+ if (data->last_chan != regval) {
+ pca954x_setmuxflag(adap, 0);
+ ret = pca954x_reg_write(adap, client, regval);
+ data->last_chan = ret < 0 ? 0 : regval;
+ }
+
+ return ret;
+}
+
+static int pca954x_deselect_mux(struct i2c_adapter *adap,
+ void *client, u32 chan)
+{
+ struct pca954x *data = i2c_get_clientdata(client);
+
+ /* Deselect active channel */
+ data->last_chan = 0;
+
+ pca954x_setmuxflag(adap, 1);
+ return pca954x_reg_write(adap, client, data->last_chan);
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+static int pca954x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
+ struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
+ struct gpio_desc *gpio;
+ int num, force, class;
+ struct pca954x *data;
+ int ret;
+
+
+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
+ return -ENODEV;
+
+ data = devm_kzalloc(&client->dev, sizeof(struct pca954x), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, data);
+
+ /* Get the mux out of reset if a reset GPIO is specified. */
+ gpio = devm_gpiod_get(&client->dev, "reset");
+ if (!IS_ERR(gpio))
+ gpiod_direction_output(gpio, 0);
+
+ /* Write the mux register at addr to verify
+ * that the mux is in fact present. This also
+ * initializes the mux to disconnected state.
+ */
+ if ((i2c_smbus_write_byte(client, 0) < 0) && (force_create_bus == 0)) {
+ dev_warn(&client->dev, "probe failed\n");
+ return -ENODEV;
+ }
+
+ data->type = id->driver_data;
+ data->last_chan = 0; /* force the first selection */
+
+ /* Now create an adapter for each channel */
+ for (num = 0; num < chips[data->type].nchans; num++) {
+ force = 0; /* dynamic adap number */
+ class = 0; /* no class by default */
+ if (pdata) {
+ if (num < pdata->num_modes) {
+ /* force static number */
+ force = pdata->modes[num].adap_id;
+ class = pdata->modes[num].class;
+ } else
+ /* discard unconfigured channels */
+ break;
+ }
+
+ data->virt_adaps[num] =
+ i2c_add_mux_adapter(adap, &client->dev, client,
+ force, num, class, pca954x_select_chan, pca954x_deselect_mux);
+
+ if (data->virt_adaps[num] == NULL) {
+ ret = -ENODEV;
+ dev_err(&client->dev,
+ "failed to register multiplexed adapter"
+ " %d as bus %d\n", num, force);
+ goto virt_reg_failed;
+ }
+ }
+
+ dev_info(&client->dev,
+ "registered %d multiplexed busses for I2C %s %s\n",
+ num, chips[data->type].muxtype == pca954x_ismux
+ ? "mux" : "switch", client->name);
+
+ return 0;
+
+virt_reg_failed:
+ for (num--; num >= 0; num--)
+ i2c_del_mux_adapter(data->virt_adaps[num]);
+ return ret;
+}
+
+static int pca954x_remove(struct i2c_client *client)
+{
+ struct pca954x *data = i2c_get_clientdata(client);
+ const struct chip_desc *chip = &chips[data->type];
+ int i;
+
+ for (i = 0; i < chip->nchans; ++i)
+ if (data->virt_adaps[i]) {
+ i2c_del_mux_adapter(data->virt_adaps[i]);
+ data->virt_adaps[i] = NULL;
+ }
+
+ return 0;
+}
+
+static struct i2c_driver pca954x_driver = {
+ .driver = {
+ .name = "pca954x",
+ .owner = THIS_MODULE,
+ },
+ .probe = pca954x_probe,
+ .remove = pca954x_remove,
+ .id_table = pca954x_id,
+};
+
+module_i2c_driver(pca954x_driver);
+
+MODULE_AUTHOR("sonic_rd sonic_rd@ruijie.com.cn");
+MODULE_DESCRIPTION("PCA954x I2C mux/switch driver");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/modules/i2c-mux-pca9641.c b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/i2c-mux-pca9641.c
new file mode 100755
index 000000000000..ba88271d6e98
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/i2c-mux-pca9641.c
@@ -0,0 +1,601 @@
+/*
+ * I2C multiplexer driver for PCA9541 bus master selector
+ *
+ * Copyright (c) 2010 Ericsson AB.
+ * Copyright (c) 2019
+ * Author: Guenter Roeck
+ *
+ * Derived from:
+ * pca954x.c
+ *
+ * Copyright (c) 2008-2009 Rodolfo Giometti
+ * Copyright (c) 2008-2009 Eurotech S.p.A.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*
+ * The PCA9541 is a bus master selector. It supports two I2C masters connected
+ * to a single slave bus.
+ *
+ * Before each bus transaction, a master has to acquire bus ownership. After the
+ * transaction is complete, bus ownership has to be released. This fits well
+ * into the I2C multiplexer framework, which provides select and release
+ * functions for this purpose. For this reason, this driver is modeled as
+ * single-channel I2C bus multiplexer.
+ *
+ * This driver assumes that the two bus masters are controlled by two different
+ * hosts. If a single host controls both masters, platform code has to ensure
+ * that only one of the masters is instantiated at any given time.
+ */
+
+#define PCA9541_CONTROL (0x01)
+#define PCA9541_ISTAT (0x02)
+
+#define PCA9541_CTL_MYBUS (1 << 0)
+#define PCA9541_CTL_NMYBUS (1 << 1)
+#define PCA9541_CTL_BUSON (1 << 2)
+#define PCA9541_CTL_NBUSON (1 << 3)
+#define PCA9541_CTL_BUSINIT (1 << 4)
+#define PCA9541_CTL_TESTON (1 << 6)
+#define PCA9541_CTL_NTESTON (1 << 7)
+#define PCA9541_ISTAT_INTIN (1 << 0)
+#define PCA9541_ISTAT_BUSINIT (1 << 1)
+#define PCA9541_ISTAT_BUSOK (1 << 2)
+#define PCA9541_ISTAT_BUSLOST (1 << 3)
+#define PCA9541_ISTAT_MYTEST (1 << 6)
+#define PCA9541_ISTAT_NMYTEST (1 << 7)
+
+#define PCA9641_ID (0x00)
+#define PCA9641_ID_MAGIC (0x38)
+#define PCA9641_CONTROL (0x01)
+#define PCA9641_STATUS (0x02)
+#define PCA9641_TIME (0x03)
+#define PCA9641_RES_TIME (0x03)
+#define PCA9641_RETRY_TIME (8)
+
+#define PCA9641_CTL_LOCK_REQ BIT(0)
+#define PCA9641_CTL_LOCK_GRANT BIT(1)
+#define PCA9641_CTL_BUS_CONNECT BIT(2)
+#define PCA9641_CTL_BUS_INIT BIT(3)
+#define PCA9641_CTL_SMBUS_SWRST BIT(4)
+#define PCA9641_CTL_IDLE_TIMER_DIS BIT(5)
+#define PCA9641_CTL_SMBUS_DIS BIT(6)
+#define PCA9641_CTL_PRIORITY BIT(7)
+#define PCA9641_STS_OTHER_LOCK BIT(0)
+#define PCA9641_STS_BUS_INIT_FAIL BIT(1)
+#define PCA9641_STS_BUS_HUNG BIT(2)
+#define PCA9641_STS_MBOX_EMPTY BIT(3)
+#define PCA9641_STS_MBOX_FULL BIT(4)
+#define PCA9641_STS_TEST_INT BIT(5)
+#define PCA9641_STS_SCL_IO BIT(6)
+#define PCA9641_STS_SDA_IO BIT(7)
+
+#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
+#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
+#define mybus(x) (!((x)&MYBUS) || ((x)&MYBUS) == MYBUS)
+#define busoff(x) (!((x)&BUSON) || ((x)&BUSON) == BUSON)
+#define BUSOFF(x, y) \
+ (!((x)&PCA9641_CTL_LOCK_GRANT) && !((y)&PCA9641_STS_OTHER_LOCK))
+#define other_lock(x) ((x)&PCA9641_STS_OTHER_LOCK)
+#define lock_grant(x) ((x)&PCA9641_CTL_LOCK_GRANT)
+
+
+int g_debug = 0;
+module_param(g_debug, int, S_IRUGO | S_IWUSR);
+
+#define PCA_DEBUG(fmt, args...) \
+ do { \
+ if (g_debug) { \
+ printk(KERN_ERR \
+ "[pca9641][VER][func:%s line:%d]\r\n" fmt, \
+ __func__, __LINE__, ##args); \
+ } \
+ } while (0)
+
+typedef struct i2c_muxs_struct_flag {
+ int nr;
+ char name[48];
+ struct mutex update_lock;
+ int flag;
+} i2c_mux_flag;
+
+i2c_mux_flag pca_flag = {
+ .flag = -1,
+};
+
+int pca9641_setmuxflag(int nr, int flag)
+{
+ if (pca_flag.nr == nr) {
+ pca_flag.flag = flag;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(pca9641_setmuxflag);
+
+/* arbitration timeouts, in jiffies */
+#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */
+#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */
+
+/* arbitration retry delays, in us */
+#define SELECT_DELAY_SHORT (50)
+#define SELECT_DELAY_LONG (1000)
+
+struct pca9541 {
+ struct i2c_adapter *mux_adap;
+ unsigned long select_timeout;
+ unsigned long arb_timeout;
+};
+
+static const struct i2c_device_id pca9541_id[] = {
+ { "pca9541", 0 },
+ { "pca9641", 1 },
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, pca9541_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id pca9541_of_match[] = {
+ { .compatible = "nxp,pca9541" },
+ { .compatible = "nxp,pca9641" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, pca9541_of_match);
+#endif
+
+/*
+ * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
+ * as they will try to lock the adapter a second time.
+ */
+static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val)
+{
+ struct i2c_adapter *adap = client->adapter;
+ int ret;
+
+ if (adap->algo->master_xfer) {
+ struct i2c_msg msg;
+ char buf[2];
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = 2;
+ buf[0] = command;
+ buf[1] = val;
+ msg.buf = buf;
+ ret = adap->algo->master_xfer(adap, &msg, 1);
+ } else {
+ union i2c_smbus_data data;
+
+ data.byte = val;
+ ret = adap->algo->smbus_xfer(adap, client->addr, client->flags,
+ I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_BYTE_DATA, &data);
+ }
+ return ret;
+}
+
+/*
+ * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
+ * as they will try to lock adapter a second time.
+ */
+static int pca9541_reg_read(struct i2c_client *client, u8 command)
+{
+ struct i2c_adapter *adap = client->adapter;
+ int ret;
+ u8 val;
+
+ if (adap->algo->master_xfer) {
+ struct i2c_msg msg[2] = { { .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &command },
+ { .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = &val } };
+ ret = adap->algo->master_xfer(adap, msg, 2);
+ if (ret == 2)
+ ret = val;
+ else if (ret >= 0)
+ ret = -EIO;
+ } else {
+ union i2c_smbus_data data;
+
+ ret = adap->algo->smbus_xfer(adap, client->addr, client->flags,
+ I2C_SMBUS_READ, command,
+ I2C_SMBUS_BYTE_DATA, &data);
+ if (!ret)
+ ret = data.byte;
+ }
+ return ret;
+}
+
+/*
+ * Arbitration management functions
+ */
+
+/* Release bus. Also reset NTESTON and BUSINIT if it was set. */
+static void pca9541_release_bus(struct i2c_client *client)
+{
+ int reg;
+
+ reg = pca9541_reg_read(client, PCA9541_CONTROL);
+ if (reg >= 0 && !busoff(reg) && mybus(reg))
+ pca9541_reg_write(client, PCA9541_CONTROL,
+ (reg & PCA9541_CTL_NBUSON) >> 1);
+}
+
+/*
+ * Arbitration is defined as a two-step process. A bus master can only activate
+ * the slave bus if it owns it; otherwise it has to request ownership first.
+ * This multi-step process ensures that access contention is resolved
+ * gracefully.
+ *
+ * Bus Ownership Other master Action
+ * state requested access
+ * ----------------------------------------------------
+ * off - yes wait for arbitration timeout or
+ * for other master to drop request
+ * off no no take ownership
+ * off yes no turn on bus
+ * on yes - done
+ * on no - wait for arbitration timeout or
+ * for other master to release bus
+ *
+ * The main contention point occurs if the slave bus is off and both masters
+ * request ownership at the same time. In this case, one master will turn on
+ * the slave bus, believing that it owns it. The other master will request
+ * bus ownership. Result is that the bus is turned on, and master which did
+ * _not_ own the slave bus before ends up owning it.
+ */
+
+/* Control commands per PCA9541 datasheet */
+static const u8 pca9541_control[16] = { 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1 };
+
+/*
+ * Channel arbitration
+ *
+ * Return values:
+ * <0: error
+ * 0 : bus not acquired
+ * 1 : bus acquired
+ */
+static int pca9541_arbitrate(struct i2c_client *client)
+{
+ struct pca9541 *data = i2c_get_clientdata(client);
+ int reg;
+
+ reg = pca9541_reg_read(client, PCA9541_CONTROL);
+ if (reg < 0)
+ return reg;
+
+ if (busoff(reg)) {
+ int istat;
+ /*
+ * Bus is off. Request ownership or turn it on unless
+ * other master requested ownership.
+ */
+ istat = pca9541_reg_read(client, PCA9541_ISTAT);
+ if (!(istat & PCA9541_ISTAT_NMYTEST) ||
+ time_is_before_eq_jiffies(data->arb_timeout)) {
+ /*
+ * Other master did not request ownership,
+ * or arbitration timeout expired. Take the bus.
+ */
+ pca9541_reg_write(client, PCA9541_CONTROL,
+ pca9541_control[reg & 0x0f] |
+ PCA9541_CTL_NTESTON);
+ data->select_timeout = SELECT_DELAY_SHORT;
+ } else {
+ /*
+ * Other master requested ownership.
+ * Set extra long timeout to give it time to acquire it.
+ */
+ data->select_timeout = SELECT_DELAY_LONG * 2;
+ }
+ } else if (mybus(reg)) {
+ /*
+ * Bus is on, and we own it. We are done with acquisition.
+ * Reset NTESTON and BUSINIT, then return success.
+ */
+ if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT))
+ pca9541_reg_write(client, PCA9541_CONTROL,
+ reg & ~(PCA9541_CTL_NTESTON |
+ PCA9541_CTL_BUSINIT));
+ return 1;
+ } else {
+ /*
+ * Other master owns the bus.
+ * If arbitration timeout has expired, force ownership.
+ * Otherwise request it.
+ */
+ data->select_timeout = SELECT_DELAY_LONG;
+ if (time_is_before_eq_jiffies(data->arb_timeout)) {
+ /* Time is up, take the bus and reset it. */
+ pca9541_reg_write(client, PCA9541_CONTROL,
+ pca9541_control[reg & 0x0f] |
+ PCA9541_CTL_BUSINIT |
+ PCA9541_CTL_NTESTON);
+ } else {
+ /* Request bus ownership if needed */
+ if (!(reg & PCA9541_CTL_NTESTON))
+ pca9541_reg_write(client, PCA9541_CONTROL,
+ reg | PCA9541_CTL_NTESTON);
+ }
+ }
+ return 0;
+}
+
+static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan)
+{
+ struct pca9541 *data = i2c_get_clientdata(client);
+ int ret;
+ unsigned long timeout = jiffies + ARB2_TIMEOUT;
+ /* give up after this time */
+
+ data->arb_timeout = jiffies + ARB_TIMEOUT;
+
+ /* force bus ownership after this time */
+ do {
+ ret = pca9541_arbitrate(client);
+ if (ret)
+ return ret < 0 ? ret : 0;
+
+ if (data->select_timeout == SELECT_DELAY_SHORT)
+ udelay(data->select_timeout);
+ else
+ msleep(data->select_timeout / 1000);
+ } while (time_is_after_eq_jiffies(timeout));
+
+ return -ETIMEDOUT;
+}
+
+static int pca9541_release_chan(struct i2c_adapter *adap, void *client,
+ u32 chan)
+{
+ pca9541_release_bus(client);
+ return 0;
+}
+
+/*
+* Arbitration management functions
+*/
+static void pca9641_release_bus(struct i2c_client *client)
+{
+ int ret;
+ ret = pca9541_reg_write(client, PCA9641_CONTROL, 0x80);
+}
+
+/*
+* Channel arbitration
+*
+* Return values:
+* <0: error
+* 0 : bus not acquired
+* 1 : bus acquired
+*/
+static int pca9641_arbitrate(struct i2c_client *client)
+{
+ struct pca9541 *data = i2c_get_clientdata(client);
+ int reg_ctl, reg_sts;
+
+ reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
+ if (reg_ctl < 0)
+ return reg_ctl;
+ reg_sts = pca9541_reg_read(client, PCA9641_STATUS);
+
+ if (BUSOFF(reg_ctl, reg_sts)) {
+ /*
+ * Bus is off. Request ownership or turn it on unless
+ * other master requested ownership.
+ */
+ reg_ctl |= PCA9641_CTL_LOCK_REQ;
+ pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
+ reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
+
+ if (lock_grant(reg_ctl)) {
+ /*
+ * Other master did not request ownership,
+ * or arbitration timeout expired. Take the bus.
+ */
+ reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ;
+ pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
+ data->select_timeout = SELECT_DELAY_SHORT;
+ return 1;
+ } else {
+ /*
+ * Other master requested ownership.
+ * Set extra long timeout to give it time to acquire it.
+ */
+ data->select_timeout = SELECT_DELAY_LONG * 2;
+ }
+ } else if (lock_grant(reg_ctl)) {
+ /*
+ * Bus is on, and we own it. We are done with acquisition.
+ */
+ reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ;
+ pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
+
+ return 1;
+ } else if (other_lock(reg_sts)) {
+ /*
+ * Other master owns the bus.
+ * If arbitration timeout has expired, force ownership.
+ * Otherwise request it.
+ */
+ data->select_timeout = SELECT_DELAY_LONG;
+ reg_ctl |= PCA9641_CTL_LOCK_REQ;
+ pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
+ }
+ return 0;
+}
+
+int pca9641_select_chan(struct i2c_adapter *adap, void *client, u32 chan)
+{
+ struct pca9541 *data = i2c_get_clientdata(client);
+ int ret;
+ int result;
+ unsigned long timeout = jiffies + ARB2_TIMEOUT;
+ /* give up after this time */
+ data->arb_timeout = jiffies + ARB_TIMEOUT;
+
+ /* force bus ownership after this time */
+ for (result = 0; result < PCA9641_RETRY_TIME; result++) {
+ do {
+ ret = pca9641_arbitrate(client);
+ if (ret == 1) {
+ return 0;
+ }
+ if (data->select_timeout == SELECT_DELAY_SHORT)
+ udelay(data->select_timeout);
+ else
+ msleep(data->select_timeout / 1000);
+ } while (time_is_after_eq_jiffies(timeout));
+ timeout = jiffies + ARB2_TIMEOUT;
+ }
+
+ return -ETIMEDOUT;
+}
+EXPORT_SYMBOL(pca9641_select_chan);
+
+static int pca9641_release_chan(struct i2c_adapter *adap, void *client,
+ u32 chan)
+{
+ if (pca_flag.flag > 0) {
+ PCA_DEBUG("release chan flag:%d\n", pca_flag.flag);
+ pca9641_release_bus(client);
+ }
+ return 0;
+}
+
+static int pca9641_detect_id(struct i2c_client *client)
+{
+ int reg;
+
+ reg = pca9541_reg_read(client, PCA9641_ID);
+ if (reg == PCA9641_ID_MAGIC)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ ** limit: only support one pca9641
+ **/
+static int pca9641_recordflag(struct i2c_adapter *adap)
+{
+ if (pca_flag.flag != -1) {
+ pr_err(" %s %d has init already!!!", __func__, __LINE__);
+ return -1;
+ }
+ pca_flag.nr = adap->nr;
+ PCA_DEBUG(" adap->nr:%d\n", adap->nr);
+ snprintf(pca_flag.name, sizeof(pca_flag.name), adap->name);
+ return 0;
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+static int pca9541_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 pca9541 *data;
+ int force;
+ int ret = -ENODEV;
+ int detect_id;
+
+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
+ goto err;
+
+ detect_id = pca9641_detect_id(client);
+ data = kzalloc(sizeof(struct pca9541), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ i2c_set_clientdata(client, data);
+
+ /*
+ * I2C accesses are unprotected here.
+ * We have to lock the adapter before releasing the bus.
+ */
+ if (detect_id == 0) {
+ i2c_lock_adapter(adap);
+ pca9541_release_bus(client);
+ i2c_unlock_adapter(adap);
+ } else {
+ i2c_lock_adapter(adap);
+ pca9641_release_bus(client);
+ i2c_unlock_adapter(adap);
+ }
+
+ /* Create mux adapter */
+ force = 0;
+ if (pdata)
+ force = pdata->modes[0].adap_id;
+ if (detect_id == 0) {
+ data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client, force,
+ 0, 0, pca9541_select_chan,
+ pca9541_release_chan);
+ } else {
+ data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client, force,
+ 0, 0, pca9641_select_chan,
+ pca9641_release_chan);
+ }
+ pca9641_recordflag(data->mux_adap);
+ if (data->mux_adap == NULL) {
+ dev_err(&client->dev, "failed to register master selector\n");
+ goto exit_free;
+ }
+
+ dev_info(&client->dev, "registered master selector for I2C %s\n", client->name);
+
+ return 0;
+
+exit_free:
+ kfree(data);
+err:
+ return ret;
+}
+
+static int pca9541_remove(struct i2c_client *client)
+{
+ struct pca9541 *data = i2c_get_clientdata(client);
+
+ i2c_del_mux_adapter(data->mux_adap);
+
+ kfree(data);
+ return 0;
+}
+
+static struct i2c_driver pca9541_driver = {
+ .driver = {
+ .name = "pca9541",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(pca9541_of_match),
+ },
+ .probe = pca9541_probe,
+ .remove = pca9541_remove,
+ .id_table = pca9541_id,
+};
+
+module_i2c_driver(pca9541_driver);
+
+MODULE_AUTHOR("Guenter Roeck ");
+MODULE_DESCRIPTION("PCA9541 I2C master selector driver");
+MODULE_LICENSE("GPL v2");
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/pmbus.h
new file mode 100755
index 000000000000..efd1a942c657
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/pmbus.h
@@ -0,0 +1,386 @@
+/*
+ * pmbus.h - Common defines and structures for PMBus devices
+ *
+ * Copyright (c) 2010, 2011 Ericsson AB.
+ * Copyright (c) 2012 Guenter Roeck
+ *
+ * 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 PMBUS_H
+#define PMBUS_H
+
+/*
+ * Registers
+ */
+#define PMBUS_PAGE (0x00)
+#define PMBUS_OPERATION (0x01)
+#define PMBUS_ON_OFF_CONFIG (0x02)
+#define PMBUS_CLEAR_FAULTS (0x03)
+#define PMBUS_PHASE (0x04)
+
+#define PMBUS_CAPABILITY (0x19)
+#define PMBUS_QUERY (0x1A)
+
+#define PMBUS_VOUT_MODE (0x20)
+#define PMBUS_VOUT_COMMAND (0x21)
+#define PMBUS_VOUT_TRIM (0x22)
+#define PMBUS_VOUT_CAL_OFFSET (0x23)
+#define PMBUS_VOUT_MAX (0x24)
+#define PMBUS_VOUT_MARGIN_HIGH (0x25)
+#define PMBUS_VOUT_MARGIN_LOW (0x26)
+#define PMBUS_VOUT_TRANSITION_RATE (0x27)
+#define PMBUS_VOUT_DROOP (0x28)
+#define PMBUS_VOUT_SCALE_LOOP (0x29)
+#define PMBUS_VOUT_SCALE_MONITOR (0x2A)
+
+#define PMBUS_COEFFICIENTS (0x30)
+#define PMBUS_POUT_MAX (0x31)
+
+#define PMBUS_FAN_CONFIG_12 (0x3A)
+#define PMBUS_FAN_COMMAND_1 (0x3B)
+#define PMBUS_FAN_COMMAND_2 (0x3C)
+#define PMBUS_FAN_CONFIG_34 (0x3D)
+#define PMBUS_FAN_COMMAND_3 (0x3E)
+#define PMBUS_FAN_COMMAND_4 (0x3F)
+
+#define PMBUS_VOUT_OV_FAULT_LIMIT (0x40)
+#define PMBUS_VOUT_OV_FAULT_RESPONSE (0x41)
+#define PMBUS_VOUT_OV_WARN_LIMIT (0x42)
+#define PMBUS_VOUT_UV_WARN_LIMIT (0x43)
+#define PMBUS_VOUT_UV_FAULT_LIMIT (0x44)
+#define PMBUS_VOUT_UV_FAULT_RESPONSE (0x45)
+#define PMBUS_IOUT_OC_FAULT_LIMIT (0x46)
+#define PMBUS_IOUT_OC_FAULT_RESPONSE (0x47)
+#define PMBUS_IOUT_OC_LV_FAULT_LIMIT (0x48)
+#define PMBUS_IOUT_OC_LV_FAULT_RESPONSE (0x49)
+#define PMBUS_IOUT_OC_WARN_LIMIT (0x4A)
+#define PMBUS_IOUT_UC_FAULT_LIMIT (0x4B)
+#define PMBUS_IOUT_UC_FAULT_RESPONSE (0x4C)
+
+#define PMBUS_OT_FAULT_LIMIT (0x4F)
+#define PMBUS_OT_FAULT_RESPONSE (0x50)
+#define PMBUS_OT_WARN_LIMIT (0x51)
+#define PMBUS_UT_WARN_LIMIT (0x52)
+#define PMBUS_UT_FAULT_LIMIT (0x53)
+#define PMBUS_UT_FAULT_RESPONSE (0x54)
+#define PMBUS_VIN_OV_FAULT_LIMIT (0x55)
+#define PMBUS_VIN_OV_FAULT_RESPONSE (0x56)
+#define PMBUS_VIN_OV_WARN_LIMIT (0x57)
+#define PMBUS_VIN_UV_WARN_LIMIT (0x58)
+#define PMBUS_VIN_UV_FAULT_LIMIT (0x59)
+
+#define PMBUS_IIN_OC_FAULT_LIMIT (0x5B)
+#define PMBUS_IIN_OC_WARN_LIMIT (0x5D)
+
+#define PMBUS_POUT_OP_FAULT_LIMIT (0x68)
+#define PMBUS_POUT_OP_WARN_LIMIT (0x6A)
+#define PMBUS_PIN_OP_WARN_LIMIT (0x6B)
+
+#define PMBUS_STATUS_BYTE (0x78)
+#define PMBUS_STATUS_WORD (0x79)
+#define PMBUS_STATUS_VOUT (0x7A)
+#define PMBUS_STATUS_IOUT (0x7B)
+#define PMBUS_STATUS_INPUT (0x7C)
+#define PMBUS_STATUS_TEMPERATURE (0x7D)
+#define PMBUS_STATUS_CML (0x7E)
+#define PMBUS_STATUS_OTHER (0x7F)
+#define PMBUS_STATUS_MFR_SPECIFIC (0x80)
+#define PMBUS_STATUS_FAN_12 (0x81)
+#define PMBUS_STATUS_FAN_34 (0x82)
+
+#define PMBUS_READ_VIN (0x88)
+#define PMBUS_READ_IIN (0x89)
+#define PMBUS_READ_VCAP (0x8A)
+#define PMBUS_READ_VOUT (0x8B)
+#define PMBUS_READ_IOUT (0x8C)
+#define PMBUS_READ_TEMPERATURE_1 (0x8D)
+#define PMBUS_READ_TEMPERATURE_2 (0x8E)
+#define PMBUS_READ_TEMPERATURE_3 (0x8F)
+#define PMBUS_READ_FAN_SPEED_1 (0x90)
+#define PMBUS_READ_FAN_SPEED_2 (0x91)
+#define PMBUS_READ_FAN_SPEED_3 (0x92)
+#define PMBUS_READ_FAN_SPEED_4 (0x93)
+#define PMBUS_READ_DUTY_CYCLE (0x94)
+#define PMBUS_READ_FREQUENCY (0x95)
+#define PMBUS_READ_POUT (0x96)
+#define PMBUS_READ_PIN (0x97)
+
+#define PMBUS_REVISION (0x98)
+#define PMBUS_MFR_ID (0x99)
+#define PMBUS_MFR_MODEL (0x9A)
+#define PMBUS_MFR_REVISION (0x9B)
+#define PMBUS_MFR_LOCATION (0x9C)
+#define PMBUS_MFR_DATE (0x9D)
+#define PMBUS_MFR_SERIAL (0x9E)
+
+/*
+ * Virtual registers.
+ * Useful to support attributes which are not supported by standard PMBus
+ * registers but exist as manufacturer specific registers on individual chips.
+ * Must be mapped to real registers in device specific code.
+ *
+ * Semantics:
+ * Virtual registers are all word size.
+ * READ registers are read-only; writes are either ignored or return an error.
+ * RESET registers are read/write. Reading reset registers returns zero
+ * (used for detection), writing any value causes the associated history to be
+ * reset.
+ * Virtual registers have to be handled in device specific driver code. Chip
+ * driver code returns non-negative register values if a virtual register is
+ * supported, or a negative error code if not. The chip driver may return
+ * -ENODATA or any other error code in this case, though an error code other
+ * than -ENODATA is handled more efficiently and thus preferred. Either case,
+ * the calling PMBus core code will abort if the chip driver returns an error
+ * code when reading or writing virtual registers.
+ */
+#define PMBUS_VIRT_BASE (0x100)
+#define PMBUS_VIRT_READ_TEMP_AVG (PMBUS_VIRT_BASE + 0)
+#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 1)
+#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 2)
+#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 3)
+#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 4)
+#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 5)
+#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 6)
+#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 7)
+#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 8)
+#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 9)
+#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 10)
+#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 11)
+#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 12)
+#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 13)
+#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 14)
+#define PMBUS_VIRT_READ_POUT_AVG (PMBUS_VIRT_BASE + 15)
+#define PMBUS_VIRT_READ_POUT_MAX (PMBUS_VIRT_BASE + 16)
+#define PMBUS_VIRT_RESET_POUT_HISTORY (PMBUS_VIRT_BASE + 17)
+#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 18)
+#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 19)
+#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 20)
+#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 21)
+#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 22)
+#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 23)
+#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 24)
+#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 25)
+#define PMBUS_VIRT_READ_TEMP2_AVG (PMBUS_VIRT_BASE + 26)
+#define PMBUS_VIRT_READ_TEMP2_MIN (PMBUS_VIRT_BASE + 27)
+#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28)
+#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29)
+
+#define PMBUS_VIRT_READ_VMON (PMBUS_VIRT_BASE + 30)
+#define PMBUS_VIRT_VMON_UV_WARN_LIMIT (PMBUS_VIRT_BASE + 31)
+#define PMBUS_VIRT_VMON_OV_WARN_LIMIT (PMBUS_VIRT_BASE + 32)
+#define PMBUS_VIRT_VMON_UV_FAULT_LIMIT (PMBUS_VIRT_BASE + 33)
+#define PMBUS_VIRT_VMON_OV_FAULT_LIMIT (PMBUS_VIRT_BASE + 34)
+#define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35)
+
+/*
+ * CAPABILITY
+ */
+#define PB_CAPABILITY_SMBALERT (1<<4)
+#define PB_CAPABILITY_ERROR_CHECK (1<<7)
+
+/*
+ * VOUT_MODE
+ */
+#define PB_VOUT_MODE_MODE_MASK (0xe0)
+#define PB_VOUT_MODE_PARAM_MASK (0x1f)
+
+#define PB_VOUT_MODE_LINEAR (0x00)
+#define PB_VOUT_MODE_VID (0x20)
+#define PB_VOUT_MODE_DIRECT (0x40)
+
+/*
+ * Fan configuration
+ */
+#define PB_FAN_2_PULSE_MASK ((1 << 0) | (1 << 1))
+#define PB_FAN_2_RPM (1 << 2)
+#define PB_FAN_2_INSTALLED (1 << 3)
+#define PB_FAN_1_PULSE_MASK ((1 << 4) | (1 << 5))
+#define PB_FAN_1_RPM (1 << 6)
+#define PB_FAN_1_INSTALLED (1 << 7)
+
+/*
+ * STATUS_BYTE, STATUS_WORD (lower)
+ */
+#define PB_STATUS_NONE_ABOVE (1<<0)
+#define PB_STATUS_CML (1<<1)
+#define PB_STATUS_TEMPERATURE (1<<2)
+#define PB_STATUS_VIN_UV (1<<3)
+#define PB_STATUS_IOUT_OC (1<<4)
+#define PB_STATUS_VOUT_OV (1<<5)
+#define PB_STATUS_OFF (1<<6)
+#define PB_STATUS_BUSY (1<<7)
+
+/*
+ * STATUS_WORD (upper)
+ */
+#define PB_STATUS_UNKNOWN (1<<8)
+#define PB_STATUS_OTHER (1<<9)
+#define PB_STATUS_FANS (1<<10)
+#define PB_STATUS_POWER_GOOD_N (1<<11)
+#define PB_STATUS_WORD_MFR (1<<12)
+#define PB_STATUS_INPUT (1<<13)
+#define PB_STATUS_IOUT_POUT (1<<14)
+#define PB_STATUS_VOUT (1<<15)
+
+/*
+ * STATUS_IOUT
+ */
+#define PB_POUT_OP_WARNING (1<<0)
+#define PB_POUT_OP_FAULT (1<<1)
+#define PB_POWER_LIMITING (1<<2)
+#define PB_CURRENT_SHARE_FAULT (1<<3)
+#define PB_IOUT_UC_FAULT (1<<4)
+#define PB_IOUT_OC_WARNING (1<<5)
+#define PB_IOUT_OC_LV_FAULT (1<<6)
+#define PB_IOUT_OC_FAULT (1<<7)
+
+/*
+ * STATUS_VOUT, STATUS_INPUT
+ */
+#define PB_VOLTAGE_UV_FAULT (1<<4)
+#define PB_VOLTAGE_UV_WARNING (1<<5)
+#define PB_VOLTAGE_OV_WARNING (1<<6)
+#define PB_VOLTAGE_OV_FAULT (1<<7)
+
+/*
+ * STATUS_INPUT
+ */
+#define PB_PIN_OP_WARNING (1<<0)
+#define PB_IIN_OC_WARNING (1<<1)
+#define PB_IIN_OC_FAULT (1<<2)
+
+/*
+ * STATUS_TEMPERATURE
+ */
+#define PB_TEMP_UT_FAULT (1<<4)
+#define PB_TEMP_UT_WARNING (1<<5)
+#define PB_TEMP_OT_WARNING (1<<6)
+#define PB_TEMP_OT_FAULT (1<<7)
+
+/*
+ * STATUS_FAN
+ */
+#define PB_FAN_AIRFLOW_WARNING (1<<0)
+#define PB_FAN_AIRFLOW_FAULT (1<<1)
+#define PB_FAN_FAN2_SPEED_OVERRIDE (1<<2)
+#define PB_FAN_FAN1_SPEED_OVERRIDE (1<<3)
+#define PB_FAN_FAN2_WARNING (1<<4)
+#define PB_FAN_FAN1_WARNING (1<<5)
+#define PB_FAN_FAN2_FAULT (1<<6)
+#define PB_FAN_FAN1_FAULT (1<<7)
+
+/*
+ * CML_FAULT_STATUS
+ */
+#define PB_CML_FAULT_OTHER_MEM_LOGIC (1<<0)
+#define PB_CML_FAULT_OTHER_COMM (1<<1)
+#define PB_CML_FAULT_PROCESSOR (1<<3)
+#define PB_CML_FAULT_MEMORY (1<<4)
+#define PB_CML_FAULT_PACKET_ERROR (1<<5)
+#define PB_CML_FAULT_INVALID_DATA (1<<6)
+#define PB_CML_FAULT_INVALID_COMMAND (1<<7)
+
+enum pmbus_sensor_classes {
+ PSC_VOLTAGE_IN = 0,
+ PSC_VOLTAGE_OUT,
+ PSC_CURRENT_IN,
+ PSC_CURRENT_OUT,
+ PSC_POWER,
+ PSC_TEMPERATURE,
+ PSC_FAN,
+ PSC_NUM_CLASSES /* Number of power sensor classes */
+};
+
+#define PMBUS_PAGES (32) /* Per PMBus specification */
+
+/* Functionality bit mask */
+#define PMBUS_HAVE_VIN (1 << 0)
+#define PMBUS_HAVE_VCAP (1 << 1)
+#define PMBUS_HAVE_VOUT (1 << 2)
+#define PMBUS_HAVE_IIN (1 << 3)
+#define PMBUS_HAVE_IOUT (1 << 4)
+#define PMBUS_HAVE_PIN (1 << 5)
+#define PMBUS_HAVE_POUT (1 << 6)
+#define PMBUS_HAVE_FAN12 (1 << 7)
+#define PMBUS_HAVE_FAN34 (1 << 8)
+#define PMBUS_HAVE_TEMP (1 << 9)
+#define PMBUS_HAVE_TEMP2 (1 << 10)
+#define PMBUS_HAVE_TEMP3 (1 << 11)
+#define PMBUS_HAVE_STATUS_VOUT (1 << 12)
+#define PMBUS_HAVE_STATUS_IOUT (1 << 13)
+#define PMBUS_HAVE_STATUS_INPUT (1 << 14)
+#define PMBUS_HAVE_STATUS_TEMP (1 << 15)
+#define PMBUS_HAVE_STATUS_FAN12 (1 << 16)
+#define PMBUS_HAVE_STATUS_FAN34 (1 << 17)
+#define PMBUS_HAVE_VMON (1 << 18)
+#define PMBUS_HAVE_STATUS_VMON (1 << 19)
+
+enum pmbus_data_format { linear = 0, direct, vid };
+
+struct pmbus_driver_info {
+ int pages; /* Total number of pages */
+ enum pmbus_data_format format[PSC_NUM_CLASSES];
+ /*
+ * Support one set of coefficients for each sensor type
+ * Used for chips providing data in direct mode.
+ */
+ int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */
+ int b[PSC_NUM_CLASSES]; /* offset */
+ int R[PSC_NUM_CLASSES]; /* exponent */
+
+ u32 func[PMBUS_PAGES]; /* Functionality, per page */
+ /*
+ * The following functions map manufacturing specific register values
+ * to PMBus standard register values. Specify only if mapping is
+ * necessary.
+ * Functions return the register value (read) or zero (write) if
+ * successful. A return value of -ENODATA indicates that there is no
+ * manufacturer specific register, but that a standard PMBus register
+ * may exist. Any other negative return value indicates that the
+ * register does not exist, and that no attempt should be made to read
+ * the standard register.
+ */
+ int (*read_byte_data)(struct i2c_client *client, int page, int reg);
+ int (*read_word_data)(struct i2c_client *client, int page, int reg);
+ int (*write_word_data)(struct i2c_client *client, int page, int reg,
+ u16 word);
+ int (*write_byte)(struct i2c_client *client, int page, u8 value);
+ /*
+ * The identify function determines supported PMBus functionality.
+ * This function is only necessary if a chip driver supports multiple
+ * chips, and the chip functionality is not pre-determined.
+ */
+ int (*identify)(struct i2c_client *client,
+ struct pmbus_driver_info *info);
+};
+
+/* Function declarations */
+
+void pmbus_clear_cache(struct i2c_client *client);
+int pmbus_set_page(struct i2c_client *client, u8 page);
+int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
+int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word);
+int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg);
+int pmbus_write_byte(struct i2c_client *client, int page, u8 value);
+void pmbus_clear_faults(struct i2c_client *client);
+bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg);
+bool pmbus_check_word_register(struct i2c_client *client, int page, int reg);
+int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
+ struct pmbus_driver_info *info);
+int pmbus_do_remove(struct i2c_client *client);
+const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client
+ *client);
+#endif /* PMBUS_H */
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/modules/rg-gpio-xeon.c b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/rg-gpio-xeon.c
new file mode 100644
index 000000000000..097360e3194a
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/rg-gpio-xeon.c
@@ -0,0 +1,340 @@
+/*
+ * GPIO interface for XEON Super I/O chip
+ *
+ * Author: sonic_rd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 2 as published
+ * by the Free Software Foundation.
+ *
+ * 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; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define GPIO_NAME "xeon-gpio"
+#define GPIO_IOSIZE (7)
+#define GPIO_BASE (0x500)
+
+#define GPIO_USE_SEL GPIO_BASE
+#define GP_IO_SEL (GPIO_BASE + 0x4)
+#define GP_LVL (GPIO_BASE + 0xC)
+
+#define GPIO_USE_SEL2 (GPIO_BASE + 0x30)
+#define GP_IO_SEL2 (GPIO_BASE + 0x34)
+#define GP_LVL2 (GPIO_BASE + 0x38)
+
+#define GPIO_USE_SEL3 (GPIO_BASE + 0x40)
+#define GP_IO_SEL3 (GPIO_BASE + 0x44)
+#define GP_LVL3 (GPIO_BASE + 0x48)
+
+#define GPIO_BASE_ID (0)
+#define BANKSIZE (32)
+
+#define GPIO_XEON_SPIN_LOCK(lock, flags) spin_lock_irqsave(&(lock), (flags))
+#define GPIO_XEON_SPIN_UNLOCK(lock, flags) spin_unlock_irqrestore(&(lock), (flags))
+static DEFINE_SPINLOCK(sio_lock);
+
+/* i2c adapter with gpio */
+#define GPIO_SDA (GPIO_BASE_ID + 17)
+#define GPIO_SCL (GPIO_BASE_ID + 1)
+
+static struct i2c_gpio_platform_data i2c_pdata = {
+ .sda_pin = GPIO_SDA,
+ .scl_pin = GPIO_SCL,
+ .udelay = 10,
+ .scl_is_output_only = 0,
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+};
+
+static void i2c_gpio_release(struct device *dev)
+{
+ return;
+}
+
+static struct platform_device i2c_gpio = {
+ .name = "i2c-gpio",
+ .num_resources = 0,
+ .id = -1,
+ .dev = {
+ .platform_data = &i2c_pdata,
+ .release = i2c_gpio_release,
+ }
+};
+
+static int xeon_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
+{
+ unsigned int data;
+ unsigned int bank, offset;
+ unsigned long flags;
+
+ data = 0;
+ bank = gpio_num / BANKSIZE;
+ offset = gpio_num % BANKSIZE;
+
+ GPIO_XEON_SPIN_LOCK(sio_lock, flags);
+ if (bank == 0) {
+ data = inl(GP_LVL) & (1 << offset);
+ if (data) {
+ data = 1;
+ }
+ } else if (bank == 1) {
+ data = inl(GP_LVL2) & (1 << offset);
+ if (data) {
+ data = 1;
+ }
+ } else if (bank == 2) {
+ data = inl(GP_LVL3) & (1 << offset);
+ if (data) {
+ data = 1;
+ }
+ }
+ GPIO_XEON_SPIN_UNLOCK(sio_lock, flags);
+
+ return data;
+}
+
+static int xeon_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
+{
+ unsigned int data;
+ unsigned int bank, offset;
+ unsigned long flags;
+
+ bank = gpio_num / BANKSIZE;
+ offset = gpio_num % BANKSIZE;
+
+ GPIO_XEON_SPIN_LOCK(sio_lock, flags);
+ if (bank == 0) {
+ data = inl(GP_IO_SEL);
+ data = data | (1 << offset);
+ outl(data, GP_IO_SEL);
+ } else if (bank == 1) {
+ data = inl(GP_IO_SEL2);
+ data = data | (1 << offset);
+ outl(data, GP_IO_SEL2);
+ } else if (bank == 2) {
+ data = inl(GP_IO_SEL3);
+ data = data | (1 << offset);
+ outl(data, GP_IO_SEL3);
+ }
+ GPIO_XEON_SPIN_UNLOCK(sio_lock, flags);
+
+ return 0;
+}
+
+static void xeon_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
+{
+ unsigned int data;
+ unsigned int bank, offset;
+ unsigned long flags;
+
+ bank = gpio_num / BANKSIZE;
+ offset = gpio_num % BANKSIZE;
+
+ GPIO_XEON_SPIN_LOCK(sio_lock, flags);
+ if (bank == 0) {
+ data = inl(GP_LVL);
+ if (val) {
+ data = data | (1 << offset);
+ } else {
+ data = data & ~(1 << offset);
+ }
+ outl(data, GP_LVL);
+ } else if (bank == 1) {
+ data = inl(GP_LVL2);
+ if (val) {
+ data = data | (1 << offset);
+ } else {
+ data = data & ~(1 << offset);
+ }
+ outl(data, GP_LVL2);
+ } else if (bank == 2) {
+ data = inl(GP_LVL3);
+ if (val) {
+ data = data | (1 << offset);
+ } else {
+ data = data & ~(1 << offset);
+ }
+ outl(data, GP_LVL3);
+ }
+ GPIO_XEON_SPIN_UNLOCK(sio_lock, flags);
+}
+
+static int xeon_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num, int val)
+{
+ unsigned int data;
+ unsigned int bank, offset;
+ unsigned long flags;
+
+ bank = gpio_num / BANKSIZE;
+ offset = gpio_num % BANKSIZE;
+
+ GPIO_XEON_SPIN_LOCK(sio_lock, flags);
+ if (bank == 0) {
+ data = inl(GP_IO_SEL);
+ data = data & ~(1 << offset);
+ outl(data, GP_IO_SEL);
+
+ data = inl(GP_LVL);
+ if (val) {
+ data = data | (1 << offset);
+ } else {
+ data = data & ~(1 << offset);
+ }
+ outl(data, GP_LVL);
+ } else if (bank == 1) {
+ data = inl(GP_IO_SEL2);
+ data = data & ~(1 << offset);
+ outl(data, GP_IO_SEL2);
+
+ data = inl(GP_LVL2);
+ if (val) {
+ data = data | (1 << offset);
+ } else {
+ data = data & ~(1 << offset);
+ }
+ outl(data, GP_LVL2);
+ } else if (bank == 2) {
+ data = inl(GP_IO_SEL3);
+ data = data & ~(1 << offset);
+ outl(data, GP_IO_SEL3);
+
+ data = inl(GP_LVL3);
+ if (val) {
+ data = data | (1 << offset);
+ } else {
+ data = data & ~(1 << offset);
+ }
+ outl(data, GP_LVL3);
+ }
+ GPIO_XEON_SPIN_UNLOCK(sio_lock, flags);
+
+ return 0;
+}
+
+static int xeon_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+ unsigned int data;
+ unsigned int bank, tmp_offset;
+ unsigned long flags;
+
+ bank = offset / BANKSIZE;
+ tmp_offset = offset % BANKSIZE;
+
+ GPIO_XEON_SPIN_LOCK(sio_lock, flags);
+ if (bank == 0) {
+ data = inl(GPIO_USE_SEL);
+ data = data | (1 << tmp_offset);
+ outl(data, GPIO_USE_SEL);
+ } else if (bank == 1) {
+ data = inl(GPIO_USE_SEL2);
+ data = data | (1 << tmp_offset);
+ outl(data, GPIO_USE_SEL2);
+ } else if (bank == 2) {
+ data = inl(GPIO_USE_SEL3);
+ data = data | (1 << tmp_offset);
+ outl(data, GPIO_USE_SEL3);
+ }
+ GPIO_XEON_SPIN_UNLOCK(sio_lock, flags);
+ return 0;
+}
+
+static void xeon_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+ unsigned int data;
+ unsigned int bank, tmp_offset;
+ unsigned long flags;
+
+ bank = offset / BANKSIZE;
+ tmp_offset = offset % BANKSIZE;
+
+ GPIO_XEON_SPIN_LOCK(sio_lock, flags);
+ if (bank == 0) {
+ data = inl(GPIO_USE_SEL);
+ data = data & ~(1 << tmp_offset);
+ outl(data, GPIO_USE_SEL);
+ } else if (bank == 1) {
+ data = inl(GPIO_USE_SEL2);
+ data = data & ~(1 << tmp_offset);
+ outl(data, GPIO_USE_SEL2);
+ } else if (bank == 2) {
+ data = inl(GPIO_USE_SEL3);
+ data = data & ~(1 << tmp_offset);
+ outl(data, GPIO_USE_SEL3);
+ }
+ GPIO_XEON_SPIN_UNLOCK(sio_lock, flags);
+}
+
+static struct gpio_chip xeon_gpio_chip = {
+ .label = GPIO_NAME,
+ .owner = THIS_MODULE,
+ .get = xeon_gpio_get,
+ .direction_input = xeon_gpio_direction_in,
+ .set = xeon_gpio_set,
+ .direction_output = xeon_gpio_direction_out,
+ .request = xeon_gpio_request,
+ .free = xeon_gpio_free,
+};
+
+static int __init xeon_gpio_init(void)
+{
+ int err;
+ if (!request_region(GPIO_BASE, GPIO_IOSIZE, GPIO_NAME))
+ return -EBUSY;
+
+ xeon_gpio_chip.base = GPIO_BASE_ID;
+ xeon_gpio_chip.ngpio = 96;
+
+ err = gpiochip_add(&xeon_gpio_chip);
+ if (err < 0)
+ goto gpiochip_add_err;
+ err = platform_device_register(&i2c_gpio);
+ if (err < 0) {
+ goto i2c_get_adapter_err;
+ }
+
+ return 0;
+
+i2c_get_adapter_err:
+ platform_device_unregister(&i2c_gpio);
+ gpiochip_remove(&xeon_gpio_chip);
+
+gpiochip_add_err:
+ release_region(GPIO_BASE, GPIO_IOSIZE);
+ return -1;
+}
+
+static void __exit xeon_gpio_exit(void)
+{
+ platform_device_unregister(&i2c_gpio);
+ mdelay(100);
+ gpiochip_remove(&xeon_gpio_chip);
+ release_region(GPIO_BASE, GPIO_IOSIZE);
+}
+
+module_init(xeon_gpio_init);
+module_exit(xeon_gpio_exit);
+
+MODULE_AUTHOR("sonic_rd ");
+MODULE_DESCRIPTION("GPIO interface for XEON Super I/O chip");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/modules/rg_fan.c b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/rg_fan.c
new file mode 100755
index 000000000000..624230fdd909
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/rg_fan.c
@@ -0,0 +1,266 @@
+/*
+ * rg_fan.c - A driver for control rg_fan base on rg_fan.c
+ *
+ * Copyright (c) 1998, 1999 Frodo Looijaard
+ * Copyright (c) 2019
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define FAN_SIZE (256)
+#define SYS_FAN_BUF_LEN (64)
+
+typedef enum {
+ DBG_START,
+ DBG_VERBOSE,
+ DBG_KEY,
+ DBG_WARN,
+ DBG_ERROR,
+ DBG_END,
+} dbg_level_t;
+
+static int debuglevel = 0;
+
+#define DBG_DEBUG(fmt, arg...) \
+ do { \
+ if (debuglevel > DBG_START && debuglevel < DBG_ERROR) { \
+ printk(KERN_INFO "[DEBUG]:<%s, %d>:" fmt, \
+ __FUNCTION__, __LINE__, ##arg); \
+ } else if (debuglevel >= DBG_ERROR) { \
+ printk(KERN_ERR "[DEBUG]:<%s, %d>:" fmt, __FUNCTION__, \
+ __LINE__, ##arg); \
+ } else { \
+ } \
+ } while (0)
+
+#define DBG_ERROR(fmt, arg...) \
+ do { \
+ if (debuglevel > DBG_START) { \
+ printk(KERN_ERR "[ERROR]:<%s, %d>:" fmt, __FUNCTION__, \
+ __LINE__, ##arg); \
+ } \
+ } while (0)
+
+extern s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command);
+extern s32 platform_i2c_smbus_read_i2c_block_data(
+ const struct i2c_client *client, u8 command, u8 length, u8 *values);
+extern s32 platform_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command);
+
+typedef enum dfd_dev_info_type_e {
+ DFD_DEV_INFO_TYPE_MAC = 1,
+ DFD_DEV_INFO_TYPE_NAME = 2,
+ DFD_DEV_INFO_TYPE_SN = 3,
+ DFD_DEV_INFO_TYPE_PWR_CONS = 4,
+ DFD_DEV_INFO_TYPE_HW_INFO = 5,
+ DFD_DEV_INFO_TYPE_DEV_TYPE = 6,
+} dfd_dev_tlv_type_t;
+
+typedef struct dfd_dev_head_info_s {
+ uint8_t ver; /* define E2PROM version,default is 0x01 */
+ uint8_t flag; /* flag is 0x7E in new version E2PROM */
+ uint8_t hw_ver; /* consists of main version and revise version */
+ uint8_t type; /* HW type */
+ int16_t tlv_len; /* 16 bits */
+} dfd_dev_head_info_t;
+
+typedef struct dfd_dev_tlv_info_s {
+ uint8_t type;
+ uint8_t len;
+ uint8_t data[0];
+} dfd_dev_tlv_info_t;
+
+struct fan_data {
+ struct i2c_client *client;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated[8]; /* In jiffies */
+ u8 data[FAN_SIZE]; /* Register value */
+};
+
+static ssize_t show_fan_sysfs_tlv_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 fan_data *data = i2c_get_clientdata(client);
+
+ dfd_dev_head_info_t info;
+ uint8_t tmp_tlv_len[sizeof(uint16_t)];
+ uint8_t *tlv_data;
+ dfd_dev_tlv_info_t *tlv;
+ int type;
+ int buf_len = SYS_FAN_BUF_LEN - 1;
+ u8 sysfs_buf[SYS_FAN_BUF_LEN];
+ int i;
+ int ret = 0;
+
+ mutex_lock(&data->update_lock);
+ memset(sysfs_buf, 0, SYS_FAN_BUF_LEN);
+ ret = platform_i2c_smbus_read_i2c_block_data(
+ client, 0, sizeof(dfd_dev_head_info_t), (uint8_t *)&info);
+ if (ret != sizeof(dfd_dev_head_info_t)) {
+ DBG_ERROR("fan maybe not set mac or not present0");
+ goto exit;
+ }
+
+ /* transform TLV_LEN */
+ memcpy(tmp_tlv_len, (uint8_t *)&info.tlv_len, sizeof(int16_t));
+ info.tlv_len = (tmp_tlv_len[0] << 8) + tmp_tlv_len[1];
+
+ if ((info.tlv_len <= 0) || (info.tlv_len > 0xFF)) {
+ DBG_ERROR("fan maybe not set mac or not present1");
+ goto exit;
+ }
+
+ type = attr->index;
+ tlv_data = (uint8_t *)kmalloc(info.tlv_len, GFP_KERNEL);
+ memset(tlv_data, 0, info.tlv_len);
+
+ if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+ for (i = 0; i < info.tlv_len; i += I2C_SMBUS_BLOCK_MAX)
+ if (platform_i2c_smbus_read_i2c_block_data(client,
+ sizeof(dfd_dev_head_info_t) + i,
+ I2C_SMBUS_BLOCK_MAX, tlv_data + i) != I2C_SMBUS_BLOCK_MAX)
+ break;
+ }
+
+ DBG_DEBUG("TLV Len:%d\n", (int)sizeof(dfd_dev_tlv_info_t));
+ for (tlv = (dfd_dev_tlv_info_t *)tlv_data;
+ (ulong)tlv < (ulong)tlv_data + info.tlv_len;) {
+ DBG_DEBUG(
+ "tlv: %p, tlv->type: 0x%x, tlv->len: 0x%x info->tlv_len: 0x%x\n",
+ tlv, tlv->type, tlv->len, info.tlv_len);
+ if (tlv->type == type && buf_len >= tlv->len) {
+ memcpy((uint8_t *)sysfs_buf, (uint8_t *)tlv->data,
+ tlv->len);
+ buf_len = (uint32_t)tlv->len;
+ break;
+ }
+ tlv = (dfd_dev_tlv_info_t *)((uint8_t *)tlv +
+ sizeof(dfd_dev_tlv_info_t) +
+ tlv->len);
+ }
+
+ kfree(tlv_data);
+ DBG_DEBUG("value: %s \n", sysfs_buf);
+exit:
+ mutex_unlock(&data->update_lock);
+ return sprintf(buf, "%s\n", sysfs_buf);
+}
+
+static ssize_t show_fan_value(struct device *dev, struct device_attribute *da, char *buf)
+{
+ struct fan_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ int i;
+
+ mutex_lock(&data->update_lock);
+
+ if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+ for (i = 0; i < FAN_SIZE; i += I2C_SMBUS_BLOCK_MAX) {
+ if (platform_i2c_smbus_read_i2c_block_data(
+ client, i, I2C_SMBUS_BLOCK_MAX, data->data + i) != I2C_SMBUS_BLOCK_MAX)
+ goto exit;
+ }
+ } else {
+ for (i = 0; i < FAN_SIZE; i += 2) {
+ int word = platform_i2c_smbus_read_word_data(client, i);
+ if (word < 0)
+ goto exit;
+ data->data[i] = word & 0xff;
+ data->data[i + 1] = word >> 8;
+ }
+ }
+ memcpy(buf, &data->data[0], FAN_SIZE);
+exit:
+ mutex_unlock(&data->update_lock);
+ return FAN_SIZE;
+}
+
+static SENSOR_DEVICE_ATTR(fan_hw_version, S_IRUGO, show_fan_sysfs_tlv_value, NULL, DFD_DEV_INFO_TYPE_HW_INFO);
+static SENSOR_DEVICE_ATTR(fan_sn, S_IRUGO, show_fan_sysfs_tlv_value, NULL, DFD_DEV_INFO_TYPE_SN);
+static SENSOR_DEVICE_ATTR(fan_type, S_IRUGO, show_fan_sysfs_tlv_value, NULL, DFD_DEV_INFO_TYPE_NAME);
+static SENSOR_DEVICE_ATTR(fan, S_IRUGO, show_fan_value, NULL, 0);
+
+static struct attribute *fan_sysfs_attrs[] = {
+ &sensor_dev_attr_fan_hw_version.dev_attr.attr,
+ &sensor_dev_attr_fan_sn.dev_attr.attr,
+ &sensor_dev_attr_fan_type.dev_attr.attr,
+ &sensor_dev_attr_fan.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group fan_sysfs_group = {
+ .attrs = fan_sysfs_attrs,
+};
+
+static int fan_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct fan_data *data;
+ int status;
+
+ status = -1;
+ DBG_DEBUG("fan_probe(0x%02x)\n", client->addr);
+ data = devm_kzalloc(&client->dev, sizeof(struct fan_data), GFP_KERNEL);
+ if (!data) {
+ return -ENOMEM;
+ }
+
+ data->client = client;
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+ status = sysfs_create_group(&client->dev.kobj, &fan_sysfs_group);
+ if (status != 0) {
+ DBG_ERROR(" sysfs_create_group err\n");
+ return status;
+ }
+ return 0;
+}
+
+static int fan_remove(struct i2c_client *client)
+{
+ sysfs_remove_group(&client->dev.kobj, &fan_sysfs_group);
+ return 0;
+}
+
+static const struct i2c_device_id fan_id[] = { { "rg_fan", 0 }, {} };
+MODULE_DEVICE_TABLE(i2c, fan_id);
+
+static struct i2c_driver rg_fan_driver = {
+ .driver = {
+ .name = "rg_fan",
+ },
+ .probe = fan_probe,
+ .remove = fan_remove,
+ .id_table = fan_id,
+};
+
+module_i2c_driver(rg_fan_driver);
+MODULE_AUTHOR("sonic_rd ");
+MODULE_DESCRIPTION("ruijie fan driver");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/modules/rg_psu.c b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/rg_psu.c
new file mode 100755
index 000000000000..982124ff87dd
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/rg_psu.c
@@ -0,0 +1,322 @@
+/*
+ * rg_cpld.c - A driver for pmbus psu
+ *
+ * Copyright (c) 2019
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define MAGIC_PSU_RATE (0xA7)
+#define MAGIC_PSU_OUT_CURRENT (0x8C)
+#define MAGIC_PSU_OUT_VOLTAGE (0x8B)
+#define MAGIC_PSU_IN_VOLTAGE (0x88)
+#define MAGIC_PSU_IN_CURRENT (0x89)
+#define MAGIC_PSU_TEMP (0x8D)
+#define MAGIC_PSU_TYPE (0x25)
+#define MAGIC_PSU_SN (0x38)
+#define MAGIC_PSU_HW (0x35)
+#define PSU_SIZE (256)
+
+typedef enum {
+ DBG_START,
+ DBG_VERBOSE,
+ DBG_KEY,
+ DBG_WARN,
+ DBG_ERROR,
+ DBG_END,
+} dbg_level_t;
+
+static int debuglevel = 0;
+
+#define DBG_DEBUG(fmt, arg...) \
+ do { \
+ if (debuglevel > DBG_START && debuglevel < DBG_ERROR) { \
+ printk(KERN_INFO "[DEBUG]:<%s, %d>:" fmt, \
+ __FUNCTION__, __LINE__, ##arg); \
+ } else if (debuglevel >= DBG_ERROR) { \
+ printk(KERN_ERR "[DEBUG]:<%s, %d>:" fmt, __FUNCTION__, \
+ __LINE__, ##arg); \
+ } else { \
+ } \
+ } while (0)
+
+#define DBG_INFO(fmt, arg...) \
+ do { \
+ if (debuglevel > DBG_KEY) { \
+ printk(KERN_INFO "[INFO]:<%s, %d>:" fmt, __FUNCTION__, \
+ __LINE__, ##arg); \
+ } \
+ } while (0)
+
+#define DBG_ERROR(fmt, arg...) \
+ do { \
+ if (debuglevel > DBG_START) { \
+ printk(KERN_ERR "[ERROR]:<%s, %d>:" fmt, __FUNCTION__, \
+ __LINE__, ##arg); \
+ } \
+ } while (0)
+
+static const unsigned short rg_i2c_psu[] = { 0x50, 0x53, 0x58, 0x5b, I2C_CLIENT_END };
+
+extern s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command);
+extern s32 platform_i2c_smbus_read_i2c_block_data(const struct i2c_client *client,
+ u8 command, u8 length, u8 *values);
+
+struct psu_data {
+ struct i2c_client *client;
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 data[PSU_SIZE]; /* Register value */
+};
+
+static ssize_t show_psu_sysfs_value(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_sysfs_15_value(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_psu_value(struct device *dev, struct device_attribute *da, char *buf);
+
+static SENSOR_DEVICE_ATTR(psu_rate, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_RATE);
+static SENSOR_DEVICE_ATTR(psu_out_current, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_OUT_CURRENT);
+static SENSOR_DEVICE_ATTR(psu_out_voltage, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_OUT_VOLTAGE);
+static SENSOR_DEVICE_ATTR(psu_in_voltage, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_IN_VOLTAGE);
+static SENSOR_DEVICE_ATTR(psu_in_current, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_IN_CURRENT);
+static SENSOR_DEVICE_ATTR(psu_temp, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_TEMP);
+static SENSOR_DEVICE_ATTR(psu_type, S_IRUGO, show_sysfs_15_value, NULL, MAGIC_PSU_TYPE);
+static SENSOR_DEVICE_ATTR(psu_sn, S_IRUGO, show_sysfs_15_value, NULL, MAGIC_PSU_SN);
+static SENSOR_DEVICE_ATTR(psu_hw, S_IRUGO, show_psu_value, NULL, MAGIC_PSU_HW);
+
+static struct attribute *psu_pmbus_sysfs_attrs[] = {
+ &sensor_dev_attr_psu_rate.dev_attr.attr,
+ &sensor_dev_attr_psu_out_current.dev_attr.attr,
+ &sensor_dev_attr_psu_out_voltage.dev_attr.attr,
+ &sensor_dev_attr_psu_in_voltage.dev_attr.attr,
+ &sensor_dev_attr_psu_in_current.dev_attr.attr,
+ &sensor_dev_attr_psu_temp.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *psu_fru_sysfs_attrs[] = {
+ &sensor_dev_attr_psu_type.dev_attr.attr,
+ &sensor_dev_attr_psu_sn.dev_attr.attr,
+ &sensor_dev_attr_psu_hw.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group psu_pmbus_sysfs_attrs_group = {
+ .attrs = psu_pmbus_sysfs_attrs,
+};
+
+static const struct attribute_group psu_fru_sysfs_attrs_group = {
+ .attrs = psu_fru_sysfs_attrs,
+};
+
+static ssize_t show_psu_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 psu_data *data = i2c_get_clientdata(client);
+ int ret;
+ char psu_buf[PSU_SIZE];
+ memset(psu_buf, 0, PSU_SIZE);
+ mutex_lock(&data->update_lock);
+ ret = platform_i2c_smbus_read_i2c_block_data(client, attr->index, 2, psu_buf);
+ if (ret < 0) {
+ DBG_ERROR("Failed to read psu\n");
+ }
+ DBG_DEBUG("cpld reg pos:0x%x value:0x%02x\n", attr->index, data->data[0]);
+ mutex_unlock(&data->update_lock);
+ return snprintf(buf, 3, "%s\n", psu_buf);
+}
+
+static int linear_to_value(short reg, bool v_out)
+{
+ short exponent;
+ int mantissa;
+ long val;
+
+ if (v_out) {
+ exponent = -9;
+ mantissa = reg;
+ } else {
+ exponent = reg >> 11;
+ mantissa = (((reg & 0x7ff) << 5)) >> 5;
+ }
+ val = mantissa;
+ val = val * 1000L;
+ if (exponent >= 0) {
+ val <<= exponent;
+ } else {
+ val >>= -exponent;
+ }
+
+ return val;
+}
+
+static ssize_t show_psu_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 psu_data *data = i2c_get_clientdata(client);
+ int ret;
+ u8 smbud_buf[PSU_SIZE];
+ uint16_t value;
+ int result;
+
+ ret = -1;
+ memset(smbud_buf, 0, PSU_SIZE);
+ mutex_lock(&data->update_lock);
+ DBG_DEBUG("ret:%d", ret);
+ ret = platform_i2c_smbus_read_i2c_block_data(client, attr->index, 2, smbud_buf);
+ if (ret < 0) {
+ DBG_ERROR("Failed to read psu \n");
+ }
+ value = smbud_buf[1];
+ value = value << 8;
+ value |= smbud_buf[0];
+
+ if (attr->index == 0x8b) {
+ result = linear_to_value(value, true);
+ } else {
+ result = linear_to_value(value, false);
+ }
+ mutex_unlock(&data->update_lock);
+ return snprintf(buf, PSU_SIZE, "%d\n", result);
+}
+
+static ssize_t show_sysfs_15_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 psu_data *data = i2c_get_clientdata(client);
+ int ret;
+ u8 smbud_buf[PSU_SIZE];
+
+ memset(smbud_buf, 0, PSU_SIZE);
+ mutex_lock(&data->update_lock);
+ ret = platform_i2c_smbus_read_i2c_block_data(client, attr->index, 15, smbud_buf);
+ if (ret < 0) {
+ DBG_ERROR("Failed to read psu\n");
+ }
+ mutex_unlock(&data->update_lock);
+ return snprintf(buf, PSU_SIZE, "%s\n", smbud_buf);
+}
+
+static int psu_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 |
+ I2C_FUNC_SMBUS_WORD_DATA))
+ return -ENODEV;
+ conf = platform_i2c_smbus_read_byte_data(new_client, 0);
+ if (!conf)
+ return -ENODEV;
+
+ return 0;
+}
+
+static int psu_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct psu_data *data;
+ int status;
+
+ status = -1;
+ data = devm_kzalloc(&client->dev, sizeof(struct psu_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->client = client;
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+ switch (client->addr) {
+ case 0x50:
+ case 0x53:
+ status = sysfs_create_group(&client->dev.kobj,
+ &psu_fru_sysfs_attrs_group);
+ if (status != 0) {
+ DBG_ERROR("%s %d sysfs_create_group err\n", __func__, __LINE__);
+ }
+ break;
+ case 0x58:
+ case 0x5b:
+ status = sysfs_create_group(&client->dev.kobj,
+ &psu_pmbus_sysfs_attrs_group);
+ if (status != 0) {
+ DBG_ERROR("%s %d sysfs_create_group err\n", __func__, __LINE__);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return status;
+}
+
+static int psu_remove(struct i2c_client *client)
+{
+ switch (client->addr) {
+ case 0x50:
+ case 0x53:
+ sysfs_remove_group(&client->dev.kobj, &psu_fru_sysfs_attrs_group);
+ break;
+ case 0x58:
+ case 0x5b:
+ sysfs_remove_group(&client->dev.kobj, &psu_pmbus_sysfs_attrs_group);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static const struct i2c_device_id psu_id[] = {
+ { "rg_psu", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, psu_id);
+
+static struct i2c_driver rg_psu_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "rg_psu",
+ },
+ .probe = psu_probe,
+ .remove = psu_remove,
+ .id_table = psu_id,
+ .detect = psu_detect,
+ .address_list = rg_i2c_psu,
+};
+
+module_i2c_driver(rg_psu_driver);
+
+MODULE_AUTHOR("sonic_rd ");
+MODULE_DESCRIPTION("ruijie pmbus psu driver");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/modules/ruijie_platform.c b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/ruijie_platform.c
new file mode 100755
index 000000000000..b1cdbe892e5a
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/modules/ruijie_platform.c
@@ -0,0 +1,97 @@
+/*
+ * ruijie_platform.c - A driver for ruijie platform module
+ *
+ * Copyright (c) 2019
+ *
+ * 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
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define PLATFORM_I2C_RETRY_TIMES (3)
+
+s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)
+{
+ int try;
+ s32 ret;
+
+ ret = -1;
+ for (try = 0; try < PLATFORM_I2C_RETRY_TIMES; try ++) {
+ if ((ret = i2c_smbus_read_byte_data(client, command)) >= 0)
+ break;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(platform_i2c_smbus_read_byte_data);
+
+s32 platform_i2c_smbus_read_i2c_block_data(const struct i2c_client *client,
+ u8 command, u8 length, u8 *values)
+{
+ int try ;
+ s32 ret;
+
+ ret = -1;
+ for (try = 0; try < PLATFORM_I2C_RETRY_TIMES; try ++) {
+ if ((ret = i2c_smbus_read_i2c_block_data(client, command, length, values)) >= 0)
+ break;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(platform_i2c_smbus_read_i2c_block_data);
+
+s32 platform_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command)
+{
+ int try;
+ s32 ret;
+
+ ret = -1;
+ for (try = 0; try < PLATFORM_I2C_RETRY_TIMES; try ++) {
+ if ((ret = i2c_smbus_read_word_data(client, command)) >= 0)
+ break;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(platform_i2c_smbus_read_word_data);
+
+static int __init ruijie_platform_init(void)
+{
+ return 0;
+}
+
+static void __exit ruijie_platform_exit(void)
+{
+ return;
+}
+
+module_init(ruijie_platform_init);
+module_exit(ruijie_platform_exit);
+
+MODULE_DESCRIPTION("ruijie Platform Support");
+MODULE_AUTHOR("sonic_rd ");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/script/avscontrol.py b/platform/broadcom/sonic-platform-modules-ruijie/common/script/avscontrol.py
new file mode 100755
index 000000000000..698dae3c8312
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/script/avscontrol.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+import sys
+import click
+import os
+import commands
+import time
+from ruijieutil import *
+import syslog
+from monitor import status
+import traceback
+try:
+ from rest.rest import BMCMessage
+except:
+ pass
+
+CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
+
+class AliasedGroup(click.Group):
+ def get_command(self, ctx, cmd_name):
+ rv = click.Group.get_command(self, ctx, cmd_name)
+ if rv is not None:
+ return rv
+ matches = [x for x in self.list_commands(ctx)
+ if x.startswith(cmd_name)]
+ if not matches:
+ return None
+ elif len(matches) == 1:
+ return click.Group.get_command(self, ctx, matches[0])
+ ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
+
+def avswarninglog(s):
+ s = s.decode('utf-8').encode('gb2312')
+ syslog.openlog("AVSCONTROL",syslog.LOG_PID)
+ syslog.syslog(syslog.LOG_WARNING,s)
+
+def avscriticallog(s):
+ s = s.decode('utf-8').encode('gb2312')
+ syslog.openlog("AVSCONTROL",syslog.LOG_PID)
+ syslog.syslog(syslog.LOG_CRIT,s)
+
+def avserror(s):
+ s = s.decode('utf-8').encode('gb2312')
+ syslog.openlog("AVSCONTROL",syslog.LOG_PID)
+ syslog.syslog(syslog.LOG_ERR,s)
+
+def avsinfo(s):
+ syslog.openlog("AVSCONTROL",syslog.LOG_PID)
+ syslog.syslog(syslog.LOG_INFO,s)
+
+def do_avs_ctrol():
+ index = 0
+ url = "/xyz/openbmc_project/hostchannel/attr/MacRov"
+
+ wait_for_docker()
+ time.sleep(10)
+ while True:
+ if STARTMODULE.has_key("avscontrol_restful") and STARTMODULE['avscontrol_restful'] == 1:
+ try:
+ if int(BMCMessage().getBmcValue(url)) >= 0:
+ break
+ except Exception as e:
+ time.sleep(2)
+ continue
+ else:
+ if AVSUTIL.mac_adj():
+ break
+
+ index += 1
+ if index >= 10:
+ avserror("%%AVSCONTROL NUM %d" % index)
+ exit(-1)
+ avsinfo("%%AVSCONTROL success")
+ exit(0)
+
+def run(interval):
+ while True:
+ try:
+ do_avs_ctrol()
+ time.sleep(interval)
+ except Exception as e:
+ traceback.print_exc()
+ print(e)
+
+@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS)
+def main():
+ '''device operator'''
+ pass
+
+@main.command()
+def start():
+ '''start fan control'''
+ avsinfo("%%AVSCONTROL start")
+ interval = 5
+ run(interval)
+
+##device_i2c operation
+if __name__ == '__main__':
+ main()
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/script/device_i2c.py b/platform/broadcom/sonic-platform-modules-ruijie/common/script/device_i2c.py
new file mode 100755
index 000000000000..a40f20880486
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/script/device_i2c.py
@@ -0,0 +1,290 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import sys
+import click
+import os
+import commands
+import time
+from ruijieconfig import *
+
+CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
+
+# wrap print() to be compatible with python2 and python3
+def rprint(*args):
+ print(" ".join(map(str, args)))
+
+class AliasedGroup(click.Group):
+
+ def get_command(self, ctx, cmd_name):
+ rv = click.Group.get_command(self, ctx, cmd_name)
+ if rv is not None:
+ return rv
+ matches = [x for x in self.list_commands(ctx) if x.startswith(cmd_name)]
+ if not matches:
+ return None
+ elif len(matches) == 1:
+ return click.Group.get_command(self, ctx, matches[0])
+ ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
+
+
+def log_os_system(cmd):
+ """Run a shell command and print its output"""
+ status, output = commands.getstatusoutput(cmd)
+ if status:
+ rprint(output)
+ return status, output
+
+
+def write_sysfs_value(reg_name, value):
+ """Write some value to a file on sysfs"""
+ retval = 'ERR'
+ mb_reg_file = "/sys/bus/i2c/devices/" + reg_name
+ if (not os.path.isfile(mb_reg_file)):
+ rprint(mb_reg_file, 'not found !')
+ return False
+ try:
+ with open(mb_reg_file, 'w') as fd:
+ fd.write(value)
+ except Exception as error:
+ return False
+ return True
+
+
+def check_driver():
+ """Check if the rg-starting driver is exists"""
+ status, output = log_os_system("lsmod | grep rg | wc -l")
+ if status:
+ return False
+ if output.isdigit() and int(output) > 0:
+ return True
+ else:
+ return False
+
+
+def get_pid(name):
+ ret = []
+ for dirname in os.listdir('/proc'):
+ if dirname == 'curproc':
+ continue
+ try:
+ with open('/proc/{}/cmdline'.format(dirname), mode='rb') as fd:
+ content = fd.read()
+ except Exception:
+ continue
+ if name in content:
+ ret.append(dirname)
+ return ret
+
+
+def start_avscontrol():
+ cmd = "nohup avscontrol.py start >/dev/null 2>&1 &"
+ rets = get_pid("avscontrol.py")
+ if len(rets) == 0:
+ os.system(cmd)
+ pass
+
+
+def start_fancontrol():
+ if STARTMODULE['fancontrol'] == 1:
+ cmd = "nohup fancontrol.py start >/dev/null 2>&1 &"
+ rets = get_pid("fancontrol.py")
+ if len(rets) == 0:
+ os.system(cmd)
+
+
+def stop_fancontrol():
+ if STARTMODULE['fancontrol'] == 1:
+ rets = get_pid("fancontrol.py")
+ for ret in rets:
+ cmd = "kill " + ret
+ os.system(cmd)
+ return True
+
+
+def remove_dev(bus, loc):
+ cmd = "echo 0x%02x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (loc, bus)
+ devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc)
+ if os.path.exists(devpath):
+ log_os_system(cmd)
+
+
+def add_dev(name, bus, loc):
+ if name == "lm75":
+ time.sleep(0.1)
+ pdevpath = "/sys/bus/i2c/devices/i2c-%d/" % (bus)
+ # wait 10 seconds at most until i2c bus created
+ for i in range(1, 100):
+ if os.path.exists(pdevpath) == True:
+ break
+ time.sleep(0.1)
+ rprint(pdevpath, 'not found, wait 0.1 second ! i %d ' % (i))
+
+ cmd = "echo %s 0x%02x > /sys/bus/i2c/devices/i2c-%d/new_device" % (
+ name, loc, bus)
+ devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc)
+ if os.path.exists(devpath) == False:
+ os.system(cmd)
+
+
+def removedevs():
+ devs = GLOBALCONFIG["DEVS"]
+ for index in range(len(devs) - 1, -1, -1):
+ remove_dev(devs[index]["bus"], devs[index]["loc"])
+
+
+def adddevs():
+ devs = GLOBALCONFIG["DEVS"]
+ for dev in range(0, devs.__len__()):
+ add_dev(devs[dev]["name"], devs[dev]["bus"], devs[dev]["loc"])
+
+
+def checksignaldriver(name):
+ """Check if the driver exists"""
+ modisexistcmd = "lsmod | grep %s | wc -l" % name
+ status, output = log_os_system(modisexistcmd)
+ if status:
+ return False
+ if output.isdigit() and int(output) > 0:
+ return True
+ else:
+ return False
+
+
+def adddriver(name, delay):
+ cmd = "modprobe %s" % name
+ if delay != 0:
+ time.sleep(delay)
+ rprint(name, 'sleep %d second!' % (delay))
+ if checksignaldriver(name) != True:
+ log_os_system(cmd)
+
+
+def removedriver(name, delay):
+ realname = name.lstrip().split(" ")[0]
+ cmd = "rmmod -f %s" % realname
+ if checksignaldriver(realname):
+ log_os_system(cmd)
+
+
+def removedrivers():
+ if GLOBALCONFIG == None:
+ click.echo("load GLOBALCONFIG error")
+ return
+ drivers = GLOBALCONFIG.get("DRIVERLISTS", None)
+ if drivers == None:
+ click.echo("load DRIVERLISTS error")
+ return
+ for index in range(len(drivers) - 1, -1, -1):
+ delay = 0
+ name = ""
+ if type(drivers[index]) == dict and drivers[index].has_key("delay"):
+ name = drivers[index].get("name")
+ delay = drivers[index]["delay"]
+ else:
+ name = drivers[index]
+ removedriver(name, delay)
+
+
+def adddrivers():
+ """Add all drivers in driver list"""
+ if GLOBALCONFIG == None:
+ click.echo("load GLOBALCONFIG error")
+ return
+ drivers = GLOBALCONFIG.get("DRIVERLISTS", None)
+ if drivers == None:
+ click.echo("load DRIVERLISTS error")
+ return
+ for index in range(0, len(drivers)):
+ delay = 0
+ name = ""
+ if type(drivers[index]) == dict and drivers[index].has_key("delay"):
+ name = drivers[index].get("name")
+ delay = drivers[index]["delay"]
+ else:
+ name = drivers[index]
+ adddriver(name, delay)
+
+
+def otherinit():
+ for index in GLOBALINITPARAM:
+ write_sysfs_value(index["loc"], index["value"])
+
+ for index in GLOBALINITCOMMAND:
+ log_os_system(index)
+
+
+def unload_driver():
+ """remove everything and back to the initialization state"""
+ stop_fancontrol() # fan control service
+ removedevs() # others
+ removedrivers() # drivers
+
+
+def reload_driver():
+ """reload everything"""
+ removedevs()
+ removedrivers()
+ time.sleep(1)
+ adddrivers()
+ adddevs()
+
+
+def i2c_check(bus, retrytime=6):
+ try:
+ i2cpath = "/sys/bus/i2c/devices/" + bus
+ while retrytime and not os.path.exists(i2cpath):
+ click.echo("%s not found,retrytime:%d," % (i2cpath, retrytime))
+ reload_driver()
+ retrytime -= 1
+ time.sleep(1)
+ except Exception as e:
+ click.echo(str(e))
+ return
+
+
+def load_driver():
+ adddrivers()
+ adddevs()
+ if STARTMODULE.get("i2ccheck", 0) == 1: #i2c HA
+ busend = i2ccheck_params.get("busend")
+ retrytime = i2ccheck_params.get("retrytime")
+ i2c_check(busend, retrytime)
+ start_fancontrol() # start fan control service
+ if STARTMODULE['avscontrol'] == 1:
+ start_avscontrol() # start avs control service
+ otherinit()
+
+
+@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS)
+def main():
+ """device operator"""
+ pass
+
+
+@main.command()
+def start():
+ """load device"""
+ if check_driver():
+ unload_driver()
+ load_driver()
+ click.echo("start")
+
+
+@main.command()
+def stop():
+ """stop device"""
+ unload_driver()
+ click.echo("stop")
+
+
+@main.command()
+def restart():
+ """restart device"""
+ unload_driver()
+ load_driver()
+ click.echo("restart")
+
+
+if __name__ == '__main__':
+ main()
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/script/fancontrol.py b/platform/broadcom/sonic-platform-modules-ruijie/common/script/fancontrol.py
new file mode 100755
index 000000000000..b201df29f02d
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/script/fancontrol.py
@@ -0,0 +1,655 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import sys
+import click
+import os
+import commands
+import time
+from ruijieutil import *
+import syslog
+from monitor import status
+import traceback
+
+CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
+
+DEBUG_COMMON = 0x01
+DEBUG_LEDCONTROL = 0x02
+DEBUG_FANCONTROL = 0x04
+
+
+class AliasedGroup(click.Group):
+
+ def get_command(self, ctx, cmd_name):
+ rv = click.Group.get_command(self, ctx, cmd_name)
+ if rv is not None:
+ return rv
+ matches = [x for x in self.list_commands(ctx) if x.startswith(cmd_name)]
+ if not matches:
+ return None
+ elif len(matches) == 1:
+ return click.Group.get_command(self, ctx, matches[0])
+ ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
+
+
+def fanwarninglog(s):
+ #s = s.decode('utf-8').encode('gb2312')
+ syslog.openlog("FANCONTROL", syslog.LOG_PID)
+ syslog.syslog(syslog.LOG_WARNING, s)
+
+
+def fancriticallog(s):
+ #s = s.decode('utf-8').encode('gb2312')
+ syslog.openlog("FANCONTROL", syslog.LOG_PID)
+ syslog.syslog(syslog.LOG_CRIT, s)
+
+
+def fanerror(s):
+ #s = s.decode('utf-8').encode('gb2312')
+ syslog.openlog("FANCONTROL", syslog.LOG_PID)
+ syslog.syslog(syslog.LOG_ERR, s)
+
+
+def fanwarningdebuglog(debuglevel, s):
+ #s = s.decode('utf-8').encode('gb2312')
+ if FANCTROLDEBUG & debuglevel:
+ syslog.openlog("FANCONTROL", syslog.LOG_PID)
+ syslog.syslog(syslog.LOG_DEBUG, s)
+
+
+class FanControl():
+ critnum = 0
+
+ def __init__(self):
+ self._fan_ok_num = 0
+ self._psu_ok_num = 0
+ self._intemp = -100.0
+ self._mac_aver = -100.0
+ self._mac_max = -100.0
+ self._pre_intemp = -1000 # previous temperature
+ self._outtemp = -100
+ self._boardtemp = -100
+ self._cputemp = -1000
+ pass
+
+ @property
+ def fan_ok_num(self):
+ return self._fan_ok_num
+
+ @property
+ def psu_ok_num(self):
+ return self._psu_ok_num
+
+ @property
+ def cputemp(self):
+ return self._cputemp
+
+ @property
+ def intemp(self):
+ return self._intemp
+
+ @property
+ def outtemp(self):
+ return self._outtemp
+
+ @property
+ def boardtemp(self):
+ return self._boardtemp
+
+ @property
+ def mac_aver(self):
+ return self._mac_aver
+
+ @property
+ def pre_intemp(self):
+ return self._pre_intemp
+
+ @property
+ def mac_max(self):
+ return self._mac_max
+
+ def sort_callback(self, element):
+ return element['id']
+
+ def get_current_speed(self):
+ try:
+ loc = fanloc[0].get("location", "")
+ sped = get_sysfs_value(loc)
+ value = strtoint(sped)
+ return value
+ except Exception as e:
+ fanerror("%%policy: get current speedlevel error")
+ fanerror(str(e))
+ return None
+
+ # lower than the latest after speed regulation is the lowest
+ def check_current_speed_set(self):
+ fanwarningdebuglog(DEBUG_FANCONTROL, "%%policy: lowest rpm regulation")
+ value = self.get_current_speed()
+ if value is None or value == 0:
+ raise Exception("%%policy: get current speed None")
+ elif value < MONITOR_CONST.MIN_SPEED:
+ self.fan_speed_set(MONITOR_CONST.MIN_SPEED)
+
+ def fan_speed_set(self, level):
+ if level >= MONITOR_CONST.MAX_SPEED:
+ level = MONITOR_CONST.MAX_SPEED
+ for item in fanloc:
+ try:
+ loc = item.get("location", "")
+ write_sysfs_value(loc, "0x%02x" % level)
+ except Exception as e:
+ fanerror(str(e))
+ fanerror("%%policy: config fan run level error")
+ self.check_current_speed_set() # make sure current is the lowest speed
+
+ def fan_speed_set_max(self):
+ try:
+ self.fan_speed_set(MONITOR_CONST.MAX_SPEED)
+ except Exception as e:
+ fanerror("%%policy:fanSpeedSetMax failed")
+ fanerror(str(e))
+
+ def fan_status_check(self): # if any errors are detected, turn the fan into the highest speed
+ if self.fan_ok_num < MONITOR_CONST.FAN_TOTAL_NUM:
+ fanwarninglog("%%FANCONTRL-FAILED_NORMALFAN_NUM : %d" %
+ (self.fan_ok_num))
+ self.fan_speed_set_max()
+ return False
+ return True
+
+ def get_cpu_temp(self, cputemp):
+ for i, item in enumerate(cputemp):
+ if item["name"] == "Physical id 0":
+ self._cputemp = float(item["temp"])
+ fanwarningdebuglog(DEBUG_COMMON, "cputemp:%f" % self._cputemp)
+
+ def get_cpu_status(self):
+ try:
+ cputemp = []
+ status.getcputemp(cputemp)
+ self.get_cpu_temp(cputemp)
+ fanwarningdebuglog(DEBUG_COMMON, "%%policy:getCpuStatus success")
+ return 0
+ except AttributeError as e:
+ fanerror(str(e))
+ except Exception as e:
+ fanerror(str(e))
+ return -1
+
+ def set_fan_attr(self, val):
+ """set the state of each fan"""
+ for item in val:
+ fanid = item.get("id")
+ fanattr = fanid + "status"
+ fanstatus = item.get("errmsg")
+ setattr(FanControl, fanattr, fanstatus)
+ fanwarningdebuglog(DEBUG_COMMON,
+ "fanattr:%s,fanstatus:%s" % (fanattr, fanstatus))
+
+ def get_fan_present_num(self, cur_fan_status):
+ fanoknum = 0
+ for i, item in enumerate(cur_fan_status):
+ if item["errcode"] == 0:
+ fanoknum += 1
+ self._fan_ok_num = fanoknum
+ fanwarningdebuglog(DEBUG_COMMON, "fanOKNum = %d" % self._fan_ok_num)
+
+ def get_fan_status(self):
+ try:
+ cur_fan_status = []
+ status.checkFan(cur_fan_status)
+ cur_fan_status.sort(key=self.sort_callback)
+ self.set_fan_attr(cur_fan_status)
+ self.get_fan_present_num(cur_fan_status)
+ fanwarningdebuglog(DEBUG_COMMON, "%%policy:getFanStatus success")
+ return 0
+ except AttributeError as e:
+ fanerror(str(e))
+ except Exception as e:
+ fanerror(str(e))
+ return -1
+
+ def get_psu_ok_num(self, cur_psu_status):
+ psuoknum = 0
+ for i, item in enumerate(cur_psu_status):
+ if item["errcode"] == 0:
+ psuoknum += 1
+ self._psu_ok_num = psuoknum
+ fanwarningdebuglog(DEBUG_COMMON, "psuOKNum = %d" % self._psu_ok_num)
+
+ def get_psu_status(self):
+ try:
+ cur_psu_status = []
+ status.getPsu(cur_psu_status)
+ cur_psu_status.sort(key=self.sort_callback)
+ self.get_psu_ok_num(cur_psu_status)
+ fanwarningdebuglog(DEBUG_COMMON, "%%policy:getPsuStatus success")
+ return 0
+ except AttributeError as e:
+ fanerror(str(e))
+ except Exception as e:
+ fanerror(str(e))
+ return -1
+
+ def get_monitor_intemp(self, temp):
+ for i, item in enumerate(temp):
+ if item["id"] == "lm75in":
+ self._intemp = float(item["temp1_input"])
+ if item["id"] == "lm75out":
+ self._outtemp = float(item["temp1_input"])
+ if item["id"] == "lm75hot":
+ self._boardtemp = float(item["temp1_input"])
+ fanwarningdebuglog(
+ DEBUG_COMMON, "intemp:%f, outtemp:%f, boadrtemp:%f" %
+ (self._intemp, self._outtemp, self._boardtemp))
+
+ def get_temp_status(self):
+ try:
+ monitortemp = []
+ status.getTemp(monitortemp)
+ monitortemp.sort(key=self.sort_callback)
+ self.get_monitor_intemp(monitortemp)
+ fanwarningdebuglog(DEBUG_COMMON, "%%policy:getTempStatus success")
+ return 0
+ except AttributeError as e:
+ fanerror(str(e))
+ except Exception as e:
+ fanerror(str(e))
+ return -1
+
+ def get_mac_status(self):
+ try:
+ sta, ret = get_MAC_temp()
+ if sta == True:
+ self._mac_aver = float(ret["average"])
+ self._mac_max = float(ret["maximum"])
+ fanwarningdebuglog(DEBUG_COMMON,
+ "mac_aver:%f, mac_max:%f" % (self.mac_aver, self._mac_max))
+ else:
+ fanwarningdebuglog(DEBUG_COMMON, "%%policy:getMacStatus failed")
+ return 0
+ except AttributeError as e:
+ fanerror(str(e))
+ return -1
+
+ def set_slot_attr(self, val):
+ """set line-card state"""
+ for item in val:
+ slotid = item.get("id")
+ slotattr = slotid + "status"
+ slotstatus = item.get("errmsg")
+ setattr(FanControl, slotattr, slotstatus)
+ fanwarningdebuglog(DEBUG_COMMON,
+ "slotattr:%s,slotstatus:%s" % (slotattr, slotstatus))
+
+ def get_slot_status(self):
+ try:
+ cur_slot_status = []
+ if hasattr(status, 'checkSlot'):
+ status.checkSlot(cur_slot_status)
+ cur_slot_status.sort(key=self.sort_callback)
+ self.set_slot_attr(cur_slot_status)
+ fanwarningdebuglog(DEBUG_COMMON, "%%policy:getSlotStatus success")
+ else:
+ pass
+ except AttributeError as e:
+ fanerror(str(e))
+ return 0
+
+ def fanctrol(self):
+ try:
+ if self.pre_intemp <= -1000:
+ self.pre_intemp = self.intemp
+ fanwarningdebuglog(DEBUG_FANCONTROL,
+ "%%policy:previous temp [%.2f] , current temp [%.2f]" % (self.pre_intemp, self.intemp))
+ if self.intemp < MONITOR_CONST.TEMP_MIN:
+ fanwarningdebuglog(DEBUG_FANCONTROL,
+ "%%policy:inlet %.2f min temp: %.2f" % (self.intemp, MONITOR_CONST.TEMP_MIN))
+ self.fan_speed_set(MONITOR_CONST.DEFAULT_SPEED)
+ elif self.intemp >= MONITOR_CONST.TEMP_MIN and self.intemp > self.pre_intemp:
+ fanwarningdebuglog(DEBUG_FANCONTROL, "%%policy: temp rised")
+ self.policy_speed(self.intemp)
+ elif self.intemp >= MONITOR_CONST.TEMP_MIN and ( self.pre_intemp - self.intemp) > MONITOR_CONST.MONITOR_FALL_TEMP:
+ fanwarningdebuglog(DEBUG_FANCONTROL,
+ "%%policy: temp drops by more then %d degrees" % MONITOR_CONST.MONITOR_FALL_TEMP)
+ self.policy_speed(self.intemp)
+ pass
+ else:
+ speed = self.get_current_speed() # feed watchdog with current rpm
+ if speed is not None:
+ self.fan_speed_set(speed)
+ fanwarningdebuglog(DEBUG_FANCONTROL, "%%policy: nothing changed")
+ except Exception as e:
+ fanerror("%%policy: fancontrol error")
+
+ def start_fan_ctrol(self):
+ if self.fan_status_check() == True:
+ self.check_dev_error()
+ self.check_crit()
+ if self.critnum == 0:
+ if self.check_warning() == False:
+ self.fanctrol()
+ fanwarningdebuglog(DEBUG_FANCONTROL,
+ "%%policy: speed regulated: %0x" % (self.get_current_speed()))
+
+ def policy_speed(self, temp): # policy of fan regulation
+ fanwarningdebuglog(DEBUG_FANCONTROL, "%%policy: speed regulate with formula")
+ sped_level = MONITOR_CONST.DEFAULT_SPEED + MONITOR_CONST.K * (temp - MONITOR_CONST.TEMP_MIN)
+ self.fan_speed_set(sped_level)
+ self.pre_intemp = self.intemp
+
+ def get_board_monitor_msg(self, ledcontrol=False):
+ ret_t = 0
+ try:
+ ret_t += self.get_fan_status() # number of fans in normal status
+ ret_t += self.get_temp_status() # inlet, outlet and highest temperatures
+ ret_t += self.get_cpu_status() # CPU's temperature
+ ret_t += self.get_mac_status() # MAC's highest & avg temperatures
+ if ledcontrol == True:
+ ret_t += self.get_slot_status() # line-card state
+ ret_t += self.get_psu_status() # numbers of psu
+ if ret_t == 0:
+ return True
+ except Exception as e:
+ fanerror(str(e))
+ return False
+
+ # error policy Tmac-Tin≥50℃ or Tmac-Tin≤-50℃
+ def check_dev_error(self):
+ try:
+ if (self.mac_aver - self.intemp) >= MONITOR_CONST.MAC_UP_TEMP \
+ or (self.mac_aver - self.intemp) <= MONITOR_CONST.MAC_LOWER_TEMP:
+ fanwarninglog("%%FANCONTRL-0-MAC_TEMP_ERROR: %.2f %.2f" %
+ (self.mac_aver, self.intemp))
+ value = self.get_current_speed()
+ if MONITOR_CONST.MAC_ERROR_SPEED >= value:
+ self.fan_speed_set(MONITOR_CONST.MAC_ERROR_SPEED)
+ else:
+ self.fan_speed_set_max()
+ pass
+ else:
+ pass
+ except Exception as e:
+ fanerror("%%policy: checkDevError failed")
+ fanerror(str(e))
+
+ def check_temp_warn(self):
+ """exceeded the normal threshold"""
+ try:
+ if self._mac_aver >= MONITOR_CONST.MAC_WARNING_THRESHOLD \
+ or self._outtemp >= MONITOR_CONST.OUTTEMP_WARNING_THRESHOLD \
+ or self._boardtemp >= MONITOR_CONST.BOARDTEMP_WARNING_THRESHOLD \
+ or self._cputemp>=MONITOR_CONST.CPUTEMP_WARNING_THRESHOLD \
+ or self._intemp >=MONITOR_CONST.INTEMP_WARNING_THRESHOLD:
+ fanwarningdebuglog(DEBUG_COMMON, "temp alarm: normal")
+ return True
+ except Exception as e:
+ fanerror("%%policy: checkTempWarning failed")
+ fanerror(str(e))
+ return False
+
+ def check_temp_crit(self):
+ """exceeded the critical threshold"""
+ try:
+ if self._mac_aver >= MONITOR_CONST.MAC_CRITICAL_THRESHOLD \
+ or ( self._outtemp >= MONITOR_CONST.OUTTEMP_CRITICAL_THRESHOLD \
+ and self._boardtemp >= MONITOR_CONST.BOARDTEMP_CRITICAL_THRESHOLD \
+ and self._cputemp>= MONITOR_CONST.CPUTEMP_CRITICAL_THRESHOLD \
+ and self._intemp >= MONITOR_CONST.INTEMP_CRITICAL_THRESHOLD):
+ fanwarningdebuglog(DEBUG_COMMON, "temp alarm: critical")
+ return True
+ except Exception as e:
+ fanerror("%%policy: checkTempCrit failed")
+ fanerror(str(e))
+ return False
+
+ def check_fan_status(self):
+ for item in MONITOR_FAN_STATUS:
+ maxoknum = item.get('maxOkNum')
+ minoknum = item.get('minOkNum')
+ status = item.get('status')
+ if self.fan_ok_num >= minoknum and self.fan_ok_num <= maxoknum:
+ fanwarningdebuglog(
+ DEBUG_COMMON, "checkFanStatus:fanOKNum:%d,status:%s" %
+ (self.fan_ok_num, status))
+ return status
+ fanwarningdebuglog(DEBUG_COMMON,
+ "checkFanStatus Error:fanOKNum:%d" % (self.fan_ok_num))
+ return None
+
+ def check_psu_status(self):
+ for item in MONITOR_PSU_STATUS:
+ maxoknum = item.get('maxOkNum')
+ minoknum = item.get('minOkNum')
+ status = item.get('status')
+ if self.psu_ok_num >= minoknum and self.psu_ok_num <= maxoknum:
+ fanwarningdebuglog(
+ DEBUG_COMMON, "checkPsuStatus:psuOKNum:%d,status:%s" %
+ (self.psu_ok_num, status))
+ return status
+ fanwarningdebuglog(DEBUG_COMMON,
+ "checkPsuStatus Error:psuOKNum:%d" % (self.psu_ok_num))
+ return None
+
+ def deal_sys_led_status(self):
+ """set sys led with temperature, fans and psu status"""
+ try:
+ fanstatus = self.check_fan_status()
+ psustatus = self.check_psu_status()
+ if self.check_temp_crit() == True \
+ or fanstatus == "red" \
+ or psustatus == "red":
+ status = "red"
+ elif self.check_temp_warn() == True \
+ or fanstatus == "yellow" \
+ or psustatus == "yellow":
+ status = "yellow"
+ else:
+ status = "green"
+ self.set_sys_led(status)
+ fanwarningdebuglog(DEBUG_LEDCONTROL,
+ "%%ledcontrol:dealSysLedStatus success, status:%s," % status)
+ except Exception as e:
+ fanerror(str(e))
+
+ def deal_sys_fan_led_status(self):
+ """set sys fans led"""
+ try:
+ status = self.check_fan_status()
+ if status is not None:
+ self.set_sys_fan_led(status)
+ fanwarningdebuglog(DEBUG_LEDCONTROL,
+ "%%ledcontrol:dealSysFanLedStatus success, status:%s," % status)
+ except Exception as e:
+ fanerror("%%ledcontrol:dealSysLedStatus error")
+ fanerror(str(e))
+
+ def deal_psu_led_status(self):
+ """set psu led"""
+ try:
+ status = self.check_psu_status()
+ if status is not None:
+ self.set_sys_psu_led(status)
+ fanwarningdebuglog(DEBUG_LEDCONTROL,
+ "%%ledcontrol:dealPsuLedStatus success, status:%s," % status)
+ except Exception as e:
+ fanerror("%%ledcontrol:dealPsuLedStatus error")
+ fanerror(str(e))
+
+ def deal_loc_fan_led_status(self):
+ """set fan led"""
+ for item in MONITOR_FANS_LED:
+ try:
+ index = MONITOR_FANS_LED.index(item) + 1
+ fanattr = "fan%dstatus" % index
+ val_t = getattr(FanControl, fanattr, None)
+ if val_t == "NOT OK":
+ rji2cset(item["bus"], item["devno"], item["addr"],
+ item["red"])
+ elif val_t == "OK":
+ rji2cset(item["bus"], item["devno"], item["addr"],
+ item["green"])
+ else:
+ pass
+ fanwarningdebuglog(
+ DEBUG_LEDCONTROL,
+ "%%ledcontrol:dealLocFanLed success.fanattr:%s, status:%s" %
+ (fanattr, val_t))
+ except Exception as e:
+ fanerror("%%ledcontrol:dealLocFanLedStatus error")
+ fanerror(str(e))
+
+ def deal_slot_led_status(self):
+ """set line-card led"""
+ slot_led_list = DEV_LEDS.get("SLOTLED", [])
+ for item in slot_led_list:
+ try:
+ index = slot_led_list.index(item) + 1
+ slotattr = "slot%dstatus" % index
+ val_t = getattr(FanControl, slotattr, None)
+ if val_t == "PRESENT":
+ rji2cset(item["bus"], item["devno"], item["addr"],
+ item["green"])
+ fanwarningdebuglog(
+ DEBUG_LEDCONTROL,
+ "%%ledcontrol:dealSlotLedStatus success.slotattr:%s, status:%s"
+ % (slotattr, val_t))
+ except Exception as e:
+ fanerror("%%ledcontrol:dealSlotLedStatus error")
+ fanerror(str(e))
+
+ def deal_bmc_led_status(self, val):
+ pass
+
+ def deal_lct_led_status(self, val):
+ pass
+
+ def set_sys_led(self, color):
+ for item in MONITOR_SYS_LED:
+ if item.get('type', 'i2c') == 'sysfs':
+ rjsysset(item["cmdstr"], item.get(color))
+ else:
+ rji2cset(item["bus"], item["devno"], item["addr"],
+ item.get(color))
+
+ def set_sys_fan_led(self, color):
+ for item in MONITOR_SYS_FAN_LED:
+ if item.get('type', 'i2c') == 'sysfs':
+ rjsysset(item["cmdstr"], item.get(color))
+ else:
+ rji2cset(item["bus"], item["devno"], item["addr"],
+ item.get(color))
+
+ def set_sys_psu_led(self, color):
+ for item in MONITOR_SYS_PSU_LED:
+ if item.get('type', 'i2c') == 'sysfs':
+ rjsysset(item["cmdstr"], item.get(color))
+ else:
+ rji2cset(item["bus"], item["devno"], item["addr"],
+ item.get(color))
+
+ def check_warning(self):
+ try:
+ if self.check_temp_warn() == True:
+ fanwarningdebuglog(DEBUG_FANCONTROL, "start anti-jitter")
+ time.sleep(MONITOR_CONST.SHAKE_TIME)
+ fanwarningdebuglog(DEBUG_FANCONTROL, "stop anti-jitter")
+ self.get_board_monitor_msg() # read twice for anti-jitter
+ if self.check_temp_warn() == True:
+ fanwarninglog("%%FANCONTROL-0-SYS_WARNING")
+ self.fan_speed_set_max() # regulate the fan to max speed
+ return True
+ except Exception as e:
+ fanerror("%%policy: checkWarning failed")
+ fanerror(str(e))
+ return False
+
+ def check_crit(self):
+ try:
+ if self.check_temp_crit() == True:
+ fanwarningdebuglog(DEBUG_FANCONTROL, "start anti-jitter")
+ time.sleep(MONITOR_CONST.SHAKE_TIME)
+ fanwarningdebuglog(DEBUG_FANCONTROL, "stop anti-jitter")
+ self.get_board_monitor_msg()
+ if self.check_temp_crit() == True:
+ fancriticallog("%%FANCONTROL-0-SYS_CRIT")
+ self.fan_speed_set_max()
+ self.critnum += 1
+ if self.critnum >= MONITOR_CONST.CRITICAL_NUM:
+ os.system("reboot")
+ fanwarningdebuglog(DEBUG_FANCONTROL, "crit num:%d" % self.critnum)
+ else:
+ self.critnum = 0
+ else:
+ self.critnum = 0
+ except Exception as e:
+ fanerror("%%policy: checkCrit failed")
+ fanerror(str(e))
+
+
+def callback():
+ pass
+
+
+def do_fan_ctrol(fanctrol):
+ ret = fanctrol.get_board_monitor_msg()
+ if ret == True:
+ fanwarningdebuglog(DEBUG_FANCONTROL, "%%policy:startFanCtrol")
+ fanctrol.start_fan_ctrol()
+ else:
+ fanctrol.fan_speed_set_max()
+ fanwarningdebuglog(DEBUG_FANCONTROL, "%%policy:getBoardMonitorMsg error")
+
+
+def do_led_ctrol(fanctrol):
+ fanctrol.get_board_monitor_msg(ledcontrol=True) # get system status
+ fanctrol.deal_sys_led_status() # turn on sys led
+ fanctrol.deal_sys_fan_led_status() # turn on sys fan led
+ fanctrol.deal_loc_fan_led_status() # turn on fan led
+ fanctrol.deal_psu_led_status() # turn on psu led
+ fanctrol.deal_slot_led_status() # turn on line-card led
+ fanwarningdebuglog(DEBUG_LEDCONTROL, "%%ledcontrol:doLedCtrol success")
+
+
+def run(interval, fanctrol):
+ loop = 0
+ while True:
+ try:
+ if loop % MONITOR_CONST.MONITOR_INTERVAL == 0: # fan regulation
+ fanwarningdebuglog(DEBUG_FANCONTROL, "%%policy:fanCtrol")
+ do_fan_ctrol(fanctrol)
+ else:
+ fanwarningdebuglog(DEBUG_LEDCONTROL, "%%ledcontrol:start ledctrol") # led control
+ do_led_ctrol(fanctrol)
+ time.sleep(interval)
+ loop += interval
+ except Exception as e:
+ traceback.print_exc()
+ fanerror(str(e))
+
+
+@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS)
+def main():
+ '''device operator'''
+ pass
+
+
+@main.command()
+def start():
+ '''start fan control'''
+ fanwarninglog("FANCTROL start")
+ fanctrol = FanControl()
+ interval = MONITOR_CONST.MONITOR_INTERVAL / 30
+ run(interval, fanctrol)
+
+
+@main.command()
+def stop():
+ '''stop fan control '''
+ fanwarninglog("stop")
+
+
+##device_i2c operation
+if __name__ == '__main__':
+ main()
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/script/ruijiecommon.py b/platform/broadcom/sonic-platform-modules-ruijie/common/script/ruijiecommon.py
new file mode 100755
index 000000000000..063c78965b91
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/script/ruijiecommon.py
@@ -0,0 +1,451 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+"""Load drivers and adapters"""
+
+fancontrol_loc = "/usr/local/bin"
+fancontrol_config_loc = "/usr/local/bin"
+
+DEVICE = "DEVICE"
+GLOBALCONFIG = "GLOBALCONFIG"
+DRIVERLISTS = "DRIVERLISTS"
+INIT_PARAM = "INIT_PARAM"
+RUIJIE_CARDID = "RUIJIE_CARDID"
+RUIJIE_PRODUCTNAME = "RUIJIE_PRODUCTNAME"
+E2_PROTECT = "E2_PROTECT"
+FAN_PROTECT = "FAN_PROTECT"
+MONITOR_CONST = "MONITOR_CONST"
+
+RUIJIE_PART_NUMBER = "RJ000001"
+RUIJIE_LABEL_REVISION = "R01"
+RUIJIE_ONIE_VERSION = "2018.02"
+RUIJIE_MAC_SIZE = 3
+RUIJIE_MANUF_NAME = "Ruijie"
+RUIJIE_MANUF_COUNTRY = "CHN"
+RUIJIE_VENDOR_NAME = "Ruijie"
+RUIJIE_DIAG_VERSION = "0.1.0.15"
+RUIJIE_SERVICE_TAG = "www.ruijie.com.cn"
+
+DEV_LEDS = {}
+MEM_SLOTS = []
+
+LOCAL_LED_CONTROL = {"CLOSE": {}, "OPEN": {}}
+FIRMWARE_TOOLS = {}
+
+STARTMODULE = {"fancontrol": 1, "avscontrol": 1}
+i2ccheck_params = {"busend": "i2c-66", "retrytime": 6}
+
+# Fan ID map
+FANS_DEF = {
+ 0x8100: "M6500-FAN-F",
+ 0x8101: "M6510-FAN-F",
+ 0x8102: "M6520-FAN-F",
+ 0x8103: "M6510-FAN-R"
+}
+
+# Fan Control Parameter
+MONITOR_TEMP_MIN = 38
+MONITOR_K = 11
+MONITOR_MAC_IN = 35
+MONITOR_DEFAULT_SPEED = 0x60
+MONITOR_MAX_SPEED = 0xFF
+MONITOR_MIN_SPEED = 0x33
+MONITOR_MAC_ERROR_SPEED = 0XBB
+MONITOR_FAN_TOTAL_NUM = 4
+MONITOR_MAC_UP_TEMP = 50
+MONITOR_MAC_LOWER_TEMP = -50
+MONITOR_MAC_MAX_TEMP = 100
+
+MONITOR_FALL_TEMP = 4
+MONITOR_MAC_WARNING_THRESHOLD = 100
+MONITOR_OUTTEMP_WARNING_THRESHOLD = 85
+MONITOR_BOARDTEMP_WARNING_THRESHOLD = 85
+MONITOR_CPUTEMP_WARNING_THRESHOLD = 85
+MONITOR_INTEMP_WARNING_THRESHOLD = 70
+
+MONITOR_MAC_CRITICAL_THRESHOLD = 105
+MONITOR_OUTTEMP_CRITICAL_THRESHOLD = 90
+MONITOR_BOARDTEMP_CRITICAL_THRESHOLD = 90
+MONITOR_CPUTEMP_CRITICAL_THRESHOLD = 100
+MONITOR_INTEMP_CRITICAL_THRESHOLD = 80
+MONITOR_CRITICAL_NUM = 3
+MONITOR_SHAKE_TIME = 20
+MONITOR_INTERVAL = 60
+
+# MAC Voltage Para
+MAC_AVS_PARAM = {
+ 0x72: 0x0384,
+ 0x73: 0x037e,
+ 0x74: 0x0378,
+ 0x75: 0x0372,
+ 0x76: 0x036b,
+ 0x77: 0x0365,
+ 0x78: 0x035f,
+ 0x79: 0x0359,
+ 0x7a: 0x0352,
+ 0x7b: 0x034c,
+ 0x7c: 0x0346,
+ 0x7d: 0x0340,
+ 0x7e: 0x0339,
+ 0x7f: 0x0333,
+ 0x80: 0x032d,
+ 0x81: 0x0327,
+ 0x82: 0x0320,
+ 0x83: 0x031a,
+ 0x84: 0x0314,
+ 0x85: 0x030e,
+ 0x86: 0x0307,
+ 0x87: 0x0301,
+ 0x88: 0x02fb,
+ 0x89: 0x02f5,
+ 0x8A: 0x02ee
+}
+
+MAC_DEFAULT_PARAM = {
+ "type": 1,
+ "default": 0x74,
+ "loopaddr": 0x00,
+ "loop": 0x00,
+ "open": 0x00,
+ "close": 0x40,
+ "bus": 2,
+ "devno": 0x60,
+ "addr": 0x21,
+ "protectaddr": 0x10,
+ "sdkreg": "DMU_PCU_OTP_CONFIG_8",
+ "sdktype": 1,
+ "macregloc": 24,
+ "mask": 0xff
+}
+
+MONITOR_SYS_LED = [{
+ "bus": 2,
+ "devno": 0x33,
+ "addr": 0xb2,
+ "yellow": 0x06,
+ "red": 0x02,
+ "green": 0x04
+}, {
+ "bus": 2,
+ "devno": 0x32,
+ "addr": 0x72,
+ "yellow": 0x06,
+ "red": 0x02,
+ "green": 0x04
+}]
+
+MONITOR_SYS_FAN_LED = [
+ {
+ "bus": 2,
+ "devno": 0x33,
+ "addr": 0xb4,
+ "yellow": 0x06,
+ "red": 0x02,
+ "green": 0x04
+ },
+]
+
+MONITOR_FANS_LED = [{
+ "bus": 2,
+ "devno": 0x32,
+ "addr": 0x23,
+ "green": 0x09,
+ "red": 0x0a
+}, {
+ "bus": 2,
+ "devno": 0x32,
+ "addr": 0x24,
+ "green": 0x09,
+ "red": 0x0a
+}, {
+ "bus": 2,
+ "devno": 0x32,
+ "addr": 0x25,
+ "green": 0x09,
+ "red": 0x0a
+}, {
+ "bus": 2,
+ "devno": 0x32,
+ "addr": 0x26,
+ "green": 0x09,
+ "red": 0x0a
+}]
+
+MONITOR_SYS_PSU_LED = [
+ {
+ "bus": 2,
+ "devno": 0x33,
+ "addr": 0xb3,
+ "yellow": 0x06,
+ "red": 0x02,
+ "green": 0x04
+ },
+]
+
+MONITOR_FAN_STATUS = [
+ {
+ 'status': 'green',
+ 'minOkNum': 4,
+ 'maxOkNum': 4
+ },
+ {
+ 'status': 'yellow',
+ 'minOkNum': 3,
+ 'maxOkNum': 3
+ },
+ {
+ 'status': 'red',
+ 'minOkNum': 0,
+ 'maxOkNum': 2
+ },
+]
+
+MONITOR_PSU_STATUS = [
+ {
+ 'status': 'green',
+ 'minOkNum': 2,
+ 'maxOkNum': 2
+ },
+ {
+ 'status': 'yellow',
+ 'minOkNum': 1,
+ 'maxOkNum': 1
+ },
+ {
+ 'status': 'red',
+ 'minOkNum': 0,
+ 'maxOkNum': 0
+ },
+]
+
+fanloc = {"name": "fanset", "location": "0-0032/fan_speed_set"}
+
+"""
+Product Adapter Area
+for RUIJIE_COMMON platform
+"""
+PCA9548START = 11
+PCA9548BUSEND = 74
+
+RUIJIE_CARDID = 0x00004040
+RUIJIE_PRODUCTNAME = "ruijie_b6510"
+
+FAN_PROTECT = {
+ "bus": 0,
+ "devno": 0x32,
+ "addr": 0x19,
+ "open": 0x00,
+ "close": 0x0f
+}
+rg_eeprom = "2-0057/eeprom"
+E2_LOC = {"bus": 2, "devno": 0x57}
+E2_PROTECT = {"bus": 2, "devno": 0x33, "addr": 0xb0, "open": 0, "close": 1}
+
+INIT_PARAM = [{
+ "loc": "1-0034/sfp_enable",
+ "value": "01"
+}, {
+ "loc": "2-0035/sfp_enable2",
+ "value": "ff"
+}, {
+ "loc": "2-0033/mac_led",
+ "value": "ff"
+}, {
+ "loc": "1-0034/sfp_txdis1",
+ "value": "00"
+}, {
+ "loc": "1-0034/sfp_txdis2",
+ "value": "00"
+}, {
+ "loc": "1-0034/sfp_txdis3",
+ "value": "00"
+}, {
+ "loc": "1-0036/sfp_txdis4",
+ "value": "00"
+}, {
+ "loc": "1-0036/sfp_txdis5",
+ "value": "00"
+}, {
+ "loc": "1-0036/sfp_txdis6",
+ "value": "00"
+}, {
+ "loc": fanloc["location"],
+ "value": "80"
+}]
+
+INIT_COMMAND = []
+
+CPLDVERSIONS = [{
+ "loc": "2-0033/cpld_version",
+ "des": "MAC CPLDA"
+}, {
+ "loc": "2-0035/cpld_version",
+ "des": "MAC CPLDB"
+}, {
+ "loc": "2-0037/cpld_version",
+ "des": "CPU cpld"
+}]
+
+DRIVERLISTS = [
+ "i2c_dev",
+ "i2c_algo_bit",
+ "i2c_gpio",
+ "i2c_mux",
+ "i2c_mux_pca9641",
+ "i2c_mux_pca954x",
+ "eeprom",
+ "at24",
+ "rg_sff",
+ "ruijie_platform",
+ "rg_avs",
+ "rg_cpld",
+ "rg_fan",
+ "rg_psu",
+ "csu550",
+ "rg_gpio_xeon",
+]
+
+DEVICE = [
+ {
+ "name": "pca9641",
+ "bus": 0,
+ "loc": 0x10
+ },
+ {
+ "name": "pca9548",
+ "bus": 2,
+ "loc": 0x70
+ },
+ {
+ "name": "lm75",
+ "bus": 2,
+ "loc": 0x48
+ },
+ {
+ "name": "lm75",
+ "bus": 2,
+ "loc": 0x49
+ },
+ {
+ "name": "lm75",
+ "bus": 2,
+ "loc": 0x4a
+ },
+ {
+ "name": "24c02",
+ "bus": 2,
+ "loc": 0x57
+ },
+ {
+ "name": "rg_cpld",
+ "bus": 2,
+ "loc": 0x33
+ },
+ {
+ "name": "rg_cpld",
+ "bus": 2,
+ "loc": 0x35
+ },
+ {
+ "name": "rg_cpld",
+ "bus": 2,
+ "loc": 0x37
+ },
+ {
+ "name": "rg_avs",
+ "bus": 2,
+ "loc": 0x60
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x70
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x71
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x72
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x73
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x74
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x75
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x76
+ },
+ {
+ "name": "pca9548",
+ "bus": 1,
+ "loc": 0x77
+ },
+ {
+ "name": "rg_fan",
+ "bus": 3,
+ "loc": 0x53
+ },
+ {
+ "name": "rg_fan",
+ "bus": 4,
+ "loc": 0x53
+ },
+ {
+ "name": "rg_fan",
+ "bus": 5,
+ "loc": 0x53
+ },
+ {
+ "name": "rg_psu",
+ "bus": 7,
+ "loc": 0x50
+ },
+ {
+ "name": "csu550",
+ "bus": 7,
+ "loc": 0x58
+ },
+ {
+ "name": "rg_psu",
+ "bus": 8,
+ "loc": 0x53
+ },
+ {
+ "name": "csu550",
+ "bus": 8,
+ "loc": 0x5b
+ },
+]
+
+# FRU info adapter
+E2TYPE = {
+ "1": "tlveeprom",
+ "2": "x86cpueeprom",
+ "3": "bmceeprom",
+ "4": "cpueeprom",
+ "5": "maceeprom",
+ "6": "sloteeprom",
+ "7": "fanconnecteeprom",
+ "8": "M1HFANI-F",
+ "9": "M1HFANI-R",
+ "A": "M2HFANI-F",
+ "B": "M2HFANI-R",
+ "C": "psu"
+}
+FRULISTS = []
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/script/ruijieconfig.py b/platform/broadcom/sonic-platform-modules-ruijie/common/script/ruijieconfig.py
new file mode 100755
index 000000000000..ee0475eb27fc
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/script/ruijieconfig.py
@@ -0,0 +1,147 @@
+#!/usr/bin/python
+# -*- coding: UTF-8 -*-
+
+import sys
+import os
+import commands
+import time
+from sonic_platform import get_machine_info
+from sonic_platform import get_platform_info
+import binascii
+import termios
+import multiprocessing
+
+
+def getdeviceplatform():
+ x = get_platform_info(get_machine_info())
+ if x != None:
+ filepath = "/usr/share/sonic/device/" + x
+ return filepath
+
+
+platform = get_platform_info(get_machine_info())
+platformpath = getdeviceplatform()
+MAILBOX_DIR = "/sys/bus/i2c/devices/"
+grtd_productfile = (platform + "_config").replace("-", "_")
+common_productfile = "ruijiecommon"
+configfile_pre = "/usr/local/bin/"
+import sys
+sys.path.append(platformpath)
+sys.path.append(configfile_pre)
+
+
+def get_rjconfig_info(attr_key):
+ rjconf_filename = platformpath + "/plugins" + "/rj.conf"
+ if not os.path.isfile(rjconf_filename):
+ return None
+ with open(rjconf_filename) as rjconf_file:
+ for line in rjconf_file:
+ tokens = line.split('=')
+ if len(tokens) < 2:
+ continue
+ if tokens[0] == attr_key:
+ return tokens[1].strip()
+ return None
+
+
+# load configuration
+global module_product
+if os.path.exists(configfile_pre + grtd_productfile + ".py"):
+ module_product = __import__(grtd_productfile, globals(), locals(), [], -1)
+elif os.path.exists(configfile_pre + common_productfile + ".py"):
+ module_product = __import__(common_productfile, globals(), locals(), [], -1)
+else:
+ print "configuration file does not exist"
+ exit(-1)
+
+
+DEVICE = module_product.DEVICE
+
+RUIJIE_GLOBALCONFIG = {
+ "DRIVERLISTS": module_product.DRIVERLISTS,
+ "DEVS": DEVICE
+}
+
+GLOBALCONFIG = RUIJIE_GLOBALCONFIG
+GLOBALINITPARAM = module_product.INIT_PARAM
+GLOBALINITCOMMAND = module_product.INIT_COMMAND
+
+fancontrol_loc = module_product.fancontrol_loc
+fancontrol_config_loc = module_product.fancontrol_config_loc
+
+STARTMODULE = module_product.STARTMODULE
+FIRMWARE_TOOLS = module_product.FIRMWARE_TOOLS
+
+fanloc = module_product.fanloc
+fanlevel = module_product.fanlevel
+CPLDVERSIONS = module_product.CPLDVERSIONS
+RUIJIE_CARDID = module_product.RUIJIE_CARDID
+RUIJIE_PRODUCTNAME = module_product.RUIJIE_PRODUCTNAME
+
+RUIJIE_PART_NUMBER = module_product.RUIJIE_PART_NUMBER
+RUIJIE_LABEL_REVISION = module_product.RUIJIE_LABEL_REVISION
+RUIJIE_ONIE_VERSION = module_product.RUIJIE_ONIE_VERSION
+RUIJIE_MAC_SIZE = module_product.RUIJIE_MAC_SIZE
+RUIJIE_MANUF_NAME = module_product.RUIJIE_MANUF_NAME
+RUIJIE_MANUF_COUNTRY = module_product.RUIJIE_MANUF_COUNTRY
+RUIJIE_VENDOR_NAME = module_product.RUIJIE_VENDOR_NAME
+RUIJIE_DIAG_VERSION = module_product.RUIJIE_DIAG_VERSION
+RUIJIE_SERVICE_TAG = module_product.RUIJIE_SERVICE_TAG
+
+E2_PROTECT = module_product.E2_PROTECT
+E2_LOC = module_product.E2_LOC
+FAN_PROTECT = module_product.FAN_PROTECT
+
+FANS_DEF = module_product.FANS_DEF
+MONITOR_SYS_LED = module_product.MONITOR_SYS_LED
+MONITOR_FANS_LED = module_product.MONITOR_FANS_LED
+MONITOR_SYS_FAN_LED = module_product.MONITOR_SYS_FAN_LED
+MONITOR_SYS_PSU_LED = module_product.MONITOR_SYS_PSU_LED
+MONITOR_FAN_STATUS = module_product.MONITOR_FAN_STATUS
+MONITOR_PSU_STATUS = module_product.MONITOR_PSU_STATUS
+
+DEV_LEDS = module_product.DEV_LEDS
+MEM_SLOTS = module_product.MEM_SLOTS
+
+MAC_AVS_PARAM = module_product.MAC_AVS_PARAM
+MAC_DEFAULT_PARAM = module_product.MAC_DEFAULT_PARAM
+E2TYPE = module_product.E2TYPE
+FRULISTS = module_product.FRULISTS
+rg_eeprom = "%d-%04x/eeprom" % (E2_LOC["bus"], E2_LOC["devno"])
+
+LOCAL_LED_CONTROL = module_product.LOCAL_LED_CONTROL
+
+i2ccheck_params = module_product.i2ccheck_params
+
+
+class MONITOR_CONST:
+ TEMP_MIN = module_product.MONITOR_TEMP_MIN
+ K = module_product.MONITOR_K
+ MAC_IN = module_product.MONITOR_MAC_IN
+ DEFAULT_SPEED = module_product.MONITOR_DEFAULT_SPEED
+ MAX_SPEED = module_product.MONITOR_MAX_SPEED
+ MIN_SPEED = module_product.MONITOR_MIN_SPEED
+ MAC_ERROR_SPEED = module_product.MONITOR_MAC_ERROR_SPEED
+ FAN_TOTAL_NUM = module_product.MONITOR_FAN_TOTAL_NUM
+ MAC_UP_TEMP = module_product.MONITOR_MAC_UP_TEMP
+ MAC_LOWER_TEMP = module_product.MONITOR_MAC_LOWER_TEMP
+ MAC_MAX_TEMP = module_product.MONITOR_MAC_MAX_TEMP
+
+ MAC_WARNING_THRESHOLD = module_product.MONITOR_MAC_WARNING_THRESHOLD
+ OUTTEMP_WARNING_THRESHOLD = module_product.MONITOR_OUTTEMP_WARNING_THRESHOLD
+ BOARDTEMP_WARNING_THRESHOLD = module_product.MONITOR_BOARDTEMP_WARNING_THRESHOLD
+ CPUTEMP_WARNING_THRESHOLD = module_product.MONITOR_CPUTEMP_WARNING_THRESHOLD
+ INTEMP_WARNING_THRESHOLD = module_product.MONITOR_INTEMP_WARNING_THRESHOLD
+
+ MAC_CRITICAL_THRESHOLD = module_product.MONITOR_MAC_CRITICAL_THRESHOLD
+ OUTTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_OUTTEMP_CRITICAL_THRESHOLD
+ BOARDTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_BOARDTEMP_CRITICAL_THRESHOLD
+ CPUTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_CPUTEMP_CRITICAL_THRESHOLD
+ INTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_INTEMP_CRITICAL_THRESHOLD
+ CRITICAL_NUM = module_product.MONITOR_CRITICAL_NUM
+ SHAKE_TIME = module_product.MONITOR_SHAKE_TIME
+ MONITOR_INTERVAL = module_product.MONITOR_INTERVAL
+ MONITOR_FALL_TEMP = module_product.MONITOR_FALL_TEMP
+
+
+FANCTROLDEBUG = 0
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/script/ruijieutil.py b/platform/broadcom/sonic-platform-modules-ruijie/common/script/ruijieutil.py
new file mode 100755
index 000000000000..fdeae8c03054
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/script/ruijieutil.py
@@ -0,0 +1,1666 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import sys
+import os
+import re
+import commands
+import syslog
+import time
+import binascii
+import tty
+import termios
+import threading
+import click
+from ruijieconfig import *
+from tabulate import tabulate
+import readline
+try:
+ from eepromutil.fru import *
+except:
+ pass
+
+MENUID = "menuid"
+MENUPARENT = "parentid"
+MENUVALUE = "value"
+CHILDID = "childid"
+MENUITEMNAME = "name"
+MENUITEMDEAL = "deal"
+GOBACK = "goBack"
+GOQUIT = "quit"
+
+file_name = "/etc/init.d/opennsl-modules-3.16.0-5-amd64"
+
+# Log Level
+CRITICAL = 50
+FATAL = CRITICAL
+ERROR = 40
+WARNING = 30
+WARN = WARNING
+INFO = 20
+DEBUG = 10
+NOTSET = 0
+
+TLV_INFO_ID_STRING = "TlvInfo\x00"
+TLV_INFO_VERSION = 0x01
+TLV_INFO_LENGTH = 0x00
+TLV_INFO_LENGTH_VALUE = 0xba
+
+# ONIE EEPROM TLV TYPE
+TLV_CODE_PRODUCT_NAME = 0x21
+TLV_CODE_PART_NUMBER = 0x22
+TLV_CODE_SERIAL_NUMBER = 0x23
+TLV_CODE_MAC_BASE = 0x24
+TLV_CODE_MANUF_DATE = 0x25
+TLV_CODE_DEVICE_VERSION = 0x26
+TLV_CODE_LABEL_REVISION = 0x27
+TLV_CODE_PLATFORM_NAME = 0x28
+TLV_CODE_ONIE_VERSION = 0x29
+TLV_CODE_MAC_SIZE = 0x2A
+TLV_CODE_MANUF_NAME = 0x2B
+TLV_CODE_MANUF_COUNTRY = 0x2C
+TLV_CODE_VENDOR_NAME = 0x2D
+TLV_CODE_DIAG_VERSION = 0x2E
+TLV_CODE_SERVICE_TAG = 0x2F
+TLV_CODE_VENDOR_EXT = 0xFD
+TLV_CODE_CRC_32 = 0xFE
+_TLV_DISPLAY_VENDOR_EXT = 1
+TLV_CODE_RJ_CARID = 0x01
+_TLV_INFO_HDR_LEN = 11
+
+SYSLOG_IDENTIFIER = "UTILTOOL"
+
+# print wrapper, compatible with python2 and python3
+def rprint(*args):
+ print(" ".join(map(str,args)))
+
+# Syslog wrappers
+def log_info(msg, also_print_to_console=False):
+ # msg = msg.decode('utf-8').encode('gb2312')
+ syslog.openlog(SYSLOG_IDENTIFIER)
+ syslog.syslog(syslog.LOG_INFO, msg)
+ syslog.closelog()
+
+ if also_print_to_console:
+ click.echo(msg)
+
+
+def log_debug(msg, also_print_to_console=False):
+ try:
+ # msg = msg.decode('utf-8').encode('gb2312')
+ syslog.openlog(SYSLOG_IDENTIFIER)
+ syslog.syslog(syslog.LOG_DEBUG, msg)
+ syslog.closelog()
+
+ if also_print_to_console:
+ click.echo(msg)
+ except Exception as e:
+ pass
+
+
+def log_warning(msg, also_print_to_console=False):
+ # msg = msg.decode('utf-8').encode('gb2312')
+ syslog.openlog(SYSLOG_IDENTIFIER)
+ syslog.syslog(syslog.LOG_WARNING, msg)
+ syslog.closelog()
+
+ if also_print_to_console:
+ click.echo(msg)
+
+
+def log_error(msg, also_print_to_console=False):
+ #msg = msg.decode('utf-8').encode('gb2312')
+ syslog.openlog(SYSLOG_IDENTIFIER)
+ syslog.syslog(syslog.LOG_ERR, msg)
+ syslog.closelog()
+
+ if also_print_to_console:
+ click.echo(msg)
+
+
+class SetMACException(Exception):
+
+ def __init__(self, param='error', errno="-1"):
+ err = "setmac error [%s]: %s" % (errno, param)
+ Exception.__init__(self, err)
+ self.param = param
+ self.errno = errno
+
+
+def checkinput(b):
+ if b.isdigit() == False:
+ raise Exception("Illegal numbers")
+ if int(b) > 0xff or int(b) < 0:
+ raise Exception("Out of range")
+
+
+def checkinputproduct(b):
+ if b.isalnum() == False:
+ raise Exception("Illegal string")
+
+
+def get_input_setmac(val):
+ bia = val.boardInfoArea
+ pia = val.productInfoArea
+ if bia != None:
+ a = raw_input("[Board Info Area]Product SN:")
+ if len(a) != 13:
+ raise Exception("Illegal SN length")
+ checkinputproduct(a)
+ bia.boardSerialNumber = a
+ b = raw_input("[Board Info Area]Product Version:(1-255)")
+ checkinput(b)
+ b = "%0x" % int(b)
+ bia.boardextra1 = b.upper()
+ if pia != None:
+ a = raw_input("[Product Info Area]Product SN:")
+ if len(a) != 13:
+ raise Exception("Illegal SN length")
+ checkinputproduct(a)
+ pia.productSerialNumber = a
+ b = raw_input("[Product Info Area]Product Version:(1-255)")
+ checkinput(b)
+ b = "%0x" % int(b)
+ pia.productVersion = b.upper()
+ return val
+
+
+class fan_tlv():
+ VERSION = 0x01
+ FLAG = 0x7E
+ HW_VER = 0X01
+ TYPE = 0xf1
+ TLV_LEN = 00
+ _FAN_TLV_HDR_LEN = 6
+ _FAN_TLV_CRC_LEN = 2
+
+ _FAN_TLV_TYPE_NAME = 0x02
+ _FAN_TLV_TYPE_SN = 0x03
+ _FAN_TLV_TYPE_HW_INFO = 0x05
+ _FAN_TLV_TYPE_DEV_TYPE = 0x06
+
+ _fandecodetime = 0
+
+ @property
+ def dstatus(self):
+ return self._dstatus
+
+ @property
+ def typename(self):
+ return self._typename
+
+ @property
+ def typesn(self):
+ return self._typesn
+
+ @property
+ def typehwinfo(self):
+ return self._typehwinfo
+
+ @property
+ def typedevtype(self):
+ return self._typedevtype
+
+ @property
+ def fanbus(self):
+ return self._fanbus
+
+ @property
+ def fanloc(self):
+ return self._fanloc
+
+ @property
+ def fandecodetime(self):
+ return self._fandecodetime
+
+ def __init__(self):
+ self._typename = ""
+ self._typesn = ""
+ self._typehwinfo = ""
+ self._typedevtype = ""
+ self._dstatus = 0
+
+ def strtoarr(self, str):
+ s = []
+ for index in str:
+ s.append(index)
+ return s
+
+ def generate_fan_value(self):
+ bin_buffer = [chr(0xff)] * 256
+ bin_buffer[0] = chr(self.VERSION)
+ bin_buffer[1] = chr(self.FLAG)
+ bin_buffer[2] = chr(self.HW_VER)
+ bin_buffer[3] = chr(self.TYPE)
+
+ temp_t = "%08x" % self.typedevtype
+ typedevtype_t = hex_to_str(temp_t)
+ total_len = len(self.typename) + len(self.typesn) + \
+ len(self.typehwinfo) + len(typedevtype_t) + 8
+
+ bin_buffer[4] = chr(total_len >> 8)
+ bin_buffer[5] = chr(total_len & 0x00FF)
+
+ index_start = 6
+ bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_NAME)
+ bin_buffer[index_start + 1] = chr(len(self.typename))
+ bin_buffer[index_start + 2:index_start + 2 +
+ len(self.typename)] = self.strtoarr(self.typename)
+ index_start = index_start + 2 + len(self.typename)
+
+ bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_SN)
+ bin_buffer[index_start + 1] = chr(len(self.typesn))
+ bin_buffer[index_start + 2:index_start + 2 +
+ len(self.typesn)] = self.strtoarr(self.typesn)
+ index_start = index_start + 2 + len(self.typesn)
+
+ bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_HW_INFO)
+ bin_buffer[index_start + 1] = chr(len(self.typehwinfo))
+ bin_buffer[index_start + 2:index_start + 2 +
+ len(self.typehwinfo)] = self.strtoarr(self.typehwinfo)
+ index_start = index_start + 2 + len(self.typehwinfo)
+
+ bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_DEV_TYPE)
+ bin_buffer[index_start + 1] = chr(len(typedevtype_t))
+ bin_buffer[index_start + 2:index_start + 2 +
+ len(typedevtype_t)] = self.strtoarr(typedevtype_t)
+ index_start = index_start + 2 + len(typedevtype_t)
+
+ crcs = fan_tlv.fancrc(''.join(bin_buffer[0:index_start])) # 2 Byte CRC
+ bin_buffer[index_start] = chr(crcs >> 8)
+ bin_buffer[index_start + 1] = chr(crcs & 0x00ff)
+ # printvalue(bin_buffer)
+ return bin_buffer
+
+ def encode(self):
+ e = []
+
+ def decode(self, e2):
+ ret = []
+ self.VERSION = ord(e2[0])
+ self.FLAG = ord(e2[1])
+ self.HW_VER = ord(e2[2])
+ self.TYPE = ord(e2[3])
+ self.TLV_LEN = (ord(e2[4]) << 8) | ord(e2[5])
+
+ tlv_index = self._FAN_TLV_HDR_LEN
+ tlv_end = self._FAN_TLV_HDR_LEN + self.TLV_LEN
+
+ # Check
+ if len(e2) < self._FAN_TLV_HDR_LEN + self.TLV_LEN + 2:
+ self._dstatus = -2
+ return ret
+ sumcrc = fan_tlv.fancrc(e2[0:self._FAN_TLV_HDR_LEN + self.TLV_LEN])
+ readcrc = ord(e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN]) << 8 | ord(
+ e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN + 1])
+ if sumcrc != readcrc:
+ self._dstatus = -1
+ return ret
+ else:
+ self._dstatus = 0
+ while (tlv_index + 2) < len(e2) and tlv_index < tlv_end:
+ s = self.decoder(e2[tlv_index:tlv_index + 2 + ord(e2[tlv_index + 1])])
+ tlv_index += ord(e2[tlv_index + 1]) + 2
+ ret.append(s)
+
+ # calculate crc
+ sumcrc = fan_tlv.fancrc(e2[0:self._FAN_TLV_HDR_LEN + self.TLV_LEN])
+
+ return ret
+
+ @staticmethod
+ def fancrc(t):
+ sum = 0
+ for index in range(len(t)):
+ sum += ord(t[index])
+ return sum
+
+ def decoder(self, t):
+ try:
+ name = ""
+ value = ""
+ if ord(t[0]) == self._FAN_TLV_TYPE_NAME:
+ name = "Product Name"
+ value = str(t[2:2 + ord(t[1])])
+ self._typename = value
+ elif ord(t[0]) == self._FAN_TLV_TYPE_SN:
+ name = "serial Number"
+ value = str(t[2:2 + ord(t[1])])
+ self._typesn = value
+ elif ord(t[0]) == self._FAN_TLV_TYPE_HW_INFO:
+ name = "hardware info"
+ value = str(t[2:2 + ord(t[1])])
+ self._typehwinfo = value
+ elif ord(t[0]) == self._FAN_TLV_TYPE_DEV_TYPE:
+ name = "dev type"
+ value = str(t[2:2 + ord(t[1])])
+ value = str_to_hex(value)
+ self._typedevtype = value
+ value = "0x08%x" % value
+ except Exception as e:
+ rprint(e)
+ return {"name": name, "code": ord(t[0]), "value": value}
+
+ def __str__(self):
+ formatstr = "VERSION : 0x%02x \n" \
+ " FLAG : 0x%02x \n" \
+ " HW_VER : 0x%02x \n" \
+ " TYPE : 0x%02x \n" \
+ "typename : %s \n" \
+ "typesn : %s \n" \
+ "typehwinfo : %s \n"
+ return formatstr % (self.VERSION, self.FLAG, self.HW_VER, self.TYPE,
+ self.typename, self.typesn, self.typehwinfo)
+
+
+class AVSUTIL():
+
+ @staticmethod
+ def mac_avs_chip(bus, devno, loc, open, close, loop, protectaddr, level, loopaddr):
+ ret = -1
+ # disable avs protection
+ rji2cset(bus, devno, protectaddr, open)
+ rji2cset(bus, devno, loopaddr, loop)
+ rji2csetword(bus, devno, loc, level)
+ ret, value = rji2cgetword(bus, devno, loc)
+ if strtoint(value) == level:
+ ret = 0
+ # enable avs protection
+ rji2cset(bus, devno, protectaddr, close)
+ if ret == 0:
+ return True
+ return False
+
+ @staticmethod
+ def macpressure_adj(macavs, avs_param, mac_def_param):
+ max_adj = max(avs_param.keys())
+ min_adj = min(avs_param.keys())
+ type = mac_def_param["type"]
+ level = 0
+ if type == 0:
+ if macavs not in range(min_adj, max_adj + 1):
+ return False
+ else:
+ level = macavs
+ else:
+ if macavs not in range(min_adj, max_adj + 1):
+ level = mac_def_param["default"]
+ else:
+ level = macavs
+ ret = AVSUTIL.mac_avs_chip(mac_def_param["bus"],
+ mac_def_param["devno"],
+ mac_def_param["addr"],
+ mac_def_param["open"],
+ mac_def_param["close"],
+ mac_def_param["loop"],
+ mac_def_param["protectaddr"],
+ avs_param[level],
+ mac_def_param["loopaddr"])
+ return ret
+
+ @staticmethod
+ def mac_adj():
+ macavs = 0
+ name = MAC_DEFAULT_PARAM["sdkreg"]
+ ret, status = get_sdk_reg(name)
+ if ret == False:
+ return False
+ status = strtoint(status)
+ if MAC_DEFAULT_PARAM["sdktype"] != 0:
+ status = (status >> MAC_DEFAULT_PARAM["macregloc"]) & MAC_DEFAULT_PARAM["mask"]
+ macavs = status
+ ret = AVSUTIL.macpressure_adj(macavs, MAC_AVS_PARAM, MAC_DEFAULT_PARAM)
+ return ret
+
+
+class I2CUtil():
+
+ @staticmethod
+ def getvaluefromdevice(name):
+ ret = []
+ for item in DEVICE:
+ if item["name"] == name:
+ ret.append(item)
+ return ret
+
+ @staticmethod
+ def open_fan_E2_protect():
+ rji2cset(FAN_PROTECT["bus"],
+ FAN_PROTECT["devno"],
+ FAN_PROTECT["addr"],
+ FAN_PROTECT["open"])
+
+ @staticmethod
+ def close_fan_E2_protect():
+ rji2cset(FAN_PROTECT["bus"],
+ FAN_PROTECT["devno"],
+ FAN_PROTECT["addr"],
+ FAN_PROTECT["close"])
+
+ @staticmethod
+ def write_to_fan_E2(bus, loc, rst_arr):
+ index = 0
+ for item in rst_arr:
+ rji2cset(bus, loc, index, ord(item))
+ index += 1
+
+ @staticmethod
+ def write_to_E2(bus, loc, rst_arr):
+ index = 0
+ for item in rst_arr:
+ rji2cset(bus, loc, index, ord(item))
+ index += 1
+
+ @staticmethod
+ def get_E2_file(bus, loc):
+ return "/sys/bus/i2c/devices/%d-00%02x/eeprom" % (bus, loc)
+
+
+class BMC():
+ _instance_lock = threading.Lock()
+
+ def __init__(self):
+ pass
+
+ def __new__(cls, *args, **kwargs):
+ if not hasattr(Singleton, "_instance"):
+ with Singleton._instance_lock:
+ if not hasattr(Singleton, "_instance"):
+ Singleton._instance = object.__new__(cls)
+ return Singleton._instance
+
+
+def get_sdk_reg(reg):
+ try:
+ cmd = "bcmcmd 'getr %s ' < /dev/null" % reg
+ ret, result = rj_os_system(cmd)
+ result_t = result.strip().replace("\r", "").replace("\n", "")
+ if ret != 0 or "Error:" in result_t:
+ return False, result
+ patt = r"%s.(.*):(.*)>drivshell" % reg
+ rt = re.findall(patt, result_t, re.S)
+ test = re.findall("=(.*)", rt[0][0])[0]
+ except Exception as e:
+ return False, 'getsdk register error'
+ return True, test
+
+
+def getfilevalue(location):
+ try:
+ with open(location, 'r') as fd:
+ value = fd.read()
+ return True, value.strip()
+ except Exception as e:
+ return False, "error"
+
+
+def get_sysfs_value(location):
+ pos_t = str(location)
+ name = get_pmc_register(pos_t)
+ return name
+
+
+def write_sysfs_value(reg_name, value):
+ file_loc = MAILBOX_DIR + reg_name
+ try:
+ if not os.path.isfile(file_loc):
+ rprint(file_loc, 'not found !')
+ return False
+ with open(file_loc, 'w') as fd:
+ fd.write(value)
+ except Exception as error:
+ log_error("Unable to open " + file_loc + "file !")
+ return False
+ return True
+
+
+def rj_printer(str):
+ print("\033[0;31m%s\033[0m" % str)
+
+
+def strtoint(str):
+ value = 0
+ rest_v = str.replace("0X", "").replace("0x", "")
+ for index in range(len(rest_v)):
+ value |= int(rest_v[index], 16) << ((len(rest_v) - index - 1) * 4)
+ return value
+
+
+def inttostr(vl, len):
+ if type(vl) != int:
+ raise Exception(" type error")
+ index = 0
+ ret_t = ""
+ while index < len:
+ ret = 0xff & (vl >> index * 8)
+ ret_t += chr(ret)
+ index += 1
+ return ret_t
+
+
+def str_to_hex(rest_v):
+ value = 0
+ for index in range(len(rest_v)):
+ value |= ord(rest_v[index]) << ((len(rest_v) - index - 1) * 8)
+ return value
+
+
+def hex_to_str(s):
+ len_t = len(s)
+ if len_t % 2 != 0:
+ return 0
+ ret = ""
+ for t in range(0, len_t / 2):
+ ret += chr(int(s[2 * t:2 * t + 2], 16))
+ return ret
+
+
+def str_to_bin(s):
+ return ' '.join([bin(ord(c)).replace('0b', '') for c in s])
+
+
+def bin_to_str(s):
+ return ''.join([chr(i) for i in [int(b, 2) for b in s.split(' ')]])
+
+
+def get_MAC_temp():
+ result = {}
+ wait_for_docker()
+ # Do twice, get the second
+ ret, log = rj_os_system("bcmcmd \"show temp\" < /dev/null")
+ ret, log = rj_os_system("bcmcmd \"show temp\" < /dev/null")
+ if ret:
+ return False, result
+ else:
+ logs = log.splitlines()
+ for line in logs:
+ if "average" in line:
+ b = re.findall(r'\d+.\d+', line)
+ result["average"] = b[0]
+ elif "maximum" in line:
+ b = re.findall(r'\d+.\d+', line)
+ result["maximum"] = b[0]
+ return True, result
+
+
+def restart_docker_service(force=False):
+ container_name = [
+ "database",
+ "snmp",
+ "syncd",
+ "swss",
+ "dhcp_relay",
+ "radv",
+ "teamd",
+ "pmon"
+ ]
+ ret, status = rj_os_system("docker ps")
+ if ret == 0:
+ for tmpname in container_name:
+ if (tmpname not in status):
+ if (force == True):
+ rj_os_system("docker restart %s" % tmpname)
+ else:
+ rj_os_system("systemctl restart %s" % tmpname)
+
+
+def wait_for_docker(need_restart=False):
+ time_cnt = 0
+ while True:
+ try:
+ ret, status = rj_os_system("docker ps |wc -l")
+ if ret == 0 and int(status) >= 9:
+ break
+ else:
+ sys.stdout.write(".")
+ sys.stdout.flush()
+ time_cnt = time_cnt + 1
+ time.sleep(1)
+ if (need_restart == True):
+ if (time_cnt >= 120 and time_cnt % 10 == 0):
+ if (time_cnt >= 180):
+ restart_docker_service(True)
+ else:
+ restart_docker_service()
+ except Exception as e:
+ continue
+
+
+def get_TLV_body(type, productname):
+ x = []
+ temp_t = ""
+ if type == TLV_CODE_MAC_BASE:
+ arr = productname.split(':')
+ for tt in arr:
+ temp_t += chr(int(tt, 16))
+ elif type == TLV_CODE_DEVICE_VERSION:
+ temp_t = chr(productname)
+ elif type == TLV_CODE_MAC_SIZE:
+ temp_t = chr(productname >> 8) + chr(productname & 0x00ff)
+ else:
+ temp_t = productname
+ x.append(chr(type))
+ x.append(chr(len(temp_t)))
+ for i in temp_t:
+ x.append(i)
+ return x
+
+
+def _crc32(v):
+ return '0x%08x' % (binascii.crc32(v) & 0xffffffff)
+
+
+def printvalue(b):
+ index = 0
+ for i in range(0, len(b)):
+ if index % 16 == 0:
+ rprint(" ")
+ rprint("%02x " % ord(b[i]),)
+ index += 1
+ rprint("\n")
+
+
+def generate_value(_t):
+ ret = []
+ for i in TLV_INFO_ID_STRING:
+ ret.append(i)
+
+ ret.append(chr(TLV_INFO_VERSION))
+ ret.append(chr(TLV_INFO_LENGTH))
+ ret.append(chr(TLV_INFO_LENGTH_VALUE))
+
+ total_len = 0
+ for key in _t:
+ x = get_TLV_body(key, _t[key])
+ ret += x
+ total_len += len(x)
+ ret[10] = chr(total_len + 6)
+
+ ret.append(chr(0xFE))
+ ret.append(chr(0x04))
+ s = _crc32(''.join(ret))
+ for t in range(0, 4):
+ ret.append(chr(int(s[2 * t + 2:2 * t + 4], 16)))
+ totallen = len(ret)
+ if (totallen < 256):
+ for left_t in range(0, 256 - totallen):
+ ret.append(chr(0x00))
+ return (ret, True)
+
+
+def getsyseeprombyid(id):
+ ret = get_sys_eeprom()
+ for item in ret:
+ if item["code"] == id:
+ return item
+ return None
+
+
+def fac_init_cardidcheck():
+ rest = getsyseeprombyid(TLV_CODE_RJ_CARID)
+ if rest == None:
+ rprint("burn bin file firstly")
+ return False
+ else:
+ rest_v = rest['value']
+ value = strtoint(rest_v)
+ if value == RUIJIE_CARDID:
+ log_debug("checking board ID pass")
+ else:
+ log_debug("checking board ID error")
+ return False
+ return True
+
+
+def is_valid_mac(mac):
+ if re.match(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}\s*$", mac):
+ return True
+ return False
+
+
+# Net setmac
+
+
+def util_setmac(eth, mac):
+ rulefile = "/etc/udev/rules.d/70-persistent-net.rules"
+ if is_valid_mac(mac) == False:
+ return False, "Illegal MAC address"
+ cmd = "ethtool -e %s | grep 0x0010 | awk '{print \"0x\"$13$12$15$14}'" % eth
+ ret, log = rj_os_system(cmd)
+ log_debug(log)
+ magic = ""
+ if ret == 0 and len(log):
+ magic = log
+ macs = mac.upper().split(":")
+
+ ifconfigcmd = "ifconfig eth0 hw ether %s" % mac
+ log_debug(ifconfigcmd)
+ ret, status = rj_os_system(ifconfigcmd)
+ if ret:
+ raise SetMACException("Software set MAC error")
+ if ret:
+ return False
+ index = 0
+ for item in macs:
+ cmd = "ethtool -E %s magic %s offset %d value 0x%s" % (eth, magic, index, item)
+ log_debug(cmd)
+ index += 1
+ ret, log = rj_os_system(cmd)
+ if ret != 0:
+ raise SetMACException("HW set MAC error")
+ return False
+ cmd_t = "ethtool -e eth0 offset 0 length 6"
+ ret, log = rj_os_system(cmd_t)
+ m = re.split(':', log)[-1].strip().upper()
+ mac_result = m.upper().split(" ")
+
+ for ind, s in enumerate(macs):
+ if s != mac_result[ind]:
+ rj_printer("MAC is not maching")
+ if os.path.exists(rulefile):
+ os.remove(rulefile)
+ rprint("MGMT MAC【%s】" % mac)
+ return True
+
+
+def get_input_check(tips):
+ str = raw_input(tips)
+ if astrcmp(str, "y") or astrcmp(str, "ye") or astrcmp(
+ str, "yes") or astrcmp(str, ""):
+ return True
+ else:
+ return False
+
+
+def getrawch():
+ fd = sys.stdin.fileno()
+ old_settings = termios.tcgetattr(fd)
+ try:
+ tty.setraw(sys.stdin.fileno())
+ ch = sys.stdin.read(1)
+ finally:
+ termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
+ return ch
+
+
+def upper_input(tips):
+ sys.stdout.write(tips)
+ sys.stdout.flush()
+ passwd = []
+ while True:
+ ch = getrawch().upper()
+ if ch == "\r" or ch == "\n":
+ print
+ return "".join(passwd)
+ elif ch == '\b' or ord(ch) == 127:
+ if passwd:
+ del passwd[-1]
+ sys.stdout.write('\b \b')
+ else:
+ sys.stdout.write(ch)
+ passwd.append(ch)
+
+
+def change_type_value(_value, type1, tips, example):
+ if type1 == TLV_CODE_PRODUCT_NAME:
+ while True:
+ rprint("Select airflow: (1)front2back/(2)back2front:",)
+ option = raw_input()
+ if option == "1":
+ _value[type1] = example + "-F-RJ"
+ rprint("front2back device, product name: %s" % _value[type1])
+ break
+ elif option == "2":
+ _value[type1] = example + "-R-RJ"
+ rprint("back2front device, product name: %s" % _value[type1])
+ break
+ else:
+ rprint("Input error, please verify")
+ return True
+ rprint("please enter [%s] like (%s):" % (tips, example),)
+ name = upper_input("")
+ if type1 == TLV_CODE_MAC_BASE:
+ if len(name) != 12:
+ raise SetMACException("Wrong MAC address length, please recheck")
+ return False
+ release_mac = ""
+ for i in range(len(name) / 2):
+ if i == 0:
+ release_mac += name[i * 2:i * 2 + 2]
+ else:
+ release_mac += ":" + name[i * 2:i * 2 + 2]
+ if is_valid_mac(release_mac) == True:
+ _value[type1] = release_mac
+ else:
+ raise SetMACException("Illegal MAC address, please recheck")
+ return False
+ elif type1 == TLV_CODE_DEVICE_VERSION:
+ if name.isdigit():
+ _value[type1] = int(name)
+ else:
+ raise SetMACException("Device version is digital, please recheck")
+ elif type1 == TLV_CODE_MAC_SIZE:
+ if name.isdigit():
+ _value[type1] = int(name, 16)
+ else:
+ raise SetMACException("Device version is digital, please recheck")
+ elif type1 == TLV_CODE_SERIAL_NUMBER:
+ if name.isalnum() == False:
+ raise SetMACException("Illegal character, please recheck")
+ elif len(name) != 13:
+ raise SetMACException("Wrong length of SN, please recheck")
+ else:
+ _value[type1] = name
+ elif type1 == TLV_CODE_VENDOR_EXT:
+ _value[type1] = name
+ else:
+ _value[type1] = name
+ return True
+
+
+def astrcmp(str1, str2):
+ return str1.lower() == str2.lower()
+
+
+def generate_ext(cardid):
+ s = "%08x" % cardid
+ ret = ""
+ for t in range(0, 4):
+ ret += chr(int(s[2 * t:2 * t + 2], 16))
+ ret = chr(0x01) + chr(len(ret)) + ret
+ return ret
+
+
+def rji2cget(bus, devno, address):
+ command_line = "i2cget -f -y %d 0x%02x 0x%02x " % (bus, devno, address)
+ retrytime = 6
+ ret_t = ""
+ for i in range(retrytime):
+ ret, ret_t = rj_os_system(command_line)
+ if ret == 0:
+ return True, ret_t
+ time.sleep(0.1)
+ return False, ret_t
+
+
+def rji2cset(bus, devno, address, byte):
+ command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x" % (bus, devno, address, byte)
+ retrytime = 6
+ ret_t = ""
+ for i in range(retrytime):
+ ret, ret_t = rj_os_system(command_line)
+ if ret == 0:
+ return True, ret_t
+ return False, ret_t
+
+
+def rjsysset(location, value):
+ command_line = "echo 0x%02x > %s" % (value, location)
+ retrytime = 6
+ ret_t = ""
+ for i in range(retrytime):
+ ret, ret_t = rj_os_system(command_line)
+ if ret == 0:
+ return True, ret_t
+ return False, ret_t
+
+
+def rji2cgetword(bus, devno, address):
+ command_line = "i2cget -f -y %d 0x%02x 0x%02x w" % (bus, devno, address)
+ retrytime = 3
+ ret_t = ""
+ for i in range(retrytime):
+ ret, ret_t = rj_os_system(command_line)
+ if ret == 0:
+ return True, ret_t
+ return False, ret_t
+
+
+def rji2csetword(bus, devno, address, byte):
+ command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%x w" % (bus, devno, address, byte)
+ rj_os_system(command_line)
+
+
+def fan_setmac():
+ rji2cset(FAN_PROTECT["bus"],
+ FAN_PROTECT["devno"],
+ FAN_PROTECT["addr"],
+ FAN_PROTECT["open"])
+
+ rji2cset(FAN_PROTECT["bus"],
+ FAN_PROTECT["devno"],
+ FAN_PROTECT["addr"],
+ FAN_PROTECT["close"])
+
+
+def checkfansninput(fan_sn, fansntemp):
+ if fan_sn in fansntemp:
+ rj_printer("Same SN already exists, please enter again")
+ return False
+ if (len(fan_sn) != 13):
+ rj_printer("Wrong length of SN, please enter again")
+ return False
+ return True
+
+
+def checkfanhwinput(hw):
+ if len(hw) != 4:
+ rj_printer("Wrong length of HW version, please enter again")
+ return False
+ if hw.find(".") != 1:
+ rj_printer("Wrong format of HW version, please enter again")
+ return False
+ return True
+
+
+def util_show_fanse2(fans):
+ formatstr = "%-8s %-20s %-20s %-20s %-20s"
+ rprint(formatstr % ("id", "Name", "HW version", "SN", "Time"))
+ rprint(formatstr % ("------", "---------------", "---------------", "---------------", "----"))
+ for fan in fans:
+ # print fan.dstatus
+ if fan.dstatus < 0:
+ rprint("%-8s" % ("Fan%d" % (fans.index(fan) + 1)),)
+ rj_printer(" wrong parsing eeprom")
+ else:
+ rprint(formatstr % ("Fan%d" % (fans.index(fan) + 1),
+ fan.typename.replace(chr(0x00), ""),
+ fan.typehwinfo.replace(chr(0x00), ""),
+ fan.typesn.replace(chr(0x00), ""),
+ fan.fandecodetime))
+
+
+def get_fane2_sysfs(bus, loc):
+ rg_fan_e2 = "%d-%04x/fan" % (bus, loc)
+ eeprom = get_sysfs_value(rg_fan_e2)
+ return eeprom
+
+
+def util_show_fane2():
+ ret = sorted(I2CUtil.getvaluefromdevice("rg_fan"))
+ if len(ret) <= 0:
+ return None
+ fans = []
+ for index in range(len(ret)):
+ t1 = (int(round(time.time() * 1000)))
+ eeprom = get_fane2_sysfs(ret[index]["bus"], ret[index]["loc"])
+ t2 = (int(round(time.time() * 1000)))
+ fane2 = fan_tlv()
+ fane2.fandecodetime = t2 - t1
+ fane2.decode(eeprom)
+ fans.append(fane2)
+ util_show_fanse2(fans)
+
+
+def get_pid(name):
+ ret = []
+ for dirname in os.listdir('/proc'):
+ if dirname == 'curproc':
+ continue
+ try:
+ with open('/proc/{}/cmdline'.format(dirname), mode='rb') as fd:
+ content = fd.read()
+ except Exception:
+ continue
+ if name in content:
+ ret.append(dirname)
+ return ret
+
+
+def fac_fans_setmac_tlv(ret):
+ if len(ret) <= 0:
+ return None
+ fans = []
+ fansntemp = []
+ for index in range(len(ret)):
+ item = ret[index]
+ log_debug(item)
+ eeprom = get_fane2_sysfs(item["bus"], item["loc"])
+ fane2 = fan_tlv()
+ fane2.decode(eeprom)
+ fane2.fanbus = item["bus"]
+ fane2.fanloc = item["loc"]
+ log_debug("decode eeprom success")
+
+ rprint("Fan [%d]-[%s] setmac" % ((index + 1), FANS_DEF[fane2.typedevtype]))
+ while True:
+ rprint("Please enter [%s]:" % "SN",)
+ fan_sn = raw_input()
+ if checkfansninput(fan_sn, fansntemp) == False:
+ continue
+ fansntemp.append(fan_sn)
+ fan_sn = fan_sn + chr(0x00)
+ fane2.typesn = fan_sn + chr(0x00)
+ break
+ while True:
+ rprint("Please enter [%s]:" % "HW version",)
+ hwinfo = raw_input()
+ if checkfanhwinput(hwinfo) == False:
+ continue
+ fan_hwinfo = hwinfo + chr(0x00)
+ fane2.typehwinfo = fan_hwinfo + chr(0x00)
+ break
+ log_debug(fane2.typedevtype)
+ fane2.typename = FANS_DEF[fane2.typedevtype] + chr(0x00)
+ fans.append(fane2)
+ rprint("\n")
+ rprint("\n*******************************\n")
+
+ util_show_fanse2(fans)
+ if get_input_check("Check to continue (Yes/No):") == True:
+ for fan in fans:
+ log_debug("ouput fan")
+ fac_fan_setmac(fan)
+ else:
+ rprint("setmac exit")
+ return False
+
+
+def fac_fan_setmac_fru(ret):
+ fans = FRULISTS.get('fans')
+
+ fanfrus = {}
+ newfrus = {}
+
+ #getmsg
+ try:
+ for fan in fans:
+ rprint("===============%s ================getmessage" % fan.get('name'))
+ eeprom = getsysvalue(I2CUtil.get_E2_file(fan.get('bus'), fan.get('loc')))
+ fru = ipmifru()
+ fru.decodeBin(eeprom)
+ fanfrus[fan.get('name')] = fru
+ except Exception as e:
+ rprint(str(e))
+ return False
+
+ #setmsg
+ for fan in fans:
+ rprint("===============%s ================setmac" % fan.get('name'))
+ fruold = fanfrus.get(fan.get('name'))
+ newfru = get_input_setmac(fruold)
+ newfru.recalcute()
+ newfrus[fan.get('name')] = newfru
+ #writemsg
+ for fan in fans:
+ rprint("===============%s ================writeToE2" % fan.get('name'))
+ ret_t = newfrus.get(fan.get('name'))
+ I2CUtil.open_fan_E2_protect()
+ I2CUtil.write_to_fan_E2(fan.get('bus'), fan.get('loc'), ret_t.bindata)
+ I2CUtil.close_fan_E2_protect()
+ #check
+ try:
+ for fan in fans:
+ rprint("===============%s ================getmessage" % fan.get('name'))
+ eeprom = getsysvalue(I2CUtil.get_E2_file(fan.get('bus'), fan.get('loc')))
+ fru = ipmifru()
+ fru.decodeBin(eeprom)
+ except Exception as e:
+ rprint(str(e))
+ return False
+ return True
+
+
+def fac_fans_setmac():
+ ret = I2CUtil.getvaluefromdevice("rg_fan")
+ if ret is not None and len(ret) > 0:
+ return fac_fans_setmac_tlv(ret)
+ fans = FRULISTS.get('fans', None)
+ if fans is not None and len(fans) > 0:
+ return fac_fan_setmac_fru(ret)
+ return False
+
+
+def fac_fan_setmac(item):
+
+ I2CUtil.open_fan_E2_protect()
+ I2CUtil.write_to_fan_E2(item.fanbus, item.fanloc, item.generate_fan_value())
+ I2CUtil.close_fan_E2_protect()
+
+ pass
+
+
+def write_to_eeprom(rst_arr):
+ rji2cset(E2_PROTECT["bus"], E2_PROTECT["devno"], E2_PROTECT["addr"],
+ E2_PROTECT["open"])
+ index = 0
+ for item in rst_arr:
+ rji2cset(E2_LOC["bus"], E2_LOC["devno"], index, ord(item))
+ index += 1
+ rji2cset(E2_PROTECT["bus"], E2_PROTECT["devno"], E2_PROTECT["addr"],
+ E2_PROTECT["close"])
+ os.system("rmmod at24 ")
+ os.system("modprobe at24 ")
+ os.system("rm -f /var/cache/sonic/decode-syseeprom/syseeprom_cache")
+
+
+def get_local_eth0_mac():
+ cmd = "ifconfig eth0 |grep HWaddr"
+ rprint(rj_os_system(cmd))
+
+
+def getonieversion():
+ if not os.path.isfile('/host/machine.conf'):
+ return ""
+ machine_vars = {}
+ with open('/host/machine.conf') as machine_file:
+ for line in machine_file:
+ tokens = line.split('=')
+ if len(tokens) < 2:
+ continue
+ machine_vars[tokens[0]] = tokens[1].strip()
+ return machine_vars.get("onie_version")
+
+
+def createbmcmac(cpumac, num=2):
+ bcmvalue = strtoint(cpumac[cpumac.rindex(":") + 1:len(cpumac)]) + num
+ # bmcmac =
+ t = cpumac.split(":")
+ t[5] = "%02x" % bcmvalue
+ bmcmac = ":".join(t)
+ return bmcmac.upper()
+
+
+def fac_board_setmac():
+ _value = {}
+ _value[TLV_CODE_VENDOR_EXT] = generate_ext(RUIJIE_CARDID)
+ _value[TLV_CODE_PRODUCT_NAME] = RUIJIE_PRODUCTNAME
+ _value[TLV_CODE_PART_NUMBER] = RUIJIE_PART_NUMBER
+ _value[TLV_CODE_LABEL_REVISION] = RUIJIE_LABEL_REVISION
+ _value[TLV_CODE_PLATFORM_NAME] = platform
+ _value[TLV_CODE_ONIE_VERSION] = getonieversion()
+ _value[TLV_CODE_MAC_SIZE] = RUIJIE_MAC_SIZE
+ _value[TLV_CODE_MANUF_NAME] = RUIJIE_MANUF_NAME
+ _value[TLV_CODE_MANUF_COUNTRY] = RUIJIE_MANUF_COUNTRY
+ _value[TLV_CODE_VENDOR_NAME] = RUIJIE_VENDOR_NAME
+ _value[TLV_CODE_DIAG_VERSION] = RUIJIE_DIAG_VERSION
+ _value[TLV_CODE_SERVICE_TAG] = RUIJIE_SERVICE_TAG
+ try:
+ if 0x00004052 == RUIJIE_CARDID:
+ _value[TLV_CODE_PRODUCT_NAME] = RUIJIE_PRODUCTNAME + "-RJ"
+ elif 0x00004051 == RUIJIE_CARDID or 0x00004050 == RUIJIE_CARDID:
+ change_type_value(_value, TLV_CODE_PRODUCT_NAME, "Product name",
+ RUIJIE_PRODUCTNAME)
+
+ change_type_value(_value, TLV_CODE_SERIAL_NUMBER, "SN", "0000000000000")
+ change_type_value(_value, TLV_CODE_DEVICE_VERSION, "HW version", "101")
+ change_type_value(_value, TLV_CODE_MAC_BASE, "MAC address", "58696cfb2108")
+ _value[TLV_CODE_MANUF_DATE] = time.strftime('%m/%d/%Y %H:%M:%S',
+ time.localtime())
+ rst, ret = generate_value(_value)
+ if util_setmac("eth0", _value[TLV_CODE_MAC_BASE]) == True:
+ write_to_eeprom(rst)
+ if FACTESTMODULE.has_key(
+ "bmcsetmac") and FACTESTMODULE['bmcsetmac'] == 1:
+ bmcmac = createbmcmac(_value[TLV_CODE_MAC_BASE])
+ if ipmi_set_mac(bmcmac) == True:
+ print("BMC MAC【%s】" % bmcmac)
+ else:
+ print("SET BMC MAC FAILED")
+ return False
+ else:
+ return False
+ except SetMACException as e:
+ #print e
+ rj_printer("\n\n%s\n\n" % e)
+ return False
+ except ValueError as e:
+ return False
+ return True
+
+
+def ipmi_set_mac(mac):
+ macs = mac.split(":")
+ cmdinit = "ipmitool raw 0x0c 0x01 0x01 0xc2 0x00"
+ cmdset = "ipmitool raw 0x0c 0x01 0x01 0x05"
+ for ind in range(len(macs)):
+ cmdset += " 0x%02x" % int(macs[ind], 16)
+ rj_os_system(cmdinit)
+ ret, status = rj_os_system(cmdset)
+ if ret:
+ rj_printer("\n\n%s\n\n" % status)
+ return False
+ return True
+
+
+def get_input_value(title, tips):
+ rprint("Please enter [%s] like (%s):" % (title, tips),)
+ name = raw_input()
+
+ return name
+
+
+def bmc_setmac():
+ tips = "BMC MAC"
+ rprint("Please enter the value [%s]:" % tips,)
+ name = raw_input()
+ if len(name) != 12:
+ rj_printer("\nIllegal MAC address, please enter again\n")
+ return False
+ release_mac = ""
+ for i in range(len(name) / 2):
+ if i == 0:
+ release_mac += name[i * 2:i * 2 + 2]
+ else:
+ release_mac += ":" + name[i * 2:i * 2 + 2]
+ if is_valid_mac(release_mac) == True:
+ if ipmi_set_mac(release_mac) == True:
+ return True
+ else:
+ rj_printer("\nIllegal MAC address, please enter again\n")
+ return False
+
+
+def close_protocol():
+ log_info("stop LLDP")
+ sys.stdout.write(".")
+ sys.stdout.flush()
+ rj_os_system("systemctl stop lldp.service")
+ log_info("stop BGP service")
+ sys.stdout.write(".")
+ sys.stdout.flush()
+ rj_os_system("systemctl stop bgp.service")
+ log_info("stop STP")
+ sys.stdout.write(".")
+ sys.stdout.flush()
+
+
+def check_sdk_mem():
+ ind = 0
+ file_data = ""
+ with open(file_name, "r") as f:
+ for line in f:
+ if "dmasize=16M" in line:
+ line = line.replace("dmasize=16M", "dmasize=256M")
+ ind = -1
+ file_data += line
+ if ind == 0:
+ return
+ with open(file_name, "w") as f:
+ f.write(file_data)
+ rprint("Revise SDK memory as 256M, it will take effect after reboot")
+ rj_os_system("sync")
+ rj_os_system("reboot")
+
+
+def getch(msg):
+ ret = ""
+ fd = sys.stdin.fileno()
+ old_ttyinfo = termios.tcgetattr(fd)
+ new_ttyinfo = old_ttyinfo[:]
+ new_ttyinfo[3] &= ~termios.ICANON
+ new_ttyinfo[3] &= ~termios.ECHO
+ sys.stdout.write(msg)
+ sys.stdout.flush()
+ try:
+ termios.tcsetattr(fd, termios.TCSANOW, new_ttyinfo)
+ ret = os.read(fd, 1)
+ finally:
+ # print "try to setting"
+ termios.tcsetattr(fd, termios.TCSANOW, old_ttyinfo)
+ return ret
+
+
+def get_raw_input():
+ ret = ""
+ fd = sys.stdin.fileno()
+ old_ttyinfo = termios.tcgetattr(fd)
+ new_ttyinfo = old_ttyinfo[:]
+ new_ttyinfo[3] &= ~termios.ICANON
+ new_ttyinfo[3] &= ~termios.ECHO
+ try:
+ termios.tcsetattr(fd, termios.TCSANOW, new_ttyinfo)
+ ret = raw_input("")
+ except Exception as e:
+ rprint(e)
+ finally:
+ termios.tcsetattr(fd, termios.TCSANOW, old_ttyinfo)
+ return ret
+
+
+def getsysvalue(location):
+ retval = None
+ mb_reg_file = location
+ if (not os.path.isfile(mb_reg_file)):
+ rprint(mb_reg_file, 'not found !')
+ return retval
+ try:
+ if (not os.path.isfile(mb_reg_file)):
+ rprint(mb_reg_file, 'not found !')
+ return retval
+ with open(mb_reg_file, 'r') as fd:
+ retval = fd.read()
+ except Exception as error:
+ log_error("Unable to open " + mb_reg_file + "file !")
+ retval = retval.rstrip('\r\n')
+ retval = retval.lstrip(" ")
+ #log_debug(retval)
+ return retval
+
+
+def get_pmc_register(reg_name):
+ retval = 'ERR'
+ mb_reg_file = MAILBOX_DIR + reg_name
+ if (not os.path.isfile(mb_reg_file)):
+ rprint(mb_reg_file, 'not found !')
+ return retval
+ try:
+ if (not os.path.isfile(mb_reg_file)):
+ rprint(mb_reg_file, 'not found !')
+ return retval
+ with open(mb_reg_file, 'r') as fd:
+ retval = fd.read()
+ except Exception as error:
+ log_error("Unable to open " + mb_reg_file + "file !")
+ retval = retval.rstrip('\r\n')
+ retval = retval.lstrip(" ")
+ #log_debug(retval)
+ return retval
+
+
+def decoder(s, t):
+ if ord(t[0]) == TLV_CODE_PRODUCT_NAME:
+ name = "Product Name"
+ value = str(t[2:2 + ord(t[1])])
+ elif ord(t[0]) == TLV_CODE_PART_NUMBER:
+ name = "Part Number"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_SERIAL_NUMBER:
+ name = "Serial Number"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_MAC_BASE:
+ name = "Base MAC Address"
+ value = ":".join([binascii.b2a_hex(T) for T in t[2:8]]).upper()
+ elif ord(t[0]) == TLV_CODE_MANUF_DATE:
+ name = "Manufacture Date"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_DEVICE_VERSION:
+ name = "Device Version"
+ value = str(ord(t[2]))
+ elif ord(t[0]) == TLV_CODE_LABEL_REVISION:
+ name = "Label Revision"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_PLATFORM_NAME:
+ name = "Platform Name"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_ONIE_VERSION:
+ name = "ONIE Version"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_MAC_SIZE:
+ name = "MAC Addresses"
+ value = str((ord(t[2]) << 8) | ord(t[3]))
+ elif ord(t[0]) == TLV_CODE_MANUF_NAME:
+ name = "Manufacturer"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_MANUF_COUNTRY:
+ name = "Manufacture Country"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_VENDOR_NAME:
+ name = "Vendor Name"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_DIAG_VERSION:
+ name = "Diag Version"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_SERVICE_TAG:
+ name = "Service Tag"
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_VENDOR_EXT:
+ name = "Vendor Extension"
+ value = ""
+ if _TLV_DISPLAY_VENDOR_EXT:
+ value = t[2:2 + ord(t[1])]
+ elif ord(t[0]) == TLV_CODE_CRC_32 and len(t) == 6:
+ name = "CRC-32"
+ value = "0x%08X" % (((ord(t[2]) << 24) | (ord(t[3]) << 16) | (ord(t[4]) << 8) | ord(t[5])),)
+ elif ord(t[0]) == TLV_CODE_RJ_CARID:
+ name = "rj_cardid"
+ value = ""
+ for c in t[2:2 + ord(t[1])]:
+ value += "%02X" % (ord(c),)
+ else:
+ name = "Unknown"
+ value = ""
+ for c in t[2:2 + ord(t[1])]:
+ value += "0x%02X " % (ord(c),)
+ return {"name": name, "code": ord(t[0]), "value": value}
+
+
+def decode_eeprom(e):
+ total_len = (ord(e[9]) << 8) | ord(e[10])
+ tlv_index = _TLV_INFO_HDR_LEN
+ tlv_end = _TLV_INFO_HDR_LEN + total_len
+ ret = []
+ while (tlv_index + 2) < len(e) and tlv_index < tlv_end:
+ rt = decoder(None, e[tlv_index:tlv_index + 2 + ord(e[tlv_index + 1])])
+ ret.append(rt)
+ if ord(e[tlv_index]) == TLV_CODE_CRC_32:
+ break
+ tlv_index += ord(e[tlv_index + 1]) + 2
+ for item in ret:
+ if item['code'] == TLV_CODE_VENDOR_EXT:
+ rt = decoder(None,
+ item["value"][0:0 + 2 + ord(item["value"][0 + 1])])
+ ret.append(rt)
+ return ret
+
+
+def get_sys_eeprom():
+ eeprom = get_sysfs_value(rg_eeprom)
+ return decode_eeprom(eeprom)
+
+
+def get_card_id():
+ ret = get_sys_eeprom()
+ for item in ret:
+ if item['code'] == TLV_CODE_RJ_CARID:
+ return item.get('value', None)
+ return None
+
+
+def rj_os_system(cmd):
+ status, output = commands.getstatusoutput(cmd)
+ return status, output
+
+
+def getsysmeminfo():
+ ret, log = rj_os_system("which dmidecode")
+ if ret != 0 or len(log) <= 0:
+ error = "cmd find dmidecode"
+ return False, error
+ cmd = log + "|grep -P -A5 \"Memory\s+Device\"|grep Size|grep -v Range"
+ result = []
+ ret1, log1 = rj_os_system(cmd)
+ if ret == 0 and len(log1):
+ log1 = log1.lstrip()
+ arr = log1.split("\n")
+ total = len(arr)
+ for i in range(len(arr)):
+ val = re.sub("\D", "", arr[i])
+ if val == "":
+ val = arr[i].lstrip()
+ val = re.sub('Size:', '', val).lstrip()
+ result.append({"slot": i + 1, "size": val})
+ return True, result
+ return False, "error"
+
+
+def getsysmeminfo_detail():
+ ret, log = rj_os_system("which dmidecode ")
+ if ret != 0 or len(log) <= 0:
+ error = "cmd find dmidecode"
+ return False, error
+ cmd = log + " -t 17 | grep -A21 \"Memory Device\""
+ ret1, log1 = rj_os_system(cmd)
+ if ret != 0 or len(log1) <= 0:
+ return False, "execute failed [%s]" % cmd
+ result_t = log1.split("--")
+ mem_rets = []
+ for item in result_t:
+ its = item.replace("\t", "").strip().split("\n")
+ ret = {}
+ for it in its:
+ if ":" in it:
+ key = it.split(":")[0].lstrip()
+ value = it.split(":")[1].lstrip()
+ ret[key] = value
+ mem_rets.append(ret)
+ return True, mem_rets
+
+
+def get_dmi_sys_by_type(type_t):
+ ret, log = rj_os_system("which dmidecode")
+ if ret != 0 or len(log) <= 0:
+ error = "cmd find dmidecode"
+ return False, error
+ cmd = log + " -t %s" % type_t
+ ret1, log1 = rj_os_system(cmd)
+ if ret != 0 or len(log1) <= 0:
+ return False, "execute failed [%s]" % cmd
+ its = log1.replace("\t", "").strip().split("\n")
+ ret = {}
+ for it in its:
+ if ":" in it:
+ key = it.split(":")[0].lstrip()
+ value = it.split(":")[1].lstrip()
+ ret[key] = value
+ return True, ret
+
+
+def gethwsys():
+ return get_dmi_sys_by_type(1)
+
+
+def getsysbios():
+ return get_dmi_sys_by_type(0)
+
+
+def search_dir_by_name(name, dir):
+ result = []
+ try:
+ files = os.listdir(dir)
+ for file in files:
+ if name in file:
+ result.append(os.path.join(dir, file))
+ except Exception as e:
+ pass
+ return result
+
+
+def get_usb_location():
+ dir = "/sys/block/"
+ spect = "sd"
+ usbpath = ""
+ result = search_dir_by_name(spect, dir)
+ if len(result) <= 0:
+ return False
+ for item in result:
+ with open(os.path.join(item, "removable"), 'r') as fd:
+ value = fd.read()
+ if value.strip() == "1":
+ usbpath = item
+ break
+ if usbpath == "":
+ log_debug("no usb found")
+ return False, usbpath
+ return True, usbpath
+
+
+def getusbinfo():
+ ret, path = get_usb_location()
+ if ret == False:
+ return False, "not usb exists"
+ str = os.path.join(path, "size")
+ ret, value = getfilevalue(str)
+ if ret == True:
+ return True, {
+ "id": os.path.basename(path),
+ "size": float(value) * 512 / 1024 / 1024 / 1024
+ }
+ else:
+ return False, "Err"
+
+
+def get_cpu_info():
+ cmd = "cat /proc/cpuinfo | grep processor -A18"
+
+ ret, log1 = rj_os_system(cmd)
+ if ret != 0 or len(log1) <= 0:
+ return False, "execute failed [%s]" % cmd
+ result_t = log1.split("--")
+ mem_rets = []
+ for item in result_t:
+ its = item.replace("\t", "").strip().split("\n")
+ ret = {}
+ for it in its:
+ if ":" in it:
+ key = it.split(":")[0].lstrip()
+ value = it.split(":")[1].lstrip()
+ ret[key] = value
+ mem_rets.append(ret)
+ return True, mem_rets
+
+
+def get_version_config_info(attr_key):
+ version_conf_filename = "/root/version.json"
+ if not os.path.isfile(version_conf_filename):
+ return None
+ with open(version_conf_filename) as rjconf_file:
+ for line in rjconf_file:
+ tokens = line.split('=')
+ if len(tokens) < 2:
+ continue
+ if tokens[0] == attr_key:
+ return tokens[1].strip()
+ return None
+
+
+def io_rd(reg_addr, len=1):
+ """IO Read"""
+ try:
+ regaddr = 0
+ if type(reg_addr) == int:
+ regaddr = reg_addr
+ else:
+ regaddr = int(reg_addr, 16)
+ devfile = "/dev/port"
+ fd = os.open(devfile, os.O_RDWR | os.O_CREAT)
+ os.lseek(fd, regaddr, os.SEEK_SET)
+ str = os.read(fd, len)
+ return "".join(["%02x" % ord(item) for item in str])
+ except ValueError:
+ return None
+ except Exception as e:
+ rprint(e)
+ return None
+ finally:
+ os.close(fd)
+ return None
+
+
+def io_wr(reg_addr, reg_data):
+ """ID write"""
+ try:
+ regdata = 0
+ regaddr = 0
+ if type(reg_addr) == int:
+ regaddr = reg_addr
+ else:
+ regaddr = int(reg_addr, 16)
+ if type(reg_data) == int:
+ regdata = reg_data
+ else:
+ regdata = int(reg_data, 16)
+ devfile = "/dev/port"
+ fd = os.open(devfile, os.O_RDWR | os.O_CREAT)
+ os.lseek(fd, regaddr, os.SEEK_SET)
+ ret = os.write(fd, chr(regdata))
+ return True
+ except ValueError as e:
+ rprint(e)
+ return False
+ except Exception as e:
+ rprint(e)
+ return False
+ finally:
+ os.close(fd)
+ return False
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/common/service/device_i2c.service b/platform/broadcom/sonic-platform-modules-ruijie/common/service/device_i2c.service
new file mode 100755
index 000000000000..8777a46b7504
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/common/service/device_i2c.service
@@ -0,0 +1,15 @@
+[Unit]
+Description= Ruijie Global Initialize I2c drivers.
+After=local-fs.target
+Before=pmon.service
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/device_i2c.py start
+ExecStop=/usr/local/bin/device_i2c.py stop
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/debian/changelog b/platform/broadcom/sonic-platform-modules-ruijie/debian/changelog
new file mode 100755
index 000000000000..c987c3560017
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/debian/changelog
@@ -0,0 +1,5 @@
+sonic-ruijie-platform-modules (1.0) unstable; urgency=low
+
+ * Initial release
+
+ -- sonic_rd Fri, 21 APR 2017 11:11:11 -0800
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/debian/compat b/platform/broadcom/sonic-platform-modules-ruijie/debian/compat
new file mode 100755
index 000000000000..45a4fb75db86
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/debian/compat
@@ -0,0 +1 @@
+8
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/debian/control b/platform/broadcom/sonic-platform-modules-ruijie/debian/control
new file mode 100755
index 000000000000..c89f2601a88f
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/debian/control
@@ -0,0 +1,10 @@
+Source: sonic-ruijie-platform-modules
+Section: main
+Priority: extra
+Maintainer: Ruijie Network
+Standards-Version: 3.9.3
+
+Package: platform-modules-ruijie-b6510-48vs8cq
+Architecture: amd64
+Description: kernel modules for platform devices such as fan, led, sfp
+
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/debian/copyright b/platform/broadcom/sonic-platform-modules-ruijie/debian/copyright
new file mode 100755
index 000000000000..c00a47507890
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/debian/copyright
@@ -0,0 +1,16 @@
+Copyright (C) 2016 Microsoft, Inc
+Copyright (C) 2018 Ruijie Network Corporation
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/debian/files b/platform/broadcom/sonic-platform-modules-ruijie/debian/files
new file mode 100755
index 000000000000..975b9caccab2
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/debian/files
@@ -0,0 +1,2 @@
+platform-modules-ruijie-b6510-48vs8cq_1.0_amd64.deb main extra
+sonic-ruijie-platform-modules_1.0_amd64.buildinfo main extra
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/debian/platform-modules-ruijie-b6510-48vs8cq.postinst b/platform/broadcom/sonic-platform-modules-ruijie/debian/platform-modules-ruijie-b6510-48vs8cq.postinst
new file mode 100755
index 000000000000..a8132f4f65a9
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/debian/platform-modules-ruijie-b6510-48vs8cq.postinst
@@ -0,0 +1,10 @@
+#!/bin/sh
+# postinst
+
+kernel_version=$(uname -r)
+
+if [ -e /boot/System.map-${kernel_version} ]; then
+ depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true
+fi
+
+#DEBHELPER#
diff --git a/platform/broadcom/sonic-platform-modules-ruijie/debian/rules b/platform/broadcom/sonic-platform-modules-ruijie/debian/rules
new file mode 100755
index 000000000000..5083acf9abdb
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-ruijie/debian/rules
@@ -0,0 +1,75 @@
+#!/usr/bin/make -f
+CC=gcc
+INSTALL_MOD_DIR:=extra
+KVERSION ?= $(shell uname -r)
+KERNEL_SRC := /lib/modules/$(KVERSION)
+MOD_SRC_DIR:= $(shell pwd)
+KBUILD_OUTPUT=$(KERNEL_SRC)/build
+
+LIB_DIR = usr/lib/python2.7/dist-packages
+CUSTOM_RULES_DIR := $(shell pwd)/debian
+
+export INSTALL_MOD_DIR top_srcdir KVERSION KERNEL_SRC CC KBUILD_OUTPUT
+
+currentdir = $(shell pwd)
+MODULE_DIRS := b6510-48vs8cq
+export CUSTOMS_DIRS MODULE_DIRS
+
+#all product need common
+COMPILE_DIRS = $(MODULE_DIRS)
+
+clean_dirs = $(MODULE_DIRS)
+clean_dirs += common
+
+custom_clean_dirs := $(addprefix _clean_,$(clean_dirs) )
+
+
+%:
+ dh $@
+build: $(COMPILE_DIRS)
+ @echo "build success"
+
+$(custom_clean_dirs):
+ $(MAKE) -C $(patsubst _clean_%,%,$@) clean
+
+common_build :
+ $(MAKE) -C $(MOD_SRC_DIR)/common
+
+$(COMPILE_DIRS): common_build
+ $(MAKE) -C $(MOD_SRC_DIR)/$@
+ dh_testdir
+ dh_installdirs
+ #dh_installdirs -pplatform-modules-ruijie-$@ usr/local/bin
+ cp -r $(MOD_SRC_DIR)/common/build/* debian/platform-modules-ruijie-$@/
+ cp -r $(MOD_SRC_DIR)/$@/build/* debian/platform-modules-ruijie-$@/
+
+binary: binary-indep
+ @echo "======================================================="
+
+binary-indep:
+ # 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
+override_dh_usrlocal:
+
+override_dh_pysupport:
+
+clean: $(custom_clean_dirs)
+ dh_testdir
+ dh_testroot
+ dh_clean
+
+.PHONY: build $(COMPILE_DIRS) binary binary-arch binary-indep clean
diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list
index ea78b8165f3a..9382bba42d66 100644
--- a/src/sonic-device-data/tests/permitted_list
+++ b/src/sonic-device-data/tests/permitted_list
@@ -139,3 +139,11 @@ xgxs_lcpll_xtal_refclk
xgxs_pdetect
xgxs_rx_lane_map
xgxs_tx_lane_map
+
+help_cli_enable
+ifp_inports_support_enable
+memlist_enable
+pbmp_gport_stack
+port_flex_enable
+reglist_enable
+cancun_dir