[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_SNH60A0_320FV2_PLATFORM_MODULE) \
|
||||||
$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \
|
$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \
|
||||||
$(BRCM_XLR_GTS_PLATFORM_MODULE) \
|
$(BRCM_XLR_GTS_PLATFORM_MODULE) \
|
||||||
$(DELTA_AG9032V2A_PLATFORM_MODULE)
|
$(DELTA_AG9032V2A_PLATFORM_MODULE) \
|
||||||
|
$(JUNIPER_QFX5210_PLATFORM_MODULE)
|
||||||
ifeq ($(INSTALL_DEBUG_TOOLS),y)
|
ifeq ($(INSTALL_DEBUG_TOOLS),y)
|
||||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
|
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
|
||||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
|
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
|
||||||
|
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-delta.mk
|
||||||
include $(PLATFORM_PATH)/platform-modules-quanta.mk
|
include $(PLATFORM_PATH)/platform-modules-quanta.mk
|
||||||
#include $(PLATFORM_PATH)/platform-modules-mitac.mk
|
#include $(PLATFORM_PATH)/platform-modules-mitac.mk
|
||||||
|
include $(PLATFORM_PATH)/platform-modules-juniper.mk
|
||||||
include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk
|
include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk
|
||||||
include $(PLATFORM_PATH)/docker-syncd-brcm.mk
|
include $(PLATFORM_PATH)/docker-syncd-brcm.mk
|
||||||
include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk
|
include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk
|
||||||
|
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