diff --git a/.gitmodules b/.gitmodules
index e0cfc0869d0..cbe82c215f7 100755
--- a/.gitmodules
+++ b/.gitmodules
@@ -35,30 +35,12 @@
[submodule "src/sonic-utilities"]
path = src/sonic-utilities
url = https://github.com/Azure/sonic-utilities
-[submodule "platform/broadcom/sonic-platform-modules-s6000"]
- path = platform/broadcom/sonic-platform-modules-s6000
- url = https://github.com/Azure/sonic-platform-modules-s6000
-[submodule "platform/broadcom/sonic-platform-modules-arista"]
- path = platform/broadcom/sonic-platform-modules-arista
- url = https://github.com/aristanetworks/sonic
-[submodule "platform/broadcom/sonic-platform-modules-dell"]
- path = platform/broadcom/sonic-platform-modules-dell
- url = https://github.com/Azure/sonic-platform-modules-dell
-[submodule "platform/broadcom/sonic-platform-modules-ingrasys"]
- path = platform/broadcom/sonic-platform-modules-ingrasys
- url = https://github.com/Ingrasys-sonic/sonic-platform-modules-ingrasys
[submodule "src/sonic-platform-common"]
path = src/sonic-platform-common
url = https://github.com/Azure/sonic-platform-common
[submodule "src/sonic-platform-daemons"]
path = src/sonic-platform-daemons
url = https://github.com/Azure/sonic-platform-daemons
-[submodule "platform/broadcom/sonic-platform-modules-accton"]
- path = platform/broadcom/sonic-platform-modules-accton
- url = https://github.com/edge-core/sonic-platform-modules-accton.git
-[submodule "platform/broadcom/sonic-platform-modules-cel"]
- path = platform/broadcom/sonic-platform-modules-cel
- url = https://github.com/celestica-Inc/sonic-platform-modules-cel.git
[submodule "src/sonic-frr/frr"]
path = src/sonic-frr/frr
url = https://github.com/FRRouting/frr.git
@@ -68,12 +50,3 @@
[submodule "platform/p4/SAI-P4-BM"]
path = platform/p4/SAI-P4-BM
url = https://github.com/Mellanox/SAI-P4-BM.git
-[submodule "platform/nephos/sonic-platform-modules-ingrasys"]
- path = platform/nephos/sonic-platform-modules-ingrasys
- url = https://github.com/Ingrasys-sonic/sonic-platform-modules-ingrasys-nephos.git
-[submodule "platform/broadcom/sonic-platform-modules-quanta"]
- path = platform/broadcom/sonic-platform-modules-quanta
- url = https://github.com/QuantaSwitchONIE/sonic-platform-modules-quanta.git
-[submodule "platform/broadcom/sonic-platform-modules-mitac"]
- path = platform/broadcom/sonic-platform-modules-mitac
- url = https://github.com/MiTAC-EBU/sonic-platform-modules-mitac.git
diff --git a/build_debian.sh b/build_debian.sh
index 2b2294194d7..297fc1da19d 100755
--- a/build_debian.sh
+++ b/build_debian.sh
@@ -114,7 +114,7 @@ echo '[INFO] Install SONiC linux kernel image'
## Note: duplicate apt-get command to ensure every line return zero
sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/initramfs-tools_*.deb || \
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f
-sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/linux-image-3.16.0-5-amd64_*.deb || \
+sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/linux-image-3.16.0-6-amd64_*.deb || \
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f
## Update initramfs for booting with squashfs+aufs
@@ -152,10 +152,10 @@ sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/union-fsck
sudo chroot $FILESYSTEM_ROOT update-initramfs -u
## Install latest intel igb driver
-sudo cp target/debs/igb.ko $FILESYSTEM_ROOT/lib/modules/3.16.0-5-amd64/kernel/drivers/net/ethernet/intel/igb/igb.ko
+sudo cp target/debs/igb.ko $FILESYSTEM_ROOT/lib/modules/3.16.0-6-amd64/kernel/drivers/net/ethernet/intel/igb/igb.ko
## Install latest intel ixgbe driver
-sudo cp target/debs/ixgbe.ko $FILESYSTEM_ROOT/lib/modules/3.16.0-5-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko
+sudo cp target/debs/ixgbe.ko $FILESYSTEM_ROOT/lib/modules/3.16.0-6-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko
## Install docker
echo '[INFO] Install docker'
@@ -204,7 +204,6 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
openssh-server \
python \
python-setuptools \
- rsyslog \
monit \
python-apt \
traceroute \
@@ -227,6 +226,10 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
grub2-common \
ethtool
+# Install a newer version of rsyslog from jessie-backports in hopes of
+# eliminating memory leaks
+sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y -t jessie-backports install rsyslog
+
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \
grub-pc-bin
@@ -269,6 +272,7 @@ check system $HOST
EOF
## Config sysctl
+## TODO: ipfrag* are for mitigating CVE-2018-5391, remove after kernel upgraded
sudo mkdir -p $FILESYSTEM_ROOT/var/core
sudo augtool --autosave "
set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/bin/coredump-compress %e %t %p'
@@ -300,11 +304,15 @@ set /files/etc/sysctl.conf/net.ipv6.conf.eth0.forwarding 0
set /files/etc/sysctl.conf/net.ipv6.conf.default.accept_dad 0
set /files/etc/sysctl.conf/net.ipv6.conf.all.accept_dad 0
+set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_dad 0
set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra_defrtr 0
set /files/etc/sysctl.conf/net.core.rmem_max 2097152
set /files/etc/sysctl.conf/net.core.wmem_max 2097152
+
+set /files/etc/sysctl.conf/net.ipv4.ipfrag_high_thresh 262144
+set /files/etc/sysctl.conf/net.ipv4.ipfrag_low_thresh 196608
" -r $FILESYSTEM_ROOT
## docker-py is needed by Ansible docker module
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2
new file mode 100644
index 00000000000..2c391214fa6
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2
@@ -0,0 +1,111 @@
+{# Default values which will be used if no actual configura available #}
+{% set default_cable = '40m' %}
+{% set default_speed = '10G' %}
+{% set default_ports_num = 54 -%}
+
+{# Port configuration to cable length look-up table #}
+{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
+{# Roles described in the minigraph #}
+{% set ports2cable = {
+ 'torrouter_server' : '5m',
+ 'leafrouter_torrouter' : '40m',
+ 'spinerouter_leafrouter' : '300m'
+ }
+%}
+
+{%- macro cable_length(port_name) -%}
+ {%- set cable_len = [] -%}
+ {%- for local_port in DEVICE_NEIGHBOR -%}
+ {%- if local_port == port_name -%}
+ {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor_role = neighbor.type -%}
+ {%- set roles1 = switch_role + '_' + neighbor_role %}
+ {%- set roles2 = neighbor_role + '_' + switch_role -%}
+ {%- set roles1 = roles1 | lower -%}
+ {%- set roles2 = roles2 | lower -%}
+ {%- if roles1 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%}
+ {%- elif roles2 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endfor -%}
+ {%- if cable_len -%}
+ {{ cable_len.0 }}
+ {%- else -%}
+ {{ default_cable }}
+ {%- endif -%}
+{% endmacro %}
+
+{%- if DEVICE_METADATA is defined %}
+{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
+{%- endif -%}
+
+{# Generate list of ports if not defined #}
+{% if PORT is not defined %}
+ {% set PORT = [] %}
+ {% for port_idx in range(0,default_ports_num) %}
+ {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
+ {% endfor %}
+{% endif -%}
+
+{% set port_names_list = [] %}
+{% for port in PORT %}
+ {%- if port_names_list.append(port) %}{% endif %}
+{% endfor %}
+{% set port_names = port_names_list | join(',') -%}
+
+{
+ "CABLE_LENGTH": {
+ "AZURE": {
+ {% for port in PORT %}
+ {% set cable = cable_length(port) -%}
+ "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %}
+
+ {% endfor %}
+ }
+ },
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "20971328",
+ "type": "ingress",
+ "mode": "static"
+ },
+ "ingress_lossy_pool": {
+ "size": "20971328",
+ "type": "ingress",
+ "mode": "static"
+ },
+ "egress_lossy_pool": {
+ "size": "20971328",
+ "type": "egress",
+ "mode": "static"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "xon":"78400",
+ "xoff":"132160",
+ "size":"3584",
+ "static_th":"82880"
+ },
+ "ingress_lossy_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossy_pool]",
+ "size":"3584",
+ "dynamic_th":"-1"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"3584",
+ "dynamic_th":"-4"
+ }
+ },
+ "BUFFER_PG": {
+ },
+ "BUFFER_QUEUE": {
+ }
+}
+
\ No newline at end of file
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini
new file mode 100644
index 00000000000..d98b0eca6d1
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold
+ 10000 5m 3584 32256 59136 36736
+ 25000 5m 3584 41216 68096 45696
+ 40000 5m 3584 47488 74368 51968
+ 50000 5m 3584 52864 79744 57344
+ 100000 5m 3584 78400 132160 82880
+ 10000 40m 3584 32256 59136 36736
+ 25000 40m 3584 41216 68096 45696
+ 40000 40m 3584 47488 74368 51968
+ 50000 40m 3584 52864 79744 57344
+ 100000 40m 3584 78400 132160 82880
+ 10000 300m 3584 32256 65856 36736
+ 25000 300m 3584 41216 84672 45696
+ 40000 300m 3584 47488 101024 51968
+ 50000 300m 3584 52864 113120 57344
+ 100000 300m 3584 78400 198688 82880
\ No newline at end of file
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini
new file mode 100644
index 00000000000..52c59bc9d29
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini
@@ -0,0 +1,55 @@
+# name lanes alias index
+Ethernet0 8 Ethernet1/1 0
+Ethernet1 9 Ethernet2/1 1
+Ethernet2 10 Ethernet3/1 2
+Ethernet3 11 Ethernet4/1 3
+Ethernet4 12 Ethernet5/1 4
+Ethernet5 13 Ethernet6/1 5
+Ethernet6 14 Ethernet7/1 6
+Ethernet7 15 Ethernet8/1 7
+Ethernet8 16 Ethernet9/1 8
+Ethernet9 17 Ethernet10/1 9
+Ethernet10 18 Ethernet11/1 10
+Ethernet11 19 Ethernet12/1 11
+Ethernet12 20 Ethernet13/1 12
+Ethernet13 21 Ethernet14/1 13
+Ethernet14 22 Ethernet15/1 14
+Ethernet15 23 Ethernet16/1 15
+Ethernet16 32 Ethernet17/1 16
+Ethernet17 33 Ethernet18/1 17
+Ethernet18 34 Ethernet19/1 18
+Ethernet19 35 Ethernet20/1 19
+Ethernet20 40 Ethernet21/1 20
+Ethernet21 41 Ethernet22/1 21
+Ethernet22 42 Ethernet23/1 22
+Ethernet23 43 Ethernet24/1 23
+Ethernet24 48 Ethernet25/1 24
+Ethernet25 49 Ethernet26/1 25
+Ethernet26 50 Ethernet27/1 26
+Ethernet27 51 Ethernet28/1 27
+Ethernet28 56 Ethernet29/1 28
+Ethernet29 57 Ethernet30/1 29
+Ethernet30 58 Ethernet31/1 30
+Ethernet31 59 Ethernet32/1 31
+Ethernet32 64 Ethernet33/1 32
+Ethernet33 65 Ethernet34/1 33
+Ethernet34 66 Ethernet35/1 34
+Ethernet35 67 Ethernet36/1 35
+Ethernet36 68 Ethernet37/1 36
+Ethernet37 69 Ethernet38/1 37
+Ethernet38 70 Ethernet39/1 38
+Ethernet39 71 Ethernet40/1 39
+Ethernet40 72 Ethernet41/1 40
+Ethernet41 73 Ethernet42/1 41
+Ethernet42 74 Ethernet43/1 42
+Ethernet43 75 Ethernet44/1 43
+Ethernet44 76 Ethernet45/1 44
+Ethernet45 77 Ethernet46/1 45
+Ethernet46 78 Ethernet47/1 46
+Ethernet47 79 Ethernet48/1 47
+Ethernet48 84,85,86,87 Ethernet49/1 48
+Ethernet49 80,81,82,83 Ethernet50/1 49
+Ethernet50 104,105,106,107 Ethernet51/1 50
+Ethernet51 108,109,110,111 Ethernet52/1 51
+Ethernet52 112,113,114,115 Ethernet53/1 52
+Ethernet53 116,117,118,119 Ethernet54/1 53
\ No newline at end of file
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps
new file mode 100644
index 00000000000..34e5a2daab8
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps
@@ -0,0 +1,358 @@
+init start stage unit=0 low-level
+init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true
+init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true
+init start stage unit=0 task-rsrc
+init start stage unit=0 module
+init start stage unit=0 task
+phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=3 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=4 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=5 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=6 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=7 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=8 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=9 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=10 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=11 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=12 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=13 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=14 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=15 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=16 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=17 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=18 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=19 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=20 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=21 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=22 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=23 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=24 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=25 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=26 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=27 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=28 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=29 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=30 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=31 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=32 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=33 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=34 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=35 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=36 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=37 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=38 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=39 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=40 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=41 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=42 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=43 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2
+phy set lane-swap portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2
+phy set lane-swap portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2
+phy set lane-swap portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1
+phy set lane-swap portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0
+phy set lane-swap portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0
+phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=3 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=4 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=5 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=6 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=7 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=8 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=9 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=10 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=11 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=12 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=13 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=14 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=15 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=16 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=17 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=18 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=19 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=20 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=21 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=22 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=23 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=24 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=25 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=26 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=27 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=28 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=29 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=30 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=31 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=32 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=33 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=34 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=35 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=36 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=37 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=38 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=39 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=40 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=41 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=42 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=43 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3
+phy set lane-swap portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2
+phy set lane-swap portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2
+phy set lane-swap portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2
+phy set lane-swap portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0
+phy set lane-swap portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0
+phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=3 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=4 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=5 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=6 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=7 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=8 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=9 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=10 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=11 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=12 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=13 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=14 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=15 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=16 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=17 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=18 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=19 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=20 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=21 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=22 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=23 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=24 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=25 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=26 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=27 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=28 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=29 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=30 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=31 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=32 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=33 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=34 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=35 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=36 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=37 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=38 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=39 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=40 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=41 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=42 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=43 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1
+phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0
+phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev portlist=0 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=1 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=2 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=3 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=4 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=5 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=6 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=7 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=8 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=9 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=10 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=11 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=12 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=13 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=14 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=15 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=16 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=17 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=18 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=19 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=20 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=21 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=22 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=23 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=24 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=25 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=26 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=27 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=28 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=29 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=30 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=31 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=32 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=33 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=34 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=35 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=36 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=37 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=38 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=39 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=40 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=41 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=42 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=43 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1
+phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0
+phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0
+phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1
+phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0
+phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0
+phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x1.1.1.1
+phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a
+phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x1.1.1.1
+phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a
+phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a
+phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x8.8.8.8
+phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x1.1.1.1
+phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a
+phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x7.7.7.7
+port set property portlist=0-47 speed=25g
+port set property portlist=48-53 speed=100g
+port set property portlist=129-130 speed=10g
+port set property portlist=0-47 medium-type=sr
+port set property portlist=48-53 medium-type=sr4
+port set property portlist=129-130 medium-type=kr
+port set adver portlist=129-130 speed-10g-kr
+port set property portlist=129-130 an=enable
+port set property portlist=0-53,129-130 admin=enable
+
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B
new file mode 100644
index 00000000000..34e5a2daab8
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B
@@ -0,0 +1,358 @@
+init start stage unit=0 low-level
+init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true
+init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true
+init start stage unit=0 task-rsrc
+init start stage unit=0 module
+init start stage unit=0 task
+phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=3 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=4 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=5 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=6 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=7 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=8 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=9 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=10 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=11 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=12 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=13 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=14 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=15 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=16 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=17 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=18 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=19 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=20 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=21 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=22 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=23 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=24 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=25 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=26 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=27 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=28 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=29 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=30 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=31 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=32 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=33 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=34 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=35 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=36 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=37 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=38 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=39 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=40 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=41 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=42 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=43 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x0
+phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x1
+phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x2
+phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x3
+phy set lane-swap portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2
+phy set lane-swap portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2
+phy set lane-swap portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2
+phy set lane-swap portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1
+phy set lane-swap portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0
+phy set lane-swap portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0
+phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=3 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=4 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=5 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=6 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=7 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=8 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=9 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=10 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=11 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=12 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=13 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=14 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=15 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=16 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=17 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=18 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=19 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=20 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=21 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=22 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=23 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=24 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=25 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=26 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=27 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=28 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=29 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=30 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=31 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=32 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=33 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=34 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=35 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=36 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=37 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=38 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=39 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=40 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=41 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=42 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=43 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x1
+phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x2
+phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x3
+phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x0
+phy set lane-swap portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3
+phy set lane-swap portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2
+phy set lane-swap portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2
+phy set lane-swap portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2
+phy set lane-swap portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0
+phy set lane-swap portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0
+phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=3 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=4 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=5 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=6 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=7 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=8 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=9 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=10 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=11 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=12 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=13 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=14 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=15 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=16 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=17 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=18 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=19 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=20 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=21 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=22 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=23 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=24 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=25 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=26 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=27 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=28 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=29 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=30 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=31 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=32 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=33 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=34 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=35 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=36 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=37 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=38 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=39 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=40 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=41 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=42 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=43 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1
+phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0
+phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev portlist=0 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=1 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=2 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=3 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=4 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=5 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=6 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=7 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=8 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=9 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=10 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=11 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=12 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=13 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=14 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=15 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=16 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=17 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=18 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=19 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=20 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=21 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=22 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=23 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=24 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=25 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=26 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=27 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=28 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=29 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=30 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=31 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=32 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=33 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=34 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=35 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=36 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=37 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=38 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=39 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=40 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=41 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=42 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=43 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1
+phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0
+phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0
+phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1
+phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0
+phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0
+phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x1.1.1.1
+phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a
+phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x1.1.1.1
+phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a
+phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c
+phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x6.6.6.6
+phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
+phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x7.7.7.7
+phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x0.0.0.0
+phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a
+phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x8.8.8.8
+phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2
+phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x1.1.1.1
+phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a
+phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x7.7.7.7
+port set property portlist=0-47 speed=25g
+port set property portlist=48-53 speed=100g
+port set property portlist=129-130 speed=10g
+port set property portlist=0-47 medium-type=sr
+port set property portlist=48-53 medium-type=sr4
+port set property portlist=129-130 medium-type=kr
+port set adver portlist=129-130 speed-10g-kr
+port set property portlist=129-130 an=enable
+port set property portlist=0-53,129-130 admin=enable
+
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B
new file mode 100644
index 00000000000..af9927ae288
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B
@@ -0,0 +1,357 @@
+init start stage unit=0 low-level
+init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true
+init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true
+init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true
+init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true
+init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true
+init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true
+init start stage unit=0 task-rsrc
+init start stage unit=0 module
+init start stage unit=0 task
+phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=tx data=0x0
+phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=tx data=0x1
+phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2
+phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3
+phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2
+phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2
+phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2
+phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1
+phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0
+phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0
+phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=rx data=0x1
+phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=rx data=0x2
+phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x3
+phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x0
+phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3
+phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2
+phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2
+phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2
+phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0
+phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0
+phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=tx data=0x0
+phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1
+phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0
+phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0
+phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0
+phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1
+phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0
+phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0
+phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1
+phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0
+phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c1 data=0x2.2.2.2
+phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x0.0.0.0
+phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x4.4.4.4
+phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e
+phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x2.2.2.2
+port set property unit=0 portlist=0-47 speed=25g
+port set property unit=0 portlist=48-53 speed=100g
+port set property unit=0 portlist=129-130 speed=10g
+port set property unit=0 portlist=0-47 medium-type=cr
+port set property unit=0 portlist=48-53 medium-type=cr4
+port set property unit=0 portlist=129-130 medium-type=kr
+port set adver unit=0 portlist=129-130 speed-10g-kr
+port set property unit=0 portlist=129-130 an=enable
+port set property unit=0 portlist=0-53,129-130 admin=enable
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2
new file mode 100644
index 00000000000..5c5fc6e4969
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2
@@ -0,0 +1,136 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "1",
+ "1": "0",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "1",
+ "1": "0",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"1",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"0",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0" : {
+ "type":"DWRR",
+ "weight": "25"
+ },
+ "scheduler.1" : {
+ "type":"DWRR",
+ "weight": "30"
+ },
+ "scheduler.2" : {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PORT_QOS_MAP": {
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSY" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"613984",
+ "red_min_threshold":"76608",
+ "yellow_max_threshold":"628320",
+ "yellow_min_threshold":"78400",
+ "green_max_threshold": "642656",
+ "green_min_threshold": "80192"
+ },
+ "AZURE_LOSSLESS" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"613984",
+ "red_min_threshold":"76608",
+ "yellow_max_threshold":"628320",
+ "yellow_min_threshold":"78400",
+ "green_max_threshold": "642656",
+ "green_min_threshold": "80192"
+ }
+ },
+ "QUEUE": {
+ }
+}
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile
new file mode 100644
index 00000000000..880f47910ac
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile
@@ -0,0 +1,2 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/led_proc_init.nps
+SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/installer.conf b/device/accton/x86_64-accton_as7116_54x-r0/installer.conf
new file mode 100644
index 00000000000..4eeedca86a4
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/installer.conf
@@ -0,0 +1,4 @@
+CONSOLE_PORT=0x3f8
+CONSOLE_DEV=0
+CONSOLE_SPEED=115200
+ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer"
\ No newline at end of file
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/led_proc_init.nps b/device/accton/x86_64-accton_as7116_54x-r0/led_proc_init.nps
new file mode 100644
index 00000000000..e25c78018ad
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/led_proc_init.nps
@@ -0,0 +1,10 @@
+#unit NPS_CFG_TYPE_XXX param0 param1 value
+#---- ---------------- ------ ------ -----
+0 NPS_CFG_TYPE_USE_UNIT_PORT 0 0 1
+0 NPS_CFG_TYPE_LED_CFG 0 0 5
+0 NPS_CFG_TYPE_CPI_PORT_MODE 129 0 1
+0 NPS_CFG_TYPE_CPI_PORT_MODE 130 0 1
+0 NPS_CFG_TYPE_USER_BUF_CTRL 0 0 1
+0 NPS_CFG_TYPE_HASH_L2_FDB_REGION_ENTRY_NUM 0 0 49152
+0 NPS_CFG_TYPE_HASH_L3_WITH_IPV6_PREFIX_64_REGION_ENTRY_NUM 0 0 32768
+
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/minigraph.xml b/device/accton/x86_64-accton_as7116_54x-r0/minigraph.xml
new file mode 100644
index 00000000000..91269c2f68f
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/minigraph.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+ HostIP
+ Loopback0
+
+ 10.1.0.32/32
+
+ 10.1.0.32/32
+
+
+
+
+
+
+
+ switch1
+
+
+
+
+
+
+
+
+
+
+
+
+ switch1
+ Accton-AS7116-54X
+
+
+
+
+
+
+ switch1
+
+
+ DhcpResources
+
+
+
+
+ NtpResources
+
+ 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org
+
+
+ SyslogResources
+
+
+
+
+
+
+
+
+ switch1
+ Accton-AS7116-54X
+
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py
new file mode 100644
index 00000000000..1e7d1046d93
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+try:
+ import exceptions
+ import binascii
+ import time
+ import optparse
+ import warnings
+ import os
+ import sys
+ from sonic_eeprom import eeprom_base
+ from sonic_eeprom import eeprom_tlvinfo
+ import subprocess
+except ImportError, e:
+ raise ImportError (str(e) + "- required module not found")
+
+class board(eeprom_tlvinfo.TlvInfoDecoder):
+ _TLV_INFO_MAX_LEN = 256
+ def __init__(self, name, path, cpld_root, ro):
+ self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom"
+ super(board, self).__init__(self.eeprom_path, 0, '', True)
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py
new file mode 100644
index 00000000000..08fd2648f31
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py
@@ -0,0 +1,92 @@
+#
+# psuutil.py
+# Platform-specific PSU status interface for SONiC
+#
+
+
+import os.path
+
+try:
+ from sonic_psu.psu_base import PsuBase
+except ImportError as e:
+ raise ImportError(str(e) + "- required module not found")
+
+
+class PsuUtil(PsuBase):
+ """Platform-specific PSUutil class"""
+
+ SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/10-0050",
+ "/sys/bus/i2c/devices/11-0053"]
+
+ def __init__(self):
+ PsuBase.__init__(self)
+
+
+ # Get sysfs attribute
+ def get_attr_value(self, attr_path):
+
+ retval = 'ERR'
+ if (not os.path.isfile(attr_path)):
+ return retval
+
+ try:
+ with open(attr_path, 'r') as fd:
+ retval = fd.read()
+ except Exception as error:
+ logging.error("Unable to open ", attr_path, " file !")
+
+ retval = retval.rstrip('\r\n')
+ return retval
+
+ def get_num_psus(self):
+ """
+ Retrieves the number of PSUs available on the device
+ :return: An integer, the number of PSUs available on the device
+ """
+ MAX_PSUS = 2
+ return MAX_PSUS
+
+ def get_psu_status(self, index):
+ """
+ Retrieves the oprational status of power supply unit (PSU) defined
+ by index
+ :param index: An integer, index of the PSU of which to query status
+ :return: Boolean, True if PSU is operating properly, False if PSU is\
+ faulty
+ """
+ status = 0
+ attr_file = 'psu_power_good'
+ attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file
+
+ attr_value = self.get_attr_value(attr_path)
+
+ if (attr_value != 'ERR'):
+ attr_value = int(attr_value, 16)
+ # Check for PSU status
+ if (attr_value == 1):
+ status = 1
+
+ return status
+
+ def get_psu_presence(self, index):
+ """
+ Retrieves the presence status of power supply unit (PSU) defined
+ by index
+ :param index: An integer, index of the PSU of which to query status
+ :return: Boolean, True if PSU is plugged, False if not
+ """
+ status = 0
+ psu_absent = 0
+ attr_file ='psu_present'
+ attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file
+
+ attr_value = self.get_attr_value(attr_path)
+
+ if (attr_value != 'ERR'):
+ attr_value = int(attr_value, 16)
+ # Check for PSU presence
+ if (attr_value == 1):
+ status = 1
+
+ return status
+
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py
new file mode 100644
index 00000000000..8abcd46ccb5
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+
+try:
+ import time
+ from sonic_sfp.sfputilbase import SfpUtilBase
+except ImportError, e:
+ raise ImportError (str(e) + "- required module not found")
+
+
+class SfpUtil(SfpUtilBase):
+ """Platform specific SfpUtill class"""
+
+ _port_start = 0
+ _port_end = 53
+ _qsfp_port_start = 48
+ _ports_in_block = 54
+
+ _port_to_eeprom_mapping = {}
+ _port_to_i2c_mapping = {
+ 0 : 37,
+ 1 : 38,
+ 2 : 39,
+ 3 : 40,
+ 4 : 41,
+ 5 : 42,
+ 6 : 43,
+ 7 : 44,
+ 8 : 45,
+ 9 : 46,
+ 10 : 47,
+ 11 : 48,
+ 12 : 49,
+ 13 : 50,
+ 14 : 51,
+ 15 : 52,
+ 16 : 53,
+ 17 : 54,
+ 18 : 55,
+ 19 : 56,
+ 20 : 57,
+ 21 : 58,
+ 22 : 59,
+ 23 : 60,
+ 24 : 61,
+ 25 : 62,
+ 26 : 63,
+ 27 : 64,
+ 28 : 65,
+ 29 : 66,
+ 30 : 67,
+ 31 : 68,
+ 32 : 69,
+ 33 : 70,
+ 34 : 71,
+ 35 : 72,
+ 36 : 73,
+ 37 : 74,
+ 38 : 75,
+ 39 : 76,
+ 40 : 77,
+ 41 : 78,
+ 42 : 79,
+ 43 : 80,
+ 44 : 81,
+ 45 : 82,
+ 46 : 83,
+ 47 : 84,
+ 48 : 21,
+ 49 : 22,
+ 50 : 23,
+ 51 : 24,
+ 52 : 25,
+ 53 : 26,
+ }
+
+ _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1)
+
+ def __init__(self):
+ eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom'
+ for x in range(self._port_start, self._port_end + 1):
+ port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x])
+ self._port_to_eeprom_mapping[x] = port_eeprom_path
+
+ SfpUtilBase.__init__(self)
+
+ def reset(self, port_num):
+ # Check for invalid port_num
+ if port_num < self._port_start or port_num > self._port_end:
+ return False
+
+ path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset"
+ port_ps = path.format(self._port_to_i2c_mapping[port_num])
+
+ try:
+ reg_file = open(port_ps, 'w')
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ #toggle reset
+ reg_file.seek(0)
+ reg_file.write('1')
+ time.sleep(1)
+ reg_file.seek(0)
+ reg_file.write('0')
+ reg_file.close()
+ return True
+
+ def set_low_power_mode(self, port_nuM, lpmode):
+ raise NotImplementedError
+
+ def get_low_power_mode(self, port_num):
+ raise NotImplementedError
+
+ def get_presence(self, port_num):
+ # Check for invalid port_num
+ if port_num < self._port_start or port_num > self._port_end:
+ return False
+
+ path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present"
+ port_ps = path.format(self._port_to_i2c_mapping[port_num])
+
+
+ try:
+ reg_file = open(port_ps)
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ reg_value = reg_file.readline().rstrip()
+ if reg_value == '1':
+ return True
+
+ return False
+
+ @property
+ def port_start(self):
+ return self._port_start
+
+ @property
+ def port_end(self):
+ return self._port_end
+
+ @property
+ def qsfp_ports(self):
+ return self._qsfp_ports
+
+ @property
+ def port_to_eeprom_mapping(self):
+ return self._port_to_eeprom_mapping
diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf b/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf
new file mode 100644
index 00000000000..9edb51a9e72
--- /dev/null
+++ b/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf
@@ -0,0 +1,13 @@
+# libsensors configuration file
+
+chip "as7116_54x_fan-*"
+ label fan1 "front fan 1"
+ label fan2 "front fan 2"
+ label fan3 "front fan 3"
+ label fan4 "front fan 4"
+ label fan5 "front fan 5"
+ label fan6 "rear fan 1"
+ label fan7 "rear fan 2"
+ label fan8 "rear fan 3"
+ label fan9 "rear fan 4"
+ label fan10 "rear fan 5"
diff --git a/device/accton/x86_64-accton_as7512_32x-r0/AS7512-C32/sai.profile b/device/accton/x86_64-accton_as7512_32x-r0/AS7512-C32/sai.profile
index 457c339c58a..211383b0064 100644
--- a/device/accton/x86_64-accton_as7512_32x-r0/AS7512-C32/sai.profile
+++ b/device/accton/x86_64-accton_as7512_32x-r0/AS7512-C32/sai.profile
@@ -1,2 +1,4 @@
mode=3
hwId=as7512
+netdevMode=1
+aclEntryMaxPrio=1024
diff --git a/device/accton/x86_64-accton_as7512_32x-r0/AS7512-S128/sai.profile b/device/accton/x86_64-accton_as7512_32x-r0/AS7512-S128/sai.profile
index 471c4395758..07c7ce4d6b2 100644
--- a/device/accton/x86_64-accton_as7512_32x-r0/AS7512-S128/sai.profile
+++ b/device/accton/x86_64-accton_as7512_32x-r0/AS7512-S128/sai.profile
@@ -1,2 +1,4 @@
mode=0
hwId=as7512
+netdevMode=1
+aclEntryMaxPrio=1024
diff --git a/device/accton/x86_64-accton_as7512_32x-r0/AS7512/sai.profile b/device/accton/x86_64-accton_as7512_32x-r0/AS7512/sai.profile
index 017996f7d7c..381a440f988 100644
--- a/device/accton/x86_64-accton_as7512_32x-r0/AS7512/sai.profile
+++ b/device/accton/x86_64-accton_as7512_32x-r0/AS7512/sai.profile
@@ -1,2 +1,4 @@
mode=1
hwId=as7512
+netdevMode=1
+aclEntryMaxPrio=1024
diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/sai.profile b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/sai.profile
index 0175b59a5da..5c613675c37 100644
--- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/sai.profile
+++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/sai.profile
@@ -1,2 +1,2 @@
-SAI_INIT_CONFIG_FILE=/etc/bcm/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm
SAI_NUM_ECMP_MEMBERS=32
diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm
new file mode 100644
index 00000000000..6d72e20b210
--- /dev/null
+++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm
@@ -0,0 +1,707 @@
+#/******************************************************************************
+# *
+# * File: config.bcm.cloverdales (7050-QX32)
+# * Name:
+# *
+# * Description: This file contains SDK properties for an Arista
+# * Cloverdales platform.
+# *
+# *-----------------------------------------------------------------------------
+# ******************************************************************************/
+####################################################################
+# BCM Config file for Cloverdale platform
+# - 16x40g + 32x10g + 8x40G Portmode
+
+# Old LPM only configuration
+# l2_mem_entries=163840
+# l3_mem_entries=90112
+# l3_alpm_enable=0
+# ipv6_lpm_128b_enable=0
+#
+# ALPM enable
+l3_alpm_enable=2
+ipv6_lpm_128b_enable=1
+l2_mem_entries=32768
+l3_mem_entries=16384
+
+# From old config file
+os=unix
+higig2_hdr_mode=1
+
+# Parity
+parity_correction=1
+parity_enable=1
+stat_if_parity_enable=0
+
+# l2 thread related config vars
+l2xmsg_hostbuf_size=8192
+l2xmsg_mode=1
+
+bcm_num_cos=8
+bcm_stat_interval=2000000
+lls_num_l2uc=12
+max_vp_lags=0
+miim_intr_enable=0
+mmu_lossless=0
+module_64ports=0
+scache_filename=/tmp/scache
+schan_intr_enable=0
+stable_size=0x2000000
+tdma_timeout_usec=5000000
+
+# for GLC transceiver
+phy_an_c73=0x0
+phy_an_c37=0x3
+
+###########################
+#port_init_speed_xe=40000
+#port_init_speed_xe.0=40000
+
+#load_firmware=0x0102
+load_firmware.0=2
+
+#########################
+# All ports are in oversubscription mode
+pbmp_oversubscribe=0x1fffffffffffffffffffffffffe
+pbmp_xport_xe.0=0x1fffffffffffffffffffffffffe
+
+##########################################
+#skip_L2_USER_ENTRY=0
+phy_aux_voltage_enable=1
+###############################
+serdes_fiber_pref=1
+###############################
+mdio_output_delay.0=0x0d
+###############################
+serdes_sgmii_m=0
+xgxs_lcpll_xtal_refclk=1
+xgxs_lcpll_xtal_refclk.0=1
+xgxs_lcpll_xtal_refclk.1=1
+xgxs_lcpll_xtal_refclk.2=1
+xgxs_lcpll_xtal_refclk.3=1
+tdma_intr_enable=1
+tslam_intr_enable=1
+tslam_dma_enable.2=1
+tslam_dma_enable.3=1
+#dport_map_port=0
+#pci2eb_overrid=0
+#bcm_xlate_port_enable.0=0
+#xgxs_pdetect_1=0
+table_dma_enable.0=1
+table_dma_enable.1=1
+table_dma_enable.2=1
+table_dma_enable.3=1
+
+
+phy_84328_1.0=1
+phy_84328_5.0=1
+phy_84328_9.0=1
+phy_84328_13.0=1
+phy_84328_101.0=1
+phy_84328_102.0=1
+phy_84328_103.0=1
+phy_84328_104.0=1
+
+phy_an_c37_1.0=0
+phy_an_c37_5.0=0
+phy_an_c37_9.0=0
+phy_an_c37_13.0=0
+phy_an_c37_17.0=0
+phy_an_c37_21.0=0
+phy_an_c37_25.0=0
+phy_an_c37_29.0=0
+phy_an_c37_33.0=0
+phy_an_c37_37.0=0
+phy_an_c37_41.0=0
+phy_an_c37_45.0=0
+phy_an_c37_49.0=0
+phy_an_c37_53.0=0
+phy_an_c37_57.0=0
+phy_an_c37_61.0=0
+phy_an_c37_65.0=3
+phy_an_c37_66.0=3
+phy_an_c37_67.0=3
+phy_an_c37_68.0=3
+phy_an_c37_69.0=3
+phy_an_c37_70.0=3
+phy_an_c37_71.0=3
+phy_an_c37_72.0=3
+phy_an_c37_73.0=3
+phy_an_c37_74.0=3
+phy_an_c37_75.0=3
+phy_an_c37_76.0=3
+phy_an_c37_77.0=3
+phy_an_c37_78.0=3
+phy_an_c37_79.0=3
+phy_an_c37_80.0=3
+phy_an_c37_81.0=3
+phy_an_c37_82.0=3
+phy_an_c37_83.0=3
+phy_an_c37_84.0=3
+phy_an_c37_85.0=3
+phy_an_c37_86.0=3
+phy_an_c37_87.0=3
+phy_an_c37_88.0=3
+phy_an_c37_89.0=3
+phy_an_c37_90.0=3
+phy_an_c37_91.0=3
+phy_an_c37_92.0=3
+phy_an_c37_93.0=3
+phy_an_c37_94.0=3
+phy_an_c37_95.0=3
+phy_an_c37_96.0=3
+phy_an_c37_97.0=0
+phy_an_c37_98.0=0
+phy_an_c37_99.0=0
+phy_an_c37_100.0=0
+phy_an_c37_101.0=0
+phy_an_c37_102.0=0
+phy_an_c37_103.0=0
+phy_an_c37_104.0=0
+
+phy_an_c73_1.0=2
+phy_an_c73_5.0=2
+phy_an_c73_9.0=2
+phy_an_c73_13.0=2
+phy_an_c73_17.0=2
+phy_an_c73_21.0=2
+phy_an_c73_25.0=2
+phy_an_c73_29.0=2
+phy_an_c73_33.0=2
+phy_an_c73_37.0=2
+phy_an_c73_41.0=2
+phy_an_c73_45.0=2
+phy_an_c73_49.0=2
+phy_an_c73_53.0=2
+phy_an_c73_57.0=2
+phy_an_c73_61.0=2
+phy_an_c73_65.0=0
+phy_an_c73_66.0=0
+phy_an_c73_67.0=0
+phy_an_c73_68.0=0
+phy_an_c73_69.0=0
+phy_an_c73_70.0=0
+phy_an_c73_71.0=0
+phy_an_c73_72.0=0
+phy_an_c73_73.0=0
+phy_an_c73_74.0=0
+phy_an_c73_75.0=0
+phy_an_c73_76.0=0
+phy_an_c73_77.0=0
+phy_an_c73_78.0=0
+phy_an_c73_79.0=0
+phy_an_c73_80.0=0
+phy_an_c73_81.0=0
+phy_an_c73_82.0=0
+phy_an_c73_83.0=0
+phy_an_c73_84.0=0
+phy_an_c73_85.0=0
+phy_an_c73_86.0=0
+phy_an_c73_87.0=0
+phy_an_c73_88.0=0
+phy_an_c73_89.0=0
+phy_an_c73_90.0=0
+phy_an_c73_91.0=0
+phy_an_c73_92.0=0
+phy_an_c73_93.0=0
+phy_an_c73_94.0=0
+phy_an_c73_95.0=0
+phy_an_c73_96.0=0
+phy_an_c73_97.0=2
+phy_an_c73_98.0=2
+phy_an_c73_99.0=2
+phy_an_c73_100.0=2
+phy_an_c73_101.0=2
+phy_an_c73_102.0=2
+phy_an_c73_103.0=2
+phy_an_c73_104.0=2
+
+phy_aux_voltage_enable_1.0=0x1
+phy_aux_voltage_enable_5.0=0x1
+phy_aux_voltage_enable_9.0=0x1
+phy_aux_voltage_enable_13.0=0x1
+phy_aux_voltage_enable_101.0=0x1
+phy_aux_voltage_enable_102.0=0x1
+phy_aux_voltage_enable_103.0=0x1
+phy_aux_voltage_enable_104.0=0x1
+
+phy_ext_rom_boot.0=0
+
+phy_ext_rom_boot_1.0=0x0
+phy_ext_rom_boot_5.0=0x0
+phy_ext_rom_boot_9.0=0x0
+phy_ext_rom_boot_13.0=0x0
+phy_ext_rom_boot_101.0=0x0
+phy_ext_rom_boot_102.0=0x0
+phy_ext_rom_boot_103.0=0x0
+phy_ext_rom_boot_104.0=0x0
+
+
+phy_line_tx_mode_1.0=1
+phy_line_tx_mode_5.0=1
+phy_line_tx_mode_9.0=1
+phy_line_tx_mode_13.0=1
+phy_line_tx_mode_101.0=1
+phy_line_tx_mode_102.0=1
+phy_line_tx_mode_103.0=1
+phy_line_tx_mode_104.0=1
+
+
+phy_rx_polarity_flip_1.0=0x0
+phy_rx_polarity_flip_5.0=0x0
+phy_rx_polarity_flip_9.0=0x0
+phy_rx_polarity_flip_13.0=0x0
+phy_rx_polarity_flip_101.0=0x0
+phy_rx_polarity_flip_102.0=0x0
+phy_rx_polarity_flip_103.0=0x0
+phy_rx_polarity_flip_104.0=0x0
+
+phy_system_tx_mode_1.0=0
+phy_system_tx_mode_5.0=0
+phy_system_tx_mode_9.0=0
+phy_system_tx_mode_13.0=0
+phy_system_tx_mode_101.0=0
+phy_system_tx_mode_102.0=0
+phy_system_tx_mode_103.0=0
+phy_system_tx_mode_104.0=0
+
+
+phy_tx_polarity_flip_1.0=0x0
+phy_tx_polarity_flip_5.0=0x0
+phy_tx_polarity_flip_9.0=0x0
+phy_tx_polarity_flip_13.0=0x0
+phy_tx_polarity_flip_101.0=0x0
+phy_tx_polarity_flip_102.0=0x0
+phy_tx_polarity_flip_103.0=0x0
+phy_tx_polarity_flip_104.0=0x0
+
+
+phy_xaui_rx_polarity_flip_1.0=0x0
+phy_xaui_rx_polarity_flip_5.0=0x0
+phy_xaui_rx_polarity_flip_9.0=0x0
+phy_xaui_rx_polarity_flip_13.0=0x0
+phy_xaui_rx_polarity_flip_17.0=0x0
+phy_xaui_rx_polarity_flip_21.0=0x0
+phy_xaui_rx_polarity_flip_25.0=0x0
+phy_xaui_rx_polarity_flip_29.0=0x0
+phy_xaui_rx_polarity_flip_33.0=0x0
+phy_xaui_rx_polarity_flip_37.0=0x0
+phy_xaui_rx_polarity_flip_41.0=0x0
+phy_xaui_rx_polarity_flip_45.0=0x0
+phy_xaui_rx_polarity_flip_49.0=0x0
+phy_xaui_rx_polarity_flip_53.0=0x0
+phy_xaui_rx_polarity_flip_57.0=0x0
+phy_xaui_rx_polarity_flip_61.0=0x0
+phy_xaui_rx_polarity_flip_65.0=0x0
+phy_xaui_rx_polarity_flip_66.0=0x0
+phy_xaui_rx_polarity_flip_67.0=0x0
+phy_xaui_rx_polarity_flip_68.0=0x0
+phy_xaui_rx_polarity_flip_69.0=0x0
+phy_xaui_rx_polarity_flip_70.0=0x0
+phy_xaui_rx_polarity_flip_71.0=0x0
+phy_xaui_rx_polarity_flip_72.0=0x0
+phy_xaui_rx_polarity_flip_73.0=0x0
+phy_xaui_rx_polarity_flip_74.0=0x0
+phy_xaui_rx_polarity_flip_75.0=0x0
+phy_xaui_rx_polarity_flip_76.0=0x0
+phy_xaui_rx_polarity_flip_77.0=0x0
+phy_xaui_rx_polarity_flip_78.0=0x0
+phy_xaui_rx_polarity_flip_79.0=0x0
+phy_xaui_rx_polarity_flip_80.0=0x0
+phy_xaui_rx_polarity_flip_81.0=0x0
+phy_xaui_rx_polarity_flip_82.0=0x0
+phy_xaui_rx_polarity_flip_83.0=0x0
+phy_xaui_rx_polarity_flip_84.0=0x0
+phy_xaui_rx_polarity_flip_85.0=0x0
+phy_xaui_rx_polarity_flip_86.0=0x0
+phy_xaui_rx_polarity_flip_87.0=0x0
+phy_xaui_rx_polarity_flip_88.0=0x0
+phy_xaui_rx_polarity_flip_89.0=0x0
+phy_xaui_rx_polarity_flip_90.0=0x0
+phy_xaui_rx_polarity_flip_91.0=0x0
+phy_xaui_rx_polarity_flip_92.0=0x0
+phy_xaui_rx_polarity_flip_93.0=0x0
+phy_xaui_rx_polarity_flip_94.0=0x0
+phy_xaui_rx_polarity_flip_95.0=0x0
+phy_xaui_rx_polarity_flip_96.0=0x0
+phy_xaui_rx_polarity_flip_97.0=0x0
+phy_xaui_rx_polarity_flip_98.0=0x0
+phy_xaui_rx_polarity_flip_99.0=0x0
+phy_xaui_rx_polarity_flip_100.0=0x0
+phy_xaui_rx_polarity_flip_101.0=0x0
+phy_xaui_rx_polarity_flip_102.0=0x0
+phy_xaui_rx_polarity_flip_103.0=0x0
+phy_xaui_rx_polarity_flip_104.0=0x0
+
+phy_xaui_tx_polarity_flip_1.0=0x0
+phy_xaui_tx_polarity_flip_5.0=0x0
+phy_xaui_tx_polarity_flip_9.0=0x0
+phy_xaui_tx_polarity_flip_13.0=0x0
+phy_xaui_tx_polarity_flip_17.0=0x0
+phy_xaui_tx_polarity_flip_21.0=0x0
+phy_xaui_tx_polarity_flip_25.0=0x0
+phy_xaui_tx_polarity_flip_29.0=0x0
+phy_xaui_tx_polarity_flip_33.0=0x0
+phy_xaui_tx_polarity_flip_37.0=0x0
+phy_xaui_tx_polarity_flip_41.0=0x0
+phy_xaui_tx_polarity_flip_45.0=0x0
+phy_xaui_tx_polarity_flip_49.0=0x0
+phy_xaui_tx_polarity_flip_53.0=0x0
+phy_xaui_tx_polarity_flip_57.0=0x0
+phy_xaui_tx_polarity_flip_61.0=0x0
+phy_xaui_tx_polarity_flip_65.0=0x0
+phy_xaui_tx_polarity_flip_66.0=0x0
+phy_xaui_tx_polarity_flip_67.0=0x0
+phy_xaui_tx_polarity_flip_68.0=0x0
+phy_xaui_tx_polarity_flip_69.0=0x0
+phy_xaui_tx_polarity_flip_70.0=0x0
+phy_xaui_tx_polarity_flip_71.0=0x0
+phy_xaui_tx_polarity_flip_72.0=0x0
+phy_xaui_tx_polarity_flip_73.0=0x0
+phy_xaui_tx_polarity_flip_74.0=0x0
+phy_xaui_tx_polarity_flip_75.0=0x0
+phy_xaui_tx_polarity_flip_76.0=0x0
+phy_xaui_tx_polarity_flip_77.0=0x0
+phy_xaui_tx_polarity_flip_78.0=0x0
+phy_xaui_tx_polarity_flip_79.0=0x0
+phy_xaui_tx_polarity_flip_80.0=0x0
+phy_xaui_tx_polarity_flip_81.0=0x0
+phy_xaui_tx_polarity_flip_82.0=0x0
+phy_xaui_tx_polarity_flip_83.0=0x0
+phy_xaui_tx_polarity_flip_84.0=0x0
+phy_xaui_tx_polarity_flip_85.0=0x0
+phy_xaui_tx_polarity_flip_86.0=0x0
+phy_xaui_tx_polarity_flip_87.0=0x0
+phy_xaui_tx_polarity_flip_88.0=0x0
+phy_xaui_tx_polarity_flip_89.0=0x0
+phy_xaui_tx_polarity_flip_90.0=0x0
+phy_xaui_tx_polarity_flip_91.0=0x0
+phy_xaui_tx_polarity_flip_92.0=0x0
+phy_xaui_tx_polarity_flip_93.0=0x0
+phy_xaui_tx_polarity_flip_94.0=0x0
+phy_xaui_tx_polarity_flip_95.0=0x0
+phy_xaui_tx_polarity_flip_96.0=0x0
+phy_xaui_tx_polarity_flip_97.0=0x0
+phy_xaui_tx_polarity_flip_98.0=0x0
+phy_xaui_tx_polarity_flip_99.0=0x0
+phy_xaui_tx_polarity_flip_100.0=0x0
+phy_xaui_tx_polarity_flip_101.0=0x0
+phy_xaui_tx_polarity_flip_102.0=0x0
+phy_xaui_tx_polarity_flip_103.0=0x0
+phy_xaui_tx_polarity_flip_104.0=0x0
+
+port_init_autoneg_17.0=0
+port_init_autoneg_21.0=0
+port_init_autoneg_25.0=0
+port_init_autoneg_29.0=0
+port_init_autoneg_33.0=0
+port_init_autoneg_37.0=0
+port_init_autoneg_41.0=0
+port_init_autoneg_45.0=0
+port_init_autoneg_49.0=0
+port_init_autoneg_53.0=0
+port_init_autoneg_57.0=0
+port_init_autoneg_61.0=0
+port_init_autoneg_65.0=0
+port_init_autoneg_66.0=0
+port_init_autoneg_67.0=0
+port_init_autoneg_68.0=0
+port_init_autoneg_69.0=0
+port_init_autoneg_70.0=0
+port_init_autoneg_71.0=0
+port_init_autoneg_72.0=0
+port_init_autoneg_73.0=0
+port_init_autoneg_74.0=0
+port_init_autoneg_75.0=0
+port_init_autoneg_76.0=0
+port_init_autoneg_77.0=0
+port_init_autoneg_78.0=0
+port_init_autoneg_79.0=0
+port_init_autoneg_80.0=0
+port_init_autoneg_81.0=0
+port_init_autoneg_82.0=0
+port_init_autoneg_83.0=0
+port_init_autoneg_84.0=0
+port_init_autoneg_85.0=0
+port_init_autoneg_86.0=0
+port_init_autoneg_87.0=0
+port_init_autoneg_88.0=0
+port_init_autoneg_89.0=0
+port_init_autoneg_90.0=0
+port_init_autoneg_91.0=0
+port_init_autoneg_92.0=0
+port_init_autoneg_93.0=0
+port_init_autoneg_94.0=0
+port_init_autoneg_95.0=0
+port_init_autoneg_96.0=0
+port_init_autoneg_97.0=0
+port_init_autoneg_98.0=0
+port_init_autoneg_99.0=0
+port_init_autoneg_100.0=0
+
+port_init_cl72_hg.0=0x11
+
+
+portmap_1.0=125:40
+portmap_5.0=121:40
+portmap_9.0=13:40
+portmap_13.0=9:40
+portmap_17.0=17:40
+portmap_21.0=21:40
+portmap_25.0=25:40
+portmap_29.0=29:40
+portmap_33.0=37:40
+portmap_37.0=33:40
+portmap_41.0=45:40
+portmap_45.0=41:40
+portmap_49.0=53:40
+portmap_53.0=49:40
+portmap_57.0=69:40
+portmap_61.0=65:40
+portmap_65.0=77:10
+portmap_66.0=78:10
+portmap_67.0=79:10
+portmap_68.0=80:10
+portmap_69.0=73:10
+portmap_70.0=74:10
+portmap_71.0=75:10
+portmap_72.0=76:10
+portmap_73.0=93:10
+portmap_74.0=94:10
+portmap_75.0=95:10
+portmap_76.0=96:10
+portmap_77.0=89:10
+portmap_78.0=90:10
+portmap_79.0=91:10
+portmap_80.0=92:10
+portmap_81.0=101:10
+portmap_82.0=102:10
+portmap_83.0=103:10
+portmap_84.0=104:10
+portmap_85.0=97:10
+portmap_86.0=98:10
+portmap_87.0=99:10
+portmap_88.0=100:10
+portmap_89.0=109:10
+portmap_90.0=110:10
+portmap_91.0=111:10
+portmap_92.0=112:10
+portmap_93.0=105:10
+portmap_94.0=106:10
+portmap_95.0=107:10
+portmap_96.0=108:10
+portmap_97.0=61:40
+portmap_98.0=57:40
+portmap_99.0=81:40
+portmap_100.0=85:40
+portmap_101.0=117:40
+portmap_102.0=113:40
+portmap_103.0=5:40
+portmap_104.0=1:40
+
+port_phy_addr_1.0=0x4
+port_phy_addr_5.0=0x0
+port_phy_addr_9.0=0x2c
+port_phy_addr_13.0=0x28
+port_phy_addr_17.0=0x7f
+port_phy_addr_21.0=0x7f
+port_phy_addr_25.0=0x7f
+port_phy_addr_29.0=0x7f
+port_phy_addr_33.0=0x7f
+port_phy_addr_37.0=0x7f
+port_phy_addr_41.0=0x7f
+port_phy_addr_45.0=0x7f
+port_phy_addr_49.0=0x7f
+port_phy_addr_53.0=0x7f
+port_phy_addr_57.0=0x7f
+port_phy_addr_61.0=0x7f
+port_phy_addr_65.0=0x7f
+port_phy_addr_66.0=0x7f
+port_phy_addr_67.0=0x7f
+port_phy_addr_68.0=0x7f
+port_phy_addr_69.0=0x7f
+port_phy_addr_70.0=0x7f
+port_phy_addr_71.0=0x7f
+port_phy_addr_72.0=0x7f
+port_phy_addr_73.0=0x7f
+port_phy_addr_74.0=0x7f
+port_phy_addr_75.0=0x7f
+port_phy_addr_76.0=0x7f
+port_phy_addr_77.0=0x7f
+port_phy_addr_78.0=0x7f
+port_phy_addr_79.0=0x7f
+port_phy_addr_80.0=0x7f
+port_phy_addr_81.0=0x7f
+port_phy_addr_82.0=0x7f
+port_phy_addr_83.0=0x7f
+port_phy_addr_84.0=0x7f
+port_phy_addr_85.0=0x7f
+port_phy_addr_86.0=0x7f
+port_phy_addr_87.0=0x7f
+port_phy_addr_88.0=0x7f
+port_phy_addr_89.0=0x7f
+port_phy_addr_90.0=0x7f
+port_phy_addr_91.0=0x7f
+port_phy_addr_92.0=0x7f
+port_phy_addr_93.0=0x7f
+port_phy_addr_94.0=0x7f
+port_phy_addr_95.0=0x7f
+port_phy_addr_96.0=0x7f
+port_phy_addr_97.0=0x7f
+port_phy_addr_98.0=0x7f
+port_phy_addr_99.0=0x7f
+port_phy_addr_100.0=0x7f
+port_phy_addr_101.0=0x54
+port_phy_addr_102.0=0x50
+port_phy_addr_103.0=0x7c
+port_phy_addr_104.0=0x78
+
+port_phy_clause_1.0=0x2d
+port_phy_clause_5.0=0x2d
+port_phy_clause_9.0=0x2d
+port_phy_clause_13.0=0x2d
+port_phy_clause_101.0=0x2d
+port_phy_clause_102.0=0x2d
+port_phy_clause_103.0=0x2d
+port_phy_clause_104.0=0x2d
+
+port_phy_id0_1.0=0x600d
+port_phy_id0_5.0=0x600d
+port_phy_id0_9.0=0x600d
+port_phy_id0_13.0=0x600d
+port_phy_id0_101.0=0x600d
+port_phy_id0_102.0=0x600d
+port_phy_id0_103.0=0x600d
+port_phy_id0_104.0=0x600d
+
+port_phy_id1_1.0=0x8500
+port_phy_id1_5.0=0x8500
+port_phy_id1_9.0=0x8500
+port_phy_id1_13.0=0x8500
+port_phy_id1_101.0=0x8500
+port_phy_id1_102.0=0x8500
+port_phy_id1_103.0=0x8500
+port_phy_id1_104.0=0x8500
+
+xgxs_rx_lane_map_1.0=0x0123
+xgxs_rx_lane_map_5.0=0x0123
+xgxs_rx_lane_map_9.0=0x0123
+xgxs_rx_lane_map_13.0=0x0123
+xgxs_rx_lane_map_17.0=0x2031
+xgxs_rx_lane_map_21.0=0x2031
+xgxs_rx_lane_map_25.0=0x2031
+xgxs_rx_lane_map_29.0=0x2031
+xgxs_rx_lane_map_33.0=0x3120
+xgxs_rx_lane_map_37.0=0x3120
+xgxs_rx_lane_map_41.0=0x3120
+xgxs_rx_lane_map_45.0=0x3120
+xgxs_rx_lane_map_49.0=0x3120
+xgxs_rx_lane_map_53.0=0x3120
+xgxs_rx_lane_map_57.0=0x3120
+xgxs_rx_lane_map_61.0=0x3120
+xgxs_rx_lane_map_65.0=0x3120
+xgxs_rx_lane_map_69.0=0x3120
+xgxs_rx_lane_map_73.0=0x3120
+xgxs_rx_lane_map_77.0=0x3120
+xgxs_rx_lane_map_81.0=0x3120
+xgxs_rx_lane_map_85.0=0x3120
+xgxs_rx_lane_map_89.0=0x3120
+xgxs_rx_lane_map_93.0=0x3120
+xgxs_rx_lane_map_97.0=0x1302
+xgxs_rx_lane_map_98.0=0x1302
+xgxs_rx_lane_map_99.0=0x0213
+xgxs_tx_lane_map_100.0=0x0213
+xgxs_tx_lane_map_101.0=0x0123
+xgxs_tx_lane_map_102.0=0x0123
+xgxs_tx_lane_map_103.0=0x0123
+xgxs_tx_lane_map_104.0=0x0123
+
+xgxs_tx_lane_map_1.0=0x0123
+xgxs_tx_lane_map_5.0=0x0123
+xgxs_tx_lane_map_9.0=0x0123
+xgxs_tx_lane_map_13.0=0x0123
+xgxs_tx_lane_map_17.0=0x1302
+xgxs_tx_lane_map_21.0=0x1302
+xgxs_tx_lane_map_25.0=0x1302
+xgxs_tx_lane_map_29.0=0x1302
+xgxs_tx_lane_map_33.0=0x3120
+xgxs_tx_lane_map_37.0=0x3120
+xgxs_tx_lane_map_41.0=0x3120
+xgxs_tx_lane_map_45.0=0x3120
+xgxs_tx_lane_map_49.0=0x3120
+xgxs_tx_lane_map_53.0=0x3120
+xgxs_tx_lane_map_57.0=0x3120
+xgxs_tx_lane_map_61.0=0x3120
+xgxs_tx_lane_map_65.0=0x3120
+xgxs_tx_lane_map_69.0=0x3120
+xgxs_tx_lane_map_73.0=0x3120
+xgxs_tx_lane_map_77.0=0x3120
+xgxs_tx_lane_map_81.0=0x3120
+xgxs_tx_lane_map_85.0=0x3120
+xgxs_tx_lane_map_89.0=0x3120
+xgxs_tx_lane_map_93.0=0x3120
+xgxs_tx_lane_map_97.0=0x2031
+xgxs_tx_lane_map_98.0=0x2031
+xgxs_tx_lane_map_99.0=0x0213
+xgxs_rx_lane_map_100.0=0x0213
+xgxs_rx_lane_map_101.0=0x0123
+xgxs_rx_lane_map_102.0=0x0123
+xgxs_rx_lane_map_103.0=0x0123
+xgxs_rx_lane_map_104.0=0x0123
+
+serdes_firmware_mode_1.0=1
+serdes_firmware_mode_5.0=1
+serdes_firmware_mode_9.0=1
+serdes_firmware_mode_13.0=1
+serdes_firmware_mode_17.0=2
+serdes_firmware_mode_21.0=2
+serdes_firmware_mode_25.0=2
+serdes_firmware_mode_29.0=2
+serdes_firmware_mode_33.0=2
+serdes_firmware_mode_37.0=2
+serdes_firmware_mode_41.0=2
+serdes_firmware_mode_45.0=2
+serdes_firmware_mode_49.0=2
+serdes_firmware_mode_53.0=2
+serdes_firmware_mode_57.0=2
+serdes_firmware_mode_61.0=2
+serdes_firmware_mode_65.0=2
+serdes_firmware_mode_66.0=2
+serdes_firmware_mode_67.0=2
+serdes_firmware_mode_68.0=2
+serdes_firmware_mode_69.0=2
+serdes_firmware_mode_70.0=2
+serdes_firmware_mode_71.0=2
+serdes_firmware_mode_72.0=2
+serdes_firmware_mode_73.0=2
+serdes_firmware_mode_74.0=2
+serdes_firmware_mode_75.0=2
+serdes_firmware_mode_76.0=2
+serdes_firmware_mode_77.0=2
+serdes_firmware_mode_78.0=2
+serdes_firmware_mode_79.0=2
+serdes_firmware_mode_80.0=2
+serdes_firmware_mode_81.0=2
+serdes_firmware_mode_82.0=2
+serdes_firmware_mode_83.0=2
+serdes_firmware_mode_84.0=2
+serdes_firmware_mode_85.0=2
+serdes_firmware_mode_86.0=2
+serdes_firmware_mode_87.0=2
+serdes_firmware_mode_88.0=2
+serdes_firmware_mode_89.0=2
+serdes_firmware_mode_90.0=2
+serdes_firmware_mode_91.0=2
+serdes_firmware_mode_92.0=2
+serdes_firmware_mode_93.0=2
+serdes_firmware_mode_94.0=2
+serdes_firmware_mode_95.0=2
+serdes_firmware_mode_96.0=2
+serdes_firmware_mode_97.0=2
+serdes_firmware_mode_98.0=2
+serdes_firmware_mode_99.0=2
+serdes_firmware_mode_100.0=2
+serdes_firmware_mode_101.0=1
+serdes_firmware_mode_102.0=1
+serdes_firmware_mode_103.0=1
+serdes_firmware_mode_104.0=1
diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2
index 10f9da575a1..782dc528f71 100644
--- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2
+++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2
@@ -69,22 +69,17 @@
},
"BUFFER_POOL": {
"ingress_lossless_pool": {
- "size": "7274496",
- "type": "ingress",
- "mode": "dynamic"
- },
- "ingress_lossy_pool": {
- "size": "5491712",
+ "size": "12766208",
"type": "ingress",
"mode": "dynamic"
},
"egress_lossless_pool": {
- "size": "7274496",
+ "size": "12766208",
"type": "egress",
"mode": "static"
},
"egress_lossy_pool": {
- "size": "5491712",
+ "size": "8072396",
"type": "egress",
"mode": "dynamic"
}
@@ -99,14 +94,14 @@
"xon_offset":"2496"
},
"ingress_lossy_profile": {
- "pool":"[BUFFER_POOL|ingress_lossy_pool]",
- "size":"1518",
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
"dynamic_th":"3"
},
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "static_th":"7274496"
+ "static_th":"12766208"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossy_pool]",
@@ -120,6 +115,9 @@
},
"{{ port_names }}|0-1": {
"profile" : "[BUFFER_PROFILE|ingress_lossy_profile]"
+ },
+ "{{ port_names }}|5": {
+ "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]"
}
},
"BUFFER_QUEUE": {
@@ -128,6 +126,9 @@
},
"{{ port_names }}|0-1": {
"profile" : "[BUFFER_PROFILE|egress_lossy_profile]"
+ },
+ "{{ port_names }}|5": {
+ "profile" : "[BUFFER_PROFILE|egress_lossy_profile]"
}
}
}
diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json
index 926911ab59d..0eb02957299 100644
--- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json
+++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json
@@ -4,7 +4,8 @@
"0": "0",
"1": "1",
"3": "3",
- "4": "4"
+ "4": "4",
+ "5": "5"
}
},
"MAP_PFC_PRIORITY_TO_QUEUE": {
@@ -12,7 +13,8 @@
"0": "0",
"1": "1",
"3": "3",
- "4": "4"
+ "4": "4",
+ "5": "5"
}
},
"TC_TO_QUEUE_MAP": {
@@ -20,7 +22,8 @@
"0": "0",
"1": "1",
"3": "3",
- "4": "4"
+ "4": "4",
+ "5": "5"
}
},
"DSCP_TO_TC_MAP": {
@@ -71,7 +74,7 @@
"43":"0",
"44":"0",
"45":"0",
- "46":"0",
+ "46":"5",
"47":"0",
"48":"0",
"49":"0",
@@ -93,14 +96,6 @@
},
"SCHEDULER": {
"scheduler.0" : {
- "type":"DWRR",
- "weight": "25"
- },
- "scheduler.1" : {
- "type":"DWRR",
- "weight": "30"
- },
- "scheduler.2" : {
"type":"DWRR",
"weight": "20"
}
@@ -120,24 +115,34 @@
"wred_yellow_enable":"true",
"wred_red_enable":"true",
"ecn":"ecn_all",
- "red_max_threshold":"312000",
- "red_min_threshold":"104000",
- "yellow_max_threshold":"312000",
- "yellow_min_threshold":"104000",
- "green_max_threshold":"312000",
- "green_min_threshold":"104000"
+ "red_max_threshold":"2097152",
+ "red_min_threshold":"1048576",
+ "yellow_max_threshold":"2097152",
+ "yellow_min_threshold":"1048576",
+ "green_max_threshold":"2097152",
+ "green_min_threshold":"1048576",
+ "green_drop_probability":"5",
+ "yellow_drop_probability":"5",
+ "red_drop_probability":"5"
}
},
"QUEUE": {
- "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : {
"scheduler" : "[SCHEDULER|scheduler.0]",
"wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
},
"Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : {
- "scheduler" : "[SCHEDULER|scheduler.1]"
+ "scheduler" : "[SCHEDULER|scheduler.0]"
},
"Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : {
- "scheduler" : "[SCHEDULER|scheduler.2]"
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
}
}
}
diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/sai.profile b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/sai.profile
index 938d3718067..27d83fcc20e 100644
--- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/sai.profile
+++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/sai.profile
@@ -1,2 +1,2 @@
-SAI_INIT_CONFIG_FILE=/etc/bcm/td2-a7050-qx32-32x40G.config.bcm
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-qx32-32x40G.config.bcm
SAI_NUM_ECMP_MEMBERS=32
diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm
new file mode 100644
index 00000000000..701a8480dcb
--- /dev/null
+++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm
@@ -0,0 +1,873 @@
+#/******************************************************************************
+# *
+# * File: config.bcm.cloverdales (7050-QX32)
+# * Name:
+# *
+# * Description: This file contains SDK properties for an Arista
+# * Cloverdales platform.
+# *
+# *-----------------------------------------------------------------------------
+# ******************************************************************************/
+####################################################################
+# BCM Config file for Cloverdale platform
+# - 32x40g Portmode
+
+# Old LPM only configuration
+# l2_mem_entries=163840
+# l3_mem_entries=90112
+# l3_alpm_enable=0
+# ipv6_lpm_128b_enable=0
+#
+# ALPM enable
+l3_alpm_enable=2
+ipv6_lpm_128b_enable=1
+l2_mem_entries=32768
+l3_mem_entries=16384
+
+# From old config file
+os=unix
+higig2_hdr_mode=1
+
+# Parity
+parity_correction=1
+parity_enable=1
+stat_if_parity_enable=0
+
+# l2 thread related config vars
+l2xmsg_hostbuf_size=8192
+l2xmsg_mode=1
+
+bcm_num_cos=8
+bcm_stat_interval=2000000
+lls_num_l2uc=12
+max_vp_lags=0
+miim_intr_enable=0
+mmu_lossless=0
+module_64ports=0
+scache_filename=/tmp/scache
+schan_intr_enable=0
+stable_size=0x2000000
+tdma_timeout_usec=5000000
+
+# for GLC transceiver
+phy_an_c73=0x0
+phy_an_c37=0x3
+
+###########################
+#port_init_speed_xe=40000
+#port_init_speed_xe.0=40000
+
+#load_firmware=0x0102
+load_firmware.0=2
+
+#########################
+# All ports are in oversubscription mode
+pbmp_oversubscribe=0x1fffffffffffffffffffffffffe
+pbmp_xport_xe.0=0x1fffffffe
+
+phy_84328_1.0=1
+phy_84328_2.0=1
+phy_84328_29.0=1
+phy_84328_3.0=1
+phy_84328_30.0=1
+phy_84328_31.0=1
+phy_84328_32.0=1
+phy_84328_4.0=1
+phy_an_c37_1.0=3
+phy_an_c37_10.0=3
+phy_an_c37_11.0=3
+phy_an_c37_12.0=3
+phy_an_c37_13.0=3
+phy_an_c37_14.0=3
+phy_an_c37_15.0=3
+phy_an_c37_16.0=3
+phy_an_c37_17.0=3
+phy_an_c37_18.0=3
+phy_an_c37_19.0=3
+phy_an_c37_2.0=3
+phy_an_c37_20.0=3
+phy_an_c37_21.0=3
+phy_an_c37_22.0=3
+phy_an_c37_23.0=3
+phy_an_c37_24.0=3
+phy_an_c37_25.0=3
+phy_an_c37_26.0=3
+phy_an_c37_27.0=3
+phy_an_c37_28.0=3
+phy_an_c37_29.0=3
+phy_an_c37_3.0=3
+phy_an_c37_30.0=3
+phy_an_c37_31.0=3
+phy_an_c37_32.0=3
+phy_an_c37_4.0=3
+phy_an_c37_5.0=3
+phy_an_c37_6.0=3
+phy_an_c37_7.0=3
+phy_an_c37_8.0=3
+phy_an_c37_9.0=3
+phy_an_c73_1.0=1
+phy_an_c73_10.0=1
+phy_an_c73_11.0=1
+phy_an_c73_12.0=1
+phy_an_c73_13.0=1
+phy_an_c73_14.0=1
+phy_an_c73_15.0=1
+phy_an_c73_16.0=1
+phy_an_c73_17.0=1
+phy_an_c73_18.0=1
+phy_an_c73_19.0=1
+phy_an_c73_2.0=1
+phy_an_c73_20.0=1
+phy_an_c73_21.0=1
+phy_an_c73_22.0=1
+phy_an_c73_23.0=1
+phy_an_c73_24.0=1
+phy_an_c73_25.0=1
+phy_an_c73_26.0=1
+phy_an_c73_27.0=1
+phy_an_c73_28.0=1
+phy_an_c73_29.0=1
+phy_an_c73_3.0=1
+phy_an_c73_30.0=1
+phy_an_c73_31.0=1
+phy_an_c73_32.0=1
+phy_an_c73_4.0=1
+phy_an_c73_5.0=1
+phy_an_c73_6.0=1
+phy_an_c73_7.0=1
+phy_an_c73_8.0=1
+phy_an_c73_9.0=1
+phy_aux_voltage_enable_1.0=0x1
+phy_aux_voltage_enable_2.0=0x1
+phy_aux_voltage_enable_29.0=0x1
+phy_aux_voltage_enable_3.0=0x1
+phy_aux_voltage_enable_30.0=0x1
+phy_aux_voltage_enable_31.0=0x1
+phy_aux_voltage_enable_32.0=0x1
+phy_aux_voltage_enable_4.0=0x1
+phy_ext_rom_boot.0=0
+phy_ext_rom_boot_1.0=0x0
+phy_ext_rom_boot_2.0=0x0
+phy_ext_rom_boot_29.0=0x0
+phy_ext_rom_boot_3.0=0x0
+phy_ext_rom_boot_30.0=0x0
+phy_ext_rom_boot_31.0=0x0
+phy_ext_rom_boot_32.0=0x0
+phy_ext_rom_boot_4.0=0x0
+phy_line_tx_mode_1.0=1
+phy_line_tx_mode_2.0=1
+phy_line_tx_mode_29.0=1
+phy_line_tx_mode_3.0=1
+phy_line_tx_mode_30.0=1
+phy_line_tx_mode_31.0=1
+phy_line_tx_mode_32.0=1
+phy_line_tx_mode_4.0=1
+phy_rx_polarity_flip_1.0=0x0
+phy_rx_polarity_flip_2.0=0x0
+phy_rx_polarity_flip_29.0=0x0
+phy_rx_polarity_flip_3.0=0x0
+phy_rx_polarity_flip_30.0=0x0
+phy_rx_polarity_flip_31.0=0x0
+phy_rx_polarity_flip_32.0=0x0
+phy_rx_polarity_flip_4.0=0x0
+phy_system_tx_mode_1.0=0
+phy_system_tx_mode_2.0=0
+phy_system_tx_mode_29.0=0
+phy_system_tx_mode_3.0=0
+phy_system_tx_mode_30.0=0
+phy_system_tx_mode_31.0=0
+phy_system_tx_mode_32.0=0
+phy_system_tx_mode_4.0=0
+phy_tx_polarity_flip_1.0=0x0
+phy_tx_polarity_flip_2.0=0x0
+phy_tx_polarity_flip_29.0=0x0
+phy_tx_polarity_flip_3.0=0x0
+phy_tx_polarity_flip_30.0=0x0
+phy_tx_polarity_flip_31.0=0x0
+phy_tx_polarity_flip_32.0=0x0
+phy_tx_polarity_flip_4.0=0x0
+phy_xaui_rx_polarity_flip_1.0=0x0
+phy_xaui_rx_polarity_flip_10.0=0x0
+phy_xaui_rx_polarity_flip_11.0=0x0
+phy_xaui_rx_polarity_flip_12.0=0x0
+phy_xaui_rx_polarity_flip_13.0=0x0
+phy_xaui_rx_polarity_flip_14.0=0x0
+phy_xaui_rx_polarity_flip_15.0=0x0
+phy_xaui_rx_polarity_flip_16.0=0x0
+phy_xaui_rx_polarity_flip_17.0=0x0
+phy_xaui_rx_polarity_flip_18.0=0x0
+phy_xaui_rx_polarity_flip_19.0=0x0
+phy_xaui_rx_polarity_flip_2.0=0x0
+phy_xaui_rx_polarity_flip_20.0=0x0
+phy_xaui_rx_polarity_flip_21.0=0x0
+phy_xaui_rx_polarity_flip_22.0=0x0
+phy_xaui_rx_polarity_flip_23.0=0x0
+phy_xaui_rx_polarity_flip_24.0=0x0
+phy_xaui_rx_polarity_flip_25.0=0x0
+phy_xaui_rx_polarity_flip_26.0=0x0
+phy_xaui_rx_polarity_flip_27.0=0x0
+phy_xaui_rx_polarity_flip_28.0=0x0
+phy_xaui_rx_polarity_flip_29.0=0x0
+phy_xaui_rx_polarity_flip_3.0=0x0
+phy_xaui_rx_polarity_flip_30.0=0x0
+phy_xaui_rx_polarity_flip_31.0=0x0
+phy_xaui_rx_polarity_flip_32.0=0x0
+phy_xaui_rx_polarity_flip_4.0=0x0
+phy_xaui_rx_polarity_flip_5.0=0x0
+phy_xaui_rx_polarity_flip_6.0=0x0
+phy_xaui_rx_polarity_flip_7.0=0x0
+phy_xaui_rx_polarity_flip_8.0=0x0
+phy_xaui_rx_polarity_flip_9.0=0x0
+phy_xaui_tx_polarity_flip_1.0=0x0
+phy_xaui_tx_polarity_flip_10.0=0x0
+phy_xaui_tx_polarity_flip_11.0=0x0
+phy_xaui_tx_polarity_flip_12.0=0x0
+phy_xaui_tx_polarity_flip_13.0=0x0
+phy_xaui_tx_polarity_flip_14.0=0x0
+phy_xaui_tx_polarity_flip_15.0=0x0
+phy_xaui_tx_polarity_flip_16.0=0x0
+phy_xaui_tx_polarity_flip_17.0=0x0
+phy_xaui_tx_polarity_flip_18.0=0x0
+phy_xaui_tx_polarity_flip_19.0=0x0
+phy_xaui_tx_polarity_flip_2.0=0x0
+phy_xaui_tx_polarity_flip_20.0=0x0
+phy_xaui_tx_polarity_flip_21.0=0x0
+phy_xaui_tx_polarity_flip_22.0=0x0
+phy_xaui_tx_polarity_flip_23.0=0x0
+phy_xaui_tx_polarity_flip_24.0=0x0
+phy_xaui_tx_polarity_flip_25.0=0x0
+phy_xaui_tx_polarity_flip_26.0=0x0
+phy_xaui_tx_polarity_flip_27.0=0x0
+phy_xaui_tx_polarity_flip_28.0=0x0
+phy_xaui_tx_polarity_flip_29.0=0x0
+phy_xaui_tx_polarity_flip_3.0=0x0
+phy_xaui_tx_polarity_flip_30.0=0x0
+phy_xaui_tx_polarity_flip_31.0=0x0
+phy_xaui_tx_polarity_flip_32.0=0x0
+phy_xaui_tx_polarity_flip_4.0=0x0
+phy_xaui_tx_polarity_flip_5.0=0x0
+phy_xaui_tx_polarity_flip_6.0=0x0
+phy_xaui_tx_polarity_flip_7.0=0x0
+phy_xaui_tx_polarity_flip_8.0=0x0
+phy_xaui_tx_polarity_flip_9.0=0x0
+port_init_autoneg_10.0=0
+port_init_autoneg_11.0=0
+port_init_autoneg_12.0=0
+port_init_autoneg_13.0=0
+port_init_autoneg_14.0=0
+port_init_autoneg_15.0=0
+port_init_autoneg_16.0=0
+port_init_autoneg_17.0=0
+port_init_autoneg_18.0=0
+port_init_autoneg_19.0=0
+port_init_autoneg_20.0=0
+port_init_autoneg_21.0=0
+port_init_autoneg_22.0=0
+port_init_autoneg_23.0=0
+port_init_autoneg_24.0=0
+port_init_autoneg_25.0=0
+port_init_autoneg_26.0=0
+port_init_autoneg_27.0=0
+port_init_autoneg_28.0=0
+port_init_autoneg_5.0=0
+port_init_autoneg_6.0=0
+port_init_autoneg_7.0=0
+port_init_autoneg_8.0=0
+port_init_autoneg_9.0=0
+port_init_cl72_hg.0=0x11
+port_phy_addr_1.0=0x4
+port_phy_addr_10.0=0x7f
+port_phy_addr_11.0=0x7f
+port_phy_addr_12.0=0x7f
+port_phy_addr_13.0=0x7f
+port_phy_addr_14.0=0x7f
+port_phy_addr_15.0=0x7f
+port_phy_addr_16.0=0x7f
+port_phy_addr_17.0=0x7f
+port_phy_addr_18.0=0x7f
+port_phy_addr_19.0=0x7f
+port_phy_addr_2.0=0x0
+port_phy_addr_20.0=0x7f
+port_phy_addr_21.0=0x7f
+port_phy_addr_22.0=0x7f
+port_phy_addr_23.0=0x7f
+port_phy_addr_24.0=0x7f
+port_phy_addr_25.0=0x7f
+port_phy_addr_26.0=0x7f
+port_phy_addr_27.0=0x7f
+port_phy_addr_28.0=0x7f
+port_phy_addr_29.0=0x54
+port_phy_addr_3.0=0x2c
+port_phy_addr_30.0=0x50
+port_phy_addr_31.0=0x7c
+port_phy_addr_32.0=0x78
+port_phy_addr_4.0=0x28
+port_phy_addr_5.0=0x7f
+port_phy_addr_6.0=0x7f
+port_phy_addr_7.0=0x7f
+port_phy_addr_8.0=0x7f
+port_phy_addr_9.0=0x7f
+port_phy_clause_1.0=0x2d
+port_phy_clause_2.0=0x2d
+port_phy_clause_29.0=0x2d
+port_phy_clause_3.0=0x2d
+port_phy_clause_30.0=0x2d
+port_phy_clause_31.0=0x2d
+port_phy_clause_32.0=0x2d
+port_phy_clause_4.0=0x2d
+port_phy_id0_1.0=0x600d
+port_phy_id0_2.0=0x600d
+port_phy_id0_29.0=0x600d
+port_phy_id0_3.0=0x600d
+port_phy_id0_30.0=0x600d
+port_phy_id0_31.0=0x600d
+port_phy_id0_32.0=0x600d
+port_phy_id0_4.0=0x600d
+port_phy_id1_1.0=0x8500
+port_phy_id1_2.0=0x8500
+port_phy_id1_29.0=0x8500
+port_phy_id1_3.0=0x8500
+port_phy_id1_30.0=0x8500
+port_phy_id1_31.0=0x8500
+port_phy_id1_32.0=0x8500
+port_phy_id1_4.0=0x8500
+portmap_1.0=125:40
+portmap_10.0=33:40
+portmap_11.0=45:40
+portmap_12.0=41:40
+portmap_13.0=53:40
+portmap_14.0=49:40
+portmap_15.0=69:40
+portmap_16.0=65:40
+portmap_17.0=77:40
+portmap_18.0=73:40
+portmap_19.0=93:40
+portmap_2.0=121:40
+portmap_20.0=89:40
+portmap_21.0=101:40
+portmap_22.0=97:40
+portmap_23.0=109:40
+portmap_24.0=105:40
+portmap_25.0=61:40
+portmap_26.0=57:40
+portmap_27.0=81:40
+portmap_28.0=85:40
+portmap_29.0=117:40
+portmap_3.0=13:40
+portmap_30.0=113:40
+portmap_31.0=5:40
+portmap_32.0=1:40
+portmap_4.0=9:40
+portmap_5.0=17:40
+portmap_6.0=21:40
+portmap_7.0=25:40
+portmap_8.0=29:40
+portmap_9.0=37:40
+serdes_firmware_mode_1.0=1
+serdes_firmware_mode_10.0=2
+serdes_firmware_mode_11.0=2
+serdes_firmware_mode_12.0=2
+serdes_firmware_mode_13.0=2
+serdes_firmware_mode_14.0=2
+serdes_firmware_mode_15.0=2
+serdes_firmware_mode_16.0=2
+serdes_firmware_mode_17.0=2
+serdes_firmware_mode_18.0=2
+serdes_firmware_mode_19.0=2
+serdes_firmware_mode_2.0=1
+serdes_firmware_mode_20.0=2
+serdes_firmware_mode_21.0=2
+serdes_firmware_mode_22.0=2
+serdes_firmware_mode_23.0=2
+serdes_firmware_mode_24.0=2
+serdes_firmware_mode_25.0=2
+serdes_firmware_mode_26.0=2
+serdes_firmware_mode_27.0=2
+serdes_firmware_mode_28.0=2
+serdes_firmware_mode_29.0=1
+serdes_firmware_mode_3.0=1
+serdes_firmware_mode_30.0=1
+serdes_firmware_mode_31.0=1
+serdes_firmware_mode_32.0=1
+serdes_firmware_mode_4.0=1
+serdes_firmware_mode_5.0=2
+serdes_firmware_mode_6.0=2
+serdes_firmware_mode_7.0=2
+serdes_firmware_mode_8.0=2
+serdes_firmware_mode_9.0=2
+xgxs_lcpll_xtal_refclk.0=1
+xgxs_rx_lane_map_1.0=0x0123
+xgxs_rx_lane_map_10.0=0x3120
+xgxs_rx_lane_map_11.0=0x3120
+xgxs_rx_lane_map_12.0=0x3120
+xgxs_rx_lane_map_13.0=0x3120
+xgxs_rx_lane_map_14.0=0x3120
+xgxs_rx_lane_map_15.0=0x3120
+xgxs_rx_lane_map_16.0=0x3120
+xgxs_rx_lane_map_17.0=0x3120
+xgxs_rx_lane_map_18.0=0x3120
+xgxs_rx_lane_map_19.0=0x3120
+xgxs_rx_lane_map_2.0=0x0123
+xgxs_rx_lane_map_20.0=0x3120
+xgxs_rx_lane_map_21.0=0x3120
+xgxs_rx_lane_map_22.0=0x3120
+xgxs_rx_lane_map_23.0=0x3120
+xgxs_rx_lane_map_24.0=0x3120
+xgxs_rx_lane_map_25.0=0x2031
+xgxs_rx_lane_map_26.0=0x2031
+xgxs_rx_lane_map_27.0=0x0213
+xgxs_rx_lane_map_28.0=0x0213
+xgxs_rx_lane_map_29.0=0x0123
+xgxs_rx_lane_map_3.0=0x0123
+xgxs_rx_lane_map_30.0=0x0123
+xgxs_rx_lane_map_31.0=0x0123
+xgxs_rx_lane_map_32.0=0x0123
+xgxs_rx_lane_map_4.0=0x0123
+xgxs_rx_lane_map_5.0=0x2031
+xgxs_rx_lane_map_6.0=0x2031
+xgxs_rx_lane_map_7.0=0x2031
+xgxs_rx_lane_map_8.0=0x2031
+xgxs_rx_lane_map_9.0=0x3120
+xgxs_tx_lane_map_1.0=0x0123
+xgxs_tx_lane_map_10.0=0x3120
+xgxs_tx_lane_map_11.0=0x3120
+xgxs_tx_lane_map_12.0=0x3120
+xgxs_tx_lane_map_13.0=0x3120
+xgxs_tx_lane_map_14.0=0x3120
+xgxs_tx_lane_map_15.0=0x3120
+xgxs_tx_lane_map_16.0=0x3120
+xgxs_tx_lane_map_17.0=0x3120
+xgxs_tx_lane_map_18.0=0x3120
+xgxs_tx_lane_map_19.0=0x3120
+xgxs_tx_lane_map_2.0=0x0123
+xgxs_tx_lane_map_20.0=0x3120
+xgxs_tx_lane_map_21.0=0x3120
+xgxs_tx_lane_map_22.0=0x3120
+xgxs_tx_lane_map_23.0=0x3120
+xgxs_tx_lane_map_24.0=0x3120
+xgxs_tx_lane_map_25.0=0x2031
+xgxs_tx_lane_map_26.0=0x2031
+xgxs_tx_lane_map_27.0=0x0213
+xgxs_tx_lane_map_28.0=0x0213
+xgxs_tx_lane_map_29.0=0x0123
+xgxs_tx_lane_map_3.0=0x0123
+xgxs_tx_lane_map_30.0=0x0123
+xgxs_tx_lane_map_31.0=0x0123
+xgxs_tx_lane_map_32.0=0x0123
+xgxs_tx_lane_map_4.0=0x0123
+xgxs_tx_lane_map_5.0=0x1302
+xgxs_tx_lane_map_6.0=0x1302
+xgxs_tx_lane_map_7.0=0x1302
+xgxs_tx_lane_map_8.0=0x1302
+xgxs_tx_lane_map_9.0=0x3120
+
+##########################################
+#skip_L2_USER_ENTRY=0
+phy_aux_voltage_enable=1
+###############################
+serdes_fiber_pref=1
+###############################
+mdio_output_delay.0=0x0d
+###############################
+serdes_sgmii_m=0
+xgxs_lcpll_xtal_refclk=1
+xgxs_lcpll_xtal_refclk.1=1
+xgxs_lcpll_xtal_refclk.2=1
+xgxs_lcpll_xtal_refclk.3=1
+tdma_intr_enable=1
+tslam_intr_enable=1
+tslam_dma_enable.2=1
+tslam_dma_enable.3=1
+#dport_map_port=0
+#dport_map_enable=0
+#dport_map_indexed=0
+#bcm_xlate_port_enable.0=0
+#xgxs_pdetect_1=0
+table_dma_enable.0=1
+table_dma_enable.1=1
+table_dma_enable.2=1
+table_dma_enable.3=1
+serdes_driver_current_lane0_1=2
+serdes_pre_driver_current_lane0_1=2
+serdes_preemphasis_lane0_1=0x8fc0
+serdes_driver_current_lane1_1=2
+serdes_pre_driver_current_lane1_1=2
+serdes_preemphasis_lane1_1=0x8fc0
+serdes_driver_current_lane2_1=2
+serdes_pre_driver_current_lane2_1=2
+serdes_preemphasis_lane2_1=0x8fc0
+serdes_driver_current_lane3_1=2
+serdes_pre_driver_current_lane3_1=2
+serdes_preemphasis_lane3_1=0x8fc0
+serdes_driver_current_lane0_2=3
+serdes_pre_driver_current_lane0_2=2
+serdes_preemphasis_lane0_2=0x8fc0
+serdes_driver_current_lane1_2=3
+serdes_pre_driver_current_lane1_2=2
+serdes_preemphasis_lane1_2=0x8fc0
+serdes_driver_current_lane2_2=3
+serdes_pre_driver_current_lane2_2=2
+serdes_preemphasis_lane2_2=0x8fc0
+serdes_driver_current_lane3_2=3
+serdes_pre_driver_current_lane3_2=2
+serdes_preemphasis_lane3_2=0x8fc0
+serdes_driver_current_lane0_3=2
+serdes_pre_driver_current_lane0_3=2
+serdes_preemphasis_lane0_3=0x8fc0
+serdes_driver_current_lane1_3=2
+serdes_pre_driver_current_lane1_3=2
+serdes_preemphasis_lane1_3=0x8fc0
+serdes_driver_current_lane2_3=2
+serdes_pre_driver_current_lane2_3=2
+serdes_preemphasis_lane2_3=0x8fc0
+serdes_driver_current_lane3_3=2
+serdes_pre_driver_current_lane3_3=2
+serdes_preemphasis_lane3_3=0x8fc0
+serdes_driver_current_lane0_4=2
+serdes_pre_driver_current_lane0_4=2
+serdes_preemphasis_lane0_4=0x8fc0
+serdes_driver_current_lane1_4=2
+serdes_pre_driver_current_lane1_4=2
+serdes_preemphasis_lane1_4=0x8fc0
+serdes_driver_current_lane2_4=2
+serdes_pre_driver_current_lane2_4=2
+serdes_preemphasis_lane2_4=0x8fc0
+serdes_driver_current_lane3_4=2
+serdes_pre_driver_current_lane3_4=2
+serdes_preemphasis_lane3_4=0x8fc0
+serdes_driver_current_lane0_5=4
+serdes_pre_driver_current_lane0_5=4
+serdes_preemphasis_lane0_5=0xbf00
+serdes_driver_current_lane1_5=4
+serdes_pre_driver_current_lane1_5=4
+serdes_preemphasis_lane1_5=0xbf00
+serdes_driver_current_lane2_5=4
+serdes_pre_driver_current_lane2_5=4
+serdes_preemphasis_lane2_5=0xbf00
+serdes_driver_current_lane3_5=4
+serdes_pre_driver_current_lane3_5=4
+serdes_preemphasis_lane3_5=0xbf00
+serdes_driver_current_lane0_6=4
+serdes_pre_driver_current_lane0_6=4
+serdes_preemphasis_lane0_6=0xbb10
+serdes_driver_current_lane1_6=4
+serdes_pre_driver_current_lane1_6=4
+serdes_preemphasis_lane1_6=0xbb10
+serdes_driver_current_lane2_6=4
+serdes_pre_driver_current_lane2_6=4
+serdes_preemphasis_lane2_6=0xbb10
+serdes_driver_current_lane3_6=4
+serdes_pre_driver_current_lane3_6=4
+serdes_preemphasis_lane3_6=0xbb10
+serdes_driver_current_lane0_7=3
+serdes_pre_driver_current_lane0_7=3
+serdes_preemphasis_lane0_7=0xcad0
+serdes_driver_current_lane1_7=3
+serdes_pre_driver_current_lane1_7=3
+serdes_preemphasis_lane1_7=0xcad0
+serdes_driver_current_lane2_7=3
+serdes_pre_driver_current_lane2_7=3
+serdes_preemphasis_lane2_7=0xcad0
+serdes_driver_current_lane3_7=3
+serdes_pre_driver_current_lane3_7=3
+serdes_preemphasis_lane3_7=0xcad0
+serdes_driver_current_lane0_8=3
+serdes_pre_driver_current_lane0_8=3
+serdes_preemphasis_lane0_8=0xcad0
+serdes_driver_current_lane1_8=3
+serdes_pre_driver_current_lane1_8=3
+serdes_preemphasis_lane1_8=0xcad0
+serdes_driver_current_lane2_8=3
+serdes_pre_driver_current_lane2_8=3
+serdes_preemphasis_lane2_8=0xcad0
+serdes_driver_current_lane3_8=3
+serdes_pre_driver_current_lane3_8=3
+serdes_preemphasis_lane3_8=0xcad0
+serdes_driver_current_lane0_9=3
+serdes_pre_driver_current_lane0_9=3
+serdes_preemphasis_lane0_9=0xc2f0
+serdes_driver_current_lane1_9=3
+serdes_pre_driver_current_lane1_9=3
+serdes_preemphasis_lane1_9=0xc2f0
+serdes_driver_current_lane2_9=3
+serdes_pre_driver_current_lane2_9=3
+serdes_preemphasis_lane2_9=0xc2f0
+serdes_driver_current_lane3_9=3
+serdes_pre_driver_current_lane3_9=3
+serdes_preemphasis_lane3_9=0xc2f0
+serdes_driver_current_lane0_10=3
+serdes_pre_driver_current_lane0_10=3
+serdes_preemphasis_lane0_10=0xc6e0
+serdes_driver_current_lane1_10=3
+serdes_pre_driver_current_lane1_10=3
+serdes_preemphasis_lane1_10=0xc6e0
+serdes_driver_current_lane2_10=3
+serdes_pre_driver_current_lane2_10=3
+serdes_preemphasis_lane2_10=0xc6e0
+serdes_driver_current_lane3_10=3
+serdes_pre_driver_current_lane3_10=3
+serdes_preemphasis_lane3_10=0xc6e0
+serdes_driver_current_lane0_11=3
+serdes_pre_driver_current_lane0_11=3
+serdes_preemphasis_lane0_11=0xc2f0
+serdes_driver_current_lane1_11=3
+serdes_pre_driver_current_lane1_11=3
+serdes_preemphasis_lane1_11=0xc2f0
+serdes_driver_current_lane2_11=3
+serdes_pre_driver_current_lane2_11=3
+serdes_preemphasis_lane2_11=0xc2f0
+serdes_driver_current_lane3_11=3
+serdes_pre_driver_current_lane3_11=3
+serdes_preemphasis_lane3_11=0xc2f0
+serdes_driver_current_lane0_12=3
+serdes_pre_driver_current_lane0_12=3
+serdes_preemphasis_lane0_12=0xc2f0
+serdes_driver_current_lane1_12=3
+serdes_pre_driver_current_lane1_12=3
+serdes_preemphasis_lane1_12=0xc2f0
+serdes_driver_current_lane2_12=3
+serdes_pre_driver_current_lane2_12=3
+serdes_preemphasis_lane2_12=0xc2f0
+serdes_driver_current_lane3_12=3
+serdes_pre_driver_current_lane3_12=3
+serdes_preemphasis_lane3_12=0xc2f0
+serdes_driver_current_lane0_13=3
+serdes_pre_driver_current_lane0_13=3
+serdes_preemphasis_lane0_13=0xc2f0
+serdes_driver_current_lane1_13=3
+serdes_pre_driver_current_lane1_13=3
+serdes_preemphasis_lane1_13=0xc2f0
+serdes_driver_current_lane2_13=3
+serdes_pre_driver_current_lane2_13=3
+serdes_preemphasis_lane2_13=0xc2f0
+serdes_driver_current_lane3_13=3
+serdes_pre_driver_current_lane3_13=3
+serdes_preemphasis_lane3_13=0xc2f0
+serdes_driver_current_lane0_14=3
+serdes_pre_driver_current_lane0_14=3
+serdes_preemphasis_lane0_14=0xc2f0
+serdes_driver_current_lane1_14=3
+serdes_pre_driver_current_lane1_14=3
+serdes_preemphasis_lane1_14=0xc2f0
+serdes_driver_current_lane2_14=3
+serdes_pre_driver_current_lane2_14=3
+serdes_preemphasis_lane2_14=0xc2f0
+serdes_driver_current_lane3_14=3
+serdes_pre_driver_current_lane3_14=3
+serdes_preemphasis_lane3_14=0xc2f0
+serdes_driver_current_lane0_15=3
+serdes_pre_driver_current_lane0_15=3
+serdes_preemphasis_lane0_15=0xc2f0
+serdes_driver_current_lane1_15=3
+serdes_pre_driver_current_lane1_15=3
+serdes_preemphasis_lane1_15=0xc2f0
+serdes_driver_current_lane2_15=3
+serdes_pre_driver_current_lane2_15=3
+serdes_preemphasis_lane2_15=0xc2f0
+serdes_driver_current_lane3_15=3
+serdes_pre_driver_current_lane3_15=3
+serdes_preemphasis_lane3_15=0xc2f0
+serdes_driver_current_lane0_16=3
+serdes_pre_driver_current_lane0_16=3
+serdes_preemphasis_lane0_16=0xc2f0
+serdes_driver_current_lane1_16=3
+serdes_pre_driver_current_lane1_16=3
+serdes_preemphasis_lane1_16=0xc2f0
+serdes_driver_current_lane2_16=3
+serdes_pre_driver_current_lane2_16=3
+serdes_preemphasis_lane2_16=0xc2f0
+serdes_driver_current_lane3_16=3
+serdes_pre_driver_current_lane3_16=3
+serdes_preemphasis_lane3_16=0xc2f0
+serdes_driver_current_lane0_17=3
+serdes_pre_driver_current_lane0_17=3
+serdes_preemphasis_lane0_17=0xc2f0
+serdes_driver_current_lane1_17=3
+serdes_pre_driver_current_lane1_17=3
+serdes_preemphasis_lane1_17=0xc2f0
+serdes_driver_current_lane2_17=3
+serdes_pre_driver_current_lane2_17=3
+serdes_preemphasis_lane2_17=0xc2f0
+serdes_driver_current_lane3_17=3
+serdes_pre_driver_current_lane3_17=3
+serdes_preemphasis_lane3_17=0xc2f0
+serdes_driver_current_lane0_18=3
+serdes_pre_driver_current_lane0_18=3
+serdes_preemphasis_lane0_18=0xc2f0
+serdes_driver_current_lane1_18=3
+serdes_pre_driver_current_lane1_18=3
+serdes_preemphasis_lane1_18=0xc2f0
+serdes_driver_current_lane2_18=3
+serdes_pre_driver_current_lane2_18=3
+serdes_preemphasis_lane2_18=0xc2f0
+serdes_driver_current_lane3_18=3
+serdes_pre_driver_current_lane3_18=3
+serdes_preemphasis_lane3_18=0xc2f0
+serdes_driver_current_lane0_19=3
+serdes_pre_driver_current_lane0_19=3
+serdes_preemphasis_lane0_19=0xc2f0
+serdes_driver_current_lane1_19=3
+serdes_pre_driver_current_lane1_19=3
+serdes_preemphasis_lane1_19=0xc2f0
+serdes_driver_current_lane2_19=3
+serdes_pre_driver_current_lane2_19=3
+serdes_preemphasis_lane2_19=0xc2f0
+serdes_driver_current_lane3_19=3
+serdes_pre_driver_current_lane3_19=3
+serdes_preemphasis_lane3_19=0xc2f0
+serdes_driver_current_lane0_20=3
+serdes_pre_driver_current_lane0_20=3
+serdes_preemphasis_lane0_20=0xc2f0
+serdes_driver_current_lane1_20=3
+serdes_pre_driver_current_lane1_20=3
+serdes_preemphasis_lane1_20=0xc2f0
+serdes_driver_current_lane2_20=3
+serdes_pre_driver_current_lane2_20=3
+serdes_preemphasis_lane2_20=0xc2f0
+serdes_driver_current_lane3_20=3
+serdes_pre_driver_current_lane3_20=3
+serdes_preemphasis_lane3_20=0xc2f0
+serdes_driver_current_lane0_21=3
+serdes_pre_driver_current_lane0_21=3
+serdes_preemphasis_lane0_21=0xc6e0
+serdes_driver_current_lane1_21=3
+serdes_pre_driver_current_lane1_21=3
+serdes_preemphasis_lane1_21=0xc6e0
+serdes_driver_current_lane2_21=3
+serdes_pre_driver_current_lane2_21=3
+serdes_preemphasis_lane2_21=0xc6e0
+serdes_driver_current_lane3_21=3
+serdes_pre_driver_current_lane3_21=3
+serdes_preemphasis_lane3_21=0xc6e0
+serdes_driver_current_lane0_22=3
+serdes_pre_driver_current_lane0_22=3
+serdes_preemphasis_lane0_22=0xc6e0
+serdes_driver_current_lane1_22=3
+serdes_pre_driver_current_lane1_22=3
+serdes_preemphasis_lane1_22=0xc6e0
+serdes_driver_current_lane2_22=3
+serdes_pre_driver_current_lane2_22=3
+serdes_preemphasis_lane2_22=0xc6e0
+serdes_driver_current_lane3_22=3
+serdes_pre_driver_current_lane3_22=3
+serdes_preemphasis_lane3_22=0xc6e0
+serdes_driver_current_lane0_23=3
+serdes_pre_driver_current_lane0_23=3
+serdes_preemphasis_lane0_23=0xcad0
+serdes_driver_current_lane1_23=3
+serdes_pre_driver_current_lane1_23=3
+serdes_preemphasis_lane1_23=0xcad0
+serdes_driver_current_lane2_23=3
+serdes_pre_driver_current_lane2_23=3
+serdes_preemphasis_lane2_23=0xcad0
+serdes_driver_current_lane3_23=3
+serdes_pre_driver_current_lane3_23=3
+serdes_preemphasis_lane3_23=0xcad0
+serdes_driver_current_lane0_24=3
+serdes_pre_driver_current_lane0_24=3
+serdes_preemphasis_lane0_24=0xcad0
+serdes_driver_current_lane1_24=3
+serdes_pre_driver_current_lane1_24=3
+serdes_preemphasis_lane1_24=0xcad0
+serdes_driver_current_lane2_24=3
+serdes_pre_driver_current_lane2_24=3
+serdes_preemphasis_lane2_24=0xcad0
+serdes_driver_current_lane3_24=3
+serdes_pre_driver_current_lane3_24=3
+serdes_preemphasis_lane3_24=0xcad0
+serdes_driver_current_lane0_25=5
+serdes_pre_driver_current_lane0_25=5
+serdes_preemphasis_lane0_25=0xc2f0
+serdes_driver_current_lane1_25=5
+serdes_pre_driver_current_lane1_25=5
+serdes_preemphasis_lane1_25=0xc2f0
+serdes_driver_current_lane2_25=5
+serdes_pre_driver_current_lane2_25=5
+serdes_preemphasis_lane2_25=0xc2f0
+serdes_driver_current_lane3_25=5
+serdes_pre_driver_current_lane3_25=5
+serdes_preemphasis_lane3_25=0xc2f0
+serdes_driver_current_lane0_26=5
+serdes_pre_driver_current_lane0_26=5
+serdes_preemphasis_lane0_26=0xc2f0
+serdes_driver_current_lane1_26=5
+serdes_pre_driver_current_lane1_26=5
+serdes_preemphasis_lane1_26=0xc2f0
+serdes_driver_current_lane2_26=5
+serdes_pre_driver_current_lane2_26=5
+serdes_preemphasis_lane2_26=0xc2f0
+serdes_driver_current_lane3_26=5
+serdes_pre_driver_current_lane3_26=5
+serdes_preemphasis_lane3_26=0xc2f0
+serdes_driver_current_lane0_27=5
+serdes_pre_driver_current_lane0_27=5
+serdes_preemphasis_lane0_27=0xc2f0
+serdes_driver_current_lane1_27=5
+serdes_pre_driver_current_lane1_27=5
+serdes_preemphasis_lane1_27=0xc2f0
+serdes_driver_current_lane2_27=5
+serdes_pre_driver_current_lane2_27=5
+serdes_preemphasis_lane2_27=0xc2f0
+serdes_driver_current_lane3_27=5
+serdes_pre_driver_current_lane3_27=5
+serdes_preemphasis_lane3_27=0xc2f0
+serdes_driver_current_lane0_28=8
+serdes_pre_driver_current_lane0_28=6
+serdes_preemphasis_lane0_28=0xc2f0
+serdes_driver_current_lane1_28=8
+serdes_pre_driver_current_lane1_28=6
+serdes_preemphasis_lane1_28=0xc2f0
+serdes_driver_current_lane2_28=8
+serdes_pre_driver_current_lane2_28=6
+serdes_preemphasis_lane2_28=0xc2f0
+serdes_driver_current_lane3_28=8
+serdes_pre_driver_current_lane3_28=6
+serdes_preemphasis_lane3_28=0xc2f0
+serdes_driver_current_lane0_29=2
+serdes_pre_driver_current_lane0_29=2
+serdes_preemphasis_lane0_29=0x8fc0
+serdes_driver_current_lane1_29=2
+serdes_pre_driver_current_lane1_29=2
+serdes_preemphasis_lane1_29=0x8fc0
+serdes_driver_current_lane2_29=2
+serdes_pre_driver_current_lane2_29=2
+serdes_preemphasis_lane2_29=0x8fc0
+serdes_driver_current_lane3_29=2
+serdes_pre_driver_current_lane3_29=2
+serdes_preemphasis_lane3_29=0x8fc0
+serdes_driver_current_lane0_30=2
+serdes_pre_driver_current_lane0_30=2
+serdes_preemphasis_lane0_30=0x8fc0
+serdes_driver_current_lane1_30=2
+serdes_pre_driver_current_lane1_30=2
+serdes_preemphasis_lane1_30=0x8fc0
+serdes_driver_current_lane2_30=2
+serdes_pre_driver_current_lane2_30=2
+serdes_preemphasis_lane2_30=0x8fc0
+serdes_driver_current_lane3_30=2
+serdes_pre_driver_current_lane3_30=2
+serdes_preemphasis_lane3_30=0x8fc0
+serdes_driver_current_lane0_31=2
+serdes_pre_driver_current_lane0_31=2
+serdes_preemphasis_lane0_31=0x8fc0
+serdes_driver_current_lane1_31=2
+serdes_pre_driver_current_lane1_31=2
+serdes_preemphasis_lane1_31=0x8fc0
+serdes_driver_current_lane2_31=2
+serdes_pre_driver_current_lane2_31=2
+serdes_preemphasis_lane2_31=0x8fc0
+serdes_driver_current_lane3_31=2
+serdes_pre_driver_current_lane3_31=2
+serdes_preemphasis_lane3_31=0x8fc0
+serdes_driver_current_lane0_32=2
+serdes_pre_driver_current_lane0_32=2
+serdes_preemphasis_lane0_32=0x8fc0
+serdes_driver_current_lane1_32=2
+serdes_pre_driver_current_lane1_32=2
+serdes_preemphasis_lane1_32=0x8fc0
+serdes_driver_current_lane2_32=2
+serdes_pre_driver_current_lane2_32=2
+serdes_preemphasis_lane2_32=0x8fc0
+serdes_driver_current_lane3_32=2
+serdes_pre_driver_current_lane3_32=2
+serdes_preemphasis_lane3_32=0x8fc0
diff --git a/device/arista/x86_64-arista_7050_qx32/platform_reboot b/device/arista/x86_64-arista_7050_qx32/platform_reboot
new file mode 100755
index 00000000000..da438b8fe52
--- /dev/null
+++ b/device/arista/x86_64-arista_7050_qx32/platform_reboot
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# Copyright (c) 2018 Arista Networks, Inc. All rights reserved.
+# Arista Networks, Inc. Confidential and Proprietary.
+
+# Reboot script for 7050QX-32
+
+from __future__ import print_function
+import sys
+import mmap, os
+import subprocess
+from struct import pack, unpack
+
+class MmapResource( object ):
+ """Resource implementation for a directly-mapped memory region."""
+
+ def __init__( self, path ):
+ try:
+ fd = os.open( path, os.O_RDWR )
+ except EnvironmentError:
+ print( "FAIL can not open scd memory-map resource file" )
+ print( "FAIL are you running on the proper platform?" )
+ sys.exit( 1 )
+ try:
+ size = os.fstat( fd ).st_size
+ except EnvironmentError:
+ print( "FAIL can not fstat scd memory-map resource file" )
+ print( "FAIL are you running on the proper platform?" )
+ sys.exit( 1 )
+ try:
+ self.mmap_ = mmap.mmap( fd, size, mmap.MAP_SHARED,
+ mmap.PROT_READ | mmap.PROT_WRITE )
+ except EnvironmentError:
+ print( "FAIL can not map scd memory-map file" )
+ print( "FAIL are you running on the proper platform?" )
+ sys.exit( 1 )
+ finally:
+ try:
+ # Note that closing the file descriptor has no effect on the memory map
+ os.close( fd )
+ except EnvironmentError:
+ print( "FAIL failed to close scd memory-map file" )
+ sys.exit( 1 )
+
+ def read32( self, addr ):
+ return unpack( ' /sys/devices/pci0000:00/0000:00:02.2/0000:02:00.0/mux
diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json
index 926911ab59d..0eb02957299 100644
--- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json
+++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json
@@ -4,7 +4,8 @@
"0": "0",
"1": "1",
"3": "3",
- "4": "4"
+ "4": "4",
+ "5": "5"
}
},
"MAP_PFC_PRIORITY_TO_QUEUE": {
@@ -12,7 +13,8 @@
"0": "0",
"1": "1",
"3": "3",
- "4": "4"
+ "4": "4",
+ "5": "5"
}
},
"TC_TO_QUEUE_MAP": {
@@ -20,7 +22,8 @@
"0": "0",
"1": "1",
"3": "3",
- "4": "4"
+ "4": "4",
+ "5": "5"
}
},
"DSCP_TO_TC_MAP": {
@@ -71,7 +74,7 @@
"43":"0",
"44":"0",
"45":"0",
- "46":"0",
+ "46":"5",
"47":"0",
"48":"0",
"49":"0",
@@ -93,14 +96,6 @@
},
"SCHEDULER": {
"scheduler.0" : {
- "type":"DWRR",
- "weight": "25"
- },
- "scheduler.1" : {
- "type":"DWRR",
- "weight": "30"
- },
- "scheduler.2" : {
"type":"DWRR",
"weight": "20"
}
@@ -120,24 +115,34 @@
"wred_yellow_enable":"true",
"wred_red_enable":"true",
"ecn":"ecn_all",
- "red_max_threshold":"312000",
- "red_min_threshold":"104000",
- "yellow_max_threshold":"312000",
- "yellow_min_threshold":"104000",
- "green_max_threshold":"312000",
- "green_min_threshold":"104000"
+ "red_max_threshold":"2097152",
+ "red_min_threshold":"1048576",
+ "yellow_max_threshold":"2097152",
+ "yellow_min_threshold":"1048576",
+ "green_max_threshold":"2097152",
+ "green_min_threshold":"1048576",
+ "green_drop_probability":"5",
+ "yellow_drop_probability":"5",
+ "red_drop_probability":"5"
}
},
"QUEUE": {
- "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : {
"scheduler" : "[SCHEDULER|scheduler.0]",
"wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
},
"Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : {
- "scheduler" : "[SCHEDULER|scheduler.1]"
+ "scheduler" : "[SCHEDULER|scheduler.0]"
},
"Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : {
- "scheduler" : "[SCHEDULER|scheduler.2]"
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
}
}
}
diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers.json.j2
new file mode 100644
index 00000000000..ff8125e1871
--- /dev/null
+++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers.json.j2
@@ -0,0 +1,138 @@
+{# Default values which will be used if no actual configura available #}
+{% set default_cable = '300m' %}
+{% set default_speed = '100G' %}
+{% set default_ports_num = 32 -%}
+
+{# Port configuration to cable length look-up table #}
+{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
+{# Roles described in the minigraph #}
+{% set ports2cable = {
+ 'torrouter_server' : '5m',
+ 'leafrouter_torrouter' : '40m',
+ 'spinerouter_leafrouter' : '300m'
+ }
+%}
+
+{%- macro cable_length(port_name) -%}
+ {%- set cable_len = [] -%}
+ {%- for local_port in DEVICE_NEIGHBOR -%}
+ {%- if local_port == port_name -%}
+ {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor_role = neighbor.type -%}
+ {%- set roles1 = switch_role + '_' + neighbor_role %}
+ {%- set roles2 = neighbor_role + '_' + switch_role -%}
+ {%- set roles1 = roles1 | lower -%}
+ {%- set roles2 = roles2 | lower -%}
+ {%- if roles1 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%}
+ {%- elif roles2 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endfor -%}
+ {%- if cable_len -%}
+ {{ cable_len.0 }}
+ {%- else -%}
+ {{ default_cable }}
+ {%- endif -%}
+{% endmacro %}
+
+{%- if DEVICE_METADATA is defined %}
+{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
+{%- endif -%}
+
+{# Generate list of ports if not defined #}
+{% if PORT is not defined %}
+ {% set PORT = [] %}
+ {% if PORT.append("Ethernet0") %}{% endif %}
+ {% if PORT.append("Ethernet1") %}{% endif %}
+ {% if PORT.append("Ethernet2") %}{% endif %}
+ {% if PORT.append("Ethernet3") %}{% endif %}
+ {% for port_idx in range(1,default_ports_num) %}
+ {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %}
+ {% endfor %}
+{% endif -%}
+
+{% set port_names_list = [] %}
+{% for port in PORT %}
+ {%- if port_names_list.append(port) %}{% endif %}
+{% endfor %}
+{% set port_names = port_names_list | join(',') -%}
+
+{
+ "CABLE_LENGTH": {
+ "AZURE": {
+ {% for port in PORT %}
+ {% set cable = cable_length(port) -%}
+ "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %}
+
+ {% endfor %}
+ }
+ },
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "12766208",
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "12766208",
+ "type": "egress",
+ "mode": "static"
+ },
+ "egress_lossy_pool": {
+ "size": "8072396",
+ "type": "egress",
+ "mode": "dynamic"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "xon":"18432",
+ "xoff":"40560",
+ "size":"41808",
+ "dynamic_th":"-3",
+ "xon_offset":"2496"
+ },
+ "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_lossy_pool]",
+ "size":"1518",
+ "dynamic_th":"3"
+ }
+ },
+ "BUFFER_PG": {
+ "{{ port_names }}|3-4": {
+ "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]"
+ },
+ "{{ port_names }}|0-1": {
+ "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]"
+ },
+ "{{ port_names }}|5": {
+ "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]"
+ }
+ },
+ "BUFFER_QUEUE": {
+ "{{ port_names }}|3-4": {
+ "profile" : "[BUFFER_PROFILE|egress_lossless_profile]"
+ },
+ "{{ port_names }}|0-1": {
+ "profile" : "[BUFFER_PROFILE|egress_lossy_profile]"
+ },
+ "{{ port_names }}|5": {
+ "profile" : "[BUFFER_PROFILE|egress_lossy_profile]"
+ }
+ }
+}
diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init
new file mode 100755
index 00000000000..e9bfe2e908a
--- /dev/null
+++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+from __future__ import print_function
+
+import mmap
+import os
+import sys
+from struct import pack, unpack
+
+class MmapResource( object ):
+ """Resource implementation for a directly-mapped memory region."""
+ def __init__( self, path ):
+ try:
+ fd = os.open( path, os.O_RDWR )
+ except EnvironmentError:
+ print( "FAIL can not open scd memory-map resource file" )
+ print( "FAIL are you running on the proper platform?" )
+ sys.exit( 1 )
+ try:
+ size = os.fstat( fd ).st_size
+ except EnvironmentError:
+ print( "FAIL can not fstat scd memory-map resource file" )
+ print( "FAIL are you running on the proper platform?" )
+ sys.exit( 1 )
+ try:
+ self.mmap_ = mmap.mmap( fd, size, mmap.MAP_SHARED,
+ mmap.PROT_READ | mmap.PROT_WRITE )
+ except EnvironmentError:
+ print( "FAIL can not map scd memory-map file" )
+ print( "FAIL are you running on the proper platform?" )
+ sys.exit( 1 )
+ finally:
+ try:
+ # Note that closing the file descriptor has no effect on the memory map
+ os.close( fd )
+ except EnvironmentError:
+ print( "FAIL failed to close scd memory-map file" )
+ sys.exit( 1 )
+ def read32( self, addr ):
+ return unpack( '
+ :param index: An integer, index of the PSU of which to query status
+ :return: Boolean, True if PSU is operating properly, False if PSU is\
+ faulty
+ """
+ status = 0
+ psu_status = self.read_psu_statuses(self.psu[index]['power'])
+ psu_status = int(psu_status, 10)
+ # Check for PSU status
+ if (psu_status == 1):
+ status = 1
+
+ return status
+
+ def get_psu_presence(self, index):
+ """
+ Retrieves the presence status of power supply unit (PSU) defined
+ by index
+ :param index: An integer, index of the PSU of which to query status
+ :return: Boolean, True if PSU is plugged, False if not
+ """
+ status = 0
+ psu_absence = self.read_psu_statuses(self.psu[index]['abs'])
+ psu_absence = (int(psu_absence, 10))
+ # Check for PSU presence
+ if (psu_absence == 0):
+ status = 1
+
+ return status
diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py
old mode 100755
new mode 100644
index f1e6b1daa3e..c361659b0f1
--- a/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py
+++ b/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py
@@ -13,12 +13,11 @@
class SfpUtil(SfpUtilBase):
"""Platform-specific SfpUtil class"""
- PORT_START = 0
- PORT_END = 31
+ PORT_START = 1
+ PORT_END = 32
PORTS_IN_BLOCK = 32
_port_to_eeprom_mapping = {}
- qsfp_ports = range(0, PORTS_IN_BLOCK + 1)
@property
def port_start(self):
@@ -30,7 +29,7 @@ def port_end(self):
@property
def qsfp_ports(self):
- return range(0, self.PORTS_IN_BLOCK + 1)
+ return range(self.PORT_START, self.PORTS_IN_BLOCK + 1)
@property
def port_to_eeprom_mapping(self):
@@ -41,7 +40,10 @@ def __init__(self):
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
for x in range(self.PORT_START, self.PORT_END + 1):
- self.port_to_eeprom_mapping[x] = eeprom_path.format( x + 26 )
+ if self.port_start == 1:
+ self.port_to_eeprom_mapping[x] = eeprom_path.format((x - 1) + 26)
+ else:
+ self.port_to_eeprom_mapping[x] = eeprom_path.format(x + 26)
SfpUtilBase.__init__(self)
def get_presence(self, port_num):
@@ -60,8 +62,14 @@ def get_presence(self, port_num):
# content is a string containing the hex representation of the register
reg_value = int(content, 16)
+ # Determind if port_num start from 1 or 0
+ if self.port_start == 1:
+ bit_index = port_num - 1
+ else:
+ bit_index = port_num
+
# Mask off the bit corresponding to our port
- mask = (1 << port_num)
+ mask = (1 << bit_index)
# ModPrsL is active low
if reg_value & mask == 0:
@@ -85,8 +93,14 @@ def get_low_power_mode(self, port_num):
# content is a string containing the hex representation of the register
reg_value = int(content, 16)
+ # Determind if port_num start from 1 or 0
+ if self.port_start == 1:
+ bit_index = port_num - 1
+ else:
+ bit_index = port_num
+
# Mask off the bit corresponding to our port
- mask = (1 << port_num)
+ mask = (1 << bit_index)
# LPMode is active high
if reg_value & mask == 0:
@@ -95,8 +109,96 @@ def get_low_power_mode(self, port_num):
return True
def set_low_power_mode(self, port_num, lpmode):
- raise NotImplementedError
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ try:
+ reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_lpmode", "r+")
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ content = reg_file.readline().rstrip()
+
+ # content is a string containing the hex representation of the register
+ reg_value = int(content, 16)
+
+ # Determind if port_num start from 1 or 0
+ if self.port_start == 1:
+ bit_index = port_num - 1
+ else:
+ bit_index = port_num
+
+ # Mask off the bit corresponding to our port
+ mask = (1 << bit_index)
+
+ # LPMode is active high; set or clear the bit accordingly
+ if lpmode is True:
+ reg_value = reg_value | mask
+ else:
+ reg_value = reg_value & ~mask
+
+ # Convert our register value back to a hex string and write back
+ content = hex(reg_value).strip('L')
+
+ reg_file.seek(0)
+ reg_file.write(content)
+ reg_file.close()
+
+ return True
def reset(self, port_num):
- raise NotImplementedError
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ try:
+ reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_reset", "r+")
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ content = reg_file.readline().rstrip()
+
+ # File content is a string containing the hex representation of the
+ # register
+ reg_value = int(content, 16)
+
+ # Determind if port_num start from 1 or 0
+ if self.port_start == 1:
+ bit_index = port_num - 1
+ else:
+ bit_index = port_num
+
+ # Mask off the bit corresponding to our port
+ mask = (1 << bit_index)
+
+ # ResetL is active low
+ reg_value = reg_value & ~mask
+
+ # Convert our register value back to a hex string and write back
+ reg_file.seek(0)
+ reg_file.write(hex(reg_value).rstrip('L'))
+ reg_file.close()
+
+ # Sleep 1 second to allow it to settle
+ time.sleep(1)
+ # Flip the bit back high and write back to the register to take port
+ # out of reset
+ try:
+ reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_reset", "w")
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ reg_value = reg_value | mask
+ reg_file.seek(0)
+ reg_file.write(hex(reg_value).rstrip('L'))
+ reg_file.close()
+
+ return True
+
+ def get_transceiver_change_event(self, timeout=0):
+ raise NotImplementedError
diff --git a/device/celestica/x86_64-cel_seastone-r0/sensors.conf b/device/celestica/x86_64-cel_seastone-r0/sensors.conf
index e25717ac589..11461a0afef 100644
--- a/device/celestica/x86_64-cel_seastone-r0/sensors.conf
+++ b/device/celestica/x86_64-cel_seastone-r0/sensors.conf
@@ -62,3 +62,17 @@ chip "dx010_lm75b-i2c-*-4e"
label temp1 "Rear-panel temp sensor 2"
set temp1_max 43
set temp1_max_hyst 28
+
+chip "emc2305-i2c-*-2e"
+ label fan2 "fan1"
+ label fan1 "fan2"
+ label fan4 "fan3"
+ label fan5 "fan4"
+ label fan3 "fan5"
+
+chip "emc2305-i2c-*-4d"
+ label fan2 "fan1"
+ label fan4 "fan2"
+ label fan5 "fan3"
+ label fan3 "fan4"
+ label fan1 "fan5"
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/buffers.json.j2 b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/buffers.json.j2
new file mode 100644
index 00000000000..08e21e428b6
--- /dev/null
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/buffers.json.j2
@@ -0,0 +1,70 @@
+{# Default values which will be used if no actual configura available #}
+{% set default_cable = '40m' %}
+{% set default_ports_num = 54 -%}
+
+{# Port configuration to cable length look-up table #}
+{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
+{# Roles described in the minigraph #}
+{% set ports2cable = {
+ 'torrouter_server' : '5m',
+ 'leafrouter_torrouter' : '40m',
+ 'spinerouter_leafrouter' : '300m'
+ }
+%}
+
+{%- macro cable_length(port_name) -%}
+ {%- set cable_len = [] -%}
+ {%- for local_port in DEVICE_NEIGHBOR -%}
+ {%- if local_port == port_name -%}
+ {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor_role = neighbor.type -%}
+ {%- set roles1 = switch_role + '_' + neighbor_role %}
+ {%- set roles2 = neighbor_role + '_' + switch_role -%}
+ {%- set roles1 = roles1 | lower -%}
+ {%- set roles2 = roles2 | lower -%}
+ {%- if roles1 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%}
+ {%- elif roles2 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endfor -%}
+ {%- if cable_len -%}
+ {{ cable_len.0 }}
+ {%- else -%}
+ {{ default_cable }}
+ {%- endif -%}
+{% endmacro %}
+
+{%- if DEVICE_METADATA is defined %}
+{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
+{%- endif -%}
+
+{# Generate list of ports if not defined #}
+{% if PORT is not defined %}
+ {% set PORT = [] %}
+ {% for port_idx in range(1,default_ports_num+1) %}
+ {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
+ {% endfor %}
+{% endif -%}
+
+{% set port_names_list = [] %}
+{% for port in PORT %}
+ {%- if port_names_list.append(port) %}{% endif %}
+{% endfor %}
+{% set port_names = port_names_list | join(',') -%}
+
+{
+ "CABLE_LENGTH": {
+ "AZURE": {
+ {% for port in PORT %}
+ {% set cable = cable_length(port) -%}
+ "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %}
+
+ {% endfor %}
+ }
+ }
+}
+
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/pg_profile_lookup.ini b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/pg_profile_lookup.ini
new file mode 100644
index 00000000000..a65244e69b5
--- /dev/null
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/pg_profile_lookup.ini
@@ -0,0 +1,21 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold
+ 1000 5m 34816 18432 16384 0
+ 10000 5m 34816 18432 16384 0
+ 25000 5m 34816 18432 16384 0
+ 40000 5m 34816 18432 16384 0
+ 50000 5m 34816 18432 16384 0
+ 100000 5m 36864 18432 18432 0
+ 1000 40m 36864 18432 18432 0
+ 10000 40m 36864 18432 18432 0
+ 25000 40m 39936 18432 21504 0
+ 40000 40m 41984 18432 23552 0
+ 50000 40m 41984 18432 23552 0
+ 100000 40m 54272 18432 35840 0
+ 1000 300m 49152 18432 30720 0
+ 10000 300m 49152 18432 30720 0
+ 25000 300m 71680 18432 53248 0
+ 40000 300m 94208 18432 75776 0
+ 50000 300m 94208 18432 75776 0
+ 100000 300m 184320 18432 165888 0
+
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini
index b9a831f22e8..95190282b25 100644
--- a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini
@@ -1,33 +1,55 @@
# name lanes
-Ethernet0 1
-Ethernet4 2
-Ethernet8 3
-Ethernet12 4
-Ethernet16 5
-Ethernet20 6
-Ethernet24 7
-Ethernet28 8
-Ethernet32 9
-Ethernet36 10
-Ethernet40 11
-Ethernet44 12
-Ethernet48 13
-Ethernet52 14
-Ethernet56 15
-Ethernet60 16
-Ethernet64 17
-Ethernet68 18
-Ethernet72 19
-Ethernet76 20
-Ethernet80 21
-Ethernet84 22
-Ethernet88 23
-Ethernet92 24
-Ethernet96 25
-Ethernet100 26
-Ethernet104 27
-Ethernet108 28
-Ethernet112 29
-Ethernet116 30
-Ethernet120 31
-Ethernet124 32
+Ethernet1 4
+Ethernet2 5
+Ethernet3 6
+Ethernet4 8
+Ethernet5 9
+Ethernet6 10
+Ethernet7 12
+Ethernet8 13
+Ethernet9 14
+Ethernet10 16
+Ethernet11 17
+Ethernet12 18
+Ethernet13 20
+Ethernet14 21
+Ethernet15 22
+Ethernet16 24
+Ethernet17 25
+Ethernet18 26
+Ethernet19 28
+Ethernet20 30
+Ethernet21 31
+Ethernet22 32
+Ethernet23 34
+Ethernet24 35
+Ethernet25 40
+Ethernet26 41
+Ethernet27 43
+Ethernet28 36
+Ethernet29 37
+Ethernet30 39
+Ethernet31 44
+Ethernet32 45
+Ethernet33 46
+Ethernet34 47
+Ethernet35 80
+Ethernet36 81
+Ethernet37 82
+Ethernet38 88
+Ethernet39 89
+Ethernet40 90
+Ethernet41 84
+Ethernet42 85
+Ethernet43 86
+Ethernet44 87
+Ethernet45 92
+Ethernet46 93
+Ethernet47 94
+Ethernet48 95
+Ethernet49 52,53,54,55
+Ethernet50 56,57,58,59
+Ethernet51 60,61,62,63
+Ethernet52 68,69,70,71
+Ethernet53 72,73,74,75
+Ethernet54 76,77,78,79
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/qos.json b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/qos.json
new file mode 100644
index 00000000000..b9dc80abb07
--- /dev/null
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/qos.json
@@ -0,0 +1,133 @@
+{
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"0",
+ "1":"0",
+ "2":"0",
+ "3":"0",
+ "4":"0",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"1",
+ "10":"1",
+ "11":"1",
+ "12":"1",
+ "13":"1",
+ "14":"1",
+ "15":"1",
+ "16":"2",
+ "17":"2",
+ "18":"2",
+ "19":"2",
+ "20":"2",
+ "21":"2",
+ "22":"2",
+ "23":"2",
+ "24":"3",
+ "25":"3",
+ "26":"3",
+ "27":"3",
+ "28":"3",
+ "29":"3",
+ "30":"3",
+ "31":"3",
+ "32":"4",
+ "33":"4",
+ "34":"4",
+ "35":"4",
+ "36":"4",
+ "37":"4",
+ "38":"4",
+ "39":"4",
+ "40":"5",
+ "41":"5",
+ "42":"5",
+ "43":"5",
+ "44":"5",
+ "45":"5",
+ "46":"5",
+ "47":"5",
+ "48":"6",
+ "49":"6",
+ "50":"6",
+ "51":"6",
+ "52":"6",
+ "53":"6",
+ "54":"6",
+ "55":"6",
+ "56":"7",
+ "57":"7",
+ "58":"7",
+ "59":"7",
+ "60":"7",
+ "61":"7",
+ "62":"7",
+ "63":"7"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0": {
+ "type":"DWRR",
+ "weight": "25"
+ },
+ "scheduler.1": {
+ "type":"DWRR",
+ "weight": "30"
+ },
+ "scheduler.2": {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PORT_QOS_MAP": {
+ "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54": {
+ "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
+ "pfc_enable": "3,4"
+ }
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSY": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "red_max_threshold":"32760",
+ "red_min_threshold":"4095",
+ "yellow_max_threshold":"32760",
+ "yellow_min_threshold":"4095",
+ "green_max_threshold": "32760",
+ "green_min_threshold": "4095"
+ },
+ "AZURE_LOSSLESS": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "red_max_threshold":"32760",
+ "red_min_threshold":"4095",
+ "yellow_max_threshold":"32760",
+ "yellow_min_threshold":"4095",
+ "green_max_threshold": "32760",
+ "green_min_threshold": "4095"
+ }
+ },
+ "QUEUE": {
+ "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": {
+ "scheduler" : "[SCHEDULER|scheduler.1]"
+ },
+ "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": {
+ "scheduler" : "[SCHEDULER|scheduler.2]"
+ },
+ "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": {
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]"
+ },
+
+ "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": {
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]"
+ },
+ "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|3-4": {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ }
+ }
+}
+
+
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/sai.profile b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/sai.profile
index 2eb3ce5f612..9842dcf57fa 100644
--- a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/sai.profile
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/sai.profile
@@ -1 +1,3 @@
BOARD_CONFIG_FILE_PATH=/etc/centec/E582-48x6q.json
+SAI_INIT_CONFIG_FILE=/etc/centec/E582-48x6q-chip-profile.txt
+SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/etc/centec/E582-48x6q-datapath-cfg.txt
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/fancontrol b/device/centec/x86_64-centec_e582_48x6q-r0/fancontrol
new file mode 100644
index 00000000000..886a4bc6c03
--- /dev/null
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/fancontrol
@@ -0,0 +1,11 @@
+# Configuration file generated by pwmconfig, changes will be lost
+INTERVAL=10
+DEVPATH=hwmon0= hwmon5=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-15/15-002f
+DEVNAME=hwmon0=acpitz hwmon5=adt7470
+FCTEMPS=hwmon5/device/pwm4=hwmon0/temp1_input hwmon5/device/pwm3=hwmon0/temp1_input hwmon5/device/pwm2=hwmon0/temp1_input hwmon5/device/pwm1=hwmon0/temp1_input
+FCFANS=hwmon5/device/pwm4=hwmon5/device/fan4_input hwmon5/device/pwm3=hwmon5/device/fan3_input hwmon5/device/pwm2=hwmon5/device/fan2_input hwmon5/device/pwm1=hwmon5/device/fan1_input
+MINTEMP=hwmon5/device/pwm4=20 hwmon5/device/pwm3=20 hwmon5/device/pwm2=20 hwmon5/device/pwm1=20
+MAXTEMP=hwmon5/device/pwm4=60 hwmon5/device/pwm3=60 hwmon5/device/pwm2=60 hwmon5/device/pwm1=60
+MINSTART=hwmon5/device/pwm4=150 hwmon5/device/pwm3=12 hwmon5/device/pwm2=12 hwmon5/device/pwm1=150
+MINSTOP=hwmon5/device/pwm4=0 hwmon5/device/pwm3=12 hwmon5/device/pwm2=12 hwmon5/device/pwm1=0
+MAXPWM= hwmon5/device/pwm4=150
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/installer.conf b/device/centec/x86_64-centec_e582_48x6q-r0/installer.conf
index 5e62742c11b..7d60bf73d36 100644
--- a/device/centec/x86_64-centec_e582_48x6q-r0/installer.conf
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/installer.conf
@@ -1 +1,2 @@
CONSOLE_SPEED=115200
+ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="acpi_enforce_resources=no"
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/eeprom.py b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/eeprom.py
new file mode 100644
index 00000000000..3fd55c63d8b
--- /dev/null
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/eeprom.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+#############################################################################
+# Centec E582-48X6Q
+#
+# Platform and model specific eeprom subclass, inherits from the base class,
+# and provides the followings:
+# - the eeprom format definition
+# - specific encoder/decoder if there is special need
+#############################################################################
+
+try:
+ import exceptions
+ import binascii
+ import time
+ import optparse
+ import warnings
+ import os
+ import sys
+ import subprocess
+ from sonic_eeprom import eeprom_base
+ from sonic_eeprom import eeprom_tlvinfo
+except ImportError, e:
+ raise ImportError (str(e) + "- required module not found")
+
+
+class board(eeprom_tlvinfo.TlvInfoDecoder):
+
+ def __init__(self, name, path, cpld_root, ro):
+ self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0057/eeprom"
+ super(board, self).__init__(self.eeprom_path, 0, '', True)
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py
new file mode 100644
index 00000000000..d25bf6f8b47
--- /dev/null
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python
+#
+# led_control.py
+#
+# Platform-specific LED control functionality for SONiC
+#
+
+try:
+ from sonic_led.led_control_base import LedControlBase
+ import swsssdk
+ import threading
+ import os
+ import logging
+ import struct
+ import time
+ import syslog
+ from socket import *
+ from select import *
+except ImportError, e:
+ raise ImportError(str(e) + " - required module not found")
+
+
+def DBG_PRINT(str):
+ syslog.openlog("centec-led")
+ syslog.syslog(syslog.LOG_INFO, str)
+ syslog.closelog()
+
+class LedControl(LedControlBase):
+ """Platform specific LED control class"""
+ SONIC_PORT_NAME_PREFIX = "Ethernet"
+ LED_MODE_UP = [11, 1]
+ LED_MODE_DOWN = [7, 2]
+
+ def _initSystemLed(self):
+ try:
+ with open(self.f_led.format("system"), 'w') as led_file:
+ led_file.write("5")
+ DBG_PRINT("init system led to normal")
+ with open(self.f_led.format("idn"), 'w') as led_file:
+ led_file.write("1")
+ DBG_PRINT("init idn led to off")
+ except IOError as e:
+ DBG_PRINT(str(e))
+
+ def _initPanelLed(self):
+ with open(self.f_led.format("port1"), 'r') as led_file:
+ shouldInit = (int(led_file.read()) == 0)
+
+ if shouldInit == True:
+ for (port, ctlid, defmode) in self.led_mapping[1:59]:
+ data = struct.pack('=HHHBBH', 0, 7, 4, ctlid, defmode, port)
+ self.udpClient.sendto(data, ('localhost', 8101))
+
+ data = struct.pack('=HHHBB34B', 0, 3, 36, 34, 0, *[x[0] for x in self.led_mapping[1:35]])
+ self.udpClient.sendto(data, ('localhost', 8101))
+ data = struct.pack('=HHHBB24B', 0, 3, 26, 24, 1, *[x[0] for x in self.led_mapping[35:59]])
+ self.udpClient.sendto(data, ('localhost', 8101))
+
+ data = struct.pack('=HHHB', 0, 5, 1, 1)
+ self.udpClient.sendto(data, ('localhost', 8101))
+
+ for idx in range(1, 55):
+ (port, ctlid, defmode) = self.led_mapping[idx]
+ with open(self.f_led.format("port{}".format(idx)), 'w') as led_file:
+ led_file.write(str(defmode))
+ DBG_PRINT("init port{} led to mode={}".format(idx, defmode))
+
+ for idx in range(1, 55):
+ (port, ctlid, defmode) = self.led_mapping[idx]
+ with open(self.f_led.format("port{}".format(idx)), 'r') as led_file:
+ defmode = int(led_file.read())
+ data = struct.pack('=HHHBBH', 0, 7, 4, ctlid, defmode, port)
+ self.udpClient.sendto(data, ('localhost', 8101))
+ DBG_PRINT("init port{} led to mode={}".format(idx, defmode))
+
+ def _initDefaultConfig(self):
+ DBG_PRINT("start init led")
+ while True:
+ try:
+ r_sel = [self.udpClient]
+ echo_req = struct.pack('=HHH', 0, 1, 0)
+ self.udpClient.sendto(echo_req, ('localhost', 8101))
+ result = select(r_sel, [], [], 1)
+ if self.udpClient in result[0]:
+ echo_rsp, srv_addr = self.udpClient.recvfrom(1024)
+ if echo_rsp:
+ break
+ DBG_PRINT("connect to sdk rpc server timeout, try again.")
+ except IOError as e:
+ DBG_PRINT(str(e))
+
+ DBG_PRINT("connect to sdk rpc server success.")
+
+ self._initSystemLed()
+ self._initPanelLed()
+
+ DBG_PRINT("init led done")
+
+
+ # Helper method to map SONiC port name to index
+ def _port_name_to_index(self, port_name):
+ # Strip "Ethernet" off port name
+ if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX):
+ return -1
+
+ port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):])
+ return port_idx
+
+ def _port_state_to_mode(self, port_idx, state):
+ if state == "up":
+ return self.LED_MODE_UP[0] if (port_idx < 49) else self.LED_MODE_UP[1]
+ else:
+ return self.LED_MODE_DOWN[0] if (port_idx < 49) else self.LED_MODE_DOWN[1]
+
+ def _port_led_mode_update(self, port_idx, ledMode):
+ with open(self.f_led.format("port{}".format(port_idx)), 'w') as led_file:
+ led_file.write(str(ledMode))
+ (port, ctlid) = (self.led_mapping[port_idx][0], self.led_mapping[port_idx][1])
+ data = struct.pack('=HHHBBH', 0, 7, 4, ctlid, ledMode, port)
+ self.udpClient.sendto(data, ('localhost', 8101))
+
+ # Concrete implementation of port_link_state_change() method
+ def port_link_state_change(self, portname, state):
+ port_idx = self._port_name_to_index(portname)
+ ledMode = self._port_state_to_mode(port_idx, state)
+ with open(self.f_led.format("port{}".format(port_idx)), 'r') as led_file:
+ saveMode = int(led_file.read())
+
+ if ledMode == saveMode:
+ return
+
+ self._port_led_mode_update(port_idx, ledMode)
+ DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode))
+
+ # Constructor
+ def __init__(self):
+ # [macid, ctlid, defaultmode]
+ self.led_mapping = [(0, 0, 0)] # resv
+ self.led_mapping.extend([(4, 0, 7), (5, 0, 7), (6, 0, 7), (8, 0, 7), (9, 0, 7), (10, 0, 7), (12, 0, 7), (13, 0, 7)]) # panel port 1~8
+ self.led_mapping.extend([(14, 0, 7), (16, 0, 7), (17, 0, 7), (18, 0, 7), (20, 0, 7), (21, 0, 7), (22, 0, 7), (24, 0, 7)]) # panel port 9~16
+ self.led_mapping.extend([(25, 0, 7), (26, 0, 7), (28, 0, 7), (30, 0, 7), (31, 0, 7), (32, 0, 7), (34, 0, 7), (35, 0, 7)]) # panel port 17~24
+ self.led_mapping.extend([(48, 0, 7), (49, 0, 7), (51, 0, 7), (36, 0, 7), (37, 0, 7), (39, 0, 7), (55, 0, 7), (54, 0, 7)]) # panel port 25~32
+ self.led_mapping.extend([(53, 0, 7), (52, 0, 7), (52, 1, 7), (53, 1, 7), (54, 1, 7), (55, 1, 7), (38, 1, 7), (37, 1, 7)]) # panel port 33~40
+ self.led_mapping.extend([(36, 1, 7), (51, 1, 7), (50, 1, 7), (49, 1, 7), (48, 1, 7), (34, 1, 7), (33, 1, 7), (32, 1, 7)]) # panel port 41~48
+ self.led_mapping.extend([(28, 1, 2), (24, 1, 2), (20, 1, 2), (12, 1, 2), (8, 1, 2), (4, 1, 2)]) # panel port 49~54
+ self.led_mapping.extend([(0, 1, 2), (0, 1, 2), (0, 1, 2), (0, 1, 2), (0, 1, 2), (0, 1, 2)])
+
+ self.f_led = "/sys/class/leds/{}/brightness"
+
+ self.udpClient = socket(AF_INET, SOCK_DGRAM)
+
+ self._initDefaultConfig()
+
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/psuutil.py b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/psuutil.py
new file mode 100644
index 00000000000..5f8ba030c1f
--- /dev/null
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/psuutil.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+
+#############################################################################
+# Mellanox
+#
+# Module contains an implementation of SONiC PSU Base API and
+# provides the PSUs status which are available in the platform
+#
+#############################################################################
+
+import os.path
+
+try:
+ from sonic_psu.psu_base import PsuBase
+except ImportError as e:
+ raise ImportError (str(e) + "- required module not found")
+
+class PsuUtil(PsuBase):
+ """Platform-specific PSUutil class"""
+
+ def __init__(self):
+ PsuBase.__init__(self)
+
+ self.psu_path = "/sys/class/psu/psu{}/"
+ self.psu_presence = "psu_presence"
+ self.psu_oper_status = "psu_status"
+
+ def get_num_psus(self):
+ """
+ Retrieves the number of PSUs available on the device
+
+ :return: An integer, the number of PSUs available on the device
+ """
+ return 2
+
+ def get_psu_status(self, index):
+ """
+ Retrieves the oprational status of power supply unit (PSU) defined
+ by 1-based index
+
+ :param index: An integer, 1-based index of the PSU of which to query status
+ :return: Boolean, True if PSU is operating properly, False if PSU is faulty
+ """
+ if index is None:
+ return False
+
+ status = 0
+ try:
+ with open(self.psu_path.format(index) + self.psu_oper_status, 'r') as power_status:
+ status = int(power_status.read())
+ except IOError:
+ return False
+
+ return status == 0
+
+ def get_psu_presence(self, index):
+ """
+ Retrieves the presence status of power supply unit (PSU) defined
+ by 1-based index
+
+ :param index: An integer, 1-based index of the PSU of which to query status
+ :return: Boolean, True if PSU is plugged, False if not
+ """
+ if index is None:
+ return False
+
+ status = 0
+ try:
+ with open(self.psu_path.format(index) + self.psu_presence, 'r') as presence_status:
+ status = int(presence_status.read())
+ except IOError:
+ return False
+
+ return status == 0
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/sfputil.py b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/sfputil.py
new file mode 100644
index 00000000000..7bb1ac0d419
--- /dev/null
+++ b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/sfputil.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+
+# sfputil.py
+#
+# Platform-specific SFP transceiver interface for SONiC
+#
+
+try:
+ import time
+ import os
+ import logging
+ import struct
+ import syslog
+ from socket import *
+ from select import *
+ from sonic_sfp.sfputilbase import SfpUtilBase
+except ImportError as e:
+ raise ImportError("%s - required module not found" % str(e))
+
+
+
+def DBG_PRINT(str):
+ print str + "\n"
+
+
+class SfpUtil(SfpUtilBase):
+ """Platform-specific SfpUtil class"""
+ SONIC_PORT_NAME_PREFIX = "Ethernet"
+ PORT_START = 1
+ PORT_END = 54
+ PORTS_IN_BLOCK = 54
+
+ @property
+ def port_start(self):
+ return self.PORT_START
+
+ @property
+ def port_end(self):
+ return self.PORT_END
+
+ @property
+ def qsfp_ports(self):
+ return range(49, self.PORTS_IN_BLOCK + 1)
+
+ @property
+ def port_to_eeprom_mapping(self):
+ return self.eeprom_mapping
+
+ def is_logical_port(self, port_name):
+ return True
+
+ def get_logical_to_physical(self, port_name):
+ if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX):
+ return None
+
+ port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):])
+
+ return [port_idx]
+
+ def get_eeprom_data(self, port):
+ (ctlid, devid) = self.fiber_mapping[port]
+ offset = (128 if port in self.qsfp_ports else 0)
+ r_sel = [self.udpClient]
+ req = struct.pack('=HHHBBHIBBBBI',
+ 0, 9, 16, # lchip/msgtype/msglen
+ ctlid, # uint8 ctl_id
+ devid, # uint8 slave_dev_id
+ 0x50, # uint16 dev_addr
+ (1< self.port_end:
+ return False
+ try:
+ with open(self.f_sfp_present.format(port_num), 'r') as sfp_file:
+ return 1 == int(sfp_file.read())
+ except IOError as e:
+ DBG_PRINT(str(e))
+
+ return False
+
+ def get_low_power_mode(self, port_num):
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ return False
+
+ def set_low_power_mode(self, port_num, lpmode):
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ return False
+
+ def reset(self, port_num):
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ return False
+
diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2
index 10f9da575a1..782dc528f71 100644
--- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2
+++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2
@@ -69,22 +69,17 @@
},
"BUFFER_POOL": {
"ingress_lossless_pool": {
- "size": "7274496",
- "type": "ingress",
- "mode": "dynamic"
- },
- "ingress_lossy_pool": {
- "size": "5491712",
+ "size": "12766208",
"type": "ingress",
"mode": "dynamic"
},
"egress_lossless_pool": {
- "size": "7274496",
+ "size": "12766208",
"type": "egress",
"mode": "static"
},
"egress_lossy_pool": {
- "size": "5491712",
+ "size": "8072396",
"type": "egress",
"mode": "dynamic"
}
@@ -99,14 +94,14 @@
"xon_offset":"2496"
},
"ingress_lossy_profile": {
- "pool":"[BUFFER_POOL|ingress_lossy_pool]",
- "size":"1518",
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
"dynamic_th":"3"
},
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "static_th":"7274496"
+ "static_th":"12766208"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossy_pool]",
@@ -120,6 +115,9 @@
},
"{{ port_names }}|0-1": {
"profile" : "[BUFFER_PROFILE|ingress_lossy_profile]"
+ },
+ "{{ port_names }}|5": {
+ "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]"
}
},
"BUFFER_QUEUE": {
@@ -128,6 +126,9 @@
},
"{{ port_names }}|0-1": {
"profile" : "[BUFFER_PROFILE|egress_lossy_profile]"
+ },
+ "{{ port_names }}|5": {
+ "profile" : "[BUFFER_PROFILE|egress_lossy_profile]"
}
}
}
diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json
index 926911ab59d..0eb02957299 100644
--- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json
+++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json
@@ -4,7 +4,8 @@
"0": "0",
"1": "1",
"3": "3",
- "4": "4"
+ "4": "4",
+ "5": "5"
}
},
"MAP_PFC_PRIORITY_TO_QUEUE": {
@@ -12,7 +13,8 @@
"0": "0",
"1": "1",
"3": "3",
- "4": "4"
+ "4": "4",
+ "5": "5"
}
},
"TC_TO_QUEUE_MAP": {
@@ -20,7 +22,8 @@
"0": "0",
"1": "1",
"3": "3",
- "4": "4"
+ "4": "4",
+ "5": "5"
}
},
"DSCP_TO_TC_MAP": {
@@ -71,7 +74,7 @@
"43":"0",
"44":"0",
"45":"0",
- "46":"0",
+ "46":"5",
"47":"0",
"48":"0",
"49":"0",
@@ -93,14 +96,6 @@
},
"SCHEDULER": {
"scheduler.0" : {
- "type":"DWRR",
- "weight": "25"
- },
- "scheduler.1" : {
- "type":"DWRR",
- "weight": "30"
- },
- "scheduler.2" : {
"type":"DWRR",
"weight": "20"
}
@@ -120,24 +115,34 @@
"wred_yellow_enable":"true",
"wred_red_enable":"true",
"ecn":"ecn_all",
- "red_max_threshold":"312000",
- "red_min_threshold":"104000",
- "yellow_max_threshold":"312000",
- "yellow_min_threshold":"104000",
- "green_max_threshold":"312000",
- "green_min_threshold":"104000"
+ "red_max_threshold":"2097152",
+ "red_min_threshold":"1048576",
+ "yellow_max_threshold":"2097152",
+ "yellow_min_threshold":"1048576",
+ "green_max_threshold":"2097152",
+ "green_min_threshold":"1048576",
+ "green_drop_probability":"5",
+ "yellow_drop_probability":"5",
+ "red_drop_probability":"5"
}
},
"QUEUE": {
- "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : {
"scheduler" : "[SCHEDULER|scheduler.0]",
"wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
},
"Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : {
- "scheduler" : "[SCHEDULER|scheduler.1]"
+ "scheduler" : "[SCHEDULER|scheduler.0]"
},
"Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : {
- "scheduler" : "[SCHEDULER|scheduler.2]"
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
}
}
}
diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini
index 3b2a417cebc..aedda37a887 100644
--- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini
+++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini
@@ -1,17 +1,17 @@
# PG lossless profiles.
# speed cable size xon xoff threshold xon_offset
- 10000 5m 1248 2288 35776 -4 2288
- 25000 5m 1248 2288 53248 -4 2288
- 40000 5m 1248 2288 66560 -4 2288
- 50000 5m 1248 2288 90272 -4 2288
- 100000 5m 1248 2288 165568 -4 2288
- 10000 40m 1248 2288 37024 -4 2288
- 25000 40m 1248 2288 53248 -4 2288
- 40000 40m 1248 2288 71552 -4 2288
- 50000 40m 1248 2288 96096 -4 2288
- 100000 40m 1248 2288 177632 -4 2288
- 10000 300m 1248 2288 46176 -4 2288
- 25000 300m 1248 2288 79040 -4 2288
- 40000 300m 1248 2288 108160 -4 2288
- 50000 300m 1248 2288 141856 -4 2288
- 100000 300m 1248 2288 268736 -4 2288
+ 10000 5m 1248 2288 35776 -3 2288
+ 25000 5m 1248 2288 53248 -3 2288
+ 40000 5m 1248 2288 66560 -3 2288
+ 50000 5m 1248 2288 90272 -3 2288
+ 100000 5m 1248 2288 165568 -3 2288
+ 10000 40m 1248 2288 37024 -3 2288
+ 25000 40m 1248 2288 53248 -3 2288
+ 40000 40m 1248 2288 71552 -3 2288
+ 50000 40m 1248 2288 96096 -3 2288
+ 100000 40m 1248 2288 177632 -3 2288
+ 10000 300m 1248 2288 46176 -3 2288
+ 25000 300m 1248 2288 79040 -3 2288
+ 40000 300m 1248 2288 108160 -3 2288
+ 50000 300m 1248 2288 141856 -3 2288
+ 100000 300m 1248 2288 268736 -3 2288
diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json
index d63cbfb8c55..aacc94e559f 100644
--- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json
+++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json
@@ -83,7 +83,7 @@
"43":"0",
"44":"0",
"45":"0",
- "46":"0",
+ "46":"5",
"47":"0",
"48":"0",
"49":"0",
@@ -105,14 +105,6 @@
},
"SCHEDULER": {
"scheduler.0" : {
- "type":"DWRR",
- "weight": "25"
- },
- "scheduler.1" : {
- "type":"DWRR",
- "weight": "30"
- },
- "scheduler.2" : {
"type":"DWRR",
"weight": "20"
}
@@ -127,41 +119,39 @@
}
},
"WRED_PROFILE": {
- "AZURE_LOSSY" : {
- "wred_green_enable":"true",
- "wred_yellow_enable":"true",
- "ecn":"ecn_all",
- "red_max_threshold":"512000",
- "red_min_threshold":"512000",
- "yellow_max_threshold":"512000",
- "yellow_min_threshold":"512000",
- "green_max_threshold": "184320",
- "green_min_threshold": "184320"
- },
"AZURE_LOSSLESS" : {
"wred_green_enable":"true",
"wred_yellow_enable":"true",
+ "wred_red_enable":"true",
"ecn":"ecn_all",
- "red_max_threshold":"512000",
- "red_min_threshold":"512000",
- "yellow_max_threshold":"512000",
- "yellow_min_threshold":"512000",
- "green_max_threshold": "184320",
- "green_min_threshold": "184320"
+ "red_max_threshold":"2097152",
+ "red_min_threshold":"1048576",
+ "yellow_max_threshold":"2097152",
+ "yellow_min_threshold":"1048576",
+ "green_max_threshold":"2097152",
+ "green_min_threshold":"1048576",
+ "green_drop_probability":"5",
+ "yellow_drop_probability":"5",
+ "red_drop_probability":"5"
}
},
"QUEUE": {
- "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|0-1" : {
- "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]"
+ "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|3" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ },
+ "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|4" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
},
- "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63!3-4" : {
+ "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|0" : {
"scheduler" : "[SCHEDULER|scheduler.0]"
},
- "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63!0" : {
- "scheduler" : "[SCHEDULER|scheduler.1]"
+ "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|1" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
},
- "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63!1" : {
- "scheduler" : "[SCHEDULER|scheduler.2]"
+ "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|5" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
}
}
}
diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2
index 92cda77668f..265d93a5aac 100644
--- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2
+++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2
@@ -11,3 +11,13 @@
{%- endif %}
{# Write the contents of sai_ profile_filename to sai.profile file #}
{{ sai_profile_contents }}
+{# make linkscan interval time equal to 2.0 sec to make Fast-Reboot faster #}
+{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['fast_reboot'] is defined -%}
+{%- set fast_reboot = DEVICE_METADATA['localhost']['fast_reboot'] -%}
+{%- if fast_reboot %}
+{%- set sai_profile_contents = 'SAI_BCM_LINKSCAN_INTERVAL=2000000' -%}
+{%- else %}
+{%- set sai_profile_contents = '' -%}
+{%- endif %}
+{{ sai_profile_contents }}
+{%- endif %}
\ No newline at end of file
diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/led_proc_init.soc b/device/dell/x86_64-dell_s6100_c2538-r0/led_proc_init.soc
new file mode 100644
index 00000000000..a4a44f15bcf
--- /dev/null
+++ b/device/dell/x86_64-dell_s6100_c2538-r0/led_proc_init.soc
@@ -0,0 +1,13 @@
+# LED microprocessor initialization for Dell S6100
+
+led 0 stop
+led 0 prog 02 00 60 FE 2E FE 67 2C 86 FE 67 5B 67 5B 67 5B 86 FE 2E FE 67 2C 86 FE 86 FE 06 FE D2 40 71 04 12 FF 85 05 D2 05 71 2A 52 00 3A A0 32 08 97 71 33 77 5B 32 00 32 01 B7 97 75 42 12 BC FE FE 02 0A 50 12 BC FE FE 95 75 4C 85 77 54 16 FF DA 02 71 5B 77 54 22 0E 87 22 0E 87 57 22 0F 87 22 0F 87 57 22 0F 87 22 0E 87 57
+led 0 auto on
+led 0 start
+
+led 1 stop
+led 1 prog 02 00 60 FE 2E FE 67 2C 86 FE 67 5B 67 5B 67 5B 86 FE 2E FE 67 2C 86 FE 86 FE 06 FE D2 40 71 04 12 FF 85 05 D2 05 71 2A 52 00 3A A0 32 08 97 71 33 77 5B 32 00 32 01 B7 97 75 42 12 BC FE FE 02 0A 50 12 BC FE FE 95 75 4C 85 77 54 16 FF DA 02 71 5B 77 54 22 0E 87 22 0E 87 57 22 0F 87 22 0F 87 57 22 0F 87 22 0E 87 57
+led 1 auto on
+led 1 start
+
+led 2 stop
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers.json.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers.json.j2
new file mode 100644
index 00000000000..0b1cb2c541b
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers.json.j2
@@ -0,0 +1,2 @@
+{%- set default_topo = 't1' %}
+{%- include 'buffers_config.j2' %}
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2
new file mode 100644
index 00000000000..5c654ab9e8a
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2
@@ -0,0 +1,47 @@
+
+{%- set default_cable = '40m' %}
+
+{%- 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": "10443264",
+ "type": "ingress",
+ "mode": "dynamic",
+ "xoff": "4625920"
+ },
+ "egress_lossy_pool": {
+ "size": "8877440",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "15982720",
+ "type": "egress",
+ "mode": "static"
+ }
+ },
+ "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":"1518",
+ "static_th":"3995680"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"1518",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/pg_profile_lookup.ini b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/pg_profile_lookup.ini
new file mode 100644
index 00000000000..aedda37a887
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold xon_offset
+ 10000 5m 1248 2288 35776 -3 2288
+ 25000 5m 1248 2288 53248 -3 2288
+ 40000 5m 1248 2288 66560 -3 2288
+ 50000 5m 1248 2288 90272 -3 2288
+ 100000 5m 1248 2288 165568 -3 2288
+ 10000 40m 1248 2288 37024 -3 2288
+ 25000 40m 1248 2288 53248 -3 2288
+ 40000 40m 1248 2288 71552 -3 2288
+ 50000 40m 1248 2288 96096 -3 2288
+ 100000 40m 1248 2288 177632 -3 2288
+ 10000 300m 1248 2288 46176 -3 2288
+ 25000 300m 1248 2288 79040 -3 2288
+ 40000 300m 1248 2288 108160 -3 2288
+ 50000 300m 1248 2288 141856 -3 2288
+ 100000 300m 1248 2288 268736 -3 2288
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/port_config.ini b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/port_config.ini
similarity index 100%
rename from device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/port_config.ini
rename to device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/port_config.ini
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json
new file mode 100644
index 00000000000..deb9f40fc0f
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json
@@ -0,0 +1,157 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"0",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"5",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0" : {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PORT_QOS_MAP": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124": {
+ "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
+ "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
+ "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
+ "pfc_enable": "3,4"
+ }
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSLESS" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"2097152",
+ "red_min_threshold":"1048576",
+ "yellow_max_threshold":"2097152",
+ "yellow_min_threshold":"1048576",
+ "green_max_threshold":"2097152",
+ "green_min_threshold":"1048576",
+ "green_drop_probability":"5",
+ "yellow_drop_probability":"5",
+ "red_drop_probability":"5"
+ }
+ },
+ "QUEUE": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ }
+ }
+}
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile
new file mode 100644
index 00000000000..a690c3ff8b9
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile
@@ -0,0 +1 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-32x100G.config.bcm
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm
new file mode 100644
index 00000000000..25aefca2daf
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm
@@ -0,0 +1,232 @@
+#TH Z9100 32x100
+
+l3_alpm_enable=2
+pfc_deadlock_seq_control=1
+bcm_stat_interval=2000000
+bcm_num_cos=8
+switch_bypass_mode=0
+mmu_lossless=0
+lpm_scaling_enable=0
+lpm_scaling_enable=0
+lpm_ipv6_128b_reserved=0
+ipv6_lpm_128b_enable=1
+l2xmsg_mode=1
+oversubscribe_mode=1
+os=unix
+
+pbmp_oversubscribe=0x3fd000000ff4000003fc000001fe
+pbmp_xport_xe=0x3fd000000ff4000003fc000001fe
+
+serdes_if_type_xe=14
+serdes_if_type_ce=14
+
+#Parity
+parity_correction=1
+parity_enable=1
+
+#Port configuration
+portmap_38=49:100
+portmap_39=53:100
+portmap_40=57:100
+portmap_41=61:100
+portmap_68=65:100
+portmap_69=69:100
+portmap_70=73:100
+portmap_71=77:100
+portmap_35=37:100
+portmap_34=33:100
+portmap_37=45:100
+portmap_36=41:100
+portmap_72=81:100
+portmap_73=85:100
+portmap_74=89:100
+portmap_75=93:100
+portmap_102=97:100
+portmap_103=101:100
+portmap_104=105:100
+portmap_105=109:100
+portmap_6=21:100
+portmap_5=17:100
+portmap_8=29:100
+portmap_7=25:100
+portmap_107=117:100
+portmap_106=113:100
+portmap_109=125:100
+portmap_108=121:100
+portmap_2=5:100
+portmap_1=1:100
+portmap_4=13:100
+portmap_3=9:100
+portmap_66=129:10
+portmap_100=131:10
+portmap_33=132:10
+portmap_67=133:10
+portmap_101=134:10
+portmap_135=135:10
+
+xgxs_tx_lane_map_ce0=0x0132
+xgxs_tx_lane_map_ce1=0x2301
+xgxs_tx_lane_map_ce2=0x0123
+xgxs_tx_lane_map_ce3=0x3201
+xgxs_tx_lane_map_ce4=0x3210
+xgxs_tx_lane_map_ce5=0x2301
+xgxs_tx_lane_map_ce6=0x0123
+xgxs_tx_lane_map_ce7=0x1320
+xgxs_tx_lane_map_ce8=0x1032
+xgxs_tx_lane_map_ce9=0x2031
+xgxs_tx_lane_map_ce10=0x1023
+xgxs_tx_lane_map_ce11=0x0132
+xgxs_tx_lane_map_ce12=0x0213
+xgxs_tx_lane_map_ce13=0x1032
+xgxs_tx_lane_map_ce14=0x0132
+xgxs_tx_lane_map_ce15=0x0123
+xgxs_tx_lane_map_ce16=0x0123
+xgxs_tx_lane_map_ce17=0x0123
+xgxs_tx_lane_map_ce18=0x1032
+xgxs_tx_lane_map_ce19=0x0123
+xgxs_tx_lane_map_ce20=0x2301
+xgxs_tx_lane_map_ce21=0x3102
+xgxs_tx_lane_map_ce22=0x1023
+xgxs_tx_lane_map_ce23=0x2130
+xgxs_tx_lane_map_ce24=0x2310
+xgxs_tx_lane_map_ce25=0x2013
+xgxs_tx_lane_map_ce26=0x0132
+xgxs_tx_lane_map_ce27=0x0123
+xgxs_tx_lane_map_ce28=0x0213
+xgxs_tx_lane_map_ce29=0x0123
+xgxs_tx_lane_map_ce30=0x2301
+xgxs_tx_lane_map_ce31=0x0123
+
+xgxs_rx_lane_map_ce0=0x1023
+xgxs_rx_lane_map_ce1=0x1302
+xgxs_rx_lane_map_ce2=0x1203
+xgxs_rx_lane_map_ce3=0x1302
+xgxs_rx_lane_map_ce4=0x3201
+xgxs_rx_lane_map_ce5=0x1302
+xgxs_rx_lane_map_ce6=0x1203
+xgxs_rx_lane_map_ce7=0x2301
+xgxs_rx_lane_map_ce8=0x0312
+xgxs_rx_lane_map_ce9=0x1302
+xgxs_rx_lane_map_ce10=0x2103
+xgxs_rx_lane_map_ce11=0x3210
+xgxs_rx_lane_map_ce12=0x2301
+xgxs_rx_lane_map_ce13=0x0213
+xgxs_rx_lane_map_ce14=0x3210
+xgxs_rx_lane_map_ce15=0x3210
+xgxs_rx_lane_map_ce16=0x3201
+xgxs_rx_lane_map_ce17=0x0213
+xgxs_rx_lane_map_ce18=0x3210
+xgxs_rx_lane_map_ce19=0x3210
+xgxs_rx_lane_map_ce20=0x3102
+xgxs_rx_lane_map_ce21=0x2103
+xgxs_rx_lane_map_ce22=0x2301
+xgxs_rx_lane_map_ce23=0x2310
+xgxs_rx_lane_map_ce24=0x3201
+xgxs_rx_lane_map_ce25=0x0123
+xgxs_rx_lane_map_ce26=0x1023
+xgxs_rx_lane_map_ce27=0x0213
+xgxs_rx_lane_map_ce28=0x1203
+xgxs_rx_lane_map_ce29=0x0213
+xgxs_rx_lane_map_ce30=0x3201
+xgxs_rx_lane_map_ce31=0x0213
+
+phy_xaui_tx_polarity_flip_ce0=0xe
+phy_xaui_tx_polarity_flip_ce1=0x2
+phy_xaui_tx_polarity_flip_ce2=0xa
+phy_xaui_tx_polarity_flip_ce3=0xb
+phy_xaui_tx_polarity_flip_ce4=0x2
+phy_xaui_tx_polarity_flip_ce5=0x0
+phy_xaui_tx_polarity_flip_ce6=0x0
+phy_xaui_tx_polarity_flip_ce7=0xa
+phy_xaui_tx_polarity_flip_ce8=0x0
+phy_xaui_tx_polarity_flip_ce9=0xb
+phy_xaui_tx_polarity_flip_ce10=0xe
+phy_xaui_tx_polarity_flip_ce11=0x6
+phy_xaui_tx_polarity_flip_ce12=0x6
+phy_xaui_tx_polarity_flip_ce13=0xf
+phy_xaui_tx_polarity_flip_ce14=0x5
+phy_xaui_tx_polarity_flip_ce15=0x8
+phy_xaui_tx_polarity_flip_ce16=0xf
+phy_xaui_tx_polarity_flip_ce17=0xf
+phy_xaui_tx_polarity_flip_ce18=0xf
+phy_xaui_tx_polarity_flip_ce19=0xf
+phy_xaui_tx_polarity_flip_ce20=0xf
+phy_xaui_tx_polarity_flip_ce21=0xf
+phy_xaui_tx_polarity_flip_ce22=0xb
+phy_xaui_tx_polarity_flip_ce23=0xa
+phy_xaui_tx_polarity_flip_ce24=0xf
+phy_xaui_tx_polarity_flip_ce25=0x0
+phy_xaui_tx_polarity_flip_ce26=0xb
+phy_xaui_tx_polarity_flip_ce27=0x7
+phy_xaui_tx_polarity_flip_ce28=0x8
+phy_xaui_tx_polarity_flip_ce29=0x3
+phy_xaui_tx_polarity_flip_ce30=0xc
+phy_xaui_tx_polarity_flip_ce31=0x3
+
+phy_xaui_rx_polarity_flip_ce0=0xc
+phy_xaui_rx_polarity_flip_ce1=0xd
+phy_xaui_rx_polarity_flip_ce2=0x2
+phy_xaui_rx_polarity_flip_ce3=0xf
+phy_xaui_rx_polarity_flip_ce4=0xc
+phy_xaui_rx_polarity_flip_ce5=0x2
+phy_xaui_rx_polarity_flip_ce6=0x2
+phy_xaui_rx_polarity_flip_ce7=0xd
+phy_xaui_rx_polarity_flip_ce8=0xd
+phy_xaui_rx_polarity_flip_ce9=0xa
+phy_xaui_rx_polarity_flip_ce10=0x7
+phy_xaui_rx_polarity_flip_ce11=0xf
+phy_xaui_rx_polarity_flip_ce12=0xf
+phy_xaui_rx_polarity_flip_ce13=0xd
+phy_xaui_rx_polarity_flip_ce14=0x4
+phy_xaui_rx_polarity_flip_ce15=0xb
+phy_xaui_rx_polarity_flip_ce16=0x2
+phy_xaui_rx_polarity_flip_ce17=0xd
+phy_xaui_rx_polarity_flip_ce18=0xf
+phy_xaui_rx_polarity_flip_ce19=0x0
+phy_xaui_rx_polarity_flip_ce20=0x0
+phy_xaui_rx_polarity_flip_ce21=0x5
+phy_xaui_rx_polarity_flip_ce22=0x0
+phy_xaui_rx_polarity_flip_ce23=0x2
+phy_xaui_rx_polarity_flip_ce24=0xc
+phy_xaui_rx_polarity_flip_ce25=0x8
+phy_xaui_rx_polarity_flip_ce26=0x4
+phy_xaui_rx_polarity_flip_ce27=0x7
+phy_xaui_rx_polarity_flip_ce28=0x7
+phy_xaui_rx_polarity_flip_ce29=0x9
+phy_xaui_rx_polarity_flip_ce30=0xc
+phy_xaui_rx_polarity_flip_ce31=0x8
+
+dport_map_port_38=1
+dport_map_port_39=2
+dport_map_port_40=3
+dport_map_port_41=4
+dport_map_port_68=5
+dport_map_port_69=6
+dport_map_port_70=7
+dport_map_port_71=8
+dport_map_port_35=9
+dport_map_port_34=10
+dport_map_port_37=11
+dport_map_port_36=12
+dport_map_port_72=13
+dport_map_port_73=14
+dport_map_port_74=15
+dport_map_port_75=16
+dport_map_port_102=17
+dport_map_port_103=18
+dport_map_port_104=19
+dport_map_port_105=20
+dport_map_port_6=21
+dport_map_port_5=22
+dport_map_port_8=23
+dport_map_port_7=24
+dport_map_port_107=25
+dport_map_port_106=26
+dport_map_port_109=27
+dport_map_port_108=28
+dport_map_port_2=29
+dport_map_port_1=30
+dport_map_port_4=31
+dport_map_port_3=32
+
+mmu_init_config="MSFT-TH-Tier1"
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers.json.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers.json.j2
new file mode 100644
index 00000000000..1083a6210fc
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers.json.j2
@@ -0,0 +1,2 @@
+{%- set default_topo = 't0' %}
+{%- include 'buffers_config.j2' %}
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2
new file mode 100644
index 00000000000..4bd35b354c8
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2
@@ -0,0 +1,61 @@
+{%- set default_cable = '5m' %}
+
+{%- macro generate_port_lists(PORT_ALL) %}
+ {# Generate list of ports #}
+ {%- for port_idx in range(0,6) %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %}
+ {%- endfor %}
+ {%- for port_idx in range(10,26) %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %}
+ {%- endfor %}
+ {%- for port_idx in range(30,32) %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %}
+ {%- endfor %}
+ {%- for port_idx in range(6,10) %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %}
+ {%- endfor %}
+ {%- for port_idx in range(26,30) %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %}
+ {%- endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "11213696",
+ "type": "ingress",
+ "mode": "dynamic",
+ "xoff": "3855488"
+ },
+ "egress_lossy_pool": {
+ "size": "9532224",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "15982720",
+ "type": "egress",
+ "mode": "static"
+ }
+ },
+ "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":"1518",
+ "static_th":"3995680"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"1518",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/pg_profile_lookup.ini b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/pg_profile_lookup.ini
new file mode 100644
index 00000000000..aedda37a887
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold xon_offset
+ 10000 5m 1248 2288 35776 -3 2288
+ 25000 5m 1248 2288 53248 -3 2288
+ 40000 5m 1248 2288 66560 -3 2288
+ 50000 5m 1248 2288 90272 -3 2288
+ 100000 5m 1248 2288 165568 -3 2288
+ 10000 40m 1248 2288 37024 -3 2288
+ 25000 40m 1248 2288 53248 -3 2288
+ 40000 40m 1248 2288 71552 -3 2288
+ 50000 40m 1248 2288 96096 -3 2288
+ 100000 40m 1248 2288 177632 -3 2288
+ 10000 300m 1248 2288 46176 -3 2288
+ 25000 300m 1248 2288 79040 -3 2288
+ 40000 300m 1248 2288 108160 -3 2288
+ 50000 300m 1248 2288 141856 -3 2288
+ 100000 300m 1248 2288 268736 -3 2288
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/port_config.ini b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/port_config.ini
new file mode 100644
index 00000000000..c1a08676485
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/port_config.ini
@@ -0,0 +1,57 @@
+# name lanes alias index speed
+Ethernet0 49,50 fiftyGigE1/1/1 1 50000
+Ethernet2 51,52 fiftyGigE1/1/2 1 50000
+Ethernet4 53,54 fiftyGigE1/2/1 2 50000
+Ethernet6 55,56 fiftyGigE1/2/2 2 50000
+Ethernet8 57,58 fiftyGigE1/3/1 3 50000
+Ethernet10 59,60 fiftyGigE1/3/2 3 50000
+Ethernet12 61,62 fiftyGigE1/4/1 4 50000
+Ethernet14 63,64 fiftyGigE1/4/2 4 50000
+Ethernet16 65,66 fiftyGigE1/5/1 5 50000
+Ethernet18 67,68 fiftyGigE1/5/2 5 50000
+Ethernet20 69,70 fiftyGigE1/6/1 6 50000
+Ethernet22 71,72 fiftyGigE1/6/2 6 50000
+Ethernet24 73,74,75,76 hundredGigE1/7 7 100000
+Ethernet28 77,78,79,80 hundredGigE1/8 8 100000
+Ethernet32 37,38,39,40 hundredGigE1/9 9 100000
+Ethernet36 33,34,35,36 hundredGigE1/10 10 100000
+Ethernet40 45,46 fiftyGigE1/11/1 11 50000
+Ethernet42 47,48 fiftyGigE1/11/2 11 50000
+Ethernet44 41,42 fiftyGigE1/12/1 12 50000
+Ethernet46 43,44 fiftyGigE1/12/2 12 50000
+Ethernet48 81,82 fiftyGigE1/13/1 13 50000
+Ethernet50 83,84 fiftyGigE1/13/2 13 50000
+Ethernet52 85,86 fiftyGigE1/14/1 14 50000
+Ethernet54 87,88 fiftyGigE1/14/2 14 50000
+Ethernet56 89,90 fiftyGigE1/15/1 15 50000
+Ethernet58 91,92 fiftyGigE1/15/2 15 50000
+Ethernet60 93,94 fiftyGigE1/16/1 16 50000
+Ethernet62 95,96 fiftyGigE1/16/2 16 50000
+Ethernet64 97,98 fiftyGigE1/17/1 17 50000
+Ethernet66 99,100 fiftyGigE1/17/2 17 50000
+Ethernet68 101,102 fiftyGigE1/18/1 18 50000
+Ethernet70 103,104 fiftyGigE1/18/2 18 50000
+Ethernet72 105,106 fiftyGigE1/19/1 19 50000
+Ethernet74 107,108 fiftyGigE1/19/2 19 50000
+Ethernet76 109,110 fiftyGigE1/20/1 20 50000
+Ethernet78 111,112 fiftyGigE1/20/2 20 50000
+Ethernet80 21,22 fiftyGigE1/21/1 21 50000
+Ethernet82 23,24 fiftyGigE1/21/2 21 50000
+Ethernet84 17,18 fiftyGigE1/22/1 22 50000
+Ethernet86 19,20 fiftyGigE1/22/2 22 50000
+Ethernet88 29,30 fiftyGigE1/23/1 23 50000
+Ethernet90 31,32 fiftyGigE1/23/2 23 50000
+Ethernet92 25,26 fiftyGigE1/24/1 24 50000
+Ethernet94 27,28 fiftyGigE1/24/2 24 50000
+Ethernet96 117,118 fiftyGigE1/25/1 25 50000
+Ethernet98 119,120 fiftyGigE1/25/2 25 50000
+Ethernet100 113,114 fiftyGigE1/26/1 26 50000
+Ethernet102 115,116 fiftyGigE1/26/2 26 50000
+Ethernet104 125,126,127,128 hundredGigE1/27 27 100000
+Ethernet108 121,122,123,124 hundredGigE1/28 28 100000
+Ethernet112 5,6,7,8 hundredGigE1/29 29 100000
+Ethernet116 1,2,3,4 hundredGigE1/30 30 100000
+Ethernet120 13,14 fiftyGigE1/31/1 31 50000
+Ethernet122 15,16 fiftyGigE1/31/2 31 50000
+Ethernet124 9,10 fiftyGigE1/32/1 32 50000
+Ethernet126 11,12 fiftyGigE1/32/2 32 50000
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json
new file mode 100644
index 00000000000..aa4b6606af2
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json
@@ -0,0 +1,157 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"0",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"5",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0" : {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PORT_QOS_MAP": {
+ "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126": {
+ "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
+ "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
+ "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
+ "pfc_enable": "3,4"
+ }
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSLESS" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"2097152",
+ "red_min_threshold":"1048576",
+ "yellow_max_threshold":"2097152",
+ "yellow_min_threshold":"1048576",
+ "green_max_threshold":"2097152",
+ "green_min_threshold":"1048576",
+ "green_drop_probability":"5",
+ "yellow_drop_probability":"5",
+ "red_drop_probability":"5"
+ }
+ },
+ "QUEUE": {
+ "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|3": {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ },
+ "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|4": {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ },
+ "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|0": {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ },
+ "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|1": {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ },
+ "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|5": {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ }
+ }
+}
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile
new file mode 100644
index 00000000000..182624c19bd
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile
@@ -0,0 +1 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-8x100G-48x50G.config.bcm
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm
new file mode 100644
index 00000000000..5dddf7d2a2d
--- /dev/null
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm
@@ -0,0 +1,380 @@
+#TH Z9100 T0
+
+l3_alpm_enable=2
+pfc_deadlock_seq_control=1
+bcm_stat_interval=2000000
+bcm_num_cos=8
+switch_bypass_mode=0
+mmu_lossless=0
+lpm_scaling_enable=0
+lpm_scaling_enable=0
+lpm_ipv6_128b_reserved=0
+ipv6_lpm_128b_enable=1
+l2xmsg_mode=1
+oversubscribe_mode=1
+os=unix
+
+pbmp_oversubscribe=0x3fffffffdffffffff7fffffffdfffffffe
+pbmp_xport_xe=0x3fffffffdffffffff7fffffffdfffffffe
+
+serdes_if_type_xe=14
+serdes_if_type_ce=14
+
+#Parity
+parity_correction=1
+parity_enable=1
+
+#Port configuration
+dport_map_port_100.0=130
+dport_map_port_10.0=126
+dport_map_port_1.0=117
+dport_map_port_102.0=65
+dport_map_port_103.0=66
+dport_map_port_106.0=69
+dport_map_port_107.0=70
+dport_map_port_110.0=73
+dport_map_port_111.0=74
+dport_map_port_114.0=77
+dport_map_port_115.0=78
+dport_map_port_118.0=101
+dport_map_port_119.0=102
+dport_map_port_122.0=97
+dport_map_port_123.0=98
+dport_map_port_126.0=109
+dport_map_port_130.0=105
+dport_map_port_13.0=121
+dport_map_port_14.0=122
+dport_map_port_17.0=85
+dport_map_port_18.0=86
+dport_map_port_21.0=81
+dport_map_port_22.0=82
+dport_map_port_25.0=93
+dport_map_port_26.0=94
+dport_map_port_29.0=89
+dport_map_port_30.0=90
+dport_map_port_34.0=37
+dport_map_port_38.0=33
+dport_map_port_42.0=45
+dport_map_port_43.0=46
+dport_map_port_46.0=41
+dport_map_port_47.0=42
+dport_map_port_50.0=1
+dport_map_port_5.0=113
+dport_map_port_51.0=2
+dport_map_port_54.0=5
+dport_map_port_55.0=6
+dport_map_port_58.0=9
+dport_map_port_59.0=10
+dport_map_port_62.0=13
+dport_map_port_63.0=14
+dport_map_port_66.0=129
+dport_map_port_68.0=17
+dport_map_port_69.0=18
+dport_map_port_72.0=21
+dport_map_port_73.0=22
+dport_map_port_76.0=25
+dport_map_port_80.0=29
+dport_map_port_84.0=49
+dport_map_port_85.0=50
+dport_map_port_88.0=53
+dport_map_port_89.0=54
+dport_map_port_9.0=125
+dport_map_port_92.0=57
+dport_map_port_93.0=58
+dport_map_port_96.0=61
+dport_map_port_97.0=62
+
+phy_xaui_rx_polarity_flip_100.0=0xf
+phy_xaui_rx_polarity_flip_10.0=0x2
+phy_xaui_rx_polarity_flip_1.0=0x9
+phy_xaui_rx_polarity_flip_102.0=0x2
+phy_xaui_rx_polarity_flip_103.0=0x0
+phy_xaui_rx_polarity_flip_106.0=0x1
+phy_xaui_rx_polarity_flip_107.0=0x3
+phy_xaui_rx_polarity_flip_110.0=0x3
+phy_xaui_rx_polarity_flip_111.0=0x3
+phy_xaui_rx_polarity_flip_114.0=0x0
+phy_xaui_rx_polarity_flip_115.0=0x0
+phy_xaui_rx_polarity_flip_118.0=0x0
+phy_xaui_rx_polarity_flip_119.0=0x2
+phy_xaui_rx_polarity_flip_122.0=0x0
+phy_xaui_rx_polarity_flip_123.0=0x3
+phy_xaui_rx_polarity_flip_126.0=0x7
+phy_xaui_rx_polarity_flip_130.0=0x4
+phy_xaui_rx_polarity_flip_13.0=0x0
+phy_xaui_rx_polarity_flip_14.0=0x3
+phy_xaui_rx_polarity_flip_17.0=0x1
+phy_xaui_rx_polarity_flip_18.0=0x1
+phy_xaui_rx_polarity_flip_21.0=0x0
+phy_xaui_rx_polarity_flip_22.0=0x0
+phy_xaui_rx_polarity_flip_25.0=0x2
+phy_xaui_rx_polarity_flip_26.0=0x0
+phy_xaui_rx_polarity_flip_29.0=0x0
+phy_xaui_rx_polarity_flip_30.0=0x0
+phy_xaui_rx_polarity_flip_34.0=0xa
+phy_xaui_rx_polarity_flip_38.0=0xd
+phy_xaui_rx_polarity_flip_42.0=0x3
+phy_xaui_rx_polarity_flip_43.0=0x3
+phy_xaui_rx_polarity_flip_46.0=0x3
+phy_xaui_rx_polarity_flip_47.0=0x1
+phy_xaui_rx_polarity_flip_50.0=0x0
+phy_xaui_rx_polarity_flip_5.0=0x7
+phy_xaui_rx_polarity_flip_51.0=0x3
+phy_xaui_rx_polarity_flip_54.0=0x1
+phy_xaui_rx_polarity_flip_55.0=0x3
+phy_xaui_rx_polarity_flip_58.0=0x2
+phy_xaui_rx_polarity_flip_59.0=0x0
+phy_xaui_rx_polarity_flip_62.0=0x3
+phy_xaui_rx_polarity_flip_63.0=0x3
+phy_xaui_rx_polarity_flip_66.0=0xf
+phy_xaui_rx_polarity_flip_68.0=0x0
+phy_xaui_rx_polarity_flip_69.0=0x3
+phy_xaui_rx_polarity_flip_72.0=0x2
+phy_xaui_rx_polarity_flip_73.0=0x0
+phy_xaui_rx_polarity_flip_76.0=0x2
+phy_xaui_rx_polarity_flip_80.0=0xd
+phy_xaui_rx_polarity_flip_84.0=0x3
+phy_xaui_rx_polarity_flip_85.0=0x3
+phy_xaui_rx_polarity_flip_88.0=0x1
+phy_xaui_rx_polarity_flip_89.0=0x3
+phy_xaui_rx_polarity_flip_9.0=0x0
+phy_xaui_rx_polarity_flip_92.0=0x0
+phy_xaui_rx_polarity_flip_93.0=0x1
+phy_xaui_rx_polarity_flip_96.0=0x3
+phy_xaui_rx_polarity_flip_97.0=0x2
+
+phy_xaui_tx_polarity_flip_100.0=0x6
+phy_xaui_tx_polarity_flip_10.0=0x0
+phy_xaui_tx_polarity_flip_1.0=0x3
+phy_xaui_tx_polarity_flip_102.0=0x3
+phy_xaui_tx_polarity_flip_103.0=0x3
+phy_xaui_tx_polarity_flip_106.0=0x3
+phy_xaui_tx_polarity_flip_107.0=0x3
+phy_xaui_tx_polarity_flip_110.0=0x3
+phy_xaui_tx_polarity_flip_111.0=0x3
+phy_xaui_tx_polarity_flip_114.0=0x3
+phy_xaui_tx_polarity_flip_115.0=0x3
+phy_xaui_tx_polarity_flip_118.0=0x0
+phy_xaui_tx_polarity_flip_119.0=0x0
+phy_xaui_tx_polarity_flip_122.0=0x3
+phy_xaui_tx_polarity_flip_123.0=0x3
+phy_xaui_tx_polarity_flip_126.0=0x7
+phy_xaui_tx_polarity_flip_130.0=0xb
+phy_xaui_tx_polarity_flip_13.0=0x0
+phy_xaui_tx_polarity_flip_14.0=0x3
+phy_xaui_tx_polarity_flip_17.0=0x3
+phy_xaui_tx_polarity_flip_18.0=0x3
+phy_xaui_tx_polarity_flip_21.0=0x3
+phy_xaui_tx_polarity_flip_22.0=0x3
+phy_xaui_tx_polarity_flip_25.0=0x2
+phy_xaui_tx_polarity_flip_26.0=0x2
+phy_xaui_tx_polarity_flip_29.0=0x3
+phy_xaui_tx_polarity_flip_30.0=0x2
+phy_xaui_tx_polarity_flip_34.0=0xb
+phy_xaui_tx_polarity_flip_38.0=0x0
+phy_xaui_tx_polarity_flip_42.0=0x2
+phy_xaui_tx_polarity_flip_43.0=0x1
+phy_xaui_tx_polarity_flip_46.0=0x2
+phy_xaui_tx_polarity_flip_47.0=0x3
+phy_xaui_tx_polarity_flip_50.0=0x2
+phy_xaui_tx_polarity_flip_5.0=0x8
+phy_xaui_tx_polarity_flip_51.0=0x3
+phy_xaui_tx_polarity_flip_54.0=0x2
+phy_xaui_tx_polarity_flip_55.0=0x0
+phy_xaui_tx_polarity_flip_58.0=0x2
+phy_xaui_tx_polarity_flip_59.0=0x2
+phy_xaui_tx_polarity_flip_62.0=0x3
+phy_xaui_tx_polarity_flip_63.0=0x2
+phy_xaui_tx_polarity_flip_66.0=0x6
+phy_xaui_tx_polarity_flip_68.0=0x2
+phy_xaui_tx_polarity_flip_69.0=0x0
+phy_xaui_tx_polarity_flip_72.0=0x0
+phy_xaui_tx_polarity_flip_73.0=0x0
+phy_xaui_tx_polarity_flip_76.0=0x0
+phy_xaui_tx_polarity_flip_80.0=0xa
+phy_xaui_tx_polarity_flip_84.0=0x2
+phy_xaui_tx_polarity_flip_85.0=0x1
+phy_xaui_tx_polarity_flip_88.0=0x3
+phy_xaui_tx_polarity_flip_89.0=0x3
+phy_xaui_tx_polarity_flip_9.0=0x3
+phy_xaui_tx_polarity_flip_92.0=0x1
+phy_xaui_tx_polarity_flip_93.0=0x1
+phy_xaui_tx_polarity_flip_96.0=0x0
+phy_xaui_tx_polarity_flip_97.0=0x2
+
+portmap_100.0=131:10
+portmap_10.0=11:50:2
+portmap_1.0=1:100
+portmap_102.0=97:50:2
+portmap_103.0=99:50:2
+portmap_106.0=101:50:2
+portmap_107.0=103:50:2
+portmap_110.0=105:50:2
+portmap_111.0=107:50:2
+portmap_114.0=109:50:2
+portmap_115.0=111:50:2
+portmap_118.0=113:50:2
+portmap_119.0=115:50:2
+portmap_122.0=117:50:2
+portmap_123.0=119:50:2
+portmap_126.0=121:100
+portmap_130.0=125:100
+portmap_13.0=13:50:2
+portmap_14.0=15:50:2
+portmap_17.0=17:50:2
+portmap_18.0=19:50:2
+portmap_21.0=21:50:2
+portmap_22.0=23:50:2
+portmap_25.0=25:50:2
+portmap_26.0=27:50:2
+portmap_29.0=29:50:2
+portmap_30.0=31:50:2
+portmap_34.0=33:100
+portmap_38.0=37:100
+portmap_42.0=41:50:2
+portmap_43.0=43:50:2
+portmap_46.0=45:50:2
+portmap_47.0=47:50:2
+portmap_50.0=49:50:2
+portmap_5.0=5:100
+portmap_51.0=51:50:2
+portmap_54.0=53:50:2
+portmap_55.0=55:50:2
+portmap_58.0=57:50:2
+portmap_59.0=59:50:2
+portmap_62.0=61:50:2
+portmap_63.0=63:50:2
+portmap_66.0=129:10
+portmap_68.0=65:50:2
+portmap_69.0=67:50:2
+portmap_72.0=69:50:2
+portmap_73.0=71:50:2
+portmap_76.0=73:100
+portmap_80.0=77:100
+portmap_84.0=81:50:2
+portmap_85.0=83:50:2
+portmap_88.0=85:50:2
+portmap_89.0=87:50:2
+portmap_9.0=9:50:2
+portmap_92.0=89:50:2
+portmap_93.0=91:50:2
+portmap_96.0=93:50:2
+portmap_97.0=95:50:2
+
+xgxs_rx_lane_map_100.0=0x3210
+xgxs_rx_lane_map_10.0=0x213
+xgxs_rx_lane_map_1.0=0x213
+xgxs_rx_lane_map_102.0=0x3201
+xgxs_rx_lane_map_103.0=0x3201
+xgxs_rx_lane_map_106.0=0x213
+xgxs_rx_lane_map_107.0=0x213
+xgxs_rx_lane_map_110.0=0x3210
+xgxs_rx_lane_map_111.0=0x3210
+xgxs_rx_lane_map_114.0=0x3210
+xgxs_rx_lane_map_115.0=0x3210
+xgxs_rx_lane_map_118.0=0x123
+xgxs_rx_lane_map_119.0=0x123
+xgxs_rx_lane_map_122.0=0x3201
+xgxs_rx_lane_map_123.0=0x3201
+xgxs_rx_lane_map_126.0=0x213
+xgxs_rx_lane_map_130.0=0x1023
+xgxs_rx_lane_map_13.0=0x3201
+xgxs_rx_lane_map_14.0=0x3201
+xgxs_rx_lane_map_17.0=0x2103
+xgxs_rx_lane_map_18.0=0x2103
+xgxs_rx_lane_map_21.0=0x3102
+xgxs_rx_lane_map_22.0=0x3102
+xgxs_rx_lane_map_25.0=0x2310
+xgxs_rx_lane_map_26.0=0x2310
+xgxs_rx_lane_map_29.0=0x2301
+xgxs_rx_lane_map_30.0=0x2301
+xgxs_rx_lane_map_34.0=0x1302
+xgxs_rx_lane_map_38.0=0x312
+xgxs_rx_lane_map_42.0=0x3210
+xgxs_rx_lane_map_43.0=0x3210
+xgxs_rx_lane_map_46.0=0x2103
+xgxs_rx_lane_map_47.0=0x2103
+xgxs_rx_lane_map_50.0=0x1023
+xgxs_rx_lane_map_5.0=0x1203
+xgxs_rx_lane_map_51.0=0x1023
+xgxs_rx_lane_map_54.0=0x1302
+xgxs_rx_lane_map_55.0=0x1302
+xgxs_rx_lane_map_58.0=0x1203
+xgxs_rx_lane_map_59.0=0x1203
+xgxs_rx_lane_map_62.0=0x1302
+xgxs_rx_lane_map_63.0=0x1302
+xgxs_rx_lane_map_66.0=0x3210
+xgxs_rx_lane_map_68.0=0x3201
+xgxs_rx_lane_map_69.0=0x3201
+xgxs_rx_lane_map_72.0=0x1302
+xgxs_rx_lane_map_73.0=0x1302
+xgxs_rx_lane_map_76.0=0x1203
+xgxs_rx_lane_map_80.0=0x2301
+xgxs_rx_lane_map_84.0=0x2301
+xgxs_rx_lane_map_85.0=0x2301
+xgxs_rx_lane_map_88.0=0x213
+xgxs_rx_lane_map_89.0=0x213
+xgxs_rx_lane_map_9.0=0x213
+xgxs_rx_lane_map_92.0=0x3210
+xgxs_rx_lane_map_93.0=0x3210
+xgxs_rx_lane_map_96.0=0x3210
+xgxs_rx_lane_map_97.0=0x3210
+xgxs_tx_lane_map_100.0=0x132
+xgxs_tx_lane_map_10.0=0x123
+xgxs_tx_lane_map_1.0=0x123
+xgxs_tx_lane_map_102.0=0x123
+xgxs_tx_lane_map_103.0=0x123
+xgxs_tx_lane_map_106.0=0x123
+xgxs_tx_lane_map_107.0=0x123
+xgxs_tx_lane_map_110.0=0x132
+xgxs_tx_lane_map_111.0=0x132
+xgxs_tx_lane_map_114.0=0x123
+xgxs_tx_lane_map_115.0=0x123
+xgxs_tx_lane_map_118.0=0x2013
+xgxs_tx_lane_map_119.0=0x2013
+xgxs_tx_lane_map_122.0=0x2310
+xgxs_tx_lane_map_123.0=0x2310
+xgxs_tx_lane_map_126.0=0x123
+xgxs_tx_lane_map_130.0=0x132
+xgxs_tx_lane_map_13.0=0x2301
+xgxs_tx_lane_map_14.0=0x2301
+xgxs_tx_lane_map_17.0=0x3102
+xgxs_tx_lane_map_18.0=0x3102
+xgxs_tx_lane_map_21.0=0x132
+xgxs_tx_lane_map_22.0=0x132
+xgxs_tx_lane_map_25.0=0x2130
+xgxs_tx_lane_map_26.0=0x2130
+xgxs_tx_lane_map_29.0=0x1023
+xgxs_tx_lane_map_30.0=0x1023
+xgxs_tx_lane_map_34.0=0x2031
+xgxs_tx_lane_map_38.0=0x1032
+xgxs_tx_lane_map_42.0=0x132
+xgxs_tx_lane_map_43.0=0x132
+xgxs_tx_lane_map_46.0=0x1023
+xgxs_tx_lane_map_47.0=0x1023
+xgxs_tx_lane_map_50.0=0x132
+xgxs_tx_lane_map_5.0=0x213
+xgxs_tx_lane_map_51.0=0x132
+xgxs_tx_lane_map_54.0=0x2301
+xgxs_tx_lane_map_55.0=0x2301
+xgxs_tx_lane_map_58.0=0x123
+xgxs_tx_lane_map_59.0=0x123
+xgxs_tx_lane_map_62.0=0x3201
+xgxs_tx_lane_map_63.0=0x3201
+xgxs_tx_lane_map_66.0=0x132
+xgxs_tx_lane_map_68.0=0x3210
+xgxs_tx_lane_map_69.0=0x3210
+xgxs_tx_lane_map_72.0=0x2301
+xgxs_tx_lane_map_73.0=0x2301
+xgxs_tx_lane_map_76.0=0x123
+xgxs_tx_lane_map_80.0=0x1320
+xgxs_tx_lane_map_84.0=0x213
+xgxs_tx_lane_map_85.0=0x213
+xgxs_tx_lane_map_88.0=0x1032
+xgxs_tx_lane_map_89.0=0x1032
+xgxs_tx_lane_map_9.0=0x123
+xgxs_tx_lane_map_92.0=0x132
+xgxs_tx_lane_map_93.0=0x132
+xgxs_tx_lane_map_96.0=0x123
+xgxs_tx_lane_map_97.0=0x123
+mmu_init_config="MSFT-TH-Tier0"
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/sai.profile
deleted file mode 100644
index 2c9a6e54c1a..00000000000
--- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/sai.profile
+++ /dev/null
@@ -1 +0,0 @@
-SAI_INIT_CONFIG_FILE=/etc/bcm/th-z9100-32x100G.config.bcm
diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/minigraph.xml b/device/dell/x86_64-dell_z9100_c2538-r0/minigraph.xml
index e1d42d180fe..3632224e48f 100644
--- a/device/dell/x86_64-dell_z9100_c2538-r0/minigraph.xml
+++ b/device/dell/x86_64-dell_z9100_c2538-r0/minigraph.xml
@@ -1040,7 +1040,7 @@
sonic
- Force10-Z9100
+ Force10-Z9100-C32
@@ -1075,5 +1075,5 @@
sonic
- Force10-Z9100
+ Force10-Z9100-C32
diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/buffers.json.j2 b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/buffers.json.j2
new file mode 100644
index 00000000000..ff2adc67e14
--- /dev/null
+++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/buffers.json.j2
@@ -0,0 +1,111 @@
+{# Default values which will be used if no actual configura available #}
+{% set default_cable = '40m' %}
+{% set default_speed = '100G' %}
+{% set default_ports_num = 32 -%}
+
+{# Port configuration to cable length look-up table #}
+{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
+{# Roles described in the minigraph #}
+{% set ports2cable = {
+ 'torrouter_server' : '5m',
+ 'leafrouter_torrouter' : '40m',
+ 'spinerouter_leafrouter' : '300m'
+ }
+%}
+
+{%- macro cable_length(port_name) -%}
+ {%- set cable_len = [] -%}
+ {%- for local_port in DEVICE_NEIGHBOR -%}
+ {%- if local_port == port_name -%}
+ {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor_role = neighbor.type -%}
+ {%- set roles1 = switch_role + '_' + neighbor_role %}
+ {%- set roles2 = neighbor_role + '_' + switch_role -%}
+ {%- set roles1 = roles1 | lower -%}
+ {%- set roles2 = roles2 | lower -%}
+ {%- if roles1 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%}
+ {%- elif roles2 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endfor -%}
+ {%- if cable_len -%}
+ {{ cable_len.0 }}
+ {%- else -%}
+ {{ default_cable }}
+ {%- endif -%}
+{% endmacro %}
+
+{%- if DEVICE_METADATA is defined %}
+{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
+{%- endif -%}
+
+{# Generate list of ports if not defined #}
+{% if PORT is not defined %}
+ {% set PORT = [] %}
+ {% for port_idx in range(0,default_ports_num) %}
+ {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %}
+ {% endfor %}
+{% endif -%}
+
+{% set port_names_list = [] %}
+{% for port in PORT %}
+ {%- if port_names_list.append(port) %}{% endif %}
+{% endfor %}
+{% set port_names = port_names_list | join(',') -%}
+
+{
+ "CABLE_LENGTH": {
+ "AZURE": {
+ {% for port in PORT %}
+ {% set cable = cable_length(port) -%}
+ "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %}
+
+ {% endfor %}
+ }
+ },
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "20971328",
+ "type": "ingress",
+ "mode": "static"
+ },
+ "ingress_lossy_pool": {
+ "size": "20971328",
+ "type": "ingress",
+ "mode": "static"
+ },
+ "egress_lossy_pool": {
+ "size": "20971328",
+ "type": "egress",
+ "mode": "static"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "xon":"78400",
+ "xoff":"132160",
+ "size":"3584",
+ "static_th":"82880"
+ },
+ "ingress_lossy_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossy_pool]",
+ "size":"3584",
+ "dynamic_th":"-1"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"11200",
+ "dynamic_th":"-4"
+ }
+ },
+ "BUFFER_PG": {
+ },
+ "BUFFER_QUEUE": {
+ }
+}
+
\ No newline at end of file
diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/pg_profile_lookup.ini b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/pg_profile_lookup.ini
new file mode 100644
index 00000000000..d98b0eca6d1
--- /dev/null
+++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold
+ 10000 5m 3584 32256 59136 36736
+ 25000 5m 3584 41216 68096 45696
+ 40000 5m 3584 47488 74368 51968
+ 50000 5m 3584 52864 79744 57344
+ 100000 5m 3584 78400 132160 82880
+ 10000 40m 3584 32256 59136 36736
+ 25000 40m 3584 41216 68096 45696
+ 40000 40m 3584 47488 74368 51968
+ 50000 40m 3584 52864 79744 57344
+ 100000 40m 3584 78400 132160 82880
+ 10000 300m 3584 32256 65856 36736
+ 25000 300m 3584 41216 84672 45696
+ 40000 300m 3584 47488 101024 51968
+ 50000 300m 3584 52864 113120 57344
+ 100000 300m 3584 78400 198688 82880
\ No newline at end of file
diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/qos.json.j2 b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/qos.json.j2
new file mode 100644
index 00000000000..42eef17c362
--- /dev/null
+++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/qos.json.j2
@@ -0,0 +1,136 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "1",
+ "1": "0",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "1",
+ "1": "0",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"1",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"0",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0" : {
+ "type":"DWRR",
+ "weight": "25"
+ },
+ "scheduler.1" : {
+ "type":"DWRR",
+ "weight": "30"
+ },
+ "scheduler.2" : {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PORT_QOS_MAP": {
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSY" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184128",
+ "green_min_threshold": "184128"
+ },
+ "AZURE_LOSSLESS" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184128",
+ "green_min_threshold": "184128"
+ }
+ },
+ "QUEUE": {
+ }
+}
diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/minigraph.xml b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/minigraph.xml
index 6b29a7eb83b..949ea6641b0 100644
--- a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/minigraph.xml
+++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/minigraph.xml
@@ -1,55 +1,6 @@
-
-
- OCPSCH0104001MS
- 10.10.1.26
- OCPSCH01040GGLF
- 10.10.1.25
- 1
- 10
- 3
-
-
- OCPSCH0104002MS
- 10.10.2.26
- OCPSCH01040GGLF
- 10.10.2.25
- 1
- 10
- 3
-
-
-
-
- 64536
- OCPSCH01040GGLF
-
-
- 10.10.1.26
-
-
-
-
- 10.10.2.26
-
-
-
-
-
-
-
- 64542
- OCPSCH0104001MS
-
-
-
- 64543
- OCPSCH0104002MS
-
-
-
@@ -72,18 +23,7 @@
OCPSCH01040GGLF
-
-
-
- Ethernet0
- 10.10.1.25/30
-
-
-
- Ethernet4
- 10.10.2.25/30
-
-
+
@@ -91,24 +31,7 @@
-
-
- 40000
- DeviceInterfaceLink
- OCPSCH0104001MS
- Ethernet24
- OCPSCH01040GGLF
- Ethernet0
-
-
- 40000
- DeviceInterfaceLink
- OCPSCH0104002MS
- Ethernet24
- OCPSCH01040GGLF
- Ethernet4
-
-
+
OCPSCH01040GGLF
@@ -136,11 +59,6 @@
-
- ErspanDestinationIpv4
-
- 2.2.2.2
-
diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/buffers.json.j2 b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/buffers.json.j2
new file mode 100644
index 00000000000..1f1cbe9fa0b
--- /dev/null
+++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/buffers.json.j2
@@ -0,0 +1,111 @@
+{# Default values which will be used if no actual configura available #}
+{% set default_cable = '40m' %}
+{% set default_speed = '100G' %}
+{% set default_ports_num = 64 -%}
+
+{# Port configuration to cable length look-up table #}
+{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
+{# Roles described in the minigraph #}
+{% set ports2cable = {
+ 'torrouter_server' : '5m',
+ 'leafrouter_torrouter' : '40m',
+ 'spinerouter_leafrouter' : '300m'
+ }
+%}
+
+{%- macro cable_length(port_name) -%}
+ {%- set cable_len = [] -%}
+ {%- for local_port in DEVICE_NEIGHBOR -%}
+ {%- if local_port == port_name -%}
+ {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
+ {%- set neighbor_role = neighbor.type -%}
+ {%- set roles1 = switch_role + '_' + neighbor_role %}
+ {%- set roles2 = neighbor_role + '_' + switch_role -%}
+ {%- set roles1 = roles1 | lower -%}
+ {%- set roles2 = roles2 | lower -%}
+ {%- if roles1 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%}
+ {%- elif roles2 in ports2cable -%}
+ {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endfor -%}
+ {%- if cable_len -%}
+ {{ cable_len.0 }}
+ {%- else -%}
+ {{ default_cable }}
+ {%- endif -%}
+{% endmacro %}
+
+{%- if DEVICE_METADATA is defined %}
+{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
+{%- endif -%}
+
+{# Generate list of ports if not defined #}
+{% if PORT is not defined %}
+ {% set PORT = [] %}
+ {% for port_idx in range(0,default_ports_num) %}
+ {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %}
+ {% endfor %}
+{% endif -%}
+
+{% set port_names_list = [] %}
+{% for port in PORT %}
+ {%- if port_names_list.append(port) %}{% endif %}
+{% endfor %}
+{% set port_names = port_names_list | join(',') -%}
+
+{
+ "CABLE_LENGTH": {
+ "AZURE": {
+ {% for port in PORT %}
+ {% set cable = cable_length(port) -%}
+ "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %}
+
+ {% endfor %}
+ }
+ },
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "20971328",
+ "type": "ingress",
+ "mode": "static"
+ },
+ "ingress_lossy_pool": {
+ "size": "20971328",
+ "type": "ingress",
+ "mode": "static"
+ },
+ "egress_lossy_pool": {
+ "size": "20971328",
+ "type": "egress",
+ "mode": "static"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "xon":"78400",
+ "xoff":"132160",
+ "size":"3584",
+ "static_th":"82880"
+ },
+ "ingress_lossy_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossy_pool]",
+ "size":"3584",
+ "dynamic_th":"-1"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"11200",
+ "dynamic_th":"-4"
+ }
+ },
+ "BUFFER_PG": {
+ },
+ "BUFFER_QUEUE": {
+ }
+}
+
\ No newline at end of file
diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/pg_profile_lookup.ini b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/pg_profile_lookup.ini
new file mode 100644
index 00000000000..d98b0eca6d1
--- /dev/null
+++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold
+ 10000 5m 3584 32256 59136 36736
+ 25000 5m 3584 41216 68096 45696
+ 40000 5m 3584 47488 74368 51968
+ 50000 5m 3584 52864 79744 57344
+ 100000 5m 3584 78400 132160 82880
+ 10000 40m 3584 32256 59136 36736
+ 25000 40m 3584 41216 68096 45696
+ 40000 40m 3584 47488 74368 51968
+ 50000 40m 3584 52864 79744 57344
+ 100000 40m 3584 78400 132160 82880
+ 10000 300m 3584 32256 65856 36736
+ 25000 300m 3584 41216 84672 45696
+ 40000 300m 3584 47488 101024 51968
+ 50000 300m 3584 52864 113120 57344
+ 100000 300m 3584 78400 198688 82880
\ No newline at end of file
diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/qos.json.j2 b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/qos.json.j2
new file mode 100644
index 00000000000..42eef17c362
--- /dev/null
+++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/qos.json.j2
@@ -0,0 +1,136 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "1",
+ "1": "0",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "1",
+ "1": "0",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"1",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"0",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0" : {
+ "type":"DWRR",
+ "weight": "25"
+ },
+ "scheduler.1" : {
+ "type":"DWRR",
+ "weight": "30"
+ },
+ "scheduler.2" : {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PORT_QOS_MAP": {
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSY" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184128",
+ "green_min_threshold": "184128"
+ },
+ "AZURE_LOSSLESS" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184128",
+ "green_min_threshold": "184128"
+ }
+ },
+ "QUEUE": {
+ }
+}
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2
new file mode 120000
index 00000000000..add8bf8bb7c
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t0.j2
new file mode 120000
index 00000000000..7bcae62336f
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t0.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t1.j2
new file mode 120000
index 00000000000..a437d613434
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t1.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/pg_profile_lookup.ini
new file mode 100644
index 00000000000..b66b129fe43
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold
+ 10000 5m 34816 18432 16384 0
+ 25000 5m 34816 18432 16384 0
+ 40000 5m 34816 18432 16384 0
+ 50000 5m 34816 18432 16384 0
+ 100000 5m 36864 18432 18432 0
+ 10000 40m 36864 18432 18432 0
+ 25000 40m 39936 18432 21504 0
+ 40000 40m 41984 18432 23552 0
+ 50000 40m 41984 18432 23552 0
+ 100000 40m 54272 18432 35840 0
+ 10000 300m 49152 18432 30720 0
+ 25000 300m 71680 18432 53248 0
+ 40000 300m 94208 18432 75776 0
+ 50000 300m 94208 18432 75776 0
+ 100000 300m 184320 18432 165888 0
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/port_config.ini b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/port_config.ini
new file mode 100644
index 00000000000..816bb0e94a7
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/port_config.ini
@@ -0,0 +1,33 @@
+# name lanes
+Ethernet0 0,1,2,3
+Ethernet4 4,5,6,7
+Ethernet8 8,9,10,11
+Ethernet12 12,13,14,15
+Ethernet16 16,17,18,19
+Ethernet20 20,21,22,23
+Ethernet24 24,25,26,27
+Ethernet28 28,29,30,31
+Ethernet32 32,33,34,35
+Ethernet36 36,37,38,39
+Ethernet40 40,41,42,43
+Ethernet44 44,45,46,47
+Ethernet48 48,49,50,51
+Ethernet52 52,53,54,55
+Ethernet56 56,57,58,59
+Ethernet60 60,61,62,63
+Ethernet64 64,65,66,67
+Ethernet68 68,69,70,71
+Ethernet72 72,73,74,75
+Ethernet76 76,77,78,79
+Ethernet80 80,81,82,83
+Ethernet84 84,85,86,87
+Ethernet88 88,89,90,91
+Ethernet92 92,93,94,95
+Ethernet96 96,97,98,99
+Ethernet100 100,101,102,103
+Ethernet104 104,105,106,107
+Ethernet108 108,109,110,111
+Ethernet112 112,113,114,115
+Ethernet116 116,117,118,119
+Ethernet120 120,121,122,123
+Ethernet124 124,125,126,127
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json
new file mode 100644
index 00000000000..df3d29c636e
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json
@@ -0,0 +1,168 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"0",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"0",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0": {
+ "type":"DWRR",
+ "weight": "25"
+ },
+ "scheduler.1": {
+ "type":"DWRR",
+ "weight": "30"
+ },
+ "scheduler.2": {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "PORT_QOS_MAP": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124": {
+ "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
+ "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
+ "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
+ "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_enable": "3,4"
+ }
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSY": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ },
+ "AZURE_LOSSLESS": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ }
+ },
+ "QUEUE": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0": {
+ "scheduler" : "[SCHEDULER|scheduler.1]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1": {
+ "scheduler" : "[SCHEDULER|scheduler.2]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1": {
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4": {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ }
+ }
+}
+
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/sai.profile b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/sai.profile
new file mode 100644
index 00000000000..9a9a38aeb06
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/sai.profile
@@ -0,0 +1 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sai_2700.xml
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/hw-management b/device/mellanox/x86_64-mlnx_lssn2700-r0/hw-management
new file mode 120000
index 00000000000..eb5e941daad
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/hw-management
@@ -0,0 +1 @@
+/etc/mlnx/msn2700
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/installer.conf b/device/mellanox/x86_64-mlnx_lssn2700-r0/installer.conf
new file mode 100644
index 00000000000..c9c9493a540
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/installer.conf
@@ -0,0 +1 @@
+ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="acpi_enforce_resources=lax acpi=noirq"
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/minigraph.xml b/device/mellanox/x86_64-mlnx_lssn2700-r0/minigraph.xml
similarity index 96%
rename from device/centec/x86_64-centec_e582_48x6q-r0/minigraph.xml
rename to device/mellanox/x86_64-mlnx_lssn2700-r0/minigraph.xml
index 950c52a6413..40eb5252610 100644
--- a/device/centec/x86_64-centec_e582_48x6q-r0/minigraph.xml
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/minigraph.xml
@@ -1040,10 +1040,40 @@
sonic
- E582-48x6q
+ LS-SN2700
+
+
+
+ sonic
+
+
+ DhcpResources
+
+
+
+
+ NtpResources
+
+ 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org
+
+
+ SyslogResources
+
+
+
+
+ ErspanDestinationIpv4
+
+ 2.2.2.2
+
+
+
+
+
+
sonic
- E582-48x6q
+ LS-SN2700
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/eeprom.py
new file mode 100644
index 00000000000..3650d9c8b70
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/eeprom.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+
+#############################################################################
+# Mellanox
+#
+# Platform and model specific eeprom subclass, inherits from the base class,
+# and provides the followings:
+# - the eeprom format definition
+# - specific encoder/decoder if there is special need
+#############################################################################
+
+try:
+ import exceptions
+ import binascii
+ import time
+ import optparse
+ import warnings
+ import os
+ import sys
+ from sonic_eeprom import eeprom_base
+ from sonic_eeprom import eeprom_tlvinfo
+ import subprocess
+except ImportError, e:
+ raise ImportError (str(e) + "- required module not found")
+
+class board(eeprom_tlvinfo.TlvInfoDecoder):
+
+ _TLV_INFO_MAX_LEN = 256
+
+ def __init__(self, name, path, cpld_root, ro):
+ self.eeprom_path = "/bsp/eeprom/sys_eeprom"
+ super(board, self).__init__(self.eeprom_path, 0, '', True)
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/psuutil.py
new file mode 100644
index 00000000000..301569c13a9
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/psuutil.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+
+#############################################################################
+# Mellanox
+#
+# Module contains an implementation of SONiC PSU Base API and
+# provides the PSUs status which are available in the platform
+#
+#############################################################################
+
+import os.path
+
+try:
+ from sonic_psu.psu_base import PsuBase
+except ImportError as e:
+ raise ImportError (str(e) + "- required module not found")
+
+class PsuUtil(PsuBase):
+ """Platform-specific PSUutil class"""
+
+ def __init__(self):
+ PsuBase.__init__(self)
+
+ self.psu_path = "/sys/bus/i2c/devices/2-0060/"
+ self.psu_presence = "psu{}_status"
+ self.psu_oper_status = "psu{}_pg_status"
+
+ def get_num_psus(self):
+ """
+ Retrieves the number of PSUs available on the device
+
+ :return: An integer, the number of PSUs available on the device
+ """
+ return 2
+
+ def get_psu_status(self, index):
+ """
+ Retrieves the oprational status of power supply unit (PSU) defined
+ by 1-based index
+
+ :param index: An integer, 1-based index of the PSU of which to query status
+ :return: Boolean, True if PSU is operating properly, False if PSU is faulty
+ """
+ if index is None:
+ return False
+
+ status = 0
+ try:
+ with open(self.psu_path + self.psu_oper_status.format(index), 'r') as power_status:
+ status = int(power_status.read())
+ except IOError:
+ return False
+
+ return status == 1
+
+ def get_psu_presence(self, index):
+ """
+ Retrieves the presence status of power supply unit (PSU) defined
+ by 1-based index
+
+ :param index: An integer, 1-based index of the PSU of which to query status
+ :return: Boolean, True if PSU is plugged, False if not
+ """
+ if index is None:
+ return False
+
+ status = 0
+ try:
+ with open(self.psu_path + self.psu_presence.format(index), 'r') as presence_status:
+ status = int(presence_status.read())
+ except IOError:
+ return False
+
+ return status == 1
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmget.py
new file mode 100644
index 00000000000..170766e9bce
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmget.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+
+import sys, errno
+import os
+from python_sdk_api.sxd_api import *
+from python_sdk_api.sx_api import *
+
+# Check if SFP port number is provided
+if len(sys.argv) < 2:
+ print "SFP module number is missed."
+ print "Usage: sfplpmget.py "
+ sys.exit(errno.EINVAL)
+
+# Init SDK API
+rc, handle = sx_api_open(None)
+if (rc != SX_STATUS_SUCCESS):
+ print "Failed to open api handle.\nPlease check that SDK is running."
+ sys.exit(errno.EACCES)
+
+pid = os.getpid()
+rc = sxd_access_reg_init(pid, None, 0)
+if (rc != 0):
+ print "Failed to initializing register access.\nPlease check that SDK is running."
+ sys.exit(errno.EACCES)
+
+# Get SFP module number
+sfp_module = int(sys.argv[1])
+
+# Get MCION
+mcion = ku_mcion_reg()
+mcion.module = sfp_module
+meta = sxd_reg_meta_t()
+meta.dev_id = 1
+meta.swid = 0
+meta.access_cmd = SXD_ACCESS_CMD_GET
+
+rc = sxd_access_reg_mcion(mcion, meta, 1, None, None)
+assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_mcion failed, rc = %d" % rc
+
+# Get low power mode status
+lpm_mask = 1 << 8
+lpm_status = (lpm_mask & mcion.module_status_bits) != 0
+print "LPM ON" if lpm_status else "LPM OFF"
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmset.py
new file mode 100644
index 00000000000..3f31af9f294
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmset.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+
+import sys, errno
+import time
+import os
+from python_sdk_api.sxd_api import *
+from python_sdk_api.sx_api import *
+
+def get_log_ports(handle, sfp_module):
+ port_attributes_list = new_sx_port_attributes_t_arr(64)
+ port_cnt_p = new_uint32_t_p()
+ uint32_t_p_assign(port_cnt_p, 64)
+
+ rc = sx_api_port_device_get(handle, 1 , 0, port_attributes_list, port_cnt_p)
+ assert rc == SX_STATUS_SUCCESS, "sx_api_port_device_get failed, rc = %d" % rc
+
+ port_cnt = uint32_t_p_value(port_cnt_p)
+ log_port_list = []
+ for i in range(0, port_cnt):
+ port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i)
+ if port_attributes.port_mapping.module_port == sfp_module:
+ log_port_list.append(port_attributes.log_port)
+
+ return log_port_list
+
+def set_sfp_admin_status(handle, meta, sfp_module, sfp_log_port_list, admin_status):
+ # Get PMAOS
+ pmaos = ku_pmaos_reg()
+ pmaos.module = sfp_module
+ meta.access_cmd = SXD_ACCESS_CMD_GET
+ rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
+ assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
+
+ # Set admin status to PMAOS
+ pmaos.ase = 1
+ pmaos.ee = 1
+ pmaos.e = 2
+ pmaos.rst = 0
+ if admin_status == SX_PORT_ADMIN_STATUS_DOWN:
+ pmaos.admin_status = 2
+ else:
+ pmaos.admin_status = 1
+
+ meta.access_cmd = SXD_ACCESS_CMD_SET
+ rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
+ assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
+
+# Check if SFP port number is provided
+if len(sys.argv) < 3:
+ print "SFP module number or LPM is missed."
+ print "Usage: sfplpmset.py "
+ sys.exit(errno.EINVAL)
+
+lpm_enable = None
+if sys.argv[2] == 'on':
+ lpm_enable = True
+elif sys.argv[2] == 'off':
+ lpm_enable = False
+else:
+ print "Unrecognized LPM parameter. Please use or values"
+ sys.exit(errno.EINVAL)
+
+# Init SDK API
+rc, handle = sx_api_open(None)
+if (rc != SX_STATUS_SUCCESS):
+ print "Failed to open api handle.\nPlease check that SDK is running."
+ sys.exit(errno.EACCES)
+
+pid = os.getpid()
+rc = sxd_access_reg_init(pid, None, 0)
+if (rc != 0):
+ print "Failed to initializing register access.\nPlease check that SDK is running."
+ sys.exit(errno.EACCES);
+
+# Get SFP module and log ports number and LPM status
+sfp_module = int(sys.argv[1])
+log_port_list = get_log_ports(handle, sfp_module)
+if not log_port_list:
+ print "Failed to get log ports"
+ sys.exit(errno.EACCES)
+
+# Get PMMP
+pmmp = ku_pmmp_reg()
+pmmp.module = sfp_module
+meta = sxd_reg_meta_t()
+meta.dev_id = 1
+meta.swid = 0
+meta.access_cmd = SXD_ACCESS_CMD_GET
+rc = sxd_access_reg_pmmp(pmmp, meta, 1, None, None)
+assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc
+
+# Disable admin status before LPM settings
+set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_DOWN)
+
+# Set low power mode status
+lpm_mask = 1 << 8
+if lpm_enable:
+ pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask
+else:
+ pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask)
+
+meta.access_cmd = SXD_ACCESS_CMD_SET
+rc = sxd_access_reg_pmmp(pmmp, meta, 1, None, None)
+assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc
+
+# Enable admin status after LPM settings
+set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_UP)
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfpreset.py
new file mode 100644
index 00000000000..69fa2be614c
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfpreset.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+import sys, errno
+import os
+from python_sdk_api.sxd_api import *
+from python_sdk_api.sx_api import *
+
+# Check if SFP port number is provided
+if len(sys.argv) < 2:
+ print "SFP module number or LPM is missed."
+ print "Usage: sfpreset.py "
+ sys.exit(errno.EINVAL)
+
+# Init SDK API
+rc, handle = sx_api_open(None)
+if (rc != SX_STATUS_SUCCESS):
+ print "Failed to open api handle.\nPlease check that SDK is running."
+ sys.exit(errno.EACCES)
+
+pid = os.getpid()
+rc = sxd_access_reg_init(pid, None, 0)
+if (rc != 0):
+ print "Failed to initializing register access.\nPlease check that SDK is running."
+ sys.exit(errno.EACCES)
+
+# Get SFP module number
+sfp_module = int(sys.argv[1])
+
+# Get PMAOS
+pmaos = ku_pmaos_reg()
+pmaos.module = sfp_module
+meta = sxd_reg_meta_t()
+meta.dev_id = 1
+meta.swid = 0
+meta.access_cmd = SXD_ACCESS_CMD_GET
+
+rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
+assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
+
+# Reset SFP
+pmaos.rst = 1
+meta.access_cmd = SXD_ACCESS_CMD_SET
+rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
+assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
+print "Reset flag is set"
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfputil.py
new file mode 100644
index 00000000000..6aef1310d51
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfputil.py
@@ -0,0 +1,151 @@
+# sfputil.py
+#
+# Platform-specific SFP transceiver interface for SONiC
+#
+
+try:
+ import time
+ import subprocess
+ from sonic_sfp.sfputilbase import SfpUtilBase
+except ImportError as e:
+ raise ImportError("%s - required module not found" % str(e))
+
+
+class SfpUtil(SfpUtilBase):
+ """Platform-specific SfpUtil class"""
+
+ PORT_START = 0
+ PORT_END = 31
+ PORTS_IN_BLOCK = 32
+
+ EEPROM_OFFSET = 1
+
+ _port_to_eeprom_mapping = {}
+
+ @property
+ def port_start(self):
+ return self.PORT_START
+
+ @property
+ def port_end(self):
+ return self.PORT_END
+
+ @property
+ def qsfp_ports(self):
+ return range(0, self.PORTS_IN_BLOCK + 1)
+
+ @property
+ def port_to_eeprom_mapping(self):
+ return self._port_to_eeprom_mapping
+
+ def __init__(self):
+ eeprom_path = "/bsp/qsfp/qsfp{0}"
+
+ for x in range(0, self.port_end + 1):
+ self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET)
+
+ SfpUtilBase.__init__(self)
+
+ def get_presence(self, port_num):
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ try:
+ reg_file = open("/bsp/qsfp/qsfp%d_status" % (port_num+1))
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ content = reg_file.readline().rstrip()
+
+ # content is a string with the qsfp status
+ if content == "good":
+ return True
+
+ return False
+
+ def get_low_power_mode(self, port_num):
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmget.py {}".format(port_num)
+
+ try:
+ output = subprocess.check_output(lpm_cmd, shell=True)
+ if 'LPM ON' in output:
+ return True
+ except subprocess.CalledProcessError as e:
+ print "Error! Unable to get LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)
+ return False
+
+ return False
+
+ def set_low_power_mode(self, port_num, lpmode):
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ curr_lpmode = self.get_low_power_mode(port_num)
+ if curr_lpmode == lpmode:
+ return True
+
+ lpm = 'on' if lpmode else 'off'
+ lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmset.py {} {}".format(port_num, lpm)
+ sfp_port_names = self.physical_to_logical[port_num]
+
+ # Get port admin status
+ try:
+ enabled_ports = subprocess.check_output("ip link show up", shell=True)
+ except subprocess.CalledProcessError as e:
+ print "Error! Unable to get ports status, err msg: {}".format(e.output)
+ return False
+
+ port_to_disable = []
+ for port in sfp_port_names:
+ if port in enabled_ports:
+ port_to_disable.append(port)
+
+ # Disable ports before LPM settings
+ for port in port_to_disable:
+ try:
+ subprocess.check_output("ifconfig {} down".format(port), shell=True)
+ except subprocess.CalledProcessError as e:
+ print "Error! Unable to set admin status to DOWN for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output)
+ return False
+
+ time.sleep(3)
+
+ # Set LPM
+ try:
+ subprocess.check_output(lpm_cmd, shell=True)
+ except subprocess.CalledProcessError as e:
+ print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)
+ return False
+
+ # Enable ports after LPM settings
+ for port in port_to_disable:
+ try:
+ subprocess.check_output("ifconfig {} up".format(port), shell=True)
+ except subprocess.CalledProcessError as e:
+ print "Error! Unable to set admin status to UP for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output)
+ return False
+
+ return True
+
+ def reset(self, port_num):
+ # Check for invalid port_num
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfpreset.py {}".format(port_num)
+
+ try:
+ subprocess.check_output(lpm_cmd, shell=True)
+ return True
+ except subprocess.CalledProcessError as e:
+ print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)
+ return False
+
+ return False
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_lssn2700-r0/sensors.conf
new file mode 100644
index 00000000000..a3e30391863
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/sensors.conf
@@ -0,0 +1,21 @@
+bus "i2c-7" "i2c-1-mux (chan_id 5)"
+chip "lm75-i2c-7-4a"
+ label temp1 "Ambient Port Temp"
+
+bus "i2c-5" "i2c-1-mux (chan_id 3)"
+chip "ucd9200-i2c-5-27"
+ label in1 "UCD1 vin"
+ label in2 "ASIC 3.3 vout"
+ label in3 "ASIC 1.2 vout"
+ label temp1 "UCD1 Temp"
+ label temp2 "UCD1 Temp2"
+
+chip "ucd9200-i2c-5-41"
+ label in1 "UCD2 vin"
+ label in2 "ASIC Vcore vout"
+ label temp1 "UCD2 Temp1"
+ label temp2 "UCD2 Temp2"
+
+bus "i2c-17" "i2c-1-mux (chan_id 7)"
+chip "lm75-i2c-17-49"
+ label temp1 "Ambient Board Temp"
diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers.json.j2
new file mode 120000
index 00000000000..add8bf8bb7c
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers.json.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t0.j2
new file mode 120000
index 00000000000..7bcae62336f
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t0.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t1.j2
new file mode 120000
index 00000000000..a437d613434
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t1.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/pg_profile_lookup.ini
new file mode 100644
index 00000000000..b66b129fe43
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold
+ 10000 5m 34816 18432 16384 0
+ 25000 5m 34816 18432 16384 0
+ 40000 5m 34816 18432 16384 0
+ 50000 5m 34816 18432 16384 0
+ 100000 5m 36864 18432 18432 0
+ 10000 40m 36864 18432 18432 0
+ 25000 40m 39936 18432 21504 0
+ 40000 40m 41984 18432 23552 0
+ 50000 40m 41984 18432 23552 0
+ 100000 40m 54272 18432 35840 0
+ 10000 300m 49152 18432 30720 0
+ 25000 300m 71680 18432 53248 0
+ 40000 300m 94208 18432 75776 0
+ 50000 300m 94208 18432 75776 0
+ 100000 300m 184320 18432 165888 0
diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json
new file mode 100644
index 00000000000..2ea9b9dc019
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json
@@ -0,0 +1,167 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"0",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"0",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0": {
+ "type":"DWRR",
+ "weight": "25"
+ },
+ "scheduler.1": {
+ "type":"DWRR",
+ "weight": "30"
+ },
+ "scheduler.2": {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "PORT_QOS_MAP": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60": {
+ "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
+ "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
+ "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
+ "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_enable": "3,4"
+ }
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSY": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ },
+ "AZURE_LOSSLESS": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ }
+ },
+ "QUEUE": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60|0": {
+ "scheduler" : "[SCHEDULER|scheduler.1]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60|1": {
+ "scheduler" : "[SCHEDULER|scheduler.2]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60|0-1": {
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60|3-4": {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ }
+ }
+}
diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers.json.j2
new file mode 120000
index 00000000000..add8bf8bb7c
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers.json.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t0.j2
new file mode 120000
index 00000000000..7bcae62336f
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t0.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t1.j2
new file mode 120000
index 00000000000..a437d613434
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t1.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/pg_profile_lookup.ini
new file mode 100644
index 00000000000..b66b129fe43
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold
+ 10000 5m 34816 18432 16384 0
+ 25000 5m 34816 18432 16384 0
+ 40000 5m 34816 18432 16384 0
+ 50000 5m 34816 18432 16384 0
+ 100000 5m 36864 18432 18432 0
+ 10000 40m 36864 18432 18432 0
+ 25000 40m 39936 18432 21504 0
+ 40000 40m 41984 18432 23552 0
+ 50000 40m 41984 18432 23552 0
+ 100000 40m 54272 18432 35840 0
+ 10000 300m 49152 18432 30720 0
+ 25000 300m 71680 18432 53248 0
+ 40000 300m 94208 18432 75776 0
+ 50000 300m 94208 18432 75776 0
+ 100000 300m 184320 18432 165888 0
diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json
new file mode 100644
index 00000000000..0d01a3f1cba
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json
@@ -0,0 +1,167 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"0",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"0",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0": {
+ "type":"DWRR",
+ "weight": "25"
+ },
+ "scheduler.1": {
+ "type":"DWRR",
+ "weight": "30"
+ },
+ "scheduler.2": {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "PORT_QOS_MAP": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220": {
+ "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
+ "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
+ "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
+ "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_enable": "3,4"
+ }
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSY": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ },
+ "AZURE_LOSSLESS": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ }
+ },
+ "QUEUE": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220|0": {
+ "scheduler" : "[SCHEDULER|scheduler.1]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220|1": {
+ "scheduler" : "[SCHEDULER|scheduler.2]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220|0-1": {
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220|3-4": {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ }
+ }
+}
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2
index da9c764db92..1083a6210fc 100644
--- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2
@@ -1,162 +1,2 @@
-{# Default values which will be used if no actual configura available #}
-{% set default_cable = '300m' %}
-{% set default_ports_num = 32 -%}
-
-{# Port configuration to cable length look-up table #}
-{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
-{# Roles described in the minigraph #}
-{% set ports2cable = {
- 'torrouter_server' : '5m',
- 'leafrouter_torrouter' : '40m',
- 'spinerouter_leafrouter' : '300m'
- }
-%}
-
-{%- macro cable_length(port_name) -%}
- {%- set cable_len = [] -%}
- {%- for local_port in DEVICE_NEIGHBOR -%}
- {%- if local_port == port_name -%}
- {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
- {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
- {%- set neighbor_role = neighbor.type -%}
- {%- set roles1 = switch_role + '_' + neighbor_role %}
- {%- set roles2 = neighbor_role + '_' + switch_role -%}
- {%- set roles1 = roles1 | lower -%}
- {%- set roles2 = roles2 | lower -%}
- {%- if roles1 in ports2cable -%}
- {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%}
- {%- elif roles2 in ports2cable -%}
- {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%}
- {%- endif -%}
- {%- endif -%}
- {%- endif -%}
- {%- endfor -%}
- {%- if cable_len -%}
- {{ cable_len.0 }}
- {%- else -%}
- {{ default_cable }}
- {%- endif -%}
-{% endmacro %}
-
-{%- if DEVICE_METADATA is defined %}
-{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
-{%- endif -%}
-
-{# Generate list of ports if not defined #}
-{% if PORT is not defined %}
- {% set PORT = [] %}
- {% for port_idx in range(0,default_ports_num) %}
- {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %}
- {% endfor %}
-{% endif -%}
-
-{% set port_names_list = [] %}
-{% for port in PORT %}
- {%- if port_names_list.append(port) %}{% endif %}
-{% endfor %}
-{% set port_names = port_names_list | join(',') -%}
-
-{
- "CABLE_LENGTH": {
- "AZURE": {
- {% for port in PORT %}
- {% set cable = cable_length(port) -%}
- "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %}
-
- {% endfor %}
- }
- },
-{%if switch_role == 'ToRRouter' %}
-{% set ingress_lossless_pool_size = '4194304' %}
-{% set ingress_lossy_pool_size = '7340032' %}
-{% set egress_lossless_pool_size = '16777152' %}
-{% set egress_lossy_pool_size = '7340032' %}
-{% else %}
-{% set ingress_lossless_pool_size = '2097152' %}
-{% set ingress_lossy_pool_size = '5242880' %}
-{% set egress_lossless_pool_size = '16777152' %}
-{% set egress_lossy_pool_size = '5242880' %}
-{%endif %}
- "BUFFER_POOL": {
- "ingress_lossless_pool": {
- "size": "{{ ingress_lossless_pool_size }}",
- "type": "ingress",
- "mode": "dynamic"
- },
- "ingress_lossy_pool": {
- "size": "{{ ingress_lossy_pool_size }}",
- "type": "ingress",
- "mode": "dynamic"
- },
- "egress_lossless_pool": {
- "size": "{{ egress_lossless_pool_size }}",
- "type": "egress",
- "mode": "dynamic"
- },
- "egress_lossy_pool": {
- "size": "{{ egress_lossy_pool_size }}",
- "type": "egress",
- "mode": "dynamic"
- }
- },
- "BUFFER_PROFILE": {
- "ingress_lossless_profile": {
- "pool":"[BUFFER_POOL|ingress_lossless_pool]",
- "size":"0",
- "dynamic_th":"0"
- },
- "ingress_lossy_profile": {
- "pool":"[BUFFER_POOL|ingress_lossy_pool]",
- "size":"0",
- "dynamic_th":"3"
- },
- "egress_lossless_profile": {
- "pool":"[BUFFER_POOL|egress_lossless_pool]",
- "size":"0",
- "dynamic_th":"7"
- },
- "egress_lossy_profile": {
- "pool":"[BUFFER_POOL|egress_lossy_pool]",
- "size":"4096",
- "dynamic_th":"3"
- },
- "pg_lossy_profile": {
- "pool":"[BUFFER_POOL|ingress_lossy_pool]",
- "size":"0",
- "dynamic_th":"3"
- },
- "q_lossless_profile": {
- "pool":"[BUFFER_POOL|egress_lossless_pool]",
- "size":"0",
- "dynamic_th":"7"
- },
- "q_lossy_profile": {
- "pool":"[BUFFER_POOL|egress_lossy_pool]",
- "size":"0",
- "dynamic_th":"3"
- }
- },
- "BUFFER_PORT_INGRESS_PROFILE_LIST": {
- "{{ port_names }}": {
- "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]"
- }
- },
- "BUFFER_PORT_EGRESS_PROFILE_LIST": {
- "{{ port_names }}": {
- "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]"
- }
- },
- "BUFFER_PG": {
- "{{ port_names }}|0-1": {
- "profile" : "[BUFFER_PROFILE|pg_lossy_profile]"
- }
- },
- "BUFFER_QUEUE": {
- "{{ port_names }}|3-4": {
- "profile" : "[BUFFER_PROFILE|q_lossless_profile]"
- },
- "{{ port_names }}|0-1": {
- "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
- }
- }
-}
+{%- set default_topo = 't0' %}
+{%- include 'buffers_config.j2' %}
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2
new file mode 100644
index 00000000000..475a0227143
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2
@@ -0,0 +1,90 @@
+{% set default_cable = '5m' %}
+{% set ingress_lossless_pool_size = '4194304' %}
+{% set ingress_lossy_pool_size = '7340032' %}
+{% set egress_lossless_pool_size = '16777152' %}
+{% set egress_lossy_pool_size = '7340032' %}
+
+{%- 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)) %}{%- endif %}
+ {%- endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "{{ ingress_lossless_pool_size }}",
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "ingress_lossy_pool": {
+ "size": "{{ ingress_lossy_pool_size }}",
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "{{ egress_lossless_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossy_pool": {
+ "size": "{{ egress_lossy_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"0"
+ },
+ "ingress_lossy_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ },
+ "egress_lossless_profile": {
+ "pool":"[BUFFER_POOL|egress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"7"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"4096",
+ "dynamic_th":"3"
+ },
+ "q_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
+
+{%- macro generate_profile_lists(port_names) %}
+ "BUFFER_PORT_INGRESS_PROFILE_LIST": {
+ "{{ port_names }}": {
+ "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]"
+ }
+ },
+ "BUFFER_PORT_EGRESS_PROFILE_LIST": {
+ "{{ port_names }}": {
+ "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]"
+ }
+ }
+{%- endmacro %}
+
+{%- macro generate_queue_buffers(port_names) %}
+ "BUFFER_QUEUE": {
+ "{{ port_names }}|3-4": {
+ "profile" : "[BUFFER_PROFILE|egress_lossless_profile]"
+ },
+ "{{ port_names }}|0-1": {
+ "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
+ }
+ }
+{%- endmacro %}
+
+
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2
new file mode 100644
index 00000000000..c292ecc2f21
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2
@@ -0,0 +1,90 @@
+{% set default_cable = '5m' %}
+{% set ingress_lossless_pool_size = '2097152' %}
+{% set ingress_lossy_pool_size = '5242880' %}
+{% set egress_lossless_pool_size = '16777152' %}
+{% set egress_lossy_pool_size = '5242880' %}
+
+{%- 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)) %}{%- endif %}
+ {%- endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "{{ ingress_lossless_pool_size }}",
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "ingress_lossy_pool": {
+ "size": "{{ ingress_lossy_pool_size }}",
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "{{ egress_lossless_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossy_pool": {
+ "size": "{{ egress_lossy_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"0"
+ },
+ "ingress_lossy_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ },
+ "egress_lossless_profile": {
+ "pool":"[BUFFER_POOL|egress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"7"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"4096",
+ "dynamic_th":"3"
+ },
+ "q_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
+
+{%- macro generate_profile_lists(port_names) %}
+ "BUFFER_PORT_INGRESS_PROFILE_LIST": {
+ "{{ port_names }}": {
+ "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]"
+ }
+ },
+ "BUFFER_PORT_EGRESS_PROFILE_LIST": {
+ "{{ port_names }}": {
+ "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]"
+ }
+ }
+{%- endmacro %}
+
+{%- macro generate_queue_buffers(port_names) %}
+ "BUFFER_QUEUE": {
+ "{{ port_names }}|3-4": {
+ "profile" : "[BUFFER_PROFILE|egress_lossless_profile]"
+ },
+ "{{ port_names }}|0-1": {
+ "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
+ }
+ }
+{%- endmacro %}
+
+
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini
index 816bb0e94a7..1e1906ff0ef 100644
--- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini
@@ -1,33 +1,33 @@
-# name lanes
-Ethernet0 0,1,2,3
-Ethernet4 4,5,6,7
-Ethernet8 8,9,10,11
-Ethernet12 12,13,14,15
-Ethernet16 16,17,18,19
-Ethernet20 20,21,22,23
-Ethernet24 24,25,26,27
-Ethernet28 28,29,30,31
-Ethernet32 32,33,34,35
-Ethernet36 36,37,38,39
-Ethernet40 40,41,42,43
-Ethernet44 44,45,46,47
-Ethernet48 48,49,50,51
-Ethernet52 52,53,54,55
-Ethernet56 56,57,58,59
-Ethernet60 60,61,62,63
-Ethernet64 64,65,66,67
-Ethernet68 68,69,70,71
-Ethernet72 72,73,74,75
-Ethernet76 76,77,78,79
-Ethernet80 80,81,82,83
-Ethernet84 84,85,86,87
-Ethernet88 88,89,90,91
-Ethernet92 92,93,94,95
-Ethernet96 96,97,98,99
-Ethernet100 100,101,102,103
-Ethernet104 104,105,106,107
-Ethernet108 108,109,110,111
-Ethernet112 112,113,114,115
-Ethernet116 116,117,118,119
-Ethernet120 120,121,122,123
-Ethernet124 124,125,126,127
+# name lanes alias
+Ethernet0 0,1,2,3 etp1
+Ethernet4 4,5,6,7 etp2
+Ethernet8 8,9,10,11 etp3
+Ethernet12 12,13,14,15 etp4
+Ethernet16 16,17,18,19 etp5
+Ethernet20 20,21,22,23 etp6
+Ethernet24 24,25,26,27 etp7
+Ethernet28 28,29,30,31 etp8
+Ethernet32 32,33,34,35 etp9
+Ethernet36 36,37,38,39 etp10
+Ethernet40 40,41,42,43 etp11
+Ethernet44 44,45,46,47 etp12
+Ethernet48 48,49,50,51 etp13
+Ethernet52 52,53,54,55 etp14
+Ethernet56 56,57,58,59 etp15
+Ethernet60 60,61,62,63 etp16
+Ethernet64 64,65,66,67 etp17
+Ethernet68 68,69,70,71 etp18
+Ethernet72 72,73,74,75 etp19
+Ethernet76 76,77,78,79 etp20
+Ethernet80 80,81,82,83 etp21
+Ethernet84 84,85,86,87 etp22
+Ethernet88 88,89,90,91 etp23
+Ethernet92 92,93,94,95 etp24
+Ethernet96 96,97,98,99 etp25
+Ethernet100 100,101,102,103 etp26
+Ethernet104 104,105,106,107 etp27
+Ethernet108 108,109,110,111 etp28
+Ethernet112 112,113,114,115 etp29
+Ethernet116 116,117,118,119 etp30
+Ethernet120 120,121,122,123 etp31
+Ethernet124 124,125,126,127 etp32
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json
index 3e01af3f2c6..df3d29c636e 100644
--- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json
@@ -127,6 +127,7 @@
"AZURE_LOSSY": {
"wred_green_enable":"true",
"wred_yellow_enable":"true",
+ "wred_red_enable":"true",
"ecn":"ecn_all",
"red_max_threshold":"516096",
"red_min_threshold":"516096",
@@ -138,6 +139,7 @@
"AZURE_LOSSLESS": {
"wred_green_enable":"true",
"wred_yellow_enable":"true",
+ "wred_red_enable":"true",
"ecn":"ecn_all",
"red_max_threshold":"516096",
"red_min_threshold":"516096",
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers.json.j2
new file mode 100644
index 00000000000..1083a6210fc
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers.json.j2
@@ -0,0 +1,2 @@
+{%- set default_topo = 't0' %}
+{%- include 'buffers_config.j2' %}
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2
new file mode 100644
index 00000000000..475a0227143
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2
@@ -0,0 +1,90 @@
+{% set default_cable = '5m' %}
+{% set ingress_lossless_pool_size = '4194304' %}
+{% set ingress_lossy_pool_size = '7340032' %}
+{% set egress_lossless_pool_size = '16777152' %}
+{% set egress_lossy_pool_size = '7340032' %}
+
+{%- 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)) %}{%- endif %}
+ {%- endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "{{ ingress_lossless_pool_size }}",
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "ingress_lossy_pool": {
+ "size": "{{ ingress_lossy_pool_size }}",
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "{{ egress_lossless_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossy_pool": {
+ "size": "{{ egress_lossy_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"0"
+ },
+ "ingress_lossy_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ },
+ "egress_lossless_profile": {
+ "pool":"[BUFFER_POOL|egress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"7"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"4096",
+ "dynamic_th":"3"
+ },
+ "q_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
+
+{%- macro generate_profile_lists(port_names) %}
+ "BUFFER_PORT_INGRESS_PROFILE_LIST": {
+ "{{ port_names }}": {
+ "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]"
+ }
+ },
+ "BUFFER_PORT_EGRESS_PROFILE_LIST": {
+ "{{ port_names }}": {
+ "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]"
+ }
+ }
+{%- endmacro %}
+
+{%- macro generate_queue_buffers(port_names) %}
+ "BUFFER_QUEUE": {
+ "{{ port_names }}|3-4": {
+ "profile" : "[BUFFER_PROFILE|egress_lossless_profile]"
+ },
+ "{{ port_names }}|0-1": {
+ "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
+ }
+ }
+{%- endmacro %}
+
+
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2
new file mode 100644
index 00000000000..c292ecc2f21
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2
@@ -0,0 +1,90 @@
+{% set default_cable = '5m' %}
+{% set ingress_lossless_pool_size = '2097152' %}
+{% set ingress_lossy_pool_size = '5242880' %}
+{% set egress_lossless_pool_size = '16777152' %}
+{% set egress_lossy_pool_size = '5242880' %}
+
+{%- 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)) %}{%- endif %}
+ {%- endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "{{ ingress_lossless_pool_size }}",
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "ingress_lossy_pool": {
+ "size": "{{ ingress_lossy_pool_size }}",
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "{{ egress_lossless_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossy_pool": {
+ "size": "{{ egress_lossy_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"0"
+ },
+ "ingress_lossy_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ },
+ "egress_lossless_profile": {
+ "pool":"[BUFFER_POOL|egress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"7"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"4096",
+ "dynamic_th":"3"
+ },
+ "q_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
+
+{%- macro generate_profile_lists(port_names) %}
+ "BUFFER_PORT_INGRESS_PROFILE_LIST": {
+ "{{ port_names }}": {
+ "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]"
+ }
+ },
+ "BUFFER_PORT_EGRESS_PROFILE_LIST": {
+ "{{ port_names }}": {
+ "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]"
+ }
+ }
+{%- endmacro %}
+
+{%- macro generate_queue_buffers(port_names) %}
+ "BUFFER_QUEUE": {
+ "{{ port_names }}|3-4": {
+ "profile" : "[BUFFER_PROFILE|egress_lossless_profile]"
+ },
+ "{{ port_names }}|0-1": {
+ "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
+ }
+ }
+{%- endmacro %}
+
+
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini
new file mode 100644
index 00000000000..b66b129fe43
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold
+ 10000 5m 34816 18432 16384 0
+ 25000 5m 34816 18432 16384 0
+ 40000 5m 34816 18432 16384 0
+ 50000 5m 34816 18432 16384 0
+ 100000 5m 36864 18432 18432 0
+ 10000 40m 36864 18432 18432 0
+ 25000 40m 39936 18432 21504 0
+ 40000 40m 41984 18432 23552 0
+ 50000 40m 41984 18432 23552 0
+ 100000 40m 54272 18432 35840 0
+ 10000 300m 49152 18432 30720 0
+ 25000 300m 71680 18432 53248 0
+ 40000 300m 94208 18432 75776 0
+ 50000 300m 94208 18432 75776 0
+ 100000 300m 184320 18432 165888 0
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini
new file mode 100644
index 00000000000..9e01da79f44
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini
@@ -0,0 +1,57 @@
+# name lanes speed alias index
+Ethernet0 0,1 50000 etp1a 1
+Ethernet2 2,3 50000 etp1b 1
+Ethernet4 4,5 50000 etp2a 2
+Ethernet6 6,7 50000 etp2b 2
+Ethernet8 8,9 50000 etp3a 3
+Ethernet10 10,11 50000 etp3b 3
+Ethernet12 12,13 50000 etp4a 4
+Ethernet14 14,15 50000 etp4b 4
+Ethernet16 16,17 50000 etp5a 5
+Ethernet18 18,19 50000 etp5b 5
+Ethernet20 20,21 50000 etp6a 6
+Ethernet22 22,23 50000 etp6b 6
+Ethernet24 24,25,26,27 100000 etp7 7
+Ethernet28 28,29,30,31 100000 etp8 8
+Ethernet32 32,33,34,35 100000 etp9 9
+Ethernet36 36,37,38,39 100000 etp10 10
+Ethernet40 40,41 50000 etp11a 11
+Ethernet42 42,43 50000 etp11b 11
+Ethernet44 44,45 50000 etp12a 12
+Ethernet46 46,47 50000 etp12b 12
+Ethernet48 48,49 50000 etp13a 13
+Ethernet50 50,51 50000 etp13b 13
+Ethernet52 52,53 50000 etp14a 14
+Ethernet54 54,55 50000 etp14b 14
+Ethernet56 56,57 50000 etp15a 15
+Ethernet58 58,59 50000 etp15b 15
+Ethernet60 60,61 50000 etp16a 16
+Ethernet62 62,63 50000 etp16b 16
+Ethernet64 64,65 50000 etp17a 17
+Ethernet66 66,67 50000 etp17b 17
+Ethernet68 68,69 50000 etp18a 18
+Ethernet70 70,71 50000 etp18b 18
+Ethernet72 72,73 50000 etp19a 19
+Ethernet74 74,75 50000 etp19b 19
+Ethernet76 76,77 50000 etp20a 20
+Ethernet78 78,79 50000 etp20b 20
+Ethernet80 80,81 50000 etp21a 21
+Ethernet82 82,83 50000 etp21b 21
+Ethernet84 84,85 50000 etp22a 22
+Ethernet86 86,87 50000 etp22b 22
+Ethernet88 88,89,90,91 100000 etp23 23
+Ethernet92 92,93,94,95 100000 etp24 24
+Ethernet96 96,97,98,99 100000 etp25 25
+Ethernet100 100,101,102,103 100000 etp26 26
+Ethernet104 104,105 50000 etp27a 27
+Ethernet106 106,107 50000 etp27b 27
+Ethernet108 108,109 50000 etp28a 28
+Ethernet110 110,111 50000 etp28b 28
+Ethernet112 112,113 50000 etp29a 29
+Ethernet114 114,115 50000 etp29b 29
+Ethernet116 116,117 50000 etp30a 30
+Ethernet118 118,119 50000 etp30b 30
+Ethernet120 120,121 50000 etp31a 31
+Ethernet122 122,123 50000 etp31b 31
+Ethernet124 124,125 50000 etp32a 32
+Ethernet126 126,127 50000 etp32b 32
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json
new file mode 100644
index 00000000000..03c89438ab6
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json
@@ -0,0 +1,168 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"0",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"0",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0": {
+ "type":"DWRR",
+ "weight": "25"
+ },
+ "scheduler.1": {
+ "type":"DWRR",
+ "weight": "30"
+ },
+ "scheduler.2": {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "3": "3",
+ "4": "4"
+ }
+ },
+ "PORT_QOS_MAP": {
+ "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68": {
+ "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
+ "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
+ "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
+ "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_enable": "3,4"
+ }
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSY": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ },
+ "AZURE_LOSSLESS": {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "wred_red_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"516096",
+ "red_min_threshold":"516096",
+ "yellow_max_threshold":"516096",
+ "yellow_min_threshold":"516096",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ }
+ },
+ "QUEUE": {
+ "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68|0": {
+ "scheduler" : "[SCHEDULER|scheduler.1]"
+ },
+ "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68|1": {
+ "scheduler" : "[SCHEDULER|scheduler.2]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1": {
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]"
+ },
+ "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68|3-4": {
+ "scheduler" : "[SCHEDULER|scheduler.0]",
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
+ }
+ }
+}
+
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai.profile b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai.profile
new file mode 100644
index 00000000000..bfbcb1e78f4
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai.profile
@@ -0,0 +1 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_2700_48x50g_8x100g.xml
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml
new file mode 100644
index 00000000000..bda7a3e1cc1
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml
@@ -0,0 +1,267 @@
+
+
+
+
+
+ 00:02:03:04:05:00
+
+
+ 32
+
+
+
+
+ 1
+ 4
+ 16
+
+
+ 3
+
+
+ 3221225472
+ 2
+
+
+ 3
+ 4
+ 17
+ 1
+ 3221225472
+ 2
+
+
+ 5
+ 4
+ 18
+ 3
+ 3221225472
+ 2
+
+
+ 7
+ 4
+ 19
+ 1
+ 3221225472
+ 2
+
+
+ 9
+ 4
+ 20
+ 3
+ 3221225472
+ 2
+
+
+ 11
+ 4
+ 21
+ 1
+ 3221225472
+ 2
+
+
+ 13
+ 4
+ 22
+ 3
+ 11534336
+
+
+ 15
+ 4
+ 23
+ 1
+ 11534336
+
+
+ 17
+ 4
+ 24
+ 3
+ 11534336
+
+
+ 19
+ 4
+ 25
+ 1
+ 11534336
+
+
+ 21
+ 4
+ 26
+ 3
+ 3221225472
+ 2
+
+
+ 23
+ 4
+ 27
+ 1
+ 3221225472
+ 2>
+
+
+ 25
+ 4
+ 28
+ 3
+ 3221225472
+ 2
+
+
+ 27
+ 4
+ 29
+ 1
+ 3221225472
+ 2
+
+
+ 29
+ 4
+ 30
+ 3
+ 3221225472
+ 2
+
+
+ 31
+ 4
+ 31
+ 1
+ 3221225472
+ 2
+
+
+ 33
+ 4
+ 14
+ 3
+ 3221225472
+ 2
+
+
+ 35
+ 4
+ 15
+ 1
+ 3221225472
+ 2
+
+
+ 37
+ 4
+ 12
+ 3
+ 3221225472
+ 2
+
+
+ 39
+ 4
+ 13
+ 1
+ 3221225472
+ 2
+
+
+ 41
+ 4
+ 10
+ 3
+ 3221225472
+ 2
+
+
+ 43
+ 4
+ 11
+ 1
+ 3221225472
+ 2
+
+
+ 45
+ 4
+ 8
+ 3
+ 11534336
+
+
+ 47
+ 4
+ 9
+ 1
+ 11534336
+
+
+ 49
+ 4
+ 6
+ 3
+ 11534336
+
+
+ 51
+ 4
+ 7
+ 1
+ 11534336
+
+
+ 53
+ 4
+ 4
+ 3
+ 3221225472
+ 2
+
+
+ 55
+ 4
+ 5
+ 1
+ 3221225472
+ 2
+
+
+ 57
+ 4
+ 2
+ 3
+ 3221225472
+ 2
+
+
+ 59
+ 4
+ 3
+ 1
+ 3221225472
+ 2
+
+
+ 61
+ 4
+ 0
+ 3
+ 3221225472
+ 2
+
+
+ 63
+ 4
+ 1
+ 1
+ 3221225472
+ 2
+
+
+
+
diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2
deleted file mode 100644
index da9c764db92..00000000000
--- a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2
+++ /dev/null
@@ -1,162 +0,0 @@
-{# Default values which will be used if no actual configura available #}
-{% set default_cable = '300m' %}
-{% set default_ports_num = 32 -%}
-
-{# Port configuration to cable length look-up table #}
-{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
-{# Roles described in the minigraph #}
-{% set ports2cable = {
- 'torrouter_server' : '5m',
- 'leafrouter_torrouter' : '40m',
- 'spinerouter_leafrouter' : '300m'
- }
-%}
-
-{%- macro cable_length(port_name) -%}
- {%- set cable_len = [] -%}
- {%- for local_port in DEVICE_NEIGHBOR -%}
- {%- if local_port == port_name -%}
- {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
- {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
- {%- set neighbor_role = neighbor.type -%}
- {%- set roles1 = switch_role + '_' + neighbor_role %}
- {%- set roles2 = neighbor_role + '_' + switch_role -%}
- {%- set roles1 = roles1 | lower -%}
- {%- set roles2 = roles2 | lower -%}
- {%- if roles1 in ports2cable -%}
- {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%}
- {%- elif roles2 in ports2cable -%}
- {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%}
- {%- endif -%}
- {%- endif -%}
- {%- endif -%}
- {%- endfor -%}
- {%- if cable_len -%}
- {{ cable_len.0 }}
- {%- else -%}
- {{ default_cable }}
- {%- endif -%}
-{% endmacro %}
-
-{%- if DEVICE_METADATA is defined %}
-{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
-{%- endif -%}
-
-{# Generate list of ports if not defined #}
-{% if PORT is not defined %}
- {% set PORT = [] %}
- {% for port_idx in range(0,default_ports_num) %}
- {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %}
- {% endfor %}
-{% endif -%}
-
-{% set port_names_list = [] %}
-{% for port in PORT %}
- {%- if port_names_list.append(port) %}{% endif %}
-{% endfor %}
-{% set port_names = port_names_list | join(',') -%}
-
-{
- "CABLE_LENGTH": {
- "AZURE": {
- {% for port in PORT %}
- {% set cable = cable_length(port) -%}
- "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %}
-
- {% endfor %}
- }
- },
-{%if switch_role == 'ToRRouter' %}
-{% set ingress_lossless_pool_size = '4194304' %}
-{% set ingress_lossy_pool_size = '7340032' %}
-{% set egress_lossless_pool_size = '16777152' %}
-{% set egress_lossy_pool_size = '7340032' %}
-{% else %}
-{% set ingress_lossless_pool_size = '2097152' %}
-{% set ingress_lossy_pool_size = '5242880' %}
-{% set egress_lossless_pool_size = '16777152' %}
-{% set egress_lossy_pool_size = '5242880' %}
-{%endif %}
- "BUFFER_POOL": {
- "ingress_lossless_pool": {
- "size": "{{ ingress_lossless_pool_size }}",
- "type": "ingress",
- "mode": "dynamic"
- },
- "ingress_lossy_pool": {
- "size": "{{ ingress_lossy_pool_size }}",
- "type": "ingress",
- "mode": "dynamic"
- },
- "egress_lossless_pool": {
- "size": "{{ egress_lossless_pool_size }}",
- "type": "egress",
- "mode": "dynamic"
- },
- "egress_lossy_pool": {
- "size": "{{ egress_lossy_pool_size }}",
- "type": "egress",
- "mode": "dynamic"
- }
- },
- "BUFFER_PROFILE": {
- "ingress_lossless_profile": {
- "pool":"[BUFFER_POOL|ingress_lossless_pool]",
- "size":"0",
- "dynamic_th":"0"
- },
- "ingress_lossy_profile": {
- "pool":"[BUFFER_POOL|ingress_lossy_pool]",
- "size":"0",
- "dynamic_th":"3"
- },
- "egress_lossless_profile": {
- "pool":"[BUFFER_POOL|egress_lossless_pool]",
- "size":"0",
- "dynamic_th":"7"
- },
- "egress_lossy_profile": {
- "pool":"[BUFFER_POOL|egress_lossy_pool]",
- "size":"4096",
- "dynamic_th":"3"
- },
- "pg_lossy_profile": {
- "pool":"[BUFFER_POOL|ingress_lossy_pool]",
- "size":"0",
- "dynamic_th":"3"
- },
- "q_lossless_profile": {
- "pool":"[BUFFER_POOL|egress_lossless_pool]",
- "size":"0",
- "dynamic_th":"7"
- },
- "q_lossy_profile": {
- "pool":"[BUFFER_POOL|egress_lossy_pool]",
- "size":"0",
- "dynamic_th":"3"
- }
- },
- "BUFFER_PORT_INGRESS_PROFILE_LIST": {
- "{{ port_names }}": {
- "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]"
- }
- },
- "BUFFER_PORT_EGRESS_PROFILE_LIST": {
- "{{ port_names }}": {
- "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]"
- }
- },
- "BUFFER_PG": {
- "{{ port_names }}|0-1": {
- "profile" : "[BUFFER_PROFILE|pg_lossy_profile]"
- }
- },
- "BUFFER_QUEUE": {
- "{{ port_names }}|3-4": {
- "profile" : "[BUFFER_PROFILE|q_lossless_profile]"
- },
- "{{ port_names }}|0-1": {
- "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
- }
- }
-}
diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2
new file mode 120000
index 00000000000..add8bf8bb7c
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t0.j2
new file mode 120000
index 00000000000..7bcae62336f
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t0.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t1.j2
new file mode 120000
index 00000000000..a437d613434
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t1.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2
\ No newline at end of file
diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers.json.j2 b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers.json.j2
new file mode 100644
index 00000000000..0b1cb2c541b
--- /dev/null
+++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers.json.j2
@@ -0,0 +1,2 @@
+{%- set default_topo = 't1' %}
+{%- include 'buffers_config.j2' %}
diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t0.j2 b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t0.j2
new file mode 100644
index 00000000000..3e39d411e8b
--- /dev/null
+++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t0.j2
@@ -0,0 +1,47 @@
+
+{%- set default_cable = '5m' %}
+
+{%- macro generate_port_lists(PORT_ALL) %}
+ {# Generate list of ports #}
+ {%- for port_idx in range(0,128,4) %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %}
+ {%- endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "11213696",
+ "type": "ingress",
+ "mode": "dynamic",
+ "xoff": "3855488"
+ },
+ "egress_lossy_pool": {
+ "size": "9532224",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "15982720",
+ "type": "egress",
+ "mode": "static"
+ }
+ },
+ "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":"1518",
+ "static_th":"3995680"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"1518",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t1.j2 b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t1.j2
new file mode 100644
index 00000000000..d9f562f9562
--- /dev/null
+++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t1.j2
@@ -0,0 +1,47 @@
+
+{%- set default_cable = '40m' %}
+
+{%- macro generate_port_lists(PORT_ALL) %}
+ {# Generate list of ports #}
+ {%- for port_idx in range(0,128,4) %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %}
+ {%- endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ "size": "10443264",
+ "type": "ingress",
+ "mode": "dynamic",
+ "xoff": "4625920"
+ },
+ "egress_lossy_pool": {
+ "size": "8877440",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "15982720",
+ "type": "egress",
+ "mode": "static"
+ }
+ },
+ "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":"1518",
+ "static_th":"3995680"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"1518",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/pg_profile_lookup.ini b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/pg_profile_lookup.ini
new file mode 100644
index 00000000000..3b2a417cebc
--- /dev/null
+++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size xon xoff threshold xon_offset
+ 10000 5m 1248 2288 35776 -4 2288
+ 25000 5m 1248 2288 53248 -4 2288
+ 40000 5m 1248 2288 66560 -4 2288
+ 50000 5m 1248 2288 90272 -4 2288
+ 100000 5m 1248 2288 165568 -4 2288
+ 10000 40m 1248 2288 37024 -4 2288
+ 25000 40m 1248 2288 53248 -4 2288
+ 40000 40m 1248 2288 71552 -4 2288
+ 50000 40m 1248 2288 96096 -4 2288
+ 100000 40m 1248 2288 177632 -4 2288
+ 10000 300m 1248 2288 46176 -4 2288
+ 25000 300m 1248 2288 79040 -4 2288
+ 40000 300m 1248 2288 108160 -4 2288
+ 50000 300m 1248 2288 141856 -4 2288
+ 100000 300m 1248 2288 268736 -4 2288
diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/qos.json b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/qos.json
new file mode 100644
index 00000000000..b724b48c2c2
--- /dev/null
+++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/qos.json
@@ -0,0 +1,167 @@
+{
+ "TC_TO_PRIORITY_GROUP_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7"
+ }
+ },
+ "MAP_PFC_PRIORITY_TO_QUEUE": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7"
+ }
+ },
+ "TC_TO_QUEUE_MAP": {
+ "AZURE": {
+ "0": "0",
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7"
+ }
+ },
+ "DSCP_TO_TC_MAP": {
+ "AZURE": {
+ "0":"0",
+ "1":"0",
+ "2":"0",
+ "3":"3",
+ "4":"4",
+ "5":"0",
+ "6":"0",
+ "7":"0",
+ "8":"1",
+ "9":"0",
+ "10":"0",
+ "11":"0",
+ "12":"0",
+ "13":"0",
+ "14":"0",
+ "15":"0",
+ "16":"0",
+ "17":"0",
+ "18":"0",
+ "19":"0",
+ "20":"0",
+ "21":"0",
+ "22":"0",
+ "23":"0",
+ "24":"0",
+ "25":"0",
+ "26":"0",
+ "27":"0",
+ "28":"0",
+ "29":"0",
+ "30":"0",
+ "31":"0",
+ "32":"0",
+ "33":"0",
+ "34":"0",
+ "35":"0",
+ "36":"0",
+ "37":"0",
+ "38":"0",
+ "39":"0",
+ "40":"0",
+ "41":"0",
+ "42":"0",
+ "43":"0",
+ "44":"0",
+ "45":"0",
+ "46":"0",
+ "47":"0",
+ "48":"0",
+ "49":"0",
+ "50":"0",
+ "51":"0",
+ "52":"0",
+ "53":"0",
+ "54":"0",
+ "55":"0",
+ "56":"0",
+ "57":"0",
+ "58":"0",
+ "59":"0",
+ "60":"0",
+ "61":"0",
+ "62":"0",
+ "63":"0"
+ }
+ },
+ "SCHEDULER": {
+ "scheduler.0" : {
+ "type":"DWRR",
+ "weight": "25"
+ },
+ "scheduler.1" : {
+ "type":"DWRR",
+ "weight": "30"
+ },
+ "scheduler.2" : {
+ "type":"DWRR",
+ "weight": "20"
+ }
+ },
+ "PORT_QOS_MAP": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124": {
+ "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
+ "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
+ "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
+ "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
+ "pfc_enable": "3,4"
+ }
+ },
+ "WRED_PROFILE": {
+ "AZURE_LOSSY" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"512000",
+ "red_min_threshold":"512000",
+ "yellow_max_threshold":"512000",
+ "yellow_min_threshold":"512000",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ },
+ "AZURE_LOSSLESS" : {
+ "wred_green_enable":"true",
+ "wred_yellow_enable":"true",
+ "ecn":"ecn_all",
+ "red_max_threshold":"512000",
+ "red_min_threshold":"512000",
+ "yellow_max_threshold":"512000",
+ "yellow_min_threshold":"512000",
+ "green_max_threshold": "184320",
+ "green_min_threshold": "184320"
+ }
+ },
+ "QUEUE": {
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1" : {
+ "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : {
+ "scheduler" : "[SCHEDULER|scheduler.0]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : {
+ "scheduler" : "[SCHEDULER|scheduler.1]"
+ },
+ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : {
+ "scheduler" : "[SCHEDULER|scheduler.2]"
+ }
+ }
+}
diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/minigraph.xml b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/minigraph.xml
index 210eac2fd62..215ac176c5d 100644
--- a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/minigraph.xml
+++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/minigraph.xml
@@ -1,1074 +1,233 @@
-
-
-
-
-
- ARISTA01T0
- 10.0.0.33
- sonic
- 10.0.0.32
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.0
- ARISTA01T2
- 10.0.0.1
- 1
- 180
- 60
-
-
- ARISTA02T0
- 10.0.0.35
- sonic
- 10.0.0.34
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.2
- ARISTA02T2
- 10.0.0.3
- 1
- 180
- 60
-
-
- ARISTA03T0
- 10.0.0.37
- sonic
- 10.0.0.36
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.4
- ARISTA03T2
- 10.0.0.5
- 1
- 180
- 60
-
-
- ARISTA04T0
- 10.0.0.39
- sonic
- 10.0.0.38
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.6
- ARISTA04T2
- 10.0.0.7
- 1
- 180
- 60
-
-
- ARISTA05T0
- 10.0.0.41
- sonic
- 10.0.0.40
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.8
- ARISTA05T2
- 10.0.0.9
- 1
- 180
- 60
-
-
- ARISTA06T0
- 10.0.0.43
- sonic
- 10.0.0.42
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.10
- ARISTA06T2
- 10.0.0.11
- 1
- 180
- 60
-
-
- ARISTA07T0
- 10.0.0.45
- sonic
- 10.0.0.44
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.12
- ARISTA07T2
- 10.0.0.13
- 1
- 180
- 60
-
-
- ARISTA08T0
- 10.0.0.47
- sonic
- 10.0.0.46
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.14
- ARISTA08T2
- 10.0.0.15
- 1
- 180
- 60
-
-
- ARISTA09T0
- 10.0.0.49
- sonic
- 10.0.0.48
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.16
- ARISTA09T2
- 10.0.0.17
- 1
- 180
- 60
-
-
- ARISTA10T0
- 10.0.0.51
- sonic
- 10.0.0.50
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.18
- ARISTA10T2
- 10.0.0.19
- 1
- 180
- 60
-
-
- ARISTA11T0
- 10.0.0.53
- sonic
- 10.0.0.52
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.20
- ARISTA11T2
- 10.0.0.21
- 1
- 180
- 60
-
-
- ARISTA12T0
- 10.0.0.55
- sonic
- 10.0.0.54
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.22
- ARISTA12T2
- 10.0.0.23
- 1
- 180
- 60
-
-
- ARISTA13T0
- 10.0.0.57
- sonic
- 10.0.0.56
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.24
- ARISTA13T2
- 10.0.0.25
- 1
- 180
- 60
-
-
- ARISTA14T0
- 10.0.0.59
- sonic
- 10.0.0.58
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.26
- ARISTA14T2
- 10.0.0.27
- 1
- 180
- 60
-
-
- ARISTA15T0
- 10.0.0.61
- sonic
- 10.0.0.60
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.28
- ARISTA15T2
- 10.0.0.29
- 1
- 180
- 60
-
-
- ARISTA16T0
- 10.0.0.63
- sonic
- 10.0.0.62
- 1
- 180
- 60
-
-
- sonic
- 10.0.0.30
- ARISTA16T2
- 10.0.0.31
- 1
- 180
- 60
-
-
-
-
- 65100
- sonic
-
-
- 10.0.0.33
-
-
-
-
- 10.0.0.1
-
-
-
-
- 10.0.0.35
-
-
-
-
- 10.0.0.3
-
-
-
-
- 10.0.0.37
-
-
-
-
- 10.0.0.5
-
-
-
-
- 10.0.0.39
-
-
-
-
- 10.0.0.7
-
-
-
-
- 10.0.0.41
-
-
-
-
- 10.0.0.9
-
-
-
-
- 10.0.0.43
-
-
-
-
- 10.0.0.11
-
-
-
-
- 10.0.0.45
-
-
-
-
- 10.0.0.13
-
-
-
-
- 10.0.0.47
-
-
-
-
- 10.0.0.15
-
-
-
-
- 10.0.0.49
-
-
-
-
- 10.0.0.17
-
-
-
-
- 10.0.0.51
-
-
-
-
- 10.0.0.19
-
-
-
-
- 10.0.0.53
-
-
-
-
- 10.0.0.21
-
-
-
-
- 10.0.0.55
-
-
-
-
- 10.0.0.23
-
-
-
-
- 10.0.0.57
-
-
-
-
- 10.0.0.25
-
-
-
-
- 10.0.0.59
-
-
-
-
- 10.0.0.27
-
-
-
-
- 10.0.0.61
-
-
-
-
- 10.0.0.29
-
-
-
-
- 10.0.0.63
-
-
-
-
- 10.0.0.31
-
-
-
-
-
-
-
- 64001
- ARISTA01T0
-
-
-
- 65200
- ARISTA01T2
-
-
-
- 64002
- ARISTA02T0
-
-
-
- 65200
- ARISTA02T2
-
-
-
- 64003
- ARISTA03T0
-
-
-
- 65200
- ARISTA03T2
-
-
-
- 64004
- ARISTA04T0
-
-
-
- 65200
- ARISTA04T2
-
-
-
- 64005
- ARISTA05T0
-
-
-
- 65200
- ARISTA05T2
-
-
-
- 64006
- ARISTA06T0
-
-
-
- 65200
- ARISTA06T2
-
-
-
- 64007
- ARISTA07T0
-
-
-
- 65200
- ARISTA07T2
-
-
-
- 64008
- ARISTA08T0
-
-
-
- 65200
- ARISTA08T2
-
-
-
- 64009
- ARISTA09T0
-
-
-
- 65200
- ARISTA09T2
-
-
-
- 64010
- ARISTA10T0
-
-
-
- 65200
- ARISTA10T2
-
-
-
- 64011
- ARISTA11T0
-
-
-
- 65200
- ARISTA11T2
-
-
-
- 64012
- ARISTA12T0
-
-
-
- 65200
- ARISTA12T2
-
-
-
- 64013
- ARISTA13T0
-
-
-
- 65200
- ARISTA13T2
-
-
-
- 64014
- ARISTA14T0
-
-
-
- 65200
- ARISTA14T2
-
-
-
- 64015
- ARISTA15T0
-
-
-
- 65200
- ARISTA15T2
-
-
-
- 64016
- ARISTA16T0
-
-
-
- 65200
- ARISTA16T2
-
-
-
-
-
-
-
-
-
- HostIP
- Loopback0
-
- 10.1.0.32/32
-
- 10.1.0.32/32
-
-
-
-
-
-
-
- sonic
-
-
-
-
-
- Ethernet0
- 10.0.0.0/31
-
-
-
- Ethernet4
- 10.0.0.2/31
-
-
-
- Ethernet8
- 10.0.0.4/31
-
-
-
- Ethernet12
- 10.0.0.6/31
-
-
-
- Ethernet16
- 10.0.0.8/31
-
-
-
- Ethernet20
- 10.0.0.10/31
-
-
-
- Ethernet24
- 10.0.0.12/31
-
-
-
- Ethernet28
- 10.0.0.14/31
-
-
-
- Ethernet32
- 10.0.0.16/31
-
-
-
- Ethernet36
- 10.0.0.18/31
-
-
-
- Ethernet40
- 10.0.0.20/31
-
-
-
- Ethernet44
- 10.0.0.22/31
-
-
-
- Ethernet48
- 10.0.0.24/31
-
-
-
- Ethernet52
- 10.0.0.26/31
-
-
-
- Ethernet56
- 10.0.0.28/31
-
-
-
- Ethernet60
- 10.0.0.30/31
-
-
-
- Ethernet64
- 10.0.0.32/31
-
-
-
- Ethernet68
- 10.0.0.34/31
-
-
-
- Ethernet72
- 10.0.0.36/31
-
-
-
- Ethernet76
- 10.0.0.38/31
-
-
-
- Ethernet80
- 10.0.0.40/31
-
-
-
- Ethernet84
- 10.0.0.42/31
-
-
-
- Ethernet88
- 10.0.0.44/31
-
-
-
- Ethernet92
- 10.0.0.46/31
-
-
-
- Ethernet96
- 10.0.0.48/31
-
-
-
- Ethernet100
- 10.0.0.50/31
-
-
-
- Ethernet104
- 10.0.0.52/31
-
-
-
- Ethernet108
- 10.0.0.54/31
-
-
-
- Ethernet112
- 10.0.0.56/31
-
-
-
- Ethernet116
- 10.0.0.58/31
-
-
-
- Ethernet120
- 10.0.0.60/31
-
-
-
- Ethernet124
- 10.0.0.62/31
-
-
-
-
-
-
-
-
-
-
-
- DeviceInterfaceLink
- sonic
- Ethernet0
- ARISTA01T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet4
- ARISTA02T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet8
- ARISTA03T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet12
- ARISTA04T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet16
- ARISTA05T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet20
- ARISTA06T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet24
- ARISTA07T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet28
- ARISTA08T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet32
- ARISTA09T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet36
- ARISTA10T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet40
- ARISTA11T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet44
- ARISTA12T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet48
- ARISTA13T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet52
- ARISTA14T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet56
- ARISTA15T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet60
- ARISTA16T2
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet64
- ARISTA01T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet68
- ARISTA02T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet72
- ARISTA03T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet76
- ARISTA04T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet80
- ARISTA05T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet84
- ARISTA06T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet88
- ARISTA07T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet92
- ARISTA08T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet96
- ARISTA09T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet100
- ARISTA10T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet104
- ARISTA11T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet108
- ARISTA12T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet112
- ARISTA13T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet116
- ARISTA14T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet120
- ARISTA15T0
- Ethernet1
-
-
- DeviceInterfaceLink
- sonic
- Ethernet124
- ARISTA16T0
- Ethernet1
-
-
-
-
- sonic
- MiTAC-LY1200-B32H0-C3
-
-
-
-
-
-
- sonic
-
-
- DhcpResources
-
-
-
-
- NtpResources
-
- 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org
-
-
- SyslogResources
-
-
-
-
-
-
-
-
- sonic
- MiTAC-LY1200-B32H0-C3
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ HostIP
+ Loopback0
+
+ 10.1.0.32/32
+
+ 10.1.0.32/32
+
+
+
+
+
+
+
+ sonic
+
+
+
+
+
+ Ethernet0
+ 10.0.0.0/31
+
+
+
+ Ethernet4
+ 10.0.0.2/31
+
+
+
+ Ethernet8
+ 10.0.0.4/31
+
+
+
+ Ethernet12
+ 10.0.0.6/31
+
+
+
+ Ethernet16
+ 10.0.0.8/31
+
+
+
+ Ethernet20
+ 10.0.0.10/31
+
+
+
+ Ethernet24
+ 10.0.0.12/31
+
+
+
+ Ethernet28
+ 10.0.0.14/31
+
+
+
+ Ethernet32
+ 10.0.0.16/31
+
+
+
+ Ethernet36
+ 10.0.0.18/31
+
+
+
+ Ethernet40
+ 10.0.0.20/31
+
+
+
+ Ethernet44
+ 10.0.0.22/31
+
+
+
+ Ethernet48
+ 10.0.0.24/31
+
+
+
+ Ethernet52
+ 10.0.0.26/31
+
+
+
+ Ethernet56
+ 10.0.0.28/31
+
+
+
+ Ethernet60
+ 10.0.0.30/31
+
+
+
+ Ethernet64
+ 10.0.0.32/31
+
+
+
+ Ethernet68
+ 10.0.0.34/31
+
+
+
+ Ethernet72
+ 10.0.0.36/31
+
+
+
+ Ethernet76
+ 10.0.0.38/31
+
+
+
+ Ethernet80
+ 10.0.0.40/31
+
+
+
+ Ethernet84
+ 10.0.0.42/31
+
+
+
+ Ethernet88
+ 10.0.0.44/31
+
+
+
+ Ethernet92
+ 10.0.0.46/31
+
+
+
+ Ethernet96
+ 10.0.0.48/31
+
+
+
+ Ethernet100
+ 10.0.0.50/31
+
+
+
+ Ethernet104
+ 10.0.0.52/31
+
+
+
+ Ethernet108
+ 10.0.0.54/31
+
+
+
+ Ethernet112
+ 10.0.0.56/31
+
+
+
+ Ethernet116
+ 10.0.0.58/31
+
+
+
+ Ethernet120
+ 10.0.0.60/31
+
+
+
+ Ethernet124
+ 10.0.0.62/31
+
+
+
+
+
+
+
+
+
+
+
+ sonic
+ MiTAC-LY1200-B32H0-C3
+
+
+
+
+
+
+ sonic
+
+
+ DhcpResources
+
+
+
+
+ NtpResources
+
+ 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org
+
+
+ SyslogResources
+
+
+
+
+
+
+
+
+ sonic
+ MiTAC-LY1200-B32H0-C3
+
\ No newline at end of file
diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/psuutil.py b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/psuutil.py
new file mode 100644
index 00000000000..8fd9d3b1f34
--- /dev/null
+++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/psuutil.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+#############################################################################
+# MiTAC
+#
+# Module contains an implementation of SONiC PSU Base API and
+# provides the PSUs status which are available in the platform
+#
+#############################################################################
+
+import os.path
+
+try:
+ from sonic_psu.psu_base import PsuBase
+except ImportError as e:
+ raise ImportError (str(e) + "- required module not found")
+
+class PsuUtil(PsuBase):
+ """Platform-specific PSUutil class"""
+
+ def __init__(self):
+ PsuBase.__init__(self)
+
+ self.psu_nums = 2
+ self.psu_path = "/sys/bus/i2c/devices/1-0032/"
+ self.psu_presence = "ps{}_ps"
+ self.psu_oper_status = "ps{}_pg"
+
+ def get_num_psus(self):
+ """
+ Retrieves the number of PSUs available on the device
+ :return: An integer, the number of PSUs available on the device
+ """
+ return self.psu_nums
+
+ def get_psu_status(self, index):
+ """
+ Retrieves the oprational status of power supply unit (PSU) defined
+ by 1-based index
+ :param index: An integer, 1-based index of the PSU of which to query status
+ :return: Boolean, True if PSU is operating properly, False if PSU is faulty
+ """
+ if index is None:
+ return False
+
+ status = 1
+ try:
+ with open(self.psu_path + self.psu_oper_status.format(index), 'r') as power_status:
+ status = int(power_status.read(), 0)
+ except IOError:
+ return False
+
+ return status == 0
+
+ def get_psu_presence(self, index):
+ """
+ Retrieves the presence status of power supply unit (PSU) defined
+ by 1-based index
+ :param index: An integer, 1-based index of the PSU of which to query status
+ :return: Boolean, True if PSU is plugged, False if not
+ """
+ if index is None:
+ return False
+
+ status = 1
+ try:
+ with open(self.psu_path + self.psu_presence.format(index), 'r') as presence_status:
+ status = int(presence_status.read(), 0)
+ except IOError:
+ return False
+
+ return status == 0
diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2
index ff52cf88e7d..43ae42a11e6 100644
--- a/dockers/docker-base/Dockerfile.j2
+++ b/dockers/docker-base/Dockerfile.j2
@@ -24,12 +24,15 @@ RUN apt-get update
# Pre-install fundamental packages
RUN apt-get -y install \
- rsyslog \
vim-tiny \
perl \
python \
less
+# Install a newer version of rsyslog from jessie-backports in hopes of
+# eliminating memory leaks
+RUN apt-get -y -t jessie-backports install rsyslog
+
COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"]
COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"]
COPY ["root/.vimrc", "/root/.vimrc"]
diff --git a/dockers/docker-base/sources.list b/dockers/docker-base/sources.list
index 2ed195cff41..7121d6fd8c2 100644
--- a/dockers/docker-base/sources.list
+++ b/dockers/docker-base/sources.list
@@ -5,3 +5,4 @@ deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-fre
deb-src http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free
deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free
deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free
+deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free
diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh
index 2ee80c4e338..0ac5ea1a10e 100755
--- a/dockers/docker-dhcp-relay/start.sh
+++ b/dockers/docker-dhcp-relay/start.sh
@@ -6,13 +6,16 @@ rm -f /var/run/rsyslogd.pid
# Start rsyslog
supervisorctl start rsyslogd
-# Wait for all interfaces to come up and be assigned IPv4 addresses before
-# starting the DHCP relay agent(s). If an interface the relay should listen
-# on is down, the relay agent will not start. If an interface the relay should
-# listen on is up but does not have an IP address assigned when the relay
-# agent starts, it will not listen or send on that interface for the lifetime
-# of the process.
-/usr/bin/wait_for_intf.sh
+# If our supervisor config has entries in the "isc-dhcp-relay" group...
+if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then
+ # Wait for all interfaces to come up and be assigned IPv4 addresses before
+ # starting the DHCP relay agent(s). If an interface the relay should listen
+ # on is down, the relay agent will not start. If an interface the relay
+ # should listen on is up but does not have an IP address assigned when the
+ # relay agent starts, it will not listen or send on that interface for the
+ # lifetime of the process.
+ /usr/bin/wait_for_intf.sh
-# Start the DHCP relay agent(s)
-supervisorctl start isc-dhcp-relay:*
+ # Start all DHCP relay agent(s)
+ supervisorctl start isc-dhcp-relay:*
+fi
diff --git a/dockers/docker-fpm-quagga/zebra.conf.j2 b/dockers/docker-fpm-quagga/zebra.conf.j2
index 8b967f98671..e4586e72dd6 100644
--- a/dockers/docker-fpm-quagga/zebra.conf.j2
+++ b/dockers/docker-fpm-quagga/zebra.conf.j2
@@ -40,11 +40,13 @@ ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200
{% set lo_ipv6_addrs = [] %}
{% if LOOPBACK_INTERFACE %}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
-{% if prefix | ipv6 %}
-{% if lo_ipv6_addrs.append(prefix) %}
-{% endif %}
-{% else %}
-{% if lo_ipv4_addrs.append(prefix) %}
+{% if name == 'Loopback0' %}
+{% if prefix | ipv6 %}
+{% if lo_ipv6_addrs.append(prefix) %}
+{% endif %}
+{% else %}
+{% if lo_ipv4_addrs.append(prefix) %}
+{% endif %}
{% endif %}
{% endif %}
{% endfor %}
diff --git a/dockers/docker-lldp-sv2/lldpd.conf.j2 b/dockers/docker-lldp-sv2/lldpd.conf.j2
index ea8be54b097..94a04596699 100644
--- a/dockers/docker-lldp-sv2/lldpd.conf.j2
+++ b/dockers/docker-lldp-sv2/lldpd.conf.j2
@@ -1,6 +1,3 @@
{% if MGMT_INTERFACE %}
configure ports eth0 lldp portidsubtype local {{ MGMT_INTERFACE.keys()[0][0] }}
{% endif %}
-{% for local_port in DEVICE_NEIGHBOR %}
-configure ports {{ local_port }} lldp portidsubtype local {{ PORT[local_port]['alias'] }} description {{ DEVICE_NEIGHBOR[local_port]['name'] }}:{{ DEVICE_NEIGHBOR[local_port]['port'] }}
-{% endfor %}
diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd
index 1d13b1aaafd..c572967d3e4 100755
--- a/dockers/docker-lldp-sv2/lldpmgrd
+++ b/dockers/docker-lldp-sv2/lldpmgrd
@@ -20,6 +20,7 @@ try:
import subprocess
import sys
import syslog
+ import os.path
from swsscommon import swsscommon
except ImportError as err:
raise ImportError("%s - required module not found" % str(err))
@@ -70,6 +71,19 @@ def signal_handler(sig, frame):
else:
log_warning("Caught unhandled signal '" + sig + "'")
+# ========================== Helpers ==================================
+
+def is_port_up(port_name):
+ filename = "/sys/class/net/%s/operstate" % port_name
+ if not os.path.exists(filename):
+ return False
+
+ with open(filename) as fp:
+ state = fp.read()
+ if 'up' in state:
+ return True
+ else:
+ return False
# ============================== Classes ==============================
@@ -112,7 +126,7 @@ class LldpManager(object):
TABLE_SEPARATOR = "|"
# Retrieve all entires for this port from the Port table
- port_table = swsscommon.Table(self.config_db, swsscommon.CFG_PORT_TABLE_NAME, TABLE_SEPARATOR)
+ port_table = swsscommon.Table(self.config_db, swsscommon.CFG_PORT_TABLE_NAME)
(status, fvp) = port_table.get(port_name)
if status:
# Convert list of tuples to a dictionary
@@ -130,7 +144,7 @@ class LldpManager(object):
lldpcli_cmd = "lldpcli configure ports {0} lldp portidsubtype local {1}".format(port_name, port_alias)
# Retrieve all entires for this port from the Device Neighbor table
- device_neighbor_table = swsscommon.Table(self.config_db, swsscommon.CFG_DEVICE_NEIGHBOR_TABLE_NAME, TABLE_SEPARATOR)
+ device_neighbor_table = swsscommon.Table(self.config_db, swsscommon.CFG_DEVICE_NEIGHBOR_TABLE_NAME)
(status, fvp) = device_neighbor_table.get(port_name)
if status:
# Convert list of tuples to a dictionary
@@ -161,6 +175,11 @@ class LldpManager(object):
to_delete = []
for (port_name, cmd) in self.pending_cmds.iteritems():
+ if not is_port_up(port_name):
+ # it doesn't make any sense to configure lldpd if the target port is unavailable
+ # let's postpone the command for the next iteration
+ continue
+
log_debug("Running command: '{}'".format(cmd))
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -197,7 +216,7 @@ class LldpManager(object):
# Listen indefinitely for changes to the PORT table in the State DB
while True:
- (state, c, fd) = sel.select(SELECT_TIMEOUT_MS)
+ (state, c) = sel.select(SELECT_TIMEOUT_MS)
if state == swsscommon.Select.OBJECT:
(key, op, fvp) = sst.pop()
diff --git a/dockers/docker-lldp-sv2/start.sh b/dockers/docker-lldp-sv2/start.sh
index 26337fb0667..adc32297981 100755
--- a/dockers/docker-lldp-sv2/start.sh
+++ b/dockers/docker-lldp-sv2/start.sh
@@ -6,8 +6,32 @@ mkdir -p /var/sonic
echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status
rm -f /var/run/rsyslogd.pid
+rm -f /var/run/lldpd.socket
supervisorctl start rsyslogd
supervisorctl start lldpd
supervisorctl start lldp-syncd
supervisorctl start lldpmgrd
+
+# Current lldpd version has a bug.
+# When lldpd starts it is in the pause state by default
+# But then it execute 'lldpcli resume' to configure and unpause itself.
+# When lldpd execute lldpcli, it doesn't check the return code
+# Sometimes lldpcli returns failure, but lldpd doesn't catch it
+# and keeps working paused and unconfigured
+#
+# The fix below addresses the issue.
+#
+
+# wait until lldpd started
+until [[ -e /var/run/lldpd.socket ]];
+do
+ sleep 1;
+done
+
+# Manually try to resume lldpd, until it's successful
+while /bin/true;
+do
+ lldpcli -u /var/run/lldpd.socket -c /etc/lldpd.conf -c /etc/lldpd.d resume > /dev/null && break
+ sleep 1
+done
diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp-sv2/supervisord.conf
index 60334e1b8ed..e8022a9a5fa 100644
--- a/dockers/docker-lldp-sv2/supervisord.conf
+++ b/dockers/docker-lldp-sv2/supervisord.conf
@@ -25,7 +25,7 @@ stderr_logfile=syslog
# - `-dd` means to stay in foreground, log warnings to console
# - `-ddd` means to stay in foreground, log warnings and info to console
# - `-dddd` means to stay in foreground, log all to console
-command=/usr/sbin/lldpd -d -I Ethernet*,eth*
+command=/usr/sbin/lldpd -d -I Ethernet*,eth* -C eth0
priority=3
autostart=false
autorestart=false
diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2
index 3d667199635..1597b436c3f 100755
--- a/dockers/docker-orchagent/Dockerfile.j2
+++ b/dockers/docker-orchagent/Dockerfile.j2
@@ -27,6 +27,7 @@ RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y
RUN rm -rf /debs
COPY ["files/arp_update", "/usr/bin"]
+COPY ["enable_counters.py", "/usr/bin"]
COPY ["start.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"]
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py
new file mode 100755
index 00000000000..712d34492b4
--- /dev/null
+++ b/dockers/docker-orchagent/enable_counters.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+import swsssdk
+import time
+
+def enable_counter_group(db, name):
+ info = {}
+ info['FLEX_COUNTER_STATUS'] = 'enable'
+ db.mod_entry("FLEX_COUNTER_TABLE", name, info)
+
+def enable_counters():
+ db = swsssdk.ConfigDBConnector()
+ db.connect()
+ enable_counter_group(db, 'PORT')
+ enable_counter_group(db, 'QUEUE')
+ enable_counter_group(db, 'PFCWD')
+
+def get_uptime():
+ with open('/proc/uptime') as fp:
+ return float(fp.read().split(' ')[0])
+
+def main():
+ # If the switch was just started (uptime less than 5 minutes),
+ # wait for 3 minutes and enable counters
+ # otherwise wait for 60 seconds and enable counters
+ uptime = get_uptime()
+ if uptime < 300:
+ time.sleep(180)
+ else:
+ time.sleep(60)
+ enable_counters()
+
+if __name__ == '__main__':
+ main()
diff --git a/dockers/docker-orchagent/ipinip.json.j2 b/dockers/docker-orchagent/ipinip.json.j2
index 2554755c701..36fccddc237 100644
--- a/dockers/docker-orchagent/ipinip.json.j2
+++ b/dockers/docker-orchagent/ipinip.json.j2
@@ -1,7 +1,7 @@
{# only IPv4 decapsulation is supported #}
{% set ipv4_loopback_addresses = [] %}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
- {%- if prefix | ipv4 %}
+ {%- if prefix | ipv4 and name == 'Loopback0' %}
{%- set ipv4_loopback_addresses = ipv4_loopback_addresses.append(prefix) %}
{%- endif %}
{% endfor %}
@@ -11,7 +11,7 @@
"tunnel_type":"IPINIP",
"src_ip":"{{ ipv4_loopback_addresses | first | ip }}",
"dst_ip":"{% for prefix in ipv4_loopback_addresses %}{{ prefix | ip }}{% if not loop.last %},{% endif %}{% endfor %}",
-{% if onie_switch_asic == "mlnx" %}
+{% if "mlnx" in DEVICE_METADATA.localhost.platform %}
"dscp_mode":"uniform",
"ecn_mode":"standard",
{% else %}
diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh
index 027c6d52a2f..0b1c5dda8c7 100755
--- a/dockers/docker-orchagent/orchagent.sh
+++ b/dockers/docker-orchagent/orchagent.sh
@@ -20,6 +20,11 @@ elif [ "$platform" == "cavium" ]; then
ORCHAGENT_ARGS+="-m $MAC_ADDRESS"
elif [ "$platform" == "nephos" ]; then
ORCHAGENT_ARGS+="-m $MAC_ADDRESS"
+elif [ "$platform" == "centec" ]; then
+ last_byte=$(python -c "print '$MAC_ADDRESS'[-2:]")
+ aligned_last_byte=$(python -c "print format(int(int('$last_byte', 16) + 1), '02x')") # put mask and take away the 0x prefix
+ ALIGNED_MAC_ADDRESS=$(python -c "print '$MAC_ADDRESS'[:-2] + '$aligned_last_byte'") # put aligned byte into the end of MAC
+ ORCHAGENT_ARGS+="-m $ALIGNED_MAC_ADDRESS"
fi
exec /usr/bin/orchagent ${ORCHAGENT_ARGS}
diff --git a/dockers/docker-orchagent/start.sh b/dockers/docker-orchagent/start.sh
index e26be9286aa..1b6b8e7959b 100755
--- a/dockers/docker-orchagent/start.sh
+++ b/dockers/docker-orchagent/start.sh
@@ -6,6 +6,11 @@ sonic-cfggen -d -t /usr/share/sonic/templates/switch.json.j2 > /etc/swss/config.
sonic-cfggen -d -t /usr/share/sonic/templates/ipinip.json.j2 > /etc/swss/config.d/ipinip.json
sonic-cfggen -d -t /usr/share/sonic/templates/ports.json.j2 > /etc/swss/config.d/ports.json
+# Executed HWSKU specific initialization tasks.
+if [ -x /usr/share/sonic/hwsku/hwsku-init ]; then
+ /usr/share/sonic/hwsku/hwsku-init
+fi
+
export platform=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`
rm -f /var/run/rsyslogd.pid
@@ -28,6 +33,8 @@ supervisorctl start intfmgrd
supervisorctl start buffermgrd
+supervisorctl start enable_counters
+
# Start arp_update when VLAN exists
VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'`
if [ "$VLAN" != "" ]; then
diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf
index 84beaed440a..2369a4c31b0 100644
--- a/dockers/docker-orchagent/supervisord.conf
+++ b/dockers/docker-orchagent/supervisord.conf
@@ -61,10 +61,10 @@ stdout_logfile=syslog
stderr_logfile=syslog
[program:arp_update]
-command=bash -c "/usr/bin/arp_update; sleep 300"
+command=/usr/bin/arp_update
priority=8
autostart=false
-autorestart=true
+autorestart=unexpected
stdout_logfile=syslog
stderr_logfile=syslog
@@ -91,3 +91,11 @@ autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
+
+[program:enable_counters]
+command=/usr/bin/enable_counters.py
+priority=11
+autostart=false
+autorestart=false
+stdout_logfile=syslog
+stderr_logfile=syslog
diff --git a/dockers/docker-orchagent/switch.json.j2 b/dockers/docker-orchagent/switch.json.j2
index 7a8c3522ece..7aaada1b1e4 100644
--- a/dockers/docker-orchagent/switch.json.j2
+++ b/dockers/docker-orchagent/switch.json.j2
@@ -1,10 +1,11 @@
+{# the range of hash_seed is 0-15 #}
{# set default hash seed to 0 #}
{% set hash_seed = 0 %}
{% if DEVICE_METADATA.localhost.type %}
{% if DEVICE_METADATA.localhost.type == "ToRRouter" %}
-{% set hash_seed = 10 %}
+{% set hash_seed = 0 %}
{% elif DEVICE_METADATA.localhost.type == "LeafRouter" %}
-{% set hash_seed = 20 %}
+{% set hash_seed = 10 %}
{% endif %}
{% endif %}
[
diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf
index 08a3e0a9487..f0bb4d5b3bb 100644
--- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf
+++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf
@@ -8,6 +8,7 @@ command=/usr/bin/start.sh
priority=1
autostart=true
autorestart=false
+startsecs=0
stdout_logfile=syslog
stderr_logfile=syslog
diff --git a/dockers/docker-router-advertiser/start.sh b/dockers/docker-router-advertiser/start.sh
index cbd5ec383bd..159006a176b 100755
--- a/dockers/docker-router-advertiser/start.sh
+++ b/dockers/docker-router-advertiser/start.sh
@@ -1,11 +1,25 @@
#!/usr/bin/env bash
-# Generate /etc/radvd.conf config file
-sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf
-
rm -f /var/run/rsyslogd.pid
supervisorctl start rsyslogd
+# Router advertiser should only run on ToR (T0) devices
+DEVICE_ROLE=$(sonic-cfggen -d -v "DEVICE_METADATA.localhost.type")
+if [ "$DEVICE_ROLE" != "ToRRouter" ]; then
+ echo "Device role is not ToRRouter. Not starting router advertiser process."
+ exit 0
+fi
+
+# Generate /etc/radvd.conf config file
+sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf
+
+# Enusre at least one interface is specified in radvd.conf
+NUM_IFACES=$(grep -c "^interface " /etc/radvd.conf)
+if [ $NUM_IFACES -eq 0 ]; then
+ echo "No interfaces specified in radvd.conf. Not starting router advertiser process."
+ exit 0
+fi
+
# Start the router advertiser
supervisorctl start radvd
diff --git a/dockers/docker-snmp-sv2/snmpd-config-updater b/dockers/docker-snmp-sv2/snmpd-config-updater
index 10c2a2b57ef..19702451495 100755
--- a/dockers/docker-snmp-sv2/snmpd-config-updater
+++ b/dockers/docker-snmp-sv2/snmpd-config-updater
@@ -11,6 +11,7 @@
import os
import re
+import signal
import subprocess
import sys
import syslog
@@ -24,6 +25,62 @@ SYSLOG_IDENTIFIER = "snmpd-config-updater"
# ============================== Classes ==============================
+class Process(object):
+ def __init__(self, pid):
+ self.pid = pid
+ self.path = '/proc/%d/status' % pid
+ self.status = None
+
+ def read_proc_status(self):
+ data = {}
+ with open(self.path) as f:
+ for line in f.readlines():
+ key, value = line.split(':', 1)
+ data[ key ] = value.strip()
+ self.status = data
+
+ def get_proc_signals(self):
+ assert self.status
+ sigBlk = int(self.status[ 'SigBlk' ], 16)
+ sigIgn = int(self.status[ 'SigIgn' ], 16)
+ sigCgt = int(self.status[ 'SigCgt' ], 16)
+ return (sigBlk, sigIgn, sigCgt)
+
+ def handle_signal(self, sig):
+ sigBlk, sigIgn, sigCgt = self.get_proc_signals()
+ mask = 1 << ( sig - 1 )
+ if mask & sigBlk:
+ return True
+ if mask & sigIgn:
+ return True
+ if mask & sigCgt:
+ return True
+ return False
+
+ def send_signal(self, sig):
+ log_info('Sending signal %s to %d' % (sig, self.pid))
+ os.kill(self.pid, sig)
+
+ def safe_send_signal(self, sig):
+ self.read_proc_status()
+ if not self.handle_signal(sig):
+ return False
+ self.send_signal(sig)
+ return True
+
+ def wait_send_signal(self, sig, interval=0.1):
+ while not self.safe_send_signal(sig):
+ log_info('Process %s has not yet registered %s' % (self.pid, sig))
+ time.sleep(interval)
+
+ @staticmethod
+ def by_name(name):
+ try:
+ pid = subprocess.check_output([ 'pidof', '-s', name ])
+ except subprocess.CalledProcessError:
+ return None
+ return Process(int(pid.rstrip()))
+
class ConfigUpdater(object):
SERVICE = "snmpd"
CONFIG_FILE_PATH = "/etc/snmp"
@@ -48,8 +105,8 @@ class ConfigUpdater(object):
if table_data["type"] != self.ACL_TABLE_TYPE_CTRLPLANE:
continue
- # Ignore non-SSH service ACLs
- if table_data["service"] != self.ACL_SERVICE_SNMP:
+ # Ignore non-SNMP service ACLs
+ if self.ACL_SERVICE_SNMP not in table_data["services"]:
continue
acl_rules = {}
@@ -125,8 +182,10 @@ class ConfigUpdater(object):
os.rename(filename_tmp, filename)
- # Force snmpd to reload its configuration
- os.system("kill -HUP $(pgrep snmpd) > /dev/null 2> /dev/null || :")
+ # Force snmpd process to reload its configuration if it is running
+ proc = Process.by_name(self.SERVICE)
+ if proc:
+ proc.wait_send_signal(signal.SIGHUP)
def notification_handler(self, key, data):
log_info("ACL configuration changed. Updating {} config accordingly...".format(self.SERVICE))
@@ -179,7 +238,7 @@ def is_platform_arista():
if proc.returncode != 0:
log_error("Failed to retrieve platform string")
- return false
+ return False
return "arista" in stdout
diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2
index b46871dfd6f..18b7af1e925 100644
--- a/dockers/docker-snmp-sv2/snmpd.conf.j2
+++ b/dockers/docker-snmp-sv2/snmpd.conf.j2
@@ -13,24 +13,9 @@
# AGENT BEHAVIOUR
#
-{% if MGMT_INTERFACE %}
-# Listen for connections on localhost, loopback ip and mgmt (eth0) ip
-agentAddress udp:127.0.0.1:161
-{% for (name, prefix) in MGMT_INTERFACE %}
-{% if prefix | ipv4 %}
-agentAddress udp:{{ prefix | ip }}:161
-{% endif %}
-{% endfor %}
-# TODO: only support ipv4 lo addresses, add ipv6 support later
-{% for (name, prefix) in LOOPBACK_INTERFACE %}
-{% if prefix | ipv4 %}
-agentAddress udp:{{ prefix | ip }}:161
-{% endif %}
-{% endfor %}
-{% else %}
-# Listen on all addresses as mgmt ip not specified
+# Listen for connections on all ip addresses, including eth0, ipv4 lo
agentAddress udp:161
-{% endif %}
+# TODO: only support ipv4 lo addresses, add ipv6 support later
###############################################################################
#
diff --git a/dockers/docker-teamd/start.sh b/dockers/docker-teamd/start.sh
index 6e80f6eb9a8..fb3b7c3dadf 100755
--- a/dockers/docker-teamd/start.sh
+++ b/dockers/docker-teamd/start.sh
@@ -6,7 +6,12 @@ rm -rf $TEAMD_CONF_PATH
mkdir -p $TEAMD_CONF_PATH
SONIC_ASIC_TYPE=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type)
-MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}')
+
+if [ "$SONIC_ASIC_TYPE" == "mellanox" ]; then
+ MAC_ADDRESS=$(sonic-cfggen -d -v DEVICE_METADATA.localhost.mac)
+else
+ MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}')
+fi
# Align last byte
if [ "$SONIC_ASIC_TYPE" == "mellanox" -o "$SONIC_ASIC_TYPE" == "centec" ]; then
diff --git a/dockers/docker-teamd/teamd.sh b/dockers/docker-teamd/teamd.sh
index 2b6d9fb5397..1c080d24bb2 100755
--- a/dockers/docker-teamd/teamd.sh
+++ b/dockers/docker-teamd/teamd.sh
@@ -6,7 +6,7 @@ function start_app {
rm -f /var/run/teamd/*
if [ "$(ls -A $TEAMD_CONF_PATH)" ]; then
for f in $TEAMD_CONF_PATH/*; do
- teamd -f $f -d
+ teamd -f $f -d -r
done
fi
teamsyncd &
diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2
index 435781a7748..7eebfeeee9d 100644
--- a/files/Aboot/boot0.j2
+++ b/files/Aboot/boot0.j2
@@ -63,6 +63,7 @@ cmdline_base="$target_path/kernel-params-base"
cmdline_image="$image_path/kernel-cmdline"
bootconfigvars="KERNEL INITRD CONSOLESPEED PASSWORD NETDEV NETAUTO NETIP NETMASK NETGW NETDOMAIN NETDNS NETHW memtest"
+flash_re=" /mnt/flash| /host"
parse_environment_config() {
for n in ${bootconfigvars}; do
@@ -148,7 +149,8 @@ platform_specific() {
# set varlog size to 100MB
local varlog_size=100
- local flash_size=$(($(df | grep -E '/mnt/flash|/host' | tr -s ' ' | cut -f2 -d' ') / 1000))
+ # detect the size of the flash partition from name in Aboot/EOS/SONiC
+ local flash_size=$(($(df | grep -E "$flash_re" | tr -s ' ' | cut -f2 -d' ') / 1000))
if [ "$platform" = "raven" ]; then
aboot_machine=arista_7050_qx32
@@ -223,8 +225,8 @@ write_boot_configs() {
# setting root partition if not overridden by kernel-params
if ! grep -q "root=" /tmp/append; then
- rootdev="$(mount | grep -E '/mnt/flash|/host' | cut -f1 -d' ')"
- rootfstype="$(mount | grep -E '/mnt/flash|/host' | cut -f5 -d' ')"
+ rootdev="$(mount | grep -E "$flash_re" | cut -f1 -d' ')"
+ rootfstype="$(mount | grep -E "$flash_re" | cut -f5 -d' ')"
rootuuid="$(get_uuid_for $rootdev)"
if [ -z "$rootuuid" ] || [ "$rootfstype" = "vfat" ] ; then
echo "root=$rootdev" >> /tmp/append
diff --git a/files/apt/sources.list b/files/apt/sources.list
index 2ed195cff41..7121d6fd8c2 100644
--- a/files/apt/sources.list
+++ b/files/apt/sources.list
@@ -5,3 +5,4 @@ deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-fre
deb-src http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free
deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free
deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free
+deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free
diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2
index 6c55b257342..f4d2fd3a6d2 100644
--- a/files/build_templates/buffers_config.j2
+++ b/files/build_templates/buffers_config.j2
@@ -4,7 +4,7 @@
{%- else %}
def
{%- endif %}
-{%- endmacro %}
+{%- endmacro -%}
{# Determine device topology and filename postfix #}
{%- if DEVICE_METADATA is defined %}
@@ -19,12 +19,12 @@ def
{%- else %}
{%- set filename_postfix = set_default_topology() %}
{%- set switch_role = '' %}
-{%- endif %}
+{%- endif -%}
{# Import default values from device HWSKU folder #}
{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %}
-{%- set default_cable = defs.default_cable %}
+{%- set default_cable = defs.default_cable -%}
{# Port configuration to cable length look-up table #}
{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
@@ -106,19 +106,41 @@ def
{% endfor %}
}
},
-{% set bufs = defs.generate_buffer_pool_and_profiles() %}
-{{ bufs }}
+
+{% if defs.generate_buffer_pool_and_profiles is defined %}
+{{ defs.generate_buffer_pool_and_profiles() }}
+{% endif %}
+
+{%- if defs.generate_profile_lists is defined %}
+{{ defs.generate_profile_lists(port_names_all) }},
+{% endif %}
+
+{%- if defs.generate_pg_profils is defined %}
+{{ defs.generate_pg_profils }},
+{% else %}
"BUFFER_PG": {
"{{ port_names_all }}|0-1": {
"profile" : "[BUFFER_PROFILE|ingress_lossy_profile]"
+ },
+ "{{ port_names_all }}|5": {
+ "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]"
}
},
+{% endif %}
+
+{% if defs.generate_queue_buffers is defined %}
+{{ defs.generate_queue_buffers(port_names_all) }}
+{% else %}
"BUFFER_QUEUE": {
"{{ port_names_all }}|3-4": {
"profile" : "[BUFFER_PROFILE|egress_lossless_profile]"
},
"{{ port_names_all }}|0-1": {
"profile" : "[BUFFER_PROFILE|egress_lossy_profile]"
+ },
+ "{{ port_names_all }}|5": {
+ "profile" : "[BUFFER_PROFILE|egress_lossy_profile]"
}
}
+{% endif %}
}
diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2
index 6592e9ed173..1216013e63c 100644
--- a/files/build_templates/docker_image_ctl.j2
+++ b/files/build_templates/docker_image_ctl.j2
@@ -52,7 +52,7 @@ start() {
# docker created with a different HWSKU, remove and recreate
echo "Removing obsolete {{docker_container_name}} container with HWSKU $DOCKERMOUNT"
- docker rm {{docker_container_name}}
+ docker rm -f {{docker_container_name}}
fi
{%- if docker_container_name == "database" %}
@@ -63,6 +63,13 @@ start() {
docker run -d {{docker_image_run_opt}} \
{%- if '--log-driver=json-file' in docker_image_run_opt or '--log-driver' not in docker_image_run_opt %}
--log-opt max-size=2M --log-opt max-file=5 \
+{%- endif %}
+{%- if docker_container_name == "syncd" and sonic_asic_platform == "mellanox" %}
+ -e SX_SNIFFER_ENABLE \
+ -e SX_SNIFFER_TARGET \
+ -e PRM_SNIFFER \
+ -e PRM_SNIFFER_FILE_PATH \
+ -v /var/log/mellanox/sniffer:/var/log/mellanox/sniffer:rw \
{%- endif %}
-v /var/run/redis:/var/run/redis:rw \
-v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \
diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2
index f0612a9cfcb..6398477ab6a 100644
--- a/files/build_templates/snmp.service.j2
+++ b/files/build_templates/snmp.service.j2
@@ -7,6 +7,3 @@ After=updategraph.service swss.service
ExecStartPre=/usr/bin/{{docker_container_name}}.sh start
ExecStart=/usr/bin/{{docker_container_name}}.sh attach
ExecStop=/usr/bin/{{docker_container_name}}.sh stop
-
-[Install]
-WantedBy=multi-user.target
diff --git a/files/build_templates/snmp.timer b/files/build_templates/snmp.timer
new file mode 100644
index 00000000000..464cf01459b
--- /dev/null
+++ b/files/build_templates/snmp.timer
@@ -0,0 +1,9 @@
+[Unit]
+Description=Delays snmp container until SONiC has started
+
+[Timer]
+OnBootSec=3min 30 sec
+Unit=snmp.service
+
+[Install]
+WantedBy=timers.target
diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2
index 0849118b83a..29bfdfcd374 100644
--- a/files/build_templates/sonic_debian_extension.j2
+++ b/files/build_templates/sonic_debian_extension.j2
@@ -93,6 +93,11 @@ sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME
sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/python-sonic-utilities_*.deb || \
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f
+# Install customized bash version to patch memory-leak issue. This instruction shall be removed
+# once the migration to Debian-9 (Stretch) is completed.
+sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/bash_*.deb || \
+ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f
+
# SONiC utilities installs bash-completion as a dependency. However, it is disabled by default
# in bash.bashrc, so we copy a version of the file with it enabled here.
sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/
@@ -155,7 +160,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable hostname-config.service
sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/
# Copy updategraph script and service file
-sudo cp $IMAGE_CONFIGS/updategraph/updategraph.service $FILESYSTEM_ROOT/etc/systemd/system/
+j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable updategraph.service
sudo cp $IMAGE_CONFIGS/updategraph/updategraph $FILESYSTEM_ROOT/usr/bin/
{% if enable_dhcp_graph_service == "y" %}
@@ -179,6 +184,7 @@ sudo cp $IMAGE_CONFIGS/asn/deployment_id_asn_map.yml $FILESYSTEM_ROOT/etc/sonic/
# Copy sudoers configuration file
sudo cp $IMAGE_CONFIGS/sudoers/sudoers $FILESYSTEM_ROOT/etc/
+sudo cp $IMAGE_CONFIGS/sudoers/sudoers.lecture $FILESYSTEM_ROOT/etc/
# Copy control plane ACL management daemon files
sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT/etc/systemd/system/
@@ -272,6 +278,11 @@ sudo LANG=C chroot $FILESYSTEM_ROOT fuser -km /sys || true
sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys
{% endif %}
+# Copy systemd timer configuration
+# It implements delayed start of services
+sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/
+sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer
+
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get remove -y python-dev
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get autoremove -y
diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/swss.service.j2
index e16ca663612..bb347e66ae0 100644
--- a/files/build_templates/swss.service.j2
+++ b/files/build_templates/swss.service.j2
@@ -2,16 +2,16 @@
Description=switch state service
Requires=database.service updategraph.service
{% if sonic_asic_platform == 'broadcom' %}
-Requires=opennsl-modules-3.16.0-5-amd64.service
+Requires=opennsl-modules-3.16.0-6-amd64.service
{% elif sonic_asic_platform == 'nephos' %}
-Requires=nps-modules-3.16.0-5-amd64.service
+Requires=nps-modules-3.16.0-6-amd64.service
{% endif %}
After=database.service updategraph.service
After=interfaces-config.service
{% if sonic_asic_platform == 'broadcom' %}
-After=opennsl-modules-3.16.0-5-amd64.service
+After=opennsl-modules-3.16.0-6-amd64.service
{% elif sonic_asic_platform == 'nephos' %}
-After=nps-modules-3.16.0-5-amd64.service
+After=nps-modules-3.16.0-6-amd64.service
{% endif %}
[Service]
diff --git a/files/image_config/updategraph/updategraph.service b/files/build_templates/updategraph.service.j2
similarity index 68%
rename from files/image_config/updategraph/updategraph.service
rename to files/build_templates/updategraph.service.j2
index 4599f56bdc6..8039f42531c 100644
--- a/files/image_config/updategraph/updategraph.service
+++ b/files/build_templates/updategraph.service.j2
@@ -3,10 +3,15 @@ Description=Update minigraph and set configuration based on minigraph
After=rc-local.service
After=database.service
Requires=database.service
+{% if sonic_asic_platform == 'mellanox' -%}
+Requires=hw-management.service
+{% endif -%}
+
[Service]
Type=oneshot
ExecStart=/usr/bin/updategraph
+RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
diff --git a/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list b/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list
index d5ecf56d406..4daa3ccba67 100644
--- a/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list
+++ b/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list
@@ -1,2 +1,3 @@
deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free
deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free
+deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free
diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd
index a61c2437a5b..6ddd6de007c 100755
--- a/files/image_config/caclmgrd/caclmgrd
+++ b/files/image_config/caclmgrd/caclmgrd
@@ -11,6 +11,7 @@
#
try:
+ import ipaddr as ipaddress
import os
import subprocess
import sys
@@ -113,90 +114,118 @@ class ControlPlaneAclManager(object):
# Add iptables command to delete all non-default chains
iptables_cmds.append("iptables -X")
+ # Add same set of commands for ip6tables
+ iptables_cmds.append("ip6tables -P INPUT ACCEPT")
+ iptables_cmds.append("ip6tables -P FORWARD ACCEPT")
+ iptables_cmds.append("ip6tables -P OUTPUT ACCEPT")
+ iptables_cmds.append("ip6tables -F")
+ iptables_cmds.append("ip6tables -X")
+
+ # Add iptables commands to allow all IPv4 and IPv6 traffic from localhost
+ iptables_cmds.append("iptables -A INPUT -s 127.0.0.1 -i lo -j ACCEPT")
+ iptables_cmds.append("ip6tables -A INPUT -s ::1 -i lo -j ACCEPT")
+
# Get current ACL tables and rules from Config DB
self._tables_db_info = self.config_db.get_table(self.ACL_TABLE)
self._rules_db_info = self.config_db.get_table(self.ACL_RULE)
# Walk the ACL tables
for (table_name, table_data) in self._tables_db_info.iteritems():
- # Ignore non-control-plane ACL tables
- if table_data["type"] != self.ACL_TABLE_TYPE_CTRLPLANE:
- continue
- acl_service = table_data["service"]
+ table_ip_version = None
- if acl_service not in self.ACL_SERVICES:
- log_warning("Ignoring control plane ACL '{}' with unrecognized service '{}'"
- .format(table_name, acl_service))
+ # Ignore non-control-plane ACL tables
+ if table_data["type"] != self.ACL_TABLE_TYPE_CTRLPLANE:
continue
- log_info("Translating ACL rules for control plane ACL '{}' (service: '{}')"
- .format(table_name, acl_service))
-
- # Obtain default IP protocol(s) and destination port(s) for this service
- ip_protocols = self.ACL_SERVICES[acl_service]["ip_protocols"]
- dst_ports = self.ACL_SERVICES[acl_service]["dst_ports"]
+ acl_services = table_data["services"]
- acl_rules = {}
-
- for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.iteritems():
- if rule_table_name == table_name:
- acl_rules[rule_props["PRIORITY"]] = rule_props
+ for acl_service in acl_services:
+ if acl_service not in self.ACL_SERVICES:
+ log_warning("Ignoring control plane ACL '{}' with unrecognized service '{}'"
+ .format(table_name, acl_service))
+ continue
- # For each ACL rule in this table (in descending order of priority)
- for priority in sorted(acl_rules.iterkeys(), reverse=True):
- rule_props = acl_rules[priority]
+ log_info("Translating ACL rules for control plane ACL '{}' (service: '{}')"
+ .format(table_name, acl_service))
- if "PACKET_ACTION" not in rule_props:
- log_error("ACL rule does not contain PACKET_ACTION property")
+ # Obtain default IP protocol(s) and destination port(s) for this service
+ ip_protocols = self.ACL_SERVICES[acl_service]["ip_protocols"]
+ dst_ports = self.ACL_SERVICES[acl_service]["dst_ports"]
+
+ acl_rules = {}
+
+ for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.iteritems():
+ if rule_table_name == table_name:
+ acl_rules[rule_props["PRIORITY"]] = rule_props
+
+ # If we haven't determined the IP version for this ACL table yet,
+ # try to do it now. We determine heuristically based on whether the
+ # src IP is an IPv4 or IPv6 address.
+ if not table_ip_version and "SRC_IP" in rule_props and rule_props["SRC_IP"]:
+ ip_addr = ipaddress.IPAddress(rule_props["SRC_IP"].split("/")[0])
+ if isinstance(ip_addr, ipaddress.IPv6Address):
+ table_ip_version = 6
+ elif isinstance(ip_addr, ipaddress.IPv4Address):
+ table_ip_version = 4
+
+ # If we were unable to determine whether this ACL table contains
+ # IPv4 or IPv6 rules, log a message and skip processing this table.
+ if not table_ip_version:
+ log_warning("Unable to determine if ACL table '{}' contains IPv4 or IPv6 rules. Skipping table..."
+ .format(table_name))
continue
- # If the rule contains an IP protocol, we will use it.
- # Otherwise, we will apply the rule to the default
- # protocol(s) for this ACL service
- if "IP_PROTOCOL" in rule_props:
- ip_protocols = [rule_props["IP_PROTOCOL"]]
-
- for ip_protocol in ip_protocols:
- for dst_port in dst_ports:
- rule_cmd = "iptables -A INPUT -p {}".format(ip_protocol)
-
- if "SRC_IP" in rule_props and rule_props["SRC_IP"]:
- rule_cmd += " -s {}".format(rule_props["SRC_IP"])
-
- rule_cmd += " --dport {}".format(dst_port)
-
- # If there are TCP flags present, append them
- if "TCP_FLAGS" in rule_props and rule_props["TCP_FLAGS"]:
- tcp_flags = int(rule_props["TCP_FLAGS"], 16)
-
- if tcp_flags > 0:
- rule_cmd += " --tcp-flags "
-
- if tcp_flags & 0x01:
- rule_cmd += "FIN,"
- if tcp_flags & 0x02:
- rule_cmd += "SYN,"
- if tcp_flags & 0x04:
- rule_cmd += "RST,"
- if tcp_flags & 0x08:
- rule_cmd += "PSH,"
- if tcp_flags & 0x10:
- rule_cmd += "ACK,"
- if tcp_flags & 0x20:
- rule_cmd += "URG,"
- if tcp_flags & 0x40:
- rule_cmd += "ECE,"
- if tcp_flags & 0x80:
- rule_cmd += "CWR,"
-
- # Delete the trailing comma
- rule_cmd = rule_cmd[:-1]
-
- # Append the packet action as the jump target
- rule_cmd += " -j {}".format(rule_props["PACKET_ACTION"])
-
- iptables_cmds.append(rule_cmd)
+ # For each ACL rule in this table (in descending order of priority)
+ for priority in sorted(acl_rules.iterkeys(), reverse=True):
+ rule_props = acl_rules[priority]
+
+ if "PACKET_ACTION" not in rule_props:
+ log_error("ACL rule does not contain PACKET_ACTION property")
+ continue
+
+ # Apply the rule to the default protocol(s) for this ACL service
+ for ip_protocol in ip_protocols:
+ for dst_port in dst_ports:
+ rule_cmd = "ip6tables" if table_ip_version == 6 else "iptables"
+ rule_cmd += " -A INPUT -p {}".format(ip_protocol)
+
+ if "SRC_IP" in rule_props and rule_props["SRC_IP"]:
+ rule_cmd += " -s {}".format(rule_props["SRC_IP"])
+
+ rule_cmd += " --dport {}".format(dst_port)
+
+ # If there are TCP flags present, append them
+ if "TCP_FLAGS" in rule_props and rule_props["TCP_FLAGS"]:
+ tcp_flags = int(rule_props["TCP_FLAGS"], 16)
+
+ if tcp_flags > 0:
+ rule_cmd += " --tcp-flags "
+
+ if tcp_flags & 0x01:
+ rule_cmd += "FIN,"
+ if tcp_flags & 0x02:
+ rule_cmd += "SYN,"
+ if tcp_flags & 0x04:
+ rule_cmd += "RST,"
+ if tcp_flags & 0x08:
+ rule_cmd += "PSH,"
+ if tcp_flags & 0x10:
+ rule_cmd += "ACK,"
+ if tcp_flags & 0x20:
+ rule_cmd += "URG,"
+ if tcp_flags & 0x40:
+ rule_cmd += "ECE,"
+ if tcp_flags & 0x80:
+ rule_cmd += "CWR,"
+
+ # Delete the trailing comma
+ rule_cmd = rule_cmd[:-1]
+
+ # Append the packet action as the jump target
+ rule_cmd += " -j {}".format(rule_props["PACKET_ACTION"])
+
+ iptables_cmds.append(rule_cmd)
return iptables_cmds
diff --git a/files/image_config/cron.d/s6100-fast-reboot b/files/image_config/cron.d/s6100-fast-reboot
new file mode 100644
index 00000000000..aa3217e61fd
--- /dev/null
+++ b/files/image_config/cron.d/s6100-fast-reboot
@@ -0,0 +1,2 @@
+# Change linkscan interval to 0.25 sec after 3 minutes after start on Dell S6100
+@reboot root sleep 180 && [ $(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) = 'x86_64-dell_s6100_c2538-r0' ] && [ $(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.fast_reboot) = 'True' ] && /usr/bin/docker exec -i syncd bcmcmd 'linkscan i=250000' > /dev/null 2>&1
diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd
index 8c03f2234a9..f156f7e9402 100755
--- a/files/image_config/hostcfgd/hostcfgd
+++ b/files/image_config/hostcfgd/hostcfgd
@@ -127,10 +127,10 @@ class AaaCfg(object):
# Add tacplus in nsswitch.conf if TACACS+ enable
if 'tacacs+' in auth['login']:
if os.path.isfile(NSS_CONF):
- os.system("sed -i -e '/tacplus/b' -e '/^passwd/s/compat/& tacplus/' /etc/nsswitch.conf")
+ os.system("sed -i -e '/tacplus/b' -e '/^passwd/s/compat/tacplus &/' /etc/nsswitch.conf")
else:
if os.path.isfile(NSS_CONF):
- os.system("sed -i -e '/^passwd/s/ tacplus//' /etc/nsswitch.conf")
+ os.system("sed -i -e '/^passwd/s/tacplus //' /etc/nsswitch.conf")
# Set tacacs+ server in nss-tacplus conf
template_file = os.path.abspath(NSS_TACPLUS_CONF_TEMPLATE)
diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh
index 06174790f04..a702917419c 100755
--- a/files/image_config/interfaces/interfaces-config.sh
+++ b/files/image_config/interfaces/interfaces-config.sh
@@ -1,5 +1,7 @@
#!/bin/bash
+ifdown --force eth0
+
sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces
[ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid
diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local
index a931efb5b46..89ccb4bd54b 100755
--- a/files/image_config/platform/rc.local
+++ b/files/image_config/platform/rc.local
@@ -85,6 +85,19 @@ update_mgmt_interface_macaddr() {
sed -i "/eth0/ s/ATTR{address}==\"$old_mac\"/ATTR{address}==\"$new_mac\"/g" /etc/udev/rules.d/70-persistent-net.rules
}
+program_console_speed()
+{
+ speed=$(cat /proc/cmdline | grep -Eo 'console=ttyS[0-9]+,[0-9]+' | cut -d "," -f2)
+ if [ -z "$speed" ]; then
+ CONSOLE_SPEED=9600
+ else
+ CONSOLE_SPEED=$speed
+ fi
+
+ sed -i "s|\-\-keep\-baud .* %I| $CONSOLE_SPEED %I|g" /lib/systemd/system/serial-getty@.service
+ systemctl daemon-reload
+}
+
# If the machine.conf is absent, it indicates that the unit booted
# into SONiC from another NOS. Extract the machine.conf from ONIE.
if [ ! -e /host/machine.conf ]; then
@@ -126,19 +139,31 @@ if [ ! -e /host/machine.conf ]; then
if [ -n "$nos_dev" ]; then
# Mount the previous NOS's partition
- mkdir -p /mnt/nos_migration
- mount $nos_dev /mnt/nos_migration
+ NOS_DIR=/mnt/nos_migration
+ MG_GZFILE=$NOS_DIR/minigraph.xml.gz.base64.txt
+ MG_FILE=$NOS_DIR/minigraph.xml
+ ACL_GZFILE=$NOS_DIR/acl.json.gz.base64.txt
+ ACL_FILE=$NOS_DIR/acl.json
+ SNMP_FILE=$NOS_DIR/snmp.yml
+ mkdir -p $NOS_DIR
+ mount $nos_dev $NOS_DIR
mkdir -p /host/fast-reboot
+ # decode & unzip minigraph.xml.gz.base64.txt
+ [ -f $MG_GZFILE ] && /usr/bin/base64 -d $MG_GZFILE | /bin/gunzip > $MG_FILE
+ [ -f $ACL_GZFILE ] && /usr/bin/base64 -d $ACL_GZFILE | /bin/gunzip > $ACL_FILE
+
# Copy relevant files
- nos_migration_import /mnt/nos_migration/mgmt_interface.cfg /host/migration
- nos_migration_import /mnt/nos_migration/minigraph.xml /host/migration
- nos_migration_import /mnt/nos_migration/arp.json /host/fast-reboot
- nos_migration_import /mnt/nos_migration/fdb.json /host/fast-reboot
- nos_migration_import /mnt/nos_migration/default_routes.json /host/fast-reboot
-
- umount /mnt/nos_migration
- rmdir /mnt/nos_migration
+ nos_migration_import $NOS_DIR/mgmt_interface.cfg /host/migration
+ nos_migration_import $MG_FILE /host/migration
+ nos_migration_import $ACL_FILE /host/migration
+ nos_migration_import $SNMP_FILE /host/migration
+ nos_migration_import $NOS_DIR/arp.json /host/fast-reboot
+ nos_migration_import $NOS_DIR/fdb.json /host/fast-reboot
+ nos_migration_import $NOS_DIR/default_routes.json /host/fast-reboot
+
+ umount $NOS_DIR
+ rmdir $NOS_DIR
fi
update_mgmt_interface_macaddr /host/migration/mgmt_interface.cfg
@@ -173,6 +198,8 @@ done
eval sonic_version=$(cat /etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d" ")
+program_console_speed
+
if [ -f /host/image-$sonic_version/platform/firsttime ]; then
if [ -n "$aboot_platform" ]; then
@@ -196,6 +223,8 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then
elif [ -n "$migration" ] && [ -f /host/migration/minigraph.xml ]; then
mkdir -p /etc/sonic/old_config
mv /host/migration/minigraph.xml /etc/sonic/old_config/
+ [ -f /host/migration/acl.json ] && mv /host/migration/acl.json /etc/sonic/old_config/
+ [ -f /host/migration/snmp.yml ] && mv /host/migration/snmp.yml /etc/sonic/old_config/
touch /tmp/pending_config_migration
[ -f /etc/sonic/updategraph.conf ] && sed -i -e "s/enabled=false/enabled=true/g" /etc/sonic/updategraph.conf
else
diff --git a/files/image_config/ssh/sshd-config-updater b/files/image_config/ssh/sshd-config-updater
index ad1ee000feb..5f7a4ce17f9 100755
--- a/files/image_config/ssh/sshd-config-updater
+++ b/files/image_config/ssh/sshd-config-updater
@@ -49,7 +49,7 @@ class ConfigUpdater(object):
continue
# Ignore non-SSH service ACLs
- if table_data["service"] != self.ACL_SERVICE_SSH:
+ if self.ACL_SERVICE_SSH not in table_data["services"]:
continue
acl_rules = {}
diff --git a/files/image_config/sudoers/sudoers b/files/image_config/sudoers/sudoers
index 952a2313bad..47d98b3fed4 100644
--- a/files/image_config/sudoers/sudoers
+++ b/files/image_config/sudoers/sudoers
@@ -10,6 +10,7 @@ Defaults env_reset
#Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults env_keep += "VTYSH_PAGER"
+Defaults lecture_file = /etc/sudoers.lecture
# Host alias specification
@@ -37,6 +38,9 @@ Cmnd_Alias PASSWD_CMDS = /usr/bin/config tacacs passkey *, \
# User privilege specification
root ALL=(ALL:ALL) ALL
+# Allow all users to execute read only commands
+ALL ALL=NOPASSWD: READ_ONLY_CMDS
+
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
diff --git a/files/image_config/sudoers/sudoers.lecture b/files/image_config/sudoers/sudoers.lecture
new file mode 100644
index 00000000000..e89340092c7
--- /dev/null
+++ b/files/image_config/sudoers/sudoers.lecture
@@ -0,0 +1,4 @@
+
+Make sure your account has RW permission to current device.
+Otherwise sudo requests will be rejected.
+
diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph
index f0cea0894a9..df1a5db6129 100755
--- a/files/image_config/updategraph/updategraph
+++ b/files/image_config/updategraph/updategraph
@@ -44,9 +44,6 @@ if [ -f /tmp/pending_config_migration ]; then
if [ "$enabled" = "true" ]; then
echo "Use minigraph.xml from old system..."
cp /etc/sonic/old_config/minigraph.xml /etc/sonic/
- if [ -f /etc/sonic/old_config/init_cfg.json ]; then
- cp /etc/sonic/old_config/init_cfg.json /etc/sonic/
- fi
if [ -f /etc/sonic/old_config/snmp.yml ]; then
cp /etc/sonic/old_config/snmp.yml /etc/sonic/
fi
diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2
index dfd2fc1d740..85b1bc41331 100644
--- a/files/initramfs-tools/arista-convertfs.j2
+++ b/files/initramfs-tools/arista-convertfs.j2
@@ -170,7 +170,7 @@ umount "$root_mnt"
# Create a new partition table (content in flash_dev will be deleted)
err_msg="Error: repartitioning $flash_dev failed"
-cmd="echo ';' | sfdisk $flash_dev || (sleep 3; blockdev --rereadpt $flash_dev && fdisk -l $flash_dev | grep -q ${root_dev}.*Linux)"
+cmd="echo '2048' | sfdisk $flash_dev || (sleep 3; blockdev --rereadpt $flash_dev && fdisk -l $flash_dev | grep -q ${root_dev}.*Linux)"
run_cmd "$cmd" "$err_msg"
sleep 5
diff --git a/files/scripts/arp_update b/files/scripts/arp_update
index cfd87c1dc51..ab44ca6a458 100755
--- a/files/scripts/arp_update
+++ b/files/scripts/arp_update
@@ -4,14 +4,17 @@
# arp_update: Send gratuitous ARP requests to VLAN member neighbors to refresh
# the neighbors state.
-VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'`
-for vlan in $VLAN; do
- # generate a list of arping commands:
- # arping -q -w 0 -c 1 -i ;
- # arping -q -w 0 -c 1 -i ;
- # ...
- arpingcmd="sed -e 's/ / -i /' -e 's/^/arping -q -w 0 -c 1 /' -e 's/$/;/'"
- ipcmd="ip -4 neigh show | grep $vlan | cut -d ' ' -f 1,3 | $arpingcmd"
+while /bin/true; do
+ VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'`
+ for vlan in $VLAN; do
+ # generate a list of arping commands:
+ # arping -q -w 0 -c 1 -i ;
+ # arping -q -w 0 -c 1 -i ;
+ # ...
+ arpingcmd="sed -e 's/ / -i /' -e 's/^/arping -q -w 0 -c 1 /' -e 's/$/;/'"
+ ipcmd="ip -4 neigh show | grep $vlan | cut -d ' ' -f 1,3 | $arpingcmd"
- eval `eval $ipcmd`
+ eval `eval $ipcmd`
+ done
+ sleep 300
done
diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh
index 825e4636d0a..f136186985a 100755
--- a/installer/x86_64/install.sh
+++ b/installer/x86_64/install.sh
@@ -163,11 +163,21 @@ create_demo_gpt_partition()
while read -r part_index; do
if [ "$blk_dev$part_index" = "$cur_part" ]; then continue; fi
echo "deleting partition $part_index ..."
+ # if the partition is already mounted, umount first
+ df $blk_dev$part_index 2>/dev/null && {
+ umount $blk_dev$part_index || {
+ echo "Error: Unable to umount $blk_dev$part_index"
+ exit 1
+ }
+ }
sgdisk -d $part_index $blk_dev || {
echo "Error: Unable to delete partition $part_index on $blk_dev"
exit 1
}
- partprobe
+ partprobe || {
+ echo "Error: Unable to partprobe"
+ exit 1
+ }
done < $tmpfifo
fi
@@ -446,7 +456,11 @@ fi
# Decompress the file for the file system directly to the partition
unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" -d $demo_mnt/$image_dir
-TAR_EXTRA_OPTION="--numeric-owner"
+if [ "$install_env" = "onie" ]; then
+ TAR_EXTRA_OPTION="--numeric-owner"
+else
+ TAR_EXTRA_OPTION="--numeric-owner --warning=no-timestamp"
+fi
mkdir -p $demo_mnt/$image_dir/$DOCKERFS_DIR
unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/$DOCKERFS_DIR
@@ -556,11 +570,11 @@ menuentry '$demo_grub_entry' {
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_msdos
insmod ext2
- linux /$image_dir/boot/vmlinuz-3.16.0-5-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \
+ linux /$image_dir/boot/vmlinuz-3.16.0-6-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \
loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \
apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX
echo 'Loading $demo_volume_label $demo_type initial ramdisk ...'
- initrd /$image_dir/boot/initrd.img-3.16.0-5-amd64
+ initrd /$image_dir/boot/initrd.img-3.16.0-6-amd64
}
EOF
diff --git a/platform/broadcom/docker-syncd-brcm/start.sh b/platform/broadcom/docker-syncd-brcm/start.sh
index d2180bce1ed..5f5dd0678c7 100755
--- a/platform/broadcom/docker-syncd-brcm/start.sh
+++ b/platform/broadcom/docker-syncd-brcm/start.sh
@@ -11,13 +11,14 @@ mkdir -p /etc/sai.d/
# Create/Copy the sai.profile to /etc/sai.d/sai.profile
if [ -f $HWSKU_DIR/sai.profile.j2 ]; then
- sonic-cfggen -d -t $HWSKU_DIR/sai.profile.j2 > /etc/sai.d/sai.profile
+ sonic-cfggen -H -d -t $HWSKU_DIR/sai.profile.j2 > /etc/sai.d/sai.profile
else
if [ -f $HWSKU_DIR/sai.profile ]; then
cp $HWSKU_DIR/sai.profile /etc/sai.d/sai.profile
fi
fi
+rm -f /var/run/sswsyncd/sswsyncd.socket
supervisorctl start syncd
# Function: wait until syncd has created the socket for bcmcmd to connect to
@@ -28,10 +29,13 @@ wait_syncd() {
fi
sleep 1
done
+
+ # wait until bcm sdk is ready to get a request
+ sleep 3
}
# If this platform has an initialization file for the Broadcom LED microprocessor, load it
if [ -r ${PLATFORM_DIR}/led_proc_init.soc ]; then
wait_syncd
- /usr/bin/bcmcmd -t 60 "rcload ${PLATFORM_DIR}/led_proc_init.soc"
+ supervisorctl start ledinit
fi
diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf
index 1af5d70a1d0..fe590ede18c 100644
--- a/platform/broadcom/docker-syncd-brcm/supervisord.conf
+++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf
@@ -26,3 +26,11 @@ autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
+
+[program:ledinit]
+command=/usr/bin/bcmcmd -t 60 "rcload /usr/share/sonic/platform/led_proc_init.soc"
+priority=4
+autostart=false
+autorestart=false
+stdout_logfile=syslog
+stderr_logfile=syslog
diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk
index 09e8b374e86..551ff37e3b3 100644
--- a/platform/broadcom/platform-modules-cel.mk
+++ b/platform/broadcom/platform-modules-cel.mk
@@ -1,6 +1,6 @@
# Celestica DX010 Platform modules
-CEL_DX010_PLATFORM_MODULE_VERSION = 0.6
+CEL_DX010_PLATFORM_MODULE_VERSION = 0.7
export CEL_DX010_PLATFORM_MODULE_VERSION
diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk
index 1f124e1b923..69e38923872 100644
--- a/platform/broadcom/sai.mk
+++ b/platform/broadcom/sai.mk
@@ -1,9 +1,9 @@
-BRCM_SAI = libsaibcm_3.1.3.4-7_amd64.deb
-$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-7_amd64.deb?sv=2015-04-05&sr=b&sig=elzOgHCA3G8oKKMfWcbFa%2BvQzAh727mtYJnnVOzVJtY%3D&se=2155-02-07T23%3A37%3A54Z&sp=r"
+BRCM_SAI = libsaibcm_3.1.3.4-18_amd64.deb
+$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-18_amd64.deb?sv=2015-04-05&sr=b&sig=FqiCA8J4cvVyaKG9VrA9HAh2TedtJHHQUmjXQOoxiJY%3D&se=2155-08-28T19%3A38%3A44Z&sp=r"
-BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-7_amd64.deb
+BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-18_amd64.deb
$(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV)))
-$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-7_amd64.deb?sv=2015-04-05&sr=b&sig=rysxdbCA%2BaqBgDnxztdRA2ixiME3ypqRvzyEds8hLw4%3D&se=2155-02-07T23%3A38%3A39Z&sp=r"
+$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-18_amd64.deb?sv=2015-04-05&sr=b&sig=kI7rK1xQ%2BkNePGDlagQgDCYmoBN%2By9Dn2UFnDAT34oA%3D&se=2155-08-28T19%3A42%3A49Z&sp=r"
SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)
$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI)
diff --git a/platform/broadcom/sdk.mk b/platform/broadcom/sdk.mk
index 05d51fc28d0..0e7eea0db59 100644
--- a/platform/broadcom/sdk.mk
+++ b/platform/broadcom/sdk.mk
@@ -1,4 +1,6 @@
-BRCM_OPENNSL_KERNEL = opennsl-modules-3.16.0-5-amd64_3.4.1.11-2_amd64.deb
-$(BRCM_OPENNSL_KERNEL)_URL = "https://sonicstorage.blob.core.windows.net/packages/opennsl-modules-3.16.0-5-amd64_3.4.1.11-2_amd64.deb?sv=2015-04-05&sr=b&sig=xtf8nafmS1pcqx5hhBsfmLNSx2BeqmwN4Dwq5uwM1bo%3D&se=2031-11-16T21%3A54%3A27Z&sp=r"
+# mock link here, need to be replaced by real link from MSFT
+
+BRCM_OPENNSL_KERNEL = opennsl-modules-3.16.0-6-amd64_3.4.1.11-7_amd64.deb
+$(BRCM_OPENNSL_KERNEL)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/opennsl-modules-3.16.0-6-amd64_3.4.1.11-7_amd64.deb?sv=2015-04-05&sr=b&sig=HGePoJSCcURIMW3bPRh5iXlx6z5SWiElmqD44mqUchI%3D&se=2155-08-28T16%3A31%3A48Z&sp=r"
SONIC_ONLINE_DEBS += $(BRCM_OPENNSL_KERNEL)
diff --git a/platform/broadcom/sonic-platform-modules-accton b/platform/broadcom/sonic-platform-modules-accton
deleted file mode 160000
index 406c4e675ea..00000000000
--- a/platform/broadcom/sonic-platform-modules-accton
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 406c4e675ea73d52827b520958c9956551a94e8e
diff --git a/platform/broadcom/sonic-platform-modules-accton/.gitignore b/platform/broadcom/sonic-platform-modules-accton/.gitignore
new file mode 100644
index 00000000000..f805e810e5c
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/.gitignore
@@ -0,0 +1,33 @@
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
diff --git a/platform/broadcom/sonic-platform-modules-accton/LICENSE b/platform/broadcom/sonic-platform-modules-accton/LICENSE
new file mode 100644
index 00000000000..bc693f7a4c4
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/LICENSE
@@ -0,0 +1,16 @@
+Copyright (C) 2016 Microsoft, Inc
+Copyright (C) 2017 Accton Technology Corporation
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/platform/broadcom/sonic-platform-modules-accton/README.md b/platform/broadcom/sonic-platform-modules-accton/README.md
new file mode 100644
index 00000000000..0ff20bb2d21
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/README.md
@@ -0,0 +1 @@
+platform drivers of Accton products for the SONiC project
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/__init__.py
new file mode 100755
index 00000000000..e69de29bb2d
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/fanutil.py
new file mode 100755
index 00000000000..c16771e214e
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/fanutil.py
@@ -0,0 +1,238 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 Accton Technology Corporation
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# ------------------------------------------------------------------
+# HISTORY:
+# mm/dd/yyyy (A.D.)
+# 11/13/2017: Polly Hsu, Create
+#
+# ------------------------------------------------------------------
+
+try:
+ import time
+ import logging
+ from collections import namedtuple
+except ImportError as e:
+ raise ImportError('%s - required module not found' % str(e))
+
+
+class FanUtil(object):
+ """Platform-specific FanUtil class"""
+
+ FAN_NUM_ON_MAIN_BROAD = 5
+ FAN_NUM_1_IDX = 1
+ FAN_NUM_2_IDX = 2
+ FAN_NUM_3_IDX = 3
+ FAN_NUM_4_IDX = 4
+ FAN_NUM_5_IDX = 5
+
+ FAN_NODE_NUM_OF_MAP = 6
+ FAN_NODE_FAULT_IDX_OF_MAP = 1
+ FAN_NODE_SPEED_IDX_OF_MAP = 2
+ FAN_NODE_DIR_IDX_OF_MAP = 3
+ FAN_NODE_DUTY_IDX_OF_MAP = 4
+ FANR_NODE_FAULT_IDX_OF_MAP = 5
+ FANR_NODE_SPEED_IDX_OF_MAP = 6
+
+ BASE_VAL_PATH = '/sys/devices/platform/as5712_54x_fan/{0}'
+
+ #logfile = ''
+ #loglevel = logging.INFO
+
+ """ Dictionary where
+ key1 = fan id index (integer) starting from 1
+ key2 = fan node index (interger) starting from 1
+ value = path to fan device file (string) """
+ _fan_to_device_path_mapping = {}
+
+ _fan_to_device_node_mapping = {
+ (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault',
+ (FAN_NUM_1_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan1_speed_rpm',
+ (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction',
+ (FAN_NUM_1_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan1_duty_cycle_percentage',
+ (FAN_NUM_1_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr1_fault',
+ (FAN_NUM_1_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr1_speed_rpm',
+
+ (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault',
+ (FAN_NUM_2_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan2_speed_rpm',
+ (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction',
+ (FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage',
+ (FAN_NUM_2_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr2_fault',
+ (FAN_NUM_2_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr2_speed_rpm',
+
+ (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault',
+ (FAN_NUM_3_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan3_speed_rpm',
+ (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction',
+ (FAN_NUM_3_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan3_duty_cycle_percentage',
+ (FAN_NUM_3_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr3_fault',
+ (FAN_NUM_3_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr3_speed_rpm',
+
+ (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault',
+ (FAN_NUM_4_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan4_speed_rpm',
+ (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction',
+ (FAN_NUM_4_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan4_duty_cycle_percentage',
+ (FAN_NUM_4_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr4_fault',
+ (FAN_NUM_4_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr4_speed_rpm',
+
+ (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault',
+ (FAN_NUM_5_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan5_speed_rpm',
+ (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction',
+ (FAN_NUM_5_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan5_duty_cycle_percentage',
+ (FAN_NUM_5_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr5_fault',
+ (FAN_NUM_5_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr5_speed_rpm',
+ }
+
+ def _get_fan_to_device_node(self, fan_num, node_num):
+ return self._fan_to_device_node_mapping[(fan_num, node_num)]
+
+ def _get_fan_node_val(self, fan_num, node_num):
+ if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
+ logging.debug('GET. Parameter error. fan_num:%d', fan_num)
+ return None
+
+ if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP:
+ logging.debug('GET. Parameter error. node_num:%d', node_num)
+ return None
+
+ device_path = self.get_fan_to_device_path(fan_num, node_num)
+ try:
+ val_file = open(device_path, 'r')
+ except IOError as e:
+ logging.error('GET. unable to open file: %s', str(e))
+ return None
+
+ content = val_file.readline().rstrip()
+
+ if content == '':
+ logging.debug('GET. content is NULL. device_path:%s', device_path)
+ return None
+
+ try:
+ val_file.close()
+ except:
+ logging.debug('GET. unable to close file. device_path:%s', device_path)
+ return None
+
+ return int(content)
+
+ def _set_fan_node_val(self, fan_num, node_num, val):
+ if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
+ logging.debug('GET. Parameter error. fan_num:%d', fan_num)
+ return None
+
+ if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP:
+ logging.debug('GET. Parameter error. node_num:%d', node_num)
+ return None
+
+ content = str(val)
+ if content == '':
+ logging.debug('GET. content is NULL. device_path:%s', device_path)
+ return None
+
+ device_path = self.get_fan_to_device_path(fan_num, node_num)
+ try:
+ val_file = open(device_path, 'w')
+ except IOError as e:
+ logging.error('GET. unable to open file: %s', str(e))
+ return None
+
+ val_file.write(content)
+
+ try:
+ val_file.close()
+ except:
+ logging.debug('GET. unable to close file. device_path:%s', device_path)
+ return None
+
+ return True
+
+ def __init__(self):
+ fan_path = self.BASE_VAL_PATH
+
+ for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1):
+ for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1):
+ self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format(
+ self._fan_to_device_node_mapping[(fan_num, node_num)])
+
+ def get_num_fans(self):
+ return self.FAN_NUM_ON_MAIN_BROAD
+
+ def get_idx_fan_start(self):
+ return self.FAN_NUM_1_IDX
+
+ def get_num_nodes(self):
+ return self.FAN_NODE_NUM_OF_MAP
+
+ def get_idx_node_start(self):
+ return self.FAN_NODE_FAULT_IDX_OF_MAP
+
+ def get_size_node_map(self):
+ return len(self._fan_to_device_node_mapping)
+
+ def get_size_path_map(self):
+ return len(self._fan_to_device_path_mapping)
+
+ def get_fan_to_device_path(self, fan_num, node_num):
+ return self._fan_to_device_path_mapping[(fan_num, node_num)]
+
+ def get_fan_fault(self, fan_num):
+ return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP)
+
+ def get_fan_speed(self, fan_num):
+ return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP)
+
+ def get_fan_dir(self, fan_num):
+ return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP)
+
+ def get_fan_duty_cycle(self, fan_num):
+ return self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP)
+
+ def set_fan_duty_cycle(self, fan_num, val):
+ return self._set_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP, val)
+
+ def get_fanr_fault(self, fan_num):
+ return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP)
+
+ def get_fanr_speed(self, fan_num):
+ return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP)
+
+ def get_fan_status(self, fan_num):
+ if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
+ logging.debug('GET. Parameter error. fan_num, %d', fan_num)
+ return None
+
+ if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0:
+ logging.debug('GET. FAN fault. fan_num, %d', fan_num)
+ return False
+
+ if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0:
+ logging.debug('GET. FANR fault. fan_num, %d', fan_num)
+ return False
+
+ return True
+
+#def main():
+# fan = FanUtil()
+#
+# print 'get_size_node_map : %d' % fan.get_size_node_map()
+# print 'get_size_path_map : %d' % fan.get_size_path_map()
+# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1):
+# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1):
+# print fan.get_fan_to_device_path(x, y)
+#
+#if __name__ == '__main__':
+# main()
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/thermalutil.py
new file mode 100755
index 00000000000..5b8f890e881
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/thermalutil.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 Accton Technology Corporation
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# ------------------------------------------------------------------
+# HISTORY:
+# mm/dd/yyyy (A.D.)
+# 11/13/2017: Polly Hsu, Create
+#
+# ------------------------------------------------------------------
+
+try:
+ import time
+ import logging
+ import glob
+ from collections import namedtuple
+except ImportError as e:
+ raise ImportError('%s - required module not found' % str(e))
+
+
+class ThermalUtil(object):
+ """Platform-specific ThermalUtil class"""
+
+ THERMAL_NUM_ON_MAIN_BROAD = 3
+ THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD
+ THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD
+ THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD
+
+ BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input'
+
+ """ Dictionary where
+ key1 = thermal id index (integer) starting from 1
+ value = path to fan device file (string) """
+ _thermal_to_device_path_mapping = {}
+
+ _thermal_to_device_node_mapping = {
+ THERMAL_NUM_1_IDX: ['61', '48'],
+ THERMAL_NUM_2_IDX: ['62', '49'],
+ THERMAL_NUM_3_IDX: ['63', '4a'],
+ }
+
+ def __init__(self):
+ thermal_path = self.BASE_VAL_PATH
+
+ for x in range(self.THERMAL_NUM_1_IDX, self.THERMAL_NUM_ON_MAIN_BROAD+1):
+ self._thermal_to_device_path_mapping[x] = thermal_path.format(
+ self._thermal_to_device_node_mapping[x][0],
+ self._thermal_to_device_node_mapping[x][1])
+
+ def _get_thermal_node_val(self, thermal_num):
+ if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD:
+ logging.debug('GET. Parameter error. thermal_num, %d', thermal_num)
+ return None
+
+ device_path = self.get_thermal_to_device_path(thermal_num)
+ for filename in glob.glob(device_path):
+ try:
+ val_file = open(filename, 'r')
+ except IOError as e:
+ logging.error('GET. unable to open file: %s', str(e))
+ return None
+
+ content = val_file.readline().rstrip()
+
+ if content == '':
+ logging.debug('GET. content is NULL. device_path:%s', device_path)
+ return None
+
+ try:
+ val_file.close()
+ except:
+ logging.debug('GET. unable to close file. device_path:%s', device_path)
+ return None
+
+ return int(content)
+
+
+ def get_num_thermals(self):
+ return self.THERMAL_NUM_ON_MAIN_BROAD
+
+ def get_idx_thermal_start(self):
+ return self.THERMAL_NUM_1_IDX
+
+ def get_size_node_map(self):
+ return len(self._thermal_to_device_node_mapping)
+
+ def get_size_path_map(self):
+ return len(self._thermal_to_device_path_mapping)
+
+ def get_thermal_to_device_path(self, thermal_num):
+ return self._thermal_to_device_path_mapping[thermal_num]
+
+ def get_thermal_1_val(self):
+ return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX)
+
+ def get_thermal_2_val(self):
+ return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX)
+
+#def main():
+# thermal = ThermalUtil()
+#
+# print 'get_size_node_map : %d' % thermal.get_size_node_map()
+# print 'get_size_path_map : %d' % thermal.get_size_path_map()
+# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1):
+# print thermal.get_thermal_to_device_path(x)
+#
+#if __name__ == '__main__':
+# main()
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/Makefile
new file mode 100755
index 00000000000..39fe78bf8ca
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/Makefile
@@ -0,0 +1,17 @@
+ifneq ($(KERNELRELEASE),)
+obj-m:= i2c-mux-accton_as5712_54x_cpld.o \
+ accton_as5712_54x_fan.o leds-accton_as5712_54x.o accton_as5712_54x_psu.o \
+ cpr_4011_4mxx.o ym2651y.o
+
+else
+ifeq (,$(KERNEL_SRC))
+$(error KERNEL_SRC is not defined)
+else
+KERNELDIR:=$(KERNEL_SRC)
+endif
+PWD:=$(shell pwd)
+default:
+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
+clean:
+ rm -rf *.o *.mod.o *.mod.o *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order
+endif
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c
new file mode 100755
index 00000000000..db81a1a8ca9
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c
@@ -0,0 +1,437 @@
+/*
+ * A hwmon driver for the Accton as5710 54x fan contrl
+ *
+ * Copyright (C) 2013 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define FAN_MAX_NUMBER 5
+#define FAN_SPEED_CPLD_TO_RPM_STEP 150
+#define FAN_SPEED_PRECENT_TO_CPLD_STEP 5
+#define FAN_DUTY_CYCLE_MIN 0 /* 10% ??*/
+#define FAN_DUTY_CYCLE_MAX 100 /* 100% */
+
+#define CPLD_REG_FAN_STATUS_OFFSET 0xC
+#define CPLD_REG_FANR_STATUS_OFFSET 0x1F
+#define CPLD_REG_FAN_DIRECTION_OFFSET 0x1E
+
+#define CPLD_FAN1_REG_SPEED_OFFSET 0x10
+#define CPLD_FAN2_REG_SPEED_OFFSET 0x11
+#define CPLD_FAN3_REG_SPEED_OFFSET 0x12
+#define CPLD_FAN4_REG_SPEED_OFFSET 0x13
+#define CPLD_FAN5_REG_SPEED_OFFSET 0x14
+
+#define CPLD_FANR1_REG_SPEED_OFFSET 0x18
+#define CPLD_FANR2_REG_SPEED_OFFSET 0x19
+#define CPLD_FANR3_REG_SPEED_OFFSET 0x1A
+#define CPLD_FANR4_REG_SPEED_OFFSET 0x1B
+#define CPLD_FANR5_REG_SPEED_OFFSET 0x1C
+
+#define CPLD_REG_FAN_PWM_CYCLE_OFFSET 0xD
+
+#define CPLD_FAN1_INFO_BIT_MASK 0x1
+#define CPLD_FAN2_INFO_BIT_MASK 0x2
+#define CPLD_FAN3_INFO_BIT_MASK 0x4
+#define CPLD_FAN4_INFO_BIT_MASK 0x8
+#define CPLD_FAN5_INFO_BIT_MASK 0x10
+
+#define PROJECT_NAME
+
+#define LOCAL_DEBUG 0
+
+static struct accton_as5712_54x_fan *fan_data = NULL;
+
+struct accton_as5712_54x_fan {
+ struct platform_device *pdev;
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* != 0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 status[FAN_MAX_NUMBER]; /* inner first fan status */
+ u32 speed[FAN_MAX_NUMBER]; /* inner first fan speed */
+ u8 direction[FAN_MAX_NUMBER]; /* reconrd the direction of inner first and second fans */
+ u32 duty_cycle[FAN_MAX_NUMBER]; /* control the speed of inner first and second fans */
+ u8 r_status[FAN_MAX_NUMBER]; /* inner second fan status */
+ u32 r_speed[FAN_MAX_NUMBER]; /* inner second fan speed */
+};
+
+/*******************/
+#define MAKE_FAN_MASK_OR_REG(name,type) \
+ CPLD_FAN##type##1_##name, \
+ CPLD_FAN##type##2_##name, \
+ CPLD_FAN##type##3_##name, \
+ CPLD_FAN##type##4_##name, \
+ CPLD_FAN##type##5_##name,
+
+/* fan related data
+ */
+static const u8 fan_info_mask[] = {
+ MAKE_FAN_MASK_OR_REG(INFO_BIT_MASK,)
+};
+
+static const u8 fan_speed_reg[] = {
+ MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,)
+};
+
+static const u8 fanr_speed_reg[] = {
+ MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,R)
+};
+
+/*******************/
+#define DEF_FAN_SET(id) \
+ FAN##id##_FAULT, \
+ FAN##id##_SPEED, \
+ FAN##id##_DUTY_CYCLE, \
+ FAN##id##_DIRECTION, \
+ FANR##id##_FAULT, \
+ FANR##id##_SPEED,
+
+enum sysfs_fan_attributes {
+ DEF_FAN_SET(1)
+ DEF_FAN_SET(2)
+ DEF_FAN_SET(3)
+ DEF_FAN_SET(4)
+ DEF_FAN_SET(5)
+};
+/*******************/
+static void accton_as5712_54x_fan_update_device(struct device *dev);
+static int accton_as5712_54x_fan_read_value(u8 reg);
+static int accton_as5712_54x_fan_write_value(u8 reg, u8 value);
+
+static ssize_t fan_set_duty_cycle(struct device *dev,
+ struct device_attribute *da,const char *buf, size_t count);
+static ssize_t fan_show_value(struct device *dev,
+ struct device_attribute *da, char *buf);
+
+extern int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg);
+extern int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+
+
+/*******************/
+#define _MAKE_SENSOR_DEVICE_ATTR(prj, id) \
+ static SENSOR_DEVICE_ATTR(prj##fan##id##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); \
+ static SENSOR_DEVICE_ATTR(prj##fan##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \
+ static SENSOR_DEVICE_ATTR(prj##fan##id##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, \
+ fan_set_duty_cycle, FAN##id##_DUTY_CYCLE); \
+ static SENSOR_DEVICE_ATTR(prj##fan##id##_direction, S_IRUGO, fan_show_value, NULL, FAN##id##_DIRECTION); \
+ static SENSOR_DEVICE_ATTR(prj##fanr##id##_fault, S_IRUGO, fan_show_value, NULL, FANR##id##_FAULT); \
+ static SENSOR_DEVICE_ATTR(prj##fanr##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED);
+
+#define MAKE_SENSOR_DEVICE_ATTR(prj,id) _MAKE_SENSOR_DEVICE_ATTR(prj,id)
+
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 1)
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 2)
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 3)
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 4)
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 5)
+/*******************/
+
+#define _MAKE_FAN_ATTR(prj, id) \
+ &sensor_dev_attr_##prj##fan##id##_fault.dev_attr.attr, \
+ &sensor_dev_attr_##prj##fan##id##_speed_rpm.dev_attr.attr, \
+ &sensor_dev_attr_##prj##fan##id##_duty_cycle_percentage.dev_attr.attr,\
+ &sensor_dev_attr_##prj##fan##id##_direction.dev_attr.attr, \
+ &sensor_dev_attr_##prj##fanr##id##_fault.dev_attr.attr, \
+ &sensor_dev_attr_##prj##fanr##id##_speed_rpm.dev_attr.attr,
+
+#define MAKE_FAN_ATTR(prj, id) _MAKE_FAN_ATTR(prj, id)
+
+static struct attribute *accton_as5712_54x_fan_attributes[] = {
+ /* fan related attributes */
+ MAKE_FAN_ATTR(PROJECT_NAME,1)
+ MAKE_FAN_ATTR(PROJECT_NAME,2)
+ MAKE_FAN_ATTR(PROJECT_NAME,3)
+ MAKE_FAN_ATTR(PROJECT_NAME,4)
+ MAKE_FAN_ATTR(PROJECT_NAME,5)
+ NULL
+};
+/*******************/
+
+/* fan related functions
+ */
+static ssize_t fan_show_value(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ ssize_t ret = 0;
+ int data_index, type_index;
+
+ accton_as5712_54x_fan_update_device(dev);
+
+ if (fan_data->valid == 0) {
+ return ret;
+ }
+
+ type_index = attr->index%FAN2_FAULT;
+ data_index = attr->index/FAN2_FAULT;
+
+ switch (type_index) {
+ case FAN1_FAULT:
+ ret = sprintf(buf, "%d\n", fan_data->status[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FAN1_SPEED:
+ ret = sprintf(buf, "%d\n", fan_data->speed[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FAN1_DUTY_CYCLE:
+ ret = sprintf(buf, "%d\n", fan_data->duty_cycle[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FAN1_DIRECTION:
+ ret = sprintf(buf, "%d\n", fan_data->direction[data_index]); /* presnet, need to modify*/
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FANR1_FAULT:
+ ret = sprintf(buf, "%d\n", fan_data->r_status[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FANR1_SPEED:
+ ret = sprintf(buf, "%d\n", fan_data->r_speed[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ default:
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d] \n", __FUNCTION__, __LINE__);
+ break;
+ }
+
+ return ret;
+}
+/*******************/
+static ssize_t fan_set_duty_cycle(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count) {
+
+ int error, value;
+
+ error = kstrtoint(buf, 10, &value);
+ if (error)
+ return error;
+
+ if (value < FAN_DUTY_CYCLE_MIN || value > FAN_DUTY_CYCLE_MAX)
+ return -EINVAL;
+
+ accton_as5712_54x_fan_write_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET, value/FAN_SPEED_PRECENT_TO_CPLD_STEP);
+
+ fan_data->valid = 0;
+
+ return count;
+}
+
+static const struct attribute_group accton_as5712_54x_fan_group = {
+ .attrs = accton_as5712_54x_fan_attributes,
+};
+
+static int accton_as5712_54x_fan_read_value(u8 reg)
+{
+ return as5712_54x_cpld_read(0x60, reg);
+}
+
+static int accton_as5712_54x_fan_write_value(u8 reg, u8 value)
+{
+ return as5712_54x_cpld_write(0x60, reg, value);
+}
+
+static void accton_as5712_54x_fan_update_device(struct device *dev)
+{
+ int speed, r_speed, fault, r_fault, ctrl_speed, direction;
+ int i;
+
+ mutex_lock(&fan_data->update_lock);
+
+ if (LOCAL_DEBUG)
+ printk ("Starting accton_as5712_54x_fan update \n");
+
+ if (!(time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) || !fan_data->valid)) {
+ /* do nothing */
+ goto _exit;
+ }
+
+ fan_data->valid = 0;
+
+ if (LOCAL_DEBUG)
+ printk ("Starting accton_as5712_54x_fan update 2 \n");
+
+ fault = accton_as5712_54x_fan_read_value(CPLD_REG_FAN_STATUS_OFFSET);
+ r_fault = accton_as5712_54x_fan_read_value(CPLD_REG_FANR_STATUS_OFFSET);
+ direction = accton_as5712_54x_fan_read_value(CPLD_REG_FAN_DIRECTION_OFFSET);
+ ctrl_speed = accton_as5712_54x_fan_read_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET);
+
+ if ( (fault < 0) || (r_fault < 0) || (direction < 0) || (ctrl_speed < 0) )
+ {
+ if (LOCAL_DEBUG)
+ printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__);
+ goto _exit; /* error */
+ }
+
+ if (LOCAL_DEBUG)
+ printk ("[fan:] fault:%d, r_fault=%d, direction=%d, ctrl_speed=%d \n",fault, r_fault, direction, ctrl_speed);
+
+ for (i=0; istatus[i] = (fault & fan_info_mask[i]) >> i;
+ if (LOCAL_DEBUG)
+ printk ("[fan%d:] fail=%d \n",i, fan_data->status[i]);
+
+ fan_data->r_status[i] = (r_fault & fan_info_mask[i]) >> i;
+ fan_data->direction[i] = (direction & fan_info_mask[i]) >> i;
+ fan_data->duty_cycle[i] = ctrl_speed * FAN_SPEED_PRECENT_TO_CPLD_STEP;
+
+ /* fan speed
+ */
+ speed = accton_as5712_54x_fan_read_value(fan_speed_reg[i]);
+ r_speed = accton_as5712_54x_fan_read_value(fanr_speed_reg[i]);
+ if ( (speed < 0) || (r_speed < 0) )
+ {
+ if (LOCAL_DEBUG)
+ printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__);
+ goto _exit; /* error */
+ }
+
+ if (LOCAL_DEBUG)
+ printk ("[fan%d:] speed:%d, r_speed=%d \n", i, speed, r_speed);
+
+ fan_data->speed[i] = speed * FAN_SPEED_CPLD_TO_RPM_STEP;
+ fan_data->r_speed[i] = r_speed * FAN_SPEED_CPLD_TO_RPM_STEP;
+ }
+
+ /* finish to update */
+ fan_data->last_updated = jiffies;
+ fan_data->valid = 1;
+
+_exit:
+ mutex_unlock(&fan_data->update_lock);
+}
+
+static int accton_as5712_54x_fan_probe(struct platform_device *pdev)
+{
+ int status = -1;
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&pdev->dev.kobj, &accton_as5712_54x_fan_group);
+ if (status) {
+ goto exit;
+
+ }
+
+ fan_data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(fan_data->hwmon_dev)) {
+ status = PTR_ERR(fan_data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&pdev->dev, "accton_as5712_54x_fan\n");
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&pdev->dev.kobj, &accton_as5712_54x_fan_group);
+exit:
+ return status;
+}
+
+static int accton_as5712_54x_fan_remove(struct platform_device *pdev)
+{
+ hwmon_device_unregister(fan_data->hwmon_dev);
+ sysfs_remove_group(&fan_data->pdev->dev.kobj, &accton_as5712_54x_fan_group);
+
+ return 0;
+}
+
+#define DRVNAME "as5712_54x_fan"
+
+static struct platform_driver accton_as5712_54x_fan_driver = {
+ .probe = accton_as5712_54x_fan_probe,
+ .remove = accton_as5712_54x_fan_remove,
+ .driver = {
+ .name = DRVNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init accton_as5712_54x_fan_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&accton_as5712_54x_fan_driver);
+ if (ret < 0) {
+ goto exit;
+ }
+
+ fan_data = kzalloc(sizeof(struct accton_as5712_54x_fan), GFP_KERNEL);
+ if (!fan_data) {
+ ret = -ENOMEM;
+ platform_driver_unregister(&accton_as5712_54x_fan_driver);
+ goto exit;
+ }
+
+ mutex_init(&fan_data->update_lock);
+ fan_data->valid = 0;
+
+ fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
+ if (IS_ERR(fan_data->pdev)) {
+ ret = PTR_ERR(fan_data->pdev);
+ platform_driver_unregister(&accton_as5712_54x_fan_driver);
+ kfree(fan_data);
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+static void __exit accton_as5712_54x_fan_exit(void)
+{
+ platform_device_unregister(fan_data->pdev);
+ platform_driver_unregister(&accton_as5712_54x_fan_driver);
+ kfree(fan_data);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton_as5712_54x_fan driver");
+MODULE_LICENSE("GPL");
+
+module_init(accton_as5712_54x_fan_init);
+module_exit(accton_as5712_54x_fan_exit);
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_psu.c
new file mode 100755
index 00000000000..9a0d1dae58b
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_psu.c
@@ -0,0 +1,371 @@
+/*
+ * An hwmon driver for accton as5712_54x Power Module
+ *
+ * Copyright (C) 2015 Accton Technology Corporation.
+ * Copyright (C) Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#if 0
+#define DEBUG
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#define PSU_STATUS_I2C_ADDR 0x60
+#define PSU_STATUS_I2C_REG_OFFSET 0x2
+
+#define IS_POWER_GOOD(id, value) (!!(value & BIT(id*4 + 1)))
+#define IS_PRESENT(id, value) (!(value & BIT(id*4)))
+
+static ssize_t show_index(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf);
+static int as5712_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len);
+extern int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg);
+static int as5712_54x_psu_model_name_get(struct device *dev);
+
+/* Addresses scanned
+ */
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+/* Each client has this additional data
+ */
+struct as5712_54x_psu_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 index; /* PSU index */
+ u8 status; /* Status(present/power_good) register read from CPLD */
+ char model_name[14]; /* Model name, read from eeprom */
+};
+
+static struct as5712_54x_psu_data *as5712_54x_psu_update_device(struct device *dev);
+
+enum as5712_54x_psu_sysfs_attributes {
+ PSU_INDEX,
+ PSU_PRESENT,
+ PSU_MODEL_NAME,
+ PSU_POWER_GOOD
+};
+
+/* sysfs attributes for hwmon
+ */
+static SENSOR_DEVICE_ATTR(psu_index, S_IRUGO, show_index, NULL, PSU_INDEX);
+static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT);
+static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME);
+static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD);
+
+static struct attribute *as5712_54x_psu_attributes[] = {
+ &sensor_dev_attr_psu_index.dev_attr.attr,
+ &sensor_dev_attr_psu_present.dev_attr.attr,
+ &sensor_dev_attr_psu_model_name.dev_attr.attr,
+ &sensor_dev_attr_psu_power_good.dev_attr.attr,
+ NULL
+};
+
+static ssize_t show_index(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_psu_data *data = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", data->index);
+}
+
+static ssize_t show_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct as5712_54x_psu_data *data = as5712_54x_psu_update_device(dev);
+ u8 status = 0;
+
+ if (!data->valid) {
+ return sprintf(buf, "0\n");
+ }
+
+ if (attr->index == PSU_PRESENT) {
+ status = IS_PRESENT(data->index, data->status);
+ }
+ else { /* PSU_POWER_GOOD */
+ status = IS_POWER_GOOD(data->index, data->status);
+ }
+
+ return sprintf(buf, "%d\n", status);
+}
+
+static ssize_t show_model_name(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct as5712_54x_psu_data *data = as5712_54x_psu_update_device(dev);
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ if (!IS_PRESENT(data->index, data->status)) {
+ return 0;
+ }
+
+ if (as5712_54x_psu_model_name_get(dev) < 0) {
+ return -ENXIO;
+ }
+
+ return sprintf(buf, "%s\n", data->model_name);
+}
+
+static const struct attribute_group as5712_54x_psu_group = {
+ .attrs = as5712_54x_psu_attributes,
+};
+
+static int as5712_54x_psu_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ struct as5712_54x_psu_data *data;
+ int status;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct as5712_54x_psu_data), GFP_KERNEL);
+ if (!data) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ data->valid = 0;
+ data->index = dev_id->driver_data;
+ mutex_init(&data->update_lock);
+
+ dev_info(&client->dev, "chip found\n");
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &as5712_54x_psu_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "%s: psu '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &as5712_54x_psu_group);
+exit_free:
+ kfree(data);
+exit:
+
+ return status;
+}
+
+static int as5712_54x_psu_remove(struct i2c_client *client)
+{
+ struct as5712_54x_psu_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &as5712_54x_psu_group);
+ kfree(data);
+
+ return 0;
+}
+
+enum psu_index
+{
+ as5712_54x_psu1,
+ as5712_54x_psu2
+};
+
+static const struct i2c_device_id as5712_54x_psu_id[] = {
+ { "as5712_54x_psu1", as5712_54x_psu1 },
+ { "as5712_54x_psu2", as5712_54x_psu2 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, as5712_54x_psu_id);
+
+static struct i2c_driver as5712_54x_psu_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "as5712_54x_psu",
+ },
+ .probe = as5712_54x_psu_probe,
+ .remove = as5712_54x_psu_remove,
+ .id_table = as5712_54x_psu_id,
+ .address_list = normal_i2c,
+};
+
+static int as5712_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,
+ int data_len)
+{
+ int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
+
+ if (unlikely(result < 0))
+ goto abort;
+ if (unlikely(result != data_len)) {
+ result = -EIO;
+ goto abort;
+ }
+
+ result = 0;
+
+abort:
+ return result;
+}
+
+enum psu_type {
+ PSU_YM_2401_JCR, /* AC110V - F2B */
+ PSU_YM_2401_JDR, /* AC110V - B2F */
+ PSU_CPR_4011_4M11, /* AC110V - F2B */
+ PSU_CPR_4011_4M21, /* AC110V - B2F */
+ PSU_CPR_6011_2M11, /* AC110V - F2B */
+ PSU_CPR_6011_2M21, /* AC110V - B2F */
+ PSU_UM400D_01G, /* DC48V - F2B */
+ PSU_UM400D01_01G /* DC48V - B2F */
+};
+
+struct model_name_info {
+ enum psu_type type;
+ u8 offset;
+ u8 length;
+ char* model_name;
+};
+
+struct model_name_info models[] = {
+{PSU_YM_2401_JCR, 0x20, 11, "YM-2401JCR"},
+{PSU_YM_2401_JDR, 0x20, 11, "YM-2401JDR"},
+{PSU_CPR_4011_4M11, 0x26, 13, "CPR-4011-4M11"},
+{PSU_CPR_4011_4M21, 0x26, 13, "CPR-4011-4M21"},
+{PSU_CPR_6011_2M11, 0x26, 13, "CPR-6011-2M11"},
+{PSU_CPR_6011_2M21, 0x26, 13, "CPR-6011-2M21"},
+{PSU_UM400D_01G, 0x50, 9, "um400d01G"},
+{PSU_UM400D01_01G, 0x50, 12, "um400d01-01G"},
+};
+
+static int as5712_54x_psu_model_name_get(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_psu_data *data = i2c_get_clientdata(client);
+ int i, status;
+
+ for (i = 0; i < ARRAY_SIZE(models); i++) {
+ memset(data->model_name, 0, sizeof(data->model_name));
+
+ status = as5712_54x_psu_read_block(client, models[i].offset,
+ data->model_name, models[i].length);
+ if (status < 0) {
+ data->model_name[0] = '\0';
+ dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n",
+ client->addr, models[i].offset);
+ return status;
+ }
+ else {
+ data->model_name[models[i].length] = '\0';
+ }
+
+ if (i == PSU_YM_2401_JCR || i == PSU_YM_2401_JDR) {
+ /* Skip the meaningless data byte 8*/
+ data->model_name[8] = data->model_name[9];
+ data->model_name[9] = data->model_name[10];
+ data->model_name[10] = '\0';
+ }
+
+ /* Determine if the model name is known, if not, read next index
+ */
+ if (strncmp(data->model_name, models[i].model_name, models[i].length) == 0) {
+ return 0;
+ }
+ else {
+ data->model_name[0] = '\0';
+ }
+ }
+
+ return -ENODATA;
+}
+
+static struct as5712_54x_psu_data *as5712_54x_psu_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_psu_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int status = -1;
+
+ dev_dbg(&client->dev, "Starting as5712_54x update\n");
+ data->valid = 0;
+
+
+ /* Read psu status */
+ status = as5712_54x_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status);
+ goto exit;
+ }
+ else {
+ data->status = status;
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+exit:
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init as5712_54x_psu_init(void)
+{
+ return i2c_add_driver(&as5712_54x_psu_driver);
+}
+
+static void __exit as5712_54x_psu_exit(void)
+{
+ i2c_del_driver(&as5712_54x_psu_driver);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton as5712_54x_psu driver");
+MODULE_LICENSE("GPL");
+
+module_init(as5712_54x_psu_init);
+module_exit(as5712_54x_psu_exit);
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_sfp.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_sfp.c
new file mode 100755
index 00000000000..d236057c4e5
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_sfp.c
@@ -0,0 +1,825 @@
+/*
+ * An hwmon driver for accton as5712_54x sfp
+ *
+ * Copyright (C) Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#if 0
+#define DEBUG
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define NUM_OF_SFF_PORT 54
+#define SFP_PORT_MAX 48
+#define I2C_ADDR_CPLD1 0x60
+#define I2C_ADDR_CPLD2 0x61
+#define I2C_ADDR_CPLD3 0x62
+#define CPLD3_OFFSET_QSFP_MOD_RST 0x15
+#define CPLD3_OFFSET_QSFP_LPMODE 0x16
+
+
+#define BIT_INDEX(i) (1ULL << (i))
+
+#if 0
+static ssize_t show_status(struct device *dev, struct device_attribute *da,char *buf);
+static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf);
+static int as5712_54x_sfp_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len);
+extern int as5712_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
+extern int as5712_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+#endif
+
+/* Addresses scanned
+ */
+static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
+
+/* Each client has this additional data
+ */
+struct as5712_54x_sfp_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ int port; /* Front port index */
+ char eeprom[256]; /* eeprom data */
+ u64 status[4]; /* bit0:port0, bit1:port1 and so on */
+ /* index 0 => is_present
+ 1 => tx_fail
+ 2 => tx_disable
+ 3 => rx_loss */
+};
+
+/* The table maps active port to cpld port.
+ * Array index 0 is for active port 1,
+ * index 1 for active port 2, and so on.
+ * The array content implies cpld port index.
+ */
+static const u8 cpld_to_front_port_table[] =
+{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 52, 50, 53, 51, 54};
+
+#define CPLD_PORT_TO_FRONT_PORT(port) (cpld_to_front_port_table[port])
+
+static struct as5712_54x_sfp_data *as5712_54x_sfp_update_device(struct device *dev, int update_eeprom);
+static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t get_lp_mode(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+extern int as5712_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
+extern int as5712_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+
+enum as5712_54x_sfp_sysfs_attributes {
+ SFP_IS_PRESENT,
+ SFP_TX_FAULT,
+ SFP_TX_DISABLE,
+ SFP_RX_LOSS,
+ SFP_PORT_NUMBER,
+ SFP_EEPROM,
+ SFP_RX_LOS_ALL,
+ SFP_IS_PRESENT_ALL,
+ SFP_LP_MODE,
+ SFP_MOD_RST,
+};
+
+/* sysfs attributes for hwmon
+ */
+static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_status, NULL, SFP_IS_PRESENT);
+static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, show_status, NULL, SFP_TX_FAULT);
+static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, show_status, set_tx_disable, SFP_TX_DISABLE);
+static SENSOR_DEVICE_ATTR(sfp_rx_loss, S_IRUGO, show_status,NULL, SFP_RX_LOSS);
+static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER);
+static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM);
+static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, show_status,NULL, SFP_RX_LOS_ALL);
+static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_status,NULL, SFP_IS_PRESENT_ALL);
+static SENSOR_DEVICE_ATTR(sfp_lp_mode, S_IWUSR | S_IRUGO, get_lp_mode, set_lp_mode, SFP_LP_MODE);
+static SENSOR_DEVICE_ATTR(sfp_mod_rst, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, SFP_MOD_RST);
+
+static struct attribute *as5712_54x_sfp_attributes[] = {
+ &sensor_dev_attr_sfp_is_present.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_fault.dev_attr.attr,
+ &sensor_dev_attr_sfp_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp_eeprom.dev_attr.attr,
+ &sensor_dev_attr_sfp_port_number.dev_attr.attr,
+ &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr,
+ &sensor_dev_attr_sfp_is_present_all.dev_attr.attr,
+ &sensor_dev_attr_sfp_lp_mode.dev_attr.attr,
+ &sensor_dev_attr_sfp_mod_rst.dev_attr.attr,
+ NULL
+};
+
+static ssize_t show_port_number(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_sfp_data *data = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port));
+}
+
+static ssize_t show_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct as5712_54x_sfp_data *data;
+ u8 val;
+ int values[7];
+
+ /* Error-check the CPLD read results. */
+#define VALIDATED_READ(_buf, _rv, _read_expr, _invert) \
+ do { \
+ _rv = (_read_expr); \
+ if(_rv < 0) { \
+ return sprintf(_buf, "READ ERROR\n"); \
+ } \
+ if(_invert) { \
+ _rv = ~_rv; \
+ } \
+ _rv &= 0xFF; \
+ } while(0)
+
+ if(attr->index == SFP_RX_LOS_ALL) {
+ /*
+ * Report the RX_LOS status for all ports.
+ * This does not depend on the currently active SFP selector.
+ */
+
+ /* RX_LOS Ports 1-8 */
+ VALIDATED_READ(buf, values[0], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x0F), 0);
+ /* RX_LOS Ports 9-16 */
+ VALIDATED_READ(buf, values[1], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x10), 0);
+ /* RX_LOS Ports 17-24 */
+ VALIDATED_READ(buf, values[2], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x11), 0);
+ /* RX_LOS Ports 25-32 */
+ VALIDATED_READ(buf, values[3], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x0F), 0);
+ /* RX_LOS Ports 33-40 */
+ VALIDATED_READ(buf, values[4], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x10), 0);
+ /* RX_LOS Ports 41-48 */
+ VALIDATED_READ(buf, values[5], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x11), 0);
+
+ /** Return values 1 -> 48 in order */
+ return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n",
+ values[0], values[1], values[2],
+ values[3], values[4], values[5]);
+ }
+
+ if(attr->index == SFP_IS_PRESENT_ALL) {
+ /*
+ * Report the SFP_PRESENCE status for all ports.
+ * This does not depend on the currently active SFP selector.
+ */
+
+ /* SFP_PRESENT Ports 1-8 */
+ VALIDATED_READ(buf, values[0], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x6), 1);
+ /* SFP_PRESENT Ports 9-16 */
+ VALIDATED_READ(buf, values[1], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x7), 1);
+ /* SFP_PRESENT Ports 17-24 */
+ VALIDATED_READ(buf, values[2], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x8), 1);
+ /* SFP_PRESENT Ports 25-32 */
+ VALIDATED_READ(buf, values[3], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x6), 1);
+ /* SFP_PRESENT Ports 33-40 */
+ VALIDATED_READ(buf, values[4], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x7), 1);
+ /* SFP_PRESENT Ports 41-48 */
+ VALIDATED_READ(buf, values[5], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x8), 1);
+ /* QSFP_PRESENT Ports 49-54 */
+ VALIDATED_READ(buf, values[6], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14), 1);
+
+ /* Return values 1 -> 54 in order */
+ return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n",
+ values[0], values[1], values[2],
+ values[3], values[4], values[5],
+ values[6] & 0x3F);
+ }
+ /*
+ * The remaining attributes are gathered on a per-selected-sfp basis.
+ */
+ data = as5712_54x_sfp_update_device(dev, 0);
+ if (attr->index == SFP_IS_PRESENT) {
+ val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 0 : 1;
+ }
+ else {
+ val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 1 : 0;
+ }
+
+ return sprintf(buf, "%d", val);
+}
+
+static ssize_t get_lp_mode(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_sfp_data *data = i2c_get_clientdata(client);
+ u8 cpld_val = 0;
+ int port_bit;
+ int status = -EINVAL;
+
+ /* Low power mode is not supported for SFP ports(1-48) */
+ if (data->port < SFP_PORT_MAX) {
+ return -EINVAL;
+ }
+ mutex_lock(&data->update_lock);
+
+ port_bit = data->port - SFP_PORT_MAX;
+ cpld_val = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_LPMODE);
+ cpld_val = cpld_val & 0x3F;
+ cpld_val = cpld_val & BIT_INDEX(port_bit);
+ status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", cpld_val>>port_bit);
+
+ mutex_unlock(&data->update_lock);
+
+ return status;
+}
+
+static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_sfp_data *data = i2c_get_clientdata(client);
+ u8 cpld_val = 0;
+ long mode;
+ int error, port_bit;
+
+ /* Tx disable is not supported for QSFP ports(49-54) */
+ if (data->port < SFP_PORT_MAX) {
+ return -EINVAL;
+ }
+ port_bit = data->port - SFP_PORT_MAX;
+ error = kstrtol(buf, 10, &mode);
+ if (error) {
+ return error;
+ }
+ mutex_lock(&data->update_lock);
+
+ cpld_val = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_LPMODE);
+ /* Update lp_mode status */
+ if (mode)
+ {
+ cpld_val |= BIT_INDEX(port_bit);
+ }
+ else
+ {
+ cpld_val &=~BIT_INDEX(port_bit);
+ }
+ as5712_54x_i2c_cpld_write(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_LPMODE, cpld_val);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+
+static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_sfp_data *data = i2c_get_clientdata(client);
+ u8 cpld_val = 0;
+ int port_bit;
+ int status = -EINVAL;
+
+ /* Low power mode is not supported for SFP ports(1-48) */
+ if (data->port < SFP_PORT_MAX) {
+ return -EINVAL;
+ }
+ mutex_lock(&data->update_lock);
+
+ port_bit = data->port - SFP_PORT_MAX;
+ cpld_val = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_MOD_RST);
+ cpld_val = cpld_val & 0x3F;
+ cpld_val = cpld_val & BIT_INDEX(port_bit);
+ status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", cpld_val>>port_bit);
+
+ mutex_unlock(&data->update_lock);
+
+ return status;
+}
+
+static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_sfp_data *data = i2c_get_clientdata(client);
+ u8 cpld_val = 0;
+ long reset;
+ int error, port_bit;
+
+ /* Tx disable is not supported for QSFP ports(49-54) */
+ if (data->port < SFP_PORT_MAX) {
+ return -EINVAL;
+ }
+ port_bit = data->port - SFP_PORT_MAX;
+ error = kstrtol(buf, 10, &reset);
+ if (error) {
+ return error;
+ }
+ mutex_lock(&data->update_lock);
+
+ cpld_val = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_MOD_RST);
+ /* Update lp_mode status */
+ if (reset)
+ {
+ cpld_val |= BIT_INDEX(port_bit);
+ }
+ else
+ {
+ cpld_val &=~BIT_INDEX(port_bit);
+ }
+ as5712_54x_i2c_cpld_write(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_MOD_RST, cpld_val);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+
+static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_sfp_data *data = i2c_get_clientdata(client);
+ unsigned short cpld_addr = 0;
+ u8 cpld_reg = 0, cpld_val = 0, cpld_bit = 0;
+ long disable;
+ int error;
+
+ /* Tx disable is not supported for QSFP ports(49-54) */
+ if (data->port >= SFP_PORT_MAX) {
+ return -EINVAL;
+ }
+
+ error = kstrtol(buf, 10, &disable);
+ if (error) {
+ return error;
+ }
+
+ mutex_lock(&data->update_lock);
+
+ if(data->port < 24) {
+ cpld_addr = I2C_ADDR_CPLD2;
+ cpld_reg = 0xC + data->port / 8;
+ cpld_bit = 1 << (data->port % 8);
+ }
+ else {
+ cpld_addr = I2C_ADDR_CPLD3;
+ cpld_reg = 0xC + (data->port - 24) / 8;
+ cpld_bit = 1 << (data->port % 8);
+ }
+
+ cpld_val = as5712_54x_i2c_cpld_read(cpld_addr, cpld_reg);
+
+ /* Update tx_disable status */
+ if (disable) {
+ data->status[SFP_TX_DISABLE] |= BIT_INDEX(data->port);
+ cpld_val |= cpld_bit;
+ }
+ else {
+ data->status[SFP_TX_DISABLE] &= ~BIT_INDEX(data->port);
+ cpld_val &= ~cpld_bit;
+ }
+
+ as5712_54x_i2c_cpld_write(cpld_addr, cpld_reg, cpld_val);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t show_eeprom(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct as5712_54x_sfp_data *data = as5712_54x_sfp_update_device(dev, 1);
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) != 0) {
+ return 0;
+ }
+
+ memcpy(buf, data->eeprom, sizeof(data->eeprom));
+
+ return sizeof(data->eeprom);
+}
+
+static const struct attribute_group as5712_54x_sfp_group = {
+ .attrs = as5712_54x_sfp_attributes,
+};
+
+static int as5712_54x_sfp_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ struct as5712_54x_sfp_data *data;
+ int status;
+
+ extern int platform_accton_as5712_54x(void);
+ if(!platform_accton_as5712_54x()) {
+ return -ENODEV;
+ }
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct as5712_54x_sfp_data), GFP_KERNEL);
+ if (!data) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ mutex_init(&data->update_lock);
+ data->port = dev_id->driver_data;
+ i2c_set_clientdata(client, data);
+
+ dev_info(&client->dev, "chip found\n");
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &as5712_54x_sfp_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "%s: sfp '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &as5712_54x_sfp_group);
+exit_free:
+ kfree(data);
+exit:
+
+ return status;
+}
+
+static int as5712_54x_sfp_remove(struct i2c_client *client)
+{
+ struct as5712_54x_sfp_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &as5712_54x_sfp_group);
+ kfree(data);
+
+ return 0;
+}
+
+enum port_numbers {
+as5712_54x_sfp1, as5712_54x_sfp2, as5712_54x_sfp3, as5712_54x_sfp4,
+as5712_54x_sfp5, as5712_54x_sfp6, as5712_54x_sfp7, as5712_54x_sfp8,
+as5712_54x_sfp9, as5712_54x_sfp10, as5712_54x_sfp11,as5712_54x_sfp12,
+as5712_54x_sfp13, as5712_54x_sfp14, as5712_54x_sfp15,as5712_54x_sfp16,
+as5712_54x_sfp17, as5712_54x_sfp18, as5712_54x_sfp19,as5712_54x_sfp20,
+as5712_54x_sfp21, as5712_54x_sfp22, as5712_54x_sfp23,as5712_54x_sfp24,
+as5712_54x_sfp25, as5712_54x_sfp26, as5712_54x_sfp27,as5712_54x_sfp28,
+as5712_54x_sfp29, as5712_54x_sfp30, as5712_54x_sfp31,as5712_54x_sfp32,
+as5712_54x_sfp33, as5712_54x_sfp34, as5712_54x_sfp35,as5712_54x_sfp36,
+as5712_54x_sfp37, as5712_54x_sfp38, as5712_54x_sfp39,as5712_54x_sfp40,
+as5712_54x_sfp41, as5712_54x_sfp42, as5712_54x_sfp43,as5712_54x_sfp44,
+as5712_54x_sfp45, as5712_54x_sfp46, as5712_54x_sfp47,as5712_54x_sfp48,
+as5712_54x_sfp49, as5712_54x_sfp52, as5712_54x_sfp50,as5712_54x_sfp53,
+as5712_54x_sfp51, as5712_54x_sfp54
+};
+
+static const struct i2c_device_id as5712_54x_sfp_id[] = {
+{ "as5712_54x_sfp1", as5712_54x_sfp1 }, { "as5712_54x_sfp2", as5712_54x_sfp2 },
+{ "as5712_54x_sfp3", as5712_54x_sfp3 }, { "as5712_54x_sfp4", as5712_54x_sfp4 },
+{ "as5712_54x_sfp5", as5712_54x_sfp5 }, { "as5712_54x_sfp6", as5712_54x_sfp6 },
+{ "as5712_54x_sfp7", as5712_54x_sfp7 }, { "as5712_54x_sfp8", as5712_54x_sfp8 },
+{ "as5712_54x_sfp9", as5712_54x_sfp9 }, { "as5712_54x_sfp10", as5712_54x_sfp10 },
+{ "as5712_54x_sfp11", as5712_54x_sfp11 }, { "as5712_54x_sfp12", as5712_54x_sfp12 },
+{ "as5712_54x_sfp13", as5712_54x_sfp13 }, { "as5712_54x_sfp14", as5712_54x_sfp14 },
+{ "as5712_54x_sfp15", as5712_54x_sfp15 }, { "as5712_54x_sfp16", as5712_54x_sfp16 },
+{ "as5712_54x_sfp17", as5712_54x_sfp17 }, { "as5712_54x_sfp18", as5712_54x_sfp18 },
+{ "as5712_54x_sfp19", as5712_54x_sfp19 }, { "as5712_54x_sfp20", as5712_54x_sfp20 },
+{ "as5712_54x_sfp21", as5712_54x_sfp21 }, { "as5712_54x_sfp22", as5712_54x_sfp22 },
+{ "as5712_54x_sfp23", as5712_54x_sfp23 }, { "as5712_54x_sfp24", as5712_54x_sfp24 },
+{ "as5712_54x_sfp25", as5712_54x_sfp25 }, { "as5712_54x_sfp26", as5712_54x_sfp26 },
+{ "as5712_54x_sfp27", as5712_54x_sfp27 }, { "as5712_54x_sfp28", as5712_54x_sfp28 },
+{ "as5712_54x_sfp29", as5712_54x_sfp29 }, { "as5712_54x_sfp30", as5712_54x_sfp30 },
+{ "as5712_54x_sfp31", as5712_54x_sfp31 }, { "as5712_54x_sfp32", as5712_54x_sfp32 },
+{ "as5712_54x_sfp33", as5712_54x_sfp33 }, { "as5712_54x_sfp34", as5712_54x_sfp34 },
+{ "as5712_54x_sfp35", as5712_54x_sfp35 }, { "as5712_54x_sfp36", as5712_54x_sfp36 },
+{ "as5712_54x_sfp37", as5712_54x_sfp37 }, { "as5712_54x_sfp38", as5712_54x_sfp38 },
+{ "as5712_54x_sfp39", as5712_54x_sfp39 }, { "as5712_54x_sfp40", as5712_54x_sfp40 },
+{ "as5712_54x_sfp41", as5712_54x_sfp41 }, { "as5712_54x_sfp42", as5712_54x_sfp42 },
+{ "as5712_54x_sfp43", as5712_54x_sfp43 }, { "as5712_54x_sfp44", as5712_54x_sfp44 },
+{ "as5712_54x_sfp45", as5712_54x_sfp45 }, { "as5712_54x_sfp46", as5712_54x_sfp46 },
+{ "as5712_54x_sfp47", as5712_54x_sfp47 }, { "as5712_54x_sfp48", as5712_54x_sfp48 },
+{ "as5712_54x_sfp49", as5712_54x_sfp49 }, { "as5712_54x_sfp50", as5712_54x_sfp50 },
+{ "as5712_54x_sfp51", as5712_54x_sfp51 }, { "as5712_54x_sfp52", as5712_54x_sfp52 },
+{ "as5712_54x_sfp53", as5712_54x_sfp53 }, { "as5712_54x_sfp54", as5712_54x_sfp54 },
+
+{}
+};
+MODULE_DEVICE_TABLE(i2c, as5712_54x_sfp_id);
+
+static struct i2c_driver as5712_54x_sfp_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "as5712_54x_sfp",
+ },
+ .probe = as5712_54x_sfp_probe,
+ .remove = as5712_54x_sfp_remove,
+ .id_table = as5712_54x_sfp_id,
+ .address_list = normal_i2c,
+};
+
+static int as5712_54x_sfp_read_byte(struct i2c_client *client, u8 command, u8 *data)
+{
+ int result = i2c_smbus_read_byte_data(client, command);
+
+ if (unlikely(result < 0)) {
+ dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result);
+ goto abort;
+ }
+
+ *data = (u8)result;
+ result = 0;
+
+abort:
+ return result;
+}
+
+#define ALWAYS_UPDATE_DEVICE 1
+
+static struct as5712_54x_sfp_data *as5712_54x_sfp_update_device(struct device *dev, int update_eeprom)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_sfp_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (ALWAYS_UPDATE_DEVICE || time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int status = -1;
+ int i = 0, j = 0;
+
+ data->valid = 0;
+ //dev_dbg(&client->dev, "Starting as5712_54x sfp status update\n");
+ memset(data->status, 0, sizeof(data->status));
+
+ /* Read status of port 1~48(SFP port) */
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 12; j++) {
+ status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2+i, 0x6+j);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status);
+ goto exit;
+ }
+
+ data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8);
+ }
+ }
+
+ /*
+ * Bring QSFPs out of reset,
+ * This is a temporary fix until the QSFP+_MOD_RST register
+ * can be exposed through the driver.
+ */
+ as5712_54x_i2c_cpld_write(I2C_ADDR_CPLD3, 0x15, 0x3F);
+
+ /* Read present status of port 49-54(QSFP port) */
+ status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status);
+ }
+ else {
+ data->status[SFP_IS_PRESENT] |= (u64)status << 48;
+ }
+
+ if (update_eeprom) {
+ /* Read eeprom data based on port number */
+ memset(data->eeprom, 0, sizeof(data->eeprom));
+
+ /* Check if the port is present */
+ if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) == 0) {
+ /* read eeprom */
+ for (i = 0; i < sizeof(data->eeprom); i++) {
+ status = as5712_54x_sfp_read_byte(client, i, data->eeprom + i);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n",
+ CPLD_PORT_TO_FRONT_PORT(data->port));
+ goto exit;
+ }
+ }
+ }
+ }
+
+ data->valid = 1;
+ data->last_updated = jiffies;
+ }
+
+exit:
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+module_i2c_driver(as5712_54x_sfp_driver);
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton as5712_54x_sfp driver");
+MODULE_LICENSE("GPL");
+
+#if 0
+ int i = 0, j = 0;
+
+ data->valid = 0;
+ //dev_dbg(&client->dev, "Starting as5712_54x sfp update\n");
+ memset(data->status, 0, sizeof(data->status));
+
+ /* Read status of port 1~48(SFP port) */
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 12; j++) {
+ status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2+i, 0x6+j);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status);
+ continue;
+ }
+
+ data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8);
+ }
+ }
+
+ /* Read present status of port 49-54(QSFP port) */
+ status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status);
+ }
+ else {
+ data->status[SFP_IS_PRESENT] |= (u64)status << 48;
+ }
+#endif
+
+/* Reserver to prevent from CPLD port mapping is changed
+ */
+#if 0
+BIT_INDEX(port_present_index[data->port])
+/* The bit index of is_present field read from CPLD
+ * Array index 0 is for as5712_54x_sfp1,
+ * index 1 is for as5712_54x_sfp2, and so on.
+ */
+static const int port_present_index[] = {
+ 4, 5, 6, 7, 9, 8, 11, 10,
+ 0, 1, 2, 3, 12, 13, 14, 15,
+16, 17, 18, 19, 28, 29, 30, 31,
+20, 21, 22, 23, 24, 25, 26, 27
+};
+#endif
+
+#if 0
+static struct as5712_54x_sfp_data *as5712_54x_sfp_update_status(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_sfp_data *data = i2c_get_clientdata(client);
+ int status = -1;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->status_last_updated + HZ + HZ / 2)
+ || !data->status_valid) {
+ int status = -1;
+ int i = 0, j = 0;
+
+ data->status_valid = 0;
+ //dev_dbg(&client->dev, "Starting as5712_54x sfp status update\n");
+ memset(data->status, 0, sizeof(data->status));
+
+ /* Read status of port 1~48(SFP port) */
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 12; j++) {
+ status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2+i, 0x6+j);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status);
+ goto exit;
+ }
+
+ data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8);
+ }
+ }
+
+ /*
+ * Bring QSFPs out of reset,
+ * This is a temporary fix until the QSFP+_MOD_RST register
+ * can be exposed through the driver.
+ */
+ as5712_54x_i2c_cpld_write(I2C_ADDR_CPLD3, 0x15, 0x3F);
+
+ /* Read present status of port 49-54(QSFP port) */
+ status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status);
+ }
+ else {
+ data->status[SFP_IS_PRESENT] |= (u64)status << 48;
+ }
+
+ data->status_valid = 1;
+ data->status_last_updated = jiffies;
+ }
+
+exit:
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static struct as5712_54x_sfp_data *as5712_54x_sfp_update_eeprom(struct device *dev)
+{
+ struct as5712_54x_sfp_data *data = NULL;
+
+ data = as5712_54x_sfp_update_status(dev);
+
+ if (data == NULL || data->status_valid == 0) {
+ data->eeprom_valid = 0;
+ return data;
+ }
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->eeprom_last_updated + HZ + HZ / 2)
+ || !data->eeprom_valid) {
+ int status = -1;
+ int i = 0;
+
+ /* Read eeprom data based on port number */
+ memset(data->eeprom, 0, sizeof(data->eeprom));
+
+ /* Check if the port is present */
+ if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) == 0) {
+ /* read eeprom */
+ for (i = 0; i < sizeof(data->eeprom)/I2C_SMBUS_BLOCK_MAX; i++) {
+ status = as5712_54x_sfp_read_block(client, i*I2C_SMBUS_BLOCK_MAX,
+ data->eeprom+(i*I2C_SMBUS_BLOCK_MAX),
+ I2C_SMBUS_BLOCK_MAX);
+ if (status < 0) {
+ dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n",
+ CPLD_PORT_TO_FRONT_PORT(data->port));
+ goto exit;
+ }
+ }
+ }
+
+ data->eeprom_last_updated = jiffies;
+ data->eeprom_valid = 1;
+ }
+
+exit:
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+#endif
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c
new file mode 100755
index 00000000000..30bea914d58
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c
@@ -0,0 +1,400 @@
+/*
+ * An hwmon driver for the CPR-4011-4Mxx Redundant Power Module
+ *
+ * Copyright (C) Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#if 0
+#define DEBUG
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define MAX_FAN_DUTY_CYCLE 100
+
+/* Addresses scanned
+ */
+static const unsigned short normal_i2c[] = { 0x3c, 0x3d, 0x3e, 0x3f, I2C_CLIENT_END };
+
+/* Each client has this additional data
+ */
+struct cpr_4011_4mxx_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 vout_mode; /* Register value */
+ u16 v_in; /* Register value */
+ u16 v_out; /* Register value */
+ u16 i_in; /* Register value */
+ u16 i_out; /* Register value */
+ u16 p_in; /* Register value */
+ u16 p_out; /* Register value */
+ u16 temp_input[2]; /* Register value */
+ u8 fan_fault; /* Register value */
+ u16 fan_duty_cycle[2]; /* Register value */
+ u16 fan_speed[2]; /* Register value */
+};
+
+static ssize_t show_linear(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count);
+static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value);
+static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev);
+
+enum cpr_4011_4mxx_sysfs_attributes {
+ PSU_V_IN,
+ PSU_V_OUT,
+ PSU_I_IN,
+ PSU_I_OUT,
+ PSU_P_IN,
+ PSU_P_OUT,
+ PSU_TEMP1_INPUT,
+ PSU_FAN1_FAULT,
+ PSU_FAN1_DUTY_CYCLE,
+ PSU_FAN1_SPEED,
+};
+
+/* sysfs attributes for hwmon
+ */
+static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, show_linear, NULL, PSU_V_IN);
+static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT);
+static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, show_linear, NULL, PSU_I_IN);
+static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT);
+static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, show_linear, NULL, PSU_P_IN);
+static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT);
+static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT);
+static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT);
+static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE);
+static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED);
+
+static struct attribute *cpr_4011_4mxx_attributes[] = {
+ &sensor_dev_attr_psu_v_in.dev_attr.attr,
+ &sensor_dev_attr_psu_v_out.dev_attr.attr,
+ &sensor_dev_attr_psu_i_in.dev_attr.attr,
+ &sensor_dev_attr_psu_i_out.dev_attr.attr,
+ &sensor_dev_attr_psu_p_in.dev_attr.attr,
+ &sensor_dev_attr_psu_p_out.dev_attr.attr,
+ &sensor_dev_attr_psu_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_psu_fan1_fault.dev_attr.attr,
+ &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr,
+ &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr,
+ NULL
+};
+
+static int two_complement_to_int(u16 data, u8 valid_bit, int mask)
+{
+ u16 valid_data = data & mask;
+ bool is_negative = valid_data >> (valid_bit - 1);
+
+ return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data;
+}
+
+static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client);
+ int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1;
+ long speed;
+ int error;
+
+ error = kstrtol(buf, 10, &speed);
+ if (error)
+ return error;
+
+ if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->fan_duty_cycle[nr] = speed;
+ cpr_4011_4mxx_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t show_linear(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev);
+
+ u16 value = 0;
+ int exponent, mantissa;
+ int multiplier = 1000;
+
+ switch (attr->index) {
+ case PSU_V_IN:
+ value = data->v_in;
+ break;
+ case PSU_I_IN:
+ value = data->i_in;
+ break;
+ case PSU_I_OUT:
+ value = data->i_out;
+ break;
+ case PSU_P_IN:
+ value = data->p_in;
+ break;
+ case PSU_P_OUT:
+ value = data->p_out;
+ break;
+ case PSU_TEMP1_INPUT:
+ value = data->temp_input[0];
+ break;
+ case PSU_FAN1_DUTY_CYCLE:
+ multiplier = 1;
+ value = data->fan_duty_cycle[0];
+ break;
+ case PSU_FAN1_SPEED:
+ multiplier = 1;
+ value = data->fan_speed[0];
+ break;
+ default:
+ break;
+ }
+
+ exponent = two_complement_to_int(value >> 11, 5, 0x1f);
+ mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff);
+
+ return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :
+ sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
+}
+
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev);
+
+ u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6;
+
+ return sprintf(buf, "%d\n", data->fan_fault >> shift);
+}
+
+static ssize_t show_vout(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev);
+ int exponent, mantissa;
+ int multiplier = 1000;
+
+ exponent = two_complement_to_int(data->vout_mode, 5, 0x1f);
+ mantissa = data->v_out;
+
+ return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :
+ sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
+}
+
+static const struct attribute_group cpr_4011_4mxx_group = {
+ .attrs = cpr_4011_4mxx_attributes,
+};
+
+static int cpr_4011_4mxx_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ struct cpr_4011_4mxx_data *data;
+ int status;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct cpr_4011_4mxx_data), GFP_KERNEL);
+ if (!data) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ data->valid = 0;
+ mutex_init(&data->update_lock);
+
+ dev_info(&client->dev, "chip found\n");
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &cpr_4011_4mxx_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "%s: psu '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group);
+exit_free:
+ kfree(data);
+exit:
+
+ return status;
+}
+
+static int cpr_4011_4mxx_remove(struct i2c_client *client)
+{
+ struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group);
+ kfree(data);
+
+ return 0;
+}
+
+static const struct i2c_device_id cpr_4011_4mxx_id[] = {
+ { "cpr_4011_4mxx", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, cpr_4011_4mxx_id);
+
+static struct i2c_driver cpr_4011_4mxx_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "cpr_4011_4mxx",
+ },
+ .probe = cpr_4011_4mxx_probe,
+ .remove = cpr_4011_4mxx_remove,
+ .id_table = cpr_4011_4mxx_id,
+ .address_list = normal_i2c,
+};
+
+static int cpr_4011_4mxx_read_byte(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int cpr_4011_4mxx_read_word(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_word_data(client, reg);
+}
+
+static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value)
+{
+ return i2c_smbus_write_word_data(client, reg, value);
+}
+
+struct reg_data_byte {
+ u8 reg;
+ u8 *value;
+};
+
+struct reg_data_word {
+ u8 reg;
+ u16 *value;
+};
+
+static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int i, status;
+ struct reg_data_byte regs_byte[] = { {0x20, &data->vout_mode},
+ {0x81, &data->fan_fault}};
+ struct reg_data_word regs_word[] = { {0x88, &data->v_in},
+ {0x8b, &data->v_out},
+ {0x89, &data->i_in},
+ {0x8c, &data->i_out},
+ {0x96, &data->p_out},
+ {0x97, &data->p_in},
+ {0x8d, &(data->temp_input[0])},
+ {0x8e, &(data->temp_input[1])},
+ {0x3b, &(data->fan_duty_cycle[0])},
+ {0x3c, &(data->fan_duty_cycle[1])},
+ {0x90, &(data->fan_speed[0])},
+ {0x91, &(data->fan_speed[1])}};
+
+ dev_dbg(&client->dev, "Starting cpr_4011_4mxx update\n");
+
+ /* Read byte data */
+ for (i = 0; i < ARRAY_SIZE(regs_byte); i++) {
+ status = cpr_4011_4mxx_read_byte(client, regs_byte[i].reg);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n",
+ regs_byte[i].reg, status);
+ }
+ else {
+ *(regs_byte[i].value) = status;
+ }
+ }
+
+ /* Read word data */
+ for (i = 0; i < ARRAY_SIZE(regs_word); i++) {
+ status = cpr_4011_4mxx_read_word(client, regs_word[i].reg);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n",
+ regs_word[i].reg, status);
+ }
+ else {
+ *(regs_word[i].value) = status;
+ }
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init cpr_4011_4mxx_init(void)
+{
+ return i2c_add_driver(&cpr_4011_4mxx_driver);
+}
+
+static void __exit cpr_4011_4mxx_exit(void)
+{
+ i2c_del_driver(&cpr_4011_4mxx_driver);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("CPR_4011_4MXX driver");
+MODULE_LICENSE("GPL");
+
+module_init(cpr_4011_4mxx_init);
+module_exit(cpr_4011_4mxx_exit);
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c
new file mode 100755
index 00000000000..d63cb14b5a6
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c
@@ -0,0 +1,1517 @@
+/*
+ * I2C multiplexer
+ *
+ * Copyright (C) Brandon Chuang
+ *
+ * This module supports the accton cpld that hold the channel select
+ * mechanism for other i2c slave devices, such as SFP.
+ * This includes the:
+ * Accton as5712_54x CPLD1/CPLD2/CPLD3
+ *
+ * Based on:
+ * pca954x.c from Kumar Gala
+ * Copyright (C) 2006
+ *
+ * Based on:
+ * pca954x.c from Ken Harrenstien
+ * Copyright (C) 2004 Google, Inc. (Ken Harrenstien)
+ *
+ * Based on:
+ * i2c-virtual_cb.c from Brian Kuschak
+ * and
+ * pca9540.c from Jean Delvare .
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#if 0
+#define DEBUG
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define I2C_RW_RETRY_COUNT 10
+#define I2C_RW_RETRY_INTERVAL 60 /* ms */
+
+#define NUM_OF_CPLD1_CHANS 0x0
+#define NUM_OF_CPLD2_CHANS 0x18
+#define NUM_OF_CPLD3_CHANS 0x1E
+#define CPLD_CHANNEL_SELECT_REG 0x2
+#define CPLD_DESELECT_CHANNEL 0xFF
+
+#if 0
+#define NUM_OF_ALL_CPLD_CHANS (NUM_OF_CPLD2_CHANS + NUM_OF_CPLD3_CHANS)
+#endif
+
+#define ACCTON_I2C_CPLD_MUX_MAX_NCHANS NUM_OF_CPLD3_CHANS
+
+static LIST_HEAD(cpld_client_list);
+static struct mutex list_lock;
+
+struct cpld_client_node {
+ struct i2c_client *client;
+ struct list_head list;
+};
+
+enum cpld_mux_type {
+ as5712_54x_cpld2,
+ as5712_54x_cpld3,
+ as5712_54x_cpld1
+};
+
+struct as5712_54x_cpld_data {
+ enum cpld_mux_type type;
+ struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS];
+ u8 last_chan; /* last register value */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+ struct i2c_client *client;
+ struct i2c_mux_core *muxc;
+#endif
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+};
+
+#if 0
+/* The mapping table between mux index and adapter index
+ array index : the mux index
+ the content : adapter index
+ */
+static int mux_adap_map[NUM_OF_ALL_CPLD_CHANS];
+#endif
+
+struct chip_desc {
+ u8 nchans;
+ u8 deselectChan;
+};
+
+/* Provide specs for the PCA954x types we know about */
+static const struct chip_desc chips[] = {
+ [as5712_54x_cpld1] = {
+ .nchans = NUM_OF_CPLD1_CHANS,
+ .deselectChan = CPLD_DESELECT_CHANNEL,
+ },
+ [as5712_54x_cpld2] = {
+ .nchans = NUM_OF_CPLD2_CHANS,
+ .deselectChan = CPLD_DESELECT_CHANNEL,
+ },
+ [as5712_54x_cpld3] = {
+ .nchans = NUM_OF_CPLD3_CHANS,
+ .deselectChan = CPLD_DESELECT_CHANNEL,
+ }
+};
+
+static const struct i2c_device_id as5712_54x_cpld_mux_id[] = {
+ { "as5712_54x_cpld1", as5712_54x_cpld1 },
+ { "as5712_54x_cpld2", as5712_54x_cpld2 },
+ { "as5712_54x_cpld3", as5712_54x_cpld3 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, as5712_54x_cpld_mux_id);
+
+#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index
+#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index
+#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index
+#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index
+#define TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index
+#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index
+
+enum as5712_54x_cpld1_sysfs_attributes {
+ CPLD_VERSION,
+ ACCESS,
+ MODULE_PRESENT_ALL,
+ MODULE_RXLOS_ALL,
+ /* transceiver attributes */
+ TRANSCEIVER_PRESENT_ATTR_ID(1),
+ TRANSCEIVER_PRESENT_ATTR_ID(2),
+ TRANSCEIVER_PRESENT_ATTR_ID(3),
+ TRANSCEIVER_PRESENT_ATTR_ID(4),
+ TRANSCEIVER_PRESENT_ATTR_ID(5),
+ TRANSCEIVER_PRESENT_ATTR_ID(6),
+ TRANSCEIVER_PRESENT_ATTR_ID(7),
+ TRANSCEIVER_PRESENT_ATTR_ID(8),
+ TRANSCEIVER_PRESENT_ATTR_ID(9),
+ TRANSCEIVER_PRESENT_ATTR_ID(10),
+ TRANSCEIVER_PRESENT_ATTR_ID(11),
+ TRANSCEIVER_PRESENT_ATTR_ID(12),
+ TRANSCEIVER_PRESENT_ATTR_ID(13),
+ TRANSCEIVER_PRESENT_ATTR_ID(14),
+ TRANSCEIVER_PRESENT_ATTR_ID(15),
+ TRANSCEIVER_PRESENT_ATTR_ID(16),
+ TRANSCEIVER_PRESENT_ATTR_ID(17),
+ TRANSCEIVER_PRESENT_ATTR_ID(18),
+ TRANSCEIVER_PRESENT_ATTR_ID(19),
+ TRANSCEIVER_PRESENT_ATTR_ID(20),
+ TRANSCEIVER_PRESENT_ATTR_ID(21),
+ TRANSCEIVER_PRESENT_ATTR_ID(22),
+ TRANSCEIVER_PRESENT_ATTR_ID(23),
+ TRANSCEIVER_PRESENT_ATTR_ID(24),
+ TRANSCEIVER_PRESENT_ATTR_ID(25),
+ TRANSCEIVER_PRESENT_ATTR_ID(26),
+ TRANSCEIVER_PRESENT_ATTR_ID(27),
+ TRANSCEIVER_PRESENT_ATTR_ID(28),
+ TRANSCEIVER_PRESENT_ATTR_ID(29),
+ TRANSCEIVER_PRESENT_ATTR_ID(30),
+ TRANSCEIVER_PRESENT_ATTR_ID(31),
+ TRANSCEIVER_PRESENT_ATTR_ID(32),
+ TRANSCEIVER_PRESENT_ATTR_ID(33),
+ TRANSCEIVER_PRESENT_ATTR_ID(34),
+ TRANSCEIVER_PRESENT_ATTR_ID(35),
+ TRANSCEIVER_PRESENT_ATTR_ID(36),
+ TRANSCEIVER_PRESENT_ATTR_ID(37),
+ TRANSCEIVER_PRESENT_ATTR_ID(38),
+ TRANSCEIVER_PRESENT_ATTR_ID(39),
+ TRANSCEIVER_PRESENT_ATTR_ID(40),
+ TRANSCEIVER_PRESENT_ATTR_ID(41),
+ TRANSCEIVER_PRESENT_ATTR_ID(42),
+ TRANSCEIVER_PRESENT_ATTR_ID(43),
+ TRANSCEIVER_PRESENT_ATTR_ID(44),
+ TRANSCEIVER_PRESENT_ATTR_ID(45),
+ TRANSCEIVER_PRESENT_ATTR_ID(46),
+ TRANSCEIVER_PRESENT_ATTR_ID(47),
+ TRANSCEIVER_PRESENT_ATTR_ID(48),
+ TRANSCEIVER_PRESENT_ATTR_ID(49),
+ TRANSCEIVER_PRESENT_ATTR_ID(50),
+ TRANSCEIVER_PRESENT_ATTR_ID(51),
+ TRANSCEIVER_PRESENT_ATTR_ID(52),
+ TRANSCEIVER_PRESENT_ATTR_ID(53),
+ TRANSCEIVER_PRESENT_ATTR_ID(54),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(1),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(2),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(3),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(4),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(5),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(6),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(7),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(8),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(9),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(10),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(11),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(12),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(13),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(14),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(15),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(16),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(17),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(18),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(19),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(20),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(21),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(22),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(23),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(24),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(25),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(26),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(27),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(28),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(29),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(30),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(31),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(32),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(33),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(34),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(35),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(36),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(37),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(38),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(39),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(40),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(41),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(42),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(43),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(44),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(45),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(46),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(47),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(48),
+ TRANSCEIVER_RXLOS_ATTR_ID(1),
+ TRANSCEIVER_RXLOS_ATTR_ID(2),
+ TRANSCEIVER_RXLOS_ATTR_ID(3),
+ TRANSCEIVER_RXLOS_ATTR_ID(4),
+ TRANSCEIVER_RXLOS_ATTR_ID(5),
+ TRANSCEIVER_RXLOS_ATTR_ID(6),
+ TRANSCEIVER_RXLOS_ATTR_ID(7),
+ TRANSCEIVER_RXLOS_ATTR_ID(8),
+ TRANSCEIVER_RXLOS_ATTR_ID(9),
+ TRANSCEIVER_RXLOS_ATTR_ID(10),
+ TRANSCEIVER_RXLOS_ATTR_ID(11),
+ TRANSCEIVER_RXLOS_ATTR_ID(12),
+ TRANSCEIVER_RXLOS_ATTR_ID(13),
+ TRANSCEIVER_RXLOS_ATTR_ID(14),
+ TRANSCEIVER_RXLOS_ATTR_ID(15),
+ TRANSCEIVER_RXLOS_ATTR_ID(16),
+ TRANSCEIVER_RXLOS_ATTR_ID(17),
+ TRANSCEIVER_RXLOS_ATTR_ID(18),
+ TRANSCEIVER_RXLOS_ATTR_ID(19),
+ TRANSCEIVER_RXLOS_ATTR_ID(20),
+ TRANSCEIVER_RXLOS_ATTR_ID(21),
+ TRANSCEIVER_RXLOS_ATTR_ID(22),
+ TRANSCEIVER_RXLOS_ATTR_ID(23),
+ TRANSCEIVER_RXLOS_ATTR_ID(24),
+ TRANSCEIVER_RXLOS_ATTR_ID(25),
+ TRANSCEIVER_RXLOS_ATTR_ID(26),
+ TRANSCEIVER_RXLOS_ATTR_ID(27),
+ TRANSCEIVER_RXLOS_ATTR_ID(28),
+ TRANSCEIVER_RXLOS_ATTR_ID(29),
+ TRANSCEIVER_RXLOS_ATTR_ID(30),
+ TRANSCEIVER_RXLOS_ATTR_ID(31),
+ TRANSCEIVER_RXLOS_ATTR_ID(32),
+ TRANSCEIVER_RXLOS_ATTR_ID(33),
+ TRANSCEIVER_RXLOS_ATTR_ID(34),
+ TRANSCEIVER_RXLOS_ATTR_ID(35),
+ TRANSCEIVER_RXLOS_ATTR_ID(36),
+ TRANSCEIVER_RXLOS_ATTR_ID(37),
+ TRANSCEIVER_RXLOS_ATTR_ID(38),
+ TRANSCEIVER_RXLOS_ATTR_ID(39),
+ TRANSCEIVER_RXLOS_ATTR_ID(40),
+ TRANSCEIVER_RXLOS_ATTR_ID(41),
+ TRANSCEIVER_RXLOS_ATTR_ID(42),
+ TRANSCEIVER_RXLOS_ATTR_ID(43),
+ TRANSCEIVER_RXLOS_ATTR_ID(44),
+ TRANSCEIVER_RXLOS_ATTR_ID(45),
+ TRANSCEIVER_RXLOS_ATTR_ID(46),
+ TRANSCEIVER_RXLOS_ATTR_ID(47),
+ TRANSCEIVER_RXLOS_ATTR_ID(48),
+ TRANSCEIVER_TXFAULT_ATTR_ID(1),
+ TRANSCEIVER_TXFAULT_ATTR_ID(2),
+ TRANSCEIVER_TXFAULT_ATTR_ID(3),
+ TRANSCEIVER_TXFAULT_ATTR_ID(4),
+ TRANSCEIVER_TXFAULT_ATTR_ID(5),
+ TRANSCEIVER_TXFAULT_ATTR_ID(6),
+ TRANSCEIVER_TXFAULT_ATTR_ID(7),
+ TRANSCEIVER_TXFAULT_ATTR_ID(8),
+ TRANSCEIVER_TXFAULT_ATTR_ID(9),
+ TRANSCEIVER_TXFAULT_ATTR_ID(10),
+ TRANSCEIVER_TXFAULT_ATTR_ID(11),
+ TRANSCEIVER_TXFAULT_ATTR_ID(12),
+ TRANSCEIVER_TXFAULT_ATTR_ID(13),
+ TRANSCEIVER_TXFAULT_ATTR_ID(14),
+ TRANSCEIVER_TXFAULT_ATTR_ID(15),
+ TRANSCEIVER_TXFAULT_ATTR_ID(16),
+ TRANSCEIVER_TXFAULT_ATTR_ID(17),
+ TRANSCEIVER_TXFAULT_ATTR_ID(18),
+ TRANSCEIVER_TXFAULT_ATTR_ID(19),
+ TRANSCEIVER_TXFAULT_ATTR_ID(20),
+ TRANSCEIVER_TXFAULT_ATTR_ID(21),
+ TRANSCEIVER_TXFAULT_ATTR_ID(22),
+ TRANSCEIVER_TXFAULT_ATTR_ID(23),
+ TRANSCEIVER_TXFAULT_ATTR_ID(24),
+ TRANSCEIVER_TXFAULT_ATTR_ID(25),
+ TRANSCEIVER_TXFAULT_ATTR_ID(26),
+ TRANSCEIVER_TXFAULT_ATTR_ID(27),
+ TRANSCEIVER_TXFAULT_ATTR_ID(28),
+ TRANSCEIVER_TXFAULT_ATTR_ID(29),
+ TRANSCEIVER_TXFAULT_ATTR_ID(30),
+ TRANSCEIVER_TXFAULT_ATTR_ID(31),
+ TRANSCEIVER_TXFAULT_ATTR_ID(32),
+ TRANSCEIVER_TXFAULT_ATTR_ID(33),
+ TRANSCEIVER_TXFAULT_ATTR_ID(34),
+ TRANSCEIVER_TXFAULT_ATTR_ID(35),
+ TRANSCEIVER_TXFAULT_ATTR_ID(36),
+ TRANSCEIVER_TXFAULT_ATTR_ID(37),
+ TRANSCEIVER_TXFAULT_ATTR_ID(38),
+ TRANSCEIVER_TXFAULT_ATTR_ID(39),
+ TRANSCEIVER_TXFAULT_ATTR_ID(40),
+ TRANSCEIVER_TXFAULT_ATTR_ID(41),
+ TRANSCEIVER_TXFAULT_ATTR_ID(42),
+ TRANSCEIVER_TXFAULT_ATTR_ID(43),
+ TRANSCEIVER_TXFAULT_ATTR_ID(44),
+ TRANSCEIVER_TXFAULT_ATTR_ID(45),
+ TRANSCEIVER_TXFAULT_ATTR_ID(46),
+ TRANSCEIVER_TXFAULT_ATTR_ID(47),
+ TRANSCEIVER_TXFAULT_ATTR_ID(48),
+ TRANSCEIVER_LPMODE_ATTR_ID(49),
+ TRANSCEIVER_LPMODE_ATTR_ID(50),
+ TRANSCEIVER_LPMODE_ATTR_ID(51),
+ TRANSCEIVER_LPMODE_ATTR_ID(52),
+ TRANSCEIVER_LPMODE_ATTR_ID(53),
+ TRANSCEIVER_LPMODE_ATTR_ID(54),
+ TRANSCEIVER_RESET_ATTR_ID(49),
+ TRANSCEIVER_RESET_ATTR_ID(50),
+ TRANSCEIVER_RESET_ATTR_ID(51),
+ TRANSCEIVER_RESET_ATTR_ID(52),
+ TRANSCEIVER_RESET_ATTR_ID(53),
+ TRANSCEIVER_RESET_ATTR_ID(54),
+};
+
+/* sysfs attributes for hwmon
+ */
+static ssize_t show_status(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t access(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t show_version(struct device *dev, struct device_attribute *da,
+ char *buf);
+static int as5712_54x_cpld_read_internal(struct i2c_client *client, u8 reg);
+static int as5712_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value);
+
+/* transceiver attributes */
+#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \
+ static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index)
+#define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr
+
+#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \
+ static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \
+ static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \
+ static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index)
+
+#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \
+ &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \
+ &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \
+ &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr
+
+#define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \
+ static SENSOR_DEVICE_ATTR(module_lp_mode_##index, S_IRUGO | S_IWUSR, show_status, set_lp_mode, MODULE_LPMODE_##index); \
+ static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, show_status, set_mode_reset, MODULE_RESET_##index)
+
+#define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \
+ &sensor_dev_attr_module_lp_mode_##index.dev_attr.attr, \
+ &sensor_dev_attr_module_reset_##index.dev_attr.attr
+
+
+static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION);
+static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS);
+/* transceiver attributes */
+static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL);
+static SENSOR_DEVICE_ATTR(module_rx_los_all, S_IRUGO, show_rxlos_all, NULL, MODULE_RXLOS_ALL);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(1);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(2);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(3);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(4);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(5);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(6);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(7);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(8);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(9);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(10);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(11);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(12);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(13);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(14);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(15);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(16);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(17);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(18);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(19);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(20);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(21);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(22);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(23);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(24);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(25);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(26);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(27);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(28);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(29);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(30);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(31);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(32);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(33);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(34);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(35);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(36);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(37);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(38);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(39);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(40);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(41);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(42);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(43);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(44);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(45);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(46);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(47);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(48);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(49);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(50);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(51);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(52);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(53);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(54);
+
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(1);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(2);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(3);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(4);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(5);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(6);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(7);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(8);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(9);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(10);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(11);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(12);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(13);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(14);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(15);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(16);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(17);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(18);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(19);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(20);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(21);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(22);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(23);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(24);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(25);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(26);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(27);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(28);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(29);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(30);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(31);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(32);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(33);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(35);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(36);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(37);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(38);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(39);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(40);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(41);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(42);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(43);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(44);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48);
+DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(49);
+DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(50);
+DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(51);
+DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(52);
+DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(53);
+DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(54);
+
+static struct attribute *as5712_54x_cpld1_attributes[] = {
+ &sensor_dev_attr_version.dev_attr.attr,
+ &sensor_dev_attr_access.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group as5712_54x_cpld1_group = {
+ .attrs = as5712_54x_cpld1_attributes,
+};
+
+static struct attribute *as5712_54x_cpld2_attributes[] = {
+ &sensor_dev_attr_version.dev_attr.attr,
+ &sensor_dev_attr_access.dev_attr.attr,
+ /* transceiver attributes */
+ &sensor_dev_attr_module_present_all.dev_attr.attr,
+ &sensor_dev_attr_module_rx_los_all.dev_attr.attr,
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(1),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(2),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(3),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(4),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(5),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(6),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(7),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(8),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(9),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(10),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(11),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(12),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(13),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(14),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(15),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(16),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(17),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(18),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(19),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(20),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(21),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(22),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(23),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(24),
+ DECLARE_SFP_TRANSCEIVER_ATTR(1),
+ DECLARE_SFP_TRANSCEIVER_ATTR(2),
+ DECLARE_SFP_TRANSCEIVER_ATTR(3),
+ DECLARE_SFP_TRANSCEIVER_ATTR(4),
+ DECLARE_SFP_TRANSCEIVER_ATTR(5),
+ DECLARE_SFP_TRANSCEIVER_ATTR(6),
+ DECLARE_SFP_TRANSCEIVER_ATTR(7),
+ DECLARE_SFP_TRANSCEIVER_ATTR(8),
+ DECLARE_SFP_TRANSCEIVER_ATTR(9),
+ DECLARE_SFP_TRANSCEIVER_ATTR(10),
+ DECLARE_SFP_TRANSCEIVER_ATTR(11),
+ DECLARE_SFP_TRANSCEIVER_ATTR(12),
+ DECLARE_SFP_TRANSCEIVER_ATTR(13),
+ DECLARE_SFP_TRANSCEIVER_ATTR(14),
+ DECLARE_SFP_TRANSCEIVER_ATTR(15),
+ DECLARE_SFP_TRANSCEIVER_ATTR(16),
+ DECLARE_SFP_TRANSCEIVER_ATTR(17),
+ DECLARE_SFP_TRANSCEIVER_ATTR(18),
+ DECLARE_SFP_TRANSCEIVER_ATTR(19),
+ DECLARE_SFP_TRANSCEIVER_ATTR(20),
+ DECLARE_SFP_TRANSCEIVER_ATTR(21),
+ DECLARE_SFP_TRANSCEIVER_ATTR(22),
+ DECLARE_SFP_TRANSCEIVER_ATTR(23),
+ DECLARE_SFP_TRANSCEIVER_ATTR(24),
+ NULL
+};
+
+static const struct attribute_group as5712_54x_cpld2_group = {
+ .attrs = as5712_54x_cpld2_attributes,
+};
+
+static struct attribute *as5712_54x_cpld3_attributes[] = {
+ &sensor_dev_attr_version.dev_attr.attr,
+ &sensor_dev_attr_access.dev_attr.attr,
+ /* transceiver attributes */
+ &sensor_dev_attr_module_present_all.dev_attr.attr,
+ &sensor_dev_attr_module_rx_los_all.dev_attr.attr,
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(25),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(26),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(27),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(28),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(29),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(30),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(31),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(32),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(33),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(34),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(35),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(36),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(37),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(38),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(39),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(40),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(41),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(42),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(43),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(44),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(45),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(46),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(47),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(48),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(49),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(50),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(51),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(52),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(53),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(54),
+ DECLARE_SFP_TRANSCEIVER_ATTR(25),
+ DECLARE_SFP_TRANSCEIVER_ATTR(26),
+ DECLARE_SFP_TRANSCEIVER_ATTR(27),
+ DECLARE_SFP_TRANSCEIVER_ATTR(28),
+ DECLARE_SFP_TRANSCEIVER_ATTR(29),
+ DECLARE_SFP_TRANSCEIVER_ATTR(30),
+ DECLARE_SFP_TRANSCEIVER_ATTR(31),
+ DECLARE_SFP_TRANSCEIVER_ATTR(32),
+ DECLARE_SFP_TRANSCEIVER_ATTR(33),
+ DECLARE_SFP_TRANSCEIVER_ATTR(34),
+ DECLARE_SFP_TRANSCEIVER_ATTR(35),
+ DECLARE_SFP_TRANSCEIVER_ATTR(36),
+ DECLARE_SFP_TRANSCEIVER_ATTR(37),
+ DECLARE_SFP_TRANSCEIVER_ATTR(38),
+ DECLARE_SFP_TRANSCEIVER_ATTR(39),
+ DECLARE_SFP_TRANSCEIVER_ATTR(40),
+ DECLARE_SFP_TRANSCEIVER_ATTR(41),
+ DECLARE_SFP_TRANSCEIVER_ATTR(42),
+ DECLARE_SFP_TRANSCEIVER_ATTR(43),
+ DECLARE_SFP_TRANSCEIVER_ATTR(44),
+ DECLARE_SFP_TRANSCEIVER_ATTR(45),
+ DECLARE_SFP_TRANSCEIVER_ATTR(46),
+ DECLARE_SFP_TRANSCEIVER_ATTR(47),
+ DECLARE_SFP_TRANSCEIVER_ATTR(48),
+ DECLARE_QSFP_TRANSCEIVER_ATTR(49),
+ DECLARE_QSFP_TRANSCEIVER_ATTR(50),
+ DECLARE_QSFP_TRANSCEIVER_ATTR(51),
+ DECLARE_QSFP_TRANSCEIVER_ATTR(52),
+ DECLARE_QSFP_TRANSCEIVER_ATTR(53),
+ DECLARE_QSFP_TRANSCEIVER_ATTR(54),
+ NULL
+};
+
+static const struct attribute_group as5712_54x_cpld3_group = {
+ .attrs = as5712_54x_cpld3_attributes,
+};
+
+static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ int i, status, num_regs = 0;
+ u8 values[4] = {0};
+ u8 regs[] = {0x6, 0x7, 0x8, 0x14};
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ num_regs = (data->type == as5712_54x_cpld2) ? 3 : 4;
+
+ for (i = 0; i < num_regs; i++) {
+ status = as5712_54x_cpld_read_internal(client, regs[i]);
+
+ if (status < 0) {
+ goto exit;
+ }
+
+ values[i] = ~(u8)status;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ /* Return values 1 -> 54 in order */
+ if (data->type == as5712_54x_cpld2) {
+ status = sprintf(buf, "%.2x %.2x %.2x\n",
+ values[0], values[1], values[2]);
+ }
+ else { /* as5712_54x_cpld3 */
+ values[3] &= 0x3F;
+ status = sprintf(buf, "%.2x %.2x %.2x %.2x\n",
+ values[0], values[1], values[2], values[3]);
+ }
+
+ return status;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ int i, status;
+ u8 values[3] = {0};
+ u8 regs[] = {0xF, 0x10, 0x11};
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ status = as5712_54x_cpld_read_internal(client, regs[i]);
+
+ if (status < 0) {
+ goto exit;
+ }
+
+ values[i] = (u8)status;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ /* Return values 1 -> 24 in order */
+ return sprintf(buf, "%.2x %.2x %.2x\n", values[0], values[1], values[2]);
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static ssize_t show_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+ int status = 0;
+ u8 reg = 0, mask = 0, revert = 0;
+
+ switch (attr->index) {
+ case MODULE_PRESENT_1 ... MODULE_PRESENT_8:
+ reg = 0x6;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_1);
+ break;
+ case MODULE_PRESENT_9 ... MODULE_PRESENT_16:
+ reg = 0x7;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_9);
+ break;
+ case MODULE_PRESENT_17 ... MODULE_PRESENT_24:
+ reg = 0x8;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_17);
+ break;
+ case MODULE_PRESENT_25 ... MODULE_PRESENT_32:
+ reg = 0x6;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_25);
+ break;
+ case MODULE_PRESENT_33 ... MODULE_PRESENT_40:
+ reg = 0x7;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_33);
+ break;
+ case MODULE_PRESENT_41 ... MODULE_PRESENT_48:
+ reg = 0x8;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_41);
+ break;
+ case MODULE_PRESENT_49:
+ reg = 0x14;
+ mask = 0x1;
+ break;
+ case MODULE_PRESENT_50:
+ reg = 0x14;
+ mask = 0x4;
+ break;
+ case MODULE_PRESENT_51:
+ reg = 0x14;
+ mask = 0x10;
+ break;
+ case MODULE_PRESENT_52:
+ reg = 0x14;
+ mask = 0x2;
+ break;
+ case MODULE_PRESENT_53:
+ reg = 0x14;
+ mask = 0x8;
+ break;
+ case MODULE_PRESENT_54:
+ reg = 0x14;
+ mask = 0x20;
+ break;
+ case MODULE_TXFAULT_1 ... MODULE_TXFAULT_8:
+ reg = 0x9;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_1);
+ break;
+ case MODULE_TXFAULT_9 ... MODULE_TXFAULT_16:
+ reg = 0xA;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_9);
+ break;
+ case MODULE_TXFAULT_17 ... MODULE_TXFAULT_24:
+ reg = 0xB;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_17);
+ break;
+ case MODULE_TXFAULT_25 ... MODULE_TXFAULT_32:
+ reg = 0x9;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_25);
+ break;
+ case MODULE_TXFAULT_33 ... MODULE_TXFAULT_40:
+ reg = 0xA;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_33);
+ break;
+ case MODULE_TXFAULT_41 ... MODULE_TXFAULT_48:
+ reg = 0xB;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_41);
+ break;
+ case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8:
+ reg = 0xC;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_1);
+ break;
+ case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16:
+ reg = 0xD;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_9);
+ break;
+ case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24:
+ reg = 0xE;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_17);
+ break;
+ case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32:
+ reg = 0xC;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_25);
+ break;
+ case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40:
+ reg = 0xD;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_33);
+ break;
+ case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48:
+ reg = 0xE;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_41);
+ break;
+ case MODULE_RXLOS_1 ... MODULE_RXLOS_8:
+ reg = 0xF;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_1);
+ break;
+ case MODULE_RXLOS_9 ... MODULE_RXLOS_16:
+ reg = 0x10;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_9);
+ break;
+ case MODULE_RXLOS_17 ... MODULE_RXLOS_24:
+ reg = 0x11;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_17);
+ break;
+ case MODULE_RXLOS_25 ... MODULE_RXLOS_32:
+ reg = 0xF;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_25);
+ break;
+ case MODULE_RXLOS_33 ... MODULE_RXLOS_40:
+ reg = 0x10;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_33);
+ break;
+ case MODULE_RXLOS_41 ... MODULE_RXLOS_48:
+ reg = 0x11;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_41);
+ break;
+ case MODULE_LPMODE_49 ... MODULE_LPMODE_54:
+ reg = 0x16;
+ mask = 0x1 << (attr->index - MODULE_LPMODE_49);
+ break;
+ case MODULE_RESET_49 ... MODULE_RESET_54:
+ reg = 0x15;
+ mask = 0x1 << (attr->index - MODULE_RESET_49);
+ break;
+ default:
+ return 0;
+ }
+
+ if (attr->index >= MODULE_PRESENT_1 && attr->index <= MODULE_PRESENT_54) {
+ revert = 1;
+ }
+
+ mutex_lock(&data->update_lock);
+ status = as5712_54x_cpld_read_internal(client, reg);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+ mutex_unlock(&data->update_lock);
+
+ return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask));
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static ssize_t set_tx_disable(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 as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+ long disable;
+ int status;
+ u8 reg = 0, mask = 0;
+
+ status = kstrtol(buf, 10, &disable);
+ if (status) {
+ return status;
+ }
+
+ switch (attr->index) {
+ case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8:
+ reg = 0xC;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_1);
+ break;
+ case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16:
+ reg = 0xD;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_9);
+ break;
+ case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24:
+ reg = 0xE;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_17);
+ break;
+ case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32:
+ reg = 0xC;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_25);
+ break;
+ case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40:
+ reg = 0xD;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_33);
+ break;
+ case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48:
+ reg = 0xE;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_41);
+ break;
+ default:
+ return 0;
+ }
+
+ /* Read current status */
+ mutex_lock(&data->update_lock);
+ status = as5712_54x_cpld_read_internal(client, reg);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ /* Update tx_disable status */
+ if (disable) {
+ status |= mask;
+ }
+ else {
+ status &= ~mask;
+ }
+
+ status = as5712_54x_cpld_write_internal(client, reg, status);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return count;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static ssize_t set_lp_mode(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 as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+ long on;
+ int status= -ENOENT;
+ u8 reg = 0x16, mask = 0;
+
+ if(attr->index < MODULE_LPMODE_49 || attr->index > MODULE_LPMODE_54)
+ return status;
+
+ status = kstrtol(buf, 10, &on);
+ if (status) {
+ return status;
+ }
+
+ /* Read current status */
+ mutex_lock(&data->update_lock);
+ status = as5712_54x_cpld_read_internal(client, reg);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ mask = 0x1 << (attr->index - MODULE_LPMODE_49);
+
+ /* Update lp_mode status */
+ if (on) {
+ status |= mask;
+ }
+ else {
+ status &= ~mask;
+ }
+
+ status = as5712_54x_cpld_write_internal(client, reg, status);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return count;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+
+}
+
+static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+ long on;
+ int status= -ENOENT;
+ u8 reg = 0x15, mask = 0;
+
+ if(attr->index < MODULE_RESET_49 || attr->index > MODULE_RESET_54)
+ return status;
+
+ status = kstrtol(buf, 10, &on);
+ if (status) {
+ return status;
+ }
+
+ /* Read current status */
+ mutex_lock(&data->update_lock);
+ status = as5712_54x_cpld_read_internal(client, reg);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ mask = 0x1 << (attr->index - MODULE_RESET_49);
+
+ /* Update tx_disable status */
+ if (on) {
+ status |= mask;
+ }
+ else {
+ status &= ~mask;
+ }
+
+ status = as5712_54x_cpld_write_internal(client, reg, status);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return count;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+
+}
+
+static ssize_t access(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ int status;
+ u32 addr, val;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+
+ if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
+ return -EINVAL;
+ }
+
+ if (addr > 0xFF || val > 0xFF) {
+ return -EINVAL;
+ }
+
+ mutex_lock(&data->update_lock);
+ status = as5712_54x_cpld_write_internal(client, addr, val);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+ mutex_unlock(&data->update_lock);
+ return count;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer()
+ for this as they will try to lock adapter a second time */
+static int as5712_54x_cpld_mux_reg_write(struct i2c_adapter *adap,
+ struct i2c_client *client, u8 val)
+{
+ unsigned long orig_jiffies;
+ unsigned short flags;
+ union i2c_smbus_data data;
+ int try;
+ s32 res = -EIO;
+
+ data.byte = val;
+ flags = client->flags;
+ flags &= I2C_M_TEN | I2C_CLIENT_PEC;
+
+ if (adap->algo->smbus_xfer) {
+ /* Retry automatically on arbitration loss */
+ orig_jiffies = jiffies;
+ for (res = 0, try = 0; try <= adap->retries; try++) {
+ res = adap->algo->smbus_xfer(adap, client->addr, flags,
+ I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG,
+ I2C_SMBUS_BYTE_DATA, &data);
+ if (res != -EAGAIN)
+ break;
+ if (time_after(jiffies,
+ orig_jiffies + adap->timeout))
+ break;
+ }
+ }
+
+ return res;
+
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc,
+ u32 chan)
+{
+ struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
+ u8 regval;
+ int ret = 0;
+ regval = chan;
+
+ /* Only select the channel if its different from the last channel */
+ if (data->last_chan != regval) {
+ ret = as5712_54x_cpld_mux_reg_write(muxc->parent, client, regval);
+ data->last_chan = regval;
+ }
+
+ return ret;
+}
+
+static int as5712_54x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc,
+ u32 chan)
+{
+ struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
+
+ /* Deselect active channel */
+ data->last_chan = chips[data->type].deselectChan;
+
+ return as5712_54x_cpld_mux_reg_write(muxc->parent, client, data->last_chan);
+}
+#else
+
+static int as5712_54x_cpld_mux_select_chan(struct i2c_adapter *adap,
+ void *client, u32 chan)
+{
+ struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+ u8 regval;
+ int ret = 0;
+ regval = chan;
+
+ /* Only select the channel if its different from the last channel */
+ if (data->last_chan != regval) {
+ ret = as5712_54x_cpld_mux_reg_write(adap, client, regval);
+ data->last_chan = regval;
+ }
+
+ return ret;
+}
+
+static int as5712_54x_cpld_mux_deselect_mux(struct i2c_adapter *adap,
+ void *client, u32 chan)
+{
+ struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+
+ /* Deselect active channel */
+ data->last_chan = chips[data->type].deselectChan;
+
+ return as5712_54x_cpld_mux_reg_write(adap, client, data->last_chan);
+}
+
+#endif /*#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)*/
+
+static void as5712_54x_cpld_add_client(struct i2c_client *client)
+{
+ struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL);
+
+ if (!node) {
+ dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr);
+ return;
+ }
+
+ node->client = client;
+
+ mutex_lock(&list_lock);
+ list_add(&node->list, &cpld_client_list);
+ mutex_unlock(&list_lock);
+}
+
+static void as5712_54x_cpld_remove_client(struct i2c_client *client)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int found = 0;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client == client) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ list_del(list_node);
+ kfree(cpld_node);
+ }
+
+ mutex_unlock(&list_lock);
+}
+
+static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int val = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+
+ val = i2c_smbus_read_byte_data(client, 0x1);
+
+ if (val < 0) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val);
+}
+
+ return sprintf(buf, "%d", val);
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+static int as5712_54x_cpld_mux_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+ int force, class;
+ struct i2c_mux_core *muxc;
+#endif
+
+ int chan=0;
+ struct as5712_54x_cpld_data *data;
+ int ret = -ENODEV;
+ const struct attribute_group *group = NULL;
+
+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
+ goto exit;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+ muxc = i2c_mux_alloc(adap, &client->dev,
+ chips[id->driver_data].nchans,
+ sizeof(*data), 0,
+ accton_i2c_cpld_mux_select_chan,
+ accton_i2c_cpld_mux_deselect_mux);
+ if (!muxc)
+ return -ENOMEM;
+
+ data = i2c_mux_priv(muxc);
+ i2c_set_clientdata(client, data);
+ data->muxc = muxc;
+ data->client = client;
+#else
+
+ data = kzalloc(sizeof(struct as5712_54x_cpld_data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+#endif
+ data->type = id->driver_data;
+ if (data->type == as5712_54x_cpld2 || data->type == as5712_54x_cpld3) {
+ data->last_chan = chips[data->type].deselectChan; /* force the first selection */
+
+ /* Now create an adapter for each channel */
+ for (chan = 0; chan < chips[data->type].nchans; chan++) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+ force = 0; /* dynamic adap number */
+ class = 0; /* no class by default */
+ ret = i2c_mux_add_adapter(muxc, force, chan, class);
+ if (ret)
+#else
+ data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan,
+ 0,
+ as5712_54x_cpld_mux_select_chan,
+ as5712_54x_cpld_mux_deselect_mux);
+ if (data->virt_adaps[chan] == NULL)
+#endif
+ {
+ ret = -ENODEV;
+ dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan);
+ goto exit_mux_register;
+ }
+ }
+
+ dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n",
+ chan, client->name);
+ }
+ /* Register sysfs hooks */
+ switch (data->type)
+ {
+ case as5712_54x_cpld1:
+ group = &as5712_54x_cpld1_group;
+ break;
+ case as5712_54x_cpld2:
+ group = &as5712_54x_cpld2_group;
+ break;
+ case as5712_54x_cpld3:
+ group = &as5712_54x_cpld3_group;
+ break;
+ default:
+ break;
+ }
+
+
+ if (group) {
+ ret = sysfs_create_group(&client->dev.kobj, group);
+ if (ret) {
+ goto exit_mux_register;
+ }
+ }
+
+ as5712_54x_cpld_add_client(client);
+ return 0;
+
+exit_mux_register:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+ i2c_mux_del_adapters(muxc);
+#else
+ for (chan--; chan >= 0; chan--) {
+ i2c_del_mux_adapter(data->virt_adaps[chan]);
+ }
+#endif
+ kfree(data);
+exit:
+ return ret;
+}
+
+static int as5712_54x_cpld_mux_remove(struct i2c_client *client)
+{
+ struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+ struct i2c_mux_core *muxc = data->muxc;
+
+ i2c_mux_del_adapters(muxc);
+#else
+ const struct chip_desc *chip = &chips[data->type];
+ int chan;
+ const struct attribute_group *group = NULL;
+
+ as5712_54x_cpld_remove_client(client);
+
+ /* Remove sysfs hooks */
+ switch (data->type) {
+ case as5712_54x_cpld1:
+ group = &as5712_54x_cpld1_group;
+ break;
+ case as5712_54x_cpld2:
+ group = &as5712_54x_cpld2_group;
+ break;
+ case as5712_54x_cpld3:
+ group = &as5712_54x_cpld3_group;
+ break;
+ default:
+ break;
+ }
+
+ if (group) {
+ sysfs_remove_group(&client->dev.kobj, group);
+ }
+
+ for (chan = 0; chan < chip->nchans; ++chan) {
+ if (data->virt_adaps[chan]) {
+ i2c_del_mux_adapter(data->virt_adaps[chan]);
+ data->virt_adaps[chan] = NULL;
+ }
+ }
+#endif
+ kfree(data);
+
+ return 0;
+}
+
+static int as5712_54x_cpld_read_internal(struct i2c_client *client, u8 reg)
+{
+ int status = 0, retry = I2C_RW_RETRY_COUNT;
+
+ while (retry) {
+ status = i2c_smbus_read_byte_data(client, reg);
+ if (unlikely(status < 0)) {
+ msleep(I2C_RW_RETRY_INTERVAL);
+ retry--;
+ continue;
+ }
+
+ break;
+ }
+
+ return status;
+}
+
+static int as5712_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value)
+{
+ int status = 0, retry = I2C_RW_RETRY_COUNT;
+
+ while (retry) {
+ status = i2c_smbus_write_byte_data(client, reg, value);
+ if (unlikely(status < 0)) {
+ msleep(I2C_RW_RETRY_INTERVAL);
+ retry--;
+ continue;
+ }
+
+ break;
+ }
+
+ return status;
+}
+
+int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int ret = -EPERM;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client->addr == cpld_addr) {
+ ret = as5712_54x_cpld_read_internal(cpld_node->client, reg);
+ break;
+ }
+ }
+
+ mutex_unlock(&list_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(as5712_54x_cpld_read);
+
+int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int ret = -EIO;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client->addr == cpld_addr) {
+ ret = as5712_54x_cpld_write_internal(cpld_node->client, reg, value);
+ break;
+ }
+ }
+
+ mutex_unlock(&list_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(as5712_54x_cpld_write);
+
+#if 0
+int accton_i2c_cpld_mux_get_index(int adap_index)
+{
+ int i;
+
+ for (i = 0; i < NUM_OF_ALL_CPLD_CHANS; i++) {
+ if (mux_adap_map[i] == adap_index) {
+ return i;
+ }
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(accton_i2c_cpld_mux_get_index);
+#endif
+
+static struct i2c_driver as5712_54x_cpld_mux_driver = {
+ .driver = {
+ .name = "as5712_54x_cpld",
+ .owner = THIS_MODULE,
+ },
+ .probe = as5712_54x_cpld_mux_probe,
+ .remove = as5712_54x_cpld_mux_remove,
+ .id_table = as5712_54x_cpld_mux_id,
+};
+
+static int __init as5712_54x_cpld_mux_init(void)
+{
+ mutex_init(&list_lock);
+ return i2c_add_driver(&as5712_54x_cpld_mux_driver);
+}
+
+static void __exit as5712_54x_cpld_mux_exit(void)
+{
+ i2c_del_driver(&as5712_54x_cpld_mux_driver);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("Accton I2C CPLD mux driver");
+MODULE_LICENSE("GPL");
+
+module_init(as5712_54x_cpld_mux_init);
+module_exit(as5712_54x_cpld_mux_exit);
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c
new file mode 100755
index 00000000000..cdea927368a
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c
@@ -0,0 +1,594 @@
+/*
+ * A LED driver for the accton_as5712_54x_led
+ *
+ * Copyright (C) 2013 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#if 0
+#define DEBUG
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+extern int as5712_54x_cpld_read (unsigned short cpld_addr, u8 reg);
+extern int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+
+extern void led_classdev_unregister(struct led_classdev *led_cdev);
+extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
+extern void led_classdev_resume(struct led_classdev *led_cdev);
+extern void led_classdev_suspend(struct led_classdev *led_cdev);
+
+#define DRVNAME "as5712_54x_led"
+
+struct accton_as5712_54x_led_data {
+ struct platform_device *pdev;
+ struct mutex update_lock;
+ char valid; /* != 0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 reg_val[4]; /* Register value, 0 = LOC/DIAG/FAN LED
+ 1 = PSU1/PSU2 LED
+ 2 = FAN1-4 LED
+ 3 = FAN5-6 LED */
+};
+
+static struct accton_as5712_54x_led_data *ledctl = NULL;
+
+/* LED related data
+ */
+#define LED_TYPE_PSU1_REG_MASK 0x03
+#define LED_MODE_PSU1_GREEN_MASK 0x02
+#define LED_MODE_PSU1_AMBER_MASK 0x01
+#define LED_MODE_PSU1_OFF_MASK 0x03
+#define LED_MODE_PSU1_AUTO_MASK 0x00
+
+#define LED_TYPE_PSU2_REG_MASK 0x0C
+#define LED_MODE_PSU2_GREEN_MASK 0x08
+#define LED_MODE_PSU2_AMBER_MASK 0x04
+#define LED_MODE_PSU2_OFF_MASK 0x0C
+#define LED_MODE_PSU2_AUTO_MASK 0x00
+
+#define LED_TYPE_DIAG_REG_MASK 0x0C
+#define LED_MODE_DIAG_GREEN_MASK 0x08
+#define LED_MODE_DIAG_AMBER_MASK 0x04
+#define LED_MODE_DIAG_OFF_MASK 0x0C
+
+#define LED_TYPE_FAN_REG_MASK 0x03
+#define LED_MODE_FAN_GREEN_MASK 0x02
+#define LED_MODE_FAN_AMBER_MASK 0x01
+#define LED_MODE_FAN_OFF_MASK 0x03
+#define LED_MODE_FAN_AUTO_MASK 0x00
+
+#define LED_TYPE_FAN1_REG_MASK 0x03
+#define LED_TYPE_FAN2_REG_MASK 0x0C
+#define LED_TYPE_FAN3_REG_MASK 0x30
+#define LED_TYPE_FAN4_REG_MASK 0xC0
+#define LED_TYPE_FAN5_REG_MASK 0x03
+#define LED_TYPE_FAN6_REG_MASK 0x0C
+
+#define LED_MODE_FANX_GREEN_MASK 0x01
+#define LED_MODE_FANX_RED_MASK 0x02
+#define LED_MODE_FANX_OFF_MASK 0x00
+
+#define LED_TYPE_LOC_REG_MASK 0x30
+#define LED_MODE_LOC_ON_MASK 0x00
+#define LED_MODE_LOC_OFF_MASK 0x10
+#define LED_MODE_LOC_BLINK_MASK 0x20
+
+static const u8 led_reg[] = {
+ 0xA, /* LOC/DIAG/FAN LED*/
+ 0xB, /* PSU1/PSU2 LED */
+ 0x16, /* FAN1-4 LED */
+ 0x17, /* FAN4-6 LED */
+};
+
+enum led_type {
+ LED_TYPE_PSU1,
+ LED_TYPE_PSU2,
+ LED_TYPE_DIAG,
+ LED_TYPE_FAN,
+ LED_TYPE_FAN1,
+ LED_TYPE_FAN2,
+ LED_TYPE_FAN3,
+ LED_TYPE_FAN4,
+ LED_TYPE_FAN5,
+ LED_TYPE_LOC
+};
+
+enum led_light_mode {
+ LED_MODE_OFF = 0,
+ LED_MODE_GREEN,
+ LED_MODE_AMBER,
+ LED_MODE_RED,
+ LED_MODE_GREEN_BLINK,
+ LED_MODE_AMBER_BLINK,
+ LED_MODE_RED_BLINK,
+ LED_MODE_AUTO,
+};
+
+struct led_type_mode {
+ enum led_type type;
+ int type_mask;
+ enum led_light_mode mode;
+ int mode_mask;
+};
+
+static struct led_type_mode led_type_mode_data[] = {
+{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK},
+{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK},
+{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU1_AUTO_MASK},
+{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK},
+{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK},
+{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK},
+{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU2_AUTO_MASK},
+{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK},
+{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK},
+{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK},
+{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AUTO, LED_MODE_FAN_AUTO_MASK},
+{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK},
+{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0},
+{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0},
+{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0},
+{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2},
+{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2},
+{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2},
+{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4},
+{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4},
+{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4},
+{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6},
+{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6},
+{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6},
+{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0},
+{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0},
+{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0},
+{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_GREEN, LED_MODE_DIAG_GREEN_MASK},
+{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_AMBER, LED_MODE_DIAG_AMBER_MASK},
+{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_OFF, LED_MODE_DIAG_OFF_MASK},
+{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER, LED_MODE_LOC_ON_MASK},
+{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_OFF, LED_MODE_LOC_OFF_MASK},
+{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER_BLINK, LED_MODE_LOC_BLINK_MASK}
+};
+
+
+struct fanx_info_s {
+ u8 cname; /* device name */
+ enum led_type type;
+ u8 reg_id; /* map to led_reg & reg_val */
+};
+
+static struct fanx_info_s fanx_info[] = {
+ {'1', LED_TYPE_FAN1, 2},
+ {'2', LED_TYPE_FAN2, 2},
+ {'3', LED_TYPE_FAN3, 2},
+ {'4', LED_TYPE_FAN4, 2},
+ {'5', LED_TYPE_FAN5, 3}
+};
+
+static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
+
+ if (type != led_type_mode_data[i].type)
+ continue;
+
+ if ((led_type_mode_data[i].type_mask & reg_val) ==
+ led_type_mode_data[i].mode_mask)
+ {
+ return led_type_mode_data[i].mode;
+ }
+ }
+
+ return 0;
+}
+
+static u8 led_light_mode_to_reg_val(enum led_type type,
+ enum led_light_mode mode, u8 reg_val) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
+ if (type != led_type_mode_data[i].type)
+ continue;
+
+ if (mode != led_type_mode_data[i].mode)
+ continue;
+
+ reg_val = led_type_mode_data[i].mode_mask |
+ (reg_val & (~led_type_mode_data[i].type_mask));
+ }
+
+ return reg_val;
+}
+
+static int accton_as5712_54x_led_read_value(u8 reg)
+{
+ return as5712_54x_cpld_read(0x60, reg);
+}
+
+static int accton_as5712_54x_led_write_value(u8 reg, u8 value)
+{
+ return as5712_54x_cpld_write(0x60, reg, value);
+}
+
+static void accton_as5712_54x_led_update(void)
+{
+ mutex_lock(&ledctl->update_lock);
+
+ if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2)
+ || !ledctl->valid) {
+ int i;
+
+ dev_dbg(&ledctl->pdev->dev, "Starting accton_as5712_54x_led update\n");
+
+ /* Update LED data
+ */
+ for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) {
+ int status = accton_as5712_54x_led_read_value(led_reg[i]);
+
+ if (status < 0) {
+ ledctl->valid = 0;
+ dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status);
+ goto exit;
+ }
+ else
+ {
+ ledctl->reg_val[i] = status;
+ }
+ }
+
+ ledctl->last_updated = jiffies;
+ ledctl->valid = 1;
+ }
+
+exit:
+ mutex_unlock(&ledctl->update_lock);
+}
+
+static void accton_as5712_54x_led_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode,
+ u8 reg, enum led_type type)
+{
+ int reg_val;
+
+ mutex_lock(&ledctl->update_lock);
+
+ reg_val = accton_as5712_54x_led_read_value(reg);
+
+ if (reg_val < 0) {
+ dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val);
+ goto exit;
+ }
+
+ reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val);
+ accton_as5712_54x_led_write_value(reg, reg_val);
+
+ /* to prevent the slow-update issue */
+ ledctl->valid = 0;
+
+exit:
+ mutex_unlock(&ledctl->update_lock);
+}
+
+static void accton_as5712_54x_led_psu_1_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1);
+}
+
+static enum led_brightness accton_as5712_54x_led_psu_1_get(struct led_classdev *cdev)
+{
+ accton_as5712_54x_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]);
+}
+
+static void accton_as5712_54x_led_psu_2_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2);
+}
+
+static enum led_brightness accton_as5712_54x_led_psu_2_get(struct led_classdev *cdev)
+{
+ accton_as5712_54x_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]);
+}
+
+static void accton_as5712_54x_led_fan_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_FAN);
+}
+
+static enum led_brightness accton_as5712_54x_led_fan_get(struct led_classdev *cdev)
+{
+ accton_as5712_54x_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[0]);
+}
+
+
+static void accton_as5712_54x_led_fanx_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ enum led_type led_type1;
+ int reg_id;
+ int i, nsize;
+ int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s);
+
+ for(i=0;iname);
+
+ if (led_cdev->name[nsize-1] == fanx_info[i].cname)
+ {
+ led_type1 = fanx_info[i].type;
+ reg_id = fanx_info[i].reg_id;
+ accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1);
+ return;
+ }
+ }
+}
+
+
+static enum led_brightness accton_as5712_54x_led_fanx_get(struct led_classdev *cdev)
+{
+ enum led_type led_type1;
+ int reg_id;
+ int i, nsize;
+ int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s);
+
+ for(i=0;iname);
+
+ if (cdev->name[nsize-1] == fanx_info[i].cname)
+ {
+ led_type1 = fanx_info[i].type;
+ reg_id = fanx_info[i].reg_id;
+ accton_as5712_54x_led_update();
+ return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]);
+ }
+ }
+
+
+ return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[2]);
+}
+
+
+static void accton_as5712_54x_led_diag_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_DIAG);
+}
+
+static enum led_brightness accton_as5712_54x_led_diag_get(struct led_classdev *cdev)
+{
+ accton_as5712_54x_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]);
+}
+
+static void accton_as5712_54x_led_loc_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_LOC);
+}
+
+static enum led_brightness accton_as5712_54x_led_loc_get(struct led_classdev *cdev)
+{
+ accton_as5712_54x_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]);
+}
+
+static struct led_classdev accton_as5712_54x_leds[] = {
+ [LED_TYPE_PSU1] = {
+ .name = "accton_as5712_54x_led::psu1",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_psu_1_set,
+ .brightness_get = accton_as5712_54x_led_psu_1_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_PSU2] = {
+ .name = "accton_as5712_54x_led::psu2",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_psu_2_set,
+ .brightness_get = accton_as5712_54x_led_psu_2_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN] = {
+ .name = "accton_as5712_54x_led::fan",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_fan_set,
+ .brightness_get = accton_as5712_54x_led_fan_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN1] = {
+ .name = "accton_as5712_54x_led::fan1",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_fanx_set,
+ .brightness_get = accton_as5712_54x_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN2] = {
+ .name = "accton_as5712_54x_led::fan2",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_fanx_set,
+ .brightness_get = accton_as5712_54x_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN3] = {
+ .name = "accton_as5712_54x_led::fan3",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_fanx_set,
+ .brightness_get = accton_as5712_54x_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN4] = {
+ .name = "accton_as5712_54x_led::fan4",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_fanx_set,
+ .brightness_get = accton_as5712_54x_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN5] = {
+ .name = "accton_as5712_54x_led::fan5",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_fanx_set,
+ .brightness_get = accton_as5712_54x_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_DIAG] = {
+ .name = "accton_as5712_54x_led::diag",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_diag_set,
+ .brightness_get = accton_as5712_54x_led_diag_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_LOC] = {
+ .name = "accton_as5712_54x_led::loc",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5712_54x_led_loc_set,
+ .brightness_get = accton_as5712_54x_led_loc_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+};
+
+static int accton_as5712_54x_led_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ int i = 0;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as5712_54x_leds); i++) {
+ led_classdev_suspend(&accton_as5712_54x_leds[i]);
+ }
+
+ return 0;
+}
+
+static int accton_as5712_54x_led_resume(struct platform_device *dev)
+{
+ int i = 0;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as5712_54x_leds); i++) {
+ led_classdev_resume(&accton_as5712_54x_leds[i]);
+ }
+
+ return 0;
+}
+
+static int accton_as5712_54x_led_probe(struct platform_device *pdev)
+{
+ int ret, i;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as5712_54x_leds); i++) {
+ ret = led_classdev_register(&pdev->dev, &accton_as5712_54x_leds[i]);
+
+ if (ret < 0)
+ break;
+ }
+
+ /* Check if all LEDs were successfully registered */
+ if (i != ARRAY_SIZE(accton_as5712_54x_leds)){
+ int j;
+
+ /* only unregister the LEDs that were successfully registered */
+ for (j = 0; j < i; j++) {
+ led_classdev_unregister(&accton_as5712_54x_leds[i]);
+ }
+ }
+
+ return ret;
+}
+
+static int accton_as5712_54x_led_remove(struct platform_device *pdev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as5712_54x_leds); i++) {
+ led_classdev_unregister(&accton_as5712_54x_leds[i]);
+ }
+
+ return 0;
+}
+
+static struct platform_driver accton_as5712_54x_led_driver = {
+ .probe = accton_as5712_54x_led_probe,
+ .remove = accton_as5712_54x_led_remove,
+ .suspend = accton_as5712_54x_led_suspend,
+ .resume = accton_as5712_54x_led_resume,
+ .driver = {
+ .name = DRVNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init accton_as5712_54x_led_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&accton_as5712_54x_led_driver);
+ if (ret < 0) {
+ goto exit;
+ }
+
+ ledctl = kzalloc(sizeof(struct accton_as5712_54x_led_data), GFP_KERNEL);
+ if (!ledctl) {
+ ret = -ENOMEM;
+ platform_driver_unregister(&accton_as5712_54x_led_driver);
+ goto exit;
+ }
+
+ mutex_init(&ledctl->update_lock);
+
+ ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
+ if (IS_ERR(ledctl->pdev)) {
+ ret = PTR_ERR(ledctl->pdev);
+ platform_driver_unregister(&accton_as5712_54x_led_driver);
+ kfree(ledctl);
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+static void __exit accton_as5712_54x_led_exit(void)
+{
+ platform_device_unregister(ledctl->pdev);
+ platform_driver_unregister(&accton_as5712_54x_led_driver);
+ kfree(ledctl);
+}
+
+module_init(accton_as5712_54x_led_init);
+module_exit(accton_as5712_54x_led_exit);
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton_as5712_54x_led driver");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c
new file mode 100755
index 00000000000..519530387e2
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c
@@ -0,0 +1,683 @@
+/*
+ * An hwmon driver for the 3Y Power YM-2651Y Power Module
+ *
+ * Copyright (C) 2014 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#if 0
+#define DEBUG
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define MAX_FAN_DUTY_CYCLE 100
+
+/* Addresses scanned
+ */
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+enum chips {
+ YM2651,
+ YM2401,
+};
+
+/* Each client has this additional data
+ */
+struct ym2651y_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 chip; /* chip id */
+ u8 capability; /* Register value */
+ u16 status_word; /* Register value */
+ u8 fan_fault; /* Register value */
+ u8 over_temp; /* Register value */
+ u16 v_out; /* Register value */
+ u16 i_out; /* Register value */
+ u16 p_out; /* Register value */
+ u8 vout_mode; /* Register value */
+ u16 temp; /* Register value */
+ u16 fan_speed; /* Register value */
+ u16 fan_duty_cycle[2]; /* Register value */
+ u8 fan_dir[5]; /* Register value */
+ u8 pmbus_revision; /* Register value */
+ u8 mfr_id[10]; /* Register value */
+ u8 mfr_model[16]; /* Register value */
+ u8 mfr_revsion[3]; /* Register value */
+ u16 mfr_vin_min; /* Register value */
+ u16 mfr_vin_max; /* Register value */
+ u16 mfr_iin_max; /* Register value */
+ u16 mfr_iout_max; /* Register value */
+ u16 mfr_pin_max; /* Register value */
+ u16 mfr_pout_max; /* Register value */
+ u16 mfr_vout_min; /* Register value */
+ u16 mfr_vout_max; /* Register value */
+};
+
+static ssize_t show_byte(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_word(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_linear(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_over_temp(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_ascii(struct device *dev, struct device_attribute *da,
+ char *buf);
+static struct ym2651y_data *ym2651y_update_device(struct device *dev);
+static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value);
+
+enum ym2651y_sysfs_attributes {
+ PSU_POWER_ON = 0,
+ PSU_TEMP_FAULT,
+ PSU_POWER_GOOD,
+ PSU_FAN1_FAULT,
+ PSU_FAN_DIRECTION,
+ PSU_OVER_TEMP,
+ PSU_V_OUT,
+ PSU_I_OUT,
+ PSU_P_OUT,
+ PSU_TEMP1_INPUT,
+ PSU_FAN1_SPEED,
+ PSU_FAN1_DUTY_CYCLE,
+ PSU_PMBUS_REVISION,
+ PSU_MFR_ID,
+ PSU_MFR_MODEL,
+ PSU_MFR_REVISION,
+ PSU_MFR_VIN_MIN,
+ PSU_MFR_VIN_MAX,
+ PSU_MFR_VOUT_MIN,
+ PSU_MFR_VOUT_MAX,
+ PSU_MFR_IIN_MAX,
+ PSU_MFR_IOUT_MAX,
+ PSU_MFR_PIN_MAX,
+ PSU_MFR_POUT_MAX
+};
+
+/* sysfs attributes for hwmon
+ */
+static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON);
+static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT);
+static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD);
+static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT);
+static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP);
+static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT);
+static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT);
+static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT);
+static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT);
+static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED);
+static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE);
+static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION);
+static SENSOR_DEVICE_ATTR(psu_pmbus_revision,S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION);
+static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID);
+static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL);
+static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION);
+static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN);
+static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN);
+static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX);
+
+static struct attribute *ym2651y_attributes[] = {
+ &sensor_dev_attr_psu_power_on.dev_attr.attr,
+ &sensor_dev_attr_psu_temp_fault.dev_attr.attr,
+ &sensor_dev_attr_psu_power_good.dev_attr.attr,
+ &sensor_dev_attr_psu_fan1_fault.dev_attr.attr,
+ &sensor_dev_attr_psu_over_temp.dev_attr.attr,
+ &sensor_dev_attr_psu_v_out.dev_attr.attr,
+ &sensor_dev_attr_psu_i_out.dev_attr.attr,
+ &sensor_dev_attr_psu_p_out.dev_attr.attr,
+ &sensor_dev_attr_psu_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr,
+ &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr,
+ &sensor_dev_attr_psu_fan_dir.dev_attr.attr,
+ &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_id.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_model.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_revision.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr,
+ NULL
+};
+
+static ssize_t show_byte(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) :
+ sprintf(buf, "0\n");
+}
+
+static ssize_t show_word(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+ u16 status = 0;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ switch (attr->index) {
+ case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */
+ status = (data->status_word & 0x40) ? 0 : 1;
+ break;
+ case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */
+ status = (data->status_word & 0x4) >> 2;
+ break;
+ case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */
+ status = (data->status_word & 0x800) ? 0 : 1;
+ break;
+ }
+
+ return sprintf(buf, "%d\n", status);
+}
+
+static int two_complement_to_int(u16 data, u8 valid_bit, int mask)
+{
+ u16 valid_data = data & mask;
+ bool is_negative = valid_data >> (valid_bit - 1);
+
+ return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data;
+}
+
+static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ym2651y_data *data = i2c_get_clientdata(client);
+ int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1;
+ long speed;
+ int error;
+
+ error = kstrtol(buf, 10, &speed);
+ if (error)
+ return error;
+
+ if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->fan_duty_cycle[nr] = speed;
+ ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t show_linear(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+
+ u16 value = 0;
+ int exponent, mantissa;
+ int multiplier = 1000;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ switch (attr->index) {
+ case PSU_V_OUT:
+ value = data->v_out;
+ break;
+ case PSU_I_OUT:
+ value = data->i_out;
+ break;
+ case PSU_P_OUT:
+ value = data->p_out;
+ break;
+ case PSU_TEMP1_INPUT:
+ value = data->temp;
+ break;
+ case PSU_FAN1_SPEED:
+ value = data->fan_speed;
+ multiplier = 1;
+ break;
+ case PSU_FAN1_DUTY_CYCLE:
+ value = data->fan_duty_cycle[0];
+ multiplier = 1;
+ break;
+ case PSU_MFR_VIN_MIN:
+ value = data->mfr_vin_min;
+ break;
+ case PSU_MFR_VIN_MAX:
+ value = data->mfr_vin_max;
+ break;
+ case PSU_MFR_VOUT_MIN:
+ value = data->mfr_vout_min;
+ break;
+ case PSU_MFR_VOUT_MAX:
+ value = data->mfr_vout_max;
+ break;
+ case PSU_MFR_PIN_MAX:
+ value = data->mfr_pin_max;
+ break;
+ case PSU_MFR_POUT_MAX:
+ value = data->mfr_pout_max;
+ break;
+ case PSU_MFR_IOUT_MAX:
+ value = data->mfr_iout_max;
+ break;
+ case PSU_MFR_IIN_MAX:
+ value = data->mfr_iin_max;
+ break;
+ }
+
+ exponent = two_complement_to_int(value >> 11, 5, 0x1f);
+ mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff);
+
+ return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :
+ sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
+}
+
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+ u8 shift;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6;
+
+ return sprintf(buf, "%d\n", data->fan_fault >> shift);
+}
+
+static ssize_t show_over_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ return sprintf(buf, "%d\n", data->over_temp >> 7);
+}
+
+static ssize_t show_ascii(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+ u8 *ptr = NULL;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ switch (attr->index) {
+ case PSU_FAN_DIRECTION: /* psu_fan_dir */
+ ptr = data->fan_dir + 1; /* Skip the first byte since it is the length of string. */
+ break;
+ case PSU_MFR_ID: /* psu_mfr_id */
+ ptr = data->mfr_id + 1; /* The first byte is the count byte of string. */;
+ break;
+ case PSU_MFR_MODEL: /* psu_mfr_model */
+ ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */
+ break;
+ case PSU_MFR_REVISION: /* psu_mfr_revision */
+ ptr = data->mfr_revsion + 1; /* The first byte is the count byte of string. */
+ break;
+ default:
+ return 0;
+ }
+
+ return sprintf(buf, "%s\n", ptr);
+}
+
+static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+ int exponent, mantissa;
+ int multiplier = 1000;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ exponent = two_complement_to_int(data->vout_mode, 5, 0x1f);
+ mantissa = data->v_out;
+
+ return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :
+ sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
+}
+
+static ssize_t show_vout(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ym2651y_data *data = i2c_get_clientdata(client);
+
+ if (data->chip == YM2401) {
+ return show_vout_by_mode(dev, da, buf);
+ }
+
+ return show_linear(dev, da, buf);
+}
+
+static const struct attribute_group ym2651y_group = {
+ .attrs = ym2651y_attributes,
+};
+
+static int ym2651y_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ struct ym2651y_data *data;
+ int status;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_WORD_DATA |
+ I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL);
+ if (!data) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+ data->chip = dev_id->driver_data;
+ dev_info(&client->dev, "chip found\n");
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &ym2651y_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "%s: psu '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &ym2651y_group);
+exit_free:
+ kfree(data);
+exit:
+
+ return status;
+}
+
+static int ym2651y_remove(struct i2c_client *client)
+{
+ struct ym2651y_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &ym2651y_group);
+ kfree(data);
+
+ return 0;
+}
+
+static const struct i2c_device_id ym2651y_id[] = {
+ { "ym2651", YM2651 },
+ { "ym2401", YM2401 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, ym2651y_id);
+
+static struct i2c_driver ym2651y_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "ym2651",
+ },
+ .probe = ym2651y_probe,
+ .remove = ym2651y_remove,
+ .id_table = ym2651y_id,
+ .address_list = normal_i2c,
+};
+
+static int ym2651y_read_byte(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int ym2651y_read_word(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_word_data(client, reg);
+}
+
+static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value)
+{
+ return i2c_smbus_write_word_data(client, reg, value);
+}
+
+static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data,
+ int data_len)
+{
+ int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
+
+ if (unlikely(result < 0))
+ goto abort;
+ if (unlikely(result != data_len)) {
+ result = -EIO;
+ goto abort;
+ }
+
+ result = 0;
+
+abort:
+ return result;
+}
+
+struct reg_data_byte {
+ u8 reg;
+ u8 *value;
+};
+
+struct reg_data_word {
+ u8 reg;
+ u16 *value;
+};
+
+static struct ym2651y_data *ym2651y_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ym2651y_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int i, status, length;
+ u8 command, buf;
+ struct reg_data_byte regs_byte[] = { {0x19, &data->capability},
+ {0x20, &data->vout_mode},
+ {0x7d, &data->over_temp},
+ {0x81, &data->fan_fault},
+ {0x98, &data->pmbus_revision}};
+ struct reg_data_word regs_word[] = { {0x79, &data->status_word},
+ {0x8b, &data->v_out},
+ {0x8c, &data->i_out},
+ {0x96, &data->p_out},
+ {0x8d, &data->temp},
+ {0x3b, &(data->fan_duty_cycle[0])},
+ {0x3c, &(data->fan_duty_cycle[1])},
+ {0x90, &data->fan_speed},
+ {0xa0, &data->mfr_vin_min},
+ {0xa1, &data->mfr_vin_max},
+ {0xa2, &data->mfr_iin_max},
+ {0xa3, &data->mfr_pin_max},
+ {0xa4, &data->mfr_vout_min},
+ {0xa5, &data->mfr_vout_max},
+ {0xa6, &data->mfr_iout_max},
+ {0xa7, &data->mfr_pout_max}};
+
+ dev_dbg(&client->dev, "Starting ym2651 update\n");
+ data->valid = 0;
+
+ /* Read byte data */
+ for (i = 0; i < ARRAY_SIZE(regs_byte); i++) {
+ status = ym2651y_read_byte(client, regs_byte[i].reg);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n",
+ regs_byte[i].reg, status);
+ goto exit;
+ }
+ else {
+ *(regs_byte[i].value) = status;
+ }
+ }
+
+ /* Read word data */
+ for (i = 0; i < ARRAY_SIZE(regs_word); i++) {
+ status = ym2651y_read_word(client, regs_word[i].reg);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n",
+ regs_word[i].reg, status);
+ goto exit;
+ }
+ else {
+ *(regs_word[i].value) = status;
+ }
+ }
+
+ /* Read fan_direction */
+ command = 0xC3;
+ status = ym2651y_read_block(client, command, data->fan_dir,
+ ARRAY_SIZE(data->fan_dir)-1);
+ data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0';
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ /* Read mfr_id */
+ command = 0x99;
+ status = ym2651y_read_block(client, command, data->mfr_id,
+ ARRAY_SIZE(data->mfr_id)-1);
+ data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0';
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ /* Read mfr_model */
+ command = 0x9a;
+ length = 1;
+
+ /* Read first byte to determine the length of data */
+ status = ym2651y_read_block(client, command, &buf, length);
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ status = ym2651y_read_block(client, command, data->mfr_model, buf+1);
+ data->mfr_model[buf+1] = '\0';
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ /* Read mfr_revsion */
+ command = 0x9b;
+ status = ym2651y_read_block(client, command, data->mfr_revsion,
+ ARRAY_SIZE(data->mfr_revsion)-1);
+ data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0';
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+exit:
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init ym2651y_init(void)
+{
+ return i2c_add_driver(&ym2651y_driver);
+}
+
+static void __exit ym2651y_exit(void)
+{
+ i2c_del_driver(&ym2651y_driver);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("3Y Power YM-2651Y driver");
+MODULE_LICENSE("GPL");
+
+module_init(ym2651y_init);
+module_exit(ym2651y_exit);
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/service/as5712-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/service/as5712-platform-monitor.service
new file mode 100755
index 00000000000..da5d283a6d6
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/service/as5712-platform-monitor.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Accton AS5712-54X Platform Monitoring service
+Before=pmon.service
+After=sysinit.target
+DefaultDependencies=no
+
+[Service]
+ExecStartPre=/usr/local/bin/accton_as5712_util.py install
+ExecStart=/usr/local/bin/accton_as5712_monitor.py
+KillSignal=SIGKILL
+SuccessExitStatus=SIGKILL
+
+# Resource Limitations
+LimitCORE=infinity
+
+[Install]
+WantedBy=multi-user.target
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/setup.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/setup.py
new file mode 100755
index 00000000000..f4cb5f960a4
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/setup.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+
+import os
+import sys
+from setuptools import setup
+os.listdir
+
+setup(
+ name='as5712_54x',
+ version='1.0',
+ description='Module to initialize Accton AS5712-54X platforms',
+
+ packages=['as5712_54x'],
+ package_dir={'as5712_54x': 'as5712-54x/classes'},
+)
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README
new file mode 100755
index 00000000000..9cd5dbdd9de
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README
@@ -0,0 +1,117 @@
+Copyright (C) 2016 Accton Networks, Inc.
+
+This program is free software: you can redistribute it and/or modify
+It under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+
+Contents of this package:
+ patch - files under patch/ is for kernel and ONIE installer
+ for the kernel:
+ config-accton-as5712_54x.patch
+ for kernel configuration.
+ driver-i2c-muxes-pca954x-always-deselect.patch
+ for i2c_mux deselects after transaction.
+ driver-patches-for-accton-as5712-fan-psu-cpld.patch
+ for as5712's fan/psu/cpld/led/sfp drivers.
+ for ONIE:
+ onie_installer-accton-AS5712-54X.patch
+ for console port setting and copy util script o rootfs.
+ module - Contains source code of as5712 kernel driver modules.
+
+The late Sonic building scripts, pushed @Dec 5 2016, will automatically
+create a docker container and run building process under it.
+User is not necessary to handle docker environment creation.
+
+1. Download sonic-buildimage environment.
+ - Run "git clone https://github.com/Azure/sonic-buildimage".
+ - cd to sonic-buildimage and run "git submodule update --init --recursive".
+2. Build kernel
+ - cd ./src/sonic-linux-kernel
+ - Copy patches and series from patch/kernel of this release to
+ sonic-linux-kernel/patch.
+ - Build kernel by "make".
+ - The built kernel package, linux-image-3.16.0-6-amd64_3.16.51-3+deb8u1_amd64.deb
+ , is generated.
+3. Build installer
+ - Change directory back to sonic-buildimage/.
+ - Get onie_installer-accton-AS5712-54X.patch" from patch/installer.
+ - Change setting for AS5712-54X by patching build_image.sh.
+ "patch -p1 < onie_installer-accton-AS5712-54X.patch"
+ !!NOTICE, patching onie_installer-accton-AS5712-54X.patch comments out the
+ "git status" checking at build_image.sh.
+ - The account and password of installed OS can be given at rules/config.
+ The default user and password are "admin" & "YourPaSsWoRd" respectively.
+ - Run "make configure PLATFORM=broadcom"
+ - Copy the built kernel debian package to target/debs/.
+ The file is linux-image-3.16.0-6-amd64_*_amd64.deb under directory
+ src/sonic-linux-kernel/.
+ - Run "make target/sonic-generic.bin"
+ - Get the installer, target/sonic-generic.bin, to target machine and install.
+
+All Linux kernel code is licensed under the GPLv1. All other code is
+licensed under the GPLv3. Please see the LICENSE file for copies of
+both licenses.
+
+The code for integacting with Accton AS5712-54X has 2 parts,
+kernel drivers and operational script.
+The kernel drivers of peripherals are under module/ directory.
+1. These drivers are patched into kernel by
+ driver-patches-for-accton-as5712-fan-psu-cpld.patch
+ Or you can build the driver under module/ by setting environment variable,
+ KERNEL_SRC, to proper linux built directory and run make.
+ It may be sonic-linux-kernel/linux-3.*/debian/build/build_amd64_none_amd64/.
+2. A operational script, accton_as5712_util.py, for device initializatian and
+ peripheral accessing should be installed at /usr/bin.
+ This script is generated by onie_installer-accton-AS5712-54X.patch.
+ It's done by patching onie_installer-accton-AS5712-54X.patch at build-image.
+ Run "accton_as5712_util.py install" to install drivers.
+
+To initialize the system, run "accton_as5712_util.py install".
+To clean up the drivers & devices, run "accton_as5712_util.py clean".
+To dump information of sensors, run "accton_as5712_util.py show".
+To dump SFP EEPROM, run "accton_as5712_util.py sff".
+To set fan speed, run "accton_as5712_util.py set fan".
+To enable/disable SFP emission, run "accton_as5712_util.py set sfp".
+To set system LEDs' color, run "accton_as5712_util.py set led"
+For more information, run "accton_as5712_util.py --help".
+
+====================================================================
+Besides applying accton_as5712_util.py to access peripherals, you can
+access peripherals by sysfs nodes directly after the installation is run.
+
+System LED:
+ There are 5 system LEDs at the lower-left corner of front panel.
+ They are loc, diag, fan, ps1, and ps2.
+ The sysfs interface color mappings are as follows:
+ Brightness:
+ 0 => off
+ 1 => green
+ 2 => amber
+ 3 => red
+ 4 => blue
+ But not all colors are available for each LED.
+
+Fan Control:
+ There are 10 fans inside 5 fan modules.
+ All fans share 1 duty setting, ranged from 0~100.
+
+Thermal sensers:
+ 3 temperature sensors are controlled by the lm75 kernel modules.
+
+PSUs:
+ There 2 power supplies slot at the left/right side of the back.
+ Once if a PSU is not plugged, the status of it is shown failed.
+
+There are 48 SFP+ and 6 QSFP modules are equipped.
+Before operating on PSU and QSFP+, please make sure it is well plugged.
+Otherwise, operation is going to fail.
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py
new file mode 100755
index 00000000000..84ab2d83bab
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 Accton Technology Corporation
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# ------------------------------------------------------------------
+# HISTORY:
+# mm/dd/yyyy (A.D.)
+# 11/13/2017: Polly Hsu, Create
+#
+# ------------------------------------------------------------------
+
+try:
+ import os
+ import sys, getopt
+ import subprocess
+ import click
+ import imp
+ import logging
+ import logging.config
+ import types
+ import time # this is only being used as part of the example
+ import traceback
+ from tabulate import tabulate
+ from as5712_54x.fanutil import FanUtil
+ from as5712_54x.thermalutil import ThermalUtil
+except ImportError as e:
+ raise ImportError('%s - required module not found' % str(e))
+
+# Deafults
+VERSION = '1.0'
+FUNCTION_NAME = 'accton_as5712_monitor'
+
+global log_file
+global log_level
+
+# Make a class we can use to capture stdout and sterr in the log
+class accton_as5712_monitor(object):
+ # static temp var
+ _ori_temp = 0
+ _new_perc = 0
+ _ori_perc = 0
+
+ def __init__(self, log_file, log_level):
+ """Needs a logger and a logger level."""
+ # set up logging to file
+ logging.basicConfig(
+ filename=log_file,
+ filemode='w',
+ level=log_level,
+ format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
+ datefmt='%H:%M:%S'
+ )
+
+ # set up logging to console
+ if log_level == logging.DEBUG:
+ console = logging.StreamHandler()
+ console.setLevel(log_level)
+ formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
+ console.setFormatter(formatter)
+ logging.getLogger('').addHandler(console)
+
+ logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level)
+
+ def manage_fans(self):
+ FAN_LEV1_UP_TEMP = 57500 # temperature
+ FAN_LEV1_DOWN_TEMP = 0 # unused
+ FAN_LEV1_SPEED_PERC = 100 # percentage*/
+
+ FAN_LEV2_UP_TEMP = 53000
+ FAN_LEV2_DOWN_TEMP = 52700
+ FAN_LEV2_SPEED_PERC = 80
+
+ FAN_LEV3_UP_TEMP = 49500
+ FAN_LEV3_DOWN_TEMP = 47700
+ FAN_LEV3_SPEED_PERC = 65
+
+ FAN_LEV4_UP_TEMP = 0 # unused
+ FAN_LEV4_DOWN_TEMP = 42700
+ FAN_LEV4_SPEED_PERC = 40
+
+
+ thermal = ThermalUtil()
+ fan = FanUtil()
+
+ temp1 = thermal.get_thermal_1_val()
+ if temp1 is None:
+ return False
+
+ temp2 = thermal.get_thermal_2_val()
+ if temp2 is None:
+ return False
+
+ new_temp = (temp1 + temp2) / 2
+
+ for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1):
+ fan_stat = fan.get_fan_status(x)
+ if fan_stat is None:
+ return False
+ if fan_stat is False:
+ self._new_perc = FAN_LEV1_SPEED_PERC
+ logging.debug('INFO. SET new_perc to %d (FAN fault. fan_num:%d)', self._new_perc, x)
+ break
+ logging.debug('INFO. fan_stat is True (fan_num:%d)', x)
+
+ if fan_stat is not None and fan_stat is not False:
+ diff = new_temp - self._ori_temp
+ if diff == 0:
+ logging.debug('INFO. RETURN. THERMAL temp not changed. %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp)
+ return True
+ else:
+ if diff >= 0:
+ is_up = True
+ logging.debug('INFO. THERMAL temp UP %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp)
+ else:
+ is_up = False
+ logging.debug('INFO. THERMAL temp DOWN %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp)
+
+ if is_up is True:
+ if new_temp >= FAN_LEV1_UP_TEMP:
+ self._new_perc = FAN_LEV1_SPEED_PERC
+ elif new_temp >= FAN_LEV2_UP_TEMP:
+ self._new_perc = FAN_LEV2_SPEED_PERC
+ elif new_temp >= FAN_LEV3_UP_TEMP:
+ self._new_perc = FAN_LEV3_SPEED_PERC
+ else:
+ self._new_perc = FAN_LEV4_SPEED_PERC
+ logging.debug('INFO. SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp)
+ else:
+ if new_temp <= FAN_LEV4_DOWN_TEMP:
+ self._new_perc = FAN_LEV4_SPEED_PERC
+ elif new_temp <= FAN_LEV3_DOWN_TEMP:
+ self._new_perc = FAN_LEV3_SPEED_PERC
+ elif new_temp <= FAN_LEV2_DOWN_TEMP:
+ self._new_perc = FAN_LEV2_SPEED_PERC
+ else:
+ self._new_perc = FAN_LEV1_SPEED_PERC
+ logging.debug('INFO. SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp)
+
+ if self._ori_perc == self._new_perc:
+ logging.debug('INFO. RETURN. FAN speed not changed. %d / %d (new_perc / ori_perc)', self._new_perc, self._ori_perc)
+ return True
+
+ set_stat = fan.set_fan_duty_cycle(fan.get_idx_fan_start(), self._new_perc)
+ if set_stat is True:
+ logging.debug('INFO: PASS. set_fan_duty_cycle (%d)', self._new_perc)
+ else:
+ logging.debug('INFO: FAIL. set_fan_duty_cycle (%d)', self._new_perc)
+
+ logging.debug('INFO: GET. ori_perc is %d. ori_temp is %d', self._ori_perc, self._ori_temp)
+ self._ori_perc = self._new_perc
+ self._ori_temp = new_temp
+ logging.debug('INFO: UPDATE. ori_perc to %d. ori_temp to %d', self._ori_perc, self._ori_temp)
+
+ return True
+
+def main(argv):
+ log_file = '%s.log' % FUNCTION_NAME
+ log_level = logging.INFO
+ if len(sys.argv) != 1:
+ try:
+ opts, args = getopt.getopt(argv,'hdl:',['lfile='])
+ except getopt.GetoptError:
+ print 'Usage: %s [-d] [-l ]' % sys.argv[0]
+ return 0
+ for opt, arg in opts:
+ if opt == '-h':
+ print 'Usage: %s [-d] [-l ]' % sys.argv[0]
+ return 0
+ elif opt in ('-d', '--debug'):
+ log_level = logging.DEBUG
+ elif opt in ('-l', '--lfile'):
+ log_file = arg
+
+ monitor = accton_as5712_monitor(log_file, log_level)
+
+ # Loop forever, doing something useful hopefully:
+ while True:
+ monitor.manage_fans()
+ time.sleep(1)
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py
new file mode 100755
index 00000000000..e958cb59686
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py
@@ -0,0 +1,602 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 Accton Networks, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+"""
+Usage: %(scriptName)s [options] command object
+
+options:
+ -h | --help : this help message
+ -d | --debug : run with debug mode
+ -f | --force : ignore error during installation or clean
+command:
+ install : install drivers and generate related sysfs nodes
+ clean : uninstall drivers and remove related sysfs nodes
+ show : show all systen status
+ sff : dump SFP eeprom
+ set : change board setting with fan|led|sfp
+"""
+
+import os
+import commands
+import sys, getopt
+import logging
+import re
+import time
+from collections import namedtuple
+
+PROJECT_NAME = 'as5712_54x'
+version = '0.2.0'
+verbose = False
+DEBUG = False
+args = []
+ALL_DEVICE = {}
+DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':54}
+
+
+led_prefix ='/sys/devices/platform/as5712_54x_led/leds/accton_'+PROJECT_NAME+'_led::'
+fan_prefix ='/sys/devices/platform/as5712_54x_'
+hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'],
+ 'fan1': ['fan'],
+ 'fan2': ['fan'],
+ 'fan3': ['fan'],
+ 'fan4': ['fan'],
+ 'fan5': ['fan'],
+ }
+hwmon_nodes = {'led': ['brightness'] ,
+ 'fan1': ['fan1_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'],
+ 'fan2': ['fan2_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'],
+ 'fan3': ['fan3_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'],
+ 'fan4': ['fan4_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'],
+ 'fan5': ['fan5_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'],
+ }
+hwmon_prefix ={'led': led_prefix,
+ 'fan1': fan_prefix,
+ 'fan2': fan_prefix,
+ 'fan3': fan_prefix,
+ 'fan4': fan_prefix,
+ 'fan5': fan_prefix,
+ }
+
+i2c_prefix = '/sys/bus/i2c/devices/'
+i2c_bus = {'thermal': ['61-0048','62-0049', '63-004a'] ,
+ 'psu': ['57-0050','58-0053'],
+ 'sfp': ['-0050']}
+i2c_nodes = {
+ 'thermal': ['hwmon/hwmon*/temp1_input'] ,
+ 'psu': ['psu_present ', 'psu_power_good'] ,
+ 'sfp': ['sfp_is_present ', 'sfp_tx_disable']}
+
+sfp_map = [2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 52, 54, 51, 53, 55]
+mknod =[
+'echo as5712_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-0/new_device',
+'echo as5712_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-0/new_device',
+'echo as5712_54x_cpld3 0x62 > /sys/bus/i2c/devices/i2c-0/new_device',
+'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device',
+
+# PSU-1
+'echo as5712_54x_psu1 0x38 > /sys/bus/i2c/devices/i2c-57/new_device',
+'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-57/new_device',
+'echo as5712_54x_psu1 0x50 > /sys/bus/i2c/devices/i2c-57/new_device',
+
+# PSU-2
+'echo as5712_54x_psu2 0x3b > /sys/bus/i2c/devices/i2c-58/new_device',
+'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-58/new_device',
+'echo as5712_54x_psu2 0x53 > /sys/bus/i2c/devices/i2c-58/new_device',
+
+'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-61/new_device',
+'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-62/new_device',
+'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device',
+
+#EERPOM
+'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device',
+]
+
+mknod2 =[
+'echo as5712_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-1/new_device',
+'echo as5712_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-1/new_device',
+'echo as5712_54x_cpld3 0x62 > /sys/bus/i2c/devices/i2c-1/new_device',
+'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device',
+
+# PSU-1
+'echo as5712_54x_psu1 0x38 > /sys/bus/i2c/devices/i2c-57/new_device',
+'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-57/new_device',
+'echo as5712_54x_psu1 0x50 > /sys/bus/i2c/devices/i2c-57/new_device',
+
+# PSU-2
+'echo as5712_54x_psu2 0x3b > /sys/bus/i2c/devices/i2c-58/new_device',
+'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-58/new_device',
+'echo as5712_54x_psu2 0x53 > /sys/bus/i2c/devices/i2c-58/new_device',
+
+'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-61/new_device',
+'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-62/new_device',
+'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device',
+
+#EERPOM
+'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device',
+]
+
+FORCE = 0
+logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG)
+logging.basicConfig(level=logging.INFO)
+
+
+if DEBUG == True:
+ print sys.argv[0]
+ print 'ARGV :', sys.argv[1:]
+
+
+def main():
+ global DEBUG
+ global args
+ global FORCE
+
+ if len(sys.argv)<2:
+ show_help()
+
+ options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help',
+ 'debug',
+ 'force',
+ ])
+ if DEBUG == True:
+ print options
+ print args
+ print len(sys.argv)
+
+ for opt, arg in options:
+ if opt in ('-h', '--help'):
+ show_help()
+ elif opt in ('-d', '--debug'):
+ DEBUG = True
+ logging.basicConfig(level=logging.INFO)
+ elif opt in ('-f', '--force'):
+ FORCE = 1
+ else:
+ logging.info('no option')
+ for arg in args:
+ if arg == 'install':
+ do_install()
+ elif arg == 'clean':
+ do_uninstall()
+ elif arg == 'show':
+ device_traversal()
+ elif arg == 'sff':
+ if len(args)!=2:
+ show_eeprom_help()
+ elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']:
+ show_eeprom_help()
+ else:
+ show_eeprom(args[1])
+ return
+ elif arg == 'set':
+ if len(args)<3:
+ show_set_help()
+ else:
+ set_device(args[1:])
+ return
+ else:
+ show_help()
+
+
+ return 0
+
+def show_help():
+ print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
+ sys.exit(0)
+
+def show_set_help():
+ cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
+ print cmd +" [led|sfp|fan]"
+ print " use \""+ cmd + " led 0-4 \" to set led color"
+ print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
+ print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable"
+ sys.exit(0)
+
+def show_eeprom_help():
+ cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
+ print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom"
+ sys.exit(0)
+
+def my_log(txt):
+ if DEBUG == True:
+ print "[ACCTON DBG]: "+txt
+ return
+
+def log_os_system(cmd, show):
+ logging.info('Run :'+cmd)
+ status = 1
+ output = ""
+ status, output = commands.getstatusoutput(cmd)
+ my_log (cmd +"with result:" + str(status))
+ my_log ("cmd:" + cmd)
+ my_log (" output:"+output)
+ if status:
+ logging.info('Failed :'+cmd)
+ if show:
+ print('Failed :'+cmd)
+ return status, output
+
+def driver_inserted():
+ ret, lsmod = log_os_system("lsmod| grep accton", 0)
+ logging.info('mods:'+lsmod)
+ if len(lsmod) ==0:
+ return False
+
+
+
+kos = [
+'depmod -ae',
+'modprobe i2c_dev',
+'modprobe i2c_mux_pca954x',
+'modprobe optoe',
+'modprobe i2c-mux-accton_as5712_54x_cpld',
+'modprobe cpr_4011_4mxx',
+'modprobe ym2651y',
+'modprobe accton_as5712_54x_fan',
+'modprobe leds-accton_as5712_54x',
+'modprobe accton_as5712_54x_psu']
+
+def driver_install():
+ global FORCE
+ for i in range(0,len(kos)):
+ status, output = log_os_system(kos[i], 1)
+ if status:
+ if FORCE == 0:
+ return status
+ return 0
+
+def driver_uninstall():
+ global FORCE
+ for i in range(0,len(kos)):
+ rm = kos[-(i+1)].replace("modprobe", "modprobe -rq")
+ rm = rm.replace("insmod", "rmmod")
+ status, output = log_os_system(rm, 1)
+ if status:
+ if FORCE == 0:
+ return status
+ return 0
+
+
+
+def i2c_order_check():
+ # i2c bus 0 and 1 might be installed in different order.
+ # Here check if 0x70 is exist @ i2c-0
+ tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device"
+ status, output = log_os_system(tmp, 0)
+ if not device_exist():
+ order = 1
+ else:
+ order = 0
+ tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device"
+ status, output = log_os_system(tmp, 0)
+ return order
+
+def device_install():
+ global FORCE
+
+ order = i2c_order_check()
+ # if 0x76 is not exist @i2c-0, use reversed bus order
+ if order:
+ for i in range(0,len(mknod2)):
+ #for pca954x need times to built new i2c buses
+ if mknod2[i].find('pca954') != -1:
+ time.sleep(2)
+
+ status, output = log_os_system(mknod2[i], 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+ else:
+ for i in range(0,len(mknod)):
+ #for pca954x need times to built new i2c buses
+ if mknod[i].find('pca954') != -1:
+ time.sleep(2)
+
+ status, output = log_os_system(mknod[i], 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+
+ for i in range(0,len(sfp_map)):
+ status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+ status, output =log_os_system("echo port"+str(i)+" > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+
+ return
+
+def device_uninstall():
+ global FORCE
+
+ status, output =log_os_system("ls /sys/bus/i2c/devices/0-0070", 0)
+ if status==0:
+ I2C_ORDER=1
+ else:
+ I2C_ORDER=0
+
+ for i in range(0,len(sfp_map)):
+ target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
+ status, output =log_os_system("echo 0x50 > "+ target, 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+
+ if I2C_ORDER==0:
+ nodelist = mknod
+ else:
+ nodelist = mknod2
+
+ for i in range(len(nodelist)):
+ target = nodelist[-(i+1)]
+ temp = target.split()
+ del temp[1]
+ temp[-1] = temp[-1].replace('new_device', 'delete_device')
+ status, output = log_os_system(" ".join(temp), 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+
+ return
+
+def system_ready():
+ if driver_inserted() == False:
+ return False
+ if not device_exist():
+ return False
+ return True
+
+def do_install():
+ print "Checking system...."
+ if driver_inserted() == False:
+ print "No driver, installing...."
+ status = driver_install()
+ if status:
+ if FORCE == 0:
+ return status
+ else:
+ print PROJECT_NAME.upper()+" drivers detected...."
+ if not device_exist():
+ print "No device, installing...."
+ status = device_install()
+ if status:
+ if FORCE == 0:
+ return status
+ else:
+ print PROJECT_NAME.upper()+" devices detected...."
+ return
+
+def do_uninstall():
+ print "Checking system...."
+ if not device_exist():
+ print PROJECT_NAME.upper() +" has no device installed...."
+ else:
+ print "Removing device...."
+ status = device_uninstall()
+ if status:
+ if FORCE == 0:
+ return status
+
+ if driver_inserted()== False :
+ print PROJECT_NAME.upper() +" has no driver installed...."
+ else:
+ print "Removing installed driver...."
+ status = driver_uninstall()
+ if status:
+ if FORCE == 0:
+ return status
+
+ return
+
+def devices_info():
+ global DEVICE_NO
+ global ALL_DEVICE
+ global i2c_bus, hwmon_types
+ for key in DEVICE_NO:
+ ALL_DEVICE[key]= {}
+ for i in range(0,DEVICE_NO[key]):
+ ALL_DEVICE[key][key+str(i+1)] = []
+
+ for key in i2c_bus:
+ buses = i2c_bus[key]
+ nodes = i2c_nodes[key]
+ for i in range(0,len(buses)):
+ for j in range(0,len(nodes)):
+ if 'fan' == key:
+ for k in range(0,DEVICE_NO[key]):
+ node = key+str(k+1)
+ path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j]
+ my_log(node+": "+ path)
+ ALL_DEVICE[key][node].append(path)
+ elif 'sfp' == key:
+ for k in range(0,DEVICE_NO[key]):
+ node = key+str(k+1)
+ path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
+ my_log(node+": "+ path)
+ ALL_DEVICE[key][node].append(path)
+ else:
+ node = key+str(i+1)
+ path = i2c_prefix+ buses[i]+"/"+ nodes[j]
+ my_log(node+": "+ path)
+ ALL_DEVICE[key][node].append(path)
+
+ for key in hwmon_types:
+ itypes = hwmon_types[key]
+ nodes = hwmon_nodes[key]
+ for i in range(0,len(itypes)):
+ for j in range(0,len(nodes)):
+ node = key+"_"+itypes[i]
+ path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
+ my_log(node+": "+ path)
+ ALL_DEVICE[key][ key+str(i+1)].append(path)
+
+ #show dict all in the order
+ if DEBUG == True:
+ for i in sorted(ALL_DEVICE.keys()):
+ print(i+": ")
+ for j in sorted(ALL_DEVICE[i].keys()):
+ print(" "+j)
+ for k in (ALL_DEVICE[i][j]):
+ print(" "+" "+k)
+ return
+
+def show_eeprom(index):
+ if system_ready()==False:
+ print("System's not ready.")
+ print("Please install first!")
+ return
+
+ if len(ALL_DEVICE)==0:
+ devices_info()
+ node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
+ node = node.replace(node.split("/")[-1], 'sfp_eeprom')
+ # check if got hexdump command in current environment
+ ret, log = log_os_system("which hexdump", 0)
+ ret, log2 = log_os_system("which busybox hexdump", 0)
+ if len(log):
+ hex_cmd = 'hexdump'
+ elif len(log2):
+ hex_cmd = ' busybox hexdump'
+ else:
+ log = 'Failed : no hexdump cmd!!'
+ logging.info(log)
+ print log
+ return 1
+
+ print node + ":"
+ ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
+ if ret==0:
+ print log
+ else:
+ print "**********device no found**********"
+ return
+
+def set_device(args):
+ global DEVICE_NO
+ global ALL_DEVICE
+ if system_ready()==False:
+ print("System's not ready.")
+ print("Please install first!")
+ return
+
+ if len(ALL_DEVICE)==0:
+ devices_info()
+
+ if args[0]=='led':
+ if int(args[1])>4:
+ show_set_help()
+ return
+ #print ALL_DEVICE['led']
+ for i in range(0,len(ALL_DEVICE['led'])):
+ for k in (ALL_DEVICE['led']['led'+str(i+1)]):
+ ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
+ if ret:
+ return ret
+ elif args[0]=='fan':
+ if int(args[1])>100:
+ show_set_help()
+ return
+ #print ALL_DEVICE['fan']
+ #fan1~6 is all fine, all fan share same setting
+ node = ALL_DEVICE['fan1'] ['fan11'][0]
+ node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage')
+ ret, log = log_os_system("cat "+ node, 1)
+ if ret==0:
+ print ("Previous fan duty: " + log.strip() +"%")
+ ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
+ if ret==0:
+ print ("Current fan duty: " + args[1] +"%")
+ return ret
+ elif args[0]=='sfp':
+ if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
+ show_set_help()
+ return
+ if len(args)<2:
+ show_set_help()
+ return
+
+ if int(args[2])>1:
+ show_set_help()
+ return
+
+ #print ALL_DEVICE[args[0]]
+ for i in range(0,len(ALL_DEVICE[args[0]])):
+ for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
+ if j.find('tx_disable')!= -1:
+ ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
+ if ret:
+ return ret
+
+ return
+
+#get digits inside a string.
+#Ex: 31 for "sfp31"
+def get_value(input):
+ digit = re.findall('\d+', input)
+ return int(digit[0])
+
+def device_traversal():
+ if system_ready()==False:
+ print("System's not ready.")
+ print("Please install first!")
+ return
+
+ if len(ALL_DEVICE)==0:
+ devices_info()
+ for i in sorted(ALL_DEVICE.keys()):
+ print("============================================")
+ print(i.upper()+": ")
+ print("============================================")
+
+ for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
+ print " "+j+":",
+ for k in (ALL_DEVICE[i][j]):
+ ret, log = log_os_system("cat "+k, 0)
+ func = k.split("/")[-1].strip()
+ func = re.sub(j+'_','',func,1)
+ func = re.sub(i.lower()+'_','',func,1)
+ if ret==0:
+ print func+"="+log+" ",
+ else:
+ print func+"="+"X"+" ",
+ print
+ print("----------------------------------------------------------------")
+
+
+ print
+ return
+
+def device_exist():
+ ret1, log = log_os_system("ls "+i2c_prefix+"*0070", 0)
+ ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0)
+ return not(ret1 or ret2)
+
+if __name__ == "__main__":
+ main()
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile
new file mode 100644
index 00000000000..697dcff656c
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile
@@ -0,0 +1,4 @@
+obj-m:=accton_i2c_cpld.o x86-64-accton-as5812-54t-fan.o \
+ x86-64-accton-as5812-54t-leds.o x86-64-accton-as5812-54t-psu.o \
+ x86-64-accton-as5812-54t-sfp.o ym2651y.o
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c
new file mode 100644
index 00000000000..c01d6bcca22
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c
@@ -0,0 +1,330 @@
+/*
+ * A hwmon driver for the accton_i2c_cpld
+ *
+ * Copyright (C) 2013 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+static LIST_HEAD(cpld_client_list);
+static struct mutex list_lock;
+
+struct cpld_client_node {
+ struct i2c_client *client;
+ struct list_head list;
+};
+
+/* Addresses scanned for accton_i2c_cpld
+ */
+static const unsigned short normal_i2c[] = { 0x31, 0x35, 0x60, 0x61, 0x62, 0x64, I2C_CLIENT_END };
+
+static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int val = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+
+ val = i2c_smbus_read_byte_data(client, 0x1);
+
+ if (val < 0) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val);
+ }
+
+ return sprintf(buf, "%d", val);
+}
+
+static struct device_attribute ver = __ATTR(version, 0600, show_cpld_version, NULL);
+
+static void accton_i2c_cpld_add_client(struct i2c_client *client)
+{
+ struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL);
+
+ if (!node) {
+ dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr);
+ return;
+ }
+
+ node->client = client;
+
+ mutex_lock(&list_lock);
+ list_add(&node->list, &cpld_client_list);
+ mutex_unlock(&list_lock);
+}
+
+static void accton_i2c_cpld_remove_client(struct i2c_client *client)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int found = 0;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client == client) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ list_del(list_node);
+ kfree(cpld_node);
+ }
+
+ mutex_unlock(&list_lock);
+}
+
+static int accton_i2c_cpld_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ int status;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr);
+ status = -EIO;
+ goto exit;
+ }
+
+ status = sysfs_create_file(&client->dev.kobj, &ver.attr);
+ if (status) {
+ goto exit;
+ }
+
+ dev_info(&client->dev, "chip found\n");
+ accton_i2c_cpld_add_client(client);
+
+ return 0;
+
+exit:
+ return status;
+}
+
+static int accton_i2c_cpld_remove(struct i2c_client *client)
+{
+ sysfs_remove_file(&client->dev.kobj, &ver.attr);
+ accton_i2c_cpld_remove_client(client);
+
+ return 0;
+}
+
+static const struct i2c_device_id accton_i2c_cpld_id[] = {
+ { "accton_i2c_cpld", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, accton_i2c_cpld_id);
+
+static struct i2c_driver accton_i2c_cpld_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "accton_i2c_cpld",
+ },
+ .probe = accton_i2c_cpld_probe,
+ .remove = accton_i2c_cpld_remove,
+ .id_table = accton_i2c_cpld_id,
+ .address_list = normal_i2c,
+};
+
+int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int ret = -EPERM;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client->addr == cpld_addr) {
+ ret = i2c_smbus_read_byte_data(cpld_node->client, reg);
+ break;
+ }
+ }
+
+ mutex_unlock(&list_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(accton_i2c_cpld_read);
+
+int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int ret = -EIO;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client->addr == cpld_addr) {
+ ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value);
+ break;
+ }
+ }
+
+ mutex_unlock(&list_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(accton_i2c_cpld_write);
+
+static int __init accton_i2c_cpld_init(void)
+{
+ mutex_init(&list_lock);
+ return i2c_add_driver(&accton_i2c_cpld_driver);
+}
+
+static void __exit accton_i2c_cpld_exit(void)
+{
+ i2c_del_driver(&accton_i2c_cpld_driver);
+}
+
+static struct dmi_system_id as7512_dmi_table[] = {
+ {
+ .ident = "Accton AS7512",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS7512"),
+ },
+ },
+ {
+ .ident = "Accton AS7512",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS7512"),
+ },
+ },
+};
+
+int platform_accton_as7512_32x(void)
+{
+ return dmi_check_system(as7512_dmi_table);
+}
+EXPORT_SYMBOL(platform_accton_as7512_32x);
+
+static struct dmi_system_id as7712_dmi_table[] = {
+ {
+ .ident = "Accton AS7712",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"),
+ },
+ },
+ {
+ .ident = "Accton AS7712",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"),
+ },
+ },
+};
+
+int platform_accton_as7712_32x(void)
+{
+ return dmi_check_system(as7712_dmi_table);
+}
+EXPORT_SYMBOL(platform_accton_as7712_32x);
+
+static struct dmi_system_id as5812_54t_dmi_table[] = {
+ {
+ .ident = "Accton AS5812 54t",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS5812-54T"),
+ },
+ },
+ {
+ .ident = "Accton AS5812 54t",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS5812-54T"),
+ },
+ },
+};
+
+int platform_accton_as5812_54t(void)
+{
+ return dmi_check_system(as5812_54t_dmi_table);
+}
+EXPORT_SYMBOL(platform_accton_as5812_54t);
+
+static struct dmi_system_id as5512_54x_dmi_table[] = {
+ {
+ .ident = "Accton AS5512",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS5512"),
+ },
+ },
+ {
+ .ident = "Accton AS5512",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS5512"),
+ },
+ },
+};
+
+int platform_accton_as5512_54x(void)
+{
+ return dmi_check_system(as5512_54x_dmi_table);
+}
+EXPORT_SYMBOL(platform_accton_as5512_54x);
+
+static struct dmi_system_id as7716_dmi_table[] = {
+ {
+ .ident = "Accton AS7716",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS7716"),
+ },
+ },
+ {
+ .ident = "Accton AS7716",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Accton"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AS7716"),
+ },
+ },
+};
+
+int platform_accton_as7716_32x(void)
+{
+ return dmi_check_system(as7716_dmi_table);
+}
+EXPORT_SYMBOL(platform_accton_as7716_32x);
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton_i2c_cpld driver");
+MODULE_LICENSE("GPL");
+
+module_init(accton_i2c_cpld_init);
+module_exit(accton_i2c_cpld_exit);
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c
new file mode 100644
index 00000000000..bad9245e93a
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c
@@ -0,0 +1,442 @@
+/*
+ * A hwmon driver for the Accton as5812 54t fan
+ *
+ * Copyright (C) 2015 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define FAN_MAX_NUMBER 5
+#define FAN_SPEED_CPLD_TO_RPM_STEP 150
+#define FAN_SPEED_PRECENT_TO_CPLD_STEP 5
+#define FAN_DUTY_CYCLE_MIN 0
+#define FAN_DUTY_CYCLE_MAX 100 /* 100% */
+
+#define CPLD_REG_FAN_STATUS_OFFSET 0xC
+#define CPLD_REG_FANR_STATUS_OFFSET 0x1F
+#define CPLD_REG_FAN_DIRECTION_OFFSET 0x1E
+
+#define CPLD_FAN1_REG_SPEED_OFFSET 0x10
+#define CPLD_FAN2_REG_SPEED_OFFSET 0x11
+#define CPLD_FAN3_REG_SPEED_OFFSET 0x12
+#define CPLD_FAN4_REG_SPEED_OFFSET 0x13
+#define CPLD_FAN5_REG_SPEED_OFFSET 0x14
+
+#define CPLD_FANR1_REG_SPEED_OFFSET 0x18
+#define CPLD_FANR2_REG_SPEED_OFFSET 0x19
+#define CPLD_FANR3_REG_SPEED_OFFSET 0x1A
+#define CPLD_FANR4_REG_SPEED_OFFSET 0x1B
+#define CPLD_FANR5_REG_SPEED_OFFSET 0x1C
+
+#define CPLD_REG_FAN_PWM_CYCLE_OFFSET 0xD
+
+#define CPLD_FAN1_INFO_BIT_MASK 0x1
+#define CPLD_FAN2_INFO_BIT_MASK 0x2
+#define CPLD_FAN3_INFO_BIT_MASK 0x4
+#define CPLD_FAN4_INFO_BIT_MASK 0x8
+#define CPLD_FAN5_INFO_BIT_MASK 0x10
+
+#define PROJECT_NAME
+
+#define LOCAL_DEBUG 0
+
+static struct accton_as5812_54t_fan *fan_data = NULL;
+
+struct accton_as5812_54t_fan {
+ struct platform_device *pdev;
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* != 0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 status[FAN_MAX_NUMBER]; /* inner first fan status */
+ u32 speed[FAN_MAX_NUMBER]; /* inner first fan speed */
+ u8 direction[FAN_MAX_NUMBER]; /* reconrd the direction of inner first and second fans */
+ u32 duty_cycle[FAN_MAX_NUMBER]; /* control the speed of inner first and second fans */
+ u8 r_status[FAN_MAX_NUMBER]; /* inner second fan status */
+ u32 r_speed[FAN_MAX_NUMBER]; /* inner second fan speed */
+};
+
+/*******************/
+#define MAKE_FAN_MASK_OR_REG(name,type) \
+ CPLD_FAN##type##1_##name, \
+ CPLD_FAN##type##2_##name, \
+ CPLD_FAN##type##3_##name, \
+ CPLD_FAN##type##4_##name, \
+ CPLD_FAN##type##5_##name,
+
+/* fan related data
+ */
+static const u8 fan_info_mask[] = {
+ MAKE_FAN_MASK_OR_REG(INFO_BIT_MASK,)
+};
+
+static const u8 fan_speed_reg[] = {
+ MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,)
+};
+
+static const u8 fanr_speed_reg[] = {
+ MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,R)
+};
+
+/*******************/
+#define DEF_FAN_SET(id) \
+ FAN##id##_FAULT, \
+ FAN##id##_SPEED, \
+ FAN##id##_DUTY_CYCLE, \
+ FAN##id##_DIRECTION, \
+ FANR##id##_FAULT, \
+ FANR##id##_SPEED,
+
+enum sysfs_fan_attributes {
+ DEF_FAN_SET(1)
+ DEF_FAN_SET(2)
+ DEF_FAN_SET(3)
+ DEF_FAN_SET(4)
+ DEF_FAN_SET(5)
+};
+/*******************/
+static void accton_as5812_54t_fan_update_device(struct device *dev);
+static int accton_as5812_54t_fan_read_value(u8 reg);
+static int accton_as5812_54t_fan_write_value(u8 reg, u8 value);
+
+static ssize_t fan_set_duty_cycle(struct device *dev,
+ struct device_attribute *da,const char *buf, size_t count);
+static ssize_t fan_show_value(struct device *dev,
+ struct device_attribute *da, char *buf);
+
+extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
+extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+
+
+/*******************/
+#define _MAKE_SENSOR_DEVICE_ATTR(prj, id) \
+ static SENSOR_DEVICE_ATTR(prj##fan##id##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); \
+ static SENSOR_DEVICE_ATTR(prj##fan##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \
+ static SENSOR_DEVICE_ATTR(prj##fan##id##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, \
+ fan_set_duty_cycle, FAN##id##_DUTY_CYCLE); \
+ static SENSOR_DEVICE_ATTR(prj##fan##id##_direction, S_IRUGO, fan_show_value, NULL, FAN##id##_DIRECTION); \
+ static SENSOR_DEVICE_ATTR(prj##fanr##id##_fault, S_IRUGO, fan_show_value, NULL, FANR##id##_FAULT); \
+ static SENSOR_DEVICE_ATTR(prj##fanr##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED);
+
+#define MAKE_SENSOR_DEVICE_ATTR(prj,id) _MAKE_SENSOR_DEVICE_ATTR(prj,id)
+
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 1)
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 2)
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 3)
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 4)
+MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 5)
+/*******************/
+
+#define _MAKE_FAN_ATTR(prj, id) \
+ &sensor_dev_attr_##prj##fan##id##_fault.dev_attr.attr, \
+ &sensor_dev_attr_##prj##fan##id##_speed_rpm.dev_attr.attr, \
+ &sensor_dev_attr_##prj##fan##id##_duty_cycle_percentage.dev_attr.attr,\
+ &sensor_dev_attr_##prj##fan##id##_direction.dev_attr.attr, \
+ &sensor_dev_attr_##prj##fanr##id##_fault.dev_attr.attr, \
+ &sensor_dev_attr_##prj##fanr##id##_speed_rpm.dev_attr.attr,
+
+#define MAKE_FAN_ATTR(prj, id) _MAKE_FAN_ATTR(prj, id)
+
+static struct attribute *accton_as5812_54t_fan_attributes[] = {
+ /* fan related attributes */
+ MAKE_FAN_ATTR(PROJECT_NAME,1)
+ MAKE_FAN_ATTR(PROJECT_NAME,2)
+ MAKE_FAN_ATTR(PROJECT_NAME,3)
+ MAKE_FAN_ATTR(PROJECT_NAME,4)
+ MAKE_FAN_ATTR(PROJECT_NAME,5)
+ NULL
+};
+/*******************/
+
+/* fan related functions
+ */
+static ssize_t fan_show_value(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ ssize_t ret = 0;
+ int data_index, type_index;
+
+ accton_as5812_54t_fan_update_device(dev);
+
+ if (fan_data->valid == 0) {
+ return ret;
+ }
+
+ type_index = attr->index%FAN2_FAULT;
+ data_index = attr->index/FAN2_FAULT;
+
+ switch (type_index) {
+ case FAN1_FAULT:
+ ret = sprintf(buf, "%d\n", fan_data->status[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FAN1_SPEED:
+ ret = sprintf(buf, "%d\n", fan_data->speed[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FAN1_DUTY_CYCLE:
+ ret = sprintf(buf, "%d\n", fan_data->duty_cycle[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FAN1_DIRECTION:
+ ret = sprintf(buf, "%d\n", fan_data->direction[data_index]); /* presnet, need to modify*/
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FANR1_FAULT:
+ ret = sprintf(buf, "%d\n", fan_data->r_status[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ case FANR1_SPEED:
+ ret = sprintf(buf, "%d\n", fan_data->r_speed[data_index]);
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index);
+ break;
+ default:
+ if (LOCAL_DEBUG)
+ printk ("[Check !!][%s][%d] \n", __FUNCTION__, __LINE__);
+ break;
+ }
+
+ return ret;
+}
+/*******************/
+static ssize_t fan_set_duty_cycle(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count) {
+
+ int error, value;
+
+ error = kstrtoint(buf, 10, &value);
+ if (error)
+ return error;
+
+ if (value < FAN_DUTY_CYCLE_MIN || value > FAN_DUTY_CYCLE_MAX)
+ return -EINVAL;
+
+ accton_as5812_54t_fan_write_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET, value/FAN_SPEED_PRECENT_TO_CPLD_STEP);
+
+ fan_data->valid = 0;
+
+ return count;
+}
+
+static const struct attribute_group accton_as5812_54t_fan_group = {
+ .attrs = accton_as5812_54t_fan_attributes,
+};
+
+static int accton_as5812_54t_fan_read_value(u8 reg)
+{
+ return accton_i2c_cpld_read(0x60, reg);
+}
+
+static int accton_as5812_54t_fan_write_value(u8 reg, u8 value)
+{
+ return accton_i2c_cpld_write(0x60, reg, value);
+}
+
+static void accton_as5812_54t_fan_update_device(struct device *dev)
+{
+ int speed, r_speed, fault, r_fault, ctrl_speed, direction;
+ int i;
+
+ mutex_lock(&fan_data->update_lock);
+
+ if (LOCAL_DEBUG)
+ printk ("Starting accton_as5812_54t_fan update \n");
+
+ if (!(time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) || !fan_data->valid)) {
+ /* do nothing */
+ goto _exit;
+ }
+
+ fan_data->valid = 0;
+
+ if (LOCAL_DEBUG)
+ printk ("Starting accton_as5812_54t_fan update 2 \n");
+
+ fault = accton_as5812_54t_fan_read_value(CPLD_REG_FAN_STATUS_OFFSET);
+ r_fault = accton_as5812_54t_fan_read_value(CPLD_REG_FANR_STATUS_OFFSET);
+ direction = accton_as5812_54t_fan_read_value(CPLD_REG_FAN_DIRECTION_OFFSET);
+ ctrl_speed = accton_as5812_54t_fan_read_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET);
+
+ if ( (fault < 0) || (r_fault < 0) || (direction < 0) || (ctrl_speed < 0) )
+ {
+ if (LOCAL_DEBUG)
+ printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__);
+ goto _exit; /* error */
+ }
+
+ if (LOCAL_DEBUG)
+ printk ("[fan:] fault:%d, r_fault=%d, direction=%d, ctrl_speed=%d \n",fault, r_fault, direction, ctrl_speed);
+
+ for (i=0; istatus[i] = (fault & fan_info_mask[i]) >> i;
+ if (LOCAL_DEBUG)
+ printk ("[fan%d:] fail=%d \n",i, fan_data->status[i]);
+
+ fan_data->r_status[i] = (r_fault & fan_info_mask[i]) >> i;
+ fan_data->direction[i] = (direction & fan_info_mask[i]) >> i;
+ fan_data->duty_cycle[i] = ctrl_speed * FAN_SPEED_PRECENT_TO_CPLD_STEP;
+
+ /* fan speed
+ */
+ speed = accton_as5812_54t_fan_read_value(fan_speed_reg[i]);
+ r_speed = accton_as5812_54t_fan_read_value(fanr_speed_reg[i]);
+ if ( (speed < 0) || (r_speed < 0) )
+ {
+ if (LOCAL_DEBUG)
+ printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__);
+ goto _exit; /* error */
+ }
+
+ if (LOCAL_DEBUG)
+ printk ("[fan%d:] speed:%d, r_speed=%d \n", i, speed, r_speed);
+
+ fan_data->speed[i] = speed * FAN_SPEED_CPLD_TO_RPM_STEP;
+ fan_data->r_speed[i] = r_speed * FAN_SPEED_CPLD_TO_RPM_STEP;
+ }
+
+ /* finish to update */
+ fan_data->last_updated = jiffies;
+ fan_data->valid = 1;
+
+_exit:
+ mutex_unlock(&fan_data->update_lock);
+}
+
+static int accton_as5812_54t_fan_probe(struct platform_device *pdev)
+{
+ int status = -1;
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&pdev->dev.kobj, &accton_as5812_54t_fan_group);
+ if (status) {
+ goto exit;
+
+ }
+
+ fan_data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(fan_data->hwmon_dev)) {
+ status = PTR_ERR(fan_data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&pdev->dev, "accton_as5812_54t_fan\n");
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&pdev->dev.kobj, &accton_as5812_54t_fan_group);
+exit:
+ return status;
+}
+
+static int accton_as5812_54t_fan_remove(struct platform_device *pdev)
+{
+ hwmon_device_unregister(fan_data->hwmon_dev);
+ sysfs_remove_group(&fan_data->pdev->dev.kobj, &accton_as5812_54t_fan_group);
+
+ return 0;
+}
+
+#define DRVNAME "as5812_54t_fan"
+
+static struct platform_driver accton_as5812_54t_fan_driver = {
+ .probe = accton_as5812_54t_fan_probe,
+ .remove = accton_as5812_54t_fan_remove,
+ .driver = {
+ .name = DRVNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init accton_as5812_54t_fan_init(void)
+{
+ int ret;
+
+ extern int platform_accton_as5812_54t(void);
+ if (!platform_accton_as5812_54t()) {
+ return -ENODEV;
+ }
+
+ ret = platform_driver_register(&accton_as5812_54t_fan_driver);
+ if (ret < 0) {
+ goto exit;
+ }
+
+ fan_data = kzalloc(sizeof(struct accton_as5812_54t_fan), GFP_KERNEL);
+ if (!fan_data) {
+ ret = -ENOMEM;
+ platform_driver_unregister(&accton_as5812_54t_fan_driver);
+ goto exit;
+ }
+
+ mutex_init(&fan_data->update_lock);
+ fan_data->valid = 0;
+
+ fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
+ if (IS_ERR(fan_data->pdev)) {
+ ret = PTR_ERR(fan_data->pdev);
+ platform_driver_unregister(&accton_as5812_54t_fan_driver);
+ kfree(fan_data);
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+static void __exit accton_as5812_54t_fan_exit(void)
+{
+ platform_device_unregister(fan_data->pdev);
+ platform_driver_unregister(&accton_as5812_54t_fan_driver);
+ kfree(fan_data);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton_as5812_54t_fan driver");
+MODULE_LICENSE("GPL");
+
+module_init(accton_as5812_54t_fan_init);
+module_exit(accton_as5812_54t_fan_exit);
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c
new file mode 100644
index 00000000000..011f62e76c0
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c
@@ -0,0 +1,601 @@
+/*
+ * A LED driver for the accton_as5812_54t_led
+ *
+ * Copyright (C) 2015 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*#define DEBUG*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
+extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+
+extern void led_classdev_unregister(struct led_classdev *led_cdev);
+extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
+extern void led_classdev_resume(struct led_classdev *led_cdev);
+extern void led_classdev_suspend(struct led_classdev *led_cdev);
+
+#define DRVNAME "as5812_54t_led"
+
+struct accton_as5812_54t_led_data {
+ struct platform_device *pdev;
+ struct mutex update_lock;
+ char valid; /* != 0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 reg_val[4]; /* Register value, 0 = LOC/DIAG/FAN LED
+ 1 = PSU1/PSU2 LED
+ 2 = FAN1-4 LED
+ 3 = FAN5-6 LED */
+};
+
+static struct accton_as5812_54t_led_data *ledctl = NULL;
+
+/* LED related data
+ */
+#define LED_TYPE_PSU1_REG_MASK 0x03
+#define LED_MODE_PSU1_GREEN_MASK 0x02
+#define LED_MODE_PSU1_AMBER_MASK 0x01
+#define LED_MODE_PSU1_OFF_MASK 0x03
+#define LED_MODE_PSU1_AUTO_MASK 0x00
+
+#define LED_TYPE_PSU2_REG_MASK 0x0C
+#define LED_MODE_PSU2_GREEN_MASK 0x08
+#define LED_MODE_PSU2_AMBER_MASK 0x04
+#define LED_MODE_PSU2_OFF_MASK 0x0C
+#define LED_MODE_PSU2_AUTO_MASK 0x00
+
+#define LED_TYPE_DIAG_REG_MASK 0x0C
+#define LED_MODE_DIAG_GREEN_MASK 0x08
+#define LED_MODE_DIAG_AMBER_MASK 0x04
+#define LED_MODE_DIAG_OFF_MASK 0x0C
+
+#define LED_TYPE_FAN_REG_MASK 0x03
+#define LED_MODE_FAN_GREEN_MASK 0x02
+#define LED_MODE_FAN_AMBER_MASK 0x01
+#define LED_MODE_FAN_OFF_MASK 0x03
+#define LED_MODE_FAN_AUTO_MASK 0x00
+
+#define LED_TYPE_FAN1_REG_MASK 0x03
+#define LED_TYPE_FAN2_REG_MASK 0x0C
+#define LED_TYPE_FAN3_REG_MASK 0x30
+#define LED_TYPE_FAN4_REG_MASK 0xC0
+#define LED_TYPE_FAN5_REG_MASK 0x03
+#define LED_TYPE_FAN6_REG_MASK 0x0C
+
+#define LED_MODE_FANX_GREEN_MASK 0x01
+#define LED_MODE_FANX_RED_MASK 0x02
+#define LED_MODE_FANX_OFF_MASK 0x00
+
+#define LED_TYPE_LOC_REG_MASK 0x30
+#define LED_MODE_LOC_ON_MASK 0x00
+#define LED_MODE_LOC_OFF_MASK 0x10
+#define LED_MODE_LOC_BLINK_MASK 0x20
+
+static const u8 led_reg[] = {
+ 0xA, /* LOC/DIAG/FAN LED*/
+ 0xB, /* PSU1/PSU2 LED */
+ 0x16, /* FAN1-4 LED */
+ 0x17, /* FAN4-6 LED */
+};
+
+enum led_type {
+ LED_TYPE_PSU1,
+ LED_TYPE_PSU2,
+ LED_TYPE_DIAG,
+ LED_TYPE_FAN,
+ LED_TYPE_FAN1,
+ LED_TYPE_FAN2,
+ LED_TYPE_FAN3,
+ LED_TYPE_FAN4,
+ LED_TYPE_FAN5,
+ LED_TYPE_LOC
+};
+
+enum led_light_mode {
+ LED_MODE_OFF = 0,
+ LED_MODE_GREEN,
+ LED_MODE_GREEN_BLINK,
+ LED_MODE_AMBER,
+ LED_MODE_AMBER_BLINK,
+ LED_MODE_RED,
+ LED_MODE_RED_BLINK,
+ LED_MODE_BLUE,
+ LED_MODE_BLUE_BLINK,
+ LED_MODE_AUTO,
+ LED_MODE_UNKNOWN
+};
+
+struct led_type_mode {
+ enum led_type type;
+ int type_mask;
+ enum led_light_mode mode;
+ int mode_mask;
+};
+
+static struct led_type_mode led_type_mode_data[] = {
+{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK},
+{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK},
+{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU1_AUTO_MASK},
+{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK},
+{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK},
+{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK},
+{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU2_AUTO_MASK},
+{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK},
+{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK},
+{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK},
+{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AUTO, LED_MODE_FAN_AUTO_MASK},
+{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK},
+{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0},
+{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0},
+{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0},
+{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2},
+{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2},
+{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2},
+{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4},
+{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4},
+{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4},
+{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6},
+{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6},
+{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6},
+{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0},
+{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0},
+{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0},
+{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_GREEN, LED_MODE_DIAG_GREEN_MASK},
+{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_AMBER, LED_MODE_DIAG_AMBER_MASK},
+{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_OFF, LED_MODE_DIAG_OFF_MASK},
+{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER, LED_MODE_LOC_ON_MASK},
+{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_OFF, LED_MODE_LOC_OFF_MASK},
+{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER_BLINK, LED_MODE_LOC_BLINK_MASK}
+};
+
+
+struct fanx_info_s {
+ u8 cname; /* device name */
+ enum led_type type;
+ u8 reg_id; /* map to led_reg & reg_val */
+};
+
+static struct fanx_info_s fanx_info[] = {
+ {'1', LED_TYPE_FAN1, 2},
+ {'2', LED_TYPE_FAN2, 2},
+ {'3', LED_TYPE_FAN3, 2},
+ {'4', LED_TYPE_FAN4, 2},
+ {'5', LED_TYPE_FAN5, 3}
+};
+
+static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
+
+ if (type != led_type_mode_data[i].type)
+ continue;
+
+ if ((led_type_mode_data[i].type_mask & reg_val) ==
+ led_type_mode_data[i].mode_mask)
+ {
+ return led_type_mode_data[i].mode;
+ }
+ }
+
+ return LED_MODE_UNKNOWN;
+}
+
+static u8 led_light_mode_to_reg_val(enum led_type type,
+ enum led_light_mode mode, u8 reg_val) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
+ if (type != led_type_mode_data[i].type)
+ continue;
+
+ if (mode != led_type_mode_data[i].mode)
+ continue;
+
+ reg_val = led_type_mode_data[i].mode_mask |
+ (reg_val & (~led_type_mode_data[i].type_mask));
+ }
+
+ return reg_val;
+}
+
+static int accton_as5812_54t_led_read_value(u8 reg)
+{
+ return accton_i2c_cpld_read(0x60, reg);
+}
+
+static int accton_as5812_54t_led_write_value(u8 reg, u8 value)
+{
+ return accton_i2c_cpld_write(0x60, reg, value);
+}
+
+static void accton_as5812_54t_led_update(void)
+{
+ mutex_lock(&ledctl->update_lock);
+
+ if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2)
+ || !ledctl->valid) {
+ int i;
+
+ dev_dbg(&ledctl->pdev->dev, "Starting accton_as5812_54t_led update\n");
+
+ /* Update LED data
+ */
+ for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) {
+ int status = accton_as5812_54t_led_read_value(led_reg[i]);
+
+ if (status < 0) {
+ ledctl->valid = 0;
+ dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status);
+ goto exit;
+ }
+ else
+ {
+ ledctl->reg_val[i] = status;
+ }
+ }
+
+ ledctl->last_updated = jiffies;
+ ledctl->valid = 1;
+ }
+
+exit:
+ mutex_unlock(&ledctl->update_lock);
+}
+
+static void accton_as5812_54t_led_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode,
+ u8 reg, enum led_type type)
+{
+ int reg_val;
+
+ mutex_lock(&ledctl->update_lock);
+
+ reg_val = accton_as5812_54t_led_read_value(reg);
+
+ if (reg_val < 0) {
+ dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val);
+ goto exit;
+ }
+
+ reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val);
+ accton_as5812_54t_led_write_value(reg, reg_val);
+
+ /* to prevent the slow-update issue */
+ ledctl->valid = 0;
+
+exit:
+ mutex_unlock(&ledctl->update_lock);
+}
+
+static void accton_as5812_54t_led_psu_1_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1);
+}
+
+static enum led_brightness accton_as5812_54t_led_psu_1_get(struct led_classdev *cdev)
+{
+ accton_as5812_54t_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]);
+}
+
+static void accton_as5812_54t_led_psu_2_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2);
+}
+
+static enum led_brightness accton_as5812_54t_led_psu_2_get(struct led_classdev *cdev)
+{
+ accton_as5812_54t_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]);
+}
+
+static void accton_as5812_54t_led_fan_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_FAN);
+}
+
+static enum led_brightness accton_as5812_54t_led_fan_get(struct led_classdev *cdev)
+{
+ accton_as5812_54t_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[0]);
+}
+
+
+static void accton_as5812_54t_led_fanx_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ enum led_type led_type1;
+ int reg_id;
+ int i, nsize;
+ int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s);
+
+ for(i=0;iname);
+
+ if (led_cdev->name[nsize-1] == fanx_info[i].cname)
+ {
+ led_type1 = fanx_info[i].type;
+ reg_id = fanx_info[i].reg_id;
+ accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1);
+ return;
+ }
+ }
+}
+
+
+static enum led_brightness accton_as5812_54t_led_fanx_get(struct led_classdev *cdev)
+{
+ enum led_type led_type1;
+ int reg_id;
+ int i, nsize;
+ int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s);
+
+ for(i=0;iname);
+
+ if (cdev->name[nsize-1] == fanx_info[i].cname)
+ {
+ led_type1 = fanx_info[i].type;
+ reg_id = fanx_info[i].reg_id;
+ accton_as5812_54t_led_update();
+ return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]);
+ }
+ }
+
+
+ return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[2]);
+}
+
+
+static void accton_as5812_54t_led_diag_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_DIAG);
+}
+
+static enum led_brightness accton_as5812_54t_led_diag_get(struct led_classdev *cdev)
+{
+ accton_as5812_54t_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]);
+}
+
+static void accton_as5812_54t_led_loc_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_LOC);
+}
+
+static enum led_brightness accton_as5812_54t_led_loc_get(struct led_classdev *cdev)
+{
+ accton_as5812_54t_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]);
+}
+
+static struct led_classdev accton_as5812_54t_leds[] = {
+ [LED_TYPE_PSU1] = {
+ .name = "accton_as5812_54t_led::psu1",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_psu_1_set,
+ .brightness_get = accton_as5812_54t_led_psu_1_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_PSU2] = {
+ .name = "accton_as5812_54t_led::psu2",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_psu_2_set,
+ .brightness_get = accton_as5812_54t_led_psu_2_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN] = {
+ .name = "accton_as5812_54t_led::fan",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_fan_set,
+ .brightness_get = accton_as5812_54t_led_fan_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN1] = {
+ .name = "accton_as5812_54t_led::fan1",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_fanx_set,
+ .brightness_get = accton_as5812_54t_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN2] = {
+ .name = "accton_as5812_54t_led::fan2",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_fanx_set,
+ .brightness_get = accton_as5812_54t_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN3] = {
+ .name = "accton_as5812_54t_led::fan3",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_fanx_set,
+ .brightness_get = accton_as5812_54t_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN4] = {
+ .name = "accton_as5812_54t_led::fan4",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_fanx_set,
+ .brightness_get = accton_as5812_54t_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_FAN5] = {
+ .name = "accton_as5812_54t_led::fan5",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_fanx_set,
+ .brightness_get = accton_as5812_54t_led_fanx_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_DIAG] = {
+ .name = "accton_as5812_54t_led::diag",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_diag_set,
+ .brightness_get = accton_as5812_54t_led_diag_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_LOC] = {
+ .name = "accton_as5812_54t_led::loc",
+ .default_trigger = "unused",
+ .brightness_set = accton_as5812_54t_led_loc_set,
+ .brightness_get = accton_as5812_54t_led_loc_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+};
+
+static int accton_as5812_54t_led_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ int i = 0;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as5812_54t_leds); i++) {
+ led_classdev_suspend(&accton_as5812_54t_leds[i]);
+ }
+
+ return 0;
+}
+
+static int accton_as5812_54t_led_resume(struct platform_device *dev)
+{
+ int i = 0;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as5812_54t_leds); i++) {
+ led_classdev_resume(&accton_as5812_54t_leds[i]);
+ }
+
+ return 0;
+}
+
+static int accton_as5812_54t_led_probe(struct platform_device *pdev)
+{
+ int ret, i;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as5812_54t_leds); i++) {
+ ret = led_classdev_register(&pdev->dev, &accton_as5812_54t_leds[i]);
+
+ if (ret < 0)
+ break;
+ }
+
+ /* Check if all LEDs were successfully registered */
+ if (i != ARRAY_SIZE(accton_as5812_54t_leds)){
+ int j;
+
+ /* only unregister the LEDs that were successfully registered */
+ for (j = 0; j < i; j++) {
+ led_classdev_unregister(&accton_as5812_54t_leds[i]);
+ }
+ }
+
+ return ret;
+}
+
+static int accton_as5812_54t_led_remove(struct platform_device *pdev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as5812_54t_leds); i++) {
+ led_classdev_unregister(&accton_as5812_54t_leds[i]);
+ }
+
+ return 0;
+}
+
+static struct platform_driver accton_as5812_54t_led_driver = {
+ .probe = accton_as5812_54t_led_probe,
+ .remove = accton_as5812_54t_led_remove,
+ .suspend = accton_as5812_54t_led_suspend,
+ .resume = accton_as5812_54t_led_resume,
+ .driver = {
+ .name = DRVNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init accton_as5812_54t_led_init(void)
+{
+ int ret;
+
+ extern int platform_accton_as5812_54t(void);
+ if (!platform_accton_as5812_54t()) {
+ return -ENODEV;
+ }
+
+ ret = platform_driver_register(&accton_as5812_54t_led_driver);
+ if (ret < 0) {
+ goto exit;
+ }
+
+ ledctl = kzalloc(sizeof(struct accton_as5812_54t_led_data), GFP_KERNEL);
+ if (!ledctl) {
+ ret = -ENOMEM;
+ platform_driver_unregister(&accton_as5812_54t_led_driver);
+ goto exit;
+ }
+
+ mutex_init(&ledctl->update_lock);
+
+ ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
+ if (IS_ERR(ledctl->pdev)) {
+ ret = PTR_ERR(ledctl->pdev);
+ platform_driver_unregister(&accton_as5812_54t_led_driver);
+ kfree(ledctl);
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+static void __exit accton_as5812_54t_led_exit(void)
+{
+ platform_device_unregister(ledctl->pdev);
+ platform_driver_unregister(&accton_as5812_54t_led_driver);
+ kfree(ledctl);
+}
+
+module_init(accton_as5812_54t_led_init);
+module_exit(accton_as5812_54t_led_exit);
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton_as5812_54t_led driver");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c
new file mode 100644
index 00000000000..a77014e877c
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c
@@ -0,0 +1,372 @@
+/*
+ * An hwmon driver for accton as5812_54t Power Module
+ *
+ * Copyright (C) 2015 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#define PSU_STATUS_I2C_ADDR 0x60
+#define PSU_STATUS_I2C_REG_OFFSET 0x2
+
+#define IS_POWER_GOOD(id, value) (!!(value & BIT(id*4 + 1)))
+#define IS_PRESENT(id, value) (!(value & BIT(id*4)))
+
+static ssize_t show_index(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf);
+static int as5812_54t_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len);
+extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
+static int as5812_54t_psu_model_name_get(struct device *dev);
+
+/* Addresses scanned
+ */
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+/* Each client has this additional data
+ */
+struct as5812_54t_psu_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 index; /* PSU index */
+ u8 status; /* Status(present/power_good) register read from CPLD */
+ char model_name[14]; /* Model name, read from eeprom */
+};
+
+static struct as5812_54t_psu_data *as5812_54t_psu_update_device(struct device *dev);
+
+enum as5812_54t_psu_sysfs_attributes {
+ PSU_INDEX,
+ PSU_PRESENT,
+ PSU_MODEL_NAME,
+ PSU_POWER_GOOD
+};
+
+/* sysfs attributes for hwmon
+ */
+static SENSOR_DEVICE_ATTR(psu_index, S_IRUGO, show_index, NULL, PSU_INDEX);
+static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT);
+static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME);
+static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD);
+
+static struct attribute *as5812_54t_psu_attributes[] = {
+ &sensor_dev_attr_psu_index.dev_attr.attr,
+ &sensor_dev_attr_psu_present.dev_attr.attr,
+ &sensor_dev_attr_psu_model_name.dev_attr.attr,
+ &sensor_dev_attr_psu_power_good.dev_attr.attr,
+ NULL
+};
+
+static ssize_t show_index(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5812_54t_psu_data *data = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", data->index);
+}
+
+static ssize_t show_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct as5812_54t_psu_data *data = as5812_54t_psu_update_device(dev);
+ u8 status = 0;
+
+ if (!data->valid) {
+ return sprintf(buf, "0\n");
+ }
+
+ if (attr->index == PSU_PRESENT) {
+ status = IS_PRESENT(data->index, data->status);
+ }
+ else { /* PSU_POWER_GOOD */
+ status = IS_POWER_GOOD(data->index, data->status);
+ }
+
+ return sprintf(buf, "%d\n", status);
+}
+
+static ssize_t show_model_name(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct as5812_54t_psu_data *data = as5812_54t_psu_update_device(dev);
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ if (!IS_PRESENT(data->index, data->status)) {
+ return 0;
+ }
+
+ if (as5812_54t_psu_model_name_get(dev) < 0) {
+ return -ENXIO;
+ }
+
+ return sprintf(buf, "%s\n", data->model_name);
+}
+
+static const struct attribute_group as5812_54t_psu_group = {
+ .attrs = as5812_54t_psu_attributes,
+};
+
+static int as5812_54t_psu_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ struct as5812_54t_psu_data *data;
+ int status;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct as5812_54t_psu_data), GFP_KERNEL);
+ if (!data) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ data->valid = 0;
+ data->index = dev_id->driver_data;
+ mutex_init(&data->update_lock);
+
+ dev_info(&client->dev, "chip found\n");
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &as5812_54t_psu_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "%s: psu '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &as5812_54t_psu_group);
+exit_free:
+ kfree(data);
+exit:
+
+ return status;
+}
+
+static int as5812_54t_psu_remove(struct i2c_client *client)
+{
+ struct as5812_54t_psu_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &as5812_54t_psu_group);
+ kfree(data);
+
+ return 0;
+}
+
+enum psu_index
+{
+ as5812_54t_psu1,
+ as5812_54t_psu2
+};
+
+static const struct i2c_device_id as5812_54t_psu_id[] = {
+ { "as5812_54t_psu1", as5812_54t_psu1 },
+ { "as5812_54t_psu2", as5812_54t_psu2 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, as5812_54t_psu_id);
+
+static struct i2c_driver as5812_54t_psu_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "as5812_54t_psu",
+ },
+ .probe = as5812_54t_psu_probe,
+ .remove = as5812_54t_psu_remove,
+ .id_table = as5812_54t_psu_id,
+ .address_list = normal_i2c,
+};
+
+static int as5812_54t_psu_read_block(struct i2c_client *client, u8 command, u8 *data,
+ int data_len)
+{
+ int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
+
+ if (unlikely(result < 0))
+ goto abort;
+ if (unlikely(result != data_len)) {
+ result = -EIO;
+ goto abort;
+ }
+
+ result = 0;
+
+abort:
+ return result;
+}
+
+enum psu_type {
+ PSU_YM_2401_JCR, /* AC110V - F2B */
+ PSU_YM_2401_JDR, /* AC110V - B2F */
+ PSU_CPR_4011_4M11, /* AC110V - F2B */
+ PSU_CPR_4011_4M21, /* AC110V - B2F */
+ PSU_CPR_6011_2M11, /* AC110V - F2B */
+ PSU_CPR_6011_2M21, /* AC110V - B2F */
+ PSU_UM400D_01G, /* DC48V - F2B */
+ PSU_UM400D01_01G /* DC48V - B2F */
+};
+
+struct model_name_info {
+ enum psu_type type;
+ u8 offset;
+ u8 length;
+ char* model_name;
+};
+
+struct model_name_info models[] = {
+{PSU_YM_2401_JCR, 0x20, 11, "YM-2401JCR"},
+{PSU_YM_2401_JDR, 0x20, 11, "YM-2401JDR"},
+{PSU_CPR_4011_4M11, 0x26, 13, "CPR-4011-4M11"},
+{PSU_CPR_4011_4M21, 0x26, 13, "CPR-4011-4M21"},
+{PSU_CPR_6011_2M11, 0x26, 13, "CPR-6011-2M11"},
+{PSU_CPR_6011_2M21, 0x26, 13, "CPR-6011-2M21"},
+{PSU_UM400D_01G, 0x50, 9, "um400d01G"},
+{PSU_UM400D01_01G, 0x50, 12, "um400d01-01G"},
+};
+
+static int as5812_54t_psu_model_name_get(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5812_54t_psu_data *data = i2c_get_clientdata(client);
+ int i, status;
+
+ for (i = 0; i < ARRAY_SIZE(models); i++) {
+ memset(data->model_name, 0, sizeof(data->model_name));
+
+ status = as5812_54t_psu_read_block(client, models[i].offset,
+ data->model_name, models[i].length);
+ if (status < 0) {
+ data->model_name[0] = '\0';
+ dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n",
+ client->addr, models[i].offset);
+ return status;
+ }
+ else {
+ data->model_name[models[i].length] = '\0';
+ }
+
+ if (i == PSU_YM_2401_JCR || i == PSU_YM_2401_JDR) {
+ /* Skip the meaningless data byte 8*/
+ data->model_name[8] = data->model_name[9];
+ data->model_name[9] = data->model_name[10];
+ data->model_name[10] = '\0';
+ }
+
+ /* Determine if the model name is known, if not, read next index
+ */
+ if (strncmp(data->model_name, models[i].model_name, models[i].length) == 0) {
+ return 0;
+ }
+ else {
+ data->model_name[0] = '\0';
+ }
+ }
+
+ return -ENODATA;
+}
+
+static struct as5812_54t_psu_data *as5812_54t_psu_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5812_54t_psu_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int status = -1;
+
+ dev_dbg(&client->dev, "Starting as5812_54t update\n");
+ data->valid = 0;
+
+ /* Read psu status */
+ status = accton_i2c_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status);
+ goto exit;
+ }
+ else {
+ data->status = status;
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+exit:
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init as5812_54t_psu_init(void)
+{
+ extern int platform_accton_as5812_54t(void);
+ if (!platform_accton_as5812_54t()) {
+ return -ENODEV;
+ }
+
+ return i2c_add_driver(&as5812_54t_psu_driver);
+}
+
+static void __exit as5812_54t_psu_exit(void)
+{
+ i2c_del_driver(&as5812_54t_psu_driver);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton as5812_54t_psu driver");
+MODULE_LICENSE("GPL");
+
+module_init(as5812_54t_psu_init);
+module_exit(as5812_54t_psu_exit);
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c
new file mode 100644
index 00000000000..88bf552de0f
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c
@@ -0,0 +1,318 @@
+/*
+ * An hwmon driver for accton as5812_54t sfp
+ *
+ * Copyright (C) 2015 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define QSFP_PORT_START_INDEX 49
+#define BIT_INDEX(i) (1ULL << (i))
+
+/* Addresses scanned
+ */
+static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
+
+/* Each client has this additional data
+ */
+struct as5812_54t_sfp_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ int port; /* Front port index */
+ char eeprom[256]; /* eeprom data */
+ u8 status; /* bit0:port49, bit1:port50 and so on */
+};
+
+static struct as5812_54t_sfp_data *as5812_54t_sfp_update_device(struct device *dev, int update_eeprom);
+static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf);
+extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
+extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+
+enum as5812_54t_sfp_sysfs_attributes {
+ SFP_IS_PRESENT,
+ SFP_PORT_NUMBER,
+ SFP_EEPROM,
+ SFP_IS_PRESENT_ALL,
+};
+
+/* sysfs attributes for hwmon
+ */
+static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_status, NULL, SFP_IS_PRESENT);
+static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER);
+static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM);
+static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_status,NULL, SFP_IS_PRESENT_ALL);
+
+static struct attribute *as5812_54t_sfp_attributes[] = {
+ &sensor_dev_attr_sfp_is_present.dev_attr.attr,
+ &sensor_dev_attr_sfp_eeprom.dev_attr.attr,
+ &sensor_dev_attr_sfp_port_number.dev_attr.attr,
+ &sensor_dev_attr_sfp_is_present_all.dev_attr.attr,
+ NULL
+};
+
+static ssize_t show_port_number(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5812_54t_sfp_data *data = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n",data->port);
+}
+
+static ssize_t show_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct as5812_54t_sfp_data *data = as5812_54t_sfp_update_device(dev, 0);
+
+ if (attr->index == SFP_IS_PRESENT) {
+ u8 val;
+
+ val = (data->status & BIT_INDEX(data->port - QSFP_PORT_START_INDEX)) ? 0 : 1;
+ return sprintf(buf, "%d", val);
+ }
+ else { /* SFP_IS_PRESENT_ALL */
+ return sprintf(buf, "%.2x\n", ~data->status);
+ }
+}
+
+static ssize_t show_eeprom(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct as5812_54t_sfp_data *data = as5812_54t_sfp_update_device(dev, 1);
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ if ((data->status & BIT_INDEX(data->port - QSFP_PORT_START_INDEX)) != 0) {
+ return 0;
+ }
+
+ memcpy(buf, data->eeprom, sizeof(data->eeprom));
+
+ return sizeof(data->eeprom);
+}
+
+static const struct attribute_group as5812_54t_sfp_group = {
+ .attrs = as5812_54t_sfp_attributes,
+};
+
+static int as5812_54t_sfp_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ struct as5812_54t_sfp_data *data;
+ int status;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct as5812_54t_sfp_data), GFP_KERNEL);
+ if (!data) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ mutex_init(&data->update_lock);
+ data->port = dev_id->driver_data;
+ i2c_set_clientdata(client, data);
+
+ dev_info(&client->dev, "chip found\n");
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &as5812_54t_sfp_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "%s: sfp '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &as5812_54t_sfp_group);
+exit_free:
+ kfree(data);
+exit:
+
+ return status;
+}
+
+static int as5812_54t_sfp_remove(struct i2c_client *client)
+{
+ struct as5812_54t_sfp_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &as5812_54t_sfp_group);
+ kfree(data);
+
+ return 0;
+}
+
+enum port_numbers {
+as5812_54t_qsfp49 = 49,
+as5812_54t_qsfp50,
+as5812_54t_qsfp51,
+as5812_54t_qsfp52,
+as5812_54t_qsfp53,
+as5812_54t_qsfp54
+};
+
+static const struct i2c_device_id as5812_54t_sfp_id[] = {
+{ "as5812_54t_qsfp49", as5812_54t_qsfp49 }, { "as5812_54t_qsfp50", as5812_54t_qsfp50 },
+{ "as5812_54t_qsfp51", as5812_54t_qsfp51 }, { "as5812_54t_qsfp52", as5812_54t_qsfp52 },
+{ "as5812_54t_qsfp53", as5812_54t_qsfp53 }, { "as5812_54t_qsfp54", as5812_54t_qsfp54 },
+{}
+};
+MODULE_DEVICE_TABLE(i2c, as5812_54t_sfp_id);
+
+static struct i2c_driver as5812_54t_sfp_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "as5812_54t_sfp",
+ },
+ .probe = as5812_54t_sfp_probe,
+ .remove = as5812_54t_sfp_remove,
+ .id_table = as5812_54t_sfp_id,
+ .address_list = normal_i2c,
+};
+
+static int as5812_54t_sfp_read_byte(struct i2c_client *client, u8 command, u8 *data)
+{
+ int result = i2c_smbus_read_byte_data(client, command);
+
+ if (unlikely(result < 0)) {
+ dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result);
+ goto abort;
+ }
+
+ *data = (u8)result;
+ result = 0;
+
+abort:
+ return result;
+}
+
+static struct as5812_54t_sfp_data *as5812_54t_sfp_update_device(struct device *dev, int update_eeprom)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as5812_54t_sfp_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid || update_eeprom) {
+ int status = -1;
+ int i = 0;
+
+ data->valid = 0;
+ //dev_dbg(&client->dev, "Starting as5812_54t sfp status update\n");
+ data->status = 0xFF;
+
+ /*
+ * Bring QSFPs out of reset,
+ * This is a temporary fix until the QSFP+_MOD_RST register
+ * can be exposed through the driver.
+ */
+ accton_i2c_cpld_write(0x60, 0x23, 0x3F);
+
+ /* Read present status of port 49-54(QSFP port) */
+ status = accton_i2c_cpld_read(0x60, 0x22);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld(0x60) reg(0x22) err %d\n", status);
+ }
+ else {
+ data->status = status & 0x3F; /* (u32)status */
+ }
+
+ if (update_eeprom) {
+ /* Read eeprom data based on port number */
+ memset(data->eeprom, 0, sizeof(data->eeprom));
+
+ /* Check if the port is present */
+ if ((data->status & BIT_INDEX(data->port - QSFP_PORT_START_INDEX)) == 0) {
+ /* read eeprom */
+ for (i = 0; i < sizeof(data->eeprom); i++) {
+ status = as5812_54t_sfp_read_byte(client, i, data->eeprom + i);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n",
+ data->port);
+ goto exit;
+ }
+ }
+ }
+ }
+
+ data->valid = 1;
+ data->last_updated = jiffies;
+ }
+
+exit:
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init as5812_54t_sfp_init(void)
+{
+ extern int platform_accton_as5812_54t(void);
+ if (!platform_accton_as5812_54t()) {
+ return -ENODEV;
+ }
+
+ return i2c_add_driver(&as5812_54t_sfp_driver);
+}
+
+static void __exit as5812_54t_sfp_exit(void)
+{
+ i2c_del_driver(&as5812_54t_sfp_driver);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton as5812_54t_sfp driver");
+MODULE_LICENSE("GPL");
+
+module_init(as5812_54t_sfp_init);
+module_exit(as5812_54t_sfp_exit);
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c
new file mode 100644
index 00000000000..7101aa411f7
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c
@@ -0,0 +1,680 @@
+/*
+ * An hwmon driver for the 3Y Power YM-2651Y Power Module
+ *
+ * Copyright (C) 2014 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define MAX_FAN_DUTY_CYCLE 100
+
+/* Addresses scanned
+ */
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+enum chips {
+ YM2651,
+ YM2401,
+};
+
+/* Each client has this additional data
+ */
+struct ym2651y_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 chip; /* chip id */
+ u8 capability; /* Register value */
+ u16 status_word; /* Register value */
+ u8 fan_fault; /* Register value */
+ u8 over_temp; /* Register value */
+ u16 v_out; /* Register value */
+ u16 i_out; /* Register value */
+ u16 p_out; /* Register value */
+ u8 vout_mode; /* Register value */
+ u16 temp; /* Register value */
+ u16 fan_speed; /* Register value */
+ u16 fan_duty_cycle[2]; /* Register value */
+ u8 fan_dir[5]; /* Register value */
+ u8 pmbus_revision; /* Register value */
+ u8 mfr_id[10]; /* Register value */
+ u8 mfr_model[16]; /* Register value */
+ u8 mfr_revsion[3]; /* Register value */
+ u16 mfr_vin_min; /* Register value */
+ u16 mfr_vin_max; /* Register value */
+ u16 mfr_iin_max; /* Register value */
+ u16 mfr_iout_max; /* Register value */
+ u16 mfr_pin_max; /* Register value */
+ u16 mfr_pout_max; /* Register value */
+ u16 mfr_vout_min; /* Register value */
+ u16 mfr_vout_max; /* Register value */
+};
+
+static ssize_t show_byte(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_word(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_linear(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_over_temp(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_ascii(struct device *dev, struct device_attribute *da,
+ char *buf);
+static struct ym2651y_data *ym2651y_update_device(struct device *dev);
+static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value);
+
+enum ym2651y_sysfs_attributes {
+ PSU_POWER_ON = 0,
+ PSU_TEMP_FAULT,
+ PSU_POWER_GOOD,
+ PSU_FAN1_FAULT,
+ PSU_FAN_DIRECTION,
+ PSU_OVER_TEMP,
+ PSU_V_OUT,
+ PSU_I_OUT,
+ PSU_P_OUT,
+ PSU_TEMP1_INPUT,
+ PSU_FAN1_SPEED,
+ PSU_FAN1_DUTY_CYCLE,
+ PSU_PMBUS_REVISION,
+ PSU_MFR_ID,
+ PSU_MFR_MODEL,
+ PSU_MFR_REVISION,
+ PSU_MFR_VIN_MIN,
+ PSU_MFR_VIN_MAX,
+ PSU_MFR_VOUT_MIN,
+ PSU_MFR_VOUT_MAX,
+ PSU_MFR_IIN_MAX,
+ PSU_MFR_IOUT_MAX,
+ PSU_MFR_PIN_MAX,
+ PSU_MFR_POUT_MAX
+};
+
+/* sysfs attributes for hwmon
+ */
+static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON);
+static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT);
+static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD);
+static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT);
+static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP);
+static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT);
+static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT);
+static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT);
+static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT);
+static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED);
+static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE);
+static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION);
+static SENSOR_DEVICE_ATTR(psu_pmbus_revision,S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION);
+static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID);
+static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL);
+static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION);
+static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN);
+static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN);
+static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX);
+static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX);
+
+static struct attribute *ym2651y_attributes[] = {
+ &sensor_dev_attr_psu_power_on.dev_attr.attr,
+ &sensor_dev_attr_psu_temp_fault.dev_attr.attr,
+ &sensor_dev_attr_psu_power_good.dev_attr.attr,
+ &sensor_dev_attr_psu_fan1_fault.dev_attr.attr,
+ &sensor_dev_attr_psu_over_temp.dev_attr.attr,
+ &sensor_dev_attr_psu_v_out.dev_attr.attr,
+ &sensor_dev_attr_psu_i_out.dev_attr.attr,
+ &sensor_dev_attr_psu_p_out.dev_attr.attr,
+ &sensor_dev_attr_psu_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr,
+ &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr,
+ &sensor_dev_attr_psu_fan_dir.dev_attr.attr,
+ &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_id.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_model.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_revision.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr,
+ &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr,
+ NULL
+};
+
+static ssize_t show_byte(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) :
+ sprintf(buf, "0\n");
+}
+
+static ssize_t show_word(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+ u16 status = 0;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ switch (attr->index) {
+ case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */
+ status = (data->status_word & 0x40) ? 0 : 1;
+ break;
+ case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */
+ status = (data->status_word & 0x4) >> 2;
+ break;
+ case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */
+ status = (data->status_word & 0x800) ? 0 : 1;
+ break;
+ }
+
+ return sprintf(buf, "%d\n", status);
+}
+
+static int two_complement_to_int(u16 data, u8 valid_bit, int mask)
+{
+ u16 valid_data = data & mask;
+ bool is_negative = valid_data >> (valid_bit - 1);
+
+ return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data;
+}
+
+static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ym2651y_data *data = i2c_get_clientdata(client);
+ int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1;
+ long speed;
+ int error;
+
+ error = kstrtol(buf, 10, &speed);
+ if (error)
+ return error;
+
+ if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->fan_duty_cycle[nr] = speed;
+ ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t show_linear(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+
+ u16 value = 0;
+ int exponent, mantissa;
+ int multiplier = 1000;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ switch (attr->index) {
+ case PSU_V_OUT:
+ value = data->v_out;
+ break;
+ case PSU_I_OUT:
+ value = data->i_out;
+ break;
+ case PSU_P_OUT:
+ value = data->p_out;
+ break;
+ case PSU_TEMP1_INPUT:
+ value = data->temp;
+ break;
+ case PSU_FAN1_SPEED:
+ value = data->fan_speed;
+ multiplier = 1;
+ break;
+ case PSU_FAN1_DUTY_CYCLE:
+ value = data->fan_duty_cycle[0];
+ multiplier = 1;
+ break;
+ case PSU_MFR_VIN_MIN:
+ value = data->mfr_vin_min;
+ break;
+ case PSU_MFR_VIN_MAX:
+ value = data->mfr_vin_max;
+ break;
+ case PSU_MFR_VOUT_MIN:
+ value = data->mfr_vout_min;
+ break;
+ case PSU_MFR_VOUT_MAX:
+ value = data->mfr_vout_max;
+ break;
+ case PSU_MFR_PIN_MAX:
+ value = data->mfr_pin_max;
+ break;
+ case PSU_MFR_POUT_MAX:
+ value = data->mfr_pout_max;
+ break;
+ case PSU_MFR_IOUT_MAX:
+ value = data->mfr_iout_max;
+ break;
+ case PSU_MFR_IIN_MAX:
+ value = data->mfr_iin_max;
+ break;
+ }
+
+ exponent = two_complement_to_int(value >> 11, 5, 0x1f);
+ mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff);
+
+ return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :
+ sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
+}
+
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+ u8 shift;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6;
+
+ return sprintf(buf, "%d\n", data->fan_fault >> shift);
+}
+
+static ssize_t show_over_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ return sprintf(buf, "%d\n", data->over_temp >> 7);
+}
+
+static ssize_t show_ascii(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+ u8 *ptr = NULL;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ switch (attr->index) {
+ case PSU_FAN_DIRECTION: /* psu_fan_dir */
+ ptr = data->fan_dir + 1; /* Skip the first byte since it is the length of string. */
+ break;
+ case PSU_MFR_ID: /* psu_mfr_id */
+ ptr = data->mfr_id + 1; /* The first byte is the count byte of string. */;
+ break;
+ case PSU_MFR_MODEL: /* psu_mfr_model */
+ ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */
+ break;
+ case PSU_MFR_REVISION: /* psu_mfr_revision */
+ ptr = data->mfr_revsion + 1; /* The first byte is the count byte of string. */
+ break;
+ default:
+ return 0;
+ }
+
+ return sprintf(buf, "%s\n", ptr);
+}
+
+static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct ym2651y_data *data = ym2651y_update_device(dev);
+ int exponent, mantissa;
+ int multiplier = 1000;
+
+ if (!data->valid) {
+ return 0;
+ }
+
+ exponent = two_complement_to_int(data->vout_mode, 5, 0x1f);
+ mantissa = data->v_out;
+
+ return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :
+ sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
+}
+
+static ssize_t show_vout(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ym2651y_data *data = i2c_get_clientdata(client);
+
+ if (data->chip == YM2401) {
+ return show_vout_by_mode(dev, da, buf);
+ }
+
+ return show_linear(dev, da, buf);
+}
+
+static const struct attribute_group ym2651y_group = {
+ .attrs = ym2651y_attributes,
+};
+
+static int ym2651y_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ struct ym2651y_data *data;
+ int status;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_WORD_DATA |
+ I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL);
+ if (!data) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+ data->chip = dev_id->driver_data;
+ dev_info(&client->dev, "chip found\n");
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &ym2651y_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "%s: psu '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &ym2651y_group);
+exit_free:
+ kfree(data);
+exit:
+
+ return status;
+}
+
+static int ym2651y_remove(struct i2c_client *client)
+{
+ struct ym2651y_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &ym2651y_group);
+ kfree(data);
+
+ return 0;
+}
+
+static const struct i2c_device_id ym2651y_id[] = {
+ { "ym2651", YM2651 },
+ { "ym2401", YM2401 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, ym2651y_id);
+
+static struct i2c_driver ym2651y_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "ym2651",
+ },
+ .probe = ym2651y_probe,
+ .remove = ym2651y_remove,
+ .id_table = ym2651y_id,
+ .address_list = normal_i2c,
+};
+
+static int ym2651y_read_byte(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int ym2651y_read_word(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_word_data(client, reg);
+}
+
+static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value)
+{
+ return i2c_smbus_write_word_data(client, reg, value);
+}
+
+static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data,
+ int data_len)
+{
+ int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
+
+ if (unlikely(result < 0))
+ goto abort;
+ if (unlikely(result != data_len)) {
+ result = -EIO;
+ goto abort;
+ }
+
+ result = 0;
+
+abort:
+ return result;
+}
+
+struct reg_data_byte {
+ u8 reg;
+ u8 *value;
+};
+
+struct reg_data_word {
+ u8 reg;
+ u16 *value;
+};
+
+static struct ym2651y_data *ym2651y_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ym2651y_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int i, status, length;
+ u8 command, buf;
+ struct reg_data_byte regs_byte[] = { {0x19, &data->capability},
+ {0x20, &data->vout_mode},
+ {0x7d, &data->over_temp},
+ {0x81, &data->fan_fault},
+ {0x98, &data->pmbus_revision}};
+ struct reg_data_word regs_word[] = { {0x79, &data->status_word},
+ {0x8b, &data->v_out},
+ {0x8c, &data->i_out},
+ {0x96, &data->p_out},
+ {0x8d, &data->temp},
+ {0x3b, &(data->fan_duty_cycle[0])},
+ {0x3c, &(data->fan_duty_cycle[1])},
+ {0x90, &data->fan_speed},
+ {0xa0, &data->mfr_vin_min},
+ {0xa1, &data->mfr_vin_max},
+ {0xa2, &data->mfr_iin_max},
+ {0xa3, &data->mfr_pin_max},
+ {0xa4, &data->mfr_vout_min},
+ {0xa5, &data->mfr_vout_max},
+ {0xa6, &data->mfr_iout_max},
+ {0xa7, &data->mfr_pout_max}};
+
+ dev_dbg(&client->dev, "Starting ym2651 update\n");
+ data->valid = 0;
+
+ /* Read byte data */
+ for (i = 0; i < ARRAY_SIZE(regs_byte); i++) {
+ status = ym2651y_read_byte(client, regs_byte[i].reg);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n",
+ regs_byte[i].reg, status);
+ goto exit;
+ }
+ else {
+ *(regs_byte[i].value) = status;
+ }
+ }
+
+ /* Read word data */
+ for (i = 0; i < ARRAY_SIZE(regs_word); i++) {
+ status = ym2651y_read_word(client, regs_word[i].reg);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n",
+ regs_word[i].reg, status);
+ goto exit;
+ }
+ else {
+ *(regs_word[i].value) = status;
+ }
+ }
+
+ /* Read fan_direction */
+ command = 0xC3;
+ status = ym2651y_read_block(client, command, data->fan_dir,
+ ARRAY_SIZE(data->fan_dir)-1);
+ data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0';
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ /* Read mfr_id */
+ command = 0x99;
+ status = ym2651y_read_block(client, command, data->mfr_id,
+ ARRAY_SIZE(data->mfr_id)-1);
+ data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0';
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ /* Read mfr_model */
+ command = 0x9a;
+ length = 1;
+
+ /* Read first byte to determine the length of data */
+ status = ym2651y_read_block(client, command, &buf, length);
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ status = ym2651y_read_block(client, command, data->mfr_model, buf+1);
+ data->mfr_model[buf+1] = '\0';
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ /* Read mfr_revsion */
+ command = 0x9b;
+ status = ym2651y_read_block(client, command, data->mfr_revsion,
+ ARRAY_SIZE(data->mfr_revsion)-1);
+ data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0';
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
+ goto exit;
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+exit:
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init ym2651y_init(void)
+{
+ return i2c_add_driver(&ym2651y_driver);
+}
+
+static void __exit ym2651y_exit(void)
+{
+ i2c_del_driver(&ym2651y_driver);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("3Y Power YM-2651Y driver");
+MODULE_LICENSE("GPL");
+
+module_init(ym2651y_init);
+module_exit(ym2651y_exit);
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service
new file mode 100755
index 00000000000..30c1703dc40
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Accton AS5712-54T Platform initialization service
+Before=pmon.service
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/accton_as5812_54t_util.py install
+ExecStop=/usr/local/bin/accton_as5812_54t_util.py clean
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/README b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/README
new file mode 100755
index 00000000000..2284eb091fc
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/README
@@ -0,0 +1,60 @@
+Copyright (C) 2016 Accton Networks, Inc.
+
+This program is free software: you can redistribute it and/or modify
+It under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+
+To initialize the system, run "accton_as5812_54t_util.py install".
+To clean up the drivers & devices, run "accton_as5812_54t_util.py clean".
+To dump information of sensors, run "accton_as5812_54t_util.py show".
+To dump SFP EEPROM, run "accton_as5812_54t_util.py sff".
+To set fan speed, run "accton_as5812_54t_util.py set fan".
+To enable/disable SFP emission, run "accton_as5812_54t_util.py set sfp".
+To set system LEDs' color, run "accton_as5812_54t_util.py set led"
+For more information, run "accton_as5812_54t_util.py --help".
+
+====================================================================
+Besides applying accton_as5812_54t_util.py to access peripherals, you can
+access peripherals by sysfs nodes directly after the installation is run.
+
+LED controls can be found under /sys/class/leds. The sysfs interface
+color mappings are as follows:
+Brightness:
+ 0 => off
+ 1 => green
+ 2 => amber
+ 3 => red
+ 4 => blue
+
+There are 5 system LEDs, loc, diag, fan, ps1, and ps2.
+They are lit automatically by CPLD, but the loc and diag.
+The loc led has only 1 color, blue.
+The diag one has 3 colors: red, amber, and green.
+
+Fan controls can be found in /sys/bus/i2c/devices/2-0066.
+There are 12 fans inside 6 fan modules.
+All fans share 1 duty setting, ranged from 0~100.
+
+Three temperature sensors are controlled by the lm75 kernel modules.
+They should already be visible under /sys/bus/i2c/drivers/lm75/.
+
+Two power supplies are controlled by the CPLD.
+Here provide their status under
+/sys/bus/i2c/devices/10-0050 and /sys/bus/i2c/devices/11-0053.
+
+There are 32 QSFP+ modules are equipped.
+Apply "accton_as5812_54t_util.py show" to get their status.
+Apply "accton_as5812_54t_util.py set sfp" to turn on/off light transmission.
+Apply "accton_as5812_54t_util.py sff" to dump EEPROM information.
+Before operating on that QSFP+, please make sure it is well plugged.
+Otherwise, operation is going to fail.
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py
new file mode 100755
index 00000000000..4e9b0795081
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py
@@ -0,0 +1,565 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 Accton Networks, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+"""
+Usage: %(scriptName)s [options] command object
+
+options:
+ -h | --help : this help message
+ -d | --debug : run with debug mode
+ -f | --force : ignore error during installation or clean
+command:
+ install : install drivers and generate related sysfs nodes
+ clean : uninstall drivers and remove related sysfs nodes
+ show : show all systen status
+ sff : dump SFP eeprom
+ set : change board setting with fan|led|sfp
+"""
+
+import os
+import commands
+import sys, getopt
+import logging
+import re
+import time
+from collections import namedtuple
+
+
+
+
+PROJECT_NAME = 'as5812_54t'
+version = '0.1.0'
+verbose = False
+DEBUG = False
+args = []
+ALL_DEVICE = {}
+DEVICE_NO = {'led':5, 'fan':5,'thermal':3, 'psu':2, 'sfp':6}
+FORCE = 0
+logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG)
+logging.basicConfig(level=logging.INFO)
+
+
+if DEBUG == True:
+ print sys.argv[0]
+ print 'ARGV :', sys.argv[1:]
+
+
+def main():
+ global DEBUG
+ global args
+ global FORCE
+
+ if len(sys.argv)<2:
+ show_help()
+
+ options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help',
+ 'debug',
+ 'force',
+ ])
+ if DEBUG == True:
+ print options
+ print args
+ print len(sys.argv)
+
+ for opt, arg in options:
+ if opt in ('-h', '--help'):
+ show_help()
+ elif opt in ('-d', '--debug'):
+ DEBUG = True
+ logging.basicConfig(level=logging.INFO)
+ elif opt in ('-f', '--force'):
+ FORCE = 1
+ else:
+ logging.info('no option')
+ for arg in args:
+ if arg == 'install':
+ do_install()
+ elif arg == 'clean':
+ do_uninstall()
+ elif arg == 'show':
+ device_traversal()
+ elif arg == 'sff':
+ if len(args)!=2:
+ show_eeprom_help()
+ elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']:
+ show_eeprom_help()
+ else:
+ show_eeprom(args[1])
+ return
+ elif arg == 'set':
+ if len(args)<3:
+ show_set_help()
+ else:
+ set_device(args[1:])
+ return
+ else:
+ show_help()
+
+
+ return 0
+
+def show_help():
+ print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
+ sys.exit(0)
+
+def show_set_help():
+ cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
+ print cmd +" [led|sfp|fan]"
+ print " use \""+ cmd + " led 0-4 \" to set led color"
+ print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
+ print " use \""+ cmd + " sfp 1-6 {0|1}\" to set sfp# tx_disable"
+ sys.exit(0)
+
+def show_eeprom_help():
+ cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
+ print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom"
+ sys.exit(0)
+
+def my_log(txt):
+ if DEBUG == True:
+ print "[ROY]"+txt
+ return
+
+def log_os_system(cmd, show):
+ logging.info('Run :'+cmd)
+ status, output = commands.getstatusoutput(cmd)
+ my_log (cmd +"with result:" + str(status))
+ my_log (" output:"+output)
+ if status:
+ logging.info('Failed :'+cmd)
+ if show:
+ print('Failed :'+cmd)
+ return status, output
+
+def driver_check():
+ ret, lsmod = log_os_system("lsmod| grep accton", 0)
+ logging.info('mods:'+lsmod)
+ if len(lsmod) ==0:
+ return False
+ return True
+
+
+ self.insmod("accton_i2c_cpld")
+ self.insmod("cpr_4011_4mxx")
+ self.insmod("ym2651y")
+ for m in [ "sfp", "psu", "fan", "leds" ]:
+ self.insmod("x86-64-accton-as5812-54t-%s" % m)
+
+kos = [
+'modprobe i2c_dev',
+'modprobe i2c_mux_pca954x force_deselect_on_exit=1',
+'modprobe accton_i2c_cpld' ,
+'modprobe cpr_4011_4mxx' ,
+'modprobe ym2651y' ,
+'modprobe x86-64-accton-as5812-54t-sfp' ,
+'modprobe x86-64-accton-as5812-54t-psu' ,
+'modprobe x86-64-accton-as5812-54t-fan' ,
+'modprobe x86-64-accton-as5812-54t-leds' ]
+
+def driver_install():
+ global FORCE
+ for i in range(0,len(kos)):
+ status, output = log_os_system(kos[i], 1)
+ if status:
+ if FORCE == 0:
+ return status
+ return 0
+
+def driver_uninstall():
+ global FORCE
+ for i in range(0,len(kos)):
+ rm = kos[-(i+1)].replace("modprobe", "modprobe -rq")
+ rm = rm.replace("insmod", "rmmod")
+ status, output = log_os_system(rm, 1)
+ if status:
+ if FORCE == 0:
+ return status
+ return 0
+
+led_prefix ='/sys/class/leds/accton_'+PROJECT_NAME+'_led::'
+hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']}
+hwmon_nodes = {'led': ['brightness'] }
+hwmon_prefix ={'led': led_prefix}
+
+i2c_prefix = '/sys/bus/i2c/devices/'
+i2c_bus = {'fan': ['2-0066'] ,
+ 'thermal': ['15-0048','16-0049', '17-004a'] ,
+ 'psu': ['11-0050','12-0053'],
+ 'sfp': ['-0050']}
+i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] ,
+ 'thermal': ['hwmon/hwmon*/temp1_input'] ,
+ 'psu': ['psu_present ', 'psu_power_good'] ,
+ 'sfp': ['sfp_is_present ', 'sfp_tx_disable_all']}
+
+sfp_map = [4,6,3,5,7,2]
+
+sfp_1st_index = 48
+
+mknod =[
+'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device',
+'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device' ,
+'echo accton_i2c_cpld 0x60 > /sys/bus/i2c/devices/i2c-0/new_device',
+'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-15/new_device',
+'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-16/new_device',
+'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-17/new_device',
+'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device',
+'echo as5812_54t_psu1 0x38 > /sys/bus/i2c/devices/i2c-11/new_device',
+'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-11/new_device',
+'echo as5812_54t_psu1 0x50 > /sys/bus/i2c/devices/i2c-11/new_device',
+'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-11/new_device',
+'echo as5812_54t_psu2 0x3b > /sys/bus/i2c/devices/i2c-12/new_device',
+'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-12/new_device',
+'echo as5812_54t_psu2 0x53 > /sys/bus/i2c/devices/i2c-12/new_device',
+'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-12/new_device']
+
+mknod2 =[
+'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device',
+'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device' ,
+'echo accton_i2c_cpld 0x60 > /sys/bus/i2c/devices/i2c-1/new_device',
+'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-15/new_device',
+'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-16/new_device',
+'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-17/new_device',
+'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device',
+'echo as5812_54t_psu1 0x38 > /sys/bus/i2c/devices/i2c-11/new_device',
+'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-11/new_device',
+'echo as5812_54t_psu1 0x50 > /sys/bus/i2c/devices/i2c-11/new_device',
+'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-11/new_device',
+'echo as5812_54t_psu2 0x3b > /sys/bus/i2c/devices/i2c-12/new_device',
+'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-12/new_device',
+'echo as5812_54t_psu2 0x53 > /sys/bus/i2c/devices/i2c-12/new_device',
+'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-12/new_device']
+
+
+
+def i2c_order_check():
+ # i2c bus 0 and 1 might be installed in different order.
+ # Here check if 0x71 is exist @ i2c-0
+ tmp = "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device"
+ status, output = log_os_system(tmp, 0)
+ if not device_exist():
+ order = 1
+ else:
+ order = 0
+ tmp = "echo 0x71 > /sys/bus/i2c/devices/i2c-0/delete_device"
+ status, output = log_os_system(tmp, 0)
+ return order
+
+def device_install():
+ global FORCE
+
+ order = i2c_order_check()
+
+ # if 0x71 is not exist @i2c-0, use reversed bus order
+ if order:
+ for i in range(0,len(mknod2)):
+ #for pca954x need times to built new i2c buses
+ if mknod2[i].find('pca954') != -1:
+ time.sleep(1)
+
+ status, output = log_os_system(mknod2[i], 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+ else:
+ for i in range(0,len(mknod)):
+ #for pca954x need times to built new i2c buses
+ if mknod[i].find('pca954') != -1:
+ time.sleep(1)
+
+ status, output = log_os_system(mknod[i], 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+ for i in range(sfp_1st_index,len(sfp_map)):
+ status, output =log_os_system("echo sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+ return
+
+def device_uninstall():
+ global FORCE
+
+ status, output =log_os_system("ls /sys/bus/i2c/devices/1-0071", 0)
+ if status==0:
+ I2C_ORDER=1
+ else:
+ I2C_ORDER=0
+
+ for i in range(sfp_1st_index,len(sfp_map)):
+ target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
+ status, output =log_os_system("echo 0x50 > "+ target, 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+
+ if I2C_ORDER==0:
+ nodelist = mknod
+ else:
+ nodelist = mknod2
+
+ for i in range(len(nodelist)):
+ target = nodelist[-(i+1)]
+ temp = target.split()
+ del temp[1]
+ temp[-1] = temp[-1].replace('new_device', 'delete_device')
+ status, output = log_os_system(" ".join(temp), 1)
+ if status:
+ print output
+ if FORCE == 0:
+ return status
+
+ return
+
+def system_ready():
+ if driver_check() == False:
+ return False
+ if not device_exist():
+ return False
+ return True
+
+def do_install():
+ print "Checking system...."
+ if driver_check() == False:
+ print "No driver, installing...."
+ status = driver_install()
+ if status:
+ if FORCE == 0:
+ return status
+ else:
+ print PROJECT_NAME.upper()+" drivers detected...."
+ if not device_exist():
+ print "No device, installing...."
+ status = device_install()
+ if status:
+ if FORCE == 0:
+ return status
+ else:
+ print PROJECT_NAME.upper()+" devices detected...."
+ return
+
+def do_uninstall():
+ print "Checking system...."
+ if not device_exist():
+ print PROJECT_NAME.upper() +" has no device installed...."
+ else:
+ print "Removing device...."
+ status = device_uninstall()
+ if status:
+ if FORCE == 0:
+ return status
+
+ if driver_check()== False :
+ print PROJECT_NAME.upper() +" has no driver installed...."
+ else:
+ print "Removing installed driver...."
+ status = driver_uninstall()
+ if status:
+ if FORCE == 0:
+ return status
+
+ return
+
+def devices_info():
+ global DEVICE_NO
+ global ALL_DEVICE
+ global i2c_bus, hwmon_types
+ for key in DEVICE_NO:
+ ALL_DEVICE[key]= {}
+ for i in range(0,DEVICE_NO[key]):
+ ALL_DEVICE[key][key+str(i+1)] = []
+
+ for key in i2c_bus:
+ buses = i2c_bus[key]
+ nodes = i2c_nodes[key]
+ for i in range(0,len(buses)):
+ for j in range(0,len(nodes)):
+ if 'fan' == key:
+ for k in range(0,DEVICE_NO[key]):
+ node = key+str(k+1)
+ path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j]
+ my_log(node+": "+ path)
+ ALL_DEVICE[key][node].append(path)
+ elif 'sfp' == key:
+ for k in range(sfp_1st_index,DEVICE_NO[key]):
+ node = key+str(k+1)
+ path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
+ my_log(node+": "+ path)
+ ALL_DEVICE[key][node].append(path)
+ else:
+ node = key+str(i+1)
+ path = i2c_prefix+ buses[i]+"/"+ nodes[j]
+ my_log(node+": "+ path)
+ ALL_DEVICE[key][node].append(path)
+
+ for key in hwmon_types:
+ itypes = hwmon_types[key]
+ nodes = hwmon_nodes[key]
+ for i in range(0,len(itypes)):
+ for j in range(0,len(nodes)):
+ node = key+"_"+itypes[i]
+ path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
+ my_log(node+": "+ path)
+ ALL_DEVICE[key][ key+str(i+1)].append(path)
+
+ #show dict all in the order
+ if DEBUG == True:
+ for i in sorted(ALL_DEVICE.keys()):
+ print(i+": ")
+ for j in sorted(ALL_DEVICE[i].keys()):
+ print(" "+j)
+ for k in (ALL_DEVICE[i][j]):
+ print(" "+" "+k)
+ return
+
+def show_eeprom(index):
+ if system_ready()==False:
+ print("System's not ready.")
+ print("Please install first!")
+ return
+
+ if len(ALL_DEVICE)==0:
+ devices_info()
+ node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
+ node = node.replace(node.split("/")[-1], 'sfp_eeprom')
+ # check if got hexdump command in current environment
+ ret, log = log_os_system("which hexdump", 0)
+ ret, log2 = log_os_system("which busybox hexdump", 0)
+ if len(log):
+ hex_cmd = 'hexdump'
+ elif len(log2):
+ hex_cmd = ' busybox hexdump'
+ else:
+ log = 'Failed : no hexdump cmd!!'
+ logging.info(log)
+ print log
+ return 1
+
+ print node + ":"
+ ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
+ if ret==0:
+ print log
+ else:
+ print "**********device no found**********"
+ return
+
+def set_device(args):
+ global DEVICE_NO
+ global ALL_DEVICE
+ if system_ready()==False:
+ print("System's not ready.")
+ print("Please install first!")
+ return
+
+ if len(ALL_DEVICE)==0:
+ devices_info()
+
+ if args[0]=='led':
+ if int(args[1])>4:
+ show_set_help()
+ return
+ #print ALL_DEVICE['led']
+ for i in range(0,len(ALL_DEVICE['led'])):
+ for k in (ALL_DEVICE['led']['led'+str(i+1)]):
+ ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
+ if ret:
+ return ret
+ elif args[0]=='fan':
+ if int(args[1])>100:
+ show_set_help()
+ return
+ #print ALL_DEVICE['fan']
+ #fan1~6 is all fine, all fan share same setting
+ node = ALL_DEVICE['fan'] ['fan1'][0]
+ node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage')
+ ret, log = log_os_system("cat "+ node, 1)
+ if ret==0:
+ print ("Previous fan duty: " + log.strip() +"%")
+ ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
+ if ret==0:
+ print ("Current fan duty: " + args[1] +"%")
+ return ret
+ elif args[0]=='sfp':
+ if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
+ show_set_help()
+ return
+ if len(args)<2:
+ show_set_help()
+ return
+
+ if int(args[2])>1:
+ show_set_help()
+ return
+
+ #print ALL_DEVICE[args[0]]
+ for i in range(0,len(ALL_DEVICE[args[0]])):
+ for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
+ if j.find('tx_disable')!= -1:
+ ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
+ if ret:
+ return ret
+
+ return
+
+#get digits inside a string.
+#Ex: 31 for "sfp31"
+def get_value(input):
+ digit = re.findall('\d+', input)
+ return int(digit[0])
+
+def device_traversal():
+ if system_ready()==False:
+ print("System's not ready.")
+ print("Please install first!")
+ return
+
+ if len(ALL_DEVICE)==0:
+ devices_info()
+ for i in sorted(ALL_DEVICE.keys()):
+ print("============================================")
+ print(i.upper()+": ")
+ print("============================================")
+
+ for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
+ print " "+j+":",
+ for k in (ALL_DEVICE[i][j]):
+ ret, log = log_os_system("cat "+k, 0)
+ func = k.split("/")[-1].strip()
+ func = re.sub(j+'_','',func,1)
+ func = re.sub(i.lower()+'_','',func,1)
+ if ret==0:
+ print func+"="+log+" ",
+ else:
+ print func+"="+"X"+" ",
+ print
+ print("----------------------------------------------------------------")
+
+
+ print
+ return
+
+def device_exist():
+ ret1, log = log_os_system("ls "+i2c_prefix+"*0071", 0)
+ ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0)
+ return not(ret1 or ret2)
+
+if __name__ == "__main__":
+ main()
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/__init__.py
new file mode 100755
index 00000000000..e69de29bb2d
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py
new file mode 100755
index 00000000000..207436c1fc9
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py
@@ -0,0 +1,255 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 Accton Technology Corporation
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# ------------------------------------------------------------------
+# HISTORY:
+# mm/dd/yyyy (A.D.)
+# 11/13/2017: Polly Hsu, Create
+# 1/10/2018: Jostar modify for as7716_32
+# 2/27/2018: Roy Lee modify for as7312_54x
+# ------------------------------------------------------------------
+
+try:
+ import time
+ import logging
+ from collections import namedtuple
+except ImportError as e:
+ raise ImportError('%s - required module not found' % str(e))
+
+
+class FanUtil(object):
+ """Platform-specific FanUtil class"""
+
+ FAN_NUM_ON_MAIN_BROAD = 6
+ FAN_NUM_1_IDX = 1
+ FAN_NUM_2_IDX = 2
+ FAN_NUM_3_IDX = 3
+ FAN_NUM_4_IDX = 4
+ FAN_NUM_5_IDX = 5
+ FAN_NUM_6_IDX = 6
+
+ FAN_NODE_NUM_OF_MAP = 2
+ FAN_NODE_FAULT_IDX_OF_MAP = 1
+ #FAN_NODE_SPEED_IDX_OF_MAP = 2
+ FAN_NODE_DIR_IDX_OF_MAP = 2
+ #FAN_NODE_DUTY_IDX_OF_MAP = 4
+ #FANR_NODE_FAULT_IDX_OF_MAP = 5
+
+ #BASE_VAL_PATH = '/sys/devices/platform/as5712_54x_fan/{0}'
+ BASE_VAL_PATH = '/sys/bus/i2c/devices/2-0066/{0}'
+ FAN_DUTY_PATH = '/sys/bus/i2c/devices/2-0066/fan_duty_cycle_percentage'
+
+ #logfile = ''
+ #loglevel = logging.INFO
+
+ """ Dictionary where
+ key1 = fan id index (integer) starting from 1
+ key2 = fan node index (interger) starting from 1
+ value = path to fan device file (string) """
+ _fan_to_device_path_mapping = {}
+
+#fan1_direction
+#fan1_fault
+#fan1_present
+
+ #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage',
+ _fan_to_device_node_mapping = {
+ (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault',
+ (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction',
+
+ (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault',
+ (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction',
+
+ (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault',
+ (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction',
+
+ (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault',
+ (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction',
+
+ (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault',
+ (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction',
+
+ (FAN_NUM_6_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan6_fault',
+ (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction',
+ }
+
+ def _get_fan_to_device_node(self, fan_num, node_num):
+ return self._fan_to_device_node_mapping[(fan_num, node_num)]
+
+ def _get_fan_node_val(self, fan_num, node_num):
+ if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
+ logging.debug('GET. Parameter error. fan_num:%d', fan_num)
+ return None
+
+ if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP:
+ logging.debug('GET. Parameter error. node_num:%d', node_num)
+ return None
+
+ device_path = self.get_fan_to_device_path(fan_num, node_num)
+
+ try:
+ val_file = open(device_path, 'r')
+ except IOError as e:
+ logging.error('GET. unable to open file: %s', str(e))
+ return None
+
+ content = val_file.readline().rstrip()
+
+ if content == '':
+ logging.debug('GET. content is NULL. device_path:%s', device_path)
+ return None
+
+ try:
+ val_file.close()
+ except:
+ logging.debug('GET. unable to close file. device_path:%s', device_path)
+ return None
+
+ return int(content)
+
+ def _set_fan_node_val(self, fan_num, node_num, val):
+ if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
+ logging.debug('GET. Parameter error. fan_num:%d', fan_num)
+ return None
+
+ if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP:
+ logging.debug('GET. Parameter error. node_num:%d', node_num)
+ return None
+
+ content = str(val)
+ if content == '':
+ logging.debug('GET. content is NULL. device_path:%s', device_path)
+ return None
+
+ device_path = self.get_fan_to_device_path(fan_num, node_num)
+ try:
+ val_file = open(device_path, 'w')
+ except IOError as e:
+ logging.error('GET. unable to open file: %s', str(e))
+ return None
+
+ val_file.write(content)
+
+ try:
+ val_file.close()
+ except:
+ logging.debug('GET. unable to close file. device_path:%s', device_path)
+ return None
+
+ return True
+
+ def __init__(self):
+ fan_path = self.BASE_VAL_PATH
+
+ for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1):
+ for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1):
+ self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format(
+ self._fan_to_device_node_mapping[(fan_num, node_num)])
+
+ def get_num_fans(self):
+ return self.FAN_NUM_ON_MAIN_BROAD
+
+ def get_idx_fan_start(self):
+ return self.FAN_NUM_1_IDX
+
+ def get_num_nodes(self):
+ return self.FAN_NODE_NUM_OF_MAP
+
+ def get_idx_node_start(self):
+ return self.FAN_NODE_FAULT_IDX_OF_MAP
+
+ def get_size_node_map(self):
+ return len(self._fan_to_device_node_mapping)
+
+ def get_size_path_map(self):
+ return len(self._fan_to_device_path_mapping)
+
+ def get_fan_to_device_path(self, fan_num, node_num):
+ return self._fan_to_device_path_mapping[(fan_num, node_num)]
+
+ def get_fan_fault(self, fan_num):
+ return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP)
+
+ #def get_fan_speed(self, fan_num):
+ # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP)
+
+ def get_fan_dir(self, fan_num):
+ return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP)
+
+ def get_fan_duty_cycle(self):
+ #duty_path = self.FAN_DUTY_PATH
+ try:
+ val_file = open(self.FAN_DUTY_PATH)
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ content = val_file.readline().rstrip()
+ val_file.close()
+
+ return int(content)
+ #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP)
+#static u32 reg_val_to_duty_cycle(u8 reg_val)
+#{
+# reg_val &= FAN_DUTY_CYCLE_REG_MASK;
+# return ((u32)(reg_val+1) * 625 + 75)/ 100;
+#}
+#
+ def set_fan_duty_cycle(self, val):
+
+ try:
+ fan_file = open(self.FAN_DUTY_PATH, 'r+')
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+ #val = ((val + 1 ) * 625 +75 ) / 100
+ fan_file.write(str(val))
+ fan_file.close()
+ return True
+
+ #def get_fanr_fault(self, fan_num):
+ # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP)
+
+ def get_fanr_speed(self, fan_num):
+ return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP)
+
+ def get_fan_status(self, fan_num):
+ if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
+ logging.debug('GET. Parameter error. fan_num, %d', fan_num)
+ return None
+
+ if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0:
+ logging.debug('GET. FAN fault. fan_num, %d', fan_num)
+ return False
+
+ #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0:
+ # logging.debug('GET. FANR fault. fan_num, %d', fan_num)
+ # return False
+
+ return True
+
+#def main():
+# fan = FanUtil()
+#
+# print 'get_size_node_map : %d' % fan.get_size_node_map()
+# print 'get_size_path_map : %d' % fan.get_size_path_map()
+# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1):
+# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1):
+# print fan.get_fan_to_device_path(x, y)
+#
+#if __name__ == '__main__':
+# main()
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py
new file mode 100755
index 00000000000..68f0ef900df
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 Accton Technology Corporation
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# ------------------------------------------------------------------
+# HISTORY:
+# mm/dd/yyyy (A.D.)
+# 11/13/2017: Polly Hsu, Create
+# 1/10/2018:Jostar modify for as7716_32x
+# 2/27/2018: Roy Lee modify for as7312_54x
+# ------------------------------------------------------------------
+
+try:
+ import time
+ import logging
+ import glob
+ from collections import namedtuple
+except ImportError as e:
+ raise ImportError('%s - required module not found' % str(e))
+
+
+class ThermalUtil(object):
+ """Platform-specific ThermalUtil class"""
+
+ THERMAL_NUM_ON_MAIN_BROAD = 3
+ THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD
+ THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD
+ THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD
+
+ BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input'
+
+ """ Dictionary where
+ key1 = thermal id index (integer) starting from 1
+ value = path to fan device file (string) """
+ _thermal_to_device_path_mapping = {}
+
+ _thermal_to_device_node_mapping = {
+ THERMAL_NUM_1_IDX: ['3', '48'],
+ THERMAL_NUM_2_IDX: ['3', '49'],
+ THERMAL_NUM_3_IDX: ['3', '4a'],
+ }
+
+ def __init__(self):
+ thermal_path = self.BASE_VAL_PATH
+
+ for x in range(self.THERMAL_NUM_1_IDX, self.THERMAL_NUM_ON_MAIN_BROAD+1):
+ self._thermal_to_device_path_mapping[x] = thermal_path.format(
+ self._thermal_to_device_node_mapping[x][0],
+ self._thermal_to_device_node_mapping[x][1])
+
+ def _get_thermal_node_val(self, thermal_num):
+ if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD:
+ logging.debug('GET. Parameter error. thermal_num, %d', thermal_num)
+ return None
+
+ device_path = self.get_thermal_to_device_path(thermal_num)
+ for filename in glob.glob(device_path):
+ try:
+ val_file = open(filename, 'r')
+ except IOError as e:
+ logging.error('GET. unable to open file: %s', str(e))
+ return None
+
+ content = val_file.readline().rstrip()
+
+ if content == '':
+ logging.debug('GET. content is NULL. device_path:%s', device_path)
+ return None
+
+ try:
+ val_file.close()
+ except:
+ logging.debug('GET. unable to close file. device_path:%s', device_path)
+ return None
+
+ return int(content)
+
+
+ def get_num_thermals(self):
+ return self.THERMAL_NUM_ON_MAIN_BROAD
+
+ def get_idx_thermal_start(self):
+ return self.THERMAL_NUM_1_IDX
+
+ def get_size_node_map(self):
+ return len(self._thermal_to_device_node_mapping)
+
+ def get_size_path_map(self):
+ return len(self._thermal_to_device_path_mapping)
+
+ def get_thermal_to_device_path(self, thermal_num):
+ return self._thermal_to_device_path_mapping[thermal_num]
+
+ def get_thermal_1_val(self):
+ return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX)
+
+ def get_thermal_2_val(self):
+ return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX)
+ def get_thermal_temp(self):
+ return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX))
+
+#def main():
+# thermal = ThermalUtil()
+#
+# print 'get_size_node_map : %d' % thermal.get_size_node_map()
+# print 'get_size_path_map : %d' % thermal.get_size_path_map()
+# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1):
+# print thermal.get_thermal_to_device_path(x)
+#
+#if __name__ == '__main__':
+# main()
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/Makefile
new file mode 100755
index 00000000000..488fdb321ca
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/Makefile
@@ -0,0 +1,17 @@
+ifneq ($(KERNELRELEASE),)
+obj-m:= accton_i2c_cpld.o \
+ accton_as7312_54x_fan.o accton_as7312_54x_leds.o \
+ accton_as7312_54x_psu.o ym2651y.o
+
+else
+ifeq (,$(KERNEL_SRC))
+$(error KERNEL_SRC is not defined)
+else
+KERNELDIR:=$(KERNEL_SRC)
+endif
+PWD:=$(shell pwd)
+default:
+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
+clean:
+ rm -rf *.o *.mod.o *.mod.o *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order
+endif
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_fan.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_fan.c
new file mode 100755
index 00000000000..8764ec8a317
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_fan.c
@@ -0,0 +1,815 @@
+/*
+ * A hwmon driver for the Accton as7312 54x fan
+ *
+ * Copyright (C) 2014 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define DRVNAME "as7312_54x_fan"
+
+#define NUM_THERMAL_SENSORS (3) /* Get sum of this number of sensors.*/
+#define THERMAL_SENSORS_DRIVER "lm75"
+#define THERMAL_SENSORS_ADDRS {0x48, 0x49, 0x4a}
+
+#define IN
+#define OUT
+
+static struct as7312_54x_fan_data *as7312_54x_fan_update_device(struct device *dev);
+static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t get_enable(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t set_enable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, char *buf);
+extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
+extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+
+/* fan related data, the index should match sysfs_fan_attributes
+ */
+static const u8 fan_reg[] = {
+ 0x0F, /* fan 1-6 present status */
+ 0x10, /* fan 1-6 direction(0:F2B 1:B2F) */
+ 0x11, /* fan PWM(for all fan) */
+ 0x12, /* front fan 1 speed(rpm) */
+ 0x13, /* front fan 2 speed(rpm) */
+ 0x14, /* front fan 3 speed(rpm) */
+ 0x15, /* front fan 4 speed(rpm) */
+ 0x16, /* front fan 5 speed(rpm) */
+ 0x17, /* front fan 6 speed(rpm) */
+ 0x22, /* rear fan 1 speed(rpm) */
+ 0x23, /* rear fan 2 speed(rpm) */
+ 0x24, /* rear fan 3 speed(rpm) */
+ 0x25, /* rear fan 4 speed(rpm) */
+ 0x26, /* rear fan 5 speed(rpm) */
+ 0x27, /* rear fan 6 speed(rpm) */
+};
+
+/* Each client has this additional data */
+struct as7312_54x_fan_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* != 0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */
+ u8 enable;
+ int system_temp; /*In unit of mini-Celsius*/
+ int sensors_found;
+};
+
+enum fan_id {
+ FAN1_ID,
+ FAN2_ID,
+ FAN3_ID,
+ FAN4_ID,
+ FAN5_ID,
+ FAN6_ID
+};
+
+enum sysfs_fan_attributes {
+ FAN_PRESENT_REG,
+ FAN_DIRECTION_REG,
+ FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */
+ FAN1_FRONT_SPEED_RPM,
+ FAN2_FRONT_SPEED_RPM,
+ FAN3_FRONT_SPEED_RPM,
+ FAN4_FRONT_SPEED_RPM,
+ FAN5_FRONT_SPEED_RPM,
+ FAN6_FRONT_SPEED_RPM,
+ FAN1_REAR_SPEED_RPM,
+ FAN2_REAR_SPEED_RPM,
+ FAN3_REAR_SPEED_RPM,
+ FAN4_REAR_SPEED_RPM,
+ FAN5_REAR_SPEED_RPM,
+ FAN6_REAR_SPEED_RPM,
+ FAN1_DIRECTION,
+ FAN2_DIRECTION,
+ FAN3_DIRECTION,
+ FAN4_DIRECTION,
+ FAN5_DIRECTION,
+ FAN6_DIRECTION,
+ FAN1_PRESENT,
+ FAN2_PRESENT,
+ FAN3_PRESENT,
+ FAN4_PRESENT,
+ FAN5_PRESENT,
+ FAN6_PRESENT,
+ FAN1_FAULT,
+ FAN2_FAULT,
+ FAN3_FAULT,
+ FAN4_FAULT,
+ FAN5_FAULT,
+ FAN6_FAULT
+};
+
+/* Define attributes
+ */
+#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \
+ static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT);\
+ static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT)
+#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \
+ &sensor_dev_attr_fan##index2##_fault.dev_attr.attr
+
+#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \
+ static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION)
+#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr
+
+#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \
+ static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\
+ static SENSOR_DEVICE_ATTR(pwm##index, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\
+ static SENSOR_DEVICE_ATTR(pwm##index##_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, FAN_DUTY_CYCLE_PERCENTAGE)
+
+#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr, \
+ &sensor_dev_attr_pwm##index.dev_attr.attr, \
+ &sensor_dev_attr_pwm##index##_enable.dev_attr.attr
+
+#define DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR() \
+ static SENSOR_DEVICE_ATTR(sys_temp, S_IRUGO, get_sys_temp, NULL, FAN_DUTY_CYCLE_PERCENTAGE)
+
+#define DECLARE_FAN_SYSTEM_TEMP_ATTR() &sensor_dev_attr_sys_temp.dev_attr.attr
+
+
+#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \
+ static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT)
+#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr
+
+#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \
+ static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\
+ static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM);\
+ static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\
+ static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM)
+#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \
+ &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \
+ &sensor_dev_attr_fan##index##_input.dev_attr.attr, \
+ &sensor_dev_attr_fan##index2##_input.dev_attr.attr
+
+/* 6 fan fault attributes in this platform */
+DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1,11);
+DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2,12);
+DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3,13);
+DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4,14);
+DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5,15);
+DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(6,16);
+/* 6 fan speed(rpm) attributes in this platform */
+DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1,11);
+DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2,12);
+DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3,13);
+DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4,14);
+DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5,15);
+DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(6,16);
+/* 6 fan present attributes in this platform */
+DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1);
+DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2);
+DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3);
+DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4);
+DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(5);
+DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(6);
+/* 6 fan direction attribute in this platform */
+DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1);
+DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2);
+DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3);
+DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4);
+DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5);
+DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(6);
+/* 1 fan duty cycle attribute in this platform */
+DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1);
+/* System temperature for fancontrol */
+DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR();
+
+static struct attribute *as7312_54x_fan_attributes[] = {
+ /* fan related attributes */
+ DECLARE_FAN_FAULT_ATTR(1,11),
+ DECLARE_FAN_FAULT_ATTR(2,12),
+ DECLARE_FAN_FAULT_ATTR(3,13),
+ DECLARE_FAN_FAULT_ATTR(4,14),
+ DECLARE_FAN_FAULT_ATTR(5,15),
+ DECLARE_FAN_FAULT_ATTR(6,16),
+ DECLARE_FAN_SPEED_RPM_ATTR(1,11),
+ DECLARE_FAN_SPEED_RPM_ATTR(2,12),
+ DECLARE_FAN_SPEED_RPM_ATTR(3,13),
+ DECLARE_FAN_SPEED_RPM_ATTR(4,14),
+ DECLARE_FAN_SPEED_RPM_ATTR(5,15),
+ DECLARE_FAN_SPEED_RPM_ATTR(6,16),
+ DECLARE_FAN_PRESENT_ATTR(1),
+ DECLARE_FAN_PRESENT_ATTR(2),
+ DECLARE_FAN_PRESENT_ATTR(3),
+ DECLARE_FAN_PRESENT_ATTR(4),
+ DECLARE_FAN_PRESENT_ATTR(5),
+ DECLARE_FAN_PRESENT_ATTR(6),
+ DECLARE_FAN_DIRECTION_ATTR(1),
+ DECLARE_FAN_DIRECTION_ATTR(2),
+ DECLARE_FAN_DIRECTION_ATTR(3),
+ DECLARE_FAN_DIRECTION_ATTR(4),
+ DECLARE_FAN_DIRECTION_ATTR(5),
+ DECLARE_FAN_DIRECTION_ATTR(6),
+ DECLARE_FAN_DUTY_CYCLE_ATTR(1),
+ DECLARE_FAN_SYSTEM_TEMP_ATTR(),
+ NULL
+};
+
+#define FAN_DUTY_CYCLE_REG_MASK 0xF
+#define FAN_MAX_DUTY_CYCLE 100
+#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100
+
+static int as7312_54x_fan_read_value(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int as7312_54x_fan_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/* fan utility functions
+ */
+static u32 reg_val_to_duty_cycle(u8 reg_val)
+{
+ reg_val &= FAN_DUTY_CYCLE_REG_MASK;
+ return ((u32)(reg_val+1) * 625 + 75)/ 100;
+}
+
+static u8 duty_cycle_to_reg_val(u8 duty_cycle)
+{
+ return ((u32)duty_cycle * 100 / 625) - 1;
+}
+
+static u32 reg_val_to_speed_rpm(u8 reg_val)
+{
+ return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP;
+}
+
+static u8 reg_val_to_direction(u8 reg_val, enum fan_id id)
+{
+ u8 mask = (1 << id);
+
+ reg_val &= mask;
+
+ return reg_val ? 1 : 0;
+}
+static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id)
+{
+ u8 mask = (1 << id);
+
+ reg_val &= mask;
+
+ return reg_val ? 0 : 1;
+}
+
+static u8 is_fan_fault(struct as7312_54x_fan_data *data, enum fan_id id)
+{
+ u8 ret = 1;
+ int front_fan_index = FAN1_FRONT_SPEED_RPM + id;
+ int rear_fan_index = FAN1_REAR_SPEED_RPM + id;
+
+ /* Check if the speed of front or rear fan is ZERO,
+ */
+ if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) &&
+ reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static ssize_t set_enable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct as7312_54x_fan_data *data = as7312_54x_fan_update_device(dev);
+ int error, value;
+
+ error = kstrtoint(buf, 10, &value);
+ if (error)
+ return error;
+
+ if (value < 0 || value > 1)
+ return -EINVAL;
+
+ data->enable = value;
+ if (value == 0)
+ {
+ return set_duty_cycle(dev, da, buf, FAN_MAX_DUTY_CYCLE);
+ }
+ return count;
+}
+
+
+static ssize_t get_enable(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct as7312_54x_fan_data *data = as7312_54x_fan_update_device(dev);
+
+ return sprintf(buf, "%u\n", data->enable);
+}
+static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ int error, value;
+ struct i2c_client *client = to_i2c_client(dev);
+
+ error = kstrtoint(buf, 10, &value);
+ if (error)
+ return error;
+
+ if (value < 0)
+ return -EINVAL;
+
+ value = (value > FAN_MAX_DUTY_CYCLE)? FAN_MAX_DUTY_CYCLE : value;
+
+ as7312_54x_fan_write_value(client, 0x33, 0); /* Disable fan speed watch dog */
+ as7312_54x_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value));
+ return count;
+}
+
+/* Due to this struct is declared at lm75.c, it cannot be include
+ * under Sonic environment. I duplicate it from lm75.c.
+ */
+struct lm75_data {
+ struct i2c_client *client;
+ struct device *hwmon_dev;
+ struct thermal_zone_device *tz;
+ struct mutex update_lock;
+ u8 orig_conf;
+ u8 resolution; /* In bits, between 9 and 12 */
+ u8 resolution_limits;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ unsigned long sample_time; /* In jiffies */
+ s16 temp[3]; /* Register values,
+ 0 = input
+ 1 = max
+ 2 = hyst */
+};
+
+/*Copied from lm75.c*/
+static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
+{
+ return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
+}
+
+/*Get hwmon_dev from i2c_client, set hwmon_dev = NULL is failed.*/
+static struct device * get_hwmon_dev(
+ struct i2c_client *client)
+{
+ struct lm75_data *data = NULL;
+
+ data = i2c_get_clientdata(client);
+ if(data)
+ {
+ if( data->valid == 1 && data->hwmon_dev)
+ {
+ return data->hwmon_dev;
+ }
+
+ }
+ return NULL;
+}
+
+/* To find hwmon index by opening hwmon under that i2c address.
+ */
+static int find_hwmon_index_by_FileOpen(
+ int bus_nr,
+ unsigned short addr,
+ OUT int *index)
+{
+#define MAX_HWMON_DEVICE (10) /* Find hwmon device in 0~10*/
+ struct file *sfd;
+ char client_name[96];
+ int i=0;
+
+ do {
+ snprintf(client_name, sizeof(client_name),
+ "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input",
+ bus_nr, addr, i);
+
+ sfd = filp_open(client_name, O_RDONLY, 0);
+ i++;
+ } while( IS_ERR(sfd) && i < MAX_HWMON_DEVICE);
+
+ if (IS_ERR(sfd)) {
+ pr_err("Failed to open file(%s)#%d\r\n", client_name, __LINE__);
+ return -ENOENT;
+ }
+ filp_close(sfd, 0);
+ *index = i - 1;
+ return 0;
+
+#undef MAX_HWMON_DEVICE
+}
+
+static int get_temp_file_path(
+ int bus_nr, unsigned short addr,
+ struct device *hwmon_dev
+ ,char *path, int max_len)
+{
+
+ if(hwmon_dev && strlen(dev_name(hwmon_dev)))
+ {
+ snprintf(path, max_len,
+ "/sys/bus/i2c/devices/%d-%04x/hwmon/%s/temp1_input",
+ bus_nr, addr, dev_name(hwmon_dev));
+ }
+ else
+ {
+ int i=0;
+ if(find_hwmon_index_by_FileOpen( bus_nr, addr, &i))
+ {
+ return -EIO;
+ }
+ snprintf(path, max_len,
+ "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input",
+ bus_nr, addr, i);
+ }
+ return 0;
+}
+
+/*File read the dev file at user space.*/
+static int read_devfile_temp1_input(
+ struct device *dev,
+ int bus_nr,
+ unsigned short addr,
+ struct device *hwmon_dev,
+ int *miniCelsius)
+{
+ struct file *sfd;
+ char buffer[96];
+ char devfile[96];
+ int rc, status;
+ int rdlen, value;
+ mm_segment_t old_fs;
+
+ rc = 0;
+ get_temp_file_path(bus_nr, addr, hwmon_dev, devfile, sizeof(devfile));
+ sfd = filp_open(devfile, O_RDONLY, 0);
+ if (IS_ERR(sfd)) {
+ pr_err("Failed to open file(%s)#%d\r\n", devfile, __LINE__);
+ return -ENOENT;
+ }
+ dev_dbg(dev, "Found device:%s\n",devfile);
+
+ if(!(sfd->f_op) || !(sfd->f_op->read) ) {
+ pr_err("file %s cann't readable ?\n",devfile);
+ return -ENOENT;
+ }
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ rdlen = sfd->f_op->read(sfd, buffer, sizeof(buffer), &sfd->f_pos);
+ if (rdlen == 0) {
+ pr_err( "File(%s) empty!\n", devfile);
+ rc = -EIO;
+ goto exit;
+ }
+ status = sscanf(buffer, "%d", &value);
+ if (status != 1) {
+ rc = -EIO;
+ goto exit;
+ }
+ *miniCelsius = value;
+ dev_dbg(dev,"found sensors: %d @i2c %d-%04x\n", value, bus_nr, addr);
+
+exit:
+ set_fs(old_fs);
+ filp_close(sfd, 0);
+ return rc;
+}
+
+static u8 is_lm75_data_due(struct i2c_client *client)
+{
+ struct lm75_data *data = NULL;
+
+ data = i2c_get_clientdata(client);
+ if (time_after(jiffies, data->last_updated + data->sample_time))
+ {
+ return 1;
+ }
+ return 0;
+}
+static int get_lm75_temp(struct i2c_client *client, int *miniCelsius)
+{
+ struct lm75_data *data = NULL;
+
+ data = i2c_get_clientdata(client);
+ *miniCelsius = lm75_reg_to_mc(data->temp[0], data->resolution);
+
+ return 0;
+}
+
+static bool lm75_addr_mached(unsigned short addr)
+{
+ int i;
+ unsigned short addrs[] = THERMAL_SENSORS_ADDRS;
+
+ for (i = 0; i < ARRAY_SIZE(addrs); i++)
+ {
+ if( addr == addrs[i])
+ return 1;
+ }
+ return 0;
+}
+
+static int _find_lm75_device(struct device *dev, void *data)
+{
+ struct device_driver *driver;
+ struct as7312_54x_fan_data *prv = data;
+ char *driver_name = THERMAL_SENSORS_DRIVER;
+
+ driver = dev->driver;
+ if (driver && driver->name &&
+ strcmp(driver->name, driver_name) == 0)
+ {
+ struct i2c_client *client;
+ client = to_i2c_client(dev);
+ if (client)
+ {
+ /*cannot use "struct i2c_adapter *adap = to_i2c_adapter(dev);"*/
+ struct i2c_adapter *adap = client->adapter;
+ int miniCelsius = 0;
+
+ if (! lm75_addr_mached(client->addr))
+ {
+ return 0;
+ }
+
+ if (!adap) {
+ return -ENXIO;
+ }
+
+ /* If the data is not updated, read them from devfile
+ to drive them updateing data from chip.*/
+ if (is_lm75_data_due(client))
+ {
+ struct device *hwmon_dev;
+
+ hwmon_dev = get_hwmon_dev(client);
+ if(0 == read_devfile_temp1_input(dev, adap->nr,
+ client->addr, hwmon_dev, &miniCelsius))
+ {
+ prv->system_temp += miniCelsius;
+ prv->sensors_found++;
+ }
+
+ }
+ else
+ {
+ get_lm75_temp(client, &miniCelsius);
+ prv->system_temp += miniCelsius;
+ prv->sensors_found++;
+
+ }
+ }
+ }
+ return 0;
+}
+
+/*Find all lm75 devices and return sum of temperatures.*/
+static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ ssize_t ret = 0;
+ struct as7312_54x_fan_data *data = as7312_54x_fan_update_device(dev);
+
+ data->system_temp=0;
+ data->sensors_found=0;
+ i2c_for_each_dev(data, _find_lm75_device);
+ if (NUM_THERMAL_SENSORS != data->sensors_found)
+ {
+ dev_dbg(dev,"only %d of %d temps are found\n",
+ data->sensors_found, NUM_THERMAL_SENSORS);
+ data->system_temp = INT_MAX;
+ }
+ ret = sprintf(buf, "%d\n",data->system_temp);
+ return ret;
+}
+
+static ssize_t fan_show_value(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct as7312_54x_fan_data *data = as7312_54x_fan_update_device(dev);
+ ssize_t ret = 0;
+
+ if (data->valid) {
+ switch (attr->index) {
+ case FAN_DUTY_CYCLE_PERCENTAGE:
+ {
+ u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]);
+ ret = sprintf(buf, "%u\n", duty_cycle);
+ break;
+ }
+ case FAN1_FRONT_SPEED_RPM:
+ case FAN2_FRONT_SPEED_RPM:
+ case FAN3_FRONT_SPEED_RPM:
+ case FAN4_FRONT_SPEED_RPM:
+ case FAN5_FRONT_SPEED_RPM:
+ case FAN6_FRONT_SPEED_RPM:
+ case FAN1_REAR_SPEED_RPM:
+ case FAN2_REAR_SPEED_RPM:
+ case FAN3_REAR_SPEED_RPM:
+ case FAN4_REAR_SPEED_RPM:
+ case FAN5_REAR_SPEED_RPM:
+ case FAN6_REAR_SPEED_RPM:
+ ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index]));
+ break;
+ case FAN1_PRESENT:
+ case FAN2_PRESENT:
+ case FAN3_PRESENT:
+ case FAN4_PRESENT:
+ case FAN5_PRESENT:
+ case FAN6_PRESENT:
+ ret = sprintf(buf, "%d\n",
+ reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG],
+ attr->index - FAN1_PRESENT));
+ break;
+ case FAN1_FAULT:
+ case FAN2_FAULT:
+ case FAN3_FAULT:
+ case FAN4_FAULT:
+ case FAN5_FAULT:
+ case FAN6_FAULT:
+ ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT));
+ break;
+ case FAN1_DIRECTION:
+ case FAN2_DIRECTION:
+ case FAN3_DIRECTION:
+ case FAN4_DIRECTION:
+ case FAN5_DIRECTION:
+ case FAN6_DIRECTION:
+ ret = sprintf(buf, "%d\n",
+ reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG],
+ attr->index - FAN1_DIRECTION));
+ break;
+ default:
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static const struct attribute_group as7312_54x_fan_group = {
+ .attrs = as7312_54x_fan_attributes,
+};
+
+static struct as7312_54x_fan_data *as7312_54x_fan_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as7312_54x_fan_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
+ int i;
+
+ dev_dbg(&client->dev, "Starting as7312_54x_fan update\n");
+ data->valid = 0;
+
+ /* Update fan data
+ */
+ for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) {
+ int status = as7312_54x_fan_read_value(client, fan_reg[i]);
+
+ if (status < 0) {
+ data->valid = 0;
+ mutex_unlock(&data->update_lock);
+ dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status);
+ return data;
+ }
+ else {
+ data->reg_val[i] = status;
+ }
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int as7312_54x_fan_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ struct as7312_54x_fan_data *data;
+ int status;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct as7312_54x_fan_data), GFP_KERNEL);
+ if (!data) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ data->valid = 0;
+ data->enable = 0;
+ mutex_init(&data->update_lock);
+
+ dev_info(&client->dev, "chip found\n");
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &as7312_54x_fan_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "%s: fan '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &as7312_54x_fan_group);
+exit_free:
+ kfree(data);
+exit:
+
+ return status;
+}
+
+static int as7312_54x_fan_remove(struct i2c_client *client)
+{
+ struct as7312_54x_fan_data *data = i2c_get_clientdata(client);
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &as7312_54x_fan_group);
+
+ return 0;
+}
+
+/* Addresses to scan */
+static const unsigned short normal_i2c[] = { 0x66, I2C_CLIENT_END };
+
+static const struct i2c_device_id as7312_54x_fan_id[] = {
+ { "as7312_54x_fan", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, as7312_54x_fan_id);
+
+static struct i2c_driver as7312_54x_fan_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = DRVNAME,
+ },
+ .probe = as7312_54x_fan_probe,
+ .remove = as7312_54x_fan_remove,
+ .id_table = as7312_54x_fan_id,
+ .address_list = normal_i2c,
+};
+
+static int __init as7312_54x_fan_init(void)
+{
+ return i2c_add_driver(&as7312_54x_fan_driver);
+}
+
+static void __exit as7312_54x_fan_exit(void)
+{
+ i2c_del_driver(&as7312_54x_fan_driver);
+}
+
+module_init(as7312_54x_fan_init);
+module_exit(as7312_54x_fan_exit);
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("as7312_54x_fan driver");
+MODULE_LICENSE("GPL");
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c
new file mode 100644
index 00000000000..1d54517c624
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c
@@ -0,0 +1,438 @@
+/*
+ * A LED driver for the accton_as7312_54x_led
+ *
+ * Copyright (C) 2014 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*#define DEBUG*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+extern int as7312_54x_cpld_read (unsigned short cpld_addr, u8 reg);
+extern int as7312_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+
+extern void led_classdev_unregister(struct led_classdev *led_cdev);
+extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
+extern void led_classdev_resume(struct led_classdev *led_cdev);
+extern void led_classdev_suspend(struct led_classdev *led_cdev);
+
+#define DRVNAME "accton_as7312_54x_led"
+
+struct accton_as7312_54x_led_data {
+ struct platform_device *pdev;
+ struct mutex update_lock;
+ char valid; /* != 0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 reg_val[1]; /* only 1 register*/
+};
+
+static struct accton_as7312_54x_led_data *ledctl = NULL;
+
+/* LED related data
+ */
+
+#define LED_CNTRLER_I2C_ADDRESS (0x60)
+
+#define LED_TYPE_DIAG_REG_MASK (0x3)
+#define LED_MODE_DIAG_GREEN_VALUE (0x02)
+#define LED_MODE_DIAG_RED_VALUE (0x01)
+#define LED_MODE_DIAG_AMBER_VALUE (0x00) /*It's yellow actually. Green+Red=Yellow*/
+#define LED_MODE_DIAG_OFF_VALUE (0x03)
+
+
+#define LED_TYPE_LOC_REG_MASK (0x80)
+#define LED_MODE_LOC_ON_VALUE (0)
+#define LED_MODE_LOC_OFF_VALUE (0x80)
+
+enum led_type {
+ LED_TYPE_DIAG,
+ LED_TYPE_LOC,
+ LED_TYPE_FAN,
+ LED_TYPE_PSU1,
+ LED_TYPE_PSU2
+};
+
+struct led_reg {
+ u32 types;
+ u8 reg_addr;
+};
+
+static const struct led_reg led_reg_map[] = {
+ {(1<update_lock);
+
+ if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2)
+ || !ledctl->valid) {
+ int i;
+
+ dev_dbg(&ledctl->pdev->dev, "Starting accton_as7312_54x_led update\n");
+
+ /* Update LED data
+ */
+ for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) {
+ int status = accton_as7312_54x_led_read_value(led_reg_map[i].reg_addr);
+
+ if (status < 0) {
+ ledctl->valid = 0;
+ dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status);
+ goto exit;
+ }
+ else
+ {
+ ledctl->reg_val[i] = status;
+ }
+ }
+
+ ledctl->last_updated = jiffies;
+ ledctl->valid = 1;
+ }
+
+exit:
+ mutex_unlock(&ledctl->update_lock);
+}
+
+static void accton_as7312_54x_led_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode,
+ enum led_type type)
+{
+ int reg_val;
+ u8 reg ;
+ mutex_lock(&ledctl->update_lock);
+
+ if( !accton_getLedReg(type, ®))
+ {
+ dev_dbg(&ledctl->pdev->dev, "Not match item for %d.\n", type);
+ }
+
+ reg_val = accton_as7312_54x_led_read_value(reg);
+
+ if (reg_val < 0) {
+ dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val);
+ goto exit;
+ }
+ reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val);
+ accton_as7312_54x_led_write_value(reg, reg_val);
+
+ /* to prevent the slow-update issue */
+ ledctl->valid = 0;
+
+exit:
+ mutex_unlock(&ledctl->update_lock);
+}
+
+
+static void accton_as7312_54x_led_diag_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as7312_54x_led_set(led_cdev, led_light_mode, LED_TYPE_DIAG);
+}
+
+static enum led_brightness accton_as7312_54x_led_diag_get(struct led_classdev *cdev)
+{
+ accton_as7312_54x_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]);
+}
+
+static void accton_as7312_54x_led_loc_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+ accton_as7312_54x_led_set(led_cdev, led_light_mode, LED_TYPE_LOC);
+}
+
+static enum led_brightness accton_as7312_54x_led_loc_get(struct led_classdev *cdev)
+{
+ accton_as7312_54x_led_update();
+ return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]);
+}
+
+static void accton_as7312_54x_led_auto_set(struct led_classdev *led_cdev,
+ enum led_brightness led_light_mode)
+{
+}
+
+static enum led_brightness accton_as7312_54x_led_auto_get(struct led_classdev *cdev)
+{
+ return LED_MODE_AUTO;
+}
+
+static struct led_classdev accton_as7312_54x_leds[] = {
+ [LED_TYPE_DIAG] = {
+ .name = "accton_as7312_54x_led::diag",
+ .default_trigger = "unused",
+ .brightness_set = accton_as7312_54x_led_diag_set,
+ .brightness_get = accton_as7312_54x_led_diag_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_RED,
+ },
+ [LED_TYPE_LOC] = {
+ .name = "accton_as7312_54x_led::loc",
+ .default_trigger = "unused",
+ .brightness_set = accton_as7312_54x_led_loc_set,
+ .brightness_get = accton_as7312_54x_led_loc_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_BLUE,
+ },
+ [LED_TYPE_FAN] = {
+ .name = "accton_as7312_54x_led::fan",
+ .default_trigger = "unused",
+ .brightness_set = accton_as7312_54x_led_auto_set,
+ .brightness_get = accton_as7312_54x_led_auto_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_PSU1] = {
+ .name = "accton_as7312_54x_led::psu1",
+ .default_trigger = "unused",
+ .brightness_set = accton_as7312_54x_led_auto_set,
+ .brightness_get = accton_as7312_54x_led_auto_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+ [LED_TYPE_PSU2] = {
+ .name = "accton_as7312_54x_led::psu2",
+ .default_trigger = "unused",
+ .brightness_set = accton_as7312_54x_led_auto_set,
+ .brightness_get = accton_as7312_54x_led_auto_get,
+ .flags = LED_CORE_SUSPENDRESUME,
+ .max_brightness = LED_MODE_AUTO,
+ },
+};
+
+static int accton_as7312_54x_led_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ int i = 0;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as7312_54x_leds); i++) {
+ led_classdev_suspend(&accton_as7312_54x_leds[i]);
+ }
+
+ return 0;
+}
+
+static int accton_as7312_54x_led_resume(struct platform_device *dev)
+{
+ int i = 0;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as7312_54x_leds); i++) {
+ led_classdev_resume(&accton_as7312_54x_leds[i]);
+ }
+
+ return 0;
+}
+
+static int accton_as7312_54x_led_probe(struct platform_device *pdev)
+{
+ int ret, i;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as7312_54x_leds); i++) {
+ ret = led_classdev_register(&pdev->dev, &accton_as7312_54x_leds[i]);
+
+ if (ret < 0)
+ break;
+ }
+
+ /* Check if all LEDs were successfully registered */
+ if (i != ARRAY_SIZE(accton_as7312_54x_leds)) {
+ int j;
+
+ /* only unregister the LEDs that were successfully registered */
+ for (j = 0; j < i; j++) {
+ led_classdev_unregister(&accton_as7312_54x_leds[i]);
+ }
+ }
+
+ return ret;
+}
+
+static int accton_as7312_54x_led_remove(struct platform_device *pdev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(accton_as7312_54x_leds); i++) {
+ led_classdev_unregister(&accton_as7312_54x_leds[i]);
+ }
+
+ return 0;
+}
+
+static struct platform_driver accton_as7312_54x_led_driver = {
+ .probe = accton_as7312_54x_led_probe,
+ .remove = accton_as7312_54x_led_remove,
+ .suspend = accton_as7312_54x_led_suspend,
+ .resume = accton_as7312_54x_led_resume,
+ .driver = {
+ .name = DRVNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init accton_as7312_54x_led_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&accton_as7312_54x_led_driver);
+ if (ret < 0) {
+ goto exit;
+ }
+
+ ledctl = kzalloc(sizeof(struct accton_as7312_54x_led_data), GFP_KERNEL);
+ if (!ledctl) {
+ ret = -ENOMEM;
+ platform_driver_unregister(&accton_as7312_54x_led_driver);
+ goto exit;
+ }
+
+ mutex_init(&ledctl->update_lock);
+
+ ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
+ if (IS_ERR(ledctl->pdev)) {
+ ret = PTR_ERR(ledctl->pdev);
+ platform_driver_unregister(&accton_as7312_54x_led_driver);
+ kfree(ledctl);
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+static void __exit accton_as7312_54x_led_exit(void)
+{
+ platform_device_unregister(ledctl->pdev);
+ platform_driver_unregister(&accton_as7312_54x_led_driver);
+ kfree(ledctl);
+}
+
+module_init(accton_as7312_54x_led_init);
+module_exit(accton_as7312_54x_led_exit);
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton_as7312_54x_led driver");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_psu.c
new file mode 100644
index 00000000000..4646224ef90
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_psu.c
@@ -0,0 +1,277 @@
+/*
+ * An hwmon driver for accton as7312_54x Power Module
+ *
+ * Copyright (C) 2014 Accton Technology Corporation.
+ * Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf);
+static int as7312_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len);
+extern int as7312_54x_cpld_read(unsigned short cpld_addr, u8 reg);
+
+/* Addresses scanned
+ */
+static const unsigned short normal_i2c[] = { 0x50, 0x53, I2C_CLIENT_END };
+
+/* Each client has this additional data
+ */
+struct as7312_54x_psu_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 index; /* PSU index */
+ u8 status; /* Status(present/power_good) register read from CPLD */
+ char model_name[9]; /* Model name, read from eeprom */
+};
+
+static struct as7312_54x_psu_data *as7312_54x_psu_update_device(struct device *dev);
+
+enum as7312_54x_psu_sysfs_attributes {
+ PSU_PRESENT,
+ PSU_MODEL_NAME,
+ PSU_POWER_GOOD
+};
+
+/* sysfs attributes for hwmon
+ */
+static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT);
+static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME);
+static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD);
+
+static struct attribute *as7312_54x_psu_attributes[] = {
+ &sensor_dev_attr_psu_present.dev_attr.attr,
+ &sensor_dev_attr_psu_model_name.dev_attr.attr,
+ &sensor_dev_attr_psu_power_good.dev_attr.attr,
+ NULL
+};
+
+static ssize_t show_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct as7312_54x_psu_data *data = as7312_54x_psu_update_device(dev);
+ u8 status = 0;
+
+ if (attr->index == PSU_PRESENT) {
+ status = !(data->status >> (1-data->index) & 0x1);
+ }
+ else { /* PSU_POWER_GOOD */
+ status = (data->status >> (3-data->index) & 0x1);
+ }
+
+ return sprintf(buf, "%d\n", status);
+}
+
+static ssize_t show_model_name(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct as7312_54x_psu_data *data = as7312_54x_psu_update_device(dev);
+
+ return sprintf(buf, "%s\n", data->model_name);
+}
+
+static const struct attribute_group as7312_54x_psu_group = {
+ .attrs = as7312_54x_psu_attributes,
+};
+
+static int as7312_54x_psu_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ struct as7312_54x_psu_data *data;
+ int status;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ status = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct as7312_54x_psu_data), GFP_KERNEL);
+ if (!data) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ data->valid = 0;
+ data->index = dev_id->driver_data;
+ mutex_init(&data->update_lock);
+
+ dev_info(&client->dev, "chip found\n");
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &as7312_54x_psu_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "%s: psu '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &as7312_54x_psu_group);
+exit_free:
+ kfree(data);
+exit:
+
+ return status;
+}
+
+static int as7312_54x_psu_remove(struct i2c_client *client)
+{
+ struct as7312_54x_psu_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &as7312_54x_psu_group);
+ kfree(data);
+
+ return 0;
+}
+
+enum psu_index
+{
+ as7312_54x_psu1,
+ as7312_54x_psu2
+};
+
+static const struct i2c_device_id as7312_54x_psu_id[] = {
+ { "as7312_54x_psu1", as7312_54x_psu1 },
+ { "as7312_54x_psu2", as7312_54x_psu2 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, as7312_54x_psu_id);
+
+static struct i2c_driver as7312_54x_psu_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "as7312_54x_psu",
+ },
+ .probe = as7312_54x_psu_probe,
+ .remove = as7312_54x_psu_remove,
+ .id_table = as7312_54x_psu_id,
+ .address_list = normal_i2c,
+};
+
+static int as7312_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,
+ int data_len)
+{
+ int result = 0;
+ int retry_count = 5;
+
+ while (retry_count) {
+ retry_count--;
+
+ result = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
+
+ if (unlikely(result < 0)) {
+ msleep(10);
+ continue;
+ }
+
+ if (unlikely(result != data_len)) {
+ result = -EIO;
+ msleep(10);
+ continue;
+ }
+
+ result = 0;
+ break;
+ }
+
+ return result;
+}
+
+static struct as7312_54x_psu_data *as7312_54x_psu_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as7312_54x_psu_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int status;
+ int power_good = 0;
+
+ dev_dbg(&client->dev, "Starting as7312_54x update\n");
+
+ /* Read psu status */
+ status = as7312_54x_cpld_read(0x60, 0x2);
+
+ if (status < 0) {
+ dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status);
+ }
+ else {
+ data->status = status;
+ }
+
+ /* Read model name */
+ memset(data->model_name, 0, sizeof(data->model_name));
+ power_good = (data->status >> (3-data->index) & 0x1);
+
+ if (power_good) {
+ status = as7312_54x_psu_read_block(client, 0x20, data->model_name,
+ ARRAY_SIZE(data->model_name)-1);
+
+ if (status < 0) {
+ data->model_name[0] = '\0';
+ dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr);
+ }
+ else {
+ data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0';
+ }
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+module_i2c_driver(as7312_54x_psu_driver);
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("as7312_54x_psu driver");
+MODULE_LICENSE("GPL");
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_sfp.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_sfp.c
new file mode 100644
index 00000000000..921d9f892ca
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_sfp.c
@@ -0,0 +1,1972 @@
+/*
+ * SFP driver for accton as7312_54x sfp
+ *
+ * Copyright (C) Brandon Chuang
+ *
+ * Based on ad7414.c
+ * Copyright 2006 Stefan Roese , DENX Software Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define DRIVER_NAME "as7312_54x_sfp" /* Platform dependent */
+
+#define DEBUG_MODE 0
+
+#if (DEBUG_MODE == 1)
+#define DEBUG_PRINT(fmt, args...) \
+ printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args)
+#else
+#define DEBUG_PRINT(fmt, args...)
+#endif
+
+#define NUM_OF_PORT 54
+#define SFP_PORT_MAX 48
+#define EEPROM_NAME "sfp_eeprom"
+#define EEPROM_SIZE 256 /* 256 byte eeprom */
+#define BIT_INDEX(i) (1ULL << (i))
+#define USE_I2C_BLOCK_READ 1 /* Platform dependent */
+#define I2C_RW_RETRY_COUNT 10
+#define I2C_RW_RETRY_INTERVAL 60 /* ms */
+
+#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1)
+
+#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0
+#define SFF8024_DEVICE_ID_SFP 0x3
+#define SFF8024_DEVICE_ID_QSFP 0xC
+#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD
+#define SFF8024_DEVICE_ID_QSFP28 0x11
+
+#define SFF8472_DIAG_MON_TYPE_ADDR 92
+#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40
+#define SFF8436_RX_LOS_ADDR 3
+#define SFF8436_TX_FAULT_ADDR 4
+#define SFF8436_TX_DISABLE_ADDR 86
+
+#define MULTIPAGE_SUPPORT 1
+
+#if (MULTIPAGE_SUPPORT == 1)
+/* fundamental unit of addressing for SFF_8472/SFF_8436 */
+#define SFF_8436_PAGE_SIZE 128
+/*
+ * The current 8436 (QSFP) spec provides for only 4 supported
+ * pages (pages 0-3).
+ * This driver is prepared to support more, but needs a register in the
+ * EEPROM to indicate how many pages are supported before it is safe
+ * to implement more pages in the driver.
+ */
+#define SFF_8436_SPECED_PAGES 4
+#define SFF_8436_EEPROM_SIZE ((1 + SFF_8436_SPECED_PAGES) * SFF_8436_PAGE_SIZE)
+#define SFF_8436_EEPROM_UNPAGED_SIZE (2 * SFF_8436_PAGE_SIZE)
+/*
+ * The current 8472 (SFP) spec provides for only 3 supported
+ * pages (pages 0-2).
+ * This driver is prepared to support more, but needs a register in the
+ * EEPROM to indicate how many pages are supported before it is safe
+ * to implement more pages in the driver.
+ */
+#define SFF_8472_SPECED_PAGES 3
+#define SFF_8472_EEPROM_SIZE ((3 + SFF_8472_SPECED_PAGES) * SFF_8436_PAGE_SIZE)
+#define SFF_8472_EEPROM_UNPAGED_SIZE (4 * SFF_8436_PAGE_SIZE)
+
+/* a few constants to find our way around the EEPROM */
+#define SFF_8436_PAGE_SELECT_REG 0x7F
+#define SFF_8436_PAGEABLE_REG 0x02
+#define SFF_8436_NOT_PAGEABLE (1<<2)
+#define SFF_8472_PAGEABLE_REG 0x40
+#define SFF_8472_PAGEABLE (1<<4)
+
+/*
+ * This parameter is to help this driver avoid blocking other drivers out
+ * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C
+ * clock, one 256 byte read takes about 1/43 second which is excessive;
+ * but the 1/170 second it takes at 400 kHz may be quite reasonable; and
+ * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible.
+ *
+ * This value is forced to be a power of two so that writes align on pages.
+ */
+static unsigned io_limit = SFF_8436_PAGE_SIZE;
+
+/*
+ * specs often allow 5 msec for a page write, sometimes 20 msec;
+ * it's important to recover from write timeouts.
+ */
+static unsigned write_timeout = 25;
+
+typedef enum qsfp_opcode {
+ QSFP_READ_OP = 0,
+ QSFP_WRITE_OP = 1
+} qsfp_opcode_e;
+#endif
+
+/* Platform dependent +++ */
+#define I2C_ADDR_CPLD1 0x60
+#define I2C_ADDR_CPLD2 0x62
+#define I2C_ADDR_CPLD3 0x64
+
+#define CPLD3_OFFSET_QSFP_MOD_RST 0x17
+/* Platform dependent --- */
+static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf);
+static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);
+static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);;
+static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int);
+static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int);
+static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
+extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+enum sfp_sysfs_attributes {
+ PRESENT,
+ PRESENT_ALL,
+ PORT_NUMBER,
+ PORT_TYPE,
+ DDM_IMPLEMENTED,
+ TX_FAULT,
+ TX_FAULT1,
+ TX_FAULT2,
+ TX_FAULT3,
+ TX_FAULT4,
+ TX_DISABLE,
+ TX_DISABLE1,
+ TX_DISABLE2,
+ TX_DISABLE3,
+ TX_DISABLE4,
+ RX_LOS,
+ RX_LOS1,
+ RX_LOS2,
+ RX_LOS3,
+ RX_LOS4,
+ RX_LOS_ALL,
+ SFP_MOD_RST
+};
+
+/* SFP/QSFP common attributes for sysfs */
+static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER);
+static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT);
+static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL);
+static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS);
+static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE);
+static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT);
+
+/* QSFP attributes for sysfs */
+static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1);
+static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2);
+static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3);
+static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4);
+static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1);
+static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2);
+static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3);
+static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4);
+static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1);
+static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2);
+static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3);
+static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4);
+static SENSOR_DEVICE_ATTR(sfp_mod_rst, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, SFP_MOD_RST);
+
+static struct attribute *qsfp_attributes[] = {
+ &sensor_dev_attr_sfp_port_number.dev_attr.attr,
+ &sensor_dev_attr_sfp_is_present.dev_attr.attr,
+ &sensor_dev_attr_sfp_is_present_all.dev_attr.attr,
+ &sensor_dev_attr_sfp_rx_los.dev_attr.attr,
+ &sensor_dev_attr_sfp_rx_los1.dev_attr.attr,
+ &sensor_dev_attr_sfp_rx_los2.dev_attr.attr,
+ &sensor_dev_attr_sfp_rx_los3.dev_attr.attr,
+ &sensor_dev_attr_sfp_rx_los4.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_fault.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr,
+ &sensor_dev_attr_sfp_mod_rst.dev_attr.attr,
+ NULL
+};
+
+/* SFP msa attributes for sysfs */
+static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL);
+static struct attribute *sfp_msa_attributes[] = {
+ &sensor_dev_attr_sfp_port_number.dev_attr.attr,
+ &sensor_dev_attr_sfp_is_present.dev_attr.attr,
+ &sensor_dev_attr_sfp_is_present_all.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_fault.dev_attr.attr,
+ &sensor_dev_attr_sfp_rx_los.dev_attr.attr,
+ &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr,
+ &sensor_dev_attr_sfp_tx_disable.dev_attr.attr,
+ NULL
+};
+
+/* Platform dependent +++ */
+#define CPLD_PORT_TO_FRONT_PORT(port) (port+1)
+
+enum port_numbers {
+ as7312_54x_port1, as7312_54x_port2, as7312_54x_port3, as7312_54x_port4,
+ as7312_54x_port5, as7312_54x_port6, as7312_54x_port7, as7312_54x_port8,
+ as7312_54x_port9, as7312_54x_port10, as7312_54x_port11, as7312_54x_port12,
+ as7312_54x_port13, as7312_54x_port14, as7312_54x_port15, as7312_54x_port16,
+ as7312_54x_port17, as7312_54x_port18, as7312_54x_port19, as7312_54x_port20,
+ as7312_54x_port21, as7312_54x_port22, as7312_54x_port23, as7312_54x_port24,
+ as7312_54x_port25, as7312_54x_port26, as7312_54x_port27, as7312_54x_port28,
+ as7312_54x_port29, as7312_54x_port30, as7312_54x_port31, as7312_54x_port32,
+ as7312_54x_port33, as7312_54x_port34, as7312_54x_port35, as7312_54x_port36,
+ as7312_54x_port37, as7312_54x_port38, as7312_54x_port39, as7312_54x_port40,
+ as7312_54x_port41, as7312_54x_port42, as7312_54x_port43, as7312_54x_port44,
+ as7312_54x_port45, as7312_54x_port46, as7312_54x_port47, as7312_54x_port48,
+ as7312_54x_port49, as7312_54x_port52, as7312_54x_port50, as7312_54x_port53,
+ as7312_54x_port51, as7312_54x_port54
+};
+
+#define I2C_DEV_ID(x) { #x, x}
+
+static const struct i2c_device_id sfp_device_id[] = {
+ I2C_DEV_ID(as7312_54x_port1),
+ I2C_DEV_ID(as7312_54x_port2),
+ I2C_DEV_ID(as7312_54x_port3),
+ I2C_DEV_ID(as7312_54x_port4),
+ I2C_DEV_ID(as7312_54x_port5),
+ I2C_DEV_ID(as7312_54x_port6),
+ I2C_DEV_ID(as7312_54x_port7),
+ I2C_DEV_ID(as7312_54x_port8),
+ I2C_DEV_ID(as7312_54x_port9),
+ I2C_DEV_ID(as7312_54x_port10),
+ I2C_DEV_ID(as7312_54x_port11),
+ I2C_DEV_ID(as7312_54x_port12),
+ I2C_DEV_ID(as7312_54x_port13),
+ I2C_DEV_ID(as7312_54x_port14),
+ I2C_DEV_ID(as7312_54x_port15),
+ I2C_DEV_ID(as7312_54x_port16),
+ I2C_DEV_ID(as7312_54x_port17),
+ I2C_DEV_ID(as7312_54x_port18),
+ I2C_DEV_ID(as7312_54x_port19),
+ I2C_DEV_ID(as7312_54x_port20),
+ I2C_DEV_ID(as7312_54x_port21),
+ I2C_DEV_ID(as7312_54x_port22),
+ I2C_DEV_ID(as7312_54x_port23),
+ I2C_DEV_ID(as7312_54x_port24),
+ I2C_DEV_ID(as7312_54x_port25),
+ I2C_DEV_ID(as7312_54x_port26),
+ I2C_DEV_ID(as7312_54x_port27),
+ I2C_DEV_ID(as7312_54x_port28),
+ I2C_DEV_ID(as7312_54x_port29),
+ I2C_DEV_ID(as7312_54x_port30),
+ I2C_DEV_ID(as7312_54x_port31),
+ I2C_DEV_ID(as7312_54x_port32),
+ I2C_DEV_ID(as7312_54x_port33),
+ I2C_DEV_ID(as7312_54x_port34),
+ I2C_DEV_ID(as7312_54x_port35),
+ I2C_DEV_ID(as7312_54x_port36),
+ I2C_DEV_ID(as7312_54x_port37),
+ I2C_DEV_ID(as7312_54x_port38),
+ I2C_DEV_ID(as7312_54x_port39),
+ I2C_DEV_ID(as7312_54x_port40),
+ I2C_DEV_ID(as7312_54x_port41),
+ I2C_DEV_ID(as7312_54x_port42),
+ I2C_DEV_ID(as7312_54x_port43),
+ I2C_DEV_ID(as7312_54x_port44),
+ I2C_DEV_ID(as7312_54x_port45),
+ I2C_DEV_ID(as7312_54x_port46),
+ I2C_DEV_ID(as7312_54x_port47),
+ I2C_DEV_ID(as7312_54x_port48),
+ I2C_DEV_ID(as7312_54x_port49),
+ I2C_DEV_ID(as7312_54x_port50),
+ I2C_DEV_ID(as7312_54x_port51),
+ I2C_DEV_ID(as7312_54x_port52),
+ I2C_DEV_ID(as7312_54x_port53),
+ I2C_DEV_ID(as7312_54x_port54),
+ { /* LIST END */ }
+};
+MODULE_DEVICE_TABLE(i2c, sfp_device_id);
+/* Platform dependent --- */
+
+enum driver_type_e {
+ DRIVER_TYPE_SFP_MSA,
+ DRIVER_TYPE_QSFP
+};
+
+/* Each client has this additional data
+ */
+struct eeprom_data {
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ struct bin_attribute bin; /* eeprom data */
+};
+
+struct sfp_msa_data {
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u64 status[6]; /* bit0:port0, bit1:port1 and so on */
+ /* index 0 => tx_fail
+ 1 => tx_disable
+ 2 => rx_loss
+ 3 => device id
+ 4 => 10G Ethernet Compliance Codes
+ to distinguish SFP or SFP+
+ 5 => DIAGNOSTIC MONITORING TYPE */
+ struct eeprom_data eeprom;
+#if (MULTIPAGE_SUPPORT == 1)
+ struct i2c_client *ddm_client; /* dummy client instance for 0xA2 */
+#endif
+};
+
+struct qsfp_data {
+ char valid; /* !=0 if registers are valid */
+ unsigned long last_updated; /* In jiffies */
+ u8 status[3]; /* bit0:port0, bit1:port1 and so on */
+ /* index 0 => tx_fail
+ 1 => tx_disable
+ 2 => rx_loss */
+
+ u8 device_id;
+ struct eeprom_data eeprom;
+};
+
+struct sfp_port_data {
+ struct mutex update_lock;
+ enum driver_type_e driver_type;
+ int port; /* CPLD port index */
+ u64 present; /* present status, bit0:port0, bit1:port1 and so on */
+
+ struct sfp_msa_data *msa;
+ struct qsfp_data *qsfp;
+
+ struct i2c_client *client;
+#if (MULTIPAGE_SUPPORT == 1)
+ int use_smbus;
+ u8 *writebuf;
+ unsigned write_max;
+#endif
+};
+
+#if (MULTIPAGE_SUPPORT == 1)
+static ssize_t sfp_port_read_write(struct sfp_port_data *port_data,
+ char *buf, loff_t off, size_t len, qsfp_opcode_e opcode);
+#endif
+static ssize_t show_port_number(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+ return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port));
+}
+
+/* Platform dependent +++ */
+static struct sfp_port_data *sfp_update_present(struct i2c_client *client)
+{
+ int i = 0, j = 0, status = -1;
+ u8 reg;
+ unsigned short cpld_addr;
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+
+ DEBUG_PRINT("Starting sfp present status update");
+ mutex_lock(&data->update_lock);
+ data->present = 0;
+
+ /* Read present status of port 1~48(SFP port) */
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 3; j++) {
+ cpld_addr = I2C_ADDR_CPLD2 + i*2;
+ reg = 0x9+j;
+ status = accton_i2c_cpld_read(cpld_addr, reg);
+
+ if (unlikely(status < 0)) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status);
+ goto exit;
+ }
+
+ DEBUG_PRINT("Present status = 0x%lx\r\n", data->present);
+ data->present |= (u64)status << ((i*24) + (j%3)*8);
+ }
+ }
+
+ /* Read present status of port 49-52(QSFP port) */
+ cpld_addr = I2C_ADDR_CPLD2;
+ reg = 0x18;
+ status = accton_i2c_cpld_read(cpld_addr, reg);
+
+ if (unlikely(status < 0)) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status);
+ goto exit;
+ }
+ else {
+ data->present |= (u64)(status & 0xF) << SFP_PORT_MAX;
+ }
+
+ /* Read present status of port 53-54(QSFP port) */
+ cpld_addr = I2C_ADDR_CPLD3;
+ reg = 0x18;
+ status = accton_i2c_cpld_read(cpld_addr, reg);
+
+ if (unlikely(status < 0)) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status);
+ goto exit;
+ }
+ else {
+ data->present |= (u64)(status & 0x3) << 52;
+ }
+
+ DEBUG_PRINT("Present status = 0x%lx", data->present);
+exit:
+ mutex_unlock(&data->update_lock);
+ return (status < 0) ? ERR_PTR(status) : data;
+}
+
+static struct sfp_port_data* sfp_update_tx_rx_status(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+ int i = 0, j = 0;
+ int status = -1;
+
+ if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) {
+ return data;
+ }
+
+ DEBUG_PRINT("Starting as7312_54x sfp tx rx status update");
+ mutex_lock(&data->update_lock);
+ data->msa->valid = 0;
+ memset(data->msa->status, 0, sizeof(data->msa->status));
+
+ /* Read status of port 1~48(SFP port) */
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 9; j++) {
+ u8 reg;
+ unsigned short cpld_addr;
+ reg = 0xc+j;
+ cpld_addr = I2C_ADDR_CPLD2 + i*2;
+
+ status = accton_i2c_cpld_read(cpld_addr, reg);
+ if (unlikely(status < 0)) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status);
+ goto exit;
+ }
+
+ data->msa->status[j/3] |= (u64)status << ((i*24) + (j%3)*8);
+ }
+ }
+
+ data->msa->valid = 1;
+ data->msa->last_updated = jiffies;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return (status < 0) ? ERR_PTR(status) : data;
+}
+
+static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+ unsigned short cpld_addr = 0;
+ u8 cpld_reg = 0, cpld_val = 0, cpld_bit = 0;
+ long disable;
+ int error;
+
+ if (data->driver_type == DRIVER_TYPE_QSFP) {
+ return qsfp_set_tx_disable(dev, da, buf, count);
+ }
+
+ error = kstrtol(buf, 10, &disable);
+ if (error) {
+ return error;
+ }
+
+ mutex_lock(&data->update_lock);
+
+ if(data->port < 24) {
+ cpld_addr = I2C_ADDR_CPLD2;
+ cpld_reg = 0xF + data->port / 8;
+ cpld_bit = 1 << (data->port % 8);
+ }
+ else { /* port 24 ~ 48 */
+ cpld_addr = I2C_ADDR_CPLD3;
+ cpld_reg = 0xF + (data->port - 24) / 8;
+ cpld_bit = 1 << (data->port % 8);
+ }
+
+ /* Read current status */
+ cpld_val = accton_i2c_cpld_read(cpld_addr, cpld_reg);
+
+ /* Update tx_disable status */
+ if (disable) {
+ data->msa->status[1] |= BIT_INDEX(data->port);
+ cpld_val |= cpld_bit;
+ }
+ else {
+ data->msa->status[1] &= ~BIT_INDEX(data->port);
+ cpld_val &= ~cpld_bit;
+ }
+
+ accton_i2c_cpld_write(cpld_addr, cpld_reg, cpld_val);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static int sfp_is_port_present(struct i2c_client *client, int port)
+{
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+
+ data = sfp_update_present(client);
+ if (IS_ERR(data)) {
+ return PTR_ERR(data);
+ }
+
+ return (data->present & BIT_INDEX(data->port)) ? 0 : 1; /* Platform dependent */
+}
+
+/* Platform dependent +++ */
+static ssize_t show_present(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+
+ if (PRESENT_ALL == attr->index) {
+ int i;
+ u8 values[7] = {0};
+ struct sfp_port_data *data = sfp_update_present(client);
+
+ if (IS_ERR(data)) {
+ return PTR_ERR(data);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(values); i++) {
+ values[i] = ~(u8)(data->present >> (i * 8));
+ }
+
+ /* Return values 1 -> 54 in order */
+ return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n",
+ values[0], values[1], values[2],
+ values[3], values[4], values[5],
+ values[6] & 0x3F);
+ }
+ else {
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+ int present = sfp_is_port_present(client, data->port);
+
+ if (IS_ERR_VALUE(present)) {
+ return present;
+ }
+
+ /* PRESENT */
+ return sprintf(buf, "%d\n", present);
+ }
+}
+/* Platform dependent --- */
+
+static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+ int i, status = -1;
+ u8 buf = 0;
+ u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR};
+
+ if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) {
+ return data;
+ }
+
+ DEBUG_PRINT("Starting sfp tx rx status update");
+ mutex_lock(&data->update_lock);
+ data->qsfp->valid = 0;
+ memset(data->qsfp->status, 0, sizeof(data->qsfp->status));
+
+ /* Notify device to update tx fault/ tx disable/ rx los status */
+ for (i = 0; i < ARRAY_SIZE(reg); i++) {
+ status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf));
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+ }
+ msleep(200);
+
+ /* Read actual tx fault/ tx disable/ rx los status */
+ for (i = 0; i < ARRAY_SIZE(reg); i++) {
+ status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf));
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]);
+ data->qsfp->status[i] = (buf & 0xF);
+ }
+
+ data->qsfp->valid = 1;
+ data->qsfp->last_updated = jiffies;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return (status < 0) ? ERR_PTR(status) : data;
+}
+
+static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+ u8 cpld_val = 0;
+ int port_bit;
+ int status = -EINVAL;
+ u8 cpld_addr[] = {I2C_ADDR_CPLD2, I2C_ADDR_CPLD3};
+
+ /* Low power mode is not supported for SFP ports(1-48) */
+ if (data->port < SFP_PORT_MAX) {
+ return -EINVAL;
+ }
+ mutex_lock(&data->update_lock);
+
+ port_bit = data->port - SFP_PORT_MAX;
+ cpld_val = accton_i2c_cpld_read(cpld_addr[port_bit/4], CPLD3_OFFSET_QSFP_MOD_RST);
+
+ pr_err("[ROY]%s#%d, %x from %x\n", __func__, __LINE__, cpld_val, cpld_addr[port_bit/4]);
+
+ cpld_val = cpld_val & 0x0F;
+ cpld_val = cpld_val & BIT_INDEX(port_bit%4);
+
+ pr_err("[ROY]%s#%d, %x of bit %d\n", __func__, __LINE__, cpld_val, port_bit);
+
+ status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", cpld_val>>(port_bit%4));
+
+ mutex_unlock(&data->update_lock);
+
+ return status;
+}
+
+static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+ u8 cpld_val = 0;
+ long reset;
+ int error, port_bit;
+ u8 cpld_addr[] = {I2C_ADDR_CPLD2, I2C_ADDR_CPLD3};
+
+ pr_err("[ROY]%s#%d, port:%d\n", __func__, __LINE__, data->port);
+
+ /* Tx disable is not supported for QSFP ports(49-54) */
+ if (data->port < SFP_PORT_MAX) {
+ return -EINVAL;
+ }
+ port_bit = data->port - SFP_PORT_MAX;
+ error = kstrtol(buf, 10, &reset);
+
+ pr_err("[ROY]%s#%d, %s == %d\n", __func__, __LINE__, buf, error);
+ if (error) {
+ return error;
+ }
+ mutex_lock(&data->update_lock);
+
+ cpld_val = accton_i2c_cpld_read(cpld_addr[port_bit/4], CPLD3_OFFSET_QSFP_MOD_RST);
+ pr_err("[ROY]%s#%d, %x\n", __func__, __LINE__, cpld_val);
+ /* Update lp_mode status */
+ if (reset)
+ {
+ cpld_val |= BIT_INDEX(port_bit%4);
+ }
+ else
+ {
+ cpld_val &= ~BIT_INDEX(port_bit%4);
+ }
+ pr_err("[ROY]%s#%d, %x to %x\n", __func__, __LINE__, cpld_val, cpld_addr[port_bit/4]);
+
+ accton_i2c_cpld_write(cpld_addr[port_bit/4], CPLD3_OFFSET_QSFP_MOD_RST, cpld_val);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ int present;
+ u8 val = 0;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+
+ present = sfp_is_port_present(client, data->port);
+ if (IS_ERR_VALUE(present)) {
+ return present;
+ }
+
+ if (present == 0) {
+ /* port is not present */
+ return -ENXIO;
+ }
+
+ data = qsfp_update_tx_rx_status(dev);
+ if (IS_ERR(data)) {
+ return PTR_ERR(data);
+ }
+
+ switch (attr->index) {
+ case TX_FAULT:
+ val = !!(data->qsfp->status[2] & 0xF);
+ break;
+ case TX_FAULT1:
+ case TX_FAULT2:
+ case TX_FAULT3:
+ case TX_FAULT4:
+ val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1));
+ break;
+ case TX_DISABLE:
+ val = data->qsfp->status[1] & 0xF;
+ break;
+ case TX_DISABLE1:
+ case TX_DISABLE2:
+ case TX_DISABLE3:
+ case TX_DISABLE4:
+ val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1));
+ break;
+ case RX_LOS:
+ val = !!(data->qsfp->status[0] & 0xF);
+ break;
+ case RX_LOS1:
+ case RX_LOS2:
+ case RX_LOS3:
+ case RX_LOS4:
+ val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1));
+ break;
+ default:
+ break;
+ }
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ long disable;
+ int status;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+
+ status = sfp_is_port_present(client, data->port);
+ if (IS_ERR_VALUE(status)) {
+ return status;
+ }
+
+ if (!status) {
+ /* port is not present */
+ return -ENXIO;
+ }
+
+ status = kstrtol(buf, 10, &disable);
+ if (status) {
+ return status;
+ }
+
+ data = qsfp_update_tx_rx_status(dev);
+ if (IS_ERR(data)) {
+ return PTR_ERR(data);
+ }
+
+ mutex_lock(&data->update_lock);
+
+ if (attr->index == TX_DISABLE) {
+ if (disable) {
+ data->qsfp->status[1] |= 0xF;
+ }
+ else {
+ data->qsfp->status[1] &= ~0xF;
+ }
+ }
+ else {/* TX_DISABLE1 ~ TX_DISABLE4*/
+ if (disable) {
+ data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1));
+ }
+ else {
+ data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1));
+ }
+ }
+
+ DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]);
+ status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1]));
+ if (unlikely(status < 0)) {
+ count = status;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+/* Platform dependent +++ */
+static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ u8 val = 0, index = 0;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+
+ if (data->driver_type == DRIVER_TYPE_QSFP) {
+ return qsfp_show_tx_rx_status(dev, da, buf);
+ }
+
+ data = sfp_update_tx_rx_status(dev);
+ if (IS_ERR(data)) {
+ return PTR_ERR(data);
+ }
+
+ if(attr->index == RX_LOS_ALL) {
+ int i = 0;
+ u8 values[6] = {0};
+
+ for (i = 0; i < ARRAY_SIZE(values); i++) {
+ values[i] = (u8)(data->msa->status[2] >> (i * 8));
+ }
+
+ /** Return values 1 -> 48 in order */
+ return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n",
+ values[0], values[1], values[2],
+ values[3], values[4], values[5]);
+ }
+
+ switch (attr->index) {
+ case TX_FAULT:
+ index = 0;
+ break;
+ case TX_DISABLE:
+ index = 1;
+ break;
+ case RX_LOS:
+ index = 2;
+ break;
+ default:
+ return 0;
+ }
+
+ val = (data->msa->status[index] & BIT_INDEX(data->port)) ? 1 : 0;
+ return sprintf(buf, "%d\n", val);
+}
+/* Platform dependent --- */
+static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data,
+ int data_len)
+{
+#if USE_I2C_BLOCK_READ
+ int status, retry = I2C_RW_RETRY_COUNT;
+
+ if (data_len > I2C_SMBUS_BLOCK_MAX) {
+ data_len = I2C_SMBUS_BLOCK_MAX;
+ }
+
+ while (retry) {
+ status = i2c_smbus_write_i2c_block_data(client, command, data_len, data);
+ if (unlikely(status < 0)) {
+ msleep(I2C_RW_RETRY_INTERVAL);
+ retry--;
+ continue;
+ }
+
+ break;
+ }
+
+ if (unlikely(status < 0)) {
+ return status;
+ }
+
+ return data_len;
+#else
+ int status, retry = I2C_RW_RETRY_COUNT;
+
+ while (retry) {
+ status = i2c_smbus_write_byte_data(client, command, *data);
+ if (unlikely(status < 0)) {
+ msleep(I2C_RW_RETRY_INTERVAL);
+ retry--;
+ continue;
+ }
+
+ break;
+ }
+
+ if (unlikely(status < 0)) {
+ return status;
+ }
+
+ return 1;
+#endif
+
+
+}
+
+#if (MULTIPAGE_SUPPORT == 0)
+static ssize_t sfp_port_write(struct sfp_port_data *data,
+ const char *buf, loff_t off, size_t count)
+{
+ ssize_t retval = 0;
+
+ if (unlikely(!count)) {
+ return count;
+ }
+
+ /*
+ * Write data to chip, protecting against concurrent updates
+ * from this host, but not from other I2C masters.
+ */
+ mutex_lock(&data->update_lock);
+
+ while (count) {
+ ssize_t status;
+
+ status = sfp_eeprom_write(data->client, off, buf, count);
+ if (status <= 0) {
+ if (retval == 0) {
+ retval = status;
+ }
+ break;
+ }
+ buf += status;
+ off += status;
+ count -= status;
+ retval += status;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return retval;
+}
+#endif
+
+static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ int present;
+ struct sfp_port_data *data;
+ DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count);
+ data = dev_get_drvdata(container_of(kobj, struct device, kobj));
+
+ present = sfp_is_port_present(data->client, data->port);
+ if (IS_ERR_VALUE(present)) {
+ return present;
+ }
+
+ if (present == 0) {
+ /* port is not present */
+ return -ENODEV;
+ }
+
+#if (MULTIPAGE_SUPPORT == 1)
+ return sfp_port_read_write(data, buf, off, count, QSFP_WRITE_OP);
+#else
+ return sfp_port_write(data, buf, off, count);
+#endif
+}
+
+static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data,
+ int data_len)
+{
+#if USE_I2C_BLOCK_READ
+ int status, retry = I2C_RW_RETRY_COUNT;
+
+ if (data_len > I2C_SMBUS_BLOCK_MAX) {
+ data_len = I2C_SMBUS_BLOCK_MAX;
+ }
+
+ while (retry) {
+ status = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
+ if (unlikely(status < 0)) {
+ msleep(I2C_RW_RETRY_INTERVAL);
+ retry--;
+ continue;
+ }
+
+ break;
+ }
+
+ if (unlikely(status < 0)) {
+ goto abort;
+ }
+ if (unlikely(status != data_len)) {
+ status = -EIO;
+ goto abort;
+ }
+
+ //result = data_len;
+
+abort:
+ return status;
+#else
+ int status, retry = I2C_RW_RETRY_COUNT;
+
+ while (retry) {
+ status = i2c_smbus_read_byte_data(client, command);
+ if (unlikely(status < 0)) {
+ msleep(I2C_RW_RETRY_INTERVAL);
+ retry--;
+ continue;
+ }
+
+ break;
+ }
+
+ if (unlikely(status < 0)) {
+ dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status);
+ goto abort;
+ }
+
+ *data = (u8)status;
+ status = 1;
+
+abort:
+ return status;
+#endif
+}
+
+#if (MULTIPAGE_SUPPORT == 1)
+/*-------------------------------------------------------------------------*/
+/*
+ * This routine computes the addressing information to be used for
+ * a given r/w request.
+ *
+ * Task is to calculate the client (0 = i2c addr 50, 1 = i2c addr 51),
+ * the page, and the offset.
+ *
+ * Handles both SFP and QSFP.
+ * For SFP, offset 0-255 are on client[0], >255 is on client[1]
+ * Offset 256-383 are on the lower half of client[1]
+ * Pages are accessible on the upper half of client[1].
+ * Offset >383 are in 128 byte pages mapped into the upper half
+ *
+ * For QSFP, all offsets are on client[0]
+ * offset 0-127 are on the lower half of client[0] (no paging)
+ * Pages are accessible on the upper half of client[1].
+ * Offset >127 are in 128 byte pages mapped into the upper half
+ *
+ * Callers must not read/write beyond the end of a client or a page
+ * without recomputing the client/page. Hence offset (within page)
+ * plus length must be less than or equal to 128. (Note that this
+ * routine does not have access to the length of the call, hence
+ * cannot do the validity check.)
+ *
+ * Offset within Lower Page 00h and Upper Page 00h are not recomputed
+ */
+static uint8_t sff_8436_translate_offset(struct sfp_port_data *port_data,
+ loff_t *offset, struct i2c_client **client)
+{
+ unsigned page = 0;
+
+ *client = port_data->client;
+
+ /* if SFP style, offset > 255, shift to i2c addr 0x51 */
+ if (port_data->driver_type == DRIVER_TYPE_SFP_MSA) {
+ if (*offset > 255) {
+ /* like QSFP, but shifted to client[1] */
+ *client = port_data->msa->ddm_client;
+ *offset -= 256;
+ }
+ }
+
+ /*
+ * if offset is in the range 0-128...
+ * page doesn't matter (using lower half), return 0.
+ * offset is already correct (don't add 128 to get to paged area)
+ */
+ if (*offset < SFF_8436_PAGE_SIZE)
+ return page;
+
+ /* note, page will always be positive since *offset >= 128 */
+ page = (*offset >> 7)-1;
+ /* 0x80 places the offset in the top half, offset is last 7 bits */
+ *offset = SFF_8436_PAGE_SIZE + (*offset & 0x7f);
+
+ return page; /* note also returning client and offset */
+}
+
+static ssize_t sff_8436_eeprom_read(struct sfp_port_data *port_data,
+ struct i2c_client *client,
+ char *buf, unsigned offset, size_t count)
+{
+ struct i2c_msg msg[2];
+ u8 msgbuf[2];
+ unsigned long timeout, read_time;
+ int status, i;
+
+ memset(msg, 0, sizeof(msg));
+
+ switch (port_data->use_smbus) {
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ /*smaller eeproms can work given some SMBus extension calls */
+ if (count > I2C_SMBUS_BLOCK_MAX)
+ count = I2C_SMBUS_BLOCK_MAX;
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ /* Check for odd length transaction */
+ count = (count == 1) ? 1 : 2;
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ count = 1;
+ break;
+ default:
+ /*
+ * When we have a better choice than SMBus calls, use a
+ * combined I2C message. Write address; then read up to
+ * io_limit data bytes. msgbuf is u8 and will cast to our
+ * needs.
+ */
+ i = 0;
+ msgbuf[i++] = offset;
+
+ msg[0].addr = client->addr;
+ msg[0].buf = msgbuf;
+ msg[0].len = i;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].buf = buf;
+ msg[1].len = count;
+ }
+
+ /*
+ * Reads fail if the previous write didn't complete yet. We may
+ * loop a few times until this one succeeds, waiting at least
+ * long enough for one entire page write to work.
+ */
+ timeout = jiffies + msecs_to_jiffies(write_timeout);
+ do {
+ read_time = jiffies;
+
+ switch (port_data->use_smbus) {
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ status = i2c_smbus_read_i2c_block_data(client, offset,
+ count, buf);
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ status = i2c_smbus_read_word_data(client, offset);
+ if (status >= 0) {
+ buf[0] = status & 0xff;
+ if (count == 2)
+ buf[1] = status >> 8;
+ status = count;
+ }
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ status = i2c_smbus_read_byte_data(client, offset);
+ if (status >= 0) {
+ buf[0] = status;
+ status = count;
+ }
+ break;
+ default:
+ status = i2c_transfer(client->adapter, msg, 2);
+ if (status == 2)
+ status = count;
+ }
+
+ dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n",
+ count, offset, status, jiffies);
+
+ if (status == count) /* happy path */
+ return count;
+
+ if (status == -ENXIO) /* no module present */
+ return status;
+
+ /* REVISIT: at HZ=100, this is sloooow */
+ msleep(1);
+ } while (time_before(read_time, timeout));
+
+ return -ETIMEDOUT;
+}
+
+static ssize_t sff_8436_eeprom_write(struct sfp_port_data *port_data,
+ struct i2c_client *client,
+ const char *buf,
+ unsigned offset, size_t count)
+{
+ struct i2c_msg msg;
+ ssize_t status;
+ unsigned long timeout, write_time;
+ unsigned next_page_start;
+ int i = 0;
+
+ /* write max is at most a page
+ * (In this driver, write_max is actually one byte!)
+ */
+ if (count > port_data->write_max)
+ count = port_data->write_max;
+
+ /* shorten count if necessary to avoid crossing page boundary */
+ next_page_start = roundup(offset + 1, SFF_8436_PAGE_SIZE);
+ if (offset + count > next_page_start)
+ count = next_page_start - offset;
+
+ switch (port_data->use_smbus) {
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ /*smaller eeproms can work given some SMBus extension calls */
+ if (count > I2C_SMBUS_BLOCK_MAX)
+ count = I2C_SMBUS_BLOCK_MAX;
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ /* Check for odd length transaction */
+ count = (count == 1) ? 1 : 2;
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ count = 1;
+ break;
+ default:
+ /* If we'll use I2C calls for I/O, set up the message */
+ msg.addr = client->addr;
+ msg.flags = 0;
+
+ /* msg.buf is u8 and casts will mask the values */
+ msg.buf = port_data->writebuf;
+
+ msg.buf[i++] = offset;
+ memcpy(&msg.buf[i], buf, count);
+ msg.len = i + count;
+ break;
+ }
+
+ /*
+ * Reads fail if the previous write didn't complete yet. We may
+ * loop a few times until this one succeeds, waiting at least
+ * long enough for one entire page write to work.
+ */
+ timeout = jiffies + msecs_to_jiffies(write_timeout);
+ do {
+ write_time = jiffies;
+
+ switch (port_data->use_smbus) {
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ status = i2c_smbus_write_i2c_block_data(client,
+ offset, count, buf);
+ if (status == 0)
+ status = count;
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ if (count == 2) {
+ status = i2c_smbus_write_word_data(client,
+ offset, (u16)((buf[0])|(buf[1] << 8)));
+ } else {
+ /* count = 1 */
+ status = i2c_smbus_write_byte_data(client,
+ offset, buf[0]);
+ }
+ if (status == 0)
+ status = count;
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ status = i2c_smbus_write_byte_data(client, offset,
+ buf[0]);
+ if (status == 0)
+ status = count;
+ break;
+ default:
+ status = i2c_transfer(client->adapter, &msg, 1);
+ if (status == 1)
+ status = count;
+ break;
+ }
+
+ dev_dbg(&client->dev, "eeprom write %zu@%d --> %ld (%lu)\n",
+ count, offset, (long int) status, jiffies);
+
+ if (status == count)
+ return count;
+
+ /* REVISIT: at HZ=100, this is sloooow */
+ msleep(1);
+ } while (time_before(write_time, timeout));
+
+ return -ETIMEDOUT;
+}
+
+
+static ssize_t sff_8436_eeprom_update_client(struct sfp_port_data *port_data,
+ char *buf, loff_t off,
+ size_t count, qsfp_opcode_e opcode)
+{
+ struct i2c_client *client;
+ ssize_t retval = 0;
+ u8 page = 0;
+ loff_t phy_offset = off;
+ int ret = 0;
+
+ page = sff_8436_translate_offset(port_data, &phy_offset, &client);
+
+ dev_dbg(&client->dev,
+ "sff_8436_eeprom_update_client off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n",
+ off, page, phy_offset, (long int) count, opcode);
+ if (page > 0) {
+ ret = sff_8436_eeprom_write(port_data, client, &page,
+ SFF_8436_PAGE_SELECT_REG, 1);
+ if (ret < 0) {
+ dev_dbg(&client->dev,
+ "Write page register for page %d failed ret:%d!\n",
+ page, ret);
+ return ret;
+ }
+ }
+
+ while (count) {
+ ssize_t status;
+
+ if (opcode == QSFP_READ_OP) {
+ status = sff_8436_eeprom_read(port_data, client,
+ buf, phy_offset, count);
+ } else {
+ status = sff_8436_eeprom_write(port_data, client,
+ buf, phy_offset, count);
+ }
+ if (status <= 0) {
+ if (retval == 0)
+ retval = status;
+ break;
+ }
+ buf += status;
+ phy_offset += status;
+ count -= status;
+ retval += status;
+ }
+
+
+ if (page > 0) {
+ /* return the page register to page 0 (why?) */
+ page = 0;
+ ret = sff_8436_eeprom_write(port_data, client, &page,
+ SFF_8436_PAGE_SELECT_REG, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "Restore page register to page %d failed ret:%d!\n",
+ page, ret);
+ return ret;
+ }
+ }
+ return retval;
+}
+
+
+/*
+ * Figure out if this access is within the range of supported pages.
+ * Note this is called on every access because we don't know if the
+ * module has been replaced since the last call.
+ * If/when modules support more pages, this is the routine to update
+ * to validate and allow access to additional pages.
+ *
+ * Returns updated len for this access:
+ * - entire access is legal, original len is returned.
+ * - access begins legal but is too long, len is truncated to fit.
+ * - initial offset exceeds supported pages, return -EINVAL
+ */
+static ssize_t sff_8436_page_legal(struct sfp_port_data *port_data,
+ loff_t off, size_t len)
+{
+ struct i2c_client *client = port_data->client;
+ u8 regval;
+ int status;
+ size_t maxlen;
+
+ if (off < 0) return -EINVAL;
+ if (port_data->driver_type == DRIVER_TYPE_SFP_MSA) {
+ /* SFP case */
+ if ((off + len) <= 256) return len;
+ /* if no pages needed, we're good */
+ //if ((off + len) <= SFF_8472_EEPROM_UNPAGED_SIZE) return len;
+ /* if offset exceeds possible pages, we're not good */
+ if (off >= SFF_8472_EEPROM_SIZE) return -EINVAL;
+
+ /* Check if ddm is supported */
+ status = sff_8436_eeprom_read(port_data, client, ®val,
+ SFF8472_DIAG_MON_TYPE_ADDR, 1);
+ if (status < 0) return status; /* error out (no module?) */
+ if (!(regval & SFF8472_DIAG_MON_TYPE_DDM_MASK)) {
+ if (off >= 256) return -EINVAL;
+ maxlen = 256 - off;
+ }
+ else {
+ /* in between, are pages supported? */
+ status = sff_8436_eeprom_read(port_data, client, ®val,
+ SFF_8472_PAGEABLE_REG, 1);
+ if (status < 0) return status; /* error out (no module?) */
+ if (regval & SFF_8472_PAGEABLE) {
+ /* Pages supported, trim len to the end of pages */
+ maxlen = SFF_8472_EEPROM_SIZE - off;
+ } else {
+ /* pages not supported, trim len to unpaged size */
+ if (off >= SFF_8472_EEPROM_UNPAGED_SIZE) return -EINVAL;
+ maxlen = SFF_8472_EEPROM_UNPAGED_SIZE - off;
+ }
+ }
+ len = (len > maxlen) ? maxlen : len;
+ dev_dbg(&client->dev,
+ "page_legal, SFP, off %lld len %ld\n",
+ off, (long int) len);
+ }
+ else if (port_data->driver_type == DRIVER_TYPE_QSFP) {
+ /* QSFP case */
+ /* if no pages needed, we're good */
+ if ((off + len) <= SFF_8436_EEPROM_UNPAGED_SIZE) return len;
+ /* if offset exceeds possible pages, we're not good */
+ if (off >= SFF_8436_EEPROM_SIZE) return -EINVAL;
+ /* in between, are pages supported? */
+ status = sff_8436_eeprom_read(port_data, client, ®val,
+ SFF_8436_PAGEABLE_REG, 1);
+ if (status < 0) return status; /* error out (no module?) */
+ if (regval & SFF_8436_NOT_PAGEABLE) {
+ /* pages not supported, trim len to unpaged size */
+ if (off >= SFF_8436_EEPROM_UNPAGED_SIZE) return -EINVAL;
+ maxlen = SFF_8436_EEPROM_UNPAGED_SIZE - off;
+ } else {
+ /* Pages supported, trim len to the end of pages */
+ maxlen = SFF_8436_EEPROM_SIZE - off;
+ }
+ len = (len > maxlen) ? maxlen : len;
+ dev_dbg(&client->dev,
+ "page_legal, QSFP, off %lld len %ld\n",
+ off, (long int) len);
+ }
+ else {
+ return -EINVAL;
+ }
+ return len;
+}
+
+
+static ssize_t sfp_port_read_write(struct sfp_port_data *port_data,
+ char *buf, loff_t off, size_t len, qsfp_opcode_e opcode)
+{
+ struct i2c_client *client = port_data->client;
+ int chunk;
+ int status = 0;
+ ssize_t retval;
+ size_t pending_len = 0, chunk_len = 0;
+ loff_t chunk_offset = 0, chunk_start_offset = 0;
+
+ if (unlikely(!len))
+ return len;
+
+ /*
+ * Read data from chip, protecting against concurrent updates
+ * from this host, but not from other I2C masters.
+ */
+ mutex_lock(&port_data->update_lock);
+
+ /*
+ * Confirm this access fits within the device suppored addr range
+ */
+ len = sff_8436_page_legal(port_data, off, len);
+ if (len < 0) {
+ status = len;
+ goto err;
+ }
+
+ /*
+ * For each (128 byte) chunk involved in this request, issue a
+ * separate call to sff_eeprom_update_client(), to
+ * ensure that each access recalculates the client/page
+ * and writes the page register as needed.
+ * Note that chunk to page mapping is confusing, is different for
+ * QSFP and SFP, and never needs to be done. Don't try!
+ */
+ pending_len = len; /* amount remaining to transfer */
+ retval = 0; /* amount transferred */
+ for (chunk = off >> 7; chunk <= (off + len - 1) >> 7; chunk++) {
+
+ /*
+ * Compute the offset and number of bytes to be read/write
+ *
+ * 1. start at offset 0 (within the chunk), and read/write
+ * the entire chunk
+ * 2. start at offset 0 (within the chunk) and read/write less
+ * than entire chunk
+ * 3. start at an offset not equal to 0 and read/write the rest
+ * of the chunk
+ * 4. start at an offset not equal to 0 and read/write less than
+ * (end of chunk - offset)
+ */
+ chunk_start_offset = chunk * SFF_8436_PAGE_SIZE;
+
+ if (chunk_start_offset < off) {
+ chunk_offset = off;
+ if ((off + pending_len) < (chunk_start_offset +
+ SFF_8436_PAGE_SIZE))
+ chunk_len = pending_len;
+ else
+ chunk_len = (chunk+1)*SFF_8436_PAGE_SIZE - off;/*SFF_8436_PAGE_SIZE - off;*/
+ } else {
+ chunk_offset = chunk_start_offset;
+ if (pending_len > SFF_8436_PAGE_SIZE)
+ chunk_len = SFF_8436_PAGE_SIZE;
+ else
+ chunk_len = pending_len;
+ }
+
+ dev_dbg(&client->dev,
+ "sff_r/w: off %lld, len %ld, chunk_start_offset %lld, chunk_offset %lld, chunk_len %ld, pending_len %ld\n",
+ off, (long int) len, chunk_start_offset, chunk_offset,
+ (long int) chunk_len, (long int) pending_len);
+
+ /*
+ * note: chunk_offset is from the start of the EEPROM,
+ * not the start of the chunk
+ */
+ status = sff_8436_eeprom_update_client(port_data, buf,
+ chunk_offset, chunk_len, opcode);
+ if (status != chunk_len) {
+ /* This is another 'no device present' path */
+ dev_dbg(&client->dev,
+ "sff_8436_update_client for chunk %d chunk_offset %lld chunk_len %ld failed %d!\n",
+ chunk, chunk_offset, (long int) chunk_len, status);
+ goto err;
+ }
+ buf += status;
+ pending_len -= status;
+ retval += status;
+ }
+ mutex_unlock(&port_data->update_lock);
+
+ return retval;
+
+err:
+ mutex_unlock(&port_data->update_lock);
+
+ return status;
+}
+
+#else
+static ssize_t sfp_port_read(struct sfp_port_data *data,
+ char *buf, loff_t off, size_t count)
+{
+ ssize_t retval = 0;
+
+ if (unlikely(!count)) {
+ DEBUG_PRINT("Count = 0, return");
+ return count;
+ }
+
+ /*
+ * Read data from chip, protecting against concurrent updates
+ * from this host, but not from other I2C masters.
+ */
+ mutex_lock(&data->update_lock);
+
+ while (count) {
+ ssize_t status;
+
+ status = sfp_eeprom_read(data->client, off, buf, count);
+ if (status <= 0) {
+ if (retval == 0) {
+ retval = status;
+ }
+ break;
+ }
+
+ buf += status;
+ off += status;
+ count -= status;
+ retval += status;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return retval;
+
+}
+#endif
+
+static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ int present;
+ struct sfp_port_data *data;
+ DEBUG_PRINT("offset = (%d), count = (%d)", off, count);
+ data = dev_get_drvdata(container_of(kobj, struct device, kobj));
+
+ present = sfp_is_port_present(data->client, data->port);
+ if (IS_ERR_VALUE(present)) {
+ return present;
+ }
+
+ if (present == 0) {
+ /* port is not present */
+ return -ENODEV;
+ }
+
+#if (MULTIPAGE_SUPPORT == 1)
+ return sfp_port_read_write(data, buf, off, count, QSFP_READ_OP);
+#else
+ return sfp_port_read(data, buf, off, count);
+#endif
+}
+
+#if (MULTIPAGE_SUPPORT == 1)
+static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom, size_t size)
+#else
+static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom)
+#endif
+{
+ int err;
+
+ sysfs_bin_attr_init(eeprom);
+ eeprom->attr.name = EEPROM_NAME;
+ eeprom->attr.mode = S_IWUSR | S_IRUGO;
+ eeprom->read = sfp_bin_read;
+ eeprom->write = sfp_bin_write;
+#if (MULTIPAGE_SUPPORT == 1)
+ eeprom->size = size;
+#else
+ eeprom->size = EEPROM_SIZE;
+#endif
+
+ /* Create eeprom file */
+ err = sysfs_create_bin_file(kobj, eeprom);
+ if (err) {
+ return err;
+ }
+
+ return 0;
+}
+
+static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom)
+{
+ sysfs_remove_bin_file(kobj, eeprom);
+ return 0;
+}
+
+
+#if (MULTIPAGE_SUPPORT == 0)
+static int sfp_i2c_check_functionality(struct i2c_client *client)
+{
+#if USE_I2C_BLOCK_READ
+ return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK);
+#else
+ return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA);
+#endif
+}
+#endif
+
+static const struct attribute_group sfp_msa_group = {
+ .attrs = sfp_msa_attributes,
+};
+
+static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id,
+ struct sfp_msa_data **data)
+{
+ int status;
+ struct sfp_msa_data *msa;
+
+#if (MULTIPAGE_SUPPORT == 0)
+ if (!sfp_i2c_check_functionality(client)) {
+ status = -EIO;
+ goto exit;
+ }
+#endif
+
+ msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL);
+ if (!msa) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ /* init eeprom */
+#if (MULTIPAGE_SUPPORT == 1)
+ status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin, SFF_8436_EEPROM_SIZE);
+#else
+ status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin);
+#endif
+ if (status) {
+ goto exit_remove;
+ }
+
+#if (MULTIPAGE_SUPPORT == 1)
+ msa->ddm_client = i2c_new_dummy(client->adapter, client->addr + 1);
+ if (!msa->ddm_client) {
+ dev_err(&client->dev, "address 0x%02x unavailable\n", client->addr + 1);
+ status = -EADDRINUSE;
+ goto exit_eeprom;
+ }
+#endif
+
+ *data = msa;
+ dev_info(&client->dev, "sfp msa '%s'\n", client->name);
+
+ return 0;
+
+exit_eeprom:
+ sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &msa->eeprom.bin);
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &sfp_msa_group);
+exit_free:
+ kfree(msa);
+exit:
+
+ return status;
+}
+
+static const struct attribute_group qsfp_group = {
+ .attrs = qsfp_attributes,
+};
+
+static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id,
+ struct qsfp_data **data)
+{
+ int status;
+ struct qsfp_data *qsfp;
+
+#if (MULTIPAGE_SUPPORT == 0)
+ if (!sfp_i2c_check_functionality(client)) {
+ status = -EIO;
+ goto exit;
+ }
+#endif
+
+ qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL);
+ if (!qsfp) {
+ status = -ENOMEM;
+ goto exit;
+ }
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &qsfp_group);
+ if (status) {
+ goto exit_free;
+ }
+
+ /* init eeprom */
+#if (MULTIPAGE_SUPPORT == 1)
+ status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin, SFF_8436_EEPROM_SIZE);
+#else
+ status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin);
+#endif
+ if (status) {
+ goto exit_remove;
+ }
+
+ *data = qsfp;
+ dev_info(&client->dev, "qsfp '%s'\n", client->name);
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &qsfp_group);
+exit_free:
+ kfree(qsfp);
+exit:
+
+ return status;
+}
+
+/* Platform dependent +++ */
+static int sfp_device_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ int ret = 0;
+ struct sfp_port_data *data = NULL;
+
+ if (client->addr != SFP_EEPROM_A0_I2C_ADDR) {
+ return -ENODEV;
+ }
+
+ if (dev_id->driver_data < as7312_54x_port1 || dev_id->driver_data > as7312_54x_port54) {
+ return -ENXIO;
+ }
+
+ data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL);
+ if (!data) {
+ return -ENOMEM;
+ }
+
+#if (MULTIPAGE_SUPPORT == 1)
+ data->use_smbus = 0;
+
+ /* Use I2C operations unless we're stuck with SMBus extensions. */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+ data->use_smbus = I2C_SMBUS_I2C_BLOCK_DATA;
+ } else if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_WORD_DATA)) {
+ data->use_smbus = I2C_SMBUS_WORD_DATA;
+ } else if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
+ data->use_smbus = I2C_SMBUS_BYTE_DATA;
+ } else {
+ ret = -EPFNOSUPPORT;
+ goto exit_kfree;
+ }
+ }
+
+ if (!data->use_smbus ||
+ (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) ||
+ i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WRITE_WORD_DATA) ||
+ i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
+ /*
+ * NOTE: AN-2079
+ * Finisar recommends that the host implement 1 byte writes
+ * only since this module only supports 32 byte page boundaries.
+ * 2 byte writes are acceptable for PE and Vout changes per
+ * Application Note AN-2071.
+ */
+ unsigned write_max = 1;
+
+ if (write_max > io_limit)
+ write_max = io_limit;
+ if (data->use_smbus && write_max > I2C_SMBUS_BLOCK_MAX)
+ write_max = I2C_SMBUS_BLOCK_MAX;
+ data->write_max = write_max;
+
+ /* buffer (data + address at the beginning) */
+ data->writebuf = kmalloc(write_max + 2, GFP_KERNEL);
+ if (!data->writebuf) {
+ ret = -ENOMEM;
+ goto exit_kfree;
+ }
+ } else {
+ dev_warn(&client->dev,
+ "cannot write due to controller restrictions.");
+ }
+
+ if (data->use_smbus == I2C_SMBUS_WORD_DATA ||
+ data->use_smbus == I2C_SMBUS_BYTE_DATA) {
+ dev_notice(&client->dev, "Falling back to %s reads, "
+ "performance will suffer\n", data->use_smbus ==
+ I2C_SMBUS_WORD_DATA ? "word" : "byte");
+ }
+#endif
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+ data->port = dev_id->driver_data;
+ data->client = client;
+
+ if (dev_id->driver_data >= as7312_54x_port1 && dev_id->driver_data <= as7312_54x_port48) {
+ data->driver_type = DRIVER_TYPE_SFP_MSA;
+ ret = sfp_msa_probe(client, dev_id, &data->msa);
+ }
+ else { /* as7312_54x_portsfp49 ~ as7312_54x_portsfp54 */
+ data->driver_type = DRIVER_TYPE_QSFP;
+ ret = qsfp_probe(client, dev_id, &data->qsfp);
+ }
+
+ if (ret < 0) {
+ goto exit_kfree_buf;
+ }
+
+
+ return ret;
+
+exit_kfree_buf:
+#if (MULTIPAGE_SUPPORT == 1)
+ if (data->writebuf) kfree(data->writebuf);
+#endif
+
+exit_kfree:
+ kfree(data);
+ return ret;
+}
+/* Platform dependent --- */
+
+static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data)
+{
+ sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin);
+#if (MULTIPAGE_SUPPORT == 1)
+ i2c_unregister_device(data->ddm_client);
+#endif
+ sysfs_remove_group(&client->dev.kobj, &sfp_msa_group);
+ kfree(data);
+ return 0;
+}
+
+static int qfp_remove(struct i2c_client *client, struct qsfp_data *data)
+{
+ sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin);
+ sysfs_remove_group(&client->dev.kobj, &qsfp_group);
+ kfree(data);
+ return 0;
+}
+
+static int sfp_device_remove(struct i2c_client *client)
+{
+ int ret = 0;
+ struct sfp_port_data *data = i2c_get_clientdata(client);
+
+ switch (data->driver_type) {
+ case DRIVER_TYPE_SFP_MSA:
+ return sfp_msa_remove(client, data->msa);
+ case DRIVER_TYPE_QSFP:
+ return qfp_remove(client, data->qsfp);
+ }
+
+#if (MULTIPAGE_SUPPORT == 1)
+ if (data->writebuf)
+ kfree(data->writebuf);
+#endif
+ kfree(data);
+ return ret;
+}
+
+/* Addresses scanned
+ */
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+static struct i2c_driver sfp_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+ .probe = sfp_device_probe,
+ .remove = sfp_device_remove,
+ .id_table = sfp_device_id,
+ .address_list = normal_i2c,
+};
+
+static int __init sfp_init(void)
+{
+ return i2c_add_driver(&sfp_driver);
+}
+
+static void __exit sfp_exit(void)
+{
+ i2c_del_driver(&sfp_driver);
+}
+
+MODULE_AUTHOR("Brandon Chuang ");
+MODULE_DESCRIPTION("accton as7312_54x_sfp driver");
+MODULE_LICENSE("GPL");
+
+module_init(sfp_init);
+module_exit(sfp_exit);
+
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_i2c_cpld.c
new file mode 100644
index 00000000000..67ecd8e036a
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_i2c_cpld.c
@@ -0,0 +1,1219 @@
+/*
+ * Copyright (C) Brandon Chuang
+ *
+ * This module supports the accton cpld that hold the channel select
+ * mechanism for other i2c slave devices, such as SFP.
+ * This includes the:
+ * Accton as7312_54x CPLD1/CPLD2/CPLD3
+ *
+ * Based on:
+ * pca954x.c from Kumar Gala
+ * Copyright (C) 2006
+ *
+ * Based on:
+ * pca954x.c from Ken Harrenstien
+ * Copyright (C) 2004 Google, Inc. (Ken Harrenstien)
+ *
+ * Based on:
+ * i2c-virtual_cb.c from Brian Kuschak
+ * and
+ * pca9540.c from Jean Delvare .
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define I2C_RW_RETRY_COUNT 10
+#define I2C_RW_RETRY_INTERVAL 60 /* ms */
+
+static LIST_HEAD(cpld_client_list);
+static struct mutex list_lock;
+
+struct cpld_client_node {
+ struct i2c_client *client;
+ struct list_head list;
+};
+
+enum cpld_type {
+ as7312_54x_cpld1,
+ as7312_54x_cpld2,
+ as7312_54x_cpld3
+};
+
+struct as7312_54x_cpld_data {
+ enum cpld_type type;
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+};
+
+static const struct i2c_device_id as7312_54x_cpld_id[] = {
+ { "as7312_54x_cpld1", as7312_54x_cpld1 },
+ { "as7312_54x_cpld2", as7312_54x_cpld2 },
+ { "as7312_54x_cpld3", as7312_54x_cpld3 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, as7312_54x_cpld_id);
+
+#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index
+#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index
+#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index
+#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index
+#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index
+
+enum as7312_54x_cpld1_sysfs_attributes {
+ CPLD_VERSION,
+ ACCESS,
+ MODULE_PRESENT_ALL,
+ MODULE_RXLOS_ALL,
+ /* transceiver attributes */
+ TRANSCEIVER_PRESENT_ATTR_ID(1),
+ TRANSCEIVER_PRESENT_ATTR_ID(2),
+ TRANSCEIVER_PRESENT_ATTR_ID(3),
+ TRANSCEIVER_PRESENT_ATTR_ID(4),
+ TRANSCEIVER_PRESENT_ATTR_ID(5),
+ TRANSCEIVER_PRESENT_ATTR_ID(6),
+ TRANSCEIVER_PRESENT_ATTR_ID(7),
+ TRANSCEIVER_PRESENT_ATTR_ID(8),
+ TRANSCEIVER_PRESENT_ATTR_ID(9),
+ TRANSCEIVER_PRESENT_ATTR_ID(10),
+ TRANSCEIVER_PRESENT_ATTR_ID(11),
+ TRANSCEIVER_PRESENT_ATTR_ID(12),
+ TRANSCEIVER_PRESENT_ATTR_ID(13),
+ TRANSCEIVER_PRESENT_ATTR_ID(14),
+ TRANSCEIVER_PRESENT_ATTR_ID(15),
+ TRANSCEIVER_PRESENT_ATTR_ID(16),
+ TRANSCEIVER_PRESENT_ATTR_ID(17),
+ TRANSCEIVER_PRESENT_ATTR_ID(18),
+ TRANSCEIVER_PRESENT_ATTR_ID(19),
+ TRANSCEIVER_PRESENT_ATTR_ID(20),
+ TRANSCEIVER_PRESENT_ATTR_ID(21),
+ TRANSCEIVER_PRESENT_ATTR_ID(22),
+ TRANSCEIVER_PRESENT_ATTR_ID(23),
+ TRANSCEIVER_PRESENT_ATTR_ID(24),
+ TRANSCEIVER_PRESENT_ATTR_ID(25),
+ TRANSCEIVER_PRESENT_ATTR_ID(26),
+ TRANSCEIVER_PRESENT_ATTR_ID(27),
+ TRANSCEIVER_PRESENT_ATTR_ID(28),
+ TRANSCEIVER_PRESENT_ATTR_ID(29),
+ TRANSCEIVER_PRESENT_ATTR_ID(30),
+ TRANSCEIVER_PRESENT_ATTR_ID(31),
+ TRANSCEIVER_PRESENT_ATTR_ID(32),
+ TRANSCEIVER_PRESENT_ATTR_ID(33),
+ TRANSCEIVER_PRESENT_ATTR_ID(34),
+ TRANSCEIVER_PRESENT_ATTR_ID(35),
+ TRANSCEIVER_PRESENT_ATTR_ID(36),
+ TRANSCEIVER_PRESENT_ATTR_ID(37),
+ TRANSCEIVER_PRESENT_ATTR_ID(38),
+ TRANSCEIVER_PRESENT_ATTR_ID(39),
+ TRANSCEIVER_PRESENT_ATTR_ID(40),
+ TRANSCEIVER_PRESENT_ATTR_ID(41),
+ TRANSCEIVER_PRESENT_ATTR_ID(42),
+ TRANSCEIVER_PRESENT_ATTR_ID(43),
+ TRANSCEIVER_PRESENT_ATTR_ID(44),
+ TRANSCEIVER_PRESENT_ATTR_ID(45),
+ TRANSCEIVER_PRESENT_ATTR_ID(46),
+ TRANSCEIVER_PRESENT_ATTR_ID(47),
+ TRANSCEIVER_PRESENT_ATTR_ID(48),
+ TRANSCEIVER_PRESENT_ATTR_ID(49),
+ TRANSCEIVER_PRESENT_ATTR_ID(50),
+ TRANSCEIVER_PRESENT_ATTR_ID(51),
+ TRANSCEIVER_PRESENT_ATTR_ID(52),
+ TRANSCEIVER_PRESENT_ATTR_ID(53),
+ TRANSCEIVER_PRESENT_ATTR_ID(54),
+ TRANSCEIVER_RESET_ATTR_ID(49),
+ TRANSCEIVER_RESET_ATTR_ID(50),
+ TRANSCEIVER_RESET_ATTR_ID(51),
+ TRANSCEIVER_RESET_ATTR_ID(52),
+ TRANSCEIVER_RESET_ATTR_ID(53),
+ TRANSCEIVER_RESET_ATTR_ID(54),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(1),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(2),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(3),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(4),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(5),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(6),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(7),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(8),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(9),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(10),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(11),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(12),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(13),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(14),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(15),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(16),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(17),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(18),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(19),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(20),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(21),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(22),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(23),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(24),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(25),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(26),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(27),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(28),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(29),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(30),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(31),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(32),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(33),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(34),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(35),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(36),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(37),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(38),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(39),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(40),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(41),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(42),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(43),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(44),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(45),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(46),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(47),
+ TRANSCEIVER_TXDISABLE_ATTR_ID(48),
+ TRANSCEIVER_RXLOS_ATTR_ID(1),
+ TRANSCEIVER_RXLOS_ATTR_ID(2),
+ TRANSCEIVER_RXLOS_ATTR_ID(3),
+ TRANSCEIVER_RXLOS_ATTR_ID(4),
+ TRANSCEIVER_RXLOS_ATTR_ID(5),
+ TRANSCEIVER_RXLOS_ATTR_ID(6),
+ TRANSCEIVER_RXLOS_ATTR_ID(7),
+ TRANSCEIVER_RXLOS_ATTR_ID(8),
+ TRANSCEIVER_RXLOS_ATTR_ID(9),
+ TRANSCEIVER_RXLOS_ATTR_ID(10),
+ TRANSCEIVER_RXLOS_ATTR_ID(11),
+ TRANSCEIVER_RXLOS_ATTR_ID(12),
+ TRANSCEIVER_RXLOS_ATTR_ID(13),
+ TRANSCEIVER_RXLOS_ATTR_ID(14),
+ TRANSCEIVER_RXLOS_ATTR_ID(15),
+ TRANSCEIVER_RXLOS_ATTR_ID(16),
+ TRANSCEIVER_RXLOS_ATTR_ID(17),
+ TRANSCEIVER_RXLOS_ATTR_ID(18),
+ TRANSCEIVER_RXLOS_ATTR_ID(19),
+ TRANSCEIVER_RXLOS_ATTR_ID(20),
+ TRANSCEIVER_RXLOS_ATTR_ID(21),
+ TRANSCEIVER_RXLOS_ATTR_ID(22),
+ TRANSCEIVER_RXLOS_ATTR_ID(23),
+ TRANSCEIVER_RXLOS_ATTR_ID(24),
+ TRANSCEIVER_RXLOS_ATTR_ID(25),
+ TRANSCEIVER_RXLOS_ATTR_ID(26),
+ TRANSCEIVER_RXLOS_ATTR_ID(27),
+ TRANSCEIVER_RXLOS_ATTR_ID(28),
+ TRANSCEIVER_RXLOS_ATTR_ID(29),
+ TRANSCEIVER_RXLOS_ATTR_ID(30),
+ TRANSCEIVER_RXLOS_ATTR_ID(31),
+ TRANSCEIVER_RXLOS_ATTR_ID(32),
+ TRANSCEIVER_RXLOS_ATTR_ID(33),
+ TRANSCEIVER_RXLOS_ATTR_ID(34),
+ TRANSCEIVER_RXLOS_ATTR_ID(35),
+ TRANSCEIVER_RXLOS_ATTR_ID(36),
+ TRANSCEIVER_RXLOS_ATTR_ID(37),
+ TRANSCEIVER_RXLOS_ATTR_ID(38),
+ TRANSCEIVER_RXLOS_ATTR_ID(39),
+ TRANSCEIVER_RXLOS_ATTR_ID(40),
+ TRANSCEIVER_RXLOS_ATTR_ID(41),
+ TRANSCEIVER_RXLOS_ATTR_ID(42),
+ TRANSCEIVER_RXLOS_ATTR_ID(43),
+ TRANSCEIVER_RXLOS_ATTR_ID(44),
+ TRANSCEIVER_RXLOS_ATTR_ID(45),
+ TRANSCEIVER_RXLOS_ATTR_ID(46),
+ TRANSCEIVER_RXLOS_ATTR_ID(47),
+ TRANSCEIVER_RXLOS_ATTR_ID(48),
+ TRANSCEIVER_TXFAULT_ATTR_ID(1),
+ TRANSCEIVER_TXFAULT_ATTR_ID(2),
+ TRANSCEIVER_TXFAULT_ATTR_ID(3),
+ TRANSCEIVER_TXFAULT_ATTR_ID(4),
+ TRANSCEIVER_TXFAULT_ATTR_ID(5),
+ TRANSCEIVER_TXFAULT_ATTR_ID(6),
+ TRANSCEIVER_TXFAULT_ATTR_ID(7),
+ TRANSCEIVER_TXFAULT_ATTR_ID(8),
+ TRANSCEIVER_TXFAULT_ATTR_ID(9),
+ TRANSCEIVER_TXFAULT_ATTR_ID(10),
+ TRANSCEIVER_TXFAULT_ATTR_ID(11),
+ TRANSCEIVER_TXFAULT_ATTR_ID(12),
+ TRANSCEIVER_TXFAULT_ATTR_ID(13),
+ TRANSCEIVER_TXFAULT_ATTR_ID(14),
+ TRANSCEIVER_TXFAULT_ATTR_ID(15),
+ TRANSCEIVER_TXFAULT_ATTR_ID(16),
+ TRANSCEIVER_TXFAULT_ATTR_ID(17),
+ TRANSCEIVER_TXFAULT_ATTR_ID(18),
+ TRANSCEIVER_TXFAULT_ATTR_ID(19),
+ TRANSCEIVER_TXFAULT_ATTR_ID(20),
+ TRANSCEIVER_TXFAULT_ATTR_ID(21),
+ TRANSCEIVER_TXFAULT_ATTR_ID(22),
+ TRANSCEIVER_TXFAULT_ATTR_ID(23),
+ TRANSCEIVER_TXFAULT_ATTR_ID(24),
+ TRANSCEIVER_TXFAULT_ATTR_ID(25),
+ TRANSCEIVER_TXFAULT_ATTR_ID(26),
+ TRANSCEIVER_TXFAULT_ATTR_ID(27),
+ TRANSCEIVER_TXFAULT_ATTR_ID(28),
+ TRANSCEIVER_TXFAULT_ATTR_ID(29),
+ TRANSCEIVER_TXFAULT_ATTR_ID(30),
+ TRANSCEIVER_TXFAULT_ATTR_ID(31),
+ TRANSCEIVER_TXFAULT_ATTR_ID(32),
+ TRANSCEIVER_TXFAULT_ATTR_ID(33),
+ TRANSCEIVER_TXFAULT_ATTR_ID(34),
+ TRANSCEIVER_TXFAULT_ATTR_ID(35),
+ TRANSCEIVER_TXFAULT_ATTR_ID(36),
+ TRANSCEIVER_TXFAULT_ATTR_ID(37),
+ TRANSCEIVER_TXFAULT_ATTR_ID(38),
+ TRANSCEIVER_TXFAULT_ATTR_ID(39),
+ TRANSCEIVER_TXFAULT_ATTR_ID(40),
+ TRANSCEIVER_TXFAULT_ATTR_ID(41),
+ TRANSCEIVER_TXFAULT_ATTR_ID(42),
+ TRANSCEIVER_TXFAULT_ATTR_ID(43),
+ TRANSCEIVER_TXFAULT_ATTR_ID(44),
+ TRANSCEIVER_TXFAULT_ATTR_ID(45),
+ TRANSCEIVER_TXFAULT_ATTR_ID(46),
+ TRANSCEIVER_TXFAULT_ATTR_ID(47),
+ TRANSCEIVER_TXFAULT_ATTR_ID(48),
+};
+
+/* sysfs attributes for hwmon
+ */
+static ssize_t show_status(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da,
+ char *buf);
+static ssize_t set_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t access(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count);
+static ssize_t show_version(struct device *dev, struct device_attribute *da,
+ char *buf);
+static int as7312_54x_cpld_read_internal(struct i2c_client *client, u8 reg);
+static int as7312_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value);
+
+/* transceiver attributes */
+#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \
+ static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index)
+#define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr
+
+#define DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(index) \
+ static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO | S_IWUSR, show_status, set_reset, MODULE_RESET_##index)
+#define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr
+
+#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \
+ static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \
+ static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \
+ static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index)
+#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \
+ &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \
+ &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \
+ &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr
+
+static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION);
+static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS);
+/* transceiver attributes */
+static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL);
+static SENSOR_DEVICE_ATTR(module_rx_los_all, S_IRUGO, show_rxlos_all, NULL, MODULE_RXLOS_ALL);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(1);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(2);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(3);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(4);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(5);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(6);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(7);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(8);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(9);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(10);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(11);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(12);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(13);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(14);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(15);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(16);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(17);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(18);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(19);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(20);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(21);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(22);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(23);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(24);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(25);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(26);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(27);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(28);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(29);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(30);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(31);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(32);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(33);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(34);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(35);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(36);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(37);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(38);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(39);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(40);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(41);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(42);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(43);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(44);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(45);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(46);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(47);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(48);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(49);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(50);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(51);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(52);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(53);
+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(54);
+
+DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(49);
+DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(50);
+DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(51);
+DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(52);
+DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(53);
+DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(54);
+
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(1);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(2);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(3);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(4);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(5);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(6);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(7);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(8);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(9);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(10);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(11);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(12);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(13);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(14);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(15);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(16);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(17);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(18);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(19);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(20);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(21);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(22);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(23);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(24);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(25);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(26);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(27);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(28);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(29);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(30);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(31);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(32);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(33);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(35);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(36);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(37);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(38);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(39);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(40);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(41);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(42);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(43);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(44);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47);
+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48);
+
+static struct attribute *as7312_54x_cpld1_attributes[] = {
+ &sensor_dev_attr_version.dev_attr.attr,
+ &sensor_dev_attr_access.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group as7312_54x_cpld1_group = {
+ .attrs = as7312_54x_cpld1_attributes,
+};
+
+static struct attribute *as7312_54x_cpld2_attributes[] = {
+ &sensor_dev_attr_version.dev_attr.attr,
+ &sensor_dev_attr_access.dev_attr.attr,
+ /* transceiver attributes */
+ &sensor_dev_attr_module_present_all.dev_attr.attr,
+ &sensor_dev_attr_module_rx_los_all.dev_attr.attr,
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(1),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(2),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(3),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(4),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(5),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(6),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(7),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(8),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(9),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(10),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(11),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(12),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(13),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(14),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(15),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(16),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(17),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(18),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(19),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(20),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(21),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(22),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(23),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(24),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(49),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(50),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(51),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(52),
+ DECLARE_TRANSCEIVER_RESET_ATTR(49),
+ DECLARE_TRANSCEIVER_RESET_ATTR(50),
+ DECLARE_TRANSCEIVER_RESET_ATTR(51),
+ DECLARE_TRANSCEIVER_RESET_ATTR(52),
+ DECLARE_SFP_TRANSCEIVER_ATTR(1),
+ DECLARE_SFP_TRANSCEIVER_ATTR(2),
+ DECLARE_SFP_TRANSCEIVER_ATTR(3),
+ DECLARE_SFP_TRANSCEIVER_ATTR(4),
+ DECLARE_SFP_TRANSCEIVER_ATTR(5),
+ DECLARE_SFP_TRANSCEIVER_ATTR(6),
+ DECLARE_SFP_TRANSCEIVER_ATTR(7),
+ DECLARE_SFP_TRANSCEIVER_ATTR(8),
+ DECLARE_SFP_TRANSCEIVER_ATTR(9),
+ DECLARE_SFP_TRANSCEIVER_ATTR(10),
+ DECLARE_SFP_TRANSCEIVER_ATTR(11),
+ DECLARE_SFP_TRANSCEIVER_ATTR(12),
+ DECLARE_SFP_TRANSCEIVER_ATTR(13),
+ DECLARE_SFP_TRANSCEIVER_ATTR(14),
+ DECLARE_SFP_TRANSCEIVER_ATTR(15),
+ DECLARE_SFP_TRANSCEIVER_ATTR(16),
+ DECLARE_SFP_TRANSCEIVER_ATTR(17),
+ DECLARE_SFP_TRANSCEIVER_ATTR(18),
+ DECLARE_SFP_TRANSCEIVER_ATTR(19),
+ DECLARE_SFP_TRANSCEIVER_ATTR(20),
+ DECLARE_SFP_TRANSCEIVER_ATTR(21),
+ DECLARE_SFP_TRANSCEIVER_ATTR(22),
+ DECLARE_SFP_TRANSCEIVER_ATTR(23),
+ DECLARE_SFP_TRANSCEIVER_ATTR(24),
+ NULL
+};
+
+static const struct attribute_group as7312_54x_cpld2_group = {
+ .attrs = as7312_54x_cpld2_attributes,
+};
+
+static struct attribute *as7312_54x_cpld3_attributes[] = {
+ &sensor_dev_attr_version.dev_attr.attr,
+ &sensor_dev_attr_access.dev_attr.attr,
+ /* transceiver attributes */
+ &sensor_dev_attr_module_present_all.dev_attr.attr,
+ &sensor_dev_attr_module_rx_los_all.dev_attr.attr,
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(25),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(26),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(27),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(28),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(29),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(30),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(31),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(32),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(33),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(34),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(35),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(36),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(37),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(38),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(39),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(40),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(41),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(42),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(43),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(44),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(45),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(46),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(47),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(48),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(53),
+ DECLARE_TRANSCEIVER_PRESENT_ATTR(54),
+ DECLARE_TRANSCEIVER_RESET_ATTR(53),
+ DECLARE_TRANSCEIVER_RESET_ATTR(54),
+ DECLARE_SFP_TRANSCEIVER_ATTR(25),
+ DECLARE_SFP_TRANSCEIVER_ATTR(26),
+ DECLARE_SFP_TRANSCEIVER_ATTR(27),
+ DECLARE_SFP_TRANSCEIVER_ATTR(28),
+ DECLARE_SFP_TRANSCEIVER_ATTR(29),
+ DECLARE_SFP_TRANSCEIVER_ATTR(30),
+ DECLARE_SFP_TRANSCEIVER_ATTR(31),
+ DECLARE_SFP_TRANSCEIVER_ATTR(32),
+ DECLARE_SFP_TRANSCEIVER_ATTR(33),
+ DECLARE_SFP_TRANSCEIVER_ATTR(34),
+ DECLARE_SFP_TRANSCEIVER_ATTR(35),
+ DECLARE_SFP_TRANSCEIVER_ATTR(36),
+ DECLARE_SFP_TRANSCEIVER_ATTR(37),
+ DECLARE_SFP_TRANSCEIVER_ATTR(38),
+ DECLARE_SFP_TRANSCEIVER_ATTR(39),
+ DECLARE_SFP_TRANSCEIVER_ATTR(40),
+ DECLARE_SFP_TRANSCEIVER_ATTR(41),
+ DECLARE_SFP_TRANSCEIVER_ATTR(42),
+ DECLARE_SFP_TRANSCEIVER_ATTR(43),
+ DECLARE_SFP_TRANSCEIVER_ATTR(44),
+ DECLARE_SFP_TRANSCEIVER_ATTR(45),
+ DECLARE_SFP_TRANSCEIVER_ATTR(46),
+ DECLARE_SFP_TRANSCEIVER_ATTR(47),
+ DECLARE_SFP_TRANSCEIVER_ATTR(48),
+ NULL
+};
+
+static const struct attribute_group as7312_54x_cpld3_group = {
+ .attrs = as7312_54x_cpld3_attributes,
+};
+
+static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ int i, status;
+ u8 values[4] = {0};
+ u8 regs[] = {0x9, 0xA, 0xB, 0x18};
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as7312_54x_cpld_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ status = as7312_54x_cpld_read_internal(client, regs[i]);
+
+ if (status < 0) {
+ goto exit;
+ }
+
+ values[i] = ~(u8)status;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ /* Return values 1 -> 54 in order */
+ if (data->type == as7312_54x_cpld2) {
+ values[3] &= 0xF;
+ }
+ else { /* as7312_54x_cpld3 */
+ values[3] &= 0x3;
+ }
+
+ return sprintf(buf, "%.2x %.2x %.2x %.2x\n",
+ values[0], values[1], values[2], values[3]);
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ int i, status;
+ u8 values[3] = {0};
+ u8 regs[] = {0x12, 0x13, 0x14};
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as7312_54x_cpld_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ status = as7312_54x_cpld_read_internal(client, regs[i]);
+
+ if (status < 0) {
+ goto exit;
+ }
+
+ values[i] = (u8)status;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ /* Return values 1 -> 24 in order */
+ return sprintf(buf, "%.2x %.2x %.2x\n", values[0], values[1], values[2]);
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static ssize_t show_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as7312_54x_cpld_data *data = i2c_get_clientdata(client);
+ int status = 0;
+ u8 reg = 0, mask = 0, revert = 0;
+
+ switch (attr->index) {
+ case MODULE_PRESENT_1 ... MODULE_PRESENT_8:
+ reg = 0x9;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_1);
+ break;
+ case MODULE_PRESENT_9 ... MODULE_PRESENT_16:
+ reg = 0xA;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_9);
+ break;
+ case MODULE_PRESENT_17 ... MODULE_PRESENT_24:
+ reg = 0xB;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_17);
+ break;
+ case MODULE_PRESENT_25 ... MODULE_PRESENT_32:
+ reg = 0x9;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_25);
+ break;
+ case MODULE_PRESENT_33 ... MODULE_PRESENT_40:
+ reg = 0xA;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_33);
+ break;
+ case MODULE_PRESENT_41 ... MODULE_PRESENT_48:
+ reg = 0xB;
+ mask = 0x1 << (attr->index - MODULE_PRESENT_41);
+ break;
+ case MODULE_PRESENT_49:
+ reg = 0x18;
+ mask = 0x1;
+ break;
+ case MODULE_PRESENT_50:
+ reg = 0x18;
+ mask = 0x2;
+ break;
+ case MODULE_PRESENT_51:
+ reg = 0x18;
+ mask = 0x4;
+ break;
+ case MODULE_PRESENT_52:
+ reg = 0x18;
+ mask = 0x8;
+ break;
+ case MODULE_PRESENT_53:
+ reg = 0x18;
+ mask = 0x1;
+ break;
+ case MODULE_PRESENT_54:
+ reg = 0x18;
+ mask = 0x2;
+ break;
+
+ case MODULE_RESET_49 ... MODULE_RESET_54:
+ reg = 0x17;
+ mask = 1 << ((attr->index - MODULE_PRESENT_49)%4);
+ break;
+
+ case MODULE_TXFAULT_1 ... MODULE_TXFAULT_8:
+ reg = 0xC;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_1);
+ break;
+ case MODULE_TXFAULT_9 ... MODULE_TXFAULT_16:
+ reg = 0xD;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_9);
+ break;
+ case MODULE_TXFAULT_17 ... MODULE_TXFAULT_24:
+ reg = 0xE;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_17);
+ break;
+ case MODULE_TXFAULT_25 ... MODULE_TXFAULT_32:
+ reg = 0xC;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_25);
+ break;
+ case MODULE_TXFAULT_33 ... MODULE_TXFAULT_40:
+ reg = 0xD;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_33);
+ break;
+ case MODULE_TXFAULT_41 ... MODULE_TXFAULT_48:
+ reg = 0xE;
+ mask = 0x1 << (attr->index - MODULE_TXFAULT_41);
+ break;
+ case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8:
+ reg = 0xF;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_1);
+ break;
+ case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16:
+ reg = 0x10;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_9);
+ break;
+ case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24:
+ reg = 0x11;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_17);
+ break;
+ case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32:
+ reg = 0xF;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_25);
+ break;
+ case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40:
+ reg = 0x10;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_33);
+ break;
+ case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48:
+ reg = 0x11;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_41);
+ break;
+ case MODULE_RXLOS_1 ... MODULE_RXLOS_8:
+ reg = 0x12;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_1);
+ break;
+ case MODULE_RXLOS_9 ... MODULE_RXLOS_16:
+ reg = 0x13;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_9);
+ break;
+ case MODULE_RXLOS_17 ... MODULE_RXLOS_24:
+ reg = 0x14;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_17);
+ break;
+ case MODULE_RXLOS_25 ... MODULE_RXLOS_32:
+ reg = 0x12;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_25);
+ break;
+ case MODULE_RXLOS_33 ... MODULE_RXLOS_40:
+ reg = 0x13;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_33);
+ break;
+ case MODULE_RXLOS_41 ... MODULE_RXLOS_48:
+ reg = 0x14;
+ mask = 0x1 << (attr->index - MODULE_RXLOS_41);
+ break;
+ default:
+ return 0;
+ }
+
+ if (attr->index >= MODULE_PRESENT_1 && attr->index <= MODULE_PRESENT_54) {
+ revert = 1;
+ }
+
+ mutex_lock(&data->update_lock);
+ status = as7312_54x_cpld_read_internal(client, reg);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+ mutex_unlock(&data->update_lock);
+
+ return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask));
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static ssize_t set_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as7312_54x_cpld_data *data = i2c_get_clientdata(client);
+ long reset;
+ int status;
+ u8 reg = 0, mask = 0;
+
+ status = kstrtol(buf, 10, &reset);
+ if (status) {
+ return status;
+ }
+
+ switch (attr->index) {
+ case MODULE_RESET_49 ... MODULE_RESET_54:
+ reg = 0x17;
+ mask = 1 << ((attr->index - MODULE_RESET_49)%4);
+ break;
+ default:
+ return 0;
+ }
+
+ /* Read current status */
+ mutex_lock(&data->update_lock);
+ status = as7312_54x_cpld_read_internal(client, reg);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ /* Update reset status */
+ if (reset) {
+ status |= mask;
+ }
+ else {
+ status &= ~mask;
+ }
+ status = as7312_54x_cpld_write_internal(client, reg, status);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return count;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+
+
+
+static ssize_t set_tx_disable(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 as7312_54x_cpld_data *data = i2c_get_clientdata(client);
+ long disable;
+ int status;
+ u8 reg = 0, mask = 0;
+
+ status = kstrtol(buf, 10, &disable);
+ if (status) {
+ return status;
+ }
+
+ switch (attr->index) {
+ case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8:
+ reg = 0xF;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_1);
+ break;
+ case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16:
+ reg = 0x10;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_9);
+ break;
+ case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24:
+ reg = 0x11;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_17);
+ break;
+ case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32:
+ reg = 0xF;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_25);
+ break;
+ case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40:
+ reg = 0x10;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_33);
+ break;
+ case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48:
+ reg = 0x11;
+ mask = 0x1 << (attr->index - MODULE_TXDISABLE_41);
+ break;
+ default:
+ return 0;
+ }
+
+ /* Read current status */
+ mutex_lock(&data->update_lock);
+ status = as7312_54x_cpld_read_internal(client, reg);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ /* Update tx_disable status */
+ if (disable) {
+ status |= mask;
+ }
+ else {
+ status &= ~mask;
+ }
+
+ status = as7312_54x_cpld_write_internal(client, reg, status);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return count;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static ssize_t access(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ int status;
+ u32 addr, val;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct as7312_54x_cpld_data *data = i2c_get_clientdata(client);
+
+ if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
+ return -EINVAL;
+ }
+
+ if (addr > 0xFF || val > 0xFF) {
+ return -EINVAL;
+ }
+
+ mutex_lock(&data->update_lock);
+ status = as7312_54x_cpld_write_internal(client, addr, val);
+ if (unlikely(status < 0)) {
+ goto exit;
+ }
+ mutex_unlock(&data->update_lock);
+ return count;
+
+exit:
+ mutex_unlock(&data->update_lock);
+ return status;
+}
+
+static void as7312_54x_cpld_add_client(struct i2c_client *client)
+{
+ struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL);
+
+ if (!node) {
+ dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr);
+ return;
+ }
+
+ node->client = client;
+
+ mutex_lock(&list_lock);
+ list_add(&node->list, &cpld_client_list);
+ mutex_unlock(&list_lock);
+}
+
+static void as7312_54x_cpld_remove_client(struct i2c_client *client)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int found = 0;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client == client) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ list_del(list_node);
+ kfree(cpld_node);
+ }
+
+ mutex_unlock(&list_lock);
+}
+
+static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int val = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+
+ val = i2c_smbus_read_byte_data(client, 0x1);
+
+ if (val < 0) {
+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val);
+ }
+
+ return sprintf(buf, "%d", val);
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+static int as7312_54x_cpld_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
+ struct as7312_54x_cpld_data *data;
+ int ret = -ENODEV;
+ const struct attribute_group *group = NULL;
+
+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
+ goto exit;
+
+ data = kzalloc(sizeof(struct as7312_54x_cpld_data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+ data->type = id->driver_data;
+
+ /* Register sysfs hooks */
+ switch (data->type) {
+ case as7312_54x_cpld1:
+ group = &as7312_54x_cpld1_group;
+ break;
+ case as7312_54x_cpld2:
+ group = &as7312_54x_cpld2_group;
+ break;
+ case as7312_54x_cpld3:
+ group = &as7312_54x_cpld3_group;
+ break;
+ default:
+ break;
+ }
+
+ if (group) {
+ ret = sysfs_create_group(&client->dev.kobj, group);
+ if (ret) {
+ goto exit_free;
+ }
+ }
+
+ as7312_54x_cpld_add_client(client);
+ return 0;
+
+exit_free:
+ kfree(data);
+exit:
+ return ret;
+}
+
+static int as7312_54x_cpld_remove(struct i2c_client *client)
+{
+ struct as7312_54x_cpld_data *data = i2c_get_clientdata(client);
+ const struct attribute_group *group = NULL;
+
+ as7312_54x_cpld_remove_client(client);
+
+ /* Remove sysfs hooks */
+ switch (data->type) {
+ case as7312_54x_cpld1:
+ group = &as7312_54x_cpld1_group;
+ break;
+ case as7312_54x_cpld2:
+ group = &as7312_54x_cpld2_group;
+ break;
+ case as7312_54x_cpld3:
+ group = &as7312_54x_cpld3_group;
+ break;
+ default:
+ break;
+ }
+
+ if (group) {
+ sysfs_remove_group(&client->dev.kobj, group);
+ }
+
+ kfree(data);
+
+ return 0;
+}
+
+static int as7312_54x_cpld_read_internal(struct i2c_client *client, u8 reg)
+{
+ int status = 0, retry = I2C_RW_RETRY_COUNT;
+
+ while (retry) {
+ status = i2c_smbus_read_byte_data(client, reg);
+ if (unlikely(status < 0)) {
+ msleep(I2C_RW_RETRY_INTERVAL);
+ retry--;
+ continue;
+ }
+
+ break;
+ }
+
+ return status;
+}
+
+static int as7312_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value)
+{
+ int status = 0, retry = I2C_RW_RETRY_COUNT;
+
+ while (retry) {
+ status = i2c_smbus_write_byte_data(client, reg, value);
+ if (unlikely(status < 0)) {
+ msleep(I2C_RW_RETRY_INTERVAL);
+ retry--;
+ continue;
+ }
+
+ break;
+ }
+
+ return status;
+}
+
+int as7312_54x_cpld_read(unsigned short cpld_addr, u8 reg)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int ret = -EPERM;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client->addr == cpld_addr) {
+ ret = as7312_54x_cpld_read_internal(cpld_node->client, reg);
+ break;
+ }
+ }
+
+ mutex_unlock(&list_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(as7312_54x_cpld_read);
+
+int as7312_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int ret = -EIO;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client->addr == cpld_addr) {
+ ret = as7312_54x_cpld_write_internal(cpld_node->client, reg, value);
+ break;
+ }
+ }
+
+ mutex_unlock(&list_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(as7312_54x_cpld_write);
+
+static struct i2c_driver as7312_54x_cpld_driver = {
+ .driver = {
+ .name = "as7312_54x_cpld",
+ .owner = THIS_MODULE,
+ },
+ .probe = as7312_54x_cpld_probe,
+ .remove = as7312_54x_cpld_remove,
+ .id_table = as7312_54x_cpld_id,
+};
+
+static int __init as7312_54x_cpld_init(void)
+{
+ mutex_init(&list_lock);
+ return i2c_add_driver(&as7312_54x_cpld_driver);
+}
+
+static void __exit as7312_54x_cpld_exit(void)
+{
+ i2c_del_driver(&as7312_54x_cpld_driver);
+}
+
+MODULE_AUTHOR("Brandon Chuang