[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:
parent
cfcf30570b
commit
fdcb69d048
@ -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
|
@ -0,0 +1 @@
|
||||
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-qfx5210-64x100G.config.bcm
|
@ -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
|
1
device/juniper/x86_64-juniper_qfx5210-r0/default_sku
Normal file
1
device/juniper/x86_64-juniper_qfx5210-r0/default_sku
Normal file
@ -0,0 +1 @@
|
||||
Juniper-QFX5210-64C t1
|
2
device/juniper/x86_64-juniper_qfx5210-r0/installer.conf
Normal file
2
device/juniper/x86_64-juniper_qfx5210-r0/installer.conf
Normal file
@ -0,0 +1,2 @@
|
||||
CONSOLE_SPEED=9600
|
||||
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="tg3.short_preamble=1 tg3.bcm5718s_reset=1"
|
155
device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc
Executable file
155
device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc
Executable 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
|
2823
device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json
Normal file
2823
device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json
Normal file
File diff suppressed because it is too large
Load Diff
40
device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py
Normal file
40
device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py
Normal 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)
|
||||
|
61
device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py
Executable file
61
device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py
Executable 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
|
761
device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py
Normal file
761
device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py
Normal 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
|
@ -51,7 +51,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
|
||||
$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \
|
||||
$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \
|
||||
$(BRCM_XLR_GTS_PLATFORM_MODULE) \
|
||||
$(DELTA_AG9032V2A_PLATFORM_MODULE)
|
||||
$(DELTA_AG9032V2A_PLATFORM_MODULE) \
|
||||
$(JUNIPER_QFX5210_PLATFORM_MODULE)
|
||||
ifeq ($(INSTALL_DEBUG_TOOLS),y)
|
||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
|
||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
|
||||
|
13
platform/broadcom/platform-modules-juniper.mk
Executable file
13
platform/broadcom/platform-modules-juniper.mk
Executable 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)
|
@ -10,6 +10,7 @@ include $(PLATFORM_PATH)/platform-modules-cel.mk
|
||||
include $(PLATFORM_PATH)/platform-modules-delta.mk
|
||||
include $(PLATFORM_PATH)/platform-modules-quanta.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)/docker-syncd-brcm.mk
|
||||
include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk
|
||||
|
50
platform/broadcom/sonic-platform-modules-juniper/.gitignore
vendored
Normal file
50
platform/broadcom/sonic-platform-modules-juniper/.gitignore
vendored
Normal 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
|
16
platform/broadcom/sonic-platform-modules-juniper/LICENSE
Normal file
16
platform/broadcom/sonic-platform-modules-juniper/LICENSE
Normal 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.
|
@ -0,0 +1 @@
|
||||
platform drivers for Juniper QFX5210 for the SONiC project
|
@ -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, ®, &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, ®, &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");
|
@ -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");
|
||||
|
||||
|
6
platform/broadcom/sonic-platform-modules-juniper/debian/changelog
Executable file
6
platform/broadcom/sonic-platform-modules-juniper/debian/changelog
Executable 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
|
||||
|
@ -0,0 +1 @@
|
||||
9
|
11
platform/broadcom/sonic-platform-modules-juniper/debian/control
Executable file
11
platform/broadcom/sonic-platform-modules-juniper/debian/control
Executable 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
|
||||
|
@ -0,0 +1,2 @@
|
||||
sonic-juniper-platform-modules_1.1_amd64.buildinfo main extra
|
||||
sonic-platform-juniper-qfx5210_1.1_amd64.deb main extra
|
86
platform/broadcom/sonic-platform-modules-juniper/debian/rules
Executable file
86
platform/broadcom/sonic-platform-modules-juniper/debian/rules
Executable 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
|
@ -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
|
@ -0,0 +1,2 @@
|
||||
systemctl enable qfx5210-platform-init.service
|
||||
systemctl start qfx5210-platform-init.service
|
@ -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
|
@ -0,0 +1 @@
|
||||
../../common/modules/juniper_i2c_cpld.c
|
@ -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");
|
||||
|
@ -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, ®)) {
|
||||
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");
|
||||
|
@ -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");
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@
|
||||
../../common/modules/ym2651y.c
|
@ -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
|
16
platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py
Executable file
16
platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py
Executable 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'},
|
||||
)
|
||||
|
@ -0,0 +1 @@
|
||||
import platform
|
@ -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")
|
@ -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
|
||||
|
87
platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README
Executable file
87
platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README
Executable 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.
|
||||
|
@ -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()
|
||||
|
@ -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()
|
106
platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/platform_poweroff
Executable file
106
platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/platform_poweroff
Executable 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
|
Loading…
Reference in New Issue
Block a user