[devices]: Adding platform support for Juniper QFX5210 (#3270)

This switch has 64 QSFP28 (40G/100G) ports, 2 SFP+ (1G/10G) ports
on Broadcom Tomahawk II chipset. CPU used in QFX5210-64C-S is
Intel Broadwell-DE. The machine has Redundant and hot-swappable
Power Supply (1+1) and also has Redundant and hot swappable fans (3+1).

Signed-off-by: Ciju Rajan K <crajank@juniper.net>
This commit is contained in:
ciju-juniper 2019-09-06 20:22:45 +05:30 committed by lguohan
parent cfcf30570b
commit fdcb69d048
41 changed files with 10676 additions and 1 deletions

View File

@ -0,0 +1,65 @@
# name lanes alias
Ethernet0 73,74,75,76 hundredGigE1
Ethernet4 65,66,67,68 hundredGigE2
Ethernet8 81,82,83,84 hundredGigE3
Ethernet12 89,90,91,92 hundredGigE4
Ethernet16 105,106,107,108 hundredGigE5
Ethernet20 97,98,99,100 hundredGigE6
Ethernet24 113,114,115,116 hundredGigE7
Ethernet28 121,122,123,124 hundredGigE8
Ethernet32 41,42,43,44 hundredGigE9
Ethernet36 33,34,35,36 hundredGigE10
Ethernet40 49,50,51,52 hundredGigE11
Ethernet44 57,58,59,60 hundredGigE12
Ethernet48 137,138,139,140 hundredGigE13
Ethernet52 129,130,131,132 hundredGigE14
Ethernet56 145,146,147,148 hundredGigE15
Ethernet60 153,154,155,156 hundredGigE16
Ethernet64 173,174,175,176 hundredGigE17
Ethernet68 165,166,167,168 hundredGigE18
Ethernet72 181,182,183,184 hundredGigE19
Ethernet76 189,190,191,192 hundredGigE20
Ethernet80 13,14,15,16 hundredGigE21
Ethernet84 5,6,7,8 hundredGigE22
Ethernet88 29,30,31,32 hundredGigE23
Ethernet92 21,22,23,24 hundredGigE24
Ethernet96 205,206,207,208 hundredGigE25
Ethernet100 197,198,199,200 hundredGigE26
Ethernet104 213,214,215,216 hundredGigE27
Ethernet108 221,222,223,224 hundredGigE28
Ethernet112 229,230,231,232 hundredGigE29
Ethernet116 237,238,239,240 hundredGigE30
Ethernet120 245,246,247,248 hundredGigE31
Ethernet124 253,254,255,256 hundredGigE32
Ethernet128 69,70,71,72 hundredGigE33
Ethernet132 77,78,79,80 hundredGigE34
Ethernet136 93,94,95,96 hundredGigE35
Ethernet140 85,86,87,88 hundredGigE36
Ethernet144 101,102,103,104 hundredGigE37
Ethernet148 109,110,111,112 hundredGigE38
Ethernet152 125,126,127,128 hundredGigE39
Ethernet156 117,118,119,120 hundredGigE40
Ethernet160 37,38,39,40 hundredGigE41
Ethernet164 45,46,47,48 hundredGigE42
Ethernet168 61,62,63,64 hundredGigE43
Ethernet172 53,54,55,56 hundredGigE44
Ethernet176 133,134,135,136 hundredGigE45
Ethernet180 141,142,143,144 hundredGigE46
Ethernet184 157,158,159,160 hundredGigE47
Ethernet188 149,150,151,152 hundredGigE48
Ethernet192 161,162,163,164 hundredGigE49
Ethernet196 169,170,171,172 hundredGigE50
Ethernet200 185,186,187,188 hundredGigE51
Ethernet204 177,178,179,180 hundredGigE52
Ethernet208 1,2,3,4 hundredGigE53
Ethernet212 9,10,11,12 hundredGigE54
Ethernet216 25,26,27,28 hundredGigE55
Ethernet220 17,18,19,20 hundredGigE56
Ethernet224 193,194,195,196 hundredGigE57
Ethernet228 201,202,203,204 hundredGigE58
Ethernet232 217,218,219,220 hundredGigE59
Ethernet236 209,210,211,212 hundredGigE60
Ethernet240 225,226,227,228 hundredGigE61
Ethernet244 233,234,235,236 hundredGigE62
Ethernet248 249,250,251,252 hundredGigE63
Ethernet252 241,242,243,244 hundredGigE64

View File

@ -0,0 +1 @@
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-qfx5210-64x100G.config.bcm

View File

@ -0,0 +1,875 @@
# Broadcom Tomahawk SDK configuration
os=unix
schan_intr_enable=0
l2_mem_entries=40960
l2xmsg_mode=1
l3_mem_entries=40960
parity_correction=0
parity_enable=0
mmu_lossless=1
pbmp_xport_xe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
pbmp_oversubscribe=0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
# platform specific setting
arl_clean_timeout_usec=15000000
asf_mem_profile=2
bcm_num_cos=8
bcm_stat_flags=1
bcm_stat_jumbo=9236
cdma_timeout_usec=15000000
dma_desc_timeout_usec=15000000
ipv6_lpm_128b_enable=1
l3_alpm_enable=2
lpm_scaling_enable=0
max_vp_lags=0
miim_intr_enable=0
module_64ports=1
oversubscribe_mode=1
#add loopback port
# port 33 is the first loopback port
portmap_33=260:10
# port 66 is the first management port
portmap_66=257:10
# port 67 is the second loopback port
portmap_67=261:10
# port 100 is the second management port
portmap_100=259:10
# port 101 is the third loopback port
portmap_101=262:10
# port 135 is the fourth loopback port
portmap_135=263:10
#Port0
#FC18
portmap_36=73:100
phy_chain_rx_lane_map_physical{73.0}=0x3210
phy_chain_tx_lane_map_physical{73.0}=0x3021
phy_chain_rx_polarity_flip_physical{73.0}=0x0
phy_chain_rx_polarity_flip_physical{74.0}=0x0
phy_chain_rx_polarity_flip_physical{75.0}=0x0
phy_chain_rx_polarity_flip_physical{76.0}=0x1
phy_chain_tx_polarity_flip_physical{73.0}=0x0
phy_chain_tx_polarity_flip_physical{74.0}=0x0
phy_chain_tx_polarity_flip_physical{75.0}=0x1
phy_chain_tx_polarity_flip_physical{76.0}=0x0
#Port1
#FC16
portmap_34=65:100
phy_chain_rx_lane_map_physical{65.0}=0x3210
phy_chain_tx_lane_map_physical{65.0}=0x3210
phy_chain_rx_polarity_flip_physical{65.0}=0x0
phy_chain_rx_polarity_flip_physical{66.0}=0x0
phy_chain_rx_polarity_flip_physical{67.0}=0x0
phy_chain_rx_polarity_flip_physical{68.0}=0x0
phy_chain_tx_polarity_flip_physical{65.0}=0x1
phy_chain_tx_polarity_flip_physical{66.0}=0x0
phy_chain_tx_polarity_flip_physical{67.0}=0x0
phy_chain_tx_polarity_flip_physical{68.0}=0x0
#Port2
#FC20
portmap_38=81:100
phy_chain_rx_lane_map_physical{81.0}=0x1230
phy_chain_tx_lane_map_physical{81.0}=0x1032
phy_chain_rx_polarity_flip_physical{81.0}=0x1
phy_chain_rx_polarity_flip_physical{82.0}=0x0
phy_chain_rx_polarity_flip_physical{83.0}=0x1
phy_chain_rx_polarity_flip_physical{84.0}=0x0
phy_chain_tx_polarity_flip_physical{81.0}=0x1
phy_chain_tx_polarity_flip_physical{82.0}=0x1
phy_chain_tx_polarity_flip_physical{83.0}=0x1
phy_chain_tx_polarity_flip_physical{84.0}=0x0
#Port3
#FC22
portmap_40=89:100
phy_chain_rx_lane_map_physical{89.0}=0x0132
phy_chain_tx_lane_map_physical{89.0}=0x1203
phy_chain_rx_polarity_flip_physical{89.0}=0x1
phy_chain_rx_polarity_flip_physical{90.0}=0x0
phy_chain_rx_polarity_flip_physical{91.0}=0x0
phy_chain_rx_polarity_flip_physical{92.0}=0x1
phy_chain_tx_polarity_flip_physical{89.0}=0x1
phy_chain_tx_polarity_flip_physical{90.0}=0x0
phy_chain_tx_polarity_flip_physical{91.0}=0x1
phy_chain_tx_polarity_flip_physical{92.0}=0x1
#Port4
#FC26
portmap_44=105:100
phy_chain_rx_lane_map_physical{105.0}=0x3210
phy_chain_tx_lane_map_physical{105.0}=0x0231
phy_chain_rx_polarity_flip_physical{105.0}=0x0
phy_chain_rx_polarity_flip_physical{106.0}=0x0
phy_chain_rx_polarity_flip_physical{107.0}=0x0
phy_chain_rx_polarity_flip_physical{108.0}=0x1
phy_chain_tx_polarity_flip_physical{105.0}=0x0
phy_chain_tx_polarity_flip_physical{106.0}=0x1
phy_chain_tx_polarity_flip_physical{107.0}=0x0
phy_chain_tx_polarity_flip_physical{108.0}=0x1
#Port5
#FC24
portmap_42=97:100
phy_chain_rx_lane_map_physical{97.0}=0x0213
phy_chain_tx_lane_map_physical{97.0}=0x3210
phy_chain_rx_polarity_flip_physical{97.0}=0x1
phy_chain_rx_polarity_flip_physical{98.0}=0x0
phy_chain_rx_polarity_flip_physical{99.0}=0x0
phy_chain_rx_polarity_flip_physical{100.0}=0x1
phy_chain_tx_polarity_flip_physical{97.0}=0x1
phy_chain_tx_polarity_flip_physical{98.0}=0x1
phy_chain_tx_polarity_flip_physical{99.0}=0x0
phy_chain_tx_polarity_flip_physical{100.0}=0x0
#Port6
#FC 28
portmap_46=113:100
phy_chain_rx_lane_map_physical{113.0}=0x3021
phy_chain_tx_lane_map_physical{113.0}=0x0312
phy_chain_rx_polarity_flip_physical{113.0}=0x0
phy_chain_rx_polarity_flip_physical{114.0}=0x1
phy_chain_rx_polarity_flip_physical{115.0}=0x1
phy_chain_rx_polarity_flip_physical{116.0}=0x0
phy_chain_tx_polarity_flip_physical{113.0}=0x1
phy_chain_tx_polarity_flip_physical{114.0}=0x0
phy_chain_tx_polarity_flip_physical{115.0}=0x0
phy_chain_tx_polarity_flip_physical{116.0}=0x1
#Port7
#FC30
portmap_48=121:100
phy_chain_rx_lane_map_physical{121.0}=0x3021
phy_chain_tx_lane_map_physical{121.0}=0x2130
phy_chain_rx_polarity_flip_physical{121.0}=0x0
phy_chain_rx_polarity_flip_physical{122.0}=0x1
phy_chain_rx_polarity_flip_physical{123.0}=0x1
phy_chain_rx_polarity_flip_physical{124.0}=0x0
phy_chain_tx_polarity_flip_physical{121.0}=0x1
phy_chain_tx_polarity_flip_physical{122.0}=0x1
phy_chain_tx_polarity_flip_physical{123.0}=0x1
phy_chain_tx_polarity_flip_physical{124.0}=0x0
#Port8
#FC10
portmap_11=41:100
phy_chain_rx_lane_map_physical{41.0}=0x0132
phy_chain_tx_lane_map_physical{41.0}=0x1302
phy_chain_rx_polarity_flip_physical{41.0}=0x0
phy_chain_rx_polarity_flip_physical{42.0}=0x0
phy_chain_rx_polarity_flip_physical{43.0}=0x0
phy_chain_rx_polarity_flip_physical{44.0}=0x0
phy_chain_tx_polarity_flip_physical{41.0}=0x1
phy_chain_tx_polarity_flip_physical{42.0}=0x0
phy_chain_tx_polarity_flip_physical{43.0}=0x0
phy_chain_tx_polarity_flip_physical{44.0}=0x0
#Port9
#FC8
portmap_9=33:100
phy_chain_rx_lane_map_physical{33.0}=0x2310
phy_chain_tx_lane_map_physical{33.0}=0x0213
phy_chain_rx_polarity_flip_physical{33.0}=0x0
phy_chain_rx_polarity_flip_physical{34.0}=0x1
phy_chain_rx_polarity_flip_physical{35.0}=0x0
phy_chain_rx_polarity_flip_physical{36.0}=0x0
phy_chain_tx_polarity_flip_physical{33.0}=0x1
phy_chain_tx_polarity_flip_physical{34.0}=0x1
phy_chain_tx_polarity_flip_physical{35.0}=0x0
phy_chain_tx_polarity_flip_physical{36.0}=0x0
#Port10
#FC12
portmap_13=49:100
phy_chain_rx_lane_map_physical{49.0}=0x3210
phy_chain_tx_lane_map_physical{49.0}=0x3102
phy_chain_rx_polarity_flip_physical{49.0}=0x1
phy_chain_rx_polarity_flip_physical{50.0}=0x0
phy_chain_rx_polarity_flip_physical{51.0}=0x1
phy_chain_rx_polarity_flip_physical{52.0}=0x0
phy_chain_tx_polarity_flip_physical{49.0}=0x1
phy_chain_tx_polarity_flip_physical{50.0}=0x1
phy_chain_tx_polarity_flip_physical{51.0}=0x0
phy_chain_tx_polarity_flip_physical{52.0}=0x1
#Port11
#FC14
portmap_15=57:100
phy_chain_rx_lane_map_physical{57.0}=0x3210
phy_chain_tx_lane_map_physical{57.0}=0x1302
phy_chain_rx_polarity_flip_physical{57.0}=0x1
phy_chain_rx_polarity_flip_physical{58.0}=0x0
phy_chain_rx_polarity_flip_physical{59.0}=0x1
phy_chain_rx_polarity_flip_physical{60.0}=0x0
phy_chain_tx_polarity_flip_physical{57.0}=0x0
phy_chain_tx_polarity_flip_physical{58.0}=0x0
phy_chain_tx_polarity_flip_physical{59.0}=0x0
phy_chain_tx_polarity_flip_physical{60.0}=0x1
#Port12
#FC34
portmap_70=137:100
phy_chain_rx_lane_map_physical{137.0}=0x3210
phy_chain_tx_lane_map_physical{137.0}=0x0213
phy_chain_rx_polarity_flip_physical{137.0}=0x0
phy_chain_rx_polarity_flip_physical{138.0}=0x0
phy_chain_rx_polarity_flip_physical{139.0}=0x1
phy_chain_rx_polarity_flip_physical{140.0}=0x0
phy_chain_tx_polarity_flip_physical{137.0}=0x1
phy_chain_tx_polarity_flip_physical{138.0}=0x0
phy_chain_tx_polarity_flip_physical{139.0}=0x0
phy_chain_tx_polarity_flip_physical{140.0}=0x0
#Port13
#FC32
portmap_68=129:100
phy_chain_rx_lane_map_physical{129.0}=0x3021
phy_chain_tx_lane_map_physical{129.0}=0x1203
phy_chain_rx_polarity_flip_physical{129.0}=0x1
phy_chain_rx_polarity_flip_physical{130.0}=0x0
phy_chain_rx_polarity_flip_physical{131.0}=0x0
phy_chain_rx_polarity_flip_physical{132.0}=0x0
phy_chain_tx_polarity_flip_physical{129.0}=0x1
phy_chain_tx_polarity_flip_physical{130.0}=0x1
phy_chain_tx_polarity_flip_physical{131.0}=0x1
phy_chain_tx_polarity_flip_physical{132.0}=0x1
#Port14
#FC36
portmap_72=145:100
phy_chain_rx_lane_map_physical{145.0}=0x0213
phy_chain_tx_lane_map_physical{145.0}=0x2301
phy_chain_rx_polarity_flip_physical{145.0}=0x1
phy_chain_rx_polarity_flip_physical{146.0}=0x1
phy_chain_rx_polarity_flip_physical{147.0}=0x0
phy_chain_rx_polarity_flip_physical{148.0}=0x0
phy_chain_tx_polarity_flip_physical{145.0}=0x0
phy_chain_tx_polarity_flip_physical{146.0}=0x0
phy_chain_tx_polarity_flip_physical{147.0}=0x0
phy_chain_tx_polarity_flip_physical{148.0}=0x1
#Port15
#FC38
portmap_74=153:100
phy_chain_rx_lane_map_physical{153.0}=0x0213
phy_chain_tx_lane_map_physical{153.0}=0x1302
phy_chain_rx_polarity_flip_physical{153.0}=0x1
phy_chain_rx_polarity_flip_physical{154.0}=0x0
phy_chain_rx_polarity_flip_physical{155.0}=0x1
phy_chain_rx_polarity_flip_physical{156.0}=0x1
phy_chain_tx_polarity_flip_physical{153.0}=0x0
phy_chain_tx_polarity_flip_physical{154.0}=0x1
phy_chain_tx_polarity_flip_physical{155.0}=0x0
phy_chain_tx_polarity_flip_physical{156.0}=0x0
#Port16
#FC43
portmap_79=173:100
phy_chain_rx_lane_map_physical{173.0}=0x1032
phy_chain_tx_lane_map_physical{173.0}=0x1203
phy_chain_rx_polarity_flip_physical{173.0}=0x0
phy_chain_rx_polarity_flip_physical{174.0}=0x0
phy_chain_rx_polarity_flip_physical{175.0}=0x0
phy_chain_rx_polarity_flip_physical{176.0}=0x0
phy_chain_tx_polarity_flip_physical{173.0}=0x1
phy_chain_tx_polarity_flip_physical{174.0}=0x1
phy_chain_tx_polarity_flip_physical{175.0}=0x0
phy_chain_tx_polarity_flip_physical{176.0}=0x1
#Port17
#FC41
portmap_77=165:100
phy_chain_rx_lane_map_physical{165.0}=0x1230
phy_chain_tx_lane_map_physical{165.0}=0x2130
phy_chain_rx_polarity_flip_physical{165.0}=0x1
phy_chain_rx_polarity_flip_physical{166.0}=0x0
phy_chain_rx_polarity_flip_physical{167.0}=0x1
phy_chain_rx_polarity_flip_physical{168.0}=0x1
phy_chain_tx_polarity_flip_physical{165.0}=0x1
phy_chain_tx_polarity_flip_physical{166.0}=0x0
phy_chain_tx_polarity_flip_physical{167.0}=0x1
phy_chain_tx_polarity_flip_physical{168.0}=0x0
#Port18
#FC45
portmap_81=181:100
phy_chain_rx_lane_map_physical{181.0}=0x0312
phy_chain_tx_lane_map_physical{181.0}=0x3120
phy_chain_rx_polarity_flip_physical{181.0}=0x0
phy_chain_rx_polarity_flip_physical{182.0}=0x1
phy_chain_rx_polarity_flip_physical{183.0}=0x1
phy_chain_rx_polarity_flip_physical{184.0}=0x0
phy_chain_tx_polarity_flip_physical{181.0}=0x0
phy_chain_tx_polarity_flip_physical{182.0}=0x0
phy_chain_tx_polarity_flip_physical{183.0}=0x1
phy_chain_tx_polarity_flip_physical{184.0}=0x0
#Port19
#FC47
portmap_83=189:100
phy_chain_rx_lane_map_physical{189.0}=0x0132
phy_chain_tx_lane_map_physical{189.0}=0x3210
phy_chain_rx_polarity_flip_physical{189.0}=0x0
phy_chain_rx_polarity_flip_physical{190.0}=0x1
phy_chain_rx_polarity_flip_physical{191.0}=0x1
phy_chain_rx_polarity_flip_physical{192.0}=0x1
phy_chain_tx_polarity_flip_physical{189.0}=0x1
phy_chain_tx_polarity_flip_physical{190.0}=0x0
phy_chain_tx_polarity_flip_physical{191.0}=0x0
phy_chain_tx_polarity_flip_physical{192.0}=0x0
#Port20
#FC3
portmap_4=13:100
phy_chain_rx_lane_map_physical{13.0}=0x3120
phy_chain_tx_lane_map_physical{13.0}=0x3210
phy_chain_rx_polarity_flip_physical{13.0}=0x1
phy_chain_rx_polarity_flip_physical{14.0}=0x0
phy_chain_rx_polarity_flip_physical{15.0}=0x1
phy_chain_rx_polarity_flip_physical{16.0}=0x1
phy_chain_tx_polarity_flip_physical{13.0}=0x0
phy_chain_tx_polarity_flip_physical{14.0}=0x0
phy_chain_tx_polarity_flip_physical{15.0}=0x0
phy_chain_tx_polarity_flip_physical{16.0}=0x1
#Port21
#FC1
portmap_2=5:100
phy_chain_rx_lane_map_physical{5.0}=0x0213
phy_chain_tx_lane_map_physical{5.0}=0x0321
phy_chain_rx_polarity_flip_physical{5.0}=0x0
phy_chain_rx_polarity_flip_physical{6.0}=0x0
phy_chain_rx_polarity_flip_physical{7.0}=0x1
phy_chain_rx_polarity_flip_physical{8.0}=0x0
phy_chain_tx_polarity_flip_physical{5.0}=0x1
phy_chain_tx_polarity_flip_physical{6.0}=0x1
phy_chain_tx_polarity_flip_physical{7.0}=0x0
phy_chain_tx_polarity_flip_physical{8.0}=0x1
#Port22
#FC7
portmap_8=29:100
phy_chain_rx_lane_map_physical{29.0}=0x3021
phy_chain_tx_lane_map_physical{29.0}=0x2130
phy_chain_rx_polarity_flip_physical{29.0}=0x1
phy_chain_rx_polarity_flip_physical{30.0}=0x0
phy_chain_rx_polarity_flip_physical{31.0}=0x0
phy_chain_rx_polarity_flip_physical{32.0}=0x1
phy_chain_tx_polarity_flip_physical{29.0}=0x1
phy_chain_tx_polarity_flip_physical{30.0}=0x0
phy_chain_tx_polarity_flip_physical{31.0}=0x0
phy_chain_tx_polarity_flip_physical{32.0}=0x0
#Port23
#FC5
portmap_6=21:100
phy_chain_rx_lane_map_physical{21.0}=0x0321
phy_chain_tx_lane_map_physical{21.0}=0x0123
phy_chain_rx_polarity_flip_physical{21.0}=0x1
phy_chain_rx_polarity_flip_physical{22.0}=0x0
phy_chain_rx_polarity_flip_physical{23.0}=0x1
phy_chain_rx_polarity_flip_physical{24.0}=0x0
phy_chain_tx_polarity_flip_physical{21.0}=0x0
phy_chain_tx_polarity_flip_physical{22.0}=0x1
phy_chain_tx_polarity_flip_physical{23.0}=0x1
phy_chain_tx_polarity_flip_physical{24.0}=0x1
#Port24
#FC51
portmap_105=205:100
phy_chain_rx_lane_map_physical{205.0}=0x0132
phy_chain_tx_lane_map_physical{205.0}=0x1230
phy_chain_rx_polarity_flip_physical{205.0}=0x1
phy_chain_rx_polarity_flip_physical{206.0}=0x1
phy_chain_rx_polarity_flip_physical{207.0}=0x1
phy_chain_rx_polarity_flip_physical{208.0}=0x0
phy_chain_tx_polarity_flip_physical{205.0}=0x0
phy_chain_tx_polarity_flip_physical{206.0}=0x1
phy_chain_tx_polarity_flip_physical{207.0}=0x0
phy_chain_tx_polarity_flip_physical{208.0}=0x1
#Port25
#FC49
portmap_103=197:100
phy_chain_rx_lane_map_physical{197.0}=0x1230
phy_chain_tx_lane_map_physical{197.0}=0x3021
phy_chain_rx_polarity_flip_physical{197.0}=0x0
phy_chain_rx_polarity_flip_physical{198.0}=0x0
phy_chain_rx_polarity_flip_physical{199.0}=0x0
phy_chain_rx_polarity_flip_physical{200.0}=0x0
phy_chain_tx_polarity_flip_physical{197.0}=0x1
phy_chain_tx_polarity_flip_physical{198.0}=0x0
phy_chain_tx_polarity_flip_physical{199.0}=0x1
phy_chain_tx_polarity_flip_physical{200.0}=0x0
#Port26
#FC53
portmap_107=213:100
phy_chain_rx_lane_map_physical{213.0}=0x3210
phy_chain_tx_lane_map_physical{213.0}=0x1230
phy_chain_rx_polarity_flip_physical{213.0}=0x0
phy_chain_rx_polarity_flip_physical{214.0}=0x1
phy_chain_rx_polarity_flip_physical{215.0}=0x0
phy_chain_rx_polarity_flip_physical{216.0}=0x1
phy_chain_tx_polarity_flip_physical{213.0}=0x0
phy_chain_tx_polarity_flip_physical{214.0}=0x0
phy_chain_tx_polarity_flip_physical{215.0}=0x0
phy_chain_tx_polarity_flip_physical{216.0}=0x1
#Port27
#FC55
portmap_109=221:100
phy_chain_rx_lane_map_physical{221.0}=0x3210
phy_chain_tx_lane_map_physical{221.0}=0x3210
phy_chain_rx_polarity_flip_physical{221.0}=0x1
phy_chain_rx_polarity_flip_physical{222.0}=0x1
phy_chain_rx_polarity_flip_physical{223.0}=0x0
phy_chain_rx_polarity_flip_physical{224.0}=0x0
phy_chain_tx_polarity_flip_physical{221.0}=0x0
phy_chain_tx_polarity_flip_physical{222.0}=0x0
phy_chain_tx_polarity_flip_physical{223.0}=0x0
phy_chain_tx_polarity_flip_physical{224.0}=0x0
#Port28
#FC57
portmap_111=229:100
phy_chain_rx_lane_map_physical{229.0}=0x2301
phy_chain_tx_lane_map_physical{229.0}=0x3210
phy_chain_rx_polarity_flip_physical{229.0}=0x1
phy_chain_rx_polarity_flip_physical{230.0}=0x1
phy_chain_rx_polarity_flip_physical{231.0}=0x0
phy_chain_rx_polarity_flip_physical{232.0}=0x1
phy_chain_tx_polarity_flip_physical{229.0}=0x0
phy_chain_tx_polarity_flip_physical{230.0}=0x1
phy_chain_tx_polarity_flip_physical{231.0}=0x0
phy_chain_tx_polarity_flip_physical{232.0}=0x0
#Port29
#FC59
portmap_113=237:100
phy_chain_rx_lane_map_physical{237.0}=0x0123
phy_chain_tx_lane_map_physical{237.0}=0x3210
phy_chain_rx_polarity_flip_physical{237.0}=0x1
phy_chain_rx_polarity_flip_physical{238.0}=0x0
phy_chain_rx_polarity_flip_physical{239.0}=0x1
phy_chain_rx_polarity_flip_physical{240.0}=0x1
phy_chain_tx_polarity_flip_physical{237.0}=0x1
phy_chain_tx_polarity_flip_physical{238.0}=0x1
phy_chain_tx_polarity_flip_physical{239.0}=0x0
phy_chain_tx_polarity_flip_physical{240.0}=0x0
#Port30
#FC61
portmap_115=245:100
phy_chain_rx_lane_map_physical{245.0}=0x0213
phy_chain_tx_lane_map_physical{245.0}=0x3210
phy_chain_rx_polarity_flip_physical{245.0}=0x0
phy_chain_rx_polarity_flip_physical{246.0}=0x0
phy_chain_rx_polarity_flip_physical{247.0}=0x1
phy_chain_rx_polarity_flip_physical{248.0}=0x1
phy_chain_tx_polarity_flip_physical{245.0}=0x1
phy_chain_tx_polarity_flip_physical{246.0}=0x0
phy_chain_tx_polarity_flip_physical{247.0}=0x1
phy_chain_tx_polarity_flip_physical{248.0}=0x0
#Port31
#FC63
portmap_117=253:100
phy_chain_rx_lane_map_physical{253.0}=0x0213
phy_chain_tx_lane_map_physical{253.0}=0x0312
phy_chain_rx_polarity_flip_physical{253.0}=0x0
phy_chain_rx_polarity_flip_physical{254.0}=0x0
phy_chain_rx_polarity_flip_physical{255.0}=0x0
phy_chain_rx_polarity_flip_physical{256.0}=0x1
phy_chain_tx_polarity_flip_physical{253.0}=0x0
phy_chain_tx_polarity_flip_physical{254.0}=0x1
phy_chain_tx_polarity_flip_physical{255.0}=0x0
phy_chain_tx_polarity_flip_physical{256.0}=0x0
#Port32
#FC17
portmap_35=69:100
phy_chain_rx_lane_map_physical{69.0}=0x1032
phy_chain_tx_lane_map_physical{69.0}=0x3102
phy_chain_rx_polarity_flip_physical{69.0}=0x1
phy_chain_rx_polarity_flip_physical{70.0}=0x0
phy_chain_rx_polarity_flip_physical{71.0}=0x0
phy_chain_rx_polarity_flip_physical{72.0}=0x1
phy_chain_tx_polarity_flip_physical{69.0}=0x0
phy_chain_tx_polarity_flip_physical{70.0}=0x0
phy_chain_tx_polarity_flip_physical{71.0}=0x1
phy_chain_tx_polarity_flip_physical{72.0}=0x1
#Port33
#FC19
portmap_37=77:100
phy_chain_rx_lane_map_physical{77.0}=0x1230
phy_chain_tx_lane_map_physical{77.0}=0x3021
phy_chain_rx_polarity_flip_physical{77.0}=0x1
phy_chain_rx_polarity_flip_physical{78.0}=0x0
phy_chain_rx_polarity_flip_physical{79.0}=0x1
phy_chain_rx_polarity_flip_physical{80.0}=0x0
phy_chain_tx_polarity_flip_physical{77.0}=0x0
phy_chain_tx_polarity_flip_physical{78.0}=0x0
phy_chain_tx_polarity_flip_physical{79.0}=0x1
phy_chain_tx_polarity_flip_physical{80.0}=0x0
#Port34
#FC23
portmap_41=93:100
phy_chain_rx_lane_map_physical{93.0}=0x1032
phy_chain_tx_lane_map_physical{93.0}=0x0231
phy_chain_rx_polarity_flip_physical{93.0}=0x1
phy_chain_rx_polarity_flip_physical{94.0}=0x1
phy_chain_rx_polarity_flip_physical{95.0}=0x1
phy_chain_rx_polarity_flip_physical{96.0}=0x1
phy_chain_tx_polarity_flip_physical{93.0}=0x0
phy_chain_tx_polarity_flip_physical{94.0}=0x1
phy_chain_tx_polarity_flip_physical{95.0}=0x1
phy_chain_tx_polarity_flip_physical{96.0}=0x1
#Port35
#FC21
portmap_39=85:100
phy_chain_rx_lane_map_physical{85.0}=0x0312
phy_chain_tx_lane_map_physical{85.0}=0x1230
phy_chain_rx_polarity_flip_physical{85.0}=0x0
phy_chain_rx_polarity_flip_physical{86.0}=0x0
phy_chain_rx_polarity_flip_physical{87.0}=0x0
phy_chain_rx_polarity_flip_physical{88.0}=0x1
phy_chain_tx_polarity_flip_physical{85.0}=0x1
phy_chain_tx_polarity_flip_physical{86.0}=0x0
phy_chain_tx_polarity_flip_physical{87.0}=0x1
phy_chain_tx_polarity_flip_physical{88.0}=0x0
#Port36
#FC25
portmap_43=101:100
phy_chain_rx_lane_map_physical{101.0}=0x1302
phy_chain_tx_lane_map_physical{101.0}=0x0213
phy_chain_rx_polarity_flip_physical{101.0}=0x1
phy_chain_rx_polarity_flip_physical{102.0}=0x0
phy_chain_rx_polarity_flip_physical{103.0}=0x0
phy_chain_rx_polarity_flip_physical{104.0}=0x0
phy_chain_tx_polarity_flip_physical{101.0}=0x0
phy_chain_tx_polarity_flip_physical{102.0}=0x1
phy_chain_tx_polarity_flip_physical{103.0}=0x0
phy_chain_tx_polarity_flip_physical{104.0}=0x1
#Port37
#FC27
portmap_45=109:100
phy_chain_rx_lane_map_physical{109.0}=0x0213
phy_chain_tx_lane_map_physical{109.0}=0x1032
phy_chain_rx_polarity_flip_physical{109.0}=0x1
phy_chain_rx_polarity_flip_physical{110.0}=0x1
phy_chain_rx_polarity_flip_physical{111.0}=0x0
phy_chain_rx_polarity_flip_physical{112.0}=0x0
phy_chain_tx_polarity_flip_physical{109.0}=0x0
phy_chain_tx_polarity_flip_physical{110.0}=0x1
phy_chain_tx_polarity_flip_physical{111.0}=0x1
phy_chain_tx_polarity_flip_physical{112.0}=0x1
#Port38
#FC31
portmap_49=125:100
phy_chain_rx_lane_map_physical{125.0}=0x2130
phy_chain_tx_lane_map_physical{125.0}=0x1203
phy_chain_rx_polarity_flip_physical{125.0}=0x0
phy_chain_rx_polarity_flip_physical{126.0}=0x0
phy_chain_rx_polarity_flip_physical{127.0}=0x1
phy_chain_rx_polarity_flip_physical{128.0}=0x1
phy_chain_tx_polarity_flip_physical{125.0}=0x0
phy_chain_tx_polarity_flip_physical{126.0}=0x1
phy_chain_tx_polarity_flip_physical{127.0}=0x1
phy_chain_tx_polarity_flip_physical{128.0}=0x1
#Port39
#FC29
portmap_47=117:100
phy_chain_rx_lane_map_physical{117.0}=0x3102
phy_chain_tx_lane_map_physical{117.0}=0x2310
phy_chain_rx_polarity_flip_physical{117.0}=0x1
phy_chain_rx_polarity_flip_physical{118.0}=0x0
phy_chain_rx_polarity_flip_physical{119.0}=0x1
phy_chain_rx_polarity_flip_physical{120.0}=0x0
phy_chain_tx_polarity_flip_physical{117.0}=0x1
phy_chain_tx_polarity_flip_physical{118.0}=0x0
phy_chain_tx_polarity_flip_physical{119.0}=0x1
phy_chain_tx_polarity_flip_physical{120.0}=0x0
#Port40
#FC9
portmap_10=37:100
phy_chain_rx_lane_map_physical{37.0}=0x3210
phy_chain_tx_lane_map_physical{37.0}=0x1302
phy_chain_rx_polarity_flip_physical{37.0}=0x1
phy_chain_rx_polarity_flip_physical{38.0}=0x0
phy_chain_rx_polarity_flip_physical{39.0}=0x0
phy_chain_rx_polarity_flip_physical{40.0}=0x0
phy_chain_tx_polarity_flip_physical{37.0}=0x1
phy_chain_tx_polarity_flip_physical{38.0}=0x0
phy_chain_tx_polarity_flip_physical{39.0}=0x1
phy_chain_tx_polarity_flip_physical{40.0}=0x1
#Port41
#FC11
portmap_12=45:100
phy_chain_rx_lane_map_physical{45.0}=0x3210
phy_chain_tx_lane_map_physical{45.0}=0x0123
phy_chain_rx_polarity_flip_physical{45.0}=0x0
phy_chain_rx_polarity_flip_physical{46.0}=0x0
phy_chain_rx_polarity_flip_physical{47.0}=0x0
phy_chain_rx_polarity_flip_physical{48.0}=0x0
phy_chain_tx_polarity_flip_physical{45.0}=0x0
phy_chain_tx_polarity_flip_physical{46.0}=0x1
phy_chain_tx_polarity_flip_physical{47.0}=0x0
phy_chain_tx_polarity_flip_physical{48.0}=0x1
#Port42
#FC15
portmap_16=61:100
phy_chain_rx_lane_map_physical{61.0}=0x3210
phy_chain_tx_lane_map_physical{61.0}=0x1230
phy_chain_rx_polarity_flip_physical{61.0}=0x0
phy_chain_rx_polarity_flip_physical{62.0}=0x1
phy_chain_rx_polarity_flip_physical{63.0}=0x0
phy_chain_rx_polarity_flip_physical{64.0}=0x0
phy_chain_tx_polarity_flip_physical{61.0}=0x0
phy_chain_tx_polarity_flip_physical{62.0}=0x1
phy_chain_tx_polarity_flip_physical{63.0}=0x1
phy_chain_tx_polarity_flip_physical{64.0}=0x0
#Port43
#FC13
portmap_14=53:100
phy_chain_rx_lane_map_physical{53.0}=0x3210
phy_chain_tx_lane_map_physical{53.0}=0x3210
phy_chain_rx_polarity_flip_physical{53.0}=0x0
phy_chain_rx_polarity_flip_physical{54.0}=0x0
phy_chain_rx_polarity_flip_physical{55.0}=0x1
phy_chain_rx_polarity_flip_physical{56.0}=0x0
phy_chain_tx_polarity_flip_physical{53.0}=0x1
phy_chain_tx_polarity_flip_physical{54.0}=0x1
phy_chain_tx_polarity_flip_physical{55.0}=0x1
phy_chain_tx_polarity_flip_physical{56.0}=0x0
#Port44
#FC33
portmap_69=133:100
phy_chain_rx_lane_map_physical{133.0}=0x0312
phy_chain_tx_lane_map_physical{133.0}=0x2310
phy_chain_rx_polarity_flip_physical{133.0}=0x0
phy_chain_rx_polarity_flip_physical{134.0}=0x0
phy_chain_rx_polarity_flip_physical{135.0}=0x1
phy_chain_rx_polarity_flip_physical{136.0}=0x0
phy_chain_tx_polarity_flip_physical{133.0}=0x0
phy_chain_tx_polarity_flip_physical{134.0}=0x1
phy_chain_tx_polarity_flip_physical{135.0}=0x0
phy_chain_tx_polarity_flip_physical{136.0}=0x1
#Port45
#FC35
portmap_71=141:100
phy_chain_rx_lane_map_physical{141.0}=0x3012
phy_chain_tx_lane_map_physical{141.0}=0x0123
phy_chain_rx_polarity_flip_physical{141.0}=0x1
phy_chain_rx_polarity_flip_physical{142.0}=0x0
phy_chain_rx_polarity_flip_physical{143.0}=0x1
phy_chain_rx_polarity_flip_physical{144.0}=0x0
phy_chain_tx_polarity_flip_physical{141.0}=0x1
phy_chain_tx_polarity_flip_physical{142.0}=0x1
phy_chain_tx_polarity_flip_physical{143.0}=0x0
phy_chain_tx_polarity_flip_physical{144.0}=0x0
#Port46
#FC39
portmap_75=157:100
phy_chain_rx_lane_map_physical{157.0}=0x2103
phy_chain_tx_lane_map_physical{157.0}=0x0231
phy_chain_rx_polarity_flip_physical{157.0}=0x0
phy_chain_rx_polarity_flip_physical{158.0}=0x0
phy_chain_rx_polarity_flip_physical{159.0}=0x1
phy_chain_rx_polarity_flip_physical{160.0}=0x0
phy_chain_tx_polarity_flip_physical{157.0}=0x0
phy_chain_tx_polarity_flip_physical{158.0}=0x1
phy_chain_tx_polarity_flip_physical{159.0}=0x0
phy_chain_tx_polarity_flip_physical{160.0}=0x0
#Port47
#FC37
portmap_73=149:100
phy_chain_rx_lane_map_physical{149.0}=0x3120
phy_chain_tx_lane_map_physical{149.0}=0x1023
phy_chain_rx_polarity_flip_physical{149.0}=0x0
phy_chain_rx_polarity_flip_physical{150.0}=0x1
phy_chain_rx_polarity_flip_physical{151.0}=0x0
phy_chain_rx_polarity_flip_physical{152.0}=0x0
phy_chain_tx_polarity_flip_physical{149.0}=0x1
phy_chain_tx_polarity_flip_physical{150.0}=0x0
phy_chain_tx_polarity_flip_physical{151.0}=0x0
phy_chain_tx_polarity_flip_physical{152.0}=0x1
#Port48
#FC40
portmap_76=161:100
phy_chain_rx_lane_map_physical{161.0}=0x3012
phy_chain_tx_lane_map_physical{161.0}=0x1023
phy_chain_rx_polarity_flip_physical{161.0}=0x1
phy_chain_rx_polarity_flip_physical{162.0}=0x1
phy_chain_rx_polarity_flip_physical{163.0}=0x0
phy_chain_rx_polarity_flip_physical{164.0}=0x0
phy_chain_tx_polarity_flip_physical{161.0}=0x0
phy_chain_tx_polarity_flip_physical{162.0}=0x1
phy_chain_tx_polarity_flip_physical{163.0}=0x0
phy_chain_tx_polarity_flip_physical{164.0}=0x0
#Port49
#FC42
portmap_78=169:100
phy_chain_rx_lane_map_physical{169.0}=0x3210
phy_chain_tx_lane_map_physical{169.0}=0x2031
phy_chain_rx_polarity_flip_physical{169.0}=0x0
phy_chain_rx_polarity_flip_physical{170.0}=0x1
phy_chain_rx_polarity_flip_physical{171.0}=0x0
phy_chain_rx_polarity_flip_physical{172.0}=0x0
phy_chain_tx_polarity_flip_physical{169.0}=0x1
phy_chain_tx_polarity_flip_physical{170.0}=0x0
phy_chain_tx_polarity_flip_physical{171.0}=0x0
phy_chain_tx_polarity_flip_physical{172.0}=0x0
#Port50
#FC46
portmap_82=185:100
phy_chain_rx_lane_map_physical{185.0}=0x2310
phy_chain_tx_lane_map_physical{185.0}=0x3021
phy_chain_rx_polarity_flip_physical{185.0}=0x1
phy_chain_rx_polarity_flip_physical{186.0}=0x0
phy_chain_rx_polarity_flip_physical{187.0}=0x1
phy_chain_rx_polarity_flip_physical{188.0}=0x0
phy_chain_tx_polarity_flip_physical{185.0}=0x0
phy_chain_tx_polarity_flip_physical{186.0}=0x1
phy_chain_tx_polarity_flip_physical{187.0}=0x0
phy_chain_tx_polarity_flip_physical{188.0}=0x0
#Port51
#FC44
portmap_80=177:100
phy_chain_rx_lane_map_physical{177.0}=0x1032
phy_chain_tx_lane_map_physical{177.0}=0x2301
phy_chain_rx_polarity_flip_physical{177.0}=0x1
phy_chain_rx_polarity_flip_physical{178.0}=0x1
phy_chain_rx_polarity_flip_physical{179.0}=0x0
phy_chain_rx_polarity_flip_physical{180.0}=0x1
phy_chain_tx_polarity_flip_physical{177.0}=0x1
phy_chain_tx_polarity_flip_physical{178.0}=0x1
phy_chain_tx_polarity_flip_physical{179.0}=0x1
phy_chain_tx_polarity_flip_physical{180.0}=0x0
#Port52
#FC6
portmap_7=25:100
phy_chain_rx_lane_map_physical{25.0}=0x3102
phy_chain_tx_lane_map_physical{25.0}=0x0132
phy_chain_rx_polarity_flip_physical{25.0}=0x0
phy_chain_rx_polarity_flip_physical{26.0}=0x0
phy_chain_rx_polarity_flip_physical{27.0}=0x1
phy_chain_rx_polarity_flip_physical{28.0}=0x0
phy_chain_tx_polarity_flip_physical{25.0}=0x0
phy_chain_tx_polarity_flip_physical{26.0}=0x1
phy_chain_tx_polarity_flip_physical{27.0}=0x0
phy_chain_tx_polarity_flip_physical{28.0}=0x1
#Port53
#FC4
portmap_5=17:100
phy_chain_rx_lane_map_physical{17.0}=0x3120
phy_chain_tx_lane_map_physical{17.0}=0x3021
phy_chain_rx_polarity_flip_physical{17.0}=0x0
phy_chain_rx_polarity_flip_physical{18.0}=0x1
phy_chain_rx_polarity_flip_physical{19.0}=0x0
phy_chain_rx_polarity_flip_physical{20.0}=0x0
phy_chain_tx_polarity_flip_physical{17.0}=0x0
phy_chain_tx_polarity_flip_physical{18.0}=0x0
phy_chain_tx_polarity_flip_physical{19.0}=0x1
phy_chain_tx_polarity_flip_physical{20.0}=0x0
#Port54
#FC0
portmap_1=1:100
phy_chain_rx_lane_map_physical{1.0}=0x2130
phy_chain_tx_lane_map_physical{1.0}=0x1203
phy_chain_rx_polarity_flip_physical{1.0}=0x1
phy_chain_rx_polarity_flip_physical{2.0}=0x0
phy_chain_rx_polarity_flip_physical{3.0}=0x1
phy_chain_rx_polarity_flip_physical{4.0}=0x1
phy_chain_tx_polarity_flip_physical{1.0}=0x0
phy_chain_tx_polarity_flip_physical{2.0}=0x0
phy_chain_tx_polarity_flip_physical{3.0}=0x0
phy_chain_tx_polarity_flip_physical{4.0}=0x1
#Port55
#FC2
portmap_3=9:100
phy_chain_rx_lane_map_physical{9.0}=0x1203
phy_chain_tx_lane_map_physical{9.0}=0x1230
phy_chain_rx_polarity_flip_physical{9.0}=0x0
phy_chain_rx_polarity_flip_physical{10.0}=0x1
phy_chain_rx_polarity_flip_physical{11.0}=0x0
phy_chain_rx_polarity_flip_physical{12.0}=0x0
phy_chain_tx_polarity_flip_physical{9.0}=0x1
phy_chain_tx_polarity_flip_physical{10.0}=0x0
phy_chain_tx_polarity_flip_physical{11.0}=0x1
phy_chain_tx_polarity_flip_physical{12.0}=0x0
#Port56
#FC48
portmap_102=193:100
phy_chain_rx_lane_map_physical{193.0}=0x2103
phy_chain_tx_lane_map_physical{193.0}=0x1230
phy_chain_rx_polarity_flip_physical{193.0}=0x0
phy_chain_rx_polarity_flip_physical{194.0}=0x1
phy_chain_rx_polarity_flip_physical{195.0}=0x0
phy_chain_rx_polarity_flip_physical{196.0}=0x1
phy_chain_tx_polarity_flip_physical{193.0}=0x0
phy_chain_tx_polarity_flip_physical{194.0}=0x0
phy_chain_tx_polarity_flip_physical{195.0}=0x1
phy_chain_tx_polarity_flip_physical{196.0}=0x0
#Port57
#FC50
portmap_104=201:100
phy_chain_rx_lane_map_physical{201.0}=0x0321
phy_chain_tx_lane_map_physical{201.0}=0x3021
phy_chain_rx_polarity_flip_physical{201.0}=0x0
phy_chain_rx_polarity_flip_physical{202.0}=0x0
phy_chain_rx_polarity_flip_physical{203.0}=0x1
phy_chain_rx_polarity_flip_physical{204.0}=0x0
phy_chain_tx_polarity_flip_physical{201.0}=0x1
phy_chain_tx_polarity_flip_physical{202.0}=0x1
phy_chain_tx_polarity_flip_physical{203.0}=0x0
phy_chain_tx_polarity_flip_physical{204.0}=0x1
#Port58
#FC54
portmap_108=217:100
phy_chain_rx_lane_map_physical{217.0}=0x1203
phy_chain_tx_lane_map_physical{217.0}=0x2031
phy_chain_rx_polarity_flip_physical{217.0}=0x1
phy_chain_rx_polarity_flip_physical{218.0}=0x0
phy_chain_rx_polarity_flip_physical{219.0}=0x1
phy_chain_rx_polarity_flip_physical{220.0}=0x1
phy_chain_tx_polarity_flip_physical{217.0}=0x1
phy_chain_tx_polarity_flip_physical{218.0}=0x0
phy_chain_tx_polarity_flip_physical{219.0}=0x1
phy_chain_tx_polarity_flip_physical{220.0}=0x0
#Port59
#FC52
portmap_106=209:100
phy_chain_rx_lane_map_physical{209.0}=0x0321
phy_chain_tx_lane_map_physical{209.0}=0x3102
phy_chain_rx_polarity_flip_physical{209.0}=0x0
phy_chain_rx_polarity_flip_physical{210.0}=0x0
phy_chain_rx_polarity_flip_physical{211.0}=0x1
phy_chain_rx_polarity_flip_physical{212.0}=0x0
phy_chain_tx_polarity_flip_physical{209.0}=0x0
phy_chain_tx_polarity_flip_physical{210.0}=0x0
phy_chain_tx_polarity_flip_physical{211.0}=0x1
phy_chain_tx_polarity_flip_physical{212.0}=0x0
#Port60
#FC56
portmap_110=225:100
phy_chain_rx_lane_map_physical{225.0}=0x2103
phy_chain_tx_lane_map_physical{225.0}=0x2031
phy_chain_rx_polarity_flip_physical{225.0}=0x0
phy_chain_rx_polarity_flip_physical{226.0}=0x0
phy_chain_rx_polarity_flip_physical{227.0}=0x1
phy_chain_rx_polarity_flip_physical{228.0}=0x1
phy_chain_tx_polarity_flip_physical{225.0}=0x1
phy_chain_tx_polarity_flip_physical{226.0}=0x0
phy_chain_tx_polarity_flip_physical{227.0}=0x1
phy_chain_tx_polarity_flip_physical{228.0}=0x1
#Port61
#FC58
portmap_112=233:100
phy_chain_rx_lane_map_physical{233.0}=0x2130
phy_chain_tx_lane_map_physical{233.0}=0x0312
phy_chain_rx_polarity_flip_physical{233.0}=0x0
phy_chain_rx_polarity_flip_physical{234.0}=0x1
phy_chain_rx_polarity_flip_physical{235.0}=0x1
phy_chain_rx_polarity_flip_physical{236.0}=0x0
phy_chain_tx_polarity_flip_physical{233.0}=0x0
phy_chain_tx_polarity_flip_physical{234.0}=0x0
phy_chain_tx_polarity_flip_physical{235.0}=0x1
phy_chain_tx_polarity_flip_physical{236.0}=0x0
#Port62
#FC62
portmap_116=249:100
phy_chain_rx_lane_map_physical{249.0}=0x1302
phy_chain_tx_lane_map_physical{249.0}=0x1302
phy_chain_rx_polarity_flip_physical{249.0}=0x0
phy_chain_rx_polarity_flip_physical{250.0}=0x1
phy_chain_rx_polarity_flip_physical{251.0}=0x0
phy_chain_rx_polarity_flip_physical{252.0}=0x1
phy_chain_tx_polarity_flip_physical{249.0}=0x1
phy_chain_tx_polarity_flip_physical{250.0}=0x1
phy_chain_tx_polarity_flip_physical{251.0}=0x1
phy_chain_tx_polarity_flip_physical{252.0}=0x1
#Port63
#FC60
portmap_114=241:100
phy_chain_rx_lane_map_physical{241.0}=0x3012
phy_chain_tx_lane_map_physical{241.0}=0x2301
phy_chain_rx_polarity_flip_physical{241.0}=0x1
phy_chain_rx_polarity_flip_physical{242.0}=0x1
phy_chain_rx_polarity_flip_physical{243.0}=0x0
phy_chain_rx_polarity_flip_physical{244.0}=0x1
phy_chain_tx_polarity_flip_physical{241.0}=0x1
phy_chain_tx_polarity_flip_physical{242.0}=0x0
phy_chain_tx_polarity_flip_physical{243.0}=0x1
phy_chain_tx_polarity_flip_physical{244.0}=0x0

View File

@ -0,0 +1 @@
Juniper-QFX5210-64C t1

View File

@ -0,0 +1,2 @@
CONSOLE_SPEED=9600
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="tg3.short_preamble=1 tg3.bcm5718s_reset=1"

View File

@ -0,0 +1,155 @@
m CMIC_LEDUP0_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000
m CMIC_LEDUP1_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000
m CMIC_LEDUP2_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000
m CMIC_LEDUP3_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000
m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=63 REMAP_PORT_1=62 REMAP_PORT_2=61 REMAP_PORT_3=60
m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=59 REMAP_PORT_5=58 REMAP_PORT_6=57 REMAP_PORT_7=56
m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=55 REMAP_PORT_9=54 REMAP_PORT_10=53 REMAP_PORT_11=52
m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=51 REMAP_PORT_13=50 REMAP_PORT_14=49 REMAP_PORT_15=48
m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 REMAP_PORT_17=46 REMAP_PORT_18=45 REMAP_PORT_19=44
m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 REMAP_PORT_21=42 REMAP_PORT_22=41 REMAP_PORT_23=40
m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 REMAP_PORT_25=38 REMAP_PORT_26=37 REMAP_PORT_27=36
m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 REMAP_PORT_29=34 REMAP_PORT_30=33 REMAP_PORT_31=32
m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=31 REMAP_PORT_33=30 REMAP_PORT_34=29 REMAP_PORT_35=28
m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=27 REMAP_PORT_37=26 REMAP_PORT_38=25 REMAP_PORT_39=24
m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=23 REMAP_PORT_41=22 REMAP_PORT_42=21 REMAP_PORT_43=20
m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=19 REMAP_PORT_45=18 REMAP_PORT_46=17 REMAP_PORT_47=16
m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 REMAP_PORT_49=14 REMAP_PORT_50=13 REMAP_PORT_51=12
m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 REMAP_PORT_53=10 REMAP_PORT_54=9 REMAP_PORT_55=8
m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 REMAP_PORT_57=6 REMAP_PORT_58=5 REMAP_PORT_59=4
m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 REMAP_PORT_61=2 REMAP_PORT_62=1 REMAP_PORT_63=0
m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=3 REMAP_PORT_1=2 REMAP_PORT_2=1 REMAP_PORT_3=0
m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=7 REMAP_PORT_5=6 REMAP_PORT_6=5 REMAP_PORT_7=4
m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=11 REMAP_PORT_9=10 REMAP_PORT_10=9 REMAP_PORT_11=8
m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=15 REMAP_PORT_13=14 REMAP_PORT_14=13 REMAP_PORT_15=12
m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=19 REMAP_PORT_17=18 REMAP_PORT_18=17 REMAP_PORT_19=16
m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=23 REMAP_PORT_21=22 REMAP_PORT_22=21 REMAP_PORT_23=20
m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=27 REMAP_PORT_25=26 REMAP_PORT_26=25 REMAP_PORT_27=24
m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=31 REMAP_PORT_29=30 REMAP_PORT_30=29 REMAP_PORT_31=28
m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=35 REMAP_PORT_33=34 REMAP_PORT_34=33 REMAP_PORT_35=32
m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=39 REMAP_PORT_37=38 REMAP_PORT_38=37 REMAP_PORT_39=36
m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=43 REMAP_PORT_41=42 REMAP_PORT_42=41 REMAP_PORT_43=40
m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=47 REMAP_PORT_45=46 REMAP_PORT_46=45 REMAP_PORT_47=44
m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=51 REMAP_PORT_49=50 REMAP_PORT_50=49 REMAP_PORT_51=48
m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=55 REMAP_PORT_53=54 REMAP_PORT_54=53 REMAP_PORT_55=52
m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=59 REMAP_PORT_57=58 REMAP_PORT_58=57 REMAP_PORT_59=56
m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60
m CMIC_LEDUP2_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=63 REMAP_PORT_1=62 REMAP_PORT_2=61 REMAP_PORT_3=60
m CMIC_LEDUP2_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=59 REMAP_PORT_5=58 REMAP_PORT_6=57 REMAP_PORT_7=56
m CMIC_LEDUP2_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=55 REMAP_PORT_9=54 REMAP_PORT_10=53 REMAP_PORT_11=52
m CMIC_LEDUP2_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=51 REMAP_PORT_13=50 REMAP_PORT_14=49 REMAP_PORT_15=48
m CMIC_LEDUP2_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 REMAP_PORT_17=46 REMAP_PORT_18=45 REMAP_PORT_19=44
m CMIC_LEDUP2_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 REMAP_PORT_21=42 REMAP_PORT_22=41 REMAP_PORT_23=40
m CMIC_LEDUP2_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 REMAP_PORT_25=38 REMAP_PORT_26=37 REMAP_PORT_27=36
m CMIC_LEDUP2_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 REMAP_PORT_29=34 REMAP_PORT_30=33 REMAP_PORT_31=32
m CMIC_LEDUP2_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=31 REMAP_PORT_33=30 REMAP_PORT_34=29 REMAP_PORT_35=28
m CMIC_LEDUP2_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=27 REMAP_PORT_37=26 REMAP_PORT_38=25 REMAP_PORT_39=24
m CMIC_LEDUP2_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=23 REMAP_PORT_41=22 REMAP_PORT_42=21 REMAP_PORT_43=20
m CMIC_LEDUP2_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=19 REMAP_PORT_45=18 REMAP_PORT_46=17 REMAP_PORT_47=16
m CMIC_LEDUP2_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 REMAP_PORT_49=14 REMAP_PORT_50=13 REMAP_PORT_51=12
m CMIC_LEDUP2_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 REMAP_PORT_53=10 REMAP_PORT_54=9 REMAP_PORT_55=8
m CMIC_LEDUP2_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 REMAP_PORT_57=6 REMAP_PORT_58=5 REMAP_PORT_59=4
m CMIC_LEDUP2_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 REMAP_PORT_61=2 REMAP_PORT_62=1 REMAP_PORT_63=0
m CMIC_LEDUP3_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=3 REMAP_PORT_1=2 REMAP_PORT_2=1 REMAP_PORT_3=0
m CMIC_LEDUP3_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=7 REMAP_PORT_5=6 REMAP_PORT_6=5 REMAP_PORT_7=4
m CMIC_LEDUP3_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=11 REMAP_PORT_9=10 REMAP_PORT_10=9 REMAP_PORT_11=8
m CMIC_LEDUP3_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=15 REMAP_PORT_13=14 REMAP_PORT_14=13 REMAP_PORT_15=12
m CMIC_LEDUP3_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=19 REMAP_PORT_17=18 REMAP_PORT_18=17 REMAP_PORT_19=16
m CMIC_LEDUP3_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=23 REMAP_PORT_21=22 REMAP_PORT_22=21 REMAP_PORT_23=20
m CMIC_LEDUP3_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=27 REMAP_PORT_25=26 REMAP_PORT_26=25 REMAP_PORT_27=24
m CMIC_LEDUP3_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=31 REMAP_PORT_29=30 REMAP_PORT_30=29 REMAP_PORT_31=28
m CMIC_LEDUP3_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=35 REMAP_PORT_33=34 REMAP_PORT_34=33 REMAP_PORT_35=32
m CMIC_LEDUP3_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=39 REMAP_PORT_37=38 REMAP_PORT_38=37 REMAP_PORT_39=36
m CMIC_LEDUP3_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=43 REMAP_PORT_41=42 REMAP_PORT_42=41 REMAP_PORT_43=40
m CMIC_LEDUP3_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=47 REMAP_PORT_45=46 REMAP_PORT_46=45 REMAP_PORT_47=44
m CMIC_LEDUP3_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=51 REMAP_PORT_49=50 REMAP_PORT_50=49 REMAP_PORT_51=48
m CMIC_LEDUP3_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=55 REMAP_PORT_53=54 REMAP_PORT_54=53 REMAP_PORT_55=52
m CMIC_LEDUP3_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=59 REMAP_PORT_57=58 REMAP_PORT_58=57 REMAP_PORT_59=56
m CMIC_LEDUP3_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60
led 0 stop
led 0 prog \
02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \
02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \
67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \
86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \
3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \
98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \
4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \
F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \
71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \
52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \
74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \
98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \
88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \
88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \
84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
led 1 stop
led 1 prog \
02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \
02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \
67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \
86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \
3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \
98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \
4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \
F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \
71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \
52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \
74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \
98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \
88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \
88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \
84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
led 2 stop
led 2 prog \
02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \
02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \
67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \
86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \
3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \
98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \
4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \
F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \
71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \
52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \
74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \
98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \
88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \
88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \
84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
led 3 stop
led 3 prog \
02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \
02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \
67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \
86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \
3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \
98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \
4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \
F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \
71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \
52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \
74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \
98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \
88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \
88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \
84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
led auto on
led 0 start
led 1 start
led 2 start
led 3 start

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
#!/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
import subprocess
import syslog
from struct import *
from array import *
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
SYSLOG_IDENTIFIER = "eeprom.py"
EEPROM_PATH = "/sys/bus/i2c/devices/0-0056/eeprom"
def log_error(msg):
syslog.openlog(SYSLOG_IDENTIFIER)
syslog.syslog(syslog.LOG_ERR, msg)
syslog.closelog()
class board(eeprom_tlvinfo.TlvInfoDecoder):
_TLV_INFO_MAX_LEN = 256
def __init__(self, name, path, cpld_root, ro):
if not os.path.exists(EEPROM_PATH):
log_error("Cannot find system eeprom")
raise RuntimeError("No syseeprom found")
self.eeprom_path = EEPROM_PATH
super(board, self).__init__(self.eeprom_path, 0, '', True)

View File

@ -0,0 +1,61 @@
#!/usr/bin/env python
#############################################################################
# Accton
#
# Module contains an implementation of SONiC PSU Base API and
# provides the PSUs status which are available in the platform
#
#############################################################################
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)
self.psu_path = "/sys/bus/i2c/devices/"
self.psu_presence = "/psu_present"
self.psu_oper_status = "/psu_power_good"
self.psu_mapping = {
1: "10-0053",
2: "9-0050",
}
def get_num_psus(self):
return len(self.psu_mapping)
def get_psu_status(self, index):
if index is None:
return False
status = 0
node = self.psu_path + self.psu_mapping[index]+self.psu_oper_status
try:
with open(node, 'r') as power_status:
status = int(power_status.read())
except IOError:
return False
return status == 1
def get_psu_presence(self, index):
if index is None:
return False
status = 0
node = self.psu_path + self.psu_mapping[index] + self.psu_presence
try:
with open(node, 'r') as presence_status:
status = int(presence_status.read())
except IOError:
return False
return status == 1

View File

@ -0,0 +1,761 @@
#!/usr/bin/env python
try:
import time
from sonic_sfp.sfputilbase import *
import sys
import os
import string
from ctypes import create_string_buffer
# sys.path.append('/usr/local/bin')
# import sfp_detect
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
qfx5210_qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)',
'Length OM2(m)', 'Length OM1(m)',
'Length Cable Assembly(m)')
qfx5210_sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)')
qfx5210_sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode',
'ESCONComplianceCodes', 'SONETComplianceCodes',
'EthernetComplianceCodes','FibreChannelLinkLength',
'FibreChannelTechnology', 'SFP+CableTechnology',
'FibreChannelTransmissionMedia','FibreChannelSpeed')
qfx5210_qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes',
'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes',
'Fibre Channel link length/Transmitter Technology',
'Fibre Channel transmission media', 'Fibre Channel Speed')
class SfpUtil(SfpUtilBase):
"""Platform specific SfpUtill class"""
_port_start = 0
_port_end = 63
ports_in_block = 64
cmd = '/var/run/sfppresence'
_port_to_eeprom_mapping = {}
port_to_i2c_mapping = {
61 : 25,
62 : 26,
63 : 27,
64 : 28,
55 : 29,
56 : 30,
53 : 31,
54 : 32,
9 : 33,
10 : 34,
11 : 35,
12 : 36,
1 : 37,
2 : 38,
3 : 39,
4 : 40,
6 : 41,
5 : 42,
8 : 43,
7 : 44,
13 : 45,
14 : 46,
15 : 47,
16 : 48,
17 : 49,
18 : 50,
19 : 51,
20 : 52,
25 : 53,
26 : 54,
27 : 55,
28 : 56,
29 : 57,
30 : 58,
31 : 59,
32 : 60,
21 : 61,
22 : 62,
23 : 63,
24 : 64,
41 : 65,
42 : 66,
43 : 67,
44 : 68,
33 : 69,
34 : 70,
35 : 71,
36 : 72,
45 : 73,
46 : 74,
47 : 75,
48 : 76,
37 : 77,
38 : 78,
39 : 79,
40 : 80,
57 : 81,
58 : 82,
59 : 83,
60 : 84,
49 : 85,
50 : 86,
51 : 87,
52 : 88,}
port_to_sysfs_map = [
'/sys/bus/i2c/devices/37-0050/sfp_is_present',
'/sys/bus/i2c/devices/38-0050/sfp_is_present',
'/sys/bus/i2c/devices/39-0050/sfp_is_present',
'/sys/bus/i2c/devices/40-0050/sfp_is_present',
'/sys/bus/i2c/devices/42-0050/sfp_is_present',
'/sys/bus/i2c/devices/41-0050/sfp_is_present',
'/sys/bus/i2c/devices/44-0050/sfp_is_present',
'/sys/bus/i2c/devices/43-0050/sfp_is_present',
'/sys/bus/i2c/devices/33-0050/sfp_is_present',
'/sys/bus/i2c/devices/34-0050/sfp_is_present',
'/sys/bus/i2c/devices/35-0050/sfp_is_present',
'/sys/bus/i2c/devices/36-0050/sfp_is_present',
'/sys/bus/i2c/devices/45-0050/sfp_is_present',
'/sys/bus/i2c/devices/46-0050/sfp_is_present',
'/sys/bus/i2c/devices/47-0050/sfp_is_present',
'/sys/bus/i2c/devices/48-0050/sfp_is_present',
'/sys/bus/i2c/devices/49-0050/sfp_is_present',
'/sys/bus/i2c/devices/50-0050/sfp_is_present',
'/sys/bus/i2c/devices/51-0050/sfp_is_present',
'/sys/bus/i2c/devices/52-0050/sfp_is_present',
'/sys/bus/i2c/devices/61-0050/sfp_is_present',
'/sys/bus/i2c/devices/62-0050/sfp_is_present',
'/sys/bus/i2c/devices/63-0050/sfp_is_present',
'/sys/bus/i2c/devices/64-0050/sfp_is_present',
'/sys/bus/i2c/devices/53-0050/sfp_is_present',
'/sys/bus/i2c/devices/54-0050/sfp_is_present',
'/sys/bus/i2c/devices/55-0050/sfp_is_present',
'/sys/bus/i2c/devices/56-0050/sfp_is_present',
'/sys/bus/i2c/devices/57-0050/sfp_is_present',
'/sys/bus/i2c/devices/58-0050/sfp_is_present',
'/sys/bus/i2c/devices/59-0050/sfp_is_present',
'/sys/bus/i2c/devices/60-0050/sfp_is_present',
'/sys/bus/i2c/devices/69-0050/sfp_is_present',
'/sys/bus/i2c/devices/70-0050/sfp_is_present',
'/sys/bus/i2c/devices/71-0050/sfp_is_present',
'/sys/bus/i2c/devices/72-0050/sfp_is_present',
'/sys/bus/i2c/devices/77-0050/sfp_is_present',
'/sys/bus/i2c/devices/78-0050/sfp_is_present',
'/sys/bus/i2c/devices/79-0050/sfp_is_present',
'/sys/bus/i2c/devices/80-0050/sfp_is_present',
'/sys/bus/i2c/devices/65-0050/sfp_is_present',
'/sys/bus/i2c/devices/66-0050/sfp_is_present',
'/sys/bus/i2c/devices/67-0050/sfp_is_present',
'/sys/bus/i2c/devices/68-0050/sfp_is_present',
'/sys/bus/i2c/devices/73-0050/sfp_is_present',
'/sys/bus/i2c/devices/74-0050/sfp_is_present',
'/sys/bus/i2c/devices/75-0050/sfp_is_present',
'/sys/bus/i2c/devices/76-0050/sfp_is_present',
'/sys/bus/i2c/devices/85-0050/sfp_is_present',
'/sys/bus/i2c/devices/86-0050/sfp_is_present',
'/sys/bus/i2c/devices/87-0050/sfp_is_present',
'/sys/bus/i2c/devices/88-0050/sfp_is_present',
'/sys/bus/i2c/devices/31-0050/sfp_is_present',
'/sys/bus/i2c/devices/32-0050/sfp_is_present',
'/sys/bus/i2c/devices/29-0050/sfp_is_present',
'/sys/bus/i2c/devices/30-0050/sfp_is_present',
'/sys/bus/i2c/devices/81-0050/sfp_is_present',
'/sys/bus/i2c/devices/82-0050/sfp_is_present',
'/sys/bus/i2c/devices/83-0050/sfp_is_present',
'/sys/bus/i2c/devices/84-0050/sfp_is_present',
'/sys/bus/i2c/devices/25-0050/sfp_is_present',
'/sys/bus/i2c/devices/26-0050/sfp_is_present',
'/sys/bus/i2c/devices/27-0050/sfp_is_present',
'/sys/bus/i2c/devices/28-0050/sfp_is_present'
]
# sys.path.append('/usr/local/bin')
_qsfp_ports = range(0, ports_in_block + 1)
def __init__(self):
eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom'
for x in range(0, self._port_end + 1):
port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x+1])
self._port_to_eeprom_mapping[x] = port_eeprom_path
SfpUtilBase.__init__(self)
def reset(self, port_num):
# Check for invalid port_num
if port_num < self._port_start or port_num > self._port_end:
return False
path = "/sys/bus/i2c/devices/19-0060/module_reset_{0}"
port_ps = path.format(port_num+1)
try:
reg_file = open(port_ps, 'w')
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
#HW will clear reset after set.
reg_file.seek(0)
reg_file.write('1')
reg_file.close()
return True
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
path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present"
port_ps = path.format(self.port_to_i2c_mapping[port_num+1])
try:
reg_file = open(port_ps)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
reg_value = reg_file.readline().rstrip()
if reg_value == '1':
return True
return False
@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(0, self.ports_in_block + 1)
@property
def port_to_eeprom_mapping(self):
return self._port_to_eeprom_mapping
# Writing to a file from a list
def write_to_file(self, file_name, from_list):
try:
fp1 = open(file_name, 'w')
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
for i in from_list:
fp1.write(i)
fp1.write('\n')
fp1.close()
return True
# Reading from a file to a list
def read_from_file(self, file_name):
try:
fp = open(file_name, 'r')
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
to_list = fp.readlines()
to_list = [x.rstrip() for x in to_list]
fp.close()
return to_list
def sfp_detect(self):
x = 0
ret_dict = {}
defl_dict = {}
current_sfp_values = [0] * 64
previous_sfp_values = [0] * 64
if not os.path.isfile(self.cmd):
pass
else:
if (self.read_from_file(self.cmd) == False):
return False, defl_dict
else:
previous_sfp_values = self.read_from_file(self.cmd)
# Read the current values from sysfs
for x in range(len(self.port_to_sysfs_map)):
try:
reg_file = open(self.port_to_sysfs_map[x], 'r')
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False, defl_dict
sfp_present = reg_file.readline().rstrip()
reg_file.close()
current_sfp_values[x] = sfp_present
if (current_sfp_values[x] != previous_sfp_values[x]):
ret_dict.update({x:current_sfp_values[x]})
if(self.write_to_file(self.cmd, current_sfp_values) == True):
return True, ret_dict
else:
return False, defl_dict
def get_transceiver_change_event(self):
time.sleep(3)
return self.sfp_detect()
def get_low_power_mode(self, port_num):
# Check for invalid port_num
if port_num < self._port_start or port_num > self._port_end:
return False
try:
eeprom = None
if not self.get_presence(port_num):
return False
eeprom = open(self.port_to_eeprom_mapping[port_num], "rb")
eeprom.seek(93)
lpmode = ord(eeprom.read(1))
if ((lpmode & 0x3) == 0x3):
return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1
else:
return False # High Power Mode if one of the following conditions is matched:
# 1. "Power override" bit is 0
# 2. "Power override" bit is 1 and "Power set" bit is 0
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
finally:
if eeprom is not None:
eeprom.close()
time.sleep(0.01)
def set_low_power_mode(self, port_num, lpmode):
# Check for invalid port_num
if port_num < self._port_start or port_num > self._port_end:
return False
try:
eeprom = None
if not self.get_presence(port_num):
return False # Port is not present, unable to set the eeprom
# Fill in write buffer
regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode
buffer = create_string_buffer(1)
buffer[0] = chr(regval)
# Write to eeprom
eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b")
eeprom.seek(93)
eeprom.write(buffer[0])
return True
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
finally:
if eeprom is not None:
eeprom.close()
time.sleep(0.01)
# Read out SFP type, vendor name, PN, REV, SN from eeprom.
def get_transceiver_info_dict(self, port_num):
transceiver_info_dict = {}
compliance_code_dict = {}
# ToDo: OSFP tranceiver info parsing not fully supported.
# in inf8628.py lack of some memory map definition
# will be implemented when the inf8628 memory map ready
if port_num in self.osfp_ports:
offset = 0
vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP
sfpi_obj = inf8628InterfaceId()
if sfpi_obj is None:
print("Error: sfp_object open failed")
return None
file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR)
if not self._sfp_eeprom_present(file_path, 0):
print("Error, file not exist %s" % file_path)
return None
try:
sysfsfile_eeprom = open(file_path, mode="rb", buffering=0)
except IOError:
print("Error: reading sysfs file %s" % file_path)
return None
sfp_type_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH)
if sfp_type_raw is not None:
sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0)
else:
return None
sfp_vendor_name_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
if sfp_vendor_name_raw is not None:
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0)
else:
return None
sfp_vendor_pn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
if sfp_vendor_pn_raw is not None:
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0)
else:
return None
sfp_vendor_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_HW_REV_OFFSET), vendor_rev_width)
if sfp_vendor_rev_raw is not None:
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0)
else:
return None
sfp_vendor_sn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
if sfp_vendor_sn_raw is not None:
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0)
else:
return None
try:
sysfsfile_eeprom.close()
except IOError:
print("Error: closing sysfs file %s" % file_path)
return None
transceiver_info_dict['type'] = sfp_type_data['data']['type']['value']
transceiver_info_dict['type_abbrv_name'] = sfp_type_data['data']['type_abbrv_name']['value']
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value']
transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
# Below part is added to avoid fail the xcvrd, shall be implemented later
transceiver_info_dict['vendor_oui'] = 'N/A'
transceiver_info_dict['vendor_date'] = 'N/A'
transceiver_info_dict['Connector'] = 'N/A'
transceiver_info_dict['encoding'] = 'N/A'
transceiver_info_dict['ext_identifier'] = 'N/A'
transceiver_info_dict['ext_rateselect_compliance'] = 'N/A'
transceiver_info_dict['cable_type'] = 'N/A'
transceiver_info_dict['cable_length'] = 'N/A'
transceiver_info_dict['specification_compliance'] = 'N/A'
transceiver_info_dict['nominal_bit_rate'] = 'N/A'
else:
if port_num in self.qsfp_ports:
offset = 128
vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP
cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP
interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP
sfp_type = 'QSFP'
sfpi_obj = sff8436InterfaceId()
if sfpi_obj is None:
print("Error: sfp_object open failed")
return None
else:
offset = 0
vendor_rev_width = XCVR_HW_REV_WIDTH_SFP
cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP
interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP
sfp_type = 'SFP'
sfpi_obj = sff8472InterfaceId()
if sfpi_obj is None:
print("Error: sfp_object open failed")
return None
file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR)
if not self._sfp_eeprom_present(file_path, 0):
print("Error, file not exist %s" % file_path)
return None
try:
sysfsfile_eeprom = open(file_path, mode="rb", buffering=0)
except IOError:
print("Error: reading sysfs file %s" % file_path)
return None
sfp_interface_bulk_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width)
if sfp_interface_bulk_raw is not None:
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0)
else:
return None
sfp_vendor_name_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
if sfp_vendor_name_raw is not None:
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0)
else:
return None
sfp_vendor_pn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
if sfp_vendor_pn_raw is not None:
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0)
else:
return None
sfp_vendor_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_HW_REV_OFFSET), vendor_rev_width)
if sfp_vendor_rev_raw is not None:
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0)
else:
return None
sfp_vendor_sn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
if sfp_vendor_sn_raw is not None:
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0)
else:
return None
sfp_vendor_oui_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
if sfp_vendor_oui_raw is not None:
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0)
else:
return None
sfp_vendor_date_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
if sfp_vendor_date_raw is not None:
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0)
else:
return None
try:
sysfsfile_eeprom.close()
except IOError:
print("Error: closing sysfs file %s" % file_path)
return None
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value']
transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value']
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']
transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value']
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
if sfp_type == 'QSFP':
for key in qfx5210_qsfp_cable_length_tup:
if key in sfp_interface_bulk_data['data']:
transceiver_info_dict['cable_type'] = key
transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value'])
break
else:
transceiver_info_dict['cable_type'] = key
transceiver_info_dict['cable_length'] = 'N/A'
for key in qfx5210_qsfp_compliance_code_tup:
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
transceiver_info_dict['specification_compliance'] = str(compliance_code_dict)
if sfp_interface_bulk_data['data'].has_key('Nominal Bit Rate(100Mbs)'):
transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value'])
else:
transceiver_info_dict['nominal_bit_rate'] = 'N/A'
else:
for key in qfx5210_sfp_cable_length_tup:
if key in sfp_interface_bulk_data['data']:
transceiver_info_dict['cable_type'] = key
transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value'])
else:
transceiver_info_dict['cable_type'] = key
transceiver_info_dict['cable_length'] = 'N/A'
for key in qfx5210_sfp_compliance_code_tup:
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
transceiver_info_dict['specification_compliance'] = str(compliance_code_dict)
if sfp_interface_bulk_data['data'].has_key('NominalSignallingRate(UnitsOf100Mbd)'):
transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
else:
transceiver_info_dict['nominal_bit_rate'] = 'N/A'
#transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
return transceiver_info_dict
def get_transceiver_dom_info_dict(self, port_num):
transceiver_dom_info_dict = {}
if port_num in self.osfp_ports:
# Below part is added to avoid fail xcvrd, shall be implemented later
transceiver_dom_info_dict['temperature'] = 'N/A'
transceiver_dom_info_dict['voltage'] = 'N/A'
transceiver_dom_info_dict['rx1power'] = 'N/A'
transceiver_dom_info_dict['rx2power'] = 'N/A'
transceiver_dom_info_dict['rx3power'] = 'N/A'
transceiver_dom_info_dict['rx4power'] = 'N/A'
transceiver_dom_info_dict['tx1bias'] = 'N/A'
transceiver_dom_info_dict['tx2bias'] = 'N/A'
transceiver_dom_info_dict['tx3bias'] = 'N/A'
transceiver_dom_info_dict['tx4bias'] = 'N/A'
transceiver_dom_info_dict['tx1power'] = 'N/A'
transceiver_dom_info_dict['tx2power'] = 'N/A'
transceiver_dom_info_dict['tx3power'] = 'N/A'
transceiver_dom_info_dict['tx4power'] = 'N/A'
elif port_num in self.qsfp_ports:
offset = 0
offset_xcvr = 128
file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR)
if not self._sfp_eeprom_present(file_path, 0):
return None
try:
sysfsfile_eeprom = open(file_path, mode="rb", buffering=0)
except IOError:
print("Error: reading sysfs file %s" % file_path)
return None
sfpd_obj = sff8436Dom()
if sfpd_obj is None:
return None
sfpi_obj = sff8436InterfaceId()
if sfpi_obj is None:
return None
# QSFP capability byte parse, through this byte can know whether it support tx_power or not.
# TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
# need to add more code for determining the capability and version compliance
# in SFF-8636 dom capability definitions evolving with the versions.
qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH)
if qsfp_dom_capability_raw is not None:
qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0)
else:
return None
dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH)
if dom_temperature_raw is not None:
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
else:
return None
dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH)
if dom_voltage_raw is not None:
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
else:
return None
qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH)
if qsfp_dom_rev_raw is not None:
qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0)
else:
return None
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
# The tx_power monitoring is only available on QSFP which compliant with SFF-8636
# and claimed that it support tx_power with one indicator bit.
dom_channel_monitor_data = {}
qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value']
qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value']
if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')):
dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH)
if dom_channel_monitor_raw is not None:
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
else:
return None
transceiver_dom_info_dict['tx1power'] = 'N/A'
transceiver_dom_info_dict['tx2power'] = 'N/A'
transceiver_dom_info_dict['tx3power'] = 'N/A'
transceiver_dom_info_dict['tx4power'] = 'N/A'
else:
dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH)
if dom_channel_monitor_raw is not None:
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0)
else:
return None
transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value']
transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value']
transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value']
transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value']
try:
sysfsfile_eeprom.close()
except IOError:
print("Error: closing sysfs file %s" % file_path)
return None
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value']
transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value']
transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value']
transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value']
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value']
transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value']
transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value']
transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value']
else:
offset = 256
file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR)
if not self._sfp_eeprom_present(file_path, 0):
return None
try:
sysfsfile_eeprom = open(file_path, mode="rb", buffering=0)
except IOError:
print("Error: reading sysfs file %s" % file_path)
return None
sfpd_obj = sff8472Dom()
if sfpd_obj is None:
return None
dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
if dom_temperature_raw is not None:
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
else:
return None
dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH)
if dom_voltage_raw is not None:
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
else:
return None
dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
if dom_channel_monitor_raw is not None:
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
else:
return None
try:
sysfsfile_eeprom.close()
except IOError:
print("Error: closing sysfs file %s" % file_path)
return None
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value']
transceiver_dom_info_dict['rx2power'] = 'N/A'
transceiver_dom_info_dict['rx3power'] = 'N/A'
transceiver_dom_info_dict['rx4power'] = 'N/A'
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value']
transceiver_dom_info_dict['tx2bias'] = 'N/A'
transceiver_dom_info_dict['tx3bias'] = 'N/A'
transceiver_dom_info_dict['tx4bias'] = 'N/A'
transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value']
transceiver_dom_info_dict['tx2power'] = 'N/A'
transceiver_dom_info_dict['tx3power'] = 'N/A'
transceiver_dom_info_dict['tx4power'] = 'N/A'
return transceiver_dom_info_dict

View File

@ -51,7 +51,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \
$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \
$(BRCM_XLR_GTS_PLATFORM_MODULE) \ $(BRCM_XLR_GTS_PLATFORM_MODULE) \
$(DELTA_AG9032V2A_PLATFORM_MODULE) $(DELTA_AG9032V2A_PLATFORM_MODULE) \
$(JUNIPER_QFX5210_PLATFORM_MODULE)
ifeq ($(INSTALL_DEBUG_TOOLS),y) ifeq ($(INSTALL_DEBUG_TOOLS),y)
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))

View File

@ -0,0 +1,13 @@
# Juniper Platform modules
JUNIPER_QFX5210_PLATFORM_MODULE_VERSION = 1.1
export JUNIPER_QFX5210_PLATFORM_MODULE_VERSION
JUNIPER_QFX5210_PLATFORM_MODULE = sonic-platform-juniper-qfx5210_$(JUNIPER_QFX5210_PLATFORM_MODULE_VERSION)_amd64.deb
$(JUNIPER_QFX5210_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-juniper
$(JUNIPER_QFX5210_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
$(JUNIPER_QFX5210_PLATFORM_MODULE)_PLATFORM = x86_64-juniper_qfx5210-r0
SONIC_DPKG_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE)
SONIC_STRETCH_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE)

View File

@ -10,6 +10,7 @@ include $(PLATFORM_PATH)/platform-modules-cel.mk
include $(PLATFORM_PATH)/platform-modules-delta.mk include $(PLATFORM_PATH)/platform-modules-delta.mk
include $(PLATFORM_PATH)/platform-modules-quanta.mk include $(PLATFORM_PATH)/platform-modules-quanta.mk
#include $(PLATFORM_PATH)/platform-modules-mitac.mk #include $(PLATFORM_PATH)/platform-modules-mitac.mk
include $(PLATFORM_PATH)/platform-modules-juniper.mk
include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk
include $(PLATFORM_PATH)/docker-syncd-brcm.mk include $(PLATFORM_PATH)/docker-syncd-brcm.mk
include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk

View File

@ -0,0 +1,50 @@
# Object files
*.o
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
# Kernel Module Compile Results
*.mod*
*.cmd
*.o.d
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# Debian packaging
*.debhelper.log
*.postinst.debhelper
*.postrm.debhelper
*.prerm.debhelper
*.substvars

View File

@ -0,0 +1,16 @@
Copyright (C) 2016 Microsoft, Inc
Copyright (C) 2019 Juniper Networks
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.

View File

@ -0,0 +1 @@
platform drivers for Juniper QFX5210 for the SONiC project

View File

@ -0,0 +1,892 @@
/*
* A hwmon driver for the juniper_i2c_cpld
*
* Tested and validated on Juniper QFX5210
* Ciju Rajan K <crajank@juniper.net>
*
* Copyright (C) 2013 Accton Technology Corporation.
* Brandon Chuang <brandon_chuang@accton.com.tw>
*
* Based on ad7414.c
* Copyright 2006 Stefan Roese <sr at denx.de>, DENX Software Engineering
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/list.h>
#define MAX_PORT_NUM 64
#define I2C_RW_RETRY_COUNT 10
#define I2C_RW_RETRY_INTERVAL 60 /* ms */
#define I2C_ADDR_CPLD1 0x60
#define I2C_ADDR_CPLD2 0x62
#define I2C_ADDR_CPLD3 0x64
#define CPLD_ADDRS {I2C_ADDR_CPLD1, I2C_ADDR_CPLD2, I2C_ADDR_CPLD3}
/*
* Number of additional attribute pointers to allocate
* with each call to krealloc
*/
#define ATTR_ALLOC_SIZE 1 /*For last attribute which is NUll.*/
#define NAME_SIZE 24
#define MAX_RESP_LENGTH 48
typedef ssize_t (*show_func)( struct device *dev,
struct device_attribute *attr,
char *buf);
typedef ssize_t (*store_func)(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count);
enum models {
AS7712_32X,
AS7716_32X,
qfx5210_64X,
AS7312_54X,
PLAIN_CPLD, /*No attribute but add i2c addr to the list.*/
NUM_MODEL
};
enum sfp_func {
HAS_SFP = 1<<0 ,
HAS_QSFP = 1<<1 ,
};
enum common_attrs {
CMN_VERSION,
CMN_ACCESS,
CMN_PRESENT_ALL,
NUM_COMMON_ATTR
};
enum sfp_attrs {
SFP_PRESENT,
SFP_RESET,
SFP_LP_MODE,
NUM_SFP_ATTR
};
struct cpld_sensor {
struct cpld_sensor *next;
char name[NAME_SIZE+1]; /* sysfs sensor name */
struct device_attribute attribute;
bool update; /* runtime sensor update needed */
int data; /* Sensor data. Negative if there was a read error */
u8 reg; /* register */
u8 mask; /* bit mask */
bool invert; /* inverted value*/
};
#define to_cpld_sensor(_attr) \
container_of(_attr, struct cpld_sensor, attribute)
struct cpld_data {
struct device *dev;
struct device *hwmon_dev;
int num_attributes;
struct attribute_group group;
enum models model;
struct cpld_sensor *sensors;
struct mutex update_lock;
bool valid;
unsigned long last_updated; /* in jiffies */
int attr_index;
u16 sfp_num;
u8 sfp_types;
struct model_attrs *cmn_attr;
};
struct cpld_client_node {
struct i2c_client *client;
struct list_head list;
};
struct base_attrs {
const char *name;
umode_t mode;
show_func get;
store_func set;
};
struct attrs {
int reg;
bool invert;
struct base_attrs *base;
};
struct model_attrs {
struct attrs **cmn;
struct attrs **portly;
};
static ssize_t show_bit(struct device *dev,
struct device_attribute *devattr, char *buf);
static ssize_t show_presnet_all(struct device *dev,
struct device_attribute *devattr, char *buf);
static ssize_t set_1bit(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
static ssize_t set_byte(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
static ssize_t access(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg);
int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
struct base_attrs common_attrs[NUM_COMMON_ATTR] =
{
[CMN_VERSION] = {"version", S_IRUGO, show_bit, NULL},
[CMN_ACCESS] = {"access", S_IWUSR, NULL, set_byte},
[CMN_PRESENT_ALL] = {"module_present_all", S_IRUGO, show_presnet_all, NULL},
};
struct attrs as7712_common[] = {
[CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]},
[CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]},
[CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]},
};
struct attrs qfx5210_common[] = {
[CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]},
[CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]},
[CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]},
};
struct attrs as7312_common[] = {
[CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]},
[CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]},
[CMN_PRESENT_ALL] = {-1, false, &common_attrs[CMN_PRESENT_ALL]},
};
struct attrs plain_common[] = {
[CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]},
};
struct base_attrs portly_attrs[] =
{
[SFP_PRESENT] = {"module_present", S_IRUGO, show_bit, NULL},
// Only root user will have the privilege to write to sysfs
// [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUGO, show_bit, set_1bit},
[SFP_RESET] = {"module_reset", S_IRUGO|S_IWUSR, show_bit, set_1bit},
};
struct attrs as7712_port[] = {
{0x30, true, &portly_attrs[SFP_PRESENT]},
{0x04, true, &portly_attrs[SFP_RESET]},
};
struct attrs qfx5210_port[] = {
{0x70, true, &portly_attrs[SFP_PRESENT]},
{0x40, true, &portly_attrs[SFP_RESET]},
};
struct attrs *as7712_cmn_list[] = {
&as7712_common[CMN_VERSION],
&as7712_common[CMN_ACCESS],
&as7712_common[CMN_PRESENT_ALL],
NULL
};
struct attrs *qfx5210_cmn_list[] = {
&qfx5210_common[CMN_VERSION],
&qfx5210_common[CMN_ACCESS],
&qfx5210_common[CMN_PRESENT_ALL],
NULL
};
struct attrs *as7312_cmn_list[] = {
&as7312_common[CMN_VERSION],
&as7312_common[CMN_ACCESS],
&as7312_common[CMN_PRESENT_ALL],
NULL
};
struct attrs *plain_cmn_list[] = {
&plain_common[CMN_VERSION],
NULL
};
struct attrs *as7712_port_list[] = {
&as7712_port[SFP_PRESENT],
&as7712_port[SFP_RESET],
NULL
};
struct attrs *qfx5210_port_list[] = {
&qfx5210_port[SFP_PRESENT],
&qfx5210_port[SFP_RESET],
NULL
};
struct model_attrs models_attr[NUM_MODEL] = {
{.cmn = as7712_cmn_list, .portly=as7712_port_list},
{.cmn = as7712_cmn_list, .portly=as7712_port_list}, /*7716's as 7712*/
{.cmn = qfx5210_cmn_list, .portly=qfx5210_port_list},
{.cmn = as7312_cmn_list, .portly=qfx5210_port_list},
{.cmn = plain_cmn_list, .portly=NULL},
};
static LIST_HEAD(cpld_client_list);
static struct mutex list_lock;
/* Addresses scanned for juniper_i2c_cpld
*/
static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
static int get_sfp_spec(int model, u16 *num, u8 *types)
{
switch (model) {
case AS7712_32X:
case AS7716_32X:
*num = 32;
*types = HAS_QSFP;
break;
case qfx5210_64X:
*num = 64;
*types = HAS_QSFP;
break;
case AS7312_54X:
*num = 54;
*types = HAS_QSFP|HAS_SFP;
default:
*types = 0;
*num = 0;
break;
}
return 0;
}
static int get_present_reg(int model, u8 port, u8 *cpld_addr, u8 *reg, u8 *num)
{
u8 cpld_address[] = CPLD_ADDRS;
switch (model) {
case AS7312_54X:
if (port < 48) {
*cpld_addr = cpld_address[1 + port/24];
*reg = 0x09 + (port%24)/8;
*num = 8;
}
else
{
*reg = 0x18;
*num = 4;
*cpld_addr = ( port < 52)? cpld_address[1]: cpld_address[2];
}
break;
default:
return -EINVAL;
}
}
/*Assume the bits for ports are listed in-a-row.*/
static int get_reg_bit(u8 reg_start, int port,
u8 *reg ,u8 *mask)
{
*reg = reg_start + ((port)/8);
*mask = 1 << ((port)%8);
return 0;
}
static int cpld_write_internal(
struct i2c_client *client, u8 reg, u8 value)
{
int status = 0, retry = I2C_RW_RETRY_COUNT;
while (retry) {
status = i2c_smbus_write_byte_data(client, reg, value);
if (unlikely(status < 0)) {
msleep(I2C_RW_RETRY_INTERVAL);
retry--;
continue;
}
break;
}
return status;
}
static int cpld_read_internal(struct i2c_client *client, u8 reg)
{
int status = 0, retry = I2C_RW_RETRY_COUNT;
while (retry) {
status = i2c_smbus_read_byte_data(client, reg);
if (unlikely(status < 0)) {
msleep(I2C_RW_RETRY_INTERVAL);
retry--;
continue;
}
break;
}
return status;
}
/*Turn a numberic array into string with " " between each element.
* e.g., {0x11, 0x33, 0xff, 0xf1} => "11 33 ff f1"
*/
static ssize_t array_stringify(char *buf, u8 *input, size_t size) {
int i;
char t[MAX_RESP_LENGTH+1];
buf[0] = '\0';
for (i = 0; i < size; i++) {
snprintf(t, MAX_RESP_LENGTH, "%x ", input[i]);
strncat(buf, t, MAX_RESP_LENGTH);
}
if (strlen(buf) > 0)
buf[strlen(buf)-1] = '\0'; /*Remove tailing blank*/
return snprintf(buf, MAX_RESP_LENGTH, "%s\n", buf);
}
static ssize_t show_presnet_all_distinct(struct device *dev,
struct device_attribute *devattr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 i, value, reg;
u8 cpld_addr, num;
u8 _value[8];
u64 *values = (u64 *)_value;
values = 0;
mutex_lock(&data->update_lock);
while(i < data->sfp_num)
{
get_present_reg(data->model, i, &cpld_addr, &reg, &num);
if(cpld_addr == client->addr)
value = cpld_read_internal(client, reg);
else
value = juniper_i2c_cpld_read(cpld_addr, reg);
if (unlikely(value < 0)) {
goto exit;
}
*values |= (value&((1<<(num))-1)) << i;
i += num;
}
mutex_unlock(&data->update_lock);
*values = cpu_to_le64(*values);
return array_stringify(buf, _value, i);
exit:
mutex_unlock(&data->update_lock);
return value;
}
static ssize_t show_presnet_all(struct device *dev,
struct device_attribute *devattr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
struct cpld_sensor *sensor = to_cpld_sensor(devattr);
u8 i, values[MAX_RESP_LENGTH/8];
if (sensor->reg < 0) {
return show_presnet_all_distinct(dev, devattr, buf);
}
mutex_lock(&data->update_lock);
for (i = 0; i < ((data->sfp_num+7)/8); i++) {
values[i] = cpld_read_internal(client, sensor->reg + i);
if (unlikely(values[i] < 0)) {
goto exit;
}
}
mutex_unlock(&data->update_lock);
return array_stringify(buf, values, i);
exit:
mutex_unlock(&data->update_lock);
return values[i];
}
static ssize_t show_bit(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int value;
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
struct cpld_sensor *sensor = to_cpld_sensor(devattr);
mutex_lock(&data->update_lock);
value = cpld_read_internal(client, sensor->reg);
value = value & sensor->mask;
if (sensor->invert)
value = !value;
mutex_unlock(&data->update_lock);
return snprintf(buf, PAGE_SIZE, "%x\n", value);
}
static ssize_t set_1bit(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
long is_reset;
int value, status;
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
struct cpld_sensor *sensor = to_cpld_sensor(devattr);
u8 cpld_bit, reg;
status = kstrtol(buf, 10, &is_reset);
if (status) {
return status;
}
reg = sensor->reg;
cpld_bit = sensor->mask;
mutex_lock(&data->update_lock);
value = cpld_read_internal(client, reg);
if (unlikely(status < 0)) {
goto exit;
}
if (sensor->invert)
is_reset = !is_reset;
if (is_reset) {
value |= cpld_bit;
}
else {
value &= ~cpld_bit;
}
status = cpld_write_internal(client, reg, value);
if (unlikely(status < 0)) {
goto exit;
}
mutex_unlock(&data->update_lock);
return count;
exit:
mutex_unlock(&data->update_lock);
return status;
}
static ssize_t set_byte(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
return access(dev, da, buf, count);
}
static ssize_t access(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
int status;
u32 addr, val;
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
return -EINVAL;
}
if (addr > 0xFF || val > 0xFF) {
return -EINVAL;
}
mutex_lock(&data->update_lock);
status = cpld_write_internal(client, addr, val);
if (unlikely(status < 0)) {
goto exit;
}
mutex_unlock(&data->update_lock);
return count;
exit:
mutex_unlock(&data->update_lock);
return status;
}
static void juniper_i2c_cpld_add_client(struct i2c_client *client)
{
struct cpld_client_node *node =
kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL);
if (!node) {
dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n",
client->addr);
return;
}
node->client = client;
mutex_lock(&list_lock);
list_add(&node->list, &cpld_client_list);
mutex_unlock(&list_lock);
}
static void juniper_i2c_cpld_remove_client(struct i2c_client *client)
{
struct list_head *list_node = NULL;
struct cpld_client_node *cpld_node = NULL;
int found = 0;
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client == client) {
found = 1;
break;
}
}
if (found) {
list_del(list_node);
kfree(cpld_node);
}
mutex_unlock(&list_lock);
}
static int cpld_add_attribute(struct cpld_data *data, struct attribute *attr)
{
int new_max_attrs = ++data->num_attributes + ATTR_ALLOC_SIZE;
void *new_attrs = krealloc(data->group.attrs,
new_max_attrs * sizeof(void *),
GFP_KERNEL);
if (!new_attrs)
return -ENOMEM;
data->group.attrs = new_attrs;
data->group.attrs[data->num_attributes-1] = attr;
data->group.attrs[data->num_attributes] = NULL;
return 0;
}
static void cpld_dev_attr_init(struct device_attribute *dev_attr,
const char *name, umode_t mode,
show_func show, store_func store)
{
sysfs_attr_init(&dev_attr->attr);
dev_attr->attr.name = name;
dev_attr->attr.mode = mode;
dev_attr->show = show;
dev_attr->store = store;
}
static struct cpld_sensor * add_sensor(struct cpld_data *data,
const char *name,
u8 reg, u8 mask, bool invert,
bool update, umode_t mode,
show_func get, store_func set)
{
struct cpld_sensor *sensor;
struct device_attribute *a;
sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL);
if (!sensor)
return NULL;
a = &sensor->attribute;
snprintf(sensor->name, sizeof(sensor->name), name);
sensor->reg = reg;
sensor->mask = mask;
sensor->update = update;
sensor->invert = invert;
cpld_dev_attr_init(a, sensor->name,
mode,
get, set);
if (cpld_add_attribute(data, &a->attr))
return NULL;
sensor->next = data->sensors;
data->sensors = sensor;
return sensor;
}
static int add_attributes_cmn(struct cpld_data *data, struct attrs **cmn)
{
u8 reg, i ;
bool invert;
struct attrs *a;
struct base_attrs *b;
if (NULL == cmn)
return -1;
for (i = 0; cmn[i]; i++)
{
a = cmn[i];
reg = a->reg;
invert = a->invert;
b = a->base;
if (NULL == b)
break;
if (add_sensor(data, b->name,
reg, 0xff, invert,
true, b->mode,
b->get, b->set) == NULL)
{
return -ENOMEM;
}
}
return 0;
}
static int add_attributes_portly(struct cpld_data *data, struct attrs **pa)
{
char name[NAME_SIZE+1];
int i, j;
u8 reg, mask, invert;
struct attrs *a;
struct base_attrs *b;
if (NULL == pa)
return -1;
for (i = 0; pa[i]; i++) {
a = pa[i];
invert = a->invert;
b = a->base;
if (b == NULL)
break;
for (j = 0; j < data->sfp_num; j++)
{
snprintf(name, NAME_SIZE, "%s_%d", b->name, j+1);
get_reg_bit(a->reg, j, &reg, &mask);
if (add_sensor(data, name, reg, mask, invert,
true, b->mode, b->get, b->set) == NULL)
{
return -ENOMEM;
}
}
}
return 0;
}
static int add_attributes(struct i2c_client *client,
struct cpld_data *data)
{
struct model_attrs *m = data->cmn_attr;
if (m == NULL)
return -EINVAL;
/* Common attributes.*/
add_attributes_cmn(data, m->cmn);
/* Port-wise attributes.*/
add_attributes_portly(data, m->portly);
return 0;
}
static int juniper_i2c_cpld_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
int status;
struct cpld_data *data = NULL;
struct device *dev = &client->dev;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_dbg(dev, "i2c_check_functionality failed (0x%x)\n", client->addr);
return -EIO;
}
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data) {
return -ENOMEM;
}
data->model = dev_id->driver_data;
data->cmn_attr = &models_attr[data->model];
get_sfp_spec(data->model, &data->sfp_num, &data->sfp_types);
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
data->dev = dev;
dev_info(dev, "chip found\n");
status = add_attributes(client, data);
if (status)
goto out_kfree;
/*
* If there are no attributes, something is wrong.
* Bail out instead of trying to register nothing.
*/
if (!data->num_attributes) {
dev_err(dev, "No attributes found\n");
status = -ENODEV;
goto out_kfree;
}
/* Register sysfs hooks */
status = sysfs_create_group(&client->dev.kobj, &data->group);
if (status) {
goto out_kfree;
}
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
juniper_i2c_cpld_add_client(client);
dev_info(dev, "%s: cpld '%s'\n",
dev_name(data->hwmon_dev), client->name);
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &data->group);
out_kfree:
kfree(data->group.attrs);
return status;
}
static int juniper_i2c_cpld_remove(struct i2c_client *client)
{
struct cpld_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &data->group);
kfree(data->group.attrs);
juniper_i2c_cpld_remove_client(client);
return 0;
}
int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg)
{
struct list_head *list_node = NULL;
struct cpld_client_node *cpld_node = NULL;
int ret = -EPERM;
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client->addr == cpld_addr) {
ret = i2c_smbus_read_byte_data(cpld_node->client, reg);
break;
}
}
mutex_unlock(&list_lock);
return ret;
}
EXPORT_SYMBOL(juniper_i2c_cpld_read);
int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
{
struct list_head *list_node = NULL;
struct cpld_client_node *cpld_node = NULL;
int ret = -EIO;
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client->addr == cpld_addr) {
ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value);
break;
}
}
mutex_unlock(&list_lock);
return ret;
}
EXPORT_SYMBOL(juniper_i2c_cpld_write);
static const struct i2c_device_id juniper_i2c_cpld_id[] = {
{ "cpld_as7712", AS7712_32X},
{ "cpld_as7716", AS7716_32X},
{ "cpld_qfx5210", qfx5210_64X},
{ "cpld_as7312", AS7312_54X},
{ "cpld_plain", PLAIN_CPLD},
{ },
};
MODULE_DEVICE_TABLE(i2c, juniper_i2c_cpld_id);
static struct i2c_driver juniper_i2c_cpld_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "juniper_i2c_cpld",
},
.probe = juniper_i2c_cpld_probe,
.remove = juniper_i2c_cpld_remove,
.id_table = juniper_i2c_cpld_id,
.address_list = normal_i2c,
};
static int __init juniper_i2c_cpld_init(void)
{
mutex_init(&list_lock);
return i2c_add_driver(&juniper_i2c_cpld_driver);
}
static void __exit juniper_i2c_cpld_exit(void)
{
i2c_del_driver(&juniper_i2c_cpld_driver);
}
module_init(juniper_i2c_cpld_init);
module_exit(juniper_i2c_cpld_exit);
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
MODULE_DESCRIPTION("juniper_i2c_cpld driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,622 @@
/*
* An hwmon driver for the 3Y Power YM-2651Y Power Module
*
* Tested and validated on Juniper QFX5210
* Ciju Rajan K <crajank@juniper.net>
*
* Copyright (C) 2014 Accton Technology Corporation.
* Brandon Chuang <brandon_chuang@accton.com.tw>
*
* Based on ad7414.c
* Copyright 2006 Stefan Roese <sr at denx.de>, DENX Software Engineering
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#define MAX_FAN_DUTY_CYCLE 100
/* Addresses scanned
*/
static const unsigned short normal_i2c[] = { 0x58, 0x5b, I2C_CLIENT_END };
enum chips {
YM2651,
YM2401,
YM2851,
};
/* Each client has this additional data
*/
struct ym2651y_data {
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* !=0 if registers are valid */
unsigned long last_updated; /* In jiffies */
u8 capability; /* Register value */
u16 status_word; /* Register value */
u8 fan_fault; /* Register value */
u8 over_temp; /* Register value */
u16 v_out; /* Register value */
u16 i_out; /* Register value */
u16 p_out; /* Register value */
u16 temp; /* Register value */
u16 fan_speed; /* Register value */
u16 fan_duty_cycle[2]; /* Register value */
u8 fan_dir[4]; /* Register value */
u8 pmbus_revision; /* Register value */
u8 mfr_id[10]; /* Register value */
u8 mfr_model[10]; /* Register value */
u8 mfr_revsion[3]; /* Register value */
u16 mfr_vin_min; /* Register value */
u16 mfr_vin_max; /* Register value */
u16 mfr_iin_max; /* Register value */
u16 mfr_iout_max; /* Register value */
u16 mfr_pin_max; /* Register value */
u16 mfr_pout_max; /* Register value */
u16 mfr_vout_min; /* Register value */
u16 mfr_vout_max; /* Register value */
};
static ssize_t show_byte(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t show_word(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t show_linear(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t show_over_temp(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t show_ascii(struct device *dev, struct device_attribute *da,
char *buf);
static struct ym2651y_data *ym2651y_update_device(struct device *dev);
static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value);
enum ym2651y_sysfs_attributes {
PSU_POWER_ON = 0,
PSU_TEMP_FAULT,
PSU_POWER_GOOD,
PSU_FAN1_FAULT,
PSU_FAN_DIRECTION,
PSU_OVER_TEMP,
PSU_V_OUT,
PSU_I_OUT,
PSU_P_OUT,
PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/
PSU_TEMP1_INPUT,
PSU_FAN1_SPEED,
PSU_FAN1_DUTY_CYCLE,
PSU_PMBUS_REVISION,
PSU_MFR_ID,
PSU_MFR_MODEL,
PSU_MFR_REVISION,
PSU_MFR_VIN_MIN,
PSU_MFR_VIN_MAX,
PSU_MFR_VOUT_MIN,
PSU_MFR_VOUT_MAX,
PSU_MFR_IIN_MAX,
PSU_MFR_IOUT_MAX,
PSU_MFR_PIN_MAX,
PSU_MFR_POUT_MAX
};
/* sysfs attributes for hwmon
*/
static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON);
static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT);
static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD);
static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT);
static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP);
static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_linear, NULL, PSU_V_OUT);
static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT);
static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT);
static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT);
static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED);
static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE);
static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION);
static SENSOR_DEVICE_ATTR(psu_pmbus_revision, S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION);
static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID);
static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL);
static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION);
static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN);
static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX);
static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN);
static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX);
static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX);
static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX);
static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX);
static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX);
/*Duplicate nodes for lm-sensors.*/
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_linear, NULL, PSU_V_OUT);
static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT);
static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_linear, NULL, PSU_P_OUT_UV);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT);
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED);
static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT);
static struct attribute *ym2651y_attributes[] = {
&sensor_dev_attr_psu_power_on.dev_attr.attr,
&sensor_dev_attr_psu_temp_fault.dev_attr.attr,
&sensor_dev_attr_psu_power_good.dev_attr.attr,
&sensor_dev_attr_psu_fan1_fault.dev_attr.attr,
&sensor_dev_attr_psu_over_temp.dev_attr.attr,
&sensor_dev_attr_psu_v_out.dev_attr.attr,
&sensor_dev_attr_psu_i_out.dev_attr.attr,
&sensor_dev_attr_psu_p_out.dev_attr.attr,
&sensor_dev_attr_psu_temp1_input.dev_attr.attr,
&sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr,
&sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr,
&sensor_dev_attr_psu_fan_dir.dev_attr.attr,
&sensor_dev_attr_psu_pmbus_revision.dev_attr.attr,
&sensor_dev_attr_psu_mfr_id.dev_attr.attr,
&sensor_dev_attr_psu_mfr_model.dev_attr.attr,
&sensor_dev_attr_psu_mfr_revision.dev_attr.attr,
&sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr,
&sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr,
&sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr,
&sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr,
&sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr,
&sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr,
&sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr,
&sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr,
/*Duplicate nodes for lm-sensors.*/
&sensor_dev_attr_curr2_input.dev_attr.attr,
&sensor_dev_attr_in3_input.dev_attr.attr,
&sensor_dev_attr_power2_input.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_temp1_fault.dev_attr.attr,
NULL
};
static ssize_t show_byte(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ym2651y_data *data = ym2651y_update_device(dev);
return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) :
sprintf(buf, "0\n");
}
static ssize_t show_word(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ym2651y_data *data = ym2651y_update_device(dev);
u16 status = 0;
switch (attr->index) {
case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */
status = (data->status_word & 0x40) ? 0 : 1;
break;
case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */
status = (data->status_word & 0x4) >> 2;
break;
case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */
status = (data->status_word & 0x800) ? 0 : 1;
break;
}
return sprintf(buf, "%d\n", status);
}
static int two_complement_to_int(u16 data, u8 valid_bit, int mask)
{
u16 valid_data = data & mask;
bool is_negative = valid_data >> (valid_bit - 1);
return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data;
}
static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct ym2651y_data *data = i2c_get_clientdata(client);
int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1;
long speed;
int error;
error = kstrtol(buf, 10, &speed);
if (error)
return error;
if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE)
return -EINVAL;
mutex_lock(&data->update_lock);
data->fan_duty_cycle[nr] = speed;
ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_linear(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ym2651y_data *data = ym2651y_update_device(dev);
u16 value = 0;
int exponent, mantissa;
int multiplier = 1000;
switch (attr->index) {
case PSU_V_OUT:
value = data->v_out;
break;
case PSU_I_OUT:
value = data->i_out;
break;
case PSU_P_OUT_UV:
multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/
/*Passing through*/
case PSU_P_OUT:
value = data->p_out;
break;
case PSU_TEMP1_INPUT:
value = data->temp;
break;
case PSU_FAN1_SPEED:
value = data->fan_speed;
multiplier = 1;
break;
case PSU_FAN1_DUTY_CYCLE:
value = data->fan_duty_cycle[0];
multiplier = 1;
break;
case PSU_MFR_VIN_MIN:
value = data->mfr_vin_min;
break;
case PSU_MFR_VIN_MAX:
value = data->mfr_vin_max;
break;
case PSU_MFR_VOUT_MIN:
value = data->mfr_vout_min;
break;
case PSU_MFR_VOUT_MAX:
value = data->mfr_vout_max;
break;
case PSU_MFR_PIN_MAX:
value = data->mfr_pin_max;
break;
case PSU_MFR_POUT_MAX:
value = data->mfr_pout_max;
break;
case PSU_MFR_IOUT_MAX:
value = data->mfr_iout_max;
break;
case PSU_MFR_IIN_MAX:
value = data->mfr_iin_max;
break;
}
exponent = two_complement_to_int(value >> 11, 5, 0x1f);
mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff);
return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :
sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
}
static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ym2651y_data *data = ym2651y_update_device(dev);
u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6;
return sprintf(buf, "%d\n", data->fan_fault >> shift);
}
static ssize_t show_over_temp(struct device *dev, struct device_attribute *da,
char *buf)
{
struct ym2651y_data *data = ym2651y_update_device(dev);
return sprintf(buf, "%d\n", data->over_temp >> 7);
}
static ssize_t show_ascii(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ym2651y_data *data = ym2651y_update_device(dev);
u8 *ptr = NULL;
switch (attr->index) {
case PSU_FAN_DIRECTION: /* psu_fan_dir */
ptr = data->fan_dir;
break;
case PSU_MFR_ID: /* psu_mfr_id */
ptr = data->mfr_id;
break;
case PSU_MFR_MODEL: /* psu_mfr_model */
ptr = data->mfr_model;
break;
case PSU_MFR_REVISION: /* psu_mfr_revision */
ptr = data->mfr_revsion;
break;
default:
return 0;
}
return sprintf(buf, "%s\n", ptr);
}
static const struct attribute_group ym2651y_group = {
.attrs = ym2651y_attributes,
};
static int ym2651y_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
struct ym2651y_data *data;
int status;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK)) {
status = -EIO;
goto exit;
}
data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL);
if (!data) {
status = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
dev_info(&client->dev, "chip found\n");
/* Register sysfs hooks */
status = sysfs_create_group(&client->dev.kobj, &ym2651y_group);
if (status) {
goto exit_free;
}
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
dev_info(&client->dev, "%s: psu '%s'\n",
dev_name(data->hwmon_dev), client->name);
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &ym2651y_group);
exit_free:
kfree(data);
exit:
return status;
}
static int ym2651y_remove(struct i2c_client *client)
{
struct ym2651y_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &ym2651y_group);
kfree(data);
return 0;
}
static const struct i2c_device_id ym2651y_id[] = {
{ "ym2651", YM2651 },
{ "ym2401", YM2401 },
{ "ym2851", YM2851 },
{}
};
MODULE_DEVICE_TABLE(i2c, ym2651y_id);
static struct i2c_driver ym2651y_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "ym2651",
},
.probe = ym2651y_probe,
.remove = ym2651y_remove,
.id_table = ym2651y_id,
.address_list = normal_i2c,
};
static int ym2651y_read_byte(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
static int ym2651y_read_word(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_word_data(client, reg);
}
static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value)
{
return i2c_smbus_write_word_data(client, reg, value);
}
static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data,
int data_len)
{
int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
if (unlikely(result < 0))
goto abort;
if (unlikely(result != data_len)) {
result = -EIO;
goto abort;
}
result = 0;
abort:
return result;
}
struct reg_data_byte {
u8 reg;
u8 *value;
};
struct reg_data_word {
u8 reg;
u16 *value;
};
static struct ym2651y_data *ym2651y_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct ym2651y_data *data = i2c_get_clientdata(client);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
int i, status;
u8 command;
u8 fan_dir[5] = {0};
struct reg_data_byte regs_byte[] = { {0x19, &data->capability},
{0x7d, &data->over_temp},
{0x81, &data->fan_fault},
{0x98, &data->pmbus_revision}
};
struct reg_data_word regs_word[] = { {0x79, &data->status_word},
{0x8b, &data->v_out},
{0x8c, &data->i_out},
{0x96, &data->p_out},
{0x8d, &data->temp},
{0x3b, &(data->fan_duty_cycle[0])},
{0x3c, &(data->fan_duty_cycle[1])},
{0x90, &data->fan_speed},
{0xa0, &data->mfr_vin_min},
{0xa1, &data->mfr_vin_max},
{0xa2, &data->mfr_iin_max},
{0xa3, &data->mfr_pin_max},
{0xa4, &data->mfr_vout_min},
{0xa5, &data->mfr_vout_max},
{0xa6, &data->mfr_iout_max},
{0xa7, &data->mfr_pout_max}
};
dev_dbg(&client->dev, "Starting ym2651 update\n");
/* Read byte data */
for (i = 0; i < ARRAY_SIZE(regs_byte); i++) {
status = ym2651y_read_byte(client, regs_byte[i].reg);
if (status < 0)
{
dev_dbg(&client->dev, "reg %d, err %d\n",
regs_byte[i].reg, status);
*(regs_byte[i].value) = 0;
}
else {
*(regs_byte[i].value) = status;
}
}
/* Read word data */
for (i = 0; i < ARRAY_SIZE(regs_word); i++) {
status = ym2651y_read_word(client, regs_word[i].reg);
if (status < 0)
{
dev_dbg(&client->dev, "reg %d, err %d\n",
regs_word[i].reg, status);
*(regs_word[i].value) = 0;
}
else {
*(regs_word[i].value) = status;
}
}
/* Read fan_direction */
command = 0xC3;
status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1);
if (status < 0) {
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
}
strncpy(data->fan_dir, fan_dir+1, ARRAY_SIZE(data->fan_dir)-1);
data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0';
/* Read mfr_id */
command = 0x99;
status = ym2651y_read_block(client, command, data->mfr_id,
ARRAY_SIZE(data->mfr_id)-1);
data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0';
if (status < 0)
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
/* Read mfr_model */
command = 0x9a;
status = ym2651y_read_block(client, command, data->mfr_model,
ARRAY_SIZE(data->mfr_model)-1);
data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0';
if (status < 0)
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
/* Read mfr_revsion */
command = 0x9b;
status = ym2651y_read_block(client, command, data->mfr_revsion,
ARRAY_SIZE(data->mfr_revsion)-1);
data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0';
if (status < 0)
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
module_i2c_driver(ym2651y_driver);
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
MODULE_DESCRIPTION("3Y Power YM-2651Y driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,6 @@
sonic-juniper-platform-modules (1.1) unstable; urgency=low
* Initial release: Add support for QFX5210.
-- Juniper Networks
Ciju Rajan K <crajank@juniper.net> Tue, 30 July 2019

View File

@ -0,0 +1 @@
9

View File

@ -0,0 +1,11 @@
Source: sonic-juniper-platform-modules
Section: main
Priority: extra
Maintainer: Juniper Networks <crajank@juniper.net>
Build-Depends: debhelper (>= 9), bzip2
Standards-Version: 3.9.3
Package: sonic-platform-juniper-qfx5210
Architecture: amd64
Description: kernel modules for platform devices such as fan, led, sfp

View File

@ -0,0 +1,2 @@
sonic-juniper-platform-modules_1.1_amd64.buildinfo main extra
sonic-platform-juniper-qfx5210_1.1_amd64.deb main extra

View File

@ -0,0 +1,86 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
include /usr/share/dpkg/pkg-info.mk
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
export INSTALL_MOD_DIR:=extra
PYTHON ?= python2
PACKAGE_PRE_NAME := sonic-platform-juniper
KVERSION ?= $(shell uname -r)
KERNEL_SRC := /lib/modules/$(KVERSION)
MOD_SRC_DIR:= $(shell pwd)
MODULE_DIRS:= qfx5210
MODULE_DIR := modules
UTILS_DIR := utils
SERVICE_DIR := service
PLATFORM_DIR := sonic_platform
CONF_DIR := conf
%:
dh $@ --with systemd,python2,python3 --buildsystem=pybuild
clean:
dh_testdir
dh_testroot
dh_clean
build:
#make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC)
(for mod in $(MODULE_DIRS); do \
make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules || exit 1; \
$(PYTHON) $${mod}/setup.py build; \
done)
binary: binary-arch binary-indep
# Nothing to do
binary-arch:
# Nothing to do
#install: build
#dh_testdir
#dh_testroot
#dh_clean -k
#dh_installdirs
binary-indep:
dh_testdir
dh_installdirs
# Custom package commands
(for mod in $(MODULE_DIRS); do \
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /usr/local/bin; \
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /lib/systemd/system; \
cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \
cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \
$(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \
done)
# Resuming debhelper scripts
dh_testroot
dh_install
dh_installchangelogs
dh_installdocs
dh_systemd_enable
dh_installinit
dh_systemd_start
dh_link
dh_fixperms
dh_compress
dh_strip
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
.PHONY: build binary binary-arch binary-indep clean

View File

@ -0,0 +1,4 @@
qfx5210/utils/juniper_qfx5210_util.py usr/local/bin
qfx5210/utils/juniper_qfx5210_monitor.py usr/local/bin
qfx5210/utils/platform_poweroff usr/local/bin
qfx5210/service/qfx5210-platform-init.service etc/systemd/system

View File

@ -0,0 +1,2 @@
systemctl enable qfx5210-platform-init.service
systemctl start qfx5210-platform-init.service

View File

@ -0,0 +1,2 @@
obj-m:=x86-64-juniper-qfx5210-64x-fan.o x86-64-juniper-qfx5210-64x-sfp.o x86-64-juniper-qfx5210-64x-leds.o \
x86-64-juniper-qfx5210-64x-psu.o juniper_i2c_cpld.o ym2651y.o

View File

@ -0,0 +1 @@
../../common/modules/juniper_i2c_cpld.c

View File

@ -0,0 +1,470 @@
/*
* A hwmon driver for the juniper qfx5210-64x fan
*
* Modified and tested to work on Juniper QFX5210
* Ciju Rajan K <crajank@juniper.net>
*
* Copyright (C) 2014 juniper Technology Corporation.
* Brandon Chuang <brandon_chuang@accton.com.tw>
*
* 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 <linux/module.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/dmi.h>
#define DRVNAME "qfx5210_64x_fan"
static struct qfx5210_64x_fan_data *qfx5210_64x_fan_update_device(struct device *dev);
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf);
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
/* fan related data, the index should match sysfs_fan_attributes
*/
static const u8 fan_reg[] = {
0x80, /* fan 1-4 present status */
0x81, /* fan 1-4 direction(0:F2B 1:B2F) */
0x87, /* fan PWM(for all fan) */
0x90, /* front fan 1 speed(rpm) */
0x91, /* front fan 2 speed(rpm) */
0x92, /* front fan 3 speed(rpm) */
0x93, /* front fan 4 speed(rpm) */
0x98, /* rear fan 1 speed(rpm) */
0x99, /* rear fan 2 speed(rpm) */
0x9A, /* rear fan 3 speed(rpm) */
0x9B, /* rear fan 4 speed(rpm) */
};
/* Each client has this additional data */
struct qfx5210_64x_fan_data {
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* != 0 if registers are valid */
unsigned long last_updated; /* In jiffies */
u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */
};
enum fan_id {
FAN1_ID,
FAN2_ID,
FAN3_ID,
FAN4_ID
};
enum sysfs_fan_attributes {
FAN_PRESENT_REG,
FAN_DIRECTION_REG,
FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */
FAN1_FRONT_SPEED_RPM,
FAN2_FRONT_SPEED_RPM,
FAN3_FRONT_SPEED_RPM,
FAN4_FRONT_SPEED_RPM,
FAN1_REAR_SPEED_RPM,
FAN2_REAR_SPEED_RPM,
FAN3_REAR_SPEED_RPM,
FAN4_REAR_SPEED_RPM,
FAN1_DIRECTION,
FAN2_DIRECTION,
FAN3_DIRECTION,
FAN4_DIRECTION,
FAN1_PRESENT,
FAN2_PRESENT,
FAN3_PRESENT,
FAN4_PRESENT,
FAN1_FAULT,
FAN2_FAULT,
FAN3_FAULT,
FAN4_FAULT
};
/* Define attributes
*/
#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \
static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT);\
static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT)
#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \
&sensor_dev_attr_fan##index2##_fault.dev_attr.attr
#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \
static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION)
#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr
#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \
static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\
static SENSOR_DEVICE_ATTR(pwm##index, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE)
#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr, \
&sensor_dev_attr_pwm##index.dev_attr.attr
#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \
static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT)
#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr
#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \
static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\
static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM);\
static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\
static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM)
#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \
&sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \
&sensor_dev_attr_fan##index##_input.dev_attr.attr, \
&sensor_dev_attr_fan##index2##_input.dev_attr.attr
/* 6 fan fault attributes in this platform */
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1,11);
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2,12);
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3,13);
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4,14);
/* 6 fan speed(rpm) attributes in this platform */
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1,11);
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2,12);
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3,13);
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4,14);
/* 6 fan present attributes in this platform */
DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1);
DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2);
DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3);
DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4);
/* 6 fan direction attribute in this platform */
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1);
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2);
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3);
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4);
/* 1 fan duty cycle attribute in this platform */
DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1);
static struct attribute *qfx5210_64x_fan_attributes[] = {
/* fan related attributes */
DECLARE_FAN_FAULT_ATTR(1,11),
DECLARE_FAN_FAULT_ATTR(2,12),
DECLARE_FAN_FAULT_ATTR(3,13),
DECLARE_FAN_FAULT_ATTR(4,14),
DECLARE_FAN_SPEED_RPM_ATTR(1,11),
DECLARE_FAN_SPEED_RPM_ATTR(2,12),
DECLARE_FAN_SPEED_RPM_ATTR(3,13),
DECLARE_FAN_SPEED_RPM_ATTR(4,14),
DECLARE_FAN_PRESENT_ATTR(1),
DECLARE_FAN_PRESENT_ATTR(2),
DECLARE_FAN_PRESENT_ATTR(3),
DECLARE_FAN_PRESENT_ATTR(4),
DECLARE_FAN_DIRECTION_ATTR(1),
DECLARE_FAN_DIRECTION_ATTR(2),
DECLARE_FAN_DIRECTION_ATTR(3),
DECLARE_FAN_DIRECTION_ATTR(4),
DECLARE_FAN_DUTY_CYCLE_ATTR(1),
NULL
};
#define FAN_DUTY_CYCLE_REG_MASK 0xF
#define FAN_MAX_DUTY_CYCLE 100
#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100
static int qfx5210_64x_fan_read_value(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
static int qfx5210_64x_fan_write_value(struct i2c_client *client, u8 reg, u8 value)
{
return i2c_smbus_write_byte_data(client, reg, value);
}
/* fan utility functions
*/
static u32 reg_val_to_duty_cycle(u8 reg_val)
{
reg_val &= FAN_DUTY_CYCLE_REG_MASK;
if (!reg_val) {
return 0;
}
if (reg_val == 0xF) {
return FAN_MAX_DUTY_CYCLE;
}
return (reg_val * 6) + 10;
}
static u8 duty_cycle_to_reg_val(u8 duty_cycle)
{
if (duty_cycle < 16) {
return 0;
}
if (duty_cycle >= 100) {
return 0xF;
}
return (duty_cycle - 10) / 6;
}
static u32 reg_val_to_speed_rpm(u8 reg_val)
{
return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP;
}
static u8 reg_val_to_direction(u8 reg_val, enum fan_id id)
{
u8 mask = (1 << id);
return !!(reg_val & mask);
}
static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id)
{
u8 mask = (1 << id);
return !(reg_val & mask);
}
static u8 is_fan_fault(struct qfx5210_64x_fan_data *data, enum fan_id id)
{
u8 ret = 1;
int front_fan_index = FAN1_FRONT_SPEED_RPM + id;
int rear_fan_index = FAN1_REAR_SPEED_RPM + id;
/* Check if the speed of front or rear fan is ZERO,
*/
if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) &&
reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) {
ret = 0;
}
return ret;
}
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
int error, value;
struct i2c_client *client = to_i2c_client(dev);
error = kstrtoint(buf, 10, &value);
if (error)
return error;
if (value > FAN_MAX_DUTY_CYCLE)
value = FAN_MAX_DUTY_CYCLE;
if (value < 0)
return -EINVAL;
qfx5210_64x_fan_write_value(client, 0x28, 0); /* Disable fan speed watch dog */
qfx5210_64x_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value));
return count;
}
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct qfx5210_64x_fan_data *data = qfx5210_64x_fan_update_device(dev);
ssize_t ret = 0;
if (data->valid) {
switch (attr->index) {
case FAN_DUTY_CYCLE_PERCENTAGE:
{
u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]);
ret = sprintf(buf, "%u\n", duty_cycle);
break;
}
case FAN1_FRONT_SPEED_RPM:
case FAN2_FRONT_SPEED_RPM:
case FAN3_FRONT_SPEED_RPM:
case FAN4_FRONT_SPEED_RPM:
case FAN1_REAR_SPEED_RPM:
case FAN2_REAR_SPEED_RPM:
case FAN3_REAR_SPEED_RPM:
case FAN4_REAR_SPEED_RPM:
{
ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index]));
break;
}
case FAN1_PRESENT:
case FAN2_PRESENT:
case FAN3_PRESENT:
case FAN4_PRESENT:
ret = sprintf(buf, "%d\n",
reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG],
attr->index - FAN1_PRESENT));
break;
case FAN1_FAULT:
case FAN2_FAULT:
case FAN3_FAULT:
case FAN4_FAULT:
ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT));
break;
case FAN1_DIRECTION:
case FAN2_DIRECTION:
case FAN3_DIRECTION:
case FAN4_DIRECTION:
ret = sprintf(buf, "%d\n",
reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG],
attr->index - FAN1_DIRECTION));
break;
default:
break;
}
}
return ret;
}
static const struct attribute_group qfx5210_64x_fan_group = {
.attrs = qfx5210_64x_fan_attributes,
};
static struct qfx5210_64x_fan_data *qfx5210_64x_fan_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct qfx5210_64x_fan_data *data = i2c_get_clientdata(client);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
!data->valid) {
int i;
dev_dbg(&client->dev, "Starting qfx5210_64x_fan update\n");
data->valid = 0;
/* Update fan data
*/
for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) {
int status = qfx5210_64x_fan_read_value(client, fan_reg[i]);
if (status < 0) {
data->valid = 0;
mutex_unlock(&data->update_lock);
dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status);
return data;
}
else {
data->reg_val[i] = status;
}
}
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
static int qfx5210_64x_fan_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
struct qfx5210_64x_fan_data *data;
int status;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
status = -EIO;
goto exit;
}
data = kzalloc(sizeof(struct qfx5210_64x_fan_data), GFP_KERNEL);
if (!data) {
status = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->valid = 0;
mutex_init(&data->update_lock);
dev_info(&client->dev, "chip found\n");
/* Register sysfs hooks */
status = sysfs_create_group(&client->dev.kobj, &qfx5210_64x_fan_group);
if (status) {
goto exit_free;
}
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
dev_info(&client->dev, "%s: fan '%s'\n",
dev_name(data->hwmon_dev), client->name);
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &qfx5210_64x_fan_group);
exit_free:
kfree(data);
exit:
return status;
}
static int qfx5210_64x_fan_remove(struct i2c_client *client)
{
struct qfx5210_64x_fan_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &qfx5210_64x_fan_group);
return 0;
}
/* Addresses to scan */
static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
static const struct i2c_device_id qfx5210_64x_fan_id[] = {
{ "qfx5210_64x_fan", 0 },
{}
};
MODULE_DEVICE_TABLE(i2c, qfx5210_64x_fan_id);
static struct i2c_driver qfx5210_64x_fan_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = DRVNAME,
},
.probe = qfx5210_64x_fan_probe,
.remove = qfx5210_64x_fan_remove,
.id_table = qfx5210_64x_fan_id,
.address_list = normal_i2c,
};
static int __init qfx5210_64x_fan_init(void)
{
return i2c_add_driver(&qfx5210_64x_fan_driver);
}
static void __exit qfx5210_64x_fan_exit(void)
{
i2c_del_driver(&qfx5210_64x_fan_driver);
}
module_init(qfx5210_64x_fan_init);
module_exit(qfx5210_64x_fan_exit);
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
MODULE_DESCRIPTION("qfx5210_64x_fan driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,450 @@
/*
* LED driver for the qfx5210
*
* Modified and tested to work on Juniper QFX5210
* Ciju Rajan K <crajank@juniper.net>
*
* Copyright (C) 2014 Accton Technology Corporation.
* Brandon Chuang <brandon_chuang@accton.com.tw>
*
* 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.
*/
/*#define DEBUG*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include <linux/dmi.h>
extern int juniper_i2c_cpld_read (u8 cpld_addr, u8 reg);
extern int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
extern void led_classdev_unregister(struct led_classdev *led_cdev);
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
extern void led_classdev_resume(struct led_classdev *led_cdev);
extern void led_classdev_suspend(struct led_classdev *led_cdev);
#define DRVNAME "qfx5210_64x_led"
struct qfx5210_64x_led_data {
struct platform_device *pdev;
struct mutex update_lock;
char valid; /* != 0 if registers are valid */
unsigned long last_updated; /* In jiffies */
u8 reg_val[1]; /* only 1 register*/
};
static struct qfx5210_64x_led_data *ledctl = NULL;
/*
* LED related data
*/
#define LED_CNTRLER_I2C_ADDRESS (0x60) /* CPLD1 i2c address */
#define LED_TYPE_ALARM_REG_MASK (0x03)
#define LED_MODE_ALARM_RED_VALUE (0x01)
#define LED_MODE_ALARM_AMBER_VALUE (0x02)
#define LED_MODE_ALARM_OFF_VALUE (0x00)
#define LED_TYPE_SYSTEM_REG_MASK (0x0C)
#define LED_MODE_SYSTEM_GREEN_VALUE (0x04)
#define LED_MODE_SYSTEM_GREEN_BLINKING_VALUE (0x08)
#define LED_MODE_SYSTEM_OFF_VALUE (0x00)
#define LED_TYPE_MASTER_REG_MASK (0x30)
#define LED_MODE_MASTER_GREEN_VALUE (0x10)
#define LED_MODE_MASTER_GREEN_BLINKING_VALUE (0x20)
#define LED_MODE_MASTER_OFF_VALUE (0x00)
#define LED_TYPE_BEACON_REG_MASK (0xC0)
#define LED_MODE_BEACON_VALUE (0x40)
#define LED_MODE_BEACON_OFF_VALUE (0x00)
enum led_type {
LED_TYPE_ALARM,
LED_TYPE_SYSTEM,
LED_TYPE_MASTER,
LED_TYPE_BEACON
};
struct led_reg {
u32 types;
u8 reg_addr;
};
static const struct led_reg led_reg_map[] = {
{(1 << LED_TYPE_ALARM) | (1 << LED_TYPE_SYSTEM) | (1 << LED_TYPE_MASTER) | (1 << LED_TYPE_BEACON), 0x30},
};
enum led_light_mode {
LED_MODE_OFF = 0,
LED_MODE_RED = 1,
LED_MODE_AMBER = 2,
LED_MODE_GREEN = 1,
LED_MODE_GREEN_BLINKING = 2,
LED_MODE_BLUE_BLINKING = 1
};
struct led_type_mode {
enum led_type type;
enum led_light_mode mode;
int reg_bit_mask;
int mode_value;
};
static struct led_type_mode led_type_mode_data[] = {
{LED_TYPE_ALARM, LED_MODE_RED, LED_TYPE_ALARM_REG_MASK, LED_MODE_ALARM_RED_VALUE},
{LED_TYPE_ALARM, LED_MODE_AMBER, LED_TYPE_ALARM_REG_MASK, LED_MODE_ALARM_AMBER_VALUE},
{LED_TYPE_ALARM, LED_MODE_OFF, LED_TYPE_ALARM_REG_MASK, LED_MODE_ALARM_OFF_VALUE},
{LED_TYPE_SYSTEM, LED_MODE_GREEN, LED_TYPE_SYSTEM_REG_MASK, LED_MODE_SYSTEM_GREEN_VALUE},
{LED_TYPE_SYSTEM, LED_MODE_GREEN_BLINKING, LED_TYPE_SYSTEM_REG_MASK, LED_MODE_SYSTEM_GREEN_BLINKING_VALUE},
{LED_TYPE_SYSTEM, LED_MODE_OFF, LED_TYPE_SYSTEM_REG_MASK, LED_MODE_SYSTEM_OFF_VALUE},
{LED_TYPE_MASTER, LED_MODE_GREEN, LED_TYPE_MASTER_REG_MASK, LED_MODE_MASTER_GREEN_VALUE},
{LED_TYPE_MASTER, LED_MODE_GREEN_BLINKING, LED_TYPE_MASTER_REG_MASK, LED_MODE_MASTER_GREEN_BLINKING_VALUE},
{LED_TYPE_MASTER, LED_MODE_OFF, LED_TYPE_MASTER_REG_MASK, LED_MODE_MASTER_OFF_VALUE},
{LED_TYPE_BEACON, LED_MODE_BLUE_BLINKING, LED_TYPE_BEACON_REG_MASK, LED_MODE_BEACON_VALUE},
{LED_TYPE_BEACON, LED_MODE_OFF, LED_TYPE_BEACON_REG_MASK, LED_MODE_BEACON_OFF_VALUE}
};
static int get_led_reg(enum led_type type, u8 *reg)
{
int i;
for (i = 0; i < ARRAY_SIZE(led_reg_map); i++) {
if(led_reg_map[i].types & (1 << type)) {
*reg = led_reg_map[i].reg_addr;
return 0;
}
}
return 1;
}
static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val)
{
int i;
for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
if (type != led_type_mode_data[i].type)
continue;
if ((led_type_mode_data[i].reg_bit_mask & reg_val) ==
led_type_mode_data[i].mode_value)
{
return led_type_mode_data[i].mode;
}
}
return 0;
}
static u8 led_light_mode_to_reg_val(enum led_type type,
enum led_light_mode mode, u8 reg_val) {
int i;
for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
if (type != led_type_mode_data[i].type)
continue;
if (mode != led_type_mode_data[i].mode)
continue;
reg_val = led_type_mode_data[i].mode_value |
(reg_val & (~led_type_mode_data[i].reg_bit_mask));
break;
}
return reg_val;
}
static int qfx5210_64x_led_read_value(u8 reg)
{
return juniper_i2c_cpld_read(LED_CNTRLER_I2C_ADDRESS, reg);
}
static int qfx5210_64x_led_write_value(u8 reg, u8 value)
{
return juniper_i2c_cpld_write(LED_CNTRLER_I2C_ADDRESS, reg, value);
}
static void qfx5210_64x_led_update(void)
{
mutex_lock(&ledctl->update_lock);
if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2)
|| !ledctl->valid) {
int i;
dev_dbg(&ledctl->pdev->dev, "Starting qfx5210_64x_led update\n");
/* Update LED data
*/
for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) {
int status = qfx5210_64x_led_read_value(led_reg_map[i].reg_addr);
if (status < 0) {
ledctl->valid = 0;
dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status);
goto exit;
}
else
{
ledctl->reg_val[i] = status;
}
}
ledctl->last_updated = jiffies;
ledctl->valid = 1;
}
exit:
mutex_unlock(&ledctl->update_lock);
}
static void qfx5210_64x_led_set(struct led_classdev *led_cdev,
enum led_brightness led_light_mode,
enum led_type type)
{
int reg_val;
u8 reg ;
mutex_lock(&ledctl->update_lock);
if( !get_led_reg(type, &reg)) {
dev_dbg(&ledctl->pdev->dev, "Not match register for %d.\n", type);
}
reg_val = qfx5210_64x_led_read_value(reg);
if (reg_val < 0) {
dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val);
goto exit;
}
reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val);
qfx5210_64x_led_write_value(reg, reg_val);
/* to prevent the slow-update issue */
ledctl->valid = 0;
exit:
mutex_unlock(&ledctl->update_lock);
}
static void qfx5210_64x_led_system_set(struct led_classdev *led_cdev,
enum led_brightness led_light_mode)
{
qfx5210_64x_led_set(led_cdev, led_light_mode, LED_TYPE_SYSTEM);
}
static enum led_brightness qfx5210_64x_led_system_get(struct led_classdev *cdev)
{
qfx5210_64x_led_update();
return led_reg_val_to_light_mode(LED_TYPE_SYSTEM, ledctl->reg_val[0]);
}
static void qfx5210_64x_led_master_set(struct led_classdev *led_cdev,
enum led_brightness led_light_mode)
{
qfx5210_64x_led_set(led_cdev, led_light_mode, LED_TYPE_MASTER);
}
static enum led_brightness qfx5210_64x_led_master_get(struct led_classdev *cdev)
{
qfx5210_64x_led_update();
return led_reg_val_to_light_mode(LED_TYPE_MASTER, ledctl->reg_val[0]);
}
static void qfx5210_64x_led_alarm_set(struct led_classdev *led_cdev,
enum led_brightness led_light_mode)
{
qfx5210_64x_led_set(led_cdev, led_light_mode, LED_TYPE_ALARM);
}
static enum led_brightness qfx5210_64x_led_alarm_get(struct led_classdev *cdev)
{
qfx5210_64x_led_update();
return led_reg_val_to_light_mode(LED_TYPE_ALARM, ledctl->reg_val[0]);
}
static void qfx5210_64x_led_beacon_set(struct led_classdev *led_cdev,
enum led_brightness led_light_mode)
{
qfx5210_64x_led_set(led_cdev, led_light_mode, LED_TYPE_BEACON);
}
static enum led_brightness qfx5210_64x_led_beacon_get(struct led_classdev *cdev)
{
qfx5210_64x_led_update();
return led_reg_val_to_light_mode(LED_TYPE_BEACON, ledctl->reg_val[0]);
}
static struct led_classdev qfx5210_64x_leds[] = {
[LED_TYPE_ALARM] = {
.name = "alarm",
.default_trigger = "unused",
.brightness_set = qfx5210_64x_led_alarm_set,
.brightness_get = qfx5210_64x_led_alarm_get,
.flags = LED_CORE_SUSPENDRESUME,
.max_brightness = LED_MODE_AMBER,
},
[LED_TYPE_SYSTEM] = {
.name = "system",
.default_trigger = "unused",
.brightness_set = qfx5210_64x_led_system_set,
.brightness_get = qfx5210_64x_led_system_get,
.flags = LED_CORE_SUSPENDRESUME,
.max_brightness = LED_MODE_GREEN_BLINKING,
},
[LED_TYPE_MASTER] = {
.name = "master",
.default_trigger = "unused",
.brightness_set = qfx5210_64x_led_master_set,
.brightness_get = qfx5210_64x_led_master_get,
.flags = LED_CORE_SUSPENDRESUME,
.max_brightness = LED_MODE_GREEN_BLINKING,
},
[LED_TYPE_BEACON] = {
.name = "beacon",
.default_trigger = "unused",
.brightness_set = qfx5210_64x_led_beacon_set,
.brightness_get = qfx5210_64x_led_beacon_get,
.flags = LED_CORE_SUSPENDRESUME,
.max_brightness = LED_MODE_BLUE_BLINKING,
},
};
static int qfx5210_64x_led_suspend(struct platform_device *dev,
pm_message_t state)
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(qfx5210_64x_leds); i++) {
led_classdev_suspend(&qfx5210_64x_leds[i]);
}
return 0;
}
static int qfx5210_64x_led_resume(struct platform_device *dev)
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(qfx5210_64x_leds); i++) {
led_classdev_resume(&qfx5210_64x_leds[i]);
}
return 0;
}
static int qfx5210_64x_led_probe(struct platform_device *pdev)
{
int ret, i;
for (i = 0; i < ARRAY_SIZE(qfx5210_64x_leds); i++) {
ret = led_classdev_register(&pdev->dev, &qfx5210_64x_leds[i]);
if (ret < 0)
break;
}
/* Check if all LEDs were successfully registered */
if (i != ARRAY_SIZE(qfx5210_64x_leds)){
int j;
/* only unregister the LEDs that were successfully registered */
for (j = 0; j < i; j++) {
led_classdev_unregister(&qfx5210_64x_leds[i]);
}
}
return ret;
}
static int qfx5210_64x_led_remove(struct platform_device *pdev)
{
int i;
for (i = 0; i < ARRAY_SIZE(qfx5210_64x_leds); i++) {
led_classdev_unregister(&qfx5210_64x_leds[i]);
}
return 0;
}
static struct platform_driver qfx5210_64x_led_driver = {
.probe = qfx5210_64x_led_probe,
.remove = qfx5210_64x_led_remove,
.suspend = qfx5210_64x_led_suspend,
.resume = qfx5210_64x_led_resume,
.driver = {
.name = DRVNAME,
.owner = THIS_MODULE,
},
};
static int __init qfx5210_64x_led_init(void)
{
int ret;
ret = platform_driver_register(&qfx5210_64x_led_driver);
if (ret < 0) {
goto exit;
}
ledctl = kzalloc(sizeof(struct qfx5210_64x_led_data), GFP_KERNEL);
if (!ledctl) {
ret = -ENOMEM;
platform_driver_unregister(&qfx5210_64x_led_driver);
goto exit;
}
mutex_init(&ledctl->update_lock);
ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
if (IS_ERR(ledctl->pdev)) {
ret = PTR_ERR(ledctl->pdev);
platform_driver_unregister(&qfx5210_64x_led_driver);
kfree(ledctl);
goto exit;
}
exit:
return ret;
}
static void __exit qfx5210_64x_led_exit(void)
{
platform_device_unregister(ledctl->pdev);
platform_driver_unregister(&qfx5210_64x_led_driver);
kfree(ledctl);
}
module_init(qfx5210_64x_led_init);
module_exit(qfx5210_64x_led_exit);
MODULE_AUTHOR("Ciju Rajan K <crajank@juniper.net>");
MODULE_DESCRIPTION("qfx5210_64x_led driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,242 @@
/*
* An hwmon driver for juniper qfx5210_64x Power Module
*
* Tested and validated on Juniper QFX5210
* Ciju Rajan K <crajank@juniper.net>
*
* Copyright (C) 2014 Accton Technology Corporation.
* Brandon Chuang <brandon_chuang@accton.com.tw>
*
* Based on ad7414.c
* Copyright 2006 Stefan Roese <sr at denx.de>, DENX Software Engineering
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#define PSU_STATUS_I2C_ADDR 0x60
#define PSU_STATUS_I2C_REG_OFFSET 0x03
#define IS_POWER_GOOD(id, value) (!!(value & BIT(2+id)))
#define IS_PRESENT(id, value) (!(value & BIT(id)))
static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf);
static struct qfx5210_64x_psu_data *qfx5210_64x_psu_update_device(struct device *dev);
extern int juniper_i2c_cpld_read (u8 cpld_addr, u8 reg);
/* Addresses scanned
*/
static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
/* Each client has this additional data
*/
struct qfx5210_64x_psu_data {
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* !=0 if registers are valid */
unsigned long last_updated; /* In jiffies */
u8 index; /* PSU index */
u8 status; /* Status(present/power_good) register read from CPLD */
};
enum qfx5210_64x_psu_sysfs_attributes {
PSU_PRESENT,
PSU_POWER_GOOD
};
/* sysfs attributes for hwmon
*/
static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT);
static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD);
static struct attribute *qfx5210_64x_psu_attributes[] = {
&sensor_dev_attr_psu_present.dev_attr.attr,
&sensor_dev_attr_psu_power_good.dev_attr.attr,
NULL
};
static ssize_t show_status(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct qfx5210_64x_psu_data *data = qfx5210_64x_psu_update_device(dev);
u8 status = 0;
if (!data->valid) {
return -EIO;
}
if (attr->index == PSU_PRESENT) {
status = IS_PRESENT(data->index, data->status);
}
else { /* PSU_POWER_GOOD */
status = IS_POWER_GOOD(data->index, data->status);
}
return sprintf(buf, "%d\n", status);
}
static const struct attribute_group qfx5210_64x_psu_group = {
.attrs = qfx5210_64x_psu_attributes,
};
static int qfx5210_64x_psu_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
struct qfx5210_64x_psu_data *data;
int status;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
status = -EIO;
goto exit;
}
data = kzalloc(sizeof(struct qfx5210_64x_psu_data), GFP_KERNEL);
if (!data) {
status = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->valid = 0;
data->index = dev_id->driver_data;
mutex_init(&data->update_lock);
dev_info(&client->dev, "chip found\n");
/* Register sysfs hooks */
status = sysfs_create_group(&client->dev.kobj, &qfx5210_64x_psu_group);
if (status) {
goto exit_free;
}
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
dev_info(&client->dev, "%s: psu '%s'\n",
dev_name(data->hwmon_dev), client->name);
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &qfx5210_64x_psu_group);
exit_free:
kfree(data);
exit:
return status;
}
static int qfx5210_64x_psu_remove(struct i2c_client *client)
{
struct qfx5210_64x_psu_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &qfx5210_64x_psu_group);
kfree(data);
return 0;
}
enum psu_index
{
qfx5210_64x_psu1,
qfx5210_64x_psu2
};
static const struct i2c_device_id qfx5210_64x_psu_id[] = {
{ "qfx5210_64x_psu1", qfx5210_64x_psu1 },
{ "qfx5210_64x_psu2", qfx5210_64x_psu2 },
{}
};
MODULE_DEVICE_TABLE(i2c, qfx5210_64x_psu_id);
static struct i2c_driver qfx5210_64x_psu_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "qfx5210_64x_psu",
},
.probe = qfx5210_64x_psu_probe,
.remove = qfx5210_64x_psu_remove,
.id_table = qfx5210_64x_psu_id,
.address_list = normal_i2c,
};
static struct qfx5210_64x_psu_data *qfx5210_64x_psu_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct qfx5210_64x_psu_data *data = i2c_get_clientdata(client);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
int status;
data->valid = 0;
dev_dbg(&client->dev, "Starting qfx5210_64x update\n");
/* Read psu status */
status = juniper_i2c_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET);
if (status < 0) {
dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status);
goto exit;
}
else {
data->status = status;
}
data->last_updated = jiffies;
data->valid = 1;
}
exit:
mutex_unlock(&data->update_lock);
return data;
}
static int __init qfx5210_64x_psu_init(void)
{
return i2c_add_driver(&qfx5210_64x_psu_driver);
}
static void __exit qfx5210_64x_psu_exit(void)
{
i2c_del_driver(&qfx5210_64x_psu_driver);
}
module_init(qfx5210_64x_psu_init);
module_exit(qfx5210_64x_psu_exit);
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
MODULE_DESCRIPTION("qfx5210_64x_psu driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1 @@
../../common/modules/ym2651y.c

View File

@ -0,0 +1,13 @@
[Unit]
Description=Juniper QFX5210 initialization service
Before=pmon.service
After=sysinit.target
DefaultDependencies=no
[Service]
ExecStartPre=/usr/local/bin/juniper_qfx5210_util.py install
ExecStart=/usr/local/bin/juniper_qfx5210_monitor.py
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python
import os
import sys
from setuptools import setup
os.listdir
setup(
name='sonic_platform',
version='1.0',
description='Module to initialize Juniper QFX5210-64X platforms',
packages=['sonic_platform'],
package_dir={'sonic_platform': 'qfx5210/sonic_platform'},
)

View File

@ -0,0 +1 @@
import platform

View File

@ -0,0 +1,149 @@
#!/usr/bin/env python
#
# Name: chassis.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
# which provide the chassis specific details
#
# Copyright (c) 2019, Juniper Networks, Inc.
# All rights reserved.
#
# Notice and Disclaimer: This code is licensed to you under the GNU General
# Public License as published by the Free Software Foundation, version 3 or
# any later version. This code is not an official Juniper product. You can
# obtain a copy of the License at <https://www.gnu.org/licenses/>
#
# OSS License:
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Third-Party Code: This code may depend on other components under separate
# copyright notice and license terms. Your use of the source code for those
# components is subject to the terms and conditions of the respective license
# as noted in the Third-Party source code file.
#
try:
import os
import commands
import sys
import time
from sonic_platform_base.chassis_base import ChassisBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Chassis(ChassisBase):
"""
JUNIPER QFX5210 Platform-specific Chassis class
"""
# Find the last reboot reason out of following
# CPLD_WATCHDOG_RESET 0x08
# POWER_ON_RESET 0x20
# CPU_WATCHDOG_RESET 0x40
# SOFTWARE_RESET 0x80
def __init__(self):
ChassisBase.__init__(self)
def get_qfx5210_parameter_value(self,parameter_name):
try:
with open("/var/run/qfx5210_eeprom", "r") as file:
for item in file:
content = item.split('=')
if content[0] == parameter_name:
return content[1:]
return "False"
except IOError:
print "Error: File not found"
return "False"
def get_product_name(self):
product_name_list = self.get_qfx5210_parameter_value('ProductName')
if product_name_list:
product_name = ''.join(product_name_list)
return product_name
else:
return False
def get_part_number(self):
part_number_list = self.get_qfx5210_parameter_value('PartNumber')
if part_number_list:
part_number = ''.join(part_number_list)
return part_number
else:
return False
def get_serial_number(self):
serial_number_list = self.get_qfx5210_parameter_value('SerialNumber')
if serial_number_list:
serial_number = ''.join(serial_number_list)
return serial_number
else:
return False
def get_base_mac(self):
mac_list = self.get_qfx5210_parameter_value('MAC')
if mac_list:
mac = ''.join(mac_list)
return mac
else:
return False
def get_platform_name(self):
platform_name_list = self.get_qfx5210_parameter_value('PlatformName')
if platform_name_list:
platform_name = ''.join(platform_name_list)
return platform_name
else:
return False
def get_fan_type(self, fantype_path):
try:
fan_type_file = open(fantype_path)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return "-1"
else:
fan_type = fan_type_file.read()
fan_type_file.close()
return str(fan_type)
def get_reboot_cause(self):
"""
Retrieves the cause of the previous reboot
"""
status, last_reboot_reason = commands.getstatusoutput("i2cget -y 0 0x65 0x24")
if (status == 0):
if last_reboot_reason == "0x80":
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08":
return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None)
elif last_reboot_reason == "0x20":
return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None)
else:
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason")
else:
time.sleep(3)
status, last_reboot_reason = commands.getstatusoutput("i2cget -y 0 0x65 0x24")
if last_reboot_reason == "0x80":
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08":
return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None)
elif last_reboot_reason == "0x20":
return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None)
else:
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason")

View File

@ -0,0 +1,67 @@
#!/usr/bin/env python
#
# Name: platform.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
# which provide the platform specific details
#
# Copyright (c) 2019, Juniper Networks, Inc.
# All rights reserved.
#
# Notice and Disclaimer: This code is licensed to you under the GNU General
# Public License as published by the Free Software Foundation, version 3 or
# any later version. This code is not an official Juniper product. You can
# obtain a copy of the License at <https://www.gnu.org/licenses/>
#
# OSS License:
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Third-Party Code: This code may depend on other components under separate
# copyright notice and license terms. Your use of the source code for those
# components is subject to the terms and conditions of the respective license
# as noted in the Third-Party source code file.
#
import sys
try:
from sonic_platform_base.platform_base import PlatformBase
except ImportError as e:
raise ImportError("%s - required module not found" % e)
platformDict = {'platform':'QFX5210-64C'}
class Platform(PlatformBase):
def __init__(self):
self.platform = self.getPlatform()
def getPlatformDict(self):
global platformDict
if platformDict:
return platformDict
def readPlatformName(self):
return self.getPlatformDict().get('platform')
def getPlatform(self):
platformCls = self.readPlatformName()
return platformCls
def get_chassis(self):
from chassis import Chassis
chassis = Chassis()
return chassis

View File

@ -0,0 +1,87 @@
Copyright (c) 2019, Juniper Networks, Inc.
All rights reserved.
Front panel LEDs
================
There are 4 system LEDs in the front panel. Master, System, Alarm, & Beacon.
LED controls can be found under /sys/class/leds. The sysfs interface &
colour mappings are as follows:
For master LED: /sys/class/leds/master/brightness
0 => off
1 => green
For system LED: /sys/class/leds/system/brightness
0 => off
1 => green
For alarm LED: /sys/class/leds/alarm/brightness
0 => off
1 => amber
2 => red
For beacon LED: /sys/class/leds/beacon/brightness
0 => off
1 => blue
For any of the above LEDs, max_brightness file can tell the maximum value
accepted.
System FANs
===========
There are 4 fans and each of the fan has 2 fan modules. Overall there are
8 fans in the system.
Fan controls can be found in /sys/bus/i2c/devices/17-0068. All the fans
are controlled by one duty cycle value, ranges from 0 to 100
Fan duty cycle can be controlled through /sys/bus/i2c/devices/17-0068/pwm1
Fan module presence is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_present
file. A value of '1' indicate that fan is present & a value of '0' otherwise.
Fan rotation direction is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_direction.
A value of '0' indicate the direction is AFO (Front to back airflow) or Airflow
out. A value of '1' indicate that direction is AFI (Back to front airflow) or
Airflow in.
Fan speed is given by fan[1-4]_input
Temperature sensors
===================
There are 6 temperature sensors. The readings are available in
/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input
System PSUs
===========
There are two independent PSUs. These are controlled by a dedicated CPLD.
The status registers are mapped under /sys/bus/i2c/devices/9-0050 and
/sys/bus/i2c/devices/10-0053.
SFPs
====
There are 64 QSFP+ modules supported in qfx5210 platform. EEPORMs will be
mapped under /sys/bus/i2c/devices/[25-88]-0050/ sysfs directory
Sensor details
==============
LM75 supported sensor modules will be available under 'sensors' command.
If you want to get all the sensor data including the SFPs & LEDs, you can
invoke 'sudo juniper_qfx5210_util.py show'
Platform poweroff
=================
Linux poweroff commands such as 'poweroff', 'shutdown', 'halt', etc. will not
power off qfx5210 platform as there are custom CPLDs control the power off
sequences. Use the command 'sudo platform_poweroff' to power off qfx5210
platform
Platform monitoring daemon
==========================
“juniper_qfx5210_monitor.py” is the platform monitoring script.
It implements the qfx5210 EM policy. This script will run as system service
and monitor the temperature sensors in every 20 seconds. Based on the EM
policy thresholds, it controls the fan rpm, manage alarm leds, and
shutdown the box.

View File

@ -0,0 +1,454 @@
#!/usr/bin/env python
#
# Name: juniper_qfx5210_monitor.py version: 1.0
#
# Description: This file contains the EM implementation for qfx5210 platform
#
# Copyright (c) 2019, Juniper Networks, Inc.
# All rights reserved.
#
# Notice and Disclaimer: This code is licensed to you under the GNU General
# Public License as published by the Free Software Foundation, version 3 or
# any later version. This code is not an official Juniper product. You can
# obtain a copy of the License at <https://www.gnu.org/licenses/>
#
# OSS License:
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Third-Party Code: This code may depend on other components under separate
# copyright notice and license terms. Your use of the source code for those
# components is subject to the terms and conditions of the respective license
# as noted in the Third-Party source code file.
try:
import os
import commands
import sys, getopt
import subprocess
import click
import imp
import logging
import logging.config
import logging.handlers
import types
import time
import traceback
import glob
import collections
from tabulate import tabulate
except ImportError as e:
raise ImportError('%s - required module not found' % str(e))
# Deafults
VERSION = '1.0'
FUNCTION_NAME = '/usr/local/bin/juniper_qfx5210_monitor'
global isPlatformAFI
temp_policy_AFI = {
0: [[70, 0, 48000], [70, 48000, 53000], [80, 53000, 0], [80, 53000, 58000], [100, 58000, 0], ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 75000], ['Fire Shut Alarm', 75000, 0]],
1: [[70, 0, 41000], [70, 41000, 47000], [80, 47000, 0], [80, 47000, 52000], [100, 52000, 0], ['Yellow Alarm', 58000, 64000], ['Red Alarm', 64000, 69000], ['Fire Shut Alarm', 69000, 0]],
2: [[70, 0, 33000], [70, 33000, 39000], [80, 39000, 0], [80, 39000, 45000], [100, 45000, 0], ['Yellow Alarm', 53000, 59000], ['Red Alarm', 59000, 64000], ['Fire Shut Alarm', 64000, 0]],
3: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 42000], [100, 42000, 0], ['Yellow Alarm', 48000, 55000], ['Red Alarm', 55000, 60000], ['Fire Shut Alarm', 60000, 0]],
4: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 42000], [100, 42000, 0], ['Yellow Alarm', 48000, 55000], ['Red Alarm', 55000, 60000], ['Fire Shut Alarm', 60000, 0]],
5: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 43000], [100, 43000, 0], ['Yellow Alarm', 49000, 56000], ['Red Alarm', 56000, 61000], ['Fire Shut Alarm', 61000, 0]],
6: [[70, 0, 70000], [70, 70000, 78000], [80, 78000, 0], [80, 78000, 86000], [100, 86000, 0], ['Yellow Alarm', 91000, 96000], ['Red Alarm', 96000, 102000], ['Fire Shut Alarm', 102000, 0]],
}
temp_policy_AFO = {
0: [[60, 0, 49000], [60, 49000, 55000], [80, 55000, 0], [80, 55000, 62000], [100, 62000, 0], ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 78000], ['Fire Shut Alarm', 78000, 0]],
1: [[60, 0, 55000], [60, 55000, 60000], [80, 60000, 0], [80, 60000, 65000], [100, 65000, 0], ['Yellow Alarm', 70000, 76000], ['Red Alarm', 76000, 80000], ['Fire Shut Alarm', 80000, 0]],
2: [[60, 0, 34000], [60, 34000, 40000], [80, 40000, 0], [80, 40000, 47000], [100, 47000, 0], ['Yellow Alarm', 54000, 60000], ['Red Alarm', 60000, 64000], ['Fire Shut Alarm', 64000, 0]],
3: [[60, 0, 36000], [60, 36000, 41000], [80, 41000, 0], [80, 41000, 47000], [100, 47000, 0], ['Yellow Alarm', 54000, 60000], ['Red Alarm', 60000, 64000], ['Fire Shut Alarm', 64000, 0]],
4: [[60, 0, 39000], [60, 39000, 45000], [80, 45000, 0], [80, 45000, 52000], [100, 52000, 0], ['Yellow Alarm', 59000, 65000], ['Red Alarm', 65000, 69000], ['Fire Shut Alarm', 69000, 0]],
5: [[60, 0, 37000], [60, 37000, 43000], [80, 43000, 0], [80, 43000, 50000], [100, 50000, 0], ['Yellow Alarm', 57000, 63000], ['Red Alarm', 63000, 67000], ['Fire Shut Alarm', 67000, 0]],
6: [[60, 0, 70000], [60, 70000, 78000], [80, 78000, 0], [80, 78000, 86000], [100, 86000, 0], ['Yellow Alarm', 91000, 96000], ['Red Alarm', 96000, 102000], ['Fire Shut Alarm', 102000, 0]],
}
class QFX5210_FanUtil(object):
"""QFX5210 Platform FanUtil class"""
FANBASE_VAL_PATH = '/sys/bus/i2c/devices/17-0068/{0}'
FAN_DUTY_PATH = '/sys/bus/i2c/devices/17-0068/fan_duty_cycle_percentage'
def __init__(self):
fan_path = self.FANBASE_VAL_PATH
def get_fan_duty_cycle(self):
try:
val_file = open(self.FAN_DUTY_PATH)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = val_file.readline().rstrip()
val_file.close()
return int(content)
def set_fan_duty_cycle(self, val):
try:
fan_file = open(self.FAN_DUTY_PATH, 'r+')
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
fan_file.write(str(val))
fan_file.close()
return True
class QFX5210_ThermalUtil(object):
"""QFX5210 Platform ThermalUtil class"""
SENSOR_NUM_ON_MAIN_BOARD = 6
SENSOR_CORETEMP_NUM_ON_MAIN_BOARD = 7
CORETEMP_NUM_ON_MAIN_BOARD = 5
THERMAL_NUM_RANGE = 8
SENSOR_NUM_1_IDX = 1
SENSORS_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input'
CORETEMP_PATH = '/sys/bus/platform/devices/coretemp.0/hwmon/hwmon1/temp{0}_input'
ALARM_LED_PATH = '/sys/class/leds/alarm/brightness'
""" Dictionary where
key1 = thermal id index (integer) starting from 1
value = path to fan device file (string) """
_sensor_to_device_path_mapping = {}
_sensor_to_device_node_mapping = [
['18', '48'],
['18', '49'],
['18', '4a'],
['18', '4b'],
['17', '4d'],
['17', '4e'],
]
_coretemp_to_device_path_mapping = {}
_coretemp_to_device_node_mapping = [1, 2, 3, 4, 5]
def __init__(self):
sensor_path = self.SENSORS_PATH
coretemp_path = self.CORETEMP_PATH
for x in range(self.SENSOR_NUM_ON_MAIN_BOARD):
self._sensor_to_device_path_mapping[x+1] = sensor_path.format(
self._sensor_to_device_node_mapping[x][0],
self._sensor_to_device_node_mapping[x][1])
for x in range(self.CORETEMP_NUM_ON_MAIN_BOARD):
self._coretemp_to_device_path_mapping[x] = coretemp_path.format(
self._coretemp_to_device_node_mapping[x])
""" Function reads the 5 temp inputs in CORETEMP_PATH
and returns the average of these 5 temp readings """
def get_coretempValue(self):
sum = 0
for x in range(self.CORETEMP_NUM_ON_MAIN_BOARD):
sum += self._get_coretemp_node_val(x)
avg = sum/self.CORETEMP_NUM_ON_MAIN_BOARD
return int(avg)
""" Function takes the Sensor number as input, constructs the device path,
opens sensor file, reads the temp content from the file and returns the value """
def _get_sensor_node_val(self, thermal_num):
if thermal_num < self.SENSOR_NUM_1_IDX or thermal_num > self.SENSOR_NUM_ON_MAIN_BOARD:
logging.debug('GET. Parameter error. thermal_num, %d', thermal_num)
return None
device_path = self.get_thermal_to_device_path(thermal_num)
for filename in glob.glob(device_path):
try:
val_file = open(filename, 'r')
except IOError as e:
logging.error('GET. unable to open file: %s', str(e))
return None
content = val_file.readline().rstrip()
if content == '':
logging.debug('GET. content is NULL. device_path:%s', device_path)
return None
try:
val_file.close()
except:
logging.debug('GET. unable to close file. device_path:%s', device_path)
return None
return int(content)
""" Function takes the coretemp number as input, constructs the device path,
opens sensor file, reads the temp content from the file and returns the value """
def _get_coretemp_node_val(self, thermal_num):
device_path = self.get_coretemp_to_device_path(thermal_num)
for filename in glob.glob(device_path):
try:
val_file = open(filename, 'r')
except IOError as e:
logging.error('GET. unable to open file: %s', str(e))
return None
content = val_file.readline().rstrip()
if content == '':
logging.debug('GET. content is NULL. device_path:%s', device_path)
return None
try:
val_file.close()
except:
logging.debug('GET. unable to close file. device_path:%s', device_path)
return None
return int(content)
def get_thermal_to_device_path(self, thermal_num):
return self._sensor_to_device_path_mapping[thermal_num]
def get_coretemp_to_device_path(self, thermal_num):
return self._coretemp_to_device_path_mapping[thermal_num]
""" Function opens the alarm LED file, reads the content from the file
and returns the value.This value indicates the Brigthness level.
The value of 1 = YELLOW ALARM
The value of 2 = RED ALARM
The value of 0 = NO ALARM """
def get_alarm_led_brightness(self):
try:
val_file = open(self.ALARM_LED_PATH)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = val_file.readline().rstrip()
val_file.close()
return int(content)
""" Function takes the value to set in the alarm LED file as input.
Reads the content from the file and sets the value.This value indicates the Brigthness level.
The value of 1 = YELLOW ALARM
The value of 2 = RED ALARM
The value of 0 = NO ALARM """
def set_alarm_led_brightness(self, val):
try:
val_file = open(self.ALARM_LED_PATH, 'r+')
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
val_file.write(str(val))
val_file.close()
return True
""" Function is called periodically every 20 secs. It reads the 6 Temp sensors and 1 core Temp sensor and sets
Sensor flags accordingly. Also reads the Fan duty cycle and depending on the FAN duty cycle reading and temp sensor reading,
set the different parameters """
def getSensorTemp(self):
sum = 0
global isPlatformAFI
#AFI
if (isPlatformAFI == True):
temp_policy = temp_policy_AFI
else:
#AFO
temp_policy = temp_policy_AFO
""" Dictionary where
key = thermal id index starting from 0. 0 is the sensor 1 ...
value = Different temp ranges """
SensorFlag = {
0: [0,0,0,0,0,0,0,0],
1: [0,0,0,0,0,0,0,0],
2: [0,0,0,0,0,0,0,0],
3: [0,0,0,0,0,0,0,0],
4: [0,0,0,0,0,0,0,0],
5: [0,0,0,0,0,0,0,0],
6: [0,0,0,0,0,0,0,0],
}
for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD):
if x < self.SENSOR_NUM_ON_MAIN_BOARD:
value = self._get_sensor_node_val(x+1)
else:
value = self.get_coretempValue()
# 60% Duty Cycle for AFO and 70% Duty Cycle for AFI
if value > temp_policy[x][0][1] and value <= temp_policy[x][0][2]:
SensorFlag[x][0] = True
# 60% Prev Duty Cycle for AFO and 70% Prev Duty Cycle for AFI
elif value > temp_policy[x][1][1] and value < temp_policy[x][1][2]:
SensorFlag[x][1] = True
# 80% Duty Cycle
elif value == temp_policy[x][2][1]:
SensorFlag[x][2] = True
#80% Prev Duty Cycle
elif value > temp_policy[x][3][1] and value < temp_policy[x][3][2]:
SensorFlag[x][3] = True
#100% Duty Cycle
elif value >= temp_policy[x][4][1]:
SensorFlag[x][4] = True
else:
pass
# Yellow Alarm
if value >= temp_policy[x][5][1] and value < temp_policy[x][5][2]:
SensorFlag[x][5] = True
# Red Alarm
elif value >= temp_policy[x][6][1] and value < temp_policy[x][6][2]:
SensorFlag[x][6] = True
# Fire Shut down
elif value >= temp_policy[x][7][1]:
SensorFlag[x][7] = True
fan = QFX5210_FanUtil()
# CHECK IF ANY TEMPERATURE SENSORS HAS SET FIRE SHUTDOWN FLAG
if SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7]:
value = self.get_alarm_led_brightness()
if ( value > 0):
self.set_alarm_led_brightness(0)
# CHECK IF ANY TEMPERATURE SENSORS HAS SET 'RED' ALARM FLAG, IF YES, SET THE ALARM LED TO 'RED'
elif SensorFlag[0][6] or SensorFlag[1][6] or SensorFlag[2][6] or SensorFlag[3][6] or SensorFlag[4][6] or SensorFlag[5][6] or SensorFlag[6][6]:
self.set_alarm_led_brightness(2)
# CHECK IF ANY TEMPERATURE SENSORS HAS SET 'YELLOW' ALARM FLAG, IF YES, SET THE ALARM LED TO 'YELLOW'
elif SensorFlag[0][5] or SensorFlag[1][5] or SensorFlag[2][5] or SensorFlag[3][5] or SensorFlag[4][5] or SensorFlag[5][5] or SensorFlag[6][5]:
self.set_alarm_led_brightness(1)
# CHECK IF ANY TEMPERATURE SENSORS HAS SET 100% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 100%
elif SensorFlag[0][4] or SensorFlag[1][4] or SensorFlag[2][4] or SensorFlag[3][4] or SensorFlag[4][4] or SensorFlag[5][4] or SensorFlag[6][4]:
fan.set_fan_duty_cycle(100)
value = self.get_alarm_led_brightness()
if ( value > 0):
self.set_alarm_led_brightness(0)
# CHECK IF ANY TEMPERATURE SENSORS HAS SET 80% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 80%
elif SensorFlag[0][3] or SensorFlag[1][3] or SensorFlag[2][3] or SensorFlag[3][3] or SensorFlag[4][3] or SensorFlag[5][3] or SensorFlag[6][3]:
fan.set_fan_duty_cycle(80)
value = self.get_alarm_led_brightness()
if ( value > 0):
self.set_alarm_led_brightness(0)
# CHECK IF ANY TEMPERATURE SENSORS HAS SET 80% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 80%
elif SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2]:
fan.set_fan_duty_cycle(80)
value = self.get_alarm_led_brightness()
if ( value > 0):
self.set_alarm_led_brightness(0)
# FOR "AFO" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 60% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 60%
# FOR "AFI" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 70% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 70%
elif SensorFlag[0][1] or SensorFlag[1][1] or SensorFlag[2][1] or SensorFlag[3][1] or SensorFlag[4][1] or SensorFlag[5][1] or SensorFlag[6][1]:
if (isPlatformAFI == True):
fan.set_fan_duty_cycle(70)
else:
fan.set_fan_duty_cycle(60)
value = self.get_alarm_led_brightness()
if ( value > 0):
self.set_alarm_led_brightness(0)
# FOR "AFO" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 60% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 60%
# FOR "AFI" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 70% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 70%
elif SensorFlag[0][0] or SensorFlag[1][0] or SensorFlag[2][0] or SensorFlag[3][0] or SensorFlag[4][0] or SensorFlag[5][0] or SensorFlag[6][0]:
if (isPlatformAFI == True):
fan.set_fan_duty_cycle(70)
else:
fan.set_fan_duty_cycle(60)
value = self.get_alarm_led_brightness()
if ( value > 0):
self.set_alarm_led_brightness(0)
else:
pass
# RESET ALL THE SENSOR FLAGS
for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD):
for y in range(self.THERMAL_NUM_RANGE):
SensorFlag[x][y] = 0
class device_monitor(object):
def __init__(self):
global isPlatformAFI
MASTER_LED_PATH = '/sys/class/leds/master/brightness'
SYSTEM_LED_PATH = '/sys/class/leds/system/brightness'
FANTYPE_PATH = '/sys/bus/i2c/devices/17-0068/fan1_direction'
import sonic_platform
platform = sonic_platform.platform.Platform()
chassis = platform.get_chassis()
fan_type = chassis.get_fan_type(FANTYPE_PATH)
# the return value of get_fan_type is AFO = 0, AFI = 1 and for error condition it is -1
# In the error condition also, we are making default platform as AFO, to continue with Energy Monitoring
if (fan_type == -1 or fan_type == 0):
if (fan_type == -1):
print "Error: unable to open sys file for fan handling, defaulting it to AFO"
isPlatformAFI = False
else:
isPlatformAFI = True
master_led_value = 1
try:
masterLED_file = open(MASTER_LED_PATH, 'r+')
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
masterLED_file.write(str(master_led_value))
masterLED_file.close()
system_led_value = 1
try:
systemLED_file = open(SYSTEM_LED_PATH, 'r+')
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
systemLED_file.write(str(system_led_value))
systemLED_file.close()
pass
def manage_device(self):
thermal = QFX5210_ThermalUtil()
thermal.getSensorTemp()
def main():
monitor = device_monitor()
while True:
monitor.manage_device()
time.sleep(20)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,545 @@
#!/usr/bin/env python
#
# Modified to work on Juniper QFX5210
#
# Based on accton_as7816_util.py
#
# Copyright (C) 2016 Accton Networks, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Usage: %(scriptName)s [options] command object
options:
-h | --help : this help message
-d | --debug : run with debug mode
-f | --force : ignore error during installation or clean
command:
install : install drivers and generate related sysfs nodes
clean : uninstall drivers and remove related sysfs nodes
show : show all systen status
sff : dump SFP eeprom
set : change board setting with fan|led|sfp
"""
import os
import commands
import sys, getopt
import binascii
import logging
import re
import time
import random
import optparse
from collections import namedtuple
PROJECT_NAME = 'qfx5210_64x'
version = '0.1.0'
verbose = False
DEBUG = False
args = []
ALL_DEVICE = {}
DEVICE_NO = {'led':4, 'fan':4,'thermal':6, 'psu':2, 'sfp':64}
FORCE = 0
#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG)
#logging.basicConfig(level=logging.INFO)
if DEBUG == True:
print sys.argv[0]
print 'ARGV :', sys.argv[1:]
def main():
global DEBUG
global args
global FORCE
if len(sys.argv)<2:
show_help()
options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help',
'debug',
'force',
])
if DEBUG == True:
print options
print args
print len(sys.argv)
for opt, arg in options:
if opt in ('-h', '--help'):
show_help()
elif opt in ('-d', '--debug'):
DEBUG = True
logging.basicConfig(level=logging.INFO)
elif opt in ('-f', '--force'):
FORCE = 1
else:
logging.info('no option')
for arg in args:
if arg == 'install':
do_install()
elif arg == 'clean':
do_uninstall()
elif arg == 'show':
device_traversal()
elif arg == 'sff':
if len(args)!=2:
show_eeprom_help()
elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']:
show_eeprom_help()
else:
show_eeprom(args[1])
return
elif arg == 'set':
if len(args)<3:
show_set_help()
else:
set_device(args[1:])
return
else:
show_help()
DisableWatchDogCmd = '/usr/sbin/i2cset -y 0 0x65 0x3 0x04'
# Disable watchdog
try:
os.system(DisableWatchDogCmd)
except OSError:
print 'Error: Execution of "%s" failed', DisableWatchDogCmd
return False
CPUeepromFileCmd = 'cat /sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom > /etc/init.d/eeprom_qfx5210_ascii'
# Write the contents of CPU EEPROM to file
try:
os.system(CPUeepromFileCmd)
except OSError:
print 'Error: Execution of "%s" failed', CPUeepromFileCmd
return False
return True
def show_help():
print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
sys.exit(0)
def show_set_help():
cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
print cmd +" [led|sfp|fan]"
print " use \""+ cmd + " led 0-4 \" to set led color"
print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable"
sys.exit(0)
def show_eeprom_help():
cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom"
sys.exit(0)
def my_log(txt):
if DEBUG == True:
print "[ROY]"+txt
return
def log_os_system(cmd, show):
logging.info('Run :'+cmd)
status, output = commands.getstatusoutput(cmd)
my_log (cmd +"with result:" + str(status))
my_log (" output:"+output)
if status:
logging.info('Failed :'+cmd)
if show:
print('Failed :'+cmd)
return status, output
def driver_check():
ret, lsmod = log_os_system("lsmod| grep juniper", 0)
logging.info('mods:'+lsmod)
if len(lsmod) ==0:
return False
return True
kos = [
'modprobe i2c_dev',
'modprobe i2c_mux_pca954x',
'modprobe juniper_i2c_cpld' ,
'modprobe ym2651y' ,
'modprobe x86-64-juniper-qfx5210-64x-fan' ,
'modprobe x86-64-juniper-qfx5210-64x-sfp' ,
'modprobe x86-64-juniper-qfx5210-64x-leds' ,
'modprobe x86-64-juniper-qfx5210-64x-psu' ]
def driver_install():
global FORCE
status, output = log_os_system("depmod", 1)
for i in range(0,len(kos)):
status, output = log_os_system(kos[i], 1)
if status:
if FORCE == 0:
return status
return 0
def driver_uninstall():
global FORCE
for i in range(0,len(kos)):
rm = kos[-(i+1)].replace("modprobe", "modprobe -rq")
rm = rm.replace("insmod", "rmmod")
status, output = log_os_system(rm, 1)
if status:
if FORCE == 0:
return status
return 0
led_prefix ='/sys/class/leds/'
hwmon_types = {'led': ['alarm','system','master','beacon']}
hwmon_nodes = {'led': ['brightness'] }
hwmon_prefix ={'led': led_prefix}
i2c_prefix = '/sys/bus/i2c/devices/'
i2c_bus = {'fan': ['17-0068'] ,
'thermal': ['18-0048','18-0049', '18-004a' , '18-004b', '17-004d', '17-004e'] ,
'psu': ['10-0053','9-0050'],
'sfp': ['-0050']}
i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] ,
'thermal': ['hwmon/hwmon*/temp1_input'] ,
'psu': ['psu_present ', 'psu_power_good'] ,
'sfp': ['sfp_is_present ', 'sfp_tx_disable']}
sfp_map = [37,38,39,40,42,41,44,43,33,34,35,36,45,46,47,48,49,50,51,52,
61,62,63,64,53,54,55,56,57,58,59,60,69,70,71,72,77,78,79,80,65,
66,67,68,73,74,75,76,85,86,87,88,31,32,29,30,81,82,83,84,25,26,
27,28]
mknod =[
'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device',
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device',
'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device',
'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device',
'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device',
'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-2/new_device',
'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-2/new_device',
'echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo qfx5210_64x_psu1 0x53 > /sys/bus/i2c/devices/i2c-10/new_device',
'echo ym2851 0x5b > /sys/bus/i2c/devices/i2c-10/new_device',
'echo qfx5210_64x_psu2 0x50 > /sys/bus/i2c/devices/i2c-9/new_device',
'echo ym2851 0x58 > /sys/bus/i2c/devices/i2c-9/new_device',
'echo qfx5210_64x_fan 0x68 > /sys/bus/i2c/devices/i2c-17/new_device',
'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-18/new_device',
'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-18/new_device',
'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-18/new_device',
'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-18/new_device',
'echo lm75 0x4d > /sys/bus/i2c/devices/i2c-17/new_device',
'echo lm75 0x4e > /sys/bus/i2c/devices/i2c-17/new_device',
'echo cpld_qfx5210 0x60 > /sys/bus/i2c/devices/i2c-19/new_device',
'echo cpld_plain 0x62 > /sys/bus/i2c/devices/i2c-20/new_device',
'echo cpld_plain 0x64 > /sys/bus/i2c/devices/i2c-21/new_device',
'echo cpld_plain 0x66 > /sys/bus/i2c/devices/i2c-22/new_device']
def i2c_order_check():
return 0
def device_install():
global FORCE
for i in range(0,len(mknod)):
#for pca954x need times to built new i2c buses
if mknod[i].find('pca954') != -1:
time.sleep(1)
status, output = log_os_system(mknod[i], 1)
if status:
print output
if FORCE == 0:
return status
for i in range(0,len(sfp_map)):
status, output =log_os_system("echo qfx5210_64x_port"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
if status:
print output
if FORCE == 0:
return status
return
def device_uninstall():
global FORCE
status, output =log_os_system("ls /sys/bus/i2c/devices/1-0076", 0)
for i in range(0,len(sfp_map)):
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
status, output =log_os_system("echo 0x50 > "+ target, 1)
if status:
print output
if FORCE == 0:
return status
nodelist = mknod
for i in range(len(nodelist)):
target = nodelist[-(i+1)]
temp = target.split()
del temp[1]
temp[-1] = temp[-1].replace('new_device', 'delete_device')
status, output = log_os_system(" ".join(temp), 1)
if status:
print output
if FORCE == 0:
return status
return
def system_ready():
if driver_check() == False:
return False
if not device_exist():
return False
return True
def do_install():
print "Checking system...."
if driver_check() == False:
print "No driver, installing...."
status = driver_install()
if status:
if FORCE == 0:
return status
else:
print PROJECT_NAME.upper()+" drivers detected...."
if not device_exist():
print "No device, installing...."
status = device_install()
if status:
if FORCE == 0:
return status
else:
print PROJECT_NAME.upper()+" devices detected...."
return
def do_uninstall():
print "Checking system...."
if not device_exist():
print PROJECT_NAME.upper() +" has no device installed...."
else:
print "Removing device...."
status = device_uninstall()
if status:
if FORCE == 0:
return status
if driver_check()== False :
print PROJECT_NAME.upper() +" has no driver installed...."
else:
print "Removing installed driver...."
status = driver_uninstall()
if status:
if FORCE == 0:
return status
return
def devices_info():
global DEVICE_NO
global ALL_DEVICE
global i2c_bus, hwmon_types
for key in DEVICE_NO:
ALL_DEVICE[key]= {}
for i in range(0,DEVICE_NO[key]):
ALL_DEVICE[key][key+str(i+1)] = []
for key in i2c_bus:
buses = i2c_bus[key]
nodes = i2c_nodes[key]
for i in range(0,len(buses)):
for j in range(0,len(nodes)):
if 'fan' == key:
for k in range(0,DEVICE_NO[key]):
node = key+str(k+1)
path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j]
my_log(node+": "+ path)
ALL_DEVICE[key][node].append(path)
elif 'sfp' == key:
for k in range(0,DEVICE_NO[key]):
node = key+str(k+1)
path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
my_log(node+": "+ path)
ALL_DEVICE[key][node].append(path)
else:
node = key+str(i+1)
path = i2c_prefix+ buses[i]+"/"+ nodes[j]
my_log(node+": "+ path)
ALL_DEVICE[key][node].append(path)
for key in hwmon_types:
itypes = hwmon_types[key]
nodes = hwmon_nodes[key]
for i in range(0,len(itypes)):
for j in range(0,len(nodes)):
node = key+"_"+itypes[i]
path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
my_log(node+": "+ path)
ALL_DEVICE[key][ key+str(i+1)].append(path)
#show dict all in the order
if DEBUG == True:
for i in sorted(ALL_DEVICE.keys()):
print(i+": ")
for j in sorted(ALL_DEVICE[i].keys()):
print(" "+j)
for k in (ALL_DEVICE[i][j]):
print(" "+" "+k)
return
def show_eeprom(index):
if system_ready()==False:
print("System's not ready.")
print("Please install first!")
return
if len(ALL_DEVICE)==0:
devices_info()
node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
node = node.replace(node.split("/")[-1], 'sfp_eeprom')
# check if got hexdump command in current environment
ret, log = log_os_system("which hexdump", 0)
ret, log2 = log_os_system("which busybox hexdump", 0)
if len(log):
hex_cmd = 'hexdump'
elif len(log2):
hex_cmd = ' busybox hexdump'
else:
log = 'Failed : no hexdump cmd!!'
logging.info(log)
print log
return 1
print node + ":"
ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
if ret==0:
print log
else:
print "**********device no found**********"
return
def set_device(args):
global DEVICE_NO
global ALL_DEVICE
if system_ready()==False:
print("System's not ready.")
print("Please install first!")
return
if len(ALL_DEVICE)==0:
devices_info()
if args[0]=='led':
if int(args[1])>4:
show_set_help()
return
#print ALL_DEVICE['led']
for i in range(0,len(ALL_DEVICE['led'])):
for k in (ALL_DEVICE['led']['led'+str(i+1)]):
ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
if ret:
return ret
elif args[0]=='fan':
if int(args[1])>100:
show_set_help()
return
#print ALL_DEVICE['fan']
#fan1~6 is all fine, all fan share same setting
node = ALL_DEVICE['fan'] ['fan1'][0]
node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage')
ret, log = log_os_system("cat "+ node, 1)
if ret==0:
print ("Previous fan duty: " + log.strip() +"%")
ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
if ret==0:
print ("Current fan duty: " + args[1] +"%")
return ret
elif args[0]=='sfp':
if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
show_set_help()
return
if len(args)<2:
show_set_help()
return
if int(args[2])>1:
show_set_help()
return
#print ALL_DEVICE[args[0]]
for i in range(0,len(ALL_DEVICE[args[0]])):
for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
if j.find('tx_disable')!= -1:
ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
if ret:
return ret
return
#get digits inside a string.
#Ex: 31 for "sfp31"
def get_value(input):
digit = re.findall('\d+', input)
return int(digit[0])
def device_traversal():
if system_ready()==False:
print("System's not ready.")
print("Please install first!")
return
if len(ALL_DEVICE)==0:
devices_info()
for i in sorted(ALL_DEVICE.keys()):
print("============================================")
print(i.upper()+": ")
print("============================================")
for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
print " "+j+":",
for k in (ALL_DEVICE[i][j]):
ret, log = log_os_system("cat "+k, 0)
func = k.split("/")[-1].strip()
func = re.sub(j+'_','',func,1)
func = re.sub(i.lower()+'_','',func,1)
if ret==0:
print func+"="+log+" ",
else:
print func+"="+"X"+" ",
print
print("----------------------------------------------------------------")
print
return
def device_exist():
ret1, log = log_os_system("ls "+i2c_prefix+"*0076", 0)
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0)
return not(ret1 or ret2)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,106 @@
#!/usr/bin/env bash
#
# Name: platform_poweroff version: 1.0
#
# Description: This file contains the implementation of qfx5210 poweroff
# sequences
#
# Copyright (c) 2019, Juniper Networks, Inc.
# All rights reserved.
#
# Notice and Disclaimer: This code is licensed to you under the GNU General
# Public License as published by the Free Software Foundation, version 2 or
# any later version. This code is not an official Juniper product. You can
# obtain a copy of the License at <https://www.gnu.org/licenses/>
#
# OSS License:
#
# 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.
#
# Third-Party Code: This code may depend on other components under separate
# copyright notice and license terms. Your use of the source code for those
# components is subject to the terms and conditions of the respective license
# as noted in the Third-Party source code file.
LOGFILE="/var/log/poweroff_log"
TIMESTAMP=`date "+%Y-%m-%d %H:%M:%S"`
retry()
{
local ret_value=0
if [ $# -ne 3 ]; then
echo 'usage: retry <num retries> <wait retry secs> "<command>"'
exit 1
fi
retries=$1
wait_retry=$2
command=$3
for i in `seq 1 $retries`; do
echo "$TIMESTAMP $command" >> $LOGFILE
$command
ret_value=$?
[ $ret_value -eq 0 ] && break
echo "$TIMESTAMP Error: Command Execution failed with $ret_value, waiting to retry..." >> $LOGFILE
sleep $wait_retry
done
return $ret_value
}
if [ -f /usr/sbin/i2cset ] && [ -f /usr/sbin/i2cget ]; then
#Check if the CPU CPLD address is present on the bus or not
#0x65 - Azurite CPU CPLD I2C Addr
retry 128 1 "i2cget -y 0 0x65 0x0"
ret_val=$?
if [ $ret_val -ne 0 ]; then
echo "$TIMESTAMP CPU CPLD I2C Addr is not accessible...Terminating the halt.." >> $LOGFILE
return $ret_value
fi
#Initing Halt condition
retry 128 1 "/usr/sbin/i2cset -f -y 0 0x65 0x14 0x00"
ret_val=$?
if [ $ret_val -ne 0 ]; then
echo "$TIMESTAMP Halt Init Failed..." >> $LOGFILE
return $ret_value
fi
#Enable 0x77 MUX's First channel to access 0x76 MUX
retry 128 1 "/usr/sbin/i2cset -f -y 0 0x77 0 0x01"
ret_val=$?
if [ $ret_val -ne 0 ]; then
echo "$TIMESTAMP Mux Level1 enabling failed..." >> $LOGFILE
return $ret_value
fi
#Enable 0x76 MUX's Third channel to access Main Board CPLD @0x60
retry 128 1 "/usr/sbin/i2cset -f -y 0 0x76 0 0x04"
ret_val=$?
if [ $ret_val -ne 0 ]; then
echo "$TIMESTAMP Mux Level2 enabling failed..." >> $LOGFILE
return $ret_value
fi
sync
echo "$TIMESTAMP System is going to Halt now ........" | tee $LOGFILE
#Sleeping for sometime, so that Print can reach to logger
sleep 1
#Asserting the Halt on Azurite
retry 128 1 "/usr/sbin/i2cset -f -y 0 0x60 0x24 0x00"
ret_val=$?
if [ $ret_val -ne 0 ]; then
echo "$TIMESTAMP Halt command execution failed...Terminating the halt.." | tee $LOGFILE
return $ret_value
fi
fi