diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers.json.j2 b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers.json.j2 new file mode 100755 index 00000000000..1083a6210fc --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t0.j2 b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t0.j2 new file mode 100755 index 00000000000..534ff465620 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t0.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "egress_lossy_pool": { + "size": "67108864", + "type": "egress", + "mode": "dynamic" + }, + "ingress_lossless_pool": { + "mode": "dynamic", + "size": "59001152", + "xoff": "7428992", + "type": "ingress" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"67108864" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t1.j2 b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t1.j2 new file mode 100755 index 00000000000..534ff465620 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t1.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "egress_lossy_pool": { + "size": "67108864", + "type": "egress", + "mode": "dynamic" + }, + "ingress_lossless_pool": { + "mode": "dynamic", + "size": "59001152", + "xoff": "7428992", + "type": "ingress" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"67108864" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/pg_profile_lookup.ini b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/pg_profile_lookup.ini new file mode 100755 index 00000000000..a5f3286beef --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/pg_profile_lookup.ini @@ -0,0 +1,23 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1270 0 190500 -2 2540 + 25000 5m 1270 0 190500 -2 2540 + 40000 5m 1270 0 190500 -2 2540 + 50000 5m 1270 0 190500 -2 2540 + 100000 5m 1270 0 190500 -2 2540 + 200000 5m 1270 0 190500 -2 2540 + 400000 5m 1270 0 190500 -2 2540 + 10000 40m 1270 0 190500 -2 2540 + 25000 40m 1270 0 190500 -2 2540 + 40000 40m 1270 0 190500 -2 2540 + 50000 40m 1270 0 190500 -2 2540 + 100000 40m 1270 0 190500 -2 2540 + 200000 40m 1270 0 190500 -2 2540 + 400000 40m 1270 0 190500 -2 2540 + 10000 300m 1270 0 190500 -2 2540 + 25000 300m 1270 0 190500 -2 2540 + 40000 300m 1270 0 190500 -2 2540 + 50000 300m 1270 0 190500 -2 2540 + 100000 300m 1270 0 190500 -2 2540 + 200000 300m 1270 0 190500 -2 2540 + 400000 300m 1270 0 190500 -2 2540 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/port_config.ini b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/port_config.ini new file mode 100755 index 00000000000..f591f69f1ad --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index speed +Ethernet0 1,2,3,4,5,6,7,8 Ethernet1/0/1 0 400000 +Ethernet8 9,10,11,12,13,14,15,16 Ethernet1/0/9 1 400000 +Ethernet16 17,18,19,20,21,22,23,24 Ethernet1/0/17 2 400000 +Ethernet24 25,26,27,28,29,30,31,32 Ethernet1/0/25 3 400000 +Ethernet32 33,34,35,36,37,38,39,40 Ethernet1/0/33 4 400000 +Ethernet40 41,42,43,44,45,46,47,48 Ethernet1/0/41 5 400000 +Ethernet48 49,50,51,52,53,54,55,56 Ethernet1/0/48 6 400000 +Ethernet56 57,58,59,60,61,62,63,64 Ethernet1/0/57 7 400000 +Ethernet64 65,66,67,68,69,70,71,72 Ethernet1/0/65 8 400000 +Ethernet72 73,74,75,76,77,78,79,80 Ethernet1/0/73 9 400000 +Ethernet80 81,82,83,84,85,86,87,88 Ethernet1/0/81 10 400000 +Ethernet88 89,90,91,92,93,94,95,96 Ethernet1/0/89 11 400000 +Ethernet96 97,98,99,100,101,102,103,104 Ethernet1/0/97 12 400000 +Ethernet104 105,106,107,108,109,110,111,112 Ethernet1/0/105 13 400000 +Ethernet112 113,114,115,116,117,118,119,120 Ethernet1/0/113 14 400000 +Ethernet120 121,122,123,124,125,126,127,128 Ethernet1/0/121 15 400000 +Ethernet128 129,130,131,132,133,134,135,136 Ethernet1/0/129 16 400000 +Ethernet136 137,138,139,140,141,142,143,144 Ethernet1/0/137 17 400000 +Ethernet144 145,146,147,148,149,150,151,152 Ethernet1/0/145 18 400000 +Ethernet152 153,154,155,156,157,158,159,160 Ethernet1/0/153 19 400000 +Ethernet160 161,162,163,164,165,166,167,168 Ethernet1/0/161 20 400000 +Ethernet168 169,170,171,172,173,174,175,176 Ethernet1/0/169 21 400000 +Ethernet176 177,178,179,180,181,182,183,184 Ethernet1/0/177 22 400000 +Ethernet184 185,186,187,188,189,190,191,192 Ethernet1/0/185 23 400000 +Ethernet192 193,194,195,196,197,198,199,200 Ethernet1/0/193 24 400000 +Ethernet200 201,202,203,204,205,206,207,208 Ethernet1/0/201 25 400000 +Ethernet208 209,210,211,212,213,214,215,216 Ethernet1/0/209 26 400000 +Ethernet216 217,218,219,220,221,222,223,224 Ethernet1/0/217 27 400000 +Ethernet224 225,226,227,228,229,230,231,232 Ethernet1/0/225 28 400000 +Ethernet232 233,234,235,236,237,238,239,240 Ethernet1/0/233 29 400000 +Ethernet240 241,242,243,244,245,246,247,248 Ethernet1/0/241 30 400000 +Ethernet248 249,250,251,252,253,254,255,256 Ethernet1/0/249 31 400000 +Ethernet256 257 Ethernet1/0/257 32 10000 +Ethernet257 258 Ethernet1/0/258 33 10000 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/qos.json.j2 b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/qos.json.j2 new file mode 100755 index 00000000000..5838547e074 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/qos.json.j2 @@ -0,0 +1,228 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "pfc_enable" : "3,4", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/sai.profile b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/sai.profile new file mode 100755 index 00000000000..9b506d71833 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-snj60b0-32x400G.config.bcm diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/th3-snj60b0-32x400G.config.bcm b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/th3-snj60b0-32x400G.config.bcm new file mode 100755 index 00000000000..f3bf629f062 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/th3-snj60b0-32x400G.config.bcm @@ -0,0 +1,298 @@ +# This property file is for JUNGFRAU 1x400Gx32 mode only. +# JUNGFRAU uses Tomahawk3 BCM56980 as its mac. Besides, it is phyless. + +os=linux +led_fw_path="/usr/share/sonic/platform/" +bcm_stat_interval.0=1000000 +bcm_linkscan_interval.0=250000 + +mdio_output_delay.0=0xf +mem_cache_enable=0 + +parity_enable=0 +core_clock_frequency=1325 + +dpr_clock_frequency=1000 + +# Blackhawk Core - 32 front ports +# BlackhawkCore[0 - 3] must map to device port[1-18], PIPE-0. +portmap_1=1:400 +portmap_5=9:400 +portmap_9=17:400 +portmap_13=25:400 + +# BlackhawkCore[4 - 7] must map to device port[20-37], PIPE-1. +portmap_20=33:400 +portmap_24=41:400 +portmap_28=49:400 +portmap_32=57:400 + +# BlackhawkCore[8 - 11] must map to logical port[40-57], PIPE-2. +portmap_40=65:400 +portmap_44=73:400 +portmap_48=81:400 +portmap_52=89:400 + +# BlackhawkCore[12 - 15] must map to logical port[60-77], PIPE-3. +portmap_60=97:400 +portmap_64=105:400 +portmap_68=113:400 +portmap_72=121:400 + +# BlackhawkCore[16 - 19] must map to logical port[80-97], PIPE-4. +portmap_80=129:400 +portmap_84=137:400 +portmap_88=145:400 +portmap_92=153:400 + +# BlackhawkCore[20 - 23] must map to logical port[100-117], PIPE-5. +portmap_100=161:400 +portmap_104=169:400 +portmap_108=177:400 +portmap_112=185:400 + +# BlackhawkCore[24 - 27] must map to logical port[120-137], PIPE-6. +portmap_120=193:400 +portmap_124=201:400 +portmap_128=209:400 +portmap_132=217:400 + +# BlackhawkCore[28 - 31] must map to logical port[140-157], PIPE-7. +portmap_140=225:400 +portmap_144=233:400 +portmap_148=241:400 +portmap_152=249:400 + +# Merlin Core - 2 management ports +portmap_38=257:10 +portmap_118=258:10 + +# Configure all front port as XE and CD ports. +pbmp_xport_xe=0x0FFFF0FFFF4FFFF0FFFF0FFFF0FFFF4FFFF1FFFE +pbmp_oversubscribe=0x0FFFF0FFFF4FFFF0FFFF0FFFF0FFFF4FFFF1FFFE + +# lane map and polarity +# BlackhawkCore0 +phy_chain_rx_lane_map_physical{1.0}=0x42735061 +serdes_core_rx_polarity_flip_physical{1}=0xe6 +phy_chain_tx_lane_map_physical{1.0}=0x71056243 +serdes_core_tx_polarity_flip_physical{1}=0xa1 + +# BlackhawkCore1 +phy_chain_rx_lane_map_physical{9.0}=0x27150634 +serdes_core_rx_polarity_flip_physical{9}=0xd8 +phy_chain_tx_lane_map_physical{9.0}=0x63520714 +serdes_core_tx_polarity_flip_physical{9}=0x2c + +# BlackhawkCore2 +phy_chain_rx_lane_map_physical{17.0}=0x43025176 +serdes_core_rx_polarity_flip_physical{17}=0xcb +phy_chain_tx_lane_map_physical{17.0}=0x21034765 +serdes_core_tx_polarity_flip_physical{17}=0x4f + +# BlackhawkCore3 +phy_chain_rx_lane_map_physical{25.0}=0x67352014 +serdes_core_rx_polarity_flip_physical{25}=0x72 +phy_chain_tx_lane_map_physical{25.0}=0x62730415 +serdes_core_tx_polarity_flip_physical{25}=0x69 + +# BlackhawkCore4 +phy_chain_rx_lane_map_physical{33.0}=0x13026754 +serdes_core_rx_polarity_flip_physical{33}=0xc3 +phy_chain_tx_lane_map_physical{33.0}=0x35274061 +serdes_core_tx_polarity_flip_physical{33}=0x8e + +# BlackhawkCore5 +phy_chain_rx_lane_map_physical{41.0}=0x35270146 +serdes_core_rx_polarity_flip_physical{41}=0x78 +phy_chain_tx_lane_map_physical{41.0}=0x73526014 +serdes_core_tx_polarity_flip_physical{41}=0xa4 + +# BlackhawkCore6 +phy_chain_rx_lane_map_physical{49.0}=0x13025647 +serdes_core_rx_polarity_flip_physical{49}=0xcc +phy_chain_tx_lane_map_physical{49.0}=0x37054162 +serdes_core_tx_polarity_flip_physical{49}=0x9b + +# BlackhawkCore7 +phy_chain_rx_lane_map_physical{57.0}=0x35270416 +serdes_core_rx_polarity_flip_physical{57}=0x78 +phy_chain_tx_lane_map_physical{57.0}=0x63720415 +serdes_core_tx_polarity_flip_physical{57}=0xb9 + +# BlackhawkCore8 +phy_chain_rx_lane_map_physical{65.0}=0x13024756 +serdes_core_rx_polarity_flip_physical{65}=0xc3 +phy_chain_tx_lane_map_physical{65.0}=0x37054162 +serdes_core_tx_polarity_flip_physical{65}=0xab + +# BlackhawkCore9 +phy_chain_rx_lane_map_physical{73.0}=0x35270146 +serdes_core_rx_polarity_flip_physical{73}=0x78 +phy_chain_tx_lane_map_physical{73.0}=0x63720514 +serdes_core_tx_polarity_flip_physical{73}=0x3c + +# BlackhawkCore10 +phy_chain_rx_lane_map_physical{81.0}=0x13024756 +serdes_core_rx_polarity_flip_physical{81}=0xc3 +phy_chain_tx_lane_map_physical{81.0}=0x35204761 +serdes_core_tx_polarity_flip_physical{81}=0x9e + +# BlackhawkCore11 +phy_chain_rx_lane_map_physical{89.0}=0x35270416 +serdes_core_rx_polarity_flip_physical{89}=0x78 +phy_chain_tx_lane_map_physical{89.0}=0x73620514 +serdes_core_tx_polarity_flip_physical{89}=0x8c + +# BlackhawkCore12 +phy_chain_rx_lane_map_physical{97.0}=0x13024756 +serdes_core_rx_polarity_flip_physical{97}=0xc3 +phy_chain_tx_lane_map_physical{97.0}=0x37154062 +serdes_core_tx_polarity_flip_physical{97}=0xaf + +# BlackhawkCore13 +phy_chain_rx_lane_map_physical{105.0}=0x45671320 +serdes_core_rx_polarity_flip_physical{105}=0x53 +phy_chain_tx_lane_map_physical{105.0}=0x62730415 +serdes_core_tx_polarity_flip_physical{105}=0x69 + +# BlackhawkCore14 +phy_chain_rx_lane_map_physical{113.0}=0x13026754 +serdes_core_rx_polarity_flip_physical{113}=0xc3 +phy_chain_tx_lane_map_physical{113.0}=0x17254063 +serdes_core_tx_polarity_flip_physical{113}=0x8e + +# BlackhawkCore15 +phy_chain_rx_lane_map_physical{121.0}=0x65471230 +serdes_core_rx_polarity_flip_physical{121}=0xaa +phy_chain_tx_lane_map_physical{121.0}=0x27351406 +serdes_core_tx_polarity_flip_physical{121}=0x3d + +# BlackhawkCore16 +phy_chain_rx_lane_map_physical{129.0}=0x62735140 +serdes_core_rx_polarity_flip_physical{129}=0x63 +phy_chain_tx_lane_map_physical{129.0}=0x52736140 +serdes_core_tx_polarity_flip_physical{129}=0xf4 + +# BlackhawkCore17 +phy_chain_rx_lane_map_physical{137.0}=0x35270416 +serdes_core_rx_polarity_flip_physical{137}=0x78 +phy_chain_tx_lane_map_physical{137.0}=0x52731604 +serdes_core_tx_polarity_flip_physical{137}=0xe2 + +# BlackhawkCore18 +phy_chain_rx_lane_map_physical{145.0}=0x02135746 +serdes_core_rx_polarity_flip_physical{145}=0x39 +phy_chain_tx_lane_map_physical{145.0}=0x15274063 +serdes_core_tx_polarity_flip_physical{145}=0x8e + +# BlackhawkCore19 +phy_chain_rx_lane_map_physical{153.0}=0x05471263 +serdes_core_rx_polarity_flip_physical{153}=0x81 +phy_chain_tx_lane_map_physical{153.0}=0x43621705 +serdes_core_tx_polarity_flip_physical{153}=0x9f + +# BlackhawkCore20 +phy_chain_rx_lane_map_physical{161.0}=0x13620475 +serdes_core_rx_polarity_flip_physical{161}=0x66 +phy_chain_tx_lane_map_physical{161.0}=0x35274061 +serdes_core_tx_polarity_flip_physical{161}=0x2f + +# BlackhawkCore21 +phy_chain_rx_lane_map_physical{169.0}=0x15074263 +serdes_core_rx_polarity_flip_physical{169}=0x71 +phy_chain_tx_lane_map_physical{169.0}=0x52731604 +serdes_core_tx_polarity_flip_physical{169}=0x62 + +# BlackhawkCore22 +phy_chain_rx_lane_map_physical{177.0}=0x13620475 +serdes_core_rx_polarity_flip_physical{177}=0xee +phy_chain_tx_lane_map_physical{177.0}=0x37254061 +serdes_core_tx_polarity_flip_physical{177}=0x8e + +# BlackhawkCore23 +phy_chain_rx_lane_map_physical{185.0}=0x15074263 +serdes_core_rx_polarity_flip_physical{185}=0x71 +phy_chain_tx_lane_map_physical{185.0}=0x52730614 +serdes_core_tx_polarity_flip_physical{185}=0x68 + +# BlackhawkCore24 +phy_chain_rx_lane_map_physical{193.0}=0x13620475 +serdes_core_rx_polarity_flip_physical{193}=0xee +phy_chain_tx_lane_map_physical{193.0}=0x37254061 +serdes_core_tx_polarity_flip_physical{193}=0x8e + +# BlackhawkCore25 +phy_chain_rx_lane_map_physical{201.0}=0x15074263 +serdes_core_rx_polarity_flip_physical{201}=0x71 +phy_chain_tx_lane_map_physical{201.0}=0x53720614 +serdes_core_tx_polarity_flip_physical{201}=0x38 + +# BlackhawkCore26 +phy_chain_rx_lane_map_physical{209.0}=0x13620745 +serdes_core_rx_polarity_flip_physical{209}=0xe8 +phy_chain_tx_lane_map_physical{209.0}=0x30156742 +serdes_core_tx_polarity_flip_physical{209}=0xa7 + +# BlackhawkCore27 +phy_chain_rx_lane_map_physical{217.0}=0x15072364 +serdes_core_rx_polarity_flip_physical{217}=0x79 +phy_chain_tx_lane_map_physical{217.0}=0x52730614 +serdes_core_tx_polarity_flip_physical{217}=0x68 + +# BlackhawkCore28 +phy_chain_rx_lane_map_physical{225.0}=0x03126574 +serdes_core_rx_polarity_flip_physical{225}=0x6c +phy_chain_tx_lane_map_physical{225.0}=0x35274061 +serdes_core_tx_polarity_flip_physical{225}=0x8e + +# BlackhawkCore29 +phy_chain_rx_lane_map_physical{233.0}=0x35472160 +serdes_core_rx_polarity_flip_physical{233}=0x26 +phy_chain_tx_lane_map_physical{233.0}=0x52630714 +serdes_core_tx_polarity_flip_physical{233}=0xcc + +# BlackhawkCore30 +phy_chain_rx_lane_map_physical{241.0}=0x03126475 +serdes_core_rx_polarity_flip_physical{241}=0x66 +phy_chain_tx_lane_map_physical{241.0}=0x37254061 +serdes_core_tx_polarity_flip_physical{241}=0x8e + +# BlackhawkCore31 +phy_chain_rx_lane_map_physical{249.0}=0x45673120 +serdes_core_rx_polarity_flip_physical{249}=0xac +phy_chain_tx_lane_map_physical{249.0}=0x37250416 +serdes_core_tx_polarity_flip_physical{249}=0x87 + +serdes_tx_taps_cd0=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd1=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd2=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd3=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd4=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd5=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd6=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd7=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd8=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd9=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd10=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd11=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd12=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd13=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd14=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd15=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd16=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd17=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd18=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd19=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd20=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd21=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd22=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd23=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd24=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd25=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd26=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd27=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd28=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd29=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd30=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd31=pam4:-24:144:0:0:0:0 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/custom_led.bin b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/custom_led.bin new file mode 100755 index 00000000000..fdbf3aa30a8 Binary files /dev/null and b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/custom_led.bin differ diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/default_sku b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/default_sku new file mode 100755 index 00000000000..073744ed338 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/default_sku @@ -0,0 +1 @@ +Alphanetworks-SNJ60B0-320F t1 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/installer.conf b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/installer.conf new file mode 100755 index 00000000000..40074bddd13 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="modprobe.blacklist=i2c-ismt,i2c_ismt,i2c-i801,i2c_i801" diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/led_proc_init.soc b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/led_proc_init.soc new file mode 100755 index 00000000000..547f4174a25 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/led_proc_init.soc @@ -0,0 +1,11 @@ +# LED microprocessor initialization for alphanetworks snj60b0-320f + +#LED FW is loaded in SAI platform_init.c +#m0 load 0 0x3800 /alpha/bcm/led/jungfrau-320f_traffic_led.bin +led start +led auto on + +# Load SFP Pre-Emphasis static configure +# This is work around for 6-taps mode +rcload /usr/share/sonic/platform/preemphasis-32x400G.soc + diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/linkscan_led_fw.bin b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/linkscan_led_fw.bin new file mode 100755 index 00000000000..b1e43d4d48d Binary files /dev/null and b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/linkscan_led_fw.bin differ diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/media_settings.json b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/media_settings.json new file mode 100755 index 00000000000..1e3db76e496 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/media_settings.json @@ -0,0 +1,836 @@ +{ + "PORT_MEDIA_SETTINGS": { + "0": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "1": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "2": { + "Default": { + "preemphasis": { + "lane0": "0x0c701c", + "lane1": "0x0c701c", + "lane2": "0x0c701c", + "lane3": "0x0c701c", + "lane4": "0x0c701c", + "lane5": "0x0c701c", + "lane6": "0x0c701c", + "lane7": "0x0c701c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c701c", + "lane1": "0x0c701c", + "lane2": "0x0c701c", + "lane3": "0x0c701c", + "lane4": "0x0c701c", + "lane5": "0x0c701c", + "lane6": "0x0c701c", + "lane7": "0x0c701c" + } + } + }, + "3": { + "Default": { + "preemphasis": { + "lane0": "0x10741c", + "lane1": "0x10741c", + "lane2": "0x10741c", + "lane3": "0x10741c", + "lane4": "0x10741c", + "lane5": "0x10741c", + "lane6": "0x10741c", + "lane7": "0x10741c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x10741c", + "lane1": "0x10741c", + "lane2": "0x10741c", + "lane3": "0x10741c", + "lane4": "0x10741c", + "lane5": "0x10741c", + "lane6": "0x10741c", + "lane7": "0x10741c" + } + } + }, + "4": { + "Default": { + "preemphasis": { + "lane0": "0x0c781c", + "lane1": "0x0c781c", + "lane2": "0x0c781c", + "lane3": "0x0c781c", + "lane4": "0x0c781c", + "lane5": "0x0c781c", + "lane6": "0x0c781c", + "lane7": "0x0c781c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c781c", + "lane1": "0x0c781c", + "lane2": "0x0c781c", + "lane3": "0x0c781c", + "lane4": "0x0c781c", + "lane5": "0x0c781c", + "lane6": "0x0c781c", + "lane7": "0x0c781c" + } + } + }, + "5": { + "Default": { + "preemphasis": { + "lane0": "0x0c7c18", + "lane1": "0x0c7c18", + "lane2": "0x0c7c18", + "lane3": "0x0c7c18", + "lane4": "0x0c7c18", + "lane5": "0x0c7c18", + "lane6": "0x0c7c18", + "lane7": "0x0c7c18" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c7c18", + "lane1": "0x0c7c18", + "lane2": "0x0c7c18", + "lane3": "0x0c7c18", + "lane4": "0x0c7c18", + "lane5": "0x0c7c18", + "lane6": "0x0c7c18", + "lane7": "0x0c7c18" + } + } + }, + "6": { + "Default": { + "preemphasis": { + "lane0": "0x008020", + "lane1": "0x008020", + "lane2": "0x008020", + "lane3": "0x008020", + "lane4": "0x008020", + "lane5": "0x008020", + "lane6": "0x008020", + "lane7": "0x008020" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x008020", + "lane1": "0x008020", + "lane2": "0x008020", + "lane3": "0x008020", + "lane4": "0x008020", + "lane5": "0x008020", + "lane6": "0x008020", + "lane7": "0x008020" + } + } + }, + "7": { + "Default": { + "preemphasis": { + "lane0": "0x00881c", + "lane1": "0x00881c", + "lane2": "0x00881c", + "lane3": "0x00881c", + "lane4": "0x00881c", + "lane5": "0x00881c", + "lane6": "0x00881c", + "lane7": "0x00881c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x00881c", + "lane1": "0x00881c", + "lane2": "0x00881c", + "lane3": "0x00881c", + "lane4": "0x00881c", + "lane5": "0x00881c", + "lane6": "0x00881c", + "lane7": "0x00881c" + } + } + }, + "8": { + "Default": { + "preemphasis": { + "lane0": "0x00881c", + "lane1": "0x00881c", + "lane2": "0x00881c", + "lane3": "0x00881c", + "lane4": "0x00881c", + "lane5": "0x00881c", + "lane6": "0x00881c", + "lane7": "0x00881c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x00881c", + "lane1": "0x00881c", + "lane2": "0x00881c", + "lane3": "0x00881c", + "lane4": "0x00881c", + "lane5": "0x00881c", + "lane6": "0x00881c", + "lane7": "0x00881c" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0": "0x00841c", + "lane1": "0x00841c", + "lane2": "0x00841c", + "lane3": "0x00841c", + "lane4": "0x00841c", + "lane5": "0x00841c", + "lane6": "0x00841c", + "lane7": "0x00841c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x00841c", + "lane1": "0x00841c", + "lane2": "0x00841c", + "lane3": "0x00841c", + "lane4": "0x00841c", + "lane5": "0x00841c", + "lane6": "0x00841c", + "lane7": "0x00841c" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0": "0x008c1c", + "lane1": "0x008c1c", + "lane2": "0x008c1c", + "lane3": "0x008c1c", + "lane4": "0x008c1c", + "lane5": "0x008c1c", + "lane6": "0x008c1c", + "lane7": "0x008c1c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x008c1c", + "lane1": "0x008c1c", + "lane2": "0x008c1c", + "lane3": "0x008c1c", + "lane4": "0x008c1c", + "lane5": "0x008c1c", + "lane6": "0x008c1c", + "lane7": "0x008c1c" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0": "0x008c1c", + "lane1": "0x008c1c", + "lane2": "0x008c1c", + "lane3": "0x008c1c", + "lane4": "0x008c1c", + "lane5": "0x008c1c", + "lane6": "0x008c1c", + "lane7": "0x008c1c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x008c1c", + "lane1": "0x008c1c", + "lane2": "0x008c1c", + "lane3": "0x008c1c", + "lane4": "0x008c1c", + "lane5": "0x008c1c", + "lane6": "0x008c1c", + "lane7": "0x008c1c" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0": "0x0c7c18", + "lane1": "0x0c7c18", + "lane2": "0x0c7c18", + "lane3": "0x0c7c18", + "lane4": "0x0c7c18", + "lane5": "0x0c7c18", + "lane6": "0x0c7c18", + "lane7": "0x0c7c18" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c7c18", + "lane1": "0x0c7c18", + "lane2": "0x0c7c18", + "lane3": "0x0c7c18", + "lane4": "0x0c7c18", + "lane5": "0x0c7c18", + "lane6": "0x0c7c18", + "lane7": "0x0c7c18" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0": "0x04841c", + "lane1": "0x04841c", + "lane2": "0x04841c", + "lane3": "0x04841c", + "lane4": "0x04841c", + "lane5": "0x04841c", + "lane6": "0x04841c", + "lane7": "0x04841c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x04841c", + "lane1": "0x04841c", + "lane2": "0x04841c", + "lane3": "0x04841c", + "lane4": "0x04841c", + "lane5": "0x04841c", + "lane6": "0x04841c", + "lane7": "0x04841c" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0": "0x0c8018", + "lane1": "0x0c8018", + "lane2": "0x0c8018", + "lane3": "0x0c8018", + "lane4": "0x0c8018", + "lane5": "0x0c8018", + "lane6": "0x0c8018", + "lane7": "0x0c8018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8018", + "lane1": "0x0c8018", + "lane2": "0x0c8018", + "lane3": "0x0c8018", + "lane4": "0x0c8018", + "lane5": "0x0c8018", + "lane6": "0x0c8018", + "lane7": "0x0c8018" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0": "0x107c18", + "lane1": "0x107c18", + "lane2": "0x107c18", + "lane3": "0x107c18", + "lane4": "0x107c18", + "lane5": "0x107c18", + "lane6": "0x107c18", + "lane7": "0x107c18" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x107c18", + "lane1": "0x107c18", + "lane2": "0x107c18", + "lane3": "0x107c18", + "lane4": "0x107c18", + "lane5": "0x107c18", + "lane6": "0x107c18", + "lane7": "0x107c18" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0": "0x107818", + "lane1": "0x107818", + "lane2": "0x107818", + "lane3": "0x107818", + "lane4": "0x107818", + "lane5": "0x107818", + "lane6": "0x107818", + "lane7": "0x107818" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x107818", + "lane1": "0x107818", + "lane2": "0x107818", + "lane3": "0x107818", + "lane4": "0x107818", + "lane5": "0x107818", + "lane6": "0x107818", + "lane7": "0x107818" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0": "0x04801c", + "lane1": "0x04801c", + "lane2": "0x04801c", + "lane3": "0x04801c", + "lane4": "0x04801c", + "lane5": "0x04801c", + "lane6": "0x04801c", + "lane7": "0x04801c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x04801c", + "lane1": "0x04801c", + "lane2": "0x04801c", + "lane3": "0x04801c", + "lane4": "0x04801c", + "lane5": "0x04801c", + "lane6": "0x04801c", + "lane7": "0x04801c" + } + } + } + } +} \ No newline at end of file diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/platform_env.conf b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/platform_env.conf new file mode 100755 index 00000000000..c8c09ab2d9d --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/platform_env.conf @@ -0,0 +1,2 @@ +dmasize=32M +usemsi=0 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/eeprom.py b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/eeprom.py new file mode 100755 index 00000000000..10df5bb12c7 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/eeprom.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +try: + import os + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/1-0056/eeprom" + #Two i2c buses might get flipped order, check them both. + if not os.path.exists(self.eeprom_path): + self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/led_control.py b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/led_control.py new file mode 100755 index 00000000000..6bb9faf4607 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/led_control.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +# try: +# from sonic_led.led_control_base import LedControlBase +# import swsssdk +# except ImportError, e: +# raise ImportError (str(e) + " - required module not found") + +import time +import glob +import os.path + +class LedControlBase(object): +# __metaclass__ = abc.ABCMeta + +# @abc.abstractmethod + def port_link_state_change(self, port, state): + """ + Called when port link state changes. Update port link state LED here. + + :param port: A string, SONiC port name (e.g., "Ethernet0") + :param state: A string, the port link state (either "up" or "down") + """ + return + +### Goreme specified ### +read_fan_fault = 0 +is_fan_all_OK = 0 +read_power_status = 0 +is_power_all_OK = 0 +is_thermal_high = 0 +is_reset_button_push = 0 +########################## + +def sysled_task(): + while True: + system_led_check() + time.sleep(5) + +########## Goreme System LED checking +def system_led_check(): + global read_fan_fault, read_power_status, is_fan_all_OK, is_power_all_OK, is_thermal_high, is_reset_button_push + is_fan_all_OK = 1 + is_power_all_OK = 0 + is_thermal_high = 0 + is_reset_button_push = 0 + + with open("/sys/bus/i2c/devices/0-005e/fan1_led", "r") as f11: + read_fan_led = int(f11.read()) + if read_fan_led == 1: + is_fan_all_OK = 1 + else: + is_fan_all_OK = 0 + + with open("/sys/bus/i2c/devices/0-005e/sys_pwr", "r") as f11: + read_pau_led = int(f11.read()) + if read_pau_led == 1: + is_power_all_OK = 1 + else: + is_power_all_OK = 0 + + if os.path.exists("/sys/bus/i2c/devices/3-004d/hwmon/"): + with open("/sys/bus/i2c/devices/3-004d/hwmon/hwmon2/temp1_input", "r") as f3: + is_thermal_high = f3.read() + if int(is_thermal_high) >= 70000: + is_thermal_high = 1 + else: + is_thermal_high = 0 + else: + node = glob.glob("/sys/bus/i2c/devices/18-004d/hwmon/hwmon*") + node = node[0] + "/temp1_input" + with open(node, "r") as f3: + is_thermal_high = f3.read() + if int(is_thermal_high) >= 70000: + is_thermal_high = 1 + else: + is_thermal_high = 0 + + with open("/sys/bus/i2c/devices/0-005e/sys_status", "w") as f2: + if is_reset_button_push == 1: + f2.write("3") + elif is_fan_all_OK == 0 or is_power_all_OK == 0 or is_thermal_high == 1: + f2.write("4") + else: + f2.write("1") + + return +########## + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Constructor + def __init__(self): + # Initialize all front-panel status LEDs to green + with open("/sys/bus/i2c/devices/0-005e/sys_locator", "w") as f: + f.write("1") + with open("/sys/bus/i2c/devices/0-005e/sys_status", "w") as f: + f.write("1") + + sysled_task() + + # Initialize: Turn all front panel QSFP LEDs off + # # for qsfp_index in range(self.QSFP_BREAKOUT_START_IDX, self.QSFP_BREAKOUT_END_IDX + 1): + # # for lane in range(1, 5): + # # led_sysfs_path = self.LED_SYSFS_PATH_BREAKOUT_CAPABLE.format(qsfp_index, lane) + # # with open(led_sysfs_path, 'w') as led_file: + # # led_file.write("%d" % self.LED_COLOR_OFF) + + # # for qsfp_index in range(self.QSFP_NO_BREAKOUT_START_IDX, self.QSFP_NO_BREAKOUT_END_IDX + 1): + # # led_sysfs_path = self.LED_SYSFS_PATH_NO_BREAKOUT.format(qsfp_index) + # # with open(led_sysfs_path, 'w') as led_file: + # # led_file.write("%d" % self.LED_COLOR_OFF) diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/pmon_daemon_control.json b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/pmon_daemon_control.json new file mode 100755 index 00000000000..6453cd2c5d0 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_fancontrol": true +} + diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/preemphasis-32x400G.soc b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/preemphasis-32x400G.soc new file mode 100755 index 00000000000..652d901fc3d --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/preemphasis-32x400G.soc @@ -0,0 +1,1313 @@ +# Preemphasis + +phy raw c45 0x81 0x1 0xffde 0 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 1 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 2 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 3 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 4 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 5 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 6 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 7 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 + +phy raw c45 0x89 0x1 0xffde 0 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 1 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 2 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 3 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 4 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 5 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 6 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 7 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 + +phy raw c45 0x91 0x1 0xffde 0 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 1 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 2 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 3 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 4 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 5 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 6 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 7 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 + +phy raw c45 0xa1 0x1 0xffde 0 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 1 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 2 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 3 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 4 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 5 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 6 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 7 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 + +phy raw c45 0xa9 0x1 0xffde 0 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 1 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 2 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 3 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 4 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 5 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 6 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 7 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 + +phy raw c45 0xb1 0x1 0xffde 0 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 1 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 2 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 3 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 4 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 5 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 6 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 7 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 + +phy raw c45 0xc1 0x1 0xffde 0 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 1 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 2 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 3 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 4 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 5 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 6 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 7 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 + +phy raw c45 0xc9 0x1 0xffde 0 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 1 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 2 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 3 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 4 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 5 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 6 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 7 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 + +phy raw c45 0xd1 0x1 0xffde 0 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 1 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 2 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 3 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 4 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 5 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 6 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 7 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 + +phy raw c45 0xe1 0x1 0xffde 0 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 1 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 2 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 3 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 4 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 5 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 6 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 7 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 + +phy raw c45 0xe9 0x1 0xffde 0 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 1 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 2 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 3 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 4 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 5 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 6 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 7 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 + +phy raw c45 0xf1 0x1 0xffde 0 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 1 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 2 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 3 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 4 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 5 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 6 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 7 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 + +phy raw c45 0x181 0x1 0xffde 0 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 1 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 2 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 3 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 4 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 5 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 6 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 7 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 + +phy raw c45 0x189 0x1 0xffde 0 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 1 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 2 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 3 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 4 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 5 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 6 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 7 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 + +phy raw c45 0x191 0x1 0xffde 0 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 1 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 2 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 3 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 4 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 5 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 6 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 7 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 + +phy raw c45 0x1a1 0x1 0xffde 0 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 1 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 2 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 3 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 4 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 5 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 6 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 7 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 + +phy raw c45 0x1a9 0x1 0xffde 0 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 1 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 2 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 3 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 4 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 5 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 6 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 7 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 + +phy raw c45 0x1b1 0x1 0xffde 0 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 1 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 2 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 3 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 4 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 5 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 6 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 7 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 + +phy raw c45 0x1c1 0x1 0xffde 0 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 1 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 2 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 3 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 4 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 5 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 6 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 7 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 + +phy raw c45 0x1c9 0x1 0xffde 0 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 1 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 2 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 3 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 4 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 5 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 6 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 7 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 + +phy raw c45 0x1d1 0x1 0xffde 0 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 1 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 2 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 3 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 4 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 5 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 6 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 7 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 + +phy raw c45 0x1e1 0x1 0xffde 0 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 1 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 2 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 3 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 4 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 5 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 6 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 7 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 + +phy raw c45 0x1e9 0x1 0xffde 0 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 1 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 2 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 3 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 4 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 5 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 6 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 7 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 + +phy raw c45 0x1f1 0x1 0xffde 0 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 1 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 2 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 3 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 4 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 5 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 6 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 7 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 + +phy raw c45 0x281 0x1 0xffde 0 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 1 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 2 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 3 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 4 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 5 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 6 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 7 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 + +phy raw c45 0x289 0x1 0xffde 0 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 1 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 2 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 3 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 4 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 5 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 6 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 7 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 + +phy raw c45 0x291 0x1 0xffde 0 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 1 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 2 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 3 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 4 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 5 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 6 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 7 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 + +phy raw c45 0x2a1 0x1 0xffde 0 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 1 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 2 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 3 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 4 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 5 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 6 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 7 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc + +phy raw c45 0x2a9 0x1 0xffde 0 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 1 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 2 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 3 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 4 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 5 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 6 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 7 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 + +phy raw c45 0x2b1 0x1 0xffde 0 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 1 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 2 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 3 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 4 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 5 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 6 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 7 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 + +phy raw c45 0x2c1 0x1 0xffde 0 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 1 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 2 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 3 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 4 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 5 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 6 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 7 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 + +phy raw c45 0x2c9 0x1 0xffde 0 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 1 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 2 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 3 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 4 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 5 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 6 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 7 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/sensors.conf b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/sensors.conf new file mode 100755 index 00000000000..ffd5cf1d0aa --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/sensors.conf @@ -0,0 +1,13 @@ +# libsensors configuration file for snj60b0_320f +# ------------------------------------------------ + +#bus "i2c-1" "SMBus I801 adapter at f000" +#chip "goreme_power_cpld-*" +# label fan1 "Fan tray 1 front" +# label fan2 "Fan tray 2 front" +# label fan3 "Fan tray 3 front" +# label fan4 "Fan tray 4 front" +# label fan11 "Fan tray 1 rear" +# label fan12 "Fan tray 2 rear" +# label fan13 "Fan tray 3 rear" +# label fan14 "Fan tray 4 rear" diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/thermal_policy.json b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/thermal_policy.json new file mode 100755 index 00000000000..95143638454 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/thermal_policy.json @@ -0,0 +1,93 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "True", + "fan_speed_when_suspend": "50" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "thermal_info" + }, + { + "type": "chassis_info" + } + ], + "policies": [ + { + "name": "temp over high critical threshold", + "conditions": [ + { + "type": "thermal.over.high_critical_threshold" + } + ], + "actions": [ + { + "type": "switch.shutdown" + } + ] + }, + { + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "fan.all.set_speed_max" + } + ] + }, + { + "name": "any fan broken", + "conditions": [ + { + "type": "fan.any.fault" + } + ], + "actions": [ + { + "type": "fan.all.set_speed_max" + } + ] + }, + { + "name": "all fan presence", + "conditions": [ + { + "type": "fan.any.presence.change" + }, + { + "type": "fan.all.presence" + }, + { + "type": "fan.all.good" + } + ], + "actions": [ + { + "type": "fan.all.set_speed_default" + } + ] + }, + { + "name": "thermal recover", + "conditions": [ + { + "type": "fan.all.presence" + }, + { + "type": "fan.all.good" + } + ], + "actions": [ + { + "type": "thermal.temp_check_and_set_all_fan_speed" + } + ] + } + ] +} \ No newline at end of file diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 86ac56b750b..eeef34499a5 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -54,6 +54,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(MITAC_LY1200_32X_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \ + $(ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE) \ $(BRCM_XLR_GTS_PLATFORM_MODULE) \ $(DELTA_AG9032V2A_PLATFORM_MODULE) \ $(JUNIPER_QFX5210_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-alphanetworks.mk b/platform/broadcom/platform-modules-alphanetworks.mk index 13e5fc4ff9e..689d5e42c8f 100644 --- a/platform/broadcom/platform-modules-alphanetworks.mk +++ b/platform/broadcom/platform-modules-alphanetworks.mk @@ -2,9 +2,11 @@ ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE_VERSION = 1.0 ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE_VERSION = 1.0 +ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE_VERSION = 1.0 export ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE_VERSION export ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE_VERSION +export ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE_VERSION ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE = sonic-platform-alphanetworks-snh60a0-320fv2_$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE_VERSION)_amd64.deb $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-alphanetworks @@ -16,5 +18,10 @@ ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE = sonic-platform-alphanetworks-snh60b $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE)_PLATFORM = x86_64-alphanetworks_snh60b0_640f-r0 $(eval $(call add_extra_package,$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE),$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE))) +ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE = sonic-platform-alphanetworks-snj60b0-320f_$(ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE_VERSION)_amd64.deb +$(ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE)_PLATFORM = x86_64-alphanetworks_snj60b0_320f-r0 +$(eval $(call add_extra_package,$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE),$(ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE))) + +SONIC_STRETCH_DEBS += $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/changelog b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/changelog index 2742b7c6a41..a0ac4888cb0 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/changelog +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/changelog @@ -1,6 +1,6 @@ sonic-alphanetworks-platform-modules (1.0) unstable; urgency=low - * Add support for SNH60A0-320FV2 and SNH60B0_640F. + * Add support for SNH60A0-320FV2 , SNH60B0_640F , SNJ60B0_320F. - -- Alphanetworks Tue, 19 Dec 2017 09:35:58 +0800 + -- Alphanetworks Tue, 16 June 2020 09:35:58 +0800 diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index 6c7b1c41446..12f0a725bc8 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -15,3 +15,7 @@ Architecture: amd64 Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp +Package: sonic-platform-alphanetworks-snj60b0-320f +Architecture: amd64 +Depends: linux-image-4.19.0-9-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/rules b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/rules index 0d1a588db6b..a14baa8b2eb 100755 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/rules +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/rules @@ -9,7 +9,7 @@ include /usr/share/dpkg/pkg-info.mk # Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 +export DH_VERBOSE=1 export INSTALL_MOD_DIR:=extra @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-alphanetworks KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= snh60a0-320fv2 snh60b0-640f +MODULE_DIRS:= snh60a0-320fv2 snh60b0-640f snj60b0-320f MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service @@ -38,7 +38,10 @@ 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; \ - $(PYTHON) $${mod}/setup.py build; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + $(PYTHON) setup.py build; \ + $(PYTHON) setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \ + cd $(MOD_SRC_DIR); \ done) binary: binary-arch binary-indep @@ -59,13 +62,18 @@ binary-indep: # 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; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/local/bin; \ + platform_name=`echo $${mod} | sed "s/-/_/g"`; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/share/sonic/device/x86_64-alphanetworks_$${platform_name}-r0; \ + 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}/$(UTILS_DIR)/*.py debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.whl debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/share/sonic/device/x86_64-alphanetworks_$${platform_name}-r0; \ 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; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + $(PYTHON) setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + cd $(MOD_SRC_DIR); \ done) # Resuming debhelper scripts dh_testroot diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/classes/__init__.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/classes/__init__.py new file mode 100755 index 00000000000..e69de29bb2d diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/Makefile b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/Makefile new file mode 100755 index 00000000000..86f32fee023 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/Makefile @@ -0,0 +1,8 @@ +# obj-m:=accton_as7712_32x_fan.o accton_as7712_32x_sfp.o leds-accton_as7712_32x.o \ +# goreme_system_cpld.o ym2651y.o optoe.o + +obj-m:=snj60b0-320f_sfp.o snj60b0-320f_fpga.o snj60b0-320f_onie_eeprom.o yesm1300am.o + + +# obj-m:=accton_as7712_32x_fan.o accton_as7712_32x_sfp.o leds-accton_as7712_32x.o \ +# accton_as7712_32x_psu.o accton_i2c_cpld.o ym2651y.o optoe.o diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_fpga.c b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_fpga.c new file mode 100755 index 00000000000..8167791d8fb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_fpga.c @@ -0,0 +1,955 @@ +/* + * A hwmon driver for the alphanetworks_snj60b0_320f_fpga + * + * Copyright (C) 2019 Alphanetworks Technology Corporation. + * Robin Chen + * 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 + * 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. + * see + * + * Copyright 2006 Stefan Roese , 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 +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DRIVER_NAME "snj60b0_fpga" +#define PSU1_STATUS_REG 0x2 +#define PSU2_STATUS_REG 0x3 +#define FAN_PWM_REG 0x18 + +#define PSU_PRESENT_BIT 0x10 +#define PSU_POWER_BIT 0x20 +#define FAN_DIRECTION_BIT 0x1 +#define FAN_PRESENT_BIT 0x2 +#define FPGA_REVISION_BIT 0xF + +#define FPGA_REVISION_REG 0x0 +#define SYS_LED_REG 0x2D +#define SYS2_LED_REG 0x2E +#define FAN12_LED_REG 0x30 +#define FAN34_LED_REG 0x31 +#define FAN56_LED_REG 0x32 + +#define FAN1_STATUS_REG 0x5 +#define FAN2_STATUS_REG 0x6 +#define FAN3_STATUS_REG 0x7 +#define FAN4_STATUS_REG 0x8 +#define FAN5_STATUS_REG 0x9 +#define FAN6_STATUS_REG 0xA + +#define SYS_RESET1_REG 0x1C +#define SYS_RESET2_REG 0x1D +#define SYS_RESET3_REG 0x1E +//#define SWI_CTRL_REG 0x4 + +#define SYS_LOCATOR_LED_BITS 0x07 +#define SYS_PWR_LED_BITS 0x38 +#define PORT_LED_DISABLE_BITS 0x40 +#define SYS_STATUS_LED_BITS 0x07 +#define SYS_FAN_LED_BITS 0x38 +#define FAN135_LED_BITS 0x07 +#define FAN246_LED_BITS 0x38 +#define REST_BUTTON_BITS 0x0 + +#define SFP_TX_FAULT_REG 0x25 +#define SFP_TX_FAULT_MASK_REG 0x26 +#define SFP_TX_DISABLE_REG 0x27 +#define SFP_PRESENT_REG 0x28 +#define SFP_PRESENT_MASK_REG 0x29 +#define SFP_RX_LOSS_REG 0x2A +#define SFP_RX_LOSS_MASK_REG 0x2B +//#define SWI_CTRL_REG 0x34 + + + + +static ssize_t psu_show_status(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t fan_pwm_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t set_fan_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t fpga_version_show(struct device *dev, struct device_attribute *attr, char *buf); + +static ssize_t fan_show_status(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t fan_show_status_reg(struct device *dev, struct device_attribute *attr, char *buf); + +static ssize_t sys_sfp_read(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sys_sfp_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t sys_led_read(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sys_led_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); + +static LIST_HEAD(fpga_client_list); +static struct mutex list_lock; + +struct fpga_client_node { + struct i2c_client *client; + struct list_head list; +}; + +/* Addresses scanned for alphanetworks_snj60b0_320f_fpga */ +static const unsigned short normal_i2c[] = { 0x5E, I2C_CLIENT_END }; + +struct alphanetworks_snj60b0_320f_pwr_fpga_data { + struct device *hwmon_dev; + struct mutex update_lock; + char model_name[9]; /* Model name, read from eeprom */ +}; + + +enum sysfs_fpga_attributes { + PSU1_PRESENT, + PSU2_PRESENT, + PSU1_POWER_GOOD, + PSU2_POWER_GOOD, + FAN_PWM, + FAN1_PRESENT=0x05, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN6_PRESENT, + FAN1_FRONT_SPEED_RPM=0x0b, + FAN1_REAR_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN6_FRONT_SPEED_RPM, + FAN6_REAR_SPEED_RPM, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN6_FAULT, + SYS_STATUS, + SYS_PWR, + SYS_FAN, + SYS_LOCATOR, + SFP_TX_FAULT, + SFP_TX_FAULT_MASK, + SFP_TX_DISABLE, + SFP_PRESENT, + SFP_PRESENT_MASK, + SFP_RX_LOSS, + SFP_RX_LOSS_MASK, + FAN1_LED, + FAN2_LED, + FAN3_LED, + FAN4_LED, + FAN5_LED, + FAN6_LED, + SYS_RESET1, + SYS_RESET2, + SYS_RESET3, + PORT_LED_DISABLE, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, + FAN6_DIRECTION, + FPGA_REVISION, +}; + + + + + + +static SENSOR_DEVICE_ATTR(psu1_present, S_IRUGO, psu_show_status, NULL, PSU1_PRESENT); +static SENSOR_DEVICE_ATTR(psu2_present, S_IRUGO, psu_show_status, NULL, PSU2_PRESENT); +static SENSOR_DEVICE_ATTR(psu1_power_good, S_IRUGO, psu_show_status, NULL, PSU1_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu2_power_good, S_IRUGO, psu_show_status, NULL, PSU2_POWER_GOOD); +static SENSOR_DEVICE_ATTR(fan_pwm, (0660), fan_pwm_show, set_fan_pwm, FAN_PWM); +static SENSOR_DEVICE_ATTR(fpga_revision, (0660), fpga_version_show, NULL, FPGA_REVISION); +static SENSOR_DEVICE_ATTR(fan1_present, S_IRUGO, fan_show_status_reg, NULL, FAN1_PRESENT); +static SENSOR_DEVICE_ATTR(fan2_present, S_IRUGO, fan_show_status_reg, NULL, FAN2_PRESENT); +static SENSOR_DEVICE_ATTR(fan3_present, S_IRUGO, fan_show_status_reg, NULL, FAN3_PRESENT); +static SENSOR_DEVICE_ATTR(fan4_present, S_IRUGO, fan_show_status_reg, NULL, FAN4_PRESENT); +static SENSOR_DEVICE_ATTR(fan5_present, S_IRUGO, fan_show_status_reg, NULL, FAN5_PRESENT); +static SENSOR_DEVICE_ATTR(fan6_present, S_IRUGO, fan_show_status_reg, NULL, FAN6_PRESENT); +static SENSOR_DEVICE_ATTR(fan1_direction, S_IRUGO, fan_show_status_reg, NULL, FAN1_DIRECTION); +static SENSOR_DEVICE_ATTR(fan2_direction, S_IRUGO, fan_show_status_reg, NULL, FAN2_DIRECTION); +static SENSOR_DEVICE_ATTR(fan3_direction, S_IRUGO, fan_show_status_reg, NULL, FAN3_DIRECTION); +static SENSOR_DEVICE_ATTR(fan4_direction, S_IRUGO, fan_show_status_reg, NULL, FAN4_DIRECTION); +static SENSOR_DEVICE_ATTR(fan5_direction, S_IRUGO, fan_show_status_reg, NULL, FAN5_DIRECTION); +static SENSOR_DEVICE_ATTR(fan6_direction, S_IRUGO, fan_show_status_reg, NULL, FAN6_DIRECTION); +static SENSOR_DEVICE_ATTR(fan1_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN1_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan2_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN2_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan3_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN3_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan4_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN4_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan5_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN5_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan6_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN6_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan1_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN1_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan2_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN2_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan3_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN3_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan4_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN4_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan5_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN5_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan6_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN6_REAR_SPEED_RPM); + +static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, fan_show_status, NULL, FAN1_FAULT); static SENSOR_DEVICE_ATTR(fan11_fault, S_IRUGO, fan_show_status, NULL, FAN1_FAULT); +static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, fan_show_status, NULL, FAN2_FAULT); static SENSOR_DEVICE_ATTR(fan12_fault, S_IRUGO, fan_show_status, NULL, FAN2_FAULT); +static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, fan_show_status, NULL, FAN3_FAULT); static SENSOR_DEVICE_ATTR(fan13_fault, S_IRUGO, fan_show_status, NULL, FAN3_FAULT); +static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, fan_show_status, NULL, FAN4_FAULT); static SENSOR_DEVICE_ATTR(fan14_fault, S_IRUGO, fan_show_status, NULL, FAN4_FAULT); +static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, fan_show_status, NULL, FAN5_FAULT); static SENSOR_DEVICE_ATTR(fan15_fault, S_IRUGO, fan_show_status, NULL, FAN5_FAULT); +static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, fan_show_status, NULL, FAN6_FAULT); static SENSOR_DEVICE_ATTR(fan16_fault, S_IRUGO, fan_show_status, NULL, FAN6_FAULT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, fan_show_status, NULL, FAN1_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, fan_show_status, NULL, FAN1_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, fan_show_status, NULL, FAN2_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, fan_show_status, NULL, FAN2_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, fan_show_status, NULL, FAN3_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan13_input, S_IRUGO, fan_show_status, NULL, FAN3_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, fan_show_status, NULL, FAN4_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan14_input, S_IRUGO, fan_show_status, NULL, FAN4_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, fan_show_status, NULL, FAN5_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan15_input, S_IRUGO, fan_show_status, NULL, FAN5_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, fan_show_status, NULL, FAN6_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan16_input, S_IRUGO, fan_show_status, NULL, FAN6_REAR_SPEED_RPM); + +static SENSOR_DEVICE_ATTR(sys_status, (0600), sys_led_read, sys_led_write, SYS_STATUS); +static SENSOR_DEVICE_ATTR(port_led_disable, (0660), sys_led_read, sys_led_write, PORT_LED_DISABLE); +static SENSOR_DEVICE_ATTR(sys_pwr, (0660), sys_led_read, sys_led_write, SYS_PWR); +static SENSOR_DEVICE_ATTR(sys_locator, (0660), sys_led_read, sys_led_write, SYS_LOCATOR); +static SENSOR_DEVICE_ATTR(fan1_led, (0660), sys_led_read, sys_led_write, FAN1_LED); +static SENSOR_DEVICE_ATTR(fan2_led, (0660), sys_led_read, sys_led_write, FAN2_LED); +static SENSOR_DEVICE_ATTR(fan3_led, (0660), sys_led_read, sys_led_write, FAN3_LED); +static SENSOR_DEVICE_ATTR(fan4_led, (0660), sys_led_read, sys_led_write, FAN4_LED); +static SENSOR_DEVICE_ATTR(fan5_led, (0660), sys_led_read, sys_led_write, FAN5_LED); +static SENSOR_DEVICE_ATTR(fan6_led, (0660), sys_led_read, sys_led_write, FAN6_LED); +static SENSOR_DEVICE_ATTR(sys_reset1, (0660), sys_led_read, sys_led_write, SYS_RESET1); +static SENSOR_DEVICE_ATTR(sys_reset2, (0660), sys_led_read, sys_led_write, SYS_RESET2); +static SENSOR_DEVICE_ATTR(sys_reset3, (0660), sys_led_read, sys_led_write, SYS_RESET3); + +static SENSOR_DEVICE_ATTR(sfp_tx_fault, (0660), sys_sfp_read, sys_sfp_write, SFP_TX_FAULT); +static SENSOR_DEVICE_ATTR(sfp_tx_fault_mask, (0660), sys_sfp_read, sys_sfp_write, SFP_TX_FAULT_MASK); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, (0660), sys_sfp_read, sys_sfp_write, SFP_TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_present, (0660), sys_sfp_read, sys_sfp_write, SFP_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_present_mask, (0660), sys_sfp_read, sys_sfp_write, SFP_PRESENT_MASK); +static SENSOR_DEVICE_ATTR(sfp_rx_loss, (0660), sys_sfp_read, sys_sfp_write, SFP_RX_LOSS); +static SENSOR_DEVICE_ATTR(sfp_rx_loss_mask, (0660), sys_sfp_read, sys_sfp_write, SFP_RX_LOSS_MASK); + + +static struct attribute *alphanetworks_snj60b0_320f_fpga_attributes[] = { + &sensor_dev_attr_psu1_present.dev_attr.attr, + &sensor_dev_attr_psu2_present.dev_attr.attr, + &sensor_dev_attr_psu1_power_good.dev_attr.attr, + &sensor_dev_attr_psu2_power_good.dev_attr.attr, + &sensor_dev_attr_fan_pwm.dev_attr.attr, + &sensor_dev_attr_fan1_present.dev_attr.attr, + &sensor_dev_attr_fan2_present.dev_attr.attr, + &sensor_dev_attr_fan3_present.dev_attr.attr, + &sensor_dev_attr_fan4_present.dev_attr.attr, + &sensor_dev_attr_fan5_present.dev_attr.attr, + &sensor_dev_attr_fan6_present.dev_attr.attr, + &sensor_dev_attr_fan1_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan2_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan3_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan4_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan5_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan6_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan1_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan2_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan3_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan4_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan5_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan6_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan1_fault.dev_attr.attr, &sensor_dev_attr_fan11_fault.dev_attr.attr, + &sensor_dev_attr_fan2_fault.dev_attr.attr, &sensor_dev_attr_fan12_fault.dev_attr.attr, + &sensor_dev_attr_fan3_fault.dev_attr.attr, &sensor_dev_attr_fan13_fault.dev_attr.attr, + &sensor_dev_attr_fan4_fault.dev_attr.attr, &sensor_dev_attr_fan14_fault.dev_attr.attr, + &sensor_dev_attr_fan5_fault.dev_attr.attr, &sensor_dev_attr_fan15_fault.dev_attr.attr, + &sensor_dev_attr_fan6_fault.dev_attr.attr, &sensor_dev_attr_fan16_fault.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan11_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan12_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, &sensor_dev_attr_fan13_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, &sensor_dev_attr_fan14_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, &sensor_dev_attr_fan15_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, &sensor_dev_attr_fan16_input.dev_attr.attr, + &sensor_dev_attr_sys_status.dev_attr.attr, + &sensor_dev_attr_sys_pwr.dev_attr.attr, + &sensor_dev_attr_fan1_led.dev_attr.attr, + &sensor_dev_attr_fan2_led.dev_attr.attr, + &sensor_dev_attr_fan3_led.dev_attr.attr, + &sensor_dev_attr_fan4_led.dev_attr.attr, + &sensor_dev_attr_fan5_led.dev_attr.attr, + &sensor_dev_attr_fan6_led.dev_attr.attr, + &sensor_dev_attr_sys_reset1.dev_attr.attr, + &sensor_dev_attr_sys_reset2.dev_attr.attr, + &sensor_dev_attr_sys_reset3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault_mask.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_present.dev_attr.attr, + &sensor_dev_attr_sfp_present_mask.dev_attr.attr, + &sensor_dev_attr_sfp_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp_rx_loss_mask.dev_attr.attr, + &sensor_dev_attr_sys_locator.dev_attr.attr, + &sensor_dev_attr_port_led_disable.dev_attr.attr, + &sensor_dev_attr_fan1_direction.dev_attr.attr, + &sensor_dev_attr_fan2_direction.dev_attr.attr, + &sensor_dev_attr_fan3_direction.dev_attr.attr, + &sensor_dev_attr_fan4_direction.dev_attr.attr, + &sensor_dev_attr_fan5_direction.dev_attr.attr, + &sensor_dev_attr_fan6_direction.dev_attr.attr, + &sensor_dev_attr_fpga_revision.dev_attr.attr, + NULL +}; + +static const struct attribute_group alphanetworks_snj60b0_320f_fpga_group = { + .attrs = alphanetworks_snj60b0_320f_fpga_attributes, +}; + + +static ssize_t psu_show_status(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0, res = 0; + u8 command; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + + switch(sda->index) { + case PSU1_PRESENT: + case PSU1_POWER_GOOD: + command = PSU1_STATUS_REG; + break; + case PSU2_PRESENT: + case PSU2_POWER_GOOD: + command = PSU2_STATUS_REG; + break; + } + + val = i2c_smbus_read_byte_data(client, command); + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + switch(sda->index) { + case PSU1_PRESENT: + case PSU2_PRESENT: + res = (val & PSU_PRESENT_BIT ? 0 : 1 ); + break; + case PSU1_POWER_GOOD: + case PSU2_POWER_GOOD: + res = (val & PSU_POWER_BIT ? 1 : 0 ); + break; + } + + return sprintf(buf, "%d\n", res); +} + +static ssize_t fan_pwm_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, FAN_PWM_REG); + + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d", val); +} + +static ssize_t set_fan_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > 0xFF) + return -EINVAL; + + i2c_smbus_write_byte_data(client, FAN_PWM_REG, value); + + return count; +} + +static ssize_t fpga_version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, FPGA_REVISION_REG); + + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d\n", (val & FPGA_REVISION_BIT)); +} + +static ssize_t fan_show_status(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + struct i2c_client *client = to_i2c_client(dev); + // struct as7712_32x_fan_data *data = as7712_32x_fan_update_device(dev); + ssize_t ret = 0; + int val, val2; + + switch (sda->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 FAN5_FRONT_SPEED_RPM: + case FAN6_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + case FAN6_REAR_SPEED_RPM: + val = i2c_smbus_read_byte_data(client, sda->index); + ret = sprintf(buf, "%d\n", val * 150); + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + val = i2c_smbus_read_byte_data(client, (sda->index - FAN1_FAULT)*2 + FAN1_FRONT_SPEED_RPM); + val2 = i2c_smbus_read_byte_data(client, (sda->index - FAN1_FAULT)*2 + FAN1_REAR_SPEED_RPM); + ret = sprintf(buf, "%d\n", (val|val2) ? 0 : 1); + break; + default: + break; + } + + return ret; +} + +static ssize_t fan_show_status_reg(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + struct i2c_client *client = to_i2c_client(dev); + ssize_t ret = 0; + int val; + u8 fan_status_offset = 0; + + switch (sda->index) { + + case FAN1_PRESENT: + case FAN1_DIRECTION: + fan_status_offset = FAN1_STATUS_REG; + break; + case FAN2_PRESENT: + case FAN2_DIRECTION: + fan_status_offset = FAN2_STATUS_REG; + break; + case FAN3_PRESENT: + case FAN3_DIRECTION: + fan_status_offset = FAN3_STATUS_REG; + break; + case FAN4_PRESENT: + case FAN4_DIRECTION: + fan_status_offset = FAN4_STATUS_REG; + break; + case FAN5_PRESENT: + case FAN5_DIRECTION: + fan_status_offset = FAN5_STATUS_REG; + break; + case FAN6_PRESENT: + case FAN6_DIRECTION: + fan_status_offset = FAN6_STATUS_REG; + break; + default: + break; + } + + switch (sda->index) { + + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + val = i2c_smbus_read_byte_data(client, fan_status_offset); + /* Debug Msg + printk(KERN_ERR "%s: Present: fan_status_offset: %d, Value: %d \n", __FUNCTION__, fan_status_offset, val); + */ + ret = sprintf(buf, "%d\n", (val & FAN_PRESENT_BIT) ? 1 : 0); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + case FAN6_DIRECTION: + val = i2c_smbus_read_byte_data(client, fan_status_offset); + /* Debug Msg + printk(KERN_ERR "%s: Direction: fan_status_offset: %d, Value: %d \n", __FUNCTION__, fan_status_offset, val); + */ + ret = sprintf(buf, "%d\n", (val & FAN_DIRECTION_BIT) ? 1 : 0); + break; + default: + break; + } + + return ret; +} + +static ssize_t sys_led_read(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0, res = 0; + u8 command; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + + switch(sda->index) { + case SYS_LOCATOR: + case SYS_PWR: + case PORT_LED_DISABLE: + command = SYS_LED_REG; + break; + case SYS_STATUS: + case FAN1_LED: + case FAN2_LED: + case FAN3_LED: + case FAN4_LED: + case FAN5_LED: + case FAN6_LED: + command = SYS2_LED_REG; + break; + case SYS_RESET1: + command = SYS_RESET1_REG; + break; + case SYS_RESET2: + command = SYS_RESET2_REG; + break; + case SYS_RESET3: + command = SYS_RESET3_REG; + break; + } + + val = i2c_smbus_read_byte_data(client, command); + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + switch(sda->index) { + case SYS_LOCATOR: + res = (val & SYS_LOCATOR_LED_BITS) >> 0; + break; + case SYS_PWR: + res = (val & SYS_PWR_LED_BITS) >> 3; + break; + case PORT_LED_DISABLE: + res = (val & PORT_LED_DISABLE_BITS) >> 6; + break; + case SYS_STATUS: + res = (val & SYS_STATUS_LED_BITS) >> 0; + break; + case FAN1_LED: + case FAN3_LED: + case FAN5_LED: + case FAN2_LED: + case FAN4_LED: + case FAN6_LED: + res = (val & SYS_FAN_LED_BITS) >> 3; + break; + case SYS_RESET1: + res = val; + break; + case SYS_RESET2: + res = val; + break; + case SYS_RESET3: + res = val; + break; + } + + return sprintf(buf, "%d\n", res); +} + +static ssize_t sys_led_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + int error, write, command, read; + + error = kstrtoint(buf, 10, &write); + if (error) + return error; + + + switch(sda->index) { + case SYS_LOCATOR: + case SYS_PWR: + case PORT_LED_DISABLE: + if(write < 0 || write > 7) + return -EINVAL; + command = SYS_LED_REG; + break; + case SYS_STATUS: + if (write < 0 || write > 7) + return -EINVAL; + command = SYS2_LED_REG; + break; + case FAN1_LED: + case FAN2_LED: + case FAN3_LED: + case FAN4_LED: + case FAN5_LED: + case FAN6_LED: + if (write < 0 || write > 7) + return -EINVAL; + command = SYS2_LED_REG; + break; + case SYS_RESET1: + if (write < 0 || write > 255) + return -EINVAL; + command = SYS_RESET1_REG; + break; + case SYS_RESET2: + if (write < 0 || write > 255) + return -EINVAL; + command = SYS_RESET2_REG; + break; + case SYS_RESET3: + if (write < 0 || write > 255) + return -EINVAL; + command = SYS_RESET3_REG; + break; + } + + read = i2c_smbus_read_byte_data(client, command); + if (read < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, read); + } + + switch(sda->index) { + case SYS_LOCATOR: + read &= ~SYS_LOCATOR_LED_BITS; + read |= write << 0; + break; + case SYS_PWR: + read &= ~SYS_PWR_LED_BITS; + read |= write << 3; + break; + case PORT_LED_DISABLE: + read &= ~PORT_LED_DISABLE_BITS; + read |= write << 6; + break; + case SYS_STATUS: + read &= ~SYS_STATUS_LED_BITS; + read |= write << 0; + break; + case FAN1_LED: + case FAN3_LED: + case FAN5_LED: + case FAN2_LED: + case FAN4_LED: + case FAN6_LED: + read &= ~SYS_FAN_LED_BITS; + read |= write << 3; + break; + case SYS_RESET1: + read = write; + break; + case SYS_RESET2: + read = write; + break; + case SYS_RESET3: + read = write; + break; + } + + i2c_smbus_write_byte_data(client, command, read); + + return count; +} + +static ssize_t sys_sfp_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + int error, write, command; + + error = kstrtoint(buf, 10, &write); + if (error) + return error; + + switch(sda->index) { + case SFP_TX_FAULT: + command = SFP_TX_FAULT_MASK_REG; + break; + case SFP_PRESENT: + command = SFP_PRESENT_MASK_REG; + case SFP_RX_LOSS: + command = SFP_RX_LOSS_MASK_REG; + break; + default: + return 0; + } + + i2c_smbus_write_byte_data(client, command, write); + + return count; + +} + +static ssize_t sys_sfp_read(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0, res = 0; + u8 command; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + + switch(sda->index) { + case SFP_TX_FAULT: + command = SFP_TX_FAULT_REG; + break; + case SFP_TX_DISABLE: + command = SFP_TX_DISABLE_REG; + break; + case SFP_PRESENT: + command = SFP_PRESENT_REG; + break; + case SFP_RX_LOSS: + command = SFP_RX_LOSS_REG; + break; + } + + val = i2c_smbus_read_byte_data(client, command); + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + res = val; + + return sprintf(buf, "%d\n", res); + +} + + +static void alpha_i2c_fpga_add_client(struct i2c_client *client) +{ + struct fpga_client_node *node = kzalloc(sizeof(struct fpga_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate fpga_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &fpga_client_list); + mutex_unlock(&list_lock); +} + +static void alpha_i2c_fpga_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct fpga_client_node *fpga_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &fpga_client_list) + { + fpga_node = list_entry(list_node, struct fpga_client_node, list); + + if (fpga_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(fpga_node); + } + + mutex_unlock(&list_lock); +} + +static int alpha_i2c_fpga_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct alphanetworks_snj60b0_320f_pwr_fpga_data* data; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct alphanetworks_snj60b0_320f_pwr_fpga_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + status = sysfs_create_group(&client->dev.kobj, &alphanetworks_snj60b0_320f_fpga_group); + if (status) { + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + alpha_i2c_fpga_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit; + } + + dev_info(&client->dev, "%s: pwr_fpga '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit: + return status; +} + +static int alpha_i2c_fpga_remove(struct i2c_client *client) +{ + struct alphanetworks_snj60b0_320f_pwr_fpga_data *data = i2c_get_clientdata(client); + sysfs_remove_group(&client->dev.kobj, &alphanetworks_snj60b0_320f_fpga_group); + alpha_i2c_fpga_remove_client(client); + kfree(data); + + return 0; +} + +static const struct i2c_device_id alpha_i2c_fpga_id[] = { + { DRIVER_NAME, 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, alpha_i2c_fpga_id); + +static struct i2c_driver alpha_i2c_fpga_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRIVER_NAME, + }, + .probe = alpha_i2c_fpga_probe, + .remove = alpha_i2c_fpga_remove, + .id_table = alpha_i2c_fpga_id, + .address_list = normal_i2c, +}; + +int alpha_i2c_fpga_read(unsigned short fpga_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct fpga_client_node *fpga_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &fpga_client_list) + { + fpga_node = list_entry(list_node, struct fpga_client_node, list); + + if (fpga_node->client->addr == fpga_addr) { + ret = i2c_smbus_read_byte_data(fpga_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(alpha_i2c_fpga_read); + +int alpha_i2c_fpga_write(unsigned short fpga_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct fpga_client_node *fpga_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &fpga_client_list) + { + fpga_node = list_entry(list_node, struct fpga_client_node, list); + + if (fpga_node->client->addr == fpga_addr) { + ret = i2c_smbus_write_byte_data(fpga_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(alpha_i2c_fpga_write); + +static int __init alpha_i2c_fpga_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&alpha_i2c_fpga_driver); +} + +static void __exit alpha_i2c_fpga_exit(void) +{ + i2c_del_driver(&alpha_i2c_fpga_driver); +} + +static struct dmi_system_id alphanetworks_snj60b0_320f_dmi_table[] = { + { + .ident = "Alpha snj60b0-320f", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Alpha"), + DMI_MATCH(DMI_PRODUCT_NAME, "snj60b0-320f"), + }, + } +}; + +int platform_alphanetworks_snj60b0_320f(void) +{ + return dmi_check_system(alphanetworks_snj60b0_320f_dmi_table); +} +EXPORT_SYMBOL(platform_alphanetworks_snj60b0_320f); + +MODULE_AUTHOR("Alpha-SID6"); +MODULE_DESCRIPTION("alpha_power_fpga driver"); +MODULE_LICENSE("GPL"); + +module_init(alpha_i2c_fpga_init); +module_exit(alpha_i2c_fpga_exit); diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_onie_eeprom.c b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_onie_eeprom.c new file mode 100755 index 00000000000..0462a009cc4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_onie_eeprom.c @@ -0,0 +1,267 @@ +/* + * A driver for snj60b0-320f onie eeprom + * + * Copyright (C) 2018 Alphanetworks Technology Corporation. + * Robin Chen + * 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 + * 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. + * see + * + * Copyright 2006 Stefan Roese , 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#define EEPROM_SIZE 256 + +#define SYS_LED_REG 0x8 +#define FAN12_LED_REG 0x9 +#define FAN34_LED_REG 0xA +#define FAN56_LED_REG 0xB +#define SYS_RESET1_REG 0x2 + +#define SYS_LOCATOR_LED_BITS 0x01 +#define SYS_PWR_LED_BITS 0x0E +#define SYS_STATUS_LED_BITS 0x70 +#define FAN135_LED_BITS 0x07 +#define FAN246_LED_BITS 0x38 + + +extern int alpha_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int alpha_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +static ssize_t onie_read(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t onie_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +/* Addresses scanned for snj60b0-320f_onie_eeprom */ +static const unsigned short normal_i2c[] = { 0x56, I2C_CLIENT_END }; + + +enum sysfs_onie_attributes { + ONIE_RW, +}; + +static SENSOR_DEVICE_ATTR(eeprom, (0660), onie_read, onie_write, ONIE_RW); + +static struct attribute *snj60b0_onie_attributes[] = { + &sensor_dev_attr_eeprom.dev_attr.attr, + NULL +}; + +static const struct attribute_group snj60b0_onie_group = { + .attrs = snj60b0_onie_attributes, +}; + + +static ssize_t onie_read(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0, res = 0; + u8 command; + struct i2c_client *client = to_i2c_client(dev); + __u8 read_write; + unsigned short offset = 0; + union i2c_smbus_data temp; + char rbuf[EEPROM_SIZE]; + + for( offset=0 ; offset < EEPROM_SIZE ; ++offset ) + { + read_write = I2C_SMBUS_WRITE; + offset = offset & 0x3fff; + temp.byte = (u8)offset; + res = i2c_smbus_xfer(client->adapter, client->addr, client->flags=0, + read_write, 0, 2, &temp); + res = i2c_smbus_xfer(client->adapter, client->addr, client->flags=0, + read_write, 0, 2, &temp); + + read_write = I2C_SMBUS_READ; + temp.byte = 0xaa; + res = i2c_smbus_xfer(client->adapter, client->addr, client->flags=0, + read_write, 0, 1, &temp); + if (!res) + { + res = temp.byte; + rbuf[offset] = (char)temp.byte; + } + + read_write = I2C_SMBUS_READ; + temp.byte = 0xbb; + res = i2c_smbus_xfer(client->adapter, client->addr, client->flags=0, + read_write, 0, 1, &temp); + if (!res) + { + res = temp.byte; + } + } + + memcpy(buf, rbuf, EEPROM_SIZE); + return EEPROM_SIZE; +} + +static ssize_t onie_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int error, write, command, read; + + error = kstrtoint(buf, 10, &write); + if (error) + return error; + + if (write < 0 || write > 255) + return -EINVAL; + + /* Not support yet */ + + return count; +} + + + +static void alpha_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 alpha_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 onie_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + status = sysfs_create_group(&client->dev.kobj, &snj60b0_onie_group); + if (status) { + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + alpha_i2c_cpld_add_client(client); + + return 0; + +exit: + return status; +} + +static int onie_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &snj60b0_onie_group); + alpha_i2c_cpld_remove_client(client); + + return 0; +} + +static const struct i2c_device_id onie_eeprom_id[] = { + { "snj60b0_onie_eeprom", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, onie_eeprom_id); + +static struct i2c_driver onie_eeprom_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "snj60b0_onie_eeprom", + }, + .probe = onie_eeprom_probe, + .remove = onie_eeprom_remove, + .id_table = onie_eeprom_id, + .address_list = normal_i2c, +}; + + +static int __init onie_eeprom_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&onie_eeprom_driver); +} + +static void __exit onie_eeprom_exit(void) + +{ + i2c_del_driver(&onie_eeprom_driver); +} + + +MODULE_AUTHOR("Alpha-SID6"); +MODULE_DESCRIPTION("onie eeprom driver"); +MODULE_LICENSE("GPL"); + +module_init(onie_eeprom_init); +module_exit(onie_eeprom_exit); diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_sfp.c b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_sfp.c new file mode 100755 index 00000000000..01925376962 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_sfp.c @@ -0,0 +1,2068 @@ +/* + * SFP driver for alphanetworks snj60b0-320f sfp + * + * Copyright (C) 2019 Alphanetworks Technology Corporation. + * Philip Wang + * + * 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 + * 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. + * see + * + * Copyright (C) Brandon Chuang + * + * Copyright 2006 Stefan Roese , 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "snj60b0-320f_sfp" + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "[%s,%d]: " fmt "\r\n", __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define NUM_OF_SFP_PORT 32 +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_CPLD_I2C_ADDR 0x5F +//#define SFP_FPGA_I2C_ADDR 0x5E +#define SFP_EEPROM_A0_I2C_ADDR 0x50 +#define SFP_EEPROM_A2_I2C_ADDR 0x68 + +#define SFPPLUS_1_PORT_NUMBER 32 +#define SFPPLUS_2_PORT_NUMBER 33 + +#define SFPPLUS_PRESENT_ADDRESS 0x28 + +#define SFP_CPLD_REG_ADDR_REVISION 0x00 +#define SFP_CPLD_REG_ADDR_PRESENT 0x03 +#define SFP_CPLD_REG_ADDR_RESET 0x04 +#define SFP_CPLD_REG_ADDR_LOWPOWERMODE 0x05 +#define SFP_CPLD_REG_ADDR_MODSELECT 0x06 +#define SFP_CPLD_REG_ADDR_LED 0x07 + +#define SFP_CPLD_REVISION_BIT 0xF + +u8 portCPLDID_0[]={13,14,15,16}; +u8 sfpPlusID_0[]={12,11}; +u8 portCPLDID_1[]={14,15,16,17}; +u8 sfpPlusID_1[]={13,12}; +u8 *portCPLDID; +u8 *sfpPlusID; + + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 +#define SFF8024_DEVICE_ID_QSFPDD 0x18 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 + +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +/* extern int alpha_i2c_cpld_read(unsigned short cpld_addr, u8 reg); */ +extern int alpha_i2c_fpga_write(unsigned short cpld_addr, u8 reg, u8 value); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { SFP_EEPROM_A0_I2C_ADDR, SFP_EEPROM_A2_I2C_ADDR, SFP_CPLD_I2C_ADDR, I2C_CLIENT_END }; + +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +sfp1, sfp2, sfp3, sfp4, sfp5, sfp6, sfp7, sfp8, +sfp9, sfp10, sfp11, sfp12, sfp13, sfp14, sfp15, sfp16, +sfp17, sfp18, sfp19, sfp20, sfp21, sfp22, sfp23, sfp24, +sfp25, sfp26, sfp27, sfp28, sfp29, sfp30, sfp31, sfp32, +sfp33, sfp34 +}; + +static const struct i2c_device_id sfp_device_id[] = { +{ "sfpcpld1", sfp1 }, { "sfpcpld2", sfp2 }, { "sfpcpld3", sfp3 }, { "sfpcpld4", sfp4 }, +{ "sfpcpld5", sfp5 }, { "sfpcpld6", sfp6 }, { "sfpcpld7", sfp7 }, { "sfpcpld8", sfp8 }, +{ "sfpcpld9", sfp9 }, { "sfpcpld10", sfp10 }, { "sfpcpld11", sfp11 }, { "sfpcpld12", sfp12 }, +{ "sfpcpld13", sfp13 }, { "sfpcpld14", sfp14 }, { "sfpcpld15", sfp15 }, { "sfpcpld16", sfp16 }, +{ "sfpcpld17", sfp17 }, { "sfpcpld18", sfp18 }, { "sfpcpld19", sfp19 }, { "sfpcpld20", sfp20 }, +{ "sfpcpld21", sfp21 }, { "sfpcpld22", sfp22 }, { "sfpcpld23", sfp23 }, { "sfpcpld24", sfp24 }, +{ "sfpcpld25", sfp25 }, { "sfpcpld26", sfp26 }, { "sfpcpld27", sfp27 }, { "sfpcpld28", sfp28 }, +{ "sfpcpld29", sfp29 }, { "sfpcpld30", sfp30 }, { "sfpcpld31", sfp31 }, { "sfpcpld32", sfp32 }, +{ "sfpcpld33", sfp33 }, { "sfpcpld34", sfp34 }, +{} +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28, + OOM_DRIVER_PORT_TYPE_QSFPDD +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[2]; /* index 0 => device id + 1 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 2 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + u64 port_reset; /* reset status, bit0:port0, bit1:port1 and so on */ + u64 port_lpmode; /* lpmode status, bit0:port0, bit1:port1 and so on */ + u64 port_led; /* port led status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +enum sfp_sysfs_port_num_attributes { + PORT1_NUMBER, + PORT2_NUMBER, + PORT3_NUMBER, + PORT4_NUMBER, + PORT5_NUMBER, + PORT6_NUMBER, + PORT7_NUMBER, + PORT8_NUMBER, + PORT_NUMBER_MAX +}; + +enum sfp_sysfs_present_attributes { + PORT1_PRESENT, + PORT2_PRESENT, + PORT3_PRESENT, + PORT4_PRESENT, + PORT5_PRESENT, + PORT6_PRESENT, + PORT7_PRESENT, + PORT8_PRESENT, + PORT1_PRESENT_ALL, + PORT2_PRESENT_ALL, + PORT3_PRESENT_ALL, + PORT4_PRESENT_ALL, + PORT5_PRESENT_ALL, + PORT6_PRESENT_ALL, + PORT7_PRESENT_ALL, + PORT8_PRESENT_ALL, + PORT_PRESENT_MAX +}; + +enum sfp_sysfs_type_attributes { + PORT1_TYPE, + PORT2_TYPE, + PORT3_TYPE, + PORT4_TYPE, + PORT5_TYPE, + PORT6_TYPE, + PORT7_TYPE, + PORT8_TYPE, + PORT_TYPE_MAX +}; + +enum sfp_sysfs_reset_attributes { + PORT1_RESET, + PORT2_RESET, + PORT3_RESET, + PORT4_RESET, + PORT5_RESET, + PORT6_RESET, + PORT7_RESET, + PORT8_RESET, + PORT_RESET_MAX +}; + +enum sfp_sysfs_rx_los_attributes { + PORT1_RX_LOS, + PORT2_RX_LOS, + PORT3_RX_LOS, + PORT4_RX_LOS, + PORT5_RX_LOS, + PORT6_RX_LOS, + PORT7_RX_LOS, + PORT8_RX_LOS, + PORT_RX_LOS_MAX +}; + +enum sfp_sysfs_rx_los1_attributes { + PORT1_RX_LOS1 = PORT_RX_LOS_MAX, + PORT2_RX_LOS1, + PORT3_RX_LOS1, + PORT4_RX_LOS1, + PORT5_RX_LOS1, + PORT6_RX_LOS1, + PORT7_RX_LOS1, + PORT8_RX_LOS1, + PORT_RX_LOS1_MAX +}; + +enum sfp_sysfs_rx_los2_attributes { + PORT1_RX_LOS2 = PORT_RX_LOS1_MAX, + PORT2_RX_LOS2, + PORT3_RX_LOS2, + PORT4_RX_LOS2, + PORT5_RX_LOS2, + PORT6_RX_LOS2, + PORT7_RX_LOS2, + PORT8_RX_LOS2, + PORT_RX_LOS2_MAX +}; + +enum sfp_sysfs_rx_los3_attributes { + PORT1_RX_LOS3 = PORT_RX_LOS2_MAX, + PORT2_RX_LOS3, + PORT3_RX_LOS3, + PORT4_RX_LOS3, + PORT5_RX_LOS3, + PORT6_RX_LOS3, + PORT7_RX_LOS3, + PORT8_RX_LOS3, + PORT_RX_LOS3_MAX +}; + +enum sfp_sysfs_rx_los4_attributes { + PORT1_RX_LOS4 = PORT_RX_LOS3_MAX, + PORT2_RX_LOS4, + PORT3_RX_LOS4, + PORT4_RX_LOS4, + PORT5_RX_LOS4, + PORT6_RX_LOS4, + PORT7_RX_LOS4, + PORT8_RX_LOS4, + PORT_RX_LOS4_MAX +}; + +enum sfp_sysfs_rx_los_all_attributes { + PORT1_RX_LOS_ALL = PORT_RX_LOS4_MAX, + PORT2_RX_LOS_ALL, + PORT3_RX_LOS_ALL, + PORT4_RX_LOS_ALL, + PORT5_RX_LOS_ALL, + PORT6_RX_LOS_ALL, + PORT7_RX_LOS_ALL, + PORT8_RX_LOS_ALL, + PORT_RX_LOS_ALL_MAX +}; + +enum sfp_sysfs_tx_disable_attributes { + PORT1_TX_DISABLE = PORT_RX_LOS_ALL_MAX, + PORT2_TX_DISABLE, + PORT3_TX_DISABLE, + PORT4_TX_DISABLE, + PORT5_TX_DISABLE, + PORT6_TX_DISABLE, + PORT7_TX_DISABLE, + PORT8_TX_DISABLE, + PORT_TX_DISABLE_MAX +}; + +enum sfp_sysfs_tx_disable1_attributes { + PORT1_TX_DISABLE1 = PORT_TX_DISABLE_MAX, + PORT2_TX_DISABLE1, + PORT3_TX_DISABLE1, + PORT4_TX_DISABLE1, + PORT5_TX_DISABLE1, + PORT6_TX_DISABLE1, + PORT7_TX_DISABLE1, + PORT8_TX_DISABLE1, + PORT_TX_DISABLE1_MAX +}; + +enum sfp_sysfs_tx_disable2_attributes { + PORT1_TX_DISABLE2 = PORT_TX_DISABLE1_MAX, + PORT2_TX_DISABLE2, + PORT3_TX_DISABLE2, + PORT4_TX_DISABLE2, + PORT5_TX_DISABLE2, + PORT6_TX_DISABLE2, + PORT7_TX_DISABLE2, + PORT8_TX_DISABLE2, + PORT_TX_DISABLE2_MAX +}; + +enum sfp_sysfs_tx_disable3_attributes { + PORT1_TX_DISABLE3 = PORT_TX_DISABLE2_MAX, + PORT2_TX_DISABLE3, + PORT3_TX_DISABLE3, + PORT4_TX_DISABLE3, + PORT5_TX_DISABLE3, + PORT6_TX_DISABLE3, + PORT7_TX_DISABLE3, + PORT8_TX_DISABLE3, + PORT_TX_DISABLE3_MAX +}; + +enum sfp_sysfs_tx_disable4_attributes { + PORT1_TX_DISABLE4 = PORT_TX_DISABLE3_MAX, + PORT2_TX_DISABLE4, + PORT3_TX_DISABLE4, + PORT4_TX_DISABLE4, + PORT5_TX_DISABLE4, + PORT6_TX_DISABLE4, + PORT7_TX_DISABLE4, + PORT8_TX_DISABLE4, + PORT_TX_DISABLE4_MAX +}; + +enum sfp_sysfs_tx_fault_attributes { + PORT1_TX_FAULT = PORT_TX_DISABLE4_MAX, + PORT2_TX_FAULT, + PORT3_TX_FAULT, + PORT4_TX_FAULT, + PORT5_TX_FAULT, + PORT6_TX_FAULT, + PORT7_TX_FAULT, + PORT8_TX_FAULT, + PORT_TX_FAULT_MAX +}; + +enum sfp_sysfs_tx_fault1_attributes { + PORT1_TX_FAULT1 = PORT_TX_FAULT_MAX, + PORT2_TX_FAULT1, + PORT3_TX_FAULT1, + PORT4_TX_FAULT1, + PORT5_TX_FAULT1, + PORT6_TX_FAULT1, + PORT7_TX_FAULT1, + PORT8_TX_FAULT1, + PORT_TX_FAULT1_MAX +}; + +enum sfp_sysfs_tx_fault2_attributes { + PORT1_TX_FAULT2 = PORT_TX_FAULT1_MAX, + PORT2_TX_FAULT2, + PORT3_TX_FAULT2, + PORT4_TX_FAULT2, + PORT5_TX_FAULT2, + PORT6_TX_FAULT2, + PORT7_TX_FAULT2, + PORT8_TX_FAULT2, + PORT_TX_FAULT2_MAX +}; + +enum sfp_sysfs_tx_fault3_attributes { + PORT1_TX_FAULT3 = PORT_TX_FAULT2_MAX, + PORT2_TX_FAULT3, + PORT3_TX_FAULT3, + PORT4_TX_FAULT3, + PORT5_TX_FAULT3, + PORT6_TX_FAULT3, + PORT7_TX_FAULT3, + PORT8_TX_FAULT3, + PORT_TX_FAULT3_MAX +}; + +enum sfp_sysfs_tx_fault4_attributes { + PORT1_TX_FAULT4 = PORT_TX_FAULT3_MAX, + PORT2_TX_FAULT4, + PORT3_TX_FAULT4, + PORT4_TX_FAULT4, + PORT5_TX_FAULT4, + PORT6_TX_FAULT4, + PORT7_TX_FAULT4, + PORT8_TX_FAULT4, + PORT_TX_FAULT4_MAX +}; + +enum sfp_sysfs_lpmode_attributes { + PORT1_LPMODE, + PORT2_LPMODE, + PORT3_LPMODE, + PORT4_LPMODE, + PORT5_LPMODE, + PORT6_LPMODE, + PORT7_LPMODE, + PORT8_LPMODE, + PORT_LPMODE_MAX +}; + +enum sfp_sysfs_eeprom_attributes { + PORT1_EEPROM, + PORT2_EEPROM, + PORT3_EEPROM, + PORT4_EEPROM, + PORT5_EEPROM, + PORT6_EEPROM, + PORT7_EEPROM, + PORT8_EEPROM, + PORT_EEPROM_MAX +}; + +enum sfp_sysfs_ddm_implemented_attributes { + PORT1_DDM_IMPLEMENTED, + PORT2_DDM_IMPLEMENTED, + PORT3_DDM_IMPLEMENTED, + PORT4_DDM_IMPLEMENTED, + PORT5_DDM_IMPLEMENTED, + PORT6_DDM_IMPLEMENTED, + PORT7_DDM_IMPLEMENTED, + PORT8_DDM_IMPLEMENTED, + PORT_DDM_IMPLEMENTED_MAX +}; + +enum sfp_sysfs_port_led_attributes { + PORT_LED, + PORT_LED_MAX +}; + +enum sfp_sysfs_cpld_revision_attributes { + CPLD_REVISION, + CPLD_REVISION_MAX +}; + +static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + if (client->addr == SFP_CPLD_I2C_ADDR) + { + val = i2c_smbus_read_byte_data(client, SFP_CPLD_REG_ADDR_REVISION); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x0) err %d\n", client->addr, val); + } + } + + return sprintf(buf, "%d\n", (val & SFP_CPLD_REVISION_BIT)); +} + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + DEBUG_PRINT("show_port_number port number:%d", data->port + attr->index); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port + attr->index)); +} + +static struct sfp_port_data *sfp_plus_update_present(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {SFPPLUS_PRESENT_ADDRESS}; + + DEBUG_PRINT("Starting sfp+ present status update"); + mutex_lock(&data->update_lock); + + /* Read present status of port */ + data->present = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + /* status = alpha_i2c_cpld_read(0x5f, regs[i]); */ + status = i2c_smbus_read_byte_data(client, regs[i]); + + if (status < 0) { + DEBUG_PRINT("SFP+ reg(0x%x) err %d", regs[i], status); + goto exit; + } + + DEBUG_PRINT("Status:%d", status); + + if(data->port == SFPPLUS_1_PORT_NUMBER) + data->present = ((status & 0x2) == 0)?0x1:0; + else + data->present = ((status & 0x1) == 0)?0x2:0; + } + + DEBUG_PRINT("Present status = 0x%llx", data->present); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {SFP_CPLD_REG_ADDR_PRESENT}; + + if(data->port >= SFPPLUS_1_PORT_NUMBER){ + if(client->addr == SFP_EEPROM_A0_I2C_ADDR) + return sfp_plus_update_present(client); + else{ + data->present = 0; + return data; + } + } + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + + /* Read present status of port 1~32 */ + data->present = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = i2c_smbus_read_byte_data(client, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld(%d) reg(0x%x) err %d", SFP_CPLD_I2C_ADDR, regs[i], status); + goto exit; + } + DEBUG_PRINT("Present status = 0x%x", status); + + data->present |= (u64)status << (i*8); + DEBUG_PRINT("Present status = 0x%llx", data->present); + } + + DEBUG_PRINT("Present status = 0x%llx", data->present); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + return NULL; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + return 0; +} + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = sfp_update_present(client); + return (data->present & BIT_INDEX(port)) ? 1 : 0; +} + +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if ((attr->index >= PORT1_PRESENT_ALL) && (attr->index <= PORT8_PRESENT_ALL)) { + } + + /* PRESENT */ + return sprintf(buf, "%d\n", sfp_is_port_present(client, attr->index)); +} + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(data->client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (status < 0) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(data->client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (status < 0) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(data->client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (status < 0) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP28; + break; + case SFF8024_DEVICE_ID_QSFPDD: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFPDD; + break; + default: + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (!sfp_is_port_present(client, attr->index)) { + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + + +static struct sfp_port_data *sfp_update_port_reset(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {SFP_CPLD_REG_ADDR_RESET}; + + mutex_lock(&data->update_lock); + + /* Read reset status of port 1~32 */ + data->port_reset = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = i2c_smbus_read_byte_data(client, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld(0x%x) reg(0x%x) err %d", SFP_CPLD_REG_ADDR_RESET, regs[i], status); + goto exit; + } + + DEBUG_PRINT("reset status = 0x%x", status); + data->port_reset |= (u64)status << (i*8); + } + + DEBUG_PRINT("reset status = 0x%llx", data->port_reset); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int is_reset = 0; + + if (!sfp_is_port_present(client, attr->index)) { + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_reset(client); + is_reset = (data->port_reset & BIT_INDEX(attr->index)); + + return sprintf(buf, "%d\n", is_reset); +} + +static ssize_t sfp_set_port_reset(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 sfp_port_data *data = i2c_get_clientdata(client); + u8 cpld_reg = 0, cpld_val = 0; /*, cpld_bit = 0; //remove unused variable */ + long is_reset; + int error; + + error = kstrtol(buf, 10, &is_reset); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + cpld_reg = SFP_CPLD_REG_ADDR_RESET; + + cpld_val = i2c_smbus_read_byte_data(client, cpld_reg); + + DEBUG_PRINT("current cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + /* Update reset status. CPLD defined 0 is reset state, 1 is normal state. + * is_reset: 0 is not reset. 1 is reset. + */ + if (is_reset == 1) { + cpld_val |= BIT_INDEX(attr->index); + } + else { + cpld_val &= ~BIT_INDEX(attr->index); + } + + i2c_smbus_write_byte_data(client, cpld_reg, cpld_val); + DEBUG_PRINT("write cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + dev_dbg(dev, "Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(data->client, reg[i], &buf, sizeof(buf)); + if (status < 0) { + goto exit; + } + } + msleep(200); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(data->client, reg[i], &buf, sizeof(buf)); + if (status < 0) { + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + mutex_unlock(&data->update_lock); + return data; + +exit: + mutex_unlock(&data->update_lock); + return NULL; +} + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sfp_port_data *data = i2c_get_clientdata(client); + + if (!sfp_is_port_present(client, attr->index)) { + return -ENODEV; + } + + data = qsfp_update_tx_rx_status(dev); + if (!data) { + return -EIO; + } + + if ((attr->index >= PORT1_TX_FAULT) && (attr->index < PORT_TX_FAULT4_MAX)){ + if (attr->index < PORT_TX_FAULT_MAX) + val = ((data->qsfp->status[2] & 0xF) == 0xF) ? 1 : 0; + else + val = (data->qsfp->status[2] & BIT_INDEX(attr->index - PORT1_TX_FAULT1)) ? 1 : 0; + } + else if ((attr->index >= PORT1_TX_DISABLE) && (attr->index < PORT_TX_DISABLE4_MAX)){ + if (attr->index < PORT_TX_DISABLE_MAX) + val = ((data->qsfp->status[1] & 0xF) == 0xF) ? 1 : 0; + else + val = (data->qsfp->status[1] & BIT_INDEX(attr->index - PORT1_TX_DISABLE1)) ? 1 : 0; + } + if ((attr->index >= PORT1_RX_LOS) && (attr->index < PORT_RX_LOS4_MAX)){ + if (attr->index < PORT_RX_LOS_MAX) + val = ((data->qsfp->status[0] & 0xf) == 0xf) ? 1 : 0; + else + val = (data->qsfp->status[0] & BIT_INDEX(attr->index - PORT1_RX_LOS1)) ? 1 : 0; + } + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int result; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sfp_port_data *data; + + result = kstrtol(buf, 10, &disable); + if (result) { + return result; + } + + data = qsfp_update_tx_rx_status(dev); + if (!data) { + return -EIO; + } + + mutex_lock(&data->update_lock); + + if((attr->index >= PORT1_TX_DISABLE) && (attr->index < PORT_TX_DISABLE_MAX)){ + DEBUG_PRINT ("disable:%ld %d==TX_DISABLE %u\r\n", disable, attr->index, data->qsfp->status[1]); + data->qsfp->status[1] = disable? 0xF:0; + } + else{ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - PORT1_TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - PORT1_TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + result = sfp_eeprom_write(client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + mutex_unlock(&data->update_lock); + return count; +} + +static struct sfp_port_data *qsfp_update_port_led(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int status = -1; + u8 reg = SFP_CPLD_REG_ADDR_LED; + + mutex_lock(&data->update_lock); + + /* Read led status of port 1~32 */ + data->port_led = 0; + + status = i2c_smbus_read_byte_data(client, reg); + + if (status < 0) { + DEBUG_PRINT("cpld reg(0x%x) err %d", reg, status); + goto exit; + } + + data->port_led = status; + + DEBUG_PRINT("led status = %ll", data->port_led); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t qsfp_show_port_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = qsfp_update_port_led(client); + + return sprintf(buf, "%ll\n", data->port_led); +} + +static ssize_t qsfp_set_port_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 cpld_reg = 0, cpld_val = 0; /*, cpld_bit = 0; //remove unused variable */ + long led_state; + int error; + int result; + + error = kstrtol(buf, 10, &led_state); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + cpld_reg = SFP_CPLD_REG_ADDR_LED; + + cpld_val = i2c_smbus_read_byte_data(client, cpld_reg); + + DEBUG_PRINT("current cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + /* Update led status. CPLD defined 0 is LED enable, 1 is LED disable. + * led_state: 0 is LED enable. 1 is LED disable. + */ + if (cpld_val != led_state){ + data->port_led = led_state; + + result = i2c_smbus_write_byte_data(client, cpld_reg, led_state); + if (result < 0) { + dev_info(&client->dev, "%s, i2c_smbus_write_byte_data fail(%d)", __FUNCTION__, result); + } + DEBUG_PRINT("write cpld reg = 0x%x value = 0x%x", cpld_reg, led_state); + } + + mutex_unlock(&data->update_lock); + + return count; +} + +static struct sfp_port_data *qsfp_update_port_lpmode(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {SFP_CPLD_REG_ADDR_LOWPOWERMODE}; + + mutex_lock(&data->update_lock); + + /* Read lpmode status of port 1~32 */ + data->port_lpmode = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = i2c_smbus_read_byte_data(client, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld reg(0x%x) err %d", regs[i], status); + goto exit; + } + + DEBUG_PRINT("lpmode status = 0x%x", status); + data->port_lpmode |= (u64)status << (i*8); + } + + DEBUG_PRINT("lpmode status = 0x%llx", data->port_lpmode); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t qsfp_show_port_lpmode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int is_lpmode = 0; + + qsfp_update_port_lpmode(client); + is_lpmode = (data->port_lpmode & BIT_INDEX(attr->index))?1:0; + + return sprintf(buf, "%d\n", is_lpmode); +} + +static ssize_t qsfp_set_port_lpmode(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 sfp_port_data *data = i2c_get_clientdata(client); + u8 cpld_reg = 0, cpld_val = 0; + long is_lpmode; + int error; + + error = kstrtol(buf, 10, &is_lpmode); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + cpld_reg = SFP_CPLD_REG_ADDR_LOWPOWERMODE; + + cpld_val = i2c_smbus_read_byte_data(client, cpld_reg); + + DEBUG_PRINT("current cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + /* Update lpmode status. CPLD defined 0 is normal mode, 1 is Low Power mode. + * is_lpmode: 0 is normal mode. 1 is Low Power mode. + */ + if (is_lpmode == 1) { + cpld_val |= BIT_INDEX(attr->index); + } + else { + cpld_val &= ~BIT_INDEX(attr->index); + } + + i2c_smbus_write_byte_data(client, cpld_reg, cpld_val); + DEBUG_PRINT("write cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (!sfp_is_port_present(client, attr->index)) { + return -ENODEV; + } + + status = sfp_eeprom_read(data->client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (status < 0) { + return -EIO; + } + + return sprintf(buf, "%d\n", (ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK) ? 1 : 0); +} + +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sfp_port_data *data; + + data = sfp_update_tx_rx_status(dev); + if (!data) { + return -EIO; + } + if ((attr->index >= PORT1_TX_FAULT) && (attr->index < PORT_TX_FAULT_MAX)){ + index = 0; + } + else if ((attr->index >= PORT1_TX_DISABLE) && (attr->index < PORT_TX_DISABLE_MAX)){ + index = 1; + } + if ((attr->index >= PORT1_RX_LOS) && (attr->index < PORT_RX_LOS_MAX)){ + index = 2; + } + + if(data->port == SFPPLUS_1_PORT_NUMBER) + val = (data->ddm->status[index] & BIT_INDEX(0)) ? 1 : 0; + else if(data->port == SFPPLUS_2_PORT_NUMBER) + val = (data->ddm->status[index] & BIT_INDEX(1)) ? 1 : 0; + else + val = (data->ddm->status[index] & BIT_INDEX(attr->index)) ? 1 : 0; + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_show_eeprom(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + char devfile[96]; + struct file *sfd; + int i2c_index = 0; + int result; + int offset[] = {SFP_CPLD_REG_ADDR_MODSELECT}; + int rdlen, rc; + mm_segment_t old_fs; + char buffer[256]; + + if (!sfp_is_port_present(client, attr->index)) { + return 0; + } + + snprintf(devfile, sizeof(devfile), "/sys/bus/i2c/devices/%d-0050/sfp_eeprom", portCPLDID_0[0]); + + /* Read SFP EEPROM */ + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + dev_info(&client->dev, "Failed to open file(%s)#%d", devfile, __LINE__); + portCPLDID = portCPLDID_1; + sfpPlusID = sfpPlusID_1; + } + else{ + portCPLDID = portCPLDID_0; + sfpPlusID = sfpPlusID_0; + } + + if(strcmp(client->name, "sfpcpld33") == 0){ + if(attr->index == 0) + i2c_index = sfpPlusID[0]; + else if(attr->index == 1) + i2c_index = sfpPlusID[1]; + } + else{ + if(strcmp(client->name, "sfpcpld1") == 0) + i2c_index = portCPLDID[0]; + else if(strcmp(client->name, "sfpcpld9") == 0) + i2c_index = portCPLDID[1]; + else if(strcmp(client->name, "sfpcpld17") == 0) + i2c_index = portCPLDID[2]; + else if(strcmp(client->name, "sfpcpld25") == 0) + i2c_index = portCPLDID[3]; + + /* Port number is 1-8 */ + result = i2c_smbus_write_byte_data(client, offset[0], BIT_INDEX(attr->index)); + if (result < 0) { + dev_info(&client->dev, "%s, i2c_smbus_write_byte_data fail(%d)", __FUNCTION__, result); + } + } + + snprintf(devfile, sizeof(devfile), "/sys/bus/i2c/devices/%d-0050/sfp_eeprom", i2c_index); + + /* Read SFP EEPROM */ + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + dev_info(&client->dev, "Failed to open file(%s)#%d", devfile, __LINE__); + return 0; + } + + if(!(sfd->f_op) || !(sfd->f_op->read) ) { + dev_info(&client->dev, "file %s cann't readable ?\n", devfile); + return 0; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + rdlen = sfd->f_op->read(sfd, buffer, sizeof(buffer), &sfd->f_pos); + if (rdlen == 0) { + dev_info(&client->dev, "File(%s) empty!\n", devfile); + rc = 0; + goto exit; + } + + rc = sizeof(buffer); + memcpy(buf, buffer, rc); + + /* Reset module select register */ + if(strcmp(client->name, "sfpcpld33") != 0){ + /* Port number is 1-8 */ + result = i2c_smbus_write_byte_data(client, offset[0], 0); + if (result < 0) { + dev_info(&client->dev, "%s, i2c_smbus_write_byte_data fail(%d)", __FUNCTION__, result); + } + } + +exit: + set_fs(old_fs); + filp_close(sfd, 0); + + return rc; +} + +#if 0 +static ssize_t qsfp_set_eeprom(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + DEBUG_PRINT("data->port:%d attr index:%d", data->port, attr->index); + return 1; +} +#endif + +/* SFP/QSFP common attributes for sysfs */ +#define DECLARE_PORT_NUMBER_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT1##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT2##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT3##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT4##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT5##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT6##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT7##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT8##_NUMBER); +#define DECLARE_PORT_NUMBER_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_port_number.dev_attr.attr, +DECLARE_PORT_NUMBER_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_IS_PRESENT_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_is_present, S_IRUGO, show_present, NULL, PORT##PORT1##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_is_present, S_IRUGO, show_present, NULL, PORT##PORT2##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_is_present, S_IRUGO, show_present, NULL, PORT##PORT3##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_is_present, S_IRUGO, show_present, NULL, PORT##PORT4##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_is_present, S_IRUGO, show_present, NULL, PORT##PORT5##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_is_present, S_IRUGO, show_present, NULL, PORT##PORT6##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_is_present, S_IRUGO, show_present, NULL, PORT##PORT7##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_is_present, S_IRUGO, show_present, NULL, PORT##PORT8##_PRESENT); +#define DECLARE_PORT_IS_PRESENT_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_is_present.dev_attr.attr, +DECLARE_PORT_IS_PRESENT_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_TYPE_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT1##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT2##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT3##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT4##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT5##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT6##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT7##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT8##_TYPE); +#define DECLARE_PORT_TYPE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) &sensor_dev_attr_sfp##PORT1##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_port_type.dev_attr.attr, +DECLARE_PORT_TYPE_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_RESET_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT1##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT2##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT3##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT4##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT5##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT6##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT7##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT8##_RESET); +#define DECLARE_PORT_RESET_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) &sensor_dev_attr_sfp##PORT1##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_port_reset.dev_attr.attr, +DECLARE_PORT_RESET_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +/* QSFP attributes for sysfs */ +#define DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT1##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT2##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT3##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT4##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT5##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT6##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT7##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT8##_RX_LOS##INDEX); +#define DECLARE_PORT_RX_LOSn_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_rx_los##INDEX.dev_attr.attr, +DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT1##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT2##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT3##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT4##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT5##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT6##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT7##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT8##_TX_DISABLE##INDEX); + +#define DECLARE_PORT_TX_DISABLEn_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_tx_disable##INDEX.dev_attr.attr, +DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT1##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT2##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT3##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT4##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT5##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT6##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT7##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT8##_TX_FAULT##INDEX); +#define DECLARE_PORT_TX_FAULTn_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_tx_fault##INDEX.dev_attr.attr, +DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_LED_DEVICE_ATTR() \ + static SENSOR_DEVICE_ATTR(sfp_led_disable, S_IWUSR | S_IRUGO, qsfp_show_port_led, qsfp_set_port_led, PORT_LED); +#define DECLARE_PORT_LED_ATTR() \ + &sensor_dev_attr_sfp_led_disable.dev_attr.attr, +DECLARE_PORT_LED_DEVICE_ATTR() + +#define DECLARE_PORT_EEPROMn_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT1##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT2##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT3##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT4##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT5##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT6##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT7##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT8##_EEPROM); +#define DECLARE_PORT_EEPROMTn_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_eeprom.dev_attr.attr, +DECLARE_PORT_EEPROMn_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_LPMODE_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT1##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT2##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT3##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT4##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT5##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT6##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT7##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT8##_LPMODE); +#define DECLARE_PORT_LPMODE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_lpmode.dev_attr.attr, +DECLARE_PORT_LPMODE_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_CPLD_REVISION() \ + static SENSOR_DEVICE_ATTR(cpld_revision, (0660), show_cpld_version, NULL, CPLD_REVISION); +#define DECLARE_PORT_CPLD_REVISION_ATTR() \ + &sensor_dev_attr_cpld_revision.dev_attr.attr, +DECLARE_PORT_CPLD_REVISION() + +static struct attribute *qsfp_attributes[] = { + DECLARE_PORT_NUMBER_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TYPE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_IS_PRESENT_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RESET_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_LPMODE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_LED_ATTR() + DECLARE_PORT_RX_LOSn_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RX_LOSn_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RX_LOSn_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RX_LOSn_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_DISABLEn_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_DISABLEn_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_DISABLEn_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_DISABLEn_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_FAULTn_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_FAULTn_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_FAULTn_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_FAULTn_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_EEPROMTn_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_CPLD_REVISION_ATTR() + NULL +}; + + +/* SFP msa attributes for sysfs */ +static struct attribute *sfp_msa_attributes[] = { + DECLARE_PORT_NUMBER_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TYPE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_IS_PRESENT_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RESET_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + NULL +}; + +/* SFP ddm attributes for sysfs */ +#define DECLARE_RX_LOS_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT1##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT2##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT3##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT4##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT5##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT6##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT7##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT8##_RX_LOS); +#define DECLARE_RX_LOS_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) &sensor_dev_attr_sfp##PORT1##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_rx_los.dev_attr.attr, +DECLARE_RX_LOS_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_TX_DISABLE_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT1##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT2##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT3##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT4##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT5##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT6##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT7##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT8##_TX_DISABLE); +#define DECLARE_TX_DISABLE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_tx_disable.dev_attr.attr, +DECLARE_TX_DISABLE_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_TX_FAULT_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT1##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT2##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT3##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT4##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT5##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT6##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT7##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT8##_TX_FAULT); +#define DECLARE_TX_FAULT_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_tx_fault.dev_attr.attr, +DECLARE_TX_FAULT_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) +static struct attribute *sfp_ddm_attributes[] = { + DECLARE_RX_LOS_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_TX_DISABLE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_TX_FAULT_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + NULL +}; + +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int result, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + result = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + return result; + } + + return data_len; +#else + int result, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + result = i2c_smbus_write_byte_data(client, command, *data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + return result; + } + + return 1; +#endif + +} + + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", (int)off, (int)count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int result, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + /* result = data_len; */ + +abort: + return result; +#else + int result, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + result = i2c_smbus_read_byte_data(client, command); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result); + goto abort; + } + + *data = (u8)result; + result = 1; + +abort: + return result; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", (int)off, (int)count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + dev_info(&client->dev, "sfp msa '%s' (sfp_sysfs_eeprom_init fail...)\n", client->name); + /* goto exit_remove; */ + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + return 0; + +/* exit_remove: */ + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + struct sfp_port_data *port_data = i2c_get_clientdata(client); + + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + if ( ((port_data->port < SFPPLUS_1_PORT_NUMBER) && (client->addr == SFP_CPLD_I2C_ADDR)) || + ((port_data->port >= SFPPLUS_1_PORT_NUMBER) && (client->addr == SFP_EEPROM_A0_I2C_ADDR)) ) + { + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + } + + if (client->addr == SFP_EEPROM_A0_I2C_ADDR){ + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + } + + /* Bring QSFPs out of reset */ + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + DEBUG_PRINT("data->port:%d client->addr:0x%0x\n", data->port, client->addr); + if (client->addr == SFP_CPLD_I2C_ADDR){ + if(data->port >= SFPPLUS_1_PORT_NUMBER){ + DEBUG_PRINT("client->addr:0x%0x\n", client->addr); + return -ENODEV; + } + } + + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); +} + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + if ((client->addr == SFP_CPLD_I2C_ADDR) || (client->addr == SFP_EEPROM_A0_I2C_ADDR)) + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + if ((client->addr == SFP_CPLD_I2C_ADDR) || (client->addr == SFP_EEPROM_A0_I2C_ADDR)) + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + if ((client->addr == SFP_CPLD_I2C_ADDR) || (client->addr == SFP_EEPROM_A0_I2C_ADDR)) + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +static struct i2c_driver sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +static int __init sfp_init(void) +{ + return i2c_add_driver(&sfp_driver); +} + +static void __exit sfp_exit(void) +{ + i2c_del_driver(&sfp_driver); +} + +MODULE_AUTHOR("Philip Wang "); +MODULE_DESCRIPTION("alphanetworks snj60b0-320f driver"); +MODULE_LICENSE("GPL"); + +module_init(sfp_init); +module_exit(sfp_exit); + diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/yesm1300am.c b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/yesm1300am.c new file mode 100755 index 00000000000..e0e58fd3a1f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/yesm1300am.c @@ -0,0 +1,390 @@ +/* + * An hwmon driver for the 3Y Power YM-2651Y Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Copyright 2006 Stefan Roese , 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 +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = {0x58, 0x59, I2C_CLIENT_END}; + +/* Each client has this additional data + */ +struct yesm1300am_data +{ + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u8 vout_mode; /* Register value */ + u16 fan_speed; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[12]; /* Register value */ +}; + +static ssize_t show_vout_by_mode(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_ascii(struct device *dev, struct device_attribute *da, + char *buf); +static struct yesm1300am_data *yesm1300am_update_device(struct device *dev); + +enum yesm1300am_sysfs_attributes +{ + PSU_V_OUT = 0, + PSU_I_OUT, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MODEL_NAME +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout_by_mode, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_ascii, NULL, PSU_MODEL_NAME); + +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_vout_by_mode, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); + +static struct attribute *yesm1300am_attributes[] = { + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_model_name.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_fan1_input.dev_attr.attr, + NULL}; + +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 show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct yesm1300am_data *data = yesm1300am_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) + { + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + 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_ascii(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct yesm1300am_data *data = yesm1300am_update_device(dev); + u8 *ptr = NULL; + + switch (attr->index) + { + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id; + break; + case PSU_MODEL_NAME: /* psu_mfr_model */ + ptr = data->mfr_model; + break; + default: + return 0; + } + + return sprintf(buf, "%s\n", ptr); +} + +static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct yesm1300am_data *data = yesm1300am_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + if (!data->valid) + { + return 0; + } + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + switch (attr->index) + { + case PSU_V_OUT: + mantissa = data->v_out; + break; + default: + return 0; + } + + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static const struct attribute_group yesm1300am_group = { + .attrs = yesm1300am_attributes, +}; + +static int yesm1300am_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct yesm1300am_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 yesm1300am_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, &yesm1300am_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, &yesm1300am_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int yesm1300am_remove(struct i2c_client *client) +{ + struct yesm1300am_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &yesm1300am_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id yesm1300am_id[] = { + {"yesm1300am", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, yesm1300am_id); + +static struct i2c_driver yesm1300am_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "yesm1300am", + }, + .probe = yesm1300am_probe, + .remove = yesm1300am_remove, + .id_table = yesm1300am_id, + .address_list = normal_i2c, +}; + +static int yesm1300am_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int yesm1300am_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int yesm1300am_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 yesm1300am_data *yesm1300am_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct yesm1300am_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; + struct reg_data_byte regs_byte[] = {{0x20, &data->vout_mode}}; + struct reg_data_word regs_word[] = {{0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x90, &data->fan_speed},}; + + dev_dbg(&client->dev, "Starting yesm1300am update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) + { + status = yesm1300am_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 = yesm1300am_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 mfr_id */ + command = 0x99; + status = yesm1300am_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + strncpy(data->mfr_id, (u8 *)&data->mfr_id + 1, ARRAY_SIZE(data->mfr_id) - 1); + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_model */ + command = 0x9a; + status = yesm1300am_read_block(client, command, data->mfr_model, + ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + strncpy(data->mfr_model, (u8 *)&data->mfr_model + 1, ARRAY_SIZE(data->mfr_model) - 1); + + 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(yesm1300am_driver); + +MODULE_AUTHOR("Alpha-SID6"); +MODULE_DESCRIPTION("3Y Power yesm1300am driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/service/snj60b0-platform-init.service b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/service/snj60b0-platform-init.service new file mode 100755 index 00000000000..1bb09836ed9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/service/snj60b0-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Alphanetworks SNJ60B0-320F Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/alphanetworks_snj60b0_util.py -f install +ExecStop=/usr/local/bin/alphanetworks_snj60b0_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/setup.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/setup.py new file mode 100755 index 00000000000..26d28fc6fed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic-platform', + version='1.0', + description='Module to initialize Alphanetworks SNJ60B0-320F platforms', + + packages=['sonic_platform'], +) + diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/__init__.py new file mode 100755 index 00000000000..83a34670c81 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/__init__.py @@ -0,0 +1 @@ +__all__ = ["platform", "chassis"] diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/chassis.py new file mode 100755 index 00000000000..d49ba4f2454 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/chassis.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys +import json + +try: + from sonic_platform_base.chassis_base import ChassisBase + from .fan import Alpha_Fan as Fan + from .psu import Alpha_Psu as Psu + from .sfp import Alpha_Sfp as Sfp + from .thermal import Alpha_Thermal as Thermal + from .component import Alpha_Component as Component + from .fan_drawer import Alpha_FanDrawer as FanDrawer + from .led import Alpha_FanLed as FanLed + from .led import Alpha_PsuLed as PsuLed +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +#from xcvrd +SFP_STATUS_INSERTED = '1' +SFP_STATUS_REMOVED = '0' + +NUM_THERMAL = 3 +NUM_FANDRAWER = 6 +NUM_FANSPERDRAWER = 2 +NUM_FAN = NUM_FANDRAWER * NUM_FANSPERDRAWER +NUM_PSU = 2 +NUM_SFP = 34 +NUM_COMPONENT = 3 +CONFIG_DB_PATH = "/etc/sonic/config_db.json" + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + # List of SfpBase-derived objects representing all sfps + # available on the chassis + _sfp_list = None + + # Leds + PSULED = None + FANLED = None + + def __init__(self): + self._sfp_list = [] + + ChassisBase.__init__(self) + # initialize thermals + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + # initialize fans, fanled + Chassis.FANLED = FanLed() + for index in range(0, NUM_FANDRAWER): + fan_drawer = FanDrawer(index) + for i in range(0, NUM_FANSPERDRAWER): + fan_index = NUM_FANSPERDRAWER * index + i + fan = Fan(fan_index) + Chassis.FANLED.add_fan(fan) + fan_drawer._fan_list.append(fan) + self._fan_list.append(fan) + self._fan_drawer_list.append(fan_drawer) + Chassis.FANLED.update_status() + + # initialize psus, psuled + Chassis.PSULED = PsuLed() + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + Chassis.PSULED.add_psu(psu) + Chassis.PSULED.update_status() + + # initialize sfps + for index in range(0, NUM_SFP): + if (index < 32): + sfp = Sfp(index, 'QSFP') + else: + sfp = Sfp(index, 'SFP') + self._sfp_list.append(sfp) + + # initialize component + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + + def __read_config_db(self): + try: + with open(CONFIG_DB_PATH, 'r') as fd: + data = json.load(fd) + return data + except IOError: + raise IOError("Unable to open config_db file !") + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + try: + self.config_data = self.__read_config_db() + base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] + return str(base_mac) + except KeyError: + raise KeyError("Base MAC not found") + + ############################################## + # SFP methods + ############################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + + Returns: + An integer, the number of sfps available on this chassis + """ + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + return self._sfp_list + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + sfp = self._sfp_list[index] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list)-1)) + + return sfp + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + port_dict = {} + port = Sfp._port_start + + # Check for OIR events and return updated port_dict + reg_value = Sfp.get_presence_all() + if reg_value != Sfp.sfp_status: + changed_ports = Sfp.sfp_status ^ reg_value + while (port >= Sfp._port_start) and (port <= Sfp._port_end): + + # Mask off the bit corresponding to our port + mask = (1 << port) + + if changed_ports & mask: + # port presence is high + if (reg_value & mask) == mask: + port_dict[port] = SFP_STATUS_INSERTED + else: + port_dict[port] = SFP_STATUS_REMOVED + + port += 1 + + # Update reg value + self.sfp_status = reg_value + return True, port_dict + + def get_thermal_manager(self): + from .thermal_manager import ThermalManager + return ThermalManager + + @classmethod + def get_psuled(cls): + return cls.PSULED + + @classmethod + def get_fanled(cls): + return cls.FANLED diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/component.py new file mode 100755 index 00000000000..1b1d4ed72de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/component.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the component information (such as CPLD, FPGA, BIOS etc) which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3"] +COMPONENT_DES_LIST = ["Main board cpld 1 (0x60)", "Main board cpld 2 (0x62)", "Main board cpld 3 (0x64)"] + +class Alpha_Component(ComponentBase): + """Platform-specific Component class""" + + + def __init__(self, component_index): + self.index = component_index+1 + self.name = self.get_name() + self.cpld_path = "/sys/bus/i2c/devices/" + self.cpld_version = "/version" + self.cpld_mapping = { + 1: "18-0060", + 2: "12-0062", + 3: "19-0064", + } + + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_NAME_LIST[self.index-1] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_DES_LIST[self.index-1] + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + cpld_version = None + + if "CPLD" in self.name: + node = self.cpld_path + self.cpld_mapping[self.index] + self.cpld_version + try: + with open(node, 'r') as version: + cpld_version = version.read() + except IOError: + return None + + + cpld_version = cpld_version.rstrip() + + return cpld_version + + def install_firmware(self, image_path): + """ + Install firmware to module + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install successfully, False if not + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan.py new file mode 100755 index 00000000000..3cfa18fca0f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Alpha_Fan(FanBase): + """Platform-specific Fan class""" + + FAN_MOD_NAME = 'snj60b0_320f_fpga' + FAN_FRONT_RPM_MAX = 21000 + FAN_REAR_RPM_MAX = 19000 + FAN_SPEED_TOLERANCE_PERCENTAGE = 10 + NUM_FANTRAYS = 6 + FANS_PERTRAY = 2 + BASE_VAL_PATH = '/sys/bus/i2c/devices/0-005e/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/0-005e/fan_pwm' + + def __init__(self, fan_index): + self.index = fan_index + 1 + FanBase.__init__(self) + + self.fantray_index = (fan_index)/self.FANS_PERTRAY + 1 + self.fan_index_intray = self.index - ((self.fantray_index-1)*self.FANS_PERTRAY) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "FAN {}".format(self.index) + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = 0 + attr = 'fan' + str(self.fantray_index) + '_fault' + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as fault: + status = int(fault.read()) + except IOError as e: + print "Error: %s"%str(e) + return False + return False if (status > 0) else True + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + status = 0 + attr = 'fan' + str(self.fantray_index) + '_present' + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as presence_status: + status = int(presence_status.read()) + except IOError as e: + print "Error: %s"%str(e) + return None + return status == 1 + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = "" + attr = 'fan' + str(self.fantray_index) + '_direction' + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as fan_dir: + direction = int(fan_dir.read()) + except IOError as e: + print "Error: %s"%str(e) + return self.FAN_DIRECTION_INTAKE + if direction == 1: + return self.FAN_DIRECTION_INTAKE + + return self.FAN_DIRECTION_EXHAUST + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + frpm = 0 + attr = 'fan' + str(self.fantray_index) + '_{}_speed_rpm'.format('front' if (self.fan_index_intray==1) else 'rear') + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as speed: + frpm = int(speed.read()) + except IOError as e: + print "Error: %s"%str(e) + return 0 + + speed = 0 + if self.fan_index_intray == 1: + speed = (frpm * 100) / self.FAN_FRONT_RPM_MAX + else: + speed = (frpm * 100) / self.FAN_REAR_RPM_MAX + + if speed > 100: + speed = 100 + + return speed + + def get_speed_rpm(self): + """ + Retrieves the speed of fan in RPM + + Returns: + An integer, representing speed of the FAN in rpm + """ + frpm = 0 + attr = 'fan' + str(self.fantray_index) + '_{}_speed_rpm'.format('front' if (self.fan_index_intray==1) else 'rear') + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as speed: + frpm = int(speed.read()) + except IOError as e: + print "Error: %s"%str(e) + return 0 + + return frpm + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + duty = 0 + node = self.FAN_DUTY_PATH + try: + with open(node, 'r') as fan_duty: + duty = int(fan_duty.read()) + duty = duty * 100 / 255 + except IOError: + duty = 0 + return duty + + def set_speed(self, speed): + """ + Sets the fan speed + + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + + Returns: + A boolean, True if speed is set successfully, False if not + """ + if speed < 0 or speed > 100: + return False + + node = self.FAN_DUTY_PATH + speed = int(round(speed * 255.0 / 100)) + try: + with open(node, 'w') as fan_duty: + fan_duty.write(str(speed)) + except IOError: + return False + return True + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return self.FAN_SPEED_TOLERANCE_PERCENTAGE + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + + Args: + color: A string representing the color with which to set the + fan module status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + from .chassis import Chassis + fanled = Chassis.get_fanled() + return fanled.update_status() + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + from .chassis import Chassis + fanled = Chassis.get_fanled() + return fanled.get_status() diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan_drawer.py new file mode 100755 index 00000000000..cc22baf10b2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan_drawer.py @@ -0,0 +1,77 @@ +# +# fan_drawer_base.py +# +# Abstract base class for implementing a platform-specific class with which +# to interact with a fan drawer module in SONiC +# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Alpha_FanDrawer(FanDrawerBase): + """ + Abstract base class for interfacing with a fan drawer + """ + # Device type definition. Note, this is a constant. + DEVICE_TYPE = "fan_drawer" + FANS_PERDRAWER = 2 + + def __init__(self, index): + FanDrawerBase.__init__(self) + self.index = index + 1 + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + + return "drawer{}".format(self.index) + + def get_num_fans(self): + """ + Retrieves the number of fans available on this fan drawer + + Returns: + An integer, the number of fan modules available on this fan drawer + """ + return len(self._fan_list) + + def get_all_fans(self): + """ + Retrieves all fan modules available on this fan drawer + + Returns: + A list of objects derived from FanBase representing all fan + modules available on this fan drawer + """ + return self._fan_list + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + + Args: + color: A string representing the color with which to set the + fan drawer status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + # fan_drawer led not support + return True + + def get_status_led(self, color): + """ + Gets the state of the fan drawer LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + # fan_drawer led not support + return True diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/led.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/led.py new file mode 100755 index 00000000000..3a5e7d14728 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/led.py @@ -0,0 +1,94 @@ +import commands + +class Led(object): + STATUS_LED_COLOR_GREEN = "green" + STATUS_LED_COLOR_AMBER = "amber" + STATUS_LED_COLOR_OFF = "off" + + value_map = { + "on": 1, + "off": 0, + "faulty": 4 + } + color_map = { + 0: STATUS_LED_COLOR_OFF, + 1: STATUS_LED_COLOR_GREEN, + 4: STATUS_LED_COLOR_AMBER + } + + _path = '' + _psu_set = set() + _fan_set = set() + + def __init__(self): + # check i2c bus order + status, output = commands.getstatusoutput("i2cdetect -l | grep I801 | grep i2c-0") + if output: + # order 0 + self._path = "/sys/bus/i2c/devices/0-005e/" + else: + # order 1 + self._path = "/sys/bus/i2c/devices/1-005e/" + + def update_status(self): + value = self.get_status_value() + + try: + with open(self.led_path, 'w') as led: + led.write(str(value)) + except IOError: + return False + + return True + + def get_status(self): + status = 0 + try: + with open(self.led_path, 'r') as led: + status = int(led.read()) + except IOError: + return False + + return self.color_map[status] + + +class Alpha_PsuLed(Led): + def __init__(self): + super(Alpha_PsuLed, self).__init__() + self.led_path = self._path + "sys_pwr" + + def add_psu(self, psu): + self._psu_set.add(psu) + + def get_status_value(self): + status = self.value_map["faulty"] + from .chassis import NUM_PSU + if len(self._psu_set) == NUM_PSU: + is_power_all_OK = True + for psu in self._psu_set: + if not psu.get_presence() or not psu.get_status(): + is_power_all_OK = False + + status = self.value_map["on"] if is_power_all_OK else self.value_map["faulty"] + return status + + +class Alpha_FanLed(Led): + def __init__(self): + super(Alpha_FanLed, self).__init__() + self.led_path = self._path + "fan1_led" + + def add_fan(self, fan): + self._fan_set.add(fan) + + def get_status_value(self): + status = self.value_map["faulty"] + from .chassis import NUM_FAN + if len(self._fan_set) == NUM_FAN: + is_fan_all_OK = True + for fan in self._fan_set: + if not fan.get_status(): + is_fan_all_OK = False + + status = self.value_map["on"] if is_fan_all_OK else self.value_map["faulty"] + return status diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/platform.py new file mode 100755 index 00000000000..58f69ba409f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/platform.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/psu.py new file mode 100755 index 00000000000..1ab48bd8dc0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/psu.py @@ -0,0 +1,319 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSU status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform_base.fan_base import FanBase + from sonic_eeprom import eeprom_base +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class PsuFan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_index): + self.index = fan_index + 1 + self.psu_path = "/sys/bus/i2c/devices/" + self.psu_fan_rpm_max = 10000 + self.psu_fan_rpm = "/psu_fan1_speed_rpm" + if os.path.exists(self.psu_path + "9-0058"): + self.psu_pmbus_mapping = { + 1: "9-0058", + 2: "10-0059", + } + else: + self.psu_pmbus_mapping = { + 1: "32-0058", + 2: "33-0059", + } + FanBase.__init__(self) + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + rpm = 0 + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_fan_rpm + try: + with open(node, 'r') as speed_rpm: + rpm = int(speed_rpm.read()) + except IOError: + return 0 + return ((rpm * 100) / self.psu_fan_rpm_max) + + def get_speed_rpm(self): + """ + Retrieves the speed of fan in revolutions per monute + + Returns: + An integer, speed of a fan in RPM + """ + rpm = 0 + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_fan_rpm + try: + with open(node, 'r') as speed_rpm: + rpm = int(speed_rpm.read()) + except IOError: + return 0 + return (rpm) + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + # yesm1300am not support. + + return self.FAN_DIRECTION_EXHAUST + +class Alpha_Psu(PsuBase): + """Platform-specific PSU class""" + def __init__(self, psu_index): + PsuBase.__init__(self) + fan = PsuFan(psu_index) + self._fan_list.append(fan) + self.index = psu_index + 1 + self.psu_drv = "yesm1300am" + self.psu_path = "/sys/bus/i2c/devices/" + self.psu_presence = { + 1: "/psu1_present", + 2: "/psu2_present", + } + self.psu_oper_status = { + 1: "/psu1_power_good", + 2: "/psu2_power_good", + } + self.psu_model_name = "/psu_model_name" + self.psu_serial_num = "/psu_serial_num" + self.psu_mfr_id = "/psu_mfr_id" + self.psu_v_out = "/psu_v_out" + self.psu_i_out = "/psu_i_out" + + self._PSU_EEPROM_SERIAL_NUM_OFFSET = 0x35 + self._PSU_EEPROM_SERIAL_NUM_LENGTH = 19 + + self.psu_mapping = "0-005e" + if not os.path.exists(self.psu_path + self.psu_mapping): + self.psu_mapping = "1-005e" + + if os.path.exists(self.psu_path + "9-0050"): + self.psu_eeprom_mapping = { + 1: "9-0050", + 2: "10-0051", + } + self.psu_pmbus_mapping = { + 1: "9-0058", + 2: "10-0059", + } + self.psu_serial_num = "/eeprom" + else: + self.psu_eeprom_mapping = { + 1: "32-0050", + 2: "33-0051", + } + self.psu_pmbus_mapping = { + 1: "32-0058", + 2: "33-0059", + } + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "{}-i2c-{}".format(self.psu_drv, self.psu_pmbus_mapping[self.index]) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + status = 0 + node = self.psu_path + self.psu_mapping + self.psu_presence[self.index] + try: + with open(node, 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + return status == 1 + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = 0 + node = self.psu_path + self.psu_mapping + self.psu_oper_status[self.index] + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + return status == 1 + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + model = "" + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_model_name + try: + with open(node, 'r') as model_name: + model = model_name.read() + except IOError: + return None + return model.rstrip() + + def get_mfr_id(self): + """ + Retrieves the manufacturer's name (or id) of the device + + Returns: + string: Manufacturer's id of device + """ + mfr = "" + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_mfr_id + try: + with open(node, 'r') as mfr_id: + mfr = mfr_id.read() + except IOError: + return None + return mfr.rstrip() + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + serial = "" + node = self.psu_path + self.psu_eeprom_mapping[self.index] + self.psu_serial_num + if self.psu_serial_num == "/eeprom": + try: + psu_eeprom = eeprom_base.EepromDecoder(node, None, 0, '', True) + serial = psu_eeprom.read_eeprom_bytes(self._PSU_EEPROM_SERIAL_NUM_LENGTH, self._PSU_EEPROM_SERIAL_NUM_OFFSET) + if len(serial) != self._PSU_EEPROM_SERIAL_NUM_LENGTH: + return None + except IOError: + return None + else: + try: + with open(node, 'r') as serial_num: + serial = serial_num.read() + except IOError: + return None + + return serial.rstrip() + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + vout = 0 + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_v_out + try: + with open(node, 'r') as v_out: + vout = int(v_out.read()) + except IOError: + return 0 + return float(vout) / 1000 + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + iout = 0 + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_i_out + try: + with open(node, 'r') as i_out: + iout = int(i_out.read()) + except IOError: + return 0 + return float(iout) / 1000 + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + status = 0 + node = self.psu_path + self.psu_mapping + self.psu_oper_status[self.index] + try: + with open(node, 'r') as powergood_status: + status = int(powergood_status.read()) + except IOError: + return False + return status == 1 + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + # yesm1300am not support. + pout = 0 + + return pout + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + + Args: + color: A string representing the color with which to set the + PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + from .platform import Chassis + psuled = Chassis.get_psuled() + return psuled.update_status() + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + from .chassis import Chassis + psuled = Chassis.get_psuled() + return psuled.get_status() diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/sfp.py new file mode 100755 index 00000000000..1e9d16e2e02 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/sfp.py @@ -0,0 +1,925 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the SFP management routines +# +############################################################################# + +try: + import os.path + import time + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +# XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes','FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia','FibreChannelSpeed') + +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') + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +INFO_OFFSET = 128 +DOM_OFFSET = 0 +DOM_OFFSET1 = 384 + +CPLD_PORT_NUM = 8 +SFP_PATH = "/sys/bus/i2c/devices/{0}-005f" +SFPPLUS_PATH = "/sys/bus/i2c/devices/{0}-005e" +SFPPLUS_EEPROM_PATH = "/sys/bus/i2c/devices/{0}-0050" + +class Alpha_Sfp(SfpBase): + """Platform-specific Sfp class""" + _port_start = 0 + _port_end = 34 + + sfp_status = 0 + + port_to_eeprom = {} + + port_to_i2cbus_0 = { + 1 : 13, + 2 : 14, + 3 : 15, + 4 : 16, + 5 : 12, + 6 : 11, + } + + port_to_i2cbus_1 = { + 1 : 14, + 2 : 15, + 3 : 16, + 4 : 17, + 5 : 13, + 6 : 12, + } + + port_to_i2cbus_mapping = {} + + sfpplus_eeprom_path = SFPPLUS_EEPROM_PATH+"/sfp_eeprom" + eeprom_path = SFP_PATH+"/sfp{1}_eeprom" + port_reset_path = SFP_PATH+"/sfp{1}_port_reset" + present_path = SFP_PATH+"/sfp{1}_is_present" + sfpplus_present_path = SFPPLUS_PATH+"/sfp_present" + lpmode_path = SFP_PATH+"/sfp{1}_lpmode" + + # Read out any bytes from any offset + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + sysfsfile_eeprom = open(self.port_to_eeprom[self.index], mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except Exception as e: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __init__(self, sfp_index, sfp_type): + SfpBase.__init__(self) + self.index = sfp_index + + # index is 0-based + if sfp_index < self._port_start or sfp_index >= self._port_end: + print "Invalid port index %d"%sfp_index + return + + self.is_qsfp_port = True if (sfp_type=='QSFP' or sfp_type=='QSFP28') else False + self.is_osfp_port = True if (sfp_type=='OSFP' or sfp_type=='QSFP-DD') else False + self.is_sfp_port = True if (sfp_type=='SFP') else False + + path = self.present_path + port_path = path.format(self.port_to_i2cbus_0[1], 1) + if not os.path.exists(port_path): + self.port_to_i2cbus_mapping = self.port_to_i2cbus_1 + else: + self.port_to_i2cbus_mapping = self.port_to_i2cbus_0 + + index = (self.index % CPLD_PORT_NUM) + 1 + cpld_index = (self.index / CPLD_PORT_NUM) + 1 + if cpld_index == 5: + path = self.sfpplus_eeprom_path + if index == 1: + self.port_to_eeprom[self.index] = path.format(self.port_to_i2cbus_mapping[cpld_index]) + else: + self.port_to_eeprom[self.index] = path.format(self.port_to_i2cbus_mapping[cpld_index+1]) + else: + path = self.eeprom_path + self.port_to_eeprom[self.index] = path.format(self.port_to_i2cbus_mapping[cpld_index], index) + + self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + cpld_index = (self.index / CPLD_PORT_NUM) + 1 + index = (self.index % CPLD_PORT_NUM) + 1 + if cpld_index == 5: + path = self.sfpplus_present_path + port_path = path.format(0) + else: + path = self.present_path + port_path = path.format(self.port_to_i2cbus_mapping[cpld_index], index) + + try: + reg_file = open(port_path, 'r') + reg_value = int(reg_file.readline().rstrip(), 16) + reg_file.close() + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + if cpld_index == 5: + if reg_value == 3: + # SFP+ 1 and 0 is not present, 0 is present + reg_value = 0 + else: + if index == 1: + reg_value = (reg_value < 2) + else: + reg_value = ((reg_value % 2) == 0) + return reg_value + + def get_presence_all(self): + bitmap = "" + port = self._port_start + + while (port >= self._port_start) and (port <= self._port_end): + self.index = port + reg_value = self.get_presence() + + if reg_value: + bitmap += '1' + " " + else: + bitmap += '0' + " " + + port += 1 + + content = bitmap.split(" ") + content = "".join(content[::-1]) + + return int(content, 2) + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + mominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + + if self.is_osfp_port: + sfpi_obj = inf8628InterfaceId() + offset = 0 + type_offset = OSFP_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + hw_rev_offset = OSFP_HW_REV_OFFSET + vendor_name_offset = OSFP_VENDOR_NAME_OFFSET + vendor_pn_offset = OSFP_VENDOR_PN_OFFSET + vendor_sn_offset = OSFP_VENDOR_SN_OFFSET + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'OSFP' + + elif self.is_qsfp_port: + sfpi_obj = sff8436InterfaceId() + offset = 128 + type_offset = XCVR_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + hw_rev_offset = XCVR_HW_REV_OFFSET + vendor_name_offset = XCVR_VENDOR_NAME_OFFSET + vendor_pn_offset = XCVR_VENDOR_PN_OFFSET + vendor_sn_offset = XCVR_VENDOR_SN_OFFSET + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + else: + sfpi_obj = sff8472InterfaceId() + offset = 0 + type_offset = XCVR_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + hw_rev_offset = XCVR_HW_REV_OFFSET + vendor_name_offset = XCVR_VENDOR_NAME_OFFSET + vendor_pn_offset = XCVR_VENDOR_PN_OFFSET + vendor_sn_offset = XCVR_VENDOR_SN_OFFSET + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + if sfpi_obj is None: + return None + + + if self.is_osfp_port: + sfp_type_raw = self.__read_eeprom_specific_bytes((offset + type_offset), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + sfp_type_abbrv_name = sfpi_obj.parse_sfp_type_abbrv_name(sfp_typ_raw, 0) + else: + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((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) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((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) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((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) + + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_name_offset), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_pn_offset), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + hw_rev_offset), vendor_rev_width) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_sn_offset), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + xcvr_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + xcvr_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + xcvr_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + xcvr_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + xcvr_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + xcvr_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + xcvr_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + else: + xcvr_info_dict['type'] = sfp_type_data['data']['type']['value'] if sfp_type_data else 'N/A' + xcvr_info_dict['type_abbrv_name'] = sfp_type_abbrv_name['data']['type_abbrv_name']['value'] if sfp_type_abbrv_name else 'N/A' + + xcvr_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + xcvr_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + xcvr_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + xcvr_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + xcvr_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + xcvr_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + xcvr_info_dict['cable_type'] = "Unknown" + xcvr_info_dict['cable_length'] = "Unknown" + + if sfp_type == 'QSFP': + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + xcvr_info_dict['cable_type'] = key + xcvr_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in 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'] + xcvr_info_dict['specification_compliance'] = str(compliance_code_dict) + + nkey='Nominal Bit Rate(100Mbs)' + if nkey in sfp_interface_bulk_data['data']: + xcvr_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + xcvr_info_dict['nominal_bit_rate'] = 'N/A' + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + xcvr_info_dict['cable_type'] = key + xcvr_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in 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'] + xcvr_info_dict['specification_compliance'] = str(compliance_code_dict) + + xcvr_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return xcvr_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + RX LOS |BOOLEAN |RX lost-of-signal status, + | |True if has RX los, False if not. + TX FAULT |BOOLEAN |TX fault status, + | |True if has TX fault, False if not. + Reset status |BOOLEAN |reset status, + | |True if SFP in reset, False if not. + LP mode |BOOLEAN |low power mode status, + | |True in lp mode, False if not. + TX disable |BOOLEAN |TX disable status, + | |True TX disabled, False if not. + TX disabled channel |HEX |disabled TX channles in hex, + | |bits 0 to 3 represent channel 0 + | |to channel 3. + Temperature |INT |module temperature in Celsius + Voltage |INT |supply voltage in mV + TX bias |INT |TX Bias Current in mA + RX power |INT |received optical power in mW + TX power |INT |TX output power in mW + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + xcvr_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + + if self.is_osfp_port: + # Below part is added to avoid fail xcvrd, shall be implemented later + pass + elif self.is_qsfp_port: + # QSFPs + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (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( (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( (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( (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 + + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_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((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 + + xcvr_dom_info_dict['tx1power'] = 'N/A' + xcvr_dom_info_dict['tx2power'] = 'N/A' + xcvr_dom_info_dict['tx3power'] = 'N/A' + xcvr_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((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 + + + xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + xcvr_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + xcvr_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + xcvr_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + xcvr_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + xcvr_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + xcvr_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + xcvr_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + xcvr_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + xcvr_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + # SFPs + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( (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( (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( (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 + + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + xcvr_dom_info_dict['rx2power'] = 'N/A' + xcvr_dom_info_dict['rx3power'] = 'N/A' + xcvr_dom_info_dict['rx4power'] = 'N/A' + xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + xcvr_dom_info_dict['tx2bias'] = 'N/A' + xcvr_dom_info_dict['tx3bias'] = 'N/A' + xcvr_dom_info_dict['tx4bias'] = 'N/A' + xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + xcvr_dom_info_dict['tx2power'] = 'N/A' + xcvr_dom_info_dict['tx3power'] = 'N/A' + xcvr_dom_info_dict['tx4power'] = 'N/A' + + xcvr_dom_info_dict['rx_los'] = self.get_rx_los() + xcvr_dom_info_dict['tx_fault'] = self.get_tx_fault() + xcvr_dom_info_dict['reset_status'] = self.get_reset_status() + xcvr_dom_info_dict['lp_mode'] = self.get_lpmode() + + + return xcvr_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + xcvr_dom_threshold_info_dict = dict.fromkeys(self.threshold_dict_keys, 'N/A') + + if self.is_osfp_port: + # Below part is added to avoid fail xcvrd, shall be implemented later + pass + elif self.is_qsfp_port: + # QSFPs + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_thres_raw = self.__read_eeprom_specific_bytes(QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) + + if dom_thres_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values( + dom_thres_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + xcvr_dom_threshold_info_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + xcvr_dom_threshold_info_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + xcvr_dom_threshold_info_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + xcvr_dom_threshold_info_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + xcvr_dom_threshold_info_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + xcvr_dom_threshold_info_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + xcvr_dom_threshold_info_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + xcvr_dom_threshold_info_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_thres_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) + if dom_thres_raw: + channel_threshold_values = sfpd_obj.parse_channel_threshold_values( + dom_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + xcvr_dom_threshold_info_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerhighalarm'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerlowalarm'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerhighwarning'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerlowwarning'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + xcvr_dom_threshold_info_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + else: + # SFPs + sfpd_obj = sff8472Dom() + offset = 256 + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, offset) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + + xcvr_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + xcvr_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + xcvr_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + xcvr_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + xcvr_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + xcvr_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + xcvr_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + xcvr_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + xcvr_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + xcvr_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + + + return xcvr_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + + Returns: + A Boolean, True if reset enabled, False if disabled + """ + cpld_index = (self.index / CPLD_PORT_NUM) + 1 + index = (self.index % CPLD_PORT_NUM) + 1 + if cpld_index == 5: + # Not support reset for SFP+ + return True + + path = self.port_reset_path + port_path = path.format(self.port_to_i2cbus_mapping[cpld_index], index) + + try: + reg_file = open(port_path) + reg_value = int(reg_file.readline().rstrip(), 16) + + reg_file.close() + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + return reg_value + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = None + if not self.get_presence(): + return rx_los + + # read the values from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los = True if ((rx_los_data & 0xF) == 0xF) else False + else: + # SFP ports + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = None + if not self.get_presence(): + return tx_fault + + # read the values from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault = True if ((tx_fault_data & 0xF) == 0xF) else False + else: + # SFP + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + index = (self.index % 8) + i2c_index = (self.index / 8) + 1 + path = self.lpmode_path + if i2c_index == 5: + return False + else: + port_path = path.format(self.port_to_i2cbus_mapping[i2c_index], (index + 1)) + + try: + reg_file = open(port_path) + reg_value = int(reg_file.readline().rstrip(), 16) + + reg_file.close() + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + return reg_value + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + cpld_index = (self.index / CPLD_PORT_NUM) + 1 + index = (self.index % CPLD_PORT_NUM) + 1 + if cpld_index == 5: + # Not support reset for SFP+ + return True + else: + path = self.port_reset_path + port_path = path.format(self.port_to_i2cbus_mapping[cpld_index], index) + + try: + reg_file = open(port_path, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # reset + reg_file.write('1') + + time.sleep(1) + + reg_file.write('0') + + reg_file.close() + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + index = (self.index % 8) + i2c_index = (self.index / 8) + 1 + path = self.lpmode_path + if i2c_index == 5: + raise NotImplementedError + else: + port_path = path.format(self.port_to_i2cbus_mapping[i2c_index], (index + 1)) + + try: + reg_file = open(port_path, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + if lpmode == True: + reg_file.write('1') + else: + reg_file.write('0') + + reg_file.close() + return True diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal.py new file mode 100755 index 00000000000..bb6a7f4f708 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the thermal status which are available in the platform +# +############################################################################# + +import glob +import os.path + +try: + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Alpha_Thermal(ThermalBase): + """Platform-specific Thermal class""" + + temp_node_map = { + 1: "/sys/bus/i2c/devices/0-004f/hwmon/", + 2: "/sys/bus/i2c/devices/3-004d/hwmon/", + 3: "/sys/bus/i2c/devices/4-004c/hwmon/" + } + + temp_name_map = { + 1: "lm75-i2c-0-004f", + 2: "lm75-i2c-3-004d", + 3: "lm75-i2c-4-004c" + } + + _high_crital_threshold = 75 + _high_threshold = 60 + _low_threshold = 50 + + def __init__(self, temp_index): + self.index = temp_index + 1 + + if os.path.exists("/sys/bus/i2c/devices/3-004d/hwmon/") == False: + self.temp_node_map = { + 1: "/sys/bus/i2c/devices/0-004f/hwmon/", + 2: "/sys/bus/i2c/devices/18-004d/hwmon/", + 3: "/sys/bus/i2c/devices/19-004c/hwmon/" + } + + self.temp_name_map = { + 1: "lm75-i2c-0-004f", + 2: "lm75-i2c-18-004d", + 3: "lm75-i2c-19-004c" + } + + ThermalBase.__init__(self) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.temp_name_map[self.index] + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + if self.get_temperature() == -255: + return False + return True + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + node = glob.glob(self.temp_node_map[self.index] + "hwmon*") + if len(node) == 0: + return False + node = node[0] + "/temp1_input" + if os.path.exists(node): + return True + return False + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temp = 0 + node = glob.glob(self.temp_node_map[self.index] + "hwmon*") + if len(node) == 0: + return -255 + node = node[0] + "/temp1_input" + try: + with open(node, 'r') as fp: + temp = float(fp.read()) / 1000 + except IOError: + temp = -255 + return temp + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self._high_threshold + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self._low_threshold + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + self._high_threshold = temperature + return True + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + self._low_threshold = temperature + return True + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self._high_crital_threshold + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return 0 diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_actions.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_actions.py new file mode 100755 index 00000000000..480115ce878 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_actions.py @@ -0,0 +1,93 @@ +from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object +from sonic_daemon_base.daemon_base import Logger + +__all__ = [ +"SetAllFanSpeedMaxAction", +"SetAllFanSpeedDefaultAction", +"ThermalRecoverAction", +"SwitchPolicyAction", +] + +logger = Logger('alpha') + +class SetFanSpeedAction(ThermalPolicyActionBase): + """ + Base thermal action class to set speed for fans + """ + @classmethod + def set_all_fan_speed(cls, thermal_info_dict, speed): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] + for fan in fan_info_obj.get_presence_fans(): + fan.set_speed(speed) + + +@thermal_json_object('fan.all.set_speed_max') +class SetAllFanSpeedMaxAction(SetFanSpeedAction): + """ + Action to set max speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Set max speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + max_speed = 100 + SetAllFanSpeedMaxAction.set_all_fan_speed(thermal_info_dict, max_speed) + +@thermal_json_object('fan.all.set_speed_default') +class SetAllFanSpeedDefaultAction(SetFanSpeedAction): + """ + Action to set default speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Set default speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + default_speed = 50 + SetAllFanSpeedDefaultAction.set_all_fan_speed(thermal_info_dict, default_speed) + + +@thermal_json_object('thermal.temp_check_and_set_all_fan_speed') +class ThermalRecoverAction(SetFanSpeedAction): + """ + Action to check thermal sensor temperature change status and set speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Check check thermal sensor temperature change status and set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + default_speed = 50 + max_speed = 100 + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + thermal_info_obj = thermal_info_dict[ThermalInfo.INFO_NAME] + if thermal_info_obj.is_warm_up_and_over_high_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, max_speed) + elif thermal_info_obj.is_cold_down_and_below_low_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, default_speed) + + +@thermal_json_object('switch.shutdown') +class SwitchPolicyAction(ThermalPolicyActionBase): + """ + Base class for thermal action. Once all thermal conditions in a thermal policy are matched, + all predefined thermal action will be executed. + """ + def execute(self, thermal_info_dict): + """ + Take action when thermal condition matches. For example, adjust speed of fan or shut + down the switch. + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + logger.log_warning("Alarm for temperature critical is detected, reboot DUT") + # import os + # os.system('reboot') diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_conditions.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_conditions.py new file mode 100755 index 00000000000..4fa22eac0e5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_conditions.py @@ -0,0 +1,77 @@ +from sonic_platform_base.sonic_thermal_control.thermal_condition_base import ThermalPolicyConditionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + +__all__ = [ +"AnyFanAbsenceCondition", +"AllFanAbsenceCondition", +"AllFanPresenceCondition", +"AnyFanFaultCondition", +"AllFanGoodCondition", +"AnyFanPresenceChangeCondition", +"ThermalOverHighCriticalCondition", +] + +class FanCondition(ThermalPolicyConditionBase): + def get_fan_info(self, thermal_info_dict): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + return thermal_info_dict[FanInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('fan.any.absence') +class AnyFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.absence') +class AllFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_presence_fans()) == 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.presence') +class AllFanPresenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) == 0 if fan_info_obj else False + + +@thermal_json_object('fan.any.fault') +class AnyFanFaultCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.good') +class AllFanGoodCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) == 0 if fan_info_obj else False + +@thermal_json_object('fan.any.presence.change') +class AnyFanPresenceChangeCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return fan_info_obj.is_presence_changed() if fan_info_obj else False + + +class ThermalCondition(ThermalPolicyConditionBase): + def get_thermal_info(self, thermal_info_dict): + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + return thermal_info_dict[ThermalInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('thermal.over.high_critical_threshold') +class ThermalOverHighCriticalCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + return thermal_info_obj.is_over_high_critical_threshold() if thermal_info_obj else False diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_infos.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_infos.py new file mode 100755 index 00000000000..308180273dc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_infos.py @@ -0,0 +1,183 @@ +from sonic_platform_base.sonic_thermal_control.thermal_info_base import ThermalPolicyInfoBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + +__all__ = [ +"FanInfo", +"ThermalInfo", +"ChassisInfo", +] + +@thermal_json_object('fan_info') +class FanInfo(ThermalPolicyInfoBase): + """ + Fan information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'fan_info' + + def __init__(self): + self._absence_fans = set() + self._presence_fans = set() + self._fault_fans = set() + self._presence_changed = False + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence fans. + :param chassis: The chassis object + :return: + """ + self._presence_changed = False + self._status_changed = False + for fan in chassis.get_all_fans(): + presence = fan.get_presence() + status = fan.get_status() + if presence and fan not in self._presence_fans: + self._presence_fans.add(fan) + self._presence_changed = True + if fan in self._absence_fans: + self._absence_fans.remove(fan) + elif not presence and fan not in self._absence_fans: + self._absence_fans.add(fan) + self._presence_changed = True + if fan in self._presence_fans: + self._presence_fans.remove(fan) + + if not status and fan not in self._fault_fans: + self._fault_fans.add(fan) + self._status_changed = True + elif status and fan in self._fault_fans: + self._fault_fans.remove(fan) + self._status_changed = True + + + def get_absence_fans(self): + """ + Retrieves absence fans + :return: A set of absence fans + """ + return self._absence_fans + + def get_presence_fans(self): + """ + Retrieves presence fans + :return: A set of presence fans + """ + return self._presence_fans + + def get_fault_fans(self): + """ + Retrieves fault fans + :return: A set of fault fans + """ + return self._fault_fans + + def is_presence_changed(self): + """ + Retrieves if the presence status of fan information changed + :return: True if status changed else False + """ + return self._presence_changed + + +@thermal_json_object('thermal_info') +class ThermalInfo(ThermalPolicyInfoBase): + """ + Thermal information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'thermal_info' + + def __init__(self): + + self.init = False + self._old_avg_temp = 0 + self._current_avg_temp = 0 + self._high_crital_threshold = 75 + self._high_threshold = 60 + self._low_threshold = 50 + self._thermal_0x4d_index = 1 + + def collect(self, chassis): + """ + Collect thermal sensor temperature change status + :param chassis: The chassis object + :return: + """ + + self._temps = [] + self._over_high_critical_threshold = False + self._warm_up_and_over_high_threshold = False + self._cold_down_and_below_low_threshold = False + + temp = 0 + num_of_thermals = chassis.get_num_thermals() + for index in range(num_of_thermals): + self._temps.insert(index, chassis.get_thermal(index).get_temperature()) + temp += self._temps[index] + + self._current_avg_temp = temp / num_of_thermals + if self.init == False: + self._old_avg_temp = self._current_avg_temp + self.init = True + + if self._current_avg_temp >= self._old_avg_temp and self._current_avg_temp >= self._high_threshold: + self._warm_up_and_over_high_threshold = True + + if self._current_avg_temp <= self._old_avg_temp and self._current_avg_temp <= self._low_threshold: + self._cold_down_and_below_low_threshold = True + + if self._temps[self._thermal_0x4d_index] >= self._high_crital_threshold: + self._over_high_critical_threshold = True + + self._old_avg_temp = self._current_avg_temp + + def is_warm_up_and_over_high_threshold(self): + """ + Retrieves if the temperature is warm up and over high threshold + :return: True if the temperature is warm up and over high threshold else False + """ + return self._warm_up_and_over_high_threshold + + def is_cold_down_and_below_low_threshold(self): + """ + Retrieves if the temperature is cold down and below low threshold + :return: True if the temperature is cold down and below low threshold else False + """ + return self._cold_down_and_below_low_threshold + + def is_over_high_critical_threshold(self): + """ + Retrieves if the temperature is over high critical threshold + :return: True if the temperature is over high critical threshold else False + """ + return self._over_high_critical_threshold + + +@thermal_json_object('chassis_info') +class ChassisInfo(ThermalPolicyInfoBase): + """ + Chassis information needed by thermal policy + """ + INFO_NAME = 'chassis_info' + + def __init__(self): + self._chassis = None + + def collect(self, chassis): + """ + Collect platform chassis. + :param chassis: The chassis object + :return: + """ + self._chassis = chassis + + def get_chassis(self): + """ + Retrieves platform chassis object + :return: A platform chassis object. + """ + return self._chassis diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_manager.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_manager.py new file mode 100755 index 00000000000..c062256576d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_manager.py @@ -0,0 +1,23 @@ +from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from .thermal_infos import * # lgtm[py/polluting-import] +from .thermal_conditions import * # lgtm[py/polluting-import] +from .thermal_actions import * # lgtm[py/polluting-import] + +class ThermalManager(ThermalManagerBase): + @classmethod + def initialize(cls): + """ + Initialize thermal manager, including register thermal condition types and thermal action types + and any other vendor specific initialization. + :return: + """ + return True + + @classmethod + def deinitialize(cls): + """ + Destroy thermal manager, including any vendor specific cleanup. The default behavior of this function + is a no-op. + :return: + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/utils/alphanetworks_snj60b0_util.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/utils/alphanetworks_snj60b0_util.py new file mode 100755 index 00000000000..06bb7a6f079 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/utils/alphanetworks_snj60b0_util.py @@ -0,0 +1,521 @@ +#!/usr/bin/env python +# +# Copyright (C) 2019 Alphanetworks Technology Corporation. +# Robin Chen +# 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 +# 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. +# see +# +# 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 . + +""" +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 +""" + +import commands +import sys, getopt +import logging +import time + + +PROJECT_NAME = 'snj60b0-320f' +DRIVER_NAME = 'snj60b0_320f' +device_path = "x86_64-alphanetworks_snj60b0_320f-r0" +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +FORCE = 0 + +devMaxPort = 34 +cpldPortNum = 8 + +FPGAAddr = "005e" +PortCPLD_Addr = "005f" + +portFPGAAddr = "0x5e" +portCPLDAddr = "0x5f" +portAddr = "0x50" + +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() + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_log(txt): + if DEBUG == True: + print PROJECT_NAME.upper()+": "+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + show_log (cmd +" with result: " + str(status)) + show_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 " + DRIVER_NAME, 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ +'modprobe i2c_ismt', +'modprobe i2c_i801', +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x', +'modprobe optoe', +'modprobe yesm1300am', +'modprobe '+PROJECT_NAME+'_fpga' , +'modprobe '+PROJECT_NAME+'_onie_eeprom' , +'modprobe '+PROJECT_NAME+'_sfp' ] + +def driver_install(): + global FORCE + status, output = log_os_system("depmod", 1) + if status: + if FORCE == 0: + return status + for i in range(0,len(kos)): + if kos[i].find('pca954') != -1: + status, output = log_os_system(kos[i]+ " force_deselect_on_exit=1", 1) + else: + 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 + +i2c_prefix = '/sys/bus/i2c/devices/' + +sfp_map = [13,14,15,16,12,11] +sfp_map2 = [14,15,16,17,13,12] + +mknod =[ +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9545 0x71 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-7/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-20/new_device', +'echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-9/new_device', +'echo 24c02 0x51 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo snj60b0_onie_eeprom 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo snj60b0_fpga 0x5e > /sys/bus/i2c/devices/i2c-0/new_device', +'echo lm75 0x4D > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4C > /sys/bus/i2c/devices/i2c-4/new_device', +'echo lm75 0x4F > /sys/bus/i2c/devices/i2c-0/new_device', +'echo yesm1300am 0x58 > /sys/bus/i2c/devices/i2c-9/new_device', +'echo yesm1300am 0x59 > /sys/bus/i2c/devices/i2c-10/new_device' ] + +mknod2 =[ +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9545 0x71 > /sys/bus/i2c/devices/i2c-6/new_device', +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-8/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-21/new_device', +'echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo 24c02 0x51 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo snj60b0_onie_eeprom 0x56 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo snj60b0_fpga 0x5e > /sys/bus/i2c/devices/i2c-1/new_device', +'echo lm75 0x4D > /sys/bus/i2c/devices/i2c-4/new_device', +'echo lm75 0x4C > /sys/bus/i2c/devices/i2c-5/new_device', +'echo lm75 0x4F > /sys/bus/i2c/devices/i2c-1/new_device', +'echo yesm1300am 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo yesm1300am 0x59 > /sys/bus/i2c/devices/i2c-11/new_device' ] + + + +def i2c_order_check(): + # i2c bus 0 and 1 might be installed in different order. + # Here check if 0x76 is exist @ i2c-0 + + status, output = log_os_system("i2cdetect -l | grep I801 | grep i2c-0", 0) + if not output: + order = 1 + tmp = "sed -i 's/0-/1-/g' /usr/share/sonic/device/"+device_path+"/plugins/led_control.py" + else: + order = 0 + tmp = "sed -i 's/1-/0-/g' /usr/share/sonic/device/"+device_path+"/plugins/led_control.py" + status, output = log_os_system(tmp, 0) + if status: + print output + if FORCE == 0: + return status + return order + +def device_install(): + global FORCE + global devMaxPort + global cpldPortNum + + order = i2c_order_check() + + # if 0x76 is not exist @i2c-0, use reversed bus order + if order: + for i in range(0,len(mknod2)): + #for pca954x need times to built new i2c buses + if mknod2[i].find('pca954') != -1: + time.sleep(1) + + if mknod2[i].find('lm75') != -1: + time.sleep(1) + + status, output = log_os_system(mknod2[i], 1) + if status: + print output + if FORCE == 0: + return status + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/1-"+FPGAAddr+"/sys_reset1", 1) + if status: + print output + if FORCE == 0: + return status + + status, output =log_os_system("echo 4 > /sys/bus/i2c/devices/1-"+FPGAAddr+"/sys_reset2", 1) + if status: + print output + if FORCE == 0: + return status + else: + 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) + + if mknod[i].find('lm75') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/0-"+FPGAAddr+"/sys_reset1", 1) + if status: + print output + if FORCE == 0: + return status + + status, output =log_os_system("echo 4 > /sys/bus/i2c/devices/0-"+FPGAAddr+"/sys_reset2", 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0, devMaxPort): + index = i / cpldPortNum + port = i % cpldPortNum + reg_sfp = 0 + if port == 0: + reg_sfp = 1 + +# Port CPLD and FPGA device add + if reg_sfp == 1: + if i < 32: + if order: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portCPLDAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/new_device", 1) + else: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portCPLDAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status +# Front port EEPROM device add + if order: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/new_device", 1) + else: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + +# Port EEPROM device add + if i == 32: + if order: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/new_device", 1) + else: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/new_device", 1) + + if status: + print output + if FORCE == 0: + return status + if i == 33: + if order: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index+1])+"/new_device", 1) + else: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index+1])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status +# Front port LED enable + if order: + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/1-"+FPGAAddr+"/port_led_disable", 1) + else: + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/0-"+FPGAAddr+"/port_led_disable", 1) + if status: + print output + if FORCE == 0: + return status + + if order: + for i in [0,1,2,3]: + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/"+str(sfp_map2[i])+"-"+PortCPLD_Addr+"/sfp_led_disable", 1) + if status: + if FORCE == 0: + return status + else: + for i in [0,1,2,3]: + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-"+PortCPLD_Addr+"/sfp_led_disable", 1) + if status: + if FORCE == 0: + return status +# end of Front port LED enable + + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0070", 0) + if status==0: + I2C_ORDER=1 + else: + I2C_ORDER=0 + +# Front port LED disable + if I2C_ORDER: + status, output =log_os_system("echo 1 > /sys/bus/i2c/devices/1-"+FPGAAddr+"/port_led_disable", 1) + else: + status, output =log_os_system("echo 1 > /sys/bus/i2c/devices/0-"+FPGAAddr+"/port_led_disable", 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER: + for i in [0,1,2,3]: + status, output =log_os_system("echo 1 > /sys/bus/i2c/devices/"+str(sfp_map2[i])+"-"+PortCPLD_Addr+"/sfp_led_disable", 1) + if status: + if FORCE == 0: + return status + else: + for i in [0,1,2,3]: + status, output =log_os_system("echo 1 > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-"+PortCPLD_Addr+"/sfp_led_disable", 1) + if status: + if FORCE == 0: + return status +# end of Front port LED disable + + + for i in range(0, devMaxPort): + index = i / cpldPortNum + port = i % cpldPortNum + reg_sfp = 0 + if port == 0: + reg_sfp = 1 + + if reg_sfp == 1: + if i < 32: + if I2C_ORDER: + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/delete_device" + else: + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/delete_device" + status, output =log_os_system("echo "+portCPLDAddr+" > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER: + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/delete_device" + else: + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/delete_device" + status, output =log_os_system("echo "+portAddr+" > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if i == 32: + if I2C_ORDER: + status, output =log_os_system("echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/delete_device", 1) + else: + status, output =log_os_system("echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/delete_device", 1) + if status: + print output + if FORCE == 0: + return status + if i == 33: + if I2C_ORDER: + status, output =log_os_system("echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index+1])+"/delete_device", 1) + else: + status, output =log_os_system("echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index+1])+"/delete_device", 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER: + nodelist = mknod2 + else: + 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 device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0070", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main()