diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers.json.j2 b/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers_defaults_def.j2 b/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers_defaults_def.j2 new file mode 100644 index 000000000000..740cfdf79e96 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers_defaults_def.j2 @@ -0,0 +1,46 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "xoff": "4625920", + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers_defaults_t0.j2 b/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..44fcf21887a6 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers_defaults_t1.j2 b/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..740cfdf79e96 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "xoff": "4625920", + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/hwsku.json b/device/celestica/x86_64-cel_ds3000-r0/DS3000/hwsku.json new file mode 100644 index 000000000000..28e50b8c0385 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/hwsku.json @@ -0,0 +1,169 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet128": { + "default_brkout_mode": "1x10G", + "autoneg": "off", + "fec": "none" + } + } +} diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/l2/config b/device/celestica/x86_64-cel_ds3000-r0/DS3000/l2/config new file mode 100644 index 000000000000..45a7b84d5032 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/l2/config @@ -0,0 +1,3 @@ +l2_mem_entries=139264 +l3_mem_entries=8192 +l3_alpm_enable=0 diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/l3/config b/device/celestica/x86_64-cel_ds3000-r0/DS3000/l3/config new file mode 100644 index 000000000000..3467c1b39716 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/l3/config @@ -0,0 +1,3 @@ +l2_mem_entries=40000 +l3_mem_entries=40000 +l3_alpm_enable=2 diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/pg_profile_lookup.ini b/device/celestica/x86_64-cel_ds3000-r0/DS3000/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/platform-def.json b/device/celestica/x86_64-cel_ds3000-r0/DS3000/platform-def.json new file mode 100644 index 000000000000..1b3dbaa9c4b2 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/platform-def.json @@ -0,0 +1,26 @@ +{ + "fec-mode": { + "Ethernet0-127": { + "1": { + "10000": [ "none", "fc" ], + "25000": [ "none", "fc" ] + }, + "2": { + "20000": [ "none", "fc" ], + "50000": [ "none", "rs" ] + }, + "4": { + "40000": [ "none", "fc" ], + "100000": [ "none", "rs" ] + } + } + }, + "native-port-supported-speeds": { + "Ethernet0-127": { + "4": ["100000","40000"] + }, + "Ethernet128-128": { + "1": ["100000","1000"] + } + } +} diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/port_config.ini b/device/celestica/x86_64-cel_ds3000-r0/DS3000/port_config.ini new file mode 100644 index 000000000000..ce9e5a2c1f85 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/port_config.ini @@ -0,0 +1,34 @@ +# name lanes alias index speed valid_speeds +Ethernet0 1,2,3,4 QSFP1 1 100000 100000,40000 +Ethernet4 5,6,7,8 QSFP2 2 100000 100000,40000 +Ethernet8 9,10,11,12 QSFP3 3 100000 100000,40000 +Ethernet12 13,14,15,16 QSFP4 4 100000 100000,40000 +Ethernet16 17,18,19,20 QSFP5 5 100000 100000,40000 +Ethernet20 21,22,23,24 QSFP6 6 100000 100000,40000 +Ethernet24 25,26,27,28 QSFP7 7 100000 100000,40000 +Ethernet28 29,30,31,32 QSFP8 8 100000 100000,40000 +Ethernet32 33,34,35,36 QSFP9 9 100000 100000,40000 +Ethernet36 37,38,39,40 QSFP10 10 100000 100000,40000 +Ethernet40 41,42,43,44 QSFP11 11 100000 100000,40000 +Ethernet44 45,46,47,48 QSFP12 12 100000 100000,40000 +Ethernet48 49,50,51,52 QSFP13 13 100000 100000,40000 +Ethernet52 53,54,55,56 QSFP14 14 100000 100000,40000 +Ethernet56 57,58,59,60 QSFP15 15 100000 100000,40000 +Ethernet60 61,62,63,64 QSFP16 16 100000 100000,40000 +Ethernet64 65,66,67,68 QSFP17 17 100000 100000,40000 +Ethernet68 69,70,71,72 QSFP18 18 100000 100000,40000 +Ethernet72 73,74,75,76 QSFP19 19 100000 100000,40000 +Ethernet76 77,78,79,80 QSFP20 20 100000 100000,40000 +Ethernet80 81,82,83,84 QSFP21 21 100000 100000,40000 +Ethernet84 85,86,87,88 QSFP22 22 100000 100000,40000 +Ethernet88 89,90,91,92 QSFP23 23 100000 100000,40000 +Ethernet92 93,94,95,96 QSFP24 24 100000 100000,40000 +Ethernet96 97,98,99,100 QSFP25 25 100000 100000,40000 +Ethernet100 101,102,103,104 QSFP26 26 100000 100000,40000 +Ethernet104 105,106,107,108 QSFP27 27 100000 100000,40000 +Ethernet108 109,110,111,112 QSFP28 28 100000 100000,40000 +Ethernet112 113,114,115,116 QSFP29 29 100000 100000,40000 +Ethernet116 117,118,119,120 QSFP30 30 100000 100000,40000 +Ethernet120 121,122,123,124 QSFP31 31 100000 100000,40000 +Ethernet124 125,126,127,128 QSFP32 32 100000 100000,40000 +Ethernet128 129 SFP1 33 10000 10000,1000 diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/qos.json.j2 b/device/celestica/x86_64-cel_ds3000-r0/DS3000/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/sai.profile b/device/celestica/x86_64-cel_ds3000-r0/DS3000/sai.profile new file mode 100644 index 000000000000..992e6ba1f49a --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ds3000-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_ds3000-r0/DS3000/td3-ds3000-32x100G.config.bcm b/device/celestica/x86_64-cel_ds3000-r0/DS3000/td3-ds3000-32x100G.config.bcm new file mode 100644 index 000000000000..943a47dea5e7 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/DS3000/td3-ds3000-32x100G.config.bcm @@ -0,0 +1,580 @@ +help_cli_enable=1 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=0x1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_max_ecmp_mode=1 +l3_mem_entries=32768 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l3_alpm_enable=2 +#lpm_scaling_enable=1 +max_vp_lags=0 +#mem_cache_enable=0 +memlist_enable=1 +reglist_enable=1 +#scache_filename=/tmp/scache +schan_intr_enable=0 +stable_size=0x5500000 +tdma_timeout_usec=3000000 +miim_intr_enable=0 +module_64ports=1 +oversubscribe_mode=1 +parity_enable=0 +serdes_lane_config_dfe=on +#serdes_fec_enable=1 +serdes_if_type_ce=14 +pbmp_gport_stack.0=0x0000000000000000000000000000000000000000000000000000000000000000 +pbmp_xport_xe=0x3ffffffffffffffffffffffffffffffffe +port_flex_enable=1 +fpem_mem_entries=32768 + +#Tunnels +bcm_tunnel_term_compatible_mode=1 +sai_tunnel_support=1 +use_all_splithorizon_groups=1 + +#RIOT Enable +riot_enable=1 +riot_overlay_l3_intf_mem_size=8192 +riot_overlay_l3_egress_mem_size=32768 +l3_ecmp_levels=2 +riot_overlay_ecmp_resilient_hash_size=16384 +flow_init_mode=1 + +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 +phy_an_c73=1 + +portmap_1=1:100 +portmap_5=5:100 +portmap_9=9:100 +portmap_13=13:100 +portmap_17=17:100 +portmap_21=21:100 +portmap_25=25:100 +portmap_29=29:100 +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:100 +portmap_45=45:100 +portmap_49=49:100 +portmap_53=53:100 +portmap_57=57:100 +portmap_61=61:100 +portmap_67=65:100 +portmap_71=69:100 +portmap_75=73:100 +portmap_79=77:100 +portmap_83=81:100 +portmap_87=85:100 +portmap_91=89:100 +portmap_95=93:100 +portmap_99=97:100 +portmap_103=101:100 +portmap_107=105:100 +portmap_111=109:100 +portmap_115=113:100 +portmap_119=117:100 +portmap_123=121:100 +portmap_127=125:100 +portmap_66=129:10:m +#portmap_130=128:10:m + +#wc0 lane swap +phy_chain_tx_lane_map_physical{1.0}=0x0132 +phy_chain_rx_lane_map_physical{1.0}=0x3210 + +#wc1 lane swap +phy_chain_tx_lane_map_physical{5.0}=0x2301 +phy_chain_rx_lane_map_physical{5.0}=0x2031 + +#wc2 lane swap +phy_chain_tx_lane_map_physical{9.0}=0x0132 +phy_chain_rx_lane_map_physical{9.0}=0x3210 + +#wc3 lane swap +phy_chain_tx_lane_map_physical{13.0}=0x3201 +phy_chain_rx_lane_map_physical{13.0}=0x2031 + +#wc4 lane swap +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x3210 + +#wc5 lane swap +phy_chain_tx_lane_map_physical{21.0}=0x2301 +phy_chain_rx_lane_map_physical{21.0}=0x2031 + +#wc6 lane swap +phy_chain_tx_lane_map_physical{25.0}=0x0123 +phy_chain_rx_lane_map_physical{25.0}=0x3210 + +#wc7 lane swap +phy_chain_tx_lane_map_physical{29.0}=0x3201 +phy_chain_rx_lane_map_physical{29.0}=0x2031 + +#wc8 lane swap +phy_chain_tx_lane_map_physical{33.0}=0x0213 +phy_chain_rx_lane_map_physical{33.0}=0x1302 + +#wc9 lane swap +phy_chain_tx_lane_map_physical{37.0}=0x1302 +phy_chain_rx_lane_map_physical{37.0}=0x2031 + +#wc10 lane swap +phy_chain_tx_lane_map_physical{41.0}=0x0231 +phy_chain_rx_lane_map_physical{41.0}=0x3120 + +#wc11 lane swap +phy_chain_tx_lane_map_physical{45.0}=0x1302 +phy_chain_rx_lane_map_physical{45.0}=0x2031 + +#wc12 lane swap +phy_chain_tx_lane_map_physical{49.0}=0x2103 +phy_chain_rx_lane_map_physical{49.0}=0x3120 + +#wc13 lane swap +phy_chain_tx_lane_map_physical{53.0}=0x2301 +phy_chain_rx_lane_map_physical{53.0}=0x2031 + +#wc14 lane swap +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x2301 + +#wc15 lane swap +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1032 + +#wc16 lane swap +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x1023 + +#wc17 lane swap +phy_chain_tx_lane_map_physical{69.0}=0x0123 +phy_chain_rx_lane_map_physical{69.0}=0x1302 + +#wc18 lane swap +phy_chain_tx_lane_map_physical{73.0}=0x2301 +phy_chain_rx_lane_map_physical{73.0}=0x1032 + +#wc19 lane swap +phy_chain_tx_lane_map_physical{77.0}=0x2013 +phy_chain_rx_lane_map_physical{77.0}=0x3120 + +#wc20 lane swap +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_rx_lane_map_physical{81.0}=0x2031 + +#wc21 lane swap +phy_chain_tx_lane_map_physical{85.0}=0x0123 +phy_chain_rx_lane_map_physical{85.0}=0x2130 + +#wc22 lane swap +phy_chain_tx_lane_map_physical{89.0}=0x2301 +phy_chain_rx_lane_map_physical{89.0}=0x2031 + +#wc23 lane swap +phy_chain_tx_lane_map_physical{93.0}=0x0312 +phy_chain_rx_lane_map_physical{93.0}=0x2310 + +#wc24 lane swap +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x1032 + +#wc25 lane swap +phy_chain_tx_lane_map_physical{101.0}=0x0123 +phy_chain_rx_lane_map_physical{101.0}=0x3210 + +#wc26 lane swap +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x1032 + +#wc27 lane swap +phy_chain_tx_lane_map_physical{109.0}=0x0123 +phy_chain_rx_lane_map_physical{109.0}=0x3210 + +#wc28 lane swap +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2031 + +#wc29 lane swap +phy_chain_tx_lane_map_physical{117.0}=0x0123 +phy_chain_rx_lane_map_physical{117.0}=0x3210 + +#wc30 lane swap +phy_chain_tx_lane_map_physical{121.0}=0x2301 +phy_chain_rx_lane_map_physical{121.0}=0x1032 + +#wc31 lane swap +phy_chain_tx_lane_map_physical{125.0}=0x0123 +phy_chain_rx_lane_map_physical{125.0}=0x3210 + +#MC lane swap +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{129.0}=0x3210 + + +#wc0 P/N flip +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 + +#wc1 P/N flip +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 + +#wc2 P/N flip +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 + +#wc3 P/N flip +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 + +#wc4 P/N flip +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 + +#wc5 P/N flip +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 + +#wc6 P/N flip +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 + +#wc7 P/N flip +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 + +#wc8 P/N flip +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 + +#wc9 P/N flip +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 + +#wc10 P/N flip +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 + +#wc11 P/N flip +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 + +#wc12 P/N flip +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 + +#wc13 P/N flip +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 + +#wc14 P/N flip +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 + +#wc15 P/N flip +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 + +#wc16 P/N flip +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 + +#wc17 P/N flip +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 + +#wc18 P/N flip +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 + +#wc19 P/N flip +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 + +#wc20 P/N flip +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 + +#wc21 P/N flip +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 + +#wc22 P/N flip +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 + +#wc23 P/N flip +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 + +#wc24 P/N flip +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 + +#wc25 P/N flip +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 + +#wc26 P/N flip +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 + +#wc27 P/N flip +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 + +#wc28 P/N flip +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 + +#wc29 P/N flip +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 + +#wc30 P/N flip +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 + +#wc31 P/N flip +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +#MC P/N flip +phy_chain_tx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 + + +# configuration for 100G optical module +serdes_preemphasis_1=0x164608 +serdes_preemphasis_5=0x164608 +serdes_preemphasis_9=0x164608 +serdes_preemphasis_13=0x134908 +serdes_preemphasis_17=0x134908 +serdes_preemphasis_21=0x134908 +serdes_preemphasis_25=0x124a08 +serdes_preemphasis_29=0x124a08 +serdes_preemphasis_33=0x114b08 +serdes_preemphasis_37=0x114b08 +serdes_preemphasis_41=0x0f4d08 +serdes_preemphasis_45=0x0f4d08 +serdes_preemphasis_49=0x0d4f08 +serdes_preemphasis_53=0x0d4f08 +serdes_preemphasis_57=0x0d4f08 +serdes_preemphasis_61=0x0d4f08 +serdes_preemphasis_67=0x0d4f08 +serdes_preemphasis_71=0x0d4f08 +serdes_preemphasis_75=0x0d4f08 +serdes_preemphasis_79=0x0d4f08 +serdes_preemphasis_83=0x0d4f08 +serdes_preemphasis_87=0x0f4d08 +serdes_preemphasis_91=0x0f4d08 +serdes_preemphasis_95=0x0f4d08 +serdes_preemphasis_99=0x114b08 +serdes_preemphasis_103=0x114b08 +serdes_preemphasis_107=0x114b08 +serdes_preemphasis_111=0x124a08 +serdes_preemphasis_115=0x134908 +serdes_preemphasis_119=0x134908 +serdes_preemphasis_123=0x134908 +serdes_preemphasis_127=0x164608 diff --git a/device/celestica/x86_64-cel_ds3000-r0/custom_led.bin b/device/celestica/x86_64-cel_ds3000-r0/custom_led.bin new file mode 100644 index 000000000000..3fb048fce6b5 Binary files /dev/null and b/device/celestica/x86_64-cel_ds3000-r0/custom_led.bin differ diff --git a/device/celestica/x86_64-cel_ds3000-r0/default_sku b/device/celestica/x86_64-cel_ds3000-r0/default_sku new file mode 100644 index 000000000000..dbfb3ae8e6b9 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/default_sku @@ -0,0 +1 @@ +DS3000 t1 diff --git a/device/celestica/x86_64-cel_ds3000-r0/installer.conf b/device/celestica/x86_64-cel_ds3000-r0/installer.conf new file mode 100644 index 000000000000..6e8098123edb --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_DEV=0 +CONSOLE_PORT=0xe060 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_iommu=off noirqdebug earlycon=uart8250,mmio,0xdf37b000" diff --git a/device/celestica/x86_64-cel_ds3000-r0/led_proc_init.soc b/device/celestica/x86_64-cel_ds3000-r0/led_proc_init.soc new file mode 100644 index 000000000000..90aa9ba607ac --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/led_proc_init.soc @@ -0,0 +1,2 @@ +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on; led start diff --git a/device/celestica/x86_64-cel_ds3000-r0/pcie.yaml b/device/celestica/x86_64-cel_ds3000-r0/pcie.yaml new file mode 100644 index 000000000000..2b9612671602 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/pcie.yaml @@ -0,0 +1,165 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1980' + name: 'Host bridge: Intel Corporation Atom Processor C3000 Series System Agent (rev + 11)' +- bus: '00' + dev: '04' + fn: '0' + id: 19a1 + name: 'Host bridge: Intel Corporation Atom Processor C3000 Series Error Registers + (rev 11)' +- bus: '00' + dev: '05' + fn: '0' + id: 19a2 + name: 'Generic system peripheral [0807]: Intel Corporation Atom Processor C3000 + Series Root Complex Event Collector (rev 11)' +- bus: '00' + dev: '06' + fn: '0' + id: 19a3 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated QAT + Root Port (rev 11)' +- bus: '00' + dev: 09 + fn: '0' + id: 19a4 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #0 (rev 11)' +- bus: '00' + dev: 0b + fn: '0' + id: 19a6 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #2 (rev 11)' +- bus: '00' + dev: 0c + fn: '0' + id: 19a7 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #3 (rev 11)' +- bus: '00' + dev: 0e + fn: '0' + id: 19a8 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #4 (rev 11)' +- bus: '00' + dev: '10' + fn: '0' + id: 19aa + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #6 (rev 11)' +- bus: '00' + dev: '12' + fn: '0' + id: 19ac + name: 'System peripheral: Intel Corporation Atom Processor C3000 Series SMBus Contoller + - Host (rev 11)' +- bus: '00' + dev: '14' + fn: '0' + id: 19c2 + name: 'SATA controller: Intel Corporation Atom Processor C3000 Series SATA Controller + 1 (rev 11)' +- bus: '00' + dev: '15' + fn: '0' + id: 19d0 + name: 'USB controller: Intel Corporation Atom Processor C3000 Series USB 3.0 xHCI + Controller (rev 11)' +- bus: '00' + dev: '16' + fn: '0' + id: 19d1 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated LAN + Root Port #0 (rev 11)' +- bus: '00' + dev: '18' + fn: '0' + id: 19d3 + name: 'Communication controller: Intel Corporation Atom Processor C3000 Series ME + HECI 1 (rev 11)' +- bus: '00' + dev: 1a + fn: '0' + id: 19d8 + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' +- bus: '00' + dev: 1a + fn: '1' + id: 19d8 + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' +- bus: '00' + dev: 1a + fn: '2' + id: 19d8 + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' +- bus: '00' + dev: 1c + fn: '0' + id: 19db + name: 'SD Host controller: Intel Corporation Device 19db (rev 11)' +- bus: '00' + dev: 1f + fn: '0' + id: 19dc + name: 'ISA bridge: Intel Corporation Atom Processor C3000 Series LPC or eSPI (rev + 11)' +- bus: '00' + dev: 1f + fn: '2' + id: 19de + name: 'Memory controller: Intel Corporation Atom Processor C3000 Series Power Management + Controller (rev 11)' +- bus: '00' + dev: 1f + fn: '4' + id: 19df + name: 'SMBus: Intel Corporation Atom Processor C3000 Series SMBus controller (rev + 11)' +- bus: '00' + dev: 1f + fn: '5' + id: 19e0 + name: 'Serial bus controller [0c80]: Intel Corporation Atom Processor C3000 Series + SPI Controller (rev 11)' +- bus: '01' + dev: '00' + fn: '0' + id: 19e2 + name: 'Co-processor: Intel Corporation Atom Processor C3000 Series QuickAssist Technology + (rev 11)' +- bus: '02' + dev: '00' + fn: '0' + id: b870 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b870 (rev 01)' +- bus: '03' + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: '06' + dev: '00' + fn: '0' + id: '7021' + name: 'Memory controller: Xilinx Corporation Device 7021' +- bus: '07' + dev: '00' + fn: '0' + id: 15c2 + name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane + (rev 11)' +- bus: '07' + dev: '00' + fn: '1' + id: 15c2 + name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane + (rev 11)' diff --git a/device/celestica/x86_64-cel_ds3000-r0/pddf/pd-plugin.json b/device/celestica/x86_64-cel_ds3000-r0/pddf/pd-plugin.json new file mode 100644 index 000000000000..46fd80ac4b2c --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/pddf/pd-plugin.json @@ -0,0 +1,91 @@ +{ + "PSU": + { + "psu_present": + { + "bmc": + { + "valmap": { "1":true, "0":false } + }, + "i2c": + { + "valmap": { "1":true, "0":false } + } + }, + + "psu_power_good": + { + "bmc": + { + "valmap": { "0": true, "8":false } + }, + "i2c": + { + "valmap": { "1": true, "0": false } + } + }, + + "psu_fan_dir": + { + "bmc": + { + "valmap": { "B2F":"INTAKE", "F2B":"EXHAUST" } + }, + "i2c": + { + "valmap": { "0": "INTAKE", "1":"EXHAUST" } + } + }, + + "psu_led_color": + { + "colmap": {"green":"green", "red":"amber"} + }, + + "PSU_FAN_MAX_SPEED":"18000" + }, + + "FAN": + { + "direction": + { + "bmc": + { + "valmap": { "B2F":"INTAKE", "F2B":"EXHAUST" } + }, + "i2c": + { + "valmap": { "1":"INTAKE", "0":"EXHAUST" } + } + }, + + "present": + { + "bmc": + { + "valmap": {"1":true, "0":false} + }, + "bmc": + { + "valmap": {"ok":true, "na":false} + }, + "i2c": + { + "valmap": {"0":true, "1":false} + } + }, + + "fan_master_led_color": + { + "colmap": {"green":"green", "red":"amber"} + }, + + "duty_cycle_to_pwm": "lambda dc: ((dc*255.0)/100)", + + "pwm_to_duty_cycle": "lambda pwm: ((pwm*100.0)/256)", + + "FRONT_FAN_MAX_RPM_SPEED":"24000", + "REAR_FAN_MAX_RPM_SPEED":"21000" + } + +} diff --git a/device/celestica/x86_64-cel_ds3000-r0/pddf/pddf-device-bmc.json b/device/celestica/x86_64-cel_ds3000-r0/pddf/pddf-device-bmc.json new file mode 100644 index 000000000000..73d23156c53b --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/pddf/pddf-device-bmc.json @@ -0,0 +1,2125 @@ +{ +"PLATFORM": +{ + "num_psus":2, + "num_fantrays":4, + "num_fans_pertray":2, + "num_ports":33, + "num_temps":9, + "num_components":9, + "pddf_dev_types": + { + "description":" - Below is the list of supported PDDF device types (chip names) for various components. If any component uses some other driver, we will create the client using 'echo > /new_device' method", + "CPLD": + [ + "i2c_cpld" + ], + "PSU": + [ + "psu_eeprom", + "psu_pmbus" + ], + "FAN": + [ + "fan_ctrl" + ], + "PORT_MODULE": + [ + "pddf_xcvr" + ], + "FPGAPCIE": + [ + "fpgapci" + ] + + }, + "std_perm_kos": + [ + "i2c_ismt", + "i2c-i801" + ], + + "std_kos": + [ + "lpc_ich", + "i2c_dev", + "ipmi_devintf", + "ipmi_si", + "i2c_mux_pca954x", + "optoe", + "mc24lc64t", + "baseboard_cpld" + ], + + "pddf_kos": + [ + "pddf_client_module", + "pddf_cpld_module", + "pddf_cpld_driver", + "pddf_mux_module", + "pddf_led_module", + "pddf_fpgai2c_module", + "pddf_fpgai2c_driver", + "pddf_xcvr_module", + "pddf_xcvr_driver_module", + "pddf_fpgapci_driver", + "pddf_fpgapci_module" + ], + + "custom_kos": + [ + "pddf_custom_fpga_algo" + ] + }, + + "COMPONENT1": + { + "comp_attr":{ "name": "BIOS", "type": "bios", "description": "Basic Input/Output System"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "echo `dmidecode -s bios-version`-`dmidecode -s bios-release-date`" }, + { "attr_name":"update", "cmd": "afulnx_64 {} /p /b /n /me /x /k" } + ] + }, + "COMPONENT2": + { + "comp_attr":{ "name": "BMC", "type": "bmc", "description":"Baseboard Management Controller "}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=(`ipmitool raw 0x6 0x1 | cut -d ' ' -f 4,5,16,15,14`) && echo ${r[0]}.${r[1]}.${r[4]}.${r[3]}${r[2]}" } + ] + }, + "COMPONENT3": + { + "comp_attr":{ "name": "BaseBoard_CPLD", "type": "cpld", "description": "Base Board CPLD"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(cat /sys/devices/platform/baseboard/version) && printf '%d.%d' $(($r>>4)) $(($r&0xf))" }, + { "attr_name":"update", "cmd": "ispvm {}" } + ] + }, + "COMPONENT4": + { + "comp_attr":{ "name": "SwitchBoard_CPLD1", "type": "cpld", "description":"Switch Board CPLD"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(i2cget -y -f 102 0x30 0) && printf '%d.%d' $(($r>>4)) $(($r&0xf))" } + ] + }, + "COMPONENT5": + { + "comp_attr":{ "name": "SwitchBoard_CPLD2", "type": "cpld", "description":"Switch Board CPLD"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(i2cget -y -f 102 0x31 0) && printf '%d.%d' $(($r>>4)) $(($r&0xf))" } + ] + }, + "COMPONENT6": + { + "comp_attr":{ "name": "COMeBoard_CPLD", "type": "cpld", "description": "COMe Board CPLD"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(cat /sys/devices/platform/baseboard/come_cpld_version) && printf '%d.%d' $(($r>>4)) $(($r&0xf))" } + ] + }, + "COMPONENT7": + { + "comp_attr":{ "name": "FPGA", "type": "fpga", "description": "Baseboard FPGA"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(cat /sys/devices/platform/fpga_sysfs/version) && printf '%d.%d' $(($r>>16)) $(($r&0xffff))" }, + { "attr_name":"update", "cmd": "fpga_prog /sys/bus/pci/devices/0000:06:00.0/resource0 {}" } + ] + }, + "COMPONENT8": + { + "comp_attr":{ "name": "PCIe", "type": "pcie", "description":"ASIC PCIe Firmware"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "bcmcmd 'pciephy fw version' | grep 'PCIe FW version' | cut -d ' ' -f 4" } + ] + }, + "COMPONENT9": + { + "comp_attr":{ "name": "SSD", "type": "ssd", "description":"SSD firmware version"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "ssdutil -v | grep 'Firmware' | awk '{ print $3 }'" } + ] + }, + + "SYSTEM": + { + "dev_info": {"device_type":"CPU", "device_name":"ROOT_COMPLEX", "device_parent":null}, + "i2c": + { + "CONTROLLERS": + [ + { "dev_name":"i2c-0", "dev":"SMBUS0" }, + { "dev_name":"i2c-1", "dev":"SMBUS1" }, + { "dev_name":"pcie-0", "dev":"PCIE0" } + ] + } + }, + + "SMBUS0": + { + "dev_info": {"device_type": "SMBUS", "device_name": "SMBUS0", "device_parent": "SYSTEM"}, + "i2c": + { + "topo_info": {"dev_addr": "0x0"}, + "DEVICES": + [ + {"dev": "EEPROM1"} + ] + } + }, + + "EEPROM1": + { + "dev_info": {"device_type": "EEPROM", "device_name": "EEPROM1", "device_parent": "SMBUS0"}, + "i2c": + { + "topo_info": {"parent_bus": "0x0", "dev_addr": "0x56", "dev_type": "24lc64t"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + + "SMBUS1": + { + "dev_info": {"device_type": "SMBUS", "device_name": "SMBUS1", "device_parent": "SYSTEM"}, + "i2c": + { + "topo_info": {"dev_addr": "0x1"}, + "DEVICES": + [ + {"dev": "COME_CPLD"} + ] + } + }, + + "COME_CPLD": + { + "dev_info": {"device_type": "CPLD", "device_name": "COME_CPLD", "device_parent": "SMBUS1"}, + "i2c": + { + "topo_info": {"parent_bus": "0x1", "dev_addr": "0x0d", "dev_type": "i2c_cpld"}, + "dev_attr": {} + } + }, + + "PCIE0": + { + "dev_info": {"device_type": "PCIE", "device_name": "PCIE0", "device_parent": "SYSTEM"}, + "i2c": + { + "DEVICES": + [ + {"dev": "FPGAPCIE0"} + ] + } + }, + + "FPGAPCIE0": + { + "dev_info": {"device_type": "FPGAPCIE", "device_name": "FPGAPCIE0", "device_parent": "PCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x0"}, + "dev_attr": { "vendor_id":"0x10EE", "device_id": "0x7021", "virt_bus": "0x64", "data_base_offset":"0x0", "data_size":"0x25000", "i2c_ch_base_offset":"0x10000", "i2c_ch_size":"0x1000", "virt_i2c_ch":"0xc"}, + "channel": + [ + { "chn":"3", "dev":"CPLD_S1" }, + { "chn":"3", "dev":"CPLD_S2" }, + { "chn":"2", "dev":"MUX1" }, + { "chn":"2", "dev":"MUX2" }, + { "chn":"2", "dev":"MUX3" }, + { "chn":"2", "dev":"MUX4" }, + { "chn":"1", "dev":"MUX5" } + ] + } + }, + + "CPLD_S1": + { + "dev_info": { "device_type":"CPLD", "device_name":"CPLD_S1", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x66", "dev_addr":"0x30", "dev_type":"i2c_cpld"}, + "dev_attr":{} + } + }, + + "CPLD_S2": + { + "dev_info": { "device_type":"CPLD", "device_name":"CPLD_S2", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x66", "dev_addr":"0x31", "dev_type":"i2c_cpld"}, + "dev_attr":{} + } + }, + + "MUX1": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX1", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x65", "dev_addr":"0x72", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x2", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"PORT1" }, + { "chn":"1", "dev":"PORT2" }, + { "chn":"2", "dev":"PORT3" }, + { "chn":"3", "dev":"PORT4" }, + { "chn":"4", "dev":"PORT5" }, + { "chn":"5", "dev":"PORT6" }, + { "chn":"6", "dev":"PORT7" }, + { "chn":"7", "dev":"PORT8" } + ] + } + }, + + "MUX2": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX2", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x65", "dev_addr":"0x73", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0xa", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"PORT9" }, + { "chn":"1", "dev":"PORT10" }, + { "chn":"2", "dev":"PORT11" }, + { "chn":"3", "dev":"PORT12" }, + { "chn":"4", "dev":"PORT13" }, + { "chn":"5", "dev":"PORT14" }, + { "chn":"6", "dev":"PORT15" }, + { "chn":"7", "dev":"PORT16" } + ] + } + }, + + "MUX3": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX3", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x65", "dev_addr":"0x74", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x12", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"PORT17" }, + { "chn":"1", "dev":"PORT18" }, + { "chn":"2", "dev":"PORT19" }, + { "chn":"3", "dev":"PORT20" }, + { "chn":"4", "dev":"PORT21" }, + { "chn":"5", "dev":"PORT22" }, + { "chn":"6", "dev":"PORT23" }, + { "chn":"7", "dev":"PORT24" } + ] + } + }, + + "MUX4": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX4", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x65", "dev_addr":"0x75", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x1a", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"PORT25" }, + { "chn":"1", "dev":"PORT26" }, + { "chn":"2", "dev":"PORT27" }, + { "chn":"3", "dev":"PORT28" }, + { "chn":"4", "dev":"PORT29" }, + { "chn":"5", "dev":"PORT30" }, + { "chn":"6", "dev":"PORT31" }, + { "chn":"7", "dev":"PORT32" } + ] + } + }, + "MUX5": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX5", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x64", "dev_addr":"0x72", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x22"}, + "channel": + [ + { "chn":"0", "dev":"PORT33" } + ] + } + }, + + "PORT1": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT1", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"1"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT1-EEPROM" }, + { "itf":"control", "dev":"PORT1-CTRL" } + + ] + } + }, + "PORT1-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT1-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT1"}, + "i2c": + { + "topo_info": { "parent_bus":"0x2", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + "PORT1-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT1-CTRL", "device_parent":"MUX1", "virt_parent":"PORT1"}, + "i2c": + { + "topo_info": { "parent_bus":"0x2", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + "PORT2": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT2", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"2"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT2-EEPROM" }, + { "itf":"control", "dev":"PORT2-CTRL" } + ] + } + }, + + "PORT2-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT2-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT2"}, + "i2c": + { + "topo_info": { "parent_bus":"0x3", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT2-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT2-CTRL", "device_parent":"MUX1", "virt_parent":"PORT2"}, + "i2c": + { + "topo_info": { "parent_bus":"0x3", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x10", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x10", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x10", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x10", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT3": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT3", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"3"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT3-EEPROM" }, + { "itf":"control", "dev":"PORT3-CTRL" } + ] + } + }, + "PORT3-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT3-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT3"}, + "i2c": + { + "topo_info": { "parent_bus":"0x4", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT3-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT3-CTRL", "device_parent":"MUX1", "virt_parent":"PORT3"}, + "i2c": + { + "topo_info": { "parent_bus":"0x4", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x20", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x20", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x20", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x20", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT4": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT4", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"4"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT4-EEPROM" }, + { "itf":"control", "dev":"PORT4-CTRL" } + ] + } + }, + "PORT4-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT4-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT4"}, + "i2c": + { + "topo_info": { "parent_bus":"0x5", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT4-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT4-CTRL", "device_parent":"MUX1", "virt_parent":"PORT4"}, + "i2c": + { + "topo_info": { "parent_bus":"0x5", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x30", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x30", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x30", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x30", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT5": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT5", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"5"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT5-EEPROM" }, + { "itf":"control", "dev":"PORT5-CTRL" } + ] + } + }, + + "PORT5-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT5-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT5"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT5-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT5-CTRL", "device_parent":"MUX1", "virt_parent":"PORT5"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x40", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x40", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x40", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x40", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT6": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT6", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"6"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT6-EEPROM" }, + { "itf":"control", "dev":"PORT6-CTRL" } + ] + } + }, + "PORT6-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT6-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT6"}, + "i2c": + { + "topo_info": { "parent_bus":"0x7", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT6-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT6-CTRL", "device_parent":"MUX1", "virt_parent":"PORT6"}, + "i2c": + { + "topo_info": { "parent_bus":"0x7", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x50", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x50", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x50", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x50", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT7": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT7", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"7"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT7-EEPROM" }, + { "itf":"control", "dev":"PORT7-CTRL" } + ] + } + }, + "PORT7-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT7-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT7"}, + "i2c": + { + "topo_info": { "parent_bus":"0x8", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT7-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT7-CTRL", "device_parent":"MUX1", "virt_parent":"PORT7"}, + "i2c": + { + "topo_info": { "parent_bus":"0x8", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x60", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x60", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x60", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x60", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT8": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT8", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"8"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT8-EEPROM" }, + { "itf":"control", "dev":"PORT8-CTRL" } + ] + } + }, + "PORT8-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT8-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT8"}, + "i2c": + { + "topo_info": { "parent_bus":"0x9", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT8-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT8-CTRL", "device_parent":"MUX1", "virt_parent":"PORT8"}, + "i2c": + { + "topo_info": { "parent_bus":"0x9", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x70", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x70", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x70", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x70", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT9": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT9", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"9"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT9-EEPROM" }, + { "itf":"control", "dev":"PORT9-CTRL" } + ] + } + }, + "PORT9-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT9-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT9"}, + "i2c": + { + "topo_info": { "parent_bus":"0xa", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT9-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT9-CTRL", "device_parent":"MUX2", "virt_parent":"PORT9"}, + "i2c": + { + "topo_info": { "parent_bus":"0xa", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x80", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x80", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x80", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x80", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT10": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT10", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"10"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT10-EEPROM" }, + { "itf":"control", "dev":"PORT10-CTRL" } + ] + } + }, + "PORT10-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT10-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT10"}, + "i2c": + { + "topo_info": { "parent_bus":"0xb", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT10-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT10-CTRL", "device_parent":"MUX2", "virt_parent":"PORT10"}, + "i2c": + { + "topo_info": { "parent_bus":"0xb", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x90", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x90", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x90", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x90", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT11": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT11", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"11"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT11-EEPROM" }, + { "itf":"control", "dev":"PORT11-CTRL" } + ] + } + }, + "PORT11-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT11-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT11"}, + "i2c": + { + "topo_info": { "parent_bus":"0xc", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT11-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT11-CTRL", "device_parent":"MUX2", "virt_parent":"PORT11"}, + "i2c": + { + "topo_info": { "parent_bus":"0xc", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xa0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xa0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xa0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xa0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT12": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT12", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"12"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT12-EEPROM" }, + { "itf":"control", "dev":"PORT12-CTRL" } + ] + } + }, + "PORT12-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT12-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT12"}, + "i2c": + { + "topo_info": { "parent_bus":"0xd", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT12-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT12-CTRL", "device_parent":"MUX2", "virt_parent":"PORT12"}, + "i2c": + { + "topo_info": { "parent_bus":"0xd", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xb0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xb0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xb0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xb0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT13": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT13", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"13"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT13-EEPROM" }, + { "itf":"control", "dev":"PORT13-CTRL" } + ] + } + }, + "PORT13-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT13-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT13"}, + "i2c": + { + "topo_info": { "parent_bus":"0xe", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT13-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT13-CTRL", "device_parent":"MUX2", "virt_parent":"PORT13"}, + "i2c": + { + "topo_info": { "parent_bus":"0xe", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xc0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xc0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xc0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xc0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT14": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT14", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"14"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT14-EEPROM" }, + { "itf":"control", "dev":"PORT14-CTRL" } + ] + } + }, + "PORT14-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT14-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT14"}, + "i2c": + { + "topo_info": { "parent_bus":"0xF", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT14-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT14-CTRL", "device_parent":"MUX2", "virt_parent":"PORT14"}, + "i2c": + { + "topo_info": { "parent_bus":"0xf", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xd0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xd0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xd0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xd0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT15": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT15", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"15"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT15-EEPROM" }, + { "itf":"control", "dev":"PORT15-CTRL" } + ] + } + }, + "PORT15-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT15-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT15"}, + "i2c": + { + "topo_info": { "parent_bus":"0x10", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT15-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT15-CTRL", "device_parent":"MUX2", "virt_parent":"PORT15"}, + "i2c": + { + "topo_info": { "parent_bus":"0x10", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xe0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xe0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xe0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xe0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT16": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT16", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"16"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT16-EEPROM" }, + { "itf":"control", "dev":"PORT16-CTRL" } + ] + } + }, + "PORT16-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT16-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT16"}, + "i2c": + { + "topo_info": { "parent_bus":"0x11", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT16-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT16-CTRL", "device_parent":"MUX2", "virt_parent":"PORT16"}, + "i2c": + { + "topo_info": { "parent_bus":"0x11", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xf0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xf0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xf0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xf0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT17": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT17", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"17"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT17-EEPROM" }, + { "itf":"control", "dev":"PORT17-CTRL" } + ] + } + }, + "PORT17-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT17-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT17"}, + "i2c": + { + "topo_info": { "parent_bus":"0x12", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT17-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT17-CTRL", "device_parent":"MUX3", "virt_parent":"PORT17"}, + "i2c": + { + "topo_info": { "parent_bus":"0x12", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x100", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x100", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x100", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x100", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT18": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT18", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"18"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT18-EEPROM" }, + { "itf":"control", "dev":"PORT18-CTRL" } + ] + } + }, + "PORT18-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT18-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT18"}, + "i2c": + { + "topo_info": { "parent_bus":"0x13", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT18-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT18-CTRL", "device_parent":"MUX3", "virt_parent":"PORT18"}, + "i2c": + { + "topo_info": { "parent_bus":"0x13", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x110", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x110", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x110", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x110", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT19": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT19", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"19"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT19-EEPROM" }, + { "itf":"control", "dev":"PORT19-CTRL" } + ] + } + }, + "PORT19-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT19-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT19"}, + "i2c": + { + "topo_info": { "parent_bus":"0x14", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT19-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT19-CTRL", "device_parent":"MUX3", "virt_parent":"PORT19"}, + "i2c": + { + "topo_info": { "parent_bus":"0x14", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x120", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x120", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x120", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x120", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT20": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT20", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"20"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT20-EEPROM" }, + { "itf":"control", "dev":"PORT20-CTRL" } + ] + } + }, + "PORT20-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT20-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT20"}, + "i2c": + { + "topo_info": { "parent_bus":"0x15", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT20-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT20-CTRL", "device_parent":"MUX3", "virt_parent":"PORT20"}, + "i2c": + { + "topo_info": { "parent_bus":"0x15", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x130", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x130", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x130", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x130", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT21": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT21", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"21"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT21-EEPROM" }, + { "itf":"control", "dev":"PORT21-CTRL" } + ] + } + }, + "PORT21-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT21-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT21"}, + "i2c": + { + "topo_info": { "parent_bus":"0x16", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT21-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT21-CTRL", "device_parent":"MUX3", "virt_parent":"PORT21"}, + "i2c": + { + "topo_info": { "parent_bus":"0x16", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x140", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x140", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x140", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x140", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT22": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT22", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"22"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT22-EEPROM" }, + { "itf":"control", "dev":"PORT22-CTRL" } + ] + } + }, + "PORT22-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT22-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT22"}, + "i2c": + { + "topo_info": { "parent_bus":"0x17", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT22-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT22-CTRL", "device_parent":"MUX3", "virt_parent":"PORT22"}, + "i2c": + { + "topo_info": { "parent_bus":"0x17", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x150", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x150", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x150", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x150", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT23": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT23", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"23"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT23-EEPROM" }, + { "itf":"control", "dev":"PORT23-CTRL" } + ] + } + }, + "PORT23-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT23-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT23"}, + "i2c": + { + "topo_info": { "parent_bus":"0x18", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT23-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT23-CTRL", "device_parent":"MUX3", "virt_parent":"PORT23"}, + "i2c": + { + "topo_info": { "parent_bus":"0x18", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x160", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x160", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x160", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x160", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT24": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT24", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"24"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT24-EEPROM" }, + { "itf":"control", "dev":"PORT24-CTRL" } + ] + } + }, + "PORT24-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT24-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT24"}, + "i2c": + { + "topo_info": { "parent_bus":"0x19", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT24-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT24-CTRL", "device_parent":"MUX3", "virt_parent":"PORT24"}, + "i2c": + { + "topo_info": { "parent_bus":"0x19", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x170", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x170", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x170", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x170", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT25": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT25", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"25"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT25-EEPROM" }, + { "itf":"control", "dev":"PORT25-CTRL" } + ] + } + }, + "PORT25-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT25-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT25"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1a", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT25-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT25-CTRL", "device_parent":"MUX4", "virt_parent":"PORT25"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1a", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x180", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x180", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x180", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x180", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT26": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT26", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"26"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT26-EEPROM" }, + { "itf":"control", "dev":"PORT26-CTRL" } + ] + } + }, + "PORT26-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT26-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT26"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1b", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT26-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT26-CTRL", "device_parent":"MUX4", "virt_parent":"PORT26"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1b", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x190", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x190", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x190", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x190", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT27": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT27", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"27"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT27-EEPROM" }, + { "itf":"control", "dev":"PORT27-CTRL" } + ] + } + }, + "PORT27-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT27-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT27"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1c", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT27-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT27-CTRL", "device_parent":"MUX4", "virt_parent":"PORT27"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1c", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1a0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1a0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1a0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1a0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT28": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT28", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"28"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT28-EEPROM" }, + { "itf":"control", "dev":"PORT28-CTRL" } + ] + } + }, + "PORT28-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT28-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT28"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1d", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT28-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT28-CTRL", "device_parent":"MUX4", "virt_parent":"PORT28"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1d", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1b0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1b0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1b0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1b0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT29": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT29", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"29"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT29-EEPROM" }, + { "itf":"control", "dev":"PORT29-CTRL" } + ] + } + }, + "PORT29-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT29-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT29"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1e", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT29-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT29-CTRL", "device_parent":"MUX4", "virt_parent":"PORT29"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1e", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1c0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1c0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1c0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1c0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT30": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT30", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"30"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT30-EEPROM" }, + { "itf":"control", "dev":"PORT30-CTRL" } + ] + } + }, + "PORT30-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT30-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT30"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1f", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT30-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT30-CTRL", "device_parent":"MUX4", "virt_parent":"PORT30"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1f", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1d0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1d0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1d0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1d0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT31": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT31", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"31"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT31-EEPROM" }, + { "itf":"control", "dev":"PORT31-CTRL" } + ] + } + }, + "PORT31-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT31-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT31"}, + "i2c": + { + "topo_info": { "parent_bus":"0x20", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT31-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT31-CTRL", "device_parent":"MUX4", "virt_parent":"PORT31"}, + "i2c": + { + "topo_info": { "parent_bus":"0x20", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1e0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1e0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1e0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1e0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT32": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT32", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"32"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT32-EEPROM" }, + { "itf":"control", "dev":"PORT32-CTRL" } + ] + } + }, + "PORT32-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT32-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT32"}, + "i2c": + { + "topo_info": { "parent_bus":"0x21", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT32-CTRL": + { + "dev_info": { "device_type":"pci", "device_name":"PORT32-CTRL", "device_parent":"MUX4", "virt_parent":"PORT32"}, + "i2c": + { + "topo_info": { "parent_bus":"0x21", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1f0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1f0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1f0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1f0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT33": + { + "dev_info": { "device_type":"SFP+", "device_name":"PORT33", "device_parent":"MUX5"}, + "dev_attr": { "dev_idx":"33"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT33-EEPROM" }, + { "itf":"control", "dev":"PORT33-CTRL" } + ] + } + }, + "PORT33-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT33-EEPROM", "device_parent":"MUX5", "virt_parent":"PORT33"}, + "i2c": + { + "topo_info": { "parent_bus":"0x22", "dev_addr":"0x50", "dev_type":"optoe2"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT33-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT33-CTRL", "device_parent":"MUX5", "virt_parent":"PORT33"}, + "i2c": + { + "topo_info": { "parent_bus":"0x22", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x0", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_txfault", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x2", "attr_cmpval":"0x4", "attr_len":"1"}, + { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x0", "attr_cmpval":"0x1", "attr_len":"1"}, + { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x0", "attr_cmpval":"0x1", "attr_len":"1"} + ] + } + }, + + "PSU1": + { + "dev_info": { "device_type":"PSU"}, + "dev_attr": { "dev_idx":"1", "num_psu_fans": "1"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"psu_power_good", "bmc_cmd":"ipmitool raw 0x04 0x2d 0x0f | awk '{print substr($0,9,1)}'", "raw": "1", "type":"mask", "mask":"0x8"}, + { "attr_name":"psu_present", "bmc_cmd":"ipmitool raw 0x04 0x2d 0x0f | awk '{print substr($0,9,1)}'", "raw": "1", "type":"mask", "mask":"0x1"}, + { "attr_name":"psu_model_name", "bmc_cmd":"ipmitool fru print 3", "raw": "0", "field_name":"Product Name", "separator":": ","field_pos":"2"}, + { "attr_name":"psu_serial_num", "bmc_cmd":"ipmitool fru print 3", "raw": "0", "field_name":"Product Serial", "separator":": ","field_pos":"2"}, + { "attr_name":"psu_mfr_id", "bmc_cmd":"ipmitool fru print 3", "raw": "0", "field_name":"Product Manufacturer", "separator":":", "field_pos":"2"}, + { "attr_name":"psu_p_out", "bmc_cmd":"ipmitool sdr", "raw": "0", "field_name":"PSU1_POut", "field_pos":"3", "mult":"1000000"}, + { "attr_name":"psu_v_out", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU1_VOut", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_i_out", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU1_COut", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_p_in", "bmc_cmd":"ipmitool sdr", "raw": "0", "field_name": "PSU1_PIn", "field_pos":"3", "mult":"1000000"}, + { "attr_name":"psu_v_in", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU1_VIn", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_i_in", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU1_CIn", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_fan1_speed_rpm", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU1_Fan", "field_pos":"3", "mult":"1"}, + { "attr_name":"psu_temp1_input", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU1_Temp1", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"PSU1_Temp1", "field_pos":"18", "mult":"1000"} + ] + } + } + }, + + "PSU2": + { + "dev_info": { "device_type":"PSU"}, + "dev_attr": { "dev_idx":"2", "num_psu_fans": "1"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"psu_power_good", "bmc_cmd":"ipmitool raw 0x04 0x2d 0x10 | awk '{print substr($0,9,1)}'", "raw": "1", "type":"mask", "mask":"0x8"}, + { "attr_name":"psu_present", "bmc_cmd":"ipmitool raw 0x04 0x2d 0x10 | awk '{print substr($0,9,1)}'", "raw": "1", "type":"mask", "mask":"0x1"}, + { "attr_name":"psu_model_name", "bmc_cmd":"ipmitool fru print 4", "raw": "0", "field_name":"Product Name", "separator":": ","field_pos":"2"}, + { "attr_name":"psu_serial_num", "bmc_cmd":"ipmitool fru print 4", "raw": "0", "field_name":"Product Serial", "separator":": ","field_pos":"2"}, + { "attr_name":"psu_mfr_id", "bmc_cmd":"ipmitool fru print 4", "raw": "0", "field_name":"Product Manufacturer", "separator":":", "field_pos":"2"}, + { "attr_name":"psu_p_out", "bmc_cmd":"ipmitool sdr", "raw": "0", "field_name":"PSU2_POut", "field_pos":"3", "mult":"1000000"}, + { "attr_name":"psu_v_out", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU2_VOut", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_i_out", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU2_COut", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_p_in", "bmc_cmd":"ipmitool sdr", "raw": "0", "field_name": "PSU2_PIn", "field_pos":"3", "mult":"1000000"}, + { "attr_name":"psu_v_in", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU2_VIn", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_i_in", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU2_CIn", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_fan1_speed_rpm", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU2_Fan", "field_pos":"3", "mult":"1"}, + { "attr_name":"psu_temp1_input", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "PSU2_Temp1", "field_pos":"3", "mult":"1000"}, + { "attr_name":"psu_temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"PSU2_Temp1", "field_pos":"18", "mult":"1000"} + ] + } + } + }, + + "FAN-CTRL": + { + "dev_info": { "device_type":"FAN"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"fan1_present", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "Fan1_Status", "field_pos":"5"}, + { "attr_name":"fan2_present", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "Fan1_Status", "field_pos":"5"}, + { "attr_name":"fan3_present", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "Fan2_Status", "field_pos":"5"}, + { "attr_name":"fan4_present", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "Fan2_Status", "field_pos":"5"}, + { "attr_name":"fan5_present", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "Fan3_Status", "field_pos":"5"}, + { "attr_name":"fan6_present", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "Fan3_Status", "field_pos":"5"}, + { "attr_name":"fan7_present", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "Fan4_Status", "field_pos":"5"}, + { "attr_name":"fan8_present", "bmc_cmd":"ipmitool sdr", "raw":"0", "field_name" : "Fan4_Status", "field_pos":"5"}, + { "attr_name":"fan1_direction", "bmc_cmd":"ipmitool fru print 5 | grep -e B2F -e F2B", "raw": "0", "field_name":"Board Extra", "separator":": ", "field_pos":"2"}, + { "attr_name":"fan2_direction", "bmc_cmd":"ipmitool fru print 5 | grep -e B2F -e F2B", "raw": "0", "field_name":"Board Extra", "separator":": ", "field_pos":"2"}, + { "attr_name":"fan3_direction", "bmc_cmd":"ipmitool fru print 6 | grep -e B2F -e F2B", "raw": "0", "field_name":"Board Extra", "separator":": ", "field_pos":"2"}, + { "attr_name":"fan4_direction", "bmc_cmd":"ipmitool fru print 6 | grep -e B2F -e F2B", "raw": "0", "field_name":"Board Extra", "separator":": ", "field_pos":"2"}, + { "attr_name":"fan5_direction", "bmc_cmd":"ipmitool fru print 7 | grep -e B2F -e F2B", "raw": "0", "field_name":"Board Extra", "separator":": ", "field_pos":"2"}, + { "attr_name":"fan6_direction", "bmc_cmd":"ipmitool fru print 7 | grep -e B2F -e F2B", "raw": "0", "field_name":"Board Extra", "separator":": ", "field_pos":"2"}, + { "attr_name":"fan7_direction", "bmc_cmd":"ipmitool fru print 8 | grep -e B2F -e F2B", "raw": "0", "field_name":"Board Extra", "separator":": ", "field_pos":"2"}, + { "attr_name":"fan8_direction", "bmc_cmd":"ipmitool fru print 8 | grep -e B2F -e F2B", "raw": "0", "field_name":"Board Extra", "separator":": ", "field_pos":"2"}, + { "attr_name":"fan1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan1_Front", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan2_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan1_Rear", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan3_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan2_Front", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan4_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan2_Rear", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan5_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan3_Front", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan6_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan3_Rear", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan7_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan4_Front", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan8_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan4_Rear", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan1_pwm", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan1_Front", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan2_pwm", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan1_Rear", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan3_pwm", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan2_Front", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan4_pwm", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan2_Rear", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan5_pwm", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan3_Front", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan6_pwm", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan3_Rear", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan7_pwm", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan4_Front", "field_pos":"3", "mult":"1"}, + { "attr_name":"fan8_pwm", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Fan4_Rear", "field_pos":"3", "mult":"1"} + ] + } + } + }, + + "TEMP1": + { + "dev_info": { "device_type":"TEMP_SENSOR"}, + "dev_attr": { "display_name":"CPU_Temp"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"temp1_high_crit_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"CPU_Temp", "field_pos":"20"}, + { "attr_name":"temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"CPU_Temp", "field_pos":"18"}, + { "attr_name":"temp1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "CPU_Temp", "field_pos":"3"}, + { "attr_name":"temp1_low_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "CPU_Temp", "field_pos":"14"} + + ] + } + } + }, + "TEMP2": + { + "dev_info": { "device_type":"TEMP_SENSOR"}, + "dev_attr": { "display_name":"Base_Temp_U5"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"temp1_high_crit_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Base_Temp_U5", "field_pos":"20"}, + { "attr_name":"temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Base_Temp_U5", "field_pos":"18"}, + { "attr_name":"temp1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Base_Temp_U5", "field_pos":"3"}, + { "attr_name":"temp1_low_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Base_Temp_U5", "field_pos":"14"} + + ] + } + } + }, + "TEMP3": + { + "dev_info": { "device_type":"TEMP_SENSOR"}, + "dev_attr": { "display_name":"Base_Temp_U56"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"temp1_high_crit_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Base_Temp_U56", "field_pos":"20"}, + { "attr_name":"temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Base_Temp_U56", "field_pos":"18"}, + { "attr_name":"temp1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Base_Temp_U56", "field_pos":"3"}, + { "attr_name":"temp1_low_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Base_Temp_U56", "field_pos":"14"} + + ] + } + } + }, + "TEMP4": + { + "dev_info": { "device_type":"TEMP_SENSOR"}, + "dev_attr": { "display_name":"Switch_Temp_U17"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"temp1_high_crit_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Switch_Temp_U17", "field_pos":"20"}, + { "attr_name":"temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Switch_Temp_U17", "field_pos":"18"}, + { "attr_name":"temp1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Switch_Temp_U17", "field_pos":"3"}, + { "attr_name":"temp1_low_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Switch_Temp_U17", "field_pos":"14"} + + ] + } + } + }, + "TEMP5": + { + "dev_info": { "device_type":"TEMP_SENSOR"}, + "dev_attr": { "display_name":"Switch_Temp_U18"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"temp1_high_crit_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Switch_Temp_U18", "field_pos":"20"}, + { "attr_name":"temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Switch_Temp_U18", "field_pos":"18"}, + { "attr_name":"temp1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Switch_Temp_U18", "field_pos":"3"}, + { "attr_name":"temp1_low_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Switch_Temp_U18", "field_pos":"14"} + + ] + } + } + }, + "TEMP6": + { + "dev_info": { "device_type":"TEMP_SENSOR"}, + "dev_attr": { "display_name":"Switch_Temp_U28"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"temp1_high_crit_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Switch_Temp_U28", "field_pos":"20"}, + { "attr_name":"temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Switch_Temp_U28", "field_pos":"18"}, + { "attr_name":"temp1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Switch_Temp_U28", "field_pos":"3"}, + { "attr_name":"temp1_low_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Switch_Temp_U28", "field_pos":"14"} + + ] + } + } + }, + "TEMP7": + { + "dev_info": { "device_type":"TEMP_SENSOR"}, + "dev_attr": { "display_name":"Switch_Temp_U29"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"temp1_high_crit_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Switch_Temp_U29", "field_pos":"20"}, + { "attr_name":"temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"Switch_Temp_U29", "field_pos":"18"}, + { "attr_name":"temp1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Switch_Temp_U29", "field_pos":"3"}, + { "attr_name":"temp1_low_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "Switch_Temp_U29", "field_pos":"14"} + + ] + } + } + }, + "TEMP8": + { + "dev_info": { "device_type":"TEMP_SENSOR"}, + "dev_attr": { "display_name":"VDD_CORE_Temp"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"temp1_high_crit_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"VDD_CORE_Temp", "field_pos":"20"}, + { "attr_name":"temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"VDD_CORE_Temp", "field_pos":"18"}, + { "attr_name":"temp1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "VDD_CORE_Temp", "field_pos":"3"}, + { "attr_name":"temp1_low_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "VDD_CORE_Temp", "field_pos":"14"} + + ] + } + } + }, + "TEMP9": + { + "dev_info": { "device_type":"TEMP_SENSOR"}, + "dev_attr": { "display_name":"VDD_ANLG_Temp"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"temp1_high_crit_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"VDD_ANLG_Temp", "field_pos":"20"}, + { "attr_name":"temp1_high_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name":"VDD_ANLG_Temp", "field_pos":"18"}, + { "attr_name":"temp1_input", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "VDD_ANLG_Temp", "field_pos":"3"}, + { "attr_name":"temp1_low_threshold", "bmc_cmd":"ipmitool sensor", "raw":"0", "field_name" : "VDD_ANLG_Temp", "field_pos":"14"} + + ] + } + } + }, + + "SYS_LED": + { + "dev_info": { "device_type":"LED", "device_name":"SYS_LED"}, + "dev_attr": { "index":"0", "flag": "ro"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"off", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x00"}, + { "attr_name":"green", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x01"}, + { "attr_name":"amber", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x02"}, + { "attr_name":"amber_blink_1hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x03"}, + { "attr_name":"amber_blink_4hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x04"}, + { "attr_name":"green_blink_1hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x05"}, + { "attr_name":"green_blink_4hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x06"}, + { "attr_name":"both_blink_1hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x07"}, + { "attr_name":"both_blink_4hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x08"}, + { "attr_name":"unknown", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x00", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x09"} + ] + } + } + }, + "ALARM_LED": + { + "dev_info": { "device_type":"LED", "device_name":"ALARM_LED"}, + "dev_attr": { "index":"0", "flag": "ro"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"off", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x01", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x00"}, + { "attr_name":"green", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x01", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x01"}, + { "attr_name":"amber", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x01", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x02"}, + { "attr_name":"amber_blink_1hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x01", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x03"}, + { "attr_name":"amber_blink_4hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x01", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x04"}, + { "attr_name":"green_blink_1hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x01", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x05"}, + { "attr_name":"green_blink_4hz", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x01", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x06"}, + { "attr_name":"unknown", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x01", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x09"} + ] + } + } + }, + "FANTRAY1_LED": + { + "dev_info": { "device_type":"LED", "device_name":"FANTRAY1_LED"}, + "dev_attr": { "index":"0", "flag": "ro"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"off", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x04", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x00"}, + { "attr_name":"green", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x04", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x01"}, + { "attr_name":"amber", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x04", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x02"}, + { "attr_name":"unknown", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x04", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x03"} + ] + } + } + }, + "FANTRAY2_LED": + { + "dev_info": { "device_type":"LED", "device_name":"FANTRAY2_LED"}, + "dev_attr": { "index":"1", "flag": "ro"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"off", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x05", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x00"}, + { "attr_name":"green", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x05", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x01"}, + { "attr_name":"amber", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x05", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x02"}, + { "attr_name":"unknown", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x05", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x03"} + ] + } + } + }, + "FANTRAY3_LED": + { + "dev_info": { "device_type":"LED", "device_name":"FANTRAY3_LED"}, + "dev_attr": { "index":"2", "flag": "ro"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"off", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x06", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x00"}, + { "attr_name":"green", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x06", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x01"}, + { "attr_name":"amber", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x06", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x02"}, + { "attr_name":"unknown", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x06", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x03"} + ] + } + } + }, + "FANTRAY4_LED": + { + "dev_info": { "device_type":"LED", "device_name":"FANTRAY4_LED"}, + "dev_attr": { "index":"3", "flag": "ro"}, + "bmc": { + "ipmitool" : { + "attr_list": + [ + { "attr_name":"off", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x07", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x00"}, + { "attr_name":"green", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x07", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x01"}, + { "attr_name":"amber", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x07", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x02"}, + { "attr_name":"unknown", "bmc_cmd":"ipmitool raw 0x3A 0x39 0x01 0x07", "raw": "1", "type":"mask", "mask" : "0xff", "descr" :"OFF", "value" : "0x03"} + ] + } + } + } +} diff --git a/device/celestica/x86_64-cel_ds3000-r0/pddf/pddf-device-nonbmc.json b/device/celestica/x86_64-cel_ds3000-r0/pddf/pddf-device-nonbmc.json new file mode 100644 index 000000000000..f0b77c7a3a66 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/pddf/pddf-device-nonbmc.json @@ -0,0 +1,2216 @@ +{ +"PLATFORM": +{ + "num_psus":2, + "num_fantrays":4, + "num_fans_pertray":2, + "num_ports":33, + "num_temps":6, + "num_components":8, + "pddf_dev_types": + { + "description":" - Below is the list of supported PDDF device types (chip names) for various components. If any component uses some other driver, we will create the client using 'echo > /new_device' method", + "CPLD": + [ + "i2c_cpld" + ], + "PSU": + [ + "psu_pmbus" + ], + "FAN": + [ + "fan_ctrl", + "fan_eeprom", + "fan_cpld" + ], + "PORT_MODULE": + [ + "pddf_xcvr" + ], + "FPGAPCIE": + [ + "fpgapci" + ] + + }, + "std_perm_kos": + [ + "i2c_ismt", + "i2c-i801" + ], + + "std_kos": + [ + "lpc_ich", + "i2c_dev", + "i2c_mux_pca954x", + "optoe", + "mc24lc64t", + "ucd9000", + "mp2975", + "lm75", + "at24" + ], + + "pddf_kos": + [ + "pddf_client_module", + "pddf_cpld_module", + "pddf_cpld_driver", + "pddf_mux_module", + "pddf_fan_module", + "pddf_psu_module", + "pddf_led_module", + "pddf_fpgai2c_module", + "pddf_fpgai2c_driver", + "pddf_xcvr_module", + "pddf_xcvr_driver_module", + "pddf_fpgapci_driver", + "pddf_fpgapci_module" + ], + + "custom_kos": + [ + "pddf_custom_psu_driver_module", + "pddf_custom_fpga_algo" + ] + }, + + "COMPONENT1": + { + "comp_attr":{ "name": "BIOS", "type": "bios", "description": "Basic Input/Output System"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "echo `dmidecode -s bios-version`-`dmidecode -s bios-release-date`" }, + { "attr_name":"update", "cmd": "afulnx_64 {} /p /b /n /me /x /k" } + ] + }, + "COMPONENT2": + { + "comp_attr":{ "name": "BaseBoard_CPLD", "type": "cpld", "description": "Base Board CPLD"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(cat /sys/devices/platform/baseboard/version) && printf '%d.%d' $(($r>>4)) $(($r&0xf))" }, + { "attr_name":"update", "cmd": "ispvm {}" } + ] + }, + "COMPONENT3": + { + "comp_attr":{ "name": "SwitchBoard_CPLD1", "type": "cpld", "description":"Switch Board CPLD"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(i2cget -y -f 102 0x30 0) && printf '%d.%d' $(($r>>4)) $(($r&0xf))" } + ] + }, + "COMPONENT4": + { + "comp_attr":{ "name": "SwitchBoard_CPLD2", "type": "cpld", "description":"Switch Board CPLD"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(i2cget -y -f 102 0x31 0) && printf '%d.%d' $(($r>>4)) $(($r&0xf))" } + ] + }, + "COMPONENT5": + { + "comp_attr":{ "name": "COMeBoard_CPLD", "type": "cpld", "description": "COMe Board CPLD"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(cat /sys/devices/platform/baseboard/come_cpld_version) && printf '%d.%d' $(($r>>4)) $(($r&0xf))" } + ] + }, + "COMPONENT6": + { + "comp_attr":{ "name": "FPGA", "type": "fpga", "description": "Baseboard FPGA"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "r=$(cat /sys/devices/platform/fpga_sysfs/version) && printf '%d.%d' $(($r>>16)) $(($r&0xffff))" }, + { "attr_name":"update", "cmd": "fpga_prog /sys/bus/pci/devices/0000:06:00.0/resource0 {}" } + ] + }, + "COMPONENT7": + { + "comp_attr":{ "name": "PCIe", "type": "pcie", "description":"ASIC PCIe Firmware"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "bcmcmd 'pciephy fw version' | grep 'PCIe FW version' | cut -d ' ' -f 4" } + ] + }, + "COMPONENT8": + { + "comp_attr":{ "name": "SSD", "type": "ssd", "description":"SSD firmware version"}, + "attr_list": + [ + { "attr_name":"version", "get_cmd": "ssdutil -v | grep 'Firmware' | awk '{ print $3 }'" } + ] + }, + + "SYSTEM": + { + "dev_info": {"device_type":"CPU", "device_name":"ROOT_COMPLEX", "device_parent":null}, + "i2c": + { + "CONTROLLERS": + [ + { "dev_name":"i2c-0", "dev":"SMBUS0" }, + { "dev_name":"i2c-1", "dev":"SMBUS1" }, + { "dev_name":"pcie-0", "dev":"PCIE0" } + ] + } + }, + + "SMBUS0": + { + "dev_info": {"device_type": "SMBUS", "device_name": "SMBUS0", "device_parent": "SYSTEM"}, + "i2c": + { + "topo_info": {"dev_addr": "0x0"}, + "DEVICES": + [ + {"dev": "EEPROM1"} + ] + } + }, + + "EEPROM1": + { + "dev_info": {"device_type": "EEPROM", "device_name": "EEPROM1", "device_parent": "SMBUS0"}, + "i2c": + { + "topo_info": {"parent_bus": "0x0", "dev_addr": "0x56", "dev_type": "24lc64t"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + + "SMBUS1": + { + "dev_info": {"device_type": "SMBUS", "device_name": "SMBUS1", "device_parent": "SYSTEM"}, + "i2c": + { + "topo_info": {"dev_addr": "0x1"}, + "DEVICES": + [ + {"dev": "COME_CPLD"} + ] + } + }, + + "COME_CPLD": + { + "dev_info": {"device_type": "CPLD", "device_name": "COME_CPLD", "device_parent": "SMBUS1"}, + "i2c": + { + "topo_info": {"parent_bus": "0x1", "dev_addr": "0x0d", "dev_type": "i2c_cpld"}, + "dev_attr": {} + } + }, + + "PCIE0": + { + "dev_info": {"device_type": "PCIE", "device_name": "PCIE0", "device_parent": "SYSTEM"}, + "i2c": + { + "DEVICES": + [ + {"dev": "FPGAPCIE0"} + ] + } + }, + + "FPGAPCIE0": + { + "dev_info": {"device_type": "FPGAPCIE", "device_name": "FPGAPCIE0", "device_parent": "PCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x0"}, + "dev_attr": { "vendor_id":"0x10EE", "device_id": "0x7021", "virt_bus": "0x64", "data_base_offset":"0x0", "data_size":"0x25000", "i2c_ch_base_offset":"0x10000", "i2c_ch_size":"0x1000", "virt_i2c_ch":"0xc"}, + "channel": + [ + { "chn":"2", "dev":"MUX1" }, + { "chn":"2", "dev":"MUX2" }, + { "chn":"2", "dev":"MUX3" }, + { "chn":"2", "dev":"MUX4" }, + { "chn":"1", "dev":"MUX5" }, + { "chn":"3", "dev":"CPLD_S1" }, + { "chn":"3", "dev":"CPLD_S2" }, + { "chn":"4", "dev":"EEPROM_COME" }, + { "chn":"4", "dev":"CPLD_COME" }, + { "chn":"5", "dev":"EEPROM_BASEBOARD" }, + { "chn":"6", "dev":"FAN-CTRL" }, + { "chn":"6", "dev":"CPLD_BASEBOARD" }, + { "chn":"7", "dev":"MUX6" }, + { "chn":"10", "dev":"TEMP1" }, + { "chn":"10", "dev":"TEMP2" }, + { "chn":"10", "dev":"TEMP3" }, + { "chn":"10", "dev":"TEMP4" }, + { "chn":"10", "dev":"TEMP5" }, + { "chn":"10", "dev":"TEMP6" }, + { "chn":"11", "dev":"MUX7" } + ] + } + }, + + "TEMP1": + { + "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP1", "device_parent":"FPGAPCIE0"}, + "dev_attr": { "display_name":"Base_Temp_U5"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6d", "dev_addr":"0x4d", "dev_type":"lm75"}, + "attr_list": + [ + { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max_hyst"}, + { "attr_name": "temp1_input"} + ] + } + }, + "TEMP2": + { + "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP2", "device_parent":"FPGAPCIE0"}, + "dev_attr": { "display_name":"Base_Temp_U56"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6d", "dev_addr":"0x4e", "dev_type":"lm75"}, + "attr_list": + [ + { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max_hyst"}, + { "attr_name": "temp1_input"} + ] + } + }, + "TEMP3": + { + "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP3", "device_parent":"FPGAPCIE0"}, + "dev_attr": { "display_name":"Switch_Temp_U17"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6d", "dev_addr":"0x4c", "dev_type":"lm75"}, + "attr_list": + [ + { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max_hyst"}, + { "attr_name": "temp1_input"} + ] + } + }, + "TEMP4": + { + "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP4", "device_parent":"FPGAPCIE0"}, + "dev_attr": { "display_name":"Switch_Temp_U18"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6d", "dev_addr":"0x49", "dev_type":"lm75"}, + "attr_list": + [ + { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max_hyst"}, + { "attr_name": "temp1_input"} + ] + } + }, + "TEMP5": + { + "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP5", "device_parent":"FPGAPCIE0"}, + "dev_attr": { "display_name":"Switch_Temp_U28"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6d", "dev_addr":"0x4a", "dev_type":"lm75"}, + "attr_list": + [ + { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max_hyst"}, + { "attr_name": "temp1_input"} + ] + } + }, + "TEMP6": + { + "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP6", "device_parent":"FPGAPCIE0"}, + "dev_attr": { "display_name":"Switch_Temp_U29"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6d", "dev_addr":"0x4b", "dev_type":"lm75"}, + "attr_list": + [ + { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max_hyst"}, + { "attr_name": "temp1_input"} + ] + } + }, + + "CPLD_BASEBOARD": + { + "dev_info": { "device_type":"CPLD", "device_name":"CPLD_BASEBOARD", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x69", "dev_addr":"0x0d", "dev_type":"i2c_cpld"}, + "dev_attr":{} + } + }, + + "EEPROM_BASEBOARD": + { + "dev_info": {"device_type": "EEPROM", "device_name": "EEPROM_BASEBOARD", "device_parent": "FPGAPCIE0"}, + "i2c": + { + "topo_info": {"parent_bus": "0x68", "dev_addr": "0x57", "dev_type": "24lc64t"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + + "EEPROM_COME": + { + "dev_info": {"device_type": "EEPROM", "device_name": "EEPROM_COME", "device_parent": "FPGAPCIE0"}, + "i2c": + { + "topo_info": {"parent_bus": "0x67", "dev_addr": "0x50", "dev_type": "24lc64t"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + + "CPLD_COME": + { + "dev_info": { "device_type":"CPLD", "device_name":"CPLD_COME", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x67", "dev_addr":"0x0d", "dev_type":"i2c_cpld"}, + "dev_attr":{} + } + }, + + "CPLD_S1": + { + "dev_info": { "device_type":"CPLD", "device_name":"CPLD_S1", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x66", "dev_addr":"0x30", "dev_type":"i2c_cpld"}, + "dev_attr":{} + } + }, + + "CPLD_S2": + { + "dev_info": { "device_type":"CPLD", "device_name":"CPLD_S2", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x66", "dev_addr":"0x31", "dev_type":"i2c_cpld"}, + "dev_attr":{} + } + }, + + "MUX1": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX1", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x65", "dev_addr":"0x72", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x2", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"PORT1" }, + { "chn":"1", "dev":"PORT2" }, + { "chn":"2", "dev":"PORT3" }, + { "chn":"3", "dev":"PORT4" }, + { "chn":"4", "dev":"PORT5" }, + { "chn":"5", "dev":"PORT6" }, + { "chn":"6", "dev":"PORT7" }, + { "chn":"7", "dev":"PORT8" } + ] + } + }, + + "MUX2": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX2", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x65", "dev_addr":"0x73", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0xa", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"PORT9" }, + { "chn":"1", "dev":"PORT10" }, + { "chn":"2", "dev":"PORT11" }, + { "chn":"3", "dev":"PORT12" }, + { "chn":"4", "dev":"PORT13" }, + { "chn":"5", "dev":"PORT14" }, + { "chn":"6", "dev":"PORT15" }, + { "chn":"7", "dev":"PORT16" } + ] + } + }, + + "MUX3": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX3", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x65", "dev_addr":"0x74", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x12", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"PORT17" }, + { "chn":"1", "dev":"PORT18" }, + { "chn":"2", "dev":"PORT19" }, + { "chn":"3", "dev":"PORT20" }, + { "chn":"4", "dev":"PORT21" }, + { "chn":"5", "dev":"PORT22" }, + { "chn":"6", "dev":"PORT23" }, + { "chn":"7", "dev":"PORT24" } + ] + } + }, + + "MUX4": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX4", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x65", "dev_addr":"0x75", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x1a", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"PORT25" }, + { "chn":"1", "dev":"PORT26" }, + { "chn":"2", "dev":"PORT27" }, + { "chn":"3", "dev":"PORT28" }, + { "chn":"4", "dev":"PORT29" }, + { "chn":"5", "dev":"PORT30" }, + { "chn":"6", "dev":"PORT31" }, + { "chn":"7", "dev":"PORT32" } + ] + } + }, + "MUX5": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX5", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x64", "dev_addr":"0x72", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x22"}, + "channel": + [ + { "chn":"0", "dev":"PORT33" } + ] + } + }, + + "MUX6": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX6", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6a", "dev_addr":"0x70", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x2a", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"PSU1" }, + { "chn":"0", "dev":"PSU1-EEPROM" }, + { "chn":"1", "dev":"PSU2" }, + { "chn":"1", "dev":"PSU2-EEPROM" } + ] + } + }, + + "MUX7": + { + "dev_info": { "device_type":"MUX", "device_name":"MUX7", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6e", "dev_addr":"0x77", "dev_type":"pca9548"}, + "dev_attr": { "virt_bus":"0x32", "idle_state":"-2" }, + "channel": + [ + { "chn":"0", "dev":"FANTRAY1_EEPROM" }, + { "chn":"1", "dev":"FANTRAY2_EEPROM" }, + { "chn":"3", "dev":"FANTRAY3_EEPROM" }, + { "chn":"4", "dev":"FANTRAY4_EEPROM" } + ] + } + }, + + "PORT1": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT1", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"1"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT1-EEPROM" }, + { "itf":"control", "dev":"PORT1-CTRL" } + + ] + } + }, + "PORT1-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT1-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT1"}, + "i2c": + { + "topo_info": { "parent_bus":"0x2", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + "PORT1-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT1-CTRL", "device_parent":"MUX1", "virt_parent":"PORT1"}, + "i2c": + { + "topo_info": { "parent_bus":"0x2", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + "PORT2": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT2", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"2"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT2-EEPROM" }, + { "itf":"control", "dev":"PORT2-CTRL" } + ] + } + }, + + "PORT2-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT2-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT2"}, + "i2c": + { + "topo_info": { "parent_bus":"0x3", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT2-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT2-CTRL", "device_parent":"MUX1", "virt_parent":"PORT2"}, + "i2c": + { + "topo_info": { "parent_bus":"0x3", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x10", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x10", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x10", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x10", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT3": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT3", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"3"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT3-EEPROM" }, + { "itf":"control", "dev":"PORT3-CTRL" } + ] + } + }, + "PORT3-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT3-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT3"}, + "i2c": + { + "topo_info": { "parent_bus":"0x4", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT3-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT3-CTRL", "device_parent":"MUX1", "virt_parent":"PORT3"}, + "i2c": + { + "topo_info": { "parent_bus":"0x4", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x20", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x20", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x20", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x20", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT4": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT4", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"4"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT4-EEPROM" }, + { "itf":"control", "dev":"PORT4-CTRL" } + ] + } + }, + "PORT4-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT4-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT4"}, + "i2c": + { + "topo_info": { "parent_bus":"0x5", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT4-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT4-CTRL", "device_parent":"MUX1", "virt_parent":"PORT4"}, + "i2c": + { + "topo_info": { "parent_bus":"0x5", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x30", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x30", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x30", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x30", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT5": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT5", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"5"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT5-EEPROM" }, + { "itf":"control", "dev":"PORT5-CTRL" } + ] + } + }, + + "PORT5-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT5-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT5"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT5-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT5-CTRL", "device_parent":"MUX1", "virt_parent":"PORT5"}, + "i2c": + { + "topo_info": { "parent_bus":"0x6", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x40", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x40", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x40", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x40", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT6": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT6", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"6"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT6-EEPROM" }, + { "itf":"control", "dev":"PORT6-CTRL" } + ] + } + }, + "PORT6-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT6-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT6"}, + "i2c": + { + "topo_info": { "parent_bus":"0x7", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT6-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT6-CTRL", "device_parent":"MUX1", "virt_parent":"PORT6"}, + "i2c": + { + "topo_info": { "parent_bus":"0x7", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x50", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x50", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x50", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x50", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT7": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT7", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"7"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT7-EEPROM" }, + { "itf":"control", "dev":"PORT7-CTRL" } + ] + } + }, + "PORT7-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT7-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT7"}, + "i2c": + { + "topo_info": { "parent_bus":"0x8", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT7-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT7-CTRL", "device_parent":"MUX1", "virt_parent":"PORT7"}, + "i2c": + { + "topo_info": { "parent_bus":"0x8", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x60", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x60", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x60", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x60", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT8": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT8", "device_parent":"MUX1"}, + "dev_attr": { "dev_idx":"8"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT8-EEPROM" }, + { "itf":"control", "dev":"PORT8-CTRL" } + ] + } + }, + "PORT8-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT8-EEPROM", "device_parent":"MUX1", "virt_parent":"PORT8"}, + "i2c": + { + "topo_info": { "parent_bus":"0x9", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT8-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT8-CTRL", "device_parent":"MUX1", "virt_parent":"PORT8"}, + "i2c": + { + "topo_info": { "parent_bus":"0x9", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x70", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x70", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x70", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x70", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT9": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT9", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"9"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT9-EEPROM" }, + { "itf":"control", "dev":"PORT9-CTRL" } + ] + } + }, + "PORT9-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT9-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT9"}, + "i2c": + { + "topo_info": { "parent_bus":"0xa", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT9-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT9-CTRL", "device_parent":"MUX2", "virt_parent":"PORT9"}, + "i2c": + { + "topo_info": { "parent_bus":"0xa", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x80", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x80", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x80", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x80", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT10": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT10", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"10"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT10-EEPROM" }, + { "itf":"control", "dev":"PORT10-CTRL" } + ] + } + }, + "PORT10-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT10-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT10"}, + "i2c": + { + "topo_info": { "parent_bus":"0xb", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT10-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT10-CTRL", "device_parent":"MUX2", "virt_parent":"PORT10"}, + "i2c": + { + "topo_info": { "parent_bus":"0xb", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x90", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x90", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x90", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x90", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT11": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT11", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"11"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT11-EEPROM" }, + { "itf":"control", "dev":"PORT11-CTRL" } + ] + } + }, + "PORT11-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT11-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT11"}, + "i2c": + { + "topo_info": { "parent_bus":"0xc", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT11-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT11-CTRL", "device_parent":"MUX2", "virt_parent":"PORT11"}, + "i2c": + { + "topo_info": { "parent_bus":"0xc", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xa0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xa0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xa0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xa0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT12": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT12", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"12"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT12-EEPROM" }, + { "itf":"control", "dev":"PORT12-CTRL" } + ] + } + }, + "PORT12-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT12-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT12"}, + "i2c": + { + "topo_info": { "parent_bus":"0xd", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT12-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT12-CTRL", "device_parent":"MUX2", "virt_parent":"PORT12"}, + "i2c": + { + "topo_info": { "parent_bus":"0xd", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xb0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xb0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xb0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xb0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT13": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT13", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"13"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT13-EEPROM" }, + { "itf":"control", "dev":"PORT13-CTRL" } + ] + } + }, + "PORT13-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT13-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT13"}, + "i2c": + { + "topo_info": { "parent_bus":"0xe", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT13-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT13-CTRL", "device_parent":"MUX2", "virt_parent":"PORT13"}, + "i2c": + { + "topo_info": { "parent_bus":"0xe", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xc0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xc0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xc0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xc0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT14": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT14", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"14"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT14-EEPROM" }, + { "itf":"control", "dev":"PORT14-CTRL" } + ] + } + }, + "PORT14-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT14-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT14"}, + "i2c": + { + "topo_info": { "parent_bus":"0xF", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT14-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT14-CTRL", "device_parent":"MUX2", "virt_parent":"PORT14"}, + "i2c": + { + "topo_info": { "parent_bus":"0xf", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xd0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xd0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xd0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xd0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT15": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT15", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"15"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT15-EEPROM" }, + { "itf":"control", "dev":"PORT15-CTRL" } + ] + } + }, + "PORT15-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT15-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT15"}, + "i2c": + { + "topo_info": { "parent_bus":"0x10", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT15-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT15-CTRL", "device_parent":"MUX2", "virt_parent":"PORT15"}, + "i2c": + { + "topo_info": { "parent_bus":"0x10", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xe0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xe0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xe0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xe0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT16": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT16", "device_parent":"MUX2"}, + "dev_attr": { "dev_idx":"16"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT16-EEPROM" }, + { "itf":"control", "dev":"PORT16-CTRL" } + ] + } + }, + "PORT16-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT16-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT16"}, + "i2c": + { + "topo_info": { "parent_bus":"0x11", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT16-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT16-CTRL", "device_parent":"MUX2", "virt_parent":"PORT16"}, + "i2c": + { + "topo_info": { "parent_bus":"0x11", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xf0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xf0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xf0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0xf0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT17": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT17", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"17"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT17-EEPROM" }, + { "itf":"control", "dev":"PORT17-CTRL" } + ] + } + }, + "PORT17-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT17-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT17"}, + "i2c": + { + "topo_info": { "parent_bus":"0x12", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT17-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT17-CTRL", "device_parent":"MUX3", "virt_parent":"PORT17"}, + "i2c": + { + "topo_info": { "parent_bus":"0x12", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x100", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x100", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x100", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x100", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT18": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT18", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"18"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT18-EEPROM" }, + { "itf":"control", "dev":"PORT18-CTRL" } + ] + } + }, + "PORT18-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT18-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT18"}, + "i2c": + { + "topo_info": { "parent_bus":"0x13", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT18-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT18-CTRL", "device_parent":"MUX3", "virt_parent":"PORT18"}, + "i2c": + { + "topo_info": { "parent_bus":"0x13", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x110", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x110", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x110", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x110", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT19": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT19", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"19"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT19-EEPROM" }, + { "itf":"control", "dev":"PORT19-CTRL" } + ] + } + }, + "PORT19-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT19-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT19"}, + "i2c": + { + "topo_info": { "parent_bus":"0x14", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT19-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT19-CTRL", "device_parent":"MUX3", "virt_parent":"PORT19"}, + "i2c": + { + "topo_info": { "parent_bus":"0x14", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x120", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x120", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x120", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x120", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT20": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT20", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"20"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT20-EEPROM" }, + { "itf":"control", "dev":"PORT20-CTRL" } + ] + } + }, + "PORT20-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT20-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT20"}, + "i2c": + { + "topo_info": { "parent_bus":"0x15", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT20-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT20-CTRL", "device_parent":"MUX3", "virt_parent":"PORT20"}, + "i2c": + { + "topo_info": { "parent_bus":"0x15", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x130", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x130", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x130", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x130", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT21": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT21", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"21"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT21-EEPROM" }, + { "itf":"control", "dev":"PORT21-CTRL" } + ] + } + }, + "PORT21-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT21-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT21"}, + "i2c": + { + "topo_info": { "parent_bus":"0x16", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT21-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT21-CTRL", "device_parent":"MUX3", "virt_parent":"PORT21"}, + "i2c": + { + "topo_info": { "parent_bus":"0x16", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x140", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x140", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x140", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x140", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT22": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT22", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"22"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT22-EEPROM" }, + { "itf":"control", "dev":"PORT22-CTRL" } + ] + } + }, + "PORT22-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT22-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT22"}, + "i2c": + { + "topo_info": { "parent_bus":"0x17", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT22-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT22-CTRL", "device_parent":"MUX3", "virt_parent":"PORT22"}, + "i2c": + { + "topo_info": { "parent_bus":"0x17", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x150", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x150", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x150", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x150", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT23": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT23", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"23"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT23-EEPROM" }, + { "itf":"control", "dev":"PORT23-CTRL" } + ] + } + }, + "PORT23-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT23-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT23"}, + "i2c": + { + "topo_info": { "parent_bus":"0x18", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT23-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT23-CTRL", "device_parent":"MUX3", "virt_parent":"PORT23"}, + "i2c": + { + "topo_info": { "parent_bus":"0x18", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x160", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x160", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x160", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x160", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT24": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT24", "device_parent":"MUX3"}, + "dev_attr": { "dev_idx":"24"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT24-EEPROM" }, + { "itf":"control", "dev":"PORT24-CTRL" } + ] + } + }, + "PORT24-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT24-EEPROM", "device_parent":"MUX3", "virt_parent":"PORT24"}, + "i2c": + { + "topo_info": { "parent_bus":"0x19", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT24-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT24-CTRL", "device_parent":"MUX3", "virt_parent":"PORT24"}, + "i2c": + { + "topo_info": { "parent_bus":"0x19", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x170", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x170", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x170", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x170", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT25": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT25", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"25"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT25-EEPROM" }, + { "itf":"control", "dev":"PORT25-CTRL" } + ] + } + }, + "PORT25-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT25-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT25"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1a", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT25-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT25-CTRL", "device_parent":"MUX4", "virt_parent":"PORT25"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1a", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x180", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x180", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x180", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x180", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT26": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT26", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"26"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT26-EEPROM" }, + { "itf":"control", "dev":"PORT26-CTRL" } + ] + } + }, + "PORT26-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT26-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT26"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1b", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + + "PORT26-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT26-CTRL", "device_parent":"MUX4", "virt_parent":"PORT26"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1b", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x190", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x190", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x190", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x190", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT27": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT27", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"27"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT27-EEPROM" }, + { "itf":"control", "dev":"PORT27-CTRL" } + ] + } + }, + "PORT27-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT27-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT27"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1c", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT27-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT27-CTRL", "device_parent":"MUX4", "virt_parent":"PORT27"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1c", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1a0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1a0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1a0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1a0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT28": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT28", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"28"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT28-EEPROM" }, + { "itf":"control", "dev":"PORT28-CTRL" } + ] + } + }, + "PORT28-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT28-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT28"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1d", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT28-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT28-CTRL", "device_parent":"MUX4", "virt_parent":"PORT28"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1d", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1b0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1b0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1b0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1b0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT29": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT29", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"29"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT29-EEPROM" }, + { "itf":"control", "dev":"PORT29-CTRL" } + ] + } + }, + "PORT29-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT29-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT29"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1e", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT29-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT29-CTRL", "device_parent":"MUX4", "virt_parent":"PORT29"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1e", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1c0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1c0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1c0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1c0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT30": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT30", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"30"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT30-EEPROM" }, + { "itf":"control", "dev":"PORT30-CTRL" } + ] + } + }, + "PORT30-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT30-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT30"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1f", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT30-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT30-CTRL", "device_parent":"MUX4", "virt_parent":"PORT30"}, + "i2c": + { + "topo_info": { "parent_bus":"0x1f", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1d0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1d0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1d0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1d0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT31": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT31", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"31"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT31-EEPROM" }, + { "itf":"control", "dev":"PORT31-CTRL" } + ] + } + }, + "PORT31-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT31-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT31"}, + "i2c": + { + "topo_info": { "parent_bus":"0x20", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT31-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT31-CTRL", "device_parent":"MUX4", "virt_parent":"PORT31"}, + "i2c": + { + "topo_info": { "parent_bus":"0x20", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1e0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1e0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1e0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1e0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + + "PORT32": + { + "dev_info": { "device_type":"QSFP28", "device_name":"PORT32", "device_parent":"MUX4"}, + "dev_attr": { "dev_idx":"32"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT32-EEPROM" }, + { "itf":"control", "dev":"PORT32-CTRL" } + ] + } + }, + "PORT32-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT32-EEPROM", "device_parent":"MUX4", "virt_parent":"PORT32"}, + "i2c": + { + "topo_info": { "parent_bus":"0x21", "dev_addr":"0x50", "dev_type":"optoe1"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT32-CTRL": + { + "dev_info": { "device_type":"pci", "device_name":"PORT32-CTRL", "device_parent":"MUX4", "virt_parent":"PORT32"}, + "i2c": + { + "topo_info": { "parent_bus":"0x21", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1f0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_reset", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1f0", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1f0", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x1f0", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} + ] + } + }, + + "PORT33": + { + "dev_info": { "device_type":"SFP+", "device_name":"PORT33", "device_parent":"MUX5"}, + "dev_attr": { "dev_idx":"33"}, + "i2c": + { + "interface": + [ + { "itf":"eeprom", "dev":"PORT33-EEPROM" }, + { "itf":"control", "dev":"PORT33-CTRL" } + ] + } + }, + "PORT33-EEPROM": + { + "dev_info": { "device_type":"", "device_name":"PORT33-EEPROM", "device_parent":"MUX5", "virt_parent":"PORT33"}, + "i2c": + { + "topo_info": { "parent_bus":"0x22", "dev_addr":"0x50", "dev_type":"optoe2"}, + "attr_list": + [ + { "attr_name":"eeprom"} + ] + } + }, + + "PORT33-CTRL": + { + "dev_info": { "device_type":"", "device_name":"PORT33-CTRL", "device_parent":"MUX5", "virt_parent":"PORT33"}, + "i2c": + { + "topo_info": { "parent_bus":"0x22", "dev_addr":"0x53", "dev_type":"pddf_xcvr"}, + "attr_list": + [ + { "attr_name":"xcvr_present", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x0", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"xcvr_txfault", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x2", "attr_cmpval":"0x4", "attr_len":"1"}, + { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x1010", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x0", "attr_cmpval":"0x1", "attr_len":"1"}, + { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x1014", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"}, + { "attr_name":"xcvr_intr_status", "attr_devaddr":"0x1018", "attr_devtype":"fpgapci", "attr_devname":"FPGAPCIE0", "attr_offset":"0x200", "attr_mask":"0x0", "attr_cmpval":"0x1", "attr_len":"1"} + ] + } + }, + + "PSU1": + { + "dev_info": { "device_type":"PSU", "device_name":"PSU1", "device_parent":"MUX6"}, + "dev_attr": { "dev_idx":"1", "num_psu_fans": "1"}, + "i2c": + { + "interface": + [ + { "itf":"pmbus", "dev":"PSU1-PMBUS" } + ] + } + }, + "PSU1-PMBUS": + { + "dev_info": { "device_type":"PSU-PMBUS", "device_name":"PSU1-PMBUS", "device_parent":"MUX6", "virt_parent":"PSU1" }, + "i2c": + { + "topo_info":{ "parent_bus":"0x2a", "dev_addr":"0x5a", "dev_type":"psu_pmbus"}, + "attr_list": + [ + {"attr_name":"psu_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0x60", "attr_mask":"0x08", "attr_cmpval":"0x00", "attr_len":"1"}, + {"attr_name":"psu_power_good", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0x60", "attr_mask":"0x02", "attr_cmpval":"0x02", "attr_len":"1"}, + {"attr_name":"psu_model_name", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"17"}, + {"attr_name":"psu_serial_num", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x9e", "attr_mask":"0x0", "attr_cmpval":"0x00", "attr_len":"13"}, + {"attr_name":"psu_mfr_id", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x99", "attr_mask":"0x0", "attr_cmpval":"0x00", "attr_len":"7"}, + {"attr_name":"psu_fan_dir", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0x00", "attr_len":"1"}, + {"attr_name":"psu_p_out", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x96", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_v_out", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x8b", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_i_out", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x8c", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_p_in", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x97", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_v_in", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x88", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_i_in", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x89", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_fan1_speed_rpm", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x90", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_temp1_input", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0x8e", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_temp1_high_threshold", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0xc0", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_v_out_max", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0xa5", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_v_out_min", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0xa4", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_p_out_max", "attr_devaddr":"0x5a", "attr_devtype":"pmbus", "attr_offset":"0xa7", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"} + ] + } + }, + "PSU1-EEPROM": + { + "dev_info": {"device_type": "EEPROM", "device_name": "PSU1-EEPROM", "device_parent": "MUX6"}, + "i2c": + { + "topo_info": {"parent_bus": "0x2a", "dev_addr": "0x52", "dev_type": "24lc64t"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + + "PSU2": + { + "dev_info": { "device_type":"PSU", "device_name":"PSU2", "device_parent":"MUX6"}, + "dev_attr": { "dev_idx":"2", "num_psu_fans": "1"}, + "i2c": + { + "interface": + [ + { "itf":"pmbus", "dev":"PSU2-PMBUS" } + ] + } + }, + "PSU2-PMBUS": + { + "dev_info": { "device_type":"PSU-PMBUS", "device_name":"PSU2-PMBUS", "device_parent":"MUX6", "virt_parent":"PSU2" }, + "i2c": + { + "topo_info":{ "parent_bus":"0x2b", "dev_addr":"0x5b", "dev_type":"psu_pmbus"}, + "attr_list": + [ + {"attr_name":"psu_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0x60", "attr_mask":"0x04", "attr_cmpval":"0x00", "attr_len":"1"}, + {"attr_name":"psu_power_good", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0x60", "attr_mask":"0x01", "attr_cmpval":"0x01", "attr_len":"1"}, + {"attr_name":"psu_model_name", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"17"}, + {"attr_name":"psu_serial_num", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x9e", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"13"}, + {"attr_name":"psu_mfr_id", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x99", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"7"}, + {"attr_name":"psu_fan_dir", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0x00", "attr_len":"1"}, + {"attr_name":"psu_p_out", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x96", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_v_out", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x8b", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_i_out", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x8c", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_p_in", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x97", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_v_in", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x88", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_i_in", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x89", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_fan1_speed_rpm", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x90", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_temp1_input", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x8e", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_temp1_high_threshold", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0xc0", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_v_out_max", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0xa5", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_v_out_min", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0xa4", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, + {"attr_name":"psu_p_out_max", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0xa7", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"} + ] + } + }, + "PSU2-EEPROM": + { + "dev_info": {"device_type": "EEPROM", "device_name": "PSU2-EEPROM", "device_parent": "MUX6"}, + "i2c": + { + "topo_info": {"parent_bus": "0x2b", "dev_addr": "0x53", "dev_type": "24lc64t"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + + "FANTRAY1_EEPROM": + { + "dev_info": {"device_type": "EEPROM", "device_name": "FANTRAY1_EEPROM", "device_parent": "MUX7"}, + "i2c": + { + "topo_info": {"parent_bus": "0x32", "dev_addr": "0x50", "dev_type": "24c64"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + "FANTRAY2_EEPROM": + { + "dev_info": {"device_type": "EEPROM", "device_name": "FANTRAY2_EEPROM", "device_parent": "MUX7"}, + "i2c": + { + "topo_info": {"parent_bus": "0x33", "dev_addr": "0x50", "dev_type": "24c64"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + "FANTRAY3_EEPROM": + { + "dev_info": {"device_type": "EEPROM", "device_name": "FANTRAY3_EEPROM", "device_parent": "MUX7"}, + "i2c": + { + "topo_info": {"parent_bus": "0x35", "dev_addr": "0x50", "dev_type": "24c64"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + "FANTRAY4_EEPROM": + { + "dev_info": {"device_type": "EEPROM", "device_name": "FANTRAY4_EEPROM", "device_parent": "MUX7"}, + "i2c": + { + "topo_info": {"parent_bus": "0x36", "dev_addr": "0x50", "dev_type": "24c64"}, + "dev_attr": {"access_mode": "BLOCK"}, + "attr_list": [ + {"attr_name": "eeprom"} + ] + } + }, + + "FAN-CTRL": + { + "dev_info": { "device_type":"FAN", "device_name":"FAN-CTRL", "device_parent":"FPGAPCIE0"}, + "i2c": + { + "topo_info": { "parent_bus":"0x69", "dev_addr":"0x16", "dev_type":"fan_cpld"}, + "dev_attr": { "num_fantrays":"4"}, + "attr_list": + [ + {"attr_name":"fan1_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb4", "attr_mask":"0x01", "attr_cmpval": "0x1", "attr_len":"1"}, + {"attr_name":"fan2_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb4", "attr_mask":"0x01", "attr_cmpval": "0x1", "attr_len":"1"}, + {"attr_name":"fan3_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xba", "attr_mask":"0x01", "attr_cmpval": "0x1", "attr_len":"1"}, + {"attr_name":"fan4_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xba", "attr_mask":"0x01", "attr_cmpval": "0x1", "attr_len":"1"}, + {"attr_name":"fan5_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc6", "attr_mask":"0x01", "attr_cmpval": "0x1", "attr_len":"1"}, + {"attr_name":"fan6_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc6", "attr_mask":"0x01", "attr_cmpval": "0x1", "attr_len":"1"}, + {"attr_name":"fan7_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xcc", "attr_mask":"0x01", "attr_cmpval": "0x1", "attr_len":"1"}, + {"attr_name":"fan8_present", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xcc", "attr_mask":"0x01", "attr_cmpval": "0x1", "attr_len":"1"}, + {"attr_name":"fan1_direction", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb4", "attr_mask":"0x02", "attr_cmpval": "0x2", "attr_len":"1"}, + {"attr_name":"fan2_direction", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb4", "attr_mask":"0x02", "attr_cmpval": "0x2", "attr_len":"1"}, + {"attr_name":"fan3_direction", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xba", "attr_mask":"0x02", "attr_cmpval": "0x2", "attr_len":"1"}, + {"attr_name":"fan4_direction", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xba", "attr_mask":"0x02", "attr_cmpval": "0x2", "attr_len":"1"}, + {"attr_name":"fan5_direction", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc6", "attr_mask":"0x02", "attr_cmpval": "0x2", "attr_len":"1"}, + {"attr_name":"fan6_direction", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc6", "attr_mask":"0x02", "attr_cmpval": "0x2", "attr_len":"1"}, + {"attr_name":"fan7_direction", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xcc", "attr_mask":"0x02", "attr_cmpval": "0x2", "attr_len":"1"}, + {"attr_name":"fan8_direction", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xcc", "attr_mask":"0x02", "attr_cmpval": "0x2", "attr_len":"1"}, + {"attr_name":"fan1_input", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb0", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"120", "attr_is_divisor":0}, + {"attr_name":"fan2_input", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb1", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"120", "attr_is_divisor":0}, + {"attr_name":"fan3_input", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb6", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"120", "attr_is_divisor":0}, + {"attr_name":"fan4_input", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb7", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"120", "attr_is_divisor":0}, + {"attr_name":"fan5_input", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc2", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"120", "attr_is_divisor":0}, + {"attr_name":"fan6_input", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc3", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"120", "attr_is_divisor":0}, + {"attr_name":"fan7_input", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc8", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"120", "attr_is_divisor":0}, + {"attr_name":"fan8_input", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc9", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"120", "attr_is_divisor":0}, + {"attr_name":"fan1_pwm", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb2", "attr_mask":"0xff", "attr_cmpval": "0x0","attr_len":"1"}, + {"attr_name":"fan2_pwm", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb2", "attr_mask":"0xff", "attr_cmpval": "0x0","attr_len":"1"}, + {"attr_name":"fan3_pwm", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb8", "attr_mask":"0xff", "attr_cmpval": "0x0","attr_len":"1"}, + {"attr_name":"fan4_pwm", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xb8", "attr_mask":"0xff", "attr_cmpval": "0x0","attr_len":"1"}, + {"attr_name":"fan5_pwm", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc4", "attr_mask":"0xff", "attr_cmpval": "0x0","attr_len":"1"}, + {"attr_name":"fan6_pwm", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xc4", "attr_mask":"0xff", "attr_cmpval": "0x0","attr_len":"1"}, + {"attr_name":"fan7_pwm", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xca", "attr_mask":"0xff", "attr_cmpval": "0x0","attr_len":"1"}, + {"attr_name":"fan8_pwm", "attr_devaddr":"0x0d", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "attr_offset":"0xca", "attr_mask":"0xff", "attr_cmpval": "0x0","attr_len":"1"} + ] + } + }, + + "FANTRAY1_LED": + { + "dev_info": { "device_type":"LED", "device_name":"FANTRAY_LED"}, + "dev_attr": { "index":"0"}, + "i2c" : { + "attr_list": + [ + {"attr_name":"off","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Off","value":"0x03","swpld_addr":"0x0d","swpld_addr_offset":"0xb3"}, + {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Green","value":"0x02","swpld_addr":"0x0d","swpld_addr_offset":"0xb3"}, + {"attr_name":"amber","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Amber","value":"0x01","swpld_addr":"0x0d","swpld_addr_offset":"0xb3"} + ] + } + }, + "FANTRAY2_LED": + { + "dev_info": { "device_type":"LED", "device_name":"FANTRAY_LED"}, + "dev_attr": { "index":"1"}, + "i2c" : { + "attr_list": + [ + {"attr_name":"off","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Off","value":"0x03","swpld_addr":"0x0d","swpld_addr_offset":"0xb9"}, + {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Green","value":"0x02","swpld_addr":"0x0d","swpld_addr_offset":"0xb9"}, + {"attr_name":"amber","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Amber","value":"0x01","swpld_addr":"0x0d","swpld_addr_offset":"0xb9"} + ] + } + }, + "FANTRAY3_LED": + { + "dev_info": { "device_type":"LED", "device_name":"FANTRAY_LED"}, + "dev_attr": { "index":"2"}, + "i2c" : { + "attr_list": + [ + {"attr_name":"off","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Off","value":"0x03","swpld_addr":"0x0d","swpld_addr_offset":"0xbf"}, + {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Green","value":"0x02","swpld_addr":"0x0d","swpld_addr_offset":"0xbf"}, + {"attr_name":"amber","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Amber","value":"0x01","swpld_addr":"0x0d","swpld_addr_offset":"0xbf"} + ] + } + }, + "FANTRAY4_LED": + { + "dev_info": { "device_type":"LED", "device_name":"FANTRAY_LED"}, + "dev_attr": { "index":"3"}, + "i2c" : { + "attr_list": + [ + {"attr_name":"off","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Off","value":"0x03","swpld_addr":"0x0d","swpld_addr_offset":"0xc5"}, + {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Green","value":"0x02","swpld_addr":"0x0d","swpld_addr_offset":"0xc5"}, + {"attr_name":"amber","attr_devtype":"cpld","attr_devname":"CPLD_BASEBOARD","bits":"1:0","descr":"Amber","value":"0x01","swpld_addr":"0x0d","swpld_addr_offset":"0xc5"} + ] + } + }, + + "PSU_LED": + { + "dev_info": { "device_type":"LED", "device_name":"PSU_LED"}, + "dev_attr": { "index":"0", "flag": "rw"}, + "i2c" : { + "attr_list": + [ + {"attr_name":"green", "descr": "Green", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "bits" : "7:6", "value" : "0x1", "swpld_addr" : "0x0d", "swpld_addr_offset" : "0x61"}, + {"attr_name":"amber", "descr": "Amber", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "bits" : "7:6", "value" : "0x2", "swpld_addr" : "0x0d", "swpld_addr_offset" : "0x61"}, + {"attr_name":"off", "descr": "Off", "attr_devtype":"cpld", "attr_devname":"CPLD_BASEBOARD", "bits" : "7:6", "value" : "0x3", "swpld_addr" : "0x0d", "swpld_addr_offset" : "0x61"} + ] + } + } +} diff --git a/device/celestica/x86_64-cel_ds3000-r0/pddf_support b/device/celestica/x86_64-cel_ds3000-r0/pddf_support new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/device/celestica/x86_64-cel_ds3000-r0/platform.json b/device/celestica/x86_64-cel_ds3000-r0/platform.json new file mode 100644 index 000000000000..2fd40e3b05a5 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/platform.json @@ -0,0 +1,559 @@ +{ + "chassis": { + "name": "DS3000", + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "Fantray1_1", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray1_2", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray2_1", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray2_2", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray3_1", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray3_2", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray4_1", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray4_2", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + } + ], + "fan_drawers": [ + { + "name": "Fantray1", + "status_led": { + "controllable": true, + "colors": ["red", "green", "amber", "off"] + }, + "fans": [ + { + "name": "Fantray1_1", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray1_2", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + } + ] + }, + { + "name": "Fantray2", + "status_led": { + "controllable": true, + "colors": ["red", "green", "amber", "off"] + }, + "fans": [ + { + "name": "Fantray2_1", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray2_2", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + } + ] + }, + { + "name": "Fantray3", + "status_led": { + "controllable": true, + "colors": ["red", "green", "amber", "off"] + }, + "fans": [ + { + "name": "Fantray3_1", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray3_2", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + } + ] + }, + { + "name": "Fantray4", + "status_led": { + "controllable": true, + "colors": ["red", "green", "amber", "off"] + }, + "fans": [ + { + "name": "Fantray4_1", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + }, + { + "name": "Fantray4_2", + "status_led": { + "controllable": false + }, + "speed": { + "controllable": false + } + } + ] + } + ], + "psus": [ + { + "name": "PSU 1", + "status_led": { + "controllable": true, + "colors": ["green", "off"] + }, + "fans": [ + { + "name": "PSU1_FAN1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "PSU 2", + "status_led": { + "controllable": true, + "colors": ["green", "off"] + }, + "fans": [ + { + "name": "PSU2_FAN1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + } + ] + } + ] + }, + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "1,2,3,4", + "breakout_modes": { + "1x100G": ["Eth1/1/1"], + "1x40G": ["Eth1/1/1"], + "4x25G": ["Eth1/1/1", "Eth1/1/2", "Eth1/1/3", "Eth1/1/4"], + "4x10G": ["Eth1/1/1", "Eth1/1/2", "Eth1/1/3", "Eth1/1/4"] + } + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "5,6,7,8", + "breakout_modes": { + "1x100G": ["Eth1/2/1"], + "1x40G": ["Eth1/2/1"], + "4x25G": ["Eth1/2/1", "Eth1/2/2", "Eth1/2/3", "Eth1/2/4"], + "4x10G": ["Eth1/2/1", "Eth1/2/2", "Eth1/2/3", "Eth1/2/4"] + } + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "9,10,11,12", + "breakout_modes": { + "1x100G": ["Eth1/3/1"], + "1x40G": ["Eth1/3/1"], + "4x25G": ["Eth1/3/1", "Eth1/3/2", "Eth1/3/3", "Eth1/3/4"], + "4x10G": ["Eth1/3/1", "Eth1/3/2", "Eth1/3/3", "Eth1/3/4"] + } + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "13,14,15,16", + "breakout_modes": { + "1x100G": ["Eth1/4/1"], + "1x40G": ["Eth1/4/1"], + "4x25G": ["Eth1/4/1", "Eth1/4/2", "Eth1/4/3", "Eth1/4/4"], + "4x10G": ["Eth1/4/1", "Eth1/4/2", "Eth1/4/3", "Eth1/4/4"] + } + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "17,18,19,20", + "breakout_modes": { + "1x100G": ["Eth1/5/1"], + "1x40G": ["Eth1/5/1"], + "4x25G": ["Eth1/5/1", "Eth1/5/2", "Eth1/5/3", "Eth1/5/4"], + "4x10G": ["Eth1/5/1", "Eth1/5/2", "Eth1/5/3", "Eth1/5/4"] + } + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "21,22,23,24", + "breakout_modes": { + "1x100G": ["Eth1/6/1"], + "1x40G": ["Eth1/6/1"], + "4x25G": ["Eth1/6/1", "Eth1/6/2", "Eth1/6/3", "Eth1/6/4"], + "4x10G": ["Eth1/6/1", "Eth1/6/2", "Eth1/6/3", "Eth1/6/4"] + } + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "25,26,27,28", + "breakout_modes": { + "1x100G": ["Eth1/7/1"], + "1x40G": ["Eth1/7/1"], + "4x25G": ["Eth1/7/1", "Eth1/7/2", "Eth1/7/3", "Eth1/7/4"], + "4x10G": ["Eth1/7/1", "Eth1/7/2", "Eth1/7/3", "Eth1/7/4"] + } + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "29,30,31,32", + "breakout_modes": { + "1x100G": ["Eth1/8/1"], + "1x40G": ["Eth1/8/1"], + "4x25G": ["Eth1/8/1", "Eth1/8/2", "Eth1/8/3", "Eth1/8/4"], + "4x10G": ["Eth1/8/1", "Eth1/8/2", "Eth1/8/3", "Eth1/8/4"] + } + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "33,34,35,36", + "breakout_modes": { + "1x100G": ["Eth1/9/1"], + "1x40G": ["Eth1/9/1"], + "4x25G": ["Eth1/9/1", "Eth1/9/2", "Eth1/9/3", "Eth1/9/4"], + "4x10G": ["Eth1/9/1", "Eth1/9/2", "Eth1/9/3", "Eth1/9/4"] + } + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "37,38,39,40", + "breakout_modes": { + "1x100G": ["Eth1/10/1"], + "1x40G": ["Eth1/10/1"], + "4x25G": ["Eth1/10/1", "Eth1/10/2", "Eth1/10/3", "Eth1/10/4"], + "4x10G": ["Eth1/10/1", "Eth1/10/2", "Eth1/10/3", "Eth1/10/4"] + } + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "41,42,43,44", + "breakout_modes": { + "1x100G": ["Eth1/11/1"], + "1x40G": ["Eth1/11/1"], + "4x25G": ["Eth1/11/1", "Eth1/11/2", "Eth1/11/3", "Eth1/11/4"], + "4x10G": ["Eth1/11/1", "Eth1/11/2", "Eth1/11/3", "Eth1/11/4"] + } + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "45,46,47,48", + "breakout_modes": { + "1x100G": ["Eth1/12/1"], + "1x40G": ["Eth1/12/1"], + "4x25G": ["Eth1/12/1", "Eth1/12/2", "Eth1/12/3", "Eth1/12/4"], + "4x10G": ["Eth1/12/1", "Eth1/12/2", "Eth1/12/3", "Eth1/12/4"] + } + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "49,50,51,52", + "breakout_modes": { + "1x100G": ["Eth1/13/1"], + "1x40G": ["Eth1/13/1"], + "4x25G": ["Eth1/13/1", "Eth1/13/2", "Eth1/13/3", "Eth1/13/4"], + "4x10G": ["Eth1/13/1", "Eth1/13/2", "Eth1/13/3", "Eth1/13/4"] + } + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "53,54,55,56", + "breakout_modes": { + "1x100G": ["Eth1/14/1"], + "1x40G": ["Eth1/14/1"], + "4x25G": ["Eth1/14/1", "Eth1/14/2", "Eth1/14/3", "Eth1/14/4"], + "4x10G": ["Eth1/14/1", "Eth1/14/2", "Eth1/14/3", "Eth1/14/4"] + } + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "57,58,59,60", + "breakout_modes": { + "1x100G": ["Eth1/15/1"], + "1x40G": ["Eth1/15/1"], + "4x25G": ["Eth1/15/1", "Eth1/15/2", "Eth1/15/3", "Eth1/15/4"], + "4x10G": ["Eth1/15/1", "Eth1/15/2", "Eth1/15/3", "Eth1/15/4"] + } + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "61,62,63,64", + "breakout_modes": { + "1x100G": ["Eth1/16/1"], + "1x40G": ["Eth1/16/1"], + "4x25G": ["Eth1/16/1", "Eth1/16/2", "Eth1/16/3", "Eth1/16/4"], + "4x10G": ["Eth1/16/1", "Eth1/16/2", "Eth1/16/3", "Eth1/16/4"] + } + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "65,66,67,68", + "breakout_modes": { + "1x100G": ["Eth1/17/1"], + "1x40G": ["Eth1/17/1"], + "4x25G": ["Eth1/17/1", "Eth1/17/2", "Eth1/17/3", "Eth1/17/4"], + "4x10G": ["Eth1/17/1", "Eth1/17/2", "Eth1/17/3", "Eth1/17/4"] + } + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "69,70,71,72", + "breakout_modes": { + "1x100G": ["Eth1/18/1"], + "1x40G": ["Eth1/18/1"], + "4x25G": ["Eth1/18/1", "Eth1/18/2", "Eth1/18/3", "Eth1/18/4"], + "4x10G": ["Eth1/18/1", "Eth1/18/2", "Eth1/18/3", "Eth1/18/4"] + } + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "73,74,75,76", + "breakout_modes": { + "1x100G": ["Eth1/19/1"], + "1x40G": ["Eth1/19/1"], + "4x25G": ["Eth1/19/1", "Eth1/19/2", "Eth1/19/3", "Eth1/19/4"], + "4x10G": ["Eth1/19/1", "Eth1/19/2", "Eth1/19/3", "Eth1/19/4"] + } + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "77,78,79,80", + "breakout_modes": { + "1x100G": ["Eth1/20/1"], + "1x40G": ["Eth1/20/1"], + "4x25G": ["Eth1/20/1", "Eth1/20/2", "Eth1/20/3", "Eth1/20/4"], + "4x10G": ["Eth1/20/1", "Eth1/20/2", "Eth1/20/3", "Eth1/20/4"] + } + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "81,82,83,84", + "breakout_modes": { + "1x100G": ["Eth1/21/1"], + "1x40G": ["Eth1/21/1"], + "4x25G": ["Eth1/21/1", "Eth1/21/2", "Eth1/21/3", "Eth1/21/4"], + "4x10G": ["Eth1/21/1", "Eth1/21/2", "Eth1/21/3", "Eth1/21/4"] + } + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "85,86,87,88", + "breakout_modes": { + "1x100G": ["Eth1/22/1"], + "1x40G": ["Eth1/22/1"], + "4x25G": ["Eth1/22/1", "Eth1/22/2", "Eth1/22/3", "Eth1/22/4"], + "4x10G": ["Eth1/22/1", "Eth1/22/2", "Eth1/22/3", "Eth1/22/4"] + } + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "89,90,91,92", + "breakout_modes": { + "1x100G": ["Eth1/23/1"], + "1x40G": ["Eth1/23/1"], + "4x25G": ["Eth1/23/1", "Eth1/23/2", "Eth1/23/3", "Eth1/23/4"], + "4x10G": ["Eth1/23/1", "Eth1/23/2", "Eth1/23/3", "Eth1/23/4"] + } + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "93,94,95,96", + "breakout_modes": { + "1x100G": ["Eth1/24/1"], + "1x40G": ["Eth1/24/1"], + "4x25G": ["Eth1/24/1", "Eth1/24/2", "Eth1/24/3", "Eth1/24/4"], + "4x10G": ["Eth1/24/1", "Eth1/24/2", "Eth1/24/3", "Eth1/24/4"] + } + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "97,98,99,100", + "breakout_modes": { + "1x100G": ["Eth1/25/1"], + "1x40G": ["Eth1/25/1"], + "4x25G": ["Eth1/25/1", "Eth1/25/2", "Eth1/25/3", "Eth1/25/4"], + "4x10G": ["Eth1/25/1", "Eth1/25/2", "Eth1/25/3", "Eth1/25/4"] + } + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "101,102,103,104", + "breakout_modes": { + "1x100G": ["Eth1/26/1"], + "1x40G": ["Eth1/26/1"], + "4x25G": ["Eth1/26/1", "Eth1/26/2", "Eth1/26/3", "Eth1/26/4"], + "4x10G": ["Eth1/26/1", "Eth1/26/2", "Eth1/26/3", "Eth1/26/4"] + } + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "105,106,107,108", + "breakout_modes": { + "1x100G": ["Eth1/27/1"], + "1x40G": ["Eth1/27/1"], + "4x25G": ["Eth1/27/1", "Eth1/27/2", "Eth1/27/3", "Eth1/27/4"], + "4x10G": ["Eth1/27/1", "Eth1/27/2", "Eth1/27/3", "Eth1/27/4"] + } + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "109,110,111,112", + "breakout_modes": { + "1x100G": ["Eth1/28/1"], + "1x40G": ["Eth1/28/1"], + "4x25G": ["Eth1/28/1", "Eth1/28/2", "Eth1/28/3", "Eth1/28/4"], + "4x10G": ["Eth1/28/1", "Eth1/28/2", "Eth1/28/3", "Eth1/28/4"] + } + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "113,114,115,116", + "breakout_modes": { + "1x100G": ["Eth1/29/1"], + "1x40G": ["Eth1/29/1"], + "4x25G": ["Eth1/29/1", "Eth1/29/2", "Eth1/29/3", "Eth1/29/4"], + "4x10G": ["Eth1/29/1", "Eth1/29/2", "Eth1/29/3", "Eth1/29/4"] + } + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "117,118,119,120", + "breakout_modes": { + "1x100G": ["Eth1/30/1"], + "1x40G": ["Eth1/30/1"], + "4x25G": ["Eth1/30/1", "Eth1/30/2", "Eth1/30/3", "Eth1/30/4"], + "4x10G": ["Eth1/30/1", "Eth1/30/2", "Eth1/30/3", "Eth1/30/4"] + } + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "121,122,123,124", + "breakout_modes": { + "1x100G": ["Eth1/31/1"], + "1x40G": ["Eth1/31/1"], + "4x25G": ["Eth1/31/1", "Eth1/31/2", "Eth1/31/3", "Eth1/31/4"], + "4x10G": ["Eth1/31/1", "Eth1/31/2", "Eth1/31/3", "Eth1/31/4"] + } + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "125,126,127,128", + "breakout_modes": { + "1x100G": ["Eth1/32/1"], + "1x40G": ["Eth1/32/1"], + "4x25G": ["Eth1/32/1", "Eth1/32/2", "Eth1/32/3", "Eth1/32/4"], + "4x10G": ["Eth1/32/1", "Eth1/32/2", "Eth1/32/3", "Eth1/32/4"] + } + }, + "Ethernet128": { + "index": "33", + "lanes": "129", + "breakout_modes": { + "1x10G": ["Eth1/33"] + } + } + } +} diff --git a/device/celestica/x86_64-cel_ds3000-r0/platform_asic b/device/celestica/x86_64-cel_ds3000-r0/platform_asic new file mode 100644 index 000000000000..960467652765 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/platform_asic @@ -0,0 +1 @@ +broadcom diff --git a/device/celestica/x86_64-cel_ds3000-r0/platform_components.json b/device/celestica/x86_64-cel_ds3000-r0/platform_components.json new file mode 100644 index 000000000000..614bf3b1d315 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/platform_components.json @@ -0,0 +1,17 @@ +{ + "chassis": { + "DS3000": { + "component": { + "BIOS": {}, + "BMC": {}, + "BaseBoard_CPLD": {}, + "SwitchBoard_CPLD1": {}, + "SwitchBoard_CPLD2": {}, + "COMeBoard_CPLD": {}, + "FPGA": {}, + "PCIe": {}, + "SSD": {} + } + } + } +} diff --git a/device/celestica/x86_64-cel_ds3000-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_ds3000-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..5e59513ef696 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/pmon_daemon_control.json @@ -0,0 +1,7 @@ +{ + "skip_ledd": true, + "skip_xcvrd": false, + "skip_psud": false, + "skip_syseepromd": false, + "skip_fancontrol": true +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_ds3000-r0/sensors.conf b/device/celestica/x86_64-cel_ds3000-r0/sensors.conf new file mode 100644 index 000000000000..8d441077a677 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/sensors.conf @@ -0,0 +1,87 @@ +# LM75B temperature sensors +bus "i2c-109" "i2c-pci-9" + chip "lm75-i2c-109-4a" + label temp1 "Switchboard U28 Sensor Temp" + set temp1_max 60 + set temp1_max_hyst 57 + chip "lm75-i2c-109-4b" + label temp1 "Switchboard U29 Sensor Temp" + set temp1_max 60 + set temp1_max_hyst 57 + chip "lm75-i2c-109-4c" + label temp1 "Switchboard U17 Sensor Temp" + chip "lm75-i2c-109-49" + label temp1 "Switchboard U18 Sensor Temp" + chip "lm75-i2c-109-4d" + label temp1 "Baseboard U5 Sensor Temp" + set temp1_max 55 + set temp1_max_hyst 52 + chip "lm75-i2c-109-4e" + label temp1 "Baseboard U56 Sensor Temp" + set temp1_max 55 + set temp1_max_hyst 52 + +# PSU +bus "i2c-43" "i2c-106-mux (chan_id 1)" + chip "psu_pmbus-i2c-43-5b" + label in3 "PSU2 input voltage" + label fan1 "PSU2 FAN speed" + label temp1 "PSU2 temperature" + label power2 "PSU2 AC Power Voltage" + label curr2 "PSU2 AC current" + +bus "i2c-42" "i2c-106-mux (chan_id 0)" + chip "psu_pmbus-i2c-42-5a" + label in3 "PSU1 input voltage" + label fan1 "PSU1 FAN speed" + label temp1 "PSU1 temperature" + label power2 "PSU1 AC Power Voltage" + label curr2 "PSU1 AC current" + +# MP2975 power chip +bus "i2c-108" "i2c-pci-8" + chip "mp2975-i2c-108-70" + label in1 "VDD ANLG input voltage" + label in2 "VDD ANLG output voltage" + label in3 "VDD ANLG output voltage" + label temp1 "VDD ANLG temperature" + label power1 "VDD ANLG input power" + label power2 "VDD ANLG output power" + label power3 "VDD ANLG output power" + label curr1 "VDD ANLG input current" + label curr2 "VDD ANLG output current" + label curr3 "VDD ANLG output current" + label curr4 "VDD ANLG output current" + label curr5 "VDD ANLG output current" + +bus "i2c-108" "i2c-pci-8" + chip "mp2975-i2c-108-7a" + label in1 "VDD CORE input voltage" + label in2 "VDD CORE output voltage" + label in3 "VDD CORE output voltage" + label temp1 "VDD CORE temperature" + label power1 "VDD CORE input power" + label power2 "VDD CORE output power" + label power3 "VDD CORE output power" + label curr1 "VDD CORE input current" + label curr2 "VDD CORE output current" + label curr3 "VDD CORE output current" + label curr4 "VDD CORE output current" + label curr5 "VDD CORE output current" + label curr6 "VDD CORE output current" + label curr7 "VDD CORE output current" + label curr8 "VDD CORE output current" + label curr9 "VDD CORE output current" + label curr10 "VDD CORE output current" + +# CPLD FAN +bus "i2c-105" "i2c-pci-5" + chip "fan_cpld-i2c-105-16" + label fan1 "FAN1 Front Fan" + label fan2 "FAN1 Rear Fan" + label fan3 "FAN2 Front Fan" + label fan4 "FAN2 Rear Fan" + label fan5 "FAN3 Front Fan" + label fan6 "FAN3 Rear Fan" + label fan7 "FAN4 Front Fan" + label fan8 "FAN4 Rear Fan" diff --git a/device/celestica/x86_64-cel_ds3000-r0/system_health_monitoring_config.json b/device/celestica/x86_64-cel_ds3000-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..42152ac3dc54 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/system_health_monitoring_config.json @@ -0,0 +1,14 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [ + "psu.temperature", + "psu.voltage" + ], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "amber", + "normal": "green", + "booting": "amber_blink" + } +} diff --git a/device/celestica/x86_64-cel_ds3000-r0/thermal_policy.json b/device/celestica/x86_64-cel_ds3000-r0/thermal_policy.json new file mode 100644 index 000000000000..515348ec6ab0 --- /dev/null +++ b/device/celestica/x86_64-cel_ds3000-r0/thermal_policy.json @@ -0,0 +1,136 @@ +{ + "interval": 4, + "thermal_control_algorithm": { + "run_at_boot_up": "True", + "fan_speed_when_suspend": "50" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "psu_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 fantray absence", + "conditions": [ + { + "type": "fantray.any.absence" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "more than one fan rotor failed", + "conditions": [ + { + "type": "fan.rotor.more_than_one.failed" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any psu absence", + "conditions": [ + { + "type": "psu.any.absence" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any thermal over high threshold", + "conditions": [ + { + "type": "thermal.any.over.high_threshold" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any thermal below high threshold", + "conditions": [ + { + "type": "thermal.any.below.low_threshold" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "10" + } + ] + }, + { + "name": "thermal control algorithm", + "conditions": [ + { + "type": "fantray.all.presence" + }, + { + "type": "fan.rotor.less_than_two.failed" + }, + { + "type": "psu.all.presence" + }, + { + "type": "thermal.all.below.high_threshold" + }, + { + "type": "thermal.all.over.low_threshold" + } + ], + "actions": [ + { + "thermal_log_level": 5, + "type": "thermal.temp_check_and_fsc_algo_control", + "cpu_pid_params": [78, 3, 0.5, 0.2], + "bcm_pid_params": [88, 4, 0.3, 0.4], + "f2b_linear_params": [34, 54, 3, 35, 100], + "b2f_linear_params": [27, 48, 3, 35, 100] + } + ] + } + ] +} diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index c9660299ed7e..150dfc7c2838 100755 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -55,6 +55,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(CEL_HALIBURTON_PLATFORM_MODULE) \ $(CEL_SEASTONE2_PLATFORM_MODULE) \ $(CEL_BELGITE_PLATFORM_MODULE) \ + $(CEL_DS3000_PLATFORM_MODULE) \ $(DELTA_AG9032V1_PLATFORM_MODULE) \ $(DELTA_AG9064_PLATFORM_MODULE) \ $(DELTA_AG5648_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index b25aeb7c0900..61c015914ff2 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -5,12 +5,14 @@ CEL_HALIBURTON_PLATFORM_MODULE_VERSION = 0.9 CEL_SEASTONE2_PLATFORM_MODULE_VERSION = 0.9 CEL_SILVERSTONE_PLATFORM_MODULE_VERSION = 0.9 CEL_BELGITE_PLATFORM_MODULE_VERSION = 0.9 +CEL_DS3000_PLATFORM_MODULE_VERSION = 0.9 export CEL_DX010_PLATFORM_MODULE_VERSION export CEL_HALIBURTON_PLATFORM_MODULE_VERSION export CEL_SEASTONE2_PLATFORM_MODULE_VERSION export CEL_SILVERSTONE_PLATFORM_MODULE_VERSION export CEL_BELGITE_PLATFORM_MODULE_VERSION +export CEL_DS3000_PLATFORM_MODULE_VERSION CEL_DX010_PLATFORM_MODULE = platform-modules-dx010_$(CEL_DX010_PLATFORM_MODULE_VERSION)_amd64.deb $(CEL_DX010_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cel @@ -33,3 +35,7 @@ $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_SILVERSTONE_P CEL_BELGITE_PLATFORM_MODULE = platform-modules-belgite_$(CEL_BELGITE_PLATFORM_MODULE_VERSION)_amd64.deb $(CEL_BELGITE_PLATFORM_MODULE)_PLATFORM = x86_64-cel_belgite-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_BELGITE_PLATFORM_MODULE))) + +CEL_DS3000_PLATFORM_MODULE = platform-modules-ds3000_$(CEL_DS3000_PLATFORM_MODULE_VERSION)_amd64.deb +$(CEL_DS3000_PLATFORM_MODULE)_PLATFORM = x86_64-cel_ds3000-r0 +$(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_DS3000_PLATFORM_MODULE))) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 0dd6eb76e00e..d9eced051abb 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -30,3 +30,8 @@ Package: platform-modules-belgite Architecture: amd64 Depends: linux-image-6.1.0-11-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp + +Package: platform-modules-ds3000 +Architecture: amd64 +Depends: linux-image-6.1.0-11-2-amd64-unsigned +Description: kernel modules for platform devices such as led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds3000.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds3000.install new file mode 100644 index 000000000000..88c82ba4fb92 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds3000.install @@ -0,0 +1,8 @@ +ds3000/systemd/pddf-platform-init.service etc/systemd/system +ds3000/pddf/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-cel_ds3000-r0/pddf +ds3000/scripts/pre_pddf_init.sh usr/local/bin +ds3000/scripts/pddf_pre_driver_install.sh usr/local/bin +ds3000/scripts/pddf_post_device_create.sh usr/local/bin +ds3000/utils/afulnx_64 usr/local/bin +ds3000/utils/fpga_prog usr/local/bin +ds3000/utils/ispvm usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds3000.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds3000.postinst new file mode 100644 index 000000000000..f8b021b6248a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds3000.postinst @@ -0,0 +1,4 @@ +depmod -a + +systemctl enable pddf-platform-init.service +systemctl start pddf-platform-init.service diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules index 7c81e2496f1d..21b8b1880795 100755 --- a/platform/broadcom/sonic-platform-modules-cel/debian/rules +++ b/platform/broadcom/sonic-platform-modules-cel/debian/rules @@ -6,7 +6,7 @@ export KBUILD_EXTRA_SYMBOLS := /sonic/platform/pddf/i2c/Module.symvers.PDDF KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= dx010 haliburton silverstone seastone2 belgite +MODULE_DIRS:= dx010 haliburton silverstone seastone2 belgite ds3000 %: dh $@ @@ -19,15 +19,13 @@ override_dh_auto_build: python3 -m build --wheel --no-isolation --outdir $(MOD_SRC_DIR)/$${mod}/modules; \ continue; \ fi; \ - if [ $$mod = "belgite" ]; then \ - cd $(MOD_SRC_DIR); \ - if [ -d $(MOD_SRC_DIR)/$${mod}/pddf ]; then \ - cd $(MOD_SRC_DIR)/$${mod}/pddf; \ - python3 -m build --wheel --no-isolation --outdir $(MOD_SRC_DIR)/$${mod}/pddf; \ - echo "Finished making pddf whl package for $$mod"; \ - fi; \ - continue; \ - fi; \ + cd $(MOD_SRC_DIR); \ + if [ -d $(MOD_SRC_DIR)/$${mod}/pddf ]; then \ + cd $(MOD_SRC_DIR)/$${mod}/pddf; \ + python3 -m build --wheel --no-isolation --outdir $(MOD_SRC_DIR)/$${mod}/pddf; \ + echo "Finished making pddf whl package for $$mod"; \ + continue; \ + fi; \ cd $(MOD_SRC_DIR)/$${mod}; \ python3 -m build --wheel --no-isolation --outdir $(MOD_SRC_DIR)/$${mod}/modules; \ done) diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/Makefile new file mode 100644 index 000000000000..031e2163cf52 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/Makefile @@ -0,0 +1,8 @@ +LED_TARGET:= pddf_custom_led_module +$(LED_TARGET)-objs := ./led_driver/pddf_custom_led_module.o + +PSU_TARGET:= pddf_custom_psu_driver_module +$(PSU_TARGET)-objs := ./psu_driver/pddf_psu_api.o ./psu_driver/pddf_psu_driver.o + +obj-m := lm75.o mc24lc64t.o baseboard_cpld.o pddf_custom_fpga_algo.o pddf_custom_fpga_extend.o +obj-m += $(LED_TARGET).o $(PSU_TARGET).o diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/baseboard_cpld.c b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/baseboard_cpld.c new file mode 100644 index 000000000000..6107d9635438 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/baseboard_cpld.c @@ -0,0 +1,414 @@ +/* + * baseboard_cpld.c - driver for DS3000 Base Board CPLD + * This driver implement sysfs for CPLD register access using LPC bus. + * Copyright (C) 2019 Celestica Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "baseboard" +/** + * CPLD register address for read and write. + */ +#define VERSION_ADDR 0xA100 +#define SCRATCH_ADDR 0xA101 +#define SYS_LED_ADDR 0xA162 +#define CARD_PRES_ADDR 0xA108 +#define COME_CPLD_VER_ADDR 0xA1E0 + +#define CPLD_REGISTER_SIZE 0x77 + +struct baseboard_cpld_data { + struct mutex cpld_lock; + uint16_t read_addr; +}; + +struct baseboard_cpld_data *cpld_data; + +/** + * Read the value from scratch register as hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +static ssize_t scratch_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf,"0x%2.2x\n", data); +} + +/** + * Set scratch register with specific hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t scratch_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned long data; + char *last; + + mutex_lock(&cpld_data->cpld_lock); + data = (uint16_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + outb(data, SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(scratch); + + +/* CPLD version attributes */ +static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = -EIO; + // CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(VERSION_ADDR)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RO(version); + + +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // CPLD register is one byte + uint16_t addr; + char *last; + + addr = (uint16_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + cpld_data->read_addr = addr; + return count; +} + +static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = -EIO; + // CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(cpld_data->read_addr)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RW(getreg); + +static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // CPLD register is one byte + uint16_t addr; + uint8_t value; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strncpy(clone, buf, strlen(buf)-1); // nosemgrep + + mutex_lock(&cpld_data->cpld_lock); + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + addr = (uint16_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + outb(value,addr); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_WO(setreg); + +/** + * Show system led status - on/off/1hz/4hz + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +static ssize_t sys_led_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = data & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "4hz" : data ==0x01 ? "1hz": "on"); +} + +/** + * Set the status of system led - on/off/1hz/4hz + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t sys_led_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "4hz")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "1hz")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "on")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~(0x3); + data = data | led_status; + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led); + +/** + * Show system led color - both/green/yellow/none + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +static ssize_t sys_led_color_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = (data >> 4) & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "yellow" : data ==0x01 ? "green": "both"); +} + +/** + * Set the color of system led - both/green/yellow/none + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t sys_led_color_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "yellow")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "green")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "both")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~( 0x3 << 4); + data = data | (led_status << 4); + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led_color); + +/** + * Show BMC card presence + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return string absent or present of BMC card. + */ +static ssize_t bmc_presence_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(CARD_PRES_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = data & 0x1; + return sprintf(buf, "%s\n", + data == 0x01 ? "absent" : "present"); +} +static DEVICE_ATTR_RO(bmc_presence); + +/* COME CPLD version attributes */ +static ssize_t come_cpld_version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = -EIO; + // COME CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(COME_CPLD_VER_ADDR)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RO(come_cpld_version); + +static struct attribute *baseboard_cpld_attrs[] = { + &dev_attr_version.attr, + &dev_attr_scratch.attr, + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + &dev_attr_sys_led.attr, + &dev_attr_sys_led_color.attr, + &dev_attr_bmc_presence.attr, + &dev_attr_come_cpld_version.attr, + NULL, +}; + +static struct attribute_group baseboard_cpld_attrs_grp = { + .attrs = baseboard_cpld_attrs, +}; + +static struct resource baseboard_cpld_resources[] = { + { + .start = 0xA100, + .end = 0xA1FF, + .flags = IORESOURCE_IO, + }, +}; + +static void baseboard_cpld_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device baseboard_cpld_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(baseboard_cpld_resources), + .resource = baseboard_cpld_resources, + .dev = { + .release = baseboard_cpld_dev_release, + } +}; + +static int baseboard_cpld_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret =0; + + cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct baseboard_cpld_data), + GFP_KERNEL); + if (!cpld_data) + return -ENOMEM; + + mutex_init(&cpld_data->cpld_lock); + + cpld_data->read_addr = VERSION_ADDR; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + return -1; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &baseboard_cpld_attrs_grp); + if (ret) { + printk(KERN_ERR "Cannot create sysfs for baseboard CPLD\n"); + } + return 0; +} + +static int baseboard_cpld_drv_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &baseboard_cpld_attrs_grp); + return 0; +} + +static struct platform_driver baseboard_cpld_drv = { + .probe = baseboard_cpld_drv_probe, + .remove = __exit_p(baseboard_cpld_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int baseboard_cpld_init(void) +{ + // Register platform device and platform driver + platform_device_register(&baseboard_cpld_dev); + platform_driver_register(&baseboard_cpld_drv); + return 0; +} + +void baseboard_cpld_exit(void) +{ + // Unregister platform device and platform driver + platform_driver_unregister(&baseboard_cpld_drv); + platform_device_unregister(&baseboard_cpld_dev); +} + +module_init(baseboard_cpld_init); +module_exit(baseboard_cpld_exit); + +MODULE_AUTHOR("Pradchaya Phucharoen "); +MODULE_DESCRIPTION("Celestica DS3000 Baseboard CPLD Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/led_driver/pddf_custom_led_defs.h b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/led_driver/pddf_custom_led_defs.h new file mode 100644 index 000000000000..63628f708312 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/led_driver/pddf_custom_led_defs.h @@ -0,0 +1,149 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. + * + * 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. + * + * + * Description + * Platform LED related defines and structures + */ + + +/***************************************** + * kobj list + *****************************************/ + +struct kobject *platform_kobj=NULL; +struct kobject *led_kobj=NULL; + +struct kobject *state_attr_kobj=NULL; +struct kobject *cur_state_kobj=NULL; + +/***************************************** + * Static Data provided from user + * space JSON data file + *****************************************/ +#define NAME_SIZE 32 +#define VALUE_SIZE 5 +typedef enum { + STATUS_LED_COLOR_OFF=0, + STATUS_LED_COLOR_GREEN=1, + STATUS_LED_COLOR_YELLOW=2, + STATUS_LED_COLOR_RED=3, + STATUS_LED_COLOR_BLUE=4, + STATUS_LED_COLOR_GREEN_BLINK=5, + STATUS_LED_COLOR_YELLOW_BLINK=6, + STATUS_LED_COLOR_RED_BLINK=7, + STATUS_LED_COLOR_BLUE_BLINK=8, + STATUS_LED_COLOR_AMBER, + STATUS_LED_COLOR_AMBER_BLINK, + MAX_LED_STATUS +}LED_STATUS; + +char* LED_STATUS_STR[] = { + "off", + "green", + "yellow", + "red", + "blue", + "green_blink", + "yellow_blink", + "red_blink", + "blue_blink", + "amber", + "amber_blink" +}; + + +typedef struct +{ + char bits[NAME_SIZE]; + int pos; + int mask_bits; +}MASK_BITS; + +typedef struct +{ + int swpld_addr; + int swpld_addr_offset; + MASK_BITS bits; + u8 reg_values[VALUE_SIZE]; + char value[NAME_SIZE]; + char attr_devtype[NAME_SIZE]; + char attr_devname[NAME_SIZE]; +} LED_DATA; + +typedef struct +{ + int state; + char color[NAME_SIZE]; +/* S3IP System LED RW sysfs */ + int sys_led; + int bmc_led; + int fan_led; + int psu_led; + int loc_led; +/* S3IP Power LED RO sysfs */ + int psu1_led; + int psu2_led; +/* S3IP Fantray LED RO sysfs */ + int fantray1_led; + int fantray2_led; + int fantray3_led; + int fantray4_led; + int fantray5_led; + int fantray6_led; + int fantray7_led; +} CUR_STATE_DATA; + +typedef struct +{ + CUR_STATE_DATA cur_state; + char device_name[NAME_SIZE]; + int index; + LED_DATA data[MAX_LED_STATUS]; + int swpld_addr; + int swpld_addr_offset; + char attr_devtype[NAME_SIZE]; + char attr_devname[NAME_SIZE]; +} LED_OPS_DATA; + +typedef enum{ + LED_SYS, + LED_PSU, + LED_FAN, + LED_FANTRAY, + LED_DIAG, + LED_LOC, + LED_BMC, + LED_TYPE_MAX +} LED_TYPE; +char* LED_TYPE_STR[LED_TYPE_MAX] = +{ + "LED_SYS", + "LED_PSU", + "LED_FAN", + "LED_FANTRAY", + "LED_DIAG", + "LED_LOC", + "LED_BMC" +}; + +/***************************************** + * Data exported from kernel for + * user space plugin to get/set + *****************************************/ +#define PDDF_LED_DATA_ATTR( _prefix, _name, _mode, _show, _store, _type, _len, _addr) \ + struct pddf_data_attribute pddf_dev_##_prefix##_attr_##_name = { .dev_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type , \ + .len = _len , \ + .addr = _addr } diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/led_driver/pddf_custom_led_module.c b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/led_driver/pddf_custom_led_module.c new file mode 100644 index 000000000000..7e88079873bf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/led_driver/pddf_custom_led_module.c @@ -0,0 +1,873 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. + * + * 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. + * + * + * A pddf kernel module to manage various LEDs of a switch + */ + +#define __STDC_WANT_LIB_EXT1__ 1 +#include +#include +#include +#include +#include +#include +#include "pddf_custom_led_defs.h" +#include "../../../../../pddf/i2c/modules/include/pddf_client_defs.h" +#include +#include +#include + +#define DEBUG 0 +#define MAX_PSU_NUM 2 +#define MAX_FANTRAY_NUM 7 +LED_OPS_DATA sys_led_ops_data[1]={0}; +LED_OPS_DATA psu_led_ops_data[MAX_PSU_NUM]={0}; +LED_OPS_DATA diag_led_ops_data[1]= {0}; +LED_OPS_DATA fan_led_ops_data[1]= {0}; +LED_OPS_DATA loc_led_ops_data[1]= {0}; +LED_OPS_DATA bmc_led_ops_data[1]= {0}; +LED_OPS_DATA fantray_led_ops_data[MAX_FANTRAY_NUM]={0}; +LED_OPS_DATA temp_data={0}; +LED_OPS_DATA* dev_list[LED_TYPE_MAX] = { + sys_led_ops_data, + psu_led_ops_data, + fan_led_ops_data, + fantray_led_ops_data, + diag_led_ops_data, + loc_led_ops_data, + bmc_led_ops_data, + NULL +}; +int num_psus = 0; +int num_fantrays = 0; + +extern int board_i2c_cpld_read_new(unsigned short cpld_addr, char *name, u8 reg); +extern int board_i2c_cpld_write_new(unsigned short cpld_addr, char *name, u8 reg, u8 value); +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); +extern int board_i2c_fpga_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_fpga_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern ssize_t show_pddf_s3ip_data(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t store_pddf_s3ip_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +static LED_STATUS find_state_index(const char* state_str) { + int index; + char *ptr = (char *)state_str; + while (*ptr && *ptr!= '\n' && *ptr !='\0') ptr++; + *ptr='\0'; + for ( index = 0; index < MAX_LED_STATUS; index++) { + if (strcmp(state_str, LED_STATUS_STR[index]) == 0 ) { + return index; + } + } + return MAX_LED_STATUS; +} + +static LED_TYPE get_dev_type(char* name) +{ + LED_TYPE ret = LED_TYPE_MAX; + if(strcasecmp(name, "SYS_LED") == 0) { + ret = LED_SYS; + } else if(strcasecmp(name, "FAN_LED") == 0) { + ret = LED_FAN; + } else if(strstr(name, "PSU_LED")) { + ret = LED_PSU; + } else if(strcasecmp(name, "DIAG_LED") == 0) { + ret = LED_DIAG; + } else if(strcasecmp(name, "LOC_LED") == 0) { + ret = LED_LOC; + } else if(strstr(name, "FANTRAY_LED")) { + ret = LED_FANTRAY; + } +#if DEBUG > 1 + pddf_dbg(LED, KERN_INFO "LED get_dev_type: %s; %d\n", name, ret); +#endif + return (ret); +} +static int dev_index_check(LED_TYPE type, int index) +{ +#if DEBUG + pddf_dbg(LED, "dev_index_check: type:%s[%d] index:%d num_psus:%d num_fantrays:%d\n", + LED_TYPE_STR[type], type, index, num_psus, num_fantrays); +#endif + switch(type) + { + case LED_PSU: + if(index >= MAX_PSU_NUM) return (-1); + break; + case LED_FANTRAY: + if(index >= MAX_FANTRAY_NUM) return (-1); + break; + default: + if(index >= 1) return (-1); + break; + } + return (0); +} + +static LED_OPS_DATA* find_led_ops_data(struct device_attribute *da) +{ + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* ptr = (LED_OPS_DATA*)_ptr->addr; + LED_TYPE led_type; + if(!ptr || strlen(ptr->device_name) == 0 ) return (NULL); + + if((led_type=get_dev_type(ptr->device_name)) == LED_TYPE_MAX) { + printk(KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); + return (NULL); + } + if(dev_index_check(led_type, ptr->index) == -1) { + printk(KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%s;%d\n", __func__, ptr->index, ptr->device_name, led_type); + return (NULL); + } +#if DEBUG > 1 + pddf_dbg(LED, "find_led_ops_data: name:%s; index=%d tempAddr:%p actualAddr:%p\n", + ptr->device_name, ptr->index, ptr, dev_list[led_type]+ptr->index); +#endif + return (dev_list[led_type]+ptr->index); +} + +static void print_led_data(LED_OPS_DATA *ptr, LED_STATUS state) +{ + int i = 0; + if(!ptr) return ; + pddf_dbg(LED, KERN_INFO "Print %s index:%d num_psus:%d num_fantrays:%d ADDR=%p\n", + ptr->device_name, ptr->index, num_psus, num_fantrays, ptr); + pddf_dbg(LED, KERN_INFO "\tindex: %d\n", ptr->index); + pddf_dbg(LED, KERN_INFO "\tdevtype/devname: %s:%s\n", ptr->attr_devtype, ptr->attr_devname); + pddf_dbg(LED, KERN_INFO "\tcur_state: %d; %s \n", ptr->cur_state.state, ptr->cur_state.color); + for (i = 0; i< MAX_LED_STATUS; i++) { + if(ptr->data[i].swpld_addr && (i == state || state == -1)) { + pddf_dbg(LED, KERN_INFO "\t\t[%s]: addr/offset:0x%x;0x%x color:%s; value:[%s][0x%x][0x%x] mask_bits: 0x%x;" + "pos:%d attr_devtype:%s attr_devname:%s\n",LED_STATUS_STR[i], ptr->data[i].swpld_addr, + ptr->data[i].swpld_addr_offset, LED_STATUS_STR[i], ptr->data[i].value, + ptr->data[i].reg_values[0], ptr->data[i].reg_values[1], ptr->data[i].bits.mask_bits, + ptr->data[i].bits.pos, ptr->data[i].attr_devtype, ptr->data[i].attr_devname); + } + } +} + +ssize_t get_status_led(struct device_attribute *da) +{ + int ret=0; + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + uint32_t color_val=0, sys_val=0; + int state=0; + int cpld_type=0; + int j; + + if (!ops_ptr) { + pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot find LED Ptr", __func__); + return (-1); + } + + if (ops_ptr->swpld_addr == 0x0) { + pddf_dbg(LED, KERN_ERR "ERROR %s: device: %s %d not configured\n", __func__, + temp_data_ptr->device_name, temp_data_ptr->index); + return (-1); + } + + if (strcmp(ops_ptr->attr_devtype, "cpld") == 0) { + cpld_type = 1; + sys_val = board_i2c_cpld_read_new(ops_ptr->swpld_addr, ops_ptr->attr_devname, ops_ptr->swpld_addr_offset); + } else if (strcmp(ops_ptr->attr_devtype, "fpgai2c") == 0) { + sys_val = board_i2c_fpga_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + } else { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d devtype:%s 0x%x:0x%x not configured\n",__func__, + ops_ptr->device_name, ops_ptr->index, ops_ptr->attr_devtype, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + return (-1); + } + + if (sys_val < 0) { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d devtype:%s 0x%x:0x%x read failed\n",__func__, + ops_ptr->device_name, ops_ptr->index, ops_ptr->attr_devtype, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + return sys_val; + } + + strncpy(temp_data.cur_state.color, "None", 4); // nosemgrep + for (state=0; statedata[state].bits.mask_bits); + for (j = 0; j < VALUE_SIZE && ops_ptr->data[state].reg_values[j] != 0xff; j++) { + if ((color_val ^ (ops_ptr->data[state].reg_values[j] << ops_ptr->data[state].bits.pos)) == 0) { + strcpy(temp_data.cur_state.color, LED_STATUS_STR[state]); // nosemgrep + break; + } + } + } +#if DEBUG + pddf_dbg(LED, KERN_ERR "Get : %s:%d addr/offset:0x%x; 0x%x devtype:%s;%s value=0x%x [%s]\n", + ops_ptr->device_name, ops_ptr->index, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, + ops_ptr->attr_devtype, cpld_type? "cpld": "fpgai2c", sys_val, temp_data.cur_state.color); +#endif + return(ret); +} + +ssize_t set_status_led(struct device_attribute *da) +{ + int ret=0; + uint32_t sys_val=0, new_val=0, read_val=0; + LED_STATUS cur_state = MAX_LED_STATUS; + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + char* _buf=temp_data_ptr->cur_state.color; + int cpld_type = 0; + + if (!ops_ptr) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: Cannot find LED Ptr", __func__); + return (-1); + } + + if (ops_ptr->swpld_addr == 0x0) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: device: %s %d not configured\n", + __func__, ops_ptr->device_name, ops_ptr->index); + return (-1); + } + + pddf_dbg(LED, KERN_ERR "%s: Set [%s;%d] color[%s]\n", __func__, + temp_data_ptr->device_name, temp_data_ptr->index, + temp_data_ptr->cur_state.color); + cur_state = find_state_index(_buf); + + if (cur_state == MAX_LED_STATUS) { + pddf_dbg(LED, KERN_ERR "ERROR %s: not supported: %s\n", _buf, __func__); + return (-1); + } + + if (ops_ptr->data[cur_state].swpld_addr != 0x0) { + if (strcmp(ops_ptr->data[cur_state].attr_devtype, "cpld") == 0) { + cpld_type = 1; + sys_val = board_i2c_cpld_read_new(ops_ptr->swpld_addr, ops_ptr->attr_devname, ops_ptr->swpld_addr_offset); + } else if (strcmp(ops_ptr->data[cur_state].attr_devtype, "fpgai2c") == 0) { + sys_val = board_i2c_fpga_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + } else { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d devtype:%s not configured\n",__func__, + ops_ptr->device_name, ops_ptr->index, ops_ptr->attr_devtype); + return (-1); + } + + if (sys_val < 0){ + return sys_val; + } + + + new_val = (sys_val & ops_ptr->data[cur_state].bits.mask_bits) | + (ops_ptr->data[cur_state].reg_values[0] << ops_ptr->data[cur_state].bits.pos); + } else { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d devtype:%s state %d; %s not configured\n",__func__, + ops_ptr->device_name, ops_ptr->index, ops_ptr->attr_devtype, cur_state, _buf); + return (-1); + } + + if (strcmp(ops_ptr->data[cur_state].attr_devtype, "cpld") == 0) { + ret = board_i2c_cpld_write_new(ops_ptr->swpld_addr, ops_ptr->attr_devname, ops_ptr->swpld_addr_offset, new_val); + read_val = board_i2c_cpld_read_new(ops_ptr->swpld_addr, ops_ptr->attr_devname, ops_ptr->swpld_addr_offset); + } else if (strcmp(ops_ptr->data[cur_state].attr_devtype, "fpgai2c") == 0) { + ret = board_i2c_fpga_write(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, (uint8_t)new_val); + read_val = board_i2c_fpga_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + } else { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d devtype:%s not configured\n",__func__, + ops_ptr->device_name, ops_ptr->index, ops_ptr->attr_devtype); + return (-1); + } + +#if DEBUG + pddf_dbg(LED, KERN_ERR "Set color:%s; 0x%x:0x%x sys_val:0x%x new_val:0x%x devtype:%s w_ret:0x%x read:0x%x devtype:%s\n", + LED_STATUS_STR[cur_state], ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, sys_val, new_val, + cpld_type? "cpld":"fpgai2c", ret, read_val, ops_ptr->data[cur_state].attr_devtype); +#endif + + return(ret); +} + + +ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, + char *buf) +{ + int ret = 0; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + switch (ptr->type) + { + case PDDF_CHAR: + ret = sprintf(buf, "%s\n", ptr->addr); + break; + case PDDF_INT_DEC: + ret = sprintf(buf, "%d\n", *(int*)(ptr->addr)); + break; + case PDDF_INT_HEX: + ret = sprintf(buf, "0x%x\n", *(int*)(ptr->addr)); + break; + case PDDF_USHORT: + ret = sprintf(buf, "0x%x\n", *(unsigned short *)(ptr->addr)); + break; + case PDDF_UINT32: + ret = sprintf(buf, "0x%x\n", *(uint32_t *)(ptr->addr)); + break; + default: + break; + } +#if DEBUG > 1 + pddf_dbg(LED, "[ READ ] DATA ATTR PTR [%s] TYPE:%d, Value:[%s]\n", + ptr->dev_attr.attr.name, ptr->type, buf); +#endif + return ret; +} + +ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret = 0, num = 0; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + switch (ptr->type) + { + case PDDF_CHAR: + strncpy(ptr->addr, buf, strlen(buf)-1); // nosemgrep // to discard newline char form buf + ptr->addr[strlen(buf)-1] = '\0'; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_CHAR VALUE:%s\n", + ptr->dev_attr.attr.name, ptr->addr); +#endif + break; + case PDDF_INT_DEC: + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_DEC VALUE:%d\n", + ptr->dev_attr.attr.name, *(int *)(ptr->addr)); +#endif + break; + case PDDF_INT_HEX: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(int *)(ptr->addr) = num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_HEX VALUE:0x%x\n", + ptr->dev_attr.attr.name, *(int *)(ptr->addr)); +#endif + break; + case PDDF_USHORT: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(unsigned short *)(ptr->addr) = (unsigned short)num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_USHORT VALUE:%x\n", + ptr->dev_attr.attr.name, *(unsigned short *)(ptr->addr)); +#endif + break; + case PDDF_UINT32: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(uint32_t *)(ptr->addr) = (uint32_t)num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_UINT32 VALUE:%d\n", + ptr->dev_attr.attr.name, *(uint32_t *)(ptr->addr)); +#endif + break; + default: + break; + } + return count; +} + +ssize_t show_pddf_s3ip_data(struct device *dev, struct device_attribute *da, + char *buf) +{ + int ret = 0; + pddf_dbg(LED, KERN_ERR " %s", __FUNCTION__); + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + if (_ptr == NULL) { + pddf_dbg(LED, KERN_ERR "%s return", __FUNCTION__); + return -1; + } + LED_OPS_DATA* ops_ptr=(LED_OPS_DATA*)_ptr->addr; + uint32_t color_val=0, sys_val=0; + int state=0, j; + int cpld_type=0; + if (!ops_ptr) { + pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot find LED Ptr", __func__); + return (-1); + } + if (ops_ptr->swpld_addr == 0x0) { + pddf_dbg(LED, KERN_ERR "ERROR %s: device: %s %d not configured\n", __func__, + ops_ptr->device_name, ops_ptr->index); + return (-1); + } + if ( strcmp(ops_ptr->attr_devtype, "cpld") == 0) { + cpld_type=1; + sys_val = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + } else if ( strcmp(ops_ptr->attr_devtype, "fpgai2c") == 0) { + sys_val = board_i2c_fpga_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + } else { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d devtype:%s 0x%x:0x%x not configured\n",__func__, + ops_ptr->device_name, ops_ptr->index, ops_ptr->attr_devtype, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + return (-1); + } + + if (sys_val < 0) { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d devtype:%s 0x%x:0x%x read failed\n",__func__, + ops_ptr->device_name, ops_ptr->index, ops_ptr->attr_devtype, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + return sys_val; + } + for (state=0; statedata[state].bits.mask_bits); + for (j = 0; j < VALUE_SIZE && ops_ptr->data[state].reg_values[j] != 0xff; j++) { + if ((color_val ^ (ops_ptr->data[state].reg_values[j] << ops_ptr->data[state].bits.pos))==0) { + ret = sprintf(buf, "%d\n", state); + break; + } + } + } +#if DEBUG + pddf_dbg(LED, KERN_ERR "Get : %s:%d addr/offset:0x%x; 0x%x devtype:%s;%s value=0x%x [%d]\n", + ops_ptr->device_name, ops_ptr->index, ops_ptr->swpld_addr, + ops_ptr->swpld_addr_offset, ops_ptr->attr_devtype, cpld_type? "cpld": "fpgai2c", sys_val, state); +#endif + return ret; +} + +ssize_t store_pddf_s3ip_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret = 0; + int cur_state = 0; + uint32_t sys_val=0, new_val=0, read_val=0; + int cpld_type=0; + + pddf_dbg(LED, KERN_ERR "%s: %s;%d", __FUNCTION__, buf, cur_state); + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + ret = kstrtoint(buf,10,&cur_state); + if (_ptr == NULL || cur_state >= MAX_LED_STATUS || ret !=0) { + pddf_dbg(LED, KERN_ERR "%s return", __FUNCTION__); + return -1; + } + LED_OPS_DATA* ops_ptr=(LED_OPS_DATA*)_ptr->addr; + + if ( strcmp(ops_ptr->attr_devtype, "cpld") == 0) { + cpld_type=1; + sys_val = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + } else if ( strcmp(ops_ptr->attr_devtype, "fpgai2c") == 0) { + sys_val = board_i2c_fpga_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + } else { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d devtype:%s 0x%x:0x%x not configured\n",__func__, + ops_ptr->device_name, ops_ptr->index, ops_ptr->attr_devtype, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + return (-1); + } + + new_val = (sys_val & ops_ptr->data[cur_state].bits.mask_bits) | + (ops_ptr->data[cur_state].reg_values[0] << ops_ptr->data[cur_state].bits.pos); + + if ( strcmp(ops_ptr->data[cur_state].attr_devtype, "cpld") == 0) { + ret = board_i2c_cpld_write(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, new_val); + read_val = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + } else if ( strcmp(ops_ptr->data[cur_state].attr_devtype, "fpgai2c") == 0) { + ret = board_i2c_fpga_write(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, (uint8_t)new_val); + read_val = board_i2c_fpga_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + } else { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d devtype:%s not configured\n",__func__, + ops_ptr->device_name, ops_ptr->index, ops_ptr->attr_devtype); + return (-1); + } + +#if DEBUG + pddf_dbg(LED, KERN_INFO "Set color:%s; 0x%x:0x%x sys_val:0x%x new_val:0x%x devtype:%s w_ret:0x%x read:0x%x devtype:%s\n", + LED_STATUS_STR[cur_state], ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, + sys_val, new_val, cpld_type? "cpld":"fpgai2c", ret, read_val, ops_ptr->data[cur_state].attr_devtype); +#endif + return count; +} + + +static int load_led_ops_data(struct device_attribute *da, LED_STATUS state) +{ + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* ptr = (LED_OPS_DATA*)_ptr->addr; + LED_TYPE led_type; + LED_OPS_DATA* ops_ptr = NULL; + int i = 0; + char *token = NULL, *value_ptr = NULL; + + if(!ptr || strlen(ptr->device_name)==0 ) { + pddf_dbg(LED, KERN_INFO "SYSTEM_LED: load_led_ops_data return -1 device_name:%s\n", ptr? ptr->device_name:"NULL"); + return(-1); + } + + if(ptr->device_name) + { + pddf_dbg(LED, KERN_INFO "[%s]: load_led_ops_data: index=%d addr=0x%x;0x%x devtype:%s devname=%s valu=%s\n", + ptr->device_name, ptr->index, ptr->swpld_addr, ptr->swpld_addr_offset, ptr->attr_devtype, ptr->attr_devname, ptr->data[0].value); + } + if((led_type=get_dev_type(ptr->device_name))==LED_TYPE_MAX) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); + return(-1); + } + if(dev_index_check(led_type, ptr->index)==-1) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%d\n", __func__, ptr->index, led_type); + return(-1); + } + ops_ptr = dev_list[led_type]+ptr->index; + + memcpy(ops_ptr->device_name, ptr->device_name, sizeof(ops_ptr->device_name)); + ops_ptr->index = ptr->index; + memcpy(&ops_ptr->data[state], &ptr->data[0], sizeof(LED_DATA)); + ops_ptr->data[state].swpld_addr = ptr->swpld_addr; + ops_ptr->data[state].swpld_addr_offset = ptr->swpld_addr_offset; + ops_ptr->swpld_addr = ptr->swpld_addr; + ops_ptr->swpld_addr_offset = ptr->swpld_addr_offset; + memcpy(ops_ptr->data[state].attr_devtype, ptr->attr_devtype, sizeof(ops_ptr->data[state].attr_devtype)); + memcpy(ops_ptr->data[state].attr_devname, ptr->attr_devname, sizeof(ops_ptr->data[state].attr_devname)); + memcpy(ops_ptr->attr_devtype, ptr->attr_devtype, sizeof(ops_ptr->attr_devtype)); + memcpy(ops_ptr->attr_devname, ptr->attr_devname, sizeof(ops_ptr->attr_devname)); +#ifdef __STDC_LIB_EXT1__ + memset_s(ops_ptr->data[state].reg_values, sizeof(ops_ptr->data[state].reg_values), 0xff, sizeof(ops_ptr->data[state].reg_values)); +#else + memset(ops_ptr->data[state].reg_values, 0xff, sizeof(ops_ptr->data[state].reg_values)); +#endif + value_ptr = kzalloc(sizeof(ops_ptr->data[state].value), GFP_KERNEL); + if (value_ptr) { + memcpy(value_ptr, ops_ptr->data[state].value, sizeof(ops_ptr->data[state].value)); + while((token = strsep((char**)&value_ptr,";")) != NULL && i < VALUE_SIZE) { + if (kstrtou8(token, 16, &ops_ptr->data[state].reg_values[i])) { + pddf_dbg(LED, KERN_ERR "load_led_ops_data: [%s] conversion error\n", token); + } + i++; + } + kfree(value_ptr); + } + + print_led_data(dev_list[led_type]+ptr->index, state); + + memset(ptr, 0, sizeof(LED_OPS_DATA)); + return (0); +} + +static int show_led_ops_data(struct device_attribute *da) +{ + LED_OPS_DATA* ops_ptr = find_led_ops_data(da); + print_led_data(ops_ptr, -1); + return(0); +} + +static int verify_led_ops_data(struct device_attribute *da) +{ + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + + if(ops_ptr) + memcpy(ptr, ops_ptr, sizeof(LED_OPS_DATA)); + else + { + pddf_dbg(LED, "SYSTEM_LED: verify_led_ops_data: Failed to find ops_ptr name:%s; index=%d\n", ptr->device_name, ptr->index); + } + return (0); +} + + +ssize_t dev_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ +#if DEBUG + pddf_dbg(LED, KERN_INFO "dev_operation [%s]\n", buf); +#endif + if(strncmp(buf, "show", strlen("show")) == 0) { + show_led_ops_data(da); + } + else if(strncmp(buf, "verify", strlen("verify")) == 0) { + verify_led_ops_data(da); + } + else if(strncmp(buf, "get_status", strlen("get_status")) == 0) { + get_status_led(da); + } + else if(strncmp(buf, "set_status", strlen("set_status")) == 0) { + set_status_led(da); + } + else { + LED_STATUS index = find_state_index(buf); + if (index < MAX_LED_STATUS) { + load_led_ops_data(da, index); + } else { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s\n", __FUNCTION__, buf); + } + } + return (count); +} + +ssize_t store_config_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret, num; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + if(strncmp(ptr->dev_attr.attr.name, "num_psus", strlen("num_psus")) == 0) { + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; +#if DEBUG + pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", + ptr->dev_attr.attr.name, num, num_psus); +#endif + return(count); + } + if (strncmp(ptr->dev_attr.attr.name, "num_fantrays", strlen("num_fantrays")) ==0) { + ret = kstrtoint(buf, 10, &num); + if (ret == 0) + *(int *)(ptr->addr) = num; +#if DEBUG + pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", + ptr->dev_attr.attr.name, num, num_fantrays); +#endif + return (count); + } + return (count); +} + +ssize_t store_bits_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int len = 0, num1 = 0, num2 = 0, i=0, rc1=0, rc2=0; + char mask=0xFF; + char *pptr=NULL; + char bits[NAME_SIZE]; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + MASK_BITS* bits_ptr=(MASK_BITS*)(ptr->addr); + strncpy(bits_ptr->bits, buf, strlen(buf)-1); // nosemgrep // to discard newline char form buf + bits_ptr->bits[strlen(buf)-1] = '\0'; + if((pptr=strstr(buf,":")) != NULL) { + len = pptr-buf; + sprintf(bits, buf); + bits[len] = '\0'; + rc1 = kstrtoint(bits, 16, &num1); + if (rc1 == 0) + { + sprintf(bits, ++pptr); + rc2 = kstrtoint(bits, 16, &num2); + if (rc2 == 0) + { + for (i=num2; i<=num1; i++) { + mask &= ~(1 << i); + } + bits_ptr->mask_bits = mask; + bits_ptr->pos = num2; + } + } + } else { + rc1 = kstrtoint(buf, 16, &num1); + if (rc1 == 0) + { + bits_ptr->mask_bits = mask & ~(1 << num1); + bits_ptr->pos = num1; + } + } +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR Bits [%s] VALUE:%s mask:0x%x; pos:0x%x\n", + ptr->dev_attr.attr.name, bits_ptr->bits, bits_ptr->mask_bits, bits_ptr->pos); +#endif + return (count); +} + +/************************************************************************** + * platform/ attributes + **************************************************************************/ +PDDF_LED_DATA_ATTR(platform, num_psus, S_IWUSR|S_IRUGO, show_pddf_data, + store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_psus); +PDDF_LED_DATA_ATTR(platform, num_fantrays, S_IWUSR|S_IRUGO, show_pddf_data, + store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_fantrays); + +struct attribute* attrs_platform[]={ + &pddf_dev_platform_attr_num_psus.dev_attr.attr, + &pddf_dev_platform_attr_num_fantrays.dev_attr.attr, + NULL, +}; +struct attribute_group attr_group_platform={ + .attrs = attrs_platform, +}; + +/************************************************************************** + * led/ attributes + **************************************************************************/ +PDDF_LED_DATA_ATTR(dev, device_name, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.device_name); +PDDF_LED_DATA_ATTR(dev, attr_devtype, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.attr_devtype); +PDDF_LED_DATA_ATTR(dev, attr_devname, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.attr_devname); +PDDF_LED_DATA_ATTR(dev, index, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&temp_data.index); +PDDF_LED_DATA_ATTR(dev, swpld_addr, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr); +PDDF_LED_DATA_ATTR(dev, swpld_addr_offset, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr_offset); +PDDF_LED_DATA_ATTR(dev, dev_ops , S_IWUSR, NULL, + dev_operation, PDDF_CHAR, NAME_SIZE, (void*)&temp_data); + +struct attribute* attrs_dev[] = { + &pddf_dev_dev_attr_device_name.dev_attr.attr, + &pddf_dev_dev_attr_attr_devtype.dev_attr.attr, + &pddf_dev_dev_attr_attr_devname.dev_attr.attr, + &pddf_dev_dev_attr_index.dev_attr.attr, + &pddf_dev_dev_attr_swpld_addr.dev_attr.attr, + &pddf_dev_dev_attr_swpld_addr_offset.dev_attr.attr, + &pddf_dev_dev_attr_dev_ops.dev_attr.attr, + NULL, +}; + +struct attribute_group attr_group_dev = { + .attrs = attrs_dev, +}; + +/************************************************************************** + * state_attr/ attributes + **************************************************************************/ +#define LED_DEV_STATE_ATTR_GROUP(name, func) \ + PDDF_LED_DATA_ATTR(name, bits, S_IWUSR|S_IRUGO, show_pddf_data, \ + store_bits_data, PDDF_CHAR, NAME_SIZE, func.bits.bits); \ + PDDF_LED_DATA_ATTR(name, value, S_IWUSR|S_IRUGO, show_pddf_data, \ + store_pddf_data, PDDF_CHAR, NAME_SIZE, func.value); \ + struct attribute* attrs_##name[]={ \ + &pddf_dev_##name##_attr_bits.dev_attr.attr, \ + &pddf_dev_##name##_attr_value.dev_attr.attr, \ + NULL, \ + }; \ + struct attribute_group attr_group_##name={ \ + .attrs = attrs_##name, \ + }; \ + + +LED_DEV_STATE_ATTR_GROUP(state_attr, (void*)&temp_data.data[0]) + +/************************************************************************** + * cur_state/ attributes + **************************************************************************/ +PDDF_LED_DATA_ATTR(cur_state, color, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.cur_state.color); +PDDF_LED_DATA_ATTR(cur_state, sys_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void*)&sys_led_ops_data); +PDDF_LED_DATA_ATTR(cur_state, loc_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, NAME_SIZE, (void*)&loc_led_ops_data); +PDDF_LED_DATA_ATTR(cur_state, bmc_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void*)&bmc_led_ops_data); +PDDF_LED_DATA_ATTR(cur_state, fan_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void*)&fan_led_ops_data); +PDDF_LED_DATA_ATTR(cur_state, psu_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), NULL); +PDDF_LED_DATA_ATTR(cur_state, psu1_led, S_IRUGO, show_pddf_s3ip_data, + NULL, PDDF_INT_DEC, sizeof(int), (void *)&psu_led_ops_data[0]); +PDDF_LED_DATA_ATTR(cur_state, psu2_led, S_IRUGO, show_pddf_s3ip_data, + NULL, PDDF_INT_DEC, sizeof(int), (void *)&psu_led_ops_data[1]); +PDDF_LED_DATA_ATTR(cur_state, fantray1_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void *)&fantray_led_ops_data[0]); +PDDF_LED_DATA_ATTR(cur_state, fantray2_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void *)&fantray_led_ops_data[1]); +PDDF_LED_DATA_ATTR(cur_state, fantray3_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void *)&fantray_led_ops_data[2]); +PDDF_LED_DATA_ATTR(cur_state, fantray4_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void *)&fantray_led_ops_data[3]); +PDDF_LED_DATA_ATTR(cur_state, fantray5_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void *)&fantray_led_ops_data[4]); +PDDF_LED_DATA_ATTR(cur_state, fantray6_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void *)&fantray_led_ops_data[5]); +PDDF_LED_DATA_ATTR(cur_state, fantray7_led, S_IWUSR|S_IRUGO, show_pddf_s3ip_data, + store_pddf_s3ip_data, PDDF_INT_DEC, sizeof(int), (void *)&fantray_led_ops_data[6]); + + +struct attribute* attrs_cur_state[] = { + &pddf_dev_cur_state_attr_color.dev_attr.attr, + &pddf_dev_cur_state_attr_sys_led.dev_attr.attr, + &pddf_dev_cur_state_attr_loc_led.dev_attr.attr, + &pddf_dev_cur_state_attr_bmc_led.dev_attr.attr, + &pddf_dev_cur_state_attr_fan_led.dev_attr.attr, + &pddf_dev_cur_state_attr_psu_led.dev_attr.attr, + &pddf_dev_cur_state_attr_psu1_led.dev_attr.attr, + &pddf_dev_cur_state_attr_psu2_led.dev_attr.attr, + &pddf_dev_cur_state_attr_fantray1_led.dev_attr.attr, + &pddf_dev_cur_state_attr_fantray2_led.dev_attr.attr, + &pddf_dev_cur_state_attr_fantray3_led.dev_attr.attr, + &pddf_dev_cur_state_attr_fantray4_led.dev_attr.attr, + &pddf_dev_cur_state_attr_fantray5_led.dev_attr.attr, + &pddf_dev_cur_state_attr_fantray6_led.dev_attr.attr, + &pddf_dev_cur_state_attr_fantray7_led.dev_attr.attr, + NULL, +}; + +struct attribute_group attr_group_cur_state={ + .attrs = attrs_cur_state, +}; + +/*************************************************************************/ +#define KOBJ_FREE(obj) \ + if(obj) kobject_put(obj); \ + +void free_kobjs(void) +{ + KOBJ_FREE(cur_state_kobj) + KOBJ_FREE(state_attr_kobj) + KOBJ_FREE(led_kobj) + KOBJ_FREE(platform_kobj) +} + +int KBOJ_CREATE(char* name, struct kobject* parent, struct kobject** child) +{ + if (parent) { + *child = kobject_create_and_add(name, parent); + } else { + printk(KERN_ERR "PDDF_LED ERROR to create %s kobj; null parent\n", name); + free_kobjs(); + return (-ENOMEM); + } + return (0); +} + +int LED_DEV_ATTR_CREATE(struct kobject *kobj, const struct attribute_group *attr, const char* name) +{ + int status = sysfs_create_group(kobj, attr); + if(status) { + pddf_dbg(LED, KERN_ERR "Driver ERROR: sysfs_create %s failed rc=%d\n", name, status); + } + return (status); +} + + +static int __init led_init(void) { + struct kobject *device_kobj; + pddf_dbg(LED, KERN_INFO "PDDF GENERIC LED MODULE init..\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + KBOJ_CREATE("platform", device_kobj, &platform_kobj); + KBOJ_CREATE("led", device_kobj, &led_kobj); + KBOJ_CREATE("state_attr", led_kobj, &state_attr_kobj); + KBOJ_CREATE("cur_state", led_kobj, &cur_state_kobj); + + LED_DEV_ATTR_CREATE(platform_kobj, &attr_group_platform, "attr_group_platform"); + LED_DEV_ATTR_CREATE(led_kobj, &attr_group_dev, "attr_group_dev"); + LED_DEV_ATTR_CREATE(state_attr_kobj, &attr_group_state_attr, "attr_group_state_attr"); + LED_DEV_ATTR_CREATE(cur_state_kobj, &attr_group_cur_state, "attr_group_cur_state"); + return (0); +} + + +static void __exit led_exit(void) { + pddf_dbg(LED, "PDDF GENERIC LED MODULE exit..\n"); + free_kobjs(); +} + +module_init(led_init); +module_exit(led_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/lm75.c b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/lm75.c new file mode 100644 index 000000000000..42e4126b754a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/lm75.c @@ -0,0 +1,958 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * lm75.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998, 1999 Frodo Looijaard + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lm75.h" + +/* + * This driver handles the LM75 and compatible digital temperature sensors. + */ + +enum lm75_type { /* keep sorted in alphabetical order */ + adt75, + at30ts74, + ds1775, + ds75, + ds7505, + g751, + lm75, + lm75a, + lm75b, + max6625, + max6626, + max31725, + mcp980x, + pct2075, + stds75, + stlm75, + tcn75, + tmp100, + tmp101, + tmp105, + tmp112, + tmp175, + tmp275, + tmp75, + tmp75b, + tmp75c, + tmp1075, +}; + +/** + * struct lm75_params - lm75 configuration parameters. + * @set_mask: Bits to set in configuration register when configuring + * the chip. + * @clr_mask: Bits to clear in configuration register when configuring + * the chip. + * @default_resolution: Default number of bits to represent the temperature + * value. + * @resolution_limits: Limit register resolution. Optional. Should be set if + * the resolution of limit registers does not match the + * resolution of the temperature register. + * @resolutions: List of resolutions associated with sample times. + * Optional. Should be set if num_sample_times is larger + * than 1, and if the resolution changes with sample times. + * If set, number of entries must match num_sample_times. + * @default_sample_time:Sample time to be set by default. + * @num_sample_times: Number of possible sample times to be set. Optional. + * Should be set if the number of sample times is larger + * than one. + * @sample_times: All the possible sample times to be set. Mandatory if + * num_sample_times is larger than 1. If set, number of + * entries must match num_sample_times. + */ + +struct lm75_params { + u8 set_mask; + u8 clr_mask; + u8 default_resolution; + u8 resolution_limits; + const u8 *resolutions; + unsigned int default_sample_time; + u8 num_sample_times; + const unsigned int *sample_times; +}; + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; + +/* The LM75 registers */ +#define LM75_REG_TEMP 0x00 +#define LM75_REG_CONF 0x01 +#define LM75_REG_HYST 0x02 +#define LM75_REG_MAX 0x03 +#define PCT2075_REG_IDLE 0x04 + +/* Each client has this additional data */ +struct lm75_data { + struct i2c_client *client; + struct regmap *regmap; + struct regulator *vs; + u8 orig_conf; + u8 current_conf; + u8 resolution; /* In bits, 9 to 16 */ + unsigned int sample_time; /* In ms */ + enum lm75_type kind; + const struct lm75_params *params; +}; + +/*-----------------------------------------------------------------------*/ + +static const u8 lm75_sample_set_masks[] = { 0 << 5, 1 << 5, 2 << 5, 3 << 5 }; + +#define LM75_SAMPLE_CLEAR_MASK (3 << 5) + +/* The structure below stores the configuration values of the supported devices. + * In case of being supported multiple configurations, the default one must + * always be the first element of the array + */ +static const struct lm75_params device_params[] = { + [adt75] = { + .clr_mask = 1 << 5, /* not one-shot mode */ + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [at30ts74] = { + .set_mask = 3 << 5, /* 12-bit mode*/ + .default_resolution = 12, + .default_sample_time = 200, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 25, 50, 100, 200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [ds1775] = { + .clr_mask = 3 << 5, + .set_mask = 2 << 5, /* 11-bit mode */ + .default_resolution = 11, + .default_sample_time = 500, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 125, 250, 500, 1000 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [ds75] = { + .clr_mask = 3 << 5, + .set_mask = 2 << 5, /* 11-bit mode */ + .default_resolution = 11, + .default_sample_time = 600, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 150, 300, 600, 1200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [stds75] = { + .clr_mask = 3 << 5, + .set_mask = 2 << 5, /* 11-bit mode */ + .default_resolution = 11, + .default_sample_time = 600, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 150, 300, 600, 1200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [stlm75] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 6, + }, + [ds7505] = { + .set_mask = 3 << 5, /* 12-bit mode*/ + .default_resolution = 12, + .default_sample_time = 200, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 25, 50, 100, 200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [g751] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [lm75] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [lm75a] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [lm75b] = { + .default_resolution = 11, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [max6625] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 7, + }, + [max6626] = { + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 7, + .resolution_limits = 9, + }, + [max31725] = { + .default_resolution = 16, + .default_sample_time = MSEC_PER_SEC / 20, + }, + [tcn75] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 18, + }, + [pct2075] = { + .default_resolution = 11, + .default_sample_time = MSEC_PER_SEC / 10, + .num_sample_times = 31, + .sample_times = (unsigned int []){ 100, 200, 300, 400, 500, 600, + 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, + 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, + 2800, 2900, 3000, 3100 }, + }, + [mcp980x] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode */ + .default_resolution = 12, + .resolution_limits = 9, + .default_sample_time = 240, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 30, 60, 120, 240 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp100] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode */ + .default_resolution = 12, + .default_sample_time = 320, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 40, 80, 160, 320 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp101] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode */ + .default_resolution = 12, + .default_sample_time = 320, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 40, 80, 160, 320 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp105] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp112] = { + .set_mask = 3 << 5, /* 8 samples / second */ + .clr_mask = 1 << 7, /* no one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 125, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 125, 250, 1000, 4000 }, + }, + [tmp175] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp275] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp75] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp75b] = { /* not one-shot mode, Conversion rate 37Hz */ + .clr_mask = 1 << 7 | 3 << 5, + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 37, + .sample_times = (unsigned int []){ MSEC_PER_SEC / 37, + MSEC_PER_SEC / 18, + MSEC_PER_SEC / 9, MSEC_PER_SEC / 4 }, + .num_sample_times = 4, + }, + [tmp75c] = { + .clr_mask = 1 << 5, /*not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 12, + }, + [tmp1075] = { /* not one-shot mode, 27.5 ms sample rate */ + .clr_mask = 1 << 5 | 1 << 6 | 1 << 7, + .default_resolution = 12, + .default_sample_time = 28, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + } +}; + +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +static int lm75_write_config(struct lm75_data *data, u8 set_mask, + u8 clr_mask) +{ + u8 value; + + clr_mask |= LM75_SHUTDOWN; + value = data->current_conf & ~clr_mask; + value |= set_mask; + + if (data->current_conf != value) { + s32 err; + + err = i2c_smbus_write_byte_data(data->client, LM75_REG_CONF, + value); + if (err) + return err; + data->current_conf = value; + } + return 0; +} + +static int lm75_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct lm75_data *data = dev_get_drvdata(dev); + unsigned int regval; + int err, reg; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_update_interval: + *val = data->sample_time; + break; + default: + return -EINVAL; + } + break; + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + reg = LM75_REG_TEMP; + break; + case hwmon_temp_max: + reg = LM75_REG_MAX; + break; + case hwmon_temp_max_hyst: + reg = LM75_REG_HYST; + break; + default: + return -EINVAL; + } + err = regmap_read(data->regmap, reg, ®val); + if (err < 0) + return err; + + *val = lm75_reg_to_mc(regval, data->resolution); + break; + default: + return -EINVAL; + } + return 0; +} + +static int lm75_write_temp(struct device *dev, u32 attr, long temp) +{ + struct lm75_data *data = dev_get_drvdata(dev); + u8 resolution; + int reg; + + switch (attr) { + case hwmon_temp_max: + reg = LM75_REG_MAX; + break; + case hwmon_temp_max_hyst: + reg = LM75_REG_HYST; + break; + default: + return -EINVAL; + } + + /* + * Resolution of limit registers is assumed to be the same as the + * temperature input register resolution unless given explicitly. + */ + if (data->params->resolution_limits) + resolution = data->params->resolution_limits; + else + resolution = data->resolution; + + temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + temp = DIV_ROUND_CLOSEST(temp << (resolution - 8), + 1000) << (16 - resolution); + + return regmap_write(data->regmap, reg, (u16)temp); +} + +static int lm75_update_interval(struct device *dev, long val) +{ + struct lm75_data *data = dev_get_drvdata(dev); + unsigned int reg; + u8 index; + s32 err; + + index = find_closest(val, data->params->sample_times, + (int)data->params->num_sample_times); + + switch (data->kind) { + default: + err = lm75_write_config(data, lm75_sample_set_masks[index], + LM75_SAMPLE_CLEAR_MASK); + if (err) + return err; + + data->sample_time = data->params->sample_times[index]; + if (data->params->resolutions) + data->resolution = data->params->resolutions[index]; + break; + case tmp112: + err = regmap_read(data->regmap, LM75_REG_CONF, ®); + if (err < 0) + return err; + reg &= ~0x00c0; + reg |= (3 - index) << 6; + err = regmap_write(data->regmap, LM75_REG_CONF, reg); + if (err < 0) + return err; + data->sample_time = data->params->sample_times[index]; + break; + case pct2075: + err = i2c_smbus_write_byte_data(data->client, PCT2075_REG_IDLE, + index + 1); + if (err) + return err; + data->sample_time = data->params->sample_times[index]; + break; + } + return 0; +} + +static int lm75_write_chip(struct device *dev, u32 attr, long val) +{ + switch (attr) { + case hwmon_chip_update_interval: + return lm75_update_interval(dev, val); + default: + return -EINVAL; + } + return 0; +} + +static int lm75_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + switch (type) { + case hwmon_chip: + return lm75_write_chip(dev, attr, val); + case hwmon_temp: + return lm75_write_temp(dev, attr, val); + default: + return -EINVAL; + } + return 0; +} + +static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct lm75_data *config_data = data; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_update_interval: + if (config_data->params->num_sample_times > 1) + return 0644; + return 0444; + } + break; + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + return 0444; + case hwmon_temp_max: + case hwmon_temp_max_hyst: + return 0644; + } + break; + default: + break; + } + return 0; +} + +static const struct hwmon_channel_info *lm75_info[] = { + HWMON_CHANNEL_INFO(chip, + HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL), + HWMON_CHANNEL_INFO(temp, + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), + NULL +}; + +static const struct hwmon_ops lm75_hwmon_ops = { + .is_visible = lm75_is_visible, + .read = lm75_read, + .write = lm75_write, +}; + +static const struct hwmon_chip_info lm75_chip_info = { + .ops = &lm75_hwmon_ops, + .info = lm75_info, +}; + +static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg) +{ + return reg != LM75_REG_TEMP; +} + +static bool lm75_is_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg == LM75_REG_TEMP || reg == LM75_REG_CONF; +} + +static const struct regmap_config lm75_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .max_register = PCT2075_REG_IDLE, + .writeable_reg = lm75_is_writeable_reg, + .volatile_reg = lm75_is_volatile_reg, + .val_format_endian = REGMAP_ENDIAN_BIG, + .cache_type = REGCACHE_RBTREE, + .use_single_read = true, + .use_single_write = true, +}; + +static void lm75_disable_regulator(void *data) +{ + struct lm75_data *lm75 = data; + + regulator_disable(lm75->vs); +} + +static void lm75_remove(void *data) +{ + struct lm75_data *lm75 = data; + struct i2c_client *client = lm75->client; + + i2c_smbus_write_byte_data(client, LM75_REG_CONF, lm75->orig_conf); +} + +static const struct i2c_device_id lm75_ids[]; + +static int lm75_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct lm75_data *data; + int status, err; + enum lm75_type kind; + + if (client->dev.of_node) + kind = (enum lm75_type)of_device_get_match_data(&client->dev); + else + kind = i2c_match_id(lm75_ids, client)->driver_data; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) + return -EIO; + + data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + data->kind = kind; + + data->vs = devm_regulator_get(dev, "vs"); + if (IS_ERR(data->vs)) + return PTR_ERR(data->vs); + + data->regmap = devm_regmap_init_i2c(client, &lm75_regmap_config); + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + + /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. + * Then tweak to be more precise when appropriate. + */ + + data->params = &device_params[data->kind]; + + /* Save default sample time and resolution*/ + data->sample_time = data->params->default_sample_time; + data->resolution = data->params->default_resolution; + + /* Enable the power */ + err = regulator_enable(data->vs); + if (err) { + dev_err(dev, "failed to enable regulator: %d\n", err); + return err; + } + + err = devm_add_action_or_reset(dev, lm75_disable_regulator, data); + if (err) + return err; + + /* Cache original configuration */ + status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(dev, "Can't read config? %d\n", status); + return status; + } + data->orig_conf = status; + data->current_conf = status; + + err = lm75_write_config(data, data->params->set_mask, + data->params->clr_mask); + if (err) + return err; + + err = devm_add_action_or_reset(dev, lm75_remove, data); + if (err) + return err; + + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, + data, &lm75_chip_info, + NULL); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name); + + return 0; +} + +static const struct i2c_device_id lm75_ids[] = { + { "adt75", adt75, }, + { "at30ts74", at30ts74, }, + { "ds1775", ds1775, }, + { "ds75", ds75, }, + { "ds7505", ds7505, }, + { "g751", g751, }, + { "lm75", lm75, }, + { "lm75a", lm75a, }, + { "lm75b", lm75b, }, + { "max6625", max6625, }, + { "max6626", max6626, }, + { "max31725", max31725, }, + { "max31726", max31725, }, + { "mcp980x", mcp980x, }, + { "pct2075", pct2075, }, + { "stds75", stds75, }, + { "stlm75", stlm75, }, + { "tcn75", tcn75, }, + { "tmp100", tmp100, }, + { "tmp101", tmp101, }, + { "tmp105", tmp105, }, + { "tmp112", tmp112, }, + { "tmp175", tmp175, }, + { "tmp275", tmp275, }, + { "tmp75", tmp75, }, + { "tmp75b", tmp75b, }, + { "tmp75c", tmp75c, }, + { "tmp1075", tmp1075, }, + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, lm75_ids); + +static const struct of_device_id __maybe_unused lm75_of_match[] = { + { + .compatible = "adi,adt75", + .data = (void *)adt75 + }, + { + .compatible = "atmel,at30ts74", + .data = (void *)at30ts74 + }, + { + .compatible = "dallas,ds1775", + .data = (void *)ds1775 + }, + { + .compatible = "dallas,ds75", + .data = (void *)ds75 + }, + { + .compatible = "dallas,ds7505", + .data = (void *)ds7505 + }, + { + .compatible = "gmt,g751", + .data = (void *)g751 + }, + { + .compatible = "national,lm75", + .data = (void *)lm75 + }, + { + .compatible = "national,lm75a", + .data = (void *)lm75a + }, + { + .compatible = "national,lm75b", + .data = (void *)lm75b + }, + { + .compatible = "maxim,max6625", + .data = (void *)max6625 + }, + { + .compatible = "maxim,max6626", + .data = (void *)max6626 + }, + { + .compatible = "maxim,max31725", + .data = (void *)max31725 + }, + { + .compatible = "maxim,max31726", + .data = (void *)max31725 + }, + { + .compatible = "maxim,mcp980x", + .data = (void *)mcp980x + }, + { + .compatible = "nxp,pct2075", + .data = (void *)pct2075 + }, + { + .compatible = "st,stds75", + .data = (void *)stds75 + }, + { + .compatible = "st,stlm75", + .data = (void *)stlm75 + }, + { + .compatible = "microchip,tcn75", + .data = (void *)tcn75 + }, + { + .compatible = "ti,tmp100", + .data = (void *)tmp100 + }, + { + .compatible = "ti,tmp101", + .data = (void *)tmp101 + }, + { + .compatible = "ti,tmp105", + .data = (void *)tmp105 + }, + { + .compatible = "ti,tmp112", + .data = (void *)tmp112 + }, + { + .compatible = "ti,tmp175", + .data = (void *)tmp175 + }, + { + .compatible = "ti,tmp275", + .data = (void *)tmp275 + }, + { + .compatible = "ti,tmp75", + .data = (void *)tmp75 + }, + { + .compatible = "ti,tmp75b", + .data = (void *)tmp75b + }, + { + .compatible = "ti,tmp75c", + .data = (void *)tmp75c + }, + { + .compatible = "ti,tmp1075", + .data = (void *)tmp1075 + }, + { }, +}; +MODULE_DEVICE_TABLE(of, lm75_of_match); + +#define LM75A_ID 0xA1 + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm75_detect(struct i2c_client *new_client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int i; + int conf, hyst, os; + bool is_lm75a = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + /* + * Now, we do the remaining detection. There is no identification- + * dedicated register so we have to rely on several tricks: + * unused bits, registers cycling over 8-address boundaries, + * addresses 0x04-0x07 returning the last read value. + * The cycling+unused addresses combination is not tested, + * since it would significantly slow the detection down and would + * hardly add any value. + * + * The National Semiconductor LM75A is different than earlier + * LM75s. It has an ID byte of 0xaX (where X is the chip + * revision, with 1 being the only revision in existence) in + * register 7, and unused registers return 0xff rather than the + * last read value. + * + * Note that this function only detects the original National + * Semiconductor LM75 and the LM75A. Clones from other vendors + * aren't detected, on purpose, because they are typically never + * found on PC hardware. They are found on embedded designs where + * they can be instantiated explicitly so detection is not needed. + * The absence of identification registers on all these clones + * would make their exhaustive detection very difficult and weak, + * and odds are that the driver would bind to unsupported devices. + */ + + /* Unused bits */ + conf = i2c_smbus_read_byte_data(new_client, 1); + if (conf & 0xe0) + return -ENODEV; + + /* First check for LM75A */ + if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { + /* + * LM75A returns 0xff on unused registers so + * just to be sure we check for that too. + */ + if (i2c_smbus_read_byte_data(new_client, 4) != 0xff + || i2c_smbus_read_byte_data(new_client, 5) != 0xff + || i2c_smbus_read_byte_data(new_client, 6) != 0xff) + return -ENODEV; + is_lm75a = 1; + hyst = i2c_smbus_read_byte_data(new_client, 2); + os = i2c_smbus_read_byte_data(new_client, 3); + } else { /* Traditional style LM75 detection */ + /* Unused addresses */ + hyst = i2c_smbus_read_byte_data(new_client, 2); + if (i2c_smbus_read_byte_data(new_client, 4) != hyst + || i2c_smbus_read_byte_data(new_client, 5) != hyst + || i2c_smbus_read_byte_data(new_client, 6) != hyst + || i2c_smbus_read_byte_data(new_client, 7) != hyst) + return -ENODEV; + os = i2c_smbus_read_byte_data(new_client, 3); + if (i2c_smbus_read_byte_data(new_client, 4) != os + || i2c_smbus_read_byte_data(new_client, 5) != os + || i2c_smbus_read_byte_data(new_client, 6) != os + || i2c_smbus_read_byte_data(new_client, 7) != os) + return -ENODEV; + } + /* + * It is very unlikely that this is a LM75 if both + * hysteresis and temperature limit registers are 0. + */ + if (hyst == 0 && os == 0) + return -ENODEV; + + /* Addresses cycling */ + for (i = 8; i <= 248; i += 40) { + if (i2c_smbus_read_byte_data(new_client, i + 1) != conf + || i2c_smbus_read_byte_data(new_client, i + 2) != hyst + || i2c_smbus_read_byte_data(new_client, i + 3) != os) + return -ENODEV; + if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) + != LM75A_ID) + return -ENODEV; + } + + strscpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); + + return 0; +} + +#ifdef CONFIG_PM +static int lm75_suspend(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + + status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status | LM75_SHUTDOWN; + i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); + return 0; +} + +static int lm75_resume(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + + status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status & ~LM75_SHUTDOWN; + i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); + return 0; +} + +static const struct dev_pm_ops lm75_dev_pm_ops = { + .suspend = lm75_suspend, + .resume = lm75_resume, +}; +#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) +#else +#define LM75_DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + +static struct i2c_driver lm75_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "lm75", + .of_match_table = of_match_ptr(lm75_of_match), + .pm = LM75_DEV_PM_OPS, + }, + .probe_new = lm75_probe, + .id_table = lm75_ids, + .detect = lm75_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(lm75_driver); + +MODULE_AUTHOR("Frodo Looijaard "); +MODULE_DESCRIPTION("Custom LM75 driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/lm75.h b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/lm75.h new file mode 100644 index 000000000000..b803ada5e3c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/lm75.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * lm75.h - Part of lm_sensors, Linux kernel modules for hardware monitoring + * Copyright (c) 2003 Mark M. Hoffman + */ + +/* + * This file contains common code for encoding/decoding LM75 type + * temperature readings, which are emulated by many of the chips + * we support. As the user is unlikely to load more than one driver + * which contains this code, we don't worry about the wasted space. + */ + +#include +#include + +/* straight from the datasheet */ +#define LM75_TEMP_MIN (-55000) +#define LM75_TEMP_MAX 125000 +#define LM75_SHUTDOWN 0x01 + +/* + * TEMP: 0.001C/bit (-55C to +125C) + * REG: (0.5C/bit, two's complement) << 7 + */ +static inline u16 LM75_TEMP_TO_REG(long temp) +{ + int ntemp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + + ntemp += (ntemp < 0 ? -250 : 250); + return (u16)((ntemp / 500) << 7); +} + +static inline int LM75_TEMP_FROM_REG(u16 reg) +{ + /* + * use integer division instead of equivalent right shift to + * guarantee arithmetic shift and preserve the sign + */ + return ((s16)reg / 128) * 500; +} diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/mc24lc64t.c new file mode 100644 index 000000000000..638d59d653ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/mc24lc64t.c @@ -0,0 +1,172 @@ +/* + * mc24lc64t.c - driver for Microchip 24LC64T + * + * Copyright (C) 2017 Celestica Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EEPROM_SIZE 8192 //mc24lt64t eeprom size in bytes. + +struct mc24lc64t_data { + struct mutex update_lock; +}; + +static ssize_t mc24lc64t_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, read_time, i = 0; + int status; + + mutex_lock(&drvdata->update_lock); + + if (i2c_smbus_write_byte_data(client, off>>8, off)) + { + status = -EIO; + goto exit; + } + + msleep(1); + +begin: + + if (i < count) + { + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + do { + read_time = jiffies; + + status = i2c_smbus_read_byte(client); + if (status >= 0) + { + buf[i++] = status; + goto begin; + } + } while (time_before(read_time, timeout)); + + status = -ETIMEDOUT; + goto exit; + } + + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + + return status; +} + + +static ssize_t mc24lc64t_write (struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count){ + + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, write_time, i = 0; + int status; + u16 value; + + mutex_lock(&drvdata->update_lock); + +begin: + if (i < count){ + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + value = (buf[i] << 8 | ( off &0xff)); + do { + write_time = jiffies; + status = i2c_smbus_write_word_data(client, off>>8, value); + if (status >= 0) + { + // increase offset + off++; + // increase buffer index + i++; + goto begin; + } + } while (time_before(write_time, timeout)); + status = -ETIMEDOUT; + goto exit; + } + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + return status; +} + + +static struct bin_attribute mc24lc64t_bit_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUGO, + }, + .size = EEPROM_SIZE, + .read = mc24lc64t_read, + .write = mc24lc64t_write, +}; + +static int mc24lc64t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct mc24lc64t_data *drvdata; + int err; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -EPFNOSUPPORT; + + if (!(drvdata = devm_kzalloc(&client->dev, + sizeof(struct mc24lc64t_data), GFP_KERNEL))) + return -ENOMEM; + + i2c_set_clientdata(client, drvdata); + mutex_init(&drvdata->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + return err; +} + +static void mc24lc64t_remove(struct i2c_client *client) +{ + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); +} + +static const struct i2c_device_id mc24lc64t_id[] = { + { "24lc64t", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mc24lc64t_id); + +static struct i2c_driver mc24lc64t_driver = { + .driver = { + .name = "mc24lc64t", + .owner = THIS_MODULE, + }, + .probe = mc24lc64t_probe, + .remove = mc24lc64t_remove, + .id_table = mc24lc64t_id, +}; + +module_i2c_driver(mc24lc64t_driver); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Microchip 24LC64T Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/pddf_custom_fpga_algo.c b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/pddf_custom_fpga_algo.c new file mode 100644 index 000000000000..2e56d03ab790 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/pddf_custom_fpga_algo.c @@ -0,0 +1,626 @@ +/* + * pddf_custom_fpga_algo.c - driver algorithm for FPGAPCIE AXI IIC. + * + * Copyright (C) 2023 Celestica Corp. + * + * 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. + * + */ + +#define __STDC_WANT_LIB_EXT1__ 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../../pddf/i2c/modules/include/pddf_i2c_algo.h" + +#define DEBUG_KERN 0 + +enum { + STATE_DONE = 0, + STATE_INIT, + STATE_ADDR, + STATE_ADDR10, + STATE_START, + STATE_WRITE, + STATE_READ, + STATE_STOP, + STATE_ERROR, +}; + +#define XIIC_MSB_OFFSET 0 +#define XIIC_REG_OFFSET (0x100 + XIIC_MSB_OFFSET) + +/* + * Register offsets in bytes from RegisterBase. Three is added to the + * base offset to access LSB (IBM style) of the word + */ +#define XIIC_CR_REG_OFFSET (0x00 + XIIC_REG_OFFSET) /* Control Register */ +#define XIIC_SR_REG_OFFSET (0x04 + XIIC_REG_OFFSET) /* Status Register */ +#define XIIC_DTR_REG_OFFSET (0x08 + XIIC_REG_OFFSET) /* Data Tx Register */ +#define XIIC_DRR_REG_OFFSET (0x0C + XIIC_REG_OFFSET) /* Data Rx Register */ +#define XIIC_ADR_REG_OFFSET (0x10 + XIIC_REG_OFFSET) /* Address Register */ +#define XIIC_TFO_REG_OFFSET (0x14 + XIIC_REG_OFFSET) /* Tx FIFO Occupancy */ +#define XIIC_RFO_REG_OFFSET (0x18 + XIIC_REG_OFFSET) /* Rx FIFO Occupancy */ +#define XIIC_TBA_REG_OFFSET (0x1C + XIIC_REG_OFFSET) /* 10 Bit Address reg */ +#define XIIC_RFD_REG_OFFSET (0x20 + XIIC_REG_OFFSET) /* Rx FIFO Depth reg */ +#define XIIC_GPO_REG_OFFSET (0x24 + XIIC_REG_OFFSET) /* Output Register */ + +/* Control Register masks */ +#define XIIC_CR_ENABLE_DEVICE_MASK 0x01 /* Device enable = 1 */ +#define XIIC_CR_TX_FIFO_RESET_MASK 0x02 /* Transmit FIFO reset=1 */ +#define XIIC_CR_MSMS_MASK 0x04 /* Master starts Txing=1 */ +#define XIIC_CR_DIR_IS_TX_MASK 0x08 /* Dir of tx. Txing=1 */ +#define XIIC_CR_NO_ACK_MASK 0x10 /* Tx Ack. NO ack = 1 */ +#define XIIC_CR_REPEATED_START_MASK 0x20 /* Repeated start = 1 */ +#define XIIC_CR_GENERAL_CALL_MASK 0x40 /* Gen Call enabled = 1 */ + +/* Status Register masks */ +#define XIIC_SR_GEN_CALL_MASK 0x01 /* 1=a mstr issued a GC */ +#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x02 /* 1=when addr as slave */ +#define XIIC_SR_BUS_BUSY_MASK 0x04 /* 1 = bus is busy */ +#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x08 /* 1=Dir: mstr <-- slave */ +#define XIIC_SR_TX_FIFO_FULL_MASK 0x10 /* 1 = Tx FIFO full */ +#define XIIC_SR_RX_FIFO_FULL_MASK 0x20 /* 1 = Rx FIFO full */ +#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x40 /* 1 = Rx FIFO empty */ +#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x80 /* 1 = Tx FIFO empty */ + +/* Interrupt Status Register masks Interrupt occurs when... */ +#define XIIC_INTR_ARB_LOST_MASK 0x01 /* 1 = arbitration lost */ +#define XIIC_INTR_TX_ERROR_MASK 0x02 /* 1=Tx error/msg complete */ +#define XIIC_INTR_TX_EMPTY_MASK 0x04 /* 1 = Tx FIFO/reg empty */ +#define XIIC_INTR_RX_FULL_MASK 0x08 /* 1=Rx FIFO/reg=OCY level */ +#define XIIC_INTR_BNB_MASK 0x10 /* 1 = Bus not busy */ +#define XIIC_INTR_AAS_MASK 0x20 /* 1 = when addr as slave */ +#define XIIC_INTR_NAAS_MASK 0x40 /* 1 = not addr as slave */ +#define XIIC_INTR_TX_HALF_MASK 0x80 /* 1 = TX FIFO half empty */ + +/* The following constants specify the depth of the FIFOs */ +#define IIC_RX_FIFO_DEPTH 16 /* Rx fifo capacity */ +#define IIC_TX_FIFO_DEPTH 16 /* Tx fifo capacity */ + +/* + * Tx Fifo upper bit masks. + */ +#define XIIC_TX_DYN_START_MASK 0x0100 /* 1 = Set dynamic start */ +#define XIIC_TX_DYN_STOP_MASK 0x0200 /* 1 = Set dynamic stop */ + +/* + * The following constants define the register offsets for the Interrupt + * registers. There are some holes in the memory map for reserved addresses + * to allow other registers to be added and still match the memory map of the + * interrupt controller registers + */ +#define XIIC_IISR_OFFSET 0x20 /* Interrupt Status Register */ +#define XIIC_RESETR_OFFSET 0x40 /* Reset Register */ + +#define XIIC_RESET_MASK 0xAUL + +#define XIIC_PM_TIMEOUT 1000 /* ms */ +/* timeout waiting for the controller to respond */ +#define XIIC_I2C_TIMEOUT (msecs_to_jiffies(1000)) + +struct fpgalogic_i2c { + void __iomem *base; + u32 reg_shift; + u32 reg_io_width; + wait_queue_head_t wait; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int ip_clock_khz; + int bus_clock_khz; + void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); + u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); + u32 timeout; + struct mutex lock; +}; + +static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; +extern void __iomem * fpga_ctl_addr; +extern int (*ptr_fpgapci_read)(uint32_t); +extern int (*ptr_fpgapci_write)(uint32_t, uint32_t); +extern int (*pddf_i2c_pci_add_numbered_bus)(struct i2c_adapter *, int); +static int xiic_reinit(struct fpgalogic_i2c *i2c); + + +void i2c_get_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_lock(&i2c->lock); +} + +/** + * i2c_release_mutex - release mutex + */ +void i2c_release_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_unlock(&i2c->lock); +} + +static inline void xiic_setreg32(struct fpgalogic_i2c *i2c, int reg, int value) +{ + (void)iowrite32(value, i2c->base + reg); +} + +static inline int xiic_getreg32(struct fpgalogic_i2c *i2c, int reg) +{ + u32 ret; + + ret = ioread32(i2c->base + reg); + + return ret; +} + +static inline void xiic_irq_clr(struct fpgalogic_i2c *i2c, u32 mask) +{ + u32 isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET); + + xiic_setreg32(i2c, XIIC_IISR_OFFSET, isr & mask); +} + +static int xiic_clear_rx_fifo(struct fpgalogic_i2c *i2c) +{ + u8 sr; + unsigned long timeout; + + timeout = jiffies + XIIC_I2C_TIMEOUT; + for (sr = xiic_getreg32(i2c, XIIC_SR_REG_OFFSET); + !(sr & XIIC_SR_RX_FIFO_EMPTY_MASK); + sr = xiic_getreg32(i2c, XIIC_SR_REG_OFFSET)) { + xiic_getreg32(i2c, XIIC_DRR_REG_OFFSET); + if (time_after(jiffies, timeout)) { + printk("Failed to clear rx fifo\n"); + return -ETIMEDOUT; + } + } + + return 0; +} + +/** + * Wait until something change in a given register + * @i2c: AXI IIC device instance + * @reg: register to query + * @mask: bitmask to apply on register value + * @val: expected result + * @timeout: timeout in jiffies + * + * Timeout is necessary to avoid to stay here forever when the chip + * does not answer correctly. + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int poll_wait(struct fpgalogic_i2c *i2c, + int reg, u8 mask, u8 val, + const unsigned long timeout) +{ + unsigned long j; + u8 status = 0; + + j = jiffies + timeout; + while (1) { + mutex_lock(&i2c->lock); + status = xiic_getreg32(i2c, reg); + mutex_unlock(&i2c->lock); + if ((status & mask) == val) + break; + if (time_after(jiffies, j)) + return -ETIMEDOUT; + cpu_relax(); + cond_resched(); + } + return 0; +} + +/** + * Wait until is possible to process some data + * @i2c: AXI IIC device instance + * + * Used when the device is in polling mode (interrupts disabled). + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int xiic_poll_wait(struct fpgalogic_i2c *i2c) +{ + u8 mask = 0, status = 0; + int err = 0; + int val = 0; + int tmp = 0; + mutex_lock(&i2c->lock); + if (i2c->state == STATE_DONE) { + /* transfer is over */ + mask = XIIC_SR_BUS_BUSY_MASK; + } else if (i2c->state == STATE_WRITE || i2c->state == STATE_START){ + /* on going transfer */ + if (0 == i2c->msg->len){ + mask = XIIC_INTR_TX_ERROR_MASK; + } else { + mask = XIIC_SR_TX_FIFO_FULL_MASK; + } + } + else if (i2c->state == STATE_READ){ + /* on going receive */ + mask = XIIC_SR_TX_FIFO_EMPTY_MASK | XIIC_SR_RX_FIFO_EMPTY_MASK; + } + mutex_unlock(&i2c->lock); + // printk("Wait for: 0x%x\n", mask); + + /* + * once we are here we expect to get the expected result immediately + * so if after 50ms we timeout then something is broken. + */ + + if (1 == i2c->nmsgs && 0 == i2c->msg->len && i2c->state == STATE_START && !(i2c->msg->flags & I2C_M_RD)) { /* for i2cdetect I2C_SMBUS_QUICK mode*/ + err = poll_wait(i2c, XIIC_IISR_OFFSET, mask, mask, msecs_to_jiffies(50)); + mutex_lock(&i2c->lock); + status = xiic_getreg32(i2c, XIIC_SR_REG_OFFSET); + mutex_unlock(&i2c->lock); + if (0 != err) { /* AXI IIC as an transceiver , if ever an XIIC_INTR_TX_ERROR_MASK interrupt happens, means no such i2c device */ + err = 0; + } else { + err = -ETIMEDOUT; + } + } else { + if (mask & XIIC_SR_TX_FIFO_EMPTY_MASK){ + err = poll_wait(i2c, XIIC_SR_REG_OFFSET, mask, XIIC_SR_TX_FIFO_EMPTY_MASK, msecs_to_jiffies(50)); + mask &= ~XIIC_SR_TX_FIFO_EMPTY_MASK; + } + if (0 == err){ + err = poll_wait(i2c, XIIC_SR_REG_OFFSET, mask, 0, msecs_to_jiffies(50)); + } + mutex_lock(&i2c->lock); + status = xiic_getreg32(i2c, XIIC_IISR_OFFSET); + + if ((status & XIIC_INTR_ARB_LOST_MASK) || + ((status & XIIC_INTR_TX_ERROR_MASK) && + !(status & XIIC_INTR_RX_FULL_MASK) && + !(i2c->msg->flags & I2C_M_RD))) { /* AXI IIC as an transceiver , if ever an XIIC_INTR_TX_ERROR_MASK interrupt happens, return */ + err = -ETIMEDOUT; + + if (status & XIIC_INTR_ARB_LOST_MASK) { + val = xiic_getreg32(i2c, XIIC_CR_REG_OFFSET); + tmp = XIIC_CR_MSMS_MASK; + val &=(~tmp); + xiic_setreg32(i2c, XIIC_CR_REG_OFFSET, val); + xiic_setreg32(i2c, XIIC_IISR_OFFSET, XIIC_INTR_ARB_LOST_MASK); + printk("%s: TRANSFER STATUS ERROR, ISR: bit 0x%x happens\n", + __func__, XIIC_INTR_ARB_LOST_MASK); + } + if (status & XIIC_INTR_TX_ERROR_MASK) { + int sta = 0; + int cr = 0; + sta = xiic_getreg32(i2c,XIIC_SR_REG_OFFSET); + cr = xiic_getreg32(i2c,XIIC_CR_REG_OFFSET); + xiic_setreg32(i2c, XIIC_IISR_OFFSET, XIIC_INTR_TX_ERROR_MASK); + printk("%s: TRANSFER STATUS ERROR, ISR: bit 0x%x happens; SR: bit 0x%x; CR: bit 0x%x\n", + __func__, status, sta, cr); + } + /* Soft reset IIC controller. */ + xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK); + (void)xiic_reinit(i2c); + mutex_unlock(&i2c->lock); + return err; + } + mutex_unlock(&i2c->lock); + } + + if (err) + printk("%s: STATUS timeout, bit 0x%x did not clear in 50ms\n", + __func__, status); + return err; +} + +static void xiic_process(struct fpgalogic_i2c *i2c) +{ + struct i2c_msg *msg = i2c->msg; + //unsigned long flags; + u16 val; + + /* + * If we spin here because we are in timeout, so we are going + * to be in STATE_ERROR. + */ + mutex_lock(&i2c->lock); + // printk("STATE: %d\n", i2c->state); + + if (i2c->state == STATE_START) { + i2c->state =(msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + /* if it's the time sequence is 'start bit + address + read bit + stop bit' */ + if (i2c->state == STATE_READ){ + /* it's the last message so we include dynamic stop bit with length */ + val = msg->len | XIIC_TX_DYN_STOP_MASK; + xiic_setreg32(i2c, XIIC_DTR_REG_OFFSET, val); + goto out; + } + } + if (i2c->state == STATE_READ){ + /* suit for I2C_FUNC_SMBUS_BLOCK_DATA */ + if (msg->flags & I2C_M_RECV_LEN) { + msg->len = xiic_getreg32(i2c, XIIC_DRR_REG_OFFSET); + msg->flags &= ~I2C_M_RECV_LEN; + msg->buf[i2c->pos++] = msg->len; + } + else { + msg->buf[i2c->pos++] = xiic_getreg32(i2c, XIIC_DRR_REG_OFFSET); + } + } else if (i2c->state == STATE_WRITE){ + /* if it reaches the last byte data to be sent */ + if ((i2c->pos == msg->len - 1) && (i2c->nmsgs == 1)){ + val = msg->buf[i2c->pos++] | XIIC_TX_DYN_STOP_MASK; + xiic_setreg32(i2c, XIIC_DTR_REG_OFFSET, val); + i2c->state = STATE_DONE; + goto out; + /* if it is not the last byte data to be sent */ + } else if (i2c->pos < msg->len) { + xiic_setreg32(i2c, XIIC_DTR_REG_OFFSET, msg->buf[i2c->pos++]); + goto out; + } + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + i2c->nmsgs--; + i2c->pos = 0; + if (i2c->nmsgs) { + i2c->msg++; + msg = i2c->msg; + if (!(msg->flags & I2C_M_NOSTART)) /* send start? */{ + i2c->state = STATE_START; + xiic_setreg32(i2c, XIIC_DTR_REG_OFFSET, i2c_8bit_addr_from_msg(msg) | XIIC_TX_DYN_START_MASK); + goto out; + } + } else { /* end? */ + i2c->state = STATE_DONE; + goto out; + } + } + +out: + mutex_unlock(&i2c->lock); + return ; +} + +static int fpga_axi_iic_poll(struct fpgalogic_i2c *i2c, + struct i2c_msg *msgs, int num) +{ + int ret = 0; + // u8 ctrl; + + mutex_lock(&i2c->lock); + /* Soft reset IIC controller. */ + xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK); + /* Set receive Fifo depth to maximum (zero based). */ + xiic_setreg32(i2c, XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1); + + /* Reset Tx Fifo. */ + xiic_setreg32(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK); + + /* Enable IIC Device, remove Tx Fifo reset & disable general call. */ + xiic_setreg32(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK); + + /* set i2c clock as 100Hz. */ + //xiic_setreg32(i2c, 0x13c, 0x7C); + + /* make sure RX fifo is empty */ + ret = xiic_clear_rx_fifo(i2c); + if (ret){ + mutex_unlock(&i2c->lock); + return ret; + } + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = STATE_START; + + // printk("STATE: %d\n", i2c->state); + + if (msgs->len == 0 && num == 1){ /* suit for i2cdetect time sequence */ + u8 status = xiic_getreg32(i2c, XIIC_IISR_OFFSET); + xiic_irq_clr(i2c, status); + /* send out the 1st byte data and stop bit */ + xiic_setreg32(i2c, XIIC_DTR_REG_OFFSET, i2c_8bit_addr_from_msg(msgs) | XIIC_TX_DYN_START_MASK | XIIC_TX_DYN_STOP_MASK); + } else { + /* send out the 1st byte data */ + xiic_setreg32(i2c, XIIC_DTR_REG_OFFSET, i2c_8bit_addr_from_msg(msgs) | XIIC_TX_DYN_START_MASK); + } + mutex_unlock(&i2c->lock); + while (1) { + int err; + + err = xiic_poll_wait(i2c); + if (err) { + i2c->state = STATE_ERROR; + break; + }else if (i2c->state == STATE_DONE){ + break; + } + xiic_process(i2c); + } + + return (i2c->state == STATE_DONE) ? num : -EIO; +} + +static int fpga_axi_iic_access(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct fpgalogic_i2c *i2c = i2c_get_adapdata(adap); + int err = -EIO; + u8 retry = 0, max_retry = 0; + + if(((1 == msgs->len && (msgs->flags & I2C_M_RD)) + || (0 == msgs->len && !(msgs->flags & I2C_M_RD)) ) && num == 1 ) /* I2C_SMBUS_QUICK or I2C_SMBUS_BYTE */ + max_retry = 1; + else + max_retry = 5; // retry 5 times if receive a NACK or other errors + + while((-EIO == err) && (retry < max_retry)) + { + err = fpga_axi_iic_poll(i2c, msgs, num); + retry++; + } + + return err; +} + +/** + * A callback function show available smbus functions. + */ +static u32 fpga_axi_iic_func(struct i2c_adapter *adap) +{ + /* a typical full-I2C adapter would use the following */ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK; +} + +static const struct i2c_algorithm axi_iic_algorithm = { + .master_xfer = fpga_axi_iic_access, + .functionality = fpga_axi_iic_func, +}; + +static int xiic_reinit(struct fpgalogic_i2c *i2c) +{ + int ret; + int val = 0; + + /* Soft reset IIC controller. */ + xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK); + + /* Set receive Fifo depth to maximum (zero based). */ + xiic_setreg32(i2c, XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1); + + /* Reset Tx Fifo. */ + xiic_setreg32(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK); + + /* Enable IIC Device, remove Tx Fifo reset & disable general call. */ + val |= XIIC_CR_ENABLE_DEVICE_MASK; + //val |= XIIC_CR_TX_FIFO_RESET_MASK; + //val |= XIIC_CR_MSMS_MASK; + val |= XIIC_CR_DIR_IS_TX_MASK; + xiic_setreg32(i2c, XIIC_CR_REG_OFFSET, val); + + /* make sure RX fifo is empty */ + ret = xiic_clear_rx_fifo(i2c); + if (ret) + return ret; + + return 0; +} + +static int fpgai2c_init(struct fpgalogic_i2c *i2c) +{ + // int prescale; + // int diff; + // u8 ctrl; + int ret; + + + //i2c->reg_set = xiic_setreg32; + //i2c->reg_get = xiic_getreg32; + + ret = xiic_reinit(i2c); + if (ret < 0) { + printk("Cannot xiic_reinit\n"); + return ret; + } + + /* Initialize interrupt handlers if not already done */ + init_waitqueue_head(&i2c->wait); + return 0; +}; + +static int adap_data_init(struct i2c_adapter *adap, int i2c_ch_index) +{ + struct fpgapci_devdata *pci_privdata = 0; + pci_privdata = (struct fpgapci_devdata*) dev_get_drvdata(adap->dev.parent); + + if (pci_privdata == 0) { + printk("[%s]: ERROR pci_privdata is 0\n", __FUNCTION__); + return -1; + } +#ifdef DEBUG_KERN + pddf_dbg(FPGA, KERN_INFO "[%s] index: [%d] fpga_data__base_addr:0x%0x8lx" + " fpgapci_bar_len:0x%08lx fpga_i2c_ch_base_addr:0x%08lx ch_size=0x%x supported_i2c_ch=%d", + __FUNCTION__, i2c_ch_index, pci_privdata->fpga_data_base_addr, + pci_privdata->bar_length, pci_privdata->fpga_i2c_ch_base_addr, + pci_privdata->fpga_i2c_ch_size, pci_privdata->max_fpga_i2c_ch); +#endif + if (i2c_ch_index >= pci_privdata->max_fpga_i2c_ch + || pci_privdata->max_fpga_i2c_ch > I2C_PCI_MAX_BUS){ + printk("[%s]: ERROR i2c_ch_index=%d max_ch_index=%d out of range: %d\n", + __FUNCTION__, i2c_ch_index, pci_privdata->max_fpga_i2c_ch, I2C_PCI_MAX_BUS); + return -1; + } + +#ifdef __STDC_LIB_EXT1__ + memset_s(&fpgalogic_i2c[i2c_ch_index], sizeof(fpgalogic_i2c[0]), 0, sizeof(fpgalogic_i2c[0])); +#else + memset(&fpgalogic_i2c[i2c_ch_index], 0, sizeof(fpgalogic_i2c[0])); +#endif + fpgalogic_i2c[i2c_ch_index].base = pci_privdata->fpga_i2c_ch_base_addr + + i2c_ch_index* pci_privdata->fpga_i2c_ch_size; + mutex_init(&fpgalogic_i2c[i2c_ch_index].lock); + fpgai2c_init(&fpgalogic_i2c[i2c_ch_index]); + + adap->algo_data = &fpgalogic_i2c[i2c_ch_index]; + i2c_set_adapdata(adap, &fpgalogic_i2c[i2c_ch_index]); + return 0; +} + +static int pddf_i2c_pci_add_numbered_bus_default (struct i2c_adapter *adap, int i2c_ch_index) +{ + int ret = 0; + + adap_data_init(adap, i2c_ch_index); + adap->algo = &axi_iic_algorithm; + ret = i2c_add_numbered_adapter(adap); + return ret; +} + +/* + * FPGAPCI APIs + */ +static int board_i2c_fpgapci_read(uint32_t offset) +{ + int data; + data=ioread32(fpga_ctl_addr+offset); + return data; +} + + +static int board_i2c_fpgapci_write(uint32_t offset, uint32_t value) +{ + iowrite32(value, fpga_ctl_addr+offset); + return (0); +} + + +static int __init pddf_custom_fpga_algo_init(void) +{ + pddf_dbg(FPGA, KERN_INFO "[%s]\n", __FUNCTION__); + pddf_i2c_pci_add_numbered_bus = &pddf_i2c_pci_add_numbered_bus_default; + ptr_fpgapci_read = board_i2c_fpgapci_read; + ptr_fpgapci_write = board_i2c_fpgapci_write; + return 0; +} +static void __exit pddf_custom_fpga_algo_exit(void) +{ + pddf_dbg(FPGA, KERN_INFO "[%s]\n", __FUNCTION__); + pddf_i2c_pci_add_numbered_bus = NULL; + ptr_fpgapci_read = NULL; + ptr_fpgapci_write = NULL; + return; +} + +module_init(pddf_custom_fpga_algo_init); +module_exit(pddf_custom_fpga_algo_exit); + +MODULE_DESCRIPTION("Module driver algorithm for 7021 FPGAPCIe AXI IIC"); +MODULE_VERSION("1.0.0"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/pddf_custom_fpga_extend.c b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/pddf_custom_fpga_extend.c new file mode 100644 index 000000000000..2840e6a87f05 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/pddf_custom_fpga_extend.c @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * fpga-cls.c - front panel port control. + * + * Copyright (C) 2019 Celestica Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "../../../../pddf/i2c/modules/include/pddf_i2c_algo.h" + +#define FPGA_VERSION_ADDR 0x0000 +#define FPGA_SCRATCH_ADDR 0x0004 +#define FPGA_BCM_TEMP_ADDR 0x001c +#define FPGA_BCM_TEMP_LOW_ADDR 0x0078 +#define FPGA_BCM_TEMP_HIGH_ADDR 0x0080 +#define FPGA_REG_SPACE_SIZE 0x2000 + + +/* + * fpga_priv - port fpga private data + * @dev: device for reference + * @base: virtual base address + * @num_ports: number of front panel ports + * @fp_devs: list of front panel port devices + */ +struct fpga_priv { + void __iomem *base; + struct mutex fpga_lock; // For FPGA internal lock + void __iomem * fpga_read_addr; +}; + +extern void __iomem * fpga_ctl_addr; + +/** + * Show the value of the register set by 'set_fpga_reg_address' + * If the address is not set by 'set_fpga_reg_address' first, + * The version register is selected by default. + * @param buf register value in hextring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + // read data from the address + uint32_t data; + struct fpga_priv *fpga = dev_get_drvdata(dev); + + data = ioread32(fpga->fpga_read_addr); + return sprintf(buf, "0x%8.8x\n", data); +} +/** + * Store the register address + * @param buf address wanted to be read value of + * @return number of bytes stored, or an error code + */ +static ssize_t set_fpga_reg_address(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t addr; + char *last; + struct fpga_priv *fpga = dev_get_drvdata(dev); + + addr = (uint32_t)strtoul(buf, &last, 16); + if (addr == 0 && buf == last) { + return -EINVAL; + } + fpga->fpga_read_addr = fpga->base + addr; + return count; +} +/** + * Show value of fpga scratch register + * @param buf register value in hexstring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_scratch(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct fpga_priv *fpga = dev_get_drvdata(dev); + + return sprintf(buf, "0x%8.8x\n", ioread32(fpga->base + FPGA_SCRATCH_ADDR) & 0xffffffff); +} +/** + * Store value of fpga scratch register + * @param buf scratch register value passing from user space + * @return number of bytes stored, or an error code + */ +static ssize_t set_fpga_scratch(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t data; + char *last; + struct fpga_priv *fpga = dev_get_drvdata(dev); + + data = (uint32_t)strtoul(buf, &last, 16); + if (data == 0 && buf == last) { + return -EINVAL; + } + iowrite32(data, fpga->base + FPGA_SCRATCH_ADDR); + return count; +} + +/** + * Show value of fpga version register + * @param buf register value in hexstring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_version(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct fpga_priv *fpga = dev_get_drvdata(dev); + + return sprintf(buf, "0x%8.8x\n", ioread32(fpga->base + FPGA_VERSION_ADDR) & 0xffffffff); +} + + +/** + * Store a value in a specific register address + * @param buf the value and address in format '0xhhhh 0xhhhhhhhh' + * @return number of bytes sent by user space, or an error code + */ +static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // register are 4 bytes + uint32_t addr; + uint32_t value; + uint32_t mode = 8; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + struct fpga_priv *fpga = dev_get_drvdata(dev); + + strncpy(clone, buf, strlen(buf)-1); // nosemgrep + mutex_lock(&fpga->fpga_lock); + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&fpga->fpga_lock); + return -EINVAL; + } + addr = (uint32_t)strtoul(tok, &last, 16); + if (addr == 0 && tok == last) { + mutex_unlock(&fpga->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&fpga->fpga_lock); + return -EINVAL; + } + value = (uint32_t)strtoul(tok, &last, 16); + if (value == 0 && tok == last) { + mutex_unlock(&fpga->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mode = 32; + } else { + mode = (uint32_t)strtoul(tok, &last, 10); + if (mode == 0 && tok == last) { + mutex_unlock(&fpga->fpga_lock); + return -EINVAL; + } + } + if (mode == 32) { + iowrite32(value, fpga->base + addr); + } else if (mode == 8) { + iowrite8(value, fpga->base + addr); + } else { + mutex_unlock(&fpga->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga->fpga_lock); + return count; +} + +/** + * Read all FPGA register in binary mode. + * @param buf Raw transceivers port startus and control register values + * @return number of bytes read, or an error code + */ +static ssize_t dump_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + unsigned long i = 0; + ssize_t status; + u8 read_reg; + struct device *dev = kobj_to_dev(kobj); + struct fpga_priv *fpga = dev_get_drvdata(dev); + + if ( off + count > FPGA_REG_SPACE_SIZE ) { + return -EINVAL; + } + mutex_lock(&fpga->fpga_lock); + while (i < count) { + read_reg = ioread8(fpga->base + off + i); + buf[i++] = read_reg; + } + status = count; + mutex_unlock(&fpga->fpga_lock); + return status; +} + +/** + * Show value of fpga bcm switch internal temp sensor register calculated by FPGA + * @param buf register value in hexstring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_bcm_temp_fpga(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct fpga_priv *fpga = dev_get_drvdata(dev); + uint32_t reg_val = ioread32(fpga->base + FPGA_BCM_TEMP_ADDR) & 0x3ffff; + + return sprintf(buf, "0x%08x\n", reg_val); +} + +/** + * Show value of fpga bcm switch internal temp sensor register + * @param buf register value in hexstring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_bcm_temp(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct fpga_priv *fpga = dev_get_drvdata(dev); + u8 low_byte = ioread32(fpga->base + FPGA_BCM_TEMP_LOW_ADDR) & 0xff; + u8 high_byte = ioread32(fpga->base + FPGA_BCM_TEMP_HIGH_ADDR) & 0xff; + + return sprintf(buf, "0x%02x%02x\n", high_byte, low_byte); +} + +/* FPGA attributes */ +static DEVICE_ATTR( getreg, 0600, get_fpga_reg_value, set_fpga_reg_address); +static DEVICE_ATTR( setreg, 0200, NULL , set_fpga_reg_value); +static DEVICE_ATTR( scratch, 0600, get_fpga_scratch, set_fpga_scratch); +static DEVICE_ATTR( version, 0400, get_fpga_version, NULL); +static DEVICE_ATTR( bcm_temp_fpga, 0400, get_fpga_bcm_temp_fpga, NULL); +static DEVICE_ATTR( bcm_temp, 0400, get_fpga_bcm_temp, NULL); +static BIN_ATTR_RO( dump, FPGA_REG_SPACE_SIZE); + +static struct bin_attribute *fpga_bin_attrs[] = { + &bin_attr_dump, + NULL, +}; + +static struct attribute *fpga_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_version.attr, + &dev_attr_bcm_temp_fpga.attr, + &dev_attr_bcm_temp.attr, + &dev_attr_setreg.attr, + NULL, +}; + +static struct attribute_group fpga_attr_grp = { + .attrs = fpga_attrs, + .bin_attrs = fpga_bin_attrs, +}; + + +static int cls_fpga_probe(struct platform_device *pdev) +{ + struct fpga_priv *fpga; + int ret = -ENOMEM; + + if (!fpga_ctl_addr){ + printk(KERN_WARNING, "fpga_ctl_addr is null"); + return ret; + } + + fpga = devm_kzalloc(&pdev->dev, sizeof(struct fpga_priv), GFP_KERNEL); + if (!fpga){ + ret = -ENOMEM; + goto err_exit; + } + + mutex_init(&fpga->fpga_lock); + dev_set_drvdata(&pdev->dev, fpga); + fpga->base = fpga_ctl_addr; + + printk("FPGA version: 0x%x\n", ioread32(fpga->base + FPGA_VERSION_ADDR)); + + ret = sysfs_create_group(&pdev->dev.kobj, &fpga_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create FPGA system sysfs attributes\n"); + goto err_remove_fpga; + } + + return 0; + +err_remove_fpga: + sysfs_remove_group(&pdev->dev.kobj, &fpga_attr_grp); +mem_unmap: + iounmap(fpga->base); +err_exit: + return ret; +} + +static int cls_fpga_remove(struct platform_device *pdev) +{ + struct fpga_priv *fpga = dev_get_drvdata(&pdev->dev); + + sysfs_remove_group(&pdev->dev.kobj, &fpga_attr_grp); + iounmap(fpga->base); + return 0; +} + +static void fpga_dev_release( struct device * dev) +{ + return; +} +static struct resource cls_fpga_resources[] = { + { + .start = NULL, + .end = NULL, + .flags = IORESOURCE_IO, + }, +}; + +static struct platform_device cls_fpga_dev = { + .name = "fpga_sysfs", + .id = -1, + .num_resources = ARRAY_SIZE(cls_fpga_resources), + .resource = cls_fpga_resources, + .dev = { + .release = fpga_dev_release, + } +}; + +static struct platform_driver cls_fpga_driver = { + .probe = cls_fpga_probe, + .remove = cls_fpga_remove, + .driver = { + .name = "fpga_sysfs", + }, +}; + +static int __init drv_init(void) +{ + int rc = 0; + + rc = platform_device_register(&cls_fpga_dev); + rc += platform_driver_register(&cls_fpga_driver); + printk("fpga drv_init:%d\n", rc); + return rc; +} + +static void __exit drv_exit(void) +{ + platform_driver_unregister(&cls_fpga_driver); + platform_device_unregister(&cls_fpga_dev); + printk("fpga drv_exit.\n"); +} + +module_init(drv_init); +module_exit(drv_exit); + +MODULE_AUTHOR("Nicholas Wu"); +MODULE_DESCRIPTION("Celestica fpga access/control driver"); +MODULE_VERSION("2.0.0"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:cls-fpga"); diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_api.c b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_api.c new file mode 100644 index 000000000000..1e1dcdba80e5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_api.c @@ -0,0 +1,478 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. + * + * 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. + * + * + * Description of various APIs related to PSU component + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../../../pddf/i2c/modules/include/pddf_psu_defs.h" +#include "pddf_psu_driver.h" + + +#define PSU_REG_VOUT_MODE 0x20 +#define PSU_REG_READ_VOUT 0x8b + +/*#define PSU_DEBUG*/ +#ifdef PSU_DEBUG +#define psu_dbg(...) printk(__VA_ARGS__) +#else +#define psu_dbg(...) +#endif + + +void get_psu_duplicate_sysfs(int idx, char *str) +{ + switch (idx) + { + case PSU_V_OUT: + strcpy(str, "in3_input"); // nosemgrep + break; + case PSU_I_OUT: + strcpy(str, "curr2_input"); // nosemgrep + break; + case PSU_P_OUT: + strcpy(str, "power2_input"); // nosemgrep + break; + case PSU_FAN1_SPEED: + strcpy(str, "fan1_input"); // nosemgrep + break; + case PSU_TEMP1_INPUT: + strcpy(str, "temp1_input"); // nosemgrep + break; + default: + break; + } + + return; +} + +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 u8 psu_get_vout_mode(struct i2c_client *client) +{ + u8 status = 0, retry = 10; + uint8_t offset = PSU_REG_VOUT_MODE; + + while (retry) + { + status = i2c_smbus_read_byte_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + printk(KERN_ERR "%s: Get PSU Vout mode failed\n", __func__); + return 0; + } + else + { + /*printk(KERN_ERR "%s: vout_mode reg value 0x%x\n", __func__, status);*/ + return status; + } +} + +static u16 psu_get_v_out(struct i2c_client *client) +{ + u16 status = 0, retry = 10; + uint8_t offset = PSU_REG_READ_VOUT; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + printk(KERN_ERR "%s: Get PSU Vout failed\n", __func__); + return 0; + } + else + { + /*printk(KERN_ERR "%s: vout reg value 0x%x\n", __func__, status);*/ + return status; + } +} + +int psu_update_hw(struct device *dev, struct psu_attr_info *info, PSU_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + PSU_SYSFS_ATTR_DATA *sysfs_attr_data = NULL; + + + mutex_lock(&info->update_lock); + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_set != NULL) + { + status = (sysfs_attr_data->pre_set)(client, udata, info); + if (status!=0) + dev_warn(&client->dev, "%s: pre_set function fails for %s attribute. ret %d\n", __FUNCTION__, udata->aname, status); + } + if (sysfs_attr_data->do_set != NULL) + { + status = (sysfs_attr_data->do_set)(client, udata, info); + if (status!=0) + dev_warn(&client->dev, "%s: do_set function fails for %s attribute. ret %d\n", __FUNCTION__, udata->aname, status); + + } + if (sysfs_attr_data->post_set != NULL) + { + status = (sysfs_attr_data->post_set)(client, udata, info); + if (status!=0) + dev_warn(&client->dev, "%s: post_set function fails for %s attribute. ret %d\n", __FUNCTION__, udata->aname, status); + } + + mutex_unlock(&info->update_lock); + + return 0; +} + + +int psu_update_attr(struct device *dev, struct psu_attr_info *data, PSU_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + PSU_SYSFS_ATTR_DATA *sysfs_attr_data=NULL; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) + { + dev_dbg(&client->dev, "Starting update for %s\n", data->name); + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_get != NULL) + { + status = (sysfs_attr_data->pre_get)(client, udata, data); + if (status!=0) + dev_warn(&client->dev, "%s: pre_get function fails for %s attribute. ret %d\n", __FUNCTION__, udata->aname, status); + } + if (sysfs_attr_data->do_get != NULL) + { + status = (sysfs_attr_data->do_get)(client, udata, data); + if (status!=0) + dev_warn(&client->dev, "%s: do_get function fails for %s attribute. ret %d\n", __FUNCTION__, udata->aname, status); + + } + if (sysfs_attr_data->post_get != NULL) + { + status = (sysfs_attr_data->post_get)(client, udata, data); + if (status!=0) + dev_warn(&client->dev, "%s: post_get function fails for %s attribute. ret %d\n", __FUNCTION__, udata->aname, status); + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + return 0; +} + +ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct psu_data *data = i2c_get_clientdata(client); + PSU_PDATA *pdata = (PSU_PDATA *)(client->dev.platform_data); + PSU_DATA_ATTR *usr_data = NULL; + struct psu_attr_info *sysfs_attr_info = NULL; + int i, status=0; + u16 value = 0; + u8 vout_mode = 0; + int exponent, mantissa; + int multiplier = 1000; + char new_str[ATTR_NAME_LEN] = ""; + PSU_SYSFS_ATTR_DATA *ptr = NULL; + + for (i=0;inum_attr;i++) + { + ptr = (PSU_SYSFS_ATTR_DATA *)pdata->psu_attrs[i].access_data; + get_psu_duplicate_sysfs(ptr->index , new_str); + if ( strcmp(attr->dev_attr.attr.name, pdata->psu_attrs[i].aname) == 0 || strcmp(attr->dev_attr.attr.name, new_str) == 0 ) + { + sysfs_attr_info = &data->attr_info[i]; + usr_data = &pdata->psu_attrs[i]; + strcpy(new_str, ""); // nosemgrep + } + } + + if (sysfs_attr_info==NULL || usr_data==NULL) + { + printk(KERN_ERR "%s is not supported attribute for this client\n", attr->dev_attr.attr.name); + goto exit; + } + + psu_update_attr(dev, sysfs_attr_info, usr_data); + + switch(attr->index) + { + case PSU_PRESENT: + case PSU_POWER_GOOD: + status = sysfs_attr_info->val.intval; + return sprintf(buf, "%d\n", status); + break; + case PSU_MODEL_NAME: + case PSU_MFR_ID: + case PSU_SERIAL_NUM: + case PSU_FAN_DIR: + return sprintf(buf, "%s\n", sysfs_attr_info->val.strval); + break; + case PSU_V_OUT: + value = psu_get_v_out(client); + vout_mode = psu_get_vout_mode(client); + if ((vout_mode >> 5) == 0) + exponent = two_complement_to_int(vout_mode & 0x1f, 5, 0x1f); + else + exponent = 0; + + mantissa = value; + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + break; + + case PSU_V_OUT_MIN: + case PSU_V_OUT_MAX: + multiplier = 1000; + value = sysfs_attr_info->val.shortval; + vout_mode = psu_get_vout_mode(client); + if ((vout_mode >> 5) == 0) + exponent = two_complement_to_int(vout_mode & 0x1f, 5, 0x1f); + else + exponent = 0; + mantissa = two_complement_to_int(value & 0xffff, 16, 0xffff); + + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + break; + case PSU_I_OUT: + case PSU_V_IN: + case PSU_I_IN: + case PSU_P_OUT_MAX: + multiplier = 1000; + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + break; + case PSU_P_IN: + case PSU_P_OUT: + multiplier = 1000000; + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + + break; + case PSU_FAN1_SPEED: + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent)); + else + return sprintf(buf, "%d\n", (mantissa) / (1 << -exponent)); + + break; + case PSU_TEMP1_INPUT: + case PSU_TEMP1_HIGH_THRESHOLD: + multiplier = 1000; + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + + break; + default: + printk(KERN_ERR "%s: Unable to find attribute index for %s\n", __FUNCTION__, usr_data->aname); + goto exit; + } + +exit: + return sprintf(buf, "%d\n", status); +} + + +ssize_t psu_store_default(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 psu_data *data = i2c_get_clientdata(client); + PSU_PDATA *pdata = (PSU_PDATA *)(client->dev.platform_data); + PSU_DATA_ATTR *usr_data = NULL; + struct psu_attr_info *sysfs_attr_info = NULL; + int i; + + for (i=0;inum_attr;i++) + { + if (strcmp(data->attr_info[i].name, attr->dev_attr.attr.name) == 0 && strcmp(pdata->psu_attrs[i].aname, attr->dev_attr.attr.name) == 0) + { + sysfs_attr_info = &data->attr_info[i]; + usr_data = &pdata->psu_attrs[i]; + } + } + + if (sysfs_attr_info==NULL || usr_data==NULL) { + printk(KERN_ERR "%s is not supported attribute for this client\n", attr->dev_attr.attr.name); + goto exit; + } + + switch(attr->index) + { + /*No write attributes for now in PSU*/ + default: + goto exit; + } + + psu_update_hw(dev, sysfs_attr_info, usr_data); + +exit: + return count; +} + +extern int board_i2c_cpld_read_new(unsigned short cpld_addr, char *name, u8 reg); +int sonic_i2c_get_psu_byte_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + int status = 0; + int val = 0; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + + + if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0) + { + val = board_i2c_cpld_read_new(adata->devaddr, adata->devname, adata->offset); + if (val < 0){ + return val; + } + padata->val.intval = ((val & adata->mask) == adata->cmpval); + psu_dbg(KERN_ERR "%s: byte_value = 0x%x\n", __FUNCTION__, padata->val.intval); + } + + return status; +} + +int sonic_i2c_get_psu_block_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + char buf[32]=""; //temporary placeholder for block data + uint8_t offset = (uint8_t)adata->offset; + int data_len = adata->len; + + while (retry) + { + status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, buf); + if (unlikely(status<0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + buf[0] = '\0'; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read block of data from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + buf[data_len-1] = '\0'; + } + + if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0) + strncpy(padata->val.strval, buf+1, data_len-1); // nosemgrep + else + strncpy(padata->val.strval, buf, data_len); // nosemgrep + + psu_dbg(KERN_ERR "%s: status = %d, buf block: %s\n", __FUNCTION__, status, padata->val.strval); + return 0; +} + +int sonic_i2c_get_psu_word_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read a word from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: word value : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_api.h b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_api.h new file mode 100644 index 000000000000..24e4ea02e7ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_api.h @@ -0,0 +1,31 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. + * + * 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. + * + * + * Description + * PSU driver related api declarations + */ + +#ifndef __PDDF_PSU_API_H__ +#define __PDDF_PSU_API_H__ + +extern void get_psu_duplicate_sysfs(int idx, char *str); +extern ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t psu_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +extern int sonic_i2c_get_psu_byte_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_block_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_word_default(void *client, PSU_DATA_ATTR *adata, void *data); + +#endif diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_defs.h b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_defs.h new file mode 100644 index 000000000000..ab0d61b23c95 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_defs.h @@ -0,0 +1,90 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. + * + * 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. + * + * + * Description: + * Platform PSU defines/structures header file + */ + +#ifndef __PDDF_PSU_DEFS_H__ +#define __PDDF_PSU_DEFS_H__ + + +#define MAX_NUM_PSU 5 +#define MAX_PSU_ATTRS 32 +#define ATTR_NAME_LEN 32 +#define STR_ATTR_SIZE 32 +#define DEV_TYPE_LEN 32 + +/* Each client has this additional data + */ + +typedef struct PSU_DATA_ATTR +{ + char aname[ATTR_NAME_LEN]; // attr name, taken from enum psu_sysfs_attributes + char devtype[DEV_TYPE_LEN]; // either a 'eeprom' or 'cpld', or 'pmbus' attribute + char devname[DEV_TYPE_LEN]; // Name of the device from where this sysfs attr is read + uint32_t devaddr; + uint32_t offset; + uint32_t mask; + uint32_t cmpval; + uint32_t len; + void *access_data; + +}PSU_DATA_ATTR; + +typedef struct PSU_SYSFS_ATTR_DATA +{ + int index; + unsigned short mode; + ssize_t (*show)(struct device *dev, struct device_attribute *da, char *buf); + int (*pre_get)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*do_get)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*post_get)(void *client, PSU_DATA_ATTR *adata, void *data); + ssize_t (*store)(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + int (*pre_set)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*do_set)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*post_set)(void *client, PSU_DATA_ATTR *adata, void *data); + void *data; +} PSU_SYSFS_ATTR_DATA; + +typedef struct PSU_SYSFS_ATTR_DATA_ENTRY +{ + char name[ATTR_NAME_LEN]; + PSU_SYSFS_ATTR_DATA *a_ptr; +} PSU_SYSFS_ATTR_DATA_ENTRY; + + +/* PSU CLIENT DATA - PLATFORM DATA FOR PSU CLIENT */ +typedef struct PSU_DATA +{ + int idx; // psu index + int num_psu_fans; + PSU_DATA_ATTR psu_attr; + int len; // no of valid attributes for this psu client + PSU_DATA_ATTR psu_attrs[MAX_PSU_ATTRS]; +}PSU_DATA; + +typedef struct PSU_PDATA +{ + int idx; // psu index + int num_psu_fans; // num of fans supported by the PSU + int len; // no of valid attributes for this psu client + PSU_DATA_ATTR *psu_attrs; +}PSU_PDATA; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#endif diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_driver.c b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_driver.c new file mode 100644 index 000000000000..27b99376304e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_driver.c @@ -0,0 +1,398 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. + * + * 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. + * + * + * A pddf kernel module driver for PSU + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../../../pddf/i2c/modules/include/pddf_client_defs.h" +#include "../../../../../pddf/i2c/modules/include/pddf_psu_defs.h" +#include "../../../../../pddf/i2c/modules/include/pddf_psu_driver.h" +#include "../../../../../pddf/i2c/modules/include/pddf_psu_api.h" + + +static unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +struct pddf_ops_t pddf_psu_ops = { + .pre_init = NULL, + .post_init = NULL, + + .pre_probe = NULL, + .post_probe = NULL, + + .pre_remove = NULL, + .post_remove = NULL, + + .pre_exit = NULL, + .post_exit = NULL, +}; +EXPORT_SYMBOL(pddf_psu_ops); + + +PSU_SYSFS_ATTR_DATA access_psu_present = {PSU_PRESENT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_byte_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_present); + +PSU_SYSFS_ATTR_DATA access_psu_model_name = {PSU_MODEL_NAME, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_block_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_model_name); + +PSU_SYSFS_ATTR_DATA access_psu_power_good = {PSU_POWER_GOOD, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_byte_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_power_good); + +PSU_SYSFS_ATTR_DATA access_psu_mfr_id = {PSU_MFR_ID, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_block_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_mfr_id); + +PSU_SYSFS_ATTR_DATA access_psu_serial_num = {PSU_SERIAL_NUM, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_block_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_serial_num); + +PSU_SYSFS_ATTR_DATA access_psu_fan_dir = {PSU_FAN_DIR, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_block_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_fan_dir); + +PSU_SYSFS_ATTR_DATA access_psu_v_out = {PSU_V_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_v_out); + +PSU_SYSFS_ATTR_DATA access_psu_v_out_min = {PSU_V_OUT_MIN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_v_out_min); + +PSU_SYSFS_ATTR_DATA access_psu_v_out_max = {PSU_V_OUT_MAX, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_v_out_max); + +PSU_SYSFS_ATTR_DATA access_psu_i_out = {PSU_I_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_i_out); + +PSU_SYSFS_ATTR_DATA access_psu_p_out = {PSU_P_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_p_out); + +PSU_SYSFS_ATTR_DATA access_psu_p_out_max = {PSU_P_OUT_MAX, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_p_out_max); + +PSU_SYSFS_ATTR_DATA access_psu_fan1_speed_rpm = {PSU_FAN1_SPEED, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_fan1_speed_rpm); + +PSU_SYSFS_ATTR_DATA access_psu_temp1_input = {PSU_TEMP1_INPUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_temp1_input); + +PSU_SYSFS_ATTR_DATA access_psu_temp1_high_threshold = {PSU_TEMP1_HIGH_THRESHOLD, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_temp1_high_threshold); + +PSU_SYSFS_ATTR_DATA access_psu_v_in = {PSU_V_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_v_in); + +PSU_SYSFS_ATTR_DATA access_psu_i_in = {PSU_I_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_i_in); + +PSU_SYSFS_ATTR_DATA access_psu_p_in = {PSU_P_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_p_in); + +PSU_SYSFS_ATTR_DATA_ENTRY psu_sysfs_attr_data_tbl[]= +{ + { "psu_present", &access_psu_present}, + { "psu_model_name", &access_psu_model_name}, + { "psu_power_good" , &access_psu_power_good}, + { "psu_mfr_id" , &access_psu_mfr_id}, + { "psu_serial_num" , &access_psu_serial_num}, + { "psu_fan_dir" , &access_psu_fan_dir}, + { "psu_v_out" , &access_psu_v_out}, + { "psu_v_out_min" , &access_psu_v_out_min}, + { "psu_v_out_max" , &access_psu_v_out_max}, + { "psu_i_out" , &access_psu_i_out}, + { "psu_p_out" , &access_psu_p_out}, + { "psu_p_out_max" , &access_psu_p_out_max}, + { "psu_fan1_speed_rpm" , &access_psu_fan1_speed_rpm}, + { "psu_temp1_input" , &access_psu_temp1_input}, + { "psu_temp1_high_threshold" , &access_psu_temp1_high_threshold}, + { "psu_v_in" , &access_psu_v_in}, + { "psu_i_in" , &access_psu_i_in}, + { "psu_p_in" , &access_psu_p_in} +}; + +void *get_psu_access_data(char *name) +{ + int i=0; + for(i=0; i<(sizeof(psu_sysfs_attr_data_tbl)/sizeof(psu_sysfs_attr_data_tbl[0])); i++) + { + if(strcmp(name, psu_sysfs_attr_data_tbl[i].name) ==0) + { + return &psu_sysfs_attr_data_tbl[i]; + } + } + return NULL; +} +EXPORT_SYMBOL(get_psu_access_data); + + +static int psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct psu_data *data; + int status =0; + int i,num, j=0; + PSU_PDATA *psu_platform_data; + PSU_DATA_ATTR *data_attr; + PSU_SYSFS_ATTR_DATA_ENTRY *sysfs_data_entry; + char new_str[ATTR_NAME_LEN] = ""; + + + if (client == NULL) { + printk("NULL Client.. \n"); + goto exit; + } + + if (pddf_psu_ops.pre_probe) + { + status = (pddf_psu_ops.pre_probe)(client, dev_id); + if (status != 0) + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + dev_info(&client->dev, "chip found\n"); + + /* Take control of the platform data */ + psu_platform_data = (PSU_PDATA *)(client->dev.platform_data); + num = psu_platform_data->len; + data->index = psu_platform_data->idx - 1; + data->num_psu_fans = psu_platform_data->num_psu_fans; + data->num_attr = num; + + + + /* Create and Add supported attr in the 'attributes' list */ + for (i=0; ipsu_attrs + i; + sysfs_data_entry = get_psu_access_data(data_attr->aname); + if (sysfs_data_entry == NULL) + { + printk(KERN_ERR "%s: Wrong attribute name provided by user '%s'\n", __FUNCTION__, data_attr->aname); + continue; + } + + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, data_attr->aname); // nosemgrep + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->psu_attribute_list[i] = &dy_ptr->dev_attr.attr; + strcpy(data->attr_info[i].name, data_attr->aname); // nosemgrep + data->attr_info[i].valid = 0; + mutex_init(&data->attr_info[i].update_lock); + + /*Create a duplicate entry*/ + get_psu_duplicate_sysfs(dy_ptr->index, new_str); + if (strcmp(new_str,"")) + { + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, new_str); // nosemgrep + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->psu_attribute_list[num+j] = &dy_ptr->dev_attr.attr; + j++; + strcpy(new_str,""); // nosemgrep + } + } + data->psu_attribute_list[i+j] = NULL; + data->psu_attribute_group.attrs = data->psu_attribute_list; + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &data->psu_attribute_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, NULL, NULL); + 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); + + /* Add a support for post probe function */ + if (pddf_psu_ops.post_probe) + { + status = (pddf_psu_ops.post_probe)(client, dev_id); + if (status != 0) + goto exit_remove; + } + + return 0; + + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->psu_attribute_group); +exit_free: + /* Free all the allocated attributes */ + for (i=0;data->psu_attribute_list[i]!=NULL;i++) + { + struct sensor_device_attribute *ptr = (struct sensor_device_attribute *)data->psu_attribute_list[i]; + kfree(ptr); + data->psu_attribute_list[i] = NULL; + pddf_dbg(PSU, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + } + kfree(data); +exit: + return status; +} + +static void psu_remove(struct i2c_client *client) +{ + int i=0, ret = 0; + struct psu_data *data = i2c_get_clientdata(client); + PSU_PDATA *platdata = (PSU_PDATA *)client->dev.platform_data; // use dev_get_platdata() + PSU_DATA_ATTR *platdata_sub = platdata->psu_attrs; + struct sensor_device_attribute *ptr = NULL; + + if (pddf_psu_ops.pre_remove) + { + ret = (pddf_psu_ops.pre_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN pre_remove function failed\n"); + } + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->psu_attribute_group); + for (i=0; data->psu_attribute_list[i]!=NULL; i++) + { + ptr = (struct sensor_device_attribute *)data->psu_attribute_list[i]; + kfree(ptr); + data->psu_attribute_list[i] = NULL; + } + pddf_dbg(PSU, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + kfree(data); + if (platdata_sub) { + printk(KERN_DEBUG "%s: Freeing platform subdata\n", __FUNCTION__); + kfree(platdata_sub); + } + if (platdata) { + printk(KERN_DEBUG "%s: Freeing platform data\n", __FUNCTION__); + kfree(platdata); + } + + if (pddf_psu_ops.post_remove) + { + ret = (pddf_psu_ops.post_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN post_remove function failed\n"); + } +} + +enum psu_intf +{ + eeprom_intf, + smbus_intf +}; + +static const struct i2c_device_id psu_id[] = { + {"psu_eeprom", eeprom_intf}, + {"psu_pmbus", smbus_intf}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, psu_id); + +static struct i2c_driver psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "psu", + }, + .probe = psu_probe, + .remove = psu_remove, + .id_table = psu_id, + .address_list = normal_i2c, +}; + +int example_fun(void) +{ + pddf_dbg(PSU, KERN_ERR "CALLING FUN...\n"); + return 0; +} +EXPORT_SYMBOL(example_fun); + + +int psu_init(void) +{ + int status = 0; + + if (pddf_psu_ops.pre_init) + { + status = (pddf_psu_ops.pre_init)(); + if (status!=0) + return status; + } + + pddf_dbg(PSU, KERN_ERR "GENERIC_PSU_DRIVER.. init Invoked..\n"); + status = i2c_add_driver(&psu_driver); + if (status!=0) + return status; + + if (pddf_psu_ops.post_init) + { + status = (pddf_psu_ops.post_init)(); + if (status!=0) + return status; + } + + return status; +} +EXPORT_SYMBOL(psu_init); + +void psu_exit(void) +{ + pddf_dbg(PSU, "GENERIC_PSU_DRIVER.. exit\n"); + if (pddf_psu_ops.pre_exit) (pddf_psu_ops.pre_exit)(); + i2c_del_driver(&psu_driver); + if (pddf_psu_ops.post_exit) (pddf_psu_ops.post_exit)(); +} +EXPORT_SYMBOL(psu_exit); + +module_init(psu_init); +module_exit(psu_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("psu driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_driver.h b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_driver.h new file mode 100644 index 000000000000..a94cf7441dbc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/psu_driver/pddf_psu_driver.h @@ -0,0 +1,70 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. + * + * 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. + * + * + * Description + * PSU driver data structures + */ +#ifndef __PDDF_PSU_DRIVER_H__ +#define __PDDF_PSU_DRIVER_H__ + +enum psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD, + PSU_MFR_ID, + PSU_SERIAL_NUM, + PSU_FAN_DIR, + PSU_V_OUT, + PSU_V_OUT_MIN, + PSU_V_OUT_MAX, + PSU_I_OUT, + PSU_P_OUT, /* This is in micro watts to comply with lm-sensors */ + PSU_P_OUT_MAX, + PSU_FAN1_SPEED, + PSU_TEMP1_INPUT, + PSU_TEMP1_HIGH_THRESHOLD, + PSU_V_IN, + PSU_I_IN, + PSU_P_IN, + PSU_ATTR_MAX +}; + + +/* Every client has psu_data which is divided into per attribute data */ +struct psu_attr_info { + char name[ATTR_NAME_LEN]; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status; + union { + char strval[STR_ATTR_SIZE]; + int intval; + u16 shortval; + u8 charval; + }val; +}; +struct psu_data { + struct device *hwmon_dev; + u8 index; + int num_psu_fans; + int num_attr; + struct attribute *psu_attribute_list[MAX_PSU_ATTRS]; + struct attribute_group psu_attribute_group; + struct psu_attr_info attr_info[MAX_PSU_ATTRS]; +}; + + +#endif diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/switchboard_fpga.c b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/switchboard_fpga.c new file mode 100644 index 000000000000..8b3ce30d8cc2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/modules/switchboard_fpga.c @@ -0,0 +1,2365 @@ +/* + * switchboard_fpga.c - driver for ds3000 Switch board FPGA/CPLD. + * + * Author: Pradchaya Phucharoen + * + * Copyright (C) 2019 Celestica Corp. + * + * 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. + * + * / + * \--sys + * \--devices + * \--platform + * \--switchboard + * |--FPGA + * |--CPLD1 + * |--CPLD2 + * \--SFF + * |--QSFP[1..32] + * \--SFP1 + * + */ + +#ifndef TEST_MODE +#define MOD_VERSION "2.2.0" +#else +#define MOD_VERSION "TEST" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int majorNumber; + +#define CLASS_NAME "ds3000_fpga" +#define DRIVER_NAME "switchboard" +#define FPGA_PCI_NAME "ds3000_fpga_pci" +#define DEVICE_NAME "fwupgrade" + + +static int smbus_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpgafw_init(void); +static void fpgafw_exit(void); + +/* +======================================== +FPGA PCIe BAR 0 Registers +======================================== +Misc Control 0x00000000 – 0x000000FF. +I2C_CH1 0x00000100 - 0x00000110 +I2C_CH2 0x00000200 - 0x00000210. +I2C_CH3 0x00000300 - 0x00000310. +I2C_CH4 0x00000400 - 0x00000410. +I2C_CH5 0x00000500 - 0x00000510. +I2C_CH6 0x00000600 - 0x00000610. +I2C_CH7 0x00000700 - 0x00000710. +I2C_CH8 0x00000800 - 0x00000810. +I2C_CH9 0x00000900 - 0x00000910. +I2C_CH10 0x00000A00 - 0x00000A10. +SPI Master 0x00001200 - 0x00001300. +PORT XCVR 0x00004000 - 0x00004FFF. +*/ + +/* MISC */ +#define FPGA_VERSION 0x0000 +#define FPGA_VERSION_MJ_MSK 0xff00 +#define FPGA_VERSION_MN_MSK 0x00ff +#define FPGA_SCRATCH 0x0004 +#define FPGA_BROAD_TYPE 0x0008 +#define FPGA_BROAD_REV_MSK 0x0038 +#define FPGA_BROAD_ID_MSK 0x0007 +#define FPGA_PLL_STATUS 0x0014 +#define BMC_I2C_SCRATCH 0x0020 +#define FPGA_SLAVE_CPLD_REST 0x0030 +#define FPGA_PERIPH_RESET_CTRL 0x0034 +#define FPGA_INT_STATUS 0x0040 +#define FPGA_INT_SRC_STATUS 0x0044 +#define FPGA_INT_FLAG 0x0048 +#define FPGA_INT_MASK 0x004c +#define FPGA_MISC_CTRL 0x0050 +#define FPGA_MISC_STATUS 0x0054 +#define FPGA_AVS_VID_STATUS 0x0068 +#define FPGA_FEATURE_CARD_GPIO 0x0070 +#define FPGA_PORT_XCVR_READY 0x000c + +/* I2C_MASTER BASE ADDR */ +#define I2C_MASTER_FREQ_1 0x0100 +#define I2C_MASTER_CTRL_1 0x0104 +#define I2C_MASTER_STATUS_1 0x0108 +#define I2C_MASTER_DATA_1 0x010c +#define I2C_MASTER_PORT_ID_1 0x0110 +#define I2C_MASTER_CH_1 1 +#define I2C_MASTER_CH_2 2 +#define I2C_MASTER_CH_3 3 +#define I2C_MASTER_CH_4 4 +#define I2C_MASTER_CH_5 5 +#define I2C_MASTER_CH_6 6 +#define I2C_MASTER_CH_7 7 +#define I2C_MASTER_CH_8 8 +#define I2C_MASTER_CH_9 9 +#define I2C_MASTER_CH_10 10 +#define I2C_MASTER_CH_TOTAL I2C_MASTER_CH_10 + +/* SPI_MASTER */ +#define SPI_MASTER_WR_EN 0x1200 /* one bit */ +#define SPI_MASTER_WR_DATA 0x1204 /* 32 bits */ +#define SPI_MASTER_CHK_ID 0x1208 /* one bit */ +#define SPI_MASTER_VERIFY 0x120c /* one bit */ +#define SPI_MASTER_STATUS 0x1210 /* 15 bits */ +#define SPI_MASTER_MODULE_RST 0x1214 /* one bit */ + +/* FPGA FRONT PANEL PORT MGMT */ +#define SFF_PORT_CTRL_BASE 0x4000 +#define SFF_PORT_STATUS_BASE 0x4004 +#define SFF_PORT_INT_STATUS_BASE 0x4008 +#define SFF_PORT_INT_MASK_BASE 0x400c + +#define PORT_XCVR_REGISTER_SIZE 0x1000 + +/* PORT CTRL REGISTER +[31:7] RSVD +[6] LPMOD 6 +[5] RSVD +[4] RST 4 +[3:1] RSVD +[0] TXDIS 0 +*/ +#define CTRL_LPMOD 6 +#define CTRL_RST 4 +#define CTRL_TXDIS 0 + +/* PORT STATUS REGISTER +[31:6] RSVD +[5] IRQ 5 +[4] PRESENT 4 +[3] RSVD +[2] TXFAULT 2 +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define STAT_IRQ 5 +#define STAT_PRESENT 4 +#define STAT_TXFAULT 2 +#define STAT_RXLOS 1 +#define STAT_MODABS 0 + +/* PORT INTRPT REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define INTR_INT_N 5 +#define INTR_PRESENT 4 +#define INTR_RXLOS 1 +#define INTR_MODABS 0 + +/* PORT INT MASK REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS_INT 1 +[0] MODABS 0 +*/ +#define MASK_INT_N 5 +#define MASK_PRESENT 4 +#define MASK_RXLOS 1 +#define MASK_MODABS 0 + +enum { + I2C_SR_BIT_RXAK = 0, + I2C_SR_BIT_MIF, + I2C_SR_BIT_SRW, + I2C_SR_BIT_BCSTM, + I2C_SR_BIT_MAL, + I2C_SR_BIT_MBB, + I2C_SR_BIT_MAAS, + I2C_SR_BIT_MCF +}; + +enum { + I2C_CR_BIT_BCST = 0, + I2C_CR_BIT_RSTA = 2, + I2C_CR_BIT_TXAK, + I2C_CR_BIT_MTX, + I2C_CR_BIT_MSTA, + I2C_CR_BIT_MIEN, + I2C_CR_BIT_MEN, +}; + +/** + * + * The function is i2c algorithm implement to allow master access to + * correct endpoint devices trough the PCA9548 switch devices. + * + * FPGA I2C Master [mutex resource] + * | + * | + * --------------------------- + * | PCA9548(s) | + * ---1--2--3--4--5--6--7--8-- + * | | | | | | | | + * EEPROM ... EEPROM + * + */ + + +#define VIRTUAL_I2C_QSFP_PORT 32 +#define VIRTUAL_I2C_SFP_PORT 1 + +#define SFF_PORT_TOTAL VIRTUAL_I2C_QSFP_PORT + VIRTUAL_I2C_SFP_PORT + +#define VIRTUAL_I2C_BUS_OFFSET 2 +#define CPLD1_SLAVE_ADDR 0x30 +#define CPLD2_SLAVE_ADDR 0x31 + +static struct class* fpgafwclass = NULL; ///< The device-driver class struct pointer +static struct device* fpgafwdev = NULL; ///< The device-driver device struct pointer +static struct platform_device *ds3000_dev; + +#define PCI_VENDOR_ID_TEST 0x1af4 + +#ifndef PCI_VENDOR_ID_XILINX +#define PCI_VENDOR_ID_XILINX 0x10EE +#endif + +#define FPGA_PCIE_DEVICE_ID 0x7021 +#define TEST_PCIE_DEVICE_ID 0x1110 + + +#ifdef DEBUG_KERN +#define info(fmt,args...) printk(KERN_INFO "line %3d : "fmt,__LINE__,##args) +#define check(REG) printk(KERN_INFO "line %3d : %-8s = %2.2X",__LINE__,#REG,ioread8(REG)); +#else +#define info(fmt,args...) +#define check(REG) +#endif + +#define GET_REG_BIT(REG,BIT) ((ioread8(REG) >> BIT) & 0x01) +#define SET_REG_BIT_H(REG,BIT) iowrite8(ioread8(REG) | (0x01 << BIT),REG) +#define SET_REG_BIT_L(REG,BIT) iowrite8(ioread8(REG) & ~(0x01 << BIT),REG) + +static struct mutex fpga_i2c_master_locks[I2C_MASTER_CH_TOTAL]; +/* Store lasted switch address and channel */ +static uint16_t fpga_i2c_lasted_access_port[I2C_MASTER_CH_TOTAL]; + +enum PORT_TYPE { + NONE, + QSFP, + SFP +}; + +struct i2c_switch { + unsigned char master_bus; // I2C bus number + unsigned char switch_addr; // PCA9548 device address, 0xFF if directly connect to a bus. + unsigned char channel; // PCA9548 channel number. If the switch_addr is 0xFF, this value is ignored. + enum PORT_TYPE port_type; // QSFP/SFP tranceiver port type. + char calling_name[20]; // Calling name. +}; + +struct i2c_dev_data { + int portid; + struct i2c_switch pca9548; +}; + +/* PREDEFINED I2C SWITCH DEVICE TOPOLOGY */ +static struct i2c_switch fpga_i2c_bus_dev[] = { + /* BUS2 QSFP Exported as virtual bus */ + {I2C_MASTER_CH_2, 0x72, 0, QSFP, "QSFP1"}, {I2C_MASTER_CH_2, 0x72, 1, QSFP, "QSFP2"}, + {I2C_MASTER_CH_2, 0x72, 2, QSFP, "QSFP3"}, {I2C_MASTER_CH_2, 0x72, 3, QSFP, "QSFP4"}, + {I2C_MASTER_CH_2, 0x72, 4, QSFP, "QSFP5"}, {I2C_MASTER_CH_2, 0x72, 5, QSFP, "QSFP6"}, + {I2C_MASTER_CH_2, 0x72, 6, QSFP, "QSFP7"}, {I2C_MASTER_CH_2, 0x72, 7, QSFP, "QSFP8"}, + {I2C_MASTER_CH_2, 0x73, 0, QSFP, "QSFP9"}, {I2C_MASTER_CH_2, 0x73, 1, QSFP, "QSFP10"}, + {I2C_MASTER_CH_2, 0x73, 2, QSFP, "QSFP11"}, {I2C_MASTER_CH_2, 0x73, 3, QSFP, "QSFP12"}, + {I2C_MASTER_CH_2, 0x73, 4, QSFP, "QSFP13"}, {I2C_MASTER_CH_2, 0x73, 5, QSFP, "QSFP14"}, + {I2C_MASTER_CH_2, 0x73, 6, QSFP, "QSFP15"}, {I2C_MASTER_CH_2, 0x73, 7, QSFP, "QSFP16"}, + {I2C_MASTER_CH_2, 0x74, 0, QSFP, "QSFP17"}, {I2C_MASTER_CH_2, 0x74, 1, QSFP, "QSFP18"}, + {I2C_MASTER_CH_2, 0x74, 2, QSFP, "QSFP19"}, {I2C_MASTER_CH_2, 0x74, 3, QSFP, "QSFP20"}, + {I2C_MASTER_CH_2, 0x74, 4, QSFP, "QSFP21"}, {I2C_MASTER_CH_2, 0x74, 5, QSFP, "QSFP22"}, + {I2C_MASTER_CH_2, 0x74, 6, QSFP, "QSFP23"}, {I2C_MASTER_CH_2, 0x74, 7, QSFP, "QSFP24"}, + {I2C_MASTER_CH_2, 0x75, 0, QSFP, "QSFP25"}, {I2C_MASTER_CH_2, 0x75, 1, QSFP, "QSFP26"}, + {I2C_MASTER_CH_2, 0x75, 2, QSFP, "QSFP27"}, {I2C_MASTER_CH_2, 0x75, 3, QSFP, "QSFP28"}, + {I2C_MASTER_CH_2, 0x75, 4, QSFP, "QSFP29"}, {I2C_MASTER_CH_2, 0x75, 5, QSFP, "QSFP30"}, + {I2C_MASTER_CH_2, 0x75, 6, QSFP, "QSFP31"}, {I2C_MASTER_CH_2, 0x75, 7, QSFP, "QSFP32"}, + /* BUS1 SFP+ Exported as virtual bus */ + {I2C_MASTER_CH_1, 0x72, 0, SFP, "SFP1"}, + /* BUS3 Switchboard CPLD */ + {I2C_MASTER_CH_3, 0xFF, 0, NONE, "I2C_3"}, +}; + +#define VIRTUAL_I2C_PORT_LENGTH ARRAY_SIZE(fpga_i2c_bus_dev) +#define VIRTUAL_I2C_CPLD_INDEX SFF_PORT_TOTAL + +struct fpga_device { + /* data mmio region */ + void __iomem *data_base_addr; + resource_size_t data_mmio_start; + resource_size_t data_mmio_len; +}; + +static struct fpga_device fpga_dev = { + .data_base_addr = 0, + .data_mmio_start = 0, + .data_mmio_len = 0, +}; + +struct ds3000_fpga_data { + struct device *sff_devices[SFF_PORT_TOTAL]; + struct i2c_client *sff_i2c_clients[SFF_PORT_TOTAL]; + struct i2c_adapter *i2c_adapter[VIRTUAL_I2C_PORT_LENGTH]; + struct mutex fpga_lock; // For FPGA internal lock + void __iomem * fpga_read_addr; + uint8_t cpld1_read_addr; + uint8_t cpld2_read_addr; +}; + +struct sff_device_data { + int portid; + enum PORT_TYPE port_type; +}; + +struct ds3000_fpga_data *fpga_data; + +/* + * Kernel object for other module drivers. + * Other module can use these kobject as a parent. + */ + +static struct kobject *fpga = NULL; +static struct kobject *cpld1 = NULL; +static struct kobject *cpld2 = NULL; + +/** + * Device node in sysfs tree. + */ +static struct device *sff_dev = NULL; + +/** + * Show the value of the register set by 'set_fpga_reg_address' + * If the address is not set by 'set_fpga_reg_address' first, + * The version register is selected by default. + * @param buf register value in hextring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_reg_value(struct device *dev, + struct device_attribute *attr, char *buf) +{ + // read data from the address + uint32_t data; + data = ioread32(fpga_data->fpga_read_addr); + return sprintf(buf, "0x%8.8x\n", data); +} + +/** + * Store the register address + * @param buf address wanted to be read value of + * @return number of bytes stored, or an error code + */ +static ssize_t set_fpga_reg_address(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + uint32_t addr; + + status = kstrtou32(buf, 0, &addr); + if (status == 0) { + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + addr; + status = count; + } + return status; +} + +/** + * Show value of fpga scratch register + * @param buf register value in hexstring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_scratch(struct device *dev, + struct device_attribute *attr, char *buf) +{ + uint32_t data; + data = ioread32(fpga_dev.data_base_addr + FPGA_SCRATCH); + data &= 0xffffffff; + return sprintf(buf, "0x%8.8x\n", data); +} + +/** + * Store value of fpga scratch register + * @param buf scratch register value passing from user space + * @return number of bytes stored, or an error code + */ +static ssize_t set_fpga_scratch(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + uint32_t data; + + status = kstrtou32(buf, 0, &data); + if (status == 0) { + iowrite32(data, fpga_dev.data_base_addr + FPGA_SCRATCH); + status = count; + } + return status; +} + +/** + * Store a value in a specific register address + * @param buf the value and address in format '0xhhhh 0xhhhhhhhh' + * @return number of bytes sent by user space, or an error code + */ +static ssize_t set_fpga_reg_value(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + //register is 4 bytes + uint32_t addr; + uint32_t value; + uint32_t mode = 8; + char *tok; + char clone[count]; + char *pclone = clone; + ssize_t status; + + strncpy(clone, buf, strlen(buf)-1); // nosemgrep + + mutex_lock(&fpga_data->fpga_lock); + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + status = kstrtou32(tok, 0, &addr); + if (status != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + status = kstrtou32(tok, 0, &value); + if (status != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mode = 32; + } else { + status = kstrtou32(tok, 0, &mode); + if (status != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + } + if (mode == 32) { + iowrite32(value, fpga_dev.data_base_addr + addr); + } else if (mode == 8) { + iowrite8(value, fpga_dev.data_base_addr + addr); + } else { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return count; +} + +/** + * Show FPGA port XCVR ready status + */ +static ssize_t ready_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + unsigned int REGISTER = FPGA_PORT_XCVR_READY; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> 0) & 1U); +} + +/* FPGA attributes */ +static DEVICE_ATTR( getreg, 0600, get_fpga_reg_value, set_fpga_reg_address); +static DEVICE_ATTR( scratch, 0600, get_fpga_scratch, set_fpga_scratch); +static DEVICE_ATTR( setreg, 0200, NULL , set_fpga_reg_value); +static DEVICE_ATTR_RO(ready); + +static struct attribute *fpga_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_setreg.attr, + &dev_attr_ready.attr, + NULL, +}; + +static struct attribute_group fpga_attr_grp = { + .attrs = fpga_attrs, +}; + +/* SW CPLDs attributes */ +static ssize_t cpld1_getreg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, fpga_data->cpld1_read_addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld1_getreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + uint8_t addr; + + status = kstrtou8(buf, 0, &addr); + if (status == 0) { + fpga_data->cpld1_read_addr = addr; + status = count; + } + return status; +} + +static ssize_t cpld1_scratch_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld1_scratch_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + // CPLD register is one byte + uint8_t data; + ssize_t status; + int err; + + status = kstrtou8(buf, 0, &data); + if (status != 0) { + return status; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + + return count; +} + +static ssize_t cpld1_setreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + + uint8_t addr, value; + char *tok; + char clone[count]; + char *pclone = clone; + ssize_t status; + int err; + + strncpy(clone, buf, strlen(buf)-1); // nosemgrep + + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + status = kstrtou8(tok, 0, &addr); + if (status != 0) { + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + status = kstrtou8(tok, 0, &value); + if (status != 0) { + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) + return err; + + return count; +} + +struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg, 0600, cpld1_getreg_show, cpld1_getreg_store); +struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch, 0600, cpld1_scratch_show, cpld1_scratch_store); +struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg, 0200, NULL, cpld1_setreg_store); + +static struct attribute *cpld1_attrs[] = { + &dev_attr_cpld1_getreg.attr, + &dev_attr_cpld1_scratch.attr, + &dev_attr_cpld1_setreg.attr, + NULL, +}; + +static struct attribute_group cpld1_attr_grp = { + .attrs = cpld1_attrs, +}; + +static ssize_t cpld2_getreg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld2_read_addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld2_getreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + // CPLD register is one byte + uint8_t addr; + ssize_t status; + + status = kstrtou8(buf, 0, &addr); + if (status == 0) { + fpga_data->cpld2_read_addr = addr; + status = count; + } + return status; +} + +static ssize_t cpld2_scratch_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld2_scratch_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + // CPLD register is one byte + uint8_t data; + int err; + ssize_t status; + + status = kstrtou8(buf, 0, &data); + if (status != 0) { + return -EINVAL; + } + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + + return count; +} + +static ssize_t cpld2_setreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + uint8_t addr, value; + char *tok; + char clone[count]; + char *pclone = clone; + ssize_t status; + int err; + + strncpy(clone, buf, strlen(buf)-1); // nosemgrep + + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + status = kstrtou8(tok, 0, &addr); + if (status != 0) { + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + status = kstrtou8(tok, 0, &value); + if (status != 0) { + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) + return err; + + return count; +} + +struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg, 0600, cpld2_getreg_show, cpld2_getreg_store); +struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch, 0600, cpld2_scratch_show, cpld2_scratch_store); +struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg, 0200, NULL, cpld2_setreg_store); + +static struct attribute *cpld2_attrs[] = { + &dev_attr_cpld2_getreg.attr, + &dev_attr_cpld2_scratch.attr, + &dev_attr_cpld2_setreg.attr, + NULL, +}; + +static struct attribute_group cpld2_attr_grp = { + .attrs = cpld2_attrs, +}; + +/* QSFP/SFP+ attributes */ +static ssize_t qsfp_modirq_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_IRQ) & 1U); +} +DEVICE_ATTR_RO(qsfp_modirq); + +static ssize_t qsfp_modprs_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_PRESENT) & 1U); +} +DEVICE_ATTR_RO(qsfp_modprs); + +static ssize_t sfp_txfault_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_TXFAULT) & 1U); +} +DEVICE_ATTR_RO(sfp_txfault); + +static ssize_t sfp_rxlos_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_RXLOS) & 1U); +} +DEVICE_ATTR_RO(sfp_rxlos); + +static ssize_t sfp_modabs_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_MODABS) & 1U); +} +DEVICE_ATTR_RO(sfp_modabs); + +static ssize_t qsfp_lpmode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_LPMOD) & 1U); +} +static ssize_t qsfp_lpmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + uint32_t value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) + data = data & ~( (u32)0x1 << CTRL_LPMOD); + else + data = data | ((u32)0x1 << CTRL_LPMOD); + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_lpmode); + +static ssize_t qsfp_reset_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_RST) & 1U); +} + +static ssize_t qsfp_reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + uint32_t value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) + data = data & ~( (u32)0x1 << CTRL_RST); + else + data = data | ((u32)0x1 << CTRL_RST); + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_reset); + +static ssize_t qsfp_isr_flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + data = (u8) ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + /* + * Unify the return pattern to 2-bit + * [1] : module interrupt + * [0] : presence + */ + data = data & valid_bits; + data = data >> 4; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t qsfp_isr_flags_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value << 4; + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_isr_flags); + +static ssize_t qsfp_isr_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + /* + * Unify the return pattern to 2-bit + * [1] : module interrupt + * [0] : presence + */ + data = data & valid_bits; + data = data >> 4; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t qsfp_isr_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value << 4; + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_isr_mask); + +static ssize_t sfp_txdisable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_TXDIS) & 1U); +} +static ssize_t sfp_txdisable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) + data = data & ~( (u32)0x1 << CTRL_TXDIS); + else + data = data | ((u32)0x1 << CTRL_TXDIS); + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_txdisable); + +static ssize_t sfp_isr_flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_RXLOS) | BIT(INTR_MODABS); + + mutex_lock(&fpga_data->fpga_lock); + data = (u8) ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + data = data & valid_bits; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t sfp_isr_flags_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_isr_flags); + +static ssize_t sfp_isr_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_RXLOS) | BIT(INTR_MODABS); + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + data = data & valid_bits; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t sfp_isr_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_RXLOS) | BIT(INTR_MODABS); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_isr_mask); + +static struct attribute *sff_attrs[] = { + &dev_attr_qsfp_modirq.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_isr_flags.attr, + &dev_attr_qsfp_isr_mask.attr, + &dev_attr_sfp_txfault.attr, + &dev_attr_sfp_rxlos.attr, + &dev_attr_sfp_modabs.attr, + &dev_attr_sfp_txdisable.attr, + &dev_attr_sfp_isr_flags.attr, + &dev_attr_sfp_isr_mask.attr, + NULL, +}; + +static struct attribute_group sff_attr_grp = { + .attrs = sff_attrs, +}; + +static const struct attribute_group *sff_attr_grps[] = { + &sff_attr_grp, + NULL +}; + + +static ssize_t port_led_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + // value can be "nomal", "test" + __u8 led_mode_1, led_mode_2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + if (err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_2); + if (err < 0) + return err; + + return sprintf(buf, "%s %s\n", + led_mode_1 ? "test" : "normal", + led_mode_2 ? "test" : "normal"); +} +static ssize_t port_led_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int status; + __u8 led_mode_1; + if (sysfs_streq(buf, "test")) { + led_mode_1 = 0x01; + } else if (sysfs_streq(buf, "normal")) { + led_mode_1 = 0x00; + } else { + return -EINVAL; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + return count; +} +DEVICE_ATTR_RW(port_led_mode); + +// Only work when port_led_mode set to 1 +static ssize_t port_led_color_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + // value can be "off", "green", "amber", "both" + __u8 led_color1, led_color2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x0A, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color1); + if (err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x0A, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color2); + if (err < 0) + return err; + return sprintf(buf, "%s %s\n", + led_color1 == 0x03 ? "off" : led_color1 == 0x02 ? "green" : led_color1 == 0x01 ? "amber" : "both", + led_color2 == 0x03 ? "off" : led_color2 == 0x02 ? "green" : led_color2 == 0x01 ? "amber" : "both"); +} + +static ssize_t port_led_color_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int status; + __u8 led_color; + if (sysfs_streq(buf, "off")) { + led_color = 0x03; + } else if (sysfs_streq(buf, "green")) { + led_color = 0x02; + } else if (sysfs_streq(buf, "amber")) { + led_color = 0x01; + } else if (sysfs_streq(buf, "both")) { + led_color = 0x00; + } else { + status = -EINVAL; + return status; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data*)&led_color); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data*)&led_color); + return count; +} +DEVICE_ATTR_RW(port_led_color); + +static struct attribute *sff_led_test[] = { + &dev_attr_port_led_mode.attr, + &dev_attr_port_led_color.attr, + NULL, +}; + +static struct attribute_group sff_led_test_grp = { + .attrs = sff_led_test, +}; + +static struct device * ds3000_sff_init(int portid) { + struct sff_device_data *new_data; + struct device *new_device; + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc sff device data @port%d", portid); + return NULL; + } + /* The QSFP port ID start from 1 */ + new_data->portid = portid + 1; + new_data->port_type = fpga_i2c_bus_dev[portid].port_type; + new_device = device_create_with_groups(fpgafwclass, sff_dev, + MKDEV(0, 0), new_data, sff_attr_grps, "%s", + fpga_i2c_bus_dev[portid].calling_name); + if (IS_ERR(new_device)) { + printk(KERN_ALERT "Cannot create sff device @port%d", portid); + kfree(new_data); + return NULL; + } + return new_device; +} + +static int i2c_wait_ack(struct i2c_adapter *a, unsigned long timeout, int writing) { + int error = 0; + int Status; + + struct i2c_dev_data *new_data = i2c_get_adapdata(a); + void __iomem *pci_bar = fpga_dev.data_base_addr; + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + unsigned int master_bus = new_data->pca9548.master_bus; + + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -EINVAL; + return error; + } + + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; + + check(pci_bar + REG_SR0); + check(pci_bar + REG_CR0); + + timeout = jiffies + msecs_to_jiffies(timeout); + while (1) { + Status = ioread8(pci_bar + REG_SR0); + if (jiffies > timeout) { + info("Status %2.2X", Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + + if (Status & (1 << I2C_SR_BIT_MIF)) { + break; + } + + if (writing == 0 && (Status & (1 << I2C_SR_BIT_MCF))) { + break; + } + } + Status = ioread8(pci_bar + REG_SR0); + iowrite8(0, pci_bar + REG_SR0); + + if (error < 0) { + info("Status %2.2X", Status); + return error; + } + + if (!(Status & (1 << I2C_SR_BIT_MCF))) { + info("Error Unfinish"); + return -EIO; + } + + if (Status & (1 << I2C_SR_BIT_MAL)) { + info("Error MAL"); + return -EAGAIN; + } + + if (Status & (1 << I2C_SR_BIT_RXAK)) { + info( "SL No Acknowlege"); + if (writing) { + info("Error No Acknowlege"); + iowrite8(1 << I2C_CR_BIT_MEN, pci_bar + REG_CR0); + return -ENXIO; + } + } else { + info( "SL Acknowlege"); + } + + return 0; +} + +static int smbus_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data) +{ + int error = 0; + int cnt = 0; + int bid = 0; + struct i2c_dev_data *dev_data; + void __iomem *pci_bar; + unsigned int portid, master_bus; + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + REG_FDR0 = 0; + REG_CR0 = 0; + REG_SR0 = 0; + REG_DR0 = 0; + REG_ID0 = 0; + + /* Write the command register */ + dev_data = i2c_get_adapdata(adapter); + portid = dev_data->portid; + pci_bar = fpga_dev.data_base_addr; + +#ifdef DEBUG_KERN + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-15s|CMD %2.2X " + , portid, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); +#endif + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } + + master_bus = dev_data->pca9548.master_bus; + + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -ENXIO; + goto Done; + } + + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; + + iowrite8(portid, pci_bar + REG_ID0); + + ////[S][ADDR/R] + // Clear status register + iowrite8(0, pci_bar + REG_SR0); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + if (rw == I2C_SMBUS_READ && + (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)) { + // sent device address with Read mode + iowrite8(addr << 1 | 0x01, pci_bar + REG_DR0); + } else { + // sent device address with Write mode + iowrite8(addr << 1 | 0x00, pci_bar + REG_DR0); + } + + + + info( "MS Start"); + + //// Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } + + //// [CMD]{A} + if (size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA || + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)) { + + // sent command code to data register + iowrite8(cmd, pci_bar + REG_DR0); + info( "MS Send CMD 0x%2.2X", cmd); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } + } + + switch (size) { + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + /* In block data modes keep number of byte in block[0] */ + cnt = data->block[0]; + break; + default: + cnt = 0; break; + } + + // [CNT] used only block data write + if (size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE) { + + iowrite8(cnt, pci_bar + REG_DR0); + info( "MS Send CNT 0x%2.2X", cnt); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } + } + + // [DATA]{A} + if ( rw == I2C_SMBUS_WRITE && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + bid = 0; + info( "MS prepare to sent [%d bytes]", cnt); + if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { + bid = 1; // block[0] is cnt; + cnt += 1; // offset from block[0] + } + for (; bid < cnt; bid++) { + + iowrite8(data->block[bid], pci_bar + REG_DR0); + info( " Data > %2.2X", data->block[bid]); + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + goto Done; + } + } + + } + + // REPEATE START + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + info( "MS Repeated Start"); + + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA | + 1 << I2C_CR_BIT_RSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + // sent Address with Read mode + iowrite8( addr << 1 | 0x1 , pci_bar + REG_DR0); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + goto Done; + } + + } + + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + + switch (size) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + // will be changed after recived first data + cnt = 3; break; + case I2C_SMBUS_I2C_BLOCK_DATA: + cnt = data->block[0]; break; + default: + cnt = 0; break; + } + + bid = 0; + info( "MS Receive"); + + //set to Receive mode + iowrite8(1 << I2C_CR_BIT_MEN | + 1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); + + for (bid = -1; bid < cnt; bid++) { + + // Wait for byte transfer + error = i2c_wait_ack(adapter, 12, 0); + if (error < 0) { + goto Done; + } + + if (bid == cnt - 2) { + info( "SET NAK"); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_TXAK); + } + + if (bid < 0) { + ioread8(pci_bar + REG_DR0); + info( "READ Dummy Byte" ); + } else { + + if (bid == cnt - 1) { + info ( "SET STOP in read loop"); + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + } + if (size == I2C_SMBUS_I2C_BLOCK_DATA) { + // block[0] is read length + data->block[bid + 1] = ioread8(pci_bar + REG_DR0); + } else { + data->block[bid] = ioread8(pci_bar + REG_DR0); + } + info( "DATA IN [%d] %2.2X", bid, data->block[bid]); + + if (size == I2C_SMBUS_BLOCK_DATA && bid == 0) { + cnt = data->block[0] + 1; + } + } + } + } + + // [P] + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + info( "MS STOP"); + +Done: + iowrite8(1 << I2C_CR_BIT_MEN, pci_bar + REG_CR0); + check(pci_bar + REG_CR0); + check(pci_bar + REG_SR0); +#ifdef DEBUG_KERN + printk(KERN_INFO "END --- Error code %d", error); +#endif + + return error; +} + +/** + * Wrapper of smbus_access access with PCA9548 I2C switch management. + * This function set PCA9548 switches to the proper slave channel. + * Only one channel among switches chip is selected during communication time. + * + * Note: If the bus does not have any PCA9548 on it, the switch_addr must be + * set to 0xFF, it will use normal smbus_access function. + */ +static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data) +{ + int error = 0; + struct i2c_dev_data *dev_data; + unsigned char master_bus; + unsigned char switch_addr; + unsigned char channel; + uint16_t prev_port = 0; + unsigned char prev_switch; + unsigned char prev_ch; + int retry; + + dev_data = i2c_get_adapdata(adapter); + master_bus = dev_data->pca9548.master_bus; + switch_addr = dev_data->pca9548.switch_addr; + channel = dev_data->pca9548.channel; + + // Acquire the master resource. + mutex_lock(&fpga_i2c_master_locks[master_bus - 1]); + prev_port = fpga_i2c_lasted_access_port[master_bus - 1]; + prev_switch = (unsigned char)(prev_port >> 8) & 0xFF; + prev_ch = (unsigned char)(prev_port & 0xFF); + + if (switch_addr != 0xFF) { + + // Check lasted access switch address on a master + if ( prev_switch != switch_addr && prev_switch != 0 ) { + // reset prev_port PCA9548 chip + retry = 3; + while (retry--) { + error = smbus_access(adapter, (u16)(prev_switch), flags, + I2C_SMBUS_WRITE, 0x00, + I2C_SMBUS_BYTE, NULL); + if (error >= 0) { + break; + } else { + dev_dbg(&adapter->dev, + "Failed to deselect ch %d of 0x%x, CODE %d\n", + prev_ch, prev_switch, error); + } + } + if (retry < 0) { + goto release_unlock; + } + // set PCA9548 to current channel + retry = 3; + while (retry--) { + error = smbus_access(adapter, switch_addr, flags, + I2C_SMBUS_WRITE, 1 << channel, + I2C_SMBUS_BYTE, NULL); + if (error >= 0) { + break; + } else { + dev_dbg(&adapter->dev, + "Failed to deselect ch %d of 0x%x, CODE %d\n", + prev_ch, prev_switch, error); + } + } + if (retry < 0) { + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + + } else { + // check if channel is also changes + if ( prev_ch != channel || prev_switch == 0 ) { + // set new PCA9548 at switch_addr to current + retry = 3; + while (retry--) { + error = smbus_access(adapter, switch_addr, flags, + I2C_SMBUS_WRITE, 1 << channel, + I2C_SMBUS_BYTE, NULL); + if (error >= 0) { + break; + } else { + dev_dbg(&adapter->dev, + "Failed to deselect ch %d of 0x%x, CODE %d\n", + prev_ch, prev_switch, error); + } + } + if (retry < 0) { + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + } + } + } + + // Do SMBus communication + error = smbus_access(adapter, addr, flags, rw, cmd, size, data); + if (error < 0) { + dev_dbg( &adapter->dev, + "smbus_xfer failed (%d) @ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " + , error, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); + } + +release_unlock: + mutex_unlock(&fpga_i2c_master_locks[master_bus - 1]); + dev_dbg(&adapter->dev, "switch ch %d of 0x%x -> ch %d of 0x%x\n", + prev_ch, prev_switch, channel, switch_addr); + return error; +} + + + +/** + * A callback function show available smbus functions. + */ +static u32 fpga_i2c_func(struct i2c_adapter *a) +{ + return I2C_FUNC_SMBUS_QUICK | + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK; +} + +static const struct i2c_algorithm ds3000_i2c_algorithm = { + .smbus_xfer = fpga_i2c_access, + .functionality = fpga_i2c_func, +}; + +/** + * Create virtual I2C bus adapter for switch devices + * @param pdev platform device pointer + * @param portid virtual i2c port id for switch device mapping + * @param bus_number_offset bus offset for virtual i2c adapter in system + * @return i2c adapter. + * + * When bus_number_offset is -1, created adapter with dynamic bus number. + * Otherwise create adapter at i2c bus = bus_number_offset + portid. + */ +static struct i2c_adapter * ds3000_i2c_init(struct platform_device *pdev, + int portid, int bus_number_offset) +{ + int error; + struct i2c_adapter *new_adapter; + struct i2c_dev_data *new_data; + void __iomem *i2c_freq_base_reg; + + new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); + if (!new_adapter) { + printk(KERN_ALERT "Cannot alloc i2c adapter for %s", + fpga_i2c_bus_dev[portid].calling_name); + return NULL; + } + + new_adapter->owner = THIS_MODULE; + new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + new_adapter->algo = &ds3000_i2c_algorithm; + /* If the bus offset is -1, use dynamic bus number */ + if (bus_number_offset == -1) { + new_adapter->nr = -1; + } else { + new_adapter->nr = bus_number_offset + portid; + } + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc i2c data for %s", + fpga_i2c_bus_dev[portid].calling_name); + kfree_sensitive(new_adapter); + return NULL; + } + + new_data->portid = portid; + new_data->pca9548.master_bus = fpga_i2c_bus_dev[portid].master_bus; + new_data->pca9548.switch_addr = fpga_i2c_bus_dev[portid].switch_addr; + new_data->pca9548.channel = fpga_i2c_bus_dev[portid].channel; + strcpy(new_data->pca9548.calling_name, fpga_i2c_bus_dev[portid].calling_name); // nosemgrep + + snprintf(new_adapter->name, sizeof(new_adapter->name), + "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); + + i2c_freq_base_reg = fpga_dev.data_base_addr + I2C_MASTER_FREQ_1; + iowrite8(0x07, i2c_freq_base_reg + (new_data->pca9548.master_bus - 1) * 0x100); // 0x07 400kHz + i2c_set_adapdata(new_adapter, new_data); + error = i2c_add_numbered_adapter(new_adapter); + if (error < 0) { + printk(KERN_ALERT "Cannot add i2c adapter %s", new_data->pca9548.calling_name); + kfree_sensitive(new_adapter); + kfree_sensitive(new_data); + return NULL; + } + + return new_adapter; +}; + +/** + * Board info for QSFP/SFP+ eeprom. + * Note: Using sff8436 as I2C eeprom driver. + */ +static struct i2c_board_info sff8436_eeprom_info[] = { + { I2C_BOARD_INFO("optoe1", 0x50) }, + { I2C_BOARD_INFO("optoe2", 0x50) }, +}; + +static int ds3000_drv_probe(struct platform_device *pdev) +{ + int ret = 0; + int portid_count; + uint8_t cpld1_version, cpld2_version; + uint16_t prev_i2c_switch = 0; + struct sff_device_data *sff_data; + + /* The device class need to be instantiated before this function called */ + BUG_ON(fpgafwclass == NULL); + + fpga_data = devm_kzalloc(&pdev->dev, sizeof(struct ds3000_fpga_data), + GFP_KERNEL); + + if (!fpga_data) + return -ENOMEM; + + // Set default read address to VERSION + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + FPGA_VERSION; + fpga_data->cpld1_read_addr = 0x00; + fpga_data->cpld2_read_addr = 0x00; + + mutex_init(&fpga_data->fpga_lock); + + for (ret = I2C_MASTER_CH_1 ; ret <= I2C_MASTER_CH_TOTAL; ret++) { + mutex_init(&fpga_i2c_master_locks[ret - 1]); + } + + fpga = kobject_create_and_add("FPGA", &pdev->dev.kobj); + if (!fpga) { + kfree_sensitive(fpga_data); + return -ENOMEM; + } + + ret = sysfs_create_group(fpga, &fpga_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create FPGA sysfs attributes\n"); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + cpld1 = kobject_create_and_add("CPLD1", &pdev->dev.kobj); + if (!cpld1) { + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld1, &cpld1_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD1 sysfs attributes\n"); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + cpld2 = kobject_create_and_add("CPLD2", &pdev->dev.kobj); + if (!cpld2) { + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld2, &cpld2_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD2 sysfs attributes\n"); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + sff_dev = device_create(fpgafwclass, NULL, MKDEV(0, 0), NULL, "sff_device"); + if (IS_ERR(sff_dev)) { + printk(KERN_ERR "Failed to create sff device\n"); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return PTR_ERR(sff_dev); + } + + ret = sysfs_create_group(&sff_dev->kobj, &sff_led_test_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create SFF attributes\n"); + device_destroy(fpgafwclass, MKDEV(0, 0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + ret = sysfs_create_link(&pdev->dev.kobj, &sff_dev->kobj, "SFF"); + if (ret != 0) { + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + device_destroy(fpgafwclass, MKDEV(0, 0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { + fpga_data->i2c_adapter[portid_count] = ds3000_i2c_init(pdev, portid_count, VIRTUAL_I2C_BUS_OFFSET); + } + + + /* Init SFF devices */ + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + struct i2c_adapter *i2c_adap = fpga_data->i2c_adapter[portid_count]; + if (i2c_adap) { + fpga_data->sff_devices[portid_count] = ds3000_sff_init(portid_count); + sff_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + BUG_ON(sff_data == NULL); + if ( sff_data->port_type == QSFP ) { + fpga_data->sff_i2c_clients[portid_count] = i2c_new_client_device(i2c_adap, &sff8436_eeprom_info[0]); + } else { + fpga_data->sff_i2c_clients[portid_count] = i2c_new_client_device(i2c_adap, &sff8436_eeprom_info[1]); + } + sff_data = NULL; + sysfs_create_link(&fpga_data->sff_devices[portid_count]->kobj, + &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, + "i2c"); + } + + } + + printk(KERN_INFO "Virtual I2C buses created\n"); + +#ifdef TEST_MODE + return 0; +#endif + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld1_version); + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld2_version); + + printk(KERN_INFO "CPLD1 VERSON: %2.2x\n", cpld1_version); + printk(KERN_INFO "CPLD2 VERSON: %2.2x\n", cpld2_version); + + /* Init I2C buses that has PCA9548 switch device. */ + for (portid_count = 0; portid_count < VIRTUAL_I2C_PORT_LENGTH; portid_count++) { + + struct i2c_dev_data *dev_data; + unsigned char master_bus; + unsigned char switch_addr; + + dev_data = i2c_get_adapdata(fpga_data->i2c_adapter[portid_count]); + master_bus = dev_data->pca9548.master_bus; + switch_addr = dev_data->pca9548.switch_addr; + + if (switch_addr != 0xFF) { + + if (prev_i2c_switch != ( (master_bus << 8) | switch_addr) ) { + // Found the bus with PCA9548, trying to clear all switch in it. + smbus_access(fpga_data->i2c_adapter[portid_count], switch_addr, 0x00, + I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); + prev_i2c_switch = ( master_bus << 8 ) | switch_addr; + } + } + } + return 0; +} + +static int ds3000_drv_remove(struct platform_device *pdev) +{ + int portid_count; + struct sff_device_data *rem_data; + + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj, "i2c"); + i2c_unregister_device(fpga_data->sff_i2c_clients[portid_count]); + } + + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { + if (fpga_data->i2c_adapter[portid_count] != NULL) { + info(KERN_INFO "<%x>", fpga_data->i2c_adapter[portid_count]); + i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); + } + } + + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + if (fpga_data->sff_devices[portid_count] != NULL) { + rem_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + device_unregister(fpga_data->sff_devices[portid_count]); + put_device(fpga_data->sff_devices[portid_count]); + kfree(rem_data); + } + } + + sysfs_remove_group(fpga, &fpga_attr_grp); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + kobject_put(fpga); + kobject_put(cpld1); + kobject_put(cpld2); + device_destroy(fpgafwclass, MKDEV(0, 0)); + devm_kfree(&pdev->dev, fpga_data); + return 0; +} + +static struct platform_driver ds3000_drv = { + .probe = ds3000_drv_probe, + .remove = __exit_p(ds3000_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +#ifdef TEST_MODE +#define FPGA_PCI_BAR_NUM 2 +#else +#define FPGA_PCI_BAR_NUM 0 +#endif + +static const struct pci_device_id fpga_id_table[] = { + { PCI_VDEVICE(XILINX, FPGA_PCIE_DEVICE_ID) }, + { PCI_VDEVICE(TEST, TEST_PCIE_DEVICE_ID) }, + {0, } +}; + +MODULE_DEVICE_TABLE(pci, fpga_id_table); + +static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int err; + struct device *dev = &pdev->dev; + uint32_t fpga_version; + + if ((err = pci_enable_device(pdev))) { + dev_err(dev, "pci_enable_device probe error %d for device %s\n", + err, pci_name(pdev)); + return err; + } + + if ((err = pci_request_regions(pdev, FPGA_PCI_NAME)) < 0) { + dev_err(dev, "pci_request_regions error %d\n", err); + goto pci_disable; + } + + /* bar0: data mmio region */ + fpga_dev.data_mmio_start = pci_resource_start(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_mmio_len = pci_resource_len(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_base_addr = pci_iomap(pdev, FPGA_PCI_BAR_NUM, 0); + if (!fpga_dev.data_base_addr) { + dev_err(dev, "cannot iomap region of size %lu\n", + (unsigned long)fpga_dev.data_mmio_len); + goto pci_release; + } + dev_info(dev, "data_mmio iomap base = 0x%lx \n", + (unsigned long)fpga_dev.data_base_addr); + dev_info(dev, "data_mmio_start = 0x%lx data_mmio_len = %lu\n", + (unsigned long)fpga_dev.data_mmio_start, + (unsigned long)fpga_dev.data_mmio_len); + + printk(KERN_INFO "FPGA PCIe driver probe OK.\n"); + printk(KERN_INFO "FPGA ioremap registers of size %lu\n", (unsigned long)fpga_dev.data_mmio_len); + printk(KERN_INFO "FPGA Virtual BAR %d at %8.8lx - %8.8lx\n", FPGA_PCI_BAR_NUM, + (unsigned long)fpga_dev.data_base_addr, + (unsigned long)(fpga_dev.data_base_addr + fpga_dev.data_mmio_len)); + printk(KERN_INFO ""); + fpga_version = ioread32(fpga_dev.data_base_addr); + printk(KERN_INFO "FPGA VERSION : %8.8x\n", fpga_version); + if ((err = fpgafw_init()) < 0) { + goto pci_unmap; + } + ds3000_dev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); + platform_driver_register(&ds3000_drv); + return 0; + +pci_unmap: + pci_iounmap(pdev, fpga_dev.data_base_addr); +pci_release: + pci_release_regions(pdev); +pci_disable: + pci_disable_device(pdev); + return -EBUSY; +} + +static void fpga_pci_remove(struct pci_dev *pdev) +{ + platform_driver_unregister(&ds3000_drv); + platform_device_unregister(ds3000_dev); + fpgafw_exit(); + pci_iounmap(pdev, fpga_dev.data_base_addr); + pci_release_regions(pdev); + pci_disable_device(pdev); + printk(KERN_INFO "FPGA PCIe driver remove OK.\n"); +}; + +static struct pci_driver pci_dev_ops = { + .name = FPGA_PCI_NAME, + .probe = fpga_pci_probe, + .remove = fpga_pci_remove, + .id_table = fpga_id_table, +}; + +enum { + READREG, + WRITEREG +}; + +struct fpga_reg_data { + uint32_t addr; + uint32_t value; +}; + +static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { + int ret = 0; + struct fpga_reg_data data; + mutex_lock(&fpga_data->fpga_lock); + +#ifdef TEST_MODE + static uint32_t status_reg; +#endif + // Switch function to read and write. + switch (cmd) { + case READREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + data.value = ioread32(fpga_dev.data_base_addr + data.addr); + if (copy_to_user((void __user*)arg , &data, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } +#ifdef TEST_MODE + if (data.addr == 0x1210) { + switch (status_reg) { + case 0x0000 : status_reg = 0x8000; + break; + + case 0x8080 : status_reg = 0x80C0; + break; + case 0x80C0 : status_reg = 0x80F0; + break; + case 0x80F0 : status_reg = 0x80F8; + break; + + } + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } +#endif + + + break; + case WRITEREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + iowrite32(data.value, fpga_dev.data_base_addr + data.addr); + +#ifdef TEST_MODE + if (data.addr == 0x1204) { + status_reg = 0x8080; + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } +#endif + + break; + default: + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return ret; +} + + +const struct file_operations fpgafw_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = fpgafw_unlocked_ioctl, +}; + + +static int fpgafw_init(void) { + printk(KERN_INFO "Initializing the switchboard driver\n"); + // Try to dynamically allocate a major number for the device -- more difficult but worth it + majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); + if (majorNumber < 0) { + printk(KERN_ALERT "Failed to register a major number\n"); + return majorNumber; + } + printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); + + // Register the device class + fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(fpgafwclass)) { // Check for error and clean up if there is + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to register device class\n"); + return PTR_ERR(fpgafwclass); + } + printk(KERN_INFO "Device class registered correctly\n"); + + // Register the device driver + fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); + if (IS_ERR(fpgafwdev)) { // Clean up if there is an error + class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); + return PTR_ERR(fpgafwdev); + } + printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); // Made it! device was initialized + return 0; +} + +static void fpgafw_exit(void) { + device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device + class_destroy(fpgafwclass); // remove the device class + unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number + printk(KERN_INFO "Goodbye!\n"); +} + +int ds3000_init(void) +{ + int rc; + rc = pci_register_driver(&pci_dev_ops); + if (rc) + return rc; + return 0; +} + +void ds3000_exit(void) +{ + pci_unregister_driver(&pci_dev_ops); +} + +module_init(ds3000_init); +module_exit(ds3000_exit); + +MODULE_AUTHOR("Pradchaya P. "); +MODULE_DESCRIPTION("Celestica ds3000 switchboard driver"); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/setup.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/setup.py new file mode 100644 index 000000000000..a1535165bb66 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/setup.py @@ -0,0 +1,28 @@ +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Celestica Platforms based on PDDF', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + packages=['sonic_platform'], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 3.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/__init__.py new file mode 100644 index 000000000000..21d9cd445e31 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/__init__.py @@ -0,0 +1,4 @@ +# All the derived classes for PDDF +__all__ = ["platform", "chassis", "sfp", "psu", "thermal"] +from . import platform +from . import chassis diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/chassis.py new file mode 100644 index 000000000000..ec8b8ffd10d3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/chassis.py @@ -0,0 +1,283 @@ +############################################################################# +# PDDF +# Module contains an implementation of SONiC Chassis API +# +############################################################################# + +try: + import os + import subprocess + from .event import XcvrEvent + from .helper import APIHelper + from .thermal import ThermalMon, THERMAL_MONITOR_SENSORS + from sonic_py_common import logger + from sonic_platform_pddf_base.pddf_chassis import PddfChassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +RESET_SOURCE_BIOS_REG = '0xa107' +LPC_SYSLED_REG = '0xa162' +LPC_GETREG_PATH = "/sys/bus/platform/devices/baseboard/getreg" +LPC_SETREG_PATH = "/sys/bus/platform/devices/baseboard/setreg" +LED_CTRL_MODE_GET_CMD = "ipmitool raw 0x3a 0x42 0x01" + +SYSLOG_IDENTIFIER = "Chassis" +helper_logger = logger.Logger(SYSLOG_IDENTIFIER) + +class Chassis(PddfChassis): + """ + PDDF Platform-specific Chassis class + """ + SYSLED_COLOR_VAL_MAP = { + 'off': '0xff', + 'green': '0xdc', + 'amber': '0xec', + 'amber_blink': '0xee', + 'amber_blink_4hz': '0xee', + 'amber_blink_1hz': '0xed', + 'green_blink': '0xde', + 'green_blink_4hz': '0xde', + 'green_blink_1hz': '0xdd' + } + + SYSLED_VAL_COLOR_MAP = { + '0xff': 'off', + '0xdc': 'green', + '0xec': 'amber', + '0xee': 'amber_blink_4hz', + '0xed': 'amber_blink_1hz', + '0xde': 'green_blink_4hz', + '0xdd': 'green_blink_1hz' + } + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + PddfChassis.__init__(self, pddf_data, pddf_plugin_data) + self._api_helper = APIHelper() + if not self._api_helper.is_bmc_present(): + thermal_count = len(self._thermal_list) + for idx, name in enumerate(THERMAL_MONITOR_SENSORS): + thermal = ThermalMon(thermal_count + idx, name) + self._thermal_list.append(thermal) + + try: + from sonic_platform_pddf_base.pddf_component import PddfComponent # noqa + except ImportError: + # Use custom Component implementation if no pddf_component support + from sonic_platform.custom_component import Component + if self._api_helper.is_bmc_present(): + NUM_COMPONENT = 9 + else: + NUM_COMPONENT = 8 + for i in range(0, NUM_COMPONENT): + component = Component(i) + self._component_list.append(component) + + def initizalize_system_led(self): + """ + This function is not defined in chassis base class, + system-health command would invoke chassis.initizalize_system_led(), + add this stub function just to let the command sucessfully execute + """ + pass + + def get_status_led(self): + """ + Gets the state of the system LED + Args: + None + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + led_status = self._api_helper.lpc_getreg(LPC_GETREG_PATH, LPC_SYSLED_REG) + color = self.SYSLED_VAL_COLOR_MAP.get(led_status, 'unknown') + return color + + def set_status_led(self, color): + """ + Sets the state of the system LED + Args: + color: A string representing the color with which to set the + system LED + Returns: + bool: True if system LED state is set successfully, False if not + """ + if self._api_helper.is_bmc_present(): + led_mode_cmd = LED_CTRL_MODE_GET_CMD + if os.getuid() != 0: + cmd = "sudo " + cmd + led_mode_cmd = "sudo " + led_mode_cmd + status, mode = self._api_helper.get_cmd_output(led_mode_cmd) + # led take automatic control mode, led not settable + if status != 0 or mode.strip() == "01": + helper_logger.log_info("SYS LED takes automatic ctrl mode!") + return False + + # Set SYS_LED through baseboard cpld + color_val = self.SYSLED_COLOR_VAL_MAP.get(color, None) + if color_val == None: + helper_logger.log_error("SYS LED color {} not support!".format(color)) + return False + + status = self._api_helper.lpc_setreg(LPC_SETREG_PATH, LPC_SYSLED_REG, color_val) + + return status + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + For Quanta the index in sfputil.py starts from 1, so override + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + if (index == 0): + raise IndexError + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("override: SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + + return sfp + # Provide the functions/variables below for which implementation is to be overwritten + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + hw_reboot_cause = self._api_helper.lpc_getreg(LPC_GETREG_PATH, RESET_SOURCE_BIOS_REG) + + if hw_reboot_cause == "0x77": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'Power Cycle Reset' + elif hw_reboot_cause == "0x66": + reboot_cause = self.REBOOT_CAUSE_WATCHDOG + description = 'Hardware Watchdog Reset' + elif hw_reboot_cause == "0x44": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'CPU Warm Reset' + elif hw_reboot_cause == "0x33": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'Soft-Set Cold Reset' + elif hw_reboot_cause == "0x22": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'Soft-Set Warm Reset' + elif hw_reboot_cause == "0x11": + reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + description = 'Power Off Reset' + elif hw_reboot_cause == "0x00": + reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + description = 'Power Cycle Reset' + else: + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'Hardware reason' + + return (reboot_cause, description) + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + try: + if self._watchdog is None: + from sonic_platform.cpld_watchdog import Watchdog + # Create the watchdog Instance from cpld watchdog + self._watchdog = Watchdog() + + except Exception as e: + helper_logger.log_error("Fail to load watchdog due to {}".format(e)) + return self._watchdog + + ############################################################## + ###################### Event methods ######################### + ############################################################## + 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. + """ + # SFP event + if self.get_num_sfps() == 0: + for index in range(self.platform_inventory['num_ports']): + sfp = Sfp(index, self.pddf_obj, self.plugin_data) + self._sfp_list.append(sfp) + + succeed, sfp_event = XcvrEvent(self._sfp_list).get_xcvr_event(timeout) + if succeed: + return True, {'sfp': sfp_event} + + return False, {'sfp': {}} + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str() + + def get_revision(self): + """ + Retrieves the hardware revision for the chassis + Returns: + A string containing the hardware revision for this chassis. + """ + return self._eeprom.revision_str() + + def get_system_airflow(self): + """ + Retrieve system airflow + Returns: + string: INTAKE or EXHAUST + """ + airflow = self.get_serial()[5:8] + if airflow == "B2F": + return "INTAKE" + elif airflow == "F2B": + return "EXHAUST" + return "Unknown" + + def get_thermal_manager(self): + """ + Retrieves thermal manager class on this chasssis + + Returns: + A class derived from ThermalManagerBase representing the + specified thermal manager + """ + if not self._api_helper.is_bmc_present(): + from .thermal_manager import ThermalManager + return ThermalManager + return None diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/component.py new file mode 100644 index 000000000000..9408cfd5fad4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/component.py @@ -0,0 +1,146 @@ +try: + import subprocess + from .helper import APIHelper + from sonic_platform_pddf_base.pddf_component import PddfComponent +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Component(PddfComponent): + + def __init__(self, component_index, pddf_data=None, pddf_plugin_data=None): + PddfComponent.__init__(self, component_index, pddf_data, pddf_plugin_data) + self._api_helper = APIHelper() + + def get_available_firmware_version(self, image_path): + """ + Retrieves the available firmware version of the component + + Note: the firmware version will be read from image + + Args: + image_path: A string, path to firmware image + + Returns: + A string containing the available firmware version of the component + """ + raise NotImplementedError + + def get_firmware_update_notification(self, image_path): + """ + Retrieves a notification on what should be done in order to complete + the component firmware update + + Args: + image_path: A string, path to firmware image + + Returns: + A string containing the component firmware update notification if required. + By default 'None' value will be used, which indicates that no actions are required + """ + type = self.get_type() + if type == 'bios': + return "BIOS will be updated, please wait for completion and reboot the device to take effect!" + elif type == 'cpld' or type == 'fpga': + return "{} will be updated, please wait for completion and power reboot device to take effect!".format(type.upper()) + elif type == 'bmc': + return "BMC image will be updated, please wait for completion!" + return None + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + This API performs firmware installation only: this may/may not be the same as firmware update. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this must be done manually by user + + Note: in case immediate actions are required to complete the component firmware update + (e.g., reboot, power cycle, etc.) - will be done automatically by API and no return value provided + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + if self.component_data == None: + self.component_data = self._get_component_data() + pre_cmd = self.component_data['pre-update'] + update_cmd = self.component_data['update'] + post_cmd = self.component_data['post-update'] + if pre_cmd != None: + status, _ = self._api_helper.get_cmd_output(pre_cmd) + if status != 0: + return False + if update_cmd != None: + update_cmd = update_cmd.format(image_path) + status, _ = self._api_helper.get_cmd_output(update_cmd) + if status != 0: + return False + if post_cmd != None: + status, _ = self._api_helper.get_cmd_output(post_cmd) + if status != 0: + return False + + return True + + def update_firmware(self, image_path): + """ + Updates firmware of the component + + This API performs firmware update: it assumes firmware installation and loading in a single call. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically by API + + Args: + image_path: A string, path to firmware image + + Returns: + Boolean False if image_path doesn't exist instead of throwing an exception error + Nothing when the update is successful + + Raises: + RuntimeError: update failed + """ + status = self.install_firmware(image_path) + if not status: + return status + + type = self.get_type() + if type == 'fpga' or type == 'cpld': + # TODO:: power cycle FPGA or CPLD + pass + + return True + + def auto_update_firmware(self, image_path, boot_type): + """ + Updates firmware of the component + + This API performs firmware update automatically based on boot_type: it assumes firmware installation + and/or creating a loading task during the reboot, if needed, in a single call. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically during the reboot. + The loading task will be created by API. + + Args: + image_path: A string, path to firmware image + boot_type: A string, reboot type following the upgrade + - none/fast/warm/cold + + Returns: + Output: A return code + return_code: An integer number, status of component firmware auto-update + - return code of a positive number indicates successful auto-update + - status_installed = 1 + - status_updated = 2 + - status_scheduled = 3 + - return_code of a negative number indicates failed auto-update + - status_err_boot_type = -1 + - status_err_image = -2 + - status_err_unknown = -3 + + Raises: + RuntimeError: auto-update failure cause + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/cpld_watchdog.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/cpld_watchdog.py new file mode 100644 index 000000000000..7889ce15f83f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/cpld_watchdog.py @@ -0,0 +1,228 @@ +#!/usr/bin/env python + +############################################################################# +# +# Watchdog contains an implementation of SONiC Platform Base Watchdog API +# +############################################################################# +try: + import ctypes + import fcntl + import os + import subprocess + import time + import array + import syslog + from .helper import APIHelper + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +LPC_CPLD_GETREG_PATH = "/sys/bus/platform/devices/baseboard/getreg" +LPC_CPLD_SETREG_PATH = "/sys/bus/platform/devices/baseboard/setreg" +LPC_WDT_SET_TIMER_L_REG = '0xa183' +LPC_WDT_SET_TIMER_M_REG = '0xa182' +LPC_WDT_SET_TIMER_H_REG = '0xa181' +LPC_WDT_TIMER_L_REG = '0xa186' +LPC_WDT_TIMER_M_REG = '0xa185' +LPC_WDT_TIMER_H_REG = '0xa184' +LPC_WDT_CTRL_REG = '0xa187' +LPC_WDT_ARM_REG = '0xa188' + +WDT_ENABLE = 0x1 +WDT_DISABLE = 0x0 +WDT_COMMON_ERROR = -1 +DEFAULT_TIMEOUT = 180 + +class CpldWatchdog(WatchdogBase): + + def __init__(self): + WatchdogBase.__init__(self) + # Set default value + self._api_helper = APIHelper() + self._ka_count = int(1) + self.armed = True if self._active() else False + self.timeout = self._gettimeout() if self.armed else DEFAULT_TIMEOUT + #self._disable() + + def _lpc_get(self, reg): + return self._api_helper.lpc_getreg(LPC_CPLD_GETREG_PATH, reg) + + def _lpc_set(self, reg, val): + if type(val) is int: + val = hex(val) + return self._api_helper.lpc_setreg(LPC_CPLD_SETREG_PATH, reg, val) + + def _active(self): + """ + WDT is active or not + """ + data = self._lpc_get(LPC_WDT_CTRL_REG) + return True if data == "0x01" else False + + def _enable(self): + """ + Turn on the watchdog timer + """ + status = self._lpc_set(LPC_WDT_CTRL_REG, WDT_ENABLE) + if not status: + pass + + def _disable(self): + """ + Turn off the watchdog timer + """ + status = self._lpc_set(LPC_WDT_CTRL_REG, WDT_DISABLE) + if not status: + pass + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + if bool(self._ka_count % 2): + status = self._lpc_set(LPC_WDT_ARM_REG, WDT_ENABLE) + else: + status = self._lpc_set(LPC_WDT_ARM_REG, WDT_DISABLE) + + if not status: + syslog.syslog(syslog.LOG_ERR, "Feed Watchdog failed") + + self._ka_count = self._ka_count + 1 + if (self._ka_count >= 11): + self._ka_count = 1 + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + ms = seconds * 1000 + ms_low_byte = ms & 0xff + ms_media_byte = (ms >> 8) & 0xff + ms_high_byte = (ms >> 16) & 0xff + self._lpc_set(LPC_WDT_SET_TIMER_L_REG, ms_low_byte) + self._lpc_set(LPC_WDT_SET_TIMER_M_REG, ms_media_byte) + self._lpc_set(LPC_WDT_SET_TIMER_H_REG, ms_high_byte) + return self._gettimeout() + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + data = [0, 0, 0] + data[0] = self._lpc_get(LPC_WDT_SET_TIMER_L_REG) + data[1] = self._lpc_get(LPC_WDT_SET_TIMER_M_REG) + data[2] = self._lpc_get(LPC_WDT_SET_TIMER_H_REG) + seconds = int((int(data[2], 16) << 16 + | int(data[1], 16) << 8 + | int(data[0], 16)) / 1000) + return seconds + + def _gettimeleft(self): + """ + Get time left before watchdog timer expires + @return time left in seconds + """ + data = [0, 0, 0] + data[0] = self._lpc_get(LPC_WDT_TIMER_L_REG) + data[1] = self._lpc_get(LPC_WDT_TIMER_M_REG) + data[2] = self._lpc_get(LPC_WDT_TIMER_H_REG) + seconds = int((int(data[2], 16) << 16 + | int(data[1], 16) << 8 + | int(data[0], 16)) / 1000) + + return seconds + + ################################################################# + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + + ret = WDT_COMMON_ERROR + if seconds < 0: + return ret + + try: + if self.armed: + self._keepalive() + if self.timeout != seconds: + self._disable() + time.sleep(1) + self.timeout = self._settimeout(seconds) + self._enable() + else: + self.timeout = self._settimeout(seconds) + self._keepalive() + self._enable() + self.armed = True + ret = self.timeout + except IOError as e: + pass + + return ret + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + disarmed = False + if self.is_armed(): + try: + self._disable() + self.armed = False + disarmed = True + except IOError: + pass + + return disarmed + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + + return self.armed + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Returns: + An integer specifying the number of seconds remaining on thei + watchdog timer. If the watchdog is not armed, returns -1. + """ + + timeleft = WDT_COMMON_ERROR + + if self.armed: + try: + timeleft = self._gettimeleft() + except IOError: + pass + + return timeleft + +class Watchdog(CpldWatchdog): + """PDDF Platform-Specific Watchdog Class""" + + def __init__(self): + CpldWatchdog.__init__(self) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/custom_component.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/custom_component.py new file mode 100644 index 000000000000..f342c2cf8058 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/custom_component.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +# +############################################################################# + +import subprocess +import re + +try: + from sonic_platform_base.component_base import ComponentBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +COMPONENT_LIST_BMC = [ + ("BIOS", "Basic input/output System"), + ("BMC", "Baseboard Management Controller"), + ("BaseBoard_CPLD", "Base board CPLD"), + ("SwitchBoard_CPLD1", "Switch board CPLD 1"), + ("SwitchBoard_CPLD2", "Switch board CPLD 2"), + ("COMeBoard_CPLD", "COMe board CPLD"), + ("FPGA", "Baseboard FPGA"), + ("PCIe", "ASIC PCIe Firmware"), + ("SSD", "Solid State Drive firmware version") +] + +COMPONENT_LIST_NONBMC = [ + ("BIOS", "Basic input/output System"), + ("BaseBoard_CPLD", "Base board CPLD"), + ("SwitchBoard_CPLD1", "Switch board CPLD 1"), + ("SwitchBoard_CPLD2", "Switch board CPLD 2"), + ("COMeBoard_CPLD", "COMe board CPLD"), + ("FPGA", "Baseboard FPGA"), + ("PCIe", "ASIC PCIe Firmware"), + ("SSD", "Solid State Drive firmware version") +] + +NAME_INDEX = 0 +DESCRIPTION_INDEX = 1 + +BIOS_VERSION_CMD = "dmidecode -s bios-version" +BASECPLD_VERSION_CMD="cat /sys/devices/platform/baseboard/version" +SWCPLD1_VERSION_CMD = "i2cget -y -f 102 0x30 0x0" +SWCPLD2_VERSION_CMD = "i2cget -y -f 102 0x31 0x0" +COMECPLD_VERSION_CMD="cat /sys/devices/platform/baseboard/come_cpld_version" +FPGA_VERSION_CMD="cat /sys/devices/platform/fpga_sysfs/version" +ASIC_PCIE_VERSION_CMD = "bcmcmd 'pciephy fw version' | grep 'PCIe FW version' | cut -d ' ' -f 4" +SSD_VERSION_CMD = "smartctl -i /dev/sda" + +UNKNOWN_VER = "unknown" + +class Component(): + """Platform-specific Component class""" + + DEVICE_TYPE = "component" + + def __init__(self, component_index): + ComponentBase.__init__(self) + self._api_helper = APIHelper() + self.index = component_index + self.name = self.get_name() + + def _get_asic_pcie_ver(self): + status, raw_ver=self.run_command(ASIC_PCIE_VERSION_CMD) + if status: + return raw_ver + else: + return UNKNOWN_VER + + def _get_bios_ver(self): + status, raw_ver=self.run_command(BIOS_VERSION_CMD) + if status: + return raw_ver + else: + return UNKNOWN_VER + + def _get_basecpld_ver(self): + status, raw_ver=self.run_command(BASECPLD_VERSION_CMD) + if status: + ver_str = "{}.{}".format(int(raw_ver[2], 16), int(raw_ver[3], 16)) + return ver_str + else: + return UNKNOWN_VER + + def _get_swcpld1_ver(self): + status, raw_ver=self.run_command(SWCPLD1_VERSION_CMD) + if status: + ver_str = "{}.{}".format(int(raw_ver[2], 16), int(raw_ver[3], 16)) + return ver_str + else: + return UNKNOWN_VER + + def _get_swcpld2_ver(self): + status, raw_ver=self.run_command(SWCPLD2_VERSION_CMD) + if status: + ver_str = "{}.{}".format(int(raw_ver[2], 16), int(raw_ver[3], 16)) + return ver_str + else: + return UNKNOWN_VER + + def _get_comecpld_ver(self): + status, raw_ver=self.run_command(COMECPLD_VERSION_CMD) + if status: + ver_str = "{}.{}".format(int(raw_ver[2], 16), int(raw_ver[3], 16)) + return ver_str + else: + return UNKNOWN_VER + + def _get_fpga_ver(self): + status, raw_ver=self.run_command(FPGA_VERSION_CMD) + if status: + iver = int(raw_ver, 16) + ver = "{}.{}".format(iver >> 16, iver & 0xffff) + return ver + else: + return UNKNOWN_VER + + def _get_bmc_ver(self): + cmd="ipmitool mc info | grep 'Firmware Revision'" + status, raw_ver=self.run_command(cmd) + if status: + bmc_ver=raw_ver.split(':')[-1].strip() + return bmc_ver + else: + return UNKNOWN_VER + + def _get_ssd_ver(self): + ssd_ver = "N/A" + status, raw_ssd_data = self.run_command(SSD_VERSION_CMD) + if status: + ret = re.search(r"Firmware Version: +(.*)[^\\]", raw_ssd_data) + if ret != None: + ssd_ver = ret.group(1) + return ssd_ver + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + if self._api_helper.is_bmc_present(): + return COMPONENT_LIST_BMC[self.index][NAME_INDEX] + else: + return COMPONENT_LIST_NONBMC[self.index][NAME_INDEX] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + if self._api_helper.is_bmc_present(): + return COMPONENT_LIST_BMC[self.index][DESCRIPTION_INDEX] + else: + return COMPONENT_LIST_NONBMC[self.index][DESCRIPTION_INDEX] + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + fw_func_map = { + "BIOS": "_get_bios_ver", + "BMC": "_get_bmc_ver", + "BaseBoard_CPLD": "_get_basecpld_ver", + "SwitchBoard_CPLD1": "_get_swcpld1_ver", + "SwitchBoard_CPLD2": "_get_swcpld2_ver", + "COMeBoard_CPLD": "_get_comecpld_ver", + "FPGA": "_get_fpga_ver", + "PCIe": "_get_asic_pcie_ver", + "SSD": "_get_ssd_ver" + } + fw_method = getattr(self, fw_func_map[self.name], None) + if fw_method: + fw_ver = fw_method() + return fw_ver + else: + return UNKNOWN_VER + + def run_command(self, cmd): + status = True + result = "" + try: + p = subprocess.Popen( # nosemgrep + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # nosemgrep + raw_data, err = p.communicate() + if err.decode('UTF-8') == '': + result = raw_data.strip().decode('UTF-8') + except Exception: + status = False + return status, result diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/eeprom.py new file mode 100644 index 000000000000..139f8641428f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/eeprom.py @@ -0,0 +1,75 @@ +try: + from sonic_platform_pddf_base.pddf_eeprom import PddfEeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Eeprom(PddfEeprom): + + _TLV_DISPLAY_VENDOR_EXT = True + _TLV_INFO_MAX_LEN = 256 + pddf_obj = {} + plugin_data = {} + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + + # system EEPROM always has device name EEPROM1 + self.eeprom_path = self.pddf_obj.get_path("EEPROM1", "eeprom") + if self.eeprom_path is None: + return + + super(PddfEeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() + try: + self.eeprom_data = self.read_eeprom() + except Exception as e: + self.eeprom_data = "N/A" + raise RuntimeError("PddfEeprom is not Programmed - Error: {}".format(str(e))) + else: + eeprom = self.eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = ((eeprom[9]) << 8) | (eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < self._TLV_INFO_MAX_LEN and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + (eeprom[tlv_index + 1])] + code = "0x%02X" % ((tlv[0])) + + if (tlv[0]) == self._TLV_CODE_VENDOR_EXT: + name = "Vendor Extension" + value = "" + if self._TLV_DISPLAY_VENDOR_EXT: + for c in tlv[2:2 + tlv[1]]: + value += "0x%02X " % c + else: + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if (eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += (eeprom[tlv_index+1]) + 2 + + + # Provide the functions/variables below for which implementation is to be overwritten + def revision_str(self): + (is_valid, results) = self.get_tlv_field(self.eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + "N/A" + if type(results[2]) is bytearray: + return str(int.from_bytes(results[2], byteorder='little')) + + return results[2].decode('ascii') diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/event.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/event.py new file mode 100644 index 000000000000..86a1390cd6b7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/event.py @@ -0,0 +1,52 @@ +try: + import time + from sonic_py_common.logger import Logger +except ImportError as e: + raise ImportError(repr(e) + " - required module not found") + +class XcvrEvent: + ''' Listen to insert/remove QSFP/SFP+ events ''' + + def __init__(self, sfp_list): + self._sfp_list = sfp_list + self._logger = Logger() + + xcvr_change_event_data = {'valid': 0, 'last': 0, 'present': 0} + + def get_xcvr_event(self, timeout): + port_dict = {} + + # Using polling mode + now = time.time() + + if timeout < 1000: + timeout = 1000 + timeout = timeout / float(1000) # Convert to secs + + if now < (self.xcvr_change_event_data['last'] + timeout) \ + and self.xcvr_change_event_data['valid']: + return True, port_dict + + bitmap = 0 + for sfp in self._sfp_list: + modpres = sfp.get_presence() + index = sfp.port_index - 1 + if modpres: + bitmap = bitmap | (1 << index) + + changed_ports = self.xcvr_change_event_data['present'] ^ bitmap + if changed_ports: + for sfp in self._sfp_list: + index = sfp.port_index - 1 + if changed_ports & (1 << index): + if (bitmap & (1 << index)) == 0: + port_dict[str(index + 1)] = '0' + else: + port_dict[str(index + 1)] = '1' + + # Update the cache dict + self.xcvr_change_event_data['present'] = bitmap + self.xcvr_change_event_data['last'] = now + self.xcvr_change_event_data['valid'] = 1 + + return True, port_dict diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/fan.py new file mode 100644 index 000000000000..1551e554b8b4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/fan.py @@ -0,0 +1,172 @@ +import os + +try: + from .helper import APIHelper + from sonic_platform_pddf_base.pddf_fan import PddfFan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Fan(PddfFan): + """PDDF Platform-Specific Fan class""" + + BMC_FAN_FSC_STATUS_CMD = "ipmitool raw 0x3a 0x26 0x00" + LPC_CPLD_SETREG_PATH = "/sys/bus/platform/devices/baseboard/setreg" + FAN_PWM_CTRL_REG_MAP = { + 1: '0xa1b2', + 2: '0xa1b8', + 3: '0xa1c4', + 4: '0xa1ca' + } + + def __init__(self, tray_idx, fan_idx=0, pddf_data=None, pddf_plugin_data=None, is_psu_fan=False, psu_index=0): + # idx is 0-based + PddfFan.__init__(self, tray_idx, fan_idx, pddf_data, pddf_plugin_data, is_psu_fan, psu_index) + self._api_helper = APIHelper() + + def get_presence(self): + """ + Retrieves the presence of fan + """ + if self.is_psu_fan: + return super().get_presence() + return super().get_presence() and self.get_status() + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + Or N/A if fan removed or abnormal + """ + if not self.get_status(): + return "N/A" + + if self.is_psu_fan: + from sonic_platform.psu import Psu + psu = Psu(self.fans_psu_index - 1, self.pddf_obj, self.plugin_data) + model = psu.get_model() + if model in ["FSP550-20FM", "G1251-0550WNA"]: + return "EXHAUST" + elif model in ["FSP550-29FM", "G1251-0550WRA"]: + return "INTAKE" + return "Unknown" + + return super().get_direction() + + + 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) + """ + target_speed = 0 + if self.is_psu_fan: + # PSU fan not controllable, return current speed + return self.get_speed() + else: + speed_rpm = self.get_speed_rpm() + if self.fan_index == 1: + max_fan_rpm = eval(self.plugin_data['FAN']['FRONT_FAN_MAX_RPM_SPEED']) # nosemgrep + else: + max_fan_rpm = eval(self.plugin_data['FAN']['REAR_FAN_MAX_RPM_SPEED']) # nosemgrep + speed_percentage = round(int((speed_rpm * 100) / max_fan_rpm)) + target_speed = speed_percentage + + return target_speed + + 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) + """ + if self.is_psu_fan: + attr = "psu_fan{}_speed_rpm".format(self.fan_index) + device = "PSU{}".format(self.fans_psu_index) + output = self.pddf_obj.get_attr_name_output(device, attr) + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + speed = int(float(output['status'])) + + max_speed = int(self.plugin_data['PSU']['PSU_FAN_MAX_SPEED']) + speed_percentage = round((speed*100)/max_speed) + return speed_percentage if speed_percentage <= 100 else 100 + else: + # Get fan rpm instead of fan pwm + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_input" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) + + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + speed = int(float(output['status'])) + + if self.fan_index == 1: + max_speed = int(self.plugin_data['FAN']['FRONT_FAN_MAX_RPM_SPEED']) + else: + max_speed = int(self.plugin_data['FAN']['REAR_FAN_MAX_RPM_SPEED']) + speed_percentage = round((speed*100)/max_speed) + + return speed_percentage if speed_percentage <= 100 else 100 + + 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 self.is_psu_fan: + print("Setting PSU fan speed is not allowed") + return False + + if speed < 0 or speed > 100: + print("Error: Invalid speed %d. Please provide a valid speed percentage" % speed) + return False + + if 'duty_cycle_to_pwm' not in self.plugin_data['FAN']: + print("Setting fan speed is not allowed !") + return False + + duty_cycle_to_pwm = eval(self.plugin_data['FAN']['duty_cycle_to_pwm']) # nosemgrep + pwm = int(round(duty_cycle_to_pwm(speed))) + + if self._api_helper.is_bmc_present(): + status, data = self._api_helper.get_cmd_output(self.BMC_FAN_FSC_STATUS_CMD) + if status != 0: + print("Error: failed to get BMC FSC status") + return False + if data == '01': + # Enable BMC FSC mode + return False + + # FAN 1 & 2 in same fantray share the same register, skip Fan2 setting + if self.fan_index == 2: + return True + # Set FAN PWM through baseboard CPLD + reg = self.FAN_PWM_CTRL_REG_MAP.get(self.fantray_index) + status = self._api_helper.lpc_setreg(self.LPC_CPLD_SETREG_PATH, reg, hex(pwm)) + + return status diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..3946e2bdec56 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/fan_drawer.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_fan_drawer import PddfFanDrawer +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(PddfFanDrawer): + """PDDF Platform-Specific Fan-Drawer class""" + + def __init__(self, tray_idx, pddf_data=None, pddf_plugin_data=None): + # idx is 0-based + PddfFanDrawer.__init__(self, tray_idx, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten + def get_presence(self): + status = False + # Usually if a tray is removed, all the fans inside it are absent + if self._fan_list and len(self._fan_list) == 2: + status = self._fan_list[0].get_presence() or self._fan_list[1].get_presence() + else: + status = self._fan_list[0].get_presence() + return status diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/helper.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/helper.py new file mode 100644 index 000000000000..e03e863a7be2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/helper.py @@ -0,0 +1,130 @@ +import fcntl +import os +import struct +import subprocess +from mmap import * + +BMC_PRES_SYS_PATH = '/sys/bus/platform/devices/baseboard/bmc_presence' + +class APIHelper(): + def pci_get_value(self, resource, offset): + status = True + result = "" + try: + fd = os.open(resource, os.O_RDWR) + mm = mmap(fd, 0) + mm.seek(int(offset)) + read_data_stream = mm.read(4) + result = struct.unpack('I', read_data_stream) + except: + status = False + return status, result + + def get_cmd_output(self, cmd): + try: + data = subprocess.check_output(cmd, shell=True, # nosemgrep + universal_newlines=True, stderr=subprocess.STDOUT).strip() # nosemgrep + status = 0 + except subprocess.CalledProcessError as ex: + data = ex.output + status = ex.returncode + return status, data + + def read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def read_one_line_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.readline() + return data.strip() + except IOError: + pass + return None + + def write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except Exception: + return False + return True + + def lpc_getreg(self, getreg_path, reg): + """ + Get the cpld reg through lpc interface + + Args: + getreg_path: getreg sysfs path + reg: 16 bits reg addr in hex str format + + Returns: + A str, register value in hex str format + """ + file = open(getreg_path, 'w+') + # Acquire an exclusive lock on the file + fcntl.flock(file, fcntl.LOCK_EX) + + try: + file.write(reg) + file.flush() + + # Seek to the beginning of the file + file.seek(0) + + # Read the content of the file + result = file.readline().strip() + finally: + # Release the lock and close the file + fcntl.flock(file, fcntl.LOCK_UN) + file.close() + + return result + + def lpc_setreg(self, setreg_path, reg, val): + """ + Set the cpld reg through lpc interface + + Args: + setreg_path: setreg sysfs path + reg: 16 bits reg addr in hex str format + val: 8 bits register value in hex str format + + Returns: + A boolean, True if speed is set successfully, False if not + """ + status = True + file = open(setreg_path, 'w') + # Acquire an exclusive lock on the file + fcntl.flock(file, fcntl.LOCK_EX) + + try: + data = "{} {}".format(reg, val) + file.write(data) + file.flush() + except: + status = False + finally: + # Release the lock and close the file + fcntl.flock(file, fcntl.LOCK_UN) + file.close() + + return status + + def is_bmc_present(self): + """ + Get the BMC card present status + + Returns: + A boolean, True if present, False if absent + """ + presence = self.read_txt_file(BMC_PRES_SYS_PATH) + if presence == None: + print("Failed to get BMC card presence status") + return True if presence == "present" else False diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/pcie.py new file mode 100644 index 000000000000..6c01e694fdb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/pcie.py @@ -0,0 +1,10 @@ +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Pcie(PcieUtil): + """Celestica Platform-specific PCIe class""" + + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/platform.py new file mode 100644 index 000000000000..8595e80692df --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/platform.py @@ -0,0 +1,23 @@ +############################################################################# +# PDDF +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + + +try: + from sonic_platform_pddf_base.pddf_platform import PddfPlatform +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PddfPlatform): + """ + PDDF Platform-Specific Platform Class + """ + + def __init__(self): + PddfPlatform.__init__(self) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/psu.py new file mode 100644 index 000000000000..3cb3bbaec923 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/psu.py @@ -0,0 +1,72 @@ +try: + from sonic_platform_pddf_base.pddf_psu import PddfPsu + from .helper import APIHelper +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +LPC_GETREG_PATH = "/sys/bus/platform/devices/baseboard/getreg" +LPC_PSU_STATUS_REG = '0xa160' +LPC_PSU_POWER_STATUS_OFFSET = 0 +LPC_PSU_PRES_STATUS_OFFSET = 2 + +class Psu(PddfPsu): + """PDDF Platform-Specific PSU class""" + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PddfPsu.__init__(self, index, pddf_data, pddf_plugin_data) + self._api_helper = APIHelper() + + # Provide the functions/variables below for which implementation is to be overwritten + def get_capacity(self): + return 550 + + def get_type(self): + return 'AC' + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + psu_status = int(self._api_helper.lpc_getreg(LPC_GETREG_PATH, LPC_PSU_STATUS_REG), 16) + presence = psu_status & (1 << (LPC_PSU_PRES_STATUS_OFFSET + 2 - self.psu_index)) + return True if presence == 0 else False + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + psu_status = int(self._api_helper.lpc_getreg(LPC_GETREG_PATH, LPC_PSU_STATUS_REG), 16) + power_status = psu_status & (1 << (LPC_PSU_POWER_STATUS_OFFSET + 2 - self.psu_index)) + return False if power_status == 0 else True + + def get_revision(self): + """ + Retrieves the revision of the device + Returns: + string: revision of device + """ + if not self.get_presence(): + return 'N/A' + + if self._api_helper.is_bmc_present(): + cmd = "ipmitool fru list {} | grep 'Product Version'".format(5 - self.psu_index) + status, output = self._api_helper.get_cmd_output(cmd) + if status == 0: + rev = output.split()[-1] + return rev + else: + # Get the revision information from FRU + cmd1 = "i2cget -y -f {} {} 0x2d b".format(42 + self.psu_index - 1, hex(0x52 + self.psu_index - 1)) + status1, output1 = self._api_helper.get_cmd_output(cmd1) + cmd2 = "i2cget -y -f {} {} 0x2e b".format(42 + self.psu_index - 1, hex(0x52 + self.psu_index - 1)) + status2, output2 = self._api_helper.get_cmd_output(cmd2) + if status1 == 0 and status2 == 0: + rev = bytes.fromhex(output1[2:] + output2[2:]).decode('utf-8') + return rev + return 'N/A' diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/sfp.py new file mode 100644 index 000000000000..7142a5733d10 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/sfp.py @@ -0,0 +1,94 @@ +try: + import sys + import syslog + import time + from multiprocessing import Lock + from sonic_platform_pddf_base.pddf_sfp import PddfSfp +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class Sfp(PddfSfp): + """ + PDDF Platform-Specific Sfp class + """ + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PddfSfp.__init__(self, index, pddf_data, pddf_plugin_data) + self.eeprom_lock = Lock() + + # Provide the functions/variables below for which implementation is to be overwritten + # Add reties to work around FPGAPCI 0050/eeprom: offset 0x0: sometimes read failed + def __read_eeprom(self, offset, num_bytes): + """ + read eeprom specfic bytes beginning from a random offset with size as num_bytes + + Args: + offset : + Integer, the offset from which the read transaction will start + num_bytes: + Integer, the number of bytes to be read + + Returns: + bytearray, if raw sequence of bytes are read correctly from the offset of size num_bytes + None, if the read_eeprom fails + """ + buf = None + eeprom_raw = [] + sysfs_sfp_i2c_client_eeprom_path = self.eeprom_path + + if not self.get_presence(): + return None + + sysfsfile_eeprom = None + attempts = 0 + max_retries = 5 + success = False + while attempts < max_retries and not success: + try: + if attempts > 0: + time.sleep(0.2) + sysfsfile_eeprom = open(sysfs_sfp_i2c_client_eeprom_path, "rb", 0) + sysfsfile_eeprom.seek(offset) + buf = sysfsfile_eeprom.read(num_bytes) + success = True + except Exception as ex: + attempts += 1 + # Eliminate the redundant errors by showing errors only for lower page and page 0 + if attempts == max_retries: + if offset < 256: + syslog.syslog(syslog.LOG_INFO, "port {0}: {1}: offset {2}: read reach retry limit, refer to last eeprom cache".format(self.port_index, sysfs_sfp_i2c_client_eeprom_path, hex(offset))) + return None + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + + if buf is None: + return None + + for x in buf: + eeprom_raw.append(x) + + while len(eeprom_raw) < num_bytes: + eeprom_raw.append(0) + return bytes(eeprom_raw) + + # Read out any bytes from any offset + def read_eeprom(self, offset, num_bytes): + """ + read eeprom specfic bytes beginning from a random offset with size as num_bytes + + Args: + offset : + Integer, the offset from which the read transaction will start + num_bytes: + Integer, the number of bytes to be read + + Returns: + bytearray, if raw sequence of bytes are read correctly from the offset of size num_bytes + None, if the read_eeprom fails + """ + self.eeprom_lock.acquire() + bytes = self.__read_eeprom(offset, num_bytes) + self.eeprom_lock.release() + return bytes diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal.py new file mode 100644 index 000000000000..911d2f7dd4b5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal.py @@ -0,0 +1,98 @@ +try: + from sonic_platform_pddf_base.pddf_thermal import PddfThermal + from sonic_platform_base.thermal_base import ThermalBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +SENSORS_LOW_THRESHOLD_MAP = {"Base_Temp_U5": -5, "Base_Temp_U56": -5, + "Switch_Temp_U28": -5, "Switch_Temp_U29": -5} + +class Thermal(PddfThermal): + """PDDF Platform-Specific Thermal class""" + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) + + # Provide the functions/variables below for which implementation is to be overwritten + + def get_high_threshold(self): + if self.is_psu_thermal: + device = "PSU{}".format(self.thermals_psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_temp1_high_threshold") + if not output: + return None + + temp1 = output['status'] + # temperature returned is in milli celcius + return float(temp1)/1000 + else: + return super().get_high_threshold() + + def get_low_threshold(self): + low_threshold = SENSORS_LOW_THRESHOLD_MAP.get(self.get_name(), None) + if low_threshold != None: + return low_threshold + return super().get_low_threshold() + + +BCM_TEMP_GET_CMD = "cat /sys/devices/platform/fpga_sysfs/bcm_temp" +THERMAL_MONITOR_SENSORS = ["CPU_Temp", "BCM_SW_Temp", "VDD_CORE_Temp", "VDD_ANLG_Temp"] +THERMAL_THRESHOLDS = { "CPU_Temp": { "high_threshold": 89, "low_threshold": 'N/A', "high_crit_threshold": 93, + "temp_cmd": "r=$(cat /sys/class/thermal/thermal_zone1/temp) && printf '%.1f' $(($r / 1000))" }, + "BCM_SW_Temp": { "high_threshold": 110, "low_threshold": 'N/A', "high_crit_threshold": 120, + "temp_cmd": "r=$(cat /sys/devices/platform/fpga_sysfs/bcm_temp) && printf '%.1f' $(((434100 - ((12500000 / $r - 1) * 535) + 5000) / 1000))"}, + "VDD_CORE_Temp": { "high_threshold": 120, "low_threshold": 'N/A', "high_crit_threshold": 'N/A', + "temp_cmd": "r=$(cat /sys/class/hwmon/hwmon45/temp1_input) && printf '%.1f' $(($r / 1000))" }, + "VDD_ANLG_Temp": { "high_threshold": 120, "low_threshold": 'N/A', "high_crit_threshold": 'N/A', + "temp_cmd": "r=$(cat /sys/class/hwmon/hwmon44/temp1_input) && printf '%.1f' $(($r / 1000))" }} + +class ThermalMon(ThermalBase): + def __init__(self, index, name): + self.thermal_index = index + 1 + self.thermal_name = name + self._helper = APIHelper() + + def get_name(self): + return self.thermal_name + + def get_presence(self): + return True + + def get_temperature(self): + if self.get_name() == "BCM_SW_Temp": + status, data = self._helper.get_cmd_output(BCM_TEMP_GET_CMD) + if status != 0: + return 'N/A' + if data.strip() == "0x0000": + return 0.0 + thermal_data = THERMAL_THRESHOLDS.get(self.thermal_name, None) + if thermal_data == None: + return 'N/A' + temp_cmd = thermal_data.get("temp_cmd") + status, data = self._helper.get_cmd_output(temp_cmd) + if status != 0: + return 'N/A' + return float(data) + + def get_high_threshold(self): + thermal_data = THERMAL_THRESHOLDS.get(self.thermal_name, None) + if thermal_data == None: + return 'N/A' + threshold = thermal_data.get("high_threshold", 'N/A') + return float(threshold) if threshold != 'N/A' else 'N/A' + + def get_low_threshold(self): + thermal_data = THERMAL_THRESHOLDS.get(self.thermal_name, None) + if thermal_data == None: + return 'N/A' + threshold = thermal_data.get("low_threshold", 'N/A') + return float(threshold) if threshold != 'N/A' else 'N/A' + + def get_high_critical_threshold(self): + thermal_data = THERMAL_THRESHOLDS.get(self.thermal_name, None) + if thermal_data == None: + return 'N/A' + threshold = thermal_data.get("high_crit_threshold", 'N/A') + return float(threshold) if threshold != 'N/A' else 'N/A' diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_actions.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_actions.py new file mode 100644 index 000000000000..8be043d94310 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_actions.py @@ -0,0 +1,341 @@ +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 .helper import APIHelper + +from sonic_py_common import logger + +sonic_logger = logger.Logger('thermal_actions') + + +class SetFanSpeedAction(ThermalPolicyActionBase): + """ + Base thermal action class to set speed for fans + """ + # JSON field definition + JSON_FIELD_SPEED = 'speed' + + def __init__(self): + """ + Constructor of SetFanSpeedAction + """ + self.default_speed = 50 + self.hightemp_speed = 100 + self.speed = self.default_speed + + def load_from_json(self, json_obj): + """ + Construct SetFanSpeedAction via JSON. JSON example: + { + "type": "fan.all.set_speed" + "speed": "100" + } + :param json_obj: A JSON object representing a SetFanSpeedAction action. + :return: + """ + if SetFanSpeedAction.JSON_FIELD_SPEED in json_obj: + speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + if speed < 0 or speed > 100: + raise ValueError('SetFanSpeedAction invalid speed value {} in JSON policy file, valid value should be [0, 100]'. + format(speed)) + self.speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_SPEED)) + + @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_all_fans(): + fan.set_speed(int(speed)) + + +@thermal_json_object('fan.all.set_speed') +class SetAllFanSpeedAction(SetFanSpeedAction): + """ + Action to set speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + SetAllFanSpeedAction.set_all_fan_speed(thermal_info_dict, self.speed) + + +class LinearFanController(): + """ + Common Linear FAN Controller for B2F and F2B + """ + def __init__(self, low_temp, high_temp, hyst_temp, low_pwm, high_pwm): + self._low_temp = low_temp + self._high_temp = high_temp + self._hyst_temp = hyst_temp + self._low_pwm = low_pwm + self._high_pwm = high_pwm + self._linear_slope = (high_pwm - low_pwm) / (high_temp - low_temp) + self._last_pwm = None + + def calc_fan_speed(self, thermal_data): + temp = thermal_data.curr_temp + descend = thermal_data.temp_descend + + low_temp = self._low_temp - self._hyst_temp if descend else self._low_temp + high_temp = self._high_temp - self._hyst_temp if descend else self._high_temp + if temp <= low_temp: + sonic_logger.log_debug("[LinearController] temp: {} equal or lower than low temp: {}, set to lowest pwm: {}".format(temp, low_temp, self._low_pwm)) + self._last_pwm = self._low_pwm + return self._low_pwm + elif temp >= high_temp: + sonic_logger.log_debug("[LinearController] temp: {} equal or higher than high temp: {}, set to highest pwm: {}".format(temp, high_temp, self._high_pwm)) + self._last_pwm = self._high_pwm + return self._high_pwm + else: + pwm = float(self._linear_slope * (temp - low_temp) + self._low_pwm) + if descend: + if self._last_pwm != None and pwm > self._last_pwm: + pwm = self._last_pwm + else: + if self._last_pwm != None and pwm < self._last_pwm: + pwm = self._last_pwm + self._last_pwm = pwm + sonic_logger.log_debug("[LinearController] temp: {}, slope: {}, low_temp: {}, low_pwm: {}, set to pwm: {}".format(temp, self._linear_slope, low_temp, self._low_pwm, pwm)) + return pwm + +class PIDFanController(): + """ + Common FAN PID controller for CPU and BCM Temp + """ + MAX_SPEED = 255 + MIN_SPEED = 89 + def __init__(self, setpoint, p_val, i_val, d_val): + self._setpoint = setpoint + self._p = p_val + self._i = i_val + self._d = d_val + self._curr_speed = self.MIN_SPEED + + def calc_fan_speed(self, thermal_data): + hist2_temp = thermal_data.hist2_temp + hist1_temp = thermal_data.hist1_temp + temp = thermal_data.curr_temp + + if hist2_temp == None or hist1_temp == None: + return round(self._curr_speed / 2.55) + speed = self._curr_speed + self._p * (temp - hist1_temp) \ + + self._i * (temp - self._setpoint) + self._d * (temp - 2 * hist1_temp + hist2_temp) + if speed > self.MAX_SPEED: + speed = self.MAX_SPEED + elif speed < self.MIN_SPEED: + speed = self.MIN_SPEED + self._curr_speed = speed + speed_percent = float(speed / 2.55) + sonic_logger.log_debug("[PIDController] setpoint: {} p: {} i: {} d: {}, temp: {} hist_temp1: {} hist_temp2: {}, pwm: {}, percent: {}".format(self._setpoint, self._p, self._i, self._d, temp, hist1_temp, hist2_temp, speed, speed_percent)) + return speed_percent + + +@thermal_json_object('thermal.temp_check_and_fsc_algo_control') +class ThermalAlgorithmAction(SetFanSpeedAction): + """ + Action to check thermal sensor temperature change status and set speed for all fans + """ + THERMAL_LOG_LEVEL = "thermal_log_level" + CPU_PID_PARAMS = "cpu_pid_params" + BCM_PID_PARAMS = "bcm_pid_params" + F2B_LINEAR_PARAMS = "f2b_linear_params" + B2F_LINEAR_PARAMS = "b2f_linear_params" + + def __init__(self): + SetFanSpeedAction.__init__(self) + self.sys_airflow = None + self.cpu_pid_params = None + self.bcm_pid_params = None + self.f2b_linear_params = None + self.b2f_linear_params = None + self.cpu_fan_controller = None + self.bcm_fan_controller = None + self.linear_fan_controller = None + + def load_from_json(self, json_obj): + """ + Construct ThermalAlgorithmAction via JSON. JSON example: + { + "type": "thermal.temp_check_and_fsc_algo_control", + "cpu_pid_params": [82, 3, 0.5, 0.2], + "bcm_pid_params": [88, 4, 0.3, 0.4], + "f2b_linear_params": [34, 54, 3, 35, 100], + "b2f_linear_params": [28, 48, 3, 35, 100] + } + :param json_obj: A JSON object representing a ThermalAlgorithmAction action. + :return: + """ + if self.THERMAL_LOG_LEVEL in json_obj: + thermal_log_level = json_obj[self.THERMAL_LOG_LEVEL] + if not isinstance(thermal_log_level, int) or thermal_log_level not in range(0,8): + raise ValueError('ThermalAlgorithmAction invalid thermal log level, a interger in range 0-7 is required') + sonic_logger.set_min_log_priority(thermal_log_level) + if self.CPU_PID_PARAMS in json_obj: + cpu_pid_params = json_obj[self.CPU_PID_PARAMS] + if not isinstance(cpu_pid_params, list) or len(cpu_pid_params) != 4: + raise ValueError('ThermalAlgorithmAction invalid SetPoint PID {} in JSON policy file, valid value should be [point, p, i, d]'. + format(cpu_pid_params)) + self.cpu_pid_params = cpu_pid_params + else: + raise ValueError('ThermalAlgorithmAction missing mandatory field [setpoint, p, i, d] in JSON policy file') + + if self.BCM_PID_PARAMS in json_obj: + bcm_pid_params = json_obj[self.BCM_PID_PARAMS] + if not isinstance(bcm_pid_params, list) or len(bcm_pid_params) != 4: + raise ValueError('ThermalAlgorithmAction invalid SetPoint PID {} in JSON policy file, valid value should be [point, p, i, d]'. + format(bcm_pid_params)) + self.bcm_pid_params = bcm_pid_params + else: + raise ValueError('ThermalAlgorithmAction missing mandatory field [setpoint, p, i, d] in JSON policy file') + + if self.F2B_LINEAR_PARAMS in json_obj: + f2b_linear_params = json_obj[self.F2B_LINEAR_PARAMS] + if not isinstance(f2b_linear_params, list) or len(f2b_linear_params) != 5: + raise ValueError('ThermalAlgorithmAction invalid SetPoint PID {} in JSON policy file, valid value should be [point, p, i, d]'. + format(f2b_linear_params)) + self.f2b_linear_params = f2b_linear_params + else: + raise ValueError('ThermalAlgorithmAction missing mandatory field [low_temp, high_temp, hyst_temp, low_pwm, high_pwm] in JSON policy file') + + if self.B2F_LINEAR_PARAMS in json_obj: + b2f_linear_params = json_obj[self.B2F_LINEAR_PARAMS] + if not isinstance(b2f_linear_params, list) or len(b2f_linear_params) != 5: + raise ValueError('ThermalAlgorithmAction invalid SetPoint PID {} in JSON policy file, valid value should be [point, p, i, d]'. + format(b2f_linear_params)) + self.b2f_linear_params = b2f_linear_params + else: + raise ValueError('ThermalAlgorithmAction missing mandatory field [low_temp, high_temp, hyst_temp, low_pwm, high_pwm] in JSON policy file') + + sonic_logger.log_info("[ThermalAlgorithmAction] cpu_pid: {}, bcm_pid: {}, f2b_linear: {}, b2f_linear: {}".format(self.cpu_pid_params, self.bcm_pid_params, self.f2b_linear_params, self.b2f_linear_params)) + + 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: + """ + if self.sys_airflow == None: + from .thermal_infos import ChassisInfo + if ChassisInfo.INFO_NAME in thermal_info_dict: + chassis_info_obj = thermal_info_dict[ChassisInfo.INFO_NAME] + chassis = chassis_info_obj.get_chassis() + self.sys_airflow = chassis.get_system_airflow() + + if self.cpu_fan_controller == None: + self.cpu_fan_controller = PIDFanController(self.cpu_pid_params[0], self.cpu_pid_params[1], + self.cpu_pid_params[2], self.cpu_pid_params[3]) + if self.bcm_fan_controller == None: + self.bcm_fan_controller = PIDFanController(self.bcm_pid_params[0], self.bcm_pid_params[1], + self.bcm_pid_params[2], self.bcm_pid_params[3]) + if self.linear_fan_controller == None: + if self.sys_airflow == 'INTAKE': + linear_params = self.b2f_linear_params + else: + linear_params = self.f2b_linear_params + self.linear_fan_controller = LinearFanController(linear_params[0], linear_params[1], linear_params[2], \ + linear_params[3], linear_params[4]) + + 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] + thermals_data = thermal_info_obj.get_thermals_data() + cpu_thermal_data = thermals_data["CPU_Temp"] + cpu_fan_pwm = self.cpu_fan_controller.calc_fan_speed(cpu_thermal_data) + bcm_thermal_data = thermals_data["BCM_SW_Temp"] + bcm_fan_pwm = self.bcm_fan_controller.calc_fan_speed(bcm_thermal_data) + if self.sys_airflow == 'INTAKE': + thermal_data = thermals_data["Base_Temp_U5"] + linear_fan_pwm1 = self.linear_fan_controller.calc_fan_speed(thermal_data) + thermal_data = thermals_data["Base_Temp_U56"] + linear_fan_pwm2 = self.linear_fan_controller.calc_fan_speed(thermal_data) + else: + thermal_data = thermals_data["Switch_Temp_U28"] + linear_fan_pwm1 = self.linear_fan_controller.calc_fan_speed(thermal_data) + thermal_data = thermals_data["Switch_Temp_U29"] + linear_fan_pwm2 = self.linear_fan_controller.calc_fan_speed(thermal_data) + target_fan_pwm = max(cpu_fan_pwm, bcm_fan_pwm, linear_fan_pwm1, linear_fan_pwm2) + sonic_logger.log_info("[ThermalAlgorithmAction] cpu_pid_pwm: {}, bcm_pid_pwm: {}, linear_fan_pwm: {}, linear_fan_pwm2: {}, target_pwm: {}".format(cpu_fan_pwm, bcm_fan_pwm, linear_fan_pwm1, linear_fan_pwm2, target_fan_pwm)) + SetAllFanSpeedAction.set_all_fan_speed(thermal_info_dict, round(target_fan_pwm)) + + +@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: + """ + sonic_logger.log_warning("Alarm for temperature critical is detected, shutdown Device") + # Wait for 30s then shutdown + import time + time.sleep(30) + # Power off COMe through CPLD + CPLD_POWRE_OFF_CMD = "echo 0xa120 0xfc > /sys/bus/platform/devices/baseboard/setreg" + api_helper = APIHelper() + api_helper.get_cmd_output(CPLD_POWER_OFF_CMD) + + +@thermal_json_object('thermal_control.control') +class ControlThermalAlgoAction(ThermalPolicyActionBase): + """ + Action to control the thermal control algorithm + """ + # JSON field definition + JSON_FIELD_STATUS = 'status' + + def __init__(self): + self.status = True + + def load_from_json(self, json_obj): + """ + Construct ControlThermalAlgoAction via JSON. JSON example: + { + "type": "thermal_control.control" + "status": "true" + } + :param json_obj: A JSON object representing a ControlThermalAlgoAction action. + :return: + """ + if ControlThermalAlgoAction.JSON_FIELD_STATUS in json_obj: + status_str = json_obj[ControlThermalAlgoAction.JSON_FIELD_STATUS].lower() + if status_str == 'true': + self.status = True + elif status_str == 'false': + self.status = False + else: + raise ValueError('Invalid {} field value, please specify true of false'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + else: + raise ValueError('ControlThermalAlgoAction ' + 'missing mandatory field {} in JSON policy file'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + + def execute(self, thermal_info_dict): + """ + Disable thermal control algorithm + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal_infos import ChassisInfo + if ChassisInfo.INFO_NAME in thermal_info_dict: + chassis_info_obj = thermal_info_dict[ChassisInfo.INFO_NAME] + chassis = chassis_info_obj.get_chassis() + thermal_manager = chassis.get_thermal_manager() + if self.status: + thermal_manager.start_thermal_control_algorithm() + else: + thermal_manager.stop_thermal_control_algorithm() diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_conditions.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_conditions.py new file mode 100644 index 000000000000..c8bb51ef966c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_conditions.py @@ -0,0 +1,121 @@ +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 + + +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('fantray.any.absence') +class AnyFantrayAbsenceCondition(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_fantrays()) > 0 if fan_info_obj else False + +@thermal_json_object('fantray.all.absence') +class AllFantrayAbsenceCondition(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_fantrays()) == 0 if fan_info_obj else False + +@thermal_json_object('fantray.all.presence') +class AllFantrayPresenceCondition(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_fantrays()) == 0 if fan_info_obj else True + +@thermal_json_object('fan.rotor.more_than_one.failed') +class FanRotorMoreThanOneFailedCondition(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()) > 1 if fan_info_obj else False + +@thermal_json_object('fan.rotor.less_than_two.failed') +class FanRotorLessThanTwoFailedCondition(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()) < 2 if fan_info_obj else True + +class PsuCondition(ThermalPolicyConditionBase): + def get_psu_info(self, thermal_info_dict): + from .thermal_infos import PsuInfo + if PsuInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[PsuInfo.INFO_NAME], PsuInfo): + return thermal_info_dict[PsuInfo.INFO_NAME] + else: + return None + +@thermal_json_object('psu.any.absence') +class AnyPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) > 0 if psu_info_obj else False + +@thermal_json_object('psu.all.absence') +class AllPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_presence_psus()) == 0 if psu_info_obj else False + +@thermal_json_object('psu.all.presence') +class AllPsuPresenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) == 0 if psu_info_obj else True + + +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) + if thermal_info_obj: + return thermal_info_obj.is_any_over_high_critical_threshold() + else: + return False + +@thermal_json_object('thermal.any.over.high_threshold') +class AnyThermalOverHighThresholdCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return thermal_info_obj.is_any_warm_up_and_over_high_threshold() + else: + return False + +@thermal_json_object('thermal.any.below.low_threshold') +class AnyThermalBelowLowThresholdCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return thermal_info_obj.is_any_cool_down_and_below_low_threshold() + else: + return False + +@thermal_json_object('thermal.all.below.high_threshold') +class AnyThermalOverHighThresholdCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return not thermal_info_obj.is_any_warm_up_and_over_high_threshold() + else: + return True + +@thermal_json_object('thermal.all.over.low_threshold') +class AnyThermalBelowLowThresholdCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return not thermal_info_obj.is_any_cool_down_and_below_low_threshold() + else: + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_infos.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_infos.py new file mode 100644 index 000000000000..4925637f8cb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_infos.py @@ -0,0 +1,362 @@ +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 +from sonic_py_common import logger + +sonic_logger = logger.Logger('thermal_infos') + +@thermal_json_object('fan_info') +class FanInfo(ThermalPolicyInfoBase): + """ + Fan information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'fan_info' + FAN_LOW_WARNING_SPEED = 1370 + FAN_FRONT_HIGH_WARNING_SPEED = 29125 + FAN_REAR_HIGH_WARNING_SPEED = 25375 + + def __init__(self): + self._all_fans = set() + self._absence_fans = set() + self._presence_fans = set() + self._absence_fantrays = set() + self._presence_fantrays = set() + self._low_warning_fans = set() + self._high_warning_fans = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence fans. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + try: + for fantray in chassis.get_all_fan_drawers(): + if fantray.get_presence() and fantray not in self._presence_fantrays: + self._presence_fantrays.add(fantray) + self._status_changed = True + if fantray in self._absence_fantrays: + self._absence_fantrays.remove(fantray) + elif not fantray.get_presence() and fantray not in self._absence_fantrays: + self._absence_fantrays.add(fantray) + self._status_changed = True + if fantray in self._presence_fantrays: + self._presence_fantrays.remove(fantray) + + for fan in fantray.get_all_fans(): + if fan.get_presence() and fantray not in self._presence_fans: + self._presence_fans.add(fan) + self._status_changed = True + if fan in self._absence_fans: + self._absence_fans.remove(fan) + elif not fan.get_presence() and fan not in self._absence_fans: + self._absence_fans.add(fan) + self._status_changed = True + if fan in self._presence_fans: + self._presence_fans.remove(fan) + + fan_name = fan.get_name() + fan_rpm = fan.get_speed_rpm() + if fan not in self._all_fans: + self._all_fans.add(fan) + # FAN Low speed warning + if fan_rpm < self.FAN_LOW_WARNING_SPEED and fan not in self._low_warning_fans: + self._low_warning_fans.add(fan) + sonic_logger.log_warning("FAN {} speed {}, low speed warning".format(fan_name, fan_rpm)) + elif fan_rpm > self.FAN_LOW_WARNING_SPEED and fan in self._low_warning_fans: + sonic_logger.log_notice("FAN {}, restore from low speed warning".format(fan_name)) + self._low_warning_fans.remove(fan) + # FAN high speed warning + if fan.fan_index == 1: + if fan_rpm > self.FAN_FRONT_HIGH_WARNING_SPEED and fan not in self._high_warning_fans: + self._high_warning_fans.add(fan) + sonic_logger.log_warning("FAN {} speed {}, high speed warning".format(fan_name, fan_rpm)) + elif fan_rpm > self.FAN_FRONT_HIGH_WARNING_SPEED and fan in self._high_warning_fans: + self._high_warning_fans.remove(fan) + sonic_logger.log_notice("FAN {}, restore from high speed warning".format(fan_name)) + else: + if fan_rpm > self.FAN_REAR_HIGH_WARNING_SPEED and fan not in self._high_warning_fans: + self._high_warning_fans.add(fan) + sonic_logger.log_warning("FAN {} speed {}, high speed warning".format(fan_name, fan_rpm)) + elif fan_rpm > self.FAN_REAR_HIGH_WARNING_SPEED and fan in self._high_warning_fans: + self._high_warning_fans.remove(fan) + sonic_logger.log_notice("FAN {}, restore from high speed warning".format(fan_name)) + except Exception as e: + sonic_logger.log_warning("Catch exception: {}, File: {}, Line: {}".format(type(e).__name__, __file__, e.__traceback__.tb_lineno)) + + def get_all_fans(self): + """ + Retrieves all fans + :return: A set of fans + """ + return self._all_fans + + def get_absence_fantrays(self): + """ + Retrieves absence fans + :return: A set of absence fantrays + """ + return self._absence_fantrays + + def get_presence_fantrays(self): + """ + Retrieves presence fans + :return: A set of presence fantrays + """ + return self._presence_fantrays + + 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_low_warning_fans(self): + """ + Retrieves low rpm warning fans + :return: A set of low rpm warning fans + """ + return self._low_warning_fans + + def get_high_warning_fans(self): + """ + Retrieves high rpm warning fans + :return: A set of high rpm warning fans + """ + return self._high_warning_fans + + def is_status_changed(self): + """ + Retrieves if the status of fan information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('psu_info') +class PsuInfo(ThermalPolicyInfoBase): + """ + PSU information needed by thermal policy + """ + INFO_NAME = 'psu_info' + PSU_TEMP_HIGH_WARNING_THRESHOLD = 65 + + def __init__(self): + self._absence_psus = set() + self._presence_psus = set() + self._high_warning_psus = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence PSUs. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + try: + for psu in chassis.get_all_psus(): + if psu.get_presence() and psu not in self._presence_psus: + self._presence_psus.add(psu) + self._status_changed = True + if psu in self._absence_psus: + self._absence_psus.remove(psu) + elif (not psu.get_presence()) and psu not in self._absence_psus: + self._absence_psus.add(psu) + self._status_changed = True + if psu in self._presence_psus: + self._presence_psus.remove(psu) + # PSU Temp high warning + psu_name = psu.get_name() + psu_temp = psu.get_temperature() + if psu_temp != None and psu_temp != 'N/A': + if psu_temp > self.PSU_TEMP_HIGH_WARNING_THRESHOLD and psu not in self._high_warning_psus: + self._high_warning_psus.add(psu) + sonic_logger.log_warning("PSU {} temp {}, high temperature warning".format(psu_name, psu_temp)) + elif psu_temp < self.PSU_TEMP_HIGH_WARNING_THRESHOLD and psu in self._high_warning_psus: + self._high_warning_psus.remove(psu) + sonic_logger.log_notice("PSU {} restore from high temperature warning".format(psu_name)) + except Exception as e: + sonic_logger.log_warning("Catch exception: {}, File: {}, Line: {}".format(type(e).__name__, __file__, e.__traceback__.tb_lineno)) + + def get_absence_psus(self): + """ + Retrieves presence PSUs + :return: A set of absence PSUs + """ + return self._absence_psus + + def get_presence_psus(self): + """ + Retrieves presence PSUs + :return: A set of presence fans + """ + return self._presence_psus + + def get_high_warning_psus(self): + """ + Retrieves high temperature warning PSUs + :return: A set of high temp fans + """ + return self._high_warning_psus + + def is_status_changed(self): + """ + Retrieves if the status of PSU information changed + :return: True if status changed else False + """ + return self._status_changed + + +class ThermalData(): + def __init__(self, name): + self.name = name + self.hist2_temp = None + self.hist1_temp = None + self.curr_temp = None + self.temp_descend = False + + def update_temp(self, temp): + self.hist2_temp = self.hist1_temp + self.hist1_temp = self.curr_temp + self.curr_temp = temp + return self + + def update_temp_trend(self): + if self.hist1_temp == None: + self.temp_descend = False + elif self.curr_temp < self.hist1_temp: + self.temp_descend = True + else: + self.temp_descend = False + return self + +@thermal_json_object('thermal_info') +class ThermalInfo(ThermalPolicyInfoBase): + """ + Thermal information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'thermal_info' + THERMAL_SHUTDOWN_TEMP_MAP = {"CPU_Temp": 93, "BCM_SW_Temp": 120} + + def __init__(self): + self.init = False + self._high_warning_thermals = set() + self._low_warning_thermals = set() + self._high_shutdown_thermals = set() + self._thermals_data = {} + + def collect(self, chassis): + """ + Collect thermal sensor temperature change status + :param chassis: The chassis object + :return: + """ + try: + for thermal in chassis.get_all_thermals(): + name = thermal.get_name() + temp = thermal.get_temperature() + if temp == None or temp == 'N/A': + continue + high_threshold = thermal.get_high_threshold() + low_threshold = thermal.get_low_threshold() + thermal_shutdown = self.THERMAL_SHUTDOWN_TEMP_MAP.get(name, None) + + # Collect thermal data + thermal_data = self._thermals_data.get(name, None) + if thermal_data == None: + thermal_data = ThermalData(name) + self._thermals_data[name] = thermal_data + thermal_data.update_temp(temp).update_temp_trend() + + # Handle high threshold condition + if high_threshold != None and high_threshold != 'N/A': + if temp > high_threshold and thermal not in self._high_warning_thermals: + self._high_warning_thermals.add(thermal) + sonic_logger.log_warning("Thermal {} temp {}, high threshold warning".format(name, temp)) + if thermal_shutdown != None and temp > thermal_shutdown: + self._high_shutdown_thermals.add(thermal) + sonic_logger.log_warning("Thermal {} temp {}, high temp shutdown warning".format(name, temp)) + elif temp < (high_threshold - 3) and thermal in self._high_warning_thermals: + self._high_warning_thermals.remove(thermal) + sonic_logger.log_notice("Thermal {}, restore from high threshold warning".format(name)) + if thermal in self._high_shutdown_thermals: + self._high_shutdown_thermals.remove(thermal) + + # Handle low threshold condition + if low_threshold != None and low_threshold != 'N/A': + if temp < low_threshold and thermal not in self._low_warning_thermals: + self._low_warning_thermals.add(thermal) + sonic_logger.log_warning("Thermal {} temp {}, low threshold warning".format(name, temp)) + elif temp > (low_threshold + 3) and thermal in self._low_warning_thermals: + self._low_warning_thermals.remove(thermal) + sonic_logger.log_notice("Thermal {}, restore from low threshold warning".format(name)) + except Exception as e: + sonic_logger.log_warning("Catch exception: {}, File: {}, Line: {}".format(type(e).__name__, __file__, e.__traceback__.tb_lineno)) + + def is_any_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 len(self._high_warning_thermals) > 0 + + def is_any_cool_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 len(self._low_warning_thermals) > 0 + + def is_any_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 len(self._high_shutdown_thermals) > 0 + + def get_thermals_data(self): + """ + Retrieves all the thermal data + :return: thermal data dict using thermal name as key + """ + return self._thermals_data + + +@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-cel/ds3000/pddf/sonic_platform/thermal_manager.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_manager.py new file mode 100644 index 000000000000..fb9557270f05 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/thermal_manager.py @@ -0,0 +1,21 @@ +from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from .thermal_infos import * +from .thermal_conditions import * +from .thermal_actions 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 True + + @classmethod + def deinitialize(cls): + """ + Destroy thermal manager, including any vendor specific cleanup. + :return: + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/watchdog.py new file mode 100644 index 000000000000..90b5ee352c08 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/pddf/sonic_platform/watchdog.py @@ -0,0 +1,14 @@ +try: + from sonic_platform_pddf_base.pddf_watchdog import PddfWatchdog +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + + +class Watchdog(PddfWatchdog): + """PDDF Platform-Specific Watchdog Class""" + + def __init__(self): + PddfWatchdog.__init__(self) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/scripts/pddf_post_device_create.sh b/platform/broadcom/sonic-platform-modules-cel/ds3000/scripts/pddf_post_device_create.sh new file mode 100755 index 000000000000..c2f193d1bc20 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/scripts/pddf_post_device_create.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +declare -r CPLD_SETREG="/sys/bus/platform/devices/baseboard/setreg" +declare -r CPLD_GETREG="/sys/bus/platform/devices/baseboard/getreg" + +# Load fpga extend driver after fpga device created +modprobe pddf_custom_fpga_extend + +# attach ucd90120 devices, bus 107, devices 0x34 and 0x35 +echo "ucd90120 0x34" > /sys/bus/i2c/devices/i2c-107/new_device +echo "ucd90120 0x35" > /sys/bus/i2c/devices/i2c-107/new_device + +# attach mp2975 devices, bus 108, devices 0x70 and 0x7a +echo "mp2975 0x70" > /sys/bus/i2c/devices/i2c-108/new_device +echo "mp2975 0x7a" > /sys/bus/i2c/devices/i2c-108/new_device + +# Set SYS_LED to Green, assuming everything came up fine. +echo "0xa162 0xdc" > ${CPLD_SETREG} + +# Disable CPLD thermal shutdown by default +echo "0xa175 0x0" > ${CPLD_SETREG} diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/scripts/pddf_pre_driver_install.sh b/platform/broadcom/sonic-platform-modules-cel/ds3000/scripts/pddf_pre_driver_install.sh new file mode 100755 index 000000000000..29bc603d447c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/scripts/pddf_pre_driver_install.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# Has customized those drivers,so rename them to lose effect +psu_driver=pddf_psu_driver_module.ko +ker_name=$(uname -r) +driver_path=/usr/lib/modules/${ker_name}/extra/ +if [ -e ${driver_path}${psu_driver} ]; then + mv ${driver_path}${psu_driver} ${driver_path}${psu_driver}-bk +fi + +echo 'pddf psu driver module has rename now' diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/scripts/pre_pddf_init.sh b/platform/broadcom/sonic-platform-modules-cel/ds3000/scripts/pre_pddf_init.sh new file mode 100755 index 000000000000..2556858cdab9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/scripts/pre_pddf_init.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Probe Baseboard CPLD driver +modprobe baseboard_cpld +sleep 1 + +# Get BMC mode +PLATFORM=`sed -n 's/onie_platform=\(.*\)/\1/p' /host/machine.conf` +BMC_PRESENCE_SYS_PATH="/sys/bus/platform/devices/baseboard/bmc_presence" +BMC_PRESENCE=`cat ${BMC_PRESENCE_SYS_PATH}` +echo "Platform ${PLATFORM} BMC card ${BMC_PRESENCE}" + +# Copy pddf-device.json according to bmc mode +PDDF_JSON="pddf-device.json" +PDDF_JSON_BMC="pddf-device-bmc.json" +PDDF_JSON_NONBMC="pddf-device-nonbmc.json" +PDDF_JSON_PATH="/usr/share/sonic/device/${PLATFORM}/pddf" +PLATFORM_COMPONENTS_FILE="/usr/share/sonic/device/${PLATFORM}/platform_components.json" +if [ ${BMC_PRESENCE} == "present" ]; then + cp ${PDDF_JSON_PATH}/${PDDF_JSON_BMC} ${PDDF_JSON_PATH}/${PDDF_JSON} + # Add BMC component if BMC exists + if ! grep -q "BMC" ${PLATFORM_COMPONENTS_FILE}; then + sed -i '6i \ "BMC": {},' ${PLATFORM_COMPONENTS_FILE} + fi +else + # BMC Card absent + cp ${PDDF_JSON_PATH}/${PDDF_JSON_NONBMC} ${PDDF_JSON_PATH}/${PDDF_JSON} + # Remove BMC component for NonBMC + sed -i '/"BMC"/d' ${PLATFORM_COMPONENTS_FILE} +fi diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/systemd/pddf-platform-init.service b/platform/broadcom/sonic-platform-modules-cel/ds3000/systemd/pddf-platform-init.service new file mode 100644 index 000000000000..f4098b34b60e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/systemd/pddf-platform-init.service @@ -0,0 +1,16 @@ +[Unit] +Description=PDDF module and device initialization service +Before=pmon.service watchdog-control.service +Before=opennsl-modules.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStartPre=-/usr/local/bin/pre_pddf_init.sh +ExecStart=/usr/local/bin/pddf_util.py install +ExecStop=/usr/local/bin/pddf_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target +WantedBy=opennsl-modules.service diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/afulnx_64 b/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/afulnx_64 new file mode 100755 index 000000000000..0ba1549c2891 Binary files /dev/null and b/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/afulnx_64 differ diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/fpga_prog b/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/fpga_prog new file mode 100755 index 000000000000..3227da590a0a Binary files /dev/null and b/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/fpga_prog differ diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/ispvm b/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/ispvm new file mode 100755 index 000000000000..f8e216556ebe Binary files /dev/null and b/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/ispvm differ diff --git a/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/pddf_switch_svc.py b/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/pddf_switch_svc.py new file mode 100644 index 000000000000..319178d62a41 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds3000/utils/pddf_switch_svc.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# Script to stop and start the respective platforms default services. +# This will be used while switching the pddf->non-pddf mode and vice versa +import os +import sys +import commands + +def check_pddf_support(): + return True + +def stop_platform_svc(): + status, output = commands.getstatusoutput("systemctl stop xxxx-platform-init.service") + if status: + print "Stop xxxx-platform-init.service failed %d"%status + return False + status, output = commands.getstatusoutput("systemctl disable xxxx-platform-init.service") + if status: + print "Disable xxxx-platform-init.service failed %d"%status + return False + + status, output = commands.getstatusoutput("/usr/local/bin/xxxx_util.py clean") + if status: + print "xxxx_util.py clean command failed %d"%status + return False + + # HACK , stop the pddf-platform-init service if it is active + status, output = commands.getstatusoutput("systemctl stop pddf-platform-init.service") + if status: + print "Stop pddf-platform-init.service along with other platform serives failed %d"%status + return False + + return True + +def start_platform_svc(): + status, output = commands.getstatusoutput("/usr/local/bin/xxxx_util.py install") + if status: + print "xxxx_util.py install command failed %d"%status + return False + + status, output = commands.getstatusoutput("systemctl enable xxxx-platform-init.service") + if status: + print "Enable xxxx-platform-init.service failed %d"%status + return False + status, output = commands.getstatusoutput("systemctl start xxxx-platform-init.service") + if status: + print "Start xxxx-platform-init.service failed %d"%status + return False + + return True + +def start_platform_pddf(): + # Enable PDDF 2.0 object class for xxxx + status, output = commands.getstatusoutput("mkdir /usr/share/sonic/platform/sonic_platform") + if status: + print "Unable to create 2.0 object class folder /usr/share/sonic/platform/sonic_platform" + return False + + status, output = commands.getstatusoutput("systemctl start pddf-platform-init.service") + if status: + print "Start pddf-platform-init.service failed %d"%status + return False + + return True + +def stop_platform_pddf(): + # Disable PDDF 2.0 object class for xxxx + status, output = commands.getstatusoutput("rm -r /usr/share/sonic/platform/sonic_platform") + if status: + print "Unable to delete 2.0 object class folder /usr/share/sonic/platform/sonic_platform" + return False + + status, output = commands.getstatusoutput("systemctl stop pddf-platform-init.service") + if status: + print "Stop pddf-platform-init.service failed %d"%status + return False + + return True + +def main(): + pass + +if __name__ == "__main__": + main()